Class MLoopTri


  • public class MLoopTri
    extends CFacade
    Generated facet for DNA struct type 'MLoopTri'.

    Class Documentation

    Blender Source Code

    MLoopTri 's are lightweight triangulation data, for functionality that doesn't support ngons (MPoly ). This is cache data created from (MPoly , MLoop & MVert arrays). There is no attempt to maintain this data's validity over time, any changes to the underlying mesh invalidate the MLoopTri array, which will need to be re-calculated.

    Users normally access this via #BKE_mesh_runtime_looptri_ensure. In rare cases its calculated directly, with #BKE_mesh_recalc_looptri.

    Typical usage includes:

    • OpenGL drawing.

    • #BVHTree creation.

    • Physics/collision detection.

    OpenGL drawing. #BVHTree creation. Physics/collision detection.

    Storing loop indices (instead of vertex indices) allows us to directly access UV's, vertex-colors as well as vertices. The index of the source polygon is stored as well, giving access to materials and polygon normals.

    Note

    This data is runtime only, never written to disk.

    This data is runtime only, never written to disk. Usage examples: material. ///accessoriginalmaterial. short short mpoly[lt->poly].mat_nr; mat_nr=mpoly[lt->poly].mat_nr; locations. ///accessvertexlocations. float float { *vtri_co[3]={ mvert[mloop[lt->tri[0]].v].co, mvert[mloop[lt->tri[0]].v].co, mvert[mloop[lt->tri[1]].v].co, mvert[mloop[lt->tri[1]].v].co, mvert[mloop[lt->tri[2]].v].co, mvert[mloop[lt->tri[2]].v].co, }; }; etc). ///accessUVcoordinates(worksforallloopdata,vertexcolors...etc). float float { *uvtri_co[3]={ mloopuv[lt->tri[0]].uv, mloopuv[lt->tri[0]].uv, mloopuv[lt->tri[1]].uv, mloopuv[lt->tri[1]].uv, mloopuv[lt->tri[2]].uv, mloopuv[lt->tri[2]].uv, }; }; ///accessoriginalmaterial. shortmat_nr=mpoly[lt->poly].mat_nr; ///accessvertexlocations. float*vtri_co[3]={ mvert[mloop[lt->tri[0]].v].co, mvert[mloop[lt->tri[1]].v].co, mvert[mloop[lt->tri[2]].v].co, }; ///accessUVcoordinates(worksforallloopdata,vertexcolors...etc). float*uvtri_co[3]={ mloopuv[lt->tri[0]].uv, mloopuv[lt->tri[1]].uv, mloopuv[lt->tri[2]].uv, };

    MLoopTri 's are allocated in an array, where each polygon's MLoopTri 's are stored contiguously, the number of triangles for each polygon is guaranteed to be (MPoly.getTotloop() - 2), even for degenerate geometry. See ME_POLY_TRI_TOT macro.

    It's also possible to perform a reverse lookup (find all MLoopTri 's for any given MPoly ).

    i ///loopoveralllooptri'sforagivenpolygon:i MPoly &mpoly[i]; *mp=&mpoly[i]; MLoopTri mp->loopstart )]; MLoopTri*lt=&looptri[poly_to_tri_count(i,mp->loopstart)]; int int ME_POLY_TRI_TOT (mp); j,lt_tot=ME_POLY_TRI_TOT(mp); for for { (j=0;jtri[0]].v, mloop[lt->tri[0]].v, mloop[lt->tri[1]].v, mloop[lt->tri[1]].v, mloop[lt->tri[2]].v, mloop[lt->tri[2]].v, }; }; printf( printf( %u\n" "tri%u%u%u\n" vtri[2]); ,vtri[0],vtri[1],vtri[2]); }; }; ///loopoveralllooptri'sforagivenpolygon:i MPoly*mp=&mpoly[i]; MLoopTri*lt=&looptri[poly_to_tri_count(i,mp->loopstart)]; intj,lt_tot=ME_POLY_TRI_TOT(mp); for(j=0;jtri[0]].v, mloop[lt->tri[1]].v, mloop[lt->tri[2]].v, }; printf("tri%u%u%u\n",vtri[0],vtri[1],vtri[2]); };

    It may also be useful to check whether or not two vertices of a triangle form an edge in the underlying mesh.

    This can be done by checking the edge of the referenced loop (MLoop.getE() ), the winding of the MLoopTri and the MLoop 's will always match, however the order of vertices in the edge is undefined.

    lt ///printrealedgesfromanMLoopTri:lt int int j_next; j,j_next; for for { (j=2,j_next=0;j_next<3;j=j_next++){ MEdge &medge[mloop[lt->tri[j]].e]; *ed=&medge[mloop[lt->tri[j]].e]; unsigned unsigned int int mloop[lt->tri[j_next]].v}; tri_edge[2]={mloop[lt->tri[j]].v,mloop[lt->tri[j_next]].v}; if if (((ed->v1 || (((ed->v1==tri_edge[0])&&(ed->v2==tri_edge[1]))|| ((ed->v1 tri_edge[0]))) ((ed->v1==tri_edge[1])&&(ed->v2==tri_edge[0]))) { { printf( printf( %u\n" "realedgefound%u%u\n" tri_edge[1]); ,tri_edge[0],tri_edge[1]); } } } } ///printrealedgesfromanMLoopTri:lt intj,j_next; for(j=2,j_next=0;j_next<3;j=j_next++){ MEdge*ed=&medge[mloop[lt->tri[j]].e]; unsignedinttri_edge[2]={mloop[lt->tri[j]].v,mloop[lt->tri[j_next]].v}; if(((ed->v1==tri_edge[0])&&(ed->v2==tri_edge[1]))|| ((ed->v1==tri_edge[1])&&(ed->v2==tri_edge[0]))) { printf("realedgefound%u%u\n",tri_edge[0],tri_edge[1]); } }

    See #BKE_mesh_looptri_get_real_edges for a utility that does this.

    Note

    A MLoopTri edges.

    A MLoopTri may be in the middle of an ngon and not reference any edges.

    • Field Detail

      • __DNA__SDNA_INDEX

        public static final int __DNA__SDNA_INDEX
        This is the sdna index of the struct MLoopTri.

        It is required when allocating a new block to store data for MLoopTri.

        See Also:
        StructDNA, BlockTable, Constant Field Values
      • __DNA__FIELD__tri

        public static final long[] __DNA__FIELD__tri
        Field descriptor (offset) for struct member 'tri'.

        Pointer Arithmetics

        This is how you get a reference on the corresponding field in the struct:

         MLoopTri mlooptri = ...;
         CPointer<Object> p = mlooptri.__dna__addressof(MLoopTri.__DNA__FIELD__tri);
         CPointer<CArrayFacade<Integer>> p_tri = p.cast(new Class[]{CArrayFacade.class, Integer.class});
         

        Metadata

        • Field: 'tri'
        • Signature: 'int[3]'
        • Actual Size (32bit/64bit): 12/12
      • __DNA__FIELD__poly

        public static final long[] __DNA__FIELD__poly
        Field descriptor (offset) for struct member 'poly'.

        Pointer Arithmetics

        This is how you get a reference on the corresponding field in the struct:

         MLoopTri mlooptri = ...;
         CPointer<Object> p = mlooptri.__dna__addressof(MLoopTri.__DNA__FIELD__poly);
         CPointer<Integer> p_poly = p.cast(new Class[]{Integer.class});
         

        Metadata

        • Field: 'poly'
        • Signature: 'int'
        • Actual Size (32bit/64bit): 4/4
    • Constructor Detail

      • MLoopTri

        public MLoopTri​(long __address,
                        Block __block,
                        BlockTable __blockTable)
      • MLoopTri

        protected MLoopTri​(MLoopTri that)
    • Method Detail

      • getTri

        public CArrayFacade<java.lang.Integer> getTri()
                                               throws java.io.IOException
        Get method for struct member 'tri'.
        Throws:
        java.io.IOException
        See Also:
        __DNA__FIELD__tri
      • setTri

        public void setTri​(CArrayFacade<java.lang.Integer> tri)
                    throws java.io.IOException
        Set method for struct member 'tri'.
        Throws:
        java.io.IOException
        See Also:
        __DNA__FIELD__tri
      • getPoly

        public int getPoly()
                    throws java.io.IOException
        Get method for struct member 'poly'.
        Throws:
        java.io.IOException
        See Also:
        __DNA__FIELD__poly
      • setPoly

        public void setPoly​(int poly)
                     throws java.io.IOException
        Set method for struct member 'poly'.
        Throws:
        java.io.IOException
        See Also:
        __DNA__FIELD__poly
      • __io__addressof

        public CPointer<MLoopTri> __io__addressof()
        Instantiates a pointer on this instance.