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:
authorSv. Lockal <lockalsash@gmail.com>2013-04-21 23:04:04 +0400
committerSv. Lockal <lockalsash@gmail.com>2013-04-21 23:04:04 +0400
commitedab8151374cbdbd877c2727170163a1ab33e8d8 (patch)
tree7a9323fde8013f830b1e59a4cceacba2627b231f
parentc44888bbbe377c88effaa4805548967ad46c7686 (diff)
Add Select More (ctrl np+) and Select Less (ctrl np-) to UV editor
These tools allow to extend or shrink uv selection like in edit mode, but also take selection mode, sync mode and sticky mode into account.
-rw-r--r--release/scripts/startup/bl_ui/space_image.py5
-rw-r--r--source/blender/editors/uvedit/uvedit_ops.c215
2 files changed, 220 insertions, 0 deletions
diff --git a/release/scripts/startup/bl_ui/space_image.py b/release/scripts/startup/bl_ui/space_image.py
index f9390cec912..5aadeb1153f 100644
--- a/release/scripts/startup/bl_ui/space_image.py
+++ b/release/scripts/startup/bl_ui/space_image.py
@@ -115,6 +115,11 @@ class IMAGE_MT_select(Menu):
layout.separator()
+ layout.operator("uv.select_less", text="Less")
+ layout.operator("uv.select_more", text="More")
+
+ layout.separator()
+
layout.operator("uv.select_split")
diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c
index 7fbcfa1c941..10789f282e7 100644
--- a/source/blender/editors/uvedit/uvedit_ops.c
+++ b/source/blender/editors/uvedit/uvedit_ops.c
@@ -1321,6 +1321,215 @@ static float *uv_sel_co_from_eve(Scene *scene, Image *ima, BMEditMesh *em, BMVer
return NULL;
}
+/* ******************** select more ******************** */
+static void uv_tag_sticky_grow(Scene *scene, Image *ima, BMLoop *start_loop, int sticky,
+ int cd_loop_uv_offset, int cd_poly_tex_offset)
+{
+ BMIter iter;
+ BMLoop *l;
+ MTexPoly *tf;
+ MLoopUV *luv1, *luv2;
+
+ BM_elem_flag_enable(start_loop, BM_ELEM_TAG);
+
+ switch (sticky) {
+ case SI_STICKY_LOC:
+ luv1 = BM_ELEM_CD_GET_VOID_P(start_loop, cd_loop_uv_offset);
+
+ BM_ITER_ELEM (l, &iter, start_loop->v, BM_LOOPS_OF_VERT) {
+ tf = BM_ELEM_CD_GET_VOID_P(l->f, cd_poly_tex_offset);
+
+ if (uvedit_face_visible_test(scene, ima, l->f, tf)) {
+ luv2 = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+
+ if (compare_v2v2(luv1->uv, luv2->uv, STD_UV_CONNECT_LIMIT)) {
+ BM_elem_flag_enable(l, BM_ELEM_TAG);
+ }
+ }
+ }
+ break;
+ case SI_STICKY_VERTEX:
+ BM_ITER_ELEM (l, &iter, start_loop->v, BM_LOOPS_OF_VERT) {
+ tf = BM_ELEM_CD_GET_VOID_P(l->f, cd_poly_tex_offset);
+
+ if (uvedit_face_visible_test(scene, ima, l->f, tf)) {
+ BM_elem_flag_enable(l, BM_ELEM_TAG);
+ }
+ }
+ break;
+ }
+}
+
+static int uv_select_more_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ Scene *scene = CTX_data_scene(C);
+ Object *obedit = CTX_data_edit_object(C);
+ Image *ima = CTX_data_edit_image(C);
+ SpaceImage *sima = CTX_wm_space_image(C);
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+
+ BMFace *efa;
+ BMLoop *l, *lf;
+ BMIter iter, liter, iterf;
+ ToolSettings *ts = scene->toolsettings;
+ int sticky = sima->sticky;
+
+ const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
+
+ if (ts->uv_flag & UV_SYNC_SELECTION) {
+ EDBM_select_more(em);
+ WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
+ return OPERATOR_FINISHED;
+ }
+
+ /* clear tags */
+ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
+ BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
+ BM_elem_flag_disable(l->next, BM_ELEM_TAG);
+ }
+ }
+
+ /* mark loops to be selected */
+ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
+ MTexPoly *tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
+
+ if (uvedit_face_visible_test(scene, ima, efa, tf)) {
+ BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
+
+ MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+
+ if (luv->flag & MLOOPUV_VERTSEL) {
+ if (ts->uv_selectmode == UV_SELECT_FACE) {
+ BM_ITER_ELEM (lf, &iterf, l->f, BM_LOOPS_OF_FACE) {
+ uv_tag_sticky_grow(scene, ima, lf, sticky, cd_loop_uv_offset, cd_poly_tex_offset);
+ }
+ }
+ else {
+ if (l->next) {
+ uv_tag_sticky_grow(scene, ima, l->next, sticky, cd_loop_uv_offset, cd_poly_tex_offset);
+ }
+ if (l->prev) {
+ uv_tag_sticky_grow(scene, ima, l->prev, sticky, cd_loop_uv_offset, cd_poly_tex_offset);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /* select tagged loops */
+ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
+ BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
+ if (BM_elem_flag_test(l, BM_ELEM_TAG)) {
+ uvedit_uv_select_enable(em, scene, l, FALSE);
+ }
+ }
+ }
+
+ WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
+
+ return OPERATOR_FINISHED;
+}
+
+static void UV_OT_select_more(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Select More";
+ ot->description = "Select more UV vertices connected to initial selection";
+ ot->idname = "UV_OT_select_more";
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* api callbacks */
+ ot->exec = uv_select_more_exec;
+ ot->poll = ED_operator_uvedit;
+}
+
+/* ******************** select less ******************** */
+static int uv_select_less_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ Scene *scene = CTX_data_scene(C);
+ Object *obedit = CTX_data_edit_object(C);
+ Image *ima = CTX_data_edit_image(C);
+ SpaceImage *sima = CTX_wm_space_image(C);
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+
+ BMFace *efa;
+ BMLoop *l;
+ BMIter iter, liter;
+ int sticky = sima->sticky;
+
+ ToolSettings *ts = scene->toolsettings;
+
+ const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
+
+ if (ts->uv_flag & UV_SYNC_SELECTION) {
+ EDBM_select_less(em);
+ WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
+ return OPERATOR_FINISHED;
+ }
+
+ /* clear tags */
+ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
+ BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
+ BM_elem_flag_disable(l->next, BM_ELEM_TAG);
+ }
+ }
+
+ /* mark loops to be deselected */
+ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
+ MTexPoly *tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
+
+ if (uvedit_face_visible_test(scene, ima, efa, tf)) {
+ BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
+ MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+
+ if (luv->flag & MLOOPUV_VERTSEL) {
+ if (l->next) {
+ MLoopUV *luv_next = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_uv_offset);
+ if (!(luv_next->flag & MLOOPUV_VERTSEL)) {
+ uv_tag_sticky_grow(scene, ima, l, sticky, cd_loop_uv_offset, cd_poly_tex_offset);
+ }
+ }
+ if (l->prev) {
+ MLoopUV *luv_prev = BM_ELEM_CD_GET_VOID_P(l->prev, cd_loop_uv_offset);
+ if (!(luv_prev->flag & MLOOPUV_VERTSEL)) {
+ uv_tag_sticky_grow(scene, ima, l, sticky, cd_loop_uv_offset, cd_poly_tex_offset);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /* deselect tagged loops */
+ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
+ BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
+ if (BM_elem_flag_test(l, BM_ELEM_TAG)) {
+ uvedit_uv_select_disable(em, scene, l);
+ }
+ }
+ }
+
+ WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
+
+ return OPERATOR_FINISHED;
+}
+
+static void UV_OT_select_less(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Select Less";
+ ot->description = "Deselect UV vertices at the boundary of each selection region";
+ ot->idname = "UV_OT_select_less";
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* api callbacks */
+ ot->exec = uv_select_less_exec;
+ ot->poll = ED_operator_uvedit;
+}
+
/* ******************** align operator **************** */
static void uv_weld_align(bContext *C, int tool)
@@ -4031,6 +4240,8 @@ void ED_operatortypes_uvedit(void)
WM_operatortype_append(UV_OT_select_border);
WM_operatortype_append(UV_OT_select_lasso);
WM_operatortype_append(UV_OT_circle_select);
+ WM_operatortype_append(UV_OT_select_more);
+ WM_operatortype_append(UV_OT_select_less);
WM_operatortype_append(UV_OT_snap_cursor);
WM_operatortype_append(UV_OT_snap_selected);
@@ -4103,6 +4314,10 @@ void ED_keymap_uvedit(wmKeyConfig *keyconf)
RNA_boolean_set(WM_keymap_add_item(keymap, "UV_OT_select_linked", LKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0)->ptr, "extend", TRUE);
RNA_boolean_set(WM_keymap_add_item(keymap, "UV_OT_select_linked_pick", LKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "extend", TRUE);
+ /* select more/less */
+ WM_keymap_add_item(keymap, "UV_OT_select_more", PADPLUSKEY, KM_PRESS, KM_CTRL, 0);
+ WM_keymap_add_item(keymap, "UV_OT_select_less", PADMINUS, KM_PRESS, KM_CTRL, 0);
+
WM_keymap_add_item(keymap, "UV_OT_unlink_selected", LKEY, KM_PRESS, KM_ALT, 0);
kmi = WM_keymap_add_item(keymap, "UV_OT_select_all", AKEY, KM_PRESS, 0, 0);
RNA_enum_set(kmi->ptr, "action", SEL_TOGGLE);