fw4spl
SVTKMesher.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 "opVTKMesh/SVTKMesher.hpp"
8 
9 #include <fwCom/Signal.hpp>
10 #include <fwCom/Signal.hxx>
11 #include <fwCom/Signals.hpp>
12 
13 #include <fwData/Mesh.hpp>
14 #include <fwData/Reconstruction.hpp>
15 
16 #include <fwMedData/ImageSeries.hpp>
17 #include <fwMedData/ModelSeries.hpp>
18 
19 #include <fwServices/macros.hpp>
20 
21 #include <fwTools/fwID.hpp>
22 
23 #include <fwVtkIO/helper/Mesh.hpp>
24 #include <fwVtkIO/vtk.hpp>
25 
26 #include <vtkDecimatePro.h>
27 #include <vtkDiscreteMarchingCubes.h>
28 #include <vtkImageData.h>
29 #include <vtkPolyDataMapper.h>
30 #include <vtkSmartPointer.h>
31 #include <vtkWindowedSincPolyDataFilter.h>
32 
33 namespace opVTKMesh
34 {
35 
36 //-----------------------------------------------------------------------------
37 
38 fwServicesRegisterMacro( ::fwServices::IOperator, ::opVTKMesh::SVTKMesher );
39 
40 static const std::string s_IMAGE_INPUT = "imageSeries";
41 static const std::string s_MODEL_OUTPUT = "modelSeries";
42 
43 //-----------------------------------------------------------------------------
44 
45 SVTKMesher::SVTKMesher() noexcept :
46  m_reduction(0)
47 {
48 }
49 
50 //-----------------------------------------------------------------------------
51 
52 SVTKMesher::~SVTKMesher() noexcept
53 {
54 }
55 
56 //-----------------------------------------------------------------------------
57 
59 {
60 }
61 
62 //-----------------------------------------------------------------------------
63 
65 {
66 }
67 
68 //-----------------------------------------------------------------------------
69 
71 {
72  const ::fwServices::IService::ConfigType& srvConfig = this->getConfigTree();
73 
74  SLM_ASSERT("You must have one <config/> element.", srvConfig.count("config") == 1 );
75 
76  const ::fwServices::IService::ConfigType& config = srvConfig.get_child("config");
77 
78  SLM_ASSERT("You must have one <percentReduction/> element.", config.count("percentReduction") == 1);
79  const ::fwServices::IService::ConfigType& reductionCfg = config.get_child("percentReduction");
80  m_reduction = reductionCfg.get_value<unsigned int>();
81 }
82 
83 //-----------------------------------------------------------------------------
84 
86 {
87  ::fwMedData::ImageSeries::csptr imageSeries = this->getInput< ::fwMedData::ImageSeries >(s_IMAGE_INPUT);
88  ::fwMedData::ModelSeries::sptr modelSeries = ::fwMedData::ModelSeries::New();
89 
90  ::fwData::Object::DeepCopyCacheType cache;
91  modelSeries->::fwMedData::Series::cachedDeepCopy(imageSeries, cache);
92 
93  // vtk img
94  vtkSmartPointer< vtkImageData > vtkImage = vtkSmartPointer< vtkImageData >::New();
95  ::fwVtkIO::toVTKImage( imageSeries->getImage(), vtkImage );
96 
97  // contour filter
98  vtkSmartPointer< vtkDiscreteMarchingCubes > contourFilter = vtkSmartPointer< vtkDiscreteMarchingCubes >::New();
99  contourFilter->SetInputData(vtkImage);
100  contourFilter->SetValue(0, 255);
101  contourFilter->ComputeScalarsOn();
102  contourFilter->ComputeNormalsOn();
103  contourFilter->Update();
104 
105  // smooth filter
106  vtkSmartPointer< vtkWindowedSincPolyDataFilter > smoothFilter =
107  vtkSmartPointer< vtkWindowedSincPolyDataFilter >::New();
108  smoothFilter->SetInputConnection(contourFilter->GetOutputPort());
109  smoothFilter->SetNumberOfIterations( 50 );
110  smoothFilter->BoundarySmoothingOn();
111  smoothFilter->SetPassBand( 0.1 );
112  smoothFilter->SetFeatureAngle(120.0);
113  smoothFilter->SetEdgeAngle(90);
114  smoothFilter->FeatureEdgeSmoothingOn();
115  smoothFilter->Update();
116 
117  // Get polyData
118  vtkSmartPointer< vtkPolyData > polyData;
119  ::fwData::Mesh::sptr mesh = ::fwData::Mesh::New();
120 
121  // decimate filter
122  if( m_reduction > 0 )
123  {
124  vtkSmartPointer< vtkDecimatePro > decimate = vtkSmartPointer< vtkDecimatePro >::New();
125  decimate->SetInputConnection( smoothFilter->GetOutputPort() );
126  decimate->SetTargetReduction( m_reduction/100.0 );
127  decimate->PreserveTopologyOff();
128  decimate->SplittingOn();
129  decimate->BoundaryVertexDeletionOn();
130  decimate->SetSplitAngle( 120 );
131  decimate->Update();
132  polyData = decimate->GetOutput();
133  OSLM_TRACE("final GetNumberOfCells = " << polyData->GetNumberOfCells());
134  ::fwVtkIO::helper::Mesh::fromVTKMesh( polyData, mesh);
135  }
136  else
137  {
138  polyData = smoothFilter->GetOutput();
139  OSLM_TRACE("final GetNumberOfCells = " << polyData->GetNumberOfCells());
140  ::fwVtkIO::helper::Mesh::fromVTKMesh( polyData, mesh);
141  }
142 
143  ::fwData::Reconstruction::sptr reconstruction = ::fwData::Reconstruction::New();
144 
145  static unsigned int organNumber = 0;
146  ++organNumber;
147  reconstruction->setOrganName("OrganMesher_VTK_" + std::to_string(organNumber));
148  reconstruction->setStructureType("OrganType");
149  reconstruction->setIsVisible(true);
150  // Set Mesh
151  reconstruction->setMesh(mesh);
152 
153  ::fwMedData::ModelSeries::ReconstructionVectorType recs = modelSeries->getReconstructionDB();
154  recs.push_back(reconstruction);
155  modelSeries->setReconstructionDB(recs);
156  modelSeries->setDicomReference(imageSeries->getDicomReference());
157 
158  this->setOutput(s_MODEL_OUTPUT, modelSeries);
159 }
160 
161 //-----------------------------------------------------------------------------
162 
163 }
virtual OPVTKMESH_API void updating() override
Perform some computations according to object (this service is attached to) attribute values and its ...
Definition: SVTKMesher.cpp:85
The namespace opVTKMesh contains an implementation of a VTK mesher.
virtual OPVTKMESH_API void configuring() override
Configure the service before starting. Apply the configuration to service.
Definition: SVTKMesher.cpp:70
#define OSLM_TRACE(message)
Definition: spyLog.hpp:230
virtual OPVTKMESH_API void starting() override
Initialize the service activity.
Definition: SVTKMesher.cpp:58
FWSERVICES_API void setOutput(const ::fwServices::IService::KeyType &key, const ::fwData::Object::sptr &object, size_t index=0)
Register an output object at a given key in the OSR, replacing it if it already exists.
Definition: IService.cpp:80
This service generates meshes from an ImageSeries using VTK library.
Definition: SVTKMesher.hpp:40
#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 interface defines operator service API.
Definition: IOperator.hpp:25
virtual OPVTKMESH_API void stopping() override
Uninitialize the service activity. The stop() method is always invoked before destroying a service...
Definition: SVTKMesher.cpp:64
static FWVTKIO_API void fromVTKMesh(vtkSmartPointer< vtkPolyData > _polyData,::fwData::Mesh::sptr _mesh)
Convert a vtkPolyData to a ::fwData::Mesh::sptr.
FWSERVICES_API ConfigType getConfigTree() const
Return the configuration, in an boost property tree.
Definition: IService.cpp:247