Improve cursor interactive logic.(mouse left button press/release handle hide/show, move and roll with image)

This commit is contained in:
Krad
2022-12-30 16:06:45 +08:00
parent 121571b13b
commit b4f98698c3
5 changed files with 119 additions and 31 deletions

View File

@@ -21,6 +21,8 @@ ResliceImageInteractorStyle::ResliceImageInteractorStyle():vtkInteractorStyleIma
picker = vtkPropPicker::New(); picker = vtkPropPicker::New();
picker->Register(this); picker->Register(this);
picker->Delete(); picker->Delete();
this->InteractionMode = VTKIS_IMAGE2D;
SetCurrentImageNumber(0);
} }
ResliceImageInteractorStyle::~ResliceImageInteractorStyle() { ResliceImageInteractorStyle::~ResliceImageInteractorStyle() {
@@ -28,40 +30,89 @@ ResliceImageInteractorStyle::~ResliceImageInteractorStyle() {
} }
void ResliceImageInteractorStyle::OnMouseMove() { void ResliceImageInteractorStyle::OnMouseMove() {
switch (this->State) { int x = this->Interactor->GetEventPosition()[0];
case VTKIS_NONE:{ int y = this->Interactor->GetEventPosition()[1];
if (triggerEvent)
{ switch (this->State) {
this->InvokeEvent(vtkCommand::UserEvent+20,Interactor->GetEventPosition()); case VTKIS_NONE: {
this->Interactor->Render(); this->InvokeEvent(ResliceCursorLegendActor::MOUSE_FREE_MOVE, Interactor->GetEventPosition());
} this->Interactor->Render();
NoneStatePick(); NoneStatePick();
break; break;
}
case VTKIS_POSITION_PROP: {
this->Interactor->Render();
auto cursor = ResliceCursorLegendActor::SafeDownCast(this->CurrentProp);
cursor->InvokeDragEvent();
}
default:
vtkInteractorStyleImage::OnMouseMove();
} }
case VTKIS_POSITION_PROP: {
this->Interactor->Render();
auto cursor = ResliceCursorLegendActor::SafeDownCast(this->CurrentProp);
cursor->InvokeDragEvent();
break;
}
case VTKIS_WINDOW_LEVEL:
this->FindPokedRenderer(x, y);
this->WindowLevel();
this->InvokeEvent(vtkCommand::InteractionEvent, nullptr);
break;
case VTKIS_PICK:
this->FindPokedRenderer(x, y);
this->Pick();
this->InvokeEvent(vtkCommand::InteractionEvent, nullptr);
break;
case VTKIS_SLICE:
this->FindPokedRenderer(x, y);
this->Slice();
this->InvokeEvent(vtkCommand::InteractionEvent, nullptr);
break;
}
// Call parent to handle all other states and perform additional work
this->Superclass::OnMouseMove();
} }
void ResliceImageInteractorStyle::OnLeftButtonDown() { void ResliceImageInteractorStyle::OnLeftButtonDown() {
triggerEvent = false; int* pos = this->Interactor->GetEventPosition();
this->FindPokedRenderer(pos[0], pos[1]);
if (this->CurrentRenderer == nullptr)
{
return;
}
this->InvokeEvent(ResliceCursorLegendActor::IMAGE_INTERACT_ON);
this->GrabFocus(this->EventCallbackCommand);
if (this->CurrentProp){ if (this->CurrentProp){
StartCursorInteractive(); StartCursorInteractive();
auto cursor = ResliceCursorLegendActor::SafeDownCast(this->CurrentProp); auto cursor = ResliceCursorLegendActor::SafeDownCast(this->CurrentProp);
cursor->SetDragStartPosition(Interactor->GetEventPosition()); cursor->SetDragStartPosition(pos);
cursor->StartDrag(); cursor->StartDrag();
} }
else{ else if (this->InteractionMode == VTKIS_WINDOW_LEVEL)
vtkInteractorStyleImage::OnLeftButtonDown(); {
this->WindowLevelStartPosition[0] = pos[0];
this->WindowLevelStartPosition[1] = pos[1];
this->StartWindowLevel();
}
else if (this->InteractionMode == VTKIS_IMAGE3D)
{
this->StartRotate();
}
else if (this->InteractionMode == VTKIS_IMAGE2D)
{
this->StartSpin();
}
else if (this->InteractionMode == VTKIS_IMAGE_SLICING)
{
this->StartSlice();
}
else
{
this->Superclass::OnLeftButtonDown();
} }
} }
void ResliceImageInteractorStyle::OnLeftButtonUp() { void ResliceImageInteractorStyle::OnLeftButtonUp() {
this->InvokeEvent(ResliceCursorLegendActor::IMAGE_INTERACT_OFF);
if (this->CurrentProp){ if (this->CurrentProp){
StopCursorInteractive(); StopCursorInteractive();
ResliceCursorLegendActor::SafeDownCast(this->CurrentProp)->StopDrag(); ResliceCursorLegendActor::SafeDownCast(this->CurrentProp)->StopDrag();
@@ -70,7 +121,6 @@ void ResliceImageInteractorStyle::OnLeftButtonUp() {
else { else {
vtkInteractorStyleImage::OnLeftButtonUp(); vtkInteractorStyleImage::OnLeftButtonUp();
} }
triggerEvent = true;
} }
void ResliceImageInteractorStyle::NoneStatePick() { void ResliceImageInteractorStyle::NoneStatePick() {

View File

@@ -129,7 +129,7 @@ void ResliceCursorLegendActor::BuildShape(vtkRenderer *renderer) {
if(dragging){ if(dragging){
Drag(renderer); Drag(renderer);
} }
if (LoadTime.GetMTime()>MTime.GetMTime()) return; if (LoadTime.GetMTime()>MTime.GetMTime() && LoadTime.GetMTime()>renderer->GetActiveCamera()->GetMTime()) return;
//handle disk //handle disk
if (HandleUpdated) { if (HandleUpdated) {
renderer->SetDisplayPoint(Handle2DPoint[0], Handle2DPoint[1], 0); renderer->SetDisplayPoint(Handle2DPoint[0], Handle2DPoint[1], 0);
@@ -208,10 +208,8 @@ int ResliceCursorLegendActor::RenderOverlay(vtkViewport *viewport) {
if (!renderer) return 0; if (!renderer) return 0;
BuildShape(renderer); BuildShape(renderer);
if (LineActor->GetVisibility())LineActor->RenderOverlay(viewport); if (LineActor->GetVisibility())LineActor->RenderOverlay(viewport);
if (ControlPointActive){ if (ControlPointSenseArea->GetVisibility())ControlPointSenseArea->RenderOverlay(viewport);
if (ControlPointSenseArea->GetVisibility())ControlPointSenseArea->RenderOverlay(viewport); if (ControlPoint->GetVisibility())ControlPoint->RenderOverlay(viewport);
if (ControlPoint->GetVisibility())ControlPoint->RenderOverlay(viewport);
}
return 1; return 1;
} }
@@ -220,7 +218,7 @@ vtkProperty2D *ResliceCursorLegendActor::GetProperty() {
} }
void ResliceCursorLegendActor::UpdateMousePosition(int* pos) { void ResliceCursorLegendActor::UpdateMousePosition(int* pos) {
ControlPointActive = true; if (!ControlPoint->GetVisibility())return;
double point0[3] = {.0,.0,.0}; double point0[3] = {.0,.0,.0};
double point1[3] = {.0,.0,.0}; double point1[3] = {.0,.0,.0};
linePolyData->GetPoints()->GetPoint(0,point0); linePolyData->GetPoints()->GetPoint(0,point0);
@@ -373,3 +371,21 @@ void ResliceCursorLegendActor::UpdateCursor3DPoint(vtkRenderer * renderer) {
vtkMath::Cross(vector, GetProjectDirectionVector(), vector); vtkMath::Cross(vector, GetProjectDirectionVector(), vector);
this->SetSliceDirectionVector(vector); this->SetSliceDirectionVector(vector);
} }
void ResliceCursorLegendActor::UpdateLoadTime() {
LoadTime.Modified();
}
void ResliceCursorLegendActor::ActiveControlPointOn() {
ControlPoint->SetVisibility(1);
ControlPointSenseArea->SetVisibility(1);
ReferenceCursor->ControlPoint->SetVisibility(1);
ReferenceCursor->ControlPointSenseArea->SetVisibility(1);
}
void ResliceCursorLegendActor::ActiveControlPointOff() {
ControlPoint->SetVisibility(0);
ControlPointSenseArea->SetVisibility(0);
ReferenceCursor->ControlPoint->SetVisibility(0);
ReferenceCursor->ControlPointSenseArea->SetVisibility(0);
}

View File

@@ -31,7 +31,10 @@ public:
enum EventType{ enum EventType{
ROLL = vtkCommand::UserEvent+1000, ROLL = vtkCommand::UserEvent+1000,
MOVE, MOVE,
END_DRAG END_DRAG,
MOUSE_FREE_MOVE,
IMAGE_INTERACT_ON,
IMAGE_INTERACT_OFF
}; };
vtkSetVector3Macro(SlicePoint,double); vtkSetVector3Macro(SlicePoint,double);
@@ -102,10 +105,15 @@ public:
} }
} }
void ActiveControlPointOn();
void ActiveControlPointOff();
void Drag(vtkRenderer* renderer); void Drag(vtkRenderer* renderer);
void InvokeDragEvent(); void InvokeDragEvent();
void UpdateLoadTime();
vtkSetMacro(ReferenceCursor,ResliceCursorLegendActor*); vtkSetMacro(ReferenceCursor,ResliceCursorLegendActor*);
protected: protected:

View File

@@ -229,7 +229,9 @@ void ResliceImageViewer::Render() {
OrientationMatrix->MultiplyPoint(sliceDirection2,sliceDirection2); OrientationMatrix->MultiplyPoint(sliceDirection2,sliceDirection2);
cursor1->SetSliceDirectionVector(sliceDirection1); cursor1->SetSliceDirectionVector(sliceDirection1);
cursor2->SetSliceDirectionVector(sliceDirection2); cursor2->SetSliceDirectionVector(sliceDirection2);
this->InteractorStyle->AddObserver(vtkCommand::UserEvent+20,this,&ResliceImageViewer::updateHandle); this->InteractorStyle->AddObserver(ResliceCursorLegendActor::MOUSE_FREE_MOVE,this,&ResliceImageViewer::updateHandle);
this->InteractorStyle->AddObserver(ResliceCursorLegendActor::IMAGE_INTERACT_ON,cursor1,&ResliceCursorLegendActor::ActiveControlPointOff);
this->InteractorStyle->AddObserver(ResliceCursorLegendActor::IMAGE_INTERACT_OFF,this,&ResliceImageViewer::ResetHandle);
this->InteractorStyle->AddObserver(ResliceCursorLegendActor::END_DRAG,this,&ResliceImageViewer::EndDrag); this->InteractorStyle->AddObserver(ResliceCursorLegendActor::END_DRAG,this,&ResliceImageViewer::EndDrag);
this->RenderWindow->AddObserver(vtkCommand::WindowResizeEvent,this,&ResliceImageViewer::handleResize); this->RenderWindow->AddObserver(vtkCommand::WindowResizeEvent,this,&ResliceImageViewer::handleResize);
@@ -320,11 +322,14 @@ void ResliceImageViewer::ChangeSliceNormal(double *normal) {
camera->GetDirectionOfProjection(proj); camera->GetDirectionOfProjection(proj);
double a = proj[0] * normal[0] + proj[1]* normal[1] + proj[2] * normal[2]; double a = proj[0] * normal[0] + proj[1]* normal[1] + proj[2] * normal[2];
double step = 30.0; double step = 30.0;
//防止图像反向翻转
if (a>0)step = step*-1.0; if (a>0)step = step*-1.0;
// vtkErrorMacro("proj:"<<proj[0]<<","<<proj[1]<<","<<proj[2]<<"; normal:"<<normal[0]<<", "<<normal[1]<<", "<<normal[2]);
camera->SetPosition(focalPt[0]+step*normal[0],focalPt[1]+step*normal[1],focalPt[2]+step*normal[2]); camera->SetPosition(focalPt[0]+step*normal[0],focalPt[1]+step*normal[1],focalPt[2]+step*normal[2]);
camera->OrthogonalizeViewUp(); camera->OrthogonalizeViewUp();
Renderer->ResetCameraClippingRange(); Renderer->ResetCameraClippingRange();
//avoid cursor update by camera modified
cursor1->UpdateLoadTime();
cursor2->UpdateLoadTime();
UpdateDirectionAnnotation(); UpdateDirectionAnnotation();
} }
@@ -383,3 +388,10 @@ void ResliceImageViewer::UpdateDirectionAnnotation() {
GetDirectionString(viewLeft, str); GetDirectionString(viewLeft, str);
annotation->SetText(6,str.c_str() ); annotation->SetText(6,str.c_str() );
} }
void ResliceImageViewer::ResetHandle() {
cursor1->ActiveControlPointOn();
int* pos = Interactor->GetEventPosition();
cursor1->UpdateMousePosition(pos);
cursor2->UpdateMousePosition(pos);
}

View File

@@ -65,6 +65,8 @@ protected:
virtual void UnInstallPipeline(); virtual void UnInstallPipeline();
void updateHandle(vtkObject* sender, unsigned long eventID, void* callData); void updateHandle(vtkObject* sender, unsigned long eventID, void* callData);
void ResetHandle();
private: private:
ResliceImageViewer(const ResliceImageViewer &) = delete; ResliceImageViewer(const ResliceImageViewer &) = delete;
void operator=(const ResliceImageViewer &) = delete; void operator=(const ResliceImageViewer &) = delete;