part 1 of cleaning up my little array macro library to be a formal API. also removed...
[blender.git] / source / blender / blenkernel / intern / editderivedbmesh.c
index c34f5253a4236c150dd2550a520f679ca4cef726..6aca8d51bc26032e2cc8d2d3ed2b277e9ebe0584 100644 (file)
@@ -60,6 +60,7 @@
 #include "BLI_memarena.h"
 #include "BLI_scanfill.h"
 #include "BLI_ghash.h"
+#include "BLI_array.h"
 
 #include "BKE_cdderivedmesh.h"
 #include "BKE_customdata.h"
@@ -124,7 +125,7 @@ static void BMEdit_RecalcTesselation_intern(BMEditMesh *tm)
 {
        BMesh *bm = tm->bm;
        BMLoop **looptris = NULL;
-       V_DYNDECLARE(looptris);
+       BLI_array_declare(looptris);
        BMIter iter, liter;
        BMFace *f;
        BMLoop *l;
@@ -132,6 +133,45 @@ static void BMEdit_RecalcTesselation_intern(BMEditMesh *tm)
        
        if (tm->looptris) MEM_freeN(tm->looptris);
 
+#if 0 //simple quad/triangle code for performance testing purposes
+       looptris = MEM_callocN(sizeof(void*)*bm->totface*8, "looptris");
+
+       f = BMIter_New(&iter, bm, BM_FACES_OF_MESH, NULL);
+       for ( ; f; f=BMIter_Step(&iter)) {
+               EditVert *v, *lastv=NULL, *firstv=NULL;
+               EditEdge *e;
+               EditFace *efa;
+
+               /*don't consider two-edged faces*/
+               if (f->len < 3) continue;
+               
+               //BLI_array_growone(looptris);
+               //BLI_array_growone(looptris);
+               //BLI_array_growone(looptris);
+
+               looptris[i*3] = f->loopbase;
+               looptris[i*3+1] = f->loopbase->head.next;
+               looptris[i*3+2] = f->loopbase->head.next->next;
+               i++;
+
+               if (f->len > 3) {
+                       //BLI_array_growone(looptris);
+                       //BLI_array_growone(looptris);
+                       //BLI_array_growone(looptris);
+
+                       looptris[i*3] = f->loopbase;
+                       looptris[i*3+1] = f->loopbase->head.next->next;
+                       looptris[i*3+2] = f->loopbase->head.next->next->next;
+                       i++;
+               }
+
+       }
+
+       tm->tottri = i;
+       tm->looptris = looptris;
+       return;
+#endif
+
        f = BMIter_New(&iter, bm, BM_FACES_OF_MESH, NULL);
        for ( ; f; f=BMIter_Step(&iter)) {
                EditVert *v, *lastv=NULL, *firstv=NULL;
@@ -166,9 +206,9 @@ static void BMEdit_RecalcTesselation_intern(BMEditMesh *tm)
                for (efa = fillfacebase.first; efa; efa=efa->next) {
                        BMLoop *l1, *l2, *l3;
 
-                       V_GROW(looptris);
-                       V_GROW(looptris);
-                       V_GROW(looptris);
+                       BLI_array_growone(looptris);
+                       BLI_array_growone(looptris);
+                       BLI_array_growone(looptris);
                        
                        looptris[i*3] = l1 = efa->v1->tmp.p;
                        looptris[i*3+1] = l2 = efa->v2->tmp.p;
@@ -213,6 +253,26 @@ void BMEdit_RecalcTesselation(BMEditMesh *tm)
        }
 }
 
+void BMEdit_UpdateLinkedCustomData(BMEditMesh *em)
+{
+       BMesh *bm = em->bm;
+       int act;
+
+       if (CustomData_has_layer(&bm->pdata, CD_MTEXPOLY)) {
+               act = CustomData_get_active_layer(&bm->pdata, CD_MTEXPOLY);
+               CustomData_set_layer_active(&bm->ldata, CD_MLOOPUV, act);
+
+               act = CustomData_get_render_layer(&bm->pdata, CD_MTEXPOLY);
+               CustomData_set_layer_render(&bm->ldata, CD_MLOOPUV, act);
+
+               act = CustomData_get_clone_layer(&bm->pdata, CD_MTEXPOLY);
+               CustomData_set_layer_clone(&bm->ldata, CD_MLOOPUV, act);
+
+               act = CustomData_get_mask_layer(&bm->pdata, CD_MTEXPOLY);
+               CustomData_set_layer_mask(&bm->ldata, CD_MLOOPUV, act);
+       }
+}
+
 /*does not free the BMEditMesh struct itself*/
 void BMEdit_Free(BMEditMesh *em)
 {
@@ -275,6 +335,9 @@ typedef struct EditDerivedBMesh {
        /*private variables, for number of verts/edges/faces
          within the above hash/table members*/
        int tv, te, tf;
+
+       /*customdata layout of the tesselated faces*/
+       CustomData tessface_layout;
 } EditDerivedBMesh;
 
 static void bmdm_recalc_lookups(EditDerivedBMesh *bmdm)
@@ -337,7 +400,7 @@ static void bmDM_recalcTesselation(DerivedMesh *dm)
 {
        EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
 
-       bmdm_recalc_lookups(bmdm);
+       //bmdm_recalc_lookups(bmdm);
 }
 
 static void bmDM_foreachMappedVert(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no_f, short *no_s), void *userData)
@@ -1312,6 +1375,8 @@ void bmDM_faceIterStep(void *self)
        iter->head.flags = BMFlags_To_MEFlags(iter->f);
        iter->head.index++;
 
+       iter->head.len = iter->f->len;
+
        iter->nextf = BMIter_Step(&iter->iter);
 
        if (!iter->nextf) iter->head.done = 1;
@@ -1330,16 +1395,16 @@ void bmDM_loopIterStep(void *self)
 {
        bmDM_loopIter *iter = self;
 
-       iter->l = iter->nextl;
+       iter->l = BMIter_Step(&iter->iter);
+       if (!iter->l) {
+               iter->head.done = 1;
+               return;
+       }
 
        bmvert_to_mvert(iter->l->v, &iter->head.v);
        iter->head.index++;
        iter->head.vindex = BMINDEX_GET(iter->l->v);
        iter->head.eindex = BMINDEX_GET(iter->l->e);
-
-       iter->nextl = BMIter_Step(&iter->iter);
-
-       if (!iter->nextl) iter->head.done = 1;
 }
 
 void *bmDM_getLoopCDData(void *self, int type, int layer)
@@ -1378,15 +1443,15 @@ DMLoopIter *bmDM_newLoopsIter(void *faceiter)
 
        iter->bm = fiter->bm;
        iter->f = fiter->f;
-       iter->nextl = BMIter_New(&iter->iter, iter->bm, BM_LOOPS_OF_FACE, iter->f);
+       iter->l = BMIter_New(&iter->iter, iter->bm, BM_LOOPS_OF_FACE, iter->f);
 
        iter->head.step = bmDM_loopIterStep;
        iter->head.getLoopCDData = bmDM_getLoopCDData;
        iter->head.getVertCDData = bmDM_getVertCDData;
 
-       bmvert_to_mvert(iter->nextl->v, &iter->head.v);
-       iter->head.vindex = BMINDEX_GET(iter->nextl->v);
-       iter->head.eindex = BMINDEX_GET(iter->nextl->e);
+       bmvert_to_mvert(iter->l->v, &iter->head.v);
+       iter->head.vindex = BMINDEX_GET(iter->l->v);
+       iter->head.eindex = BMINDEX_GET(iter->l->e);
 
        return (DMLoopIter*) iter;
 }
