fw4spl
STransform.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 "visuVTKAdaptor/STransform.hpp"
8 
9 #include <fwCom/Signal.hpp>
10 #include <fwCom/Signal.hxx>
11 
12 #include <fwData/Boolean.hpp>
13 #include <fwData/Material.hpp>
14 #include <fwData/mt/ObjectReadLock.hpp>
15 #include <fwData/mt/ObjectWriteLock.hpp>
16 #include <fwData/Reconstruction.hpp>
17 #include <fwData/TransformationMatrix3D.hpp>
18 
19 #include <fwServices/macros.hpp>
20 
21 #include <vtkCommand.h>
22 #include <vtkMatrix4x4.h>
23 #include <vtkRenderWindowInteractor.h>
24 #include <vtkTransform.h>
25 
26 class TransformCallback : public ::vtkCommand
27 {
28 public:
29 
30  //------------------------------------------------------------------------------
31 
32  static TransformCallback* New(::visuVTKAdaptor::STransform* adaptor)
33  {
35  cb->m_adaptor = adaptor;
36  return cb;
37  }
38 
40  m_adaptor(nullptr)
41  {
42  }
44  {
45  }
46 
47  //------------------------------------------------------------------------------
48 
49  virtual void Execute( ::vtkObject* pCaller, unsigned long, void* )
50  {
51  m_adaptor->updateFromVtk();
52  }
53 
55 };
56 
57 fwServicesRegisterMacro( ::fwRenderVTK::IAdaptor, ::visuVTKAdaptor::STransform);
58 
59 namespace visuVTKAdaptor
60 {
61 
62 const ::fwServices::IService::KeyType STransform::s_TM3D_INOUT = "tm3d";
63 
64 //------------------------------------------------------------------------------
65 
66 STransform::STransform() noexcept :
67  m_transform(nullptr),
68  m_transformCommand(TransformCallback::New(this))
69 {
70 }
71 
72 //------------------------------------------------------------------------------
73 
74 STransform::~STransform() noexcept
75 {
76  if( m_transformCommand )
77  {
78  m_transformCommand->Delete();
79  }
80  m_transformCommand = nullptr;
81 }
82 
83 //------------------------------------------------------------------------------
84 
85 void STransform::configuring()
86 {
87  this->configureParams();
88 
89  const ConfigType config = this->getConfigTree().get_child("config.<xmlattr>");
90 
91  m_parentId = config.get< std::string >("parent", "");
92 }
93 
94 //------------------------------------------------------------------------------
95 
96 void STransform::starting()
97 {
98  this->initialize();
99 
100  if(!m_transformId.empty())
101  {
102  m_renderService.lock()->getOrAddVtkTransform(m_transformId);
103  }
104  if(!m_parentId.empty())
105  {
106  m_parentTransform = m_renderService.lock()->getOrAddVtkTransform(m_parentId);
107  }
108 
109  this->updating();
110  this->getTransform()->AddObserver( ::vtkCommand::ModifiedEvent, m_transformCommand );
111 }
112 
113 //------------------------------------------------------------------------------
114 
115 void STransform::updateFromVtk()
116 {
117  vtkTransform* vtkTrf = this->getTransform();
118 
119  vtkTrf->RemoveObserver( m_transformCommand );
120  ::fwData::TransformationMatrix3D::sptr trf = this->getInOut< ::fwData::TransformationMatrix3D >(s_TM3D_INOUT);
121  SLM_ASSERT("matrix '" + s_TM3D_INOUT + "' is not defined", trf);
122 
123  vtkMatrix4x4* mat = nullptr;
124 
125  if(m_parentTransform)
126  {
127  // Get the matrix before concatenation
128  mat = vtkTrf->GetConcatenatedTransform(0)->GetMatrix();
129  }
130  else
131  {
132  mat = vtkTrf->GetMatrix();
133  }
134 
135  {
137  for(int lt = 0; lt < 4; lt++)
138  {
139  for(int ct = 0; ct < 4; ct++)
140  {
141  trf->setCoefficient(static_cast<size_t>(lt), static_cast<size_t>(ct), mat->GetElement(lt, ct));
142  }
143  }
144  }
145 
147  {
148  ::fwCom::Connection::Blocker block(sig->getConnection(m_slotUpdate));
149  sig->asyncEmit();
150  }
151 
152  vtkTrf->AddObserver( ::vtkCommand::ModifiedEvent, m_transformCommand );
153 }
154 
155 //------------------------------------------------------------------------------
156 
157 void STransform::updating()
158 {
159  vtkTransform* vtkTrf = this->getTransform();
160 
161  vtkTrf->RemoveObserver( m_transformCommand );
162  ::fwData::TransformationMatrix3D::sptr trf = this->getInOut< ::fwData::TransformationMatrix3D >(s_TM3D_INOUT);
163  SLM_ASSERT("matrix '" + s_TM3D_INOUT + "' is not defined", trf);
164 
165  vtkMatrix4x4* mat = vtkMatrix4x4::New();
166 
167  {
169  for(int lt = 0; lt < 4; lt++)
170  {
171  for(int ct = 0; ct < 4; ct++)
172  {
173  mat->SetElement(lt, ct, trf->getCoefficient(static_cast<size_t>(lt), static_cast<size_t>(ct)));
174  }
175  }
176  }
177 
178  if(m_parentTransform)
179  {
180  vtkTrf->PostMultiply();
181  vtkTrf->SetMatrix( mat );
182  vtkTrf->Concatenate( m_parentTransform );
183  }
184  else
185  {
186  vtkTrf->SetMatrix(mat);
187  }
188 
189  vtkTrf->Modified();
190  vtkTrf->AddObserver( ::vtkCommand::ModifiedEvent, m_transformCommand );
191  mat->Delete();
192  this->setVtkPipelineModified();
193  this->requestRender();
194 }
195 
196 //------------------------------------------------------------------------------
197 
198 void STransform::setTransform(vtkTransform* t)
199 {
200  if ( m_transform != t )
201  {
202  if (m_transform)
203  {
204  m_transform->Delete();
205  }
206  if(t)
207  {
208  t->Register(nullptr);
209  }
210  }
211  m_transform = t;
212 }
213 
214 //------------------------------------------------------------------------------
215 
216 vtkTransform* STransform::getTransform()
217 {
218  vtkTransform* t = m_transform;
219  if (t == 0)
220  {
221  t = this->IAdaptor::getTransform();
222  }
223  return t;
224 }
225 
226 //------------------------------------------------------------------------------
227 
228 void STransform::swapping()
229 {
230  this->updating();
231 }
232 
233 //------------------------------------------------------------------------------
234 
235 void STransform::stopping()
236 {
237  this->getTransform()->RemoveObserver(m_transformCommand);
238 }
239 
240 //------------------------------------------------------------------------------
241 
242 ::fwServices::IService::KeyConnectionsMap STransform::getAutoConnections() const
243 {
244  KeyConnectionsMap connections;
245  connections.push(s_TM3D_INOUT, ::fwData::TransformationMatrix3D::s_MODIFIED_SIG, s_UPDATE_SLOT);
246 
247  return connections;
248 }
249 
250 } //namespace visuVTKAdaptor
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...
A helper to lock object on read mode.
A helper to lock object on exclusive mode.
VISUVTKADAPTOR_API void updateFromVtk()
Updates the TransformationMatrix3D from the vtkTransform.
Definition: STransform.cpp:115
#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
Adaptor binding a TransformationMatrix3D to a vtkTransform.
Definition: STransform.hpp:44
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_MODIFIED_SIG
Key in m_signals map of signal m_sigModified.