void dual(HMesh::Manifold& m) { FaceAttributeVector<Vec3d> face_center(m.no_faces()); for (auto f : m.faces()) { // find mid point Vec3d mpt(0.0, 0.0, 0.0); int nb_p = 0; for (auto hw = m.walker(f); !hw.full_circle(); hw = hw.circulate_face_ccw()) { mpt += m.pos(hw.vertex()); nb_p++; } mpt = mpt / nb_p; face_center[f] = mpt; } Manifold newMesh; for (auto v : m.vertices()) { vector<Vec3d> pts; for (auto hw = m.walker(v); !hw.full_circle(); hw = hw.circulate_vertex_ccw()) { // if (hw.opp().face() == InvalidFaceID) // { // pts.push_back((m.pos(hw.vertex()) + m.pos(hw.opp().vertex()))/2.0); // pts.push_back(face_center[hw.face()]); // } // else if(hw.face() == InvalidFaceID) // { // pts.push_back((m.pos(hw.vertex()) + m.pos(hw.opp().vertex()))/2.0); // } // else if (m.in_use(hw.face())) { pts.push_back(face_center[hw.face()]); } } newMesh.add_face(pts); } stitch_mesh(newMesh, 0.01); m = newMesh; }
void volume_polygonize(const XForm& xform, const Geometry::RGrid<float>& grid, HMesh::Manifold& mani, float tau, bool make_triangles) { mani.clear(); vector<Vec3d> quad_vertices; polygonize(xform, grid, quad_vertices, tau); vector<int> indices; vector<int> faces(quad_vertices.size()/4,4); for(int i=0;i<quad_vertices.size();++i) indices.push_back(i); build(mani, quad_vertices.size(), quad_vertices[0].get(), faces.size(), &faces[0], &indices[0]); stitch_more(mani, 1e-5); if(make_triangles) triangulate(mani); float avg_edge_len=0; for(HalfEdgeIDIterator h = mani.halfedges_begin(); h != mani.halfedges_end();++h) avg_edge_len += length(mani, *h); avg_edge_len /= mani.no_halfedges(); VolumetricImplicit imp(xform, grid); for(int iter=0;iter<4;++iter) { TAL_smoothing(mani, .25, 1); for(auto v: mani.vertices()) if(mani.in_use(v)) { Vec3d p = mani.pos(v); if(!std::isnan(p[0])) imp.push_to_surface(p,0,avg_edge_len*0.5); if(std::isnan(p[0])) mani.remove_vertex(v); else mani.pos(v) = p; } } mani.cleanup(); cout << "Produced " << mani.no_faces() << " faces " << endl; }