Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/action.c
| Show First 20 Lines • Show All 114 Lines • ▼ Show 20 Lines | void BKE_action_free(bAction *act) | ||||
| BLI_freelistN(&act->groups); | BLI_freelistN(&act->groups); | ||||
| /* Free pose-references (aka local markers) */ | /* Free pose-references (aka local markers) */ | ||||
| BLI_freelistN(&act->markers); | BLI_freelistN(&act->markers); | ||||
| } | } | ||||
| /* .................................. */ | /* .................................. */ | ||||
| bAction *BKE_action_copy(Main *bmain, const 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 *grp_dst, *grp_src; | ||||
| bActionGroup *dgrp, *sgrp; | FCurve *fcu_dst, *fcu_src; | ||||
| FCurve *dfcu, *sfcu; | |||||
| if (src == NULL) | |||||
| return NULL; | |||||
| dst = BKE_libblock_copy(bmain, &src->id); | |||||
| /* duplicate the lists of groups and markers */ | /* duplicate the lists of groups and markers */ | ||||
| BLI_duplicatelist(&dst->groups, &src->groups); | BLI_duplicatelist(&act_dst->groups, &act_src->groups); | ||||
| BLI_duplicatelist(&dst->markers, &src->markers); | BLI_duplicatelist(&act_dst->markers, &act_src->markers); | ||||
| /* copy F-Curves, fixing up the links as we go */ | /* copy F-Curves, fixing up the links as we go */ | ||||
| BLI_listbase_clear(&dst->curves); | BLI_listbase_clear(&act_dst->curves); | ||||
| for (sfcu = src->curves.first; sfcu; sfcu = sfcu->next) { | for (fcu_src = act_src->curves.first; fcu_src; fcu_src = fcu_src->next) { | ||||
| /* duplicate F-Curve */ | /* duplicate F-Curve */ | ||||
| dfcu = copy_fcurve(sfcu); | fcu_dst = copy_fcurve(fcu_src); /* XXX TODO pass subdata flag? But surprisingly does not seem to be doing any ID refcounting... */ | ||||
| BLI_addtail(&dst->curves, dfcu); | BLI_addtail(&act_dst->curves, fcu_dst); | ||||
| /* fix group links (kindof bad list-in-list search, but this is the most reliable way) */ | /* 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) { | for (grp_dst = act_dst->groups.first, grp_src = act_src->groups.first; | ||||
| if (sfcu->grp == sgrp) { | grp_dst && grp_src; | ||||
| dfcu->grp = dgrp; | grp_dst = grp_dst->next, grp_src = grp_src->next) | ||||
| { | |||||
| if (dgrp->channels.first == sfcu) | if (fcu_src->grp == grp_src) { | ||||
| dgrp->channels.first = dfcu; | fcu_dst->grp = grp_dst; | ||||
| if (dgrp->channels.last == sfcu) | |||||
| dgrp->channels.last = dfcu; | |||||
| 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; | break; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | |||||
| BKE_id_copy_ensure_local(bmain, &src->id, &dst->id); | bAction *BKE_action_copy(Main *bmain, const bAction *act_src) | ||||
| { | |||||
| return dst; | bAction *act_copy; | ||||
| BKE_id_copy_ex(bmain, &act_src->id, (ID **)&act_copy, 0, false); | |||||
| return act_copy; | |||||
| } | } | ||||
| /* *************** Action Groups *************** */ | /* *************** Action Groups *************** */ | ||||
| /* Get the active action-group for an Action */ | /* Get the active action-group for an Action */ | ||||
| bActionGroup *get_active_actiongroup(bAction *act) | bActionGroup *get_active_actiongroup(bAction *act) | ||||
| { | { | ||||
| bActionGroup *agrp = NULL; | bActionGroup *agrp = NULL; | ||||
| ▲ Show 20 Lines • Show All 347 Lines • ▼ Show 20 Lines | |||||
| } | } | ||||
| /** | /** | ||||
| * 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 it's channels | ||||
| * into the new pose. *dst is set to the newly allocated structure, and assumed to be NULL. | * 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. | * \param dst Should be freed already, makes entire duplicate. | ||||
| */ | */ | ||||
| void BKE_pose_copy_data(bPose **dst, const 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; | bPose *outPose; | ||||
| bPoseChannel *pchan; | bPoseChannel *pchan; | ||||
| ListBase listb; | ListBase listb; | ||||
| if (!src) { | if (!src) { | ||||
| *dst = NULL; | *dst = NULL; | ||||
| return; | return; | ||||
| Show All 13 Lines | void BKE_pose_copy_data_ex(bPose **dst, const bPose *src, const int flag, const bool copy_constraints) | ||||
| } | } | ||||
| outPose->iksolver = src->iksolver; | outPose->iksolver = src->iksolver; | ||||
| outPose->ikdata = NULL; | outPose->ikdata = NULL; | ||||
| outPose->ikparam = MEM_dupallocN(src->ikparam); | outPose->ikparam = MEM_dupallocN(src->ikparam); | ||||
| outPose->avs = src->avs; | outPose->avs = src->avs; | ||||
| for (pchan = outPose->chanbase.first; pchan; pchan = pchan->next) { | for (pchan = outPose->chanbase.first; pchan; pchan = pchan->next) { | ||||
| if ((flag & LIB_ID_COPY_NO_USER_REFCOUNT) == 0) { | |||||
| if (pchan->custom) { | id_us_plus((ID *)pchan->custom); | ||||
| id_us_plus(&pchan->custom->id); | |||||
| } | } | ||||
| /* warning, O(n2) here, if done without the hash, but these are rarely used features. */ | /* warning, O(n2) here, if done without the hash, but these are rarely used features. */ | ||||
| if (pchan->custom_tx) { | if (pchan->custom_tx) { | ||||
| pchan->custom_tx = BKE_pose_channel_find_name(outPose, pchan->custom_tx->name); | pchan->custom_tx = BKE_pose_channel_find_name(outPose, pchan->custom_tx->name); | ||||
| } | } | ||||
| if (pchan->bbone_prev) { | if (pchan->bbone_prev) { | ||||
| pchan->bbone_prev = BKE_pose_channel_find_name(outPose, pchan->bbone_prev->name); | pchan->bbone_prev = BKE_pose_channel_find_name(outPose, pchan->bbone_prev->name); | ||||
| } | } | ||||
| if (pchan->bbone_next) { | if (pchan->bbone_next) { | ||||
| pchan->bbone_next = BKE_pose_channel_find_name(outPose, pchan->bbone_next->name); | pchan->bbone_next = BKE_pose_channel_find_name(outPose, pchan->bbone_next->name); | ||||
| } | } | ||||
| if (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->constraints = listb; | ||||
| pchan->mpath = NULL; /* motion paths should not get copied yet... */ | pchan->mpath = NULL; /* motion paths should not get copied yet... */ | ||||
| } | } | ||||
| if (pchan->prop) { | if (pchan->prop) { | ||||
| pchan->prop = IDP_CopyProperty(pchan->prop); | pchan->prop = IDP_CopyProperty_ex(pchan->prop, flag); | ||||
| } | } | ||||
| } | } | ||||
| /* for now, duplicate Bone Groups too when doing this */ | /* for now, duplicate Bone Groups too when doing this */ | ||||
| if (copy_constraints) { | if (copy_constraints) { | ||||
| BLI_duplicatelist(&outPose->agroups, &src->agroups); | BLI_duplicatelist(&outPose->agroups, &src->agroups); | ||||
| } | } | ||||
| *dst = outPose; | *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) | void BKE_pose_itasc_init(bItasc *itasc) | ||||
| { | { | ||||
| if (itasc) { | if (itasc) { | ||||
| itasc->iksolver = IKSOLVER_ITASC; | itasc->iksolver = IKSOLVER_ITASC; | ||||
| itasc->minstep = 0.01f; | itasc->minstep = 0.01f; | ||||
| itasc->maxstep = 0.06f; | itasc->maxstep = 0.06f; | ||||
| itasc->numiter = 100; | itasc->numiter = 100; | ||||
| itasc->numstep = 4; | itasc->numstep = 4; | ||||
| ▲ Show 20 Lines • Show All 881 Lines • Show Last 20 Lines | |||||