Array modifier is now implemented using bmesh
authorJoseph Eagar <joeedh@gmail.com>
Tue, 23 Jun 2009 05:35:49 +0000 (05:35 +0000)
committerJoseph Eagar <joeedh@gmail.com>
Tue, 23 Jun 2009 05:35:49 +0000 (05:35 +0000)
(though it's not completely feature-complete yet).
I ported over the remove doubles code from the
old bmesh branch for this, and split it into two
bmops, "Weld Verts" and "Remove Doubles".

Weld verts welds specific verts together, while remove
doubles finds doubles and welds them.

I also reverted the hotkey change I made earlier.

35 files changed:
source/blender/blenkernel/BKE_DerivedMesh.h
source/blender/blenkernel/BKE_customdata.h
source/blender/blenkernel/intern/DerivedMesh.c
source/blender/blenkernel/intern/cdderivedmesh.c
source/blender/blenkernel/intern/customdata.c
source/blender/blenkernel/intern/editderivedbmesh.c
source/blender/blenkernel/intern/modifier.c
source/blender/blenkernel/intern/modifiers_bmesh.c [new file with mode: 0644]
source/blender/blenkernel/intern/subsurf_ccg.c
source/blender/bmesh/bmesh.h
source/blender/bmesh/bmesh_operator_api.h
source/blender/bmesh/bmesh_queries.h
source/blender/bmesh/intern/bmesh_construct.c
source/blender/bmesh/intern/bmesh_eulers.c
source/blender/bmesh/intern/bmesh_interp.c
source/blender/bmesh/intern/bmesh_mesh.c
source/blender/bmesh/intern/bmesh_mods.c
source/blender/bmesh/intern/bmesh_opdefines.c
source/blender/bmesh/intern/bmesh_operators.c
source/blender/bmesh/intern/bmesh_operators_private.h
source/blender/bmesh/intern/bmesh_queries.c
source/blender/bmesh/intern/bmesh_structure.c
source/blender/bmesh/intern/bmesh_to_editmesh.c
source/blender/bmesh/intern/editmesh_to_bmesh.c
source/blender/bmesh/operators/createops.c
source/blender/bmesh/operators/dissolveops.c
source/blender/bmesh/operators/extrudeops.c
source/blender/bmesh/operators/mesh_conv.c
source/blender/bmesh/operators/subdivideop.c
source/blender/bmesh/operators/triangulateop.c
source/blender/bmesh/operators/utils.c
source/blender/editors/mesh/bmesh_tools.c
source/blender/editors/mesh/editmesh_lib.c
source/blender/editors/mesh/mesh_ops.c
source/blender/editors/space_view3d/view3d_buttons.c

index 926ecb0f7992f36d5c6c0a9ef90766b382d9c66f..bb50056b7f2d19c8605817afab7d1eba4fe2ff69 100644 (file)
@@ -175,6 +175,19 @@ struct DerivedMesh {
        void *(*getVertDataArray)(DerivedMesh *dm, int type);
        void *(*getEdgeDataArray)(DerivedMesh *dm, int type);
        void *(*getTessFaceDataArray)(DerivedMesh *dm, int type);
+       
+       /*retrieves the base CustomData structures for 
+         verts/edges/tessfaces/loops/facdes*/
+       CustomData *(*getVertDataLayout)(DerivedMesh *dm);
+       CustomData *(*getEdgeDataLayout)(DerivedMesh *dm);
+       CustomData *(*getTessFaceDataLayout)(DerivedMesh *dm);
+       CustomData *(*getLoopDataLayout)(DerivedMesh *dm);
+       CustomData *(*getFaceDataLayout)(DerivedMesh *dm);
+       
+       /*copies all customdata for an element source into dst at index dest*/
+       void (*copyFromVertCData)(DerivedMesh *dm, int source, CustomData *dst, int dest);
+       void (*copyFromEdgeCData)(DerivedMesh *dm, int source, CustomData *dst, int dest);
+       void (*copyFromFaceCData)(DerivedMesh *dm, int source, CustomData *dst, int dest);
 
        /* Iterate over each mapped vertex in the derived mesh, calling the
         * given function with the original vert and the mapped vert's new
index f083703c65a182ba252a1e6c4d07eae37ede6bea..b9e27a1abd44ddbd419866b04a6a09d2cc2279f1 100644 (file)
@@ -69,6 +69,12 @@ void CustomData_copy(const struct CustomData *source, struct CustomData *dest,
 void CustomData_merge(const struct CustomData *source, struct CustomData *dest,
                       CustomDataMask mask, int alloctype, int totelem);
 
+/*bmesh version of CustomData_merge; merges the layouts of source and dest,
+  then goes through the mesh and makes sure all the customdata blocks are
+  consistent with the new layout.*/
+void CustomData_bmesh_merge(struct CustomData *source, struct CustomData *dest, 
+                            int mask, int alloctype, struct BMesh *bm, int type);
+
 /* frees data associated with a CustomData object (doesn't free the object
  * itself, though)
  */
index d8e5ebabe74855e32c382b29ba9ff68db0b8504b..7bd47d4a4c0ef5158b3e7da588556adc67e584ae 100644 (file)
@@ -163,6 +163,31 @@ static MFace *dm_dupFaceArray(DerivedMesh *dm)
        return tmp;
 }
 
+CustomData *dm_getVertCData(DerivedMesh *dm)
+{
+       return &dm->vertData;
+}
+
+CustomData *dm_getEdgeCData(DerivedMesh *dm)
+{
+       return &dm->edgeData;
+}
+
+CustomData *dm_getFaceCData(DerivedMesh *dm)
+{
+       return &dm->faceData;
+}
+
+CustomData *dm_getLoopCData(DerivedMesh *dm)
+{
+       return &dm->loopData;
+}
+
+CustomData *dm_getPolyCData(DerivedMesh *dm)
+{
+       return &dm->polyData;
+}
+
 void DM_init_funcs(DerivedMesh *dm)
 {
        /* default function implementations */
@@ -173,6 +198,12 @@ void DM_init_funcs(DerivedMesh *dm)
        dm->dupEdgeArray = dm_dupEdgeArray;
        dm->dupTessFaceArray = dm_dupFaceArray;
 
+       dm->getVertDataLayout = dm_getVertCData;
+       dm->getEdgeDataLayout = dm_getEdgeCData;
+       dm->getTessFaceDataLayout = dm_getFaceCData;
+       dm->getLoopDataLayout = dm_getLoopCData;
+       dm->getFaceDataLayout = dm_getPolyCData;
+
        dm->getVertData = DM_get_vert_data;
        dm->getEdgeData = DM_get_edge_data;
        dm->getTessFaceData = DM_get_face_data;
index 542e09162170ee9639ec6ce70791a02954dd468f..1e12fcb23783bb3bdfa31c6dd3b68d4cd186334d 100644 (file)
@@ -1089,7 +1089,7 @@ static void loops_to_customdata_corners(BMesh *bm, CustomData *facedata,
 
        for(i=0; i < numTex; i++){
                texface = CustomData_get_n(facedata, CD_MTFACE, cdindex, i);
-               texpoly = CustomData_bmesh_get_n(&bm->pdata, f->data, CD_MTEXPOLY, i);
+               texpoly = CustomData_bmesh_get_n(&bm->pdata, f->head.data, CD_MTEXPOLY, i);
                
                texface->tpage = texpoly->tpage;
                texface->flag = texpoly->flag;
@@ -1100,7 +1100,7 @@ static void loops_to_customdata_corners(BMesh *bm, CustomData *facedata,
        
                for (j=0; j<3; i++) {
                        l = l3[j];
-                       mloopuv = CustomData_bmesh_get_n(&bm->ldata, l->data, CD_MLOOPUV, i);
+                       mloopuv = CustomData_bmesh_get_n(&bm->ldata, l->head.data, CD_MLOOPUV, i);
                        texface->uv[j][0] = mloopuv->uv[0];
                        texface->uv[j][1] = mloopuv->uv[1];
                }
@@ -1111,7 +1111,7 @@ static void loops_to_customdata_corners(BMesh *bm, CustomData *facedata,
                
                for (j=0; j<3; j++) {
                        l = l3[j];
-                       mloopcol = CustomData_bmesh_get_n(&bm->ldata, l->data, CD_MLOOPCOL, i);
+                       mloopcol = CustomData_bmesh_get_n(&bm->ldata, l->head.data, CD_MLOOPCOL, i);
                        mcol[j].r = mloopcol->r;
                        mcol[j].g = mloopcol->g;
                        mcol[j].b = mloopcol->b;
@@ -1137,14 +1137,17 @@ DerivedMesh *CDDM_from_BMEditMesh(BMEditMesh *em, Mesh *me)
        MPoly *mpoly = cddm->mpoly;
        int numCol = CustomData_number_of_layers(&em->bm->ldata, CD_MLOOPCOL);
        int numTex = CustomData_number_of_layers(&em->bm->pdata, CD_MTEXPOLY);
-       int i, j, *index;
+       int i, j, *index, add_orig;
 
        dm->deformedOnly = 1;
+       
+       /*don't add origindex layer if one already exists*/
+       add_orig = !CustomData_has_layer(&em->bm->pdata, CD_ORIGINDEX);
 
        CustomData_merge(&em->bm->vdata, &dm->vertData, CD_MASK_DERIVEDMESH,
                         CD_CALLOC, dm->numVertData);
-       /* CustomData_merge(&em->edata, &dm->edgeData, CD_MASK_DERIVEDMESH,
-                        CD_CALLOC, dm->numEdgeData); */
+       CustomData_merge(&em->bm->edata, &dm->edgeData, CD_MASK_DERIVEDMESH,
+                        CD_CALLOC, dm->numEdgeData);
        CustomData_merge(&em->bm->pdata, &dm->faceData, CD_MASK_DERIVEDMESH,
                         CD_CALLOC, dm->numFaceData);
        CustomData_merge(&em->bm->ldata, &dm->loopData, CD_MASK_DERIVEDMESH,
@@ -1174,6 +1177,8 @@ DerivedMesh *CDDM_from_BMEditMesh(BMEditMesh *em, Mesh *me)
 
                VECCOPY(mv->co, eve->co);
 
+               BMINDEX_SET(eve, i);
+
                mv->no[0] = eve->no[0] * 32767.0;
                mv->no[1] = eve->no[1] * 32767.0;
                mv->no[2] = eve->no[2] * 32767.0;
@@ -1182,9 +1187,9 @@ DerivedMesh *CDDM_from_BMEditMesh(BMEditMesh *em, Mesh *me)
                mv->mat_nr = 0;
                mv->flag = BMFlags_To_MEFlags(eve);
 
-               *index = i;
+               if (add_orig) *index = i;
 
-               CustomData_from_bmesh_block(&bm->vdata, &dm->vertData, eve->data, i);
+               CustomData_from_bmesh_block(&bm->vdata, &dm->vertData, eve->head.data, i);
        }
 
        index = dm->getEdgeDataArray(dm, CD_ORIGINDEX);
@@ -1192,6 +1197,8 @@ DerivedMesh *CDDM_from_BMEditMesh(BMEditMesh *em, Mesh *me)
        for (i=0; eed; eed=BMIter_Step(&iter), i++, index++) {
                MEdge *med = &medge[i];
 
+               BMINDEX_SET(eed, i);
+
                med->v1 = BMINDEX_GET(eed->v1);
                med->v2 = BMINDEX_GET(eed->v2);
                med->crease = (unsigned char) (eed->crease * 255.0f);
@@ -1200,9 +1207,8 @@ DerivedMesh *CDDM_from_BMEditMesh(BMEditMesh *em, Mesh *me)
                
                med->flag = BMFlags_To_MEFlags(eed);
 
-               *index = i;
-
-               /* CustomData_from_em_block(&em->edata, &dm->edgeData, eed->data, i); */
+               CustomData_from_bmesh_block(&bm->edata, &dm->edgeData, eed->head.data, i);
+               if (add_orig) *index = i;
        }
 
        efa = BMIter_New(&iter, bm, BM_FACES_OF_MESH, NULL);
@@ -1222,15 +1228,14 @@ DerivedMesh *CDDM_from_BMEditMesh(BMEditMesh *em, Mesh *me)
                mf->v4 = 0;
                mf->mat_nr = efa->mat_nr;
                mf->flag = BMFlags_To_MEFlags(efa);
-
-               *index = BMINDEX_GET(efa);
+               
+               *index = add_orig ? BMINDEX_GET(efa) : *(int*)CustomData_bmesh_get(&bm->pdata, efa->head.data, CD_ORIGINDEX);
 
                loops_to_customdata_corners(bm, &dm->faceData, i, l, numCol, numTex);
-
                test_index_face(mf, &dm->faceData, i, 3);
        }
        
-       index = CustomData_get(&dm->polyData, 0, CD_ORIGINDEX);
+       index = CustomData_get_layer(&dm->polyData, CD_ORIGINDEX);
        j = 0;
        efa = BMIter_New(&iter, bm, BM_FACES_OF_MESH, NULL);
        for (i=0; efa; i++, efa=BMIter_Step(&iter), index++) {
@@ -1245,13 +1250,15 @@ DerivedMesh *CDDM_from_BMEditMesh(BMEditMesh *em, Mesh *me)
                BM_ITER(l, &liter, bm, BM_LOOPS_OF_FACE, efa) {
                        mloop->v = BMINDEX_GET(l->v);
                        mloop->e = BMINDEX_GET(l->e);
-                       CustomData_from_bmesh_block(&bm->ldata, &dm->loopData, l->data, j);
+                       CustomData_from_bmesh_block(&bm->ldata, &dm->loopData, l->head.data, j);
 
                        j++;
                        mloop++;
                }
 
-               *index = i;
+               CustomData_from_bmesh_block(&bm->pdata, &dm->polyData, efa->head.data, i);
+
+               if (add_orig) *index = i;
        }
 
        return dm;
@@ -1357,8 +1364,6 @@ void cddm_loopiter_step(void *self)
        liter->head.eindex = ml->e;
        liter->head.v = liter->cddm->mvert[ml->v];
        liter->head.vindex = ml->v;
-
-       return;
 }
 
 DMFaceIter *cdDM_newFaceIter(DerivedMesh *source)
index b088f33c7ef36be5050674c2d58100c5d55b24a7..5c29ca02e7ead2561f1c26bd22202df550d1741f 100644 (file)
@@ -45,6 +45,8 @@
 
 #include "MEM_guardedalloc.h"
 
+#include "bmesh.h"
+
 #include <math.h>
 #include <string.h>
 
@@ -753,7 +755,7 @@ const CustomDataMask CD_MASK_DERIVEDMESH =
        CD_MASK_MCOL | CD_MASK_ORIGINDEX | CD_MASK_PROP_FLT | CD_MASK_PROP_INT |
        CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_MTEXPOLY |
        CD_MASK_PROP_STR | CD_MASK_ORIGSPACE | CD_MASK_ORCO | CD_MASK_TANGENT | CD_MASK_WEIGHT_MCOL;
-const CustomDataMask CD_MASK_BMESH = 
+const CustomDataMask CD_MASK_BMESH = CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_MTEXPOLY |
        CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR;
 const CustomDataMask CD_MASK_FACECORNERS =
        CD_MASK_MTFACE | CD_MASK_MCOL | CD_MASK_MTEXPOLY | CD_MASK_MLOOPUV |
@@ -1862,6 +1864,54 @@ void CustomData_bmesh_init_pool(CustomData *data, int allocsize){
        if(data->totlayer)data->pool = BLI_mempool_create(data->totsize, allocsize, allocsize);
 }
 
+void CustomData_bmesh_merge(CustomData *source, CustomData *dest, 
+                            int mask, int alloctype, BMesh *bm, int type)
+{
+       BMHeader *h;
+       BMIter iter;
+       CustomData destold = *dest;
+       void *tmp;
+       int i, t;
+       
+       CustomData_merge(source, dest, mask, alloctype, 0);
+       CustomData_bmesh_init_pool(dest, 512);
+
+       switch (type) {
+               case BM_VERT:
+                       t = BM_VERTS_OF_MESH; break;
+               case BM_EDGE:
+                       t = BM_EDGES_OF_MESH; break;
+               case BM_LOOP:
+                       t = BM_LOOPS_OF_FACE; break;
+               case BM_FACE:
+                       t = BM_FACES_OF_MESH; break;
+       }
+
+       if (t != BM_LOOPS_OF_FACE) {
+               /*ensure all current elements follow new customdata layout*/
+               BM_ITER(h, &iter, bm, t, NULL) {
+                       CustomData_bmesh_copy_data(&destold, dest, h->data, &tmp);
+                       CustomData_bmesh_free_block(&destold, &h->data);
+                       h->data = tmp;
+               }
+       } else {
+               BMFace *f;
+               BMLoop *l;
+               BMIter liter;
+
+               /*ensure all current elements follow new customdata layout*/
+               BM_ITER(f, &iter, bm, BM_FACES_OF_MESH, NULL) {
+                       BM_ITER(l, &liter, bm, BM_LOOPS_OF_FACE, f) {
+                               CustomData_bmesh_copy_data(&destold, dest, h->data, &tmp);
+                               CustomData_bmesh_free_block(&destold, &h->data);
+                               h->data = tmp;
+                       }
+               }
+       }
+
+       if (destold.pool) BLI_mempool_destroy(destold.pool);
+}
+
 void CustomData_bmesh_free_block(CustomData *data, void **block)
 {
     const LayerTypeInfo *typeInfo;
index 6f9ddd576becc2df7ba88414739597d5e3f5d9c7..2964914de4b6a2cd47098b6e0da0c6dd58cee3e8 100644 (file)
@@ -59,6 +59,7 @@
 #include "BLI_linklist.h"
 #include "BLI_memarena.h"
 #include "BLI_scanfill.h"
+#include "BLI_ghash.h"
 
 #include "BKE_cdderivedmesh.h"
 #include "BKE_customdata.h"
@@ -119,7 +120,7 @@ BMEditMesh *BMEdit_Copy(BMEditMesh *tm)
        return tm2;
 }
 
-void BMEdit_RecalcTesselation(BMEditMesh *tm)
+static void BMEdit_RecalcTesselation_intern(BMEditMesh *tm)
 {
        BMesh *bm = tm->bm;
        BMLoop **looptris = NULL;
@@ -208,6 +209,21 @@ void BMEdit_RecalcTesselation(BMEditMesh *tm)
        tm->looptris = looptris;
 }
 
+void BMEdit_RecalcTesselation(BMEditMesh *tm)
+{
+       BMEdit_RecalcTesselation_intern(tm);
+
+       if (tm->derivedFinal && tm->derivedFinal == tm->derivedCage) {
+               if (tm->derivedFinal->recalcTesselation) 
+                       tm->derivedFinal->recalcTesselation(tm->derivedFinal);
+       } else if (tm->derivedFinal) {
+               if (tm->derivedCage->recalcTesselation) 
+                       tm->derivedCage->recalcTesselation(tm->derivedCage);
+               if (tm->derivedFinal->recalcTesselation) 
+                       tm->derivedFinal->recalcTesselation(tm->derivedFinal);
+       }
+}
+
 /*does not free the BMEditMesh struct itself*/
 void BMEdit_Free(BMEditMesh *em)
 {
@@ -259,8 +275,74 @@ typedef struct EditDerivedBMesh {
        float (*vertexCos)[3];
        float (*vertexNos)[3];
        float (*faceNos)[3];
+
+       /*lookup caches; these are rebuilt on dm->RecalcTesselation()
+         (or when the derivedmesh is created, of course)*/
+       GHash *vhash, *ehash, *fhash;
+       BMVert **vtable;
+       BMEdge **etable;
+       BMFace **ftable;
+
+       /*private variables, for number of verts/edges/faces
+         within the above hash/table members*/
+       int tv, te, tf;
 } EditDerivedBMesh;
 
+static void bmdm_recalc_lookups(EditDerivedBMesh *bmdm)
+{
+       BMIter iter;
+       BMHeader *h;
+       int a, i, iters[3] = {BM_VERTS_OF_MESH, BM_EDGES_OF_MESH, BM_FACES_OF_MESH};
+       
+       bmdm->tv = bmdm->tc->bm->totvert;
+       bmdm->te = bmdm->tc->bm->totedge;
+       bmdm->tf = bmdm->tc->bm->totface;
+
+       if (bmdm->vhash) BLI_ghash_free(bmdm->vhash, NULL, NULL);
+       if (bmdm->ehash) BLI_ghash_free(bmdm->ehash, NULL, NULL);
+       if (bmdm->fhash) BLI_ghash_free(bmdm->fhash, NULL, NULL);
+
+       bmdm->vhash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
+       bmdm->ehash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
+       bmdm->fhash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
+       
+       if (bmdm->vtable) MEM_freeN(bmdm->vtable);
+       if (bmdm->etable) MEM_freeN(bmdm->etable);
+       if (bmdm->ftable) MEM_freeN(bmdm->ftable);
+       
+       bmdm->vtable = MEM_mallocN(sizeof(void**)*bmdm->tc->bm->totvert, "bmdm->vtable");
+       bmdm->etable = MEM_mallocN(sizeof(void**)*bmdm->tc->bm->totedge, "bmdm->etable");
+       bmdm->ftable = MEM_mallocN(sizeof(void**)*bmdm->tc->bm->totface, "bmdm->ftable");
+       
+       for (a=0; a<3; a++) {
+               h = BMIter_New(&iter, bmdm->tc->bm, iters[a], NULL);
+               for (i=0; h; h=BMIter_Step(&iter), i++) {
+                       switch (a) {
+                               case 0:
+                                       bmdm->vtable[i] = (BMVert*) h;
+                                       BLI_ghash_insert(bmdm->vhash, h, SET_INT_IN_POINTER(i));
+                                       break;
+                               case 1:
+                                       bmdm->etable[i] = (BMEdge*) h;
+                                       BLI_ghash_insert(bmdm->ehash, h, SET_INT_IN_POINTER(i));
+                                       break;
+                               case 2:
+                                       bmdm->ftable[i] = (BMFace*) h;
+                                       BLI_ghash_insert(bmdm->fhash, h, SET_INT_IN_POINTER(i));
+                                       break;
+
+                       }
+               }
+       }
+}
+
+static void bmDM_recalcTesselation(DerivedMesh *dm)
+{
+       EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
+
+       BMEdit_RecalcTesselation_intern(bmdm->tc);
+       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)
 {
@@ -946,6 +1028,13 @@ static int bmDM_getNumTessFaces(DerivedMesh *dm)
        return bmdm->tc->tottri;
 }
 
+static int bmDM_getNumFaces(DerivedMesh *dm)
+{
+       EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
+       
+       return bmdm->tc->bm->totface;
+}
+
 static int bmvert_to_mvert(BMVert *ev, MVert *vert_r)
 {
        VECCOPY(vert_r->co, ev->co);
@@ -966,14 +1055,12 @@ static void bmDM_getVert(DerivedMesh *dm, int index, MVert *vert_r)
        BMIter iter;
        int i;
 
-       ev = BMIter_New(&iter, ((EditDerivedBMesh *)dm)->tc->bm, BM_VERTS_OF_MESH, NULL);
-       for(i = 0; i < index; ++i) ev = BMIter_Step(&iter);
-
-       if (!ev) {
+       if (index < 0 || index >= ((EditDerivedBMesh *)dm)->tv) {
                printf("error in bmDM_getVert.\n");
                return;
        }
 
+       ev = ((EditDerivedBMesh *)dm)->vtable[index];
        bmvert_to_mvert(ev, vert_r);
 }
 
@@ -986,8 +1073,12 @@ static void bmDM_getEdge(DerivedMesh *dm, int index, MEdge *edge_r)
        BMIter iter;
        int i;
 
-       e = BMIter_New(&iter, bmdm->tc->bm, BM_EDGES_OF_MESH, NULL);
-       for(i = 0; i < index; ++i) e = BMIter_Step(&iter);
+       if (index < 0 || index >= ((EditDerivedBMesh *)dm)->te) {
+               printf("error in bmDM_getEdge.\n");
+               return;
+       }
+
+       e = bmdm->etable[index];
 
        edge_r->crease = (unsigned char) (e->crease*255.0f);
        edge_r->bweight = (unsigned char) (e->bweight*255.0f);
@@ -999,65 +1090,36 @@ static void bmDM_getEdge(DerivedMesh *dm, int index, MEdge *edge_r)
        if (!ee->f2) edge_r->flag |= ME_LOOSEEDGE;
 #endif
        
-       /*gah, stupid O(n^2) behaviour.  should cache this or something,
-         I probably could put it in the TessCache structure. . .*/
-       v1 = e->v1;
-       v2 = e->v2;
-       ev = BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL);
-       for(i = 0; v1 || v2; i++, ev = BMIter_Step(&iter)) {
-               if(ev == v1) {
-                       edge_r->v1 = i;
-                       v1 = NULL;
-               }
-               if(ev == v2) {
-                       edge_r->v2 = i;
-                       v2 = NULL;
-               }
-       }
+       edge_r->v1 = GET_INT_FROM_POINTER(BLI_ghash_lookup(bmdm->vhash, e->v1));
+       edge_r->v2 = GET_INT_FROM_POINTER(BLI_ghash_lookup(bmdm->vhash, e->v2));
 }
 
-static void bmDM_getFace(DerivedMesh *dm, int index, MFace *face_r)
+static void bmDM_getTessFace(DerivedMesh *dm, int index, MFace *face_r)
 {
-       BMesh *bm = ((EditDerivedBMesh *)dm)->tc->bm;
+       EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
+       BMesh *bm = bmdm->tc->bm;
        BMFace *ef;
-       BMVert *ev, *v1, *v2, *v3;
        BMIter iter;
        BMLoop **l;
        int i;
        
+       if (index < 0 || index >= ((EditDerivedBMesh *)dm)->tf) {
+               printf("error in bmDM_getTessFace.\n");
+               return;
+       }
+
        l = ((EditDerivedBMesh *)dm)->tc->looptris[index];
 
        ef = l[0]->f;
 
        face_r->mat_nr = (unsigned char) ef->mat_nr;
-       //need to convert flags here!
        face_r->flag = BMFlags_To_MEFlags(ef);
 
-       /*while it's possible to store a cache to lookup these indices faster,
-         that would require going over the code and ensuring the cache is
-         always up to date.*/
-       v1 = l[0]->v;
-       v2 = l[1]->v;
-       v3 = l[2]->v;
+       face_r->v1 = GET_INT_FROM_POINTER(BLI_ghash_lookup(bmdm->vhash, l[0]->v));
+       face_r->v2 = GET_INT_FROM_POINTER(BLI_ghash_lookup(bmdm->vhash, l[1]->v));
+       face_r->v3 = GET_INT_FROM_POINTER(BLI_ghash_lookup(bmdm->vhash, l[2]->v));
        face_r->v4 = 0;
 
-       ev = BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL);
-       for(i = 0, ev; v1 || v2 || v3;
-           i++, ev = BMIter_Step(&iter)) {
-               if(ev == v1) {
-                       face_r->v1 = i;
-                       v1 = NULL;
-               }
-               if(ev == v2) {
-                       face_r->v2 = i;
-                       v2 = NULL;
-               }
-               if(ev == v3) {
-                       face_r->v3 = i;
-                       v3 = NULL;
-               }
-       }
-
        test_index_face(face_r, NULL, 0, 3);
 }
 
@@ -1175,9 +1237,9 @@ static void *bmDM_getFaceDataArray(DerivedMesh *dm, int type)
                        data = datalayer = DM_get_face_data_layer(dm, type);
                        for (i=0; i<bmdm->tc->tottri; i++, data+=size) {
                                efa = bmdm->tc->looptris[i][0]->f;
-                               /*need to still add tface data, derived from the
-                                 loops.*/
-                               bmdata = CustomData_bmesh_get(&bm->pdata, efa->data, type);
+                               /*BMESH_TODO: need to still add tface data,
+                                 derived from the loops.*/
+                               bmdata = CustomData_bmesh_get(&bm->pdata, efa->head.data, type);
                                memcpy(data, bmdata, size);
                        }
                }
@@ -1225,8 +1287,8 @@ void *bmDM_getFaceCDData(void *self, int type, int layer)
        bmDM_faceIter *iter = self;
 
        if (layer == -1) 
-               return CustomData_bmesh_get(&iter->bm->pdata, iter->f->data, type);
-       else return CustomData_bmesh_get_n(&iter->bm->pdata, iter->f->data, type, layer);
+               return CustomData_bmesh_get(&iter->bm->pdata, iter->f->head.data, type);
+       else return CustomData_bmesh_get_n(&iter->bm->pdata, iter->f->head.data, type, layer);
 }
 
 void bmDM_loopIterStep(void *self)
@@ -1250,8 +1312,8 @@ void *bmDM_getLoopCDData(void *self, int type, int layer)
        bmDM_loopIter *iter = self;
 
        if (layer == -1) 
-               return CustomData_bmesh_get(&iter->bm->ldata, iter->l->data, type);
-       else return CustomData_bmesh_get_n(&iter->bm->ldata, iter->l->data, type, layer);
+               return CustomData_bmesh_get(&iter->bm->ldata, iter->l->head.data, type);
+       else return CustomData_bmesh_get_n(&iter->bm->ldata, iter->l->head.data, type, layer);
 }
 
 void *bmDM_getVertCDData(void *self, int type, int layer)
@@ -1259,8 +1321,8 @@ void *bmDM_getVertCDData(void *self, int type, int layer)
        bmDM_loopIter *iter = self;
 
        if (layer == -1) 
-               return CustomData_bmesh_get(&iter->bm->vdata, iter->l->v->data, type);
-       else return CustomData_bmesh_get_n(&iter->bm->vdata, iter->l->v->data, type, layer);
+               return CustomData_bmesh_get(&iter->bm->vdata, iter->l->v->head.data, type);
+       else return CustomData_bmesh_get_n(&iter->bm->vdata, iter->l->v->head.data, type, layer);
 }
 
 void bmDM_iterFree(void *self)
