void coarse(SurfaceMesh &mesh, double coarseRate, double flatRate, double denseWeight){ // TODO: Check if all polygons are closed (0) std::cout << "Before coarsening: " << mesh.size<1>() << " " << mesh.size<2>() << " " << mesh.size<3>() << std::endl; // Compute the average edge length double avgLen = 0; if (denseWeight > 0){ avgLen = surfacemesh_detail::getMeanEdgeLength(mesh); } double sparsenessRatio = 1; double flatnessRatio = 1; // Construct list of vertices to decimate std::vector<SurfaceMesh::SimplexID<1> > toRemove; for(auto vertexID : mesh.get_level_id<1>()){ // Sparseness as coarsening criteria if(denseWeight > 0){ // Get max length of edges. auto edges = mesh.up(vertexID); double maxLen = 0; for(auto edgeID : edges){ auto name = mesh.get_name(edgeID); auto v = *mesh.get_simplex_down(edgeID, name[0]) - *mesh.get_simplex_down(edgeID, name[1]); double tmpLen = std::sqrt(v|v); if(tmpLen > maxLen) maxLen = tmpLen; } sparsenessRatio = std::pow(maxLen/avgLen, denseWeight); } // Curvature as coarsening criteria if(flatRate > 0){ auto lst = surfacemesh_detail::computeLocalStructureTensor(mesh, vertexID, RINGS); auto eigenvalues = surfacemesh_detail::getEigenvalues(lst).eigenvalues(); // The closer this ratio is to 0 the flatter the local region. flatnessRatio = std::pow(eigenvalues[1]/eigenvalues[2], flatRate); } // Add vertex to delete list if(sparsenessRatio * flatnessRatio < coarseRate){ toRemove.push_back(vertexID); } } std::cout << toRemove.size() << " vertices are marked to be removed." << std::endl; for(auto vertexID : toRemove){ surfacemesh_detail::decimateVertex(mesh, vertexID); } std::cout << "After coarsening: " << mesh.size<1>() << " " << mesh.size<2>() << " " << mesh.size<3>() << std::endl; }
void coarseIT(SurfaceMesh &mesh, double coarseRate, double flatRate, double denseWeight){ std::cout << "Before coarsening: " << mesh.size<1>() << " " << mesh.size<2>() << " " << mesh.size<3>() << std::endl; // Compute the average edge length double avgLen = 0; if (denseWeight > 0){ avgLen = surfacemesh_detail::getMeanEdgeLength(mesh); } double sparsenessRatio = 1; double flatnessRatio = 1; // Backup vertices so we can modify in place auto range = mesh.get_level_id<1>(); const std::vector<SurfaceMesh::SimplexID<1> > Vertices(range.begin(), range.end()); for(auto vertexID : Vertices) { // Sparseness as coarsening criteria if(denseWeight > 0){ // Get max length of edges. auto edges = mesh.up(vertexID); double maxLen = 0; for(auto edgeID : edges){ auto name = mesh.get_name(edgeID); auto v = *mesh.get_simplex_down(edgeID, name[0]) - *mesh.get_simplex_down(edgeID, name[1]); double tmpLen = std::sqrt(v|v); if(tmpLen > maxLen) maxLen = tmpLen; } sparsenessRatio = std::pow(maxLen/avgLen, denseWeight); } // Curvature as coarsening criteria if(flatRate > 0){ auto lst = surfacemesh_detail::computeLocalStructureTensor(mesh, vertexID, RINGS); auto eigenvalues = surfacemesh_detail::getEigenvalues(lst).eigenvalues(); // The closer this ratio is to 0 the flatter the local region. flatnessRatio = std::pow(eigenvalues[1]/eigenvalues[2], flatRate); } // Check if we should delete if(sparsenessRatio * flatnessRatio < coarseRate){ surfacemesh_detail::decimateVertex(mesh, vertexID); } } std::cout << "After coarsening: " << mesh.size<1>() << " " << mesh.size<2>() << " " << mesh.size<3>() << std::endl; }