@@ -1438,9 +1503,9 @@ static void bmDM_release(void *dm)
                        MEM_freeN(bmdm->faceNos);
                }
                
-               BLI_ghash_free(bmdm->fhash, NULL, NULL);
-               BLI_ghash_free(bmdm->ehash, NULL, NULL);
-               BLI_ghash_free(bmdm->vhash, NULL, NULL);
+               if (bmdm->fhash) BLI_ghash_free(bmdm->fhash, NULL, NULL);
+               if (bmdm->ehash) BLI_ghash_free(bmdm->ehash, NULL, NULL);
+               if (bmdm->vhash) BLI_ghash_free(bmdm->vhash, NULL, NULL);
 
                if (bmdm->vtable) MEM_freeN(bmdm->vtable);
                if (bmdm->etable) MEM_freeN(bmdm->etable);
@@ -1450,19 +1515,76 @@ static void bmDM_release(void *dm)
        }
 }
 
+CustomData *bmDm_getVertDataLayout(DerivedMesh *dm)
+{
+       EditDerivedBMesh *bmdm = (EditDerivedBMesh*)dm;
+
+       return &bmdm->tc->bm->vdata;
+}
+
+CustomData *bmDm_getEdgeDataLayout(DerivedMesh *dm)
+{
+       EditDerivedBMesh *bmdm = (EditDerivedBMesh*)dm;
+
+       return &bmdm->tc->bm->edata;
+}
+
+CustomData *bmDm_getTessFaceDataLayout(DerivedMesh *dm)
+{
+       EditDerivedBMesh *bmdm = (EditDerivedBMesh*)dm;
+
+       return &bmdm->tessface_layout;
+}
+
+CustomData *bmDm_getLoopDataLayout(DerivedMesh *dm)
+{
+       EditDerivedBMesh *bmdm = (EditDerivedBMesh*)dm;
+
+       return &bmdm->tc->bm->ldata;
+}
+
+CustomData *bmDm_getFaceDataLayout(DerivedMesh *dm)
+{
+       EditDerivedBMesh *bmdm = (EditDerivedBMesh*)dm;
+
+       return &bmdm->tc->bm->pdata;
+}
+
+
 DerivedMesh *getEditDerivedBMesh(BMEditMesh *em, Object *ob,
                                            float (*vertexCos)[3])
 {
        EditDerivedBMesh *bmdm = MEM_callocN(sizeof(*bmdm), "bmdm");
        BMesh *bm = em->bm;
-
+       int i;
+       
        bmdm->tc = em;
 
        DM_init((DerivedMesh*)bmdm, em->bm->totvert, em->bm->totedge, em->tottri,
                 em->bm->totloop, em->bm->totface);
+       
+       for (i=0; i<bm->ldata.totlayer; i++) {
+               if (bm->ldata.layers[i].type == CD_MLOOPCOL) {
+                       CustomData_add_layer(&bmdm->tessface_layout, CD_MCOL, CD_ASSIGN, NULL, 0);
+               } else if (bm->ldata.layers[i].type == CD_MLOOPUV) {
+                       CustomData_add_layer(&bmdm->tessface_layout, CD_MTFACE, CD_ASSIGN, NULL, 0);
+               }
+       }
+
+       bmdm->dm.numVertData = bm->totvert;
+       bmdm->dm.numEdgeData = bm->totedge;
+       bmdm->dm.numFaceData = em->tottri;
+       bmdm->dm.numLoopData = bm->totloop;
+       bmdm->dm.numPolyData = bm->totface;
 
        bmdm->dm.getMinMax = bmDM_getMinMax;
 
+       bmdm->dm.getVertDataLayout = bmDm_getVertDataLayout;
+       bmdm->dm.getEdgeDataLayout = bmDm_getEdgeDataLayout;
+       bmdm->dm.getTessFaceDataLayout = bmDm_getTessFaceDataLayout;
+       bmdm->dm.getLoopDataLayout = bmDm_getLoopDataLayout;
+       bmdm->dm.getFaceDataLayout = bmDm_getFaceDataLayout;
+
        bmdm->dm.getNumVerts = bmDM_getNumVerts;
        bmdm->dm.getNumEdges = bmDM_getNumEdges;
        bmdm->dm.getNumTessFaces = bmDM_getNumTessFaces;
@@ -1548,7 +1670,7 @@ DerivedMesh *getEditDerivedBMesh(BMEditMesh *em, Object *ob,
                }
        }
 
-       bmdm_recalc_lookups(bmdm);
+       //bmdm_recalc_lookups(bmdm);
 
        return (DerivedMesh*) bmdm;
 }