diff options
Diffstat (limited to 'source/blender/blenkernel/intern/action.c')
-rw-r--r-- | source/blender/blenkernel/intern/action.c | 70 |
1 files changed, 63 insertions, 7 deletions
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index b35d2183408..85ac2c693cb 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -37,6 +37,7 @@ #include "BLI_blenlib.h" #include "BLI_ghash.h" #include "BLI_math.h" +#include "BLI_session_uuid.h" #include "BLI_string_utils.h" #include "BLI_utildefines.h" @@ -482,6 +483,11 @@ void action_groups_clear_tempflags(bAction *act) /* *************** Pose channels *************** */ +void BKE_pose_channel_session_uuid_generate(bPoseChannel *pchan) +{ + pchan->runtime.session_uuid = BLI_session_uuid_generate(); +} + /** * Return a pointer to the pose channel of the given name * from this pose. @@ -524,6 +530,8 @@ bPoseChannel *BKE_pose_channel_verify(bPose *pose, const char *name) /* If not, create it and add it */ chan = MEM_callocN(sizeof(bPoseChannel), "verifyPoseChannel"); + BKE_pose_channel_session_uuid_generate(chan); + BLI_strncpy(chan->name, name, sizeof(chan->name)); chan->custom_scale = 1.0f; @@ -698,6 +706,10 @@ void BKE_pose_copy_data_ex(bPose **dst, id_us_plus((ID *)pchan->custom); } + if ((flag & LIB_ID_CREATE_NO_MAIN) == 0) { + BKE_pose_channel_session_uuid_generate(pchan); + } + /* warning, O(n2) here, if done without the hash, but these are rarely used features. */ if (pchan->custom_tx) { pchan->custom_tx = BKE_pose_channel_find_name(outPose, pchan->custom_tx->name); @@ -726,7 +738,7 @@ void BKE_pose_copy_data_ex(bPose **dst, pchan->draw_data = NULL; /* Drawing cache, no need to copy. */ /* Runtime data, no need to copy. */ - memset(&pchan->runtime, 0, sizeof(pchan->runtime)); + BKE_pose_channel_runtime_reset_on_copy(&pchan->runtime); } /* for now, duplicate Bone Groups too when doing this */ @@ -956,6 +968,14 @@ void BKE_pose_channel_runtime_reset(bPoseChannel_Runtime *runtime) memset(runtime, 0, sizeof(*runtime)); } +/* Reset all non-persistent fields. */ +void BKE_pose_channel_runtime_reset_on_copy(bPoseChannel_Runtime *runtime) +{ + const SessionUUID uuid = runtime->session_uuid; + memset(runtime, 0, sizeof(*runtime)); + runtime->session_uuid = uuid; +} + /** Deallocates runtime cache of a pose channel */ void BKE_pose_channel_runtime_free(bPoseChannel_Runtime *runtime) { @@ -1512,8 +1532,10 @@ short action_get_item_transforms(bAction *act, Object *ob, bPoseChannel *pchan, /* ************** Pose Management Tools ****************** */ -/* for do_all_pose_actions, clears the pose. Now also exported for proxy and tools */ -void BKE_pose_rest(bPose *pose) +/** + * Zero the pose transforms for the entire pose or only for selected bones. + */ +void BKE_pose_rest(bPose *pose, bool selected_bones_only) { bPoseChannel *pchan; @@ -1525,6 +1547,9 @@ void BKE_pose_rest(bPose *pose) memset(pose->cyclic_offset, 0, sizeof(pose->cyclic_offset)); for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) { + if (selected_bones_only && pchan->bone != NULL && (pchan->bone->flag & BONE_SELECTED) == 0) { + continue; + } zero_v3(pchan->loc); zero_v3(pchan->eul); unit_qt(pchan->quat); @@ -1612,8 +1637,12 @@ void BKE_pose_tag_recalc(Main *bmain, bPose *pose) /* For the calculation of the effects of an Action at the given frame on an object * This is currently only used for the Action Constraint */ -void what_does_obaction( - Object *ob, Object *workob, bPose *pose, bAction *act, char groupname[], float cframe) +void what_does_obaction(Object *ob, + Object *workob, + bPose *pose, + bAction *act, + char groupname[], + const AnimationEvalContext *anim_eval_context) { bActionGroup *agrp = BKE_action_group_find_name(act, groupname); @@ -1669,7 +1698,7 @@ void what_does_obaction( RNA_id_pointer_create(&workob->id, &id_ptr); /* execute action for this group only */ - animsys_evaluate_action_group(&id_ptr, act, agrp, cframe); + animsys_evaluate_action_group(&id_ptr, act, agrp, anim_eval_context); } else { AnimData adt = {NULL}; @@ -1680,6 +1709,33 @@ void what_does_obaction( adt.action = act; /* execute effects of Action on to workob (or it's PoseChannels) */ - BKE_animsys_evaluate_animdata(&workob->id, &adt, cframe, ADT_RECALC_ANIM, false); + BKE_animsys_evaluate_animdata(&workob->id, &adt, anim_eval_context, ADT_RECALC_ANIM, false); + } +} + +void BKE_pose_check_uuids_unique_and_report(const bPose *pose) +{ + if (pose == NULL) { + return; } + + struct GSet *used_uuids = BLI_gset_new( + BLI_session_uuid_ghash_hash, BLI_session_uuid_ghash_compare, "sequencer used uuids"); + + LISTBASE_FOREACH (bPoseChannel *, pchan, &pose->chanbase) { + const SessionUUID *session_uuid = &pchan->runtime.session_uuid; + if (!BLI_session_uuid_is_generated(session_uuid)) { + printf("Pose channel %s does not have UUID generated.\n", pchan->name); + continue; + } + + if (BLI_gset_lookup(used_uuids, session_uuid) != NULL) { + printf("Pose channel %s has duplicate UUID generated.\n", pchan->name); + continue; + } + + BLI_gset_insert(used_uuids, (void *)session_uuid); + } + + BLI_gset_free(used_uuids, NULL); } |