7 #include "visuVTKAdaptor/SImageSlice.hpp" 9 #include <fwCom/Slot.hpp> 10 #include <fwCom/Slot.hxx> 11 #include <fwCom/Slots.hpp> 12 #include <fwCom/Slots.hxx> 14 #include <fwData/Image.hpp> 16 #include <fwDataTools/fieldHelper/Image.hpp> 17 #include <fwDataTools/fieldHelper/MedicalImageHelpers.hpp> 19 #include <fwServices/macros.hpp> 21 #include <fwVtkIO/vtk.hpp> 24 #include <vtkCellArray.h> 25 #include <vtkImageActor.h> 26 #include <vtkImageBlend.h> 27 #include <vtkImageData.h> 28 #include <vtkImageMapper3D.h> 29 #include <vtkPolyData.h> 30 #include <vtkPolyDataMapper.h> 31 #include <vtkProperty.h> 32 #include <vtkRenderer.h> 33 #include <vtkTransform.h> 40 static const ::fwCom::Slots::SlotKeyType s_UPDATE_SLICE_INDEX_SLOT =
"updateSliceIndex";
41 static const ::fwCom::Slots::SlotKeyType s_UPDATE_SLICE_TYPE_SLOT =
"updateSliceType";
43 static const ::fwServices::IService::KeyType s_IMAGE_INOUT =
"image";
47 SImageSlice::SImageSlice() noexcept :
48 m_interpolation(true),
50 m_imageSource(
nullptr),
51 m_imageActor(vtkImageActor::New()),
52 m_planeOutlinePolyData(vtkPolyData::New()),
53 m_planeOutlineMapper(vtkPolyDataMapper::New()),
54 m_planeOutlineActor(vtkActor::New())
56 newSlot(s_UPDATE_SLICE_INDEX_SLOT, &SImageSlice::updateSliceIndex,
this);
57 newSlot(s_UPDATE_SLICE_TYPE_SLOT, &SImageSlice::updateSliceType,
this);
62 SImageSlice::~SImageSlice() noexcept
64 m_imageActor->Delete();
65 m_imageActor =
nullptr;
67 m_planeOutlineActor->Delete();
68 m_planeOutlineActor =
nullptr;
70 m_planeOutlineMapper->Delete();
71 m_planeOutlineMapper =
nullptr;
73 m_planeOutlinePolyData->Delete();
74 m_planeOutlinePolyData =
nullptr;
102 ::fwData::Image::sptr image = this->getInOut< ::fwData::Image >(s_IMAGE_INOUT);
104 SLM_ASSERT(
"Input image must be three-dimensional. vtkImageActor does not handle 2D images.",
105 image->getNumberOfDimensions() == 3);
110 this->buildPipeline();
111 this->updateImage(image);
112 this->updateSImageSliceIndex(image);
113 this->updateOutline();
121 void SImageSlice::updateSliceIndex(
int axial,
int frontal,
int sagittal)
127 ::fwData::Image::sptr image = this->getInOut< ::fwData::Image >(s_IMAGE_INOUT);
130 this->updateSImageSliceIndex(image);
131 this->updateOutline();
136 void SImageSlice::updateSliceType(
int from,
int to)
155 const ConfigType config = this->
getConfigTree().get_child(
"config.<xmlattr>");
157 const std::string orientation = config.get<std::string>(
"sliceIndex",
"axial");
158 if(orientation ==
"axial" )
162 else if(orientation ==
"frontal" )
166 else if(orientation ==
"sagittal" )
171 this->setVtkImageSourceId( config.get<std::string>(
"vtkimagesource",
""));
173 const std::string interpolation = config.get<std::string>(
"interpolation",
"off");
174 SLM_ASSERT(
"'interpolation' value must be 'on' or 'off', actual: " + interpolation,
175 interpolation ==
"on" || interpolation ==
"off");
176 this->setInterpolation(interpolation ==
"yes");
178 this->setActorOpacity(config.get<
double>(
"actorOpacity", 1.));
183 void SImageSlice::updateImage( ::fwData::Image::sptr image )
191 void SImageSlice::updateSImageSliceIndex( ::fwData::Image::sptr image )
197 const int pos[3] = { sagittalIndex, frontalIndex, axialIndex };
204 void SImageSlice::setSlice(
int slice, ::fwData::Image::sptr image )
207 std::fill( extent, extent+6, 0);
208 extent[1] =
static_cast<int>(image->getSize()[0]-1);
209 extent[3] =
static_cast<int>(image->getSize()[1]-1);
210 extent[5] =
static_cast<int>(image->getSize()[2]-1);
214 OSLM_TRACE(
"DisplayExtent : " <<
" X min: " << extent[0] <<
" X max: " << extent[1] <<
215 " Y min: " << extent[2] <<
" Y max: " << extent[3] <<
216 " Z min: " << extent[4] <<
" Z max: " << extent[5]
219 m_imageActor->SetDisplayExtent( extent );
226 void SImageSlice::buildPipeline( )
228 if (!m_imageSourceId.empty())
233 vtkImageAlgorithm* algorithm = vtkImageAlgorithm::SafeDownCast(m_imageSource);
234 vtkImageData* imageData = vtkImageData::SafeDownCast(m_imageSource);
237 SLM_ASSERT(
"Invalid vtk image source", algorithm||imageData );
240 SLM_TRACE(
"Input is a vtkImageAlgorithm");
241 m_imageActor->GetMapper()->SetInputConnection(algorithm->GetOutputPort());
251 m_imageActor->SetInputData(imageData);
259 m_imageActor->SetInterpolate(m_interpolation);
260 m_imageActor->SetOpacity(m_actorOpacity);
262 this->buildOutline();
268 void SImageSlice::buildOutline()
270 vtkPoints* points = vtkPoints::New(VTK_DOUBLE);
271 points->SetNumberOfPoints(4);
273 for (i = 0; i < 4; i++)
275 points->SetPoint(i, 0.0, 0.0, 0.0);
278 vtkCellArray* cells = vtkCellArray::New();
279 cells->Allocate(cells->EstimateSize(4, 2));
281 pts[0] = 3; pts[1] = 2;
282 cells->InsertNextCell(2, pts);
283 pts[0] = 0; pts[1] = 1;
284 cells->InsertNextCell(2, pts);
285 pts[0] = 0; pts[1] = 3;
286 cells->InsertNextCell(2, pts);
287 pts[0] = 1; pts[1] = 2;
288 cells->InsertNextCell(2, pts);
290 m_planeOutlinePolyData->SetPoints(points);
293 m_planeOutlinePolyData->SetLines(cells);
297 m_planeOutlineMapper = vtkPolyDataMapper::New();
298 m_planeOutlineMapper->SetInputData( m_planeOutlinePolyData );
299 m_planeOutlineMapper->SetResolveCoincidentTopologyToPolygonOffset();
300 m_planeOutlineActor->SetMapper(m_planeOutlineMapper);
301 m_planeOutlineActor->PickableOff();
302 m_planeOutlineActor->GetProperty()->SetOpacity(0.9);
305 m_planeOutlineActor->SetUserTransform(this->
getTransform());
312 void SImageSlice::updateOutline()
314 static const int indexZ[12] = { 0, 2, 4, 1, 2, 4, 1, 3, 4, 0, 3, 4 };
315 static const int indexY[12] = { 0, 2, 4, 1, 2, 4, 1, 2, 5, 0, 2, 5 };
316 static const int indexX[12] = { 0, 2, 4, 0, 2, 5, 0, 3, 5, 0, 3, 4 };
317 static const int* indexSet[3] = { indexX, indexY, indexZ };
318 static double colors[3][3] = { {0., 0., 1.}, {0., 1., 0.}, {1., 0., 0.} };
320 double* extent = m_imageActor->GetBounds();
321 vtkPoints* points = m_planeOutlinePolyData->GetPoints();
324 for (
int i = 0; i < 4; ++i)
327 pt[0] = extent[ *(index++) ];
328 pt[1] = extent[ *(index++) ];
329 pt[2] = extent[ *(index++) ];
330 points->SetPoint(i, pt);
333 points->GetData()->Modified();
334 m_planeOutlinePolyData->Modified();
336 m_planeOutlineActor->GetProperty()->SetColor( colors[
m_orientation]);
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.
FWRENDERVTK_API void addToRenderer(vtkProp *prop)
Adds the vtkProp to the renderer.
FWRENDERVTK_API vtkObject * getVtkObject(const SRender::VtkObjectIdType &objectId) const
Returns the vtk object defined by 'objectId' in the vtk scene.
FWRENDERVTK_API void addToPicker(vtkProp *prop, std::string pickerId="")
Adds the vtkProp to the picking list.
The namespace visuVTKAdaptor contains the list of adaptors available for the generic scene...
FWRENDERVTK_API void configureParams()
Parse the xml configuration for renderer, picker and transform.
VISUVTKADAPTOR_API void configuring() override
Configure the service before starting. Apply the configuration to service.
FWRENDERVTK_API void requestRender()
notify a render request iff vtkPipeline is modified
FWRENDERVTK_API void setVtkPipelineModified()
End-user have to call this method when a vtk structure has been modified, thus a render request will ...
#define OSLM_TRACE(message)
FWRENDERVTK_API void removeAllPropFromRenderer()
Removes all the vtkProp from the renderer.
virtual VISUVTKADAPTOR_API KeyConnectionsMap getAutoConnections() const override
Returns proposals to connect service slots to associated object signals, this method is used for obj/...
VISUVTKADAPTOR_API void updating() override
Perform some computations according to object (this service is attached to) attribute values and its ...
FWRENDERVTK_API vtkTransform * getTransform()
Returns the transform used by this adaptor.
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_ASSERT(message, cond)
work like 'assert' from 'cassert', with in addition a message logged by spylog (with FATAL loglevel) ...
FWRENDERVTK_API SRender::VtkObjectIdType getTransformId() const
Returns the identifier of the transform used by this adaptor.
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_BUFFER_MODIFIED_SIG
Type of signal when image's buffer is added.
FWRENDERVTK_API void removeFromPicker(vtkProp *prop, std::string pickerId="")
Removes the vtkProp to the picking list.
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_MODIFIED_SIG
Key in m_signals map of signal m_sigModified.
#define SLM_TRACE(message)
FWRENDERVTK_API void initialize()
Initialize the adaptor with the associated render service. (must be call in starting).
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_SLICE_TYPE_MODIFIED_SIG
Type of signal when image's buffer is added.
static FWSERVICES_APIconst::fwCom::Slots::SlotKeyType s_UPDATE_SLOT
Slot to call start method.
Base class for VTK adaptors.
Adaptor to display only one slice of an image.
FWSERVICES_API ConfigType getConfigTree() const
Return the configuration, in an boost property tree.