OpenMesh halfedge 网格库有一个
split_edge
函数,通过在边中插入新顶点来分割给定的边句柄,但该函数不会返回新边。
如何获得分割后的新线段以及它们如何相对于原始边缘进行定向?
OpenMesh 支持三角形网格和多边形网格,并以不同的方式处理边,因为三角形网格需要插入更多边来在分割后重新对相邻面进行三角剖分,而在多边形网格中,生成的多边形仅多一条边。
在两种类型的网格中,原始边都保留为与分割顶点相邻的边之一。
对于多边形网格,网格会更新,使得主半边
eh.h0()
远离新顶点,插入边的主半边指向新顶点,即 new_eh.h0().to() == new_vh
和 eh.h0().from() == new_vh
。
在三角形网格中,调整三角剖分,使得原始边和插入的边远离新顶点,在某种程度上,两个主半边
eh.h0()
和 new_eh.h0()
都远离插入的顶点new_vh
,即 new_eh.h0().from() == new_vh
和 eh.h0().from() == new_vh
;
对于使用 PolyConnectivity 进行网格分割,split_edge(EdgeHandle _eh, VertexHandle _vh) 函数会导致
new_vh
的价数为 2 并且与两个段相邻。
当沿原始主半边
eh.h0()
的方向对线段进行排序时,我们得到路径new_eh.h0().to()
,new_vh
,eh.h0().to()
,其中new_eh = eh.h0().prev().edge()
。
此函数在半边处分割网格并返回指向原始半边方向的线段半边:
template <typename PolyMeshT>
std::pair<OpenMesh::SmartHalfedgeHandle, OpenMesh::SmartHalfedgeHandle> split_edge(PolyMeshT mesh, const OpenMesh::SmartHalfedgeHandle heh, OpenMesh::SmartVertexHandle new_vh) {
auto eh = heh.edge();
mesh.split_edge(eh, new_vh);
auto new_heh = eh.h0().prev();
if(heh == eh.h0()) {
return {new_heh, heh};
} else {
// heh == eh.h1()
return {heh, new_heh.opp()};
}
}
对于使用 TriConnectivity 进行网格分割,split_edge(EdgeHandle _eh, VertexHandle _vh) 函数会导致
new_vh
的化合价为 4 作为连接 new_vh
的两条支撑边,并且相邻三角形的顶点为不在边缘上,插入以重新三角化脸。
当沿原始主半边
eh.h0()
的方向对线段进行排序时,我们得到路径new_eh.h1().to()
,new_vh
,eh.h0().to()
,但由于现在有支撑边,我们需要围绕new_vh
循环找到新的边缘:new_eh = eh.h0().prev().opp().prev().edge()
。
此函数在半边处分割网格并返回指向原始半边方向的线段半边:
template <typename TriMeshT>
std::pair<OpenMesh::SmartHalfedgeHandle, OpenMesh::SmartHalfedgeHandle> split_edge(TriMeshT mesh, const OpenMesh::SmartHalfedgeHandle heh, OpenMesh::SmartVertexHandle new_vh) {
auto eh = heh.edge();
mesh.split_edge(eh, new_vh);
auto new_heh = eh.h0().prev().opp().prev();
if(heh == eh.h0()) {
return {new_heh, heh};
} else {
// heh = eh.h1()
return {heh, new_heh.opp()};
}
}