/* Simplificate a mesh using CGALs Triangulated Surface Mesh Simplification (http://doc.cgal.org/latest/Surface_mesh_simplification/index.html#Chapter_Triangulated_Surface_Mesh_Simplification) */ const char* CGALSimplificateSurface(const char* inputMeshFile, const char* outputMeshFile, int stopnr, std::vector<double> box = std::vector<double>()) { vtkSmartPointer<vtkPolyData> inputPoly = IOHelper::VTKReadPolyData(inputMeshFile); Polyhedron polyhedron; VTKPolydataToCGALPolyhedron_converter(inputPoly, &polyhedron); //create stop predicate CGAL::Surface_mesh_simplification::Count_stop_predicate<Polyhedron> stop(stopnr); Constrains_map constrains_map ; //if box contains exactly six values, use region inside box to mark non-removable edges if(box.size()==6) { int totalEdges=0; int constrainedEdges=0; log_debug()<<"bounding box given"<<std::endl; //iterate over all edges, edges inside box will be marked as non-removable for(Polyhedron::Halfedge_iterator eb = polyhedron.halfedges_begin(), ee = polyhedron.halfedges_end() ; eb != ee ; ++ eb ) { Point currentPoint = eb->vertex()->point(); //test if edge vertex is within box if( (currentPoint[0]>=box[0]) && (currentPoint[1]>=box[1]) && (currentPoint[2]>=box[2]) && (currentPoint[0]<=box[3]) && (currentPoint[1]<=box[4]) && (currentPoint[2]<=box[5])) { //add to map of non-removable edges constrains_map.set_is_constrained(eb,true); constrainedEdges++; } totalEdges++; } log_debug()<<"total edges: "<<totalEdges<<" constrained: "<<constrainedEdges<<std::endl; } //simplificate mesh int r = CGAL::Surface_mesh_simplification::edge_collapse (polyhedron,stop, CGAL::vertex_index_map(boost::get(CGAL::vertex_external_index,polyhedron)) .edge_index_map (boost::get(CGAL::edge_external_index ,polyhedron)) .edge_is_border_map(constrains_map) ); log_debug()<<"Edges removed: "<<r<<std::endl; //now create polydata-object vtkSmartPointer<vtkPolyData> vtkpoly = vtkSmartPointer<vtkPolyData>::New(); //convert polyhedron to polydata CGALPolyhedronToVTKPolydata_converter(&polyhedron, vtkpoly); //write polydata to disk bool result = IOHelper::VTKWritePolyData(outputMeshFile,vtkpoly); return outputMeshFile; }
void mergeColinear(Polyhedron& p) { int vertBefore = p.size_of_vertices(); bool colinearFound = true; while (colinearFound) { colinearFound = false; // Set temporarily to false, if merge degments then set true int percCount = 1; for (Polyhedron::Halfedge_iterator hit = p.halfedges_begin(); hit != p.halfedges_end(); ++hit,++percCount){ if (CGAL::circulator_size(hit->vertex_begin()) == 1) { std::cerr << "WARNING: Loose edge, but how??"<<std::endl; while (CGAL::circulator_size(hit->vertex_begin()) == 1) hit = p.join_vertex(hit->opposite()); break; } if ((CGAL::circulator_size(hit->vertex_begin()) == 2) && // if only two he connected to vertex (hit->facet_degree()>3 && hit->opposite()->facet_degree()>3)) { // if faces are not triangles // prob faster Vector_3 cur(hit->prev()->vertex()->point(),hit->vertex()->point()); Vector_3 nex(hit->vertex()->point(),hit->next()->vertex()->point()); if ( is_colinear(cur,nex)) { // check if colinear std::cout << "\rVertices before/after: "<<vertBefore<<" -> "<< p.size_of_vertices()<<". ("<<100*percCount/p.size_of_halfedges()<<"%)"; p.join_vertex(hit->opposite()); // move cur to prev point colinearFound = true; break; } } } } std::cout << "\rVertices before/after: "<<vertBefore<<" -> "<< p.size_of_vertices()<<". (100%)" << std::endl; }