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-28 13:36:31 +0400
committerJoseph Eagar <joeedh@gmail.com>2009-08-28 13:36:31 +0400
commit989dde470736d51e50ef8eb3dea508624cb68e88 (patch)
treeed604a9f548fde134de79c045804f0440754e936
parent6dd345a323c9a563533538c1cb6caa4b01077666 (diff)
Shift-G (select similar) is now bmeshafied for edge select mode.
The patch was by Wael El Oraiby. Commit of patch #19257.
-rw-r--r--source/blender/blenkernel/BKE_DerivedMesh.h3
-rw-r--r--source/blender/blenkernel/intern/cdderivedmesh.c148
-rw-r--r--source/blender/blenkernel/intern/subsurf_ccg.c1
-rw-r--r--source/blender/bmesh/bmesh_operators.h12
-rw-r--r--source/blender/bmesh/intern/bmesh_opdefines.c17
-rw-r--r--source/blender/bmesh/intern/bmesh_operators_private.h2
-rw-r--r--source/blender/bmesh/operators/utils.c213
-rw-r--r--source/blender/editors/mesh/bmesh_select.c42
8 files changed, 406 insertions, 32 deletions
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h
index ba831cdf015..c35900ef2be 100644
--- a/source/blender/blenkernel/BKE_DerivedMesh.h
+++ b/source/blender/blenkernel/BKE_DerivedMesh.h
@@ -107,7 +107,8 @@ struct BMEditMesh;
#define SUB_ELEMS_FACE 50
/*
-note: all mface interfaces now officially operate on tesselated data.
+Note: all mface interfaces now officially operate on tesselated data.
+ Also, the mface origindex layer indexes mpolys, not mfaces.
*/
/*DM Iterators. For now, first implement face iterators.
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index ff5bf2d5bae..b284bb80184 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -46,6 +46,8 @@
#include "BKE_utildefines.h"
#include "BKE_tessmesh.h"
+#include "BLI_editVert.h"
+#include "BLI_scanfill.h"
#include "BLI_arithb.h"
#include "BLI_blenlib.h"
#include "BLI_edgehash.h"
@@ -482,7 +484,7 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm,
}
}
-static void cdDM_drawFacesTex(DerivedMesh *dm, int (*setDrawOptions)(MTFace *tface, MCol *mcol, int matnr))
+static void cdDM_drawFacesTex(DerivedMesh *dm, int (*setDrawOptions)(MTFace *tface, int has_vcol, int matnr))
{
cdDM_drawFacesTex_common(dm, setDrawOptions, NULL, NULL);
}
@@ -781,9 +783,6 @@ static void cdDM_foreachMappedFaceCenter(
MVert *mv = cddm->mvert;
MPoly *mf = cddm->mpoly;
MLoop *ml = cddm->mloop;
- float (*cents)[3];
- float (*nors)[3];
- int *flens;
int i, j, orig, *index;
int maxf=0;
@@ -820,6 +819,132 @@ static void cdDM_foreachMappedFaceCenter(
}
+void cddm_loops_to_corners(CustomData *fdata, CustomData *ldata,
+ CustomData *pdata, int lindex[3], int findex,
+ int polyindex, int numTex, int numCol)
+{
+ MTFace *texface;
+ MTexPoly *texpoly;
+ MCol *mcol;
+ MLoopCol *mloopcol;
+ MLoopUV *mloopuv;
+ int i, j;
+
+ for(i=0; i < numTex; i++){
+ texface = CustomData_get_n(fdata, CD_MTFACE, findex, i);
+ texpoly = CustomData_get_n(pdata, CD_MTEXPOLY, polyindex, i);
+
+ texface->tpage = texpoly->tpage;
+ texface->flag = texpoly->flag;
+ texface->transp = texpoly->transp;
+ texface->mode = texpoly->mode;
+ texface->tile = texpoly->tile;
+ texface->unwrap = texpoly->unwrap;
+
+ for (j=0; j<3; j++) {
+ mloopuv = CustomData_get_n(ldata, CD_MLOOPUV, lindex[j], i);
+ texface->uv[j][0] = mloopuv->uv[0];
+ texface->uv[j][1] = mloopuv->uv[1];
+ }
+ }
+
+ for(i=0; i < numCol; i++){
+ mcol = CustomData_get_n(fdata, CD_MCOL, findex, i);
+
+ for (j=0; j<3; j++) {
+ mloopcol = CustomData_get_n(ldata, CD_MLOOPCOL, lindex[j], i);
+ mcol[j].r = mloopcol->r;
+ mcol[j].g = mloopcol->g;
+ mcol[j].b = mloopcol->b;
+ mcol[j].a = mloopcol->a;
+ }
+ }
+}
+
+static void cdDM_recalcTesselation(DerivedMesh *dm)
+{
+ CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
+ MPoly *mp;
+ MLoop *ml;
+ MFace *mf = NULL;
+ V_DECLARE(mf);
+ EditVert *v, *lastv, *firstv;
+ EditFace *f;
+ V_DECLARE(origIndex);
+ int i, j, k, lindex[3], *origIndex = NULL, *polyorigIndex;
+ int numTex, numCol;
+
+ numTex = CustomData_number_of_layers(&dm->loopData, CD_MLOOPUV);
+ numCol = CustomData_number_of_layers(&dm->loopData, CD_MLOOPCOL);
+
+ k = 0;
+ mp = cddm->mpoly;
+ polyorigIndex = CustomData_get_layer(&dm->polyData, CD_ORIGINDEX);
+ for (i=0; i<dm->numPolyData; i++, mp++) {
+ ml = cddm->mloop + mp->loopstart;
+ firstv = NULL;
+ lastv = NULL;
+ for (j=0; j<mp->totloop; j++, ml++) {
+ v = BLI_addfillvert(cddm->mvert[ml->v].co);
+ if (polyorigIndex)
+ v->f1 = polyorigIndex[i];
+ else
+ v->f1 = i;
+
+ v->f2 = mp->loopstart + j;
+
+ if (lastv)
+ BLI_addfilledge(lastv, v);
+
+ if (!firstv)
+ firstv = v;
+ lastv = v;
+ }
+ BLI_addfilledge(firstv, v);
+
+ BLI_edgefill(0, 0);
+ for (f=fillfacebase.first; f; f=f->next) {
+ V_GROW(mf);
+ V_GROW(origIndex);
+
+ /*these are loop indices, they'll be transformed
+ into vert indices later.*/
+ mf[k].v1 = f->v1->f2;
+ mf[k].v2 = f->v2->f2;
+ mf[k].v3 = f->v3->f2;
+ origIndex[k] = f->v1->f1;
+
+ k++;
+ }
+
+ BLI_end_edgefill();
+ }
+
+ memset(&dm->faceData, 0, sizeof(CustomData));
+ dm->numFaceData = k;
+
+ CustomData_add_layer(&dm->faceData, CD_MFACE, CD_ASSIGN, mf, dm->numFaceData);
+ CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_ASSIGN, origIndex, dm->numFaceData);
+ CustomData_from_bmeshpoly(&dm->faceData, &dm->polyData, &dm->loopData, dm->numFaceData);
+
+ /*set convienence pointer*/
+ cddm->mface = mf;
+
+ for (i=0; i<dm->numFaceData; i++, mf++) {
+ lindex[0] = mf->v1;
+ lindex[1] = mf->v2;
+ lindex[2] = mf->v3;
+
+ /*transform loop indices to vert indices*/
+ mf->v1 = cddm->mloop[mf->v1].v;
+ mf->v2 = cddm->mloop[mf->v2].v;
+ mf->v3 = cddm->mloop[mf->v3].v;
+
+ cddm_loops_to_corners(&dm->faceData, &dm->loopData, &dm->polyData,
+ lindex, i, origIndex[i], numTex, numCol);
+ }
+}
+
static void cdDM_release(DerivedMesh *dm)
{
CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
@@ -858,6 +983,9 @@ static CDDerivedMesh *cdDM_create(const char *desc)
dm->getVertDataArray = DM_get_vert_data_layer;
dm->getEdgeDataArray = DM_get_edge_data_layer;
dm->getTessFaceDataArray = DM_get_tessface_data_layer;
+
+ //doesn't work yet for all cases
+ //dm->recalcTesselation = cdDM_recalcTesselation;
dm->getVertCos = cdDM_getVertCos;
dm->getVertCo = cdDM_getVertCo;
@@ -929,7 +1057,6 @@ DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *ob)
CustomData_add_layer(&dm->vertData, CD_ORIGINDEX, CD_CALLOC, NULL, mesh->totvert);
CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, mesh->totedge);
- CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_CALLOC, NULL, mesh->totface);
CustomData_add_layer(&dm->polyData, CD_ORIGINDEX, CD_CALLOC, NULL, mesh->totpoly);
dm->deformedOnly = 1;
@@ -940,8 +1067,6 @@ DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *ob)
mesh->totvert);
CustomData_merge(&mesh->edata, &dm->edgeData, mask, alloctype,
mesh->totedge);
- CustomData_merge(&mesh->fdata, &dm->faceData, mask, alloctype,
- mesh->totface);
CustomData_merge(&mesh->ldata, &dm->loopData, mask, alloctype,
mesh->totloop);
CustomData_merge(&mesh->pdata, &dm->polyData, mask, alloctype,
@@ -949,7 +1074,6 @@ DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *ob)
cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
- cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP);
cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
@@ -961,14 +1085,14 @@ DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *ob)
for(i = 0; i < mesh->totedge; ++i, ++index)
*index = i;
- index = CustomData_get_layer(&dm->faceData, CD_ORIGINDEX);
- for(i = 0; i < mesh->totface; ++i, ++index)
- *index = i;
-
index = CustomData_get_layer(&dm->polyData, CD_ORIGINDEX);
for(i = 0; i < mesh->totpoly; ++i, ++index)
*index = i;
+ /*recalculates mfaces and sets the mface origindex layer
+ to index mypolys.*/
+ cdDM_recalcTesselation((DerivedMesh*)cddm);
+
return dm;
}
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index f5133759a4d..628d55d8439 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -55,6 +55,7 @@
#include "BLI_blenlib.h"
#include "BLI_editVert.h"
+
#include "BLI_arithb.h"
#include "BLI_linklist.h"
#include "BLI_memarena.h"
diff --git a/source/blender/bmesh/bmesh_operators.h b/source/blender/bmesh/bmesh_operators.h
index 5879765de0b..f5be0f3be91 100644
--- a/source/blender/bmesh/bmesh_operators.h
+++ b/source/blender/bmesh/bmesh_operators.h
@@ -22,6 +22,7 @@ enum {
SUBD_STRAIGHT_CUT,
};
+/* similar face selection slot values */
enum {
SIMFACE_MATERIAL = 201,
SIMFACE_IMAGE,
@@ -31,6 +32,17 @@ enum {
SIMFACE_COPLANAR,
};
+/* similar edge selection slot values */
+enum {
+ SIMEDGE_LENGTH = 101,
+ SIMEDGE_DIR,
+ SIMEDGE_FACE,
+ SIMEDGE_FACE_ANGLE,
+ SIMEDGE_CREASE,
+ SIMEDGE_SEAM,
+ SIMEDGE_SHARP,
+};
+
extern BMOpDefine *opdefines[];
extern int bmesh_total_ops;
diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c
index e5e7da115c4..acde51dd2eb 100644
--- a/source/blender/bmesh/intern/bmesh_opdefines.c
+++ b/source/blender/bmesh/intern/bmesh_opdefines.c
@@ -629,6 +629,22 @@ BMOpDefine def_similarfaces = {
0
};
+/*
+ Similar edges select
+
+ Select similar edges (length, direction, edge, seam,....).
+*/
+BMOpDefine def_similaredges = {
+ "similaredges",
+ {{BMOP_OPSLOT_ELEMENT_BUF, "edges"}, /* input edges */
+ {BMOP_OPSLOT_ELEMENT_BUF, "edgeout"}, /* output edges */
+ {BMOP_OPSLOT_INT, "type"}, /* type of selection */
+ {BMOP_OPSLOT_FLT, "thresh"}, /* threshold of selection */
+ {0} /*null-terminating sentinel*/},
+ bmesh_similaredges_exec,
+ 0
+};
+
BMOpDefine *opdefines[] = {
&def_splitop,
&def_dupeop,
@@ -670,6 +686,7 @@ BMOpDefine *opdefines[] = {
&def_pointmerge,
&def_collapse,
&def_similarfaces,
+ &def_similaredges,
};
int bmesh_total_ops = (sizeof(opdefines) / sizeof(void*));
diff --git a/source/blender/bmesh/intern/bmesh_operators_private.h b/source/blender/bmesh/intern/bmesh_operators_private.h
index 6cb8b2f9cf5..31d20bef8ee 100644
--- a/source/blender/bmesh/intern/bmesh_operators_private.h
+++ b/source/blender/bmesh/intern/bmesh_operators_private.h
@@ -47,5 +47,5 @@ void bmesh_collapsecon_exec(BMesh *bm, BMOperator *op);
void bmesh_pointmerge_exec(BMesh *bm, BMOperator *op);
void bmesh_collapse_exec(BMesh *bm, BMOperator *op);
void bmesh_similarfaces_exec(BMesh *bm, BMOperator *op);
-
+void bmesh_similaredges_exec(BMesh *bm, BMOperator *op);
#endif
diff --git a/source/blender/bmesh/operators/utils.c b/source/blender/bmesh/operators/utils.c
index a5446112c66..4fc4e7dcf56 100644
--- a/source/blender/bmesh/operators/utils.c
+++ b/source/blender/bmesh/operators/utils.c
@@ -501,7 +501,7 @@ void bmesh_similarfaces_exec(BMesh *bm, BMOperator *op)
BMIter fm_iter;
BMFace *fs, *fm;
BMOIter fs_iter;
- int num_tex, num_sels = 0, num_total = 0, i = 0, idx = 0;
+ int num_sels = 0, num_total = 0, i = 0, idx = 0;
float angle = 0.0f;
tmp_face_ext *f_ext = NULL;
int *indices = NULL;
@@ -526,8 +526,8 @@ void bmesh_similarfaces_exec(BMesh *bm, BMOperator *op)
}
/* allocate memory for the selected faces indices and for all temporary faces */
- indices = (int*)malloc(sizeof(int) * num_sels);
- f_ext = (tmp_face_ext*)malloc(sizeof(tmp_face_ext) * num_total);
+ indices = (int*)MEM_callocN(sizeof(int) * num_sels, "face indices util.c");
+ f_ext = (tmp_face_ext*)MEM_callocN(sizeof(tmp_face_ext) * num_total, "f_ext util.c");
/* loop through all the faces and fill the faces/indices structure */
BM_ITER(fm, &fm_iter, bm, BM_FACES_OF_MESH, NULL) {
@@ -543,7 +543,7 @@ void bmesh_similarfaces_exec(BMesh *bm, BMOperator *op)
** Save us some computation burden: In case of perimeter/area/coplanar selection we compute
** only once.
*/
- if( type == SIMFACE_PERIMETER || type == SIMFACE_AREA || type == SIMFACE_COPLANAR || type == SIMFACE_IMAGE ) {
+ if( type == SIMFACE_PERIMETER || type == SIMFACE_AREA || type == SIMFACE_COPLANAR || type == SIMFACE_IMAGE ) {
for( i = 0; i < num_total; i++ ) {
switch( type ) {
case SIMFACE_PERIMETER:
@@ -579,11 +579,9 @@ void bmesh_similarfaces_exec(BMesh *bm, BMOperator *op)
}
/* now select the rest (if any) */
- //BM_ITER(fm, &fm_iter, bm, BM_FACES_OF_MESH, NULL) {
for( i = 0; i < num_total; i++ ) {
fm = f_ext[i].f;
- if (!BMO_TestFlag(bm, fm, FACE_MARK)) {
- //BMO_ITER(fs, &fs_iter, bm, op, "faces", BM_FACE) {
+ if( !BMO_TestFlag(bm, fm, FACE_MARK) && !BM_TestHFlag(fm, BM_HIDDEN) ) {
int cont = 1;
for( idx = 0; idx < num_sels && cont == 1; idx++ ) {
fs = f_ext[indices[idx]].f;
@@ -638,9 +636,206 @@ void bmesh_similarfaces_exec(BMesh *bm, BMOperator *op)
}
}
- free(f_ext);
- free(indices);
+ MEM_freeN(f_ext);
+ MEM_freeN(indices);
/* transfer all marked faces to the output slot */
BMO_Flag_To_Slot(bm, op, "faceout", FACE_MARK, BM_FACE);
}
+
+/******************************************************************************
+** Similar Edges
+******************************************************************************/
+#define EDGE_MARK 1
+
+/*
+** compute the angle of an edge (i.e. the angle between two faces)
+*/
+static float edge_angle(BMesh *bm, BMEdge *e)
+{
+ BMIter fiter;
+ BMFace *f;
+ int num_faces = 0;
+ float n1[3], n2[3];
+ float angle = 0.0f;
+
+ BM_ITER(f, &fiter, bm, BM_FACES_OF_EDGE, e) {
+ if( num_faces == 0 ) {
+ n1[0] = f->no[0];
+ n1[1] = f->no[1];
+ n1[2] = f->no[2];
+ num_faces++;
+ } else {
+ n2[0] = f->no[0];
+ n2[1] = f->no[1];
+ n2[2] = f->no[2];
+ num_faces++;
+ }
+ }
+
+ angle = VecAngle2(n1, n2) / 180.0;
+
+ return angle;
+}
+/*
+** extra edge information
+*/
+typedef struct tmp_edge_ext {
+ BMEdge *e;
+ union {
+ float dir[3];
+ float angle; /* angle between the faces*/
+ };
+
+ union {
+ float length; /* edge length */
+ int faces; /* faces count */
+ };
+} tmp_edge_ext;
+
+/*
+** select similar edges: the choices are in the enum in source/blender/bmesh/bmesh_operators.h
+** choices are length, direction, face, ...
+*/
+void bmesh_similaredges_exec(BMesh *bm, BMOperator *op)
+{
+ BMOIter es_iter; /* selected edges iterator */
+ BMIter e_iter; /* mesh edges iterator */
+ BMEdge *es; /* selected edge */
+ BMEdge *e; /* mesh edge */
+ int idx = 0, i = 0, f = 0;
+ int *indices = NULL;
+ tmp_edge_ext *e_ext = NULL;
+ float *angles = NULL;
+ float angle;
+
+ int num_sels = 0, num_total = 0;
+ int type = BMO_Get_Int(op, "type");
+ float thresh = BMO_Get_Float(op, "thresh");
+
+ num_total = BM_Count_Element(bm, BM_EDGE);
+
+ /* iterate through all selected edges and mark them */
+ BMO_ITER(es, &es_iter, bm, op, "edges", BM_EDGE) {
+ BMO_SetFlag(bm, es, EDGE_MARK);
+ num_sels++;
+ }
+
+ /* allocate memory for the selected edges indices and for all temporary edges */
+ indices = (int*)MEM_callocN(sizeof(int) * num_sels, "indices util.c");
+ e_ext = (tmp_edge_ext*)MEM_callocN(sizeof(tmp_edge_ext) * num_total, "e_ext util.c");
+
+ /* loop through all the edges and fill the edges/indices structure */
+ BM_ITER(e, &e_iter, bm, BM_EDGES_OF_MESH, NULL) {
+ e_ext[i].e = e;
+ if (BMO_TestFlag(bm, e, EDGE_MARK)) {
+ indices[idx] = i;
+ idx++;
+ }
+ i++;
+ }
+
+ /* save us some computation time by doing heavy computation once */
+ if( type == SIMEDGE_LENGTH || type == SIMEDGE_FACE || type == SIMEDGE_DIR ||
+ type == SIMEDGE_FACE_ANGLE ) {
+ for( i = 0; i < num_total; i++ ) {
+ switch( type ) {
+ case SIMEDGE_LENGTH: /* compute the length of the edge */
+ e_ext[i].length = VecLenf(e_ext[i].e->v1->co, e_ext[i].e->v2->co);
+ break;
+
+ case SIMEDGE_DIR: /* compute the direction */
+ VecSubf(e_ext[i].dir, e_ext[i].e->v1->co, e_ext[i].e->v2->co);
+ break;
+
+ case SIMEDGE_FACE: /* count the faces around the edge */
+ e_ext[i].faces = BM_Edge_FaceCount(e_ext[i].e);
+ break;
+
+ case SIMEDGE_FACE_ANGLE:
+ e_ext[i].faces = BM_Edge_FaceCount(e_ext[i].e);
+ if( e_ext[i].faces == 2 )
+ e_ext[i].angle = edge_angle(bm, e_ext[i].e);
+ break;
+ }
+ }
+ }
+
+ /* select the edges if any */
+ for( i = 0; i < num_total; i++ ) {
+ e = e_ext[i].e;
+ if( !BMO_TestFlag(bm, e, EDGE_MARK) && !BM_TestHFlag(e, BM_HIDDEN) ) {
+ int cont = 1;
+ for( idx = 0; idx < num_sels && cont == 1; idx++ ) {
+ es = e_ext[indices[idx]].e;
+ switch( type ) {
+ case SIMEDGE_LENGTH:
+ if( fabs(e_ext[i].length - e_ext[indices[idx]].length) <= thresh ) {
+ BMO_SetFlag(bm, e, EDGE_MARK);
+ cont = 0;
+ }
+ break;
+
+ case SIMEDGE_DIR:
+ /* compute the angle between the two edges */
+ angle = VecAngle2(e_ext[i].dir, e_ext[indices[idx]].dir);
+
+ if( angle > 90.0 ) /* use the smallest angle between the edges */
+ angle = fabs(angle - 180.0f);
+
+ if( angle / 90.0 <= thresh ) {
+ BMO_SetFlag(bm, e, EDGE_MARK);
+ cont = 0;
+ }
+ break;
+
+ case SIMEDGE_FACE:
+ if( e_ext[i].faces == e_ext[indices[idx]].faces ) {
+ BMO_SetFlag(bm, e, EDGE_MARK);
+ cont = 0;
+ }
+ break;
+
+ case SIMEDGE_FACE_ANGLE:
+ if( e_ext[i].faces == 2 ) {
+ if( e_ext[indices[idx]].faces == 2 ) {
+ if( fabs(e_ext[i].angle - e_ext[indices[idx]].angle) <= thresh ) {
+ BMO_SetFlag(bm, e, EDGE_MARK);
+ cont = 0;
+ }
+ }
+ } else cont = 0;
+ break;
+
+ case SIMEDGE_CREASE:
+ if( fabs(e->crease - es->crease) <= thresh ) {
+ BMO_SetFlag(bm, e, EDGE_MARK);
+ cont = 0;
+ }
+ break;
+
+ case SIMEDGE_SEAM:
+ if( BM_TestHFlag(e, BM_SEAM) == BM_TestHFlag(es, BM_SEAM) ) {
+ BMO_SetFlag(bm, e, EDGE_MARK);
+ cont = 0;
+ }
+ break;
+
+ case SIMEDGE_SHARP:
+ if( BM_TestHFlag(e, BM_SHARP) == BM_TestHFlag(es, BM_SHARP) ) {
+ BMO_SetFlag(bm, e, EDGE_MARK);
+ cont = 0;
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ MEM_freeN(e_ext);
+ MEM_freeN(indices);
+
+ /* transfer all marked edges to the output slot */
+ BMO_Flag_To_Slot(bm, op, "edgeout", EDGE_MARK, BM_EDGE);
+}
+
diff --git a/source/blender/editors/mesh/bmesh_select.c b/source/blender/editors/mesh/bmesh_select.c
index 8eeb209ad63..8060036aea8 100644
--- a/source/blender/editors/mesh/bmesh_select.c
+++ b/source/blender/editors/mesh/bmesh_select.c
@@ -699,18 +699,10 @@ static int similar_face_select_exec(bContext *C, wmOperator *op)
/* 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, "FACE", 0, "Amount of Faces Around an Edge", ""},
{SIMEDGE_FACE_ANGLE, "FACE_ANGLE", 0, "Face Angles", ""},
{SIMEDGE_CREASE, "CREASE", 0, "Crease", ""},
{SIMEDGE_SEAM, "SEAM", 0, "Seam", ""},
@@ -920,6 +912,38 @@ static int similar_edge_select__internal(Scene *scene, EditMesh *em, int mode)
/* 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 *ob = CTX_data_edit_object(C);
+ BMEditMesh *em = ((Mesh*)ob->data)->edit_btmesh;
+ BMOperator bmop;
+
+ /* get the type from RNA */
+ int type = RNA_enum_get(op->ptr, "type");
+
+ float thresh = scene->toolsettings->select_thresh;
+
+ /* initialize the bmop using EDBM api, which does various ui error reporting and other stuff */
+ EDBM_InitOpf(em, &bmop, op, "similaredges edges=%he type=%d thresh=%f", BM_SELECT, type, thresh);
+
+ /* execute the operator */
+ BMO_Exec_Op(em->bm, &bmop);
+
+ /* clear the existing selection */
+ EDBM_clear_flag_all(em, BM_SELECT);
+
+ /* select the output */
+ BMO_HeaderFlag_Buffer(em->bm, &bmop, "edgeout", BM_SELECT, BM_ALL);
+
+ /* finish the operator */
+ if( !EDBM_FinishOp(em, &bmop, op, 1) )
+ return OPERATOR_CANCELLED;
+
+ /* dependencies graph and notification stuff */
+ DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_OBJECT | ND_GEOM_SELECT, ob);
+
+ /* we succeeded */
+ return OPERATOR_FINISHED;
#if 0
Scene *scene= CTX_data_scene(C);
Object *obedit= CTX_data_edit_object(C);