¿Cómo corregir el enrollamiento de los triángulos en sentido contrario a las agujas del reloj de un modelo de malla 3D?

En primer lugar, permítame aclarar ... No estoy preguntando acerca de la malla 2D, para determinar el orden de enrollamiento de la malla 2D es muy fácil con la dirección z normal.

En segundo lugar, no estoy pidiendo ningún algoritmo optimizado, no me preocupo por el tiempo ni la velocidad, solo quiero hacerlo con mi malla.

Cuando triangulo un objeto 3D usando el algoritmo de Triangulación de Proyección Greedy, este problema ocurre. Revisa las imágenes adjuntas.

Si aplico enfoques 2D a este modelo utilizando "Calcular área firmada" o "Producción cruzada de vectores AB y BC de un triángulo", solo resuelve la malla 2D, pero ¿qué tal una malla 3D?

Primero debemos verificar qué triángulos están en la dirección de bobinado incorrecta en la malla 3D, luego solo consideramos esos triángulos, entonces el problema es, ¿cómo podemos verificar qué triángulos están en la dirección de bobinado incorrecta en 3D? No podemos hacerlo solo con el enfoque 2D, lo he probado y sin éxito.

Por ejemplo, en el caso de una esfera, no podemos aplicar el enfoque 2D a la esfera. Entonces, ¿hay alguna manera de resolver este problema?

Gracias.

Actualización # 1:

A continuación se muestra el algoritmo para verificar qué borde tiene el mismo devanado. No funciona bien, no sé por qué. Teóricamente debería corregir todos los triángulos pero no está corrigiendo. Por ejemplo, en el caso de una verificación de esfera en la figura adjunta. Algo está mal con eso.

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

Respuestas a la pregunta(2)

Su respuesta a la pregunta