Improve cursor interactive logic.(mouse left button press/release handle hide/show, move and roll with image)
This commit is contained in:
@@ -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() {
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user