diff options
author | Campbell Barton <ideasman42@gmail.com> | 2018-03-14 10:08:37 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2018-03-14 10:08:37 +0300 |
commit | d430d12123d88780480e1523340af7a0cddacf96 (patch) | |
tree | 2532976198a2e8d36ee388f94f3c8a273cb700ae /source/blender/editors/mesh/editmesh_select.c | |
parent | 7314904a777534fce6ec45cc410a8e2c8b0cf970 (diff) | |
parent | 8803c5ca5d8a99d97529ce2c170a268b52335997 (diff) |
Merge branch 'master' into blender2.8
Diffstat (limited to 'source/blender/editors/mesh/editmesh_select.c')
-rw-r--r-- | source/blender/editors/mesh/editmesh_select.c | 438 |
1 files changed, 297 insertions, 141 deletions
diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index ca1002c7268..a6bbebb834e 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -75,7 +75,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, @@ -168,21 +170,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 */ @@ -203,21 +218,21 @@ bool EDBM_backbuf_border_init( struct ImBuf *buf; unsigned int *dr; int a; - + if (vc->obedit == NULL || !V3D_IS_ZBUF(vc->v3d)) { return false; } - + buf = ED_view3d_backbuf_read(eval_ctx, 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) { @@ -267,9 +282,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(const struct EvaluationContext *eval_ctx, ViewContext *vc, const int mcords[][2], short tot, short xmin, short ymin, short xmax, short ymax) { @@ -277,7 +292,7 @@ bool EDBM_backbuf_border_mask_init(const struct EvaluationContext *eval_ctx, Vie 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, eval_ctx->object_mode)) { @@ -306,7 +321,7 @@ bool EDBM_backbuf_border_mask_init(const struct EvaluationContext *eval_ctx, Vie /* 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) { @@ -329,7 +344,7 @@ bool EDBM_backbuf_circle_init( 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, eval_ctx->object_mode)) { @@ -348,7 +363,7 @@ bool EDBM_backbuf_circle_init( } dr = buf->rect; - + /* build selection lookup */ selbuf = edbm_backbuf_alloc(bm_vertoffs + 1); radsq = rads * rads; @@ -364,12 +379,12 @@ bool EDBM_backbuf_circle_init( IMB_freeImBuf(buf); return true; - + } +/** \} */ /* -------------------------------------------------------------------- */ - /** \name Find Nearest Vert/Edge/Face * * \note Screen-space manhatten distances are used here, @@ -451,14 +466,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(eval_ctx, vc); index = ED_view3d_backbuf_sample_rect( eval_ctx, 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; @@ -817,7 +832,7 @@ BMFace *EDBM_face_find_nearest_ex( index = ED_view3d_backbuf_sample(eval_ctx, 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; } @@ -895,8 +910,8 @@ BMFace *EDBM_face_find_nearest(const struct EvaluationContext *eval_ctx, ViewCon #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 */ @@ -914,7 +929,7 @@ static int unified_findnearest( float dist = dist_init; BMFace *efa_zbuf = NULL; BMEdge *eed_zbuf = NULL; - + BMVert *eve = NULL; BMEdge *eed = NULL; BMFace *efa = NULL; @@ -976,8 +991,10 @@ static int unified_findnearest( /** \} */ +/* -------------------------------------------------------------------- */ +/** \name Select Similar (Vert/Edge/Face) Operator + * \{ */ -/* **************** SIMILAR "group" SELECTS. FACE, EDGE AND VERTEX ************** */ static const EnumPropertyItem prop_similar_compare_types[] = { {SIM_CMP_EQ, "EQUAL", 0, "Equal", ""}, {SIM_CMP_GT, "GREATER", 0, "Greater", ""}, @@ -1054,7 +1071,7 @@ static int similar_face_select_exec(bContext *C, wmOperator *op) EDBM_update_generic(em, false, false); return OPERATOR_FINISHED; -} +} /* ***************************************************** */ @@ -1160,8 +1177,9 @@ static int edbm_select_similar_exec(bContext *C, wmOperator *op) else return similar_face_select_exec(C, op); } -static const 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; @@ -1213,15 +1231,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); @@ -1231,9 +1249,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) { @@ -1254,9 +1274,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); @@ -1321,8 +1342,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) { @@ -1393,12 +1417,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; @@ -1453,7 +1480,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; @@ -1462,17 +1489,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]; @@ -1489,7 +1516,7 @@ 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->data); return OPERATOR_FINISHED; @@ -1501,23 +1528,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) { @@ -1572,7 +1599,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) { EvaluationContext eval_ctx; @@ -1651,11 +1677,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 @@ -1682,7 +1712,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);*/ @@ -1706,14 +1738,15 @@ static bool mouse_mesh_loop(bContext *C, const int mval[2], bool extend, bool de 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; } @@ -1728,14 +1761,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"); @@ -1749,11 +1782,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; @@ -1763,7 +1796,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); @@ -1808,6 +1846,12 @@ 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); @@ -1839,10 +1883,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) { EvaluationContext eval_ctx; @@ -1978,6 +2027,12 @@ bool EDBM_select_pick(bContext *C, const int mval[2], bool extend, bool deselect return false; } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Select Mode Utilities + * \{ */ + static void edbm_strip_selections(BMEditMesh *em) { BMEditSelection *ese, *nextese; @@ -2016,11 +2071,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) @@ -2183,8 +2238,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); @@ -2280,9 +2336,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 */ @@ -2305,6 +2362,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; @@ -2333,7 +2396,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)) @@ -2356,9 +2419,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; @@ -2391,8 +2462,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 @@ -2713,6 +2789,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) @@ -2916,15 +2998,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"); @@ -2937,6 +3019,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) { @@ -3012,6 +3099,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) { @@ -3083,6 +3175,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) { @@ -3131,7 +3228,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) { @@ -3155,13 +3256,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); @@ -3184,13 +3291,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. */ @@ -3414,12 +3527,17 @@ void MESH_OT_select_nth(wmOperatorType *ot) void em_setup_viewcontext(bContext *C, ViewContext *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) { @@ -3460,20 +3578,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); @@ -3541,20 +3665,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); @@ -3576,12 +3706,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)) { @@ -3591,7 +3721,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)) { @@ -3622,11 +3752,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; @@ -3646,6 +3776,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); @@ -3692,9 +3828,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; } @@ -3711,11 +3847,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)) { @@ -3782,6 +3924,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) @@ -3868,6 +4015,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); @@ -3881,22 +4034,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); @@ -3931,29 +4084,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) { 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 */ @@ -3967,9 +4127,9 @@ static int loop_find_region(BMLoop *l, int flag, } } } - + BLI_array_free(stack); - + *region_out = region; return BLI_array_count(region); } @@ -3979,10 +4139,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; @@ -4001,7 +4160,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__); @@ -4015,21 +4174,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; @@ -4051,26 +4210,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; } @@ -4081,25 +4240,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); @@ -4119,9 +4276,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 *************************/ +/** \} */ |