fw4spl
SCamera.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/SCamera.hpp"
8 
9 #include <fwCom/Signal.hpp>
10 #include <fwCom/Signal.hxx>
11 
12 #include <fwData/Boolean.hpp>
13 #include <fwData/mt/ObjectReadLock.hpp>
14 #include <fwData/mt/ObjectWriteLock.hpp>
15 #include <fwData/TransformationMatrix3D.hpp>
16 
17 #include <fwDataTools/fieldHelper/Image.hpp>
18 
19 #include <fwServices/macros.hpp>
20 
21 #include <vtkActor.h>
22 #include <vtkCamera.h>
23 #include <vtkCommand.h>
24 #include <vtkIdentityTransform.h>
25 #include <vtkMatrix4x4.h>
26 #include <vtkPerspectiveTransform.h>
27 #include <vtkRenderer.h>
28 #include <vtkTransform.h>
29 
30 class CameraClallback : public ::vtkCommand
31 {
32 public:
33 
34  //------------------------------------------------------------------------------
35 
36  static CameraClallback* New(::visuVTKAdaptor::SCamera* adaptor)
37  {
39  cb->m_adaptor = adaptor;
40  return cb;
41  }
42 
43  CameraClallback() :
44  m_adaptor(nullptr)
45  {
46  }
48  {
49  }
50 
51  //------------------------------------------------------------------------------
52 
53  virtual void Execute( ::vtkObject* pCaller, unsigned long eventId, void* )
54  {
55  m_adaptor->updateFromVtk();
56  }
57 
58  ::visuVTKAdaptor::SCamera* m_adaptor;
59 };
60 
61 fwServicesRegisterMacro( ::fwRenderVTK::IAdaptor, ::visuVTKAdaptor::SCamera);
62 
63 static const ::fwServices::IService::KeyType s_TRANSFORM_INOUT = "transform";
64 
65 namespace visuVTKAdaptor
66 {
67 
68 //------------------------------------------------------------------------------
69 
70 SCamera::SCamera() noexcept :
71  m_cameraCommand(CameraClallback::New(this)),
72  m_transOrig(nullptr),
73  m_viewAngle(30.)
74 {
75 }
76 
77 //------------------------------------------------------------------------------
78 
79 SCamera::~SCamera() noexcept
80 {
81 }
82 
83 //------------------------------------------------------------------------------
84 
85 void SCamera::configuring()
86 {
87  this->configureParams();
88 
89  const ConfigType config = this->getConfigTree().get_child("config.<xmlattr>.");
90  m_viewAngle = config.get<double>("viewAngle", m_viewAngle);
91 
92 }
93 
94 //------------------------------------------------------------------------------
95 
96 void SCamera::starting()
97 {
98  this->initialize();
99 
100  vtkCamera* camera = this->getRenderer()->GetActiveCamera();
101 
102  double position[] = {0.0, 0.0, 0.0};
103  double focal[] = {1.0, 0.0, 0.0};
104  double viewUp[] = {0.0, 0.0, 1.0};
105 
106  m_transOrig = vtkPerspectiveTransform::New();
107  m_transOrig->Identity();
108  m_transOrig->SetupCamera(position, focal, viewUp );
109 
110  camera->SetPosition(position);
111  camera->SetFocalPoint(focal);
112  camera->SetViewUp(viewUp);
113  camera->SetViewAngle(m_viewAngle);
114 
115  camera->AddObserver( ::vtkCommand::ModifiedEvent, m_cameraCommand );
116  this->requestRender();
117 }
118 
119 //------------------------------------------------------------------------------
120 
121 void SCamera::updating()
122 {
123  vtkCamera* camera = this->getRenderer()->GetActiveCamera();
124  camera->RemoveObserver( m_cameraCommand );
125 
126  ::fwData::TransformationMatrix3D::csptr transMat =
127  this->getInOut< ::fwData::TransformationMatrix3D >(s_TRANSFORM_INOUT);
128 
129  vtkMatrix4x4* mat = vtkMatrix4x4::New();
130 
131  ::fwData::mt::ObjectReadLock lock(transMat);
132 
133  for(int lt = 0; lt < 4; lt++)
134  {
135  for(int ct = 0; ct < 4; ct++)
136  {
137  mat->SetElement(lt, ct, transMat->getCoefficient(static_cast<size_t>(lt), static_cast<size_t>(ct)));
138  }
139  }
140 
141  lock.unlock();
142 
143  // Position camera on origin
144  vtkPerspectiveTransform* oldTrans = vtkPerspectiveTransform::New();
145  oldTrans->Identity();
146  oldTrans->SetupCamera(camera->GetPosition(), camera->GetFocalPoint(), camera->GetViewUp());
147  oldTrans->Inverse();
148  oldTrans->Concatenate(m_transOrig);
149  oldTrans->Inverse();
150 
151  // Apply new transform
152  vtkTransform* trans = vtkTransform::New();
153  trans->SetMatrix(mat);
154  trans->Concatenate(oldTrans->GetMatrix());
155  camera->ApplyTransform(trans);
156 
157  this->getRenderer()->ResetCameraClippingRange();
158  this->setVtkPipelineModified();
159 
160  camera->AddObserver( ::vtkCommand::ModifiedEvent, m_cameraCommand );
161 
162  mat->Delete();
163  oldTrans->Delete();
164  trans->Delete();
165  this->requestRender();
166 }
167 
168 //------------------------------------------------------------------------------
169 
170 void SCamera::stopping()
171 {
172  vtkCamera* camera = this->getRenderer()->GetActiveCamera();
173  camera->RemoveObserver( m_cameraCommand );
174  this->unregisterServices();
175  m_transOrig->Delete();
176  this->requestRender();
177 }
178 
179 //------------------------------------------------------------------------------
180 
181 void SCamera::updateFromVtk()
182 {
183  vtkCamera* camera = this->getRenderer()->GetActiveCamera();
184  camera->RemoveObserver( m_cameraCommand );
185 
186  ::fwData::TransformationMatrix3D::sptr trf = this->getInOut< ::fwData::TransformationMatrix3D >(s_TRANSFORM_INOUT);
188 
189  vtkPerspectiveTransform* trans = vtkPerspectiveTransform::New();
190  trans->Identity();
191  trans->SetupCamera(camera->GetPosition(), camera->GetFocalPoint(), camera->GetViewUp());
192 
193  trans->Inverse();
194  trans->Concatenate(m_transOrig);
195  vtkMatrix4x4* mat = trans->GetMatrix();
196 
197  for(int lt = 0; lt < 4; lt++)
198  {
199  for(int ct = 0; ct < 4; ct++)
200  {
201  trf->setCoefficient(static_cast<size_t>(lt), static_cast<size_t>(ct), mat->GetElement(lt, ct));
202  }
203  }
204 
205  lock.unlock();
206 
208  {
209  ::fwCom::Connection::Blocker block(sig->getConnection(m_slotUpdate));
210  sig->asyncEmit();
211  }
212 
213  camera->AddObserver( ::vtkCommand::ModifiedEvent, m_cameraCommand );
214 
215  trans->Delete();
216 }
217 
218 //------------------------------------------------------------------------------
219 
220 ::fwServices::IService::KeyConnectionsMap SCamera::getAutoConnections() const
221 {
222  KeyConnectionsMap connections;
223  connections.push(s_TRANSFORM_INOUT, ::fwData::TransformationMatrix3D::s_MODIFIED_SIG, s_UPDATE_SLOT);
224 
225  return connections;
226 }
227 
228 //------------------------------------------------------------------------------
229 
230 } //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.
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_MODIFIED_SIG
Key in m_signals map of signal m_sigModified.
FWDATA_API void unlock()
Releases lock on object mutex.
This adaptor updates the camera position according to a matrix (and vice versa)
Definition: SCamera.hpp:39