小编典典

如何将三角形的绕组校正为3D Mesh模型的逆时针方向?

algorithm

首先让我清楚..我不是在问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);
    }
}

阅读 434

收藏
2020-07-28

共1个答案

小编典典

要获取相邻信息,请假设我们有一种方法可以
在给定的边上返回三角形的邻居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))
2020-07-28