Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoseph Eagar <joeedh@gmail.com>2009-07-14 10:13:43 +0400
committerJoseph Eagar <joeedh@gmail.com>2009-07-14 10:13:43 +0400
commit3bade135035dacfdb4a3833f3fac3bf5811ce7de (patch)
tree9e27978f6c2b27670ed03bcc9d8909b8407864e7
parent020de22d85ae0dbe6dedf507b00153959ad88b70 (diff)
pre-merge commit. the mirror modifier is currently in pieces, to be picked back up after the merge. there should be some removedoubles fixes, along with some other assorted fixes.
-rw-r--r--projectfiles_vc9/blender/blenkernel/BKE_blenkernel.vcproj4
-rw-r--r--source/blender/blenkernel/BKE_customdata.h3
-rw-r--r--source/blender/blenkernel/intern/BME_conversions.c4
-rw-r--r--source/blender/blenkernel/intern/customdata.c9
-rw-r--r--source/blender/blenkernel/intern/editderivedbmesh.c23
-rw-r--r--source/blender/blenkernel/intern/modifier.c2
-rw-r--r--source/blender/blenkernel/intern/modifiers_bmesh.c200
-rw-r--r--source/blender/blenkernel/intern/object.c2
-rw-r--r--source/blender/blenloader/intern/readfile.c125
-rw-r--r--source/blender/bmesh/bmesh_operator_api.h7
-rw-r--r--source/blender/bmesh/intern/bmesh_eulers.c13
-rw-r--r--source/blender/bmesh/intern/bmesh_interp.c2
-rw-r--r--source/blender/bmesh/intern/bmesh_opdefines.c14
-rw-r--r--source/blender/bmesh/intern/bmesh_operators.c15
-rw-r--r--source/blender/bmesh/intern/bmesh_operators_private.h11
-rw-r--r--source/blender/bmesh/intern/editmesh_to_bmesh.c2
-rw-r--r--source/blender/bmesh/operators/bmesh_dupeops.c70
-rw-r--r--source/blender/bmesh/operators/mesh_conv.c12
-rw-r--r--source/blender/bmesh/operators/removedoubles.c91
19 files changed, 538 insertions, 71 deletions
diff --git a/projectfiles_vc9/blender/blenkernel/BKE_blenkernel.vcproj b/projectfiles_vc9/blender/blenkernel/BKE_blenkernel.vcproj
index 8a53eed0c63..4474eb8da1f 100644
--- a/projectfiles_vc9/blender/blenkernel/BKE_blenkernel.vcproj
+++ b/projectfiles_vc9/blender/blenkernel/BKE_blenkernel.vcproj
@@ -674,6 +674,10 @@
>
</File>
<File
+ RelativePath="..\..\..\source\blender\blenkernel\intern\modifiers_bmesh.c"
+ >
+ </File>
+ <File
RelativePath="..\..\..\source\blender\blenkernel\intern\multires.c"
>
</File>
diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h
index b9e27a1abd4..d442a57b525 100644
--- a/source/blender/blenkernel/BKE_customdata.h
+++ b/source/blender/blenkernel/BKE_customdata.h
@@ -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*/
-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
diff --git a/source/blender/blenkernel/intern/BME_conversions.c b/source/blender/blenkernel/intern/BME_conversions.c
index dcfe4e6fa36..0f372790a9d 100644
--- a/source/blender/blenkernel/intern/BME_conversions.c
+++ b/source/blender/blenkernel/intern/BME_conversions.c
@@ -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_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]);
@@ -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_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]);
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index 5c29ca02e7e..0173e660e18 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -1835,16 +1835,17 @@ void CustomData_from_em_block(const CustomData *source, CustomData *dest,
/*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){
- 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)
- 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){
diff --git a/source/blender/blenkernel/intern/editderivedbmesh.c b/source/blender/blenkernel/intern/editderivedbmesh.c
index 2964914de4b..fa9747ec54f 100644
--- a/source/blender/blenkernel/intern/editderivedbmesh.c
+++ b/source/blender/blenkernel/intern/editderivedbmesh.c
@@ -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);
- 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);
@@ -340,7 +348,6 @@ static void bmDM_recalcTesselation(DerivedMesh *dm)
{
EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
- BMEdit_RecalcTesselation_intern(bmdm->tc);
bmdm_recalc_lookups(bmdm);
}
@@ -1403,6 +1410,14 @@ static void bmDM_release(void *dm)
MEM_freeN(bmdm->faceNos);
}
+ BLI_ghash_free(bmdm->fhash, NULL, NULL);
+ BLI_ghash_free(bmdm->ehash, NULL, NULL);
+ BLI_ghash_free(bmdm->vhash, NULL, NULL);
+
+ if (bmdm->vtable) MEM_freeN(bmdm->vtable);
+ if (bmdm->etable) MEM_freeN(bmdm->etable);
+ if (bmdm->ftable) MEM_freeN(bmdm->ftable);
+
MEM_freeN(bmdm);
}
}
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index 879699e755a..4e1f6d8265a 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -1826,6 +1826,7 @@ void vertgroup_flip_name (char *name, int strip_number)
sprintf (name, "%s%s%s%s", prefix, replace, suffix, number);
}
+#if 0
static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd,
Object *ob,
DerivedMesh *dm,
@@ -2047,6 +2048,7 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd,
return result;
}
+#endif
static DerivedMesh *mirrorModifier__doMirror(MirrorModifierData *mmd,
Object *ob, DerivedMesh *dm,
diff --git a/source/blender/blenkernel/intern/modifiers_bmesh.c b/source/blender/blenkernel/intern/modifiers_bmesh.c
index d52f624a91b..b3ce91855b2 100644
--- a/source/blender/blenkernel/intern/modifiers_bmesh.c
+++ b/source/blender/blenkernel/intern/modifiers_bmesh.c
@@ -220,14 +220,53 @@ BMEditMesh *CDDM_To_BMesh(DerivedMesh *dm, BMEditMesh *existing)
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);
- 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];
@@ -237,6 +276,7 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
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;
@@ -316,16 +356,16 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
*/
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);
- 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);
- finalFaces += end_cap->getNumTessFaces(end_cap);
+ finalFaces += end_cap->getNumFaces(end_cap);
}
/* 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);
}
-
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++) {
+ 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_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");
+ #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);
- 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);
+ MEM_freeN(indexMap);
return cddm;
}
@@ -385,4 +497,72 @@ DerivedMesh *arrayModifier_applyModifierEM(ModifierData *md, Object *ob,
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;
+}
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index a5ac6a7ca6c..c45a1593b8a 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -864,7 +864,7 @@ void free_lamp(Lamp *la)
BKE_free_animdata((ID *)la);
- curvemapping_free(la->curfalloff);
+ curvemapping_free(la->curfalloff);
BKE_previewimg_free(&la->preview);
BKE_icon_delete(&la->id);
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 9779f3f99bb..9e4f3ceb335 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -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);
@@ -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);
-
+
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]);
}
}
+
+ /*check if we need to convert mfaces to mpolys*/
+ if (mesh->totface && !mesh->totpoly) {
+ convert_mfaces_to_mpolys(mesh);
+ }
}
/* ************ READ LATTICE ***************** */
diff --git a/source/blender/bmesh/bmesh_operator_api.h b/source/blender/bmesh/bmesh_operator_api.h
index 7d1513e0b80..0c0e0db0e6e 100644
--- a/source/blender/bmesh/bmesh_operator_api.h
+++ b/source/blender/bmesh/bmesh_operator_api.h
@@ -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);
-
/*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);
+/*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))
diff --git a/source/blender/bmesh/intern/bmesh_eulers.c b/source/blender/bmesh/intern/bmesh_eulers.c
index 4173f368557..6a68989a42a 100644
--- a/source/blender/bmesh/intern/bmesh_eulers.c
+++ b/source/blender/bmesh/intern/bmesh_eulers.c
@@ -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;
- 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)
- goto error;
+ return NULL;
/*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);
- if(edok != 2) goto error;
+ if(edok != 2) return NULL;
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*/
@@ -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*/
+
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;
-error:
- for(i=0;i<len;i++) elist[i]->head.eflag1=elist[i]->head.eflag2 = 0;
- return NULL;
-
}
/* KILL Eulers */
diff --git a/source/blender/bmesh/intern/bmesh_interp.c b/source/blender/bmesh/intern/bmesh_interp.c
index bbe6ae748ee..6dc116dc7cd 100644
--- a/source/blender/bmesh/intern/bmesh_interp.c
+++ b/source/blender/bmesh/intern/bmesh_interp.c
@@ -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)
{
- int i, j;
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;
+ int i, j;
for(i=0; i < numTex; i++){
texface = CustomData_get_n(&me->fdata, CD_MTFACE, findex, i);
diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c
index 97e99f35a49..8c89697f5f2 100644
--- a/source/blender/bmesh/intern/bmesh_opdefines.c
+++ b/source/blender/bmesh/intern/bmesh_opdefines.c
@@ -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!*/
+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.*/
@@ -304,6 +317,7 @@ BMOpDefine *opdefines[] = {
&def_makevert,
&def_weldverts,
&def_removedoubles,
+ &def_finddoubles,
};
int bmesh_total_ops = (sizeof(opdefines) / sizeof(void*));
diff --git a/source/blender/bmesh/intern/bmesh_operators.c b/source/blender/bmesh/intern/bmesh_operators.c
index 6f25c81bfe7..d168d85b025 100644
--- a/source/blender/bmesh/intern/bmesh_operators.c
+++ b/source/blender/bmesh/intern/bmesh_operators.c
@@ -927,13 +927,17 @@ void *BMO_IterNew(BMOIter *iter, BMesh *bm, BMOperator *op,
{
BMOpSlot *slot = BMO_GetSlot(op, slotname);
+ memset(iter, 0, sizeof(BMOIter));
+
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);
+ else return NULL;
+ }
return BMO_IterStep(iter);
}
@@ -973,6 +977,15 @@ void *BMO_IterMapVal(BMOIter *iter)
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 {
diff --git a/source/blender/bmesh/intern/bmesh_operators_private.h b/source/blender/bmesh/intern/bmesh_operators_private.h
index 04c4fe15e10..3eaaf4e8913 100644
--- a/source/blender/bmesh/intern/bmesh_operators_private.h
+++ b/source/blender/bmesh/intern/bmesh_operators_private.h
@@ -4,12 +4,12 @@
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);
@@ -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 bmesh_finddoubles_exec(BMesh *bm, BMOperator *op);
#endif
diff --git a/source/blender/bmesh/intern/editmesh_to_bmesh.c b/source/blender/bmesh/intern/editmesh_to_bmesh.c
index 6f7fac9fa45..81e3572dec6 100644
--- a/source/blender/bmesh/intern/editmesh_to_bmesh.c
+++ b/source/blender/bmesh/intern/editmesh_to_bmesh.c
@@ -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_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]);
diff --git a/source/blender/bmesh/operators/bmesh_dupeops.c b/source/blender/bmesh/operators/bmesh_dupeops.c
index 1a1089c427b..b5c327bc24c 100644
--- a/source/blender/bmesh/operators/bmesh_dupeops.c
+++ b/source/blender/bmesh/operators/bmesh_dupeops.c
@@ -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");
- /*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))){
@@ -217,17 +224,30 @@ static void copy_mesh(BMOperator *op, BMesh *source, BMesh *target)
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);
diff --git a/source/blender/bmesh/operators/mesh_conv.c b/source/blender/bmesh/operators/mesh_conv.c
index 28991f2cae7..3ca95ea1e32 100644
--- a/source/blender/bmesh/operators/mesh_conv.c
+++ b/source/blender/bmesh/operators/mesh_conv.c
@@ -45,7 +45,7 @@ void mesh_to_bmesh_exec(BMesh *bm, BMOperator *op) {
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*/
@@ -53,6 +53,16 @@ void mesh_to_bmesh_exec(BMesh *bm, BMOperator *op) {
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);
diff --git a/source/blender/bmesh/operators/removedoubles.c b/source/blender/bmesh/operators/removedoubles.c
index 1bbb222d67e..605626d15e0 100644
--- a/source/blender/bmesh/operators/removedoubles.c
+++ b/source/blender/bmesh/operators/removedoubles.c
@@ -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);
@@ -79,7 +79,8 @@ void bmesh_weldverts_exec(BMesh *bm, BMOperator *op)
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;
@@ -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;
- 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);
+ V_RESET(loops);
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);
- e2 = BM_Edge_Exist(v, v2);
+ e2 = v != v2 ? BM_Edge_Exist(v, v2) : NULL;
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);
+
+ 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*/
@@ -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_KEEP 8
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);
}
+
+
+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);
+}