如何纠正三角形绕组的3D网格模型逆时针方向?角形、绕组、网格、模型

2023-09-11 00:14:15 作者:Д~泛怪情绪,♂

首先让我清楚。我不是问2D目,以确定2D的环绕顺序目它很容易与正常Z方向。

First of all let me clear .. I am not asking about 2D mesh, to determine the winding order of 2D mesh its very easy with normal-z direction.

二是,我不要求任何优化算法,我不担心时间和速度,我只想用我的网做到这一点。

Second is, I am not asking any optimized algorithm, I do not worry about the time or speed, I just want to do it with my mesh.

当我使用三角测量贪婪投影三角算法3D对象,会出现此问题。 检查附件图片。

When I triangulate a 3D object using Greedy Projection Triangulation algorithm, This problem happens. check the attached images.

如果我申请的2D方法使用计算签名区或交叉生产三角形AB和BC矢量这一模式,它只是解决了二维网状但如何对一个三维网格?

If I apply 2D approaches to this model using "Calculate Signed Area" or "Cross production of AB and BC vectors of a triangle", it only solves the 2D mesh but how about a 3D mesh?

首先,我们需要检查哪些三角形是在三维网格错卷绕方向,那么我们只考虑那些三角形,这样的问题是,我们如何可以检查哪些三角形是在3D错误的缠绕方向?我们不能只是做我已经测试过它,但没有成功的2D方法。

First we need to check that which triangles are in wrong winding direction in 3D mesh, then we only consider those triangles, so the issue is, how can we check that which triangles are in wrong winding direction in 3D? We can not just do with 2D approach I have tested it and but no success.

例如在壳体的球的,我们不能2D方法应用到球体。 那么,有没有办法解决这个问题?

For example in case of a sphere, we can not apply 2D approach to sphere. So is there any way to solve this issue ?

感谢。

更新#1:的

下面是算法检查其边缘具有相同的绕组。它不能很好地工作,我不知道为什么。理论上它应当纠正所有的三角形,但它不校正。例如,在情况下,在附图球体支票。什么是错的。

Below is the algorithm to check which edge has the same winding. It doesn't work well, I don't know why. Theoretically it should correct all the triangles but it is not correcting. For example in case of a sphere check in the attached figure. Something is wrong with it.

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,边缘)

To retrieve neighboring information lets assume we have method that returns neighbor of triangle on given edge neighbor_on_egde( next_tria, edge ).

这方法可以与信息的每一个中哪些三角形它用于顶点实现。这是顶点索引映射到三角形索引列表字典结构。这是很容易通过三角形的列表,并设置三角右字典元素的每个三角形顶点索引创建的。

That method can be implemented with information for each vertex in which triangles it is used. That is dictionary structure that maps vertex index to list of triangle indices. It is easily created by passing through list of triangles and setting for each triangle vertex index of triangle in right dictionary element.

遍历是通过存储哪些三角形来检查取向和其三角形已经检查完成。虽然有三角形检查,使检查它,并添加如果他们不检查,以检查它的邻国。伪code是这样的:

Traversal is done by storing which triangles to check for orientation and which triangles are already checked. While there are triangles to check, make check on it and add it's neighbors to be checked if they weren't checked. Pseudo code looks like:

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))