diff options
author | Campbell Barton <ideasman42@gmail.com> | 2011-11-29 06:58:38 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2011-11-29 06:58:38 +0400 |
commit | 9e39a66c938cd8cc3be8e054fdacf2ab9e8b7aa8 (patch) | |
tree | 5ac81576f22d7d97549412fd63691df95fcdde7f /source/blender/blenkernel/intern/anim.c | |
parent | b25f2386d0adfc33d5d7ea3398e10a791a9a6798 (diff) |
fix for duplifaces with quads/ngons, bmesh was using triangulated faces so each quad would result in 2 duplis.
Diffstat (limited to 'source/blender/blenkernel/intern/anim.c')
-rw-r--r-- | source/blender/blenkernel/intern/anim.c | 100 |
1 files changed, 57 insertions, 43 deletions
diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index 33df6132c13..4ebdd40a8fd 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -1012,11 +1012,12 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa DupliObject *dob; DerivedMesh *dm; Mesh *me= par->data; - MTFace *mtface; - MFace *mface; + MLoopUV *mloopuv; + MPoly *mpoly, *mp; + MLoop *mloop; MVert *mvert; float pmat[4][4], imat[3][3], (*orco)[3] = NULL, w; - int lay, oblay, totface, a; + int lay, oblay, totface, totloop, a; Scene *sce = NULL; Group *group = NULL; GroupObject *go = NULL; @@ -1033,18 +1034,24 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa int totvert; dm= editbmesh_get_derived_cage(scene, par, em, CD_MASK_BAREMESH); - totface= dm->getNumTessFaces(dm); - mface= MEM_mallocN(sizeof(MFace)*totface, "mface temp"); - dm->copyTessFaceArray(dm, mface); + totface= dm->getNumFaces(dm); + mpoly= MEM_mallocN(sizeof(MPoly)*totface, "mface temp"); + dm->copyPolyArray(dm, mpoly); + + totloop= dm->numLoopData; /* BMESH_TODO, we should have an api function for this! */ + mloop= MEM_mallocN(sizeof(MLoop)*totloop, "mloop temp"); + dm->copyLoopArray(dm, mloop); + totvert= dm->getNumVerts(dm); mvert= MEM_mallocN(sizeof(MVert)*totvert, "mvert temp"); dm->copyVertArray(dm, mvert); } else { dm = mesh_get_derived_deform(scene, par, CD_MASK_BAREMESH); - - totface= dm->getNumTessFaces(dm); - mface= dm->getTessFaceArray(dm); + + totface= dm->getNumFaces(dm); + mpoly= dm->getPolyArray(dm); + mloop= dm->getLoopArray(dm); mvert= dm->getVertArray(dm); } @@ -1052,11 +1059,11 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa orco= (float(*)[3])get_mesh_orco_verts(par); transform_mesh_orco_verts(me, orco, me->totvert, 0); - mtface= me->mtface; + mloopuv= me->mloopuv; } else { orco= NULL; - mtface= NULL; + mloopuv= NULL; } /* having to loop on scene OR group objects is NOT FUN */ @@ -1100,22 +1107,36 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa /* mballs have a different dupli handling */ if(ob->type!=OB_MBALL) ob->flag |= OB_DONE; /* doesnt render */ - for(a=0; a<totface; a++) { - int mv1 = mface[a].v1; - int mv2 = mface[a].v2; - int mv3 = mface[a].v3; - int mv4 = mface[a].v4; - float *v1= mvert[mv1].co; - float *v2= mvert[mv2].co; - float *v3= mvert[mv3].co; - float *v4= (mv4)? mvert[mv4].co: NULL; + for(a=0, mp= mpoly; a<totface; a++, mp++) { + int mv1; + int mv2; + int mv3; + /* int mv4; */ /* UNUSED */ + float *v1; + float *v2; + float *v3; + /* float *v4; */ /* UNUSED */ float cent[3], quat[4], mat[3][3], mat3[3][3], tmat[4][4], obmat[4][4]; + MLoop *loopstart= mloop + mp->loopstart; + + if (mp->totloop < 3) { + /* highly unlikely but to be safe */ + continue; + } + else { + v1= mvert[(mv1= loopstart[0].v)].co; + v2= mvert[(mv2= loopstart[1].v)].co; + v3= mvert[(mv3= loopstart[2].v)].co; + /* + if (mp->totloop > 3) { + v4= mvert[(mv4= loopstart[3].v)].co; + } + */ + } /* translation */ - if(v4) - cent_quad_v3(cent, v1, v2, v3, v4); - else - cent_tri_v3(cent, v1, v2, v3); + mesh_calc_poly_center(mp, loopstart, mvert, cent); + mul_m4_v3(pmat, cent); sub_v3_v3v3(cent, cent, pmat[3]); @@ -1131,7 +1152,7 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa /* scale */ if(par->transflag & OB_DUPLIFACES_SCALE) { - float size= v4? area_quad_v3(v1, v2, v3, v4): area_tri_v3(v1, v2, v3); + float size= mesh_calc_poly_area(mp, loopstart, mvert, NULL); size= sqrtf(size) * par->dupfacesca; mul_m3_fl(mat, size); } @@ -1144,27 +1165,19 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa dob= new_dupli_object(lb, ob, obmat, par->lay, a, OB_DUPLIFACES, animated); if(G.rendering) { - w= (mv4)? 0.25f: 1.0f/3.0f; + w= 1.0f / (float)mp->totloop; if(orco) { - madd_v3_v3v3fl(dob->orco, dob->orco, orco[mv1], w); - madd_v3_v3v3fl(dob->orco, dob->orco, orco[mv2], w); - madd_v3_v3v3fl(dob->orco, dob->orco, orco[mv3], w); - if(mv4) - madd_v3_v3v3fl(dob->orco, dob->orco, orco[mv4], w); + int j; + for (j = 0; j < mpoly->totloop; j++) { + madd_v3_v3fl(dob->orco, orco[loopstart[j].v], w); + } } - if(mtface) { - dob->uv[0] += w*mtface[a].uv[0][0]; - dob->uv[1] += w*mtface[a].uv[0][1]; - dob->uv[0] += w*mtface[a].uv[1][0]; - dob->uv[1] += w*mtface[a].uv[1][1]; - dob->uv[0] += w*mtface[a].uv[2][0]; - dob->uv[1] += w*mtface[a].uv[2][1]; - - if(mv4) { - dob->uv[0] += w*mtface[a].uv[3][0]; - dob->uv[1] += w*mtface[a].uv[3][1]; + if(mloopuv) { + int j; + for (j = 0; j < mpoly->totloop; j++) { + madd_v2_v2fl(dob->orco, mloopuv[loopstart[j].v].uv, w); } } } @@ -1188,7 +1201,8 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa } if(em) { - MEM_freeN(mface); + MEM_freeN(mpoly); + MEM_freeN(mloop); MEM_freeN(mvert); } |