vtkResliceCursorWidget源码阅读

/*=========================================================================

Program: Visualization Toolkit
Module: vtkResliceCursorWidget.cxx

Copyright © Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

 This software is distributed WITHOUT ANY WARRANTY; without even
 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include “vtkResliceCursorWidget.h”
#include “vtkResliceCursorLineRepresentation.h”
#include “vtkCommand.h”
#include “vtkResliceCursor.h”
#include “vtkCallbackCommand.h”
#include “vtkRenderWindowInteractor.h”
#include “vtkObjectFactory.h”
#include “vtkRenderer.h”
#include “vtkRenderWindow.h”
#include “vtkWidgetEventTranslator.h”
#include “vtkWidgetCallbackMapper.h”
#include “vtkEvent.h”
#include “vtkWidgetEvent.h”
#include “vtkImageData.h”
#include “vtkInteractorStyleImage.h”
#include “vtkImageMapToWindowLevelColors.h”

vtkStandardNewMacro(vtkResliceCursorWidget);

//----------------------------------------------------------------------------
vtkResliceCursorWidget::vtkResliceCursorWidget()
{
// Set the initial state
this->WidgetState = vtkResliceCursorWidget::Start;

this->ModifierActive = 0;

//设置微件的回调,将鼠标左键按下事件转换为 vtkWidgetEvent::Select,这个事件
//没有设置修改器(修改器就是指有没有按住shift ctrl这种,)
//直接调用的方法就是vtkResliceCursorWidget::SelectAction),这是一个静态方法。
//vtkWidgetEvent::Select这个在这个cpp中没有用到,不知道在这个cpp里的作用,
//但是如果你想在类外面给微件添加回调,可以添加这个事件,等于左键按下
this->CallbackMapper->SetCallbackMethod(vtkCommand::LeftButtonPressEvent,
vtkEvent::NoModifier, 0, 0, nullptr,
vtkWidgetEvent::Select,
this, vtkResliceCursorWidget::SelectAction);
//这里就加了一个Control修改器,同样都是左键按下,如果按了ctrl那么执行的就是
// vtkResliceCursorWidget::RotateAction 这个
this->CallbackMapper->SetCallbackMethod(vtkCommand::LeftButtonPressEvent,
vtkEvent::ControlModifier, 0, 0, nullptr,
vtkWidgetEvent::Rotate,
this, vtkResliceCursorWidget::RotateAction);
this->CallbackMapper->SetCallbackMethod(vtkCommand::LeftButtonReleaseEvent,
vtkWidgetEvent::EndSelect,
this, vtkResliceCursorWidget::EndSelectAction);
this->CallbackMapper->SetCallbackMethod(vtkCommand::RightButtonPressEvent,
vtkWidgetEvent::Resize,
this, vtkResliceCursorWidget::ResizeThicknessAction);
this->CallbackMapper->SetCallbackMethod(vtkCommand::RightButtonReleaseEvent,
vtkWidgetEvent::EndResize,
this, vtkResliceCursorWidget::EndSelectAction);
this->CallbackMapper->SetCallbackMethod(vtkCommand::MouseMoveEvent,
vtkWidgetEvent::Move,
this, vtkResliceCursorWidget::MoveAction);
this->CallbackMapper->SetCallbackMethod(vtkCommand::KeyPressEvent,
vtkEvent::NoModifier, 111, 1, “o”,
vtkWidgetEvent::Reset,
this, vtkResliceCursorWidget::ResetResliceCursorAction);

this->ManageWindowLevel = 1;
}

//----------------------------------------------------------------------------
vtkResliceCursorWidget::~vtkResliceCursorWidget() = default;

//----------------------------------------------------------------------
void vtkResliceCursorWidget::SetEnabled(int enabling)
{
this->Superclass::SetEnabled(enabling);
}
//创建默认表达
//----------------------------------------------------------------------
void vtkResliceCursorWidget::CreateDefaultRepresentation()
{
if ( ! this->WidgetRep )
{
this->WidgetRep = vtkResliceCursorLineRepresentation::New();
}
}
//根据鼠标目前位置状态,来为鼠标设置外观,
//-------------------------------------------------------------------------
void vtkResliceCursorWidget::SetCursor(int cState)
{
switch (cState)
{
case vtkResliceCursorRepresentation::OnAxis1:
case vtkResliceCursorRepresentation::OnAxis2:
this->RequestCursorShape(VTK_CURSOR_HAND);
break;
case vtkResliceCursorRepresentation::OnCenter:
if (vtkEvent::GetModifier(this->Interactor) != vtkEvent::ControlModifier)
{
this->RequestCursorShape(VTK_CURSOR_SIZEALL);
}
break;
case vtkResliceCursorRepresentation::Outside:
default:
this->RequestCursorShape(VTK_CURSOR_DEFAULT);
}
}
//暂时还没看mip相关
//-------------------------------------------------------------------------
void vtkResliceCursorWidget::ResizeThicknessAction(vtkAbstractWidget *w)
{
vtkResliceCursorWidget self = reinterpret_cast<vtkResliceCursorWidget>(w);
vtkResliceCursorRepresentation rep =
reinterpret_cast<vtkResliceCursorRepresentation
>(self->WidgetRep);

int X = self->Interactor->GetEventPosition()[0];
int Y = self->Interactor->GetEventPosition()[1];

rep->ComputeInteractionState(X, Y, self->ModifierActive);

if ( self->WidgetRep->GetInteractionState()
== vtkResliceCursorRepresentation::Outside ||
rep->GetResliceCursor()->GetThickMode() == 0 )
{
return;
}

rep->SetManipulationMode(vtkResliceCursorRepresentation::ResizeThickness);

self->GrabFocus(self->EventCallbackCommand);
double eventPos[2];
eventPos[0] = static_cast(X);
eventPos[1] = static_cast(Y);
self->WidgetRep->StartWidgetInteraction(eventPos);

// We are definitely selected
self->WidgetState = vtkResliceCursorWidget::Active;
self->SetCursor(self->WidgetRep->GetInteractionState());

// Highlight as necessary
self->WidgetRep->Highlight(1);

self->EventCallbackCommand->SetAbortFlag(1);
self->StartInteraction();
self->InvokeEvent(vtkCommand::StartInteractionEvent,nullptr);
self->Render();

self->InvokeAnEvent();

// Show the thickness in “mm”
rep->ActivateText(1);
}

//-------------------------------------------------------------------------
void vtkResliceCursorWidget::EndResizeThicknessAction(vtkAbstractWidget *)
{
}
//这里等于左键按下事件,这里是一个静态函数,没有this指针,但是这里通过传参的方
//法弄了一个self指针
//-------------------------------------------------------------------------
void vtkResliceCursorWidget::SelectAction(vtkAbstractWidget *w)
{
vtkResliceCursorWidget self = reinterpret_cast<vtkResliceCursorWidget>(w);
vtkResliceCursorRepresentation rep =
reinterpret_cast<vtkResliceCursorRepresentation
>(self->WidgetRep);

int X = self->Interactor->GetEventPosition()[0];
int Y = self->Interactor->GetEventPosition()[1];
//这里判断有没有按住shif或者ctrl之类的
self->ModifierActive = vtkEvent::GetModifier(self->Interactor);
rep->ComputeInteractionState(X, Y, self->ModifierActive);
//下面就是根据不同状态触发不同事件
if ( self->WidgetRep->GetInteractionState()
== vtkResliceCursorRepresentation::Outside )
{
if (self->GetManageWindowLevel() && rep->GetShowReslicedImage())
{
self->StartWindowLevel();
}
else
{
rep->SetManipulationMode(vtkResliceCursorRepresentation::None);
return;
}
}
else
{
rep->SetManipulationMode(vtkResliceCursorRepresentation::PanAndRotate);
}

if (rep->GetManipulationMode() == vtkResliceCursorRepresentation::None)
{
return;
}

self->GrabFocus(self->EventCallbackCommand);
double eventPos[2];
eventPos[0] = static_cast(X);
eventPos[1] = static_cast(Y);
self->WidgetRep->StartWidgetInteraction(eventPos);

// We are definitely selected
self->WidgetState = vtkResliceCursorWidget::Active;
self->SetCursor(self->WidgetRep->GetInteractionState());

// Highlight as necessary
self->WidgetRep->Highlight(1);

self->EventCallbackCommand->SetAbortFlag(1);
self->StartInteraction();
//最后根据vtkCommand::StartInteractionEvent去执行对应事件
self->InvokeEvent(vtkCommand::StartInteractionEvent,nullptr);
self->Render();

self->InvokeAnEvent();
}
//按住ctrl执行的事件两轴同时旋转
//-------------------------------------------------------------------------
void vtkResliceCursorWidget::RotateAction(vtkAbstractWidget *w)
{
vtkResliceCursorWidget self = reinterpret_cast<vtkResliceCursorWidget>(w);
vtkResliceCursorRepresentation rep =
reinterpret_cast<vtkResliceCursorRepresentation
>(self->WidgetRep);

int X = self->Interactor->GetEventPosition()[0];
int Y = self->Interactor->GetEventPosition()[1];

self->ModifierActive = vtkEvent::GetModifier(self->Interactor);
rep->ComputeInteractionState(X, Y, self->ModifierActive);

if ( self->WidgetRep->GetInteractionState()
== vtkResliceCursorRepresentation::Outside )
{
return;
}

rep->SetManipulationMode(vtkResliceCursorRepresentation::RotateBothAxes);

self->GrabFocus(self->EventCallbackCommand);
double eventPos[2];
eventPos[0] = static_cast(X);
eventPos[1] = static_cast(Y);
self->WidgetRep->StartWidgetInteraction(eventPos);

// We are definitely selected
self->WidgetState = vtkResliceCursorWidget::Active;
self->SetCursor(self->WidgetRep->GetInteractionState());

// Highlight as necessary
self->WidgetRep->Highlight(1);

self->EventCallbackCommand->SetAbortFlag(1);
self->StartInteraction();
self->InvokeEvent(vtkCommand::StartInteractionEvent,nullptr);
self->Render();

self->InvokeAnEvent();
}

//-------------------------------------------------------------------------
void vtkResliceCursorWidget::MoveAction(vtkAbstractWidget *w)
{
vtkResliceCursorWidget self = reinterpret_cast<vtkResliceCursorWidget>(w);
vtkResliceCursorRepresentation rep =
reinterpret_cast<vtkResliceCursorRepresentation
>(self->WidgetRep);

// compute some info we need for all cases
int X = self->Interactor->GetEventPosition()[0];
int Y = self->Interactor->GetEventPosition()[1];

// Set the cursor appropriately
if ( self->WidgetState == vtkResliceCursorWidget::Start )
{
self->ModifierActive = vtkEvent::GetModifier(self->Interactor);
int state = self->WidgetRep->GetInteractionState();

rep->ComputeInteractionState(X, Y, self->ModifierActive );

self->SetCursor(self->WidgetRep->GetInteractionState());

if ( state != self->WidgetRep->GetInteractionState() )
{
  self->Render();
}
return;

}

// Okay, adjust the representation

double eventPosition[2];
eventPosition[0] = static_cast(X);
eventPosition[1] = static_cast(Y);
self->WidgetRep->WidgetInteraction(eventPosition);

// Got this event, we are finished
self->EventCallbackCommand->SetAbortFlag(1);
self->InvokeEvent(vtkCommand::InteractionEvent,nullptr);
self->Render();

self->InvokeAnEvent();
}

//-------------------------------------------------------------------------
void vtkResliceCursorWidget::EndSelectAction(vtkAbstractWidget *w)
{
vtkResliceCursorWidget self = static_cast<vtkResliceCursorWidget>(w);
vtkResliceCursorRepresentation rep =
reinterpret_cast<vtkResliceCursorRepresentation
>(self->WidgetRep);

if ( self->WidgetState != vtkResliceCursorWidget::Active )
{
return;
}

int X = self->Interactor->GetEventPosition()[0];
int Y = self->Interactor->GetEventPosition()[1];

double eventPos[2];
eventPos[0] = static_cast(X);
eventPos[1] = static_cast(Y);

self->WidgetRep->EndWidgetInteraction(eventPos);

// return to initial state
self->WidgetState = vtkResliceCursorWidget::Start;
self->ModifierActive = 0;

// Highlight as necessary
self->WidgetRep->Highlight(0);

// Remove any text displays. We are no longer active.
rep->ActivateText(0);

// stop adjusting
self->ReleaseFocus();
self->EventCallbackCommand->SetAbortFlag(1);
self->EndInteraction();
self->InvokeEvent(vtkCommand::EndInteractionEvent,nullptr);
self->WidgetState = vtkResliceCursorWidget::Start;
rep->SetManipulationMode(vtkResliceCursorRepresentation::None);

self->Render();

self->InvokeAnEvent();
}

//-------------------------------------------------------------------------
void vtkResliceCursorWidget::ResetResliceCursorAction(vtkAbstractWidget *w)
{
vtkResliceCursorWidget self = reinterpret_cast<vtkResliceCursorWidget>(w);
self->ResetResliceCursor();

// Render in response to changes
self->Render();

// Invoke a reslice cursor event
self->InvokeEvent( vtkResliceCursorWidget::ResetCursorEvent, nullptr );
}
//重置状态
//-------------------------------------------------------------------------
void vtkResliceCursorWidget::ResetResliceCursor()
{
vtkResliceCursorRepresentation rep =
reinterpret_cast<vtkResliceCursorRepresentation
>(this->WidgetRep);

if (!rep->GetResliceCursor())
{
return; // nothing to reset
}

// Reset the reslice cursor
rep->GetResliceCursor()->Reset();
rep->InitializeReslicePlane();
}

//----------------------------------------------------------------------------
void vtkResliceCursorWidget::StartWindowLevel()
{
vtkResliceCursorRepresentation rep =
reinterpret_cast<vtkResliceCursorRepresentation
>(this->WidgetRep);

int X = this->Interactor->GetEventPosition()[0];
int Y = this->Interactor->GetEventPosition()[1];

// Okay, make sure that the pick is in the current renderer
if (!this->CurrentRenderer || !this->CurrentRenderer->IsInViewport(X, Y))
{
rep->SetManipulationMode(vtkResliceCursorRepresentation::None);
return;
}

rep->SetManipulationMode(vtkResliceCursorRepresentation::WindowLevelling);

rep->ActivateText(1);
rep->ManageTextDisplay();
}

//----------------------------------------------------------------------------
void vtkResliceCursorWidget::InvokeAnEvent()
{
// We invoke the appropriate event. In cases where the cursor is moved
// around, or rotated, also have the reslice cursor invoke an event.
//每个widget,都绑定了rep,这里就是根据绑定的rep来执行对应事件
vtkResliceCursorRepresentation rep =
reinterpret_cast<vtkResliceCursorRepresentation
>(this->WidgetRep);
if (rep)
{
int mode = rep->GetManipulationMode();
if (mode == vtkResliceCursorRepresentation::WindowLevelling)
{
this->InvokeEvent(WindowLevelEvent,nullptr);
}
else if (mode == vtkResliceCursorRepresentation::PanAndRotate)
{
this->InvokeEvent(ResliceAxesChangedEvent,nullptr);
rep->GetResliceCursor()->InvokeEvent(ResliceAxesChangedEvent,nullptr);
}
else if (mode == vtkResliceCursorRepresentation::RotateBothAxes)
{
this->InvokeEvent(ResliceAxesChangedEvent,nullptr);
rep->GetResliceCursor()->InvokeEvent(ResliceAxesChangedEvent,nullptr);
}
else if (mode == vtkResliceCursorRepresentation::ResizeThickness)
{
this->InvokeEvent(ResliceThicknessChangedEvent,nullptr);
rep->GetResliceCursor()->InvokeEvent(ResliceAxesChangedEvent,nullptr);
}
}
}

//----------------------------------------------------------------------------
void vtkResliceCursorWidget::PrintSelf(ostream& os, vtkIndent indent)
{
//Superclass typedef defined in vtkTypeMacro() found in vtkSetGet.h
this->Superclass::PrintSelf(os,indent);

os << indent << "ManageWindowLevel: " << this->ManageWindowLevel << endl;
// this->ModifierActive;
// this->WidgetState;

}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值