fw4spl
SPoint.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 #ifndef ANDROID
8 
9 #include "visuVTKAdaptor/SPoint.hpp"
10 
11 #include "fwRenderVTK/vtk/Helpers.hpp"
12 #include "fwRenderVTK/vtk/MarkedSphereHandleRepresentation.hpp"
13 
14 #include <fwCom/Signal.hpp>
15 #include <fwCom/Signal.hxx>
16 
17 #include <fwData/Material.hpp>
18 #include <fwData/Point.hpp>
19 
20 #include <fwServices/macros.hpp>
21 
22 #include <vtkActor.h>
23 #include <vtkCommand.h>
24 #include <vtkHandleWidget.h>
25 #include <vtkPicker.h>
26 #include <vtkPolyDataMapper.h>
27 #include <vtkPropCollection.h>
28 #include <vtkProperty.h>
29 #include <vtkRenderer.h>
30 #include <vtkRenderWindowInteractor.h>
31 #include <vtkSphereHandleRepresentation.h>
32 #include <vtkSphereSource.h>
33 #include <vtkWidgetEventTranslator.h>
34 
35 fwServicesRegisterMacro( ::fwRenderVTK::IAdaptor, ::visuVTKAdaptor::SPoint);
36 
37 namespace visuVTKAdaptor
38 {
39 
40 const ::fwCom::Signals::SignalKeyType SPoint::s_INTERACTION_STARTED_SIG = "interactionStarted";
41 
42 const ::fwServices::IService::KeyType SPoint::s_POINT_INOUT = "point";
43 
44 //------------------------------------------------------------------------------
45 
46 class vtkPointUpdateCallBack : public vtkCommand
47 {
48 
49 public:
50  //------------------------------------------------------------------------------
51 
52  static vtkPointUpdateCallBack* New( ::fwRenderVTK::IAdaptor* service)
53  {
54  return new vtkPointUpdateCallBack(service);
55  }
56 
58  m_service(service),
59  m_pickLimiter(0)
60  {
61  }
62 
63  //------------------------------------------------------------------------------
64 
65  virtual void Execute( vtkObject* caller, unsigned long eventId, void*)
66  {
67  vtkHandleWidget* handler = vtkHandleWidget::SafeDownCast(caller);
68  if (!handler)
69  {
70  return;
71  }
72 
73  if ( eventId == vtkCommand::StartInteractionEvent)
74  {
75  handler->AddObserver("EndInteractionEvent", this );
76  handler->AddObserver("InteractionEvent", this );
77 
78  }
79  else if ( eventId == vtkCommand::EndInteractionEvent )
80  {
81  handler->RemoveObservers("EndInteractionEvent", this );
82  handler->RemoveObservers("InteractionEvent", this );
83  }
84 
85  ::fwData::Point::sptr point = m_service->getInOut< ::fwData::Point >(SPoint::s_POINT_INOUT);
86  SLM_ASSERT("inout 'point' is not defined", point);
87 
88  vtkHandleRepresentation* representation = vtkHandleRepresentation::SafeDownCast(handler->GetRepresentation());
89  SLM_ASSERT("handler not instanced", handler);
90  double* world = representation->GetWorldPosition();
91 
92  if ( (eventId == vtkCommand::InteractionEvent)
93  || eventId == vtkCommand::EndInteractionEvent )
94  {
95  double display[3];
96  int x, y;
97  handler->GetInteractor()->GetLastEventPosition(x, y);
98  display[0] = x;
99  display[1] = y;
100  display[2] = 0;
101 
102  if ( m_service->getPicker() && m_service->getPicker()->Pick( display, m_service->getRenderer() ) )
103  {
104  ::fwRenderVTK::vtk::getNearestPickedPosition(m_service->getPicker(), m_service->getRenderer(), world);
105  }
106 
107  std::copy( world, world+3, point->getCoord().begin() );
108 
110  sig->asyncEmit();
111  }
112  else if (eventId == vtkCommand::StartInteractionEvent)
113  {
115  sig->asyncEmit();
116  }
117  }
118 
119 protected:
120 
121  ::fwRenderVTK::IAdaptor* m_service;
122 
123  int m_pickLimiter;
124 };
125 
126 //------------------------------------------------------------------------------
127 
128 SPoint::SPoint() noexcept :
129  m_handle( vtkHandleWidget::New() ),
130  m_representation( ::fwRenderVTK::vtk::MarkedSphereHandleRepresentation::New() ),
131  m_pointUpdateCommand(nullptr),
132  m_radius(7.0),
133  m_interaction(true)
134 {
135  m_ptColor = ::fwData::Color::New();
136  m_ptSelectedColor = ::fwData::Color::New();
137 
138  m_ptSelectedColor->setRGBA("#00FF00");
139 
140  m_handle->SetRepresentation(m_representation);
141  m_handle->SetPriority(0.8f);
142 
143  vtkWidgetEventTranslator* translator = m_handle->GetEventTranslator();
144 
145  translator->RemoveTranslation(vtkCommand::MiddleButtonPressEvent);
146  translator->RemoveTranslation(vtkCommand::MiddleButtonReleaseEvent);
147  translator->RemoveTranslation(vtkCommand::RightButtonPressEvent);
148  translator->RemoveTranslation(vtkCommand::RightButtonReleaseEvent);
149 
151  ::fwRenderVTK::vtk::MarkedSphereHandleRepresentation::SafeDownCast(m_representation);
152 
153  rep->GetSelectedProperty()->SetOpacity(.3);
154  rep->GetMarkerProperty()->SetOpacity(.3);
155  rep->SetHandleSize(m_radius);
156 
157  newSignal<InteractionStartedSignalType>(s_INTERACTION_STARTED_SIG);
158 }
159 
160 //------------------------------------------------------------------------------
161 
162 SPoint::~SPoint() noexcept
163 {
164  m_handle->SetRepresentation(0);
165  m_handle->Delete();
166  m_handle = nullptr;
167 
168  m_representation->Delete();
169  m_representation = nullptr;
170 }
171 
172 //------------------------------------------------------------------------------
173 
175 {
176  this->configureParams();
177 
178  const ConfigType config = this->getConfigTree().get_child("config.<xmlattr>");
179 
180  const std::string hexaSelectedColor = config.get<std::string>("selectedColor", "");
181  m_ptSelectedColor = ::fwData::Color::New();
182  if (!hexaSelectedColor.empty())
183  {
184  m_ptSelectedColor->setRGBA(hexaSelectedColor);
185  }
186 
187  const std::string hexaColor = config.get<std::string>("color", "");
188  m_ptColor = ::fwData::Color::New();
189  if (!hexaColor.empty())
190  {
191  m_ptColor->setRGBA(hexaColor);
192  }
193 
194  const std::string radius = config.get<std::string>("radius", "");
195  if(!radius.empty())
196  {
197  m_radius = std::stod(radius);
198  }
199 
200  const std::string interaction = config.get<std::string>("interaction", "");
201  if(!interaction.empty())
202  {
203  SLM_FATAL_IF("value for 'interaction' must be 'on' or 'off', actual: " + interaction,
204  interaction != "on" && interaction != "off");
205  m_interaction = (interaction == "on");
206  }
207 }
208 
209 //------------------------------------------------------------------------------
210 
212 {
213  this->initialize();
214 
215  m_handle->SetInteractor( this->getInteractor() );
216  m_handle->KeyPressActivationOff();
217 
218  m_pointUpdateCommand = vtkPointUpdateCallBack::New(this);
219 
220  m_handle->AddObserver( "StartInteractionEvent", m_pointUpdateCommand );
221 
222  m_handle->On();
223 
224  // We don't want to add m_representation to the renderer, m_handle
225  // is already managing that.
226  this->registerProp(m_representation);
227 
228  this->updating();
229 }
230 
231 //------------------------------------------------------------------------------
232 
234 {
235  ::fwData::Point::sptr point = this->getInOut< ::fwData::Point >(s_POINT_INOUT);
236  SLM_ASSERT("point not instanced", point);
237 
238  double ps[3];
239 
240  std::copy(point->getCoord().begin(), point->getCoord().end(), ps );
241  m_representation->SetWorldPosition( ps );
242 
243  getRenderer()->ResetCameraClippingRange();
244 
246  ::fwRenderVTK::vtk::MarkedSphereHandleRepresentation::SafeDownCast(m_representation);
247 
248  SLM_ASSERT("MarkedSphereHandleRepresentation cast failed", rep);
249 
250  rep->SetHandleSize(m_radius);
251 
252  rep->GetProperty()->SetColor(m_ptColor->red(), m_ptColor->green(), m_ptColor->blue());
253  rep->GetProperty()->SetOpacity(m_ptColor->alpha());
254 
255  rep->GetSelectedProperty()->SetColor(m_ptSelectedColor->red(), m_ptSelectedColor->green(),
256  m_ptSelectedColor->blue());
257  rep->GetSelectedProperty()->SetOpacity(m_ptSelectedColor->alpha());
258 
259  m_handle->SetProcessEvents(m_interaction);
260  m_handle->SetManagesCursor(m_interaction);
261 
262  this->setVtkPipelineModified();
263  this->requestRender();
264 }
265 
266 //------------------------------------------------------------------------------
267 
269 {
270  m_handle->Off();
271  m_handle->RemoveObserver(m_pointUpdateCommand);
272 
273  m_pointUpdateCommand->Delete();
274  m_pointUpdateCommand = 0;
275 
276  m_handle->SetInteractor(0);
277 
278  this->unregisterProps();
279  this->setVtkPipelineModified();
280  this->requestRender();
281 }
282 
283 //------------------------------------------------------------------------------
284 
285 void SPoint::setRadius(const double radius)
286 {
287  m_radius = radius;
288  updating();
289 }
290 
291 //------------------------------------------------------------------------------
292 
293 void SPoint::setColor(const float red, const float green, const float blue, const float alpha)
294 {
295  m_ptColor->setRGBA(red, green, blue, alpha);
296  updating();
297 }
298 
299 //------------------------------------------------------------------------------
300 
301 void SPoint::setSelectedColor(const float red, const float green, const float blue, const float alpha)
302 {
303  m_ptSelectedColor->setRGBA(red, green, blue, alpha);
304  updating();
305 }
306 
307 //------------------------------------------------------------------------------
308 
309 void SPoint::setInteraction(const bool interaction)
310 {
311  m_interaction = interaction;
312  updating();
313 }
314 
315 //------------------------------------------------------------------------------
316 
318 {
319  KeyConnectionsMap connections;
320  connections.push(s_POINT_INOUT, ::fwData::Point::s_MODIFIED_SIG, s_UPDATE_SLOT);
321 
322  return connections;
323 }
324 
325 //------------------------------------------------------------------------------
326 
327 } //namespace visuVTKAdaptor
328 
329 #endif // ANDROID
This class is a helper to define the connections of a service and its data.
Definition: IService.hpp:454
Adaptor to display a point.
Definition: SPoint.hpp:53
FWRENDERVTK_API vtkRenderer * getRenderer()
Returns the renderer.
The namespace visuVTKAdaptor contains the list of adaptors available for the generic scene...
This class define a 3D point.
Definition: Point.hpp:22
static VISUVTKADAPTOR_APIconst::fwCom::Signals::SignalKeyType s_INTERACTION_STARTED_SIG
Type of signal when point interaction is started.
Definition: SPoint.hpp:81
VISUVTKADAPTOR_API void starting() override
Initialize the service activity.
Definition: SPoint.cpp:211
virtual VISUVTKADAPTOR_API KeyConnectionsMap getAutoConnections() const override
Returns proposals to connect service slots to associated object signals, this method is used for obj/...
Definition: SPoint.cpp:317
FWRENDERVTK_API vtkAbstractPropPicker * getPicker(std::string pickerId="")
Get the picker.
VISUVTKADAPTOR_API void stopping() override
Uninitialize the service activity. The stop() method is always invoked before destroying a service...
Definition: SPoint.cpp:268
VISUVTKADAPTOR_API void configuring() override
Configure the service before starting. Apply the configuration to service.
Definition: SPoint.cpp:174
VISUVTKADAPTOR_API void updating() override
Perform some computations according to object (this service is attached to) attribute values and its ...
Definition: SPoint.cpp:233
#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
#define SLM_FATAL_IF(message, cond)
Definition: spyLog.hpp:287
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_MODIFIED_SIG
Key in m_signals map of signal m_sigModified.
std::shared_ptr< DATATYPE > getInOut(const KeyType &key) const
Return the inout object at the given key. Asserts if the data is not of the right type...
Definition: IService.hxx:47