How to correct winding of triangles to counter-clockwise direction of a 3D Mesh model?

前端 未结 2 1009
无人及你
无人及你 2021-01-03 06:21

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 ask

相关标签:
2条回答
  • 2021-01-03 06:46

    Does your mesh include edge adjacency information? i.e. each triangle T contains three vertices A,B,C and three edges AB, BC and CA, where AB is a link to the triangle T1 which shares common vertices A,B and includes a new vertex D. Something like

    struct Vertex 
    {
     double x,y,z;
    };
    
    struct Triangle
    {
       int vertices[3],edges[3];
    };
    
    
    struct TriangleMesh
    {
       Vertex Vertices[];
       Triangle Triangles[];
    };
    

    If this is the case, for any triangle T = {{VA,VB,VC},{TAB,TBC,TCA}} with neighbour TE = &TAB at edge AB, A and B must appear in the reverse order for T and TE to have the same winding. e.g. TAB = {{VB,VA,VD},{TBA,TAD,TDA}} where TBA = &T. This can be used to give all the triangles the same winding.

    0 讨论(0)
  • 2021-01-03 06:47

    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.

    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))
    
    0 讨论(0)
提交回复
热议问题