Bugfix #19616: vertex group select as IK target cause crash in Blender2.5
authorJoshua Leung <aligorith@gmail.com>
Mon, 12 Oct 2009 09:39:57 +0000 (09:39 +0000)
committerJoshua Leung <aligorith@gmail.com>
Mon, 12 Oct 2009 09:39:57 +0000 (09:39 +0000)
Thanks to Masahito Takahashi (mato)  for the report and patch to fix this!

source/blender/blenkernel/BKE_constraint.h
source/blender/blenkernel/intern/constraint.c
source/blender/editors/object/object_relations.c
source/blender/ikplugin/intern/iksolver_plugin.c
source/blender/ikplugin/intern/itasc_plugin.cpp

index 126816f5a95e044cd0b42f587a34e0a8d04e0598..6446b48d553e6ea74b5cdfc69b5751994f7df43c 100644 (file)
@@ -131,7 +131,7 @@ void constraints_clear_evalob(struct bConstraintOb *cob);
 
 void constraint_mat_convertspace(struct Object *ob, struct bPoseChannel *pchan, float mat[][4], short from, short to);
 
-void get_constraint_target_matrix(struct bConstraint *con, int n, short ownertype, void *ownerdata, float mat[][4], float ctime);
+void get_constraint_target_matrix(struct Scene *scene, struct bConstraint *con, int n, short ownertype, void *ownerdata, float mat[][4], float ctime);
 void solve_constraints(struct ListBase *conlist, struct bConstraintOb *cob, float ctime);
 
 #ifdef __cplusplus
index 8846fe77809f23bffe20c293138e0d52352c5d58..cf919f024b89001e1190949c83c40161948203c7 100644 (file)
@@ -3553,7 +3553,7 @@ short proxylocked_constraints_owner (Object *ob, bPoseChannel *pchan)
  * None of the actual calculations of the matricies should be done here! Also, this function is 
  * not to be used by any new constraints, particularly any that have multiple targets.
  */