@@ -1281,15 +1343,15 @@ DMLoopIter *bmDM_newLoopsIter(void *faceiter)
 
        iter->bm = fiter->bm;
        iter->f = fiter->f;
-       iter->l = BMIter_New(&iter->iter, iter->bm, BM_LOOPS_OF_FACE, iter->f);
+       iter->nextl = 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->l->v, &iter->head.v);
-       iter->head.vindex = BMINDEX_GET(iter->l->v);
-       iter->head.eindex = BMINDEX_GET(iter->l->e);
+       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);
 
        return (DMLoopIter*) iter;
 }
@@ -1304,7 +1366,7 @@ static DMFaceIter *bmDM_getFaceIter(void *dm)
        int i;
 
        iter->bm = bmdm->tc->bm;
-       iter->f = BMIter_New(&iter->iter, iter->bm, BM_FACES_OF_MESH, NULL);
+       iter->f = iter->nextf = BMIter_New(&iter->iter, iter->bm, BM_FACES_OF_MESH, NULL);
        
        iter->head.step = bmDM_faceIterStep;
        iter->head.free = bmDM_iterFree;
@@ -1361,16 +1423,18 @@ DerivedMesh *getEditDerivedBMesh(BMEditMesh *em, Object *ob,
        bmdm->dm.getNumVerts = bmDM_getNumVerts;
        bmdm->dm.getNumEdges = bmDM_getNumEdges;
        bmdm->dm.getNumTessFaces = bmDM_getNumTessFaces;
+       bmdm->dm.getNumFaces = bmDM_getNumFaces;
 
        bmdm->dm.getVert = bmDM_getVert;
        bmdm->dm.getEdge = bmDM_getEdge;
-       bmdm->dm.getTessFace = bmDM_getFace;
+       bmdm->dm.getTessFace = bmDM_getTessFace;
        bmdm->dm.copyVertArray = bmDM_copyVertArray;
        bmdm->dm.copyEdgeArray = bmDM_copyEdgeArray;
        bmdm->dm.copyTessFaceArray = bmDM_copyFaceArray;
        bmdm->dm.getTessFaceDataArray = bmDM_getFaceDataArray;
 
        bmdm->dm.newFaceIter = bmDM_getFaceIter;
+       bmdm->dm.recalcTesselation = bmDM_recalcTesselation;
 
        bmdm->dm.foreachMappedVert = bmDM_foreachMappedVert;
        bmdm->dm.foreachMappedEdge = bmDM_foreachMappedEdge;
@@ -1400,7 +1464,7 @@ DerivedMesh *getEditDerivedBMesh(BMEditMesh *em, Object *ob,
                eve = BMIter_New(&iter, bmdm->tc->bm, BM_VERTS_OF_MESH, NULL);
                for (i=0; eve; eve=BMIter_Step(&iter), i++)
                        DM_set_vert_data(&bmdm->dm, i, CD_MDEFORMVERT,
-                                        CustomData_bmesh_get(&bm->vdata, eve->data, CD_MDEFORMVERT));
+                                        CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MDEFORMVERT));
        }
 
        if(vertexCos) {
@@ -1441,5 +1505,7 @@ DerivedMesh *getEditDerivedBMesh(BMEditMesh *em, Object *ob,
                }
        }
 
