Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel/intern/action.c')
-rw-r--r--source/blender/blenkernel/intern/action.c70
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);
}