1 #include <tclap/CmdLine.h> 3 #include <vtkContourFilter.h> 4 #include <vtkDecimatePro.h> 5 #include <vtkSmoothPolyDataFilter.h> 6 #include <vtkXMLPolyDataWriter.h> 7 #include <vtkPolyDataWriter.h> 8 #include <vtkPolyData.h> 10 #include <itkImageToVTKImageFilter.h> 13 int main(
int argc,
char **argv)
15 TCLAP::CmdLine cmd(
"Performs isosurface extraction followed by mesh decimation and surface smoothing. INRIA / IRISA - VisAGeS/Empenn Team",
' ',ANIMA_VERSION);
17 TCLAP::ValueArg<std::string> inArg(
"i",
"input",
"Input binary image",
true,
"",
"input binary image",cmd);
18 TCLAP::ValueArg<std::string> outArg(
"o",
"output",
"Output surface (.vtk or .vtp)",
true,
"",
"output surface",cmd);
20 TCLAP::SwitchArg preSmoothArg(
"P",
"pre-smooth",
"Smoothes also before decimation", cmd,
false);
21 TCLAP::ValueArg<double> thrArg(
"t",
"thr",
"Threshold for isosurface generation (default: 0.5)",
false,0.5,
"generation threshold",cmd);
22 TCLAP::ValueArg<double> smoothIntensityArg(
"s",
"smooth",
"Smoothing intensity (default: 0.2)",
false,0.2,
"smoothing intensity",cmd);
23 TCLAP::ValueArg<unsigned int> smoothIterArg(
"I",
"iter",
"Number of smoothing iterations (default: 50)",
false,50,
"smoothing iterations",cmd);
24 TCLAP::ValueArg<double> decimateArg(
"d",
"dec",
"Fraction of surface point to decimate (default: 0.75)",
false,0.75,
"deicimation fraction",cmd);
30 catch (TCLAP::ArgException& e)
32 std::cerr <<
"Error: " << e.error() <<
"for argument " << e.argId() << std::endl;
36 typedef itk::Image <double,3> ImageType;
37 ImageType::Pointer inputImage = anima::readImage <ImageType> (inArg.getValue());
39 typedef itk::ImageToVTKImageFilter <ImageType> GlueFilterType;
40 GlueFilterType::Pointer glueFilter = GlueFilterType::New();
42 glueFilter->SetInput(inputImage);
45 vtkSmartPointer <vtkContourFilter> contourExtractor = vtkContourFilter::New();
46 contourExtractor->SetInputData(glueFilter->GetOutput());
47 contourExtractor->SetValue(0,thrArg.getValue());
48 contourExtractor->ComputeGradientsOff();
49 contourExtractor->ComputeNormalsOff();
50 contourExtractor->ComputeScalarsOff();
52 vtkSmartPointer <vtkDecimatePro> decimateFilter = vtkDecimatePro::New();
53 if (preSmoothArg.isSet())
55 vtkSmartPointer <vtkSmoothPolyDataFilter> smoothFilterPre = vtkSmoothPolyDataFilter::New();
56 smoothFilterPre->SetInputConnection(contourExtractor->GetOutputPort());
57 smoothFilterPre->SetFeatureAngle(90);
58 smoothFilterPre->SetNumberOfIterations(smoothIterArg.getValue());
59 smoothFilterPre->SetRelaxationFactor(smoothIntensityArg.getValue());
61 decimateFilter->SetInputConnection(smoothFilterPre->GetOutputPort());
64 decimateFilter->SetInputConnection(contourExtractor->GetOutputPort());
66 decimateFilter->SetTargetReduction(decimateArg.getValue());
67 decimateFilter->PreserveTopologyOn();
69 vtkSmartPointer <vtkSmoothPolyDataFilter> smoothFilter = vtkSmoothPolyDataFilter::New();
70 smoothFilter->SetInputConnection(decimateFilter->GetOutputPort());
71 smoothFilter->SetFeatureAngle(90);
72 smoothFilter->SetNumberOfIterations(smoothIterArg.getValue());
73 smoothFilter->SetRelaxationFactor(smoothIntensityArg.getValue());
75 smoothFilter->Update();
77 vtkSmartPointer <vtkPolyData> outputSurface = smoothFilter->GetOutput();
78 itk::ContinuousIndex <double, 3> currentIndex;
79 double currentPoint[3];
80 typedef ImageType::PointType PointType;
81 typedef ImageType::SpacingType SpacingType;
82 PointType outputPoint;
83 PointType origin = inputImage->GetOrigin();
84 SpacingType spacing = inputImage->GetSpacing();
86 for (
unsigned int i = 0;i < outputSurface->GetNumberOfPoints();++i)
88 outputSurface->GetPoint(i,currentPoint);
89 for (
unsigned int j = 0;j < 3;++j)
90 currentIndex[j] = (currentPoint[j] - origin[j]) / spacing[j];
92 inputImage->TransformContinuousIndexToPhysicalPoint(currentIndex,outputPoint);
94 for (
unsigned int j = 0;j < 3;++j)
95 currentPoint[j] = outputPoint[j];
97 outputSurface->GetPoints()->SetPoint(i,currentPoint);
100 if (outArg.getValue().find(
".vtk") != std::string::npos)
102 vtkSmartPointer <vtkPolyDataWriter> legacyWriter = vtkPolyDataWriter::New();
103 legacyWriter->SetInputData(outputSurface);
104 legacyWriter->SetFileName(outArg.getValue().c_str());
106 legacyWriter->Update();
110 vtkSmartPointer <vtkXMLPolyDataWriter> vtkWriter = vtkXMLPolyDataWriter::New();
111 vtkWriter->SetInputData(outputSurface);
112 vtkWriter->SetFileName(outArg.getValue().c_str());
113 vtkWriter->SetDataModeToBinary();
114 vtkWriter->EncodeAppendedDataOff();
115 vtkWriter->SetCompressorTypeToZLib();
int main(int argc, char **argv)