fw4spl
SImagesProbeCursor.cpp
1 /* ***** BEGIN LICENSE BLOCK *****
2  * FW4SPL - Copyright (C) IRCAD, 2009-2017.
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 "visuVTKAdaptor/SImagesProbeCursor.hpp"
8 
9 #include <fwData/Composite.hpp>
10 #include <fwData/Image.hpp>
11 #include <fwData/Integer.hpp>
12 
13 #include <fwDataTools/fieldHelper/Image.hpp>
14 #include <fwDataTools/fieldHelper/MedicalImageHelpers.hpp>
15 #include <fwDataTools/helper/Image.hpp>
16 
17 #include <fwRenderVTK/vtk/Helpers.hpp>
18 
19 #include <fwServices/macros.hpp>
20 
21 #include <boost/foreach.hpp>
22 #include <boost/format.hpp>
23 
24 #include <vtkAbstractPropPicker.h>
25 #include <vtkActor.h>
26 #include <vtkCellArray.h>
27 #include <vtkCellData.h>
28 #include <vtkCommand.h>
29 #include <vtkInteractorStyleImage.h>
30 #include <vtkPolyData.h>
31 #include <vtkPolyDataMapper.h>
32 #include <vtkProperty.h>
33 #include <vtkRenderWindowInteractor.h>
34 #include <vtkTextActor.h>
35 #include <vtkTextMapper.h>
36 #include <vtkTextProperty.h>
37 #include <vtkTransform.h>
38 
39 fwServicesRegisterMacro(::fwRenderVTK::IAdaptor, ::visuVTKAdaptor::SImagesProbeCursor);
40 
41 #define START_PROBE_EVENT vtkCommand::LeftButtonPressEvent
42 #define STOP_PROBE_EVENT vtkCommand::LeftButtonReleaseEvent
43 
44 namespace visuVTKAdaptor
45 {
46 
47 static const ::fwServices::IService::KeyType s_IMAGE_GROUP = "image";
48 
49 //------------------------------------------------------------------------------
50 
51 SImagesProbeCursor::SImagesProbeCursor() noexcept
52 {
53  m_priority = 0.61f; // must be greater than SProbeCursor to be visible
54 }
55 
56 //------------------------------------------------------------------------------
57 
58 SImagesProbeCursor::~SImagesProbeCursor() noexcept
59 {
60 }
61 
62 //------------------------------------------------------------------------------
63 
65 {
67 
68  const ConfigType config = this->getConfigTree().get_child("inout");
69 
70  SLM_ASSERT("configured group must be '" + s_IMAGE_GROUP + "'",
71  config.get<std::string>("<xmlattr>.group", "") == s_IMAGE_GROUP);
72 
73  BOOST_FOREACH(const ::fwServices::IService::ConfigType::value_type &v, config.equal_range("key"))
74  {
75  const ::fwServices::IService::ConfigType& specAssoc = v.second;
76  const ::fwServices::IService::ConfigType& attr = specAssoc.get_child("<xmlattr>");
77  const std::string name = attr.get("name", "");
78  m_imagesNames.push_back(name);
79  }
80 }
81 
82 //------------------------------------------------------------------------------
83 
85 {
86  this->SProbeCursor::starting();
87 }
88 
89 //------------------------------------------------------------------------------
90 
92 {
93  ::fwData::Image::sptr firstImage = this->getInOut< ::fwData::Image >(s_IMAGE_GROUP, 0);
94  if (firstImage)
95  {
96  this->updateImageInfos(firstImage);
97  this->setVisibility(false);
98  this->requestRender();
99  }
100 }
101 
102 //------------------------------------------------------------------------------
103 
105 {
106  this->SProbeCursor::stopping();
107 }
108 
109 //------------------------------------------------------------------------------
110 
111 void SImagesProbeCursor::updateView( double world[3] )
112 {
113  const size_t nbImages = this->getKeyGroupSize(s_IMAGE_GROUP);
114  SLM_ASSERT("There must be as much images as names", nbImages == m_imagesNames.size());
115 
116  std::stringstream txt;
117 
118  ::fwData::Image::sptr firstImage = this->getInOut< ::fwData::Image >(s_IMAGE_GROUP, 0);
119  if (firstImage)
120  {
122  {
123  this->updateImageInfos(firstImage);
124 
125  int index[3];
126  this->worldToImageSliceIndex( world, index );
127  OSLM_TRACE("index=" << index[0] << "," << index[1] << "," << index[2] );
128 
129  if ( world[0] < firstImage->getOrigin()[0] ||
130  world[1] < firstImage->getOrigin()[1] ||
131  world[2] < firstImage->getOrigin()[2] ||
132  index[0] < 0 || index[1] < 0 || index[2] < 0 ||
133  static_cast<size_t>(index[0]) >= firstImage->getSize()[0] ||
134  static_cast<size_t>(index[1]) >= firstImage->getSize()[1] ||
135  static_cast<size_t>(index[2]) >= firstImage->getSize()[2]
136  )
137  {
138  txt << "(---,---,---)" << std::endl;
139  }
140  else
141  {
142  ::fwDataTools::helper::Image imageHelper(firstImage);
143  txt << (::boost::format("(% 4li,% 4li,% 4li)") % index[0] % index[1] % index[2] ).str() << std::endl;
144 
145  // update polyData
146  double worldCross[4][3];
147  this->computeCrossExtremity(firstImage, index, worldCross);
148 
149  vtkPoints* points = m_cursorPolyData->GetPoints();
150  for ( int i = 0; i < 4; ++i)
151  {
152  OSLM_TRACE("p=" << worldCross[i][0] << "," << worldCross[i][2] << "," << worldCross[i][2] << "," );
153  points->SetPoint(i, worldCross[i]);
154  }
155  m_cursorPolyData->Modified();
156  }
157  }
158  }
159 
160  for(size_t i = 0; i < nbImages; ++i)
161  {
162  ::fwData::Image::sptr image = this->getInOut< ::fwData::Image >(s_IMAGE_GROUP, i);
163  if (image)
164  {
166  {
167  ::fwDataTools::helper::Image imageHelper(image);
168  this->updateImageInfos(image);
169 
170  int index[3];
171  this->worldToImageSliceIndex( world, index );
172  OSLM_TRACE("index=" << index[0] << "," << index[1] << "," << index[2] << "," );
173 
174  if ( !( world[0] < image->getOrigin()[0] ||
175  world[1] < image->getOrigin()[1] ||
176  world[2] < image->getOrigin()[2] ||
177  index[0] < 0 || index[1] < 0 || index[2] < 0 ||
178  static_cast<size_t>(index[0]) >= image->getSize()[0] ||
179  static_cast<size_t>(index[1]) >= image->getSize()[1] ||
180  static_cast<size_t>(index[2]) >= image->getSize()[2])
181  )
182  {
183  std::string greyLevel = imageHelper.getPixelAsString(static_cast<size_t>(index[0]),
184  static_cast<size_t>(index[1]),
185  static_cast<size_t>(index[2]) );
186  txt << m_imagesNames[i] << " : " << greyLevel << std::endl;
187  }
188  }
189  }
190  }
191  m_textMapper->SetInput(txt.str().c_str());
192 
193  this->setVtkPipelineModified();
194  this->requestRender();
195 }
196 
197 //------------------------------------------------------------------------------
198 
200 {
201  KeyConnectionsMap connections;
202  connections.push(s_IMAGE_GROUP, ::fwData::Image::s_MODIFIED_SIG, s_UPDATE_SLOT);
203  connections.push(s_IMAGE_GROUP, ::fwData::Image::s_SLICE_INDEX_MODIFIED_SIG, s_UPDATE_SLICE_INDEX_SLOT);
204  connections.push(s_IMAGE_GROUP, ::fwData::Image::s_BUFFER_MODIFIED_SIG, s_UPDATE_SLOT);
205 
206  return connections;
207 }
208 
209 } //namespace visuVTKAdaptor
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_SLICE_INDEX_MODIFIED_SIG
Type of signal when image&#39;s buffer is added.
This class is a helper to define the connections of a service and its data.
Definition: IService.hpp:454
The namespace visuVTKAdaptor contains the list of adaptors available for the generic scene...
VISUVTKADAPTOR_API void starting() override
Initialize the service activity.
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)
Definition: spyLog.hpp:230
VISUVTKADAPTOR_API void updating() override
Perform some computations according to object (this service is attached to) attribute values and its ...
VISUVTKADAPTOR_API void stopping() override
Uninitialize the service activity. The stop() method is always invoked before destroying a service...
FWDATATOOLS_API void worldToImageSliceIndex(const double world[3], int index[3])
Convert coordinates in the world to coordinates in the image.
Defines an helper to modify an fwData::Image by adding few medical fields and create in parallel the ...
VISUVTKADAPTOR_API void starting() override
Initialize the service activity.
FWDATATOOLS_API const std::string getPixelAsString(SizeType::value_type x, SizeType::value_type y, SizeType::value_type z)
Helpers for 3D images.
FWDATATOOLS_API void updateImageInfos(::fwData::Image::sptr image)
Update the image information (slice index, min/max,...)
virtual VISUVTKADAPTOR_API KeyConnectionsMap getAutoConnections() const override
Returns proposals to connect service slots to associated object signals, this method is used for obj/...
#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
size_t getKeyGroupSize(const KeyType &keybase) const
Return the number of key in a group of keys.
Definition: IService.hxx:119
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_BUFFER_MODIFIED_SIG
Type of signal when image&#39;s buffer is added.
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_MODIFIED_SIG
Key in m_signals map of signal m_sigModified.
Displays pixel information from images.
static FWDATATOOLS_API bool checkImageValidity(::fwData::Image::csptr _pImg)
Check if the image is valid.
VISUVTKADAPTOR_API void configuring() override
Configure the service before starting. Apply the configuration to service.
VISUVTKADAPTOR_API void configuring() override
Configure the service before starting. Apply the configuration to service.
VISUVTKADAPTOR_API void stopping() override
Uninitialize the service activity. The stop() method is always invoked before destroying a service...
static FWSERVICES_APIconst::fwCom::Slots::SlotKeyType s_UPDATE_SLOT
Slot to call start method.
Definition: IService.hpp:177
FWSERVICES_API ConfigType getConfigTree() const
Return the configuration, in an boost property tree.
Definition: IService.cpp:247