fw4spl
SMesh.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/SMesh.hpp"
8 
9 #include "visuVTKAdaptor/SMaterial.hpp"
10 #include "visuVTKAdaptor/SMeshNormals.hpp"
11 #include "visuVTKAdaptor/STexture.hpp"
12 #include "visuVTKAdaptor/STransform.hpp"
13 
14 #include <fwCom/Signal.hxx>
15 #include <fwCom/Slot.hpp>
16 #include <fwCom/Slot.hxx>
17 #include <fwCom/Slots.hpp>
18 #include <fwCom/Slots.hxx>
19 
20 #include <fwData/Material.hpp>
21 #include <fwData/Mesh.hpp>
22 #include <fwData/mt/ObjectReadLock.hpp>
23 
24 #include <fwRuntime/EConfigurationElement.hpp>
25 
26 #include <fwServices/macros.hpp>
27 #include <fwServices/op/Add.hpp>
28 
29 #include <fwVtkIO/helper/Mesh.hpp>
30 #include <fwVtkIO/vtk.hpp>
31 
32 #include <vtkActor.h>
33 #include <vtkCamera.h>
34 #include <vtkCommand.h>
35 #include <vtkDepthSortPolyData.h>
36 #include <vtkMath.h>
37 #include <vtkMatrix4x4.h>
38 #include <vtkPicker.h>
39 #include <vtkPlaneCollection.h>
40 #include <vtkPolyDataMapper.h>
41 #include <vtkPolyDataNormals.h>
42 #include <vtkProperty.h>
43 #include <vtkRenderer.h>
44 #include <vtkRenderWindowInteractor.h>
45 #include <vtkTextureMapToCylinder.h>
46 #include <vtkTextureMapToPlane.h>
47 #include <vtkTextureMapToSphere.h>
48 #include <vtkTransform.h>
49 
50 fwServicesRegisterMacro( ::fwRenderVTK::IAdaptor, ::visuVTKAdaptor::SMesh);
51 
52 //-----------------------------------------------------------------------------
53 
54 namespace visuVTKAdaptor
55 {
56 
57 //-----------------------------------------------------------------------------
58 
59 const ::fwCom::Signals::SignalKeyType SMesh::s_TEXTURE_APPLIED_SIG = "textureApplied";
60 
61 const ::fwCom::Slots::SlotKeyType SMesh::s_UPDATE_VISIBILITY_SLOT = "updateVisibility";
62 const ::fwCom::Slots::SlotKeyType SMesh::s_UPDATE_POINT_COLORS_SLOT = "updatePointColors";
63 const ::fwCom::Slots::SlotKeyType SMesh::s_UPDATE_CELL_COLORS_SLOT = "updateCellColors";
64 const ::fwCom::Slots::SlotKeyType SMesh::s_UPDATE_VERTEX_SLOT = "updateVertex";
65 const ::fwCom::Slots::SlotKeyType SMesh::s_UPDATE_POINT_NORMALS_SLOT = "updatePointNormals";
66 const ::fwCom::Slots::SlotKeyType SMesh::s_UPDATE_CELL_NORMALS_SLOT = "updateCellNormals";
67 const ::fwCom::Slots::SlotKeyType SMesh::s_UPDATE_POINT_TEX_COORDS_SLOT = "updatePointTexCoords";
68 const ::fwCom::Slots::SlotKeyType SMesh::s_UPDATE_CELL_TEX_COORDS_SLOT = "updateCellTexCoords";
69 const ::fwCom::Slots::SlotKeyType SMesh::s_SHOW_POINT_COLORS_SLOT = "showPointColors";
70 const ::fwCom::Slots::SlotKeyType SMesh::s_SHOW_CELL_COLORS_SLOT = "showCellColors";
71 const ::fwCom::Slots::SlotKeyType SMesh::s_HIDE_COLORS_SLOT = "hideColors";
72 const ::fwCom::Slots::SlotKeyType SMesh::s_UPDATE_COLOR_MODE_SLOT = "updateColorMode";
73 const ::fwCom::Slots::SlotKeyType SMesh::s_UPDATE_NORMAL_MODE_SLOT = "updateNormalMode";
74 const ::fwCom::Slots::SlotKeyType SMesh::s_UPDATE_MATRIX_FIELD_SLOT = "updateMatrixField";
75 
76 const ::fwServices::IService::KeyType SMesh::s_MESH_INPUT = "mesh";
77 
78 static const std::string s_MATRIX_FIELD_NAME = "TransformMatrix";
79 
80 //-----------------------------------------------------------------------------
81 
82 class MeshVtkCommand : public vtkCommand
83 {
84 public:
85  virtual void Stop() = 0;
86 };
87 
88 //------------------------------------------------------------------------------
89 
91 {
92 public:
93 
94  //------------------------------------------------------------------------------
95 
96  static PlaneShifterCallback* New( vtkPlane* src, vtkPlane* dst, double factor = 1.)
97  {
98  return new PlaneShifterCallback( src, dst, factor );
99  }
100 
101  //--------------------------------------------------------------------------
102  PlaneShifterCallback( vtkPlane* src, vtkPlane* dst, double factor ) :
103  m_planeSrc(src),
104  m_planeDst(dst),
105  m_factor(factor)
106  {
107  m_planeSrc->Register(this);
108  m_planeDst->Register(this);
109  src->AddObserver(vtkCommand::ModifiedEvent, this);
110  this->Execute( 0, vtkCommand::ModifiedEvent, 0);
111  }
112 
113  //------------------------------------------------------------------------------
114 
115  void Stop()
116  {
117  m_planeSrc->RemoveObserver(this);
118  m_planeSrc->UnRegister(this);
119  m_planeDst->UnRegister(this);
120  }
121 
122  //------------------------------------------------------------------------------
123 
124  virtual void Execute( vtkObject* caller, unsigned long eventId, void* )
125  {
126  if (eventId == vtkCommand::ModifiedEvent)
127  {
128  double n[3];
129  double o[3];
130 
131  m_planeSrc->GetNormal(n);
132  m_planeSrc->GetOrigin(o);
133 
134  if (m_factor < 0)
135  {
136  for (int i = 0; i < 3; i++)
137  {
138  n[i] = -n[i];
139  }
140  }
141 
142  m_planeDst->SetNormal( n );
143  m_planeDst->SetOrigin( o );
144  m_planeDst->Push( m_factor );
145  m_planeDst->Modified();
146  }
147 
148  }
149 
150 protected:
151  vtkPlane* m_planeSrc;
152  vtkPlane* m_planeDst;
153  double m_factor;
154 };
155 
157 {
158 public:
159 
160  //------------------------------------------------------------------------------
161 
162  static PlaneCollectionAdaptorStarter* New(
163  ::visuVTKAdaptor::SMesh::sptr service,
164  vtkPlaneCollection* src,
165  double factor = 1. )
166  {
167  return new PlaneCollectionAdaptorStarter( service, src, factor );
168  }
169 
170  //--------------------------------------------------------------------------
171  PlaneCollectionAdaptorStarter( ::visuVTKAdaptor::SMesh::sptr service,
172  vtkPlaneCollection* src,
173  double factor) :
174  m_service(service),
175  m_planeCollectionSrc(src),
176  m_factor(factor)
177  {
178  m_planeCollectionSrc->Register(this);
179  m_planeCollectionSrc->AddObserver(vtkCommand::ModifiedEvent, this);
180  this->Execute( 0, vtkCommand::ModifiedEvent, 0);
181  }
182 
183  //------------------------------------------------------------------------------
184 
185  void Stop()
186  {
187  m_planeCollectionSrc->RemoveObserver(this);
188  m_planeCollectionSrc->UnRegister(this);
189  this->Clear();
190  }
191 
192  //------------------------------------------------------------------------------
193 
194  void Clear()
195  {
196  for( ::visuVTKAdaptor::SMesh::wptr adaptor : m_meshServices )
197  {
198  if (!adaptor.expired())
199  {
200  adaptor.lock()->stop();
201  ::fwServices::OSR::unregisterService(adaptor.lock());
202  }
203  }
204  m_meshServices.clear();
205 
206  for( PlaneShifterCallback* psc : m_planeCallbacks )
207  {
208  psc->Stop();
209  psc->Delete();
210  psc = 0;
211  }
212  m_planeCallbacks.clear();
213 
214  for( vtkPlaneCollection* planeCol : m_planeCollections )
215  {
216  planeCol->Delete();
217  }
218  m_planeCollections.clear();
219 
220  if (!m_service.expired())
221  {
222  m_service.lock()->setActorPropertyToUnclippedMaterial( false );
223  }
224  }
225 
226  //------------------------------------------------------------------------------
227 
228  virtual void Execute( vtkObject* caller, unsigned long eventId, void* data)
229  {
230  ::visuVTKAdaptor::SMesh::sptr service;
231 
232  if (m_service.expired())
233  {
234  this->Stop();
235  this->Delete();
236  return;
237  }
238 
239  if (eventId == vtkCommand::ModifiedEvent)
240  {
241  service = m_service.lock();
242 
243  this->Clear();
244 
245  vtkPlane* plane = NULL;
246  for ( m_planeCollectionSrc->InitTraversal();
247  (plane = m_planeCollectionSrc->GetNextItem());
248  )
249  {
250  vtkPlane* newPlane = vtkPlane::New();
251  m_planeCallbacks.push_back(PlaneShifterCallback::New(plane, newPlane, m_factor));
252 
253  vtkPlaneCollection* newCollection = vtkPlaneCollection::New();
254  newCollection->AddItem(newPlane);
255 
256  ::fwServices::registry::ServiceFactory::sptr srvFactory =
258 
259  ::fwServices::IService::sptr srv = srvFactory->create("::visuVTKAdaptor::SMesh");
260  SLM_ASSERT("Service of type '::visuVTKAdaptor::SMesh' cannot be instantiated.", srv);
261 
262  ::fwRenderVTK::IAdaptor::sptr meshService = ::fwRenderVTK::IAdaptor::dynamicCast(srv);
263  SLM_ASSERT("Service of type '::visuVTKAdaptor::SMesh' is not an adaptor", meshService);
264 
265  ::fwServices::OSR::registerServiceInput(service->getInput< ::fwData::Mesh >(SMesh::s_MESH_INPUT),
266  SMesh::s_MESH_INPUT, srv);
267 
268  ::visuVTKAdaptor::SMesh::sptr meshAdaptor = SMesh::dynamicCast(meshService);
269 
270  // Create the config to auto-connect the mesh to the new adaptor
272  config.m_type = "::visuVTKAdaptor::SMesh";
273  config.m_globalAutoConnect = false;
274  config.m_config = ::fwRuntime::EConfigurationElement::New("service");
276  objConfig.m_key = SMesh::s_MESH_INPUT;
277  objConfig.m_access = ::fwServices::IService::AccessType::INPUT;
278  objConfig.m_autoConnect = true;
279  objConfig.m_optional = false;
280  config.m_objects.push_back(objConfig);
281 
282  meshAdaptor->setConfiguration(config);
283  meshAdaptor->setRenderService(service->getRenderService());
284  meshAdaptor->setRendererId(service->getRendererId());
285  meshAdaptor->setPickerId(service->getPickerId());
286  meshAdaptor->setMaterial(service->getMaterial());
287  meshAdaptor->setVtkClippingPlanes(newCollection);
288  meshAdaptor->setShowClippedPart(false);
289  meshAdaptor->setTransformId(service->getTransformId());
290 
291  meshAdaptor->start().wait();
292  meshAdaptor->updateVisibility(service->getVisibility());
293 
294  m_planeCollections.push_back(newCollection);
295  m_meshServices.push_back(meshAdaptor);
296 
297  newPlane->Delete();
298  }
299 
300  bool hasItems = !m_meshServices.empty();
301  service->setActorPropertyToUnclippedMaterial( hasItems );
302  }
303  else if ( eventId == vtkCommand::UserEvent )
304  {
305  for( ::visuVTKAdaptor::SMesh::wptr adaptor : m_meshServices )
306  {
307  if (!adaptor.expired())
308  {
309  adaptor.lock()->updateVisibility(*(bool*)data);
310  }
311  }
312  }
313  }
314 
315 protected:
316 
317  ::visuVTKAdaptor::SMesh::wptr m_service;
318 
319  vtkPlaneCollection* m_planeCollectionSrc;
320  ::fwData::Mesh::sptr m_mesh;
321 
322  std::vector< ::visuVTKAdaptor::SMesh::wptr > m_meshServices;
323 
324  std::vector< PlaneShifterCallback* > m_planeCallbacks;
325  std::vector< vtkPlaneCollection* > m_planeCollections;
326 
327  double m_factor;
328 };
329 
330 //------------------------------------------------------------------------------
331 
332 SMesh::SMesh() noexcept :
333  m_showClippedPart(true),
334  m_autoResetCamera(true),
335  m_polyData(nullptr),
336  m_mapper(vtkPolyDataMapper::New()),
337  m_actor(nullptr),
338  m_clippingPlanes(nullptr),
339  m_servicesStarterCallback(nullptr),
340  m_transform(vtkTransform::New()),
341  m_uvgen(NONE)
342 {
343  m_unclippedPartMaterial = ::fwData::Material::New();
344  m_material = ::fwData::Material::New();
345  m_unclippedPartMaterial->diffuse()->setRGBA("#aaaaff44");
346  m_clippingPlanesId = "";
347 
348  m_sigTextureApplied = newSignal<TextureAppliedSignalType>(s_TEXTURE_APPLIED_SIG);
349 
350  newSlot(s_UPDATE_VISIBILITY_SLOT, &SMesh::updateVisibility, this);
351  newSlot(s_UPDATE_POINT_COLORS_SLOT, &SMesh::updatePointColors, this);
352  newSlot(s_UPDATE_CELL_COLORS_SLOT, &SMesh::updateCellColors, this);
353  newSlot(s_UPDATE_VERTEX_SLOT, &SMesh::updateVertex, this);
354  newSlot(s_UPDATE_POINT_NORMALS_SLOT, &SMesh::updatePointNormals, this);
355  newSlot(s_UPDATE_CELL_NORMALS_SLOT, &SMesh::updateCellNormals, this);
356  newSlot(s_UPDATE_POINT_TEX_COORDS_SLOT, &SMesh::updatePointTexCoords, this);
357  newSlot(s_UPDATE_CELL_TEX_COORDS_SLOT, &SMesh::updateCellTexCoords, this);
358  newSlot(s_SHOW_POINT_COLORS_SLOT, &SMesh::showPointColors, this);
359  newSlot(s_SHOW_CELL_COLORS_SLOT, &SMesh::showCellColors, this);
360  newSlot(s_HIDE_COLORS_SLOT, &SMesh::hideColors, this);
361  newSlot(s_UPDATE_COLOR_MODE_SLOT, &SMesh::updateColorMode, this);
362  newSlot(s_UPDATE_NORMAL_MODE_SLOT, &SMesh::updateNormalMode, this);
363  newSlot(s_UPDATE_MATRIX_FIELD_SLOT, &SMesh::updateMatrixField, this);
364 }
365 
366 //------------------------------------------------------------------------------
367 
368 SMesh::~SMesh() noexcept
369 {
370  m_clippingPlanes = nullptr;
371 
372  m_mapper->Delete();
373  m_mapper = nullptr;
374 
375  m_transform->Delete();
376  m_transform = nullptr;
377 
378  if(m_actor)
379  {
380  m_actor->Delete();
381  m_actor = nullptr;
382  }
383 
384  if (m_polyData)
385  {
386  m_polyData->Delete();
387  m_polyData = nullptr;
388  }
389 }
390 
391 //------------------------------------------------------------------------------
392 
394 {
395  this->configureParams();
396 
397  const ConfigType config = this->getConfigTree().get_child("config.<xmlattr>");
398 
399  const std::string color = config.get<std::string>("color", "#ffffffff");
400  const std::string unclippedColor = config.get<std::string>("unclippedcolor", "#aaaaff44");
401 
402  m_material->diffuse()->setRGBA(color);
403 
404  m_unclippedPartMaterial->diffuse()->setRGBA(unclippedColor);
405 
406  const std::string autoresetcamera = config.get<std::string>("autoresetcamera", "yes");
407  SLM_ASSERT("'autoresetcamera' must be 'yes' or 'no'", autoresetcamera == "yes" || autoresetcamera == "no");
408  m_autoResetCamera = (autoresetcamera == "yes");
409 
410  const std::string uvGen = config.get<std::string>("uvgen", "none");
411 
412  if(uvGen == "none")
413  {
414  m_uvgen = NONE;
415  }
416  else if(uvGen == "sphere")
417  {
418  m_uvgen = SPHERE;
419  }
420  else if(uvGen == "cylinder")
421  {
422  m_uvgen = CYLINDER;
423  }
424  else if(uvGen == "plane")
425  {
426  m_uvgen = PLANE;
427  }
428  else
429  {
430  SLM_FATAL("'uvgen' value must be 'none', 'sphere', 'cylinder' or 'plane', actual: " + uvGen);
431  }
432 
433  if (config.count("texture"))
434  {
435  SLM_FATAL("'texture' is deprecated, you need to connect manually the SMesh::textureApplied signal to the "
436  "STexture::applyTexture slot.");
437  }
438 
439  if (config.count("shadingMode"))
440  {
441  const std::string shading = config.get<std::string>("shadingMode");
442  const ::fwData::Material::ShadingType shadingMode = (shading == "ambient") ? ::fwData::Material::AMBIENT :
443  (shading == "flat") ? ::fwData::Material::FLAT :
444  (shading == "gouraud") ? ::fwData::Material::GOURAUD :
445  ::fwData::Material::PHONG;
446  m_material->setShadingMode(shadingMode);
447  }
448 
449  this->setClippingPlanesId(config.get<std::string>("clippingplane", ""));
450 }
451 
452 //------------------------------------------------------------------------------
453 
455 {
456  ::fwData::Mesh::csptr mesh = this->getInput < ::fwData::Mesh >(s_MESH_INPUT);
457  SLM_ASSERT("Missing mesh", mesh);
458  this->updateMesh( mesh );
459  this->requestRender();
460 }
461 
462 //------------------------------------------------------------------------------
463 
465 {
466  this->initialize();
467 
468  this->buildPipeline();
469 
470  this->requestRender();
471 }
472 
473 //------------------------------------------------------------------------------
474 
476 {
477  this->removeAllPropFromRenderer();
478  if (this->getPicker())
479  {
480  this->removeFromPicker(m_actor);
481  }
482 
483  this->removeNormalsService();
484  this->removeServicesStarterCommand();
485 
486  this->unregisterServices();
487 
488  m_connections.disconnect();
489  this->requestRender();
490 }
491 
492 //------------------------------------------------------------------------------
493 
494 void SMesh::createTransformService()
495 {
496  ::fwData::Mesh::csptr mesh = this->getInput < ::fwData::Mesh >(s_MESH_INPUT);
497  SLM_ASSERT("Missing mesh", mesh);
498 
499  ::fwData::TransformationMatrix3D::sptr fieldTransform;
500  {
501  ::fwData::mt::ObjectReadLock lock(mesh);
502  fieldTransform = mesh->getField< ::fwData::TransformationMatrix3D >(s_MATRIX_FIELD_NAME);
503  }
504 
505  if (fieldTransform)
506  {
507  auto prevTransformService = m_transformService.lock();
508  if (prevTransformService)
509  {
510  auto trf = prevTransformService->getInOut< ::fwData::TransformationMatrix3D >(STransform::s_TM3D_INOUT);
511 
512  if (trf == fieldTransform)
513  {
514  return;
515  }
516 
517  this->unregisterService(prevTransformService);
518  m_transformService.reset();
519  m_transform->Pop();
520  }
521 
522  vtkTransform* vtkFieldTransform = vtkTransform::New();
523  vtkFieldTransform->Identity();
524 
525  // create the srv configuration for objects auto-connection
526  auto transformService = this->registerService< ::visuVTKAdaptor::STransform>( "::visuVTKAdaptor::STransform");
527  m_transformService = transformService;
528  transformService->registerInOut(fieldTransform, STransform::s_TM3D_INOUT, true);
529 
530  transformService->setRenderService( this->getRenderService() );
531  transformService->setRendererId( this->getRendererId() );
532  transformService->setTransform(vtkFieldTransform);
533  transformService->start();
534 
535  m_transform->Concatenate(vtkFieldTransform);
536  m_transform->Modified();
537  vtkFieldTransform->Delete();
538  }
539 }
540 
541 //------------------------------------------------------------------------------
542 
543 ::fwData::Material::sptr SMesh::getMaterial() const
544 {
545  return m_material;
546 }
547 
548 //------------------------------------------------------------------------------
549 
550 ::fwData::Material::sptr SMesh::getUnclippedMaterial() const
551 {
552  return m_unclippedPartMaterial;
553 }
554 
555 //------------------------------------------------------------------------------
556 
557 void SMesh::setActorPropertyToUnclippedMaterial(bool opt)
558 {
559  ::visuVTKAdaptor::SMaterial::sptr mat;
560 
561  if (opt)
562  {
563  SLM_ASSERT("Material service expired", !m_unclippedPartMaterialService.expired());
564  mat = ::visuVTKAdaptor::SMaterial::dynamicCast(m_unclippedPartMaterialService.lock());
565  }
566  else
567  {
568  SLM_ASSERT("Material service expired", !m_materialService.expired());
569  mat = ::visuVTKAdaptor::SMaterial::dynamicCast(m_materialService.lock());
570  }
571 
572  SLM_ASSERT("Invalid Material Adaptor", mat);
573 
574  m_actor->SetProperty( mat->getVtkProperty() );
575  this->setVtkPipelineModified();
576 }
577 
578 //------------------------------------------------------------------------------
579 
580 void SMesh::setShowClippedPart(bool show)
581 {
582  m_showClippedPart = show;
583 }
584 
585 //------------------------------------------------------------------------------
586 
587 void SMesh::setClippingPlanesId(::fwRenderVTK::SRender::VtkObjectIdType id)
588 {
589  m_clippingPlanesId = id;
590 }
591 
592 //------------------------------------------------------------------------------
593 
594 void SMesh::setServiceOnMaterial(::fwRenderVTK::IAdaptor::sptr& srv, ::fwData::Material::sptr material)
595 {
596  if (!srv)
597  {
598  // create the srv configuration for objects auto-connection
599  srv = this->registerService< ::fwRenderVTK::IAdaptor>("::visuVTKAdaptor::SMaterial");
600  srv->registerInput(material, SMaterial::s_MATERIAL_INPUT, true);
601 
602  srv->setRenderService(this->getRenderService());
603  srv->start();
604  srv->update();
605  }
606 }
607 
608 //------------------------------------------------------------------------------
609 
610 void SMesh::setMaterial(::fwData::Material::sptr material)
611 {
612  m_material = material;
613 }
614 
615 //------------------------------------------------------------------------------
616 
617 void SMesh::setUnclippedPartMaterial(::fwData::Material::sptr material)
618 {
619  m_unclippedPartMaterial = material;
620 }
621 
622 //------------------------------------------------------------------------------
623 
625 {
626  if (m_material->getOptionsMode() == ::fwData::Material::NORMALS)
627  {
628  this->createNormalsService();
629  }
630  else
631  {
632  this->removeNormalsService();
633  }
634 }
635 
636 //------------------------------------------------------------------------------
637 
638 void SMesh::createNormalsService()
639 {
640  if ( m_normalsService.expired() )
641  {
642  ::fwData::Mesh::csptr mesh = this->getInput < ::fwData::Mesh >(s_MESH_INPUT);
643  SLM_ASSERT("Missing mesh", mesh);
644 
645  // create the srv configuration for objects auto-connection
646  auto service = this->registerService< ::visuVTKAdaptor::SMeshNormals >("::visuVTKAdaptor::SMeshNormals");
647  service->registerInput(mesh, SMeshNormals::s_MESH_INPUT, true);
648 
649  service->setRenderService( this->getRenderService() );
650  service->setRendererId( this->getRendererId() );
651  service->setPickerId( this->getPickerId() );
652  service->setPolyData( m_polyData );
653  service->start();
654 
655  m_normalsService = service;
656  }
657 }
658 
659 //------------------------------------------------------------------------------
660 
661 void SMesh::removeNormalsService()
662 {
663  if ( !m_normalsService.expired() )
664  {
665  this->unregisterService(m_normalsService.lock());
666  m_normalsService.reset();
667  }
668 }
669 
670 //------------------------------------------------------------------------------
671 
672 void SMesh::buildPipeline()
673 {
674  ::fwData::Mesh::csptr mesh = this->getInput < ::fwData::Mesh >(s_MESH_INPUT);
675  SLM_ASSERT("Missing mesh", mesh);
676 
677  if (!m_clippingPlanesId.empty())
678  {
679  vtkObject* o = this->getVtkObject(m_clippingPlanesId);
680  vtkPlaneCollection* planes = vtkPlaneCollection::SafeDownCast(o);
681  this->setVtkClippingPlanes( planes );
682  }
683 
684  ::fwRenderVTK::IAdaptor::sptr materialService;
685  ::fwRenderVTK::IAdaptor::sptr unclippedPartMaterialService;
686 
687  this->setServiceOnMaterial(materialService, m_material);
688  this->setServiceOnMaterial(unclippedPartMaterialService, m_unclippedPartMaterial);
689 
690  m_materialService = materialService;
691  m_unclippedPartMaterialService = unclippedPartMaterialService;
692 
693  if (!m_actor)
694  {
695  m_actor = this->newActor();
696 
697  if(!this->getTransformId().empty())
698  {
699  vtkTransform* t = m_renderService.lock()->getOrAddVtkTransform(m_transformId);
700  m_transform->Concatenate(t);
701  }
702  m_actor->SetUserTransform(m_transform);
703 
704  this->createTransformService();
705 
706  this->addToRenderer(m_actor);
707  if (this->getPicker())
708  {
709  this->addToPicker(m_actor);
710  }
711  }
712 
713  this->updateMesh( mesh );
714  this->updateOptionsMode();
715 
716  this->setActorPropertyToUnclippedMaterial(false);
717 
718  this->removeServicesStarterCommand();
719 
720  if( m_clippingPlanes && m_showClippedPart )
721  {
722  this->createServicesStarterCommand();
723  }
724  this->setVtkPipelineModified();
725 }
726 
727 //------------------------------------------------------------------------------
728 
729 void SMesh::updateMesh( ::fwData::Mesh::csptr mesh )
730 {
731  if (m_polyData)
732  {
733  m_polyData->Delete();
734  m_polyData = 0;
735  }
736  m_polyData = vtkPolyData::New();
737 
738  {
739  ::fwData::mt::ObjectReadLock lock(mesh);
740  ::fwVtkIO::helper::Mesh::toVTKMesh(mesh, m_polyData);
741  }
742 
743  if(m_uvgen == SPHERE)
744  {
745  vtkSmartPointer<vtkTextureMapToSphere> texCoord = vtkSmartPointer<vtkTextureMapToSphere>::New();
746  texCoord->SetInputData(m_polyData);
747  m_mapper->SetInputConnection(texCoord->GetOutputPort());
748  }
749  else if(m_uvgen == CYLINDER)
750  {
751  vtkSmartPointer<vtkTextureMapToCylinder> texCoord = vtkSmartPointer<vtkTextureMapToCylinder>::New();
752  texCoord->SetInputData(m_polyData);
753  m_mapper->SetInputConnection(texCoord->GetOutputPort());
754  }
755  else if(m_uvgen == PLANE)
756  {
757  vtkSmartPointer<vtkTextureMapToPlane> texCoord = vtkSmartPointer<vtkTextureMapToPlane>::New();
758  texCoord->SetInputData(m_polyData);
759  m_mapper->SetInputConnection(texCoord->GetOutputPort());
760  }
761  else
762  {
763  m_mapper->SetInputData(m_polyData);
764  }
765 
766  ::fwData::Material::sptr material = this->getMaterial();
767  SLM_ASSERT("Missing material", material);
768  m_sigTextureApplied->asyncEmit(material);
769 
770  if (m_autoResetCamera)
771  {
772  this->getRenderer()->ResetCamera();
773  }
774  this->setVtkPipelineModified();
775 }
776 
777 //------------------------------------------------------------------------------
778 
779 vtkActor* SMesh::newActor()
780 {
781  vtkActor* actor = vtkActor::New();
782 
783  m_mapper->SetInputData(m_polyData);
784 
785  if (m_clippingPlanes)
786  {
787  m_mapper->SetClippingPlanes(m_clippingPlanes);
788  }
789 
790  actor->SetMapper(m_mapper);
791  this->setVtkPipelineModified();
792  return actor;
793 }
794 
795 //------------------------------------------------------------------------------
796 
797 void SMesh::updateVisibility( bool isVisible)
798 {
799  if (m_actor)
800  {
801  m_actor->SetVisibility( isVisible );
802  }
803 
804  if (m_servicesStarterCallback)
805  {
806  m_servicesStarterCallback->Execute(0, vtkCommand::UserEvent, &isVisible);
807  }
808  this->setVtkPipelineModified();
809  this->requestRender();
810 }
811 
812 //------------------------------------------------------------------------------
813 
814 bool SMesh::getVisibility() const
815 {
816  bool visible = false;
817  if (m_actor)
818  {
819  visible = m_actor->GetVisibility() == 1;
820  }
821  return visible;
822 }
823 
824 //------------------------------------------------------------------------------
825 
826 void SMesh::setVtkClippingPlanes(vtkPlaneCollection* planes)
827 {
828  m_clippingPlanes = planes;
829 }
830 
831 //------------------------------------------------------------------------------
832 
833 void SMesh::createServicesStarterCommand()
834 {
835  if(!m_servicesStarterCallback)
836  {
837  ::visuVTKAdaptor::SMesh::sptr srv = ::visuVTKAdaptor::SMesh::dynamicCast(this->getSptr());
838  m_servicesStarterCallback = PlaneCollectionAdaptorStarter::New( srv, m_clippingPlanes, -1. );
839  }
840 }
841 
842 //------------------------------------------------------------------------------
843 
844 void SMesh::removeServicesStarterCommand()
845 {
846  if(m_servicesStarterCallback)
847  {
848  m_servicesStarterCallback->Stop();
849  m_servicesStarterCallback->Delete();
850  m_servicesStarterCallback = 0;
851  }
852 }
853 
854 //------------------------------------------------------------------------------
855 
856 void SMesh::setAutoResetCamera(bool autoResetCamera)
857 {
858  m_autoResetCamera = autoResetCamera;
859 }
860 
861 //------------------------------------------------------------------------------
862 
864 {
865  KeyConnectionsMap connections;
866  connections.push( s_MESH_INPUT, ::fwData::Mesh::s_MODIFIED_SIG, s_UPDATE_SLOT );
867  connections.push( s_MESH_INPUT, ::fwData::Mesh::s_POINT_COLORS_MODIFIED_SIG, s_UPDATE_POINT_COLORS_SLOT );
868  connections.push( s_MESH_INPUT, ::fwData::Mesh::s_CELL_COLORS_MODIFIED_SIG, s_UPDATE_CELL_COLORS_SLOT);
869  connections.push( s_MESH_INPUT, ::fwData::Mesh::s_VERTEX_MODIFIED_SIG, s_UPDATE_VERTEX_SLOT);
870  connections.push( s_MESH_INPUT, ::fwData::Mesh::s_POINT_NORMALS_MODIFIED_SIG, s_UPDATE_POINT_NORMALS_SLOT);
871  connections.push( s_MESH_INPUT, ::fwData::Mesh::s_CELL_NORMALS_MODIFIED_SIG, s_UPDATE_CELL_NORMALS_SLOT);
872  connections.push( s_MESH_INPUT, ::fwData::Mesh::s_POINT_TEX_COORDS_MODIFIED_SIG, s_UPDATE_POINT_TEX_COORDS_SLOT);
873  connections.push( s_MESH_INPUT, ::fwData::Mesh::s_CELL_TEX_COORDS_MODIFIED_SIG, s_UPDATE_CELL_TEX_COORDS_SLOT);
874  connections.push( s_MESH_INPUT, ::fwData::Mesh::s_ADDED_FIELDS_SIG, s_UPDATE_MATRIX_FIELD_SLOT);
875  connections.push( s_MESH_INPUT, ::fwData::Mesh::s_REMOVED_FIELDS_SIG, s_UPDATE_MATRIX_FIELD_SLOT);
876  connections.push( s_MESH_INPUT, ::fwData::Mesh::s_CHANGED_FIELDS_SIG, s_UPDATE_MATRIX_FIELD_SLOT);
877 
878  return connections;
879 }
880 
881 //------------------------------------------------------------------------------
882 
884 {
885  ::fwData::Mesh::csptr mesh = this->getInput < ::fwData::Mesh >(s_MESH_INPUT);
886  SLM_ASSERT("Missing mesh", mesh);
887  SLM_ASSERT("m_polyData not instanced", m_polyData);
888 
889  ::fwData::mt::ObjectReadLock lock(mesh);
891  this->setVtkPipelineModified();
892  this->requestRender();
893 }
894 
895 //------------------------------------------------------------------------------
896 
898 {
899  ::fwData::Mesh::csptr mesh = this->getInput < ::fwData::Mesh >(s_MESH_INPUT);
900  SLM_ASSERT("Missing mesh", mesh);
901  SLM_ASSERT("m_polyData not instanced", m_polyData);
902 
903  ::fwData::mt::ObjectReadLock lock(mesh);
905  this->setVtkPipelineModified();
906  this->requestRender();
907 }
908 
909 //------------------------------------------------------------------------------
910 
912 {
913  ::fwData::Mesh::csptr mesh = this->getInput < ::fwData::Mesh >(s_MESH_INPUT);
914  SLM_ASSERT("Missing mesh", mesh);
915  SLM_ASSERT("m_polyData not instanced", m_polyData);
916 
917  ::fwData::mt::ObjectReadLock lock(mesh);
919 
920  if (m_autoResetCamera)
921  {
922  this->getRenderer()->ResetCamera();
923  }
924  this->setVtkPipelineModified();
925  this->requestRender();
926 }
927 
928 //------------------------------------------------------------------------------
929 
931 {
932  ::fwData::Mesh::csptr mesh = this->getInput < ::fwData::Mesh >(s_MESH_INPUT);
933  SLM_ASSERT("Missing mesh", mesh);
934  ::fwData::mt::ObjectReadLock lock(mesh);
936  this->setVtkPipelineModified();
937  this->requestRender();
938 }
939 
940 //------------------------------------------------------------------------------
941 
943 {
944  ::fwData::Mesh::csptr mesh = this->getInput < ::fwData::Mesh >(s_MESH_INPUT);
945  SLM_ASSERT("Missing mesh", mesh);
946  ::fwData::mt::ObjectReadLock lock(mesh);
948  this->setVtkPipelineModified();
949  this->requestRender();
950 }
951 
952 //------------------------------------------------------------------------------
953 
955 {
956  ::fwData::Mesh::csptr mesh = this->getInput < ::fwData::Mesh >(s_MESH_INPUT);
957  SLM_ASSERT("Missing mesh", mesh);
958  ::fwData::mt::ObjectReadLock lock(mesh);
960  this->setVtkPipelineModified();
961  this->requestRender();
962 }
963 
964 //------------------------------------------------------------------------------
965 
967 {
968  ::fwData::Mesh::csptr mesh = this->getInput < ::fwData::Mesh >(s_MESH_INPUT);
969  SLM_ASSERT("Missing mesh", mesh);
970  ::fwData::mt::ObjectReadLock lock(mesh);
972  this->setVtkPipelineModified();
973  this->requestRender();
974 }
975 
976 //------------------------------------------------------------------------------
977 
979 {
980  m_mapper->ScalarVisibilityOn();
981  m_mapper->SetScalarModeToUsePointData();
982  this->setVtkPipelineModified();
983  this->requestRender();
984 }
985 
986 //------------------------------------------------------------------------------
987 
989 {
990  m_mapper->ScalarVisibilityOn();
991  m_mapper->SetScalarModeToUseCellData();
992  this->setVtkPipelineModified();
993  this->requestRender();
994 }
995 
996 //------------------------------------------------------------------------------
997 
999 {
1000  m_mapper->ScalarVisibilityOff();
1001  this->setVtkPipelineModified();
1002  this->requestRender();
1003 }
1004 
1005 //------------------------------------------------------------------------------
1006 
1007 void SMesh::updateColorMode(std::uint8_t mode)
1008 {
1009  switch (mode)
1010  {
1011  case 0:
1012  {
1013  this->hideColors();
1014  break;
1015  }
1016  case 1:
1017  {
1018  this->showPointColors();
1019  break;
1020  }
1021  case 2:
1022  {
1023  this->showCellColors();
1024  break;
1025  }
1026  default:
1027  {
1028  OSLM_ERROR("mode " << mode << " is not allowed");
1029  break;
1030  }
1031  }
1032 }
1033 
1034 //------------------------------------------------------------------------------
1035 
1036 void SMesh::updateNormalMode(std::uint8_t mode)
1037 {
1038  this->updateOptionsMode();
1039  if (!m_normalsService.expired())
1040  {
1041  ::visuVTKAdaptor::SMeshNormals::sptr normalsAdaptor =
1042  ::visuVTKAdaptor::SMeshNormals::dynamicCast(m_normalsService.lock());
1043  normalsAdaptor->updateNormalMode(mode);
1044  }
1045 }
1046 
1047 //------------------------------------------------------------------------------
1048 
1050 {
1051  if (fields.find(s_MATRIX_FIELD_NAME) != fields.end())
1052  {
1053  this->createTransformService();
1054  }
1055 }
1056 
1057 //------------------------------------------------------------------------------
1058 
1059 } //namespace visuVTKAdaptor
static FWVTKIO_API void updatePolyDataPointColor(vtkSmartPointer< vtkPolyData > polyDataDst, const ::fwData::Mesh::csptr &meshSrc)
Update a vtkPolyData with point color of fwData::Mesh.
static VISUVTKADAPTOR_APIconst::fwCom::Slots::SlotKeyType s_SHOW_POINT_COLORS_SLOT
Slot: update mesh visibility (true = visible)
Definition: SMesh.hpp:119
This class is a helper to define the connections of a service and its data.
Definition: IService.hpp:454
void showCellColors()
Slot: used to show cell colors.
Definition: SMesh.cpp:988
void updateColorMode(std::uint8_t mode)
Slot: used to update color mode (0: none, 1: point, 2: cell)
Definition: SMesh.cpp:1007
void hideColors()
Slot: used to hide colors.
Definition: SMesh.cpp:998
static VISUVTKADAPTOR_APIconst::fwCom::Slots::SlotKeyType s_UPDATE_VISIBILITY_SLOT
Slot: update mesh visibility (true = visible)
Definition: SMesh.hpp:111
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_POINT_NORMALS_MODIFIED_SIG
Key in m_signals map of signal m_sigPointNormalsModified.
The namespace visuVTKAdaptor contains the list of adaptors available for the generic scene...
static FWVTKIO_API void toVTKMesh(const ::fwData::Mesh::csptr &_mesh, vtkSmartPointer< vtkPolyData > _polyData)
Convert a ::fwData::Mesh::csptr to a vtkPolyData.
void updatePointTexCoords()
Slot: used to update point tex coords.
Definition: SMesh.cpp:954
static VISUVTKADAPTOR_APIconst::fwCom::Slots::SlotKeyType s_UPDATE_MATRIX_FIELD_SLOT
Slot: update mesh visibility (true = visible)
Definition: SMesh.hpp:124
void updateCellColors()
Slot: used to update cell colors.
Definition: SMesh.cpp:897
A helper to lock object on read mode.
VISUVTKADAPTOR_API void configuring() override
Configure the service before starting. Apply the configuration to service.
Definition: SMesh.cpp:393
static VISUVTKADAPTOR_APIconst::fwCom::Slots::SlotKeyType s_SHOW_CELL_COLORS_SLOT
Slot: update mesh visibility (true = visible)
Definition: SMesh.hpp:120
static VISUVTKADAPTOR_APIconst::fwCom::Slots::SlotKeyType s_UPDATE_COLOR_MODE_SLOT
Slot: update mesh visibility (true = visible)
Definition: SMesh.hpp:122
static FWVTKIO_API void updatePolyDataPoints(vtkSmartPointer< vtkPolyData > polyDataDst, const ::fwData::Mesh::csptr &meshSrc)
Update a vtkPolyData with ::fwData::Mesh::sptr points.
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_CELL_COLORS_MODIFIED_SIG
Key in m_signals map of signal m_sigCellColorsModified.
static VISUVTKADAPTOR_APIconst::fwCom::Slots::SlotKeyType s_UPDATE_CELL_TEX_COORDS_SLOT
Slot: update mesh visibility (true = visible)
Definition: SMesh.hpp:118
void updateMatrixField(::fwData::Object::FieldsContainerType fields)
Slot: update the matrix service if the &#39;TransformMatrix&#39; field changed.
Definition: SMesh.cpp:1049
Display a fwData::Mesh in the generic scene.
Definition: SMesh.hpp:88
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_CHANGED_FIELDS_SIG
Type of signal m_sigModified.
void updateCellNormals()
Slot: used to update cell normals.
Definition: SMesh.cpp:942
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_CELL_NORMALS_MODIFIED_SIG
Key in m_signals map of signal m_sigCellNormalsModified.
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_ADDED_FIELDS_SIG
Type of signal m_sigModified.
Used to store object configuration in a service.
Definition: IService.hpp:90
void showPointColors()
Slot: used to show point colors.
Definition: SMesh.cpp:978
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_POINT_TEX_COORDS_MODIFIED_SIG
Key in m_signals map of signal m_sigPointTexCoorddModified.
std::map< std::string,::fwData::Object::sptr > FieldsContainerType
Type of signal m_sigModified.
static VISUVTKADAPTOR_APIconst::fwCom::Slots::SlotKeyType s_UPDATE_NORMAL_MODE_SLOT
Slot: update mesh visibility (true = visible)
Definition: SMesh.hpp:123
virtual VISUVTKADAPTOR_API KeyConnectionsMap getAutoConnections() const override
Returns proposals to connect service slots to associated object signals, this method is used for obj/...
Definition: SMesh.cpp:863
VISUVTKADAPTOR_API void updating() override
Perform some computations according to object (this service is attached to) attribute values and its ...
Definition: SMesh.cpp:454
static VISUVTKADAPTOR_APIconst::fwCom::Slots::SlotKeyType s_UPDATE_VERTEX_SLOT
Slot: update mesh visibility (true = visible)
Definition: SMesh.hpp:114
static VISUVTKADAPTOR_APIconst::fwCom::Slots::SlotKeyType s_UPDATE_POINT_NORMALS_SLOT
Slot: update mesh visibility (true = visible)
Definition: SMesh.hpp:115
#define SLM_FATAL(message)
Definition: spyLog.hpp:283
#define OSLM_ERROR(message)
Definition: spyLog.hpp:274
static FWVTKIO_API void updatePolyDataCellColor(vtkSmartPointer< vtkPolyData > polyDataDst, const ::fwData::Mesh::csptr &meshSrc)
Update a vtkPolyData with cell color of fwData::Mesh.
static VISUVTKADAPTOR_APIconst::fwCom::Slots::SlotKeyType s_UPDATE_CELL_NORMALS_SLOT
Slot: update mesh visibility (true = visible)
Definition: SMesh.hpp:116
void updateCellTexCoords()
Slot: used to update cell tex coords.
Definition: SMesh.cpp:966
#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
This class represents a 3D transformation matrix (4x4).
static VISUVTKADAPTOR_APIconst::fwCom::Slots::SlotKeyType s_UPDATE_CELL_COLORS_SLOT
Slot: update mesh visibility (true = visible)
Definition: SMesh.hpp:113
static FWVTKIO_API void updatePolyDataCellTexCoords(vtkSmartPointer< vtkPolyData > polyDataDst, const ::fwData::Mesh::csptr &meshSrc)
Update a vtkPolyData with cell texCoords of fwData::Mesh.
void updatePointNormals()
Slot: used to update point normals.
Definition: SMesh.cpp:930
static FWVTKIO_API void updatePolyDataCellNormals(vtkSmartPointer< vtkPolyData > polyDataDst, const ::fwData::Mesh::csptr &meshSrc)
Update a vtkPolyData with cell normals of fwData::Mesh.
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_CELL_TEX_COORDS_MODIFIED_SIG
Key in m_signals map of signal m_sigCellTexCoorddModified.
VISUVTKADAPTOR_API void setAutoResetCamera(bool autoResetCamera)
Active/Inactive automatic reset on camera. By default =true.
Definition: SMesh.cpp:856
void updateVertex()
Slot: used to update mesh vertex.
Definition: SMesh.cpp:911
VISUVTKADAPTOR_API void updateVisibility(bool isVisible)
Slot: update mesh visibility (true = visible)
Definition: SMesh.cpp:797
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_VERTEX_MODIFIED_SIG
Key in m_signals map of signal m_sigVertexModified.
static VISUVTKADAPTOR_APIconst::fwCom::Slots::SlotKeyType s_HIDE_COLORS_SLOT
Slot: update mesh visibility (true = visible)
Definition: SMesh.hpp:121
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_MODIFIED_SIG
Key in m_signals map of signal m_sigModified.
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_REMOVED_FIELDS_SIG
Type of signal m_sigModified.
static FWVTKIO_API void updatePolyDataPointNormals(vtkSmartPointer< vtkPolyData > polyDataDst, const ::fwData::Mesh::csptr &meshSrc)
Update a vtkPolyData with point normals of fwData::Mesh.
VISUVTKADAPTOR_API void updateOptionsMode()
Creates normals adaptor if material has NORMALS, else remove normals adaptor.
Definition: SMesh.cpp:624
VISUVTKADAPTOR_API void stopping() override
Uninitialize the service activity. The stop() method is always invoked before destroying a service...
Definition: SMesh.cpp:475
static FWSERVICES_API ServiceFactory::sptr getDefault()
Return the unique Instance, create it if required at first access.
static FWVTKIO_API void updatePolyDataPointTexCoords(vtkSmartPointer< vtkPolyData > polyDataDst, const ::fwData::Mesh::csptr &meshSrc)
Update a vtkPolyData with point texCoords of fwData::Mesh.
void updatePointColors()
Slot: used to update point colors.
Definition: SMesh.cpp:883
Data holding a geometric structure composed of points, lines, triangles, quads or polygons...
static VISUVTKADAPTOR_APIconst::fwCom::Slots::SlotKeyType s_UPDATE_POINT_TEX_COORDS_SLOT
Slot: update mesh visibility (true = visible)
Definition: SMesh.hpp:117
static VISUVTKADAPTOR_APIconst::fwCom::Slots::SlotKeyType s_UPDATE_POINT_COLORS_SLOT
Slot: update mesh visibility (true = visible)
Definition: SMesh.hpp:112
Used to store a service configuration.
Definition: IService.hpp:100
VISUVTKADAPTOR_API void updateNormalMode(std::uint8_t mode)
Used to update normal mode (0: none, 1: point, 2: cell)
Definition: SMesh.cpp:1036
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_POINT_COLORS_MODIFIED_SIG
Key in m_signals map of signal m_sigPointColorsModified.
VISUVTKADAPTOR_API void starting() override
Initialize the service activity.
Definition: SMesh.cpp:464