pre-merge commit. the mirror modifier is currently in pieces, to be picked back...
authorJoseph Eagar <joeedh@gmail.com>
Tue, 14 Jul 2009 06:13:43 +0000 (06:13 +0000)
committerJoseph Eagar <joeedh@gmail.com>
Tue, 14 Jul 2009 06:13:43 +0000 (06:13 +0000)
19 files changed:
projectfiles_vc9/blender/blenkernel/BKE_blenkernel.vcproj
source/blender/blenkernel/BKE_customdata.h
source/blender/blenkernel/intern/BME_conversions.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
source/blender/blenkernel/intern/object.c
source/blender/blenloader/intern/readfile.c
source/blender/bmesh/bmesh_operator_api.h
source/blender/bmesh/intern/bmesh_eulers.c
source/blender/bmesh/intern/bmesh_interp.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/editmesh_to_bmesh.c
source/blender/bmesh/operators/bmesh_dupeops.c
source/blender/bmesh/operators/mesh_conv.c
source/blender/bmesh/operators/removedoubles.c

index 8a53eed0c631ab2526a608296a6b16de64ed8cdb..4474eb8da1f4b8cbfea97024da9df3dc0e7e4ab6 100644 (file)
                                RelativePath="..\..\..\source\blender\blenkernel\intern\modifier.c"\r
                                >\r
                        </File>\r
                                RelativePath="..\..\..\source\blender\blenkernel\intern\modifier.c"\r
                                >\r
                        </File>\r
+                       <File\r
+                               RelativePath="..\..\..\source\blender\blenkernel\intern\modifiers_bmesh.c"\r
+                               >\r
+                       </File>\r
                        <File\r
                                RelativePath="..\..\..\source\blender\blenkernel\intern\multires.c"\r
                                >\r
                        <File\r
                                RelativePath="..\..\..\source\blender\blenkernel\intern\multires.c"\r
                                >\r
index b9e27a1abd44ddbd419866b04a6a09d2cc2279f1..d442a57b5252b546dbab64481ec0c70ee12bd697 100644 (file)
@@ -282,7 +282,8 @@ void CustomData_set_layer_unique_name(struct CustomData *data, int index);
 int CustomData_verify_versions(struct CustomData *data, int index);
 
 /*BMesh specific customdata stuff*/
 int CustomData_verify_versions(struct CustomData *data, int index);
 
 /*BMesh specific customdata stuff*/
-void CustomData_to_bmeshpoly(struct CustomData *fdata, struct CustomData *pdata, struct CustomData *ldata);
+void CustomData_to_bmeshpoly(struct CustomData *fdata, struct CustomData *pdata,
+                             struct CustomData *ldata, int totloop, int totpoly);
 void CustomData_from_bmeshpoly(struct CustomData *fdata, struct CustomData *pdata, struct CustomData *ldata, int total);
 void CustomData_bmesh_init_pool(struct CustomData *data, int allocsize);
 #endif
 void CustomData_from_bmeshpoly(struct CustomData *fdata, struct CustomData *pdata, struct CustomData *ldata, int total);
 void CustomData_bmesh_init_pool(struct CustomData *data, int allocsize);
 #endif
index dcfe4e6fa362f85f49ec05285a74443a271013e9..0f372790a9d6c08af7b9e2ad6590ddfd561a47b5 100644 (file)
@@ -268,7 +268,7 @@ BME_Mesh *BME_editmesh_to_bmesh(EditMesh *em) {
        CustomData_copy(&em->fdata, &bm->pdata, CD_MASK_BMESH, CD_CALLOC, 0);
 
        /*copy face corner data*/
        CustomData_copy(&em->fdata, &bm->pdata, CD_MASK_BMESH, CD_CALLOC, 0);
 
        /*copy face corner data*/
-       CustomData_to_bmeshpoly(&em->fdata, &bm->pdata, &bm->ldata);
+       CustomData_to_bmeshpoly(&em->fdata, &bm->pdata, &bm->ldata, 0, 0);
        /*initialize memory pools*/
        CustomData_bmesh_init_pool(&bm->vdata, allocsize[0]);
        CustomData_bmesh_init_pool(&bm->edata, allocsize[1]);
        /*initialize memory pools*/
        CustomData_bmesh_init_pool(&bm->vdata, allocsize[0]);
        CustomData_bmesh_init_pool(&bm->edata, allocsize[1]);
@@ -463,7 +463,7 @@ BME_Mesh *BME_derivedmesh_to_bmesh(DerivedMesh *dm)
        CustomData_copy(&dm->faceData, &bm->pdata, CD_MASK_BMESH, CD_CALLOC, 0);
 
        /*copy face corner data*/
        CustomData_copy(&dm->faceData, &bm->pdata, CD_MASK_BMESH, CD_CALLOC, 0);
 
        /*copy face corner data*/
-       CustomData_to_bmeshpoly(&dm->faceData, &bm->pdata, &bm->ldata);
+       CustomData_to_bmeshpoly(&dm->faceData, &bm->pdata, &bm->ldata, 0, 0);
        /*initialize memory pools*/
        CustomData_bmesh_init_pool(&bm->vdata, allocsize[0]);
        CustomData_bmesh_init_pool(&bm->edata, allocsize[1]);
        /*initialize memory pools*/
        CustomData_bmesh_init_pool(&bm->vdata, allocsize[0]);
        CustomData_bmesh_init_pool(&bm->edata, allocsize[1]);
index 5c29ca02e7ead2561f1c26bd22202df550d1741f..0173e660e185180c98da95132457acb8e03e551c 100644 (file)
@@ -1835,16 +1835,17 @@ void CustomData_from_em_block(const CustomData *source, CustomData *dest,
 
 /*Bmesh functions*/
 /*needed to convert to/from different face reps*/
 
 /*Bmesh functions*/
 /*needed to convert to/from different face reps*/
-void CustomData_to_bmeshpoly(CustomData *fdata, CustomData *pdata, CustomData *ldata)
+void CustomData_to_bmeshpoly(CustomData *fdata, CustomData *pdata, CustomData *ldata,
+                            int totloop, int totpoly)
 {
        int i;
        for(i=0; i < fdata->totlayer; i++){
                if(fdata->layers[i].type == CD_MTFACE){
 {
        int i;
        for(i=0; i < fdata->totlayer; i++){
                if(fdata->layers[i].type == CD_MTFACE){
-                       CustomData_add_layer(pdata, CD_MTEXPOLY, CD_CALLOC, &(fdata->layers[i].name), 0);
-                       CustomData_add_layer(ldata, CD_MLOOPUV, CD_CALLOC, &(fdata->layers[i].name), 0);
+                       CustomData_add_layer(pdata, CD_MTEXPOLY, CD_CALLOC, &(fdata->layers[i].name), totpoly);
+                       CustomData_add_layer(ldata, CD_MLOOPUV, CD_CALLOC, &(fdata->layers[i].name), totloop);
                }
                else if(fdata->layers[i].type == CD_MCOL)
                }
                else if(fdata->layers[i].type == CD_MCOL)
-                       CustomData_add_layer(ldata, CD_MLOOPCOL, CD_CALLOC, &(fdata->layers[i].name), 0);
+                       CustomData_add_layer(ldata, CD_MLOOPCOL, CD_CALLOC, &(fdata->layers[i].name), totloop);
        }               
 }
 void CustomData_from_bmeshpoly(CustomData *fdata, CustomData *pdata, CustomData *ldata, int total){
        }               
 }
 void CustomData_from_bmeshpoly(CustomData *fdata, CustomData *pdata, CustomData *ldata, int total){
index 2964914de4b6a2cd47098b6e0da0c6dd58cee3e8..fa9747ec54fad99832fdd745f61be07c46fadb83 100644 (file)
@@ -310,9 +310,17 @@ static void bmdm_recalc_lookups(EditDerivedBMesh *bmdm)
        if (bmdm->etable) MEM_freeN(bmdm->etable);
        if (bmdm->ftable) MEM_freeN(bmdm->ftable);
        
        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");
+       if (bmdm->tc->bm->totvert)
+               bmdm->vtable = MEM_mallocN(sizeof(void**)*bmdm->tc->bm->totvert, "bmdm->vtable");
+       else bmdm->vtable = NULL;
+
+       if (bmdm->tc->bm->totedge)
+               bmdm->etable = MEM_mallocN(sizeof(void**)*bmdm->tc->bm->totedge, "bmdm->etable");
+       else bmdm->etable = NULL;
+       
+       if (bmdm->tc->bm->totface)
+               bmdm->ftable = MEM_mallocN(sizeof(void**)*bmdm->tc->bm->totface, "bmdm->ftable");
+       else bmdm->ftable = NULL;
        
        for (a=0; a<3; a++) {
                h = BMIter_New(&iter, bmdm->tc->bm, iters[a], NULL);
        
        for (a=0; a<3; a++) {
                h = BMIter_New(&iter, bmdm->tc->bm, iters[a], NULL);
@@ -340,7 +348,6 @@ static void bmDM_recalcTesselation(DerivedMesh *dm)
 {
        EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
 
 {
        EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
 
-       BMEdit_RecalcTesselation_intern(bmdm->tc);
        bmdm_recalc_lookups(bmdm);
 }
 
        bmdm_recalc_lookups(bmdm);
 }
 
@@ -1403,6 +1410,14 @@ static void bmDM_release(void *dm)
                        MEM_freeN(bmdm->faceNos);
                }
                
                        MEM_freeN(bmdm->faceNos);
                }
                
+               BLI_ghash_free(bmdm->fhash, NULL, NULL);
+               BLI_ghash_free(bmdm->ehash, NULL, NULL);
+               BLI_ghash_free(bmdm->vhash, NULL, NULL);
+
+               if (bmdm->vtable) MEM_freeN(bmdm->vtable);
+               if (bmdm->etable) MEM_freeN(bmdm->etable);
+               if (bmdm->ftable) MEM_freeN(bmdm->ftable);
+               
                MEM_freeN(bmdm);
        }
 }
                MEM_freeN(bmdm);
        }
 }
