diff --git a/src/src/measure/ActorDraggableInteractorStyle.cpp b/src/src/measure/ActorDraggableInteractorStyle.cpp index 3f52f62..b150ed8 100644 --- a/src/src/measure/ActorDraggableInteractorStyle.cpp +++ b/src/src/measure/ActorDraggableInteractorStyle.cpp @@ -2,337 +2,331 @@ // Created by 87714 on 2021/6/19. // +#include "ActorDraggableInteractorStyle.h" + #include -#include +#include +#include #include #include #include -#include -#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 +#include +#include +#include +#include +#include +#include +#include +#include +#include #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); + this->AddObserver(vtkCommand::InteractionEvent, this, &ActorDraggableInteractorStyle::DispatchEvent); #ifdef _DEBUG - this->AddObserver(DraggableStyleEvents::EndDollyEvent, this, &ActorDraggableInteractorStyle::TestOutPut); - this->AddObserver(vtkCommand::EventIds::EndPanEvent, this, &ActorDraggableInteractorStyle::TestOutPut); - this->AddObserver(vtkCommand::EventIds::EndRotateEvent, this, &ActorDraggableInteractorStyle::TestOutPut); - this->AddObserver(vtkCommand::EventIds::EndWindowLevelEvent, this, &ActorDraggableInteractorStyle::TestOutPut); - this->AddObserver(DraggableStyleEvents::SlicedEvent, this, &ActorDraggableInteractorStyle::TestOutPut); + this->AddObserver(DraggableStyleEvents::EndDollyEvent, this, &ActorDraggableInteractorStyle::TestOutPut); + this->AddObserver(vtkCommand::EventIds::EndPanEvent, this, &ActorDraggableInteractorStyle::TestOutPut); + this->AddObserver(vtkCommand::EventIds::EndRotateEvent, this, &ActorDraggableInteractorStyle::TestOutPut); + this->AddObserver(vtkCommand::EventIds::EndWindowLevelEvent, this, &ActorDraggableInteractorStyle::TestOutPut); + this->AddObserver(DraggableStyleEvents::SlicedEvent, this, &ActorDraggableInteractorStyle::TestOutPut); #endif } ActorDraggableInteractorStyle::~ActorDraggableInteractorStyle() { - if (scalarProp) { - scalarProp->Delete(); - scalarProp = nullptr; - } - if (CornerAnnotation) { - CornerAnnotation->UnRegister(this); - } + if (scalarProp) { + scalarProp->Delete(); + scalarProp = nullptr; + } + if (CornerAnnotation) { + CornerAnnotation->UnRegister(this); + } } template -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) - { - message += vtkVariant(tuple[c]).ToString(); - if (c != (components - 1)) - { - message += ", "; - } - } - //message += " )"; +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) { + message += vtkVariant(tuple[c]).ToString(); + if (c != (components - 1)) { + 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() { - switch (this->State) { - case VTKIS_DRAG: - DraggableActor::SafeDownCast(dragProp)->ApplyTransform(); - this->EndDrag(); - break; - case VTKIS_MEASURE: - measure->SetPlacing(measure->onMeasureLeftButtonUp(this->Interactor)); - if (!measure->isMeasurePlacing()) { - this->EndMeasure(); - auto temp = measure; - measure = measure->GetNextMeasure(); - if (!temp->Valid()) { - temp->ForceDelete(); - temp = nullptr; - } - } - break; - case VTKIS_COLORMAP: - this->EndColorMapping(); - break; - } - 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; - } + switch (this->State) { + case VTKIS_DRAG: + DraggableActor::SafeDownCast(dragProp)->ApplyTransform(); + this->EndDrag(); + break; + case VTKIS_MEASURE: + measure->SetPlacing(measure->onMeasureLeftButtonUp(this->Interactor)); + if (!measure->isMeasurePlacing()) { + this->EndMeasure(); + auto temp = measure; + measure = measure->GetNextMeasure(); + if (!temp->Valid()) { + temp->ForceDelete(); + temp = nullptr; + } + } + break; + case VTKIS_COLORMAP: + this->EndColorMapping(); + break; + } + vtkInteractorStyleImage::OnLeftButtonUp(); } +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) - { - 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; - } - if (dragProp != obj && dragProp) { - - DraggableActor::SafeDownCast(dragProp)->MouseLeave(); - dragProp = nullptr; - } - if (obj->IsA("vtkImageSlice")) - { - //active pick pixel - vtkNew 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(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(); - + 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::OnMouseMove() { - int x = this->Interactor->GetEventPosition()[0]; - int y = this->Interactor->GetEventPosition()[1]; + int x = this->Interactor->GetEventPosition()[0]; + int y = this->Interactor->GetEventPosition()[1]; - switch (this->State) { - case VTKIS_MEASURE: - MeasurePlace(); - //照抄源码,不是很清楚这句话的作用,可能有加速处理用户输入事件的作用(连续InteractionEvent处理连续操作,避免外部判断) - this->InvokeEvent(vtkCommand::InteractionEvent, nullptr); - break; - case VTKIS_DRAG: - Drag(); - this->InvokeEvent(vtkCommand::InteractionEvent, nullptr); - break; - case VTKIS_NONE: - NoneStatePick(); - this->InvokeEvent(vtkCommand::InteractionEvent, nullptr); - break; - case VTKIS_COLORMAP: - this->FindPokedRenderer(x, y); - this->ColorMapping(); - this->InvokeEvent(vtkCommand::InteractionEvent, nullptr); - break; + switch (this->State) { + case VTKIS_MEASURE: + MeasurePlace(); + //照抄源码,不是很清楚这句话的作用,可能有加速处理用户输入事件的作用(连续InteractionEvent处理连续操作,避免外部判断) + this->InvokeEvent(vtkCommand::InteractionEvent, nullptr); + break; + case VTKIS_DRAG: + Drag(); + this->InvokeEvent(vtkCommand::InteractionEvent, nullptr); + break; + case VTKIS_NONE: + NoneStatePick(); + this->InvokeEvent(vtkCommand::InteractionEvent, nullptr); + break; + case VTKIS_COLORMAP: + this->FindPokedRenderer(x, y); + this->ColorMapping(); + this->InvokeEvent(vtkCommand::InteractionEvent, nullptr); + break; - } - vtkInteractorStyleImage::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::OnChar() { + vtkInteractorStyleImage::OnChar(); + vtkRenderWindowInteractor *rwi = this->Interactor; + std::string keySym = rwi->GetKeySym(); + if (keySym == "Delete") { + if (selectedProp) { + this->InvokeEvent(DraggableStyleEvents::DeleteMeasureEvent, selectedProp); + } + } } -void ActorDraggableInteractorStyle::Slice() -{ - if (this->CurrentRenderer == nullptr) - { +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 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(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::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); + } + this->measure = m; +} + +void ActorDraggableInteractorStyle::UnActiveMeasure() { + if (this->measure) { + this->measure->onTerminate(this->Interactor); + } + this->EndMeasure(); + this->measure = nullptr; +} + +void ActorDraggableInteractorStyle::Slice() { + if (this->CurrentRenderer == nullptr) { return; } vtkRenderWindowInteractor *rwi = this->Interactor; - int dy = (-rwi->GetEventPosition()[1] + rwi->GetLastEventPosition()[1])/2; + int dy = (-rwi->GetEventPosition()[1] + rwi->GetLastEventPosition()[1]) / 2; // vtkCamera *camera = this->CurrentRenderer->GetActiveCamera(); // @@ -346,291 +340,229 @@ void ActorDraggableInteractorStyle::Slice() // 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); - 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::ActiveMeasure(Measure* m) { - if (this->measure && nullptr == m) { - this->measure->onTerminate(this->Interactor); - } - this->measure = m; -} - -void ActorDraggableInteractorStyle::UnActiveMeasure() { - if (this->measure) { - this->measure->onTerminate(this->Interactor); - } - this->EndMeasure(); - this->measure = nullptr; -} - - -void ActorDraggableInteractorStyle::DispatchEvent() { - switch (this->State) { - case VTKIS_SLICE: - - if (this->HandleObservers) { - //double check - if (!this->CurrentImageSlice) { - this->SetCurrentImageNumber(this->CurrentImageNumber); - } - if (!this->CurrentImageSlice) return; - vtkImageSliceMapper* mapper = vtkImageSliceMapper::SafeDownCast(this->CurrentImageSlice->GetMapper()); - int slice[1] = { mapper ? mapper->GetSliceNumber() : -1 }; - //鼠标滑动不一定能造成翻页!!!所以需要进行一次判定 - if (slice[0] != lastslice) { - this->InvokeEvent(DraggableStyleEvents::SlicedEvent, slice); - lastslice = slice[0]; - } - break; - } - } -} - -//重写部分逻辑,在取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 *p = &dy; + this->InvokeEvent(SliceEvent, p); } void ActorDraggableInteractorStyle::StartPan() { - vtkInteractorStyle::StartPan(); - vtkCamera* camera = this->CurrentRenderer->GetActiveCamera(); - camera->GetFocalPoint(PanStartOrigin); + 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(); + 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(); + 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); - } - } + +//重写部分逻辑,在取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) { + case VTKIS_SLICE: + + if (this->HandleObservers) { + //double check + if (!this->CurrentImageSlice) { + this->SetCurrentImageNumber(this->CurrentImageNumber); + } + if (!this->CurrentImageSlice) return; + vtkImageSliceMapper *mapper = vtkImageSliceMapper::SafeDownCast(this->CurrentImageSlice->GetMapper()); + int slice[1] = {mapper ? mapper->GetSliceNumber() : -1}; + //鼠标滑动不一定能造成翻页!!!所以需要进行一次判定 + if (slice[0] != lastslice) { + this->InvokeEvent(DraggableStyleEvents::SlicedEvent, slice); + lastslice = slice[0]; + } + break; + } + } } diff --git a/src/src/measure/ActorDraggableInteractorStyle.h b/src/src/measure/ActorDraggableInteractorStyle.h index b58d484..8b9e32c 100644 --- a/src/src/measure/ActorDraggableInteractorStyle.h +++ b/src/src/measure/ActorDraggableInteractorStyle.h @@ -24,216 +24,229 @@ class vtkProp; + class Measure; + class vtkImageSlice; -class ActorDraggableInteractorStyle : public vtkInteractorStyleImage { +class ActorDraggableInteractorStyle : public vtkInteractorStyleImage { public: - static ActorDraggableInteractorStyle* New(); - vtkTypeMacro(ActorDraggableInteractorStyle, vtkInteractorStyleImage); + static ActorDraggableInteractorStyle *New(); - enum DraggableStyleEvents - { - DragEvent = vtkCommand::UserEvent + 300, - DragEndEvent, - StartMeasureEvent, - EndMeasureEvent, - SliceEvent, - SlicedEvent, - EndDollyEvent, - PopPropEvent, - DoubleClickEvent, - DeleteMeasureEvent, - RightButtonClickEvent, - ScalarOpacityEvent, - ScalarShiftEvent, - AfterViewerClicked - }; +vtkTypeMacro(ActorDraggableInteractorStyle, vtkInteractorStyleImage); - /** - * Called when the user moves the mouse - * Default behavior forwards the event to the observed scene. - */ - void OnMouseMove() override; + enum DraggableStyleEvents { + DragEvent = vtkCommand::UserEvent + 300, + DragEndEvent, + StartMeasureEvent, + EndMeasureEvent, + SliceEvent, + SlicedEvent, + EndDollyEvent, + PopPropEvent, + DoubleClickEvent, + DeleteMeasureEvent, + RightButtonClickEvent, + ScalarOpacityEvent, + ScalarShiftEvent, + AfterViewerClicked + }; - /** - * Called when the user clicks the mouse left button. - * Default behavior forwards the event to the observed scene. - */ - void OnRightButtonDown() override; - void OnLeftButtonDown() override; + /** + * Called when the user moves the mouse + * Default behavior forwards the event to the observed scene. + */ + void OnMouseMove() override; - /** - * Called when the user releases the mouse left button. - * Default behavior forwards the event to the observed scene. - */ - void OnLeftButtonUp() override; + /** + * Called when the user clicks the mouse left button. + * Default behavior forwards the event to the observed scene. + */ + void OnRightButtonDown() override; - void OnMouseWheelForward() override{} - void OnMouseWheelBackward() override{} + void OnLeftButtonDown() override; - void OnChar() override; - void EndDolly() override; + /** + * Called when the user releases the mouse left button. + * Default behavior forwards the event to the observed scene. + */ + void OnLeftButtonUp() override; + + void OnMouseWheelForward() override {} + + void OnMouseWheelBackward() override {} + + void OnChar() override; + + void EndDolly() override; - void WindowLevel() override; + void WindowLevel() override; + void Slice() override; - void SetCurrentImageNumber(int i) override; + void SetCurrentImageNumber(int i) override; - vtkSetClampMacro(InteractionMode, int, VTKIS_IMAGE2D, VTKIS_IMAGE_WINDOWLEVEL); - void SetInteractionModeToImage2D() {} - void SetInteractionModeToImage3D() {} + void SetInteractionModeFromEnum(int InteractionMode) { + this->UnActiveMeasure(); + this->SetInteractionMode(InteractionMode); + } - void SetInteractionModeFromEnum(int InteractionMode) - { - this->UnActiveMeasure(); - this->SetInteractionMode(InteractionMode); - } - - //void SetInteractionModeToImageSlicing() { - // this->UnActiveMeasure(); - // this->SetInteractionMode(VTKIS_IMAGE_SLICING); - //} - //void SetInteractionModeToImagePan(){ - // this->UnActiveMeasure(); - // this->SetInteractionMode(VTKIS_IMAGE_PAN); - //} - //void SetInteractionModeToImageWindowLevel(){ - // this->UnActiveMeasure(); - // this->SetInteractionMode(VTKIS_IMAGE_WINDOWLEVEL); - //} - //void SetInteractionModeToImageZoom(){ - // this->UnActiveMeasure(); - // this->SetInteractionMode(VTKIS_IMAGE_ZOOM); - //} + //void SetInteractionModeToImageSlicing() { + // this->UnActiveMeasure(); + // this->SetInteractionMode(VTKIS_IMAGE_SLICING); + //} + //void SetInteractionModeToImagePan(){ + // this->UnActiveMeasure(); + // this->SetInteractionMode(VTKIS_IMAGE_PAN); + //} + //void SetInteractionModeToImageWindowLevel(){ + // this->UnActiveMeasure(); + // this->SetInteractionMode(VTKIS_IMAGE_WINDOWLEVEL); + //} + //void SetInteractionModeToImageZoom(){ + // this->UnActiveMeasure(); + // this->SetInteractionMode(VTKIS_IMAGE_ZOOM); + //} - vtkSetObjectMacro(CornerAnnotation, vtkCornerAnnotation); + vtkSetObjectMacro(CornerAnnotation, vtkCornerAnnotation); - vtkProp* GetSelectedProp() - { - return selectedProp; - } - void ClearSelectedProp() { - if (dragProp == selectedProp) dragProp = nullptr; - selectedProp = nullptr; - } - void ActiveMeasure(Measure* m); - void UnActiveMeasure(); + vtkProp *GetSelectedProp() { + return selectedProp; + } - void SetCurrentImageSlice(vtkImageSlice* slice){ - CurrentImageSlice = slice; - CurrentImageProperty = slice->GetProperty(); - } + void ClearSelectedProp() { + if (dragProp == selectedProp) dragProp = nullptr; + selectedProp = nullptr; + } + + void ActiveMeasure(Measure *m); + + void UnActiveMeasure(); + + void SetCurrentImageSlice(vtkImageSlice *slice) { + CurrentImageSlice = slice; + CurrentImageProperty = slice->GetProperty(); + } protected: - ActorDraggableInteractorStyle(); - ~ActorDraggableInteractorStyle() override; - void StartDrag() { - this->StartState(VTKIS_DRAG); - } - void EndDrag() { - if (this->State != VTKIS_DRAG) - { - return; - } - this->StopState(); - } - void Drag(); + ActorDraggableInteractorStyle(); + + ~ActorDraggableInteractorStyle() override; + + void StartDrag() { + this->StartState(VTKIS_DRAG); + } + + void EndDrag() { + if (this->State != VTKIS_DRAG) { + return; + } + this->StopState(); + } + + void Drag(); - void StartColorMapping() - { - OpacityTrigger = false; - ConsumedOpacity = 0; - this->StartState(VTKIS_COLORMAP); - } + void StartColorMapping() { + OpacityTrigger = false; + ConsumedOpacity = 0; + this->StartState(VTKIS_COLORMAP); + } - void EndColorMapping(); - void ColorMapping(); - bool OpacityTrigger = false; + void EndColorMapping(); - void StartMeasure() { - this->StartState(VTKIS_MEASURE); - } - void EndMeasure() { - 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(); + void ColorMapping(); + + bool OpacityTrigger = false; + + void StartMeasure() { + this->StartState(VTKIS_MEASURE); + } + + void EndMeasure() { + 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; - vtkNew picker; + ActorDraggableInteractorStyle(const ActorDraggableInteractorStyle &) = delete; - 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 }; - double DollyStartScale = 1.0; - vtkImageSlice * CurrentImageSlice = nullptr; - int lastslice = -1; + void operator=(const ActorDraggableInteractorStyle &) = delete; - int ScalarStartPosition[2] = { 0, 0 }; - int ScalarCurrentPosition[2] = { 0, 0 }; - double ConsumedOpacity = 0; + vtkNew picker; - void TestOutPut(vtkObject*, unsigned long eventid, void* calldata) { - switch (eventid) { - case DraggableStyleEvents::SlicedEvent: - { - int* r = (int*)calldata; + 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}; + double DollyStartScale = 1.0; + vtkImageSlice *CurrentImageSlice = nullptr; + int lastslice = -1; - printf("Sliced, current slice number:%d \r\n", r[0]); + int ScalarStartPosition[2] = {0, 0}; + int ScalarCurrentPosition[2] = {0, 0}; + double ConsumedOpacity = 0; - break; - } - case DraggableStyleEvents::EndDollyEvent: { - double *d = (double *)calldata; + void TestOutPut(vtkObject *, unsigned long eventid, void *calldata) { + switch (eventid) { + case DraggableStyleEvents::SlicedEvent: { + int *r = (int *) calldata; - printf("EndDolly, scale param:%f,%f \r\n", d[0], d[1]); + printf("Sliced, current slice number:%d \r\n", r[0]); - break; - } - case vtkCommand::EventIds::EndPanEvent: { - double *d = (double *)calldata; + break; + } + case DraggableStyleEvents::EndDollyEvent: { + 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]); + printf("EndDolly, scale param:%f,%f \r\n", d[0], d[1]); - break; - } - case vtkCommand::EventIds::EndWindowLevelEvent: - { - double *d = (double *)calldata; + break; + } + case vtkCommand::EventIds::EndPanEvent: { + double *d = (double *) calldata; - printf("EndWindowLevel, scale param:%f,%f \r\n", d[0], d[1]); + 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; - } - default: + break; + } + case vtkCommand::EventIds::EndWindowLevelEvent: { + double *d = (double *) calldata; - printf("current event :%s", vtkCommand::GetStringFromEventId(eventid)); - break; - } - } + printf("EndWindowLevel, scale param:%f,%f \r\n", d[0], d[1]); + + break; + } + default: + + printf("current event :%s", vtkCommand::GetStringFromEventId(eventid)); + break; + } + } }; #endif //OMEGAV_ACTORDRAGGABLEINTERACTORSTYLE_H