diff options
author | Alexander Gavrilov <angavrilov@gmail.com> | 2018-10-31 19:12:59 +0300 |
---|---|---|
committer | Alexander Gavrilov <angavrilov@gmail.com> | 2018-10-31 20:04:01 +0300 |
commit | 748b89f12462c13025e0f9c61cc6f38e22cd53f2 (patch) | |
tree | 7ad4d89b12e21278a85f6b3fea074909b172eb8e /source/blender | |
parent | 9fbba61f4b4b95b7f4d9e8c45b3db57dc97fe15d (diff) |
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
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/blenkernel/BKE_armature.h | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/armature.c | 39 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_armature.c | 61 |
3 files changed, 78 insertions, 23 deletions
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...) */ |