index 879699e755aafe5483164def195e3999ed5f19fd..4e1f6d8265a6d8e31f3d2158ae13555838774342 100644 (file)
@@ -1826,6 +1826,7 @@ void vertgroup_flip_name (char *name, int strip_number)
        sprintf (name, "%s%s%s%s", prefix, replace, suffix, number);
 }
 
        sprintf (name, "%s%s%s%s", prefix, replace, suffix, number);
 }
 
+#if 0
 static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd,
                Object *ob,
                DerivedMesh *dm,
 static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd,
                Object *ob,
                DerivedMesh *dm,
@@ -2047,6 +2048,7 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd,
 
        return result;
 }
 
        return result;
 }
+#endif
 
 static DerivedMesh *mirrorModifier__doMirror(MirrorModifierData *mmd,
                                            Object *ob, DerivedMesh *dm,
 
 static DerivedMesh *mirrorModifier__doMirror(MirrorModifierData *mmd,
                                            Object *ob, DerivedMesh *dm,
index d52f624a91bfbc6aa70ad9cf829bfac783bf616f..b3ce91855b26f78eeaf579360cfabae2e3f1d540 100644 (file)
@@ -220,14 +220,53 @@ BMEditMesh *CDDM_To_BMesh(DerivedMesh *dm, BMEditMesh *existing)
 
 float vertarray_size(MVert *mvert, int numVerts, int axis);
 
 
 float vertarray_size(MVert *mvert, int numVerts, int axis);
 
+
+typedef struct IndexMapEntry {
+       /* the new vert index that this old vert index maps to */
+       int new;
+       /* -1 if this vert isn't merged, otherwise the old vert index it
+       * should be replaced with
+       */
+       int merge;
+       /* 1 if this vert's first copy is merged with the last copy of its
+       * merge target, otherwise 0
+       */
+       short merge_final;
+} IndexMapEntry;
+
+/* indexMap - an array of IndexMap entries
+ * oldIndex - the old index to map
+ * copyNum - the copy number to map to (original = 0, first copy = 1, etc.)
+ */
+static int calc_mapping(IndexMapEntry *indexMap, int oldIndex, int copyNum)
+{
+       if(indexMap[oldIndex].merge < 0) {
+               /* vert wasn't merged, so use copy of this vert */
+               return indexMap[oldIndex].new + copyNum;
+       } else if(indexMap[oldIndex].merge == oldIndex) {
+               /* vert was merged with itself */
+               return indexMap[oldIndex].new;
+       } else {
+               /* vert was merged with another vert */
+               /* follow the chain of merges to the end, or until we've passed
+               * a number of vertices equal to the copy number
+               */
+               if(copyNum <= 0)
+                       return indexMap[oldIndex].new;
+               else
+                       return calc_mapping(indexMap, indexMap[oldIndex].merge,
+                                           copyNum - 1);
+       }
+}
+
 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);
 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;
+       BMOperator op, oldop, weldop;
+       int i, j, indexLen;
        /* offset matrix */
        float offset[4][4];
        float final_offset[4][4];
        /* offset matrix */
        float offset[4][4];
        float final_offset[4][4];
@@ -237,6 +276,7 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
        int numVerts, numEdges, numFaces;
        int maxVerts, maxEdges, maxFaces;
        int finalVerts, finalEdges, finalFaces;
        int numVerts, numEdges, numFaces;
        int maxVerts, maxEdges, maxFaces;
        int finalVerts, finalEdges, finalFaces;
+       int *indexMap;
        DerivedMesh *result, *start_cap = NULL, *end_cap = NULL;
        MVert *src_mvert;
 
        DerivedMesh *result, *start_cap = NULL, *end_cap = NULL;
        MVert *src_mvert;
 
@@ -316,16 +356,16 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
        */
        finalVerts = dm->getNumVerts(dm) * count;
        finalEdges = dm->getNumEdges(dm) * count;
        */
        finalVerts = dm->getNumVerts(dm) * count;
        finalEdges = dm->getNumEdges(dm) * count;
-       finalFaces = dm->getNumTessFaces(dm) * count;
+       finalFaces = dm->getNumFaces(dm) * count;
        if(start_cap) {
                finalVerts += start_cap->getNumVerts(start_cap);
                finalEdges += start_cap->getNumEdges(start_cap);
        if(start_cap) {
                finalVerts += start_cap->getNumVerts(start_cap);
                finalEdges += start_cap->getNumEdges(start_cap);
-               finalFaces += start_cap->getNumTessFaces(start_cap);
+               finalFaces += start_cap->getNumFaces(start_cap);
        }
        if(end_cap) {
                finalVerts += end_cap->getNumVerts(end_cap);
                finalEdges += end_cap->getNumEdges(end_cap);
        }
        if(end_cap) {
                finalVerts += end_cap->getNumVerts(end_cap);
                finalEdges += end_cap->getNumEdges(end_cap);
-               finalFaces += end_cap->getNumTessFaces(end_cap);
+               finalFaces += end_cap->getNumFaces(end_cap);
        }
 
        /* calculate the offset matrix of the final copy (for merging) */ 
        }
 
        /* calculate the offset matrix of the final copy (for merging) */ 
@@ -336,31 +376,103 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
                MTC_Mat4CpyMat4(final_offset, tmp_mat);
        }
 
                MTC_Mat4CpyMat4(final_offset, tmp_mat);
        }
 
