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:
authorJoshua Leung <aligorith@gmail.com>2015-01-21 16:08:29 +0300
committerJoshua Leung <aligorith@gmail.com>2015-01-21 16:09:16 +0300
commit3df93d063e2d52a2c2e73cfe31801c15682bf0b4 (patch)
treefab2039dd84ce9666d02fb4e1af68eaa645337bc /source/blender/blenkernel
parentf087e9930d5b8c876206af117ce085dec0ec4578 (diff)
Fix: Joining armatures loses drivers
Currently, when joining two armatures, the drivers of the armatures being merged in are lost. This commit introduces a new AnimData API function for merging animation data into another AnimData block. NOTE: * For now, this only copies the drivers over. As a result, manual effort will still be needed to go through and fix the drivers. I am working on automating that process, but it's more important that the drivers don't have to be created from scratch for now (since this is needed for the Goosberry rigging work).
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/BKE_animsys.h14
-rw-r--r--source/blender/blenkernel/intern/anim_sys.c71
2 files changed, 85 insertions, 0 deletions
diff --git a/source/blender/blenkernel/BKE_animsys.h b/source/blender/blenkernel/BKE_animsys.h
index a5109acfa56..24abd114a90 100644
--- a/source/blender/blenkernel/BKE_animsys.h
+++ b/source/blender/blenkernel/BKE_animsys.h
@@ -73,6 +73,20 @@ bool BKE_copy_animdata_id(struct ID *id_to, struct ID *id_from, const bool do_ac
/* Copy AnimData Actions */
void BKE_copy_animdata_id_action(struct ID *id);
+/* Merge copies of data from source AnimData block */
+typedef enum eAnimData_MergeCopy_Modes {
+ /* Keep destination action */
+ ADT_MERGECOPY_KEEP_DST = 0,
+
+ /* Use src action (make a new copy) */
+ ADT_MERGECOPY_SRC_COPY = 1,
+
+ /* Use src action (but just reference the existing version) */
+ ADT_MERGECOPY_SRC_REF = 2
+} eAnimData_MergeCopy_Modes;
+
+void BKE_animdata_merge_copy(struct ID *dst_id, struct ID *src_id, eAnimData_MergeCopy_Modes action_mode, bool fix_drivers);
+
/* Make Local */
void BKE_animdata_make_local(struct AnimData *adt);
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
index 8e36449f214..00e5c1be48e 100644
--- a/source/blender/blenkernel/intern/anim_sys.c
+++ b/source/blender/blenkernel/intern/anim_sys.c
@@ -318,6 +318,77 @@ void BKE_copy_animdata_id_action(ID *id)
}
}
+/* Merge copies of the data from the src AnimData into the destination AnimData */
+void BKE_animdata_merge_copy(ID *dst_id, ID *src_id, eAnimData_MergeCopy_Modes action_mode, bool fix_drivers)
+{
+ AnimData *src = BKE_animdata_from_id(src_id);
+ AnimData *dst = BKE_animdata_from_id(dst_id);
+
+ /* sanity checks */
+ if (ELEM(NULL, dst, src))
+ return;
+
+ // TODO: we must unset all "tweakmode" flags
+ if ((src->flag & ADT_NLA_EDIT_ON) || (dst->flag & ADT_NLA_EDIT_ON)) {
+ printf("ERROR: Merging AnimData blocks while editing NLA is dangerous as it may cause data corruption\n");
+ return;
+ }
+
+ /* handle actions... */
+ if (action_mode == ADT_MERGECOPY_SRC_COPY) {
+ /* make a copy of the actions */
+ dst->action = BKE_action_copy(src->action);
+ dst->tmpact = BKE_action_copy(src->tmpact);
+ }
+ else if (action_mode == ADT_MERGECOPY_SRC_REF) {
+ /* make a reference to it */
+ dst->action = src->action;
+ id_us_plus((ID *)dst->action);
+
+ dst->tmpact = src->tmpact;
+ id_us_plus((ID *)dst->tmpact);
+ }
+
+ /* duplicate NLA data */
+ if (src->nla_tracks.first) {
+ ListBase tracks = {NULL, NULL};
+
+ copy_nladata(&tracks, &src->nla_tracks);
+ BLI_movelisttolist(&dst->nla_tracks, &tracks);
+ }
+
+ /* duplicate drivers (F-Curves) */
+ if (src->drivers.first) {
+ ListBase drivers = {NULL, NULL};
+
+ copy_fcurves(&drivers, &src->drivers);
+
+ /* Fix up all driver targets using the old target id
+ * - This assumes that the src ID is being merged into the dst ID
+ */
+ if (fix_drivers) {
+ FCurve *fcu;
+
+ for (fcu = drivers.first; fcu; fcu = fcu->next) {
+ ChannelDriver *driver = fcu->driver;
+ DriverVar *dvar;
+
+ for (dvar = driver->variables.first; dvar; dvar = dvar->next) {
+ DRIVER_TARGETS_USED_LOOPER(dvar)
+ {
+ if (dtar->id == src_id) {
+ dtar->id = dst_id;
+ }
+ }
+ DRIVER_TARGETS_LOOPER_END
+ }
+ }
+ }
+
+ BLI_movelisttolist(&dst->drivers, &drivers);
+ }
+}
+
/* Make Local -------------------------------------------- */
static void make_local_strips(ListBase *strips)