fw4spl
SBoxWidget.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 #ifndef ANDROID
8 
9 #include "visuVTKAdaptor/SBoxWidget.hpp"
10 
11 #include <fwData/TransformationMatrix3D.hpp>
12 
13 #include <fwRenderVTK/vtk/fwVtkBoxRepresentation.hpp>
14 
15 #include <fwServices/macros.hpp>
16 
17 #include <vtkBoxRepresentation.h>
18 #include <vtkBoxWidget2.h>
19 #include <vtkCamera.h>
20 #include <vtkCommand.h>
21 #include <vtkMatrix4x4.h>
22 #include <vtkRenderer.h>
23 #include <vtkRenderWindow.h>
24 #include <vtkRenderWindowInteractor.h>
25 #include <vtkTransform.h>
26 
27 namespace visuVTKAdaptor
28 {
29 
30 class BoxClallback : public ::vtkCommand
31 {
32 public:
33 
34  //------------------------------------------------------------------------------
35 
36  static BoxClallback* New(::visuVTKAdaptor::SBoxWidget* adaptor)
37  {
38  BoxClallback* cb = new BoxClallback;
39  cb->m_adaptor = adaptor;
40  return cb;
41  }
42 
43  BoxClallback() :
44  m_adaptor(nullptr)
45  {
46  }
47  ~BoxClallback()
48  {
49  }
50 
51  //------------------------------------------------------------------------------
52 
53  virtual void Execute( ::vtkObject*, unsigned long, void* )
54  {
55  m_adaptor->updateFromVtk();
56  }
57 
59 };
60 
61 // SBoxWidget
62 
63 fwServicesRegisterMacro(::fwRenderVTK::IAdaptor, ::visuVTKAdaptor::SBoxWidget);
64 
65 static const ::fwServices::IService::KeyType s_TRANSFORM_INOUT = "transform";
66 
67 //------------------------------------------------------------------------------
68 
69 SBoxWidget::SBoxWidget() noexcept :
71  m_transform(nullptr),
72  m_vtkBoxWidget(nullptr),
73  m_boxWidgetCommand(nullptr),
74  m_scaleFactor(1.0),
75  m_enableScaling(true)
76 {
77  m_boxWidgetCommand = BoxClallback::New(this);
78 }
79 
80 //------------------------------------------------------------------------------
81 
82 SBoxWidget::~SBoxWidget() noexcept
83 {
84 }
85 
86 //------------------------------------------------------------------------------
87 
89 {
90  this->configureParams();
91 
92  const ConfigType config = this->getConfigTree().get_child("config.<xmlattr>");
93 
94  m_scaleFactor = config.get("scaleFactor", 1.);
95 
96  const std::string enableScaling = config.get("enableScaling", "no");
97 
98  SLM_ASSERT("Wrong value for 'enableScaling', must be 'yes' or 'no'",
99  enableScaling == "yes" || enableScaling == "no");
100 
101  m_enableScaling = (enableScaling == "yes");
102 }
103 
104 //------------------------------------------------------------------------------
105 
107 {
108  this->initialize();
109 
110  SLM_ASSERT("vtk transform must be defined.", !this->getTransformId().empty());
111  m_transform = this->getRenderService()->getOrAddVtkTransform(this->getTransformId());
112 
113  fwVtkBoxRepresentation* boxRep = fwVtkBoxRepresentation::New();
114  boxRep->SetPlaceFactor(m_scaleFactor);
115 
116  double bounds[] = {-1, 1, -1, 1, -1, 1};
117  boxRep->PlaceWidget(bounds);
118 
119  m_vtkBoxWidget = ::vtkBoxWidget2::New();
120  m_vtkBoxWidget->SetRepresentation(boxRep);
121  m_vtkBoxWidget->SetInteractor( this->getInteractor() );
122  if (!m_enableScaling)
123  {
124  boxRep->ScalingEnabledOff();
125  }
126  m_vtkBoxWidget->On();
127 
128  boxRep->SetTransform(m_transform);
129 
130  m_vtkBoxWidget->AddObserver( ::vtkCommand::InteractionEvent, m_boxWidgetCommand );
131 
132  this->updating();
133 }
134 
135 //------------------------------------------------------------------------------
136 
138 {
139  m_transform->Delete();
140  m_transform = 0;
141  m_vtkBoxWidget->RemoveObserver( m_boxWidgetCommand );
142  m_vtkBoxWidget->Delete();
143  m_vtkBoxWidget = 0;
144  this->requestRender();
145 }
146 
147 //------------------------------------------------------------------------------
148 
149 void SBoxWidget::updateFromVtk()
150 {
151  m_vtkBoxWidget->RemoveObserver( m_boxWidgetCommand );
152 
153  vtkBoxRepresentation* repr = vtkBoxRepresentation::SafeDownCast( m_vtkBoxWidget->GetRepresentation() );
154  if( repr )
155  {
156  repr->GetTransform(m_transform);
157  m_transform->Modified();
158  }
159 
160  ::fwData::TransformationMatrix3D::sptr trf = this->getInOut< ::fwData::TransformationMatrix3D >(s_TRANSFORM_INOUT);
161  vtkMatrix4x4* mat = m_transform->GetMatrix();
162 
163  for(int lt = 0; lt < 4; lt++)
164  {
165  for(int ct = 0; ct < 4; ct++)
166  {
167  trf->setCoefficient(static_cast<size_t>(lt), static_cast<size_t>(ct), mat->GetElement(lt, ct));
168  }
169  }
170 
172  {
173  ::fwCom::Connection::Blocker block(sig->getConnection(m_slotUpdate));
174  sig->asyncEmit();
175  }
176 
177  m_vtkBoxWidget->AddObserver( ::vtkCommand::InteractionEvent, m_boxWidgetCommand );
178 }
179 
180 //------------------------------------------------------------------------------
181 
183 {
184  m_vtkBoxWidget->RemoveObserver( m_boxWidgetCommand );
185  vtkBoxRepresentation* repr = vtkBoxRepresentation::SafeDownCast( m_vtkBoxWidget->GetRepresentation() );
186  if( repr )
187  {
188  ::fwData::TransformationMatrix3D::sptr transMat =
189  this->getInOut< ::fwData::TransformationMatrix3D >(s_TRANSFORM_INOUT);
190 
191  vtkMatrix4x4* mat = vtkMatrix4x4::New();
192 
193  for(int lt = 0; lt < 4; lt++)
194  {
195  for(int ct = 0; ct < 4; ct++)
196  {
197  mat->SetElement(lt, ct, transMat->getCoefficient(static_cast<size_t>(lt), static_cast<size_t>(ct)));
198  }
199  }
200  m_transform->SetMatrix(mat);
201  repr->SetTransform(m_transform);
202  this->setVtkPipelineModified();
203  }
204  m_vtkBoxWidget->AddObserver( ::vtkCommand::InteractionEvent, m_boxWidgetCommand );
205  this->requestRender();
206 }
207 
208 //------------------------------------------------------------------------------
209 
211 {
212  KeyConnectionsMap connections;
213  connections.push(s_TRANSFORM_INOUT, ::fwData::TransformationMatrix3D::s_MODIFIED_SIG, s_UPDATE_SLOT);
214 
215  return connections;
216 }
217 
218 //------------------------------------------------------------------------------
219 
220 } // namespace visuVTKAdaptor
221 
222 #endif
This class is a helper to define the connections of a service and its data.
Definition: IService.hpp:454
Class allowing to block a Connection.
Definition: Connection.hpp:20
The namespace visuVTKAdaptor contains the list of adaptors available for the generic scene...
Displays a box widget that updates the associated TransformationMatrix3D.
Definition: SBoxWidget.hpp:43
VISUVTKADAPTOR_API void starting() override
Initialize the service activity.
Definition: SBoxWidget.cpp:106
VISUVTKADAPTOR_API void stopping() override
Uninitialize the service activity. The stop() method is always invoked before destroying a service...
Definition: SBoxWidget.cpp:137
#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 VISUVTKADAPTOR_API KeyConnectionsMap getAutoConnections() const override
Returns proposals to connect service slots to associated object signals, this method is used for obj/...
Definition: SBoxWidget.cpp:210
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_MODIFIED_SIG
Key in m_signals map of signal m_sigModified.
VISUVTKADAPTOR_API void updating() override
Perform some computations according to object (this service is attached to) attribute values and its ...
Definition: SBoxWidget.cpp:182
VISUVTKADAPTOR_API void configuring() override
Configure the service before starting. Apply the configuration to service.
Definition: SBoxWidget.cpp:88