-
        cddm->needsFree = 1;
        cddm->release(cddm);
        
        cddm->needsFree = 1;
        cddm->release(cddm);
        
+       BMO_Init_Op(&weldop, "weldverts");
        BMO_InitOpf(em->bm, &op, "dupe geom=%avef");
        oldop = op;
        for (j=0; j < count; j++) {
        BMO_InitOpf(em->bm, &op, "dupe geom=%avef");
        oldop = op;
        for (j=0; j < count; j++) {
+               BMVert *v, *v2;
+               BMOpSlot *s1;
+               BMOpSlot *s2;
+
                BMO_InitOpf(em->bm, &op, "dupe geom=%s", &oldop, j==0 ? "geom" : "newout");
                BMO_Exec_Op(em->bm, &op);
 
                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;
+               s1 = BMO_GetSlot(&op, "geom");
+               s2 = BMO_GetSlot(&op, "newout");
 
                BMO_CallOpf(em->bm, "transform mat=%m4 verts=%s", offset, &op, "newout");
 
 
                BMO_CallOpf(em->bm, "transform mat=%m4 verts=%s", offset, &op, "newout");
 
+               #define _E(s, i) ((BMVert**)(s)->data.buf)[i]
+
+               /*calculate merge mapping*/
+               if (j == 0) {
+                       BMOperator findop;
+                       BMOIter oiter;
+                       BMIter iter;
+                       BMVert *v, *v2;
+                       BMHeader *h;
+
+                       BMO_InitOpf(em->bm, &findop, 
+                               "finddoubles verts=%av dist=%f keepverts=%s", 
+                               amd->merge_dist, &op, "geom");
+
+                       i = 0;
+                       BMO_ITER(h, &oiter, em->bm, &op, "geom", BM_ALL) {
+                               BMINDEX_SET(h, i);
+                               i++;
+                       }
+
+                       BMO_ITER(h, &oiter, em->bm, &op, "newout", BM_ALL) {
+                               BMINDEX_SET(h, i);
+                               i++;
+                       }
+
+                       BMO_Exec_Op(em->bm, &findop);
+
+                       indexLen = i;
+                       indexMap = MEM_callocN(sizeof(int)*indexLen, "indexMap");
+
+                       /*element type argument doesn't do anything here*/
+                       BMO_ITER(v, &oiter, em->bm, &findop, "targetmapout", 0) {
+                               v2 = BMO_IterMapValp(&oiter);
+
+                               /*make sure merge pairs are duplicate-to-duplicate*/
+                               /*if (BMINDEX_GET(v) >= s1->len && BMINDEX_GET(v2) >= s1->len) 
+                                       continue;
+                               else if (BMINDEX_GET(v) < s1->len && BMINDEX_GET(v2) < s1->len) 
+                                       continue;*/
+
+                               indexMap[BMINDEX_GET(v)] = BMINDEX_GET(v2)+1;
+                       }
+
+                       BMO_Finish_Op(em->bm, &findop);
+               } 
+
+               /*generate merge mappping using index map.  we do this by using the
+                 operator slots as lookup arrays.*/
+               #define E(i) (i) < s1->len ? _E(s1, i) : _E(s2, (i)-s1->len)
+
+               for (i=0; i<indexLen; i++) {
+                       if (!indexMap[i]) continue;
+
+                       v = E(i);
+                       v2 = E(indexMap[i]-1);
+
+                       BMO_Insert_MapPointer(em->bm, &weldop, "targetmap", v, v2);
+               }
+
+               #undef E
+               #undef _E
+
+               BMO_Finish_Op(em->bm, &oldop);
+               oldop = op;
        }
 
        if (j > 0) BMO_Finish_Op(em->bm, &op);
 
        }
 
        if (j > 0) BMO_Finish_Op(em->bm, &op);
 
-       BMO_CallOpf(em->bm, "removedoubles verts=%av dist=%f", amd->merge_dist);
+       BMO_Exec_Op(em->bm, &weldop);
+       BMO_Finish_Op(em->bm, &weldop);
+
+       //BMO_CallOpf(em->bm, "removedoubles verts=%av dist=%f", amd->merge_dist);
 
        BMEdit_RecalcTesselation(em);
        cddm = CDDM_from_BMEditMesh(em, NULL);
 
        BMEdit_Free(em);
 
        BMEdit_RecalcTesselation(em);
        cddm = CDDM_from_BMEditMesh(em, NULL);
 
        BMEdit_Free(em);
+       MEM_freeN(indexMap);
 
        return cddm;
 }
 
        return cddm;
 }
@@ -385,4 +497,72 @@ DerivedMesh *arrayModifier_applyModifierEM(ModifierData *md, Object *ob,
                                            DerivedMesh *derivedData)
 {
        return arrayModifier_applyModifier(md, ob, derivedData, 0, 1);
                                            DerivedMesh *derivedData)
 {
        return arrayModifier_applyModifier(md, ob, derivedData, 0, 1);
-}
\ No newline at end of file
+}
+
+/* Mirror */
+
+DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd,
+               Object *ob,
+               DerivedMesh *dm,
+               int initFlags,
+               int axis)
+{
+       int i;
+       float tolerance = mmd->tolerance;
+       DerivedMesh *result, *cddm;
+       BMEditMesh *em;
+       BMesh *bm;
+       int numVerts, numEdges, numFaces;
+       int maxVerts = dm->getNumVerts(dm);
+       int maxEdges = dm->getNumEdges(dm);
+       int maxFaces = dm->getNumTessFaces(dm);
+       int vector_size=0, j, a, b;
+       bDeformGroup *def, *defb;
+       bDeformGroup **vector_def = NULL;
+       int (*indexMap)[2];
+       float mtx[4][4], imtx[4][4];
+
+       cddm = CDDM_copy(dm);
+       em = CDDM_To_BMesh(dm, NULL);
+
+       cddm->needsFree = 1;
+       cddm->release(cddm);
+       
+       /*convienence variable*/
+       bm = em->bm;
+
+       numVerts = numEdges = numFaces = 0;
+       indexMap = MEM_mallocN(sizeof(*indexMap) * maxVerts, "indexmap");
+       result = CDDM_from_template(dm, maxVerts * 2, maxEdges * 2, maxFaces * 2, 0, 0);
+
+       if (mmd->flag & MOD_MIR_VGROUP) {
+               /* calculate the number of deformedGroups */
+               for(vector_size = 0, def = ob->defbase.first; def;
+                   def = def->next, vector_size++);
+
+               /* load the deformedGroups for fast access */
+               vector_def =
+                   (bDeformGroup **)MEM_mallocN(sizeof(bDeformGroup*) * vector_size,
+                                                "group_index");
+               for(a = 0, def = ob->defbase.first; def; def = def->next, a++) {
+                       vector_def[a] = def;
+               }
+       }
+
+       if (mmd->mirror_ob) {
+               float obinv[4][4];
+               
+               Mat4Invert(obinv, mmd->mirror_ob->obmat);
+               Mat4MulMat4(mtx, ob->obmat, obinv);
+               Mat4Invert(imtx, mtx);
+       }
+
+
+
+       BMEdit_RecalcTesselation(em);
+       result = CDDM_from_BMEditMesh(em, NULL);
+
+       BMEdit_Free(em);
+
+       return result;
+}
index a5ac6a7ca6c3dd18b71ba3cbfe80bf4aee27f275..c45a1593b8ab9946d7451309601092609c36ed06 100644 (file)
@@ -864,7 +864,7 @@ void free_lamp(Lamp *la)
        
        BKE_free_animdata((ID *)la);
 
        
        BKE_free_animdata((ID *)la);
 
