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
path: root/source
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 /source
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.
Diffstat (limited to 'source')
-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
18 files changed, 534 insertions, 71 deletions
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);
+}