+       bmdm_recalc_lookups(bmdm);
+
        return (DerivedMesh*) bmdm;
 }
index 9ff7ea0f6284723c253ad9d9f8359abe52d3c8cc..879699e755aafe5483164def195e3999ed5f19fd 100644 (file)
@@ -24,7 +24,8 @@
 *                 Ton Roosendaal,
 *                 Ben Batt,
 *                 Brecht Van Lommel,
-*                 Campbell Barton
+*                 Campbell Barton,
+*                 Joseph Eagar
 *
 * ***** END GPL LICENSE BLOCK *****
 *
@@ -1094,6 +1095,7 @@ static int calc_mapping(IndexMapEntry *indexMap, int oldIndex, int copyNum)
        }
 }
 
+#if 0
 static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
                                          Scene *scene, Object *ob, DerivedMesh *dm,
        int initFlags)
@@ -1658,6 +1660,14 @@ static DerivedMesh *arrayModifier_applyModifierEM(
 {
        return arrayModifier_applyModifier(md, ob, derivedData, 0, 1);
 }
+#endif
+
+DerivedMesh *arrayModifier_applyModifier(ModifierData *md, Object *ob, 
+                                        DerivedMesh *derivedData,
+                                         int useRenderParams, int isFinalCalc);
+DerivedMesh *arrayModifier_applyModifierEM(ModifierData *md, Object *ob,
+                                           BMEditMesh *editData, 
+                                           DerivedMesh *derivedData);
 
 /* Mirror */
 
diff --git a/source/blender/blenkernel/intern/modifiers_bmesh.c b/source/blender/blenkernel/intern/modifiers_bmesh.c
new file mode 100644 (file)
index 0000000..d52f624
--- /dev/null
@@ -0,0 +1,388 @@
+/*
+* $Id: modifier_bmesh.c 20831 2009-06-12 14:02:37Z joeedh $
+*
+* ***** BEGIN GPL LICENSE BLOCK *****
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software  Foundation,
+* Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+*
+* The Original Code is Copyright (C) 2005 by the Blender Foundation.
+* All rights reserved.
+*
+* Contributor(s): Joseph Eagar
+*
+* ***** END GPL LICENSE BLOCK *****
+*
+* Modifier stack implementation.
+*
+* BKE_modifier.h contains the function prototypes for this file.
+*
+*/
+
+#include "string.h"
+#include "stdarg.h"
+#include "math.h"
+#include "float.h"
+#include "ctype.h"
+
+#include "BLI_arithb.h"
+#include "BLI_blenlib.h"
+#include "BLI_kdopbvh.h"
+#include "BLI_kdtree.h"
+#include "BLI_linklist.h"
+#include "BLI_rand.h"
+#include "BLI_edgehash.h"
+#include "BLI_ghash.h"
+#include "BLI_memarena.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_action_types.h"
+#include "DNA_armature_types.h"
+#include "DNA_camera_types.h"
+#include "DNA_cloth_types.h"
+#include "DNA_curve_types.h"
+#include "DNA_effect_types.h"
+#include "DNA_material_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_modifier_types.h"
+#include "DNA_object_types.h"
+#include "DNA_object_force.h"
+#include "DNA_particle_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_texture_types.h"
+
+#include "BLI_editVert.h"
+
+#include "MTC_matrixops.h"
+#include "MTC_vectorops.h"
+
+#include "BKE_main.h"
+#include "BKE_anim.h"
+#include "BKE_bmesh.h"
+// XXX #include "BKE_booleanops.h"
+#include "BKE_cloth.h"
+#include "BKE_collision.h"
+#include "BKE_cdderivedmesh.h"
+#include "BKE_curve.h"
+#include "BKE_customdata.h"
+#include "BKE_DerivedMesh.h"
+#include "BKE_displist.h"
+#include "BKE_fluidsim.h"
+#include "BKE_global.h"
+#include "BKE_multires.h"
+#include "BKE_lattice.h"
+#include "BKE_library.h"
+#include "BKE_material.h"
+#include "BKE_mesh.h"
+#include "BKE_modifier.h"
+#include "BKE_object.h"
+#include "BKE_particle.h"
+#include "BKE_pointcache.h"
+#include "BKE_softbody.h"
+#include "BKE_subsurf.h"
+#include "BKE_texture.h"
+#include "BKE_utildefines.h"
+#include "BKE_tessmesh.h"
+
+#include "depsgraph_private.h"
+#include "BKE_deform.h"
+#include "BKE_shrinkwrap.h"
+#include "BKE_simple_deform.h"
+
+#include "CCGSubSurf.h"
+#include "RE_shader_ext.h"
+#include "LOD_decimation.h"
+
+/*converts a cddm to a BMEditMesh.  if existing is non-NULL, the
+  new geometry will be put in there.*/
+BMEditMesh *CDDM_To_BMesh(DerivedMesh *dm, BMEditMesh *existing)
+{
+       int allocsize[4] = {512, 512, 2048, 512};
+       BMesh *bm, bmold; /*bmold is for storing old customdata layout*/
+       BMEditMesh *em = existing;
+       MVert *mv;
+       MEdge *me;
+       DMFaceIter *dfiter;
+       DMLoopIter *dliter;
+       BMVert *v, **vtable, **verts=NULL;
+       BMEdge *e, **etable, **edges=NULL;
+       BMFace *f;
+       BMIter liter, iter;
+       V_DECLARE(verts);
+       V_DECLARE(edges);
+       void *tmp;
+       int numTex, numCol;
+       int i, j, k, tot, totvert, totedge, totface;
+       
+       if (em) bm = em->bm;
+       else bm = BM_Make_Mesh(allocsize);
+
+       bmold = *bm;
+
+       /*merge custom data layout*/
+       CustomData_bmesh_merge(&dm->vertData, &bm->vdata, CD_MASK_BMESH|CD_MASK_ORIGINDEX, CD_CALLOC, bm, BM_VERT);
+       CustomData_bmesh_merge(&dm->edgeData, &bm->edata, CD_MASK_BMESH|CD_MASK_ORIGINDEX, CD_CALLOC, bm, BM_EDGE);
+       CustomData_bmesh_merge(&dm->loopData, &bm->ldata, CD_MASK_BMESH|CD_MASK_ORIGINDEX, CD_CALLOC, bm, BM_LOOP);
+       CustomData_bmesh_merge(&dm->polyData, &bm->pdata, CD_MASK_BMESH|CD_MASK_ORIGINDEX, CD_CALLOC, bm, BM_FACE);
+
+       /*needed later*/
+       numTex = CustomData_number_of_layers(&bm->pdata, CD_MTEXPOLY);
+       numCol = CustomData_number_of_layers(&bm->ldata, CD_MLOOPCOL);
+
+       totvert = dm->getNumVerts(dm);
+       totedge = dm->getNumEdges(dm);
+       totface = dm->getNumFaces(dm);
+
+       vtable = MEM_callocN(sizeof(void**)*totvert, "vert table in BMDM_Copy");
+       etable = MEM_callocN(sizeof(void**)*totedge, "edge table in BMDM_Copy");
+
+       /*do verts*/
+       mv = dm->dupVertArray(dm);
+       for (i=0; i<totvert; i++, mv++) {
+               v = BM_Make_Vert(bm, mv->co, NULL);
+               
+               v->bweight = mv->bweight;
+               VECCOPY(v->no, mv->no);
+               v->head.flag = MEFlags_To_BMFlags(mv->flag, BM_VERT);
+
+               CustomData_to_bmesh_block(&dm->vertData, &bm->vdata, i, &v->head.data);
+               vtable[i] = v;
+       }
+
+       /*do edges*/
+       me = dm->dupEdgeArray(dm);
+       for (i=0; i<totedge; i++, me++) {
+               e = BM_Make_Edge(bm, vtable[me->v1], vtable[me->v2], NULL, 0);
+
+               e->bweight = me->bweight;
+               e->crease = me->crease;
+               e->head.flag = MEFlags_To_BMFlags(me->flag, BM_EDGE);
+
+               CustomData_to_bmesh_block(&dm->edgeData, &bm->edata, i, &e->head.data);
+               etable[i] = e;
+       }
+       
+       k = 0;
+       dfiter = dm->newFaceIter(dm);
+       for (; !dfiter->done; dfiter->step(dfiter)) {
+               BMLoop *l;
+
+               V_RESET(verts);
+               V_RESET(edges);
+
+               dliter = dfiter->getLoopsIter(dfiter);
+               for (j=0; !dliter->done; dliter->step(dliter), j++) {
+                       V_GROW(verts);
+                       V_GROW(edges);
+
+                       verts[j] = vtable[dliter->vindex];
+                       edges[j] = etable[dliter->eindex];
+               }
+               
+               f = BM_Make_Ngon(bm, verts[0], verts[1], edges, dfiter->len, 0);
+               f->head.flag = MEFlags_To_BMFlags(dfiter->flags, BM_FACE);
+
+               if (!f) 
+                       continue;
+
+               dliter = dfiter->getLoopsIter(dfiter);
+               l = BMIter_New(&liter, bm, BM_LOOPS_OF_FACE, f);
+               for (j=0; l; l=BMIter_Step(&liter)) {
+                       CustomData_to_bmesh_block(&dm->loopData, &bm->ldata, k, &l->head.data);
+                       k += 1;
+               }
+
+               CustomData_to_bmesh_block(&dm->polyData, &bm->pdata, 
+                       dfiter->index, &f->head.data);
+       }
+
+       MEM_freeN(vtable);
+       MEM_freeN(etable);
+       
+       if (!em) em = BMEdit_Create(bm);
+       else BMEdit_RecalcTesselation(em);
+
+       return em;
+}
+
+float vertarray_size(MVert *mvert, int numVerts, int axis);
+
+static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
+                                         Scene *scene, Object *ob, DerivedMesh *dm,
+                                          int initFlags)
+{
+       DerivedMesh *cddm = CDDM_copy(dm);
+       BMEditMesh *em = CDDM_To_BMesh(cddm, NULL);
+       BMOperator op, oldop;
+       int i, j;
+       /* offset matrix */
+       float offset[4][4];
+       float final_offset[4][4];
+       float tmp_mat[4][4];
+       float length = amd->length;
+       int count = amd->count;
+       int numVerts, numEdges, numFaces;
+       int maxVerts, maxEdges, maxFaces;
+       int finalVerts, finalEdges, finalFaces;
+       DerivedMesh *result, *start_cap = NULL, *end_cap = NULL;
+       MVert *src_mvert;
+
+       /* need to avoid infinite recursion here */
+       if(amd->start_cap && amd->start_cap != ob)
+               start_cap = mesh_get_derived_final(scene, amd->start_cap, CD_MASK_MESH);
+       if(amd->end_cap && amd->end_cap != ob)
+               end_cap = mesh_get_derived_final(scene, amd->end_cap, CD_MASK_MESH);
+
+       MTC_Mat4One(offset);
+
+       src_mvert = cddm->getVertArray(dm);
+       maxVerts = cddm->getNumVerts(dm);
+
+       if(amd->offset_type & MOD_ARR_OFF_CONST)
+               VecAddf(offset[3], offset[3], amd->offset);
+       if(amd->offset_type & MOD_ARR_OFF_RELATIVE) {
+               for(j = 0; j < 3; j++)
+                       offset[3][j] += amd->scale[j] * vertarray_size(src_mvert,
+                                       maxVerts, j);
+       }
+
+       if((amd->offset_type & MOD_ARR_OFF_OBJ) && (amd->offset_ob)) {
+               float obinv[4][4];
+               float result_mat[4][4];
+
+               if(ob)
+                       MTC_Mat4Invert(obinv, ob->obmat);
+               else
+                       MTC_Mat4One(obinv);
+
+               MTC_Mat4MulSerie(result_mat, offset,
+                                obinv, amd->offset_ob->obmat,
+                                 NULL, NULL, NULL, NULL, NULL);
+               MTC_Mat4CpyMat4(offset, result_mat);
+       }
+
+       if(amd->fit_type == MOD_ARR_FITCURVE && amd->curve_ob) {
+               Curve *cu = amd->curve_ob->data;
+               if(cu) {
+                       float tmp_mat[3][3];
+                       float scale;
+                       
+                       object_to_mat3(amd->curve_ob, tmp_mat);
+                       scale = Mat3ToScalef(tmp_mat);
+                               
+                       if(!cu->path) {
+                               cu->flag |= CU_PATH; // needed for path & bevlist
+                               makeDispListCurveTypes(scene, amd->curve_ob, 0);
+                       }
+                       if(cu->path)
+                               length = scale*cu->path->totdist;
+               }
+       }
+
+       /* calculate the maximum number of copies which will fit within the
+       prescribed length */
+       if(amd->fit_type == MOD_ARR_FITLENGTH
+                 || amd->fit_type == MOD_ARR_FITCURVE)
+       {
+               float dist = sqrt(MTC_dot3Float(offset[3], offset[3]));
+
+               if(dist > 1e-6f)
+                       /* this gives length = first copy start to last copy end
+                       add a tiny offset for floating point rounding errors */
+                       count = (length + 1e-6f) / dist;
+               else
+                       /* if the offset has no translation, just make one copy */
+                       count = 1;
+       }
+
+       if(count < 1)
+               count = 1;
+
+       /* allocate memory for count duplicates (including original) plus
+                 * start and end caps
+       */
+       finalVerts = dm->getNumVerts(dm) * count;
+       finalEdges = dm->getNumEdges(dm) * count;
+       finalFaces = dm->getNumTessFaces(dm) * count;
+       if(start_cap) {
+               finalVerts += start_cap->getNumVerts(start_cap);
+               finalEdges += start_cap->getNumEdges(start_cap);
+               finalFaces += start_cap->getNumTessFaces(start_cap);
+       }
+       if(end_cap) {
+               finalVerts += end_cap->getNumVerts(end_cap);
+               finalEdges += end_cap->getNumEdges(end_cap);
+               finalFaces += end_cap->getNumTessFaces(end_cap);
+       }
+
+       /* calculate the offset matrix of the final copy (for merging) */ 
+       MTC_Mat4One(final_offset);
+
+       for(j=0; j < count - 1; j++) {
+               MTC_Mat4MulMat4(tmp_mat, final_offset, offset);
+               MTC_Mat4CpyMat4(final_offset, tmp_mat);
+       }
+
+
+       cddm->needsFree = 1;
+       cddm->release(cddm);
+       
+       BMO_InitOpf(em->bm, &op, "dupe geom=%avef");
+       oldop = op;
+       for (j=0; j < count; j++) {
+               BMO_InitOpf(em->bm, &op, "dupe geom=%s", &oldop, j==0 ? "geom" : "newout");
+               BMO_Exec_Op(em->bm, &op);
+
+               BMO_Finish_Op(em->bm, &oldop);
+               oldop = op;
+
+               BMO_CallOpf(em->bm, "transform mat=%m4 verts=%s", offset, &op, "newout");
+
+       }
+
+       if (j > 0) BMO_Finish_Op(em->bm, &op);
+
+       BMO_CallOpf(em->bm, "removedoubles verts=%av dist=%f", amd->merge_dist);
+
+       BMEdit_RecalcTesselation(em);
+       cddm = CDDM_from_BMEditMesh(em, NULL);
+
+       BMEdit_Free(em);
+
+       return cddm;
+}
+
+DerivedMesh *arrayModifier_applyModifier(ModifierData *md, Object *ob, 
+                                        DerivedMesh *derivedData,
+                                         int useRenderParams, int isFinalCalc)
+{
+       DerivedMesh *result;
+       ArrayModifierData *amd = (ArrayModifierData*) md;
+
+       result = arrayModifier_doArray(amd, md->scene, ob, derivedData, 0);
+
+       //if(result != derivedData)
+       //      CDDM_calc_normals(result);
+
+       return result;
+}
+
+DerivedMesh *arrayModifier_applyModifierEM(ModifierData *md, Object *ob,
+                                           BMEditMesh *editData, 
+                                           DerivedMesh *derivedData)
+{
+       return arrayModifier_applyModifier(md, ob, derivedData, 0, 1);
+}
\ No newline at end of file
index 0c5d37119dd02cd94a518ac1f6e0b902932bc222..59f97ba13dfc4de9f719173f56812d4f3c6a4323 100644 (file)
@@ -1472,9 +1472,9 @@ void ccgDM_loopIterStep(void *self)
        }
 
        liter->head.vindex = in;