-       curvemapping_free(la->curfalloff);
+       curvemapping_free(la->curfalloff); 
        
        BKE_previewimg_free(&la->preview);
        BKE_icon_delete(&la->id);
        
        BKE_previewimg_free(&la->preview);
        BKE_icon_delete(&la->id);
index 9779f3f99bbd7d6366905ec4c7c39c868faffd5c..9e4f3ceb335e5d4e54a1c700187576c90ae26864 100644 (file)
@@ -3116,6 +3116,124 @@ static void direct_link_customdata(FileData *fd, CustomData *data, int count)
        }
 }
 
        }
 }
 
+
+void bmesh_corners_to_loops(Mesh *me, int findex, int loopstart, int numTex, int numCol) 
+{
+       MTFace *texface;
+       MTexPoly *texpoly;
+       MCol *mcol;
+       MLoopCol *mloopcol;
+       MLoopUV *mloopuv;
+       MFace *mf;
+       int i;
+
+       for(i=0; i < numTex; i++){
+               texface = CustomData_get_n(&me->fdata, CD_MTFACE, findex, i);
+               texpoly = CustomData_get_n(&me->pdata, CD_MTEXPOLY, findex, i); 
+               mf = me->mface + findex;
+               
+               texpoly->tpage = texface->tpage;
+               texpoly->flag = texface->flag;
+               texpoly->transp = texface->transp;
+               texpoly->mode = texface->mode;
+               texpoly->tile = texface->tile;
+               texpoly->unwrap = texface->unwrap;
+       
+               mloopuv = CustomData_get_n(&me->ldata, CD_MLOOPUV, loopstart, i);
+               mloopuv->uv[0] = texface->uv[0][0]; mloopuv->uv[1] = texface->uv[0][1]; mloopuv++;
+               mloopuv->uv[0] = texface->uv[1][0]; mloopuv->uv[1] = texface->uv[1][1]; mloopuv++;
+               mloopuv->uv[0] = texface->uv[2][0]; mloopuv->uv[1] = texface->uv[2][1]; mloopuv++;
+
+               if (mf->v4) {
+                       mloopuv->uv[0] = texface->uv[3][0]; mloopuv->uv[1] = texface->uv[3][1]; mloopuv++;
+               }
+       }
+
+       for(i=0; i < numCol; i++){
+               mf = me->mface + findex;
+               mloopcol = CustomData_get_n(&me->ldata, CD_MLOOPCOL, loopstart, i);
+               mcol = CustomData_get_n(&me->fdata, CD_MCOL, findex, i);
+
+               mloopcol->r = mcol[0].r; mloopcol->g = mcol[0].g; mloopcol->b = mcol[0].b; mloopcol->a = mcol[0].a; mloopcol++;
+               mloopcol->r = mcol[1].r; mloopcol->g = mcol[1].g; mloopcol->b = mcol[1].b; mloopcol->a = mcol[1].a; mloopcol++;
+               mloopcol->r = mcol[2].r; mloopcol->g = mcol[2].g; mloopcol->b = mcol[2].b; mloopcol->a = mcol[2].a; mloopcol++;
+               if (mf->v4) {
+                       mloopcol->r = mcol[3].r; mloopcol->g = mcol[3].g; mloopcol->b = mcol[3].b; mloopcol->a = mcol[3].a; mloopcol++;
+               }
+       }
+}
+
+static void convert_mfaces_to_mpolys(Mesh *mesh)
+{
+       MFace *mf;
+       MLoop *ml;
+       MPoly *mp;
+       MEdge *me;
+       EdgeHash *eh;
+       int numTex, numCol;
+       int i, j, totloop;
+
+       mesh->totpoly = mesh->totface;
+       mesh->mpoly = MEM_callocN(sizeof(MPoly)*mesh->totpoly, "mpoly converted");
+       CustomData_add_layer(&mesh->pdata, CD_MPOLY, CD_ASSIGN, mesh->mpoly, mesh->totpoly);
+
+       numTex = CustomData_number_of_layers(&mesh->fdata, CD_MTFACE);
+       numCol = CustomData_number_of_layers(&mesh->fdata, CD_MCOL);
+       
+       totloop = 0;
+       mf = mesh->mface;
+       for (i=0; i<mesh->totface; i++, mf++) {
+               totloop += mf->v4 ? 4 : 3;
+       }
+       
+       mesh->totloop = totloop;
+       mesh->mloop = MEM_callocN(sizeof(MLoop)*mesh->totloop, "mloop converted");
+
+       CustomData_add_layer(&mesh->ldata, CD_MLOOP, CD_ASSIGN, mesh->mloop, totloop);
+       CustomData_to_bmeshpoly(&mesh->fdata, &mesh->pdata, &mesh->ldata,
+               mesh->totloop, mesh->totpoly);
+
+       eh = BLI_edgehash_new();
+
+       /*build edge hash*/
+       me = mesh->medge;
+       for (i=0; i<mesh->totedge; i++, me++) {
+               BLI_edgehash_insert(eh, me->v1, me->v2, SET_INT_IN_POINTER(i));
+       }
+
+       j = 0; /*current loop index*/
+       ml = mesh->mloop;
+       mf = mesh->mface;
+       mp = mesh->mpoly;
+       for (i=0; i<mesh->totface; i++, mf++, mp++) {
+               mp->loopstart = j;
+               
+               mp->totloop = mf->v4 ? 4 : 3;
+
+               mp->mat_nr = mf->mat_nr;
+               mp->flag = mf->flag;
+               
+               #define ML(v1, v2) {ml->v = mf->##v1; ml->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(eh, mf->##v1, mf->##v2)); ml++; j++;}
+               
+               ML(v1, v2);
+               ML(v2, v3);
+               if (mf->v4) {
+                       ML(v3, v4);
+                       ML(v4, v1);
+               } else {
+                       ML(v3, v1);
+               }
+               
+               #undef ML
+
+               bmesh_corners_to_loops(mesh, i, mp->loopstart, numTex, numCol);
+       }
+
+       /*BMESH_TODO now to deal with fgons*/
+
+       BLI_edgehash_free(eh, NULL);
+}
+
 static void direct_link_mesh(FileData *fd, Mesh *mesh)
 {
        mesh->mat= newdataadr(fd, mesh->mat);
 static void direct_link_mesh(FileData *fd, Mesh *mesh)
 {
        mesh->mat= newdataadr(fd, mesh->mat);
@@ -3153,7 +3271,7 @@ static void direct_link_mesh(FileData *fd, Mesh *mesh)
        direct_link_customdata(fd, &mesh->fdata, mesh->pv ? mesh->pv->totface : mesh->totface);
        direct_link_customdata(fd, &mesh->ldata, mesh->totloop);
        direct_link_customdata(fd, &mesh->pdata, mesh->totpoly);
        direct_link_customdata(fd, &mesh->fdata, mesh->pv ? mesh->pv->totface : mesh->totface);
        direct_link_customdata(fd, &mesh->ldata, mesh->totloop);
        direct_link_customdata(fd, &mesh->pdata, mesh->totpoly);
-
+       
        mesh->bb= NULL;
        mesh->mselect = NULL;
        mesh->edit_btmesh= NULL;
        mesh->bb= NULL;
        mesh->mselect = NULL;
        mesh->edit_btmesh= NULL;
@@ -3208,6 +3326,11 @@ static void direct_link_mesh(FileData *fd, Mesh *mesh)
                        SWITCH_INT(tf->col[3]);
                }
        }
                        SWITCH_INT(tf->col[3]);
                }
        }
