From f00cb93dbec7bf5dc05302c868f20fcd5aed7db7 Mon Sep 17 00:00:00 2001 From: Philipp Oeser Date: Thu, 3 Sep 2020 14:59:34 +0200 Subject: Fix T63125: Gpencil: bones cannot be selected in weightpaint mode Some underlying functionality was not ready for greasepencil: - BKE_modifiers_get_virtual_modifierlist (now introduce dedicated BKE_gpencil_modifiers_get_virtual_modifierlist) - BKE_modifiers_is_deformed_by_armature - checks in drawing code - checks in (pose) selection code A couple of changes to make this work: - `eGpencilModifierType_Armature` has to be respected (not only `eModifierType_Armature`) - `OB_MODE_WEIGHT_GPENCIL` has to be respected (not only `OB_MODE_WEIGHT_PAINT`) -- (now use new `OB_MODE_ALL_WEIGHT_PAINT`) - `gpencil_weightmode_toggle_exec` now shares functionality from `wpaint_mode_toggle_exec` -- moved to new `ED_object_posemode_set_for_weight_paint` This patch will also set the context member "weight_paint_object" for greasepencil (otherwise some appropriate pose operators wont work when in weightpaint mode) Reviewed By: campbellbarton Maniphest Tasks: T63125 Differential Revision: https://developer.blender.org/D8483 --- source/blender/editors/object/object_modes.c | 72 ++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) (limited to 'source/blender/editors/object') diff --git a/source/blender/editors/object/object_modes.c b/source/blender/editors/object/object_modes.c index 5d4476ecb8c..d4dd6617c53 100644 --- a/source/blender/editors/object/object_modes.c +++ b/source/blender/editors/object/object_modes.c @@ -29,7 +29,10 @@ #include "BLI_utildefines.h" #include "BKE_context.h" +#include "BKE_gpencil_modifier.h" #include "BKE_layer.h" +#include "BKE_main.h" +#include "BKE_modifier.h" #include "BKE_object.h" #include "BKE_paint.h" #include "BKE_report.h" @@ -304,6 +307,75 @@ static bool ed_object_mode_generic_exit_ex(struct Main *bmain, return false; } +/* When locked, it's almost impossible to select the pose-object + * then the mesh-object to enter weight paint mode. + * Even when the object mode is not locked this is inconvenient - so allow in either case. + * + * In this case move our pose object in/out of pose mode. + * This is in fits with the convention of selecting multiple objects and entering a mode. + */ +static void ed_object_posemode_set_for_weight_paint_ex(bContext *C, + Main *bmain, + Object *ob_arm, + const bool is_mode_set) +{ + View3D *v3d = CTX_wm_view3d(C); + ViewLayer *view_layer = CTX_data_view_layer(C); + + if (ob_arm != NULL) { + const Base *base_arm = BKE_view_layer_base_find(view_layer, ob_arm); + if (base_arm && BASE_VISIBLE(v3d, base_arm)) { + if (is_mode_set) { + if ((ob_arm->mode & OB_MODE_POSE) != 0) { + ED_object_posemode_exit_ex(bmain, ob_arm); + } + } + else { + /* Only check selected status when entering weight-paint mode + * because we may have multiple armature objects. + * Selecting one will de-select the other, which would leave it in pose-mode + * when exiting weight paint mode. While usable, this looks like inconsistent + * behavior from a user perspective. */ + if (base_arm->flag & BASE_SELECTED) { + if ((ob_arm->mode & OB_MODE_POSE) == 0) { + ED_object_posemode_enter_ex(bmain, ob_arm); + } + } + } + } + } +} + +void ED_object_posemode_set_for_weight_paint(bContext *C, + Main *bmain, + Object *ob, + const bool is_mode_set) +{ + if (ob->type == OB_GPENCIL) { + GpencilVirtualModifierData virtualModifierData; + GpencilModifierData *md = BKE_gpencil_modifiers_get_virtual_modifierlist(ob, + &virtualModifierData); + for (; md; md = md->next) { + if (md->type == eGpencilModifierType_Armature) { + ArmatureGpencilModifierData *amd = (ArmatureGpencilModifierData *)md; + Object *ob_arm = amd->object; + ed_object_posemode_set_for_weight_paint_ex(C, bmain, ob_arm, is_mode_set); + } + } + } + else { + VirtualModifierData virtualModifierData; + ModifierData *md = BKE_modifiers_get_virtual_modifierlist(ob, &virtualModifierData); + for (; md; md = md->next) { + if (md->type == eModifierType_Armature) { + ArmatureModifierData *amd = (ArmatureModifierData *)md; + Object *ob_arm = amd->object; + ed_object_posemode_set_for_weight_paint_ex(C, bmain, ob_arm, is_mode_set); + } + } + } +} + void ED_object_mode_generic_exit(struct Main *bmain, struct Depsgraph *depsgraph, struct Scene *scene, -- cgit v1.2.3