Add 3D Reslice MPR free rotate.
This commit is contained in:
@@ -232,3 +232,49 @@ void ResliceImageInteractorStyle::WindowLevel() {
|
|||||||
void ResliceImageInteractorStyle::SetMode(int mode) {
|
void ResliceImageInteractorStyle::SetMode(int mode) {
|
||||||
this->InteractionMode = mode;
|
this->InteractionMode = mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ResliceImageInteractorStyle::Rotate()
|
||||||
|
{
|
||||||
|
if (this->CurrentRenderer == nullptr)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
vtkRenderWindowInteractor* rwi = this->Interactor;
|
||||||
|
|
||||||
|
int dx = rwi->GetEventPosition()[0] - rwi->GetLastEventPosition()[0];
|
||||||
|
int dy = rwi->GetEventPosition()[1] - rwi->GetLastEventPosition()[1];
|
||||||
|
|
||||||
|
const int* size = this->CurrentRenderer->GetRenderWindow()->GetSize();
|
||||||
|
|
||||||
|
double delta_elevation = -20.0 / size[1];
|
||||||
|
double delta_azimuth = -20.0 / size[0];
|
||||||
|
|
||||||
|
double rxf = dx * delta_azimuth * this->MotionFactor;
|
||||||
|
double ryf = dy * delta_elevation * this->MotionFactor;
|
||||||
|
|
||||||
|
vtkCamera* camera = this->CurrentRenderer->GetActiveCamera();
|
||||||
|
camera->Azimuth(rxf);
|
||||||
|
camera->Elevation(ryf);
|
||||||
|
camera->OrthogonalizeViewUp();
|
||||||
|
|
||||||
|
if (this->AutoAdjustCameraClippingRange)
|
||||||
|
{
|
||||||
|
this->CurrentRenderer->ResetCameraClippingRange();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rwi->GetLightFollowCamera())
|
||||||
|
{
|
||||||
|
this->CurrentRenderer->UpdateLightsGeometryToFollowCamera();
|
||||||
|
}
|
||||||
|
if (this->HandleObservers &&
|
||||||
|
this->HasObserver(vtkCommand::RotateEvent)) {
|
||||||
|
this->InvokeEvent(vtkCommand::RotateEvent, this);
|
||||||
|
}
|
||||||
|
rwi->Render();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResliceImageInteractorStyle::EndRotate() {
|
||||||
|
this->InvokeEvent(vtkCommand::EndRotateEvent);
|
||||||
|
vtkInteractorStyle::EndRotate();
|
||||||
|
}
|
||||||
|
|||||||
@@ -37,6 +37,11 @@ public:
|
|||||||
this->State = VTKIS_NONE;
|
this->State = VTKIS_NONE;
|
||||||
}
|
}
|
||||||
vtkSetMacro(CurrentImageProperty, vtkImageProperty*);
|
vtkSetMacro(CurrentImageProperty, vtkImageProperty*);
|
||||||
|
|
||||||
|
void Rotate() override;
|
||||||
|
|
||||||
|
void EndRotate() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
ResliceImageInteractorStyle();
|
ResliceImageInteractorStyle();
|
||||||
|
|||||||
@@ -129,7 +129,13 @@ void ResliceCursorLegendActor::BuildShape(vtkRenderer *renderer) {
|
|||||||
if(dragging){
|
if(dragging){
|
||||||
Drag(renderer);
|
Drag(renderer);
|
||||||
}
|
}
|
||||||
|
auto style = vtkInteractorStyle::SafeDownCast(renderer->GetRenderWindow()->GetInteractor()->GetInteractorStyle());
|
||||||
|
if (style){
|
||||||
|
//avoid 3d rotate update
|
||||||
|
if (style->GetState() == VTKIS_ROTATE) return;
|
||||||
|
}
|
||||||
if (LoadTime.GetMTime()>MTime.GetMTime() && LoadTime.GetMTime()>renderer->GetActiveCamera()->GetMTime()) return;
|
if (LoadTime.GetMTime()>MTime.GetMTime() && LoadTime.GetMTime()>renderer->GetActiveCamera()->GetMTime()) return;
|
||||||
|
if (StopUpdateFlag) return;
|
||||||
//handle disk
|
//handle disk
|
||||||
if (HandleUpdated) {
|
if (HandleUpdated) {
|
||||||
renderer->SetDisplayPoint(Handle2DPoint[0], Handle2DPoint[1], 0);
|
renderer->SetDisplayPoint(Handle2DPoint[0], Handle2DPoint[1], 0);
|
||||||
@@ -187,8 +193,15 @@ void ResliceCursorLegendActor::BuildShape(vtkRenderer *renderer) {
|
|||||||
if (IntersectLine2D(p0, v1, pt, screenVectors[i], intersectPoint)) {
|
if (IntersectLine2D(p0, v1, pt, screenVectors[i], intersectPoint)) {
|
||||||
int pcV = (int) intersectPoint.getValue(i);
|
int pcV = (int) intersectPoint.getValue(i);
|
||||||
if (pcV >= -1 && pcV <= size[i] + 1) {
|
if (pcV >= -1 && pcV <= size[i] + 1) {
|
||||||
linePolyData->GetPoints()->SetPoint(pointIdx++, (int) intersectPoint.X + 0.05,
|
//避免double计算精度导致的极小的移动产生的hair cross振动
|
||||||
(int) intersectPoint.Y + 0.05, 0);
|
double oldPt[3] = {.0, .0, .0};
|
||||||
|
linePolyData->GetPoints()->GetPoint(pointIdx, oldPt);
|
||||||
|
double newPt[3] = {(int) intersectPoint.X + 0.05,
|
||||||
|
(int) intersectPoint.Y + 0.05, .0};
|
||||||
|
if (vtkMath::Distance2BetweenPoints(oldPt,newPt)>0.9){
|
||||||
|
linePolyData->GetPoints()->SetPoint(pointIdx, newPt);
|
||||||
|
}
|
||||||
|
pointIdx++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -105,6 +105,13 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void StopUpdate(){
|
||||||
|
StopUpdateFlag = true;
|
||||||
|
}
|
||||||
|
void BeginUpdate(){
|
||||||
|
StopUpdateFlag = false;
|
||||||
|
}
|
||||||
|
|
||||||
void ActiveControlPointOn();
|
void ActiveControlPointOn();
|
||||||
void ActiveControlPointOff();
|
void ActiveControlPointOff();
|
||||||
|
|
||||||
@@ -144,6 +151,7 @@ private:
|
|||||||
bool dragging = false;
|
bool dragging = false;
|
||||||
bool Moving = false;
|
bool Moving = false;
|
||||||
bool Rolling = false;
|
bool Rolling = false;
|
||||||
|
bool StopUpdateFlag = false;
|
||||||
int DragStartPosition[2] = {0,0};
|
int DragStartPosition[2] = {0,0};
|
||||||
double Handle2DPoint[2] = {.0, .0, };
|
double Handle2DPoint[2] = {.0, .0, };
|
||||||
double SliceDirectionVector[3] = {.0, .0, .0};
|
double SliceDirectionVector[3] = {.0, .0, .0};
|
||||||
|
|||||||
@@ -198,6 +198,8 @@ void ResliceImageViewer::Render() {
|
|||||||
this->InteractorStyle->AddObserver(SliceEvent,this, &ResliceImageViewer::SliceCallback);
|
this->InteractorStyle->AddObserver(SliceEvent,this, &ResliceImageViewer::SliceCallback);
|
||||||
this->InteractorStyle->AddObserver(vtkCommand::WindowLevelEvent,this, &ResliceImageViewer::WindowLevelCallback);
|
this->InteractorStyle->AddObserver(vtkCommand::WindowLevelEvent,this, &ResliceImageViewer::WindowLevelCallback);
|
||||||
this->InteractorStyle->AddObserver(vtkCommand::EndWindowLevelEvent,this, &ResliceImageViewer::EndWindowLevelCallback);
|
this->InteractorStyle->AddObserver(vtkCommand::EndWindowLevelEvent,this, &ResliceImageViewer::EndWindowLevelCallback);
|
||||||
|
this->InteractorStyle->AddObserver(vtkCommand::RotateEvent,this, &ResliceImageViewer::EndRotateCallback);
|
||||||
|
// this->InteractorStyle->AddObserver(vtkCommand::EndRotateEvent,this, &ResliceImageViewer::EndRotateCallback);
|
||||||
|
|
||||||
this->RenderWindow->AddObserver(vtkCommand::WindowResizeEvent,this,&ResliceImageViewer::handleResize);
|
this->RenderWindow->AddObserver(vtkCommand::WindowResizeEvent,this,&ResliceImageViewer::handleResize);
|
||||||
cursor1->AddObserver(ResliceCursorLegendActor::ROLL,this, &ResliceImageViewer::handleRoll);
|
cursor1->AddObserver(ResliceCursorLegendActor::ROLL,this, &ResliceImageViewer::handleRoll);
|
||||||
@@ -494,3 +496,25 @@ void ResliceImageViewer::WindowLevelCallback() {
|
|||||||
(int)Actor->GetProperty()->GetColorWindow());
|
(int)Actor->GetProperty()->GetColorWindow());
|
||||||
annotation->SetText(5, buff);
|
annotation->SetText(5, buff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ResliceImageViewer::EndRotateCallback() {
|
||||||
|
auto camera = Renderer->GetActiveCamera();
|
||||||
|
cursor1->SetProjectDirectionVector(camera->GetDirectionOfProjection());
|
||||||
|
cursor2->SetProjectDirectionVector(camera->GetDirectionOfProjection());
|
||||||
|
cursor1->UpdateCursor3DPoint(this->Renderer);
|
||||||
|
cursor2->UpdateCursor3DPoint(this->Renderer);
|
||||||
|
this->InvokeEvent(vtkCommand::RotateEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResliceImageViewer::ChangeCursorVector(double * vector1, double * vector2) {
|
||||||
|
auto camera = Renderer->GetActiveCamera();
|
||||||
|
cursor1->SetProjectDirectionVector(camera->GetDirectionOfProjection());
|
||||||
|
cursor2->SetProjectDirectionVector(camera->GetDirectionOfProjection());
|
||||||
|
cursor1->SetSliceDirectionVector(vector1);
|
||||||
|
cursor2->SetSliceDirectionVector(vector2);
|
||||||
|
}
|
||||||
|
|
||||||
|
double* ResliceImageViewer::GetSliceNormal() {
|
||||||
|
return Renderer->GetActiveCamera()->GetDirectionOfProjection();
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -61,6 +61,10 @@ public:
|
|||||||
|
|
||||||
void ChangeSliceNormal(double * normal);
|
void ChangeSliceNormal(double * normal);
|
||||||
|
|
||||||
|
void ChangeCursorVector(double * vector1, double * vector2);
|
||||||
|
|
||||||
|
double* GetSliceNormal();
|
||||||
|
|
||||||
void EndDrag();
|
void EndDrag();
|
||||||
|
|
||||||
void UpdateSliceCursor();
|
void UpdateSliceCursor();
|
||||||
@@ -77,6 +81,8 @@ public:
|
|||||||
|
|
||||||
void EndWindowLevelCallback();
|
void EndWindowLevelCallback();
|
||||||
|
|
||||||
|
void EndRotateCallback();
|
||||||
|
|
||||||
void GetWindowLevel(double* windowLeveL);
|
void GetWindowLevel(double* windowLeveL);
|
||||||
|
|
||||||
void SetWindowLevel(double* windowLeveL);
|
void SetWindowLevel(double* windowLeveL);
|
||||||
|
|||||||
@@ -50,6 +50,9 @@ void ResliceImageManager::InitEvents() {
|
|||||||
viewerA->AddObserver(SliceEvent,this,&ResliceImageManager::MoveCallback);
|
viewerA->AddObserver(SliceEvent,this,&ResliceImageManager::MoveCallback);
|
||||||
viewerS->AddObserver(SliceEvent,this,&ResliceImageManager::MoveCallback);
|
viewerS->AddObserver(SliceEvent,this,&ResliceImageManager::MoveCallback);
|
||||||
viewerC->AddObserver(SliceEvent,this,&ResliceImageManager::MoveCallback);
|
viewerC->AddObserver(SliceEvent,this,&ResliceImageManager::MoveCallback);
|
||||||
|
viewerA->AddObserver(vtkCommand::RotateEvent,this,&ResliceImageManager::RotateCallback);
|
||||||
|
viewerS->AddObserver(vtkCommand::RotateEvent,this,&ResliceImageManager::RotateCallback);
|
||||||
|
viewerC->AddObserver(vtkCommand::RotateEvent,this,&ResliceImageManager::RotateCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResliceImageManager::RollCallback(vtkObject *sender, unsigned long eventID, void *data) {
|
void ResliceImageManager::RollCallback(vtkObject *sender, unsigned long eventID, void *data) {
|
||||||
@@ -113,10 +116,10 @@ void ResliceImageManager::EndDrag(vtkObject *sender, unsigned long eventID, void
|
|||||||
|
|
||||||
void ResliceImageManager::ClickCallback(vtkObject *sender, unsigned long eventID, void *data) {
|
void ResliceImageManager::ClickCallback(vtkObject *sender, unsigned long eventID, void *data) {
|
||||||
auto viewer = ResliceImageViewer::SafeDownCast(sender);
|
auto viewer = ResliceImageViewer::SafeDownCast(sender);
|
||||||
if (viewer){
|
if (viewer) {
|
||||||
viewerA->SetChecked(viewer==viewerA);
|
viewerA->SetChecked(viewer == viewerA);
|
||||||
viewerS->SetChecked(viewer==viewerS);
|
viewerS->SetChecked(viewer == viewerS);
|
||||||
viewerC->SetChecked(viewer==viewerC);
|
viewerC->SetChecked(viewer == viewerC);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,3 +146,33 @@ void ResliceImageManager::WindowLevelCallback(vtkObject *sender, unsigned long e
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ResliceImageManager::RotateCallback(vtkObject *sender, unsigned long eventID, void *data) {
|
||||||
|
auto viewer = ResliceImageViewer::SafeDownCast(sender);
|
||||||
|
if (viewer){
|
||||||
|
if (viewer==viewerA){
|
||||||
|
viewerC->ChangeSliceNormal(viewer->GetCursorSliceDirection2());
|
||||||
|
viewerC->ChangeCursorVector(viewer->GetCursorSliceDirection1(),viewer->GetSliceNormal());
|
||||||
|
viewerC->Render();
|
||||||
|
viewerS->ChangeSliceNormal(viewer->GetCursorSliceDirection1());
|
||||||
|
viewerS->ChangeCursorVector(viewer->GetSliceNormal(),viewer->GetCursorSliceDirection2());
|
||||||
|
viewerS->Render();
|
||||||
|
}
|
||||||
|
if (viewer==viewerC){
|
||||||
|
viewerA->ChangeSliceNormal(viewer->GetCursorSliceDirection2());
|
||||||
|
viewerA->ChangeCursorVector(viewer->GetCursorSliceDirection1(),viewer->GetSliceNormal());
|
||||||
|
viewerA->Render();
|
||||||
|
viewerS->ChangeSliceNormal(viewer->GetCursorSliceDirection1());
|
||||||
|
viewerS->ChangeCursorVector(viewer->GetSliceNormal(),viewer->GetCursorSliceDirection2());
|
||||||
|
viewerS->Render();
|
||||||
|
}
|
||||||
|
if (viewer==viewerS){
|
||||||
|
viewerC->ChangeSliceNormal(viewer->GetCursorSliceDirection2());
|
||||||
|
viewerC->ChangeCursorVector(viewer->GetCursorSliceDirection1(),viewer->GetSliceNormal());
|
||||||
|
viewerC->Render();
|
||||||
|
viewerA->ChangeSliceNormal(viewer->GetCursorSliceDirection1());
|
||||||
|
viewerA->ChangeCursorVector(viewer->GetSliceNormal(),viewer->GetCursorSliceDirection2());
|
||||||
|
viewerA->Render();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ private:
|
|||||||
void MoveCallback(vtkObject* sender, unsigned long eventID, void* data);
|
void MoveCallback(vtkObject* sender, unsigned long eventID, void* data);
|
||||||
void ClickCallback(vtkObject* sender, unsigned long eventID, void* data);
|
void ClickCallback(vtkObject* sender, unsigned long eventID, void* data);
|
||||||
void WindowLevelCallback(vtkObject* sender, unsigned long eventID, void* data);
|
void WindowLevelCallback(vtkObject* sender, unsigned long eventID, void* data);
|
||||||
|
void RotateCallback(vtkObject* sender, unsigned long eventID, void* data);
|
||||||
// void SliceCallback(vtkObject* sender, unsigned long eventID, void* data);
|
// void SliceCallback(vtkObject* sender, unsigned long eventID, void* data);
|
||||||
void EndDrag(vtkObject* sender, unsigned long eventID, void* data);
|
void EndDrag(vtkObject* sender, unsigned long eventID, void* data);
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user