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.c207
1 files changed, 188 insertions, 19 deletions
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c
index 64a8ae15fd3..126063288d8 100644
--- a/source/blender/blenkernel/intern/action.c
+++ b/source/blender/blenkernel/intern/action.c
@@ -47,6 +47,7 @@
#include "BLT_translation.h"
#include "BKE_action.h"
+#include "BKE_anim_data.h"
#include "BKE_anim_visualization.h"
#include "BKE_animsys.h"
#include "BKE_armature.h"
@@ -60,6 +61,7 @@
#include "BKE_main.h"
#include "BKE_object.h"
+#include "DEG_depsgraph.h"
#include "DEG_depsgraph_build.h"
#include "BIK_api.h"
@@ -198,17 +200,17 @@ static void action_blend_read_data(BlendDataReader *reader, ID *id)
bAction *act = (bAction *)id;
BLO_read_list(reader, &act->curves);
- BLO_read_list(reader, &act->chanbase); // XXX deprecated - old animation system
+ BLO_read_list(reader, &act->chanbase); /* XXX deprecated - old animation system */
BLO_read_list(reader, &act->groups);
BLO_read_list(reader, &act->markers);
- // XXX deprecated - old animation system <<<
+ /* XXX deprecated - old animation system <<< */
LISTBASE_FOREACH (bActionChannel *, achan, &act->chanbase) {
BLO_read_data_address(reader, &achan->grp);
BLO_read_list(reader, &achan->constraintChannels);
}
- // >>> XXX deprecated - old animation system
+ /* >>> XXX deprecated - old animation system */
BKE_fcurve_blend_read_data(reader, &act->curves);
@@ -229,12 +231,12 @@ static void action_blend_read_lib(BlendLibReader *reader, ID *id)
{
bAction *act = (bAction *)id;
- // XXX deprecated - old animation system <<<
+ /* XXX deprecated - old animation system <<< */
LISTBASE_FOREACH (bActionChannel *, chan, &act->chanbase) {
BLO_read_id_address(reader, act->id.lib, &chan->ipo);
blend_read_lib_constraint_channels(reader, &act->id, &chan->constraintChannels);
}
- // >>> XXX deprecated - old animation system
+ /* >>> XXX deprecated - old animation system */
BKE_fcurve_blend_read_lib(reader, &act->id, &act->curves);
@@ -256,12 +258,12 @@ static void action_blend_read_expand(BlendExpander *expander, ID *id)
{
bAction *act = (bAction *)id;
- // XXX deprecated - old animation system --------------
+ /* XXX deprecated - old animation system -------------- */
LISTBASE_FOREACH (bActionChannel *, chan, &act->chanbase) {
BLO_expand(expander, chan->ipo);
blend_read_expand_constraint_channels(expander, &chan->constraintChannels);
}
- // ---------------------------------------------------
+ /* --------------------------------------------------- */
/* F-Curves in Action */
BKE_fcurve_blend_read_expand(expander, &act->curves);
@@ -281,7 +283,7 @@ IDTypeInfo IDType_ID_AC = {
.name = "Action",
.name_plural = "actions",
.translation_context = BLT_I18NCONTEXT_ID_ACTION,
- .flags = 0,
+ .flags = IDTYPE_FLAGS_NO_ANIMDATA,
.init_data = NULL,
.copy_data = action_copy_data,
@@ -294,6 +296,8 @@ IDTypeInfo IDType_ID_AC = {
.blend_read_data = action_blend_read_data,
.blend_read_lib = action_blend_read_lib,
.blend_read_expand = action_blend_read_expand,
+
+ .blend_read_undo_preserve = NULL,
};
/* ***************** Library data level operations on action ************** */
@@ -302,20 +306,13 @@ bAction *BKE_action_add(Main *bmain, const char name[])
{
bAction *act;
- act = BKE_libblock_alloc(bmain, ID_AC, name, 0);
+ act = BKE_id_new(bmain, ID_AC, name);
return act;
}
/* .................................. */
-bAction *BKE_action_copy(Main *bmain, const bAction *act_src)
-{
- bAction *act_copy;
- BKE_id_copy(bmain, &act_src->id, (ID **)&act_copy);
- return act_copy;
-}
-
/* *************** Action Groups *************** */
/* Get the active action-group for an Action */
@@ -774,7 +771,7 @@ const char *BKE_pose_ikparam_get_name(bPose *pose)
}
/**
- * Allocate a new pose on the heap, and copy the src pose and it's channels
+ * Allocate a new pose on the heap, and copy the src pose and its channels
* into the new pose. *dst is set to the newly allocated structure, and assumed to be NULL.
*
* \param dst: Should be freed already, makes entire duplicate.
@@ -833,7 +830,7 @@ void BKE_pose_copy_data_ex(bPose **dst,
if (copy_constraints) {
BKE_constraints_copy_ex(
- &listb, &pchan->constraints, flag, true); // BKE_constraints_copy NULLs listb
+ &listb, &pchan->constraints, flag, true); /* BKE_constraints_copy NULLs listb */
pchan->constraints = listb;
/* XXX: This is needed for motionpath drawing to work.
@@ -1817,8 +1814,9 @@ void what_does_obaction(Object *ob,
workob->adt = &adt;
adt.action = act;
+ BKE_animdata_action_ensure_idroot(&workob->id, act);
- /* execute effects of Action on to workob (or it's PoseChannels) */
+ /* execute effects of Action on to workob (or its PoseChannels) */
BKE_animsys_evaluate_animdata(&workob->id, &adt, anim_eval_context, ADT_RECALC_ANIM, false);
}
}
@@ -1849,3 +1847,174 @@ void BKE_pose_check_uuids_unique_and_report(const bPose *pose)
BLI_gset_free(used_uuids, NULL);
}
+
+void BKE_pose_blend_write(BlendWriter *writer, bPose *pose, bArmature *arm)
+{
+ /* Write each channel */
+ if (pose == NULL) {
+ return;
+ }
+
+ BLI_assert(arm != NULL);
+
+ /* Write channels */
+ LISTBASE_FOREACH (bPoseChannel *, chan, &pose->chanbase) {
+ /* Write ID Properties -- and copy this comment EXACTLY for easy finding
+ * of library blocks that implement this.*/
+ if (chan->prop) {
+ IDP_BlendWrite(writer, chan->prop);
+ }
+
+ BKE_constraint_blend_write(writer, &chan->constraints);
+
+ animviz_motionpath_blend_write(writer, chan->mpath);
+
+ /* Prevent crashes with autosave,
+ * when a bone duplicated in edit-mode has not yet been assigned to its pose-channel.
+ * Also needed with memundo, in some cases we can store a step before pose has been
+ * properly rebuilt from previous undo step. */
+ Bone *bone = (pose->flag & POSE_RECALC) ? BKE_armature_find_bone_name(arm, chan->name) :
+ chan->bone;
+ if (bone != NULL) {
+ /* gets restored on read, for library armatures */
+ chan->selectflag = bone->flag & BONE_SELECTED;
+ }
+
+ BLO_write_struct(writer, bPoseChannel, chan);
+ }
+
+ /* Write groups */
+ LISTBASE_FOREACH (bActionGroup *, grp, &pose->agroups) {
+ BLO_write_struct(writer, bActionGroup, grp);
+ }
+
+ /* write IK param */
+ if (pose->ikparam) {
+ const char *structname = BKE_pose_ikparam_get_name(pose);
+ if (structname) {
+ BLO_write_struct_by_name(writer, structname, pose->ikparam);
+ }
+ }
+
+ /* Write this pose */
+ BLO_write_struct(writer, bPose, pose);
+}
+
+void BKE_pose_blend_read_data(BlendDataReader *reader, bPose *pose)
+{
+ if (!pose) {
+ return;
+ }
+
+ BLO_read_list(reader, &pose->chanbase);
+ BLO_read_list(reader, &pose->agroups);
+
+ pose->chanhash = NULL;
+ pose->chan_array = NULL;
+
+ LISTBASE_FOREACH (bPoseChannel *, pchan, &pose->chanbase) {
+ BKE_pose_channel_runtime_reset(&pchan->runtime);
+ BKE_pose_channel_session_uuid_generate(pchan);
+
+ pchan->bone = NULL;
+ BLO_read_data_address(reader, &pchan->parent);
+ BLO_read_data_address(reader, &pchan->child);
+ BLO_read_data_address(reader, &pchan->custom_tx);
+
+ BLO_read_data_address(reader, &pchan->bbone_prev);
+ BLO_read_data_address(reader, &pchan->bbone_next);
+
+ BKE_constraint_blend_read_data(reader, &pchan->constraints);
+
+ BLO_read_data_address(reader, &pchan->prop);
+ IDP_BlendDataRead(reader, &pchan->prop);
+
+ BLO_read_data_address(reader, &pchan->mpath);
+ if (pchan->mpath) {
+ animviz_motionpath_blend_read_data(reader, pchan->mpath);
+ }
+
+ BLI_listbase_clear(&pchan->iktree);
+ BLI_listbase_clear(&pchan->siktree);
+
+ /* in case this value changes in future, clamp else we get undefined behavior */
+ CLAMP(pchan->rotmode, ROT_MODE_MIN, ROT_MODE_MAX);
+
+ pchan->draw_data = NULL;
+ }
+ pose->ikdata = NULL;
+ if (pose->ikparam != NULL) {
+ BLO_read_data_address(reader, &pose->ikparam);
+ }
+}
+
+void BKE_pose_blend_read_lib(BlendLibReader *reader, Object *ob, bPose *pose)
+{
+ bArmature *arm = ob->data;
+
+ if (!pose || !arm) {
+ return;
+ }
+
+ /* always rebuild to match proxy or lib changes, but on Undo */
+ bool rebuild = false;
+
+ if (!BLO_read_lib_is_undo(reader)) {
+ if (ob->proxy || ob->id.lib != arm->id.lib) {
+ rebuild = true;
+ }
+ }
+
+ if (ob->proxy) {
+ /* sync proxy layer */
+ if (pose->proxy_layer) {
+ arm->layer = pose->proxy_layer;
+ }
+
+ /* sync proxy active bone */
+ if (pose->proxy_act_bone[0]) {
+ Bone *bone = BKE_armature_find_bone_name(arm, pose->proxy_act_bone);
+ if (bone) {
+ arm->act_bone = bone;
+ }
+ }
+ }
+
+ LISTBASE_FOREACH (bPoseChannel *, pchan, &pose->chanbase) {
+ BKE_constraint_blend_read_lib(reader, (ID *)ob, &pchan->constraints);
+
+ pchan->bone = BKE_armature_find_bone_name(arm, pchan->name);
+
+ IDP_BlendReadLib(reader, pchan->prop);
+
+ BLO_read_id_address(reader, arm->id.lib, &pchan->custom);
+ if (UNLIKELY(pchan->bone == NULL)) {
+ rebuild = true;
+ }
+ else if ((ob->id.lib == NULL) && arm->id.lib) {
+ /* local pose selection copied to armature, bit hackish */
+ pchan->bone->flag &= ~BONE_SELECTED;
+ pchan->bone->flag |= pchan->selectflag;
+ }
+ }
+
+ if (rebuild) {
+ Main *bmain = BLO_read_lib_get_main(reader);
+ DEG_id_tag_update_ex(
+ bmain, &ob->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_ANIMATION);
+ BKE_pose_tag_recalc(bmain, pose);
+ }
+}
+
+void BKE_pose_blend_read_expand(BlendExpander *expander, bPose *pose)
+{
+ if (!pose) {
+ return;
+ }
+
+ LISTBASE_FOREACH (bPoseChannel *, chan, &pose->chanbase) {
+ BKE_constraint_blend_read_expand(expander, &chan->constraints);
+ IDP_BlendReadExpand(expander, chan->prop);
+ BLO_expand(expander, chan->custom);
+ }
+}