7 #include "opVTKMesh/SVTKMesher.hpp" 9 #include <fwCom/Signal.hpp> 10 #include <fwCom/Signal.hxx> 11 #include <fwCom/Signals.hpp> 13 #include <fwData/Mesh.hpp> 14 #include <fwData/Reconstruction.hpp> 16 #include <fwMedData/ImageSeries.hpp> 17 #include <fwMedData/ModelSeries.hpp> 19 #include <fwServices/macros.hpp> 21 #include <fwTools/fwID.hpp> 23 #include <fwVtkIO/helper/Mesh.hpp> 24 #include <fwVtkIO/vtk.hpp> 26 #include <vtkDecimatePro.h> 27 #include <vtkDiscreteMarchingCubes.h> 28 #include <vtkImageData.h> 29 #include <vtkPolyDataMapper.h> 30 #include <vtkSmartPointer.h> 31 #include <vtkWindowedSincPolyDataFilter.h> 40 static const std::string s_IMAGE_INPUT =
"imageSeries";
41 static const std::string s_MODEL_OUTPUT =
"modelSeries";
45 SVTKMesher::SVTKMesher() noexcept :
52 SVTKMesher::~SVTKMesher() noexcept
72 const ::fwServices::IService::ConfigType& srvConfig = this->
getConfigTree();
74 SLM_ASSERT(
"You must have one <config/> element.", srvConfig.count(
"config") == 1 );
76 const ::fwServices::IService::ConfigType& config = srvConfig.get_child(
"config");
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>();
87 ::fwMedData::ImageSeries::csptr imageSeries = this->getInput< ::fwMedData::ImageSeries >(s_IMAGE_INPUT);
88 ::fwMedData::ModelSeries::sptr modelSeries = ::fwMedData::ModelSeries::New();
90 ::fwData::Object::DeepCopyCacheType cache;
91 modelSeries->::fwMedData::Series::cachedDeepCopy(imageSeries, cache);
94 vtkSmartPointer< vtkImageData > vtkImage = vtkSmartPointer< vtkImageData >::New();
95 ::fwVtkIO::toVTKImage( imageSeries->getImage(), vtkImage );
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();
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();
118 vtkSmartPointer< vtkPolyData > polyData;
119 ::fwData::Mesh::sptr mesh = ::fwData::Mesh::New();
122 if( m_reduction > 0 )
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 );
132 polyData = decimate->GetOutput();
133 OSLM_TRACE(
"final GetNumberOfCells = " << polyData->GetNumberOfCells());
138 polyData = smoothFilter->GetOutput();
139 OSLM_TRACE(
"final GetNumberOfCells = " << polyData->GetNumberOfCells());
143 ::fwData::Reconstruction::sptr reconstruction = ::fwData::Reconstruction::New();
145 static unsigned int organNumber = 0;
147 reconstruction->setOrganName(
"OrganMesher_VTK_" + std::to_string(organNumber));
148 reconstruction->setStructureType(
"OrganType");
149 reconstruction->setIsVisible(
true);
151 reconstruction->setMesh(mesh);
153 ::fwMedData::ModelSeries::ReconstructionVectorType recs = modelSeries->getReconstructionDB();
154 recs.push_back(reconstruction);
155 modelSeries->setReconstructionDB(recs);
156 modelSeries->setDicomReference(imageSeries->getDicomReference());
158 this->
setOutput(s_MODEL_OUTPUT, modelSeries);
virtual OPVTKMESH_API void updating() override
Perform some computations according to object (this service is attached to) attribute values and its ...
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.
#define OSLM_TRACE(message)
virtual OPVTKMESH_API void starting() override
Initialize the service activity.
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.
This service generates meshes from an ImageSeries using VTK library.
#define SLM_ASSERT(message, cond)
work like 'assert' from 'cassert', with in addition a message logged by spylog (with FATAL loglevel) ...
This interface defines operator service API.
virtual OPVTKMESH_API void stopping() override
Uninitialize the service activity. The stop() method is always invoked before destroying a service...
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.