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->Register(this);
picker->Delete();
this->InteractionMode = VTKIS_IMAGE2D;
SetCurrentImageNumber(0);
}
ResliceImageInteractorStyle::~ResliceImageInteractorStyle() {
@@ -28,13 +30,13 @@ ResliceImageInteractorStyle::~ResliceImageInteractorStyle() {
}
void ResliceImageInteractorStyle::OnMouseMove() {
int x = this->Interactor->GetEventPosition()[0];
int y = this->Interactor->GetEventPosition()[1];
switch (this->State) {
case VTKIS_NONE: {
if (triggerEvent)
{
this->InvokeEvent(vtkCommand::UserEvent+20,Interactor->GetEventPosition());
this->InvokeEvent(ResliceCursorLegendActor::MOUSE_FREE_MOVE, Interactor->GetEventPosition());
this->Interactor->Render();
}
NoneStatePick();
break;
}
@@ -42,26 +44,75 @@ void ResliceImageInteractorStyle::OnMouseMove() {
this->Interactor->Render();
auto cursor = ResliceCursorLegendActor::SafeDownCast(this->CurrentProp);
cursor->InvokeDragEvent();
break;
}
default:
vtkInteractorStyleImage::OnMouseMove();
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() {
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){
StartCursorInteractive();
auto cursor = ResliceCursorLegendActor::SafeDownCast(this->CurrentProp);
cursor->SetDragStartPosition(Interactor->GetEventPosition());
cursor->SetDragStartPosition(pos);
cursor->StartDrag();
}
else{
vtkInteractorStyleImage::OnLeftButtonDown();
else if (this->InteractionMode == VTKIS_WINDOW_LEVEL)
{
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() {
this->InvokeEvent(ResliceCursorLegendActor::IMAGE_INTERACT_OFF);
if (this->CurrentProp){
StopCursorInteractive();
ResliceCursorLegendActor::SafeDownCast(this->CurrentProp)->StopDrag();
@@ -70,7 +121,6 @@ void ResliceImageInteractorStyle::OnLeftButtonUp() {
else {
vtkInteractorStyleImage::OnLeftButtonUp();
}
triggerEvent = true;
}
void ResliceImageInteractorStyle::NoneStatePick() {

View File

@@ -129,7 +129,7 @@ void ResliceCursorLegendActor::BuildShape(vtkRenderer *renderer) {
if(dragging){
Drag(renderer);
}
if (LoadTime.GetMTime()>MTime.GetMTime()) return;
if (LoadTime.GetMTime()>MTime.GetMTime() && LoadTime.GetMTime()>renderer->GetActiveCamera()->GetMTime()) return;
//handle disk
if (HandleUpdated) {
renderer->SetDisplayPoint(Handle2DPoint[0], Handle2DPoint[1], 0);
@@ -208,10 +208,8 @@ int ResliceCursorLegendActor::RenderOverlay(vtkViewport *viewport) {
if (!renderer) return 0;
BuildShape(renderer);
if (LineActor->GetVisibility())LineActor->RenderOverlay(viewport);
if (ControlPointActive){
if (ControlPointSenseArea->GetVisibility())ControlPointSenseArea->RenderOverlay(viewport);
if (ControlPoint->GetVisibility())ControlPoint->RenderOverlay(viewport);
}
return 1;
}
@@ -220,7 +218,7 @@ vtkProperty2D *ResliceCursorLegendActor::GetProperty() {
}
void ResliceCursorLegendActor::UpdateMousePosition(int* pos) {
ControlPointActive = true;
if (!ControlPoint->GetVisibility())return;
double point0[3] = {.0,.0,.0};
double point1[3] = {.0,.0,.0};
linePolyData->GetPoints()->GetPoint(0,point0);
@@ -373,3 +371,21 @@ void ResliceCursorLegendActor::UpdateCursor3DPoint(vtkRenderer * renderer) {
vtkMath::Cross(vector, GetProjectDirectionVector(), 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{
ROLL = vtkCommand::UserEvent+1000,
MOVE,
END_DRAG
END_DRAG,
MOUSE_FREE_MOVE,
IMAGE_INTERACT_ON,
IMAGE_INTERACT_OFF
};
vtkSetVector3Macro(SlicePoint,double);
@@ -102,10 +105,15 @@ public:
}
}
void ActiveControlPointOn();
void ActiveControlPointOff();
void Drag(vtkRenderer* renderer);
void InvokeDragEvent();
void UpdateLoadTime();
vtkSetMacro(ReferenceCursor,ResliceCursorLegendActor*);
protected:

View File

@@ -229,7 +229,9 @@ void ResliceImageViewer::Render() {
OrientationMatrix->MultiplyPoint(sliceDirection2,sliceDirection2);
cursor1->SetSliceDirectionVector(sliceDirection1);
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->RenderWindow->AddObserver(vtkCommand::WindowResizeEvent,this,&ResliceImageViewer::handleResize);
@@ -320,11 +322,14 @@ void ResliceImageViewer::ChangeSliceNormal(double *normal) {
camera->GetDirectionOfProjection(proj);
double a = proj[0] * normal[0] + proj[1]* normal[1] + proj[2] * normal[2];
double step = 30.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->OrthogonalizeViewUp();
Renderer->ResetCameraClippingRange();
//avoid cursor update by camera modified
cursor1->UpdateLoadTime();
cursor2->UpdateLoadTime();
UpdateDirectionAnnotation();
}
@@ -383,3 +388,10 @@ void ResliceImageViewer::UpdateDirectionAnnotation() {
GetDirectionString(viewLeft, 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();
void updateHandle(vtkObject* sender, unsigned long eventID, void* callData);
void ResetHandle();
private:
ResliceImageViewer(const ResliceImageViewer &) = delete;
void operator=(const ResliceImageViewer &) = delete;