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-08-19 00:05:08 +0400
committerJoseph Eagar <joeedh@gmail.com>2009-08-19 00:05:08 +0400
commitf7cef59b3dff4c3094aaae0f54cd8fe35e011748 (patch)
tree802b2c66b22c37eafcbac2cd7631135cef5e2073 /source/blender
parent3c7b9347ec6f4cb506e5954433ae5f2a0cde5b3d (diff)
rearranged some code a bit
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenkernel/BKE_customdata.h5
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c94
-rw-r--r--source/blender/blenkernel/intern/cdderivedmesh.c10
-rw-r--r--source/blender/blenkernel/intern/customdata.c10
-rw-r--r--source/blender/blenkernel/intern/editderivedbmesh.c82
-rw-r--r--source/blender/blenkernel/intern/modifiers_bmesh.c2
-rw-r--r--source/blender/blenkernel/intern/subsurf_ccg.c212
-rw-r--r--source/blender/bmesh/bmesh.h27
-rw-r--r--source/blender/bmesh/bmesh_operator_api.h4
-rw-r--r--source/blender/editors/mesh/bmesh_select.c553
-rw-r--r--source/blender/editors/mesh/editmesh_mods.c646
-rw-r--r--source/blender/editors/space_view3d/view3d_snap.c4
12 files changed, 867 insertions, 782 deletions
diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h
index 2c7348873be..f11d7824db6 100644
--- a/source/blender/blenkernel/BKE_customdata.h
+++ b/source/blender/blenkernel/BKE_customdata.h
@@ -162,12 +162,13 @@ void CustomData_set_only_copy(const struct CustomData *data,
void CustomData_copy_data(const struct CustomData *source,
struct CustomData *dest, int source_index,
int dest_index, int count);
+void CustomData_copy_elements(int type, void *source, void *dest, int count);
void CustomData_em_copy_data(const struct CustomData *source,
struct CustomData *dest, void *src_block,
void **dest_block);
void CustomData_bmesh_copy_data(const struct CustomData *source,
- struct CustomData *dest,void *src_block,
- void **dest_block);
+ struct CustomData *dest, void *src_block,
+ void **dest_block);
/* frees data in a CustomData object
* return 1 on success, 0 on failure
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index eadb4e566ce..ca6dc9407ff 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -282,27 +282,75 @@ void dm_add_polys_from_iter(CustomData *ldata, CustomData *pdata, DerivedMesh *d
{
DMFaceIter *iter = dm->newFaceIter(dm);
DMLoopIter *liter;
+ CustomData *oldata, *opdata;
MPoly *mpoly;
MLoop *mloop;
- int i;
+ int l, i, j, lasttype;
+
+ oldata = dm->getLoopDataLayout(dm);
+ opdata = dm->getFaceDataLayout(dm);
+
+ CustomData_copy(oldata, ldata, CD_MASK_DERIVEDMESH, CD_CALLOC, totloop);
+ CustomData_copy(opdata, pdata, CD_MASK_DERIVEDMESH, CD_CALLOC, dm->getNumFaces(dm));
mloop = MEM_callocN(sizeof(MLoop)*totloop, "MLoop from dm_add_polys_from_iter");
- mpoly = MEM_callocN(sizeof(MPoly)*dm->getNumFaces(dm), "MPoly from dm_add_polys_from_iter");
-
CustomData_add_layer(ldata, CD_MLOOP, CD_ASSIGN, mloop, totloop);
+ mpoly = MEM_callocN(sizeof(MPoly)*dm->getNumFaces(dm), "MPoly from dm_add_polys_from_iter");
CustomData_add_layer(pdata, CD_MPOLY, CD_ASSIGN, mpoly, dm->getNumFaces(dm));
- i = 0;
+ l = 0;
for (; !iter->done; iter->step(iter), mpoly++) {
mpoly->flag = iter->flags;
- mpoly->loopstart = i;
+ mpoly->loopstart = l;
mpoly->totloop = iter->len;
mpoly->mat_nr = iter->mat_nr;
+ j = 0;
+ lasttype = -1;
+ for (i=0; i<opdata->totlayer; i++) {
+ void *e1, *e2;
+
+ if (opdata->layers[i].type == CD_MPOLY)
+ continue;
+
+ e1 = iter->getCDData(iter, opdata->layers[i].type, j);
+ e2 = CustomData_get_layer_n(pdata, opdata->layers[i].type, j);
+
+ CustomData_copy_elements(opdata->layers[i].type, e1, e2, 1);
+
+ if (opdata->layers[i].type == lasttype)
+ j++;
+ else
+ j = 0;
+
+ lasttype = opdata->layers[i].type;
+ }
+
liter = iter->getLoopsIter(iter);
- for (; !liter->done; liter->step(liter), mloop++, i++) {
+ for (; !liter->done; liter->step(liter), mloop++, l++) {
mloop->v = liter->vindex;
mloop->e = liter->eindex;
+
+ j = 0;
+ lasttype = -1;
+ for (i=0; i<oldata->totlayer; i++) {
+ void *e1, *e2;
+
+ if (oldata->layers[i].type == CD_MLOOP)
+ continue;
+
+ e1 = liter->getLoopCDData(liter, oldata->layers[i].type, j);
+ e2 = CustomData_get_layer_n(ldata, oldata->layers[i].type, j);
+
+ CustomData_copy_elements(oldata->layers[i].type, e1, e2, 1);
+
+ if (oldata->layers[i].type == lasttype)
+ j++;
+ else
+ j = 0;
+
+ lasttype = oldata->layers[i].type;
+ }
}
}
iter->free(iter);
@@ -312,33 +360,21 @@ void DM_DupPolys(DerivedMesh *source, DerivedMesh *target)
{
DMFaceIter *iter = source->newFaceIter(source);
DMLoopIter *liter;
- MPoly *mpoly;
- MLoop *mloop;
- int i;
+ int totloop = 0;
- mloop = MEM_callocN(sizeof(MLoop)*source->numLoopData, "MLoop from dm_add_polys_from_iter");
- mpoly = MEM_callocN(sizeof(MPoly)*source->getNumFaces(source), "MPoly from dm_add_polys_from_iter");
-
- CustomData_add_layer(&target->loopData, CD_MLOOP, CD_ASSIGN, mloop, source->numLoopData);
- CustomData_add_layer(&target->polyData, CD_MPOLY, CD_ASSIGN, mpoly, source->getNumFaces(source));
-
- target->numLoopData = source->numLoopData;
- target->numPolyData = source->numPolyData;
-
- i = 0;
- for (; !iter->done; iter->step(iter), mpoly++) {
- mpoly->flag = iter->flags;
- mpoly->loopstart = i;
- mpoly->totloop = iter->len;
- mpoly->mat_nr = iter->mat_nr;
-
+ for (; !iter->done; iter->step(iter)) {
liter = iter->getLoopsIter(iter);
- for (; !liter->done; liter->step(liter), mloop++, i++) {
- mloop->v = liter->vindex;
- mloop->e = liter->eindex;
+ for (; !liter->done; liter->step(liter)) {
+ totloop++;
}
}
+
iter->free(iter);
+
+ dm_add_polys_from_iter(&target->loopData, &target->polyData, source, totloop);
+
+ target->numLoopData = totloop;
+ target->numPolyData = source->getNumFaces(source);
}
void DM_to_mesh(DerivedMesh *dm, Mesh *me)
@@ -1044,7 +1080,7 @@ static void emDM_drawFacesTex_common(void *dm,
}
}
-static void emDM_drawFacesTex(void *dm, int (*setDrawOptions)(MTFace *tface, MCol *mcol, int matnr))
+static void emDM_drawFacesTex(void *dm, int (*setDrawOptions)(MTFace *tface, int has_vcol, int matnr))
{
emDM_drawFacesTex_common(dm, setDrawOptions, NULL, NULL);
}
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index 61355c4265e..0f7ebc05558 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -1311,7 +1311,7 @@ void *cddm_faceiter_getcddata(void *self, int type, int layer)
void *cddm_loopiter_getcddata(void *self, int type, int layer)
{
- CDDM_FaceIter *iter = self;
+ CDDM_LoopIter *iter = self;
if (layer == -1) return CustomData_get(&iter->cddm->dm.loopData,
iter->head.index, type);
@@ -1321,13 +1321,13 @@ void *cddm_loopiter_getcddata(void *self, int type, int layer)
void *cddm_loopiter_getvertcddata(void *self, int type, int layer)
{
- CDDM_FaceIter *iter = self;
+ CDDM_LoopIter *iter = self;
if (layer == -1) return CustomData_get(&iter->cddm->dm.vertData,
- iter->cddm->mloop[iter->head.index].v,
+ iter->cddm->mloop[iter->head.vindex].v,
type);
else return CustomData_get_n(&iter->cddm->dm.vertData, type,
- iter->cddm->mloop[iter->head.index].v, layer);
+ iter->cddm->mloop[iter->head.vindex].v, layer);
}
DMLoopIter *cddmiter_get_loopiter(void *self)
@@ -1406,8 +1406,6 @@ DerivedMesh *CDDM_copy(DerivedMesh *source)
CustomData_copy_data(&source->vertData, &dm->vertData, 0, 0, numVerts);
CustomData_copy_data(&source->edgeData, &dm->edgeData, 0, 0, numEdges);
CustomData_copy_data(&source->faceData, &dm->faceData, 0, 0, numFaces);
- CustomData_copy_data(&source->loopData, &dm->loopData, 0, 0, numLoops);
- CustomData_copy_data(&source->polyData, &dm->polyData, 0, 0, numPolys);
/* now add mvert/medge/mface layers */
cddm->mvert = source->dupVertArray(source);
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index 17a822aaee0..72c3e3b0188 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -1465,6 +1465,16 @@ void CustomData_set_only_copy(const struct CustomData *data,
data->layers[i].flag |= CD_FLAG_NOCOPY;
}
+void CustomData_copy_elements(int type, void *source, void *dest, int count)
+{
+ const LayerTypeInfo *typeInfo = layerType_getInfo(type);
+
+ if (typeInfo->copy)
+ typeInfo->copy(source, dest, count);
+ else
+ memcpy(dest, source, typeInfo->size*count);
+}
+
void CustomData_copy_data(const CustomData *source, CustomData *dest,
int source_index, int dest_index, int count)
{
diff --git a/source/blender/blenkernel/intern/editderivedbmesh.c b/source/blender/blenkernel/intern/editderivedbmesh.c
index c34f5253a42..a17d16ce754 100644
--- a/source/blender/blenkernel/intern/editderivedbmesh.c
+++ b/source/blender/blenkernel/intern/editderivedbmesh.c
@@ -275,6 +275,9 @@ typedef struct EditDerivedBMesh {
/*private variables, for number of verts/edges/faces
within the above hash/table members*/
int tv, te, tf;
+
+ /*customdata layout of the tesselated faces*/
+ CustomData tessface_layout;
} EditDerivedBMesh;
static void bmdm_recalc_lookups(EditDerivedBMesh *bmdm)
@@ -1312,6 +1315,8 @@ void bmDM_faceIterStep(void *self)
iter->head.flags = BMFlags_To_MEFlags(iter->f);
iter->head.index++;
+ iter->head.len = iter->f->len;
+
iter->nextf = BMIter_Step(&iter->iter);
if (!iter->nextf) iter->head.done = 1;
@@ -1330,16 +1335,16 @@ void bmDM_loopIterStep(void *self)
{
bmDM_loopIter *iter = self;
- iter->l = iter->nextl;
+ iter->l = BMIter_Step(&iter->iter);
+ if (!iter->l) {
+ iter->head.done = 1;
+ return;
+ }
bmvert_to_mvert(iter->l->v, &iter->head.v);
iter->head.index++;
iter->head.vindex = BMINDEX_GET(iter->l->v);
iter->head.eindex = BMINDEX_GET(iter->l->e);
-
- iter->nextl = BMIter_Step(&iter->iter);
-
- if (!iter->nextl) iter->head.done = 1;
}
void *bmDM_getLoopCDData(void *self, int type, int layer)
@@ -1378,15 +1383,15 @@ DMLoopIter *bmDM_newLoopsIter(void *faceiter)
iter->bm = fiter->bm;
iter->f = fiter->f;
- iter->nextl = BMIter_New(&iter->iter, iter->bm, BM_LOOPS_OF_FACE, iter->f);
+ iter->l = BMIter_New(&iter->iter, iter->bm, BM_LOOPS_OF_FACE, iter->f);
iter->head.step = bmDM_loopIterStep;
iter->head.getLoopCDData = bmDM_getLoopCDData;
iter->head.getVertCDData = bmDM_getVertCDData;
- bmvert_to_mvert(iter->nextl->v, &iter->head.v);
- iter->head.vindex = BMINDEX_GET(iter->nextl->v);
- iter->head.eindex = BMINDEX_GET(iter->nextl->e);
+ bmvert_to_mvert(iter->l->v, &iter->head.v);
+ iter->head.vindex = BMINDEX_GET(iter->l->v);
+ iter->head.eindex = BMINDEX_GET(iter->l->e);
return (DMLoopIter*) iter;
}
@@ -1450,19 +1455,76 @@ static void bmDM_release(void *dm)
}
}
+CustomData *bmDm_getVertDataLayout(DerivedMesh *dm)
+{
+ EditDerivedBMesh *bmdm = (EditDerivedBMesh*)dm;
+
+ return &bmdm->tc->bm->vdata;
+}
+
+CustomData *bmDm_getEdgeDataLayout(DerivedMesh *dm)
+{
+ EditDerivedBMesh *bmdm = (EditDerivedBMesh*)dm;
+
+ return &bmdm->tc->bm->edata;
+}
+
+CustomData *bmDm_getTessFaceDataLayout(DerivedMesh *dm)
+{
+ EditDerivedBMesh *bmdm = (EditDerivedBMesh*)dm;
+
+ return &bmdm->tessface_layout;
+}
+
+CustomData *bmDm_getLoopDataLayout(DerivedMesh *dm)
+{
+ EditDerivedBMesh *bmdm = (EditDerivedBMesh*)dm;
+
+ return &bmdm->tc->bm->ldata;
+}
+
+CustomData *bmDm_getFaceDataLayout(DerivedMesh *dm)
+{
+ EditDerivedBMesh *bmdm = (EditDerivedBMesh*)dm;
+
+ return &bmdm->tc->bm->pdata;
+}
+
+
DerivedMesh *getEditDerivedBMesh(BMEditMesh *em, Object *ob,
float (*vertexCos)[3])
{
EditDerivedBMesh *bmdm = MEM_callocN(sizeof(*bmdm), "bmdm");
BMesh *bm = em->bm;
-
+ int i;
+
bmdm->tc = em;
DM_init((DerivedMesh*)bmdm, em->bm->totvert, em->bm->totedge, em->tottri,
em->bm->totloop, em->bm->totface);
+
+ for (i=0; i<bm->ldata.totlayer; i++) {
+ if (bm->ldata.layers[i].type == CD_MLOOPCOL) {
+ CustomData_add_layer(&bmdm->tessface_layout, CD_MCOL, CD_ASSIGN, NULL, 0);
+ } else if (bm->ldata.layers[i].type == CD_MLOOPUV) {
+ CustomData_add_layer(&bmdm->tessface_layout, CD_MTFACE, CD_ASSIGN, NULL, 0);
+ }
+ }
+
+ bmdm->dm.numVertData = bm->totvert;
+ bmdm->dm.numEdgeData = bm->totedge;
+ bmdm->dm.numFaceData = em->tottri;
+ bmdm->dm.numLoopData = bm->totloop;
+ bmdm->dm.numPolyData = bm->totface;
bmdm->dm.getMinMax = bmDM_getMinMax;
+ bmdm->dm.getVertDataLayout = bmDm_getVertDataLayout;
+ bmdm->dm.getEdgeDataLayout = bmDm_getEdgeDataLayout;
+ bmdm->dm.getTessFaceDataLayout = bmDm_getTessFaceDataLayout;
+ bmdm->dm.getLoopDataLayout = bmDm_getLoopDataLayout;
+ bmdm->dm.getFaceDataLayout = bmDm_getFaceDataLayout;
+
bmdm->dm.getNumVerts = bmDM_getNumVerts;
bmdm->dm.getNumEdges = bmDM_getNumEdges;
bmdm->dm.getNumTessFaces = bmDM_getNumTessFaces;
diff --git a/source/blender/blenkernel/intern/modifiers_bmesh.c b/source/blender/blenkernel/intern/modifiers_bmesh.c
index 33ca50bfe85..f69e0efcea6 100644
--- a/source/blender/blenkernel/intern/modifiers_bmesh.c
+++ b/source/blender/blenkernel/intern/modifiers_bmesh.c
@@ -605,7 +605,7 @@ DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd,
BMO_Finish_Op(bm, &op);
BMEdit_RecalcTesselation(em);
- result = CDDM_from_BMEditMesh(em, NULL);
+ result = CDDM_from_BMEditMesh(em, NULL); //CDDM_copy(getEditDerivedBMesh(em, ob, NULL));
BMEdit_Free(em);
MEM_freeN(em);
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index 93efaf87c96..ba53bbe7767 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -91,6 +91,10 @@ typedef struct CCGDerivedMesh CCGDerivedMesh;
static int cgdm_getVertMapIndex(CSubSurf *ss, CCVert *v);
static int cgdm_getEdgeMapIndex(CSubSurf *ss, CCEdge *e);
static int cgdm_getFaceMapIndex(CSubSurf *ss, CCFace *f);
+static CCGDerivedMesh *getCCGDerivedMesh(CSubSurf *ss,
+ int drawInteriorEdges,
+ int useSubsurfUv,
+ DerivedMesh *dm);
///
@@ -177,6 +181,7 @@ static int getEdgeIndex(CSubSurf *ss, CCEdge *e, int x, int edgeSize) {
return edgeBase + x-1;
}
}
+
static int getFaceIndex(CSubSurf *ss, CCFace *f, int S, int x, int y, int edgeSize, int gridSize) {
int faceBase = *((int*) CCS_getFaceUserData(ss, f));
int numVerts = CCS_getFaceNumVerts(f);
@@ -573,6 +578,15 @@ static DerivedMesh *ss_to_cdderivedmesh(CSubSurf *ss, int ssFromEditmesh,
int drawInteriorEdges, int useSubsurfUv,
DerivedMesh *dm, MultiresSubsurf *ms)
{
+ DerivedMesh *cgdm, *result;
+
+ cgdm = getCCGDerivedMesh(ss, drawInteriorEdges, useSubsurfUv, dm);
+ result = CDDM_copy(cgdm);
+ cgdm->needsFree = 1;
+ cgdm->release(cgdm);
+
+ return result;
+#if 0
DerivedMesh *result;
int edgeSize = CCS_getEdgeSize(ss);
int gridSize = CCS_getGridSize(ss);
@@ -948,6 +962,7 @@ static DerivedMesh *ss_to_cdderivedmesh(CSubSurf *ss, int ssFromEditmesh,
V_FREE(w);
return result;
+#endif
}
static void ss_sync_from_derivedmesh(CSubSurf *ss, DerivedMesh *dm,
@@ -1455,6 +1470,7 @@ typedef struct cgdm_faceIter {
MFace mface;
cgdm_loopIter liter;
+ EdgeHash *ehash; /*edge map for populating loopiter->eindex*/
} cgdm_faceIter;
void cgdm_faceIterStep(void *self)
@@ -1494,7 +1510,7 @@ void cgdm_loopIterStep(void *self)
{
cgdm_loopIter *liter = self;
MFace *mf = &liter->fiter->mface;
- int i, in;
+ int i, v1, v2;
if (liter->head.index >= liter->fiter->head.len) {
liter->head.done = 1;
@@ -1506,23 +1522,27 @@ void cgdm_loopIterStep(void *self)
switch (i) {
case 0:
- in = liter->fiter->mface.v1;
+ v1 = liter->fiter->mface.v1;
+ v2 = liter->fiter->mface.v2;
break;
case 1:
- in = liter->fiter->mface.v2;
+ v1 = liter->fiter->mface.v2;
+ v2 = liter->fiter->mface.v3;
break;
case 2:
- in = liter->fiter->mface.v3;
+ v1 = liter->fiter->mface.v3;
+ v2 = liter->fiter->mface.v4;
break;
case 3:
- in = liter->fiter->mface.v4;
+ v1 = liter->fiter->mface.v4;
+ v2 = liter->fiter->mface.v1;
break;
}
- liter->head.vindex = in;
-
- /*we don't set .eindex*/
- cgdm_getFinalVert((DerivedMesh*)liter->cgdm, in, &liter->head.v);
+ liter->head.vindex = v1;
+ liter->head.eindex = GET_INT_FROM_POINTER(BLI_edgehash_lookup(liter->fiter->ehash, v1, v2));
+
+ cgdm_getFinalVert((DerivedMesh*)liter->cgdm, v1, &liter->head.v);
}
void *cgdm_loopIterGetVCData(void *self, int type, int layer)
@@ -1554,11 +1574,27 @@ DMLoopIter *cgdm_faceIterGetLIter(void *self)
return (DMLoopIter*) &fiter->liter;
}
+void cgdm_faceIterFree(void *vfiter)
+{
+ cgdm_faceIter *fiter = vfiter;
+ BLI_edgehash_free(fiter->ehash, NULL);
+ MEM_freeN(fiter);
+}
+
DMFaceIter *cgdm_newFaceIter(DerivedMesh *dm)
{
cgdm_faceIter *fiter = MEM_callocN(sizeof(cgdm_faceIter), "cgdm_faceIter");
+ MEdge medge;
+ int i, totedge = cgdm_getNumEdges(dm);
+
+ fiter->ehash = BLI_edgehash_new();
- fiter->head.free = MEM_freeN;
+ for (i=0; i<totedge; i++) {
+ cgdm_getFinalEdge(dm, i, &medge);
+ BLI_edgehash_insert(fiter->ehash, medge.v1, medge.v2, SET_INT_IN_POINTER(i));
+ }
+
+ fiter->head.free = cgdm_faceIterFree;
fiter->head.step = cgdm_faceIterStep;
fiter->head.index = -1;
fiter->head.getCDData = cgdm_faceIterCData;
@@ -2174,7 +2210,7 @@ static void cgdm_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned cha
}
static void cgdm_drawFacesTex_common(DerivedMesh *dm,
- int (*drawParams)(MTFace *tface, MCol *mcol, int matnr),
+ int (*drawParams)(MTFace *tface, int has_vcol, int matnr),
int (*drawParamsMapped)(void *userData, int index),
void *userData)
{
@@ -2205,7 +2241,7 @@ static void cgdm_drawFacesTex_common(DerivedMesh *dm,
}
if(drawParams)
- flag = drawParams(tf, mcol, mat_nr);
+ flag = drawParams(tf, mcol!=NULL, mat_nr);
else
flag= (drawParamsMapped)? drawParamsMapped(userData, index): 1;
@@ -2305,7 +2341,7 @@ static void cgdm_drawFacesTex_common(DerivedMesh *dm,
}
}
-static void cgdm_drawFacesTex(DerivedMesh *dm, int (*setDrawOptions)(MTFace *tface, MCol *mcol, int matnr))
+static void cgdm_drawFacesTex(DerivedMesh *dm, int (*setDrawOptions)(MTFace *tface, int has_vcol, int matnr))
{
cgdm_drawFacesTex_common(dm, setDrawOptions, NULL, NULL);
}
@@ -2578,8 +2614,9 @@ static CCGDerivedMesh *getCCGDerivedMesh(CSubSurf *ss,
int *vertOrigIndex, *faceOrigIndex, *polyOrigIndex; /* *edgeOrigIndex - as yet, unused */
int *edgeFlags;
char *faceFlags, *polyFlags;
- int *loopidx = NULL;
+ int *loopidx = NULL, *vertidx = NULL;
V_DECLARE(loopidx);
+ V_DECLARE(vertidx);
int loopindex, loopindex2;
int edgeSize;
int gridSize;
@@ -2591,8 +2628,6 @@ static CCGDerivedMesh *getCCGDerivedMesh(CSubSurf *ss,
int gridInternalEdges;
int index2;
float *w = NULL;
- DMFaceIter *dfiter, *dfiter2;
- DMLoopIter *dliter, *dliter2;
WeightTable wtable = {0};
V_DECLARE(w);
/* MVert *mvert = NULL; - as yet unused */
@@ -2732,52 +2767,82 @@ static CCGDerivedMesh *getCCGDerivedMesh(CSubSurf *ss,
mcol = DM_get_tessface_data_layer(&cgdm->dm, CD_MCOL);
index2 = 0;
- dfiter = dm->newFaceIter(dm);
- dfiter2 = cgdm->dm.newFaceIter(cgdm);
loopindex = loopindex2 = 0; //current loop index
- for (index = 0; index < totface; index++, dfiter->step(dfiter)) {
+ for (index = 0; index < totface; index++) {
CCFace *f = cgdm->faceMap[index].face;
int numVerts = CCS_getFaceNumVerts(f);
int numFinalEdges = numVerts * (gridSideEdges + gridInternalEdges);
int mapIndex = cgdm_getFaceMapIndex(ss, f);
int origIndex = GET_INT_FROM_POINTER(CCS_getFaceFaceHandle(ss, f));
int g2_wid = gridCuts+2;
+ float *w2;
int s, x, y;
+ w = get_ss_weights(&wtable, gridCuts, numVerts);
+
cgdm->faceMap[index].startVert = vertNum;
cgdm->faceMap[index].startEdge = edgeNum;
- cgdm->faceMap[index].startFace = faceNum;
-
- V_RESET(w);
+ cgdm->faceMap[index].startFace = index2;
+
V_RESET(loopidx);
-
+
for (s=0; s<numVerts; s++) {
V_GROW(loopidx);
loopidx[s] = loopindex++;
}
+
+ V_RESET(vertidx);
+ for(s = 0; s < numVerts; s++) {
+ CCVert *v = CCS_getFaceVert(ss, f, s);
+
+ V_GROW(vertidx);
+ vertidx[s] = GET_INT_FROM_POINTER(CCS_getVertVertHandle(v));
+ }
+
- w = get_ss_weights(&wtable, gridCuts, numVerts);
+ w2 = w + s*numVerts*g2_wid*g2_wid;
+ DM_interp_vert_data(dm, &cgdm->dm, vertidx, w2,
+ numVerts, vertNum);
+ if (vertOrigIndex)
+ *vertOrigIndex = ORIGINDEX_NONE;
+ ++vertOrigIndex;
+ ++vertNum;
- /* set the face base vert */
- *((int*)CCS_getFaceUserData(ss, f)) = vertNum;
- for (s=0; s<numVerts; s++) {
- int x1, y1;
+ /*interpolate per-vert data*/
+ for(s = 0; s < numVerts; s++) {
+ for(x = 1; x < gridFaces; x++) {
+ w2 = w + s*numVerts*g2_wid*g2_wid + x*numVerts;
+ DM_interp_vert_data(dm, &cgdm->dm, vertidx, w2,
+ numVerts, vertNum);
- for (y1=0; y1<gridFaces; y1++) {
- for (x1=0; x1<gridFaces; x1++) {
- float *w2;
+ if (vertOrigIndex)
+ *vertOrigIndex = ORIGINDEX_NONE;
+ ++vertOrigIndex;
+ ++vertNum;
+ }
+ }
- x = x1; //gridFaces - x1 - 1;
- y = y1; //gridFaces - y1 - 1;
- //for (i=0; i<4; i++) {
- /*float f1, f2;
- f1 = (float)x / ((float)gridFaces-1.0f);
- f2 = (float)y / ((float)gridFaces-1.0f);
+ for(s = 0; s < numVerts; s++) {
+ for(y = 1; y < gridFaces; y++) {
+ for(x = 1; x < gridFaces; x++) {
+ w2 = w + s*numVerts*g2_wid*g2_wid + (y*g2_wid+x)*numVerts;
+ DM_interp_vert_data(dm, &cgdm->dm, vertidx, w2,
+ numVerts, vertNum);
- mcol->r = f1*255.0f;
- mcol->g = f2*255.0f;
- mcol->b = 0;*/
+ if (vertOrigIndex)
+ *vertOrigIndex = ORIGINDEX_NONE;
+ ++vertOrigIndex;
+ ++vertNum;
+ }
+ }
+ }
+ /* set the face base vert */
+ *((int*)CCS_getFaceUserData(ss, f)) = vertNum;
+ for (s=0; s<numVerts; s++) {
+ /*interpolate per-face data*/
+ for (y=0; y<gridFaces; y++) {
+ for (x=0; x<gridFaces; x++) {
w2 = w + s*numVerts*g2_wid*g2_wid + (y*g2_wid+x)*numVerts;
CustomData_interp(&dm->loopData, &cgdm->dm.loopData,
loopidx, w2, NULL, numVerts, loopindex2);
@@ -2798,9 +2863,10 @@ static CCGDerivedMesh *getCCGDerivedMesh(CSubSurf *ss,
loopidx, w2, NULL, numVerts, loopindex2);
loopindex2++;
- //}
+ /*copy over poly data, e.g. mtexpoly*/
CustomData_interp(&dm->polyData, &cgdm->dm.polyData, &origIndex, w, NULL, 1, index2);
+ /*generate tesselated face data used for drawing*/
ccg_loops_to_corners(&cgdm->dm.faceData, &cgdm->dm.loopData,
&cgdm->dm.polyData, loopindex2-4, index2, index2, numTex, numCol);
@@ -2808,6 +2874,69 @@ static CCGDerivedMesh *getCCGDerivedMesh(CSubSurf *ss,
}
}
}
+
+ edgeNum += numFinalEdges;
+ }
+
+ for(index = 0; index < totvert; ++index) {
+ CCVert *v = cgdm->vertMap[index].vert;
+ int mapIndex = cgdm_getVertMapIndex(cgdm->ss, v);
+ int vidx;
+
+ vidx = GET_INT_FROM_POINTER(CCS_getVertVertHandle(v));
+
+ cgdm->vertMap[index].startVert = vertNum;
+
+ /* set the vert base vert */
+ *((int*) CCS_getVertUserData(ss, v)) = vertNum;
+
+ DM_copy_vert_data(dm, &cgdm->dm, vidx, vertNum, 1);
+
+ *vertOrigIndex = mapIndex;
+ ++vertOrigIndex;
+ ++vertNum;
+ }
+
+ edgeFlags = DM_get_edge_data_layer(&cgdm->dm, CD_FLAGS);
+ for(index = 0; index < totedge; ++index) {
+ CCEdge *e = cgdm->edgeMap[index].edge;
+ int numFinalEdges = edgeSize - 1;
+ int mapIndex = cgdm_getEdgeMapIndex(ss, e);
+ int x;
+ int vertIdx[2];
+ int edgeIdx = GET_INT_FROM_POINTER(CCS_getEdgeEdgeHandle(e));
+
+ CCVert *v;
+ v = CCS_getEdgeVert0(e);
+ vertIdx[0] = GET_INT_FROM_POINTER(CCS_getVertVertHandle(v));
+ v = CCS_getEdgeVert1(e);
+ vertIdx[1] = GET_INT_FROM_POINTER(CCS_getVertVertHandle(v));
+
+ cgdm->edgeMap[index].startVert = vertNum;
+ cgdm->edgeMap[index].startEdge = edgeNum;
+
+ /* set the edge base vert */
+ *((int*)CCS_getEdgeUserData(ss, e)) = vertNum;
+
+ for(x = 1; x < edgeSize - 1; x++) {
+ float w[2];
+ w[1] = (float) x / (edgeSize - 1);
+ w[0] = 1 - w[1];
+ DM_interp_vert_data(dm, &cgdm->dm, vertIdx, w, 2, vertNum);
+ *vertOrigIndex = ORIGINDEX_NONE;
+ ++vertOrigIndex;
+ ++vertNum;
+ }
+
+ for(i = 0; i < numFinalEdges; ++i) {
+ if(edgeIdx >= 0 && edgeFlags)
+ edgeFlags[edgeNum + i] = medge[edgeIdx].flag;
+
+ *(int *)DM_get_edge_data(&cgdm->dm, edgeNum + i,
+ CD_ORIGINDEX) = mapIndex;
+ }
+
+ edgeNum += numFinalEdges;
}
#if 0
for(index = 0; index < totface; ++index) {
@@ -2838,7 +2967,6 @@ static CCGDerivedMesh *getCCGDerivedMesh(CSubSurf *ss,
++vertOrigIndex;
++vertNum;
-
for(S = 0; S < numVerts; S++) {
int prevS = (S - 1 + numVerts) % numVerts;
int nextS = (S + 1) % numVerts;
diff --git a/source/blender/bmesh/bmesh.h b/source/blender/bmesh/bmesh.h
index f9fddac6e57..e3518e77477 100644
--- a/source/blender/bmesh/bmesh.h
+++ b/source/blender/bmesh/bmesh.h
@@ -95,9 +95,9 @@ struct EditMesh;
/*BMHeader->type*/
#define BM_VERT 1
#define BM_EDGE 2
-#define BM_FACE 4
-#define BM_LOOP 8
-#define BM_ALL (BM_VERT | BM_EDGE | BM_FACE | BM_LOOP)
+#define BM_LOOP 4
+#define BM_FACE 8
+#define BM_ALL (BM_VERT | BM_EDGE | BM_LOOP | BM_FACE)
/*BMHeader->flag*/
#define BM_SELECT (1<<0)
@@ -117,14 +117,15 @@ typedef struct BMHeader {
/*don't confuse this with tool flags. this flag
member is what "header flag" means.*/
int flag;
- int type;
+ int type; /*the element type, can be BM_VERT, BM_EDGE, BM_LOOP, or BM_FACE*/
int eflag1, eflag2; /*Flags used by eulers. Try and get rid of/minimize some of these*/
- //this can only be used to store a temporary index. don't use it for anything else.
- //use the BMINDEX_GET and BMINDEX_SET macros!!
+ /*this is only used to store temporary integers.
+ don't use it for anything else.
+ use the BMINDEX_GET and BMINDEX_SET macros to access it*/
int index;
struct BMFlagLayer *flags; /*Dynamically allocated block of flag layers for operators to use*/
- void *data; /*customdata*/
+ void *data; /*customdata block*/
} BMHeader;
typedef struct BMFlagLayer {
@@ -132,7 +133,7 @@ typedef struct BMFlagLayer {
short mask, pflag;
} BMFlagLayer;
-#define BM_OVERLAP (1<<14) /*used by bmesh_verts_in_face*/
+#define BM_OVERLAP (1<<14) /*used by bmesh_verts_in_face*/
#define BM_EDGEVERT (1<<15) /*used by bmesh_make_ngon*/
/*
@@ -182,8 +183,7 @@ typedef struct BMVert {
float co[3];
float no[3];
struct BMEdge *edge;
- void *tmp; /*what?*/
- float bweight; /*please, someone just get rid of me...*/
+ float bweight; /*please, someone just get rid of me...*/
} BMVert;
typedef struct BMEdge {
@@ -254,12 +254,6 @@ void BM_Face_CopyShared(BMesh *bm, BMFace *f);
to another of the same type.*/
void BM_Copy_Attributes(struct BMesh *source_mesh, struct BMesh *target_mesh, void *source, void *target);
-/*remove tool flagged elements*/
-void BM_remove_tagged_faces(struct BMesh *bm, int flag);
-void BM_remove_tagged_edges(struct BMesh *bm, int flag);
-void BM_remove_tagged_verts(struct BMesh *bm, int flag);
-
-
/*Modification*/
/*join two adjacent faces together along an edge. note that
the faces must only be joined by on edge. e is the edge you
@@ -323,6 +317,7 @@ void BM_free_data_layer(BMesh *em, CustomData *data, int type);
/*computes the centroid of a face, using the center of the bounding box*/
int BM_Compute_Face_Center(BMesh *bm, BMFace *f, float center[3]);
+
void BM_SelectMode_Flush(BMesh *bm);
/*convert an editmesh to a bmesh*/
diff --git a/source/blender/bmesh/bmesh_operator_api.h b/source/blender/bmesh/bmesh_operator_api.h
index ce81d2ddd57..de6bbdcdcdf 100644
--- a/source/blender/bmesh/bmesh_operator_api.h
+++ b/source/blender/bmesh/bmesh_operator_api.h
@@ -195,6 +195,10 @@ BMOpSlot *BMO_GetSlot(struct BMOperator *op, char *slotname);
void BMO_CopySlot(struct BMOperator *source_op, struct BMOperator *dest_op,
char *src, char *dst);
+/*remove tool flagged elements*/
+void BM_remove_tagged_faces(struct BMesh *bm, int flag);
+void BM_remove_tagged_edges(struct BMesh *bm, int flag);
+void BM_remove_tagged_verts(struct BMesh *bm, int flag);
void BMO_Set_Float(struct BMOperator *op, char *slotname, float f);
float BMO_Get_Float(BMOperator *op, char *slotname);
diff --git a/source/blender/editors/mesh/bmesh_select.c b/source/blender/editors/mesh/bmesh_select.c
index 15c9cf68e8f..4a154eb3b6d 100644
--- a/source/blender/editors/mesh/bmesh_select.c
+++ b/source/blender/editors/mesh/bmesh_select.c
@@ -643,28 +643,26 @@ static int unified_findnearest(ViewContext *vc, BMVert **eve, BMEdge **eed, BMFa
return (*eve || *eed || *efa);
}
-
/* **************** SIMILAR "group" SELECTS. FACE, EDGE AND VERTEX ************** */
-/* selects new faces/edges/verts based on the
- existing selection
+/* selects new faces/edges/verts based on the existing selection */
-FACES GROUP
- mode 1: same material
- mode 2: same image
- mode 3: same area
- mode 4: same perimeter
- mode 5: same normal
- mode 6: same co-planer
-*/
+/* FACES GROUP */
+
+#define SIMFACE_MATERIAL 201
+#define SIMFACE_IMAGE 202
+#define SIMFACE_AREA 203
+#define SIMFACE_PERIMETER 204
+#define SIMFACE_NORMAL 205
+#define SIMFACE_COPLANAR 206
static EnumPropertyItem prop_simface_types[] = {
- {1, "MATERIAL", 0, "Material", ""},
- {2, "IMAGE", 0, "Image", ""},
- {3, "AREA", 0, "Area", ""},
- {4, "PERIMETER", 0, "Perimeter", ""},
- {5, "NORMAL", 0, "Normal", ""},
- {6, "COPLANAR", 0, "Co-planar", ""},
+ {SIMFACE_MATERIAL, "MATERIAL", 0, "Material", ""},
+ {SIMFACE_IMAGE, "IMAGE", 0, "Image", ""},
+ {SIMFACE_AREA, "AREA", 0, "Area", ""},
+ {SIMFACE_PERIMETER, "PERIMETER", 0, "Perimeter", ""},
+ {SIMFACE_NORMAL, "NORMAL", 0, "Normal", ""},
+ {SIMFACE_COPLANAR, "COPLANAR", 0, "Co-planar", ""},
{0, NULL, 0, NULL, NULL}
};
@@ -673,10 +671,10 @@ static EnumPropertyItem prop_simface_types[] = {
*0.5 so smaller faces arnt ALWAYS selected with a thresh of 1.0 */
#define SCALE_CMP(a,b) ((a+a*thresh >= b) && (a-(a*thresh*0.5) <= b))
-static int similar_face_select__internal(Scene *scene, BMEditMesh *em, int mode)
+static int similar_face_select__internal(Scene *scene, EditMesh *em, int mode)
{
-#if 0 //BMESH_TODO
- BMFace *efa, *base_efa=NULL;
+#if 0
+ EditFace *efa, *base_efa=NULL;
unsigned int selcount=0; /*count how many new faces we select*/
/*deselcount, count how many deselected faces are left, so we can bail out early
@@ -700,12 +698,11 @@ static int similar_face_select__internal(Scene *scene, BMEditMesh *em, int mode)
if (!ok || !deselcount) /* no data selected OR no more data to select */
return 0;
- /*if mode is 3 then record face areas, 4 record perimeter */
- if (mode==3) {
+ if (mode==SIMFACE_AREA) {
for(efa= em->faces.first; efa; efa= efa->next) {
efa->tmp.fp= EM_face_area(efa);
}
- } else if (mode==4) {
+ } else if (mode==SIMFACE_PERIMETER) {
for(efa= em->faces.first; efa; efa= efa->next) {
efa->tmp.fp= EM_face_perimeter(efa);
}
@@ -713,7 +710,7 @@ static int similar_face_select__internal(Scene *scene, BMEditMesh *em, int mode)
for(base_efa= em->faces.first; base_efa; base_efa= base_efa->next) {
if (base_efa->f1) { /* This was one of the faces originaly selected */
- if (mode==1) { /* same material */
+ if (mode==SIMFACE_MATERIAL) { /* same material */
for(efa= em->faces.first; efa; efa= efa->next) {
if (
!(efa->f & SELECT) &&
@@ -727,7 +724,7 @@ static int similar_face_select__internal(Scene *scene, BMEditMesh *em, int mode)
return selcount;
}
}
- } else if (mode==2) { /* same image */
+ } else if (mode==SIMFACE_IMAGE) { /* same image */
MTFace *tf, *base_tf;
base_tf = (MTFace*)CustomData_em_get(&em->fdata, base_efa->data,
@@ -750,7 +747,7 @@ static int similar_face_select__internal(Scene *scene, BMEditMesh *em, int mode)
}
}
}
- } else if (mode==3 || mode==4) { /* same area OR same perimeter, both use the same temp var */
+ } else if (mode==SIMFACE_AREA || mode==SIMFACE_PERIMETER) { /* same area OR same perimeter, both use the same temp var */
for(efa= em->faces.first; efa; efa= efa->next) {
if (
(!(efa->f & SELECT) && !efa->h) &&
@@ -763,7 +760,7 @@ static int similar_face_select__internal(Scene *scene, BMEditMesh *em, int mode)
return selcount;
}
}
- } else if (mode==5) { /* same normal */
+ } else if (mode==SIMFACE_NORMAL) {
float angle;
for(efa= em->faces.first; efa; efa= efa->next) {
if (!(efa->f & SELECT) && !efa->h) {
@@ -777,7 +774,7 @@ static int similar_face_select__internal(Scene *scene, BMEditMesh *em, int mode)
}
}
}
- } else if (mode==6) { /* same planer */
+ } else if (mode==SIMFACE_COPLANAR) { /* same planer */
float angle, base_dot, dot;
base_dot= Inpf(base_efa->cent, base_efa->n);
for(efa= em->faces.first; efa; efa= efa->next) {
@@ -802,6 +799,506 @@ static int similar_face_select__internal(Scene *scene, BMEditMesh *em, int mode)
#endif
}
+static int similar_face_select_exec(bContext *C, wmOperator *op)
+{
+#if 0
+ Scene *scene= CTX_data_scene(C);
+ Object *obedit= CTX_data_edit_object(C);
+ Mesh *me= obedit->data;
+ EditMesh *em= BKE_mesh_get_editmesh(me);
+
+ int selcount = similar_face_select__internal(scene, em, RNA_int_get(op->ptr, "type"));
+
+ if (selcount) {
+ /* here was an edge-mode only select flush case, has to be generalized */
+ EM_selectmode_flush(em);
+ WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+ BKE_mesh_end_editmesh(me, em);
+ return OPERATOR_FINISHED;
+ }
+
+ BKE_mesh_end_editmesh(me, em);
+#endif
+ return OPERATOR_CANCELLED;
+}
+
+/* ***************************************************** */
+
+/* EDGE GROUP */
+
+#define SIMEDGE_LENGTH 101
+#define SIMEDGE_DIR 102
+#define SIMEDGE_FACE 103
+#define SIMEDGE_FACE_ANGLE 104
+#define SIMEDGE_CREASE 105
+#define SIMEDGE_SEAM 106
+#define SIMEDGE_SHARP 107
+
+static EnumPropertyItem prop_simedge_types[] = {
+ {SIMEDGE_LENGTH, "LENGTH", 0, "Length", ""},
+ {SIMEDGE_DIR, "DIR", 0, "Direction", ""},
+ {SIMEDGE_FACE, "FACE", 0, "Amount of Vertices in Face", ""},
+ {SIMEDGE_FACE_ANGLE, "FACE_ANGLE", 0, "Face Angles", ""},
+ {SIMEDGE_CREASE, "CREASE", 0, "Crease", ""},
+ {SIMEDGE_SEAM, "SEAM", 0, "Seam", ""},
+ {SIMEDGE_SHARP, "SHARP", 0, "Sharpness", ""},
+ {0, NULL, 0, NULL, NULL}
+};
+
+static int similar_edge_select__internal(Scene *scene, EditMesh *em, int mode)
+{
+#if 0
+ EditEdge *eed, *base_eed=NULL;
+ unsigned int selcount=0; /* count how many new edges we select*/
+
+ /*count how many visible selected edges there are,
+ so we can return when there are none left */
+ unsigned int deselcount=0;
+
+ short ok=0;
+ float thresh= scene->toolsettings->select_thresh;
+
+ for(eed= em->edges.first; eed; eed= eed->next) {
+ if (!eed->h) {
+ if (eed->f & SELECT) {
+ eed->f1=1;
+ ok=1;
+ } else {
+ eed->f1=0;
+ deselcount++;
+ }
+ /* set all eed->tmp.l to 0 we use it later.
+ for counting face users*/
+ eed->tmp.l=0;
+ eed->f2=0; /* only for mode SIMEDGE_FACE_ANGLE, edge animations */
+ }
+ }
+
+ if (!ok || !deselcount) /* no data selected OR no more data to select*/
+ return 0;
+
+ if (mode==SIMEDGE_LENGTH) { /*store length*/
+ for(eed= em->edges.first; eed; eed= eed->next) {
+ if (!eed->h) /* dont calc data for hidden edges*/
+ eed->tmp.fp= VecLenf(eed->v1->co, eed->v2->co);
+ }
+ } else if (mode==SIMEDGE_FACE) { /*store face users*/
+ EditFace *efa;
+ /* cound how many faces each edge uses use tmp->l */
+ for(efa= em->faces.first; efa; efa= efa->next) {
+ efa->e1->tmp.l++;
+ efa->e2->tmp.l++;
+ efa->e3->tmp.l++;
+ if (efa->e4) efa->e4->tmp.l++;
+ }
+ } else if (mode==SIMEDGE_FACE_ANGLE) { /*store edge angles */
+ EditFace *efa;
+ int j;
+ /* cound how many faces each edge uses use tmp.l */
+ for(efa= em->faces.first; efa; efa= efa->next) {
+ /* here we use the edges temp data to assign a face
+ if a face has alredy been assigned (eed->f2==1)
+ we calculate the angle between the current face and
+ the edges previously found face.
+ store the angle in eed->tmp.fp (loosing the face eed->tmp.f)
+ but tagging eed->f2==2, so we know not to look at it again.
+ This only works for edges that connect to 2 faces. but its good enough
+ */
+
+ /* se we can loop through face edges*/
+ j=0;
+ eed= efa->e1;
+ while (j<4) {
+ if (j==1) eed= efa->e2;
+ else if (j==2) eed= efa->e3;
+ else if (j==3) {
+ eed= efa->e4;
+ if (!eed)
+ break;
+ } /* done looping */
+
+ if (!eed->h) { /* dont calc data for hidden edges*/
+ if (eed->f2==2)
+ break;
+ else if (eed->f2==0) /* first access, assign the face */
+ eed->tmp.f= efa;
+ else if (eed->f2==1) /* second, we assign the angle*/
+ eed->tmp.fp= VecAngle2(eed->tmp.f->n, efa->n)/180;
+ eed->f2++; /* f2==0 no face assigned. f2==1 one face found. f2==2 angle calculated.*/
+ }
+ j++;
+ }
+ }
+ }
+
+ for(base_eed= em->edges.first; base_eed; base_eed= base_eed->next) {
+ if (base_eed->f1) {
+ if (mode==SIMEDGE_LENGTH) { /* same length */
+ for(eed= em->edges.first; eed; eed= eed->next) {
+ if (
+ !(eed->f & SELECT) &&
+ !eed->h &&
+ SCALE_CMP(base_eed->tmp.fp, eed->tmp.fp)
+ ) {
+ EM_select_edge(eed, 1);
+ selcount++;
+ deselcount--;
+ if (!deselcount) /*have we selected all posible faces?, if so return*/
+ return selcount;
+ }
+ }
+ } else if (mode==SIMEDGE_DIR) { /* same direction */
+ float base_dir[3], dir[3], angle;
+ VecSubf(base_dir, base_eed->v1->co, base_eed->v2->co);
+ for(eed= em->edges.first; eed; eed= eed->next) {
+ if (!(eed->f & SELECT) && !eed->h) {
+ VecSubf(dir, eed->v1->co, eed->v2->co);
+ angle= VecAngle2(base_dir, dir);
+
+ if (angle>90) /* use the smallest angle between the edges */
+ angle= fabs(angle-180.0f);
+
+ if (angle/90.0<=thresh) {
+ EM_select_edge(eed, 1);
+ selcount++;
+ deselcount--;
+ if (!deselcount) /*have we selected all posible faces?, if so return*/
+ return selcount;
+ }
+ }
+ }
+ } else if (mode==SIMEDGE_FACE) { /* face users */
+ for(eed= em->edges.first; eed; eed= eed->next) {
+ if (
+ !(eed->f & SELECT) &&
+ !eed->h &&
+ base_eed->tmp.l==eed->tmp.l
+ ) {
+ EM_select_edge(eed, 1);
+ selcount++;
+ deselcount--;
+ if (!deselcount) /*have we selected all posible faces?, if so return*/
+ return selcount;
+ }
+ }
+ } else if (mode==SIMEDGE_FACE_ANGLE && base_eed->f2==2) { /* edge angles, f2==2 means the edge has an angle. */
+ for(eed= em->edges.first; eed; eed= eed->next) {
+ if (
+ !(eed->f & SELECT) &&
+ !eed->h &&
+ eed->f2==2 &&
+ (fabs(base_eed->tmp.fp-eed->tmp.fp)<=thresh)
+ ) {
+ EM_select_edge(eed, 1);
+ selcount++;
+ deselcount--;
+ if (!deselcount) /*have we selected all posible faces?, if so return*/
+ return selcount;
+ }
+ }
+ } else if (mode==SIMEDGE_CREASE) { /* edge crease */
+ for(eed= em->edges.first; eed; eed= eed->next) {
+ if (
+ !(eed->f & SELECT) &&
+ !eed->h &&
+ (fabs(base_eed->crease-eed->crease) <= thresh)
+ ) {
+ EM_select_edge(eed, 1);
+ selcount++;
+ deselcount--;
+ if (!deselcount) /*have we selected all posible faces?, if so return*/
+ return selcount;
+ }
+ }
+ } else if (mode==SIMEDGE_SEAM) { /* edge seam */
+ for(eed= em->edges.first; eed; eed= eed->next) {
+ if (
+ !(eed->f & SELECT) &&
+ !eed->h &&
+ (eed->seam == base_eed->seam)
+ ) {
+ EM_select_edge(eed, 1);
+ selcount++;
+ deselcount--;
+ if (!deselcount) /*have we selected all posible faces?, if so return*/
+ return selcount;
+ }
+ }
+ } else if (mode==SIMEDGE_SHARP) { /* edge sharp */
+ for(eed= em->edges.first; eed; eed= eed->next) {
+ if (
+ !(eed->f & SELECT) &&
+ !eed->h &&
+ (eed->sharp == base_eed->sharp)
+ ) {
+ EM_select_edge(eed, 1);
+ selcount++;
+ deselcount--;
+ if (!deselcount) /*have we selected all posible faces?, if so return*/
+ return selcount;
+ }
+ }
+ }
+ }
+ }
+ return selcount;
+#endif
+}
+/* wrap the above function but do selection flushing edge to face */
+static int similar_edge_select_exec(bContext *C, wmOperator *op)
+{
+#if 0
+ Scene *scene= CTX_data_scene(C);
+ Object *obedit= CTX_data_edit_object(C);
+ Mesh *me= obedit->data;
+ EditMesh *em= BKE_mesh_get_editmesh(me);
+
+ int selcount = similar_edge_select__internal(scene, em, RNA_int_get(op->ptr, "type"));
+
+ if (selcount) {
+ /* here was an edge-mode only select flush case, has to be generalized */
+ EM_selectmode_flush(em);
+ WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+ BKE_mesh_end_editmesh(me, em);
+ return OPERATOR_FINISHED;
+ }
+
+ BKE_mesh_end_editmesh(me, em);
+ return OPERATOR_CANCELLED;
+#endif
+}
+
+/* ********************************* */
+
+/*
+VERT GROUP
+ mode 1: same normal
+ mode 2: same number of face users
+ mode 3: same vertex groups
+*/
+
+#define SIMVERT_NORMAL 0
+#define SIMVERT_FACE 1
+#define SIMVERT_VGROUP 2
+
+static EnumPropertyItem prop_simvertex_types[] = {
+ {SIMVERT_NORMAL, "NORMAL", 0, "Normal", ""},
+ {SIMVERT_FACE, "FACE", 0, "Amount of Vertices in Face", ""},
+ {SIMVERT_VGROUP, "VGROUP", 0, "Vertex Groups", ""},
+ {0, NULL, 0, NULL, NULL}
+};
+
+
+static int similar_vert_select_exec(bContext *C, wmOperator *op)
+{
+#if 0
+ Scene *scene= CTX_data_scene(C);
+ Object *obedit= CTX_data_edit_object(C);
+ Mesh *me= obedit->data;
+ EditMesh *em= BKE_mesh_get_editmesh(me);
+ EditVert *eve, *base_eve=NULL;
+ unsigned int selcount=0; /* count how many new edges we select*/
+
+ /*count how many visible selected edges there are,
+ so we can return when there are none left */
+ unsigned int deselcount=0;
+ int mode= RNA_enum_get(op->ptr, "type");
+
+ short ok=0;
+ float thresh= scene->toolsettings->select_thresh;
+
+ for(eve= em->verts.first; eve; eve= eve->next) {
+ if (!eve->h) {
+ if (eve->f & SELECT) {
+ eve->f1=1;
+ ok=1;
+ } else {
+ eve->f1=0;
+ deselcount++;
+ }
+ /* set all eve->tmp.l to 0 we use them later.*/
+ eve->tmp.l=0;
+ }
+
+ }
+
+ if (!ok || !deselcount) { /* no data selected OR no more data to select*/
+ BKE_mesh_end_editmesh(me, em);
+ return 0;
+ }
+
+ if(mode == SIMVERT_FACE) {
+ /* store face users */
+ EditFace *efa;
+
+ /* count how many faces each edge uses use tmp->l */
+ for(efa= em->faces.first; efa; efa= efa->next) {
+ efa->v1->tmp.l++;
+ efa->v2->tmp.l++;
+ efa->v3->tmp.l++;
+ if (efa->v4) efa->v4->tmp.l++;
+ }
+ }
+
+
+ for(base_eve= em->verts.first; base_eve; base_eve= base_eve->next) {
+ if (base_eve->f1) {
+
+ if(mode == SIMVERT_NORMAL) {
+ float angle;
+ for(eve= em->verts.first; eve; eve= eve->next) {
+ if (!(eve->f & SELECT) && !eve->h) {
+ angle= VecAngle2(base_eve->no, eve->no);
+ if (angle/180.0<=thresh) {
+ eve->f |= SELECT;
+ selcount++;
+ deselcount--;
+ if (!deselcount) {/*have we selected all posible faces?, if so return*/
+ BKE_mesh_end_editmesh(me, em);
+ return selcount;
+ }
+ }
+ }
+ }
+ }
+ else if(mode == SIMVERT_FACE) {
+ for(eve= em->verts.first; eve; eve= eve->next) {
+ if (
+ !(eve->f & SELECT) &&
+ !eve->h &&
+ base_eve->tmp.l==eve->tmp.l
+ ) {
+ eve->f |= SELECT;
+ selcount++;
+ deselcount--;
+ if (!deselcount) {/*have we selected all posible faces?, if so return*/
+ BKE_mesh_end_editmesh(me, em);
+ return selcount;
+ }
+ }
+ }
+ }
+ else if(mode == SIMVERT_VGROUP) {
+ MDeformVert *dvert, *base_dvert;
+ short i, j; /* weight index */
+
+ base_dvert= CustomData_em_get(&em->vdata, base_eve->data,
+ CD_MDEFORMVERT);
+
+ if (!base_dvert || base_dvert->totweight == 0) {
+ BKE_mesh_end_editmesh(me, em);
+ return selcount;
+ }
+
+ for(eve= em->verts.first; eve; eve= eve->next) {
+ dvert= CustomData_em_get(&em->vdata, eve->data,
+ CD_MDEFORMVERT);
+
+ if (dvert && !(eve->f & SELECT) && !eve->h && dvert->totweight) {
+ /* do the extra check for selection in the following if, so were not
+ checking verts that may be alredy selected */
+ for (i=0; base_dvert->totweight >i && !(eve->f & SELECT); i++) {
+ for (j=0; dvert->totweight >j; j++) {
+ if (base_dvert->dw[i].def_nr==dvert->dw[j].def_nr) {
+ eve->f |= SELECT;
+ selcount++;
+ deselcount--;
+ if (!deselcount) { /*have we selected all posible faces?, if so return*/
+ BKE_mesh_end_editmesh(me, em);
+ return selcount;
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ } /* end basevert loop */
+
+ if(selcount) {
+ WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+ BKE_mesh_end_editmesh(me, em);
+ return OPERATOR_FINISHED;
+ }
+
+ BKE_mesh_end_editmesh(me, em);
+#endif
+ return OPERATOR_CANCELLED;
+}
+
+static int select_similar_exec(bContext *C, wmOperator *op)
+{
+ int type= RNA_enum_get(op->ptr, "type");
+
+ if(type < 100)
+ return similar_vert_select_exec(C, op);
+ else if(type < 200)
+ return similar_edge_select_exec(C, op);
+ else
+ return similar_face_select_exec(C, op);
+}
+
+static EnumPropertyItem *select_similar_type_itemf(bContext *C, PointerRNA *ptr, int *free)
+{
+ Object *obedit;
+ EnumPropertyItem *item= NULL;
+ int totitem= 0;
+
+ if(C==NULL) {
+ /* needed for doc generation */
+ RNA_enum_items_add(&item, &totitem, prop_simvertex_types);
+ RNA_enum_items_add(&item, &totitem, prop_simedge_types);
+ RNA_enum_items_add(&item, &totitem, prop_simface_types);
+ RNA_enum_item_end(&item, &totitem);
+ *free= 1;
+
+ return item;
+ }
+
+ obedit= CTX_data_edit_object(C);
+
+ if(obedit && obedit->type == OB_MESH) {
+ EditMesh *em= BKE_mesh_get_editmesh(obedit->data);
+
+ if(em->selectmode & SCE_SELECT_VERTEX)
+ RNA_enum_items_add(&item, &totitem, prop_simvertex_types);
+ else if(em->selectmode & SCE_SELECT_EDGE)
+ RNA_enum_items_add(&item, &totitem, prop_simedge_types);
+ else if(em->selectmode & SCE_SELECT_FACE)
+ RNA_enum_items_add(&item, &totitem, prop_simface_types);
+ RNA_enum_item_end(&item, &totitem);
+
+ *free= 1;
+
+ return item;
+ }
+
+ return NULL;
+}
+
+void MESH_OT_select_similar(wmOperatorType *ot)
+{
+ PropertyRNA *prop;
+
+ /* identifiers */
+ ot->name= "Select Similar";
+ ot->idname= "MESH_OT_select_similar";
+
+ /* api callbacks */
+ ot->invoke= WM_menu_invoke;
+ ot->exec= select_similar_exec;
+ ot->poll= ED_operator_editmesh;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ /* properties */
+ prop= RNA_def_enum(ot->srna, "type", prop_simvertex_types, 0, "Type", "");
+ RNA_def_enum_funcs(prop, select_similar_type_itemf);
+}
+
/* ***************************************************** */
/* **************** LOOP SELECTS *************** */
diff --git a/source/blender/editors/mesh/editmesh_mods.c b/source/blender/editors/mesh/editmesh_mods.c
index 225a85b2db0..06870915e1d 100644
--- a/source/blender/editors/mesh/editmesh_mods.c
+++ b/source/blender/editors/mesh/editmesh_mods.c
@@ -329,655 +329,9 @@ int EM_init_backbuf_circle(ViewContext *vc, short xs, short ys, short rads)
}
-/* **************** SIMILAR "group" SELECTS. FACE, EDGE AND VERTEX ************** */
-
-/* selects new faces/edges/verts based on the existing selection */
-
-/* FACES GROUP */
-
-#define SIMFACE_MATERIAL 201
-#define SIMFACE_IMAGE 202
-#define SIMFACE_AREA 203
-#define SIMFACE_PERIMETER 204
-#define SIMFACE_NORMAL 205
-#define SIMFACE_COPLANAR 206
-
-static EnumPropertyItem prop_simface_types[] = {
- {SIMFACE_MATERIAL, "MATERIAL", 0, "Material", ""},
- {SIMFACE_IMAGE, "IMAGE", 0, "Image", ""},
- {SIMFACE_AREA, "AREA", 0, "Area", ""},
- {SIMFACE_PERIMETER, "PERIMETER", 0, "Perimeter", ""},
- {SIMFACE_NORMAL, "NORMAL", 0, "Normal", ""},
- {SIMFACE_COPLANAR, "COPLANAR", 0, "Co-planar", ""},
- {0, NULL, 0, NULL, NULL}
-};
-
-
-/* this as a way to compare the ares, perim of 2 faces thay will scale to different sizes
-*0.5 so smaller faces arnt ALWAYS selected with a thresh of 1.0 */
-#define SCALE_CMP(a,b) ((a+a*thresh >= b) && (a-(a*thresh*0.5) <= b))
-
-static int similar_face_select__internal(Scene *scene, EditMesh *em, int mode)
-{
- EditFace *efa, *base_efa=NULL;
- unsigned int selcount=0; /*count how many new faces we select*/
-
- /*deselcount, count how many deselected faces are left, so we can bail out early
- also means that if there are no deselected faces, we can avoid a lot of looping */
- unsigned int deselcount=0;
- float thresh= scene->toolsettings->select_thresh;
- short ok=0;
-
- for(efa= em->faces.first; efa; efa= efa->next) {
- if (!efa->h) {
- if (efa->f & SELECT) {
- efa->f1=1;
- ok=1;
- } else {
- efa->f1=0;
- deselcount++; /* a deselected face we may select later */
- }
- }
- }
-
- if (!ok || !deselcount) /* no data selected OR no more data to select */
- return 0;
-
- if (mode==SIMFACE_AREA) {
- for(efa= em->faces.first; efa; efa= efa->next) {
- efa->tmp.fp= EM_face_area(efa);
- }
- } else if (mode==SIMFACE_PERIMETER) {
- for(efa= em->faces.first; efa; efa= efa->next) {
- efa->tmp.fp= EM_face_perimeter(efa);
- }
- }
-
- for(base_efa= em->faces.first; base_efa; base_efa= base_efa->next) {
- if (base_efa->f1) { /* This was one of the faces originaly selected */
- if (mode==SIMFACE_MATERIAL) { /* same material */
- for(efa= em->faces.first; efa; efa= efa->next) {
- if (
- !(efa->f & SELECT) &&
- !efa->h &&
- base_efa->mat_nr == efa->mat_nr
- ) {
- EM_select_face(efa, 1);
- selcount++;
- deselcount--;
- if (!deselcount) /*have we selected all posible faces?, if so return*/
- return selcount;
- }
- }
- } else if (mode==SIMFACE_IMAGE) { /* same image */
- MTFace *tf, *base_tf;
-
- base_tf = (MTFace*)CustomData_em_get(&em->fdata, base_efa->data,
- CD_MTFACE);
-
- if(!base_tf)
- return selcount;
-
- for(efa= em->faces.first; efa; efa= efa->next) {
- if (!(efa->f & SELECT) && !efa->h) {
- tf = (MTFace*)CustomData_em_get(&em->fdata, efa->data,
- CD_MTFACE);
-
- if(base_tf->tpage == tf->tpage) {
- EM_select_face(efa, 1);
- selcount++;
- deselcount--;
- if (!deselcount) /*have we selected all posible faces?, if so return*/
- return selcount;
- }
- }
- }
- } else if (mode==SIMFACE_AREA || mode==SIMFACE_PERIMETER) { /* same area OR same perimeter, both use the same temp var */
- for(efa= em->faces.first; efa; efa= efa->next) {
- if (
- (!(efa->f & SELECT) && !efa->h) &&
- SCALE_CMP(base_efa->tmp.fp, efa->tmp.fp)
- ) {
- EM_select_face(efa, 1);
- selcount++;
- deselcount--;
- if (!deselcount) /*have we selected all posible faces?, if so return*/
- return selcount;
- }
- }
- } else if (mode==SIMFACE_NORMAL) {
- float angle;
- for(efa= em->faces.first; efa; efa= efa->next) {
- if (!(efa->f & SELECT) && !efa->h) {
- angle= VecAngle2(base_efa->n, efa->n);
- if (angle/180.0<=thresh) {
- EM_select_face(efa, 1);
- selcount++;
- deselcount--;
- if (!deselcount) /*have we selected all posible faces?, if so return*/
- return selcount;
- }
- }
- }
- } else if (mode==SIMFACE_COPLANAR) { /* same planer */
- float angle, base_dot, dot;
- base_dot= Inpf(base_efa->cent, base_efa->n);
- for(efa= em->faces.first; efa; efa= efa->next) {
- if (!(efa->f & SELECT) && !efa->h) {
- angle= VecAngle2(base_efa->n, efa->n);
- if (angle/180.0<=thresh) {
- dot=Inpf(efa->cent, base_efa->n);
- if (fabs(base_dot-dot) <= thresh) {
- EM_select_face(efa, 1);
- selcount++;
- deselcount--;
- if (!deselcount) /*have we selected all posible faces?, if so return*/
- return selcount;
- }
- }
- }
- }
- }
- }
- } /* end base_efa loop */
- return selcount;
-}
-
-static int similar_face_select_exec(bContext *C, wmOperator *op)
-{
- Scene *scene= CTX_data_scene(C);
- Object *obedit= CTX_data_edit_object(C);
- Mesh *me= obedit->data;
- EditMesh *em= BKE_mesh_get_editmesh(me);
-
- int selcount = similar_face_select__internal(scene, em, RNA_int_get(op->ptr, "type"));
-
- if (selcount) {
- /* here was an edge-mode only select flush case, has to be generalized */
- EM_selectmode_flush(em);
- WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
- BKE_mesh_end_editmesh(me, em);
- return OPERATOR_FINISHED;
- }
-
- BKE_mesh_end_editmesh(me, em);
- return OPERATOR_CANCELLED;
-}
-
-/* ***************************************************** */
-
-/* EDGE GROUP */
-
-#define SIMEDGE_LENGTH 101
-#define SIMEDGE_DIR 102
-#define SIMEDGE_FACE 103
-#define SIMEDGE_FACE_ANGLE 104
-#define SIMEDGE_CREASE 105
-#define SIMEDGE_SEAM 106
-#define SIMEDGE_SHARP 107
-
-static EnumPropertyItem prop_simedge_types[] = {
- {SIMEDGE_LENGTH, "LENGTH", 0, "Length", ""},
- {SIMEDGE_DIR, "DIR", 0, "Direction", ""},
- {SIMEDGE_FACE, "FACE", 0, "Amount of Vertices in Face", ""},
- {SIMEDGE_FACE_ANGLE, "FACE_ANGLE", 0, "Face Angles", ""},
- {SIMEDGE_CREASE, "CREASE", 0, "Crease", ""},
- {SIMEDGE_SEAM, "SEAM", 0, "Seam", ""},
- {SIMEDGE_SHARP, "SHARP", 0, "Sharpness", ""},
- {0, NULL, 0, NULL, NULL}
-};
-
-static int similar_edge_select__internal(Scene *scene, EditMesh *em, int mode)
-{
- EditEdge *eed, *base_eed=NULL;
- unsigned int selcount=0; /* count how many new edges we select*/
-
- /*count how many visible selected edges there are,
- so we can return when there are none left */
- unsigned int deselcount=0;
-
- short ok=0;
- float thresh= scene->toolsettings->select_thresh;
-
- for(eed= em->edges.first; eed; eed= eed->next) {
- if (!eed->h) {
- if (eed->f & SELECT) {
- eed->f1=1;
- ok=1;
- } else {
- eed->f1=0;
- deselcount++;
- }
- /* set all eed->tmp.l to 0 we use it later.
- for counting face users*/
- eed->tmp.l=0;
- eed->f2=0; /* only for mode SIMEDGE_FACE_ANGLE, edge animations */
- }
- }
-
- if (!ok || !deselcount) /* no data selected OR no more data to select*/
- return 0;
-
- if (mode==SIMEDGE_LENGTH) { /*store length*/
- for(eed= em->edges.first; eed; eed= eed->next) {
- if (!eed->h) /* dont calc data for hidden edges*/
- eed->tmp.fp= VecLenf(eed->v1->co, eed->v2->co);
- }
- } else if (mode==SIMEDGE_FACE) { /*store face users*/
- EditFace *efa;
- /* cound how many faces each edge uses use tmp->l */
- for(efa= em->faces.first; efa; efa= efa->next) {
- efa->e1->tmp.l++;
- efa->e2->tmp.l++;
- efa->e3->tmp.l++;
- if (efa->e4) efa->e4->tmp.l++;
- }
- } else if (mode==SIMEDGE_FACE_ANGLE) { /*store edge angles */
- EditFace *efa;
- int j;
- /* cound how many faces each edge uses use tmp.l */
- for(efa= em->faces.first; efa; efa= efa->next) {
- /* here we use the edges temp data to assign a face
- if a face has alredy been assigned (eed->f2==1)
- we calculate the angle between the current face and
- the edges previously found face.
- store the angle in eed->tmp.fp (loosing the face eed->tmp.f)
- but tagging eed->f2==2, so we know not to look at it again.
- This only works for edges that connect to 2 faces. but its good enough
- */
-
- /* se we can loop through face edges*/
- j=0;
- eed= efa->e1;
- while (j<4) {
- if (j==1) eed= efa->e2;
- else if (j==2) eed= efa->e3;
- else if (j==3) {
- eed= efa->e4;
- if (!eed)
- break;
- } /* done looping */
-
- if (!eed->h) { /* dont calc data for hidden edges*/
- if (eed->f2==2)
- break;
- else if (eed->f2==0) /* first access, assign the face */
- eed->tmp.f= efa;
- else if (eed->f2==1) /* second, we assign the angle*/
- eed->tmp.fp= VecAngle2(eed->tmp.f->n, efa->n)/180;
- eed->f2++; /* f2==0 no face assigned. f2==1 one face found. f2==2 angle calculated.*/
- }
- j++;
- }
- }
- }
-
- for(base_eed= em->edges.first; base_eed; base_eed= base_eed->next) {
- if (base_eed->f1) {
- if (mode==SIMEDGE_LENGTH) { /* same length */
- for(eed= em->edges.first; eed; eed= eed->next) {
- if (
- !(eed->f & SELECT) &&
- !eed->h &&
- SCALE_CMP(base_eed->tmp.fp, eed->tmp.fp)
- ) {
- EM_select_edge(eed, 1);
- selcount++;
- deselcount--;
- if (!deselcount) /*have we selected all posible faces?, if so return*/
- return selcount;
- }
- }
- } else if (mode==SIMEDGE_DIR) { /* same direction */
- float base_dir[3], dir[3], angle;
- VecSubf(base_dir, base_eed->v1->co, base_eed->v2->co);
- for(eed= em->edges.first; eed; eed= eed->next) {
- if (!(eed->f & SELECT) && !eed->h) {
- VecSubf(dir, eed->v1->co, eed->v2->co);
- angle= VecAngle2(base_dir, dir);
-
- if (angle>90) /* use the smallest angle between the edges */
- angle= fabs(angle-180.0f);
-
- if (angle/90.0<=thresh) {
- EM_select_edge(eed, 1);
- selcount++;
- deselcount--;
- if (!deselcount) /*have we selected all posible faces?, if so return*/
- return selcount;
- }
- }
- }
- } else if (mode==SIMEDGE_FACE) { /* face users */
- for(eed= em->edges.first; eed; eed= eed->next) {
- if (
- !(eed->f & SELECT) &&
- !eed->h &&
- base_eed->tmp.l==eed->tmp.l
- ) {
- EM_select_edge(eed, 1);
- selcount++;
- deselcount--;
- if (!deselcount) /*have we selected all posible faces?, if so return*/
- return selcount;
- }
- }
- } else if (mode==SIMEDGE_FACE_ANGLE && base_eed->f2==2) { /* edge angles, f2==2 means the edge has an angle. */
- for(eed= em->edges.first; eed; eed= eed->next) {
- if (
- !(eed->f & SELECT) &&
- !eed->h &&
- eed->f2==2 &&
- (fabs(base_eed->tmp.fp-eed->tmp.fp)<=thresh)
- ) {
- EM_select_edge(eed, 1);
- selcount++;
- deselcount--;
- if (!deselcount) /*have we selected all posible faces?, if so return*/
- return selcount;
- }
- }
- } else if (mode==SIMEDGE_CREASE) { /* edge crease */
- for(eed= em->edges.first; eed; eed= eed->next) {
- if (
- !(eed->f & SELECT) &&
- !eed->h &&
- (fabs(base_eed->crease-eed->crease) <= thresh)
- ) {
- EM_select_edge(eed, 1);
- selcount++;
- deselcount--;
- if (!deselcount) /*have we selected all posible faces?, if so return*/
- return selcount;
- }
- }
- } else if (mode==SIMEDGE_SEAM) { /* edge seam */
- for(eed= em->edges.first; eed; eed= eed->next) {
- if (
- !(eed->f & SELECT) &&
- !eed->h &&
- (eed->seam == base_eed->seam)
- ) {
- EM_select_edge(eed, 1);
- selcount++;
- deselcount--;
- if (!deselcount) /*have we selected all posible faces?, if so return*/
- return selcount;
- }
- }
- } else if (mode==SIMEDGE_SHARP) { /* edge sharp */
- for(eed= em->edges.first; eed; eed= eed->next) {
- if (
- !(eed->f & SELECT) &&
- !eed->h &&
- (eed->sharp == base_eed->sharp)
- ) {
- EM_select_edge(eed, 1);
- selcount++;
- deselcount--;
- if (!deselcount) /*have we selected all posible faces?, if so return*/
- return selcount;
- }
- }
- }
- }
- }
- return selcount;
-}
-/* wrap the above function but do selection flushing edge to face */
-static int similar_edge_select_exec(bContext *C, wmOperator *op)
-{
- Scene *scene= CTX_data_scene(C);
- Object *obedit= CTX_data_edit_object(C);
- Mesh *me= obedit->data;
- EditMesh *em= BKE_mesh_get_editmesh(me);
-
- int selcount = similar_edge_select__internal(scene, em, RNA_int_get(op->ptr, "type"));
-
- if (selcount) {
- /* here was an edge-mode only select flush case, has to be generalized */
- EM_selectmode_flush(em);
- WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
- BKE_mesh_end_editmesh(me, em);
- return OPERATOR_FINISHED;
- }
-
- BKE_mesh_end_editmesh(me, em);
- return OPERATOR_CANCELLED;
-}
-
-/* ********************************* */
-
-/*
-VERT GROUP
- mode 1: same normal
- mode 2: same number of face users
- mode 3: same vertex groups
-*/
-
-#define SIMVERT_NORMAL 0
-#define SIMVERT_FACE 1
-#define SIMVERT_VGROUP 2
-
-static EnumPropertyItem prop_simvertex_types[] = {
- {SIMVERT_NORMAL, "NORMAL", 0, "Normal", ""},
- {SIMVERT_FACE, "FACE", 0, "Amount of Vertices in Face", ""},
- {SIMVERT_VGROUP, "VGROUP", 0, "Vertex Groups", ""},
- {0, NULL, 0, NULL, NULL}
-};
-
-
-static int similar_vert_select_exec(bContext *C, wmOperator *op)
-{
- Scene *scene= CTX_data_scene(C);
- Object *obedit= CTX_data_edit_object(C);
- Mesh *me= obedit->data;
- EditMesh *em= BKE_mesh_get_editmesh(me);
- EditVert *eve, *base_eve=NULL;
- unsigned int selcount=0; /* count how many new edges we select*/
-
- /*count how many visible selected edges there are,
- so we can return when there are none left */
- unsigned int deselcount=0;
- int mode= RNA_enum_get(op->ptr, "type");
-
- short ok=0;
- float thresh= scene->toolsettings->select_thresh;
-
- for(eve= em->verts.first; eve; eve= eve->next) {
- if (!eve->h) {
- if (eve->f & SELECT) {
- eve->f1=1;
- ok=1;
- } else {
- eve->f1=0;
- deselcount++;
- }
- /* set all eve->tmp.l to 0 we use them later.*/
- eve->tmp.l=0;
- }
-
- }
-
- if (!ok || !deselcount) { /* no data selected OR no more data to select*/
- BKE_mesh_end_editmesh(me, em);
- return 0;
- }
-
- if(mode == SIMVERT_FACE) {
- /* store face users */
- EditFace *efa;
-
- /* count how many faces each edge uses use tmp->l */
- for(efa= em->faces.first; efa; efa= efa->next) {
- efa->v1->tmp.l++;
- efa->v2->tmp.l++;
- efa->v3->tmp.l++;
- if (efa->v4) efa->v4->tmp.l++;
- }
- }
-
-
- for(base_eve= em->verts.first; base_eve; base_eve= base_eve->next) {
- if (base_eve->f1) {
-
- if(mode == SIMVERT_NORMAL) {
- float angle;
- for(eve= em->verts.first; eve; eve= eve->next) {
- if (!(eve->f & SELECT) && !eve->h) {
- angle= VecAngle2(base_eve->no, eve->no);
- if (angle/180.0<=thresh) {
- eve->f |= SELECT;
- selcount++;
- deselcount--;
- if (!deselcount) {/*have we selected all posible faces?, if so return*/
- BKE_mesh_end_editmesh(me, em);
- return selcount;
- }
- }
- }
- }
- }
- else if(mode == SIMVERT_FACE) {
- for(eve= em->verts.first; eve; eve= eve->next) {
- if (
- !(eve->f & SELECT) &&
- !eve->h &&
- base_eve->tmp.l==eve->tmp.l
- ) {
- eve->f |= SELECT;
- selcount++;
- deselcount--;
- if (!deselcount) {/*have we selected all posible faces?, if so return*/
- BKE_mesh_end_editmesh(me, em);
- return selcount;
- }
- }
- }
- }
- else if(mode == SIMVERT_VGROUP) {
- MDeformVert *dvert, *base_dvert;
- short i, j; /* weight index */
-
- base_dvert= CustomData_em_get(&em->vdata, base_eve->data,
- CD_MDEFORMVERT);
-
- if (!base_dvert || base_dvert->totweight == 0) {
- BKE_mesh_end_editmesh(me, em);
- return selcount;
- }
-
- for(eve= em->verts.first; eve; eve= eve->next) {
- dvert= CustomData_em_get(&em->vdata, eve->data,
- CD_MDEFORMVERT);
-
- if (dvert && !(eve->f & SELECT) && !eve->h && dvert->totweight) {
- /* do the extra check for selection in the following if, so were not
- checking verts that may be alredy selected */
- for (i=0; base_dvert->totweight >i && !(eve->f & SELECT); i++) {
- for (j=0; dvert->totweight >j; j++) {
- if (base_dvert->dw[i].def_nr==dvert->dw[j].def_nr) {
- eve->f |= SELECT;
- selcount++;
- deselcount--;
- if (!deselcount) { /*have we selected all posible faces?, if so return*/
- BKE_mesh_end_editmesh(me, em);
- return selcount;
- }
- break;
- }
- }
- }
- }
- }
- }
- }
- } /* end basevert loop */
-
- if(selcount) {
- WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
- BKE_mesh_end_editmesh(me, em);
- return OPERATOR_FINISHED;
- }
-
- BKE_mesh_end_editmesh(me, em);
- return OPERATOR_CANCELLED;
-}
-
-static int select_similar_exec(bContext *C, wmOperator *op)
-{
- int type= RNA_enum_get(op->ptr, "type");
-
- if(type < 100)
- return similar_vert_select_exec(C, op);
- else if(type < 200)
- return similar_edge_select_exec(C, op);
- else
- return similar_face_select_exec(C, op);
-}
-
-static EnumPropertyItem *select_similar_type_itemf(bContext *C, PointerRNA *ptr, int *free)
-{
- Object *obedit;
- EnumPropertyItem *item= NULL;
- int totitem= 0;
-
- if(C==NULL) {
- /* needed for doc generation */
- RNA_enum_items_add(&item, &totitem, prop_simvertex_types);
- RNA_enum_items_add(&item, &totitem, prop_simedge_types);
- RNA_enum_items_add(&item, &totitem, prop_simface_types);
- RNA_enum_item_end(&item, &totitem);
- *free= 1;
-
- return item;
- }
-
- obedit= CTX_data_edit_object(C);
-
- if(obedit && obedit->type == OB_MESH) {
- EditMesh *em= BKE_mesh_get_editmesh(obedit->data);
-
- if(em->selectmode & SCE_SELECT_VERTEX)
- RNA_enum_items_add(&item, &totitem, prop_simvertex_types);
- else if(em->selectmode & SCE_SELECT_EDGE)
- RNA_enum_items_add(&item, &totitem, prop_simedge_types);
- else if(em->selectmode & SCE_SELECT_FACE)
- RNA_enum_items_add(&item, &totitem, prop_simface_types);
- RNA_enum_item_end(&item, &totitem);
-
- *free= 1;
-
- return item;
- }
-
- return NULL;
-}
-
-void MESH_OT_select_similar(wmOperatorType *ot)
-{
- PropertyRNA *prop;
-
- /* identifiers */
- ot->name= "Select Similar";
- ot->idname= "MESH_OT_select_similar";
-
- /* api callbacks */
- ot->invoke= WM_menu_invoke;
- ot->exec= select_similar_exec;
- ot->poll= ED_operator_editmesh;
-
- /* flags */
- ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
-
- /* properties */
- prop= RNA_def_enum(ot->srna, "type", prop_simvertex_types, 0, "Type", "");
- RNA_def_enum_funcs(prop, select_similar_type_itemf);
-}
/* ******************************************* */
-
int mesh_layers_menu_charlen(CustomData *data, int type)
{
int i, len = 0;
diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c
index 98980548b86..5ec34d35d45 100644
--- a/source/blender/editors/space_view3d/view3d_snap.c
+++ b/source/blender/editors/space_view3d/view3d_snap.c
@@ -217,7 +217,7 @@ static void make_trans_verts(Object *obedit, float *min, float *max, int mode)
eed = BMIter_New(&iter, bm, BM_EDGES_OF_MESH, NULL);
for (; eed; eed=BMIter_Step(&iter)) {
- if(!BM_TestHFlag(eve, BM_HIDDEN) && BM_TestHFlag(eve, BM_SELECT))
+ if(!BM_TestHFlag(eed, BM_HIDDEN) && BM_TestHFlag(eed, BM_SELECT))
BMINDEX_SET(eed->v1, 0), BMINDEX_SET(eed->v2, 0);
}
eve = BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL);
@@ -233,7 +233,7 @@ static void make_trans_verts(Object *obedit, float *min, float *max, int mode)
efa = BMIter_New(&iter, bm, BM_FACES_OF_MESH, NULL);
for (; efa; efa=BMIter_Step(&iter)) {
- if(!BM_TestHFlag(eve, BM_HIDDEN) && BM_TestHFlag(eve, BM_SELECT)) {
+ if(!BM_TestHFlag(efa, BM_HIDDEN) && BM_TestHFlag(efa, BM_SELECT)) {
BMIter liter;
BMLoop *l;