Shift-G (select similar) is now bmeshafied for edge select mode.
The patch was by Wael El Oraiby. Commit of patch #19257.
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_editVert.h"
|
||||
|
||||
#include "BLI_arithb.h"
|
||||
#include "BLI_linklist.h"
|
||||
#include "BLI_memarena.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;
|
||||
|
||||
|
||||
@@ -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*));
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user