我正在尝试使用Matlab实现Catmull-Clark细分,因为后续需要将结果与已在Matlab中实现的其他内容进行比较。第一次尝试使用顶点-面网格,算法可以工作,但效率不高,因为需要邻近边和面的信息。因此,我现在使用半边网格。请参见{{link3:设计多面体表面数据结构,作者Lutz Kettner}}(该页面上有PDF链接)。
我的问题在于找到孪生半边,我不确定如何做到这一点。下面我将描述我的实现想法,力求简洁。
半边数据结构网格(使用顶点/半边/面的索引):
Vertex (x,y,z,Outgoing_HalfEdge)
HalfEdge (HeadVertex (or TailVertex, which one should I use), Next, Face, Twin).
Face (HalfEdge)
为了简单起见,现在假设每个面都是四边形。实际网格是由顶点、半边和面的列表组成的。新网格将由NewVertices、NewHalfEdges和NewFaces组成,如下所示(注意:Number_...代表...的数量):
NumberNewVertices: Number_Faces + Number_HalfEdges/2 + Number_Vertices
NumberNewHalfEdges: 4 * 4 * NumberFaces
NumberNewfaces: 4 * NumberFaces
Catmull-Clark:
Find the FacePoint (centroid) of each Face:
--> Just average the x,y,z values of the vertices, save as a NewVertex.
Find the EdgePoint of each HalfEdge:
--> To prevent duplicates (each HalfEdge has a Twin which would result in the same HalfEdge)
--> Only calculate EdgePoints of the HalfEdge which has the lowest index of the Pair.
Update old Vertices
好的,现在所有新顶点都已经计算出来了(但是它们的Outgoing_HalfEdge仍然未知)。下一步是保存新的HalfEdges和Faces。这是导致我问题的部分!
Loop through each old Face, there are 4 new Faces to be created
(because of the quadrilateral assumption)
First create the 4 new HalfEdges per New Face, starting at the FacePoint to the Edgepoint
Next a new HalfEdge from the EdgePoint to an Updated Vertex
Another new one from the Updated Vertex to the next EdgePoint
Finally the fourth new HalfEdge from the EdgePoint back to the FacePoint.
每个新HalfEdge的HeadVertex已知,下一个HalfEdge也是如此。由于它是创建的新面,因此Face也是已知的!唯一未知的是Twin HalfEdge,我该如何知道呢?
顺便说一下,在循环遍历新面的顶点时,将Outgoing_HalfEdge分配给顶点。这可能是找到Twin HalfEdge的地方。
最后,在创建4个新的HalfEdges之后,使用最后一个新创建的HalfVertex的HalfVertex索引保存Face。
我希望您能理解,如果需要的话,我可以发布我的(显然还未完成的)Matlab代码。
编辑:感谢您把我的帖子移动了过来。我在评论中发布了源代码链接,请注意,此实现考虑了一般多边形网格,而不仅仅是四边形网格。
此外,如果您将旧的四边形面分为4个新面(绿色数字),则可以相对容易地找到新HalfEdges 1和4的孪生兄弟(每个新面中的红色数字):
那么,如何找到 2 和 3 HalfEdges 的 Twins(孪生)呢?