[Bf-blender-cvs] [291136eecea] blender-v2.83-release: Fix T76689: Armature layers not indicating the existence of bones

Sybren A. Stüvel noreply at git.blender.org
Tue May 19 09:40:32 CEST 2020


Commit: 291136eecea31c13232054accc2663dcdf7b2a33
Author: Sybren A. Stüvel
Date:   Tue May 12 18:22:14 2020 +0200
Branches: blender-v2.83-release
https://developer.blender.org/rB291136eecea31c13232054accc2663dcdf7b2a33

Fix T76689: Armature layers not indicating the existence of bones

>From what I can see, there are two issues at play in {T76689} and its merged-in report {T76590}:

- In Blender ≤ 2.79 the bone layer dots were updated in the draw code. This ensured the info was up to date before drawing. This is no longer possible, as the drawing code uses evaluated objects, and those should not be written to. This has been addressed in rB709f126e8143 by calling the update function explicitly in various places in the code. The problem is that this wasn't added to all necessary spots.
- When in edit mode, changes are made to the edit bones but not to the 'actual' bones (this is synced when exiting edit mode). This causes undo to mess up the layer indicators.

I think both issues can be addressed by having the dependency graph update the used layer info as part of the armature evaluation. This will make the undo system work properly, and allows the removal of some `BKE_armature_refresh_layer_used()` from various places.

There is still the issue that there are two functions (`BKE_armature_refresh_layer_used()` and `ED_armature_edit_refresh_layer_used()`) that are both responsible for updating `bArmature::layer_used`. This is a trickier thing to solve, though, as the definition of the `EditBone` struct resides in the armature editor module. This means that blenkernel can't iterate over edit bones, but on the other hand the dependency graph shouldn't call any editor functions either. This is why I left the  [...]

The downside of recalculating `layer_used` from the dependency graph (at least in the way that I did it now) is that it is called every time a user moves a bone in pose mode. This frequency of updates is not necessary.

Differential Revision: https://developer.blender.org/D7709

===================================================================

M	source/blender/blenkernel/BKE_armature.h
M	source/blender/blenkernel/intern/armature.c
M	source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
M	source/blender/editors/armature/armature_relations.c
M	source/blender/editors/armature/pose_edit.c
M	source/blender/makesrna/intern/rna_armature.c

===================================================================

diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h
index 6c383ae5011..54022a0a632 100644
--- a/source/blender/blenkernel/BKE_armature.h
+++ b/source/blender/blenkernel/BKE_armature.h
@@ -89,7 +89,7 @@ void BKE_armature_bone_hash_free(struct bArmature *arm);
 
 bool BKE_armature_bone_flag_test_recursive(const struct Bone *bone, int flag);
 
-void BKE_armature_refresh_layer_used(struct bArmature *arm);
+void BKE_armature_refresh_layer_used(struct Depsgraph *depsgraph, struct bArmature *arm);
 
 float distfactor_to_bone(
     const float vec[3], const float b1[3], const float b2[3], float r1, float r2, float rdist);
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index af98992cc01..04051edd334 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -66,6 +66,7 @@
 #include "BKE_scene.h"
 
 #include "DEG_depsgraph_build.h"
+#include "DEG_depsgraph_query.h"
 
 #include "BIK_api.h"
 
@@ -480,14 +481,21 @@ static void armature_refresh_layer_used_recursive(bArmature *arm, ListBase *bone
   }
 }
 
