MeshCoordinates thin_plate_energy_hole_inpainting(CMesh& mesh, const ZGeom::MeshRegion& hole_region, int nIter, double eps) { const vector<int> anchor_verts = ZGeom::vertSurroundingVerts(mesh, hole_region.vert_inside, 2); vector<int> submesh_verts; int inside_vert_count = (int)hole_region.vert_inside.size(); int anchor_vert_count = (int)anchor_verts.size(); vector<int> newVert2oldVert(inside_vert_count); for (int i = 0; i < inside_vert_count; ++i) { int vi = hole_region.vert_inside[i]; submesh_verts.push_back(vi); newVert2oldVert[i] = vi; } for (int vi : anchor_verts) submesh_verts.push_back(vi); CMesh submesh; mesh.getSubMesh(submesh_verts, "hole_mesh", submesh); MeshCoordinates faired_sub_coord = thin_plate_energy_fairing(submesh, inside_vert_count); MeshCoordinates result(mesh.getVertCoordinates()); for (int sub_vIdx = 0; sub_vIdx < inside_vert_count; ++sub_vIdx) { result.setVertCoord(newVert2oldVert[sub_vIdx], faired_sub_coord[sub_vIdx]); } return result; }
MeshCoordinates least_square_hole_inpainting(CMesh& mesh, const std::vector<ZGeom::MeshRegion>& hole_regions, int anchor_ring, double anchor_weight) { ZGeom::logic_assert(anchor_weight >= 0, "Illegal parameter!"); MeshCoordinates result(mesh.getVertCoordinates()); if (anchor_ring <= 0) { vector<int> hole_verts = getMeshRegionsInsideVerts(hole_regions); set<int> set_hole_verts(hole_verts.begin(), hole_verts.end()); set<int> anchor_verts; for (int vi = 0; vi < (int)mesh.vertCount(); ++vi) { if (!setHas(set_hole_verts, vi)) anchor_verts.insert(vi); } MeshCoordinates faired_coord = least_square_inpainting(mesh, vector<int>(anchor_verts.begin(),anchor_verts.end()), anchor_weight); for (int vi : hole_verts) result.setVertCoord(vi, faired_coord[vi]); return result; } for (const MeshRegion& mr : hole_regions) { const vector<int> anchor_verts = ZGeom::vertSurroundingVerts(mesh, mr.vert_inside, anchor_ring); vector<int> submesh_verts; int inside_vert_count = (int)mr.vert_inside.size(); int anchor_vert_count = (int)anchor_verts.size(); vector<int> newVert2oldVert(inside_vert_count); int newVertIdx(0); for (int vi : mr.vert_inside) { submesh_verts.push_back(vi); newVert2oldVert[newVertIdx++] = vi; } for (int vi : anchor_verts) submesh_verts.push_back(vi); CMesh submesh; mesh.getSubMesh(submesh_verts, "hole_mesh", submesh); vector<int> control_verts; for (int i = inside_vert_count; i < (int)submesh_verts.size(); ++i) control_verts.push_back(i); MeshCoordinates faired_sub_coord = least_square_inpainting(submesh, control_verts, anchor_weight); for (int sub_vIdx = 0; sub_vIdx < inside_vert_count; ++sub_vIdx) { result.setVertCoord(newVert2oldVert[sub_vIdx], faired_sub_coord[sub_vIdx]); } } return result; }
MeshCoordinates l1_ls_hole_inpainting(CMesh& mesh, const std::vector<ZGeom::MeshRegion>& hole_regions, ParaL1LsInpainting& para) { MeshCoordinates result(mesh.getVertCoordinates()); if (para.fitting_ring <= 0) { vector<int> hole_verts = getMeshRegionsInsideVerts(hole_regions); MeshCoordinates faired_coord = l1_ls_inpainting(mesh, hole_verts, para); for (int vi : hole_verts) result.setVertCoord(vi, faired_coord[vi]); return result; } for (const ZGeom::MeshRegion& mr : hole_regions) { const vector<int> anchor_verts = ZGeom::vertSurroundingVerts(mesh, mr.vert_inside, para.fitting_ring); vector<int> submesh_verts; int inside_vert_count = (int)mr.vert_inside.size(); int anchor_vert_count = (int)anchor_verts.size(); vector<int> newVert2oldVert(inside_vert_count); vector<int> missing_verts; int newVertIdx(0); for (int vi : mr.vert_inside) { submesh_verts.push_back(vi); missing_verts.push_back(newVertIdx); newVert2oldVert[newVertIdx++] = vi; } for (int vi : anchor_verts) submesh_verts.push_back(vi); CMesh submesh; mesh.getSubMesh(submesh_verts, "hole_mesh", submesh); MeshCoordinates faired_sub_coord = l1_ls_inpainting(submesh, missing_verts, para); for (int sub_vIdx = 0; sub_vIdx < inside_vert_count; ++sub_vIdx) { result.setVertCoord(newVert2oldVert[sub_vIdx], faired_sub_coord[sub_vIdx]); } } return result; }
MeshCoordinates meshHoleDLRS(CMesh& mesh, const std::vector<MeshRegion>& hole_regions, double lambda, int anchor_ring) { MeshCoordinates result(mesh.getVertCoordinates()); if (anchor_ring <= 0) { vector<int> hole_verts = getMeshRegionsInsideVerts(hole_regions); MeshCoordinates faired_coord = meshDLRS(mesh, lambda); for (int vi : hole_verts) result.setVertCoord(vi, faired_coord[vi]); return result; } for (const MeshRegion& mr : hole_regions) { const vector<int> anchor_verts = ZGeom::vertSurroundingVerts(mesh, mr.vert_inside, anchor_ring); vector<int> submesh_verts; int inside_vert_count = (int)mr.vert_inside.size(); vector<int> newVert2oldVert(inside_vert_count); int newVertIdx(0); for (int vi : mr.vert_inside) { submesh_verts.push_back(vi); newVert2oldVert[newVertIdx++] = vi; } for (int vi : anchor_verts) submesh_verts.push_back(vi); CMesh submesh; mesh.getSubMesh(submesh_verts, "hole_mesh", submesh); MeshCoordinates faired_sub_coord = meshDLRS(submesh, lambda); for (int sub_vIdx = 0; sub_vIdx < inside_vert_count; ++sub_vIdx) { result.setVertCoord(newVert2oldVert[sub_vIdx], faired_sub_coord[sub_vIdx]); } } return result; }