+
        /*we don't set .eindex*/
-       ccgDM_getFinalVert((DerivedMesh*)liter->ccgdm, in, &liter->head.v);
-       
+       ccgDM_getFinalVert((DerivedMesh*)liter->ccgdm, in, &liter->head.v);     
 }
 
 void *ccgDM_loopIterGetVCData(void *self, int type, int layer)
@@ -1482,8 +1482,8 @@ void *ccgDM_loopIterGetVCData(void *self, int type, int layer)
        ccgDM_loopIter *liter = self;
 
        if (layer == -1)
-               return CustomData_get(&liter->ccgdm->dm.vertData, liter->head.index, type);
-       else return CustomData_get_n(&liter->ccgdm->dm.vertData, type, liter->head.index, layer);
+               return CustomData_get(&liter->ccgdm->dm.vertData, liter->head.vindex, type);
+       else return CustomData_get_n(&liter->ccgdm->dm.vertData, type, liter->head.vindex, layer);
 }
 
 void *ccgDM_loopIterGetCData(void *self, int type, int layer)
index 65c1ef2721415382a67df04013d2d5f696589de3..06665d4b8ba6908c426b083109164f639492cc57 100644 (file)
@@ -93,7 +93,7 @@ struct EditMesh;
 #define BM_EDGE        2
 #define BM_FACE        4
 #define BM_LOOP        8
-#define BM_ALL         BM_VERT | BM_EDGE | BM_FACE | BM_LOOP
+#define BM_ALL         (BM_VERT | BM_EDGE | BM_FACE | BM_LOOP)
 
 /*BMHeader->flag*/
 #define BM_SELECT      (1<<0)
@@ -114,11 +114,13 @@ typedef struct BMHeader {
          member is what "header flag" means.*/
        int             flag;
        int             type;
-       int                     eflag1, eflag2; /*Flags used by eulers. Try and get rid of/minimize some of these*/
+       int             eflag1, eflag2; /*Flags used by eulers. Try and get rid of/minimize some of these*/
        
        //this can only be used to store a temporary index.  don't use it for anything else.
+       //use the BMINDEX_GET and BMINDEX_SET macros!!
        int index;
        struct BMFlagLayer *flags; /*Dynamically allocated block of flag layers for operators to use*/
+       void *data; /*customdata*/
 } BMHeader;
 
 typedef struct BMFlagLayer {
@@ -173,7 +175,6 @@ typedef struct BMVert {
        float co[3];                                                                    
        float no[3];                                                                    
        struct BMEdge *edge;
-       void *data;
        void *tmp;                                                                                                      /*what?*/
        float bweight;                                                                                          /*please, someone just get rid of me...*/
 } BMVert;
@@ -183,7 +184,6 @@ typedef struct BMEdge {
        struct BMVert *v1, *v2;
        struct BMNode d1, d2;
        struct BMLoop *loop;
-       void *data;
        float crease, bweight; /*make these custom data.... no really, please....*/
 } BMEdge;
 
@@ -193,14 +193,12 @@ typedef struct BMLoop  {
        struct BMVert *v;
        struct BMEdge *e;
        struct BMFace *f;       
-       void *data;
 } BMLoop;
 
 typedef struct BMFace {
        struct BMHeader head;
        struct BMLoop *loopbase;
        int len;
-       void *data;
        float no[3];
 
        /*custom data again*/
@@ -334,7 +332,7 @@ int BMFlags_To_MEFlags(void *element);
   and represents the type of the element
   parameter (the three defines map to
   MVert, MEdge, and MPoly, respectively).*/
-int MEFlags_To_BMFlags(void *element, int type);
+int MEFlags_To_BMFlags(int flag, int type);
 
 /*convert MLoop*** in a bmface to mtface and mcol in
   an MFace*/
index 4990a296db14fa62a7c0fd7565b0837c26834760..7d1513e0b80b0767fb31878a1ab7b80f38f745a6 100644 (file)
@@ -55,7 +55,10 @@ struct GHashIterator;
 
   dynamically allocated arrays.  we
   leave a space in the identifiers
-  for future growth.*/
+  for future growth.
+
+  */
+//it's very important this remain a power of two
 #define BMOP_OPSLOT_ELEMENT_BUF                8
 #define BMOP_OPSLOT_MAPPING            9
 #define BMOP_OPSLOT_TYPES              10
@@ -159,7 +162,10 @@ int BMO_CountFlag(struct BMesh *bm, int flag, int type);
          so e.g. %hf will do faces, %hfe will do faces and edges,
          %hv will do verts, etc.  must pass in at least one
          element type letter.
-     %f[f/e/v] - same as %h.
+     %f[f/e/v] - same as %h, except it deals with tool flags instead of
+                  header flags.
+     %a[f/e/v] - pass all elements (of types specified by f/e/v) to the
+                 slot.
      %v - pointer to a float vector of length 3.
      %m[3/4] - matrix, 3/4 refers to the matrix size, 3 or 4.  the
                corrusponding argument must be a pointer to
@@ -262,9 +268,9 @@ void BMO_Mapping_To_Flag(struct BMesh *bm, struct BMOperator *op,
   do NOT use these for non-operator-api-allocated memory! instead
   use BMO_Get_MapData and BMO_Insert_Mapping, which copies the data.*/
 void BMO_Insert_MapPointer(BMesh *bm, BMOperator *op, char *slotname, 
-                       void *element, void *val);
+                       void *key, void *val);
 void *BMO_Get_MapPointer(BMesh *bm, BMOperator *op, char *slotname,
-                      void *element);
+                      void *key);
 
 
 /*this part of the API is used to iterate over element buffer or
@@ -275,7 +281,7 @@ void *BMO_Get_MapPointer(BMesh *bm, BMOperator *op, char *slotname,
          BMOIter oiter;
          BMFace *f;
 
-         f = BMO_IterNew(&oiter, bm, some_operator, "slotname");
+         f = BMO_IterNew(&oiter, bm, some_operator, "slotname", BM_FACE);
          for (; f; f=BMO_IterStep(&oiter)) {
                /do something with the face
          }
@@ -285,7 +291,7 @@ void *BMO_Get_MapPointer(BMesh *bm, BMOperator *op, char *slotname,
          void *key;
          void *val;
 
-         key = BMO_IterNew(&oiter, bm, some_operator, "slotname");
+         key = BMO_IterNew(&oiter, bm, some_operator, "slotname", 0);
          for (; key; key=BMO_IterStep(&oiter)) {
                val = BMO_IterMapVal(&oiter);
                //do something with the key/val pair
@@ -306,18 +312,22 @@ typedef struct BMOIter {
        int cur; //for arrays
        struct GHashIterator giter;
        void *val;
+       int restrict;
 } BMOIter;
 
+/*restrictmask restricts the iteration to certain element types
+  (e.g. combination of BM_VERT, BM_EDGE, BM_FACE), if iterating
+  over an element buffer (not a mapping).*/
 void *BMO_IterNew(BMOIter *iter, BMesh *bm, BMOperator *op, 
-                 char *slotname);
+                 char *slotname, int restrictmask);
 void *BMO_IterStep(BMOIter *iter);
 
 /*returns a pointer to the key value when iterating over mappings.
   remember for pointer maps this will be a pointer to a pointer.*/
 void *BMO_IterMapVal(BMOIter *iter);
 
-#define BMO_ITER(ele, iter, bm, op, slotname) \
-       ele = BMO_IterNew(iter, bm, op, slotname); \
+#define BMO_ITER(ele, iter, bm, op, slotname, restrict) \
+       ele = BMO_IterNew(iter, bm, op, slotname, restrict); \
        for ( ; ele; ele=BMO_IterStep(iter))
 
 #endif /* _BMESH_OPERATOR_H */
\ No newline at end of file
index 10662251e058d42a898ec44119fd0bec8b60cf08..ee2b8605a170bb5e6db6d5dbe881770841eef3c4 100644 (file)
@@ -6,18 +6,15 @@
 /*counts number of elements of type type are in the mesh.*/
 int BM_Count_Element(struct BMesh *bm, int type);
 
