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-22 12:04:16 +0300
committerJoshua Leung <aligorith@gmail.com>2015-01-22 16:33:31 +0300
commit99a5f376a21099a1cacb611482d1889e9e627923 (patch)
treeb477575499c9ecaa93667a9d84d19897c889acaa
parent6248381783d527dd19d915dba393d093be668ff4 (diff)
WIP: Attempt to get driver links remapped correctly when joining armatures
Now, RNA Paths and driver targets get corrected, but at the expense of this always happening (i.e. even for those affecting drivers which existed before).
-rw-r--r--source/blender/editors/armature/armature_relations.c73
1 files changed, 70 insertions, 3 deletions
diff --git a/source/blender/editors/armature/armature_relations.c b/source/blender/editors/armature/armature_relations.c
index 38e3588f267..155267af370 100644
--- a/source/blender/editors/armature/armature_relations.c
+++ b/source/blender/editors/armature/armature_relations.c
@@ -29,6 +29,8 @@
* \ingroup edarmature
*/
+#include "MEM_guardedalloc.h"
+
#include "DNA_anim_types.h"
#include "DNA_armature_types.h"
#include "DNA_constraint_types.h"
@@ -36,6 +38,7 @@
#include "DNA_scene_types.h"
#include "BLI_blenlib.h"
+#include "BLI_ghash.h"
#include "BLI_math.h"
#include "BLF_translation.h"
@@ -45,6 +48,7 @@
#include "BKE_constraint.h"
#include "BKE_context.h"
#include "BKE_depsgraph.h"
+#include "BKE_fcurve.h"
#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_report.h"
@@ -111,15 +115,66 @@ static void joined_armature_fix_links_constraints(
}
}
+/* userdata for joined_armature_fix_animdata_cb() */
+typedef struct tJoinArmature_AdtFixData {
+ Object *srcArm;
+ Object *tarArm;
+
+ GHash *names_map;
+} tJoinArmature_AdtFixData;
+
+/* Callback to pass to void BKE_animdata_main_cb() for fixing driver ID's to point to the new ID */
+static void joined_armature_fix_animdata_cb(ID *id, AnimData *adt, void *user_data)
+{
+ tJoinArmature_AdtFixData *afd = (tJoinArmature_AdtFixData *)user_data;
+ ID *src_id = &afd->srcArm->id;
+ ID *dst_id = &afd->tarArm->id;
+
+ GHashIterator gh_iter;
+ FCurve *fcu;
+
+ /* Fix paths - Unless we duplicate the logic, we're going to have to do it this way */
+ // FIXME: this is too crude... it just does everything!
+ GHASH_ITER(gh_iter, afd->names_map) {
+ const char *old_name = BLI_ghashIterator_getKey(&gh_iter);
+ const char *new_name = BLI_ghashIterator_getValue(&gh_iter);
+
+ /* only remap if changed; this still means there will be some waste if there aren't many drivers/keys */
+ if (strcmp(old_name, new_name)) {
+ // XXX: ref_id == ??? (the point of this seems really vague)
+ BKE_animdata_fix_paths_rename(id, adt, src_id, "pose.bones", old_name, new_name, 0, 0, false);
+ }
+ }
+
+ /* Drivers */
+ for (fcu = adt->drivers.first; fcu; fcu = fcu->next) {
+ ChannelDriver *driver = fcu->driver;
+ DriverVar *dvar;
+
+ /* fix driver references to invalid ID's */
+ for (dvar = driver->variables.first; dvar; dvar = dvar->next) {
+ /* only change the used targets, since the others will need fixing manually anyway */
+ DRIVER_TARGETS_USED_LOOPER(dvar)
+ {
+ /* change the ID's used... */
+ if (dtar->id == src_id) {
+ dtar->id = dst_id;
+ }
+ }
+ DRIVER_TARGETS_LOOPER_END
+ }
+ }
+}
+
/* Helper function for armature joining - link fixing */
-static void joined_armature_fix_links(Object *tarArm, Object *srcArm, bPoseChannel *pchan, EditBone *curbone)
+static void joined_armature_fix_links(Main *bmain, Object *tarArm, Object *srcArm, bPoseChannel *pchan, EditBone *curbone)
{
Object *ob;
bPose *pose;
bPoseChannel *pchant;
/* let's go through all objects in database */
- for (ob = G.main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
/* do some object-type specific things */
if (ob->type == OB_ARMATURE) {
pose = ob->pose;
@@ -193,11 +248,17 @@ int join_armature_exec(bContext *C, wmOperator *op)
CTX_DATA_BEGIN(C, Base *, base, selected_editable_bases)
{
if ((base->object->type == OB_ARMATURE) && (base->object != ob)) {
+ tJoinArmature_AdtFixData afd = {NULL};
bArmature *curarm = base->object->data;
/* we assume that each armature datablock is only used in a single place */
BLI_assert(ob->data != base->object->data);
+ /* init callback data for fixing up AnimData links later */
+ afd.srcArm = base->object;
+ afd.tarArm = ob;
+ afd.names_map = BLI_ghash_str_new("join_armature_adt_fix");
+
/* copy over animdata first, so that the link fixing can access and fix the links */
if (base->object->adt) {
if (ob->adt == NULL) {
@@ -241,6 +302,7 @@ int join_armature_exec(bContext *C, wmOperator *op)
/* Get new name */
unique_editbone_name(arm->edbo, curbone->name, NULL);
+ BLI_ghash_insert(afd.names_map, BLI_strdup(pchan->name), curbone->name);
/* Transform the bone */
{
@@ -271,7 +333,7 @@ int join_armature_exec(bContext *C, wmOperator *op)
}
/* Fix Constraints and Other Links to this Bone and Armature */
- joined_armature_fix_links(ob, base->object, pchan, curbone);
+ joined_armature_fix_links(bmain, ob, base->object, pchan, curbone);
/* Rename pchan */
BLI_strncpy(pchan->name, curbone->name, sizeof(pchan->name));
@@ -286,6 +348,11 @@ int join_armature_exec(bContext *C, wmOperator *op)
BKE_pose_channels_hash_free(pose);
}
+ /* Fix all the drivers (and animation data) */
+ BKE_animdata_main_cb(bmain, joined_armature_fix_animdata_cb, &afd);
+ BLI_ghash_free(afd.names_map, MEM_freeN, NULL);
+
+ /* Free the old object data */
ED_base_object_free_and_unlink(bmain, scene, base);
}
}