7 #include "visuVTKAdaptor/SNegatoSlicingInteractor.hpp" 9 #include <fwCom/Signal.hpp> 10 #include <fwCom/Signal.hxx> 11 #include <fwCom/Signals.hpp> 12 #include <fwCom/Slot.hpp> 13 #include <fwCom/Slot.hxx> 14 #include <fwCom/Slots.hpp> 15 #include <fwCom/Slots.hxx> 17 #include <fwData/Image.hpp> 18 #include <fwData/Integer.hpp> 19 #include <fwData/String.hpp> 20 #include <fwData/TransferFunction.hpp> 22 #include <fwDataTools/fieldHelper/Image.hpp> 23 #include <fwDataTools/fieldHelper/MedicalImageHelpers.hpp> 25 #include <fwRenderVTK/vtk/fwVtkCellPicker.hpp> 26 #include <fwRenderVTK/vtk/Helpers.hpp> 28 #include <fwServices/macros.hpp> 31 #include <vtkActorCollection.h> 32 #include <vtkAssemblyNode.h> 33 #include <vtkCellPicker.h> 34 #include <vtkCommand.h> 35 #include <vtkInteractorStyleImage.h> 36 #include <vtkProp3DCollection.h> 37 #include <vtkRenderWindowInteractor.h> 44 #define START_SLICING_EVENT vtkCommand::MiddleButtonPressEvent 45 #define STOP_SLICING_EVENT vtkCommand::MiddleButtonReleaseEvent 59 m_localPicker(
nullptr),
60 m_pickedProp(
nullptr),
61 m_mouseMoveObserved(
false)
63 this->PassiveObserverOff();
72 bool Pick(
double pickPoint[3],
double position[3])
74 SLM_ASSERT(
"m_picker should be set before picking.", m_picker);
76 if ( m_picker->Pick( pickPoint, m_adaptor->getRenderer() ) )
78 m_picker->GetPickPosition(position);
86 bool localPick(
double pickPoint[3],
double position[3])
88 SLM_ASSERT(
"m_localPicker should be set before picking.", m_localPicker);
90 if ( m_localPicker->Pick( pickPoint, m_adaptor->getRenderer() ) )
92 m_localPicker->GetPickPosition(position);
102 SLM_TRACE(
"vtkEvent: MiddleButtonPressEvent");
103 SLM_ASSERT(
"m_adaptor not instanced", m_adaptor);
104 SLM_ASSERT(
"m_picker not instanced", m_picker);
107 double pickedPoint[3];
110 m_adaptor->getInteractor()->GetEventPosition(x, y);
116 "vtkEvent: MiddleButtonPressEvent: picking " << pickPoint[0] <<
", " << pickPoint[1] <<
", " <<
119 if ( this->Pick(pickPoint, pickedPoint) )
121 SLM_TRACE(
"vtkEvent: MiddleButtonPressEvent:picked point");
122 SLM_ASSERT(
"Slicing has already begun", !m_mouseMoveObserved);
123 m_adaptor->getInteractor()->AddObserver(vtkCommand::MouseMoveEvent,
this, 1.);
124 m_mouseMoveObserved =
true;
128 m_pickedProp = ::fwRenderVTK::vtk::getNearestPickedProp(m_picker, m_adaptor->getRenderer());
129 m_localPicker = fwVtkCellPicker::New();
130 m_localPicker->InitializePickList();
131 m_localPicker->PickFromListOn();
132 m_localPicker->AddPickList(m_pickedProp);
134 double localPickedPoint[3];
135 this->localPick(pickPoint, localPickedPoint);
137 m_adaptor->startSlicing(localPickedPoint);
145 SLM_TRACE(
"vtkEvent: MiddleButtonReleaseEvent");
146 SLM_ASSERT(
"m_adaptor not instanced", m_adaptor);
147 SLM_ASSERT(
"m_picker not instanced", m_picker);
148 SLM_ASSERT(
"Slicing doesn't begun", m_mouseMoveObserved);
150 m_adaptor->getInteractor()->RemoveObservers(vtkCommand::MouseMoveEvent,
this);
151 m_mouseMoveObserved =
false;
152 m_adaptor->stopSlicing();
153 m_localPicker->Delete();
154 m_localPicker =
nullptr;
155 m_pickedProp =
nullptr;
160 virtual void Execute( vtkObject* caller,
unsigned long eventId,
void*)
162 if(m_mouseMoveObserved && eventId == START_SLICING_EVENT)
167 if(m_mouseMoveObserved || !m_adaptor->getInteractor()->GetShiftKey())
169 if (eventId == START_SLICING_EVENT && !m_mouseMoveObserved)
174 else if(eventId == STOP_SLICING_EVENT && m_mouseMoveObserved)
178 else if (eventId == vtkCommand::MouseMoveEvent)
181 SLM_ASSERT(
"m_mouseMoveObserved not instanced", m_mouseMoveObserved);
185 double pickedPoint[3];
187 m_adaptor->getInteractor()->GetEventPosition(x, y);
192 if ( this->localPick(pickPoint, pickedPoint))
194 m_adaptor->updateSlicing(pickedPoint);
197 else if (eventId == vtkCommand::KeyPressEvent && !m_adaptor->getInteractor()->GetControlKey())
199 vtkRenderWindowInteractor* rwi = vtkRenderWindowInteractor::SafeDownCast(caller);
200 char* keySym = rwi->GetKeySym();
202 if ( std::string(keySym) ==
"A" || std::string(keySym) ==
"a" )
204 m_adaptor->pushSlice(-1, m_adaptor->getOrientation());
206 else if (std::string(keySym) ==
"Z" || std::string(keySym) ==
"z" )
208 m_adaptor->pushSlice(1, m_adaptor->getOrientation());
210 if ( std::string(keySym) ==
"T" || std::string(keySym) ==
"t" )
212 m_adaptor->pushSlice(-1, ::fwDataTools::helper::MedicalImageAdaptor::Z_AXIS);
214 else if (std::string(keySym) ==
"Y" || std::string(keySym) ==
"y" )
216 m_adaptor->pushSlice(1, ::fwDataTools::helper::MedicalImageAdaptor::Z_AXIS);
218 else if (std::string(keySym) ==
"G" || std::string(keySym) ==
"g" )
220 m_adaptor->pushSlice(-1, ::fwDataTools::helper::MedicalImageAdaptor::Y_AXIS);
222 else if (std::string(keySym) ==
"H" || std::string(keySym) ==
"h" )
224 m_adaptor->pushSlice(1, ::fwDataTools::helper::MedicalImageAdaptor::Y_AXIS);
226 else if (std::string(keySym) ==
"B" || std::string(keySym) ==
"b" )
228 m_adaptor->pushSlice(-1, ::fwDataTools::helper::MedicalImageAdaptor::X_AXIS);
230 else if (std::string(keySym) ==
"N" || std::string(keySym) ==
"n" )
232 m_adaptor->pushSlice(1, ::fwDataTools::helper::MedicalImageAdaptor::X_AXIS);
234 else if (std::string(keySym) ==
"space" && !m_mouseMoveObserved)
236 this->startSlicing();
239 else if(eventId == vtkCommand::KeyReleaseEvent)
241 vtkRenderWindowInteractor* rwi = vtkRenderWindowInteractor::SafeDownCast(caller);
242 char* keySym = rwi->GetKeySym();
244 if (std::string(keySym) ==
"space" && m_mouseMoveObserved)
250 else if (m_adaptor->getInteractor()->GetShiftKey())
252 if (eventId == MouseWheelForwardEvent)
254 m_adaptor->pushSlice(1, m_adaptor->getOrientation());
256 else if (eventId == vtkCommand::MouseWheelBackwardEvent)
258 m_adaptor->pushSlice(-1, m_adaptor->getOrientation());
265 void setAdaptor( SNegatoSlicingInteractor::sptr adaptor)
272 void setPicker( vtkAbstractPropPicker* picker)
278 SNegatoSlicingInteractor::sptr m_adaptor;
279 vtkAbstractPropPicker* m_picker;
280 vtkAbstractPropPicker* m_localPicker;
281 vtkProp* m_pickedProp;
282 bool m_mouseMoveObserved;
285 static const ::fwCom::Slots::SlotKeyType s_UPDATE_SLICE_INDEX_SLOT =
"updateSliceIndex";
286 static const ::fwCom::Slots::SlotKeyType s_UPDATE_SLICE_TYPE_SLOT =
"updateSliceType";
291 static const ::fwServices::IService::KeyType s_IMAGE_INOUT =
"image";
295 SNegatoSlicingInteractor::SNegatoSlicingInteractor() noexcept :
296 m_vtkObserver(
nullptr),
299 m_sigSlicingStarted = newSignal< SlicingStartedSignalType >(s_SLICING_STARTED_SIG);
300 m_sigSlicingStopped = newSignal< SlicingStoppedSignalType >(s_SLICING_STOPPED_SIG);
308 SNegatoSlicingInteractor::~SNegatoSlicingInteractor() noexcept
316 this->configureParams();
318 const ConfigType config = this->getConfigTree().get_child(
"config.<xmlattr>");
320 const std::string orientation = config.get<std::string>(
"sliceIndex",
"axial");
321 if(orientation ==
"axial" )
323 m_orientation = Z_AXIS;
325 else if(orientation ==
"frontal" )
327 m_orientation = Y_AXIS;
329 else if(orientation ==
"sagittal" )
331 m_orientation = X_AXIS;
342 observer->setAdaptor( SNegatoSlicingInteractor::dynamicCast(this->getSptr()) );
343 observer->setPicker(this->getPicker());
345 m_vtkObserver = observer;
347 this->getInteractor()->AddObserver(START_SLICING_EVENT, m_vtkObserver, m_priority);
348 this->getInteractor()->AddObserver(STOP_SLICING_EVENT, m_vtkObserver, m_priority);
349 this->getInteractor()->AddObserver(vtkCommand::KeyPressEvent, m_vtkObserver, m_priority);
350 this->getInteractor()->AddObserver(vtkCommand::KeyReleaseEvent, m_vtkObserver, m_priority);
351 this->getInteractor()->AddObserver(vtkCommand::MouseWheelForwardEvent, m_vtkObserver, m_priority);
352 this->getInteractor()->AddObserver(vtkCommand::MouseWheelBackwardEvent, m_vtkObserver, m_priority);
354 ::fwData::Image::sptr image = this->getInOut< ::fwData::Image >(s_IMAGE_INOUT);
356 this->updateImageInfos(image);
363 ::fwData::Image::sptr image = this->getInOut< ::fwData::Image >(s_IMAGE_INOUT);
365 this->updateImageInfos(image);
372 this->getInteractor()->RemoveObservers(START_SLICING_EVENT, m_vtkObserver);
373 this->getInteractor()->RemoveObservers(STOP_SLICING_EVENT, m_vtkObserver);
374 this->getInteractor()->RemoveObservers(vtkCommand::KeyPressEvent, m_vtkObserver);
375 this->getInteractor()->RemoveObservers(vtkCommand::KeyReleaseEvent, m_vtkObserver);
376 this->getInteractor()->RemoveObservers(vtkCommand::MouseWheelForwardEvent, m_vtkObserver);
377 this->getInteractor()->RemoveObservers(vtkCommand::MouseWheelBackwardEvent, m_vtkObserver);
378 m_vtkObserver->Delete();
379 m_vtkObserver =
nullptr;
386 m_axialIndex->value() = axial;
387 m_frontalIndex->value() = frontal;
388 m_sagittalIndex->value() = sagittal;
395 if( to == static_cast<int>(m_orientation) )
397 setOrientation( static_cast< Orientation >( from ));
399 else if(from == static_cast<int>(m_orientation))
401 setOrientation( static_cast< Orientation >( to ));
407 void SNegatoSlicingInteractor::startSlicing(
double pickedPoint[3] )
409 ::fwData::Integer::sptr sliceIndex[3];
410 this->getSliceIndex(sliceIndex);
413 this->worldToImageSliceIndex(pickedPoint, index);
414 m_sigSlicingStarted->asyncEmit();
417 for (i = 0; i < 3; i++)
419 if (index[i] == sliceIndex[i]->value())
428 this->updateSlicing(pickedPoint);
434 void SNegatoSlicingInteractor::stopSlicing()
436 ::fwData::Image::sptr image = this->getInOut< ::fwData::Image >(s_IMAGE_INOUT);
438 m_sigSlicingStopped->asyncEmit();
444 sig->asyncEmit(m_axialIndex->value(), m_frontalIndex->value(), m_sagittalIndex->value());
450 void SNegatoSlicingInteractor::updateSlicing(
double pickedPoint[3] )
452 ::fwData::Image::sptr image = this->getInOut< ::fwData::Image >(s_IMAGE_INOUT);
455 ::fwData::Integer::sptr sliceIndex[3];
456 this->getSliceIndex(sliceIndex);
459 int originalIndex = sliceIndex[m_orientation]->value();
461 this->worldToImageSliceIndex(pickedPoint, index);
462 index[m_orientation] = originalIndex;
464 OSLM_TRACE(
"sliceIndex[0] "<< sliceIndex[0]->value()<<
" index[0] " << index[0] <<
" pickedPt "<<pickedPoint[0]);
465 OSLM_TRACE(
"sliceIndex[1] "<< sliceIndex[1]->value()<<
" index[1] " << index[1] <<
" pickedPt "<<pickedPoint[1]);
466 OSLM_TRACE(
"sliceIndex[2] "<< sliceIndex[2]->value()<<
" index[2] " << index[2] <<
" pickedPt "<<pickedPoint[2]);
469 for (
int i = 0; i < image->getNumberOfDimensions(); i++ )
472 <<
" and image->getSize()[" << i <<
"] = " << image->getSize()[i],
473 index[i] >= 0 && index[i] < image->getSize()[i]);
477 if(setSliceIndex(index))
483 sig->asyncEmit(m_axialIndex->value(), m_frontalIndex->value(), m_sagittalIndex->value());
490 void SNegatoSlicingInteractor::pushSlice(
int factor,
Orientation axis)
492 ::fwData::Integer::sptr sliceIndex[3];
493 this->getSliceIndex(sliceIndex);
496 index[0] = sliceIndex[0]->value();
497 index[1] = sliceIndex[1]->value();
498 index[2] = sliceIndex[2]->value();
499 index[axis] += factor;
502 this->getImageDataSize(size);
508 else if (index[axis] >= size[axis])
510 index[axis] = size[axis]-1;
513 if(setSliceIndex(index))
515 ::fwData::Image::sptr image = this->getInOut< ::fwData::Image >(s_IMAGE_INOUT);
518 m_sigSlicingStopped->asyncEmit();
524 sig->asyncEmit(m_axialIndex->value(), m_frontalIndex->value(), m_sagittalIndex->value());
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_SLICE_INDEX_MODIFIED_SIG
Type of signal when image's buffer is added.
This class is a helper to define the connections of a service and its data.
#define OSLM_ASSERT(message, cond)
work like 'assert' from 'cassert', with in addition a message logged by spylog (with FATAL loglevel) ...
Class allowing to block a Connection.
The namespace visuVTKAdaptor contains the list of adaptors available for the generic scene...
static VISUVTKADAPTOR_APIconst::fwCom::Signals::SignalKeyType s_SLICING_STARTED_SIG
Type of signal when slicing is updated.
void updateSliceIndex(int axial, int frontal, int sagittal)
Slot: update image slice index.
static VISUVTKADAPTOR_APIconst::fwCom::Signals::SignalKeyType s_SLICING_STOPPED_SIG
Type of signal when slicing is updated.
#define OSLM_TRACE(message)
VISUVTKADAPTOR_API void stopping() override
Uninitialize the service activity. The stop() method is always invoked before destroying a service...
VISUVTKADAPTOR_API void starting() override
Initialize the service activity.
#define SLM_INFO_IF(message, cond)
#define SLM_ASSERT(message, cond)
work like 'assert' from 'cassert', with in addition a message logged by spylog (with FATAL loglevel) ...
VISUVTKADAPTOR_API void updating() override
Perform some computations according to object (this service is attached to) attribute values and its ...
VISUVTKADAPTOR_API void configuring() override
Configure the service before starting. Apply the configuration to service.
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_BUFFER_MODIFIED_SIG
Type of signal when image's buffer is added.
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_MODIFIED_SIG
Key in m_signals map of signal m_sigModified.
#define SLM_TRACE(message)
virtual VISUVTKADAPTOR_API KeyConnectionsMap getAutoConnections() const override
Returns proposals to connect service slots to associated object signals, this method is used for obj/...
void updateSliceType(int from, int to)
Slot: update image slice type.
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_SLICE_TYPE_MODIFIED_SIG
Type of signal when image's buffer is added.
Base class for VTK adaptors.