[Bf-blender-cvs] [748b89f1246] blender2.8: Allow changing B-Bone custom handle references from Pose Mode.

Alexander Gavrilov noreply at git.blender.org
Wed Oct 31 18:04:40 CET 2018


Commit: 748b89f12462c13025e0f9c61cc6f38e22cd53f2
Author: Alexander Gavrilov
Date:   Wed Oct 31 19:12:59 2018 +0300
Branches: blender2.8
https://developer.blender.org/rB748b89f12462c13025e0f9c61cc6f38e22cd53f2

Allow changing B-Bone custom handle references from Pose Mode.

@jpbouza was rather upset these were made read-only, and unlike
parents, it's not that hard to allow changing these Bone fields:
all is needed is to carefully refresh the matching fields in the
relevant bPoseChannel objects and properly tag update.

Reviewers: brecht

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

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

M	release/scripts/startup/bl_ui/properties_data_bone.py
M	source/blender/blenkernel/BKE_armature.h
M	source/blender/blenkernel/intern/armature.c
M	source/blender/makesrna/intern/rna_armature.c

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

diff --git a/release/scripts/startup/bl_ui/properties_data_bone.py b/release/scripts/startup/bl_ui/properties_data_bone.py
index 60464ca48cb..4fafadc0559 100644
--- a/release/scripts/startup/bl_ui/properties_data_bone.py
+++ b/release/scripts/startup/bl_ui/properties_data_bone.py
@@ -130,7 +130,7 @@ class BONE_PT_curved(BoneButtonsPanel, Panel):
         bone = context.bone
         # arm = context.armature
         pchan = None
-        edit = False
+        bone_list = "bones"
 
         if ob and bone:
             pchan = ob.pose.bones[bone.name]
@@ -138,7 +138,7 @@ class BONE_PT_curved(BoneButtonsPanel, Panel):
         elif bone is None:
             bone = context.edit_bone
             bbone = bone
-            edit = True
+            bone_list = "edit_bones"
         else:
             bbone = bone
 
@@ -176,22 +176,14 @@ class BONE_PT_curved(BoneButtonsPanel, Panel):
 
         col = col.column(align=True)
         col.active = (bone.bbone_handle_type_start != "AUTO")
-        if edit:
-            col.prop_search(bone, "bbone_custom_handle_start", ob.data, "edit_bones", text="Custom")
-        else:
-            # read-only
-            col.prop(bbone, "bbone_custom_handle_start", text="Custom")
+        col.prop_search(bone, "bbone_custom_handle_start", ob.data, bone_list, text="Custom")
 
         col = topcol.column(align=True)
         col.prop(bone, "bbone_handle_type_end", text="End Handle")
 
         col = col.column(align=True)
         col.active = (bone.bbone_handle_type_end != "AUTO")
-        if edit:
-            col.prop_search(bone, "bbone_custom_handle_end", ob.data, "edit_bones", text="Custom")
-        else:
-            # read-only
-            col.prop(bbone, "bbone_custom_handle_end", text="Custom")
+        col.prop_search(bone, "bbone_custom_handle_end", ob.data, bone_list, text="Custom")
 
 
 class BONE_PT_relations(BoneButtonsPanel, Panel):
diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h
index 666c6758ce0..b57630a348e 100644
--- a/source/blender/blenkernel/BKE_armature.h
+++ b/source/blender/blenkernel/BKE_armature.h
@@ -100,6 +100,7 @@ void BKE_armature_where_is(struct bArmature *arm);
 void BKE_armature_where_is_bone(struct Bone *bone, struct Bone *prevbone, const bool use_recursion);
 void BKE_pose_clear_pointers(struct bPose *pose);
 void BKE_pose_remap_bone_pointers(struct bArmature *armature, struct bPose *pose);
+void BKE_pchan_rebuild_bbone_handles(struct bPose *pose, struct bPoseChannel *pchan);
 void BKE_pose_rebuild(struct Main *bmain, struct Object *ob, struct bArmature *arm, const bool do_id_user);
 void BKE_pose_where_is(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob);
 void BKE_pose_where_is_bone(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob, struct bPoseChannel *pchan, float ctime, bool do_extra);
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index e0caec323c1..be29819a0ee 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -1953,6 +1953,8 @@ static void pose_proxy_synchronize(Object *ob, Object *from, int layer_protected
 			pchanw.parent = pchan->parent;
 			pchanw.child = pchan->child;
 			pchanw.custom_tx = pchan->custom_tx;
+			pchanw.bbone_prev = pchan->bbone_prev;
+			pchanw.bbone_next = pchan->bbone_next;
 
 			pchanw.mpath = pchan->mpath;
 			pchan->mpath = NULL;
@@ -2077,6 +2079,19 @@ void BKE_pose_remap_bone_pointers(bArmature *armature, bPose *pose)
 	BLI_ghash_free(bone_hash, NULL, NULL);
 }
 
