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:
authorCampbell Barton <campbell@blender.org>2022-11-04 05:06:53 +0300
committerCampbell Barton <campbell@blender.org>2022-11-04 05:58:57 +0300
commit3d72c37f7ad3bf36ae36bc9860a9b0de16bd60ea (patch)
tree1c21379aaaa7ea37163ae47de858479323fb03b6
parent1452b4435240d5a78bacc61035574fdefd4faf80 (diff)
Fix T101686: WPaint + Pose select fails with GPU depth-picking disabled
Regression in [0], however the primary purpose of that code was to cycle away from the active object (behavior which was intentionally removed, see: T96752). This broke weight-paint + pose-selection (Ctrl-LMB) when the GPU depth picking preference was disabled. Causing selection to pick the mesh object instead of the pose bones. This de-selected the armature, making the pose bones unselectable instead of selecting the pose bone as intended. Adding the old code back (restricting it to weight-paint mode) fixes the bug but reintroduces fairly involved logic unnecessarily. Instead, prioritize bone selecting when in weight-paint & pose mode (previously this was only done in pose-mode). [0]: b1908f2e0b23988627772f6a6d968d8351dca6d7
-rw-r--r--source/blender/blenkernel/BKE_object.h10
-rw-r--r--source/blender/blenkernel/intern/object.cc22
-rw-r--r--source/blender/editors/space_view3d/view3d_select.cc16
3 files changed, 45 insertions, 3 deletions
diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h
index 5cbd7937f3f..cfad8c5cfdb 100644
--- a/source/blender/blenkernel/BKE_object.h
+++ b/source/blender/blenkernel/BKE_object.h
@@ -283,7 +283,17 @@ void BKE_object_apply_parent_inverse(struct Object *ob);
void BKE_object_matrix_local_get(struct Object *ob, float r_mat[4][4]);
bool BKE_object_pose_context_check(const struct Object *ob);
+
struct Object *BKE_object_pose_armature_get(struct Object *ob);
+/**
+ * A version of #BKE_object_pose_armature_get with an additional check.
+ * When `ob` isn't an armature: only return the referenced pose object
+ * when the active object is in weight paint mode.
+ *
+ * \note Some callers need to check that pose bones are selectable
+ * which isn't the case when the object using the armature isn't in weight-paint mode.
+ */
+struct Object *BKE_object_pose_armature_get_with_wpaint_check(struct Object *ob);
struct Object *BKE_object_pose_armature_get_visible(struct Object *ob,
const struct Scene *scene,
struct ViewLayer *view_layer,
diff --git a/source/blender/blenkernel/intern/object.cc b/source/blender/blenkernel/intern/object.cc
index 6d1b7caeea6..9085a54d86f 100644
--- a/source/blender/blenkernel/intern/object.cc
+++ b/source/blender/blenkernel/intern/object.cc
@@ -2541,6 +2541,28 @@ Object *BKE_object_pose_armature_get(Object *ob)
return nullptr;
}
+Object *BKE_object_pose_armature_get_with_wpaint_check(Object *ob)
+{
+ /* When not in weight paint mode. */
+ if (ob) {
+ switch (ob->type) {
+ case OB_MESH: {
+ if ((ob->mode & OB_MODE_WEIGHT_PAINT) == 0) {
+ return nullptr;
+ }
+ break;
+ }
+ case OB_GPENCIL: {
+ if ((ob->mode & OB_MODE_WEIGHT_GPENCIL) == 0) {
+ return nullptr;
+ }
+ break;
+ }
+ }
+ }
+ return BKE_object_pose_armature_get(ob);
+}
+
Object *BKE_object_pose_armature_get_visible(Object *ob,
const Scene *scene,
ViewLayer *view_layer,
diff --git a/source/blender/editors/space_view3d/view3d_select.cc b/source/blender/editors/space_view3d/view3d_select.cc
index 9c450e85d23..a7be569894d 100644
--- a/source/blender/editors/space_view3d/view3d_select.cc
+++ b/source/blender/editors/space_view3d/view3d_select.cc
@@ -2616,6 +2616,12 @@ static bool ed_object_select_pick(bContext *C,
Base *basact = nullptr;
const eObjectMode object_mode = oldbasact ? static_cast<eObjectMode>(oldbasact->object->mode) :
OB_MODE_OBJECT;
+ /* For the most part this is equivalent to `(object_mode & OB_MODE_POSE) != 0`
+ * however this logic should also run with weight-paint + pose selection.
+ * Without this, selection in weight-paint mode can de-select armatures which isn't useful,
+ * see: T101686. */
+ const bool has_pose_old = (oldbasact &&
+ BKE_object_pose_armature_get_with_wpaint_check(oldbasact->object));
/* When enabled, don't attempt any further selection. */
bool handled = false;
@@ -2654,7 +2660,7 @@ static bool ed_object_select_pick(bContext *C,
*
* This way prioritizing based on pose-mode has a bias to stay in pose-mode
* without having to enforce this through locking the object mode. */
- bool do_bones_get_priotity = (object_mode & OB_MODE_POSE) != 0;
+ bool do_bones_get_priotity = has_pose_old;
basact = (gpu->hits > 0) ? mouse_select_eval_buffer(&vc,
gpu->buffer,
@@ -2666,10 +2672,14 @@ static bool ed_object_select_pick(bContext *C,
nullptr;
}
+ /* See comment for `has_pose_old`, the same rationale applies here. */
+ const bool has_pose_new = (basact &&
+ BKE_object_pose_armature_get_with_wpaint_check(basact->object));
+
/* Select pose-bones or camera-tracks. */
if (((gpu->hits > 0) && gpu->has_bones) ||
/* Special case, even when there are no hits, pose logic may de-select all bones. */
- ((gpu->hits == 0) && (object_mode & OB_MODE_POSE))) {
+ ((gpu->hits == 0) && has_pose_old)) {
if (basact && (gpu->has_bones && (basact->object->type == OB_CAMERA))) {
MovieClip *clip = BKE_object_movieclip_get(scene, basact->object, false);
@@ -2729,7 +2739,7 @@ static bool ed_object_select_pick(bContext *C,
handled = true;
}
- else if ((object_mode & OB_MODE_POSE) && (basact->object->mode & OB_MODE_POSE)) {
+ else if (has_pose_old && has_pose_new) {
/* Within pose-mode, keep the current selection when switching pose bones,
* this is noticeable when in pose mode with multiple objects at once.
* Where selecting the bone of a different object would de-select this one.