-/*returns true if v is in e.*/
-int BM_Vert_In_Edge(struct BMEdge *e, struct BMVert *v);
-
 /*returns true if v is in f*/
 int BM_Vert_In_Face(struct BMFace *f, struct BMVert *v);
 
 // int BM_VERTS_OF_MESH_In_Face(struct BMFace *f, struct BMVert **varr, int len);
-int BM_VERTS_OF_MESH_In_Face(struct BMesh *bm, struct BMFace *f, struct BMVert **varr, int len);
+int BM_Verts_In_Face(struct BMesh *bm, struct BMFace *f, struct BMVert **varr, int len);
 
 int BM_Edge_In_Face(struct BMFace *f, struct BMEdge *e);
 
-int BM_VERTS_OF_MESH_In_Edge(struct BMVert *v1, struct BMVert *v2, BMEdge *e);
+int BM_Vert_In_Edge(struct BMVert *v1, struct BMVert *v2, BMEdge *e);
 
 
 /*get opposing vert from v in edge e.*/
index ea97bfa8886e42927667b8ca415b2df0a222d526..58025fd33cc3f14bdf9a6c611aac3a1db3adcda0 100644 (file)
@@ -73,7 +73,7 @@ BMVert *BM_Make_Vert(BMesh *bm, float co[3], BMVert *example)
        BMVert *v = NULL;
        v = bmesh_mv(bm, co);
        if(example)
-               CustomData_bmesh_copy_data(&bm->vdata, &bm->vdata, example->data, &v->data);
+               CustomData_bmesh_copy_data(&bm->vdata, &bm->vdata, example->head.data, &v->head.data);
        return v;
 }
 
@@ -103,7 +103,7 @@ BMEdge *BM_Make_Edge(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge *example, int nod
                e = bmesh_me(bm, v1, v2);
 
                if(example)
-                       CustomData_bmesh_copy_data(&bm->edata, &bm->edata, example->data, &e->data);
+                       CustomData_bmesh_copy_data(&bm->edata, &bm->edata, example->head.data, &e->head.data);
        }
        
        return e;
@@ -202,7 +202,7 @@ BMFace *BM_Make_Quadtriangle(BMesh *bm, BMVert **verts, BMEdge **edges, int len,
                else f = bmesh_mf(bm, verts[0], verts[1], edar, 3);
        
                if(example)
-                       CustomData_bmesh_copy_data(&bm->pdata, &bm->pdata, example->data, &f->data);
+                       CustomData_bmesh_copy_data(&bm->pdata, &bm->pdata, example->head.data, &f->head.data);
 
        }
 
