19 #include <vtkIdList.h>
20 #include <vtkIntArray.h>
21 #include <vtkIsotropicDiscreteRemeshing.h>
22 #include <vtkMultiThreader.h>
23 #include <vtkPolyData.h>
24 #include <vtkPolyDataNormals.h>
25 #include <vtkSmartPointer.h>
26 #include <vtkSurface.h>
28 struct ClustersQuadrics
30 explicit ClustersQuadrics(
int size) : Elements(new double *[size]), Size(size)
32 for (
int i = 0; i < size; ++i)
34 Elements[i] =
new double[9];
36 for (
int j = 0; j < 9; ++j)
43 for (
int i = 0; i < Size; ++i)
53 ClustersQuadrics(
const ClustersQuadrics &);
54 ClustersQuadrics &operator=(
const ClustersQuadrics &);
62 if (t >= surface->GetSizeOfPolyDataSeries())
63 mitkThrow() <<
"Input surface doesn't have data at time step " << t <<
"!";
65 vtkPolyData *polyData =
const_cast<mitk::Surface *
>(surface.GetPointer())->GetVtkPolyData(t);
67 if (polyData ==
nullptr)
68 mitkThrow() <<
"PolyData of input surface at time step " << t <<
" is NULL!";
70 if (polyData->GetNumberOfPolys() == 0)
71 mitkThrow() <<
"Input surface has no polygons at time step " << t <<
"!";
80 int optimizationLevel,
89 surfacePolyData->DeepCopy(const_cast<Surface *>(surface.GetPointer())->GetVtkPolyData(t));
93 mesh->CreateFromPolyData(surfacePolyData);
94 mesh->GetCellData()->Initialize();
95 mesh->GetPointData()->Initialize();
97 mesh->DisplayMeshProperties();
100 numVertices = surfacePolyData->GetNumberOfPoints();
102 if (edgeSplitting != 0.0)
103 mesh->SplitLongEdges(edgeSplitting);
107 remesher->GetMetric()->SetGradation(gradation);
108 remesher->SetBoundaryFixing(boundaryFixing);
109 remesher->SetConsoleOutput(1);
110 remesher->SetForceManifold(forceManifold);
111 remesher->SetInput(mesh);
112 remesher->SetNumberOfClusters(numVertices);
113 remesher->SetNumberOfThreads(vtkMultiThreader::GetGlobalDefaultNumberOfThreads());
114 remesher->SetSubsamplingThreshold(subsampling);
119 if (optimizationLevel != 0)
121 ClustersQuadrics clustersQuadrics(numVertices);
124 vtkSmartPointer<vtkIntArray> clustering = remesher->GetClustering();
125 vtkSmartPointer<vtkSurface> remesherInput = remesher->GetInput();
126 int clusteringType = remesher->GetClusteringType();
127 int numItems = remesher->GetNumberOfItems();
128 int numMisclassifiedItems = 0;
130 for (
int i = 0; i < numItems; ++i)
132 int cluster = clustering->GetValue(i);
134 if (cluster >= 0 && cluster < numVertices)
136 if (clusteringType != 0)
138 remesherInput->GetVertexNeighbourFaces(i, faceList);
139 int numIds =
static_cast<int>(faceList->GetNumberOfIds());
141 for (
int j = 0; j < numIds; ++j)
142 vtkQuadricTools::AddTriangleQuadric(
143 clustersQuadrics.Elements[cluster], remesherInput, faceList->GetId(j),
false);
147 vtkQuadricTools::AddTriangleQuadric(clustersQuadrics.Elements[cluster], remesherInput, i,
false);
152 ++numMisclassifiedItems;
156 if (numMisclassifiedItems != 0)
157 std::cout << numMisclassifiedItems <<
" items with wrong cluster association" << std::endl;
159 vtkSmartPointer<vtkSurface> remesherOutput = remesher->GetOutput();
162 for (
int i = 0; i < numVertices; ++i)
164 remesherOutput->GetPoint(i, point);
165 vtkQuadricTools::ComputeRepresentativePoint(clustersQuadrics.Elements[i], point, optimizationLevel);
166 remesherOutput->SetPointCoordinates(i, point);
169 std::cout <<
"After quadrics post-processing:" << std::endl;
170 remesherOutput->DisplayMeshProperties();
175 normals->SetInputData(remesher->GetOutput());
176 normals->AutoOrientNormalsOn();
177 normals->ComputeCellNormalsOff();
178 normals->ComputePointNormalsOn();
179 normals->ConsistencyOff();
180 normals->FlipNormalsOff();
181 normals->NonManifoldTraversalOff();
182 normals->SplittingOff();
187 remeshedSurface->SetVtkPolyData(normals->GetOutput());
191 return remeshedSurface;
194 mitk::ACVD::RemeshFilter::RemeshFilter()
199 m_EdgeSplitting(0.0),
200 m_OptimizationLevel(1),
201 m_ForceManifold(false),
202 m_BoundaryFixing(false)
205 this->SetNthOutput(0, output);
208 mitk::ACVD::RemeshFilter::~RemeshFilter()
223 this->SetNthOutput(0, output);
MITKREMESHING_EXPORT Surface::Pointer Remesh(Surface::ConstPointer surface, unsigned int t, int numVertices, double gradation, int subsampling=10, double edgeSplitting=0.0, int optimizationLevel=1, bool forceManifold=false, bool boundaryFixing=false)
Remesh a surface and store the result in a new surface.
Class for storing surfaces (vtkPolyData).
static void ValidateSurface(mitk::Surface::ConstPointer surface, unsigned int t)
void GenerateData() override
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.