-void get_constraint_target_matrix (bConstraint *con, int n, short ownertype, void *ownerdata, float mat[][4], float ctime)
+void get_constraint_target_matrix (struct Scene *scene, bConstraint *con, int n, short ownertype, void *ownerdata, float mat[][4], float ctime)
 {
        bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
        ListBase targets = {NULL, NULL};
@@ -3564,6 +3564,7 @@ void get_constraint_target_matrix (bConstraint *con, int n, short ownertype, voi
                /* make 'constraint-ob' */
                cob= MEM_callocN(sizeof(bConstraintOb), "tempConstraintOb");
                cob->type= ownertype;
+               cob->scene = scene;
                switch (ownertype) {
                        case CONSTRAINT_OBTYPE_OBJECT: /* it is usually this case */
                        {
index d6a55077be954202756356d3e9a00431f14d3d94..0c97b94503728700c576d491bc84b4ae7534c428 100644 (file)
@@ -618,7 +618,7 @@ static int parent_set_exec(bContext *C, wmOperator *op)
                                        
                                        add_constraint_to_object(con, ob);
                                        
-                                       get_constraint_target_matrix(con, 0, CONSTRAINT_OBTYPE_OBJECT, NULL, cmat, scene->r.cfra - give_timeoffset(ob));
+                                       get_constraint_target_matrix(scene, con, 0, CONSTRAINT_OBTYPE_OBJECT, NULL, cmat, scene->r.cfra - give_timeoffset(ob));
                                        VecSubf(vec, ob->obmat[3], cmat[3]);
                                        
                                        ob->loc[0] = vec[0];
index 68afbcd0db2334164acc6cf2e790689e046fa844..b160e7346bdb7d1995189013222207d38926a17a 100644 (file)
@@ -210,7 +210,7 @@ static void where_is_ik_bone(bPoseChannel *pchan, float ik_mat[][3])   // nr = t
 
 /* called from within the core where_is_pose loop, all animsystems and constraints
 were executed & assigned. Now as last we do an IK pass */
-static void execute_posetree(Object *ob, PoseTree *tree)
+static void execute_posetree(struct Scene *scene, Object *ob, PoseTree *tree)
 {
        float R_parmat[3][3], identity[3][3];
        float iR_parmat[3][3];
@@ -347,7 +347,7 @@ static void execute_posetree(Object *ob, PoseTree *tree)
                /* 1.0=ctime, we pass on object for auto-ik (owner-type here is object, even though
                 * strictly speaking, it is a posechannel)
                 */
-               get_constraint_target_matrix(target->con, 0, CONSTRAINT_OBTYPE_OBJECT, ob, rootmat, 1.0);
+               get_constraint_target_matrix(scene, target->con, 0, CONSTRAINT_OBTYPE_OBJECT, ob, rootmat, 1.0);
                
                /* and set and transform goal */
                Mat4MulMat4(goal, rootmat, goalinv);
@@ -357,7 +357,7 @@ static void execute_posetree(Object *ob, PoseTree *tree)
                
                /* same for pole vector target */
                if(data->poletar) {
-                       get_constraint_target_matrix(target->con, 1, CONSTRAINT_OBTYPE_OBJECT, ob, rootmat, 1.0);
+                       get_constraint_target_matrix(scene, target->con, 1, CONSTRAINT_OBTYPE_OBJECT, ob, rootmat, 1.0);
                        
                        if(data->flag & CONSTRAINT_IK_SETANGLE) {
                                /* don't solve IK when we are setting the pole angle */
@@ -511,7 +511,7 @@ void iksolver_execute_tree(struct Scene *scene, struct Object *ob,  struct bPose
                        tree->pchan[a]->flag |= POSE_CHAIN;
                }
                /* 5. execute the IK solver */
-               execute_posetree(ob, tree);
+               execute_posetree(scene, ob, tree);
                
                /* 6. apply the differences to the channels, 
                          we need to calculate the original differences first */
index dc0c2c4c12fa1d82749ef29db6e73fbc37fdc98a..7f4c19672075c13acdd1955b1804a324089e551c 100644 (file)
@@ -89,6 +89,7 @@ void KDL::SetToZero(JntArray& array);
 // one structure for each target in the scene
 struct IK_Target
 {
+       struct Scene                    *blscene;
        iTaSC::MovingFrame*             target;
        iTaSC::ConstraintSet*   constraint;
        struct bConstraint*             blenderConstraint;
@@ -105,6 +106,7 @@ struct IK_Target
        float                                   eeRest[4][4];   //end effector initial pose relative to armature
 
        IK_Target() {
+               blscene = NULL;
                target = NULL;
                constraint = NULL;
                blenderConstraint = NULL;
@@ -155,6 +157,7 @@ struct IK_Channel {
 
 struct IK_Scene
 {
+       struct Scene            *blscene;
        IK_Scene*                       next;
        int                                     numchan;        // number of channel in pchan
        int                                     numjoint;       // number of joint in jointArray
@@ -172,6 +175,7 @@ struct IK_Scene
        std::vector<IK_Target*>         targets;
 
        IK_Scene() {
+               blscene = NULL;
                next = NULL;
                channels = NULL;
                armature = NULL;
@@ -533,7 +537,7 @@ static bool target_callback(const iTaSC::Timestamp& timestamp, const iTaSC::Fram
        bConstraint* constraint = (bConstraint*)target->blenderConstraint;
        float tarmat[4][4];
 
-       get_constraint_target_matrix(constraint, 0, CONSTRAINT_OBTYPE_OBJECT, target->owner, tarmat, 1.0);
+       get_constraint_target_matrix(target->blscene, constraint, 0, CONSTRAINT_OBTYPE_OBJECT, target->owner, tarmat, 1.0);
 
        // rootmat contains the target pose in world coordinate
        // if enforce is != 1.0, blend the target position with the end effector position
@@ -601,7 +605,7 @@ static bool base_callback(const iTaSC::Timestamp& timestamp, const iTaSC::Frame&
                IK_Channel &rootchan = ikscene->channels[0];
 
                // get polar target matrix in world space
-               get_constraint_target_matrix(ikscene->polarConstraint, 1, CONSTRAINT_OBTYPE_OBJECT, ikscene->blArmature, mat, 1.0);
+               get_constraint_target_matrix(ikscene->blscene, ikscene->polarConstraint, 1, CONSTRAINT_OBTYPE_OBJECT, ikscene->blArmature, mat, 1.0);
                // convert to armature space
                Mat4MulMat4(polemat, mat, imat);
                // get the target in world space (was computed before as target object are defined before base object)
@@ -1050,6 +1054,7 @@ static IK_Scene* convert_tree(Scene *blscene, Object *ob, bPoseChannel *pchan)
                return NULL;
 
        ikscene = new IK_Scene;
+       ikscene->blscene = blscene;
        arm = new iTaSC::Armature();
        scene = new iTaSC::Scene();
        ikscene->channels = new IK_Channel[tree->totchannel];
@@ -1382,6 +1387,7 @@ static IK_Scene* convert_tree(Scene *blscene, Object *ob, bPoseChannel *pchan)
        // finally add the constraint
        for (t=0; t<ikscene->targets.size(); t++) {
                IK_Target* iktarget = ikscene->targets[t];
+               iktarget->blscene = blscene;
                condata= (bKinematicConstraint*)iktarget->blenderConstraint->data;
                pchan = tree->pchan[iktarget->channel];
                unsigned int controltype, bonecnt;