@@ -248,8 +248,18 @@ BMFace *BM_Make_Ngon(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **edges, int len,
        BMVert **verts = vert_buf, *lastv;
        BMFace *f = NULL;
        int overlap = 0, i, j;
+       
+       /*note: need to make sure this is correct*/
+       if(bmesh_verts_in_edge(v1,v2,edges[0]) == 0) {
+               if (v1 == edges[0]->v1)
+                       v2 = edges[0]->v2;
+               else {
+                       v1 = edges[0]->v2;
+                       v2 = edges[0]->v1;
+               }
+       }
 
-       if(nodouble){
+       if(nodouble) {
                if(len > VERT_BUF_SIZE)
                        verts = MEM_callocN(sizeof(BMVert *) * len, "bmesh make ngon vertex array");
                
@@ -350,25 +360,25 @@ void BM_remove_tagged_verts(BMesh *bm, int flag)
 
 static void bm_copy_vert_attributes(BMesh *source_mesh, BMesh *target_mesh, BMVert *source_vertex, BMVert *target_vertex)
 {
-       CustomData_bmesh_copy_data(&source_mesh->vdata, &target_mesh->vdata, source_vertex->data, &target_vertex->data);        
+       CustomData_bmesh_copy_data(&source_mesh->vdata, &target_mesh->vdata, source_vertex->head.data, &target_vertex->head.data);      
        target_vertex->bweight = source_vertex->bweight;
 }
 
 static void bm_copy_edge_attributes(BMesh *source_mesh, BMesh *target_mesh, BMEdge *source_edge, BMEdge *target_edge)
 {
-       CustomData_bmesh_copy_data(&source_mesh->edata, &target_mesh->edata, source_edge->data, &target_edge->data);
+       CustomData_bmesh_copy_data(&source_mesh->edata, &target_mesh->edata, source_edge->head.data, &target_edge->head.data);
        target_edge->crease = source_edge->crease;
        target_edge->bweight = source_edge->bweight;
 }
 
 static void bm_copy_loop_attributes(BMesh *source_mesh, BMesh *target_mesh, BMLoop *source_loop, BMLoop *target_loop)
 {
-       CustomData_bmesh_copy_data(&source_mesh->ldata, &target_mesh->ldata, source_loop->data, &target_loop->data);
+       CustomData_bmesh_copy_data(&source_mesh->ldata, &target_mesh->ldata, source_loop->head.data, &target_loop->head.data);
 }
 
 static void bm_copy_face_attributes(BMesh *source_mesh, BMesh *target_mesh, BMFace *source_face, BMFace *target_face)
 {
-       CustomData_bmesh_copy_data(&source_mesh->pdata, &target_mesh->pdata, source_face->data, &target_face->data);    
+       CustomData_bmesh_copy_data(&source_mesh->pdata, &target_mesh->pdata, source_face->head.data, &target_face->head.data);  
        target_face->mat_nr = source_face->mat_nr;
 }
 
@@ -535,24 +545,21 @@ int BMFlags_To_MEFlags(void *element) {
   type must be either BM_VERT, BM_EDGE,
   or BM_FACE.
 */
-int MEFlags_To_BMFlags(void *element, int type) {
+int MEFlags_To_BMFlags(int flag, int type) {
        int f = 0;
 
        if (type == BM_FACE) {
-               MPoly *mp = element;
-               if (mp->flag & ME_FACE_SEL) f |= BM_SELECT;
-               if (mp->flag & ME_SMOOTH) f |= BM_SMOOTH;
-               if (mp->flag & ME_HIDE) f |= BM_HIDDEN;
+               if (flag & ME_FACE_SEL) f |= BM_SELECT;
+               if (flag & ME_SMOOTH) f |= BM_SMOOTH;
+               if (flag & ME_HIDE) f |= BM_HIDDEN;
        } else if (type == BM_EDGE) {
-               MEdge *me = element;
-               if (me->flag & SELECT) f |= BM_SELECT;
-               if (me->flag & ME_SEAM) f |= BM_SEAM;
-               if (me->flag & ME_SHARP) f |= BM_SHARP;
-               if (me->flag & ME_HIDE) f |= BM_HIDDEN;
+               if (flag & SELECT) f |= BM_SELECT;
+               if (flag & ME_SEAM) f |= BM_SEAM;
+               if (flag & ME_SHARP) f |= BM_SHARP;
+               if (flag & ME_HIDE) f |= BM_HIDDEN;
        } else if (type == BM_VERT) {
-               MVert *mv = element;
-               if (mv->flag & SELECT) f |= BM_SELECT;
-               if (mv->flag & ME_HIDE) f |= BM_HIDDEN;
+               if (flag & SELECT) f |= BM_SELECT;
+               if (flag & ME_HIDE) f |= BM_HIDDEN;
        }
 
        return f;
index 3b48946e25a41a32f9847c51d8a0ee5b4b6c3a31..4173f368557c01f63174323260797963ee6db3a0 100644 (file)
@@ -203,7 +203,8 @@ BMFace *bmesh_mf(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **elist, int len)
        if(len < 2) goto error;
        
        /*make sure that v1 and v2 are in elist[0]*/
-       if(bmesh_verts_in_edge(v1,v2,elist[0]) == 0) goto error;
+       if(bmesh_verts_in_edge(v1,v2,elist[0]) == 0) 
+               goto error;
        
        /*clear euler flags*/
        for(i=0;i<len;i++) elist[i]->head.eflag1=elist[i]->head.eflag2 = 0;
index 672cbb2ff7ca9fd9ef466a6fba9f28b845f3e303..bbe6ae748ee98b9dc4d1ba8c669eb9113fbeccdd 100644 (file)
@@ -60,12 +60,12 @@ void BM_Data_Interp_From_Verts(BMesh *bm, BMVert *v1, BMVert *v2, BMVert *v, flo
 {
        void *src[2];
        float w[2];
-       if (v1->data && v2->data) {
-               src[0]= v1->data;
-               src[1]= v2->data;
+       if (v1->head.data && v2->head.data) {
+               src[0]= v1->head.data;
+               src[1]= v2->head.data;
                w[0] = 1.0f-fac;
                w[1] = fac;
-               CustomData_bmesh_interp(&bm->vdata, src, w, NULL, 2, v->data);
+               CustomData_bmesh_interp(&bm->vdata, src, w, NULL, 2, v->head.data);
        }
 }
 
@@ -101,10 +101,10 @@ void BM_Data_Facevert_Edgeinterp(BMesh *bm, BMVert *v1, BMVert *v2, BMVert *v, B
                        
                }
 
-               src[0] = v1loop->data;
-               src[1] = v2loop->data;                                  
+               src[0] = v1loop->head.data;
+               src[1] = v2loop->head.data;                                     
 
-               CustomData_bmesh_interp(&bm->ldata, src,w, NULL, 2, vloop->data);                               
+               CustomData_bmesh_interp(&bm->ldata, src,w, NULL, 2, vloop->head.data);                          
                l = l->radial.next->data;
        }while(l!=e1->loop);
 }
@@ -123,7 +123,7 @@ void BM_loops_to_corners(BMesh *bm, Mesh *me, int findex,
 
        for(i=0; i < numTex; i++){
                texface = CustomData_get_n(&me->fdata, CD_MTFACE, findex, i);
-               texpoly = CustomData_bmesh_get_n(&bm->pdata, f->data, CD_MTEXPOLY, i);
+               texpoly = CustomData_bmesh_get_n(&bm->pdata, f->head.data, CD_MTEXPOLY, i);
                
                texface->tpage = texpoly->tpage;
                texface->flag = texpoly->flag;
@@ -134,7 +134,7 @@ void BM_loops_to_corners(BMesh *bm, Mesh *me, int findex,
 
                j = 0;
                BM_ITER(l, &iter, bm, BM_LOOPS_OF_FACE, f) {
-                       mloopuv = CustomData_bmesh_get_n(&bm->ldata, l->data, CD_MLOOPUV, i);
+                       mloopuv = CustomData_bmesh_get_n(&bm->ldata, l->head.data, CD_MLOOPUV, i);
                        texface->uv[j][0] = mloopuv->uv[0];
                        texface->uv[j][1] = mloopuv->uv[1];
 
@@ -148,7 +148,7 @@ void BM_loops_to_corners(BMesh *bm, Mesh *me, int findex,
 
                j = 0;
                BM_ITER(l, &iter, bm, BM_LOOPS_OF_FACE, f) {
-                       mloopcol = CustomData_bmesh_get_n(&bm->ldata, l->data, CD_MLOOPCOL, i);
+                       mloopcol = CustomData_bmesh_get_n(&bm->ldata, l->head.data, CD_MLOOPCOL, i);
                        mcol[j].r = mloopcol->r;
                        mcol[j].g = mloopcol->g;
                        mcol[j].b = mloopcol->b;
index be983139249cdc5de87ede9b3ddcb3312cd0abb4..48b0d117843a702aac3ac0a6de3043e7d40468b3 100644 (file)
@@ -132,11 +132,11 @@ void BM_Free_Mesh_Data(BMesh *bm)
        BMIter faces;
        BMIter loops;
        
-       for(v = BMIter_New(&verts, bm, BM_VERTS_OF_MESH, bm ); v; v = BMIter_Step(&verts)) CustomData_bmesh_free_block( &(bm->vdata), &(v->data) );
-       for(e = BMIter_New(&edges, bm, BM_EDGES_OF_MESH, bm ); e; e = BMIter_Step(&edges)) CustomData_bmesh_free_block( &(bm->edata), &(e->data) );
+       for(v = BMIter_New(&verts, bm, BM_VERTS_OF_MESH, bm ); v; v = BMIter_Step(&verts)) CustomData_bmesh_free_block( &(bm->vdata), &(v->head.data) );
+       for(e = BMIter_New(&edges, bm, BM_EDGES_OF_MESH, bm ); e; e = BMIter_Step(&edges)) CustomData_bmesh_free_block( &(bm->edata), &(e->head.data) );
        for(f = BMIter_New(&faces, bm, BM_FACES_OF_MESH, bm ); f; f = BMIter_Step(&faces)){
-               CustomData_bmesh_free_block( &(bm->pdata), &(f->data) );
-               for(l = BMIter_New(&loops, bm, BM_LOOPS_OF_FACE, f ); l; l = BMIter_Step(&loops)) CustomData_bmesh_free_block( &(bm->ldata), &(l->data) );
+               CustomData_bmesh_free_block( &(bm->pdata), &(f->head.data) );
+               for(l = BMIter_New(&loops, bm, BM_LOOPS_OF_FACE, f ); l; l = BMIter_Step(&loops)) CustomData_bmesh_free_block( &(bm->ldata), &(l->head.data) );
        }
 
        /*Free custom data pools, This should probably go in CustomData_free?*/
index 95baf1182dc792902bbb0ce38da8e0db5b42a057..433b8a74387fa682fe6f5deecc7eae2bd4e3b844 100644 (file)
@@ -316,9 +316,9 @@ void BM_Collapse_Vert(BMesh *bm, BMEdge *ke, BMVert *kv, float fac){
                                tvloop = l;
                                kvloop = ((BMLoop*)(l->head.next));
 
-                               src[0] = kvloop->data;
-                               src[1] = tvloop->data;
-                               CustomData_bmesh_interp(&bm->ldata, src,w, NULL, 2, kvloop->data);
+                               src[0] = kvloop->head.data;
+                               src[1] = tvloop->head.data;
+                               CustomData_bmesh_interp(&bm->ldata, src,w, NULL, 2, kvloop->head.data);
                        }
                        l=l->radial.next->data;
                }while(l!=ke->loop);
index 4ead478c6ff29a12d6f5d9bd60ad303fda0e8008..97e99f35a49821f84185b24bef60e2fa1b222831 100644 (file)
@@ -3,6 +3,28 @@
 
 #include <stdio.h>
 
+/*do not rename any operator or slot names! otherwise you must go 
+  through the code and find all references to them!*/
+
+BMOpDefine def_removedoubles = {
+       "removedoubles",
+       /*maps welded vertices to verts they should weld to.*/
+       {{BMOP_OPSLOT_ELEMENT_BUF, "verts"},
+        {BMOP_OPSLOT_FLT,         "dist"},
+        {0, /*null-terminating sentinel*/}},
+       bmesh_removedoubles_exec,
+       0,
+};
+
+BMOpDefine def_weldverts = {
+       "weldverts",
+       /*maps welded vertices to verts they should weld to.*/
+       {{BMOP_OPSLOT_MAPPING, "targetmap"},
+        {0, /*null-terminating sentinel*/}},
+       bmesh_weldverts_exec,
+       0,
+};
+
 BMOpDefine def_makevert = {
        "makevert",
        {{BMOP_OPSLOT_VEC, "co"},
@@ -157,6 +179,15 @@ BMOpDefine def_dissolveedgessop = {
        0
 };
 
+BMOpDefine def_dissolveedgeloopsop = {
+       "dissolveedgeloop",
+       {{BMOP_OPSLOT_ELEMENT_BUF, "edges"},
+       {BMOP_OPSLOT_ELEMENT_BUF, "regionout"},
+       {0} /*null-terminating sentinel*/},
+       dissolve_edgeloop_exec,
+       0
+};
+
 BMOpDefine def_dissolvefacesop = {
        "dissolvefaces",
        {{BMOP_OPSLOT_ELEMENT_BUF, "faces"},
@@ -256,6 +287,7 @@ BMOpDefine *opdefines[] = {
        &def_triangop,
        &def_dissolvefacesop,
        &def_dissolveedgessop,
+       &def_dissolveedgeloopsop,
        &def_dissolvevertsop,
        &def_makefgonsop,
        &def_extrudefaceregion,
@@ -270,6 +302,8 @@ BMOpDefine *opdefines[] = {
        &def_edgenet_fill,
        &def_contextual_create,
        &def_makevert,
+       &def_weldverts,
+       &def_removedoubles,
 };
 
 int bmesh_total_ops = (sizeof(opdefines) / sizeof(void*));
index d57bc826fdb0d79fa54e709dd3c4cc9bcf1234b8..6f25c81bfe7ff56770f67377d3cef7a6ce81dc3d 100644 (file)
@@ -587,12 +587,58 @@ static void *alloc_slot_buffer(BMOperator *op, char *slotname, int len){
        return op->slots[slotcode].data.buf;
 }
 
+
+/*
+ *
+ * BMO_ALL_TO_SLOT
+ *
+ * Copies all elements of a certain type into an operator slot.
+ *
+*/
+
+void BMO_All_To_Slot(BMesh *bm, BMOperator *op, char *slotname, int type)
+{
+       BMIter elements;
+       BMHeader *e;
+       BMOpSlot *output = BMO_GetSlot(op, slotname);
+       int totelement=0, i=0;
+       
+       if (type & BM_VERT) totelement += bm->totvert;
+       if (type & BM_EDGE) totelement += bm->totedge;
+       if (type & BM_FACE) totelement += bm->totface;
+
+       if(totelement){
+               alloc_slot_buffer(op, slotname, totelement);
+
+               if (type & BM_VERT) {
+                       for (e = BMIter_New(&elements, bm, BM_VERTS_OF_MESH, bm); e; e = BMIter_Step(&elements)) {
+                               ((BMHeader**)output->data.p)[i] = e;
+                               i++;
+                       }
+               }
+
+               if (type & BM_EDGE) {
+                       for (e = BMIter_New(&elements, bm, BM_EDGES_OF_MESH, bm); e; e = BMIter_Step(&elements)) {
+                               ((BMHeader**)output->data.p)[i] = e;
+                               i++;
+                       }
+               }
+
+               if (type & BM_FACE) {
+                       for (e = BMIter_New(&elements, bm, BM_FACES_OF_MESH, bm); e; e = BMIter_Step(&elements)) {
+                               ((BMHeader**)output->data.p)[i] = e;
+                               i++;
+                       }
+               }
+       }
+}
+
 /*
  *
  * BMO_HEADERFLAG_TO_SLOT
  *
  * Copies elements of a certain type, which have a certain header flag set 
- * into an output slot for an operator.
+ * into a slot for an operator.
  *
 */
 
@@ -603,7 +649,7 @@ void BMO_HeaderFlag_To_Slot(BMesh *bm, BMOperator *op, char *slotname, int flag,
        BMOpSlot *output = BMO_GetSlot(op, slotname);
        int totelement=0, i=0;
        
-       totelement = BM_CountFlag(bm, type, BM_SELECT);
+       totelement = BM_CountFlag(bm, type, flag);
 
        if(totelement){
                alloc_slot_buffer(op, slotname, totelement);
@@ -877,12 +923,13 @@ static void clear_flag_layer(BMesh *bm)
 }
 
 void *BMO_IterNew(BMOIter *iter, BMesh *bm, BMOperator *op, 
-                 char *slotname)
+                 char *slotname, int restrict)
 {
        BMOpSlot *slot = BMO_GetSlot(op, slotname);
 
        iter->slot = slot;
        iter->cur = 0;
+       iter->restrict = restrict;
 
        if (iter->slot->slottype == BMOP_OPSLOT_MAPPING)
                if (iter->slot->data.ghash)
@@ -894,9 +941,17 @@ void *BMO_IterNew(BMOIter *iter, BMesh *bm, BMOperator *op,
 void *BMO_IterStep(BMOIter *iter)
 {
        if (iter->slot->slottype == BMOP_OPSLOT_ELEMENT_BUF) {
+               BMHeader *h;
+
                if (iter->cur >= iter->slot->len) return NULL;
 
-               return ((void**)iter->slot->data.buf)[iter->cur++];
+               h = ((void**)iter->slot->data.buf)[iter->cur++];
+               while (!(iter->restrict & h->type)) {
+                       if (iter->cur >= iter->slot->len) return NULL;
+                       h = ((void**)iter->slot->data.buf)[iter->cur++];
+               }
+
+               return h;
        } else if (iter->slot->slottype == BMOP_OPSLOT_MAPPING) {
                struct element_mapping *map; 
                void *ret = BLI_ghashIterator_getKey(&iter->giter);
@@ -1151,6 +1206,7 @@ int BMO_VInitOpf(BMesh *bm, BMOperator *op, char *fmt, va_list vlist)
                                break;
                        case 'f':
                        case 'h':
+                       case 'a':
                                type = *fmt;
 
                                if (nextc(fmt) == ' ' || nextc(fmt) == '\t' || 
@@ -1176,6 +1232,8 @@ int BMO_VInitOpf(BMesh *bm, BMOperator *op, char *fmt, va_list vlist)
                                        if (type == 'h')
                                                BMO_HeaderFlag_To_Slot(bm, op, 
                                                   slotname, va_arg(vlist, int), ret);
+                                       else if (type == 'a')
+                                               BMO_All_To_Slot(bm, op, slotname, ret);
                                        else
                                                BMO_Flag_To_Slot(bm, op, slotname, 
                                                             va_arg(vlist, int), ret);
index f5c349af1288ee75f0bd9d4bad7f7ee43d905b8c..04c4fe15e10b65cf7bb372bb9296b6866b0677bb 100644 (file)
@@ -30,5 +30,8 @@ void bmesh_edgenet_fill_exec(BMesh *bm, BMOperator *op);
 void bmesh_rotate_exec(BMesh *bm, BMOperator *op);
 void bmesh_makevert_exec(BMesh *bm, BMOperator *op);
 void dissolveedges_exec(BMesh *bm, BMOperator *op);
+void dissolve_edgeloop_exec(BMesh *bm, BMOperator *op);
+void bmesh_weldverts_exec(BMesh *bm, BMOperator *op);
+void bmesh_removedoubles_exec(BMesh *bm, BMOperator *op);
 
 #endif
index 44ced6f064e2359a2ae12a56b00a844a191b82bf..c5a9916ae24c58efe9bb54fda0c4a165066c73ce 100644 (file)
@@ -98,7 +98,7 @@ int BM_Vert_In_Face(BMFace *f, BMVert *v)
  * that appear in a given face
  *
 */
-int BM_VERTS_OF_MESH_In_Face(BMesh *bm, BMFace *f, BMVert **varr, int len)
+int BM_Verts_In_Face(BMesh *bm, BMFace *f, BMVert **varr, int len)
 {
        BMLoop *curloop = NULL;
        int i, count = 0;
@@ -146,7 +146,7 @@ int BM_Edge_In_Face(BMFace *f, BMEdge *e)
  *
 */
 
-int BM_VERTS_OF_MESH_In_Edge(BMVert *v1, BMVert *v2, BMEdge *e)
+int BM_Verts_In_Edge(BMVert *v1, BMVert *v2, BMEdge *e)
 {
        return bmesh_verts_in_edge(v1,v2,e);
 }
@@ -500,7 +500,7 @@ int BM_Exist_Face_Overlaps(BMesh *bm, BMVert **varr, int len, BMFace **overlapfa
        for(i=0; i < len; i++){
                f = BMIter_New(&vertfaces, bm, BM_FACES_OF_VERT, varr[i] );
                while(f){
-                       amount = BM_VERTS_OF_MESH_In_Face(bm, f, varr, len);
+                       amount = BM_Verts_In_Face(bm, f, varr, len);
                        if(amount >= len){
                                if (overlapface) *overlapface = f;
                                return 1;                               
@@ -536,7 +536,7 @@ int BM_Face_Exists(BMesh *bm, BMVert **varr, int len, BMFace **existface)
        for(i=0; i < len; i++){
                f = BMIter_New(&vertfaces, bm, BM_FACES_OF_VERT, varr[i] );
                while(f){
-                       amount = BM_VERTS_OF_MESH_In_Face(bm, f, varr, len);
+                       amount = BM_Verts_In_Face(bm, f, varr, len);
                        if(amount == len && amount == f->len){
                                if (existface) *existface = f;
                                return 1;                               
index 61c88988bd59ef9704d9a6e4c96b438351bdd546..a14f1d662aeed9a6016b07d543cd643025b31a0d 100644 (file)
@@ -93,7 +93,7 @@ BMVert *bmesh_addvertlist(BMesh *bm, BMVert *example){
        v->co[0] = v->co[1] = v->co[2] = 0.0f;
        v->no[0] = v->no[1] = v->no[2] = 0.0f;
        v->edge = NULL;
-       v->data = NULL;
+       v->head.data = NULL;
        v->bweight = 0.0f;
        BLI_addtail(&(bm->verts), &(v->head));
        bm->nextv++;
@@ -101,10 +101,10 @@ BMVert *bmesh_addvertlist(BMesh *bm, BMVert *example){
 
        if(example){
                VECCOPY(v->co,example->co);
-               CustomData_bmesh_copy_data(&bm->vdata, &bm->vdata, example->data, &v->data);
+               CustomData_bmesh_copy_data(&bm->vdata, &bm->vdata, example->head.data, &v->head.data);
        }
        else
-               CustomData_bmesh_set_default(&bm->vdata, &v->data);
+               CustomData_bmesh_set_default(&bm->vdata, &v->head.data);
 
        /*allocate flags*/
        v->head.flags = BLI_mempool_calloc(bm->flagpool);
@@ -124,16 +124,16 @@ BMEdge *bmesh_addedgelist(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge *example){
        e->d1.data = e;
        e->d2.data = e;
        e->loop = NULL;
-       e->data = NULL;
+       e->head.data = NULL;
        e->crease = e->bweight = 0.0f;
        bm->nexte++;
        bm->totedge++;
        BLI_addtail(&(bm->edges), &(e->head));
        
        if(example)
-               CustomData_bmesh_copy_data(&bm->edata, &bm->edata, example->data, &e->data);
+               CustomData_bmesh_copy_data(&bm->edata, &bm->edata, example->head.data, &e->head.data);
        else
-               CustomData_bmesh_set_default(&bm->edata, &e->data);
+               CustomData_bmesh_set_default(&bm->edata, &e->head.data);
 
        /*allocate flags*/
        e->head.flags = BLI_mempool_calloc(bm->flagpool);
@@ -152,14 +152,14 @@ BMLoop *bmesh_create_loop(BMesh *bm, BMVert *v, BMEdge *e, BMFace *f, BMLoop *ex
        l->v = v;
        l->e = e;
        l->f = f;
-       l->data = NULL;
+       l->head.data = NULL;
        bm->nextl++;
        bm->totloop++;
        
        if(example)
-               CustomData_bmesh_copy_data(&bm->ldata, &bm->ldata, example->data, &l->data);
+               CustomData_bmesh_copy_data(&bm->ldata, &bm->ldata, example->head.data, &l->head.data);
        else
-               CustomData_bmesh_set_default(&bm->ldata, &l->data);
+               CustomData_bmesh_set_default(&bm->ldata, &l->head.data);
 
        return l;
 }
@@ -173,16 +173,16 @@ BMFace *bmesh_addpolylist(BMesh *bm, BMFace *example){
        f->head.type = BM_FACE;
        f->loopbase = NULL;
        f->len = 0;
-       f->data = NULL;
+       f->head.data = NULL;
        f->mat_nr = 0;
        BLI_addtail(&(bm->polys),&(f->head));
        bm->nextp++;
        bm->totface++;
 
        if(example)
-               CustomData_bmesh_copy_data(&bm->pdata, &bm->pdata, example->data, &f->data);
+               CustomData_bmesh_copy_data(&bm->pdata, &bm->pdata, example->head.data, &f->head.data);
        else
-               CustomData_bmesh_set_default(&bm->pdata, &f->data);
+               CustomData_bmesh_set_default(&bm->pdata, &f->head.data);
 
        /*allocate flags*/
        f->head.flags = BLI_mempool_calloc(bm->flagpool);
@@ -195,13 +195,13 @@ BMFace *bmesh_addpolylist(BMesh *bm, BMFace *example){
 */
 void bmesh_free_vert(BMesh *bm, BMVert *v){
        bm->totvert--;
-       CustomData_bmesh_free_block(&bm->vdata, &v->data);
+       CustomData_bmesh_free_block(&bm->vdata, &v->head.data);
        BLI_mempool_free(bm->flagpool, v->head.flags);
        BLI_mempool_free(bm->vpool, v);
 }
 void bmesh_free_edge(BMesh *bm, BMEdge *e){
        bm->totedge--;
-       CustomData_bmesh_free_block(&bm->edata, &e->data);
+       CustomData_bmesh_free_block(&bm->edata, &e->head.data);
        BLI_mempool_free(bm->flagpool, e->head.flags);
        BLI_mempool_free(bm->epool, e);
 }
@@ -210,13 +210,13 @@ void bmesh_free_poly(BMesh *bm, BMFace *f){
                bm->act_face = NULL;
 
        bm->totface--;
-       CustomData_bmesh_free_block(&bm->pdata, &f->data);
+       CustomData_bmesh_free_block(&bm->pdata, &f->head.data);
        BLI_mempool_free(bm->flagpool, f->head.flags);
        BLI_mempool_free(bm->ppool, f);
 }
 void bmesh_free_loop(BMesh *bm, BMLoop *l){
        bm->totloop--;
-       CustomData_bmesh_free_block(&bm->ldata, &l->data);
+       CustomData_bmesh_free_block(&bm->ldata, &l->head.data);
        BLI_mempool_free(bm->lpool, l);
 }
 /**
index 4d082d6f83449b5202b72b267ccc11d9b50bc1c8..4654d3532554c56b1948b73727314fea8a81482e 100644 (file)
@@ -48,7 +48,7 @@ static void loops_to_editmesh_corners(BMesh *bm, CustomData *facedata, void *fac
 
        for(i=0; i < numTex; i++){
                texface = CustomData_em_get_n(facedata, face_block, CD_MTFACE, i);
-               texpoly = CustomData_bmesh_get_n(&bm->pdata, f->data, CD_MTEXPOLY, i);
+               texpoly = CustomData_bmesh_get_n(&bm->pdata, f->head.data, CD_MTEXPOLY, i);
                
                texface->tpage = texpoly->tpage;
                texface->flag = texpoly->flag;
@@ -60,7 +60,7 @@ static void loops_to_editmesh_corners(BMesh *bm, CustomData *facedata, void *fac
                j = 0;
                l = f->loopbase;
                do {
-                       mloopuv = CustomData_bmesh_get_n(&bm->ldata, l->data, CD_MLOOPUV, i);
+                       mloopuv = CustomData_bmesh_get_n(&bm->ldata, l->head.data, CD_MLOOPUV, i);
                        texface->uv[j][0] = mloopuv->uv[0];
                        texface->uv[j][1] = mloopuv->uv[1];
                        j++;
@@ -74,7 +74,7 @@ static void loops_to_editmesh_corners(BMesh *bm, CustomData *facedata, void *fac
                j = 0;
                l = f->loopbase;
                do {
-                       mloopcol = CustomData_bmesh_get_n(&bm->ldata, l->data, CD_MLOOPCOL, i);
+                       mloopcol = CustomData_bmesh_get_n(&bm->ldata, l->head.data, CD_MLOOPCOL, i);
                        mcol[j].r = mloopcol->r;
                        mcol[j].g = mloopcol->g;
                        mcol[j].b = mloopcol->b;
@@ -99,7 +99,7 @@ static EditVert *bmeshvert_to_editvert(BMesh *bm, EditMesh *em, BMVert *v, int i
        if (v->head.flag & BM_SELECT) eve->f |= SELECT;
 
        eve->bweight = v->bweight;
-       CustomData_em_copy_data(&bm->vdata, &em->vdata, v->data, &eve->data);
+       CustomData_em_copy_data(&bm->vdata, &em->vdata, v->head.data, &eve->data);
        /*copy normal*/
        eve->no[0] = v->no[0];
        eve->no[1] = v->no[1];
@@ -120,7 +120,7 @@ static void bmeshedge_to_editedge_internal(BMesh *bm, EditMesh *em, BMEdge *e, E
        if (e->head.flag & BM_HIDDEN) eed->h = 1;
        if (e->head.flag & BM_FGON) eed->h |= EM_FGON;
 
-       CustomData_em_copy_data(&bm->edata, &em->edata, e->data, &eed->data);
+       CustomData_em_copy_data(&bm->edata, &em->edata, e->head.data, &eed->data);
 }
 
 static EditEdge *bmeshedge_to_editedge(BMesh *bm, EditMesh *em, BMEdge *e, EditVert **evlist)
@@ -178,7 +178,7 @@ static EditFace *bmeshface_to_editface(BMesh *bm, EditMesh *em, BMFace *f, EditV
        if (f->head.flag & BM_SMOOTH) efa->flag |= ME_SMOOTH;
        if (f->head.flag & BM_ACTIVE) EM_set_actFace(em, efa);
 
-       CustomData_em_copy_data(&bm->pdata, &em->fdata, f->data, &efa->data);
+       CustomData_em_copy_data(&bm->pdata, &em->fdata, f->head.data, &efa->data);
        loops_to_editmesh_corners(bm, &em->fdata, efa->data, f, numCol,numTex);
        
        return efa;
index 25c30bcd053ea641c909aef45dfb5ccf2b5da5fc..6f7fac9fa45337e3283d02c2ca7c53589fb607cc 100644 (file)
@@ -51,7 +51,7 @@ static void editmesh_corners_to_loops(BMesh *bm, CustomData *facedata, void *fac
 
        for(i=0; i < numTex; i++){
                texface = CustomData_em_get_n(facedata, face_block, CD_MTFACE, i);
-               texpoly = CustomData_bmesh_get_n(&bm->pdata, f->data, CD_MTEXPOLY, i);
+               texpoly = CustomData_bmesh_get_n(&bm->pdata, f->head.data, CD_MTEXPOLY, i);
                
                texpoly->tpage = texface->tpage;
                texpoly->flag = texface->flag;
@@ -61,7 +61,7 @@ static void editmesh_corners_to_loops(BMesh *bm, CustomData *facedata, void *fac
                texpoly->unwrap = texface->unwrap;
                
                for (j=0, l=BMIter_New(&iter, bm, BM_LOOPS_OF_FACE, f); l; j++, l=BMIter_Step(&iter)) {
-                       mloopuv = CustomData_bmesh_get_n(&bm->ldata, l->data, CD_MLOOPUV, i);
+                       mloopuv = CustomData_bmesh_get_n(&bm->ldata, l->head.data, CD_MLOOPUV, i);
                        mloopuv->uv[0] = texface->uv[j][0];
                        mloopuv->uv[1] = texface->uv[j][1];
                }
@@ -70,7 +70,7 @@ static void editmesh_corners_to_loops(BMesh *bm, CustomData *facedata, void *fac
        for(i=0; i < numCol; i++){
                mcol = CustomData_em_get_n(facedata, face_block, CD_MCOL, i);
                for (j=0, l=BMIter_New(&iter, bm, BM_LOOPS_OF_FACE, f); l; j++, l=BMIter_Step(&iter)) {
-                       mloopcol = CustomData_bmesh_get_n(&bm->ldata, l->data, CD_MLOOPCOL, i);
+                       mloopcol = CustomData_bmesh_get_n(&bm->ldata, l->head.data, CD_MLOOPCOL, i);
                        mloopcol->r = mcol[j].r;
                        mloopcol->g = mcol[j].g;
                        mloopcol->b = mcol[j].b;
@@ -102,7 +102,7 @@ static BMVert *editvert_to_BMVert(BMesh *bm, BMOperator *op, EditMesh *em, EditV
                BMO_Insert_MapPointer(bm, op, "map", eve, v);
 
                /*Copy Custom Data*/
-               CustomData_bmesh_copy_data(&em->vdata, &bm->vdata, eve->data, &v->data);
+               CustomData_bmesh_copy_data(&em->vdata, &bm->vdata, eve->data, &v->head.data);
                
                return v;
 }      
@@ -126,7 +126,7 @@ static void editedge_to_BMEdge_internal(BMesh *bm, BMOperator *op, EditMesh *em,
        e->head.flag |= eed->h & EM_FGON ? BM_FGON : 0;
        e->head.flag |= eed->sharp ? BM_SHARP : 0;
 
-       CustomData_bmesh_copy_data(&em->edata, &bm->edata, eed->data, &e->data);
+       CustomData_bmesh_copy_data(&em->edata, &bm->edata, eed->data, &e->head.data);
 
        BMO_Insert_MapPointer(bm, op, "map", eed, e);
 }
@@ -203,7 +203,7 @@ static BMFace *editface_to_BMFace(BMesh *bm, BMOperator *op, EditMesh *em, EditF
 
                if (efa == em->act_face) f->head.flag |= BM_ACTIVE;
                
-               CustomData_bmesh_copy_data(&em->fdata, &bm->pdata, efa->data, &f->data);
+               CustomData_bmesh_copy_data(&em->fdata, &bm->pdata, efa->data, &f->head.data);
                editmesh_corners_to_loops(bm, &em->fdata, efa->data, f,numCol,numTex);
 
                return f;
index ef4d3ff661c8ecd3862ea1d7b07732d6534cbf20..29ec08868ec933146a083a3eef3f0b7a209175ed 100644 (file)
@@ -69,7 +69,7 @@ void bmesh_contextual_create_exec(BMesh *bm, BMOperator *op)
        int totv=0, tote=0, totf=0, amount;
 
        /*count number of each element type we were passed*/
-       BMO_ITER(h, &oiter, bm, op, "geom") {
+       BMO_ITER(h, &oiter, bm, op, "geom", BM_VERT|BM_EDGE|BM_FACE) {
                switch (h->type) {
                        case BM_VERT: totv++; break;
                        case BM_EDGE: tote++; break;
@@ -82,7 +82,7 @@ void bmesh_contextual_create_exec(BMesh *bm, BMOperator *op)
        /*first call dissolve faces*/
        BMO_InitOpf(bm, &op2, "dissolvefaces faces=%ff", ELE_NEW);
        BMO_Exec_Op(bm, &op2);
-       BMO_ITER(f, &oiter, bm, &op2, "regionout") {
+       BMO_ITER(f, &oiter, bm, &op2, "regionout", BM_FACE) {
                BMO_SetFlag(bm, f, ELE_OUT);
 
                /*unflag verts associated with dissolved faces*/
@@ -95,7 +95,7 @@ void bmesh_contextual_create_exec(BMesh *bm, BMOperator *op)
        /*then call edgenet create, which may still be unimplemented, heh*/
        BMO_InitOpf(bm, &op2, "edgenet_fill edges=%fe", ELE_NEW);
        BMO_Exec_Op(bm, &op2);
-       BMO_ITER(f, &oiter, bm, &op2, "faceout") {
+       BMO_ITER(f, &oiter, bm, &op2, "faceout", BM_FACE) {
                BMO_SetFlag(bm, f, ELE_OUT);
 
                /*unflag verts associated with the output faces*/
index c9b47fc2c8c9281630dda46614e5bf0d0dbce136..997a24d0507bdbcaec4e4dde8aa41fd0e88b99ac 100644 (file)
@@ -62,7 +62,7 @@ void dissolvefaces_exec(BMesh *bm, BMOperator *op)
        BMO_Flag_Buffer(bm, op, "faces", FACE_MARK);
        
        /*collect regions*/
-       f = BMO_IterNew(&oiter, bm, op, "faces");
+       f = BMO_IterNew(&oiter, bm, op, "faces", BM_FACE);
        for (; f; f=BMO_IterStep(&oiter)) {
                if (!BMO_TestFlag(bm, f, FACE_MARK)) continue;
 
@@ -188,7 +188,8 @@ cleanup:
        V_FREE(regions);
 }
 
-void dissolveedges_exec(BMesh *bm, BMOperator *op)
+/*almost identical to dissolve edge, except it cleans up vertices*/
+void dissolve_edgeloop_exec(BMesh *bm, BMOperator *op)
 {
        BMOperator fop;
        BMOIter oiter;
@@ -199,7 +200,7 @@ void dissolveedges_exec(BMesh *bm, BMOperator *op)
        BMFace *f;
        int i;
 
-       BMO_ITER(e, &oiter, bm, op, "edges") {
+       BMO_ITER(e, &oiter, bm, op, "edges", BM_EDGE) {
                if (BM_Edge_FaceCount(e) == 2) {
                        BMO_SetFlag(bm, e->v1, VERT_MARK);
                        BMO_SetFlag(bm, e->v2, VERT_MARK);
@@ -219,6 +220,7 @@ void dissolveedges_exec(BMesh *bm, BMOperator *op)
                }
        }
 
+       /*clean up extreneous 2-valence vertices*/
        for (i=0; i<V_COUNT(verts); i++) {
                BM_Collapse_Vert(bm, verts[i]->edge, verts[i], 1.0);
        }
@@ -233,6 +235,36 @@ void dissolveedges_exec(BMesh *bm, BMOperator *op)
        //BMO_Finish_Op(bm, &fop);
 }
 
+
+void dissolveedges_exec(BMesh *bm, BMOperator *op)
+{
+       BMOperator fop;
+       BMOIter oiter;
+       BMIter iter;
+       BMVert *v;
+       BMEdge *e;
+       BMFace *f;
+       int i;
+
+       BMO_ITER(e, &oiter, bm, op, "edges", BM_EDGE) {
+               if (BM_Edge_FaceCount(e) == 2) {
+                       BMO_SetFlag(bm, e->v1, VERT_MARK);
+                       BMO_SetFlag(bm, e->v2, VERT_MARK);
+
+                       BM_Join_Faces(bm, e->loop->f, 
+                                     ((BMLoop*)e->loop->radial.next->data)->f,
+                                     e);
+               }
+       }
+
+       //BMO_InitOpf(bm, &fop, "dissolvefaces faces=%ff", FACE_MARK);
+       //BMO_Exec_Op(bm, &fop);
+
+       //BMO_CopySlot(op, &fop, "regionout", "regionout");
+
+       //BMO_Finish_Op(bm, &fop);
+}
+
 static int test_extra_verts(BMesh *bm, BMVert *v)
 {
        BMIter iter, liter, iter2, iter3;
index 3d2235e8138704e885a1b402803ad46bf1c79294..5417d232205fb02999e59357b81eab4eb97658ab 100644 (file)
@@ -20,7 +20,7 @@ void extrude_vert_indiv_exec(BMesh *bm, BMOperator *op)
        BMVert *v, *dupev;
        BMEdge *e;
 
-       v = BMO_IterNew(&siter, bm, op, "verts");
+       v = BMO_IterNew(&siter, bm, op, "verts", BM_VERT);
        for (; v; v=BMO_IterStep(&siter)) {
                dupev = BM_Make_Vert(bm, v->co, NULL);
                VECCOPY(dupev->no, v->no);
@@ -118,7 +118,7 @@ void extrude_edge_context_exec(BMesh *bm, BMOperator *op)
        }
        
        BMO_CopySlot(&dupeop, op, "newout", "geomout");
-       e = BMO_IterNew(&siter, bm, &dupeop, "boundarymap");
+       e = BMO_IterNew(&siter, bm, &dupeop, "boundarymap", 0);
        for (; e; e=BMO_IterStep(&siter)) {
                if (BMO_InMap(bm, op, "exclude", e)) continue;
 
@@ -178,7 +178,7 @@ void extrude_edge_context_exec(BMesh *bm, BMOperator *op)
        }
 
        /*link isolated verts*/
-       v = BMO_IterNew(&siter, bm, &dupeop, "isovertmap");
+       v = BMO_IterNew(&siter, bm, &dupeop, "isovertmap", 0);
        for (; v; v=BMO_IterStep(&siter)) {
                v2 = *((void**)BMO_IterMapVal(&siter));
                BM_Make_Edge(bm, v, v2, v->edge, 1);
index a39e0f1f0595fb447f2b0a8d0e633bbb43bcec1b..28991f2cae7f4235c17ee6b932df65616fcb305a 100644 (file)
@@ -66,9 +66,9 @@ void mesh_to_bmesh_exec(BMesh *bm, BMOperator *op) {
                v->bweight = (float)mvert->bweight / 255.0f;
 
                /*Copy Custom Data*/
-               CustomData_to_bmesh_block(&me->vdata, &bm->vdata, i, &v->data);
+               CustomData_to_bmesh_block(&me->vdata, &bm->vdata, i, &v->head.data);
 
-               v->head.flag = MEFlags_To_BMFlags(mvert, BM_VERT);
+               v->head.flag = MEFlags_To_BMFlags(mvert->flag, BM_VERT);
        }
 
        if (!me->totedge) return;
@@ -81,12 +81,12 @@ void mesh_to_bmesh_exec(BMesh *bm, BMOperator *op) {
                et[i] = e;
                
                /*Copy Custom Data*/
-               CustomData_to_bmesh_block(&me->edata, &bm->edata, i, &e->data);
+               CustomData_to_bmesh_block(&me->edata, &bm->edata, i, &e->head.data);
                
                e->crease = (float)medge->crease / 255.0f;
                e->bweight = (float)medge->bweight / 255.0f;
 
-               e->head.flag = MEFlags_To_BMFlags(medge, BM_EDGE);
+               e->head.flag = MEFlags_To_BMFlags(medge->flag, BM_EDGE);
        }
        
        if (!me->totpoly) return;
@@ -117,11 +117,11 @@ void mesh_to_bmesh_exec(BMesh *bm, BMOperator *op) {
 
                f = BM_Make_Ngon(bm, v1, v2, fedges, mpoly->totloop, 0);
                
-               f->head.flag = MEFlags_To_BMFlags(mpoly, BM_FACE);
+               f->head.flag = MEFlags_To_BMFlags(mpoly->flag, BM_FACE);
                if (i == me->act_face) bm->act_face = f;
 
                /*Copy Custom Data*/
-               CustomData_to_bmesh_block(&me->fdata, &bm->pdata, i, &f->data);
+               CustomData_to_bmesh_block(&me->fdata, &bm->pdata, i, &f->head.data);
        }
 }
 
index 0fa6f113c0a9e9482dd8ed5c9521a9e1fee5e932..549146af1b7226b1ccae961544b832cadd027cc8 100644 (file)
@@ -795,7 +795,7 @@ void BM_esubdivideflag(Object *obedit, BMesh *bm, int selflag, float rad,
                BMHeader *ele;
                int i;
                
-               ele = BMO_IterNew(&iter,bm,&op, "outinner");
+               ele = BMO_IterNew(&iter,bm,&op, "outinner", BM_EDGE|BM_VERT);
                for (; ele; ele=BMO_IterStep(&iter)) {
                        BM_Select(bm, ele, 1);
                }
index e64ffa9539db759a6465a777ff2af1e539b09cf9..732a3a858601cd52686fe65a49e7b10bdb2e0796 100644 (file)
@@ -22,7 +22,7 @@ void triangulate_exec(BMesh *bm, BMOperator *op)
        V_DECLARE(projectverts);
        int i, lastlen=0, count = 0;
        
-       face = BMO_IterNew(&siter, bm, op, "faces");
+       face = BMO_IterNew(&siter, bm, op, "faces", BM_FACE);
        for (; face; face=BMO_IterStep(&siter)) {
                if (lastlen < face->len) {
                        V_RESET(projectverts);
index 3e25272c144068fe197274a38b80f47f6f02bda5..77e0b7083e21aba14415f61ddc8b0b678ad0f967 100644 (file)
@@ -48,7 +48,7 @@ void bmesh_transform_exec(BMesh *bm, BMOperator *op) {
 
        BMO_Get_Mat4(op, "mat", mat);
 
-       BMO_ITER(v, &iter, bm, op, "verts") {
+       BMO_ITER(v, &iter, bm, op, "verts", BM_VERT) {
                Mat4MulVecfl(mat, v->co);
        }
 }
index 553ff273c1524fe8821cb551f32a8e457bf99de6..b3be20b35aa057155a73f665dac1327394550fe1 100644 (file)
@@ -456,14 +456,14 @@ short EDBM_Extrude_verts_indiv(BMEditMesh *em, wmOperator *op, short flag, float
        EDBM_InitOpf(em, &bmop, op, "extrude_vert_indiv verts=%hv", flag);
 
        /*deselect original verts*/
-       v = BMO_IterNew(&siter, em->bm, &bmop, "verts");
+       v = BMO_IterNew(&siter, em->bm, &bmop, "verts", BM_VERT);
        for (; v; v=BMO_IterStep(&siter)) {
                BM_Select(em->bm, v, 0);
        }
 
        BMO_Exec_Op(em->bm, &bmop);
 
-       v = BMO_IterNew(&siter, em->bm, &bmop, "vertout");
+       v = BMO_IterNew(&siter, em->bm, &bmop, "vertout", BM_VERT);
        for (; v; v=BMO_IterStep(&siter)) {
                BM_Select(em->bm, v, 1);
        }
@@ -555,7 +555,7 @@ short EDBM_Extrude_edge(Object *obedit, BMEditMesh *em, int flag, float *nor)
 
        nor[0] = nor[1] = nor[2] = 0.0f;
        
-       BMO_ITER(el, &siter, bm, &extop, "geomout") {
+       BMO_ITER(el, &siter, bm, &extop, "geomout", BM_ALL) {
                BM_Select(bm, el, 1);
 
                if (el->type == BM_FACE) {
@@ -925,7 +925,7 @@ static int dupli_extrude_cursor(bContext *C, wmOperator *op, wmEvent *event)
                EDBM_InitOpf(vc.em, &bmop, op, "makevert co=%v", min);
                BMO_Exec_Op(vc.em->bm, &bmop);
 
-               BMO_ITER(v1, &oiter, vc.em->bm, &bmop, "newvertout") {
+               BMO_ITER(v1, &oiter, vc.em->bm, &bmop, "newvertout", BM_VERT) {
                        BM_Select(vc.em->bm, v1, 1);
                }
 
@@ -966,6 +966,11 @@ static int delete_mesh(Object *obedit, wmOperator *op, int event, Scene *scene)
                if (!EDBM_CallOpf(bem, op, "del geom=%hv context=%i", BM_SELECT, DEL_VERTS))
                        return OPERATOR_CANCELLED;
        } 
+       else if(event==11) {
+               //"Edge Loop"
+               if (!EDBM_CallOpf(bem, op, "dissolveedgeloop edges=%he", BM_SELECT))
+                       return OPERATOR_CANCELLED;
+       }
        else if(event==7) {
                //"Dissolve"
                if (bem->selectmode & SCE_SELECT_FACE) {
@@ -1011,6 +1016,7 @@ static EnumPropertyItem prop_mesh_delete_types[] = {
        {10,"VERT",             "Vertices", ""},
        {1, "EDGE",             "Edges", ""},
        {2, "FACE",             "Faces", ""},
+       {11, "EDGE_LOOP", "Edge Loop", ""},
        {4, "EDGE_FACE","Edges & Faces", ""},
        {5, "ONLY_FACE","Only Faces", ""},
        {0, NULL, NULL, NULL}
@@ -1125,7 +1131,7 @@ void MESH_OT_selection_type(wmOperatorType *ot)
        ot->idname= "MESH_OT_selection_type";
        
        /* api callbacks */
-       ot->invoke= NULL;
+       ot->invoke= WM_menu_invoke;
        ot->exec= mesh_selection_type_exec;
        
        ot->poll= ED_operator_editmesh;
index 98d69419fdb360a8315b459e3327dbdf9d186ab0..120606d9fb0a0c0957548433c845f5b195c6e5b8 100644 (file)
@@ -1228,7 +1228,7 @@ short BM_extrude_edgeflag(Object *obedit, BMesh *bm, int eflag, float *nor)
 
        BMO_Exec_Op(bm, &extop);
 
-       el =  BMO_IterNew(&siter, bm, &extop, "geomout");
+       el =  BMO_IterNew(&siter, bm, &extop, "geomout", BM_ALL);
        for (; el; el=BMO_IterStep(&siter)) {
                BM_Select(bm, el, 1);
        }
index 2399e8c615789aefbfa67607d93a5d7d7bed6560..81a5261894722132ee83edb65e386ae96ded9bea 100644 (file)
@@ -220,7 +220,7 @@ void ED_keymap_mesh(wmWindowManager *wm)
        RNA_float_set(WM_keymap_add_item(keymap, "MESH_OT_faces_select_linked_flat", FKEY, KM_PRESS, (KM_CTRL|KM_SHIFT|KM_ALT), 0)->ptr,"sharpness",135.0);
        RNA_float_set(WM_keymap_add_item(keymap, "MESH_OT_edges_select_sharp", SKEY, KM_PRESS, (KM_CTRL|KM_SHIFT|KM_ALT), 0)->ptr,"sharpness",135.0);
        
-       //WM_keymap_add_item(keymap, "MESH_OT_select_random", SPACEKEY, KM_PRESS, 0, 0);
+       WM_keymap_add_item(keymap, "MESH_OT_select_random", SPACEKEY, KM_PRESS, 0, 0);
        WM_keymap_add_item(keymap, "MESH_OT_vertices_transform_to_sphere", SKEY, KM_PRESS, KM_CTRL|KM_SHIFT , 0);
 
        WM_keymap_add_item(keymap, "MESH_OT_mark_seam", ONEKEY, KM_PRESS, KM_CTRL , 0);
@@ -235,12 +235,12 @@ void ED_keymap_mesh(wmWindowManager *wm)
        WM_keymap_add_item(keymap, "MESH_OT_faces_select_similar", GKEY, KM_PRESS, KM_SHIFT|KM_CTRL2, 0);
        
        /* selection mode */
-       kmi = WM_keymap_add_item(keymap, "MESH_OT_selection_type", QKEY, KM_PRESS, 0, 0);
-       RNA_int_set(kmi->ptr, "type", 1);
+       kmi = WM_keymap_add_item(keymap, "MESH_OT_selection_type", TABKEY, KM_PRESS, KM_CTRL, 0);
+       /*RNA_int_set(kmi->ptr, "type", 1);
        kmi = WM_keymap_add_item(keymap, "MESH_OT_selection_type", WKEY, KM_PRESS, 0, 0);
        RNA_int_set(kmi->ptr, "type", 2);
        kmi = WM_keymap_add_item(keymap, "MESH_OT_selection_type", EKEY, KM_PRESS, 0, 0);
-       RNA_int_set(kmi->ptr, "type", 3);
+       RNA_int_set(kmi->ptr, "type", 3);*/
 
        /* hide */
        WM_keymap_add_item(keymap, "MESH_OT_hide", HKEY, KM_PRESS, 0, 0);
@@ -253,12 +253,12 @@ void ED_keymap_mesh(wmWindowManager *wm)
        WM_keymap_add_item(keymap, "MESH_OT_vertices_smooth", THREEKEY, KM_PRESS, KM_CTRL , 0);
        WM_keymap_add_item(keymap, "MESH_OT_flip_editnormals", THREEKEY, KM_PRESS, KM_ALT , 0);
        
-       WM_keymap_add_item(keymap, "MESH_OT_subdivs", SPACEKEY, KM_PRESS, 0, 0); // this is the menu
+       WM_keymap_add_item(keymap, "MESH_OT_subdivs", WKEY, KM_PRESS, 0, 0); // this is the menu
        /*WM_keymap_add_item(keymap, "MESH_OT_subdivide_multi", WKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0);
        WM_keymap_add_item(keymap, "MESH_OT_subdivide_multi_fractal", WKEY, KM_PRESS, KM_ALT, 0);
        WM_keymap_add_item(keymap, "MESH_OT_subdivide_smooth", WKEY, KM_PRESS, KM_CTRL|KM_ALT, 0);*/
        WM_keymap_add_item(keymap, "MESH_OT_remove_doubles", VKEY, KM_PRESS, KM_CTRL, 0);
-       WM_keymap_add_item(keymap, "MESH_OT_extrude", TKEY, KM_PRESS, 0, 0);
+       WM_keymap_add_item(keymap, "MESH_OT_extrude", EKEY, KM_PRESS, 0, 0);
        
        WM_keymap_add_item(keymap, "MESH_OT_spin", RKEY, KM_PRESS, KM_ALT, 0);
        WM_keymap_add_item(keymap, "MESH_OT_screw", NINEKEY, KM_PRESS, KM_CTRL, 0);
index acb29ada61954938a020c7a1ea4cfb091194eda7..8d50a8afb2944ee83f6861f5166ea9768fbb4d26 100644 (file)
@@ -190,7 +190,7 @@ static void v3d_editvertex_buts(const bContext *C, uiBlock *block, View3D *v3d,
 
                /* check for defgroups */
                if(evedef)
-                       dvert= CustomData_bmesh_get(&em->bm->vdata, evedef->data, CD_MDEFORMVERT);
+                       dvert= CustomData_bmesh_get(&em->bm->vdata, evedef->head.data, CD_MDEFORMVERT);
                if(tot==1 && dvert && dvert->totweight) {
                        bDeformGroup *dg;
                        int i, max=1, init=1;