fw4spl
vtkSimpleNegato/src/vtkSimpleNegato/SRenderer.cpp
1 /* ***** BEGIN LICENSE BLOCK *****
2  * FW4SPL - Copyright (C) IRCAD, 2009-2018.
3  * Distributed under the terms of the GNU Lesser General Public License (LGPL) as
4  * published by the Free Software Foundation.
5  * ****** END LICENSE BLOCK ****** */
6 
7 #include "vtkSimpleNegato/SRenderer.hpp"
8 
9 #include <fwCom/Slot.hpp>
10 #include <fwCom/Slot.hxx>
11 #include <fwCom/Slots.hpp>
12 #include <fwCom/Slots.hxx>
13 
14 #include <fwData/Image.hpp>
15 
16 #include <fwDataTools/fieldHelper/MedicalImageHelpers.hpp>
17 
18 #include <fwServices/macros.hpp>
19 
20 #include <fwVtkIO/vtk.hpp>
21 
22 #include <vtkCellPicker.h>
23 #include <vtkCommand.h>
24 #include <vtkImageData.h>
25 #include <vtkLookupTable.h>
26 #include <vtkPolyDataMapper.h>
27 #include <vtkProperty.h>
28 #include <vtkRenderWindow.h>
29 #include <vtkSmartPointer.h>
30 
31 //-----------------------------------------------------------------------------
32 
33 fwServicesRegisterMacro( ::fwRender::IRender, ::vtkSimpleNegato::SRenderer, ::fwData::Image);
34 
35 //-----------------------------------------------------------------------------
36 
37 namespace vtkSimpleNegato
38 {
39 
40 static const ::fwCom::Slots::SlotKeyType s_REFRESH_SLOT = "refresh";
41 
42 static const std::string s_IMAGE_KEY = "image";
43 
44 //-----------------------------------------------------------------------------
45 
47  m_render( nullptr ),
48  m_bPipelineIsInit(false)
49 {
51  newSlot(s_REFRESH_SLOT, &SRenderer::refresh, this);
52 }
53 
54 //-----------------------------------------------------------------------------
55 
57 {
59 }
60 
61 //-----------------------------------------------------------------------------
62 
64 {
66  this->initialize();
67 }
68 
69 //-----------------------------------------------------------------------------
70 
72 {
73  this->create();
74 
75  m_interactorManager = ::fwRenderVTK::IVtkRenderWindowInteractorManager::createManager();
76  m_interactorManager->installInteractor( this->getContainer() );
77 
78  m_bPipelineIsInit = false;
79 
80  // Renderer
81  m_render = vtkRenderer::New();
82  m_interactorManager->getInteractor()->GetRenderWindow()->AddRenderer(m_render);
83 
84  this->refresh();
85 }
86 
87 //-----------------------------------------------------------------------------
88 
90 {
91  if( m_render == nullptr )
92  {
93  return;
94  }
95 
96  if(m_bPipelineIsInit)
97  {
98  m_negatoSagittal->Delete();
99  m_negatoFrontal->Delete();
100  m_negatoAxial->Delete();
101  m_outline->Delete();
102  }
103 
104  SLM_ASSERT("m_render not instanced", m_render);
105  m_render->Delete();
106  m_render = nullptr;
107 
108  m_interactorManager->uninstallInteractor();
109  m_interactorManager.reset();
110 
111  this->destroy();
112 }
113 
114 //-----------------------------------------------------------------------------
115 
117 {
118  this->refresh();
119 }
120 
121 //-----------------------------------------------------------------------------
122 
123 void SRenderer::refresh()
124 {
125  auto img = this->getInput< ::fwData::Image >(s_IMAGE_KEY);
126  SLM_ASSERT("'" + s_IMAGE_KEY + "' key not found", img);
128  if(imageIsValid )
129  {
130  if(!m_bPipelineIsInit)
131  {
132  initVTKPipeline();
133  m_bPipelineIsInit = true;
134  }
135  else
136  {
137  updateVTKPipeline();
138  }
139 
140  //
141  int axialIndex = static_cast<int>(img->getSize()[2]/2);
142  int frontalIndex = static_cast<int>(img->getSize()[1]/2);
143  int sagittalIndex = static_cast<int>(img->getSize()[0]/2);
144 
145  m_negatoAxial->SetSliceIndex( axialIndex );
146  m_negatoFrontal->SetSliceIndex( frontalIndex );
147  m_negatoSagittal->SetSliceIndex( sagittalIndex );
148  m_interactorManager->getInteractor()->Render();
149  }
150 }
151 
152 //-----------------------------------------------------------------------------
153 
154 void SRenderer::initVTKPipeline()
155 {
156  vtkSmartPointer< vtkImageData > vtkImg = vtkSmartPointer< vtkImageData >::New();
157 
158  auto image = this->getInput< ::fwData::Image >(s_IMAGE_KEY);
159  SLM_ASSERT("'" + s_IMAGE_KEY + "' key not found", image);
160  ::fwVtkIO::toVTKImage( image, vtkImg);
161 
162  m_outline = vtkOutlineFilter::New();
163  m_outline->SetInputData(vtkImg);
164 
165  vtkPolyDataMapper* outlineMapper = vtkPolyDataMapper::New();
166  outlineMapper->SetInputConnection(m_outline->GetOutputPort());
167 
168  vtkActor* outlineActor = vtkActor::New();
169  outlineActor->SetMapper( outlineMapper);
170 
171  vtkCellPicker* picker = vtkCellPicker::New();
172  picker->SetTolerance(0.005);
173 
174  //assign default props to the ipw's texture plane actor
175 
176  m_negatoSagittal = vtkImagePlaneWidget::New();
177  m_negatoSagittal->SetInteractor( m_interactorManager->getInteractor() );
178  m_negatoSagittal->SetKeyPressActivationValue('x');
179  m_negatoSagittal->SetPicker(picker);
180  m_negatoSagittal->GetPlaneProperty()->SetColor(1, 0, 0);
181  m_negatoSagittal->TextureInterpolateOn();
182  m_negatoSagittal->SetInputData(vtkImg);
183  m_negatoSagittal->SetPlaneOrientationToXAxes();
184  m_negatoSagittal->DisplayTextOn();
185  m_negatoSagittal->On();
186  m_negatoSagittal->InteractionOn();
187 
188  m_negatoFrontal = vtkImagePlaneWidget::New();
189  m_negatoFrontal->SetInteractor( m_interactorManager->getInteractor() );
190  m_negatoFrontal->SetKeyPressActivationValue('y');
191  m_negatoFrontal->SetPicker(picker);
192  m_negatoFrontal->GetPlaneProperty()->SetColor(0, 1, 0);
193  m_negatoFrontal->TextureInterpolateOn();
194  m_negatoFrontal->SetInputData(vtkImg);
195  m_negatoFrontal->SetPlaneOrientationToYAxes();
196  m_negatoFrontal->SetLookupTable( m_negatoSagittal->GetLookupTable());
197  m_negatoFrontal->DisplayTextOn();
198  m_negatoFrontal->UpdatePlacement();
199  m_negatoFrontal->On();
200 
201  m_negatoAxial = vtkImagePlaneWidget::New();
202  m_negatoAxial->SetInteractor( m_interactorManager->getInteractor() );
203  m_negatoAxial->SetKeyPressActivationValue('z');
204  m_negatoAxial->SetPicker(picker);
205  m_negatoAxial->GetPlaneProperty()->SetColor(0, 0, 1);
206  m_negatoAxial->TextureInterpolateOn();
207  m_negatoAxial->SetInputData(vtkImg);
208  m_negatoAxial->SetPlaneOrientationToZAxes();
209  m_negatoAxial->SetLookupTable( m_negatoSagittal->GetLookupTable());
210  m_negatoAxial->DisplayTextOn();
211  m_negatoAxial->On();
212 
213  // Add the actors
214  m_render->AddActor( outlineActor);
215 
216  // Repaint and resize window
217  m_render->ResetCamera();
218 
219  picker->Delete();
220  outlineActor->Delete();
221  outlineMapper->Delete();
222 }
223 
224 //-----------------------------------------------------------------------------
225 
226 void SRenderer::updateVTKPipeline()
227 {
228  auto image = this->getInput< ::fwData::Image >(s_IMAGE_KEY);
229  SLM_ASSERT("'" + s_IMAGE_KEY + "' key not found", image);
230 
231  vtkSmartPointer< vtkImageData > vtkImg = vtkSmartPointer< vtkImageData >::New();
232  ::fwVtkIO::toVTKImage( image, vtkImg);
233 
234  m_outline->SetInputData(vtkImg);
235  m_negatoSagittal->SetInputData(vtkImg);
236  m_negatoFrontal->SetInputData(vtkImg);
237  m_negatoAxial->SetInputData(vtkImg);
238 }
239 
240 //------------------------------------------------------------------------------
241 
243 {
244  KeyConnectionsMap connections;
245  connections.push( s_IMAGE_KEY, ::fwData::Image::s_MODIFIED_SIG, s_REFRESH_SLOT );
246  connections.push( s_IMAGE_KEY, ::fwData::Image::s_BUFFER_MODIFIED_SIG, s_REFRESH_SLOT );
247 
248  return connections;
249 }
250 
251 //-----------------------------------------------------------------------------
252 
253 }
This class is a helper to define the connections of a service and its data.
Definition: IService.hpp:454
virtual VTKSIMPLENEGATO_API void stopping() override
Stopping method.
#define SLM_TRACE_FUNC()
Trace contextual function signature.
Definition: spyLog.hpp:329
FWGUI_API void destroy()
Stops sub-views and toobar services. Destroys view, sub-views and toolbar containers.
virtual VTKSIMPLENEGATO_API void configuring() override
This method is used to configure the service.
virtual VTKSIMPLENEGATO_API ~SRenderer() noexcept
Destructor.
The namespace vtkSimpleNegato has a visualization service of medical image (fwData::Image).
Defines the service interface managing the rendering service for object.
Definition: IRender.hpp:36
VTKSIMPLENEGATO_API SRenderer() noexcept
Constructor.
#define SLM_ASSERT(message, cond)
work like &#39;assert&#39; from &#39;cassert&#39;, with in addition a message logged by spylog (with FATAL loglevel) ...
Definition: spyLog.hpp:308
virtual VTKSIMPLENEGATO_API void starting() override
Starting method.
FWGUI_API void create()
Creates view, sub-views and toolbar containers. Manages sub-views and toobar services.
virtual VTKSIMPLENEGATO_API void updating() override
Updating method.
virtual VTKSIMPLENEGATO_API KeyConnectionsMap getAutoConnections() const override
Returns proposals to connect service slots to associated object signals, this method is used for obj/...
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_BUFFER_MODIFIED_SIG
Type of signal when image&#39;s buffer is added.
Service rendering a fwData::Image using VTK.
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_MODIFIED_SIG
Key in m_signals map of signal m_sigModified.
static FWDATATOOLS_API bool checkImageValidity(::fwData::Image::csptr _pImg)
Check if the image is valid.
This class defines an image.
FWGUI_API void initialize()
Initialize managers.