+/** Find the matching pose channel using the bone name, if not NULL. */
+static bPoseChannel *pose_channel_find_bone(bPose *pose, Bone *bone)
+{
+	return (bone != NULL) ? BKE_pose_channel_find_name(pose, bone->name) : NULL;
+}
+
+/** Update the links for the B-Bone handles from Bone data. */
+void BKE_pchan_rebuild_bbone_handles(bPose *pose, bPoseChannel *pchan)
+{
+	pchan->bbone_prev = pose_channel_find_bone(pose, pchan->bone->bbone_prev);
+	pchan->bbone_next = pose_channel_find_bone(pose, pchan->bone->bbone_next);
+}
+
 /**
  * Only after leave editmode, duplicating, validating older files, library syncing.
  *
@@ -2117,23 +2132,15 @@ void BKE_pose_rebuild(Main *bmain, Object *ob, bArmature *arm, const bool do_id_
 			BKE_pose_channels_hash_free(pose);
 			BLI_freelinkN(&pose->chanbase, pchan);
 		}
-		else {
-			/* Find the custom B-Bone handles. */
-			if (pchan->bone->bbone_prev) {
-				pchan->bbone_prev = BKE_pose_channel_find_name(pose, pchan->bone->bbone_prev->name);
-			}
-			else {
-				pchan->bbone_prev = NULL;
-			}
+	}
 
-			if (pchan->bone->bbone_next) {
-				pchan->bbone_next = BKE_pose_channel_find_name(pose, pchan->bone->bbone_next->name);
-			}
-			else {
-				pchan->bbone_next = NULL;
-			}
-		}
+	BKE_pose_channels_hash_make(pose);
+
+	for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) {
+		/* Find the custom B-Bone handles. */
+		BKE_pchan_rebuild_bbone_handles(pose, pchan);
 	}
+
 	/* printf("rebuild pose %s, %d bones\n", ob->id.name, counter); */
 
 	/* synchronize protected layers with proxy */
@@ -2150,8 +2157,6 @@ void BKE_pose_rebuild(Main *bmain, Object *ob, bArmature *arm, const bool do_id_
 	pose->flag &= ~POSE_RECALC;
 	pose->flag |= POSE_WAS_REBUILT;
 
-	BKE_pose_channels_hash_make(pose);
-
 	/* Rebuilding poses forces us to also rebuild the dependency graph, since there is one node per pose/bone... */
 	if (bmain != NULL) {
 		DEG_relations_tag_update(bmain);
diff --git a/source/blender/makesrna/intern/rna_armature.c b/source/blender/makesrna/intern/rna_armature.c
index 2a83d7350bb..ea39b1f46eb 100644
--- a/source/blender/makesrna/intern/rna_armature.c
+++ b/source/blender/makesrna/intern/rna_armature.c
@@ -43,6 +43,7 @@
 
 #ifdef RNA_RUNTIME
 
+#include "BKE_action.h"
 #include "BKE_context.h"
 #include "BKE_global.h"
 #include "BKE_idprop.h"
@@ -449,6 +450,26 @@ static void rna_EditBone_matrix_set(PointerRNA *ptr, const float *values)
 	ED_armature_ebone_from_mat4(ebone, (float(*)[4])values);
 }
 
+static void rna_Bone_bbone_handle_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+{
+	bArmature *arm = (bArmature *)ptr->id.data;
+	Bone *bone = (Bone *)ptr->data;
+
+	/* Update all users of this armature after changing B-Bone handles. */
+	for (Object *obt = bmain->object.first; obt; obt = obt->id.next) {
+		if (obt->data == arm && obt->pose) {
+			bPoseChannel *pchan = BKE_pose_channel_find_name(obt->pose, bone->name);
+
+			if (pchan && pchan->bone == bone) {
+				BKE_pchan_rebuild_bbone_handles(obt->pose, pchan);
+				DEG_id_tag_update(&obt->id, DEG_TAG_COPY_ON_WRITE);
+			}
+		}
+	}
+
+	rna_Armature_dependency_update(bmain, scene, ptr);
+}
+
 static PointerRNA rna_EditBone_bbone_prev_get(PointerRNA *ptr)
 {
 	EditBone *data = (EditBone *)(ptr->data);
@@ -466,6 +487,17 @@ static void rna_EditBone_bbone_prev_set(PointerRNA *ptr, PointerRNA value)
 	}
 }
 
