5

首先让我清楚.. 我不是在询问 2D 网格,要确定 2D 网格的缠绕顺序,它非常容易使用 normal-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);
    }
}

在此处输入图像描述

4

2 回答 2

2

您的网格是否包含边缘邻接信息?即每个三角形 T 包含三个顶点 A、B、C 和三个边 AB、BC 和 CA,其中 AB 是三角形 T1 的链接,它共享公共顶点 A、B 并包含一个新顶点 D。类似的东西

struct Vertex 
{
 double x,y,z;
};

struct Triangle
{
   int vertices[3],edges[3];
};


struct TriangleMesh
{
   Vertex Vertices[];
   Triangle Triangles[];
};

如果是这种情况,对于任何三角形 T = {{VA,VB,VC},{TAB,TBC,TCA}},在边 AB 处相邻的 TE = &TAB,A 和 B 必须以相反的顺序出现 T 和 TE具有相同的绕组。例如 TAB = {{ VB,VA ,VD},{TBA,TAD,TDA}} 其中 TBA = &T。这可用于为所有三角形提供相同的绕组。

于 2013-06-11T07:20:19.417 回答
2

要检索相邻信息,假设我们有方法可以返回给定边上三角形的邻居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))
于 2013-06-17T07:46:11.977 回答