-/* Update the layers_used variable after bones are moved between layer
- * NOTE: Used to be done in drawing code in 2.7, but that won't work with
- *       Copy-on-Write, as drawing uses evaluated copies.
- */
-void BKE_armature_refresh_layer_used(bArmature *arm)
+void BKE_armature_refresh_layer_used(struct Depsgraph *depsgraph, struct bArmature *arm)
 {
+  if (arm->edbo != NULL) {
+    /* Don't perform this update when the armature is in edit mode. In that case it should be
+     * handled by ED_armature_edit_refresh_layer_used(). */
+    return;
+  }
+
   arm->layer_used = 0;
   armature_refresh_layer_used_recursive(arm, &arm->bonebase);
+
+  if (depsgraph == NULL || DEG_is_active(depsgraph)) {
+    bArmature *arm_orig = (bArmature *)DEG_get_original_id(&arm->id);
+    arm_orig->layer_used = arm->layer_used;
+  }
 }
 
 /* Finds the best possible extension to the name on a particular axis. (For renaming, check for
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
index f6834feeeae..0e84494b2b7 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
@@ -1413,7 +1413,11 @@ void DepsgraphNodeBuilder::build_armature(bArmature *armature)
   build_animdata(&armature->id);
   build_parameters(&armature->id);
   /* Make sure pose is up-to-date with armature updates. */
-  add_operation_node(&armature->id, NodeType::ARMATURE, OperationCode::ARMATURE_EVAL);
+  bArmature *armature_cow = (bArmature *)get_cow_id(&armature->id);
+  add_operation_node(&armature->id,
+                     NodeType::ARMATURE,
+                     OperationCode::ARMATURE_EVAL,
+                     function_bind(BKE_armature_refresh_layer_used, _1, armature_cow));
   build_armature_bones(&armature->bonebase);
 }
 
diff --git a/source/blender/editors/armature/armature_relations.c b/source/blender/editors/armature/armature_relations.c
index bc854747a68..d544aed5481 100644
--- a/source/blender/editors/armature/armature_relations.c
+++ b/source/blender/editors/armature/armature_relations.c
@@ -432,7 +432,6 @@ int join_armature_exec(bContext *C, wmOperator *op)
   ED_armature_from_edit(bmain, arm);
   ED_armature_edit_free(arm);
 
-  BKE_armature_refresh_layer_used(arm);
   DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
   WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
 
@@ -689,9 +688,7 @@ static int separate_armature_exec(bContext *C, wmOperator *op)
 
     /* 5) restore original conditions */
     ED_armature_to_edit(ob_old->data);
-
     ED_armature_edit_refresh_layer_used(ob_old->data);
-    BKE_armature_refresh_layer_used(ob_new->data);
 
     /* parents tips remain selected when connected children are removed. */
     ED_armature_edit_deselect_all(ob_old);
diff --git a/source/blender/editors/armature/pose_edit.c b/source/blender/editors/armature/pose_edit.c
index b86da6374be..c5b9f6adb28 100644
--- a/source/blender/editors/armature/pose_edit.c
+++ b/source/blender/editors/armature/pose_edit.c
@@ -901,8 +901,6 @@ static int pose_bone_layers_exec(bContext *C, wmOperator *op)
     RNA_boolean_set_array(&ptr, "layers", layers);
 
     if (prev_ob != ob) {
-      BKE_armature_refresh_layer_used(ob->data);
-
       /* Note, notifier might evolve. */
       WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
       DEG_id_tag_update((ID *)ob->data, ID_RECALC_COPY_ON_WRITE);
diff --git a/source/blender/makesrna/intern/rna_armature.c b/source/blender/makesrna/intern/rna_armature.c
index 3afbd0405fe..fe35af8c2e0 100644
--- a/source/blender/makesrna/intern/rna_armature.c
+++ b/source/blender/makesrna/intern/rna_armature.c
@@ -301,8 +301,7 @@ static void rna_Bone_layer_set(PointerRNA *ptr, const bool *values)
   Bone *bone = (Bone *)ptr->data;
 
   rna_bone_layer_set(&bone->layer, values);
-
-  BKE_armature_refresh_layer_used(arm);
+  BKE_armature_refresh_layer_used(NULL, arm);
 }
 
 /* TODO: remove the deprecation stubs. */



More information about the Bf-blender-cvs mailing list