+
+       /*check if we need to convert mfaces to mpolys*/
+       if (mesh->totface && !mesh->totpoly) {
+               convert_mfaces_to_mpolys(mesh);
+       }
 }
 
 /* ************ READ LATTICE ***************** */
 }
 
 /* ************ READ LATTICE ***************** */
index 7d1513e0b80b0767fb31878a1ab7b80f38f745a6..0c0e0db0e6ecf89de0cbf7bc1fce2a2805d9a9c8 100644 (file)
@@ -272,7 +272,6 @@ void BMO_Insert_MapPointer(BMesh *bm, BMOperator *op, char *slotname,
 void *BMO_Get_MapPointer(BMesh *bm, BMOperator *op, char *slotname,
                       void *key);
 
 void *BMO_Get_MapPointer(BMesh *bm, BMOperator *op, char *slotname,
                       void *key);
 
-
 /*this part of the API is used to iterate over element buffer or
   mapping slots.
   
 /*this part of the API is used to iterate over element buffer or
   mapping slots.
   
@@ -326,6 +325,12 @@ void *BMO_IterStep(BMOIter *iter);
   remember for pointer maps this will be a pointer to a pointer.*/
 void *BMO_IterMapVal(BMOIter *iter);
 
   remember for pointer maps this will be a pointer to a pointer.*/
 void *BMO_IterMapVal(BMOIter *iter);
 
+/*use this for pointer mappings*/
+void *BMO_IterMapValp(BMOIter *iter);
+
+/*use this for float mappings*/
+float BMO_IterMapValf(BMOIter *iter);
+
 #define BMO_ITER(ele, iter, bm, op, slotname, restrict) \
        ele = BMO_IterNew(iter, bm, op, slotname, restrict); \
        for ( ; ele; ele=BMO_IterStep(iter))
 #define BMO_ITER(ele, iter, bm, op, slotname, restrict) \
        ele = BMO_IterNew(iter, bm, op, slotname, restrict); \
        for ( ; ele; ele=BMO_IterStep(iter))
index 4173f368557c01f63174323260797963ee6db3a0..6a68989a42ac7dd8354ac9d5f6e17b03f3336b37 100644 (file)
@@ -200,11 +200,11 @@ BMFace *bmesh_mf(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **elist, int len)
        BMVert *curvert, *tv, **vlist;
        int i, j, done, cont, edok;
        
        BMVert *curvert, *tv, **vlist;
        int i, j, done, cont, edok;
        
-       if(len < 2) goto error;
+       if(len < 2) return NULL;
        
        /*make sure that v1 and v2 are in elist[0]*/
        if(bmesh_verts_in_edge(v1,v2,elist[0]) == 0) 
        
        /*make sure that v1 and v2 are in elist[0]*/
        if(bmesh_verts_in_edge(v1,v2,elist[0]) == 0) 
-               goto error;
+               return NULL;
        
        /*clear euler flags*/
        for(i=0;i<len;i++) elist[i]->head.eflag1=elist[i]->head.eflag2 = 0;
        
        /*clear euler flags*/
        for(i=0;i<len;i++) elist[i]->head.eflag1=elist[i]->head.eflag2 = 0;
@@ -222,9 +222,9 @@ BMFace *bmesh_mf(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **elist, int len)
        */
        for(i=0; i<len; i++){
                edok = bmesh_disk_count_edgeflag(elist[i]->v1, MF_CANDIDATE, 0);
        */
        for(i=0; i<len; i++){
                edok = bmesh_disk_count_edgeflag(elist[i]->v1, MF_CANDIDATE, 0);
-               if(edok != 2) goto error;
+               if(edok != 2) return NULL;
                edok = bmesh_disk_count_edgeflag(elist[i]->v2, MF_CANDIDATE, 0);
                edok = bmesh_disk_count_edgeflag(elist[i]->v2, MF_CANDIDATE, 0);
-               if(edok != 2) goto error;
+               if(edok != 2) return NULL;
        }
        
        /*set start edge, start vert and target vert for our loop traversal*/
        }
        
        /*set start edge, start vert and target vert for our loop traversal*/
@@ -238,6 +238,7 @@ BMFace *bmesh_mf(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **elist, int len)
                bm->vtarlen = len;
        }
        /*insert tv into vlist since its the first vertex in face*/
                bm->vtarlen = len;
        }
        /*insert tv into vlist since its the first vertex in face*/
+       
        i=0;
        vlist=bm->vtar;
        vlist[i] = tv;
        i=0;
        vlist=bm->vtar;
        vlist[i] = tv;
@@ -321,10 +322,6 @@ BMFace *bmesh_mf(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **elist, int len)
 
        for(i=0;i<len;i++) elist[i]->head.eflag1=elist[i]->head.eflag2 = 0;
        return f;
 
        for(i=0;i<len;i++) elist[i]->head.eflag1=elist[i]->head.eflag2 = 0;
        return f;
-error:
-       for(i=0;i<len;i++) elist[i]->head.eflag1=elist[i]->head.eflag2 = 0;
-       return NULL;
-
 }
 
 /* KILL Eulers */
 }
 
 /* KILL Eulers */
