diff options
6 files changed, 49 insertions, 18 deletions
diff --git a/source/blender/depsgraph/intern/builder/deg_builder.cc b/source/blender/depsgraph/intern/builder/deg_builder.cc index 5e35a620c81..b8e0ba51019 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder.cc @@ -26,6 +26,7 @@ #include <cstring> #include "DNA_anim_types.h" +#include "DNA_armature_types.h" #include "DNA_layer_types.h" #include "DNA_ID.h" #include "DNA_object_types.h" @@ -34,6 +35,8 @@ #include "BLI_ghash.h" #include "BLI_stack.h" +#include "BKE_action.h" + extern "C" { #include "BKE_animsys.h" } @@ -97,6 +100,38 @@ bool DepsgraphBuilder::need_pull_base_into_graph(Base *base) return cache_->isPropertyAnimated(&object->id, property_id); } +bool DepsgraphBuilder::check_pchan_has_bbone(Object *object, const bPoseChannel *pchan) +{ + BLI_assert(object->type == OB_ARMATURE); + if (pchan->bone == NULL) { + return false; + } + /* We don't really care whether segments are higher than 1 due to static user input (as in, + * rigger entered value like 3 manually), or due to animation. In either way we need to create + * special evaluation. */ + if (pchan->bone->segments > 1) { + return true; + } + bArmature *armature = static_cast<bArmature *>(object->data); + AnimatedPropertyID property_id(&armature->id, &RNA_Bone, pchan->bone, "bbone_segments"); + return cache_->isPropertyAnimated(&armature->id, property_id); +} + +bool DepsgraphBuilder::check_pchan_has_bbone_segments(Object *object, const bPoseChannel *pchan) +{ + /* Proxies don't have BONE_SEGMENTS */ + if (ID_IS_LINKED(object) && object->proxy_from != NULL) { + return false; + } + return check_pchan_has_bbone(object, pchan); +} + +bool DepsgraphBuilder::check_pchan_has_bbone_segments(Object *object, const char *bone_name) +{ + const bPoseChannel *pchan = BKE_pose_channel_find_name(object->pose, bone_name); + return check_pchan_has_bbone_segments(object, pchan); +} + /******************************************************************************* * Builder finalizer. */ diff --git a/source/blender/depsgraph/intern/builder/deg_builder.h b/source/blender/depsgraph/intern/builder/deg_builder.h index 2f5bc42aeae..224e3212d57 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder.h +++ b/source/blender/depsgraph/intern/builder/deg_builder.h @@ -23,8 +23,10 @@ #pragma once +struct bPoseChannel; struct Base; struct Main; +struct Object; namespace DEG { @@ -35,6 +37,10 @@ class DepsgraphBuilder { public: bool need_pull_base_into_graph(Base *base); + bool check_pchan_has_bbone(Object *object, const bPoseChannel *pchan); + bool check_pchan_has_bbone_segments(Object *object, const bPoseChannel *pchan); + bool check_pchan_has_bbone_segments(Object *object, const char *bone_name); + protected: /* NOTE: The builder does NOT take ownership over any of those resources. */ DepsgraphBuilder(Main *bmain, Depsgraph *graph, DepsgraphBuilderCache *cache); @@ -46,6 +52,6 @@ class DepsgraphBuilder { }; bool deg_check_base_in_depsgraph(const Depsgraph *graph, Base *base); -void deg_graph_build_finalize(struct Main *bmain, struct Depsgraph *graph); +void deg_graph_build_finalize(Main *bmain, Depsgraph *graph); } // namespace DEG diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc index 6f141bd7222..979e1a02e71 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc @@ -231,7 +231,7 @@ void DepsgraphNodeBuilder::build_rig(Object *object, bool is_object_visible) function_bind(BKE_pose_bone_done, _1, object_cow, pchan_index)); /* B-Bone shape computation - the real last step if present. */ - if (pchan->bone != NULL && pchan->bone->segments > 1) { + if (check_pchan_has_bbone(object, pchan)) { op_node = add_operation_node( &object->id, NodeType::BONE, diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 36cc105273d..147d82c5999 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -196,17 +196,6 @@ static OperationCode bone_target_opcode(ID *target, return OperationCode::BONE_DONE; } -static bool bone_has_segments(Object *object, const char *bone_name) -{ - /* Proxies don't have BONE_SEGMENTS */ - if (ID_IS_LINKED(object) && object->proxy_from != NULL) { - return false; - } - /* Only B-Bones have segments. */ - bPoseChannel *pchan = BKE_pose_channel_find_name(object->pose, bone_name); - return pchan && pchan->bone && pchan->bone->segments > 1; -} - /* **** General purpose functions **** */ DepsgraphRelationBuilder::DepsgraphRelationBuilder(Main *bmain, @@ -1019,7 +1008,7 @@ void DepsgraphRelationBuilder::build_constraints(ID *id, } /* if needs bbone shape, reference the segment computation */ if (BKE_constraint_target_uses_bbone(con, ct) && - bone_has_segments(ct->tar, ct->subtarget)) { + check_pchan_has_bbone_segments(ct->tar, ct->subtarget)) { opcode = OperationCode::BONE_SEGMENTS; } OperationKey target_key(&ct->tar->id, NodeType::BONE, ct->subtarget, opcode); diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc index c1f904150f3..fadce685d31 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc @@ -374,7 +374,7 @@ void DepsgraphRelationBuilder::build_rig(Object *object) * to done, with transitive reduction removing this one. */ add_relation(bone_ready_key, bone_done_key, "Ready -> Done"); /* B-Bone shape is the real final step after Done if present. */ - if (pchan->bone != NULL && pchan->bone->segments > 1) { + if (check_pchan_has_bbone(object, pchan)) { OperationKey bone_segments_key( &object->id, NodeType::BONE, pchan->name, OperationCode::BONE_SEGMENTS); /* B-Bone shape depends on the final position of the bone. */ @@ -434,7 +434,7 @@ void DepsgraphRelationBuilder::build_proxy_rig(Object *object) add_relation(bone_done_key, pose_cleanup_key, "Bone Done -> Pose Cleanup"); add_relation(bone_done_key, pose_done_key, "Bone Done -> Pose Done", RELATION_FLAG_GODMODE); /* Make sure bone in the proxy is not done before it's FROM is done. */ - if (pchan->bone && pchan->bone->segments > 1) { + if (check_pchan_has_bbone(object, pchan)) { OperationKey from_bone_segments_key( &proxy_from->id, NodeType::BONE, pchan->name, OperationCode::BONE_SEGMENTS); add_relation(from_bone_segments_key, diff --git a/source/blender/depsgraph/intern/builder/deg_builder_rna.cc b/source/blender/depsgraph/intern/builder/deg_builder_rna.cc index ac4e8e84d44..1238cdc70c6 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_rna.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_rna.cc @@ -197,8 +197,9 @@ RNANodeIdentifier RNANodeQuery::construct_node_identifier(const PointerRNA *ptr, node_identifier.type = NodeType::BONE; node_identifier.component_name = pchan->name; /* But B-Bone properties should connect to the actual operation. */ - if (!ELEM(NULL, pchan->bone, prop) && pchan->bone->segments > 1 && - STRPREFIX(RNA_property_identifier(prop), "bbone_")) { + Object *object = reinterpret_cast<Object *>(node_identifier.id); + if (!ELEM(NULL, pchan->bone, prop) && STRPREFIX(RNA_property_identifier(prop), "bbone_") && + builder_->check_pchan_has_bbone_segments(object, pchan)) { node_identifier.operation_code = OperationCode::BONE_SEGMENTS; } } |