From cda05639dff6e2c0d07035de14214911c3fb8255 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Mon, 20 Nov 2017 00:28:03 +1300 Subject: Fix T53229: "Sample Keyframes" errors with multiple pairs of keyframes selected There were 2 issues here (first was the one reported): 1) Curve shape changes if multiple consecutive pairs of keyframes are selected. The problem is that after the first pair is handled, subsequent pairs get sampled on the basis of the modified curve. 2) With multiple separate "islands" selected, unselected points in between would get ignored, causing the entire curve to get sampled. --- source/blender/editors/animation/keyframes_general.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/animation/keyframes_general.c b/source/blender/editors/animation/keyframes_general.c index 97f53561bfe..bf5d4ec0300 100644 --- a/source/blender/editors/animation/keyframes_general.c +++ b/source/blender/editors/animation/keyframes_general.c @@ -448,6 +448,18 @@ void sample_fcurve(FCurve *fcu) /* check if selected, and which end this is */ if (BEZT_ISSEL_ANY(bezt)) { if (start) { + /* If next bezt is also selected, don't start sampling yet, + * but instead wait for that one to reconsider, to avoid + * changing the curve when sampling consecutive segments + * (T53229) + */ + if (i < fcu->totvert - 1) { + BezTriple *next = &fcu->bezt[i + 1]; + if (BEZT_ISSEL_ANY(next)) { + continue; + } + } + /* set end */ end = bezt; @@ -480,8 +492,8 @@ void sample_fcurve(FCurve *fcu) i += (range - 1); } - /* bezt was selected, so it now marks the start of a whole new chain to search */ - start = bezt; + /* the current selection island has ended, so start again from scratch */ + start = NULL; end = NULL; } else { -- cgit v1.2.3 From c01ffefb687260c11b3eae8411e5af051f0ce10a Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Mon, 20 Nov 2017 00:31:07 +1300 Subject: Pasting poses now updates motion paths --- source/blender/editors/armature/pose_transform.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'source/blender/editors') diff --git a/source/blender/editors/armature/pose_transform.c b/source/blender/editors/armature/pose_transform.c index 2d86610e065..3707b914ecb 100644 --- a/source/blender/editors/armature/pose_transform.c +++ b/source/blender/editors/armature/pose_transform.c @@ -484,12 +484,15 @@ static int pose_paste_exec(bContext *C, wmOperator *op) bPoseChannel *chan; const bool flip = RNA_boolean_get(op->ptr, "flipped"); bool selOnly = RNA_boolean_get(op->ptr, "selected_mask"); + /* Get KeyingSet to use. */ KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_WHOLE_CHARACTER_ID); + /* Sanity checks. */ if (ELEM(NULL, ob, ob->pose)) { return OPERATOR_CANCELLED; } + /* Read copy buffer .blend file. */ char str[FILE_MAX]; Main *tmp_bmain = BKE_main_new(); @@ -505,6 +508,7 @@ static int pose_paste_exec(bContext *C, wmOperator *op) BKE_main_free(tmp_bmain); return OPERATOR_CANCELLED; } + Object *object_from = tmp_bmain->object.first; bPose *pose_from = object_from->pose; if (pose_from == NULL) { @@ -512,6 +516,7 @@ static int pose_paste_exec(bContext *C, wmOperator *op) BKE_main_free(tmp_bmain); return OPERATOR_CANCELLED; } + /* If selOnly option is enabled, if user hasn't selected any bones, * just go back to default behavior to be more in line with other * pose tools. @@ -521,6 +526,7 @@ static int pose_paste_exec(bContext *C, wmOperator *op) selOnly = false; } } + /* Safely merge all of the channels in the buffer pose into any * existing pose. */ @@ -535,8 +541,15 @@ static int pose_paste_exec(bContext *C, wmOperator *op) } } BKE_main_free(tmp_bmain); + /* Update event for pose and deformation children. */ DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + + /* Recalculate paths if any of the bones have paths... */ + if ((ob->pose->avs.path_bakeflag & MOTIONPATH_BAKE_HAS_PATHS)) { + ED_pose_recalculate_paths(scene, ob); + } + /* Notifiers for updates, */ WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob); -- cgit v1.2.3 From c5f59f5854732f7d2c2020ca7ec67f1eaa043b78 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Mon, 20 Nov 2017 01:00:27 +1300 Subject: Tweaks to make it easier to update bone motion paths (without the active bone needing to have any paths itself) This commit introduces the following changes: * Modified the poll callback on the "Update Paths" operator for bones so that it only checks if there are bones that have motion paths (instead of checking whether the active bone has paths). This makes it easier to update paths without having to first select one that has them - useful when the paths are all on hidden/hard-to-select bones. * Add a readonly property, "has_motion_paths" to the animviz.motion_path RNA struct, providing easier access to the internal flag used above. This makes it possible for the UI to display the "Update" button without having to check various bones for motion paths. Notes: * The flag being used in these changes already existed, and was only really intended for internal use. However, since it was already used in many places for determining if auto-update of all bone paths was needed (e.g. after certain editing ops), it should be safe to use here too. * The update_paths operator currently bakes all paths when activated, so there's currently no loss of functionality with changing to not checking if the active bone has any paths (e.g. we couldn't only update the active bone only either). That is still listed as a todo in the code. --- source/blender/editors/armature/pose_edit.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/armature/pose_edit.c b/source/blender/editors/armature/pose_edit.c index c49a370c286..57c01157f8e 100644 --- a/source/blender/editors/armature/pose_edit.c +++ b/source/blender/editors/armature/pose_edit.c @@ -265,8 +265,8 @@ void POSE_OT_paths_calculate(wmOperatorType *ot) static int pose_update_paths_poll(bContext *C) { if (ED_operator_posemode_exclusive(C)) { - bPoseChannel *pchan = CTX_data_active_pose_bone(C); - return (pchan && pchan->mpath); + Object *ob = CTX_data_active_object(C); + return (ob->pose->avs.path_bakeflag & MOTIONPATH_BAKE_HAS_PATHS) != 0; } return false; -- cgit v1.2.3 From cc1253a5d92c0a5241263f021fb2ca7e6b2c06f6 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Mon, 20 Nov 2017 01:47:21 +1300 Subject: Fix: "Lock Markers" option was not being obeyed by the "Sync Markers (when transforming)" option --- source/blender/editors/animation/anim_markers.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c index 30aaee8cbd9..04398e88499 100644 --- a/source/blender/editors/animation/anim_markers.c +++ b/source/blender/editors/animation/anim_markers.c @@ -133,10 +133,13 @@ int ED_markers_post_apply_transform(ListBase *markers, Scene *scene, int mode, f float cfra = (float)CFRA; int changed_tot = 0; - /* sanity check */ - if (markers == NULL) + /* sanity check - no markers, or locked markers */ + if ((scene->toolsettings->lock_markers) || + (markers == NULL)) + { return changed_tot; - + } + /* affect selected markers - it's unlikely that we will want to affect all in this way? */ for (marker = markers->first; marker; marker = marker->next) { if (marker->flag & SELECT) { -- cgit v1.2.3 From 6f578740ef1b29723d37e9ec09721f58879615c1 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Mon, 20 Nov 2017 02:55:17 +1300 Subject: Fix T53300: Bone Extrude via Ctrl + Click is not done from active bone tail --- source/blender/editors/armature/armature_add.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source/blender/editors') diff --git a/source/blender/editors/armature/armature_add.c b/source/blender/editors/armature/armature_add.c index e419100bd04..3d0981ea6c8 100644 --- a/source/blender/editors/armature/armature_add.c +++ b/source/blender/editors/armature/armature_add.c @@ -945,6 +945,7 @@ static int armature_extrude_exec(bContext *C, wmOperator *op) } /* if only one bone, make this one active */ if (totbone == 1 && first) arm->act_edbone = first; + else arm->act_edbone = newbone; if (totbone == 0) return OPERATOR_CANCELLED; -- cgit v1.2.3 From 2317fa6dcc6c7b3aae11a0916130277ed723333b Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Mon, 20 Nov 2017 02:56:40 +1300 Subject: Cleanup - Style --- source/blender/editors/armature/armature_add.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/armature/armature_add.c b/source/blender/editors/armature/armature_add.c index 3d0981ea6c8..368d54fc3ad 100644 --- a/source/blender/editors/armature/armature_add.c +++ b/source/blender/editors/armature/armature_add.c @@ -944,10 +944,16 @@ static int armature_extrude_exec(bContext *C, wmOperator *op) } } /* if only one bone, make this one active */ - if (totbone == 1 && first) arm->act_edbone = first; - else arm->act_edbone = newbone; + if (totbone == 1 && first) { + arm->act_edbone = first; + } + else { + arm->act_edbone = newbone; + } - if (totbone == 0) return OPERATOR_CANCELLED; + if (totbone == 0) { + return OPERATOR_CANCELLED; + } /* Transform the endpoints */ ED_armature_sync_selection(arm->edbo); -- cgit v1.2.3 From d2b03d23647197f933d7afdeb53da35ed074bf94 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Mon, 20 Nov 2017 03:06:13 +1300 Subject: Fix: Undo pushes were missing for Add/Remove Driver Variable buttons, and Remove Driver button --- source/blender/editors/space_graph/graph_buttons.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_graph/graph_buttons.c b/source/blender/editors/space_graph/graph_buttons.c index 985cca7c4af..df6bd01144d 100644 --- a/source/blender/editors/space_graph/graph_buttons.c +++ b/source/blender/editors/space_graph/graph_buttons.c @@ -64,6 +64,7 @@ #include "ED_anim_api.h" #include "ED_keyframing.h" #include "ED_screen.h" +#include "ED_util.h" #include "UI_interface.h" #include "UI_resources.h" @@ -503,25 +504,28 @@ static void driver_remove_cb(bContext *C, void *ale_v, void *UNUSED(arg)) /* call API method to remove this driver */ ANIM_remove_driver(reports, id, fcu->rna_path, fcu->array_index, 0); + ED_undo_push(C, "Remove Driver"); } /* callback to add a target variable to the active driver */ -static void driver_add_var_cb(bContext *UNUSED(C), void *driver_v, void *UNUSED(arg)) +static void driver_add_var_cb(bContext *C, void *driver_v, void *UNUSED(arg)) { ChannelDriver *driver = (ChannelDriver *)driver_v; /* add a new variable */ driver_add_new_variable(driver); + ED_undo_push(C, "Add Driver Variable"); } /* callback to remove target variable from active driver */ -static void driver_delete_var_cb(bContext *UNUSED(C), void *driver_v, void *dvar_v) +static void driver_delete_var_cb(bContext *C, void *driver_v, void *dvar_v) { ChannelDriver *driver = (ChannelDriver *)driver_v; DriverVar *dvar = (DriverVar *)dvar_v; /* remove the active variable */ driver_free_variable_ex(driver, dvar); + ED_undo_push(C, "Delete Driver Variable"); } /* callback to report why a driver variable is invalid */ -- cgit v1.2.3 From 92ea28101725631f8ebe6c6cfd37007175f1af03 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 20 Nov 2017 01:35:49 +1100 Subject: Cleanup: remove BKE_utildefines This was meant to be used for less general macros but was never used. Rename BKE_BIT_TEST_SET to SET_FLAG_FROM_TEST --- source/blender/editors/mesh/editface.c | 3 +-- source/blender/editors/object/object_lattice.c | 3 +-- source/blender/editors/space_view3d/view3d_select.c | 8 +++----- source/blender/editors/transform/transform_generics.c | 3 +-- 4 files changed, 6 insertions(+), 11 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/mesh/editface.c b/source/blender/editors/mesh/editface.c index 6c6c106b19a..4336fff45d5 100644 --- a/source/blender/editors/mesh/editface.c +++ b/source/blender/editors/mesh/editface.c @@ -42,7 +42,6 @@ #include "BKE_mesh.h" #include "BKE_context.h" #include "BKE_editmesh.h" -#include "BKE_utildefines.h" #include "BIF_gl.h" @@ -231,7 +230,7 @@ static void select_linked_tfaces_with_seams(Mesh *me, const unsigned int index, for (a = 0, mp = me->mpoly; a < me->totpoly; a++, mp++) { if (BLI_BITMAP_TEST(poly_tag, a)) { - BKE_BIT_TEST_SET(mp->flag, select, ME_FACE_SEL); + SET_FLAG_FROM_TEST(mp->flag, select, ME_FACE_SEL); } } diff --git a/source/blender/editors/object/object_lattice.c b/source/blender/editors/object/object_lattice.c index ac8d438d9e6..57053ddc020 100644 --- a/source/blender/editors/object/object_lattice.c +++ b/source/blender/editors/object/object_lattice.c @@ -57,7 +57,6 @@ #include "BKE_lattice.h" #include "BKE_deform.h" #include "BKE_report.h" -#include "BKE_utildefines.h" #include "ED_lattice.h" #include "ED_object.h" @@ -369,7 +368,7 @@ static int lattice_select_more_less(bContext *C, const bool select) lattice_test_bitmap_uvw(lt, selpoints, u, v, w + 1, select) || lattice_test_bitmap_uvw(lt, selpoints, u, v, w - 1, select)) { - BKE_BIT_TEST_SET(bp->f1, select, SELECT); + SET_FLAG_FROM_TEST(bp->f1, select, SELECT); } } bp++; diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index 67597729d15..05cf552e5cc 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -70,8 +70,6 @@ #include "BKE_paint.h" #include "BKE_editmesh.h" #include "BKE_tracking.h" -#include "BKE_utildefines.h" - #include "BIF_gl.h" #include "BIF_glutil.h" @@ -726,7 +724,7 @@ static void do_lasso_select_meshobject__doSelectVert(void *userData, MVert *mv, if (BLI_rctf_isect_pt_v(data->rect_fl, screen_co) && BLI_lasso_is_point_inside(data->mcords, data->moves, screen_co[0], screen_co[1], IS_CLIPPED)) { - BKE_BIT_TEST_SET(mv->flag, data->select, SELECT); + SET_FLAG_FROM_TEST(mv->flag, data->select, SELECT); } } static void do_lasso_select_paintvert(ViewContext *vc, const int mcords[][2], short moves, bool extend, bool select) @@ -1672,7 +1670,7 @@ static void do_paintvert_box_select__doSelectVert(void *userData, MVert *mv, con BoxSelectUserData *data = userData; if (BLI_rctf_isect_pt_v(data->rect_fl, screen_co)) { - BKE_BIT_TEST_SET(mv->flag, data->select, SELECT); + SET_FLAG_FROM_TEST(mv->flag, data->select, SELECT); } } static int do_paintvert_box_select(ViewContext *vc, rcti *rect, bool select, bool extend) @@ -2498,7 +2496,7 @@ static void paint_vertsel_circle_select_doSelectVert(void *userData, MVert *mv, CircleSelectUserData *data = userData; if (len_squared_v2v2(data->mval_fl, screen_co) <= data->radius_squared) { - BKE_BIT_TEST_SET(mv->flag, data->select, SELECT); + SET_FLAG_FROM_TEST(mv->flag, data->select, SELECT); } } static void paint_vertsel_circle_select(ViewContext *vc, const bool select, const int mval[2], float rad) diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index 179b68dd270..277e01d1e2b 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -82,7 +82,6 @@ #include "BKE_editmesh.h" #include "BKE_tracking.h" #include "BKE_mask.h" -#include "BKE_utildefines.h" #include "ED_anim_api.h" #include "ED_armature.h" @@ -1208,7 +1207,7 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve if (prop_id && (prop = RNA_struct_find_property(op->ptr, prop_id)) && RNA_property_is_set(op->ptr, prop)) { - BKE_BIT_TEST_SET(t->flag, RNA_property_boolean_get(op->ptr, prop), T_ALT_TRANSFORM); + SET_FLAG_FROM_TEST(t->flag, RNA_property_boolean_get(op->ptr, prop), T_ALT_TRANSFORM); } } -- cgit v1.2.3 From 0a69e3b307f05aeab8bd84f69560b4118c9bfaf2 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 20 Nov 2017 02:28:07 +1100 Subject: Option not to select with un-hide D1518 from @mba105 w/ edits --- source/blender/editors/armature/armature_edit.c | 8 ++-- source/blender/editors/armature/pose_edit.c | 17 +++++--- source/blender/editors/curve/editcurve.c | 11 +++-- source/blender/editors/gpencil/gpencil_data.c | 52 +++++++++++++++++++++-- source/blender/editors/include/ED_mesh.h | 4 +- source/blender/editors/mask/mask_ops.c | 7 ++- source/blender/editors/mesh/editface.c | 6 +-- source/blender/editors/mesh/editmesh_tools.c | 9 ++-- source/blender/editors/mesh/editmesh_utils.c | 4 +- source/blender/editors/metaball/mball_edit.c | 19 ++++++--- source/blender/editors/object/object_edit.c | 7 ++- source/blender/editors/physics/particle_edit.c | 13 ++++-- source/blender/editors/sculpt_paint/paint_utils.c | 7 +-- source/blender/editors/space_graph/graph_ops.c | 12 ++++-- source/blender/editors/uvedit/uvedit_ops.c | 18 +++++--- 15 files changed, 139 insertions(+), 55 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/armature/armature_edit.c b/source/blender/editors/armature/armature_edit.c index ab9a3e068d0..a2fbfe645f7 100644 --- a/source/blender/editors/armature/armature_edit.c +++ b/source/blender/editors/armature/armature_edit.c @@ -1564,17 +1564,18 @@ void ARMATURE_OT_hide(wmOperatorType *ot) RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "Hide unselected rather than selected"); } -static int armature_reveal_exec(bContext *C, wmOperator *UNUSED(op)) +static int armature_reveal_exec(bContext *C, wmOperator *op) { Object *obedit = CTX_data_edit_object(C); bArmature *arm = obedit->data; EditBone *ebone; + const bool select = RNA_boolean_get(op->ptr, "select"); for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { if (arm->layer & ebone->layer) { if (ebone->flag & BONE_HIDDEN_A) { if (!(ebone->flag & BONE_UNSELECTABLE)) { - ebone->flag |= (BONE_TIPSEL | BONE_SELECTED | BONE_ROOTSEL); + SET_FLAG_FROM_TEST(ebone->flag, select, (BONE_TIPSEL | BONE_SELECTED | BONE_ROOTSEL)); } ebone->flag &= ~BONE_HIDDEN_A; } @@ -1593,7 +1594,7 @@ void ARMATURE_OT_reveal(wmOperatorType *ot) /* identifiers */ ot->name = "Reveal Bones"; ot->idname = "ARMATURE_OT_reveal"; - ot->description = "Unhide all bones that have been tagged to be hidden in Edit Mode"; + ot->description = "Reveal all bones hidden in Edit Mode"; /* api callbacks */ ot->exec = armature_reveal_exec; @@ -1602,4 +1603,5 @@ void ARMATURE_OT_reveal(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + RNA_def_boolean(ot->srna, "select", true, "Select", ""); } diff --git a/source/blender/editors/armature/pose_edit.c b/source/blender/editors/armature/pose_edit.c index 57c01157f8e..acbf23ecf82 100644 --- a/source/blender/editors/armature/pose_edit.c +++ b/source/blender/editors/armature/pose_edit.c @@ -1098,16 +1098,18 @@ void POSE_OT_hide(wmOperatorType *ot) RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", ""); } -static int show_pose_bone_cb(Object *ob, Bone *bone, void *UNUSED(ptr)) +static int show_pose_bone_cb(Object *ob, Bone *bone, void *data) { + const bool select = GET_INT_FROM_POINTER(data); + bArmature *arm = ob->data; if (arm->layer & bone->layer) { if (bone->flag & BONE_HIDDEN_P) { - bone->flag &= ~BONE_HIDDEN_P; if (!(bone->flag & BONE_UNSELECTABLE)) { - bone->flag |= BONE_SELECTED; + SET_FLAG_FROM_TEST(bone->flag, select, BONE_SELECTED); } + bone->flag &= ~BONE_HIDDEN_P; } } @@ -1115,12 +1117,13 @@ static int show_pose_bone_cb(Object *ob, Bone *bone, void *UNUSED(ptr)) } /* active object is armature in posemode, poll checked */ -static int pose_reveal_exec(bContext *C, wmOperator *UNUSED(op)) +static int pose_reveal_exec(bContext *C, wmOperator *op) { Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C)); bArmature *arm = ob->data; + const bool select = RNA_boolean_get(op->ptr, "select"); - bone_looper(ob, arm->bonebase.first, NULL, show_pose_bone_cb); + bone_looper(ob, arm->bonebase.first, SET_INT_IN_POINTER(select), show_pose_bone_cb); /* note, notifier might evolve */ WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob); @@ -1133,7 +1136,7 @@ void POSE_OT_reveal(wmOperatorType *ot) /* identifiers */ ot->name = "Reveal Selected"; ot->idname = "POSE_OT_reveal"; - ot->description = "Unhide all bones that have been tagged to be hidden in Pose Mode"; + ot->description = "Reveal all bones hidden in Pose Mode"; /* api callbacks */ ot->exec = pose_reveal_exec; @@ -1141,6 +1144,8 @@ void POSE_OT_reveal(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + RNA_def_boolean(ot->srna, "select", true, "Select", ""); } /* ********************************************** */ diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index 4916c206a85..fc363475608 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -2926,7 +2926,7 @@ void CURVE_OT_hide(wmOperatorType *ot) /********************** reveal operator *********************/ -static int reveal_exec(bContext *C, wmOperator *UNUSED(op)) +static int reveal_exec(bContext *C, wmOperator *op) { Object *obedit = CTX_data_edit_object(C); ListBase *editnurb = object_editcurve_get(obedit); @@ -2934,6 +2934,7 @@ static int reveal_exec(bContext *C, wmOperator *UNUSED(op)) BPoint *bp; BezTriple *bezt; int a; + const bool select = RNA_boolean_get(op->ptr, "select"); for (nu = editnurb->first; nu; nu = nu->next) { nu->hide = 0; @@ -2942,7 +2943,7 @@ static int reveal_exec(bContext *C, wmOperator *UNUSED(op)) a = nu->pntsu; while (a--) { if (bezt->hide) { - select_beztriple(bezt, SELECT, SELECT, HIDDEN); + select_beztriple(bezt, select, SELECT, HIDDEN); bezt->hide = 0; } bezt++; @@ -2953,7 +2954,7 @@ static int reveal_exec(bContext *C, wmOperator *UNUSED(op)) a = nu->pntsu * nu->pntsv; while (a--) { if (bp->hide) { - select_bpoint(bp, SELECT, SELECT, HIDDEN); + select_bpoint(bp, select, SELECT, HIDDEN); bp->hide = 0; } bp++; @@ -2972,7 +2973,7 @@ void CURVE_OT_reveal(wmOperatorType *ot) /* identifiers */ ot->name = "Reveal Hidden"; ot->idname = "CURVE_OT_reveal"; - ot->description = "Show again hidden control points"; + ot->description = "Reveal hidden control points"; /* api callbacks */ ot->exec = reveal_exec; @@ -2980,6 +2981,8 @@ void CURVE_OT_reveal(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + RNA_def_boolean(ot->srna, "select", true, "Select", ""); } /********************** subdivide operator *********************/ diff --git a/source/blender/editors/gpencil/gpencil_data.c b/source/blender/editors/gpencil/gpencil_data.c index 93c9d21e717..5bd5c9c74b9 100644 --- a/source/blender/editors/gpencil/gpencil_data.c +++ b/source/blender/editors/gpencil/gpencil_data.c @@ -423,18 +423,59 @@ static int gp_reveal_poll(bContext *C) return ED_gpencil_data_get_active(C) != NULL; } -static int gp_reveal_exec(bContext *C, wmOperator *UNUSED(op)) +static void gp_reveal_select_frame(bContext *C, bGPDframe *frame, bool select) +{ + bGPDstroke *gps; + for (gps = frame->strokes.first; gps; gps = gps->next) { + + /* only deselect strokes that are valid in this view */ + if (ED_gpencil_stroke_can_use(C, gps)) { + + /* (de)select points */ + int i; + bGPDspoint *pt; + for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { + SET_FLAG_FROM_TEST(pt->flag, select, GP_SPOINT_SELECT); + } + + /* (de)select stroke */ + SET_FLAG_FROM_TEST(gps->flag, select, GP_STROKE_SELECT); + } + } +} + +static int gp_reveal_exec(bContext *C, wmOperator *op) { bGPdata *gpd = ED_gpencil_data_get_active(C); bGPDlayer *gpl; - + const bool select = RNA_boolean_get(op->ptr, "select"); + /* sanity checks */ if (gpd == NULL) return OPERATOR_CANCELLED; - /* make all layers visible */ for (gpl = gpd->layers.first; gpl; gpl = gpl->next) { - gpl->flag &= ~GP_LAYER_HIDE; + + if (gpl->flag & GP_LAYER_HIDE) { + gpl->flag &= ~GP_LAYER_HIDE; + + /* select or deselect if requested, only on hidden layers */ + if (gpd->flag & GP_DATA_STROKE_EDITMODE) { + if (select) { + /* select all strokes on active frame only (same as select all operator) */ + if (gpl->actframe) { + gp_reveal_select_frame(C, gpl->actframe, true); + } + } + else { + /* deselect strokes on all frames (same as deselect all operator) */ + bGPDframe *gpf; + for (gpf = gpl->frames.first; gpf; gpf = gpf->next) { + gp_reveal_select_frame(C, gpf, false); + } + } + } + } } /* notifiers */ @@ -456,6 +497,9 @@ void GPENCIL_OT_reveal(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* props */ + RNA_def_boolean(ot->srna, "select", true, "Select", ""); } /* ***************** Lock/Unlock All Layers ************************ */ diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index c867df2d01a..c2c00ad5635 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -103,7 +103,7 @@ void undo_push_mesh(struct bContext *C, const char *name); bool EDBM_vert_color_check(struct BMEditMesh *em); void EDBM_mesh_hide(struct BMEditMesh *em, bool swap); -void EDBM_mesh_reveal(struct BMEditMesh *em); +void EDBM_mesh_reveal(struct BMEditMesh *em, bool select); void EDBM_update_generic(struct BMEditMesh *em, const bool do_tessface, const bool is_destructive); @@ -205,7 +205,7 @@ void paintface_select_linked(struct bContext *C, struct Object *ob, const int mv bool paintface_minmax(struct Object *ob, float r_min[3], float r_max[3]); void paintface_hide(struct Object *ob, const bool unselected); -void paintface_reveal(struct Object *ob); +void paintface_reveal(struct Object *ob, const bool select); void paintvert_deselect_all_visible(struct Object *ob, int action, bool flush_flags); void paintvert_select_ungrouped(struct Object *ob, bool extend, bool flush_flags); diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c index 101ef70fb70..97d5ee1eff0 100644 --- a/source/blender/editors/mask/mask_ops.c +++ b/source/blender/editors/mask/mask_ops.c @@ -1937,16 +1937,17 @@ void MASK_OT_handle_type_set(wmOperatorType *ot) /* ********* clear/set restrict view *********/ -static int mask_hide_view_clear_exec(bContext *C, wmOperator *UNUSED(op)) +static int mask_hide_view_clear_exec(bContext *C, wmOperator *op) { Mask *mask = CTX_data_edit_mask(C); MaskLayer *masklay; bool changed = false; + const bool select = RNA_boolean_get(op->ptr, "select"); for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { if (masklay->restrictflag & OB_RESTRICT_VIEW) { - ED_mask_layer_select_set(masklay, true); + ED_mask_layer_select_set(masklay, select); masklay->restrictflag &= ~OB_RESTRICT_VIEW; changed = true; } @@ -1977,6 +1978,8 @@ void MASK_OT_hide_view_clear(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + RNA_def_boolean(ot->srna, "select", true, "Select", ""); } static int mask_hide_view_set_exec(bContext *C, wmOperator *op) diff --git a/source/blender/editors/mesh/editface.c b/source/blender/editors/mesh/editface.c index 4336fff45d5..87c8c55b0a1 100644 --- a/source/blender/editors/mesh/editface.c +++ b/source/blender/editors/mesh/editface.c @@ -138,7 +138,7 @@ void paintface_hide(Object *ob, const bool unselected) } -void paintface_reveal(Object *ob) +void paintface_reveal(Object *ob, const bool select) { Mesh *me; MPoly *mpoly; @@ -151,8 +151,8 @@ void paintface_reveal(Object *ob) a = me->totpoly; while (a--) { if (mpoly->flag & ME_HIDE) { - mpoly->flag |= ME_FACE_SEL; - mpoly->flag -= ME_HIDE; + SET_FLAG_FROM_TEST(mpoly->flag, select, ME_FACE_SEL); + mpoly->flag &= ~ME_HIDE; } mpoly++; } diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index bf25f7ee7d1..bc251869e3d 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -1652,12 +1652,13 @@ void MESH_OT_hide(wmOperatorType *ot) RNA_def_boolean(ot->srna, "unselected", false, "Unselected", "Hide unselected rather than selected"); } -static int edbm_reveal_exec(bContext *C, wmOperator *UNUSED(op)) +static int edbm_reveal_exec(bContext *C, wmOperator *op) { Object *obedit = CTX_data_edit_object(C); BMEditMesh *em = BKE_editmesh_from_object(obedit); - - EDBM_mesh_reveal(em); + const bool select = RNA_boolean_get(op->ptr, "select"); + + EDBM_mesh_reveal(em, select); EDBM_update_generic(em, true, false); @@ -1677,6 +1678,8 @@ void MESH_OT_reveal(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + RNA_def_boolean(ot->srna, "select", true, "Select", ""); } static int edbm_normals_make_consistent_exec(bContext *C, wmOperator *op) diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c index c8151862b6c..fc568a8b8ee 100644 --- a/source/blender/editors/mesh/editmesh_utils.c +++ b/source/blender/editors/mesh/editmesh_utils.c @@ -1225,7 +1225,7 @@ void EDBM_mesh_hide(BMEditMesh *em, bool swap) } -void EDBM_mesh_reveal(BMEditMesh *em) +void EDBM_mesh_reveal(BMEditMesh *em, bool select) { const char iter_types[3] = {BM_VERTS_OF_MESH, BM_EDGES_OF_MESH, @@ -1264,7 +1264,7 @@ void EDBM_mesh_reveal(BMEditMesh *em) BM_ITER_MESH (ele, &iter, em->bm, iter_types[i]) { if (BM_elem_flag_test(ele, BM_ELEM_TAG)) { - BM_elem_select_set(em->bm, ele, true); + BM_elem_select_set(em->bm, ele, select); } } } diff --git a/source/blender/editors/metaball/mball_edit.c b/source/blender/editors/metaball/mball_edit.c index 009aa921e11..5b4078b98b7 100644 --- a/source/blender/editors/metaball/mball_edit.c +++ b/source/blender/editors/metaball/mball_edit.c @@ -542,19 +542,21 @@ void MBALL_OT_hide_metaelems(wmOperatorType *ot) /***************************** Unhide operator *****************************/ /* Unhide all edited MetaElems */ -static int reveal_metaelems_exec(bContext *C, wmOperator *UNUSED(op)) +static int reveal_metaelems_exec(bContext *C, wmOperator *op) { Object *obedit = CTX_data_edit_object(C); MetaBall *mb = (MetaBall *)obedit->data; - MetaElem *ml; - - ml = mb->editelems->first; + const bool select = RNA_boolean_get(op->ptr, "select"); + bool changed = false; - if (ml) { - while (ml) { + for (MetaElem *ml = mb->editelems->first; ml; ml = ml->next) { + if (ml->flag & MB_HIDE) { + SET_FLAG_FROM_TEST(ml->flag, select, SELECT); ml->flag &= ~MB_HIDE; - ml = ml->next; + changed = true; } + } + if (changed) { WM_event_add_notifier(C, NC_GEOM | ND_DATA, mb); DAG_id_tag_update(obedit->data, 0); } @@ -575,6 +577,9 @@ void MBALL_OT_reveal_metaelems(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* props */ + RNA_def_boolean(ot->srna, "select", true, "Select", ""); } /* Select MetaElement with mouse click (user can select radius circle or diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index 4e949c82a9f..d7c7976c344 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -133,7 +133,7 @@ Object *ED_object_active_context(bContext *C) /* ********* clear/set restrict view *********/ -static int object_hide_view_clear_exec(bContext *C, wmOperator *UNUSED(op)) +static int object_hide_view_clear_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); ScrArea *sa = CTX_wm_area(C); @@ -141,12 +141,13 @@ static int object_hide_view_clear_exec(bContext *C, wmOperator *UNUSED(op)) Scene *scene = CTX_data_scene(C); Base *base; bool changed = false; + const bool select = RNA_boolean_get(op->ptr, "select"); /* XXX need a context loop to handle such cases */ for (base = FIRSTBASE; base; base = base->next) { if ((base->lay & v3d->lay) && base->object->restrictflag & OB_RESTRICT_VIEW) { if (!(base->object->restrictflag & OB_RESTRICT_SELECT)) { - base->flag |= SELECT; + SET_FLAG_FROM_TEST(base->flag, select, SELECT); } base->object->flag = base->flag; base->object->restrictflag &= ~OB_RESTRICT_VIEW; @@ -176,6 +177,8 @@ void OBJECT_OT_hide_view_clear(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + RNA_def_boolean(ot->srna, "select", true, "Select", ""); } static int object_hide_view_set_exec(bContext *C, wmOperator *op) diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c index 199d5e0fbfa..da66ec44235 100644 --- a/source/blender/editors/physics/particle_edit.c +++ b/source/blender/editors/physics/particle_edit.c @@ -1950,11 +1950,12 @@ void PARTICLE_OT_hide(wmOperatorType *ot) /*************************** reveal operator **************************/ -static int reveal_exec(bContext *C, wmOperator *UNUSED(op)) +static int reveal_exec(bContext *C, wmOperator *op) { Object *ob= CTX_data_active_object(C); Scene *scene= CTX_data_scene(C); - PTCacheEdit *edit= PE_get_current(scene, ob); + PTCacheEdit *edit = PE_get_current(scene, ob); + const bool select = RNA_boolean_get(op->ptr, "select"); POINT_P; KEY_K; LOOP_POINTS { @@ -1962,8 +1963,9 @@ static int reveal_exec(bContext *C, wmOperator *UNUSED(op)) point->flag &= ~PEP_HIDE; point->flag |= PEP_EDIT_RECALC; - LOOP_KEYS - key->flag |= PEK_SELECT; + LOOP_KEYS { + SET_FLAG_FROM_TEST(key->flag, select, PEK_SELECT); + } } } @@ -1986,6 +1988,9 @@ void PARTICLE_OT_reveal(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + + /* props */ + RNA_def_boolean(ot->srna, "select", true, "Select", ""); } /************************ select less operator ************************/ diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c index 8304e782b07..1c2ab442e95 100644 --- a/source/blender/editors/sculpt_paint/paint_utils.c +++ b/source/blender/editors/sculpt_paint/paint_utils.c @@ -749,10 +749,11 @@ void PAINT_OT_face_select_hide(wmOperatorType *ot) RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "Hide unselected rather than selected objects"); } -static int face_select_reveal_exec(bContext *C, wmOperator *UNUSED(op)) +static int face_select_reveal_exec(bContext *C, wmOperator *op) { + const bool select = RNA_boolean_get(op->ptr, "select"); Object *ob = CTX_data_active_object(C); - paintface_reveal(ob); + paintface_reveal(ob, select); ED_region_tag_redraw(CTX_wm_region(C)); return OPERATOR_FINISHED; } @@ -768,5 +769,5 @@ void PAINT_OT_face_select_reveal(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "Hide unselected rather than selected objects"); + RNA_def_boolean(ot->srna, "select", true, "Select", ""); } diff --git a/source/blender/editors/space_graph/graph_ops.c b/source/blender/editors/space_graph/graph_ops.c index 5c670a216d8..62275abcd02 100644 --- a/source/blender/editors/space_graph/graph_ops.c +++ b/source/blender/editors/space_graph/graph_ops.c @@ -333,13 +333,14 @@ static void GRAPH_OT_hide(wmOperatorType *ot) /* ........ */ -static int graphview_curves_reveal_exec(bContext *C, wmOperator *UNUSED(op)) +static int graphview_curves_reveal_exec(bContext *C, wmOperator *op) { bAnimContext ac; ListBase anim_data = {NULL, NULL}; ListBase all_data = {NULL, NULL}; bAnimListElem *ale; int filter; + const bool select = RNA_boolean_get(op->ptr, "select"); /* get editor data */ if (ANIM_animdata_get_context(C, &ac) == 0) @@ -364,8 +365,11 @@ static int graphview_curves_reveal_exec(bContext *C, wmOperator *UNUSED(op)) continue; /* select if it is not visible */ - if (ANIM_channel_setting_get(&ac, ale, ACHANNEL_SETTING_VISIBLE) == 0) - ANIM_channel_setting_set(&ac, ale, ACHANNEL_SETTING_SELECT, ACHANNEL_SETFLAG_ADD); + if (ANIM_channel_setting_get(&ac, ale, ACHANNEL_SETTING_VISIBLE) == 0) { + ANIM_channel_setting_set( + &ac, ale, ACHANNEL_SETTING_SELECT, + select ? ACHANNEL_SETFLAG_ADD : ACHANNEL_SETFLAG_CLEAR); + } /* change the visibility setting */ ANIM_channel_setting_set(&ac, ale, ACHANNEL_SETTING_VISIBLE, ACHANNEL_SETFLAG_ADD); @@ -397,6 +401,8 @@ static void GRAPH_OT_reveal(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + RNA_def_boolean(ot->srna, "select", true, "Select", ""); } /* ************************** registration - operator types **********************************/ diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index c369068fe05..d69588e91c6 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -3761,7 +3761,7 @@ static void UV_OT_hide(wmOperatorType *ot) /****************** reveal operator ******************/ -static int uv_reveal_exec(bContext *C, wmOperator *UNUSED(op)) +static int uv_reveal_exec(bContext *C, wmOperator *op) { SpaceImage *sima = CTX_wm_space_image(C); Object *obedit = CTX_data_edit_object(C); @@ -3777,12 +3777,14 @@ static int uv_reveal_exec(bContext *C, wmOperator *UNUSED(op)) const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + const bool select = RNA_boolean_get(op->ptr, "select"); + /* note on tagging, selecting faces needs to be delayed so it doesn't select the verts and * confuse our checks on selected verts. */ /* call the mesh function if we are in mesh sync sel */ if (ts->uv_flag & UV_SYNC_SELECTION) { - EDBM_mesh_reveal(em); + EDBM_mesh_reveal(em, select); WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); return OPERATOR_FINISHED; @@ -3794,7 +3796,7 @@ static int uv_reveal_exec(bContext *C, wmOperator *UNUSED(op)) if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN) && !BM_elem_flag_test(efa, BM_ELEM_SELECT)) { BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - luv->flag |= MLOOPUV_VERTSEL; + SET_FLAG_FROM_TEST(luv->flag, select, MLOOPUV_VERTSEL); } /* BM_face_select_set(em->bm, efa, true); */ BM_elem_flag_enable(efa, BM_ELEM_TAG); @@ -3815,7 +3817,7 @@ static int uv_reveal_exec(bContext *C, wmOperator *UNUSED(op)) if (!totsel) { BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - luv->flag |= MLOOPUV_VERTSEL; + SET_FLAG_FROM_TEST(luv->flag, select, MLOOPUV_VERTSEL); } /* BM_face_select_set(em->bm, efa, true); */ BM_elem_flag_enable(efa, BM_ELEM_TAG); @@ -3830,7 +3832,7 @@ static int uv_reveal_exec(bContext *C, wmOperator *UNUSED(op)) BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { if (BM_elem_flag_test(l->v, BM_ELEM_SELECT) == 0) { luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - luv->flag |= MLOOPUV_VERTSEL; + SET_FLAG_FROM_TEST(luv->flag, select, MLOOPUV_VERTSEL); } } /* BM_face_select_set(em->bm, efa, true); */ @@ -3846,7 +3848,7 @@ static int uv_reveal_exec(bContext *C, wmOperator *UNUSED(op)) if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN) && !BM_elem_flag_test(efa, BM_ELEM_SELECT)) { BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - luv->flag |= MLOOPUV_VERTSEL; + SET_FLAG_FROM_TEST(luv->flag, select, MLOOPUV_VERTSEL); } /* BM_face_select_set(em->bm, efa, true); */ BM_elem_flag_enable(efa, BM_ELEM_TAG); @@ -3860,7 +3862,7 @@ static int uv_reveal_exec(bContext *C, wmOperator *UNUSED(op)) BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { if (BM_elem_flag_test(l->v, BM_ELEM_SELECT) == 0) { luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - luv->flag |= MLOOPUV_VERTSEL; + SET_FLAG_FROM_TEST(luv->flag, select, MLOOPUV_VERTSEL); } } /* BM_face_select_set(em->bm, efa, true); */ @@ -3888,6 +3890,8 @@ static void UV_OT_reveal(wmOperatorType *ot) /* api callbacks */ ot->exec = uv_reveal_exec; ot->poll = ED_operator_uvedit; + + RNA_def_boolean(ot->srna, "select", true, "Select", ""); } /******************** set 3d cursor operator ********************/ -- cgit v1.2.3 From ed3b7a5cd4597274f523d832494eabdf153aa597 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 20 Nov 2017 16:01:04 +1100 Subject: Fix T53342: Outliner 'select hierarchy' broken Was using cursor position from within menu, clicking on the same position for every selected item (toggling). Now operate on each selected outliner element, without toggling. --- .../editors/space_outliner/outliner_intern.h | 8 +- .../editors/space_outliner/outliner_select.c | 186 +++++++++++++-------- .../editors/space_outliner/outliner_tools.c | 13 +- 3 files changed, 128 insertions(+), 79 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h index ccc52f2dba8..ca7dbe4f73c 100644 --- a/source/blender/editors/space_outliner/outliner_intern.h +++ b/source/blender/editors/space_outliner/outliner_intern.h @@ -150,7 +150,13 @@ eOLDrawState tree_element_type_active( TreeElement *te, TreeStoreElem *tselem, const eOLSetState set, bool recursive); eOLDrawState tree_element_active(struct bContext *C, struct Scene *scene, SpaceOops *soops, TreeElement *te, const eOLSetState set, const bool handle_all_types); -int outliner_item_do_activate(struct bContext *C, int x, int y, bool extend, bool recursive); + +void outliner_item_do_activate_from_tree_element( + struct bContext *C, TreeElement *te, TreeStoreElem *tselem, + bool extend, bool recursive); +int outliner_item_do_activate_from_cursor( + struct bContext *C, const int mval[2], + bool extend, bool recursive); /* outliner_edit.c ---------------------------------------------- */ typedef void (*outliner_operation_cb)( diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c index 5cc83d3ee94..9f79b575966 100644 --- a/source/blender/editors/space_outliner/outliner_select.c +++ b/source/blender/editors/space_outliner/outliner_select.c @@ -816,7 +816,7 @@ eOLDrawState tree_element_active(bContext *C, Scene *scene, SpaceOops *soops, Tr { switch (te->idcode) { /* Note: ID_OB only if handle_all_type is true, else objects are handled specially to allow multiple - * selection. See do_outliner_item_activate. */ + * selection. See do_outliner_item_activate_from_cursor. */ case ID_OB: if (handle_all_types) { return tree_element_set_active_object(C, scene, soops, te, set, false); @@ -892,10 +892,85 @@ eOLDrawState tree_element_type_active( /* ================================================ */ -static bool do_outliner_item_activate(bContext *C, Scene *scene, ARegion *ar, SpaceOops *soops, - TreeElement *te, bool extend, bool recursive, const float mval[2]) +/** + * Action when clicking to activate an item (typically under the mouse cursor), + * but don't do any cursor intersection checks. + * + * Needed to run from operators accessed from a menu. + */ +static void do_outliner_item_activate_tree_element( + bContext *C, Scene *scene, SpaceOops *soops, + TreeElement *te, TreeStoreElem *tselem, + bool extend, bool recursive) +{ + /* always makes active object, except for some specific types. + * Note about TSE_EBONE: In case of a same ID_AR datablock shared among several objects, we do not want + * to switch out of edit mode (see T48328 for details). */ + if (!ELEM(tselem->type, TSE_SEQUENCE, TSE_SEQ_STRIP, TSE_SEQUENCE_DUP, TSE_EBONE)) { + tree_element_set_active_object( + C, scene, soops, te, + (extend && tselem->type == 0) ? OL_SETSEL_EXTEND : OL_SETSEL_NORMAL, + recursive && tselem->type == 0); + } + + if (tselem->type == 0) { // the lib blocks + /* editmode? */ + if (te->idcode == ID_SCE) { + if (scene != (Scene *)tselem->id) { + ED_screen_set_scene(C, CTX_wm_screen(C), (Scene *)tselem->id); + } + } + else if (te->idcode == ID_GR) { + Group *gr = (Group *)tselem->id; + GroupObject *gob; + + if (extend) { + int sel = BA_SELECT; + for (gob = gr->gobject.first; gob; gob = gob->next) { + if (gob->ob->flag & SELECT) { + sel = BA_DESELECT; + break; + } + } + + for (gob = gr->gobject.first; gob; gob = gob->next) { + ED_base_object_select(BKE_scene_base_find(scene, gob->ob), sel); + } + } + else { + BKE_scene_base_deselect_all(scene); + + for (gob = gr->gobject.first; gob; gob = gob->next) { + if ((gob->ob->flag & SELECT) == 0) + ED_base_object_select(BKE_scene_base_find(scene, gob->ob), BA_SELECT); + } + } + + WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene); + } + else if (ELEM(te->idcode, ID_ME, ID_CU, ID_MB, ID_LT, ID_AR)) { + WM_operator_name_call(C, "OBJECT_OT_editmode_toggle", WM_OP_INVOKE_REGION_WIN, NULL); + } + else { // rest of types + tree_element_active(C, scene, soops, te, OL_SETSEL_NORMAL, false); + } + + } + else { + tree_element_type_active( + C, scene, soops, te, tselem, + extend ? OL_SETSEL_EXTEND : OL_SETSEL_NORMAL, + recursive); + } +} + +/** + * Activates tree items, also handles clicking on arrows. + */ +static bool do_outliner_item_activate_from_cursor( + bContext *C, Scene *scene, ARegion *ar, SpaceOops *soops, + TreeElement *te, bool extend, bool recursive, const float mval[2]) { - if (mval[1] > te->ys && mval[1] < te->ys + UI_UNIT_Y) { TreeStoreElem *tselem = TREESTORE(te); bool openclose = false; @@ -922,78 +997,49 @@ static bool do_outliner_item_activate(bContext *C, Scene *scene, ARegion *ar, Sp } /* name and first icon */ else if (mval[0] > te->xs + UI_UNIT_X && mval[0] < te->xend) { - - /* always makes active object, except for some specific types. - * Note about TSE_EBONE: In case of a same ID_AR datablock shared among several objects, we do not want - * to switch out of edit mode (see T48328 for details). */ - if (!ELEM(tselem->type, TSE_SEQUENCE, TSE_SEQ_STRIP, TSE_SEQUENCE_DUP, TSE_EBONE)) { - tree_element_set_active_object(C, scene, soops, te, - (extend && tselem->type == 0) ? OL_SETSEL_EXTEND : OL_SETSEL_NORMAL, - recursive && tselem->type == 0); - } - - if (tselem->type == 0) { // the lib blocks - /* editmode? */ - if (te->idcode == ID_SCE) { - if (scene != (Scene *)tselem->id) { - ED_screen_set_scene(C, CTX_wm_screen(C), (Scene *)tselem->id); - } - } - else if (te->idcode == ID_GR) { - Group *gr = (Group *)tselem->id; - GroupObject *gob; - - if (extend) { - int sel = BA_SELECT; - for (gob = gr->gobject.first; gob; gob = gob->next) { - if (gob->ob->flag & SELECT) { - sel = BA_DESELECT; - break; - } - } - - for (gob = gr->gobject.first; gob; gob = gob->next) { - ED_base_object_select(BKE_scene_base_find(scene, gob->ob), sel); - } - } - else { - BKE_scene_base_deselect_all(scene); - - for (gob = gr->gobject.first; gob; gob = gob->next) { - if ((gob->ob->flag & SELECT) == 0) - ED_base_object_select(BKE_scene_base_find(scene, gob->ob), BA_SELECT); - } - } - - WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene); - } - else if (ELEM(te->idcode, ID_ME, ID_CU, ID_MB, ID_LT, ID_AR)) { - WM_operator_name_call(C, "OBJECT_OT_editmode_toggle", WM_OP_INVOKE_REGION_WIN, NULL); - } - else { // rest of types - tree_element_active(C, scene, soops, te, OL_SETSEL_NORMAL, false); - } - - } - else { - tree_element_type_active(C, scene, soops, te, tselem, - extend ? OL_SETSEL_EXTEND : OL_SETSEL_NORMAL, - recursive); - } - + do_outliner_item_activate_tree_element( + C, scene, soops, + te, tselem, + extend, recursive); return true; } } for (te = te->subtree.first; te; te = te->next) { - if (do_outliner_item_activate(C, scene, ar, soops, te, extend, recursive, mval)) { + if (do_outliner_item_activate_from_cursor(C, scene, ar, soops, te, extend, recursive, mval)) { return true; } } return false; } -int outliner_item_do_activate(bContext *C, int x, int y, bool extend, bool recursive) +/** + * A version of #outliner_item_do_acticate_from_cursor that takes the tree element directly. + * and doesn't depend on the pointer position. + * + * This allows us to simulate clicking on an item without dealing with the mouse cursor. + */ +void outliner_item_do_activate_from_tree_element( + bContext *C, TreeElement *te, TreeStoreElem *tselem, + bool extend, bool recursive) +{ + Scene *scene = CTX_data_scene(C); + SpaceOops *soops = CTX_wm_space_outliner(C); + + do_outliner_item_activate_tree_element( + C, scene, soops, + te, tselem, + extend, recursive); +} + +/** + * Action to run when clicking in the outliner, + * + * May expend/collapse branches or activate items. + * */ +int outliner_item_do_activate_from_cursor( + bContext *C, const int mval[2], + bool extend, bool recursive) { Scene *scene = CTX_data_scene(C); ARegion *ar = CTX_wm_region(C); @@ -1001,7 +1047,7 @@ int outliner_item_do_activate(bContext *C, int x, int y, bool extend, bool recur TreeElement *te; float fmval[2]; - UI_view2d_region_to_view(&ar->v2d, x, y, &fmval[0], &fmval[1]); + UI_view2d_region_to_view(&ar->v2d, mval[0], mval[1], &fmval[0], &fmval[1]); if (!ELEM(soops->outlinevis, SO_DATABLOCKS, SO_USERDEF) && !(soops->flag & SO_HIDE_RESTRICTCOLS) && @@ -1011,7 +1057,9 @@ int outliner_item_do_activate(bContext *C, int x, int y, bool extend, bool recur } for (te = soops->tree.first; te; te = te->next) { - if (do_outliner_item_activate(C, scene, ar, soops, te, extend, recursive, fmval)) break; + if (do_outliner_item_activate_from_cursor(C, scene, ar, soops, te, extend, recursive, fmval)) { + break; + } } if (te) { @@ -1046,9 +1094,7 @@ static int outliner_item_activate(bContext *C, wmOperator *op, const wmEvent *ev { bool extend = RNA_boolean_get(op->ptr, "extend"); bool recursive = RNA_boolean_get(op->ptr, "recursive"); - int x = event->mval[0]; - int y = event->mval[1]; - return outliner_item_do_activate(C, x, y, extend, recursive); + return outliner_item_do_activate_from_cursor(C, event->mval, extend, recursive); } void OUTLINER_OT_item_activate(wmOperatorType *ot) diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c index 3321c2669d8..cf9deeaedf8 100644 --- a/source/blender/editors/space_outliner/outliner_tools.c +++ b/source/blender/editors/space_outliner/outliner_tools.c @@ -372,17 +372,14 @@ static void object_select_cb( } static void object_select_hierarchy_cb( - bContext *C, ReportList *UNUSED(reports), Scene *UNUSED(scene), TreeElement *UNUSED(te), - TreeStoreElem *UNUSED(tsep), TreeStoreElem *UNUSED(tselem), void *UNUSED(user_data)) + bContext *C, ReportList *UNUSED(reports), Scene *UNUSED(scene), TreeElement *te, + TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data)) { - /* From where do i get the x,y coordinate of the mouse event ? */ - wmWindow *win = CTX_wm_window(C); - int x = win->eventstate->mval[0]; - int y = win->eventstate->mval[1]; - outliner_item_do_activate(C, x, y, true, true); + /* Don't extend because this toggles, which is nice for Ctrl-Click but not for a menu item. + * it's especially confusing when multiple items are selected since some toggle on/off. */ + outliner_item_do_activate_from_tree_element(C, te, tselem, false, true); } - static void object_deselect_cb( bContext *UNUSED(C), ReportList *UNUSED(reports), Scene *scene, TreeElement *te, TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data)) -- cgit v1.2.3 From 65af15ad887b30e678db9acab75efc7897c9197e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 20 Nov 2017 19:51:19 +1100 Subject: UV Cube Project: improve default behavior - initialize the cube-size from the bounding box when it's not set. - no longer wrap faces to keep in 0-1 bounds, other projection methods don't do this and calculating the scale prevents the UV's from being too far outside the view. --- source/blender/editors/uvedit/uvedit_unwrap_ops.c | 127 +++++++++++++--------- 1 file changed, 73 insertions(+), 54 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c index ce763243602..bc38a1cd3bb 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c @@ -868,70 +868,89 @@ void ED_uvedit_live_unwrap(Scene *scene, Object *obedit) #define POLAR_ZX 0 #define POLAR_ZY 1 -static void uv_map_transform_center(Scene *scene, View3D *v3d, float *result, Object *ob, BMEditMesh *em) +static void uv_map_transform_calc_bounds(BMEditMesh *em, float r_min[3], float r_max[3]) +{ + BMFace *efa; + BMIter iter; + INIT_MINMAX(r_min, r_max); + BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { + if (BM_elem_flag_test(efa, BM_ELEM_SELECT)) { + BM_face_calc_bounds_expand(efa, r_min, r_max); + } + } +} + +static void uv_map_transform_calc_center_median(BMEditMesh *em, float r_center[3]) +{ + BMFace *efa; + BMIter iter; + uint center_accum_num = 0; + zero_v3(r_center); + BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { + if (BM_elem_flag_test(efa, BM_ELEM_SELECT)) { + float center[3]; + BM_face_calc_center_mean(efa, center); + add_v3_v3(r_center, center); + center_accum_num += 1; + } + } + mul_v3_fl(r_center, 1.0f / (float)center_accum_num); +} + +static void uv_map_transform_center( + Scene *scene, View3D *v3d, Object *ob, BMEditMesh *em, + float r_center[3], + float r_bounds[2][3]) { /* only operates on the edit object - this is all that's needed now */ const int around = (v3d) ? v3d->around : V3D_AROUND_CENTER_BOUNDS; + float bounds[2][3]; + INIT_MINMAX(bounds[0], bounds[1]); + bool is_minmax_set = false; + switch (around) { case V3D_AROUND_CENTER_BOUNDS: /* bounding box center */ { - BMFace *efa; - BMLoop *l; - BMIter iter, liter; - float min[3], max[3]; - - INIT_MINMAX(min, max); - - BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { - if (BM_elem_flag_test(efa, BM_ELEM_SELECT)) { - BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - minmax_v3v3_v3(min, max, l->v->co); - } - } - } - mid_v3_v3v3(result, min, max); + uv_map_transform_calc_bounds(em, bounds[0], bounds[1]); + is_minmax_set = true; + mid_v3_v3v3(r_center, bounds[0], bounds[1]); break; } case V3D_AROUND_CENTER_MEAN: { - BMFace *efa; - BMLoop *l; - BMIter iter, liter; - int result_accum = 0; - - zero_v3(result); - BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { - if (BM_elem_flag_test(efa, BM_ELEM_SELECT)) { - BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - add_v3_v3(result, l->v->co); - result_accum += 1; - } - } - } - mul_v3_fl(result, 1.0f / (float)result_accum); + uv_map_transform_calc_center_median(em, r_center); break; } case V3D_AROUND_CURSOR: /* cursor center */ { invert_m4_m4(ob->imat, ob->obmat); - mul_v3_m4v3(result, ob->imat, ED_view3d_cursor3d_get(scene, v3d)); + mul_v3_m4v3(r_center, ob->imat, ED_view3d_cursor3d_get(scene, v3d)); break; } case V3D_AROUND_ACTIVE: { BMEditSelection ese; if (BM_select_history_active_get(em->bm, &ese)) { - BM_editselection_center(&ese, result); + BM_editselection_center(&ese, r_center); break; } ATTR_FALLTHROUGH; } case V3D_AROUND_LOCAL_ORIGINS: /* object center */ default: - zero_v3(result); + zero_v3(r_center); break; } + + /* if this is passed, always set! */ + if (r_bounds) { + if (!is_minmax_set) { + uv_map_transform_calc_bounds(em, bounds[0], bounds[1]); + } + copy_v3_v3(r_bounds[0], bounds[0]); + copy_v3_v3(r_bounds[1], bounds[1]); + } } static void uv_map_rotation_matrix(float result[4][4], RegionView3D *rv3d, Object *ob, @@ -1514,7 +1533,7 @@ static int sphere_project_exec(bContext *C, wmOperator *op) cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); uv_map_transform(C, op, rotmat); - uv_map_transform_center(scene, v3d, center, obedit, em); + uv_map_transform_center(scene, v3d, obedit, em, center, NULL); BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { if (!BM_elem_flag_test(efa, BM_ELEM_SELECT)) @@ -1595,7 +1614,7 @@ static int cylinder_project_exec(bContext *C, wmOperator *op) cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); uv_map_transform(C, op, rotmat); - uv_map_transform_center(scene, v3d, center, obedit, em); + uv_map_transform_center(scene, v3d, obedit, em, center, NULL); BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { if (!BM_elem_flag_test(efa, BM_ELEM_SELECT)) @@ -1670,26 +1689,10 @@ void ED_uvedit_unwrap_cube_project(BMesh *bm, float cube_size, bool use_select, axis_dominant_v3(&cox, &coy, efa->no); - float uv_delta[2] = {0.0f}; - BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); luv->uv[0] = 0.5f + 0.5f * cube_size * (l->v->co[cox] - loc[cox]); luv->uv[1] = 0.5f + 0.5f * cube_size * (l->v->co[coy] - loc[coy]); - - add_v2_v2(uv_delta, luv->uv); - } - - mul_v2_fl(uv_delta, 1.0f / (float)efa->len); - uv_delta[0] = floor(uv_delta[0]); - uv_delta[1] = floor(uv_delta[1]); - - if (uv_delta[0] != 0.0f || uv_delta[1] != 0.0f) { - BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - luv->uv[0] -= uv_delta[0]; - luv->uv[1] -= uv_delta[1]; - } } } } @@ -1700,15 +1703,31 @@ static int cube_project_exec(bContext *C, wmOperator *op) View3D *v3d = CTX_wm_view3d(C); Object *obedit = CTX_data_edit_object(C); BMEditMesh *em = BKE_editmesh_from_object(obedit); - float cube_size = RNA_float_get(op->ptr, "cube_size"); + PropertyRNA *prop_cube_size = RNA_struct_find_property(op->ptr, "cube_size"); + float cube_size = RNA_property_float_get(op->ptr, prop_cube_size); float center[3]; + float bounds[2][3]; + float (*bounds_buf)[3] = NULL; /* add uvs if they don't exist yet */ if (!ED_uvedit_ensure_uvs(C, scene, obedit)) { return OPERATOR_CANCELLED; } - uv_map_transform_center(scene, v3d, center, obedit, em); + if (!RNA_property_is_set(op->ptr, prop_cube_size)) { + bounds_buf = bounds; + } + + uv_map_transform_center(scene, v3d, obedit, em, center, bounds_buf); + + /* calculate based on bounds */ + if (bounds_buf) { + float dims[3]; + sub_v3_v3v3(dims, bounds[1], bounds[0]); + cube_size = max_fff(UNPACK3(dims)); + cube_size = cube_size ? 2.0f / cube_size : 1.0f; + RNA_property_float_set(op->ptr, prop_cube_size, cube_size); + } ED_uvedit_unwrap_cube_project(em->bm, cube_size, true, center); -- cgit v1.2.3