index bbe6ae748ee98b9dc4d1ba8c669eb9113fbeccdd..6dc116dc7cdc0bc9869abc5352123e1ce796c85d 100644 (file)
@@ -112,7 +112,6 @@ void BM_Data_Facevert_Edgeinterp(BMesh *bm, BMVert *v1, BMVert *v2, BMVert *v, B
 void BM_loops_to_corners(BMesh *bm, Mesh *me, int findex,
                          BMFace *f, int numTex, int numCol) 
 {
 void BM_loops_to_corners(BMesh *bm, Mesh *me, int findex,
                          BMFace *f, int numTex, int numCol) 
 {
-       int i, j;
        BMLoop *l;
        BMIter iter;
        MTFace *texface;
        BMLoop *l;
        BMIter iter;
        MTFace *texface;
@@ -120,6 +119,7 @@ void BM_loops_to_corners(BMesh *bm, Mesh *me, int findex,
        MCol *mcol;
        MLoopCol *mloopcol;
        MLoopUV *mloopuv;
        MCol *mcol;
        MLoopCol *mloopcol;
        MLoopUV *mloopuv;
+       int i, j;
 
        for(i=0; i < numTex; i++){
                texface = CustomData_get_n(&me->fdata, CD_MTFACE, findex, i);
 
        for(i=0; i < numTex; i++){
                texface = CustomData_get_n(&me->fdata, CD_MTFACE, findex, i);
index 97e99f35a49821f84185b24bef60e2fa1b222831..8c89697f5f2d9fdabad94bc0017289b2afc16a1d 100644 (file)
@@ -6,6 +6,19 @@
 /*do not rename any operator or slot names! otherwise you must go 
   through the code and find all references to them!*/
 
 /*do not rename any operator or slot names! otherwise you must go 
   through the code and find all references to them!*/
 
+BMOpDefine def_finddoubles = {
+       "finddoubles",
+       /*maps welded vertices to verts they should weld to.*/
+       {{BMOP_OPSLOT_ELEMENT_BUF, "verts"},
+        //list of verts to keep
+        {BMOP_OPSLOT_ELEMENT_BUF, "keepverts"},
+        {BMOP_OPSLOT_FLT,         "dist"},
+        {BMOP_OPSLOT_MAPPING, "targetmapout"},
+        {0, /*null-terminating sentinel*/}},
+       bmesh_finddoubles_exec,
+       0,
+};
+
 BMOpDefine def_removedoubles = {
        "removedoubles",
        /*maps welded vertices to verts they should weld to.*/
 BMOpDefine def_removedoubles = {
        "removedoubles",
        /*maps welded vertices to verts they should weld to.*/
@@ -304,6 +317,7 @@ BMOpDefine *opdefines[] = {
        &def_makevert,
        &def_weldverts,
        &def_removedoubles,
        &def_makevert,
        &def_weldverts,
        &def_removedoubles,
+       &def_finddoubles,
 };
 
 int bmesh_total_ops = (sizeof(opdefines) / sizeof(void*));
 };
 
 int bmesh_total_ops = (sizeof(opdefines) / sizeof(void*));
index 6f25c81bfe7ff56770f67377d3cef7a6ce81dc3d..d168d85b02511af9a3a2f9333ab449a88ba02de4 100644 (file)
@@ -927,13 +927,17 @@ void *BMO_IterNew(BMOIter *iter, BMesh *bm, BMOperator *op,
 {
        BMOpSlot *slot = BMO_GetSlot(op, slotname);
 
 {
        BMOpSlot *slot = BMO_GetSlot(op, slotname);
 
+       memset(iter, 0, sizeof(BMOIter));
+
        iter->slot = slot;
        iter->cur = 0;
        iter->restrict = restrict;
 
        iter->slot = slot;
        iter->cur = 0;
        iter->restrict = restrict;
 
-       if (iter->slot->slottype == BMOP_OPSLOT_MAPPING)
+       if (iter->slot->slottype == BMOP_OPSLOT_MAPPING) {
                if (iter->slot->data.ghash)
                        BLI_ghashIterator_init(&iter->giter, slot->data.ghash);
                if (iter->slot->data.ghash)
                        BLI_ghashIterator_init(&iter->giter, slot->data.ghash);
+               else return NULL;
+       }
 
        return BMO_IterStep(iter);
 }
 
        return BMO_IterStep(iter);
 }
@@ -973,6 +977,15 @@ void *BMO_IterMapVal(BMOIter *iter)
        return iter->val;
 }
 
        return iter->val;
 }
 
+void *BMO_IterMapValp(BMOIter *iter)
+{
+       return *((void**)iter->val);
+}
+
+float BMO_IterMapValf(BMOIter *iter)
+{
+       return *((float*)iter->val);
+}
 
 /*error system*/
 typedef struct bmop_error {
 
 /*error system*/
 typedef struct bmop_error {
index 04c4fe15e10b65cf7bb372bb9296b6866b0677bb..3eaaf4e8913a230a2bffb51d3928158a9d49353d 100644 (file)
@@ -4,12 +4,12 @@
 struct BMesh;
 struct BMOperator;
 
 struct BMesh;
 struct BMOperator;
 
-void BMO_push(struct BMesh *bm, struct BMOperator *op);
-void BMO_pop(struct BMesh *bm);
+void BMO_push(BMesh *bm, BMOperator *op);
+void BMO_pop(BMesh *bm);
 
 
-void splitop_exec(struct BMesh *bm, struct BMOperator *op);
-void dupeop_exec(struct BMesh *bm, struct BMOperator *op);
-void delop_exec(struct BMesh *bm, struct BMOperator *op);
+void splitop_exec(BMesh *bm, BMOperator *op);
+void dupeop_exec(BMesh *bm, BMOperator *op);
+void delop_exec(BMesh *bm, BMOperator *op);
 void esubdivide_exec(BMesh *bmesh, BMOperator *op);
 void edit2bmesh_exec(BMesh *bmesh, BMOperator *op);
 void bmesh2edit_exec(BMesh *bmesh, BMOperator *op);
 void esubdivide_exec(BMesh *bmesh, BMOperator *op);
 void edit2bmesh_exec(BMesh *bmesh, BMOperator *op);
 void bmesh2edit_exec(BMesh *bmesh, BMOperator *op);
@@ -33,5 +33,6 @@ 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);
 void dissolve_edgeloop_exec(BMesh *bm, BMOperator *op);
 void bmesh_weldverts_exec(BMesh *bm, BMOperator *op);
 void bmesh_removedoubles_exec(BMesh *bm, BMOperator *op);
+void bmesh_finddoubles_exec(BMesh *bm, BMOperator *op);
 
 #endif
 
 #endif
index 6f7fac9fa45337e3283d02c2ca7c53589fb607cc..81e3572dec6e3ecb9be763d0e86e253b611840d2 100644 (file)
@@ -386,7 +386,7 @@ BMesh *editmesh_to_bmesh_intern(EditMesh *em, BMesh *bm, BMOperator *op) {
        CustomData_copy(&em->fdata, &bm->pdata, CD_MASK_BMESH, CD_CALLOC, 0);
 
        /*copy face corner data*/
        CustomData_copy(&em->fdata, &bm->pdata, CD_MASK_BMESH, CD_CALLOC, 0);
 
        /*copy face corner data*/
-       CustomData_to_bmeshpoly(&em->fdata, &bm->pdata, &bm->ldata);
+       CustomData_to_bmeshpoly(&em->fdata, &bm->pdata, &bm->ldata, 0, 0);
        
        CustomData_bmesh_init_pool(&bm->vdata, allocsize[0]);
        CustomData_bmesh_init_pool(&bm->edata, allocsize[1]);
        
        CustomData_bmesh_init_pool(&bm->vdata, allocsize[0]);
        CustomData_bmesh_init_pool(&bm->edata, allocsize[1]);
index 1a1089c427b17a954a37ce32578aee1389f498d8..b5c327bc24cbef288109abfd290210cdee34ab49 100644 (file)
@@ -177,29 +177,36 @@ static void copy_mesh(BMOperator *op, BMesh *source, BMesh *target)
        }
        edar = MEM_callocN(sizeof(BMEdge*) * maxlength, "BM copy mesh edge pointer array");
        
        }
        edar = MEM_callocN(sizeof(BMEdge*) * maxlength, "BM copy mesh edge pointer array");
        
-       /*first we dupe all flagged faces and their elements from source*/
-       for(f = BMIter_New(&faces, source, BM_FACES_OF_MESH, source); f; f= BMIter_Step(&faces)){
-               if(BMO_TestFlag(source, (BMHeader*)f, DUPE_INPUT)){
-                       /*vertex pass*/
-                       for(v = BMIter_New(&verts, source, BM_VERTS_OF_FACE, f); v; v = BMIter_Step(&verts)){
-                               if(!BMO_TestFlag(source, (BMHeader*)v, DUPE_DONE)){ 
-                                       copy_vertex(source,v, target, vhash);
-                                       BMO_SetFlag(source, (BMHeader*)v, DUPE_DONE);
+       for(v = BMIter_New(&verts, source, BM_VERTS_OF_MESH, source); v; v = BMIter_Step(&verts)){
+               if(BMO_TestFlag(source, (BMHeader*)v, DUPE_INPUT) && (!BMO_TestFlag(source, (BMHeader*)v, DUPE_DONE))){
+                       BMIter iter;
+                       int iso = 1;
+
+                       v2 = copy_vertex(source, v, target, vhash);
+
+                       BM_ITER(f, &iter, source, BM_FACES_OF_VERT, v) {
+                               if (BMO_TestFlag(source, f, DUPE_INPUT)) {
+                                       iso = 0;
+                                       break;
                                }
                        }
 
                                }
                        }
 
-                       /*edge pass*/
-                       for(e = BMIter_New(&edges, source, BM_EDGES_OF_FACE, f); e; e = BMIter_Step(&edges)){
-                               if(!BMO_TestFlag(source, (BMHeader*)e, DUPE_DONE)){
-                                       copy_edge(op, source, e, target,  vhash,  ehash);
-                                       BMO_SetFlag(source, (BMHeader*)e, DUPE_DONE);
+                       if (iso) {
+                               BM_ITER(e, &iter, source, BM_EDGES_OF_VERT, v) {
+                                       if (BMO_TestFlag(source, e, DUPE_INPUT)) {
+                                               iso = 0;
+                                               break;
+                                       }
                                }
                        }
                                }
                        }
-                       copy_face(op, source, f, target, edar, vhash, ehash);
-                       BMO_SetFlag(source, (BMHeader*)f, DUPE_DONE);
+                       
+                       if (iso) 
+                               BMO_Insert_MapPointer(source, op, "isovertmap", v, v2);
+
+                       BMO_SetFlag(source, (BMHeader*)v, DUPE_DONE);
                }
        }
                }
        }
-       
+
        /*now we dupe all the edges*/
        for(e = BMIter_New(&edges, source, BM_EDGES_OF_MESH, source); e; e = BMIter_Step(&edges)){
                if(BMO_TestFlag(source, (BMHeader*)e, DUPE_INPUT) && (!BMO_TestFlag(source, (BMHeader*)e, DUPE_DONE))){
        /*now we dupe all the edges*/
        for(e = BMIter_New(&edges, source, BM_EDGES_OF_MESH, source); e; e = BMIter_Step(&edges)){
                if(BMO_TestFlag(source, (BMHeader*)e, DUPE_INPUT) && (!BMO_TestFlag(source, (BMHeader*)e, DUPE_DONE))){
@@ -217,17 +224,30 @@ static void copy_mesh(BMOperator *op, BMesh *source, BMesh *target)
                        BMO_SetFlag(source, (BMHeader*)e, DUPE_DONE); 
                }
        }
                        BMO_SetFlag(source, (BMHeader*)e, DUPE_DONE); 
                }
        }
-       
-       /*finally dupe all loose vertices*/
-       for(v = BMIter_New(&verts, source, BM_VERTS_OF_MESH, source); v; v = BMIter_Step(&verts)){
-               if(BMO_TestFlag(source, (BMHeader*)v, DUPE_INPUT) && (!BMO_TestFlag(source, (BMHeader*)v, DUPE_DONE))){
-                       v2 = copy_vertex(source, v, target, vhash);
-                       BMO_Insert_MapPointer(source, op, 
-                                        "isovertmap", v, v2);
-                       BMO_SetFlag(source, (BMHeader*)v, DUPE_DONE);
+
+       /*first we dupe all flagged faces and their elements from source*/
+       for(f = BMIter_New(&faces, source, BM_FACES_OF_MESH, source); f; f= BMIter_Step(&faces)){
+               if(BMO_TestFlag(source, (BMHeader*)f, DUPE_INPUT)){
+                       /*vertex pass*/
+                       for(v = BMIter_New(&verts, source, BM_VERTS_OF_FACE, f); v; v = BMIter_Step(&verts)){
+                               if(!BMO_TestFlag(source, (BMHeader*)v, DUPE_DONE)){ 
+                                       copy_vertex(source,v, target, vhash);
+                                       BMO_SetFlag(source, (BMHeader*)v, DUPE_DONE);
+                               }
+                       }
+
+                       /*edge pass*/
+                       for(e = BMIter_New(&edges, source, BM_EDGES_OF_FACE, f); e; e = BMIter_Step(&edges)){
+                               if(!BMO_TestFlag(source, (BMHeader*)e, DUPE_DONE)){
+                                       copy_edge(op, source, e, target,  vhash,  ehash);
+                                       BMO_SetFlag(source, (BMHeader*)e, DUPE_DONE);
+                               }
+                       }
+                       copy_face(op, source, f, target, edar, vhash, ehash);
+                       BMO_SetFlag(source, (BMHeader*)f, DUPE_DONE);
                }
        }
                }
        }
-
+       
        /*free pointer hashes*/
        BLI_ghash_free(vhash, NULL, NULL);
        BLI_ghash_free(ehash, NULL, NULL);      
        /*free pointer hashes*/
        BLI_ghash_free(vhash, NULL, NULL);
        BLI_ghash_free(ehash, NULL, NULL);      
index 28991f2cae7f4235c17ee6b932df65616fcb305a..3ca95ea1e32bbaf47e9accc2f485d62489e157c1 100644 (file)
@@ -45,7 +45,7 @@ void mesh_to_bmesh_exec(BMesh *bm, BMOperator *op) {
        BMEdge *e, **fedges=NULL, **et;
        V_DECLARE(fedges);
        BMFace *f;
        BMEdge *e, **fedges=NULL, **et;
        V_DECLARE(fedges);
        BMFace *f;
-       int i, j;
+       int i, j, allocsize[4] = {512, 512, 2048, 512};
 
        if (!me || !me->totvert) return; /*sanity check*/
        
 
        if (!me || !me->totvert) return; /*sanity check*/
        
@@ -53,6 +53,16 @@ void mesh_to_bmesh_exec(BMesh *bm, BMOperator *op) {
 
        vt = MEM_mallocN(sizeof(void**)*me->totvert, "mesh to bmesh vtable");
 
 
        vt = MEM_mallocN(sizeof(void**)*me->totvert, "mesh to bmesh vtable");
 
+       CustomData_copy(&bm->vdata, &me->vdata, CD_MASK_BMESH, CD_CALLOC, 0);
+       CustomData_copy(&bm->edata, &me->edata, CD_MASK_BMESH, CD_CALLOC, 0);
+       CustomData_copy(&bm->ldata, &me->ldata, CD_MASK_BMESH, CD_CALLOC, 0);
+       CustomData_copy(&bm->pdata, &me->pdata, CD_MASK_BMESH, CD_CALLOC, 0);
+
+       CustomData_bmesh_init_pool(&bm->vdata, allocsize[0]);
+       CustomData_bmesh_init_pool(&bm->edata, allocsize[1]);
+       CustomData_bmesh_init_pool(&bm->ldata, allocsize[2]);
+       CustomData_bmesh_init_pool(&bm->pdata, allocsize[3]);
+
        for (i=0; i<me->totvert; i++, mvert++) {
                v = BM_Make_Vert(bm, mvert->co, NULL);
                VECCOPY(v->no, mvert->no);
        for (i=0; i<me->totvert; i++, mvert++) {
                v = BM_Make_Vert(bm, mvert->co, NULL);
                VECCOPY(v->no, mvert->no);
index 1bbb222d67e41224c6a2e4414c198f5841a357ec..605626d15e0da88fcf1e48c0504c1fc8d51f1171 100644 (file)
@@ -34,7 +34,7 @@ void remdoubles_splitface(BMFace *f, BMesh *bm, BMOperator *op)
                }
        }
 
                }
        }
 
-       if (split) {
+       if (split && doub != v2) {
                BMLoop *nl;
                BMFace *f2 = BM_Split_Face(bm, f, doub, v2, &nl, NULL);
 
                BMLoop *nl;
                BMFace *f2 = BM_Split_Face(bm, f, doub, v2, &nl, NULL);
 
@@ -79,7 +79,8 @@ void bmesh_weldverts_exec(BMesh *bm, BMOperator *op)
        BMVert *v, *v2;
        BMEdge *e, *e2, **edges = NULL;
        V_DECLARE(edges);
        BMVert *v, *v2;
        BMEdge *e, *e2, **edges = NULL;
        V_DECLARE(edges);
-       BMLoop *l;
+       BMLoop *l, *l2, **loops = NULL;
+       V_DECLARE(loops);
        BMFace *f, *f2;
        int a;
 
        BMFace *f, *f2;
        int a;
 
@@ -119,12 +120,13 @@ void bmesh_weldverts_exec(BMesh *bm, BMOperator *op)
 
        BM_ITER(f, &iter, bm, BM_FACES_OF_MESH, NULL) {
                if (!BMO_TestFlag(bm, f, FACE_MARK)) continue;
 
        BM_ITER(f, &iter, bm, BM_FACES_OF_MESH, NULL) {
                if (!BMO_TestFlag(bm, f, FACE_MARK)) continue;
-               if (f->len - BMINDEX_GET(f) + 1 < 3) {
+               if (f->len - BMINDEX_GET(f) < 3) {
                        BMO_SetFlag(bm, f, ELE_DEL);
                        continue;
                }
 
                V_RESET(edges);
                        BMO_SetFlag(bm, f, ELE_DEL);
                        continue;
                }
 
                V_RESET(edges);
+               V_RESET(loops);
                a = 0;
                BM_ITER(l, &liter, bm, BM_LOOPS_OF_FACE, f) {
                        v = l->v;
                a = 0;
                BM_ITER(l, &liter, bm, BM_LOOPS_OF_FACE, f) {
                        v = l->v;
@@ -134,17 +136,39 @@ void bmesh_weldverts_exec(BMesh *bm, BMOperator *op)
                        if (BMO_TestFlag(bm, v2, ELE_DEL)) 
                                        v2 = BMO_Get_MapPointer(bm, op, "targetmap", v2);
                        
                        if (BMO_TestFlag(bm, v2, ELE_DEL)) 
                                        v2 = BMO_Get_MapPointer(bm, op, "targetmap", v2);
                        
-                       e2 = BM_Edge_Exist(v, v2);
+                       e2 = v != v2 ? BM_Edge_Exist(v, v2) : NULL;
                        if (e2) {
                                V_GROW(edges);
                        if (e2) {
                                V_GROW(edges);
-                               edges[a++] = e2;
+                               V_GROW(loops);
+
+                               edges[a] = e2;
+                               loops[a] = l;
+
+                               a++;
                        }
                }
                
                        }
                }
                
+               v = loops[0]->v;
+               v2 = loops[1]->v;
+
+               if (BMO_TestFlag(bm, v, ELE_DEL)) 
+                       v = BMO_Get_MapPointer(bm, op, "targetmap", v);
+               if (BMO_TestFlag(bm, v2, ELE_DEL)) 
+                       v2 = BMO_Get_MapPointer(bm, op, "targetmap", v2);
+               
+
                f2 = BM_Make_Ngon(bm, v, v2, edges, a, 0);
                if (f2) {
                        BM_Copy_Attributes(bm, bm, f, f2);
                        BMO_SetFlag(bm, f, ELE_DEL);
                f2 = BM_Make_Ngon(bm, v, v2, edges, a, 0);
                if (f2) {
                        BM_Copy_Attributes(bm, bm, f, f2);
                        BMO_SetFlag(bm, f, ELE_DEL);
+
+                       a = 0;
+                       BM_ITER(l, &liter, bm, BM_LOOPS_OF_FACE, f2) {
+                               l2 = loops[a];
+                               BM_Copy_Attributes(bm, bm, l2, l);
+
+                               a++;
+                       }
                }
 
                /*need to still copy customdata stuff here, will do later*/
                }
 
                /*need to still copy customdata stuff here, will do later*/
@@ -169,6 +193,7 @@ static int vergaverco(const void *e1, const void *e2)
 #define VERT_TESTED    1
 #define VERT_DOUBLE    2
 #define VERT_TARGET    4
 #define VERT_TESTED    1
 #define VERT_DOUBLE    2
 #define VERT_TARGET    4
+#define VERT_KEEP      8
 
 void bmesh_removedoubles_exec(BMesh *bm, BMOperator *op)
 {
 
 void bmesh_removedoubles_exec(BMesh *bm, BMOperator *op)
 {
@@ -226,3 +251,59 @@ void bmesh_removedoubles_exec(BMesh *bm, BMOperator *op)
        BMO_Exec_Op(bm, &weldop);
        BMO_Finish_Op(bm, &weldop);
 }
        BMO_Exec_Op(bm, &weldop);
        BMO_Finish_Op(bm, &weldop);
 }
+
+
+void bmesh_finddoubles_exec(BMesh *bm, BMOperator *op)
+{
+       BMOIter oiter;
+       BMVert *v, *v2;
+       BMVert **verts=NULL;
+       V_DECLARE(verts);
+       float dist, distsqr;
+       int i, j, len;
+
+       dist = BMO_Get_Float(op, "dist");
+       distsqr = dist*dist;
+
+       i = 0;
+       BMO_ITER(v, &oiter, bm, op, "verts", BM_VERT) {
+               V_GROW(verts);
+               verts[i++] = v;
+       }
+
+       /*sort by vertex coordinates added together*/
+       //qsort(verts, V_COUNT(verts), sizeof(void*), vergaverco);
+       
+       BMO_Flag_Buffer(bm, op, "keepverts", VERT_KEEP);
+
+       len = V_COUNT(verts);
+       for (i=0; i<len; i++) {
+               v = verts[i];
+               if (BMO_TestFlag(bm, v, VERT_DOUBLE)) continue;
+               
+               //BMO_SetFlag(bm, v, VERT_TESTED);
+               for (j=0; j<len; j++) {
+                       if (j == i) continue;
+
+                       //float vec[3];
+                       if (BMO_TestFlag(bm, v, VERT_KEEP)) continue;
+
+                       v2 = verts[j];
+                       //if ((v2->co[0]+v2->co[1]+v2->co[2]) - (v->co[0]+v->co[1]+v->co[2])
+                       //     > distsqr) break;
+
+                       //vec[0] = v->co[0] - v2->co[0];
+                       //vec[1] = v->co[1] - v2->co[1];
+                       //vec[2] = v->co[2] - v2->co[2];
+                       
+                       if (VecLenCompare(v->co, v2->co, dist)) {
+                               BMO_SetFlag(bm, v2, VERT_DOUBLE);
+                               BMO_SetFlag(bm, v, VERT_TARGET);
+                       
+                               BMO_Insert_MapPointer(bm, op, "targetmapout", v2, v);
+                       }
+               }
+       }
+
+       V_FREE(verts);
+}