From 989dde470736d51e50ef8eb3dea508624cb68e88 Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Fri, 28 Aug 2009 09:36:31 +0000 Subject: Shift-G (select similar) is now bmeshafied for edge select mode. The patch was by Wael El Oraiby. Commit of patch #19257. --- source/blender/blenkernel/BKE_DerivedMesh.h | 3 +- source/blender/blenkernel/intern/cdderivedmesh.c | 148 ++++++++++++-- source/blender/blenkernel/intern/subsurf_ccg.c | 1 + source/blender/bmesh/bmesh_operators.h | 12 ++ source/blender/bmesh/intern/bmesh_opdefines.c | 17 ++ .../blender/bmesh/intern/bmesh_operators_private.h | 2 +- source/blender/bmesh/operators/utils.c | 213 ++++++++++++++++++++- source/blender/editors/mesh/bmesh_select.c | 42 +++- 8 files changed, 406 insertions(+), 32 deletions(-) (limited to 'source/blender') 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; inumPolyData; i++, mp++) { + ml = cddm->mloop + mp->loopstart; + firstv = NULL; + lastv = NULL; + for (j=0; jtotloop; 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; inumFaceData; 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); -- cgit v1.2.3