首先让我清楚..我不是在问2D网格,而是 很容易确定2D网格在法线z方向上的缠绕顺序。
其次,我不问任何优化算法,我不担心 时间或速度,我只想对我的网格进行处理。
当我使用贪婪投影三角剖分 算法对3D对象进行三角剖分时,会发生此问题。检查附带的图像。
如果我使用“计算符号区域”或“ 三角形的AB和BC向量的交叉产生”对此模型应用2D方法,则它只能求解2D网格,但是 3D网格又如何?
首先,我们需要检查 3D网格中哪些三角形的缠绕方向错误,然后仅考虑这些三角形,所以问题在于,如何 检查3D网格中哪些三角形的缠绕方向错误?我们不能 仅仅使用我已经测试过的2D方法,但是没有成功。
例如,对于球体,我们不能将2D方法应用于球体。那么 有什么办法可以解决这个问题?
谢谢。
在此处输入图片说明 在此处输入图片说明
更新#1:
以下是检查哪个边具有相同绕组的算法。它不能 很好地工作,我不知道为什么。理论上,它应该校正所有三角形, 但不能校正。例如,如果是球形,请检查 附图。它有问题。
void GLReversedEdge(int i, int j, GLFace *temp) { //i'th triangle int V1 = temp[i].v1; int V2 = temp[i].v2; int V3 = temp[i].v3; //i'th triangle edges int E1[] ={V1, V2}; int E2[] ={V2, V3}; int E3[] ={V3, V1}; //adjacent triangle int jV1 = temp[j].v1; int jV2 = temp[j].v2; int jV3 = temp[j].v3; //adjacent edges int jE1[] ={jV1, jV2}; int jE2[] ={jV2, jV3}; int jE3[] ={jV3, jV1}; // 1st edge of adjacent triangle is checking with all edges of ith triangle if((jE1[0] == E1[0] && jE1[1] == E1[1]) || (jE1[0] == E2[0] && jE1[1] == E2[1]) || (jE1[0] == E3[0] && jE1[1] == E3[1])) { temp[j].set(jV2, jV1, jV3); // 1st edges orientation is same, so reverse/swap it } // 2nd edge of adjacent triangle is checking with all edges of ith triangle else if((jE2[0] == E1[0] && jE2[1] == E1[1]) || (jE2[0] == E2[0] && jE2[1] == E2[1]) || (jE2[0] == E3[0] && jE2[1] == E3[1])) { temp[j].set(jV1, jV3, jV2); // 2nd edges orientation is same, so reverse/swap it } // 3rd edge of adjacent triangle is checking with all edges of ith triangle else if((jE3[0] == E1[0] && jE3[1] == E1[1]) || (jE3[0] == E2[0] && jE3[1] == E2[1]) || (jE3[0] == E3[0] && jE3[1] == E3[1])) { temp[j].set(jV3, jV2, jV1); // 3rd edges orientation is same, so reverse/swap it } } void GetCorrectWindingOfMesh() { for(int i=0; i<nbF; i++) { int j1 = AdjacentTriangleToEdgeV1V2; if(j1 >= 0) GLReversedEdge(i, j1, temp); int j2 = AdjacentTriangleToEdgeV2V3; if(j2 >= 0) GLReversedEdge(i, j2, temp); int j3 = AdjacentTriangleToEdgeV3V1; if(j3 >= 0) GLReversedEdge(i, j3, temp); } }
要获取相邻信息,请假设我们有一种方法可以 在给定的边上返回三角形的邻居neighbor_on_egde( next_tria, edge )。
该方法可以使用在每个 三角形中使用每个顶点的信息来实现。那是将顶点索引映射到 三角形索引列表的字典结构。通过遍历 三角形列表并为右 字典元素中的三角形的每个三角形顶点索引设置,可以轻松地创建它。
通过存储要检查方向的 三角形以及已检查哪些三角形来完成遍历。当有三角形要检查时,对其进行 检查,并添加要检查的邻居(如果未选中)。 伪代码如下所示:
to_process = set of pairs triangle and orientation edge initial state is one good oriented triangle with any edge on it processed = set of processed triangles; initial empty while to_process is not empty: next_tria, orientation_edge = to_process.pop() add next_tria in processed if next_tria is not opposite oriented than orientation_edge: change next_tria (ABC) orientation (B<->C) for each edge (AB) in next_tria: neighbor_tria = neighbor_on_egde( next_tria, edge ) if neighbor_tria exists and neighbor_tria not in processed: to_process add (neighbor_tria, edge opposite oriented (BA))