+static void rna_Bone_bbone_prev_set(PointerRNA *ptr, PointerRNA value)
+{
+	Bone *bone = (Bone *)ptr->data;
+	Bone *hbone = (Bone *)value.data;
+
+	/* Within the same armature? */
+	if (hbone == NULL || value.id.data == ptr->id.data) {
+		bone->bbone_prev = hbone;
+	}
+}
+
 static PointerRNA rna_EditBone_bbone_next_get(PointerRNA *ptr)
 {
 	EditBone *data = (EditBone *)(ptr->data);
@@ -483,6 +515,17 @@ static void rna_EditBone_bbone_next_set(PointerRNA *ptr, PointerRNA value)
 	}
 }
 
+static void rna_Bone_bbone_next_set(PointerRNA *ptr, PointerRNA value)
+{
+	Bone *bone = (Bone *)ptr->data;
+	Bone *hbone = (Bone *)value.data;
+
+	/* Within the same armature? */
+	if (hbone == NULL || value.id.data == ptr->id.data) {
+		bone->bbone_next = hbone;
+	}
+}
+
 static void rna_Armature_editbone_transform_update(Main *bmain, Scene *scene, PointerRNA *ptr)
 {
 	bArmature *arm = (bArmature *)ptr->id.data;
@@ -799,13 +842,16 @@ static void rna_def_bone_common(StructRNA *srna, int editbone)
 	RNA_def_property_pointer_sdna(prop, NULL, "bbone_prev");
 	RNA_def_property_struct_type(prop, editbone ? "EditBone" : "Bone");
 	if (editbone) {
-		RNA_def_property_flag(prop, PROP_EDITABLE);
 		RNA_def_property_pointer_funcs(prop, "rna_EditBone_bbone_prev_get", "rna_EditBone_bbone_prev_set", NULL, NULL);
+		RNA_def_property_update(prop, 0, "rna_Armature_dependency_update");
 	}
-	RNA_def_property_flag(prop, PROP_PTR_NO_OWNERSHIP);
+	else {
+		RNA_def_property_pointer_funcs(prop, NULL, "rna_Bone_bbone_prev_set", NULL, NULL);
+		RNA_def_property_update(prop, 0, "rna_Bone_bbone_handle_update");
+	}
+	RNA_def_property_flag(prop, PROP_EDITABLE | PROP_PTR_NO_OWNERSHIP);
 	RNA_def_property_ui_text(prop, "B-Bone Start Handle",
 	                         "Bone that serves as the start handle for the B-Bone curve");
-	RNA_def_property_update(prop, 0, "rna_Armature_dependency_update");
 
 	prop = RNA_def_property(srna, "bbone_handle_type_end", PROP_ENUM, PROP_NONE);
 	RNA_def_property_enum_sdna(prop, NULL, "bbone_next_type");
@@ -818,13 +864,16 @@ static void rna_def_bone_common(StructRNA *srna, int editbone)
 	RNA_def_property_pointer_sdna(prop, NULL, "bbone_next");
 	RNA_def_property_struct_type(prop, editbone ? "EditBone" : "Bone");
 	if (editbone) {
-		RNA_def_property_flag(prop, PROP_EDITABLE);
 		RNA_def_property_pointer_funcs(prop, "rna_EditBone_bbone_next_get", "rna_EditBone_bbone_next_set", NULL, NULL);
+		RNA_def_property_update(prop, 0, "rna_Armature_dependency_update");
 	}
-	RNA_def_property_flag(prop, PROP_PTR_NO_OWNERSHIP);
+	else {
+		RNA_def_property_pointer_funcs(prop, NULL, "rna_Bone_bbone_next_set", NULL, NULL);
+		RNA_def_property_update(prop, 0, "rna_Bone_bbone_handle_update");
+	}
+	RNA_def_property_flag(prop, PROP_EDITABLE | PROP_PTR_NO_OWNERSHIP);
 	RNA_def_property_ui_text(prop, "B-Bone End Handle",
 	                         "Bone that serves as the end handle for the B-Bone curve");
-	RNA_def_property_update(prop, 0, "rna_Armature_dependency_update");
 }
 
 /* err... bones should not be directly edited (only editbones should be...) */



More information about the Bf-blender-cvs mailing list