add the option to select Equal/Greater/Less when selecting similar.
Recently addons were submitted for review and this was the only advantage they had over blenders existing internal select-similar tool.
This commit is contained in:
parent
b5e8e8da6f
commit
330c0178ce
@ -822,10 +822,11 @@ static BMOpDefine bmo_spin_def = {
|
||||
*/
|
||||
static BMOpDefine bmo_similar_faces_def = {
|
||||
"similar_faces",
|
||||
{{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
|
||||
{BMO_OP_SLOT_ELEMENT_BUF, "faceout"}, /* output faces */
|
||||
{BMO_OP_SLOT_INT, "type"}, /* type of selection */
|
||||
{BMO_OP_SLOT_FLT, "thresh"}, /* threshold of selection */
|
||||
{{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
|
||||
{BMO_OP_SLOT_ELEMENT_BUF, "faceout"}, /* output faces */
|
||||
{BMO_OP_SLOT_INT, "type"}, /* type of selection */
|
||||
{BMO_OP_SLOT_FLT, "thresh"}, /* threshold of selection */
|
||||
{BMO_OP_SLOT_INT, "compare"}, /* comparison method */
|
||||
{0} /* null-terminating sentinel */},
|
||||
bmo_similar_faces_exec,
|
||||
0
|
||||
@ -838,10 +839,11 @@ static BMOpDefine bmo_similar_faces_def = {
|
||||
*/
|
||||
static BMOpDefine bmo_similar_edges_def = {
|
||||
"similar_edges",
|
||||
{{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edges */
|
||||
{BMO_OP_SLOT_ELEMENT_BUF, "edgeout"}, /* output edges */
|
||||
{BMO_OP_SLOT_INT, "type"}, /* type of selection */
|
||||
{BMO_OP_SLOT_FLT, "thresh"}, /* threshold of selection */
|
||||
{{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edges */
|
||||
{BMO_OP_SLOT_ELEMENT_BUF, "edgeout"}, /* output edges */
|
||||
{BMO_OP_SLOT_INT, "type"}, /* type of selection */
|
||||
{BMO_OP_SLOT_FLT, "thresh"}, /* threshold of selection */
|
||||
{BMO_OP_SLOT_INT, "compare"}, /* comparison method */
|
||||
{0} /* null-terminating sentinel */},
|
||||
bmo_similar_edges_exec,
|
||||
0
|
||||
@ -854,10 +856,11 @@ static BMOpDefine bmo_similar_edges_def = {
|
||||
*/
|
||||
static BMOpDefine bmo_similar_verts_def = {
|
||||
"similar_verts",
|
||||
{{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertices */
|
||||
{BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, /* output vertices */
|
||||
{BMO_OP_SLOT_INT, "type"}, /* type of selection */
|
||||
{BMO_OP_SLOT_FLT, "thresh"}, /* threshold of selection */
|
||||
{{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertices */
|
||||
{BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, /* output vertices */
|
||||
{BMO_OP_SLOT_INT, "type"}, /* type of selection */
|
||||
{BMO_OP_SLOT_FLT, "thresh"}, /* threshold of selection */
|
||||
{BMO_OP_SLOT_INT, "compare"}, /* comparison method */
|
||||
{0} /* null-terminating sentinel */},
|
||||
bmo_similar_verts_exec,
|
||||
0
|
||||
|
@ -46,6 +46,12 @@ enum {
|
||||
SUBDIV_SELECT_LOOPCUT
|
||||
};
|
||||
|
||||
enum {
|
||||
SIM_CMP_EQ = 0,
|
||||
SIM_CMP_GT,
|
||||
SIM_CMP_LT
|
||||
};
|
||||
|
||||
/* similar face selection slot values */
|
||||
enum {
|
||||
SIMFACE_MATERIAL = 201,
|
||||
|
@ -528,6 +528,34 @@ typedef struct SimSel_FaceExt {
|
||||
};
|
||||
} SimSel_FaceExt;
|
||||
|
||||
static int bm_sel_similar_cmp_fl(const float delta, const float thresh, const int compare)
|
||||
{
|
||||
switch (compare) {
|
||||
case SIM_CMP_EQ:
|
||||
return (fabsf(delta) <= thresh);
|
||||
case SIM_CMP_GT:
|
||||
return ((delta + thresh) >= 0.0f);
|
||||
case SIM_CMP_LT:
|
||||
return ((delta - thresh) <= 0.0f);
|
||||
default:
|
||||
BLI_assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
static int bm_sel_similar_cmp_i(const int delta, const int compare)
|
||||
{
|
||||
switch (compare) {
|
||||
case SIM_CMP_EQ:
|
||||
return (delta == 0);
|
||||
case SIM_CMP_GT:
|
||||
return (delta > 0);
|
||||
case SIM_CMP_LT:
|
||||
return (delta < 0);
|
||||
default:
|
||||
BLI_assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Select similar faces, the choices are in the enum in source/blender/bmesh/bmesh_operators.h
|
||||
* We select either similar faces based on material, image, area, perimeter, normal, or the coplanar faces
|
||||
@ -545,6 +573,11 @@ void bmo_similar_faces_exec(BMesh *bm, BMOperator *op)
|
||||
const int type = BMO_slot_int_get(op, "type");
|
||||
const float thresh = BMO_slot_float_get(op, "thresh");
|
||||
const float thresh_radians = thresh * (float)M_PI;
|
||||
const int compare = BMO_slot_int_get(op, "compare");
|
||||
|
||||
/* initial_elem - other_elem */
|
||||
float delta_fl;
|
||||
int delta_i;
|
||||
|
||||
num_total = BM_mesh_elem_count(bm, BM_FACE);
|
||||
|
||||
@ -648,7 +681,8 @@ void bmo_similar_faces_exec(BMesh *bm, BMOperator *op)
|
||||
case SIMFACE_COPLANAR:
|
||||
angle = angle_normalized_v3v3(fs->no, fm->no); /* angle -> 0 */
|
||||
if (angle <= thresh_radians) { /* and dot product difference -> 0 */
|
||||
if (fabsf(f_ext[i].d - f_ext[indices[idx]].d) <= thresh) {
|
||||
delta_fl = f_ext[i].d - f_ext[indices[idx]].d;
|
||||
if (bm_sel_similar_cmp_fl(delta_fl, thresh, compare)) {
|
||||
BMO_elem_flag_enable(bm, fm, FACE_MARK);
|
||||
cont = FALSE;
|
||||
}
|
||||
@ -656,25 +690,30 @@ void bmo_similar_faces_exec(BMesh *bm, BMOperator *op)
|
||||
break;
|
||||
|
||||
case SIMFACE_AREA:
|
||||
if (fabsf(f_ext[i].area - f_ext[indices[idx]].area) <= thresh) {
|
||||
delta_fl = f_ext[i].area - f_ext[indices[idx]].area;
|
||||
if (bm_sel_similar_cmp_fl(delta_fl, thresh, compare)) {
|
||||
BMO_elem_flag_enable(bm, fm, FACE_MARK);
|
||||
cont = FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case SIMFACE_SIDES:
|
||||
if (fm->len == fs->len) {
|
||||
delta_i = fm->len - fs->len;
|
||||
if (bm_sel_similar_cmp_i(delta_i, compare)) {
|
||||
BMO_elem_flag_enable(bm, fm, FACE_MARK);
|
||||
cont = FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case SIMFACE_PERIMETER:
|
||||
if (fabsf(f_ext[i].perim - f_ext[indices[idx]].perim) <= thresh) {
|
||||
delta_fl = f_ext[i].perim - f_ext[indices[idx]].perim;
|
||||
if (bm_sel_similar_cmp_fl(delta_fl, thresh, compare)) {
|
||||
BMO_elem_flag_enable(bm, fm, FACE_MARK);
|
||||
cont = FALSE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
BLI_assert(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -725,8 +764,13 @@ void bmo_similar_edges_exec(BMesh *bm, BMOperator *op)
|
||||
float angle;
|
||||
|
||||
int num_sels = 0, num_total = 0;
|
||||
int type = BMO_slot_int_get(op, "type");
|
||||
const int type = BMO_slot_int_get(op, "type");
|
||||
const float thresh = BMO_slot_float_get(op, "thresh");
|
||||
const int compare = BMO_slot_int_get(op, "compare");
|
||||
|
||||
/* initial_elem - other_elem */
|
||||
float delta_fl;
|
||||
int delta_i;
|
||||
|
||||
/* sanity checks that the data we need is available */
|
||||
switch (type) {
|
||||
@ -799,7 +843,8 @@ void bmo_similar_edges_exec(BMesh *bm, BMOperator *op)
|
||||
es = e_ext[indices[idx]].e;
|
||||
switch (type) {
|
||||
case SIMEDGE_LENGTH:
|
||||
if (fabsf(e_ext[i].length - e_ext[indices[idx]].length) <= thresh) {
|
||||
delta_fl = e_ext[i].length - e_ext[indices[idx]].length;
|
||||
if (bm_sel_similar_cmp_fl(delta_fl, thresh, compare)) {
|
||||
BMO_elem_flag_enable(bm, e, EDGE_MARK);
|
||||
cont = FALSE;
|
||||
}
|
||||
@ -819,7 +864,8 @@ void bmo_similar_edges_exec(BMesh *bm, BMOperator *op)
|
||||
break;
|
||||
|
||||
case SIMEDGE_FACE:
|
||||
if (e_ext[i].faces == e_ext[indices[idx]].faces) {
|
||||
delta_i = e_ext[i].faces - e_ext[indices[idx]].faces;
|
||||
if (bm_sel_similar_cmp_i(delta_i, compare)) {
|
||||
BMO_elem_flag_enable(bm, e, EDGE_MARK);
|
||||
cont = FALSE;
|
||||
}
|
||||
@ -845,8 +891,9 @@ void bmo_similar_edges_exec(BMesh *bm, BMOperator *op)
|
||||
|
||||
c1 = CustomData_bmesh_get(&bm->edata, e->head.data, CD_CREASE);
|
||||
c2 = CustomData_bmesh_get(&bm->edata, es->head.data, CD_CREASE);
|
||||
delta_fl = *c1 - *c2;
|
||||
|
||||
if (fabsf(*c1 - *c2) <= thresh) {
|
||||
if (bm_sel_similar_cmp_fl(delta_fl, thresh, compare)) {
|
||||
BMO_elem_flag_enable(bm, e, EDGE_MARK);
|
||||
cont = FALSE;
|
||||
}
|
||||
@ -859,8 +906,9 @@ void bmo_similar_edges_exec(BMesh *bm, BMOperator *op)
|
||||
|
||||
c1 = CustomData_bmesh_get(&bm->edata, e->head.data, CD_BWEIGHT);
|
||||
c2 = CustomData_bmesh_get(&bm->edata, es->head.data, CD_BWEIGHT);
|
||||
delta_fl = *c1 - *c2;
|
||||
|
||||
if (fabsf(*c1 - *c2) <= thresh) {
|
||||
if (bm_sel_similar_cmp_fl(delta_fl, thresh, compare)) {
|
||||
BMO_elem_flag_enable(bm, e, EDGE_MARK);
|
||||
cont = FALSE;
|
||||
}
|
||||
@ -880,6 +928,8 @@ void bmo_similar_edges_exec(BMesh *bm, BMOperator *op)
|
||||
cont = FALSE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
BLI_assert(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -919,9 +969,14 @@ void bmo_similar_verts_exec(BMesh *bm, BMOperator *op)
|
||||
SimSel_VertExt *v_ext = NULL;
|
||||
int *indices = NULL;
|
||||
int num_total = 0, num_sels = 0, i = 0, idx = 0;
|
||||
int type = BMO_slot_int_get(op, "type");
|
||||
const int type = BMO_slot_int_get(op, "type");
|
||||
const float thresh = BMO_slot_float_get(op, "thresh");
|
||||
const float thresh_radians = thresh * (float)M_PI;
|
||||
const int compare = BMO_slot_int_get(op, "compare");
|
||||
|
||||
/* initial_elem - other_elem */
|
||||
// float delta_fl;
|
||||
int delta_i;
|
||||
|
||||
num_total = BM_mesh_elem_count(bm, BM_VERT);
|
||||
|
||||
@ -982,7 +1037,8 @@ void bmo_similar_verts_exec(BMesh *bm, BMOperator *op)
|
||||
break;
|
||||
case SIMVERT_FACE:
|
||||
/* number of adjacent faces */
|
||||
if (v_ext[i].num_faces == v_ext[indices[idx]].num_faces) {
|
||||
delta_i = v_ext[i].num_faces - v_ext[indices[idx]].num_faces;
|
||||
if (bm_sel_similar_cmp_i(delta_i, compare)) {
|
||||
BMO_elem_flag_enable(bm, v, VERT_MARK);
|
||||
cont = FALSE;
|
||||
}
|
||||
@ -990,6 +1046,7 @@ void bmo_similar_verts_exec(BMesh *bm, BMOperator *op)
|
||||
|
||||
case SIMVERT_VGROUP:
|
||||
if (v_ext[i].dvert != NULL && v_ext[indices[idx]].dvert != NULL) {
|
||||
/* XXX, todo, make static function for this */
|
||||
int v1, v2;
|
||||
for (v1 = 0; v1 < v_ext[i].dvert->totweight && cont == 1; v1++) {
|
||||
for (v2 = 0; v2 < v_ext[indices[idx]].dvert->totweight; v2++) {
|
||||
@ -1004,11 +1061,14 @@ void bmo_similar_verts_exec(BMesh *bm, BMOperator *op)
|
||||
break;
|
||||
case SIMVERT_EDGE:
|
||||
/* number of adjacent edges */
|
||||
if (v_ext[i].num_edges == v_ext[indices[idx]].num_edges) {
|
||||
delta_i = v_ext[i].num_edges - v_ext[indices[idx]].num_edges;
|
||||
if (bm_sel_similar_cmp_i(delta_i, compare)) {
|
||||
BMO_elem_flag_enable(bm, v, VERT_MARK);
|
||||
cont = FALSE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
BLI_assert(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1249,7 +1309,7 @@ void bmo_shortest_path_exec(BMesh *bm, BMOperator *op)
|
||||
ElemNode *vert_list = NULL;
|
||||
|
||||
int num_total = 0 /*, num_sels = 0 */, i = 0;
|
||||
int type = BMO_slot_int_get(op, "type");
|
||||
const int type = BMO_slot_int_get(op, "type");
|
||||
|
||||
BMO_ITER (vs, &vs_iter, bm, op, "startv", BM_VERT) {
|
||||
sv = vs;
|
||||
|
@ -671,6 +671,11 @@ static int unified_findnearest(ViewContext *vc, BMVert **r_eve, BMEdge **r_eed,
|
||||
}
|
||||
|
||||
/* **************** SIMILAR "group" SELECTS. FACE, EDGE AND VERTEX ************** */
|
||||
static EnumPropertyItem prop_similar_compare_types[] = {
|
||||
{SIM_CMP_EQ, "EQUAL", 0, "Equal", ""},
|
||||
{SIM_CMP_GT, "GREATER", 0, "Greater", ""},
|
||||
{SIM_CMP_LT, "LESS", 0, "Less", ""}
|
||||
};
|
||||
|
||||
static EnumPropertyItem prop_similar_types[] = {
|
||||
{SIMVERT_NORMAL, "NORMAL", 0, "Normal", ""},
|
||||
@ -707,11 +712,14 @@ static int similar_face_select_exec(bContext *C, wmOperator *op)
|
||||
BMOperator bmop;
|
||||
|
||||
/* get the type from RNA */
|
||||
int type = RNA_enum_get(op->ptr, "type");
|
||||
float thresh = RNA_float_get(op->ptr, "threshold");
|
||||
const int type = RNA_enum_get(op->ptr, "type");
|
||||
const float thresh = RNA_float_get(op->ptr, "threshold");
|
||||
const int compare = RNA_enum_get(op->ptr, "compare");
|
||||
|
||||
/* initialize the bmop using EDBM api, which does various ui error reporting and other stuff */
|
||||
EDBM_op_init(em, &bmop, op, "similar_faces faces=%hf type=%i thresh=%f", BM_ELEM_SELECT, type, thresh);
|
||||
EDBM_op_init(em, &bmop, op,
|
||||
"similar_faces faces=%hf type=%i thresh=%f compare=%i",
|
||||
BM_ELEM_SELECT, type, thresh, compare);
|
||||
|
||||
/* execute the operator */
|
||||
BMO_op_exec(em->bm, &bmop);
|
||||
@ -745,11 +753,14 @@ static int similar_edge_select_exec(bContext *C, wmOperator *op)
|
||||
BMOperator bmop;
|
||||
|
||||
/* get the type from RNA */
|
||||
int type = RNA_enum_get(op->ptr, "type");
|
||||
float thresh = RNA_float_get(op->ptr, "threshold");
|
||||
const int type = RNA_enum_get(op->ptr, "type");
|
||||
const float thresh = RNA_float_get(op->ptr, "threshold");
|
||||
const int compare = RNA_enum_get(op->ptr, "compare");
|
||||
|
||||
/* initialize the bmop using EDBM api, which does various ui error reporting and other stuff */
|
||||
EDBM_op_init(em, &bmop, op, "similar_edges edges=%he type=%i thresh=%f", BM_ELEM_SELECT, type, thresh);
|
||||
EDBM_op_init(em, &bmop, op,
|
||||
"similar_edges edges=%he type=%i thresh=%f compare=%i",
|
||||
BM_ELEM_SELECT, type, thresh, compare);
|
||||
|
||||
/* execute the operator */
|
||||
BMO_op_exec(em->bm, &bmop);
|
||||
@ -786,11 +797,14 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op)
|
||||
BMEditMesh *em = BMEdit_FromObject(ob);
|
||||
BMOperator bmop;
|
||||
/* get the type from RNA */
|
||||
int type = RNA_enum_get(op->ptr, "type");
|
||||
const int type = RNA_enum_get(op->ptr, "type");
|
||||
float thresh = RNA_float_get(op->ptr, "threshold");
|
||||
const int compare = RNA_enum_get(op->ptr, "compare");
|
||||
|
||||
/* initialize the bmop using EDBM api, which does various ui error reporting and other stuff */
|
||||
EDBM_op_init(em, &bmop, op, "similar_verts verts=%hv type=%i thresh=%f", BM_ELEM_SELECT, type, thresh);
|
||||
EDBM_op_init(em, &bmop, op,
|
||||
"similar_verts verts=%hv type=%i thresh=%f compare=%i",
|
||||
BM_ELEM_SELECT, type, thresh, compare);
|
||||
|
||||
/* execute the operator */
|
||||
BMO_op_exec(em->bm, &bmop);
|
||||
@ -819,7 +833,7 @@ static int edbm_select_similar_exec(bContext *C, wmOperator *op)
|
||||
ToolSettings *ts = CTX_data_tool_settings(C);
|
||||
PropertyRNA *prop = RNA_struct_find_property(op->ptr, "threshold");
|
||||
|
||||
int type = RNA_enum_get(op->ptr, "type");
|
||||
const int type = RNA_enum_get(op->ptr, "type");
|
||||
|
||||
if (!RNA_property_is_set(op->ptr, prop)) {
|
||||
RNA_property_float_set(op->ptr, prop, ts->select_thresh);
|
||||
@ -830,7 +844,7 @@ static int edbm_select_similar_exec(bContext *C, wmOperator *op)
|
||||
|
||||
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);
|
||||
else return similar_face_select_exec(C, op);
|
||||
}
|
||||
|
||||
static EnumPropertyItem *select_similar_type_itemf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop),
|
||||
@ -894,7 +908,9 @@ void MESH_OT_select_similar(wmOperatorType *ot)
|
||||
prop = ot->prop = RNA_def_enum(ot->srna, "type", prop_similar_types, SIMVERT_NORMAL, "Type", "");
|
||||
RNA_def_enum_funcs(prop, select_similar_type_itemf);
|
||||
|
||||
RNA_def_float(ot->srna, "threshold", 0.0, 0.0, 1.0, "Threshold", "", 0.01, 1.0);
|
||||
RNA_def_enum(ot->srna, "compare", prop_similar_compare_types, SIM_CMP_EQ, "Compare", "");
|
||||
|
||||
RNA_def_float(ot->srna, "threshold", 0.0, 0.0, 1.0, "Threshold", "", 0.0, 1.0);
|
||||
}
|
||||
|
||||
/* ***************************************************** */
|
||||
|
Loading…
Reference in New Issue
Block a user