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:
Diffstat (limited to 'source/blender/editors/mesh/editmesh_select.c')
-rw-r--r--source/blender/editors/mesh/editmesh_select.c521
1 files changed, 352 insertions, 169 deletions
diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c
index a6de1b284b7..019aa6d4201 100644
--- a/source/blender/editors/mesh/editmesh_select.c
+++ b/source/blender/editors/mesh/editmesh_select.c
@@ -73,7 +73,9 @@
/* use bmesh operator flags for a few operators */
#define BMO_ELE_TAG 1
-/* ****************************** MIRROR **************** */
+/* -------------------------------------------------------------------- */
+/** \name Select Mirror
+ * \{ */
void EDBM_select_mirrored(
BMEditMesh *em, const int axis, const bool extend,
@@ -166,21 +168,34 @@ void EDBM_select_mirrored(
*r_totfail = totfail;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Select Auto-Merge
+ *
+ * Used after transform operations.
+ * \{ */
+
void EDBM_automerge(Scene *scene, Object *obedit, bool update, const char hflag)
{
bool ok;
BMEditMesh *em = BKE_editmesh_from_object(obedit);
- ok = BMO_op_callf(em->bm, BMO_FLAG_DEFAULTS,
- "automerge verts=%hv dist=%f",
- hflag, scene->toolsettings->doublimit);
+ ok = BMO_op_callf(
+ em->bm, BMO_FLAG_DEFAULTS,
+ "automerge verts=%hv dist=%f",
+ hflag, scene->toolsettings->doublimit);
if (LIKELY(ok) && update) {
EDBM_update_generic(em, true, true);
}
}
-/* ****************************** SELECTION ROUTINES **************** */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Back-Buffer OpenGL Selection
+ * \{ */
unsigned int bm_solidoffs = 0, bm_wireoffs = 0, bm_vertoffs = 0; /* set in drawobject.c ... for colorindices */
@@ -199,21 +214,21 @@ bool EDBM_backbuf_border_init(ViewContext *vc, short xmin, short ymin, short xma
struct ImBuf *buf;
unsigned int *dr;
int a;
-
+
if (vc->obedit == NULL || !V3D_IS_ZBUF(vc->v3d)) {
return false;
}
-
+
buf = ED_view3d_backbuf_read(vc, xmin, ymin, xmax, ymax);
if ((buf == NULL) || (bm_vertoffs == 0)) {
return false;
}
dr = buf->rect;
-
+
/* build selection lookup */
selbuf = edbm_backbuf_alloc(bm_vertoffs + 1);
-
+
a = (xmax - xmin + 1) * (ymax - ymin + 1);
while (a--) {
if (*dr > 0 && *dr <= bm_vertoffs) {
@@ -263,9 +278,9 @@ static void edbm_mask_lasso_px_cb(int x, int x_end, int y, void *user_data)
/* mcords is a polygon mask
* - grab backbuffer,
- * - draw with black in backbuffer,
+ * - draw with black in backbuffer,
* - grab again and compare
- * returns 'OK'
+ * returns 'OK'
*/
bool EDBM_backbuf_border_mask_init(ViewContext *vc, const int mcords[][2], short tot, short xmin, short ymin, short xmax, short ymax)
{
@@ -273,7 +288,7 @@ bool EDBM_backbuf_border_mask_init(ViewContext *vc, const int mcords[][2], short
struct ImBuf *buf;
int a;
struct LassoMaskData lasso_mask_data;
-
+
/* method in use for face selecting too */
if (vc->obedit == NULL) {
if (!BKE_paint_select_elem_test(vc->obact)) {
@@ -302,7 +317,7 @@ bool EDBM_backbuf_border_mask_init(ViewContext *vc, const int mcords[][2], short
/* build selection lookup */
selbuf = edbm_backbuf_alloc(bm_vertoffs + 1);
-
+
a = (xmax - xmin + 1) * (ymax - ymin + 1);
while (a--) {
if (*dr > 0 && *dr <= bm_vertoffs && *dr_mask == true) {
@@ -323,7 +338,7 @@ bool EDBM_backbuf_circle_init(ViewContext *vc, short xs, short ys, short rads)
unsigned int *dr;
short xmin, ymin, xmax, ymax, xc, yc;
int radsq;
-
+
/* method in use for face selecting too */
if (vc->obedit == NULL) {
if (!BKE_paint_select_elem_test(vc->obact)) {
@@ -342,7 +357,7 @@ bool EDBM_backbuf_circle_init(ViewContext *vc, short xs, short ys, short rads)
}
dr = buf->rect;
-
+
/* build selection lookup */
selbuf = edbm_backbuf_alloc(bm_vertoffs + 1);
radsq = rads * rads;
@@ -358,12 +373,12 @@ bool EDBM_backbuf_circle_init(ViewContext *vc, short xs, short ys, short rads)
IMB_freeImBuf(buf);
return true;
-
+
}
+/** \} */
/* -------------------------------------------------------------------- */
-
/** \name Find Nearest Vert/Edge/Face
*
* \note Screen-space manhatten distances are used here,
@@ -445,11 +460,14 @@ BMVert *EDBM_vert_find_nearest_ex(
float dist_test;
unsigned int index;
BMVert *eve;
-
+
+ /* No afterqueue (yet), so we check it now, otherwise the bm_xxxofs indices are bad. */
+ ED_view3d_backbuf_validate(vc);
+
index = ED_view3d_backbuf_sample_rect(
vc, vc->mval, dist_px, bm_wireoffs, 0xFFFFFF, &dist_test);
eve = index ? BM_vert_at_index_find_or_table(bm, index - 1) : NULL;
-
+
if (eve) {
if (dist_test < *r_dist) {
*r_dist = dist_test;
@@ -630,9 +648,18 @@ BMEdge *EDBM_edge_find_nearest_ex(
float dist_test = 0.0f;
unsigned int index;
BMEdge *eed;
-
+
+ /* Make sure that the edges are considered for selection.
+ * TODO: cleanup: add `selectmode` as a parameter */
+ const short ts_selectmode = vc->scene->toolsettings->selectmode;
+ vc->scene->toolsettings->selectmode |= SCE_SELECT_EDGE;
+
+ /* No afterqueue (yet), so we check it now, otherwise the bm_xxxofs indices are bad. */
ED_view3d_backbuf_validate(vc);
+ /* restore `selectmode` */
+ vc->scene->toolsettings->selectmode = ts_selectmode;
+
index = ED_view3d_backbuf_sample_rect(vc, vc->mval, dist_px, bm_solidoffs, bm_wireoffs, &dist_test);
eed = index ? BM_edge_at_index_find_or_table(bm, index - 1) : NULL;
@@ -799,7 +826,7 @@ BMFace *EDBM_face_find_nearest_ex(
index = ED_view3d_backbuf_sample(vc, vc->mval[0], vc->mval[1]);
efa = index ? BM_face_at_index_find_or_table(bm, index - 1) : NULL;
-
+
if (r_efa_zbuf) {
*r_efa_zbuf = efa;
}
@@ -877,8 +904,8 @@ BMFace *EDBM_face_find_nearest(ViewContext *vc, float *r_dist)
#undef FIND_NEAR_CYCLE_THRESHOLD_MIN
-/* best distance based on screen coords.
- * use em->selectmode to define how to use
+/* best distance based on screen coords.
+ * use em->selectmode to define how to use
* selected vertices and edges get disadvantage
* return 1 if found one
*/
@@ -894,7 +921,7 @@ static int unified_findnearest(ViewContext *vc, BMVert **r_eve, BMEdge **r_eed,
float dist = dist_init;
BMFace *efa_zbuf = NULL;
BMEdge *eed_zbuf = NULL;
-
+
BMVert *eve = NULL;
BMEdge *eed = NULL;
BMFace *efa = NULL;
@@ -956,9 +983,11 @@ static int unified_findnearest(ViewContext *vc, BMVert **r_eve, BMEdge **r_eed,
/** \} */
+/* -------------------------------------------------------------------- */
+/** \name Select Similar (Vert/Edge/Face) Operator
+ * \{ */
-/* **************** SIMILAR "group" SELECTS. FACE, EDGE AND VERTEX ************** */
-static EnumPropertyItem prop_similar_compare_types[] = {
+static const EnumPropertyItem prop_similar_compare_types[] = {
{SIM_CMP_EQ, "EQUAL", 0, "Equal", ""},
{SIM_CMP_GT, "GREATER", 0, "Greater", ""},
{SIM_CMP_LT, "LESS", 0, "Less", ""},
@@ -966,7 +995,7 @@ static EnumPropertyItem prop_similar_compare_types[] = {
{0, NULL, 0, NULL, NULL}
};
-static EnumPropertyItem prop_similar_types[] = {
+static const EnumPropertyItem prop_similar_types[] = {
{SIMVERT_NORMAL, "NORMAL", 0, "Normal", ""},
{SIMVERT_FACE, "FACE", 0, "Amount of Adjacent Faces", ""},
{SIMVERT_VGROUP, "VGROUP", 0, "Vertex Groups", ""},
@@ -1034,7 +1063,7 @@ static int similar_face_select_exec(bContext *C, wmOperator *op)
EDBM_update_generic(em, false, false);
return OPERATOR_FINISHED;
-}
+}
/* ***************************************************** */
@@ -1140,8 +1169,9 @@ static int edbm_select_similar_exec(bContext *C, wmOperator *op)
else return similar_face_select_exec(C, op);
}
-static EnumPropertyItem *select_similar_type_itemf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop),
- bool *r_free)
+static const EnumPropertyItem *select_similar_type_itemf(
+ bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop),
+ bool *r_free)
{
Object *obedit;
@@ -1193,15 +1223,15 @@ void MESH_OT_select_similar(wmOperatorType *ot)
ot->name = "Select Similar";
ot->idname = "MESH_OT_select_similar";
ot->description = "Select similar vertices, edges or faces by property types";
-
+
/* api callbacks */
ot->invoke = WM_menu_invoke;
ot->exec = edbm_select_similar_exec;
ot->poll = ED_operator_editmesh;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
prop = ot->prop = RNA_def_enum(ot->srna, "type", prop_similar_types, SIMVERT_NORMAL, "Type", "");
RNA_def_enum_funcs(prop, select_similar_type_itemf);
@@ -1211,9 +1241,11 @@ void MESH_OT_select_similar(wmOperatorType *ot)
RNA_def_float(ot->srna, "threshold", 0.0f, 0.0f, 1.0f, "Threshold", "", 0.0f, 1.0f);
}
+/** \} */
/* -------------------------------------------------------------------- */
-/* Select Similar Regions */
+/** \name Select Similar Region Operator
+ * \{ */
static int edbm_select_similar_region_exec(bContext *C, wmOperator *op)
{
@@ -1234,9 +1266,10 @@ static int edbm_select_similar_region_exec(bContext *C, wmOperator *op)
}
groups_array = MEM_mallocN(sizeof(*groups_array) * bm->totfacesel, __func__);
- group_tot = BM_mesh_calc_face_groups(bm, groups_array, &group_index,
- NULL, NULL,
- BM_ELEM_SELECT, BM_VERT);
+ group_tot = BM_mesh_calc_face_groups(
+ bm, groups_array, &group_index,
+ NULL, NULL,
+ BM_ELEM_SELECT, BM_VERT);
BM_mesh_elem_table_ensure(bm, BM_FACE);
@@ -1277,7 +1310,7 @@ static int edbm_select_similar_region_exec(bContext *C, wmOperator *op)
MEM_freeN(group_index);
if (changed) {
- WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit);
+ WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
}
else {
BKE_report(op->reports, RPT_WARNING, "No matching face regions found");
@@ -1301,8 +1334,11 @@ void MESH_OT_select_similar_region(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
+/** \} */
-/* **************** Mode Select *************** */
+/* -------------------------------------------------------------------- */
+/** \name Select Mode Vert/Edge/Face Operator
+ * \{ */
static int edbm_select_mode_exec(bContext *C, wmOperator *op)
{
@@ -1335,14 +1371,14 @@ void MESH_OT_select_mode(wmOperatorType *ot)
{
PropertyRNA *prop;
- static EnumPropertyItem elem_items[] = {
+ static const EnumPropertyItem elem_items[] = {
{SCE_SELECT_VERTEX, "VERT", ICON_VERTEXSEL, "Vertices", ""},
{SCE_SELECT_EDGE, "EDGE", ICON_EDGESEL, "Edges", ""},
{SCE_SELECT_FACE, "FACE", ICON_FACESEL, "Faces", ""},
{0, NULL, 0, NULL, NULL},
};
- static EnumPropertyItem actions_items[] = {
+ static const EnumPropertyItem actions_items[] = {
{0, "DISABLE", 0, "Disable", "Disable selected markers"},
{1, "ENABLE", 0, "Enable", "Enable selected markers"},
{2, "TOGGLE", 0, "Toggle", "Toggle disabled flag for selected markers"},
@@ -1373,12 +1409,15 @@ void MESH_OT_select_mode(wmOperatorType *ot)
RNA_def_enum(ot->srna, "action", actions_items, 2, "Action", "Selection action to execute");
}
-/* ***************************************************** */
+/** \} */
-/* **************** LOOP SELECTS *************** */
+/* -------------------------------------------------------------------- */
+/** \name Select Loop (Non Modal) Operator
+ * \{ */
-static void walker_select_count(BMEditMesh *em, int walkercode, void *start, const bool select, const bool select_mix,
- int *r_totsel, int *r_totunsel)
+static void walker_select_count(
+ BMEditMesh *em, int walkercode, void *start, const bool select, const bool select_mix,
+ int *r_totsel, int *r_totunsel)
{
BMesh *bm = em->bm;
BMElem *ele;
@@ -1433,7 +1472,7 @@ static int edbm_loop_multiselect_exec(bContext *C, wmOperator *op)
BMEdge **edarray;
int edindex;
const bool is_ring = RNA_boolean_get(op->ptr, "ring");
-
+
BMIter iter;
int totedgesel = 0;
@@ -1442,17 +1481,17 @@ static int edbm_loop_multiselect_exec(bContext *C, wmOperator *op)
totedgesel++;
}
}
-
+
edarray = MEM_mallocN(sizeof(BMEdge *) * totedgesel, "edge array");
edindex = 0;
-
+
BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) {
edarray[edindex] = eed;
edindex++;
}
}
-
+
if (is_ring) {
for (edindex = 0; edindex < totedgesel; edindex += 1) {
eed = edarray[edindex];
@@ -1469,8 +1508,8 @@ static int edbm_loop_multiselect_exec(bContext *C, wmOperator *op)
}
MEM_freeN(edarray);
// if (EM_texFaceCheck())
-
- WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit);
+
+ WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
return OPERATOR_FINISHED;
}
@@ -1481,23 +1520,23 @@ void MESH_OT_loop_multi_select(wmOperatorType *ot)
ot->name = "Multi Select Loops";
ot->idname = "MESH_OT_loop_multi_select";
ot->description = "Select a loop of connected edges by connection type";
-
+
/* api callbacks */
ot->exec = edbm_loop_multiselect_exec;
ot->poll = ED_operator_editmesh;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
RNA_def_boolean(ot->srna, "ring", 0, "Ring", "");
}
-
-/* ***************** MAIN MOUSE SELECTION ************** */
-
+/** \} */
-/* ***************** loop select (non modal) ************** */
+/* -------------------------------------------------------------------- */
+/** \name Select Loop (Cursor Pick) Operator
+ * \{ */
static void mouse_mesh_loop_face(BMEditMesh *em, BMEdge *eed, bool select, bool select_clear)
{
@@ -1552,7 +1591,6 @@ static void mouse_mesh_loop_edge(BMEditMesh *em, BMEdge *eed, bool select, bool
}
}
-
static bool mouse_mesh_loop(bContext *C, const int mval[2], bool extend, bool deselect, bool toggle, bool ring)
{
ViewContext vc;
@@ -1569,9 +1607,17 @@ static bool mouse_mesh_loop(bContext *C, const int mval[2], bool extend, bool de
mvalf[1] = (float)(vc.mval[1] = mval[1]);
em = vc.em;
+ /* Make sure that the edges are also considered for selection.
+ * TODO: cleanup: add `selectmode` as a parameter */
+ const short ts_selectmode = vc.scene->toolsettings->selectmode;
+ vc.scene->toolsettings->selectmode |= SCE_SELECT_EDGE;
+
/* no afterqueue (yet), so we check it now, otherwise the bm_xxxofs indices are bad */
ED_view3d_backbuf_validate(&vc);
+ /* restore `selectmode` */
+ vc.scene->toolsettings->selectmode = ts_selectmode;
+
eed = EDBM_edge_find_nearest_ex(&vc, &dist, NULL, true, true, NULL);
if (eed == NULL) {
return false;
@@ -1621,11 +1667,15 @@ static bool mouse_mesh_loop(bContext *C, const int mval[2], bool extend, bool de
/* We can't be sure this has already been set... */
ED_view3d_init_mats_rv3d(vc.obedit, vc.rv3d);
- if (ED_view3d_project_float_object(vc.ar, eed->v1->co, v1_co, V3D_PROJ_TEST_CLIP_NEAR) == V3D_PROJ_RET_OK) {
+ if (ED_view3d_project_float_object(
+ vc.ar, eed->v1->co, v1_co, V3D_PROJ_TEST_CLIP_NEAR) == V3D_PROJ_RET_OK)
+ {
length_1 = len_squared_v2v2(mvalf, v1_co);
}
- if (ED_view3d_project_float_object(vc.ar, eed->v2->co, v2_co, V3D_PROJ_TEST_CLIP_NEAR) == V3D_PROJ_RET_OK) {
+ if (ED_view3d_project_float_object(
+ vc.ar, eed->v2->co, v2_co, V3D_PROJ_TEST_CLIP_NEAR) == V3D_PROJ_RET_OK)
+ {
length_2 = len_squared_v2v2(mvalf, v2_co);
}
#if 0
@@ -1652,7 +1702,9 @@ static bool mouse_mesh_loop(bContext *C, const int mval[2], bool extend, bool de
float co[2], tdist;
BM_face_calc_center_mean(f, cent);
- if (ED_view3d_project_float_object(vc.ar, cent, co, V3D_PROJ_TEST_CLIP_NEAR) == V3D_PROJ_RET_OK) {
+ if (ED_view3d_project_float_object(
+ vc.ar, cent, co, V3D_PROJ_TEST_CLIP_NEAR) == V3D_PROJ_RET_OK)
+ {
tdist = len_squared_v2v2(mvalf, co);
if (tdist < best_dist) {
/* printf("Best face: %p (%f)\n", f, tdist);*/
@@ -1669,21 +1721,22 @@ static bool mouse_mesh_loop(bContext *C, const int mval[2], bool extend, bool de
}
}
- WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc.obedit);
+ WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc.obedit->data);
return true;
}
static int edbm_select_loop_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
-
+
view3d_operator_needs_opengl(C);
-
- if (mouse_mesh_loop(C, event->mval,
- RNA_boolean_get(op->ptr, "extend"),
- RNA_boolean_get(op->ptr, "deselect"),
- RNA_boolean_get(op->ptr, "toggle"),
- RNA_boolean_get(op->ptr, "ring")))
+
+ if (mouse_mesh_loop(
+ C, event->mval,
+ RNA_boolean_get(op->ptr, "extend"),
+ RNA_boolean_get(op->ptr, "deselect"),
+ RNA_boolean_get(op->ptr, "toggle"),
+ RNA_boolean_get(op->ptr, "ring")))
{
return OPERATOR_FINISHED;
}
@@ -1698,14 +1751,14 @@ void MESH_OT_loop_select(wmOperatorType *ot)
ot->name = "Loop Select";
ot->idname = "MESH_OT_loop_select";
ot->description = "Select a loop of connected edges";
-
+
/* api callbacks */
ot->invoke = edbm_select_loop_invoke;
ot->poll = ED_operator_editmesh_region_view3d;
-
+
/* flags */
ot->flag = OPTYPE_UNDO;
-
+
/* properties */
RNA_def_boolean(ot->srna, "extend", 0, "Extend Select", "Extend the selection");
RNA_def_boolean(ot->srna, "deselect", 0, "Deselect", "Remove from the selection");
@@ -1719,11 +1772,11 @@ void MESH_OT_edgering_select(wmOperatorType *ot)
ot->name = "Edge Ring Select";
ot->idname = "MESH_OT_edgering_select";
ot->description = "Select an edge ring";
-
+
/* callbacks */
ot->invoke = edbm_select_loop_invoke;
ot->poll = ED_operator_editmesh_region_view3d;
-
+
/* flags */
ot->flag = OPTYPE_UNDO;
@@ -1733,7 +1786,12 @@ void MESH_OT_edgering_select(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "ring", 1, "Select Ring", "Select ring");
}
-/* ******************** (de)select all operator **************** */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name (De)Select All Operator
+ * \{ */
+
static int edbm_select_all_exec(bContext *C, wmOperator *op)
{
Object *obedit = CTX_data_edit_object(C);
@@ -1756,7 +1814,7 @@ static int edbm_select_all_exec(bContext *C, wmOperator *op)
break;
}
- WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit);
+ WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
return OPERATOR_FINISHED;
}
@@ -1778,13 +1836,19 @@ void MESH_OT_select_all(wmOperatorType *ot)
WM_operator_properties_select_all(ot);
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Select Interior Faces Operator
+ * \{ */
+
static int edbm_faces_select_interior_exec(bContext *C, wmOperator *UNUSED(op))
{
Object *obedit = CTX_data_edit_object(C);
BMEditMesh *em = BKE_editmesh_from_object(obedit);
if (EDBM_select_interior_faces(em)) {
- WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit);
+ WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
return OPERATOR_FINISHED;
}
@@ -1809,10 +1873,15 @@ void MESH_OT_select_interior_faces(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Select Picking API
+ *
+ * Here actual select happens,
+ * Gets called via generic mouse select operator.
+ * \{ */
-/* ************************************************** */
-/* here actual select happens */
-/* gets called via generic mouse select operator */
bool EDBM_select_pick(bContext *C, const int mval[2], bool extend, bool deselect, bool toggle)
{
ViewContext vc;
@@ -1921,13 +1990,19 @@ bool EDBM_select_pick(bContext *C, const int mval[2], bool extend, bool deselect
}
- WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc.obedit);
+ WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc.obedit->data);
return true;
}
return false;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Select Mode Utilities
+ * \{ */
+
static void edbm_strip_selections(BMEditMesh *em)
{
BMEditSelection *ese, *nextese;
@@ -1966,11 +2041,11 @@ void EDBM_selectmode_set(BMEditMesh *em)
BMEdge *eed;
BMFace *efa;
BMIter iter;
-
+
em->bm->selectmode = em->selectmode;
edbm_strip_selections(em); /* strip BMEditSelections from em->selected that are not relevant to new mode */
-
+
if (em->bm->totvertsel == 0 &&
em->bm->totedgesel == 0 &&
em->bm->totfacesel == 0)
@@ -2133,8 +2208,9 @@ void EDBM_selectmode_convert(BMEditMesh *em, const short selectmode_old, const s
}
/* user facing function, does notification */
-bool EDBM_selectmode_toggle(bContext *C, const short selectmode_new,
- const int action, const bool use_extend, const bool use_expand)
+bool EDBM_selectmode_toggle(
+ bContext *C, const short selectmode_new,
+ const int action, const bool use_extend, const bool use_expand)
{
ToolSettings *ts = CTX_data_tool_settings(C);
Object *obedit = CTX_data_edit_object(C);
@@ -2230,9 +2306,10 @@ bool EDBM_selectmode_toggle(bContext *C, const short selectmode_new,
*
* \return true if the mode is changed.
*/
-bool EDBM_selectmode_disable(Scene *scene, BMEditMesh *em,
- const short selectmode_disable,
- const short selectmode_fallback)
+bool EDBM_selectmode_disable(
+ Scene *scene, BMEditMesh *em,
+ const short selectmode_disable,
+ const short selectmode_fallback)
{
/* note essential, but switch out of vertex mode since the
* selected regions wont be nicely isolated after flushing */
@@ -2255,6 +2332,12 @@ bool EDBM_selectmode_disable(Scene *scene, BMEditMesh *em,
}
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Select Toggle
+ * \{ */
+
void EDBM_deselect_by_material(BMEditMesh *em, const short index, const bool select)
{
BMIter iter;
@@ -2283,7 +2366,7 @@ void EDBM_select_swap(BMEditMesh *em) /* exported for UV */
BMVert *eve;
BMEdge *eed;
BMFace *efa;
-
+
if (em->bm->selectmode & SCE_SELECT_VERTEX) {
BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
if (BM_elem_flag_test(eve, BM_ELEM_HIDDEN))
@@ -2306,9 +2389,17 @@ void EDBM_select_swap(BMEditMesh *em) /* exported for UV */
}
}
-// if (EM_texFaceCheck())
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Select Interior Faces
+ *
+ * \note This algorithm is limited to single faces and could be improved, see:
+ * https://blender.stackexchange.com/questions/18916
+ * \{ */
+
bool EDBM_select_interior_faces(BMEditMesh *em)
{
BMesh *bm = em->bm;
@@ -2341,8 +2432,13 @@ bool EDBM_select_interior_faces(BMEditMesh *em)
return changed;
}
+/** \} */
-/************************ Select Linked Operator *************************/
+/* -------------------------------------------------------------------- */
+/** \name Select Linked Operator
+ *
+ * Support delimiting on different edge properties.
+ * \{ */
/* so we can have last-used default depend on selection mode (rare exception!) */
#define USE_LINKED_SELECT_DEFAULT_HACK
@@ -2402,10 +2498,10 @@ static bool select_linked_delimit_test(
* Gets the default from the operator fallback to own last-used value
* (selected based on mode)
*/
-static int select_linked_delimit_default_from_op(wmOperator *op, BMEditMesh *em)
+static int select_linked_delimit_default_from_op(wmOperator *op, int select_mode)
{
static char delimit_last_store[2] = {0, BMO_DELIM_SEAM};
- int delimit_last_index = (em->selectmode & (SCE_SELECT_VERTEX | SCE_SELECT_EDGE)) == 0;
+ int delimit_last_index = (select_mode & (SCE_SELECT_VERTEX | SCE_SELECT_EDGE)) == 0;
char *delimit_last = &delimit_last_store[delimit_last_index];
PropertyRNA *prop_delimit = RNA_struct_find_property(op->ptr, "delimit");
int delimit;
@@ -2475,7 +2571,7 @@ static int edbm_select_linked_exec(bContext *C, wmOperator *op)
BMWalker walker;
#ifdef USE_LINKED_SELECT_DEFAULT_HACK
- int delimit = select_linked_delimit_default_from_op(op, em);
+ int delimit = select_linked_delimit_default_from_op(op, em->selectmode);
#else
int delimit = RNA_enum_get(op->ptr, "delimit");
#endif
@@ -2633,7 +2729,7 @@ static int edbm_select_linked_exec(bContext *C, wmOperator *op)
select_linked_delimit_end(em);
}
- WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit);
+ WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
return OPERATOR_FINISHED;
}
@@ -2645,7 +2741,7 @@ void MESH_OT_select_linked(wmOperatorType *ot)
/* identifiers */
ot->name = "Select Linked All";
ot->idname = "MESH_OT_select_linked";
- ot->description = "Select all vertices linked to the active mesh";
+ ot->description = "Select all vertices connected to the current selection";
/* api callbacks */
ot->exec = edbm_select_linked_exec;
@@ -2663,6 +2759,12 @@ void MESH_OT_select_linked(wmOperatorType *ot)
#endif
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Select Linked (Cursor Pick) Operator
+ * \{ */
+
static int edbm_select_linked_pick_exec(bContext *C, wmOperator *op);
static void edbm_select_linked_pick_ex(BMEditMesh *em, BMElem *ele, bool sel, int delimit)
@@ -2801,13 +2903,13 @@ static int edbm_select_linked_pick_invoke(bContext *C, wmOperator *op, const wmE
/* return warning! */
if (unified_findnearest(&vc, &eve, &eed, &efa) == 0) {
- WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit);
+ WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
return OPERATOR_CANCELLED;
}
#ifdef USE_LINKED_SELECT_DEFAULT_HACK
- int delimit = select_linked_delimit_default_from_op(op, em);
+ int delimit = select_linked_delimit_default_from_op(op, em->selectmode);
#else
int delimit = RNA_enum_get(op->ptr, "delimit");
#endif
@@ -2822,7 +2924,7 @@ static int edbm_select_linked_pick_invoke(bContext *C, wmOperator *op, const wmE
RNA_int_set(op->ptr, "index", index);
- WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit);
+ WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
return OPERATOR_FINISHED;
}
@@ -2844,14 +2946,14 @@ static int edbm_select_linked_pick_exec(bContext *C, wmOperator *op)
BMElem *ele = EDBM_elem_from_index_any(em, index);
#ifdef USE_LINKED_SELECT_DEFAULT_HACK
- int delimit = select_linked_delimit_default_from_op(op, em);
+ int delimit = select_linked_delimit_default_from_op(op, em->selectmode);
#else
int delimit = RNA_enum_get(op->ptr, "delimit");
#endif
edbm_select_linked_pick_ex(em, ele, sel, delimit);
- WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit);
+ WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
return OPERATOR_FINISHED;
}
@@ -2864,15 +2966,15 @@ void MESH_OT_select_linked_pick(wmOperatorType *ot)
ot->name = "Select Linked";
ot->idname = "MESH_OT_select_linked_pick";
ot->description = "(De)select all vertices linked to the edge under the mouse cursor";
-
+
/* api callbacks */
ot->invoke = edbm_select_linked_pick_invoke;
ot->exec = edbm_select_linked_pick_exec;
ot->poll = ED_operator_editmesh;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
RNA_def_boolean(ot->srna, "deselect", 0, "Deselect", "");
prop = RNA_def_enum_flag(ot->srna, "delimit", rna_enum_mesh_delimit_mode_items, BMO_DELIM_SEAM, "Delimit",
"Delimit selected region");
@@ -2885,6 +2987,11 @@ void MESH_OT_select_linked_pick(wmOperatorType *ot)
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Select Face by Sides Operator
+ * \{ */
static int edbm_select_face_by_sides_exec(bContext *C, wmOperator *op)
{
@@ -2960,6 +3067,11 @@ void MESH_OT_select_face_by_sides(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "extend", true, "Extend", "Extend the selection");
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Select Loose Operator
+ * \{ */
static int edbm_select_loose_exec(bContext *C, wmOperator *op)
{
@@ -3031,6 +3143,11 @@ void MESH_OT_select_loose(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend the selection");
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Select Mirror Operator
+ * \{ */
static int edbm_select_mirror_exec(bContext *C, wmOperator *op)
{
@@ -3079,7 +3196,11 @@ void MESH_OT_select_mirror(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Extend the existing selection");
}
-/* ******************** **************** */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Select More Operator
+ * \{ */
static int edbm_select_more_exec(bContext *C, wmOperator *op)
{
@@ -3089,7 +3210,7 @@ static int edbm_select_more_exec(bContext *C, wmOperator *op)
EDBM_select_more(em, use_face_step);
- WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit);
+ WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
return OPERATOR_FINISHED;
}
@@ -3103,13 +3224,19 @@ void MESH_OT_select_more(wmOperatorType *ot)
/* api callbacks */
ot->exec = edbm_select_more_exec;
ot->poll = ED_operator_editmesh;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
RNA_def_boolean(ot->srna, "use_face_step", true, "Face Step", "Connected faces (instead of edges)");
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Select More Operator
+ * \{ */
+
static int edbm_select_less_exec(bContext *C, wmOperator *op)
{
Object *obedit = CTX_data_edit_object(C);
@@ -3118,7 +3245,7 @@ static int edbm_select_less_exec(bContext *C, wmOperator *op)
EDBM_select_less(em, use_face_step);
- WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit);
+ WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
return OPERATOR_FINISHED;
}
@@ -3132,13 +3259,19 @@ void MESH_OT_select_less(wmOperatorType *ot)
/* api callbacks */
ot->exec = edbm_select_less_exec;
ot->poll = ED_operator_editmesh;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
RNA_def_boolean(ot->srna, "use_face_step", true, "Face Step", "Connected faces (instead of edges)");
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Select N'th Operator
+ * \{ */
+
/**
* Check if we're connected to another selected efge.
*/
@@ -3361,13 +3494,18 @@ void MESH_OT_select_nth(wmOperatorType *ot)
void em_setup_viewcontext(bContext *C, ViewContext *vc)
{
- view3d_set_viewcontext(C, vc);
-
+ ED_view3d_viewcontext_init(C, vc);
+
if (vc->obedit) {
vc->em = BKE_editmesh_from_object(vc->obedit);
}
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Select Sharp Edges Operator
+ * \{ */
static int edbm_select_sharp_edges_exec(bContext *C, wmOperator *op)
{
@@ -3395,6 +3533,13 @@ static int edbm_select_sharp_edges_exec(bContext *C, wmOperator *op)
}
}
+ if ((em->bm->selectmode & (SCE_SELECT_VERTEX | SCE_SELECT_EDGE)) == 0) {
+ /* Since we can't select individual edges, select faces connected to them. */
+ EDBM_selectmode_convert(em, SCE_SELECT_EDGE, SCE_SELECT_FACE);
+ }
+ else {
+ EDBM_selectmode_flush(em);
+ }
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
return OPERATOR_FINISHED;
@@ -3408,20 +3553,26 @@ void MESH_OT_edges_select_sharp(wmOperatorType *ot)
ot->name = "Select Sharp Edges";
ot->description = "Select all sharp-enough edges";
ot->idname = "MESH_OT_edges_select_sharp";
-
+
/* api callbacks */
ot->exec = edbm_select_sharp_edges_exec;
ot->poll = ED_operator_editmesh;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* props */
prop = RNA_def_float_rotation(ot->srna, "sharpness", 0, NULL, DEG2RADF(0.01f), DEG2RADF(180.0f),
"Sharpness", "", DEG2RADF(1.0f), DEG2RADF(180.0f));
RNA_def_property_float_default(prop, DEG2RADF(30.0f));
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Select Linked Flat Faces Operator
+ * \{ */
+
static int edbm_select_linked_flat_faces_exec(bContext *C, wmOperator *op)
{
Object *obedit = CTX_data_edit_object(C);
@@ -3489,20 +3640,26 @@ void MESH_OT_faces_select_linked_flat(wmOperatorType *ot)
ot->name = "Select Linked Flat Faces";
ot->description = "Select linked faces by angle";
ot->idname = "MESH_OT_faces_select_linked_flat";
-
+
/* api callbacks */
ot->exec = edbm_select_linked_flat_faces_exec;
ot->poll = ED_operator_editmesh;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* props */
prop = RNA_def_float_rotation(ot->srna, "sharpness", 0, NULL, DEG2RADF(0.01f), DEG2RADF(180.0f),
"Sharpness", "", DEG2RADF(1.0f), DEG2RADF(180.0f));
RNA_def_property_float_default(prop, DEG2RADF(1.0f));
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Select Non-Manifold Operator
+ * \{ */
+
static int edbm_select_non_manifold_exec(bContext *C, wmOperator *op)
{
Object *obedit = CTX_data_edit_object(C);
@@ -3524,12 +3681,12 @@ static int edbm_select_non_manifold_exec(bContext *C, wmOperator *op)
/* Selects isolated verts, and edges that do not have 2 neighboring
* faces
*/
-
+
if (em->selectmode == SCE_SELECT_FACE) {
BKE_report(op->reports, RPT_ERROR, "Does not work in face selection mode");
return OPERATOR_CANCELLED;
}
-
+
if (use_verts) {
BM_ITER_MESH (v, &iter, em->bm, BM_VERTS_OF_MESH) {
if (!BM_elem_flag_test(v, BM_ELEM_HIDDEN)) {
@@ -3539,7 +3696,7 @@ static int edbm_select_non_manifold_exec(bContext *C, wmOperator *op)
}
}
}
-
+
if (use_wire || use_boundary || use_multi_face || use_non_contiguous) {
BM_ITER_MESH (e, &iter, em->bm, BM_EDGES_OF_MESH) {
if (!BM_elem_flag_test(e, BM_ELEM_HIDDEN)) {
@@ -3570,11 +3727,11 @@ void MESH_OT_select_non_manifold(wmOperatorType *ot)
ot->name = "Select Non Manifold";
ot->description = "Select all non-manifold vertices or edges";
ot->idname = "MESH_OT_select_non_manifold";
-
+
/* api callbacks */
ot->exec = edbm_select_non_manifold_exec;
ot->poll = ED_operator_editmesh;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -3594,6 +3751,12 @@ void MESH_OT_select_non_manifold(wmOperatorType *ot)
"Vertices connecting multiple face regions");
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Select Random Operator
+ * \{ */
+
static int edbm_select_random_exec(bContext *C, wmOperator *op)
{
Object *obedit = CTX_data_edit_object(C);
@@ -3640,9 +3803,9 @@ static int edbm_select_random_exec(bContext *C, wmOperator *op)
else {
EDBM_deselect_flush(em);
}
-
+
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
-
+
return OPERATOR_FINISHED;
}
@@ -3659,11 +3822,17 @@ void MESH_OT_select_random(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* props */
WM_operator_properties_select_random(ot);
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Select Ungrouped Operator
+ * \{ */
+
static int edbm_select_ungrouped_poll(bContext *C)
{
if (ED_operator_editmesh(C)) {
@@ -3730,6 +3899,11 @@ void MESH_OT_select_ungrouped(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend the selection");
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Select Axis Operator
+ * \{ */
/* BMESH_TODO - some way to select on an arbitrary axis */
static int edbm_select_axis_exec(bContext *C, wmOperator *op)
@@ -3784,14 +3958,14 @@ static int edbm_select_axis_exec(bContext *C, wmOperator *op)
void MESH_OT_select_axis(wmOperatorType *ot)
{
- static EnumPropertyItem axis_mode_items[] = {
+ static const EnumPropertyItem axis_mode_items[] = {
{0, "POSITIVE", 0, "Positive Axis", ""},
{1, "NEGATIVE", 0, "Negative Axis", ""},
{-1, "ALIGNED", 0, "Aligned Axis", ""},
{0, NULL, 0, NULL, NULL}
};
- static EnumPropertyItem axis_items_xyz[] = {
+ static const EnumPropertyItem axis_items_xyz[] = {
{0, "X_AXIS", 0, "X Axis", ""},
{1, "Y_AXIS", 0, "Y Axis", ""},
{2, "Z_AXIS", 0, "Z Axis", ""},
@@ -3816,6 +3990,12 @@ void MESH_OT_select_axis(wmOperatorType *ot)
RNA_def_float(ot->srna, "threshold", 0.0001f, 0.000001f, 50.0f, "Threshold", "", 0.00001f, 10.0f);
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Select Region to Loop Operator
+ * \{ */
+
static int edbm_region_to_loop_exec(bContext *C, wmOperator *UNUSED(op))
{
Object *obedit = CTX_data_edit_object(C);
@@ -3829,22 +4009,22 @@ static int edbm_region_to_loop_exec(bContext *C, wmOperator *UNUSED(op))
BM_ITER_MESH (f, &iter, em->bm, BM_FACES_OF_MESH) {
BMLoop *l1, *l2;
BMIter liter1, liter2;
-
+
BM_ITER_ELEM (l1, &liter1, f, BM_LOOPS_OF_FACE) {
int tot = 0, totsel = 0;
-
+
BM_ITER_ELEM (l2, &liter2, l1->e, BM_LOOPS_OF_EDGE) {
tot++;
totsel += BM_elem_flag_test(l2->f, BM_ELEM_SELECT) != 0;
}
-
+
if ((tot != totsel && totsel > 0) || (totsel == 1 && tot == 1))
BM_elem_flag_enable(l1->e, BM_ELEM_TAG);
}
}
EDBM_flag_disable_all(em, BM_ELEM_SELECT);
-
+
BM_ITER_MESH (e, &iter, em->bm, BM_EDGES_OF_MESH) {
if (BM_elem_flag_test(e, BM_ELEM_TAG)) {
BM_edge_select_set(em->bm, e, true);
@@ -3879,29 +4059,36 @@ void MESH_OT_region_to_loop(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-static int loop_find_region(BMLoop *l, int flag,
- GSet *visit_face_set, BMFace ***region_out)
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Select Loop to Region Operator
+ * \{ */
+
+static int loop_find_region(
+ BMLoop *l, int flag,
+ GSet *visit_face_set, BMFace ***region_out)
{
BMFace **region = NULL;
BMFace **stack = NULL;
BLI_array_declare(region);
BLI_array_declare(stack);
BMFace *f;
-
+
BLI_array_append(stack, l->f);
BLI_gset_insert(visit_face_set, l->f);
-
- while (BLI_array_count(stack) > 0) {
+
+ while (BLI_array_len(stack) > 0) {
BMIter liter1, liter2;
BMLoop *l1, *l2;
-
+
f = BLI_array_pop(stack);
BLI_array_append(region, f);
-
+
BM_ITER_ELEM (l1, &liter1, f, BM_LOOPS_OF_FACE) {
if (BM_elem_flag_test(l1->e, flag))
continue;
-
+
BM_ITER_ELEM (l2, &liter2, l1->e, BM_LOOPS_OF_EDGE) {
/* avoids finding same region twice
* (otherwise) the logic works fine without */
@@ -3915,11 +4102,11 @@ static int loop_find_region(BMLoop *l, int flag,
}
}
}
-
+
BLI_array_free(stack);
-
+
*region_out = region;
- return BLI_array_count(region);
+ return BLI_array_len(region);
}
static int verg_radial(const void *va, const void *vb)
@@ -3927,10 +4114,9 @@ static int verg_radial(const void *va, const void *vb)
const BMEdge *e_a = *((const BMEdge **)va);
const BMEdge *e_b = *((const BMEdge **)vb);
- int a, b;
- a = BM_edge_face_count(e_a);
- b = BM_edge_face_count(e_b);
-
+ const int a = BM_edge_face_count(e_a);
+ const int b = BM_edge_face_count(e_b);
+
if (a > b) return -1;
if (a < b) return 1;
return 0;
@@ -3949,7 +4135,7 @@ static int loop_find_regions(BMEditMesh *em, const bool selbigger)
const int edges_len = em->bm->totedgesel;
BMEdge *e, **edges;
int count = 0, i;
-
+
visit_face_set = BLI_gset_ptr_new_ex(__func__, edges_len);
edges = MEM_mallocN(sizeof(*edges) * edges_len, __func__);
@@ -3963,21 +4149,21 @@ static int loop_find_regions(BMEditMesh *em, const bool selbigger)
BM_elem_flag_disable(e, BM_ELEM_TAG);
}
}
-
+
/* sort edges by radial cycle length */
qsort(edges, edges_len, sizeof(*edges), verg_radial);
-
+
for (i = 0; i < edges_len; i++) {
BMIter liter;
BMLoop *l;
BMFace **region = NULL, **region_out;
int c, tot = 0;
-
+
e = edges[i];
-
+
if (!BM_elem_flag_test(e, BM_ELEM_TAG))
continue;
-
+
BM_ITER_ELEM (l, &liter, e, BM_LOOPS_OF_EDGE) {
if (BLI_gset_haskey(visit_face_set, l->f))
continue;
@@ -3999,26 +4185,26 @@ static int loop_find_regions(BMEditMesh *em, const bool selbigger)
MEM_freeN(region_out);
}
}
-
+
if (region) {
int j;
-
+
for (j = 0; j < tot; j++) {
BM_elem_flag_enable(region[j], BM_ELEM_TAG);
BM_ITER_ELEM (l, &liter, region[j], BM_LOOPS_OF_FACE) {
BM_elem_flag_disable(l->e, BM_ELEM_TAG);
}
}
-
+
count += tot;
-
+
MEM_freeN(region);
}
}
-
+
MEM_freeN(edges);
BLI_gset_free(visit_face_set, NULL);
-
+
return count;
}
@@ -4029,25 +4215,23 @@ static int edbm_loop_to_region_exec(bContext *C, wmOperator *op)
BMIter iter;
BMFace *f;
const bool select_bigger = RNA_boolean_get(op->ptr, "select_bigger");
- int a, b;
-
/* find the set of regions with smallest number of total faces */
BM_mesh_elem_hflag_disable_all(em->bm, BM_FACE, BM_ELEM_TAG, false);
- a = loop_find_regions(em, select_bigger);
- b = loop_find_regions(em, !select_bigger);
+ const int a = loop_find_regions(em, select_bigger);
+ const int b = loop_find_regions(em, !select_bigger);
BM_mesh_elem_hflag_disable_all(em->bm, BM_FACE, BM_ELEM_TAG, false);
loop_find_regions(em, ((a <= b) != select_bigger) ? select_bigger : !select_bigger);
-
+
EDBM_flag_disable_all(em, BM_ELEM_SELECT);
-
+
BM_ITER_MESH (f, &iter, em->bm, BM_FACES_OF_MESH) {
if (BM_elem_flag_test(f, BM_ELEM_TAG) && !BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
BM_face_select_set(em->bm, f, true);
}
}
-
+
EDBM_selectmode_flush(em);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
@@ -4067,9 +4251,8 @@ void MESH_OT_loop_to_region(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
RNA_def_boolean(ot->srna, "select_bigger", 0, "Select Bigger", "Select bigger regions instead of smaller ones");
}
-
-/************************ Select Path Operator *************************/
+/** \} */