mitk::SurfaceInterpolationController::ContourPositionInformation CreateContourPositionInformation(mitk::Surface::Pointer contour) { mitk::SurfaceInterpolationController::ContourPositionInformation contourInfo; contourInfo.contour = contour; double n[3]; double p[3]; contour->GetVtkPolyData()->GetPoints()->GetPoint(0, p); vtkPolygon::ComputeNormal(contour->GetVtkPolyData()->GetPoints(), n); contourInfo.contourNormal = n; contourInfo.contourPoint = p; return contourInfo; }
mitk::Surface::Pointer mitk::SurfaceModifier::DeepCopy(mitk::Surface::Pointer originalSurface) { mitk::Surface::Pointer clonedSurface = mitk::Surface::New(); vtkSmartPointer<vtkPolyData> clonedPolyData = vtkPolyData::New(); clonedPolyData->DeepCopy(originalSurface->GetVtkPolyData()); clonedSurface->SetVtkPolyData(clonedPolyData); return clonedSurface; }
void mitk::SurfaceInterpolationController::AddNewContour (mitk::Surface::Pointer newContour) { if( newContour->GetVtkPolyData()->GetNumberOfPoints() > 0) { ContourPositionInformation contourInfo = CreateContourPositionInformation(newContour); this->AddToInterpolationPipeline(contourInfo); this->Modified(); } }
bool CompareSurfacePointPositions(mitk::Surface::Pointer s1, mitk::Surface::Pointer s2) { vtkPoints* p1 = s1->GetVtkPolyData()->GetPoints(); vtkPoints* p2 = s2->GetVtkPolyData()->GetPoints(); if(p1->GetNumberOfPoints() != p2->GetNumberOfPoints()) return false; for(int i = 0; i < p1->GetNumberOfPoints(); ++i) { if(p1->GetPoint(i)[0] != p2->GetPoint(i)[0] || p1->GetPoint(i)[1] != p2->GetPoint(i)[1] || p1->GetPoint(i)[2] != p2->GetPoint(i)[2] ) { return true; } } return false; }
bool mitk::SurfaceModifier::AddOutlierToSurface(mitk::Surface::Pointer surface, double varianceX, double varianceY, double varianceZ, double outlierChance) { vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New(); points->ShallowCopy(surface->GetVtkPolyData()->GetPoints()); for(unsigned int i = 0; i < points->GetNumberOfPoints(); i++) { double p[3]; points->GetPoint(i, p); mitk::Point3D point; point[0] = p[0]; point[1] = p[1]; point[2] = p[2]; if((outlierChance-vtkMath::Random(0,1))>0) point = PerturbePoint(point,varianceX,varianceY,varianceZ); p[0] = point[0]; p[1] = point[1]; p[2] = point[2]; points->SetPoint(i, p); } surface->GetVtkPolyData()->SetPoints(points); return true; }
bool mitk::SurfaceModifier::PerturbeSurface(mitk::Surface::Pointer surface, double varianceX, double varianceY, double varianceZ, double maxNoiseVectorLenght) { vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New(); points->ShallowCopy(surface->GetVtkPolyData()->GetPoints()); for(unsigned int i = 0; i < points->GetNumberOfPoints(); i++) { double p[3]; points->GetPoint(i, p); mitk::Point3D point; point[0] = p[0]; point[1] = p[1]; point[2] = p[2]; point = PerturbePoint(point,varianceX,varianceY,varianceZ,maxNoiseVectorLenght); p[0] = point[0]; p[1] = point[1]; p[2] = point[2]; points->SetPoint(i, p); } surface->GetVtkPolyData()->SetPoints(points); return true; }
bool mitk::SurfaceModifier::TransformSurface(mitk::Surface::Pointer surface, itk::Matrix<double,3,3> TransformationR, itk::Vector<double,3> TransformationT) { //apply transformation vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New(); points->ShallowCopy(surface->GetVtkPolyData()->GetPoints()); for(unsigned int i = 0; i < points->GetNumberOfPoints(); i++) { double p[3]; points->GetPoint(i, p); mitk::Point3D point; point[0] = p[0]; point[1] = p[1]; point[2] = p[2]; point = TransformPoint(point,TransformationR,TransformationT); p[0] = point[0]; p[1] = point[1]; p[2] = point[2]; points->SetPoint(i, p); } surface->GetVtkPolyData()->SetPoints(points); return true; }
void mitk::SurfaceInterpolationController::ReinitializeInterpolation(mitk::Surface::Pointer contours) { // 1. detect coplanar contours // 2. merge coplanar contours into a single surface // 4. add contour to pipeline // Split the surface into separate polygons vtkSmartPointer<vtkCellArray> existingPolys; vtkSmartPointer<vtkPoints> existingPoints; existingPolys = contours->GetVtkPolyData()->GetPolys(); existingPoints = contours->GetVtkPolyData()->GetPoints(); existingPolys->InitTraversal(); vtkSmartPointer<vtkIdList> ids = vtkSmartPointer<vtkIdList>::New(); typedef std::pair<mitk::Vector3D, mitk::Point3D> PointNormalPair; std::vector<ContourPositionInformation> list; std::vector<vtkSmartPointer<vtkPoints> > pointsList; int count (0); for( existingPolys->InitTraversal(); existingPolys->GetNextCell(ids);) { // Get the points vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New(); existingPoints->GetPoints(ids, points); ++count; pointsList.push_back(points); PointNormalPair p_n; double n[3]; vtkPolygon::ComputeNormal(points, n); p_n.first = n; double p[3]; existingPoints->GetPoint(ids->GetId(0), p); p_n.second = p; ContourPositionInformation p_info; p_info.contourNormal = n; p_info.contourPoint = p; list.push_back(p_info); continue; } // Detect and sort coplanar polygons auto outer = list.begin(); std::vector< std::vector< vtkSmartPointer<vtkPoints> > > relatedPoints; while (outer != list.end()) { auto inner = outer; ++inner; std::vector< vtkSmartPointer<vtkPoints> > rel; auto pointsIter = pointsList.begin(); rel.push_back((*pointsIter)); pointsIter = pointsList.erase(pointsIter); while (inner != list.end()) { if(ContoursCoplanar((*outer),(*inner))) { inner = list.erase(inner); rel.push_back((*pointsIter)); pointsIter = pointsList.erase(pointsIter); } else { ++inner; ++pointsIter; } } relatedPoints.push_back(rel); ++outer; } // Build the separate surfaces again std::vector<mitk::Surface::Pointer> finalSurfaces; for (unsigned int i = 0; i < relatedPoints.size(); ++i) { vtkSmartPointer<vtkPolyData> contourSurface = vtkSmartPointer<vtkPolyData>::New(); vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New(); vtkSmartPointer<vtkCellArray> polygons = vtkSmartPointer<vtkCellArray>::New(); unsigned int pointId (0); for (unsigned int j = 0; j < relatedPoints.at(i).size(); ++j) { unsigned int numPoints = relatedPoints.at(i).at(j)->GetNumberOfPoints(); vtkSmartPointer<vtkPolygon> polygon = vtkSmartPointer<vtkPolygon>::New(); polygon->GetPointIds()->SetNumberOfIds(numPoints); polygon->GetPoints()->SetNumberOfPoints(numPoints); vtkSmartPointer<vtkPoints> currentPoints = relatedPoints.at(i).at(j); for (unsigned k = 0; k < numPoints; ++k) { points->InsertPoint(pointId, currentPoints->GetPoint(k)); polygon->GetPointIds()->SetId(k, pointId); ++pointId; } polygons->InsertNextCell(polygon); } contourSurface->SetPoints(points); contourSurface->SetPolys(polygons); contourSurface->BuildLinks(); mitk::Surface::Pointer surface = mitk::Surface::New(); surface->SetVtkPolyData(contourSurface); finalSurfaces.push_back(surface); } // Add detected contours to interpolation pipeline this->AddNewContours(finalSurfaces); }
mitk::Surface::Pointer mitk::ACVD::Remesh(mitk::Surface::Pointer surface, int numVertices, double gradation, int subsampling, double edgeSplitting, int optimizationLevel, bool forceManifold, bool boundaryFixing) { MITK_INFO << "Start remeshing..."; vtkSmartPointer<vtkPolyData> surfacePolyData = vtkSmartPointer<vtkPolyData>::New(); surfacePolyData->DeepCopy(surface->GetVtkPolyData()); vtkSmartPointer<vtkSurface> mesh = vtkSmartPointer<vtkSurface>::New(); mesh->CreateFromPolyData(surfacePolyData); mesh->GetCellData()->Initialize(); mesh->GetPointData()->Initialize(); mesh->DisplayMeshProperties(); if (edgeSplitting != 0.0) mesh->SplitLongEdges(edgeSplitting); vtkSmartPointer<vtkIsotropicDiscreteRemeshing> remesher = vtkSmartPointer<vtkIsotropicDiscreteRemeshing>::New(); remesher->GetMetric()->SetGradation(gradation); remesher->SetBoundaryFixing(boundaryFixing); remesher->SetConsoleOutput(1); remesher->SetForceManifold(forceManifold); remesher->SetInput(mesh); remesher->SetNumberOfClusters(numVertices); remesher->SetNumberOfThreads(vtkMultiThreader::GetGlobalDefaultNumberOfThreads()); remesher->SetSubsamplingThreshold(subsampling); remesher->Remesh(); if (optimizationLevel != 0) { ClustersQuadrics clustersQuadrics(numVertices); vtkSmartPointer<vtkIdList> faceList = vtkSmartPointer<vtkIdList>::New(); vtkSmartPointer<vtkIntArray> clustering = remesher->GetClustering(); vtkSmartPointer<vtkSurface> remesherInput = remesher->GetInput(); int clusteringType = remesher->GetClusteringType(); int numItems = remesher->GetNumberOfItems(); int numMisclassifiedItems = 0; for (int i = 0; i < numItems; ++i) { int cluster = clustering->GetValue(i); if (cluster >= 0 && cluster < numVertices) { if (clusteringType != 0) { remesherInput->GetVertexNeighbourFaces(i, faceList); int numIds = static_cast<int>(faceList->GetNumberOfIds()); for (int j = 0; j < numIds; ++j) vtkQuadricTools::AddTriangleQuadric(clustersQuadrics.Elements[cluster], remesherInput, faceList->GetId(j), false); } else { vtkQuadricTools::AddTriangleQuadric(clustersQuadrics.Elements[cluster], remesherInput, i, false); } } else { ++numMisclassifiedItems; } } if (numMisclassifiedItems != 0) std::cout << numMisclassifiedItems << " items with wrong cluster association" << std::endl; vtkSmartPointer<vtkSurface> remesherOutput = remesher->GetOutput(); double point[3]; for (int i = 0; i < numVertices; ++i) { remesherOutput->GetPoint(i, point); vtkQuadricTools::ComputeRepresentativePoint(clustersQuadrics.Elements[i], point, optimizationLevel); remesherOutput->SetPointCoordinates(i, point); } std::cout << "After quadrics post-processing:" << std::endl; remesherOutput->DisplayMeshProperties(); } vtkSmartPointer<vtkPolyDataNormals> normals = vtkSmartPointer<vtkPolyDataNormals>::New(); normals->SetInput(remesher->GetOutput()); normals->AutoOrientNormalsOn(); normals->ComputeCellNormalsOff(); normals->ComputePointNormalsOn(); normals->ConsistencyOff(); normals->FlipNormalsOff(); normals->NonManifoldTraversalOff(); normals->SplittingOff(); normals->Update(); Surface::Pointer remeshedSurface = Surface::New(); remeshedSurface->SetVtkPolyData(normals->GetOutput()); MITK_INFO << "Finished remeshing"; return remeshedSurface; }