public class MLoopTri extends CFacade
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.
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.
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.totloop
- 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
///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;jMPoly
&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;j
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.e
), 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++){
///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]);
}
}
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]);
} }
} }
See #BKE_mesh_looptri_get_real_edges for a utility that does this.
A MLoopTri
edges.
Modifier and Type | Field and Description |
---|---|
static long[] |
__DNA__FIELD__poly
Field descriptor (offset) for struct member 'poly'.
|
static long[] |
__DNA__FIELD__tri
Field descriptor (offset) for struct member 'tri'.
|
static int |
__DNA__SDNA_INDEX
This is the sdna index of the struct MLoopTri.
|
__io__address, __io__arch_index, __io__block, __io__blockTable, __io__pointersize
Modifier | Constructor and Description |
---|---|
|
MLoopTri(long __address,
Block __block,
BlockTable __blockTable) |
protected |
MLoopTri(MLoopTri that) |
Modifier and Type | Method and Description |
---|---|
CPointer<MLoopTri> |
__io__addressof()
Instantiates a pointer on this instance.
|
int |
getPoly()
Get method for struct member 'poly'.
|
CArrayFacade<java.lang.Integer> |
getTri()
Get method for struct member 'tri'.
|
void |
setPoly(int poly)
Set method for struct member 'poly'.
|
void |
setTri(CArrayFacade<java.lang.Integer> tri)
Set method for struct member 'tri'.
|
__io__addressof, __io__addressof, __io__equals, __io__generic__copy, __io__generic__copy, __io__instanceof, __io__native__copy, __io__newInstance, __io__same__encoding, __io__sizeof, __io__sizeof, __io__subclassof
public static final int __DNA__SDNA_INDEX
It is required when allocating a new block to store data for MLoopTri.
org.cakelab.blender.io.dna.internal.StructDNA}
,
org.cakelab.blender.io.block.BlockTable#allocate}
,
Constant Field Valuespublic static final long[] __DNA__FIELD__tri
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});
public static final long[] __DNA__FIELD__poly
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});
public MLoopTri(long __address, Block __block, BlockTable __blockTable)
protected MLoopTri(MLoopTri that)
public CArrayFacade<java.lang.Integer> getTri() throws java.io.IOException
java.io.IOException
__DNA__FIELD__tri
public void setTri(CArrayFacade<java.lang.Integer> tri) throws java.io.IOException
java.io.IOException
__DNA__FIELD__tri
public int getPoly() throws java.io.IOException
java.io.IOException
__DNA__FIELD__poly
public void setPoly(int poly) throws java.io.IOException
java.io.IOException
__DNA__FIELD__poly