Format ActorDraggableInteractorStyle

This commit is contained in:
Krad
2022-06-29 14:09:15 +08:00
parent 21958db474
commit d9e53284ad
2 changed files with 683 additions and 738 deletions

View File

@@ -2,33 +2,30 @@
// Created by 87714 on 2021/6/19.
//
#include "ActorDraggableInteractorStyle.h"
#include <vtkObjectFactory.h>
#include <vtkCornerAnnotation.h>
#include <vtkCollection.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkImageSlice.h>
#include <vtkImageMapper3D.h>
#include <vtkImageData.h>
#include <vtkCollection.h>
#include "ActorDraggableInteractorStyle.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkProp.h"
#include "vtkPropCollection.h"
#include "vtkImageSlice.h"
#include "vtkImageStack.h"
#include "vtkAssemblyPath.h"
#include "vtkRenderer.h"
#include "vtkImageSliceMapper.h"
#include "vtkCamera.h"
#include <vtkProp.h>
#include <vtkPropCollection.h>
#include <vtkAssemblyPath.h>
#include <vtkRenderer.h>
#include <vtkImageSliceMapper.h>
#include <vtkCamera.h>
#include <vtkCellPicker.h>
#include <vtkCallbackCommand.h>
#include <vtkImageProperty.h>
#include <vtkPointData.h>
#include "DraggableActor.h"
#include "vtkPointPicker.h"
#include "vtkCellPicker.h"
#include "vtkCallbackCommand.h"
#include "Measure.h"
#include "vtkImageProperty.h"
#include "QGlobals.h"
vtkStandardNewMacro(ActorDraggableInteractorStyle);
vtkStandardNewMacro(ActorDraggableInteractorStyle)
ActorDraggableInteractorStyle::ActorDraggableInteractorStyle() {
this->AddObserver(vtkCommand::InteractionEvent, this, &ActorDraggableInteractorStyle::DispatchEvent);
#ifdef _DEBUG
@@ -51,23 +48,90 @@ ActorDraggableInteractorStyle::~ActorDraggableInteractorStyle() {
}
template<typename T>
void vtkValueMessageTemplate(vtkImageData* image, int* position, std::string& message)
{
T* tuple = ((T*)image->GetScalarPointer(position));
if (!tuple)
{
void vtkValueMessageTemplate(vtkImageData *image, int *position, std::string &message) {
T *tuple = ((T *) image->GetScalarPointer(position));
if (!tuple) {
return;
}
int components = image->GetNumberOfScalarComponents();
for (int c = 0; c < components; ++c)
{
for (int c = 0; c < components; ++c) {
message += vtkVariant(tuple[c]).ToString();
if (c != (components - 1))
{
if (c != (components - 1)) {
message += ", ";
}
}
//message += " )";
}
void ActorDraggableInteractorStyle::OnLeftButtonDown() {
this->InvokeEvent(AfterViewerClicked);
int x = this->Interactor->GetEventPosition()[0];
int y = this->Interactor->GetEventPosition()[1];
this->FindPokedRenderer(x, y);
if (this->CurrentRenderer == nullptr) {
return;
}
// Redefine this button to handle window/level
this->GrabFocus(this->EventCallbackCommand);
if (selectedProp) {
selectedProp->InvokeEvent(DraggableActor::DraggableActorEvents::UnSelectedEvent);
selectedProp = nullptr;
}
if (dragProp) {
selectedProp = dragProp;
selectedProp->InvokeEvent(DraggableActor::DraggableActorEvents::SelectedEvent);
if (this->Interactor->GetRepeatCount()) {
dragProp->InvokeEvent(DraggableStyleEvents::PopPropEvent, nullptr);
}
DragStartOrigin[0] = x;
DragStartOrigin[1] = y;
this->StartDrag();
return;
}
if (Interactor->GetRepeatCount()) {
if (measure) {
measure->SetPlacing(measure->onMeasureDoubleClick(this->Interactor));
if (!measure->isMeasurePlacing()) {
this->EndMeasure();
auto temp = measure;
measure = measure->GetNextMeasure();
if (!temp->Valid()) {
temp->ForceDelete();
temp = nullptr;
}
}
return;
}
this->InvokeEvent(DraggableStyleEvents::DoubleClickEvent, nullptr);
return;
}
if (measure) {
measure->SetPlacing(measure->onMeasureLeftButtonDown(this->Interactor));
if (this->State != VTKIS_MEASURE) this->StartMeasure();
return;
}
if (scalarProp) {
ScalarStartPosition[0] = x;
ScalarStartPosition[1] = y;
this->StartColorMapping();
return;
}
if (this->InteractionMode == VTKIS_IMAGE_WINDOWLEVEL) {
this->WindowLevelStartPosition[0] = x;
this->WindowLevelStartPosition[1] = y;
this->StartWindowLevel();
} else if (this->InteractionMode == VTKIS_IMAGE_ZOOM) {
this->DollyStartScale = this->CurrentRenderer->GetActiveCamera()->GetParallelScale();
this->StartDolly();
} else if (this->InteractionMode == VTKIS_IMAGE_PAN) {
this->StartPan();
} else if (this->InteractionMode == VTKIS_IMAGE_SLICING) {
this->StartSlice();
}
}
void ActorDraggableInteractorStyle::OnLeftButtonUp() {
@@ -94,132 +158,21 @@ void ActorDraggableInteractorStyle::OnLeftButtonUp() {
}
vtkInteractorStyleImage::OnLeftButtonUp();
}
void ActorDraggableInteractorStyle::ColorMapping()
{
vtkRenderWindowInteractor* rwi = this->Interactor;
this->ScalarCurrentPosition[1] = rwi->GetEventPosition()[1];
double total = 0.01 * ((this->ScalarCurrentPosition[1] - this->ScalarStartPosition[1]) / scalarSensitivity);
double left = total - ConsumedOpacity;
if (abs(left) >= 0.01) {
OpacityTrigger = true;
this->InvokeEvent(ScalarOpacityEvent, &left);
ConsumedOpacity += left;
}
}
void ActorDraggableInteractorStyle::OnRightButtonDown() {
this->InvokeEvent(AfterViewerClicked);
int x = this->Interactor->GetEventPosition()[0];
int y = this->Interactor->GetEventPosition()[1];
void ActorDraggableInteractorStyle::EndColorMapping()
{
if (!OpacityTrigger)
{
this->InvokeEvent(ScalarShiftEvent, nullptr);
}
if (this->State != VTKIS_COLORMAP)
{
this->FindPokedRenderer(x, y);
if (this->CurrentRenderer == nullptr) {
return;
}
this->StopState();
}
void ActorDraggableInteractorStyle::Drag() {
int* pos = this->Interactor->GetEventPosition();
this->FindPokedRenderer(pos[0], pos[1]);
DraggableActor::SafeDownCast(dragProp)->Transform(pos[0] - DragStartOrigin[0], pos[1] - DragStartOrigin[1]);
this->Interactor->Render();
}
void ActorDraggableInteractorStyle::MeasurePlace() {
measure->onMeasureMouseMove(this->Interactor);
}
void ActorDraggableInteractorStyle::NoneStatePick() {
if (AnnoHelper::IsAnno())
{
int* pos = this->Interactor->GetEventPosition();
this->FindPokedRenderer(pos[0], pos[1]);
int result = picker->PickProp(pos[0], pos[1], this->CurrentRenderer);
if (result)
{
vtkProp* obj = picker->GetViewProp();
if (scalarProp != obj && scalarProp) {
scalarProp = nullptr;
// Redefine this button to handle window/level
this->GrabFocus(this->EventCallbackCommand);
if (dragProp) {
dragProp->InvokeEvent(DraggableStyleEvents::RightButtonClickEvent, this->Interactor);
}
if (dragProp != obj && dragProp) {
DraggableActor::SafeDownCast(dragProp)->MouseLeave();
dragProp = nullptr;
}
if (obj->IsA("vtkImageSlice"))
{
//active pick pixel
vtkNew<vtkCellPicker> p;
p->SetPickFromList(1);
p->AddPickList(obj);
p->Pick(pos[0], pos[1], 0.0, this->CurrentRenderer);
int* ijk = p->GetPointIJK();
//TODO: sometimes ijk will have value less than 0;need to fid out the reason
//Firstly: simple fix by set value to 0
for (int i = 0; i < 3 ; i++){
ijk[i] = ijk[i]<0?0:ijk[i];
}
std::string message = "X:";
message += vtkVariant(ijk[0]).ToString();
message += " Y:";
message += vtkVariant(ijk[1]).ToString();
message += ", ";
message += vtkVariant(ijk[2]).ToString();
message += " Val:";
vtkImageData* imageData = vtkImageSlice::SafeDownCast(obj)->GetMapper()->GetInput();
switch (imageData->GetScalarType())
{
vtkTemplateMacro((vtkValueMessageTemplate<VTK_TT>(imageData, ijk, message)));
default:
return;
}
this->CornerAnnotation->SetText(BOTTOM_LEFT, message.c_str());
this->Interactor->Render();
return;
}
if (obj->IsA("DraggableActor"))
{
//active highlight
if (dragProp != obj) {
dragProp = obj;
DraggableActor::SafeDownCast(dragProp)->MouseEntered();
}
}
if (obj->IsA("vtkScalarBarActor"))
{
if (scalarProp != obj)
{
scalarProp = obj;
}
}
}
//nopicked but moving
else if (dragProp) {
if (scalarProp) {
scalarProp = nullptr;
}
DraggableActor::SafeDownCast(dragProp)->MouseLeave();
}
else {
if (scalarProp) {
scalarProp = nullptr;
}
dragProp = nullptr;
if (this->CornerAnnotation)this->CornerAnnotation->SetText(BOTTOM_LEFT, "");
}
}
if (this->CornerAnnotation)this->CornerAnnotation->SetText(BOTTOM_LEFT, "");
this->Interactor->Render();
}
void ActorDraggableInteractorStyle::OnMouseMove() {
@@ -251,207 +204,108 @@ void ActorDraggableInteractorStyle::OnMouseMove() {
vtkInteractorStyleImage::OnMouseMove();
}
void ActorDraggableInteractorStyle::WindowLevel()
{
vtkRenderWindowInteractor* rwi = this->Interactor;
this->WindowLevelCurrentPosition[0] = rwi->GetEventPosition()[0];
this->WindowLevelCurrentPosition[1] = rwi->GetEventPosition()[1];
if (this->HandleObservers &&
this->HasObserver(vtkCommand::WindowLevelEvent))
{
this->InvokeEvent(vtkCommand::WindowLevelEvent, this);
}
if (this->CurrentImageProperty)
{
int* size = this->CurrentRenderer->GetSize();
double window = this->WindowLevelInitial[0];
double level = this->WindowLevelInitial[1];
// Compute normalized delta
double dx = (this->WindowLevelCurrentPosition[0] -
this->WindowLevelStartPosition[0]) * 4.0 / size[0];
double dy = (this->WindowLevelStartPosition[1] -
this->WindowLevelCurrentPosition[1]) * 4.0 / size[1];
// Scale by current values
if (fabs(window) > 0.01)
{
dx = dx * window;
}
else
{
dx = dx * (window < 0 ? -0.01 : 0.01);
}
if (fabs(level) > 0.01)
{
dy = dy * level;
}
else
{
dy = dy * (level < 0 ? -0.01 : 0.01);
}
// Abs so that direction does not flip
if (window < 0.0)
{
dx = -1 * dx;
}
if (level < 0.0)
{
dy = -1 * dy;
}
// Compute new window level
double newWindow = dx + window;
double newLevel = level - dy;
if (newWindow < 0.01)
{
newWindow = 0.01;
}
this->CurrentImageProperty->SetColorWindow(newWindow);
this->CurrentImageProperty->SetColorLevel(newLevel);
this->Interactor->Render();
}
}
void ActorDraggableInteractorStyle::Slice()
{
if (this->CurrentRenderer == nullptr)
{
return;
}
void ActorDraggableInteractorStyle::OnChar() {
vtkInteractorStyleImage::OnChar();
vtkRenderWindowInteractor *rwi = this->Interactor;
int dy = (-rwi->GetEventPosition()[1] + rwi->GetLastEventPosition()[1])/2;
// vtkCamera *camera = this->CurrentRenderer->GetActiveCamera();
//
//
// // scale the interaction by the height of the viewport
// double viewportHeight = 0.0;
// viewportHeight = camera->GetParallelScale();
//
//
// int *size = this->CurrentRenderer->GetSize();
// double delta = dy*viewportHeight/size[1];
// int dSlice = -(int)round(delta);
// printf("dy:%d,delta:%f,dslice:%d\r\n",dy,delta,dSlice);
void* p = &dy;
this->InvokeEvent(SliceEvent,p);
}
void ActorDraggableInteractorStyle::OnRightButtonDown()
{
this->InvokeEvent(AfterViewerClicked);
int x = this->Interactor->GetEventPosition()[0];
int y = this->Interactor->GetEventPosition()[1];
this->FindPokedRenderer(x, y);
if (this->CurrentRenderer == nullptr)
{
return;
}
// Redefine this button to handle window/level
this->GrabFocus(this->EventCallbackCommand);
if (dragProp) {
dragProp->InvokeEvent(DraggableStyleEvents::RightButtonClickEvent, this->Interactor);
}
}
void ActorDraggableInteractorStyle::OnLeftButtonDown() {
this->InvokeEvent(AfterViewerClicked);
int x = this->Interactor->GetEventPosition()[0];
int y = this->Interactor->GetEventPosition()[1];
this->FindPokedRenderer(x, y);
if (this->CurrentRenderer == nullptr)
{
return;
}
// Redefine this button to handle window/level
this->GrabFocus(this->EventCallbackCommand);
std::string keySym = rwi->GetKeySym();
if (keySym == "Delete") {
if (selectedProp) {
selectedProp->InvokeEvent(DraggableActor::DraggableActorEvents::UnSelectedEvent);
selectedProp = nullptr;
this->InvokeEvent(DraggableStyleEvents::DeleteMeasureEvent, selectedProp);
}
if (dragProp) {
selectedProp = dragProp;
selectedProp->InvokeEvent(DraggableActor::DraggableActorEvents::SelectedEvent);
if (this->Interactor->GetRepeatCount())
{
dragProp->InvokeEvent(DraggableStyleEvents::PopPropEvent, nullptr);
}
DragStartOrigin[0] = x;
DragStartOrigin[1] = y;
this->StartDrag();
}
void ActorDraggableInteractorStyle::NoneStatePick() {
if (AnnoHelper::IsAnno()) {
int *pos = this->Interactor->GetEventPosition();
this->FindPokedRenderer(pos[0], pos[1]);
int result = picker->PickProp(pos[0], pos[1], this->CurrentRenderer);
if (result) {
vtkProp *obj = picker->GetViewProp();
if (scalarProp != obj && scalarProp) {
scalarProp = nullptr;
}
if (dragProp != obj && dragProp) {
DraggableActor::SafeDownCast(dragProp)->MouseLeave();
dragProp = nullptr;
}
if (obj->IsA("vtkImageSlice")) {
//active pick pixel
vtkNew<vtkCellPicker> p;
p->SetPickFromList(1);
p->AddPickList(obj);
p->Pick(pos[0], pos[1], 0.0, this->CurrentRenderer);
int *ijk = p->GetPointIJK();
//TODO: sometimes ijk will have value less than 0;need to fid out the reason
//Firstly: simple fix by set value to 0
for (int i = 0; i < 3; i++) {
ijk[i] = ijk[i] < 0 ? 0 : ijk[i];
}
std::string message = "X:";
message += vtkVariant(ijk[0]).ToString();
message += " Y:";
message += vtkVariant(ijk[1]).ToString();
message += ", ";
message += vtkVariant(ijk[2]).ToString();
message += " Val:";
vtkImageData *imageData = vtkImageSlice::SafeDownCast(obj)->GetMapper()->GetInput();
switch (imageData->GetScalarType()) {
vtkTemplateMacro((vtkValueMessageTemplate<VTK_TT>(imageData, ijk, message)));
default:
return;
}
if (Interactor->GetRepeatCount()) {
if (measure)
{
measure->SetPlacing(measure->onMeasureDoubleClick(this->Interactor));
if (!measure->isMeasurePlacing()) {
this->EndMeasure();
auto temp = measure;
measure = measure->GetNextMeasure();
if (!temp->Valid()) {
temp->ForceDelete();
temp = nullptr;
}
}
this->CornerAnnotation->SetText(BOTTOM_LEFT, message.c_str());
this->Interactor->Render();
return;
}
this->InvokeEvent(DraggableStyleEvents::DoubleClickEvent, nullptr);
return;
if (obj->IsA("DraggableActor")) {
//active highlight
if (dragProp != obj) {
dragProp = obj;
DraggableActor::SafeDownCast(dragProp)->MouseEntered();
}
}
if (obj->IsA("vtkScalarBarActor")) {
if (scalarProp != obj) {
scalarProp = obj;
}
if (measure)
{
measure->SetPlacing(measure->onMeasureLeftButtonDown(this->Interactor));
if (this->State != VTKIS_MEASURE) this->StartMeasure();
return;
}
if (scalarProp)
{
ScalarStartPosition[0] = x;
ScalarStartPosition[1] = y;
this->StartColorMapping();
return;
}
if (this->InteractionMode == VTKIS_IMAGE_WINDOWLEVEL)
{
this->WindowLevelStartPosition[0] = x;
this->WindowLevelStartPosition[1] = y;
this->StartWindowLevel();
//nopicked but moving
else if (dragProp) {
if (scalarProp) {
scalarProp = nullptr;
}
else if (this->InteractionMode == VTKIS_IMAGE_ZOOM)
{
this->DollyStartScale = this->CurrentRenderer->GetActiveCamera()->GetParallelScale();
this->StartDolly();
DraggableActor::SafeDownCast(dragProp)->MouseLeave();
} else {
if (scalarProp) {
scalarProp = nullptr;
}
else if (this->InteractionMode == VTKIS_IMAGE_PAN)
{
this->StartPan();
dragProp = nullptr;
if (this->CornerAnnotation)this->CornerAnnotation->SetText(BOTTOM_LEFT, "");
}
else if (this->InteractionMode == VTKIS_IMAGE_SLICING)
{
this->StartSlice();
}
if (this->CornerAnnotation)this->CornerAnnotation->SetText(BOTTOM_LEFT, "");
this->Interactor->Render();
}
void ActorDraggableInteractorStyle::ActiveMeasure(Measure* m) {
void ActorDraggableInteractorStyle::MeasurePlace() {
measure->onMeasureMouseMove(this->Interactor);
}
void ActorDraggableInteractorStyle::Drag() {
int *pos = this->Interactor->GetEventPosition();
this->FindPokedRenderer(pos[0], pos[1]);
DraggableActor::SafeDownCast(dragProp)->Transform(pos[0] - DragStartOrigin[0], pos[1] - DragStartOrigin[1]);
this->Interactor->Render();
}
void ActorDraggableInteractorStyle::ActiveMeasure(Measure *m) {
if (this->measure && nullptr == m) {
this->measure->onTerminate(this->Interactor);
}
@@ -466,6 +320,228 @@ void ActorDraggableInteractorStyle::UnActiveMeasure() {
this->measure = nullptr;
}
void ActorDraggableInteractorStyle::Slice() {
if (this->CurrentRenderer == nullptr) {
return;
}
vtkRenderWindowInteractor *rwi = this->Interactor;
int dy = (-rwi->GetEventPosition()[1] + rwi->GetLastEventPosition()[1]) / 2;
// vtkCamera *camera = this->CurrentRenderer->GetActiveCamera();
//
//
// // scale the interaction by the height of the viewport
// double viewportHeight = 0.0;
// viewportHeight = camera->GetParallelScale();
//
//
// int *size = this->CurrentRenderer->GetSize();
// double delta = dy*viewportHeight/size[1];
// int dSlice = -(int)round(delta);
// printf("dy:%d,delta:%f,dslice:%d\r\n",dy,delta,dSlice);
void *p = &dy;
this->InvokeEvent(SliceEvent, p);
}
void ActorDraggableInteractorStyle::StartPan() {
vtkInteractorStyle::StartPan();
vtkCamera *camera = this->CurrentRenderer->GetActiveCamera();
camera->GetFocalPoint(PanStartOrigin);
}
void ActorDraggableInteractorStyle::ColorMapping() {
vtkRenderWindowInteractor *rwi = this->Interactor;
this->ScalarCurrentPosition[1] = rwi->GetEventPosition()[1];
double total = 0.01 * ((this->ScalarCurrentPosition[1] - this->ScalarStartPosition[1]) / scalarSensitivity);
double left = total - ConsumedOpacity;
if (abs(left) >= 0.01) {
OpacityTrigger = true;
this->InvokeEvent(ScalarOpacityEvent, &left);
ConsumedOpacity += left;
}
}
void ActorDraggableInteractorStyle::EndColorMapping() {
if (!OpacityTrigger) {
this->InvokeEvent(ScalarShiftEvent, nullptr);
}
if (this->State != VTKIS_COLORMAP) {
return;
}
this->StopState();
}
void ActorDraggableInteractorStyle::EndPan() {
if (this->State != VTKIS_PAN) return;
if (this->HandleObservers) {
vtkCamera *camera = this->CurrentRenderer->GetActiveCamera();
double *nf = camera->GetFocalPoint();
double calldata[6] = {PanStartOrigin[0], PanStartOrigin[1], PanStartOrigin[2], nf[0], nf[1], nf[2]};
this->InvokeEvent(vtkCommand::EventIds::EndPanEvent, calldata);
}
this->StopState();
}
void ActorDraggableInteractorStyle::EndDolly() {
if (this->State != VTKIS_DOLLY) {
return;
}
this->StopState();
if (this->CurrentRenderer == nullptr) {
return;
}
//激发缩放完成事件
if (this->HandleObservers) {
vtkCamera *camera = this->CurrentRenderer->GetActiveCamera();
double result[2] = {0.0, 0.0};
//image 必然是ParallelProjection
result[0] = this->DollyStartScale;
result[1] = camera->GetParallelScale();
this->InvokeEvent(DraggableStyleEvents::EndDollyEvent, result);
}
}
void ActorDraggableInteractorStyle::WindowLevel() {
vtkRenderWindowInteractor *rwi = this->Interactor;
this->WindowLevelCurrentPosition[0] = rwi->GetEventPosition()[0];
this->WindowLevelCurrentPosition[1] = rwi->GetEventPosition()[1];
if (this->HandleObservers &&
this->HasObserver(vtkCommand::WindowLevelEvent)) {
this->InvokeEvent(vtkCommand::WindowLevelEvent, this);
}
if (this->CurrentImageProperty) {
int *size = this->CurrentRenderer->GetSize();
double window = this->WindowLevelInitial[0];
double level = this->WindowLevelInitial[1];
// Compute normalized delta
double dx = (this->WindowLevelCurrentPosition[0] -
this->WindowLevelStartPosition[0]) * 4.0 / size[0];
double dy = (this->WindowLevelStartPosition[1] -
this->WindowLevelCurrentPosition[1]) * 4.0 / size[1];
// Scale by current values
if (fabs(window) > 0.01) {
dx = dx * window;
} else {
dx = dx * (window < 0 ? -0.01 : 0.01);
}
if (fabs(level) > 0.01) {
dy = dy * level;
} else {
dy = dy * (level < 0 ? -0.01 : 0.01);
}
// Abs so that direction does not flip
if (window < 0.0) {
dx = -1 * dx;
}
if (level < 0.0) {
dy = -1 * dy;
}
// Compute new window level
double newWindow = dx + window;
double newLevel = level - dy;
if (newWindow < 0.01) {
newWindow = 0.01;
}
this->CurrentImageProperty->SetColorWindow(newWindow);
this->CurrentImageProperty->SetColorLevel(newLevel);
this->Interactor->Render();
}
}
void ActorDraggableInteractorStyle::EndWindowLevel() {
if (this->State != VTKIS_WINDOW_LEVEL) {
return;
}
if (this->HandleObservers) {
double calldata[2] = {this->CurrentImageProperty->GetColorWindow(),
this->CurrentImageProperty->GetColorLevel()};
this->InvokeEvent(vtkCommand::EndWindowLevelEvent, calldata);
}
this->StopState();
}
//重写部分逻辑在取imageProperty的时候把ImageSlice也取了。
void ActorDraggableInteractorStyle::SetCurrentImageNumber(int i) {
// return;
this->CurrentImageNumber = i;
if (!this->CurrentRenderer) {
return;
}
vtkPropCollection *props = this->CurrentRenderer->GetViewProps();
vtkProp *prop = nullptr;
vtkAssemblyPath *path;
vtkImageSlice *imageProp = nullptr;
vtkCollectionSimpleIterator pit;
for (int k = 0; k < 2; k++) {
int j = 0;
for (props->InitTraversal(pit); (prop = props->GetNextProp(pit));) {
bool foundImageProp = false;
for (prop->InitPathTraversal(); (path = prop->GetNextPath());) {
vtkProp *tryProp = path->GetLastNode()->GetViewProp();
imageProp = vtkImageSlice::SafeDownCast(tryProp);
if (imageProp) {
if (j == i) {
foundImageProp = true;
break;
}
imageProp = nullptr;
j++;
}
}
if (foundImageProp) {
break;
}
}
if (i < 0) {
i += j;
}
}
vtkImageProperty *property = nullptr;
if (imageProp) {
property = imageProp->GetProperty();
if (imageProp != this->CurrentImageSlice) {
if (this->CurrentImageSlice) {
this->CurrentImageSlice->Delete();
}
this->CurrentImageSlice = imageProp;
if (this->CurrentImageSlice) {
this->CurrentImageSlice->Register(this);
}
}
}
if (property != this->CurrentImageProperty) {
if (this->CurrentImageProperty) {
this->CurrentImageProperty->Delete();
}
this->CurrentImageProperty = property;
if (this->CurrentImageProperty) {
this->CurrentImageProperty->Register(this);
}
}
}
void ActorDraggableInteractorStyle::DispatchEvent() {
switch (this->State) {
@@ -477,8 +553,8 @@ void ActorDraggableInteractorStyle::DispatchEvent() {
this->SetCurrentImageNumber(this->CurrentImageNumber);
}
if (!this->CurrentImageSlice) return;
vtkImageSliceMapper* mapper = vtkImageSliceMapper::SafeDownCast(this->CurrentImageSlice->GetMapper());
int slice[1] = { mapper ? mapper->GetSliceNumber() : -1 };
vtkImageSliceMapper *mapper = vtkImageSliceMapper::SafeDownCast(this->CurrentImageSlice->GetMapper());
int slice[1] = {mapper ? mapper->GetSliceNumber() : -1};
//鼠标滑动不一定能造成翻页!!!所以需要进行一次判定
if (slice[0] != lastslice) {
this->InvokeEvent(DraggableStyleEvents::SlicedEvent, slice);
@@ -489,148 +565,4 @@ void ActorDraggableInteractorStyle::DispatchEvent() {
}
}
//重写部分逻辑在取imageProperty的时候把ImageSlice也取了。
void ActorDraggableInteractorStyle::SetCurrentImageNumber(int i)
{
// return;
this->CurrentImageNumber = i;
if (!this->CurrentRenderer)
{
return;
}
vtkPropCollection* props = this->CurrentRenderer->GetViewProps();
vtkProp* prop = nullptr;
vtkAssemblyPath* path;
vtkImageSlice* imageProp = nullptr;
vtkCollectionSimpleIterator pit;
for (int k = 0; k < 2; k++)
{
int j = 0;
for (props->InitTraversal(pit); (prop = props->GetNextProp(pit));)
{
bool foundImageProp = false;
for (prop->InitPathTraversal(); (path = prop->GetNextPath());)
{
vtkProp* tryProp = path->GetLastNode()->GetViewProp();
imageProp = vtkImageSlice::SafeDownCast(tryProp);
if (imageProp)
{
if (j == i)
{
foundImageProp = true;
break;
}
imageProp = nullptr;
j++;
}
}
if (foundImageProp)
{
break;
}
}
if (i < 0)
{
i += j;
}
}
vtkImageProperty* property = nullptr;
if (imageProp)
{
property = imageProp->GetProperty();
if (imageProp != this->CurrentImageSlice)
{
if (this->CurrentImageSlice)
{
this->CurrentImageSlice->Delete();
}
this->CurrentImageSlice = imageProp;
if (this->CurrentImageSlice)
{
this->CurrentImageSlice->Register(this);
}
}
}
if (property != this->CurrentImageProperty)
{
if (this->CurrentImageProperty)
{
this->CurrentImageProperty->Delete();
}
this->CurrentImageProperty = property;
if (this->CurrentImageProperty)
{
this->CurrentImageProperty->Register(this);
}
}
}
void ActorDraggableInteractorStyle::EndDolly() {
if (this->State != VTKIS_DOLLY)
{
return;
}
this->StopState();
if (this->CurrentRenderer == nullptr)
{
return;
}
//激发缩放完成事件
if (this->HandleObservers) {
vtkCamera* camera = this->CurrentRenderer->GetActiveCamera();
double result[2] = { 0.0, 0.0 };
//image 必然是ParallelProjection
result[0] = this->DollyStartScale;
result[1] = camera->GetParallelScale();
this->InvokeEvent(DraggableStyleEvents::EndDollyEvent, result);
}
}
void ActorDraggableInteractorStyle::StartPan() {
vtkInteractorStyle::StartPan();
vtkCamera* camera = this->CurrentRenderer->GetActiveCamera();
camera->GetFocalPoint(PanStartOrigin);
}
void ActorDraggableInteractorStyle::EndPan() {
if (this->State != VTKIS_PAN) return;
if (this->HandleObservers) {
vtkCamera* camera = this->CurrentRenderer->GetActiveCamera();
double* nf = camera->GetFocalPoint();
double calldata[6] = { PanStartOrigin[0], PanStartOrigin[1], PanStartOrigin[2], nf[0], nf[1], nf[2] };
this->InvokeEvent(vtkCommand::EventIds::EndPanEvent, calldata);
}
this->StopState();
}
void ActorDraggableInteractorStyle::EndWindowLevel() {
if (this->State != VTKIS_WINDOW_LEVEL) {
return;
}
if (this->HandleObservers) {
double calldata[2] = { this->CurrentImageProperty->GetColorWindow(),this->CurrentImageProperty->GetColorLevel() };
this->InvokeEvent(vtkCommand::EndWindowLevelEvent, calldata);
}
this->StopState();
}
void ActorDraggableInteractorStyle::OnChar() {
vtkInteractorStyleImage::OnChar();
vtkRenderWindowInteractor* rwi = this->Interactor;
std::string keySym = rwi->GetKeySym();
if (keySym == "Delete")
{
if (selectedProp)
{
this->InvokeEvent(DraggableStyleEvents::DeleteMeasureEvent, selectedProp);
}
}
}

View File

@@ -24,16 +24,18 @@
class vtkProp;
class Measure;
class vtkImageSlice;
class ActorDraggableInteractorStyle : public vtkInteractorStyleImage {
public:
static ActorDraggableInteractorStyle* New();
vtkTypeMacro(ActorDraggableInteractorStyle, vtkInteractorStyleImage);
static ActorDraggableInteractorStyle *New();
enum DraggableStyleEvents
{
vtkTypeMacro(ActorDraggableInteractorStyle, vtkInteractorStyleImage);
enum DraggableStyleEvents {
DragEvent = vtkCommand::UserEvent + 300,
DragEndEvent,
StartMeasureEvent,
@@ -61,6 +63,7 @@ public:
* Default behavior forwards the event to the observed scene.
*/
void OnRightButtonDown() override;
void OnLeftButtonDown() override;
/**
@@ -69,24 +72,22 @@ public:
*/
void OnLeftButtonUp() override;
void OnMouseWheelForward() override{}
void OnMouseWheelBackward() override{}
void OnMouseWheelForward() override {}
void OnMouseWheelBackward() override {}
void OnChar() override;
void EndDolly() override;
void WindowLevel() override;
void Slice() override;
void SetCurrentImageNumber(int i) override;
vtkSetClampMacro(InteractionMode, int, VTKIS_IMAGE2D, VTKIS_IMAGE_WINDOWLEVEL);
void SetInteractionModeToImage2D() {}
void SetInteractionModeToImage3D() {}
void SetInteractionModeFromEnum(int InteractionMode)
{
void SetInteractionModeFromEnum(int InteractionMode) {
this->UnActiveMeasure();
this->SetInteractionMode(InteractionMode);
}
@@ -111,18 +112,20 @@ public:
vtkSetObjectMacro(CornerAnnotation, vtkCornerAnnotation);
vtkProp* GetSelectedProp()
{
vtkProp *GetSelectedProp() {
return selectedProp;
}
void ClearSelectedProp() {
if (dragProp == selectedProp) dragProp = nullptr;
selectedProp = nullptr;
}
void ActiveMeasure(Measure* m);
void ActiveMeasure(Measure *m);
void UnActiveMeasure();
void SetCurrentImageSlice(vtkImageSlice* slice){
void SetCurrentImageSlice(vtkImageSlice *slice) {
CurrentImageSlice = slice;
CurrentImageProperty = slice->GetProperty();
}
@@ -130,99 +133,109 @@ public:
protected:
ActorDraggableInteractorStyle();
~ActorDraggableInteractorStyle() override;
void StartDrag() {
this->StartState(VTKIS_DRAG);
}
void EndDrag() {
if (this->State != VTKIS_DRAG)
{
if (this->State != VTKIS_DRAG) {
return;
}
this->StopState();
}
void Drag();
void StartColorMapping()
{
void StartColorMapping() {
OpacityTrigger = false;
ConsumedOpacity = 0;
this->StartState(VTKIS_COLORMAP);
}
void EndColorMapping();
void ColorMapping();
bool OpacityTrigger = false;
void StartMeasure() {
this->StartState(VTKIS_MEASURE);
}
void EndMeasure() {
if (this->State != VTKIS_MEASURE)
{
if (this->State != VTKIS_MEASURE) {
return;
}
this->StopState();
this->InvokeEvent(EndMeasureEvent, this->measure);
}
void StartPan() override;
void EndPan() override;
void EndWindowLevel() override;
void MeasurePlace();
void NoneStatePick();
void DispatchEvent();
private:
ActorDraggableInteractorStyle(const ActorDraggableInteractorStyle&) = delete;
void operator=(const ActorDraggableInteractorStyle&) = delete;
ActorDraggableInteractorStyle(const ActorDraggableInteractorStyle &) = delete;
void operator=(const ActorDraggableInteractorStyle &) = delete;
vtkNew<vtkPropPicker> picker;
vtkProp* scalarProp = nullptr;
vtkProp* dragProp = nullptr;
vtkProp* selectedProp = nullptr;
int DragStartOrigin[2] = { 0, 0 };
vtkCornerAnnotation * CornerAnnotation = nullptr;
vtkProp *scalarProp = nullptr;
vtkProp *dragProp = nullptr;
vtkProp *selectedProp = nullptr;
int DragStartOrigin[2] = {0, 0};
vtkCornerAnnotation *CornerAnnotation = nullptr;
//bool isCornderAnno = true;
Measure* measure = nullptr;
double PanStartOrigin[3] = { 0.0, 0.0, 0.0 };
Measure *measure = nullptr;
double PanStartOrigin[3] = {0.0, 0.0, 0.0};
double DollyStartScale = 1.0;
vtkImageSlice * CurrentImageSlice = nullptr;
vtkImageSlice *CurrentImageSlice = nullptr;
int lastslice = -1;
int ScalarStartPosition[2] = { 0, 0 };
int ScalarCurrentPosition[2] = { 0, 0 };
int ScalarStartPosition[2] = {0, 0};
int ScalarCurrentPosition[2] = {0, 0};
double ConsumedOpacity = 0;
void TestOutPut(vtkObject*, unsigned long eventid, void* calldata) {
void TestOutPut(vtkObject *, unsigned long eventid, void *calldata) {
switch (eventid) {
case DraggableStyleEvents::SlicedEvent:
{
int* r = (int*)calldata;
case DraggableStyleEvents::SlicedEvent: {
int *r = (int *) calldata;
printf("Sliced, current slice number:%d \r\n", r[0]);
break;
}
case DraggableStyleEvents::EndDollyEvent: {
double *d = (double *)calldata;
double *d = (double *) calldata;
printf("EndDolly, scale param:%f,%f \r\n", d[0], d[1]);
break;
}
case vtkCommand::EventIds::EndPanEvent: {
double *d = (double *)calldata;
double *d = (double *) calldata;
printf("EndPan, last focalpoint:%f,%f,%f;current focalpoint:%f,%f,%f \r\n", d[0], d[1], d[2], d[3],
d[4], d[5]);
break;
}
case vtkCommand::EventIds::EndWindowLevelEvent:
{
double *d = (double *)calldata;
case vtkCommand::EventIds::EndWindowLevelEvent: {
double *d = (double *) calldata;
printf("EndWindowLevel, scale param:%f,%f \r\n", d[0], d[1]);