diff options
Diffstat (limited to 'source/blender/blenkernel/intern/action.c')
-rw-r--r-- | source/blender/blenkernel/intern/action.c | 109 |
1 files changed, 67 insertions, 42 deletions
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index 1e33fe4ab46..c06a1a8106c 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -84,11 +84,11 @@ /* ***************** Library data level operations on action ************** */ -bAction *add_empty_action(Main *bmain, const char name[]) +bAction *BKE_action_add(Main *bmain, const char name[]) { bAction *act; - act = BKE_libblock_alloc(bmain, ID_AC, name); + act = BKE_libblock_alloc(bmain, ID_AC, name, 0); return act; } @@ -120,46 +120,56 @@ void BKE_action_free(bAction *act) /* .................................. */ -bAction *BKE_action_copy(Main *bmain, bAction *src) +/** + * Only copy internal data of Action ID from source to already allocated/initialized destination. + * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs. + * + * WARNING! This function will not handle ID user count! + * + * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more). + */ +void BKE_action_copy_data(Main *UNUSED(bmain), bAction *act_dst, const bAction *act_src, const int UNUSED(flag)) { - bAction *dst = NULL; - bActionGroup *dgrp, *sgrp; - FCurve *dfcu, *sfcu; - - if (src == NULL) - return NULL; - dst = BKE_libblock_copy(bmain, &src->id); - + bActionGroup *grp_dst, *grp_src; + FCurve *fcu_dst, *fcu_src; + /* duplicate the lists of groups and markers */ - BLI_duplicatelist(&dst->groups, &src->groups); - BLI_duplicatelist(&dst->markers, &src->markers); - + BLI_duplicatelist(&act_dst->groups, &act_src->groups); + BLI_duplicatelist(&act_dst->markers, &act_src->markers); + /* copy F-Curves, fixing up the links as we go */ - BLI_listbase_clear(&dst->curves); - - for (sfcu = src->curves.first; sfcu; sfcu = sfcu->next) { + BLI_listbase_clear(&act_dst->curves); + + for (fcu_src = act_src->curves.first; fcu_src; fcu_src = fcu_src->next) { /* duplicate F-Curve */ - dfcu = copy_fcurve(sfcu); - BLI_addtail(&dst->curves, dfcu); - + fcu_dst = copy_fcurve(fcu_src); /* XXX TODO pass subdata flag? But surprisingly does not seem to be doing any ID refcounting... */ + BLI_addtail(&act_dst->curves, fcu_dst); + /* fix group links (kindof bad list-in-list search, but this is the most reliable way) */ - for (dgrp = dst->groups.first, sgrp = src->groups.first; dgrp && sgrp; dgrp = dgrp->next, sgrp = sgrp->next) { - if (sfcu->grp == sgrp) { - dfcu->grp = dgrp; - - if (dgrp->channels.first == sfcu) - dgrp->channels.first = dfcu; - if (dgrp->channels.last == sfcu) - dgrp->channels.last = dfcu; - + for (grp_dst = act_dst->groups.first, grp_src = act_src->groups.first; + grp_dst && grp_src; + grp_dst = grp_dst->next, grp_src = grp_src->next) + { + if (fcu_src->grp == grp_src) { + fcu_dst->grp = grp_dst; + + if (grp_dst->channels.first == fcu_src) { + grp_dst->channels.first = fcu_dst; + } + if (grp_dst->channels.last == fcu_src) { + grp_dst->channels.last = fcu_dst; + } break; } } } - - BKE_id_copy_ensure_local(bmain, &src->id, &dst->id); +} - return dst; +bAction *BKE_action_copy(Main *bmain, const bAction *act_src) +{ + bAction *act_copy; + BKE_id_copy_ex(bmain, &act_src->id, (ID **)&act_copy, 0, false); + return act_copy; } /* *************** Action Groups *************** */ @@ -489,7 +499,7 @@ bPoseChannel *BKE_pose_channel_active(Object *ob) } /** - * \see #ED_armature_bone_get_mirrored (edit-mode, matching function) + * \see #ED_armature_ebone_get_mirrored (edit-mode, matching function) */ bPoseChannel *BKE_pose_channel_get_mirrored(const bPose *pose, const char *name) { @@ -523,7 +533,7 @@ const char *BKE_pose_ikparam_get_name(bPose *pose) * * \param dst Should be freed already, makes entire duplicate. */ -void BKE_pose_copy_data(bPose **dst, bPose *src, const bool copy_constraints) +void BKE_pose_copy_data_ex(bPose **dst, const bPose *src, const int flag, const bool copy_constraints) { bPose *outPose; bPoseChannel *pchan; @@ -553,9 +563,8 @@ void BKE_pose_copy_data(bPose **dst, bPose *src, const bool copy_constraints) outPose->avs = src->avs; for (pchan = outPose->chanbase.first; pchan; pchan = pchan->next) { - - if (pchan->custom) { - id_us_plus(&pchan->custom->id); + if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) { + id_us_plus((ID *)pchan->custom); } /* warning, O(n2) here, if done without the hash, but these are rarely used features. */ @@ -570,13 +579,13 @@ void BKE_pose_copy_data(bPose **dst, bPose *src, const bool copy_constraints) } if (copy_constraints) { - BKE_constraints_copy(&listb, &pchan->constraints, true); // BKE_constraints_copy NULLs listb + BKE_constraints_copy_ex(&listb, &pchan->constraints, flag, true); // BKE_constraints_copy NULLs listb pchan->constraints = listb; pchan->mpath = NULL; /* motion paths should not get copied yet... */ } if (pchan->prop) { - pchan->prop = IDP_CopyProperty(pchan->prop); + pchan->prop = IDP_CopyProperty_ex(pchan->prop, flag); } } @@ -588,6 +597,11 @@ void BKE_pose_copy_data(bPose **dst, bPose *src, const bool copy_constraints) *dst = outPose; } +void BKE_pose_copy_data(bPose **dst, const bPose *src, const bool copy_constraints) +{ + BKE_pose_copy_data_ex(dst, src, 0, copy_constraints); +} + void BKE_pose_itasc_init(bItasc *itasc) { if (itasc) { @@ -856,6 +870,8 @@ static void copy_pose_channel_data(bPoseChannel *pchan, const bPoseChannel *chan pchan->curveInY = chan->curveInY; pchan->curveOutX = chan->curveOutX; pchan->curveOutY = chan->curveOutY; + pchan->ease1 = chan->ease1; + pchan->ease2 = chan->ease2; pchan->scaleIn = chan->scaleIn; pchan->scaleOut = chan->scaleOut; @@ -1115,9 +1131,13 @@ void calc_action_range(const bAction *act, float *start, float *end, short incl_ if (fcu->totvert) { float nmin, nmax; - /* get extents for this curve */ - /* TODO: allow enabling/disabling this? */ - calc_fcurve_range(fcu, &nmin, &nmax, false, true); + /* get extents for this curve + * - no "selected only", since this is often used in the backend + * - no "minimum length" (we will apply this later), otherwise + * single-keyframe curves will increase the overall length by + * a phantom frame (T50354) + */ + calc_fcurve_range(fcu, &nmin, &nmax, false, false); /* compare to the running tally */ min = min_ff(min, nmin); @@ -1170,7 +1190,9 @@ void calc_action_range(const bAction *act, float *start, float *end, short incl_ } if (foundvert || foundmod) { + /* ensure that action is at least 1 frame long (for NLA strips to have a valid length) */ if (min == max) max += 1.0f; + *start = min; *end = max; } @@ -1341,6 +1363,7 @@ void BKE_pose_rest(bPose *pose) pchan->roll1 = pchan->roll2 = 0.0f; pchan->curveInX = pchan->curveInY = 0.0f; pchan->curveOutX = pchan->curveOutY = 0.0f; + pchan->ease1 = pchan->ease2 = 0.0f; pchan->scaleIn = pchan->scaleOut = 1.0f; pchan->flag &= ~(POSE_LOC | POSE_ROT | POSE_SIZE | POSE_BBONE_SHAPE); @@ -1384,6 +1407,8 @@ bool BKE_pose_copy_result(bPose *to, bPose *from) pchanto->curveInY = pchanfrom->curveInY; pchanto->curveOutX = pchanfrom->curveOutX; pchanto->curveOutY = pchanfrom->curveOutY; + pchanto->ease1 = pchanfrom->ease1; + pchanto->ease2 = pchanfrom->ease2; pchanto->scaleIn = pchanfrom->scaleIn; pchanto->scaleOut = pchanfrom->scaleOut; |