From 2b6e4f242230d99470ef70c7c00f1809a098d200 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Mon, 7 Nov 2011 13:25:17 +0000 Subject: Bugfix [#29064] armature with curve contraint - crash Spline IK and Auto-IK working together on the same bone chain could crash due to the somewhat hacky way that they were sharing the same list for the "iktree" forest. Resolved by doing what I should have done from the beginning, and made Spline-IK save its ik chains off into a separate list. While this fixes the crash, it might be worth investigating outright disabling this from working in this case, since it can be a bit confusing to have it appear to not work. --- source/blender/blenkernel/intern/armature.c | 35 +++++++++++------------- source/blender/blenloader/intern/readfile.c | 1 + source/blender/ikplugin/intern/iksolver_plugin.c | 6 ++-- source/blender/makesdna/DNA_action_types.h | 4 ++- 4 files changed, 24 insertions(+), 22 deletions(-) diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index 50f305e4400..a9c29728650 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -1818,7 +1818,7 @@ static void splineik_init_tree_from_pchan(Scene *scene, Object *UNUSED(ob), bPos tree->ikData= ikData; /* AND! link the tree to the root */ - BLI_addtail(&pchanRoot->iktree, tree); + BLI_addtail(&pchanRoot->siktree, tree); } /* mark root channel having an IK tree */ @@ -2045,27 +2045,24 @@ static void splineik_execute_tree(Scene *scene, Object *ob, bPoseChannel *pchan_ tSplineIK_Tree *tree; /* for each pose-tree, execute it if it is spline, otherwise just free it */ - for (tree= pchan_root->iktree.first; tree; tree= pchan_root->iktree.first) { - /* only evaluate if tagged for Spline IK */ - if (tree->type == CONSTRAINT_TYPE_SPLINEIK) { - int i; - - /* walk over each bone in the chain, calculating the effects of spline IK - * - the chain is traversed in the opposite order to storage order (i.e. parent to children) - * so that dependencies are correct - */ - for (i= tree->chainlen-1; i >= 0; i--) { - bPoseChannel *pchan= tree->chain[i]; - splineik_evaluate_bone(tree, scene, ob, pchan, i, ctime); - } - - /* free the tree info specific to SplineIK trees now */ - if (tree->chain) MEM_freeN(tree->chain); - if (tree->free_points) MEM_freeN(tree->points); + while ((tree = pchan_root->siktree.first) != NULL) { + int i; + + /* walk over each bone in the chain, calculating the effects of spline IK + * - the chain is traversed in the opposite order to storage order (i.e. parent to children) + * so that dependencies are correct + */ + for (i= tree->chainlen-1; i >= 0; i--) { + bPoseChannel *pchan= tree->chain[i]; + splineik_evaluate_bone(tree, scene, ob, pchan, i, ctime); } + /* free the tree info specific to SplineIK trees now */ + if (tree->chain) MEM_freeN(tree->chain); + if (tree->free_points) MEM_freeN(tree->points); + /* free this tree */ - BLI_freelinkN(&pchan_root->iktree, tree); + BLI_freelinkN(&pchan_root->siktree, tree); } } diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 9f6ce4eb79b..ba1d333f44f 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -4064,6 +4064,7 @@ static void direct_link_pose(FileData *fd, bPose *pose) direct_link_motionpath(fd, pchan->mpath); pchan->iktree.first= pchan->iktree.last= NULL; + pchan->siktree.first= pchan->siktree.last= NULL; /* incase this value changes in future, clamp else we get undefined behavior */ CLAMP(pchan->rotmode, ROT_MODE_MIN, ROT_MODE_MAX); diff --git a/source/blender/ikplugin/intern/iksolver_plugin.c b/source/blender/ikplugin/intern/iksolver_plugin.c index 787766f0fa6..2a83052c827 100644 --- a/source/blender/ikplugin/intern/iksolver_plugin.c +++ b/source/blender/ikplugin/intern/iksolver_plugin.c @@ -526,12 +526,14 @@ void iksolver_execute_tree(struct Scene *scene, struct Object *ob, struct bPose /* 6. apply the differences to the channels, we need to calculate the original differences first */ - for(a=0; atotchannel; a++) + for(a=0; atotchannel; a++) { make_dmats(tree->pchan[a]); + } - for(a=0; atotchannel; a++) + for(a=0; atotchannel; a++) { /* sets POSE_DONE */ where_is_ik_bone(tree->pchan[a], tree->basis_change[a]); + } /* 7. and free */ BLI_remlink(&pchan->iktree, tree); diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h index db574160771..b198231df3a 100644 --- a/source/blender/makesdna/DNA_action_types.h +++ b/source/blender/makesdna/DNA_action_types.h @@ -198,7 +198,9 @@ typedef struct bPoseChannel { struct Bone *bone; /* set on read file or rebuild pose */ struct bPoseChannel *parent; /* set on read file or rebuild pose */ struct bPoseChannel *child; /* set on read file or rebuild pose, the 'ik' child, for b-bones */ - struct ListBase iktree; /* only while evaluating pose */ + + struct ListBase iktree; /* "IK trees" - only while evaluating pose */ + struct ListBase siktree; /* Spline-IK "trees" - only while evaluating pose */ bMotionPath *mpath; /* motion path cache for this bone */ struct Object *custom; /* draws custom object instead of default bone shape */ -- cgit v1.2.3