== PyConstraints - Now working again ==
authorJoshua Leung <aligorith@gmail.com>
Tue, 23 Oct 2007 08:23:57 +0000 (08:23 +0000)
committerJoshua Leung <aligorith@gmail.com>
Tue, 23 Oct 2007 08:23:57 +0000 (08:23 +0000)
I've finally traced down the causes of several of the bugs which caused PyConstraints to work incorrectly (or not at all).

* Freeing is now done using BLI_freelistN inside the pycon_free function, instead of looping through the targets ourselves. This fixes all of those Memblock free: pointer not in list errors.
* BPY_pyconstraint_update now correctly creates/frees the constraint's targets as needed. Previously, it was creating/removing the wrong number of targets. Also, pyconstraints no longer get disabled when using armatures (not bones)
* The panel drawing was also not working right, as there were still some offset issues.

source/blender/blenkernel/intern/constraint.c
source/blender/python/BPY_interface.c
source/blender/src/buttons_object.c

index c9fb21d4333ab5e7445e6307c87e4a4f45665076..9dce9c3a611676745a687883d25da858c869d64a 100644 (file)
@@ -1804,15 +1804,13 @@ static bConstraintTypeInfo CTI_SIZELIKE = {
 static void pycon_free (bConstraint *con)
 {
        bPythonConstraint *data= con->data;
-       bConstraintTarget *ct;
        
        /* id-properties */
        IDP_FreeProperty(data->prop);
        MEM_freeN(data->prop);
        
        /* multiple targets */
-       while ( (ct = data->targets.first) ) 
-               MEM_freeN(ct);
+       BLI_freelistN(&data->targets);
 }      
 
 static void pycon_relink (bConstraint *con)
index 27cfc2fa11cc027c6efb006b12a3a327e38ec246..238c05d54a483dca73e67cbc0c3b73ea69a450bf 100644 (file)
@@ -1188,11 +1188,11 @@ void BPY_pyconstraint_update(Object *owner, bConstraint *con)
                /* script does exist. it is assumed that this is a valid pyconstraint script */
                PyObject *globals;
                PyObject *retval, *gval;
-               int num;
+               int num, i;
                
-               /* clear the flag first */
+               /* clear the relevant flags first */
                data->flag = 0;
-               
+                               
                /* populate globals dictionary */
                globals = CreateGlobalDictionary();
                retval = RunPython(data->text, globals);
@@ -1222,18 +1222,23 @@ void BPY_pyconstraint_update(Object *owner, bConstraint *con)
                        /* check if the number of targets has changed */
                        if (num < data->tarnum) {
                                /* free a few targets */
-                               for (ct=data->targets.last; num > -1; num--, ct=data->targets.last, data->tarnum--)
+                               num= data->tarnum - num;
+                               for (i = 0; i < num; i++, data->tarnum--) {
+                                       ct= data->targets.last;
                                        BLI_freelinkN(&data->targets, ct);
+                               }
                        }
                        else if (num > data->tarnum) {
                                /* add a few targets */
-                               for ( ; num > -1; num--, data->tarnum++) {
+                               num = num - data->tarnum;
+                               for (i = 0; i < num; i++, data->tarnum++) {
                                        ct= MEM_callocN(sizeof(bConstraintTarget), "PyConTarget");
                                        BLI_addtail(&data->targets, ct);
                                }
                        }
                        
                        /* validate targets */
+                       con->flag &= ~CONSTRAINT_DISABLE;
                        for (ct= data->targets.first; ct; ct= ct->next) {
                                if (!exist_object(ct->tar)) {
                                        ct->tar = NULL;
@@ -1241,11 +1246,11 @@ void BPY_pyconstraint_update(Object *owner, bConstraint *con)
                                        break;
                                }
                                
-                               if ( (ct->tar == owner) &&
-                                        (!get_named_bone(get_armature(owner), ct->subtarget)) ) 
-                               {
-                                       con->flag |= CONSTRAINT_DISABLE;
-                                       break;
+                               if ((ct->tar == owner) && (ct->subtarget[0] != 0)) {
+                                       if (get_named_bone(get_armature(owner), ct->subtarget) == NULL) {
+                                               con->flag |= CONSTRAINT_DISABLE;
+                                               break;
+                                       }
                                }
                        }
                        
@@ -1268,6 +1273,7 @@ void BPY_pyconstraint_update(Object *owner, bConstraint *con)
                /* no script, so clear any settings/data now */
                data->tarnum = 0;
                data->flag = 0;
+               con->flag &= ~CONSTRAINT_DISABLE;
                
                BLI_freelistN(&data->targets);
                
index 20f423621c202d99571a1c57bde6c4d8a32150cb..bccd662102b2fcf88c8de9c65e65c9f800af0ace 100644 (file)
@@ -583,21 +583,21 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
                                                
                                                /* target label */
                                                sprintf(tarstr, "Target %02d:", tarnum);
-                                               uiDefBut(block, LABEL, B_CONSTRAINT_TEST, tarstr, *xco+60, *yco-(48+yoffset), 55, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
+                                               uiDefBut(block, LABEL, B_CONSTRAINT_TEST, tarstr, *xco+45, *yco-(48+yoffset), 60, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
                                                
                                                /* target space-selector - per target */
                                                if (is_armature_target(ct->tar)) {
                                                        uiDefButS(block, MENU, B_CONSTRAINT_TEST, "Target Space %t|World Space %x0|Pose Space %x3|Local with Parent %x4|Local Space %x1", 
-                                                                                                                       *xco+60, *yco-(66+yoffset), 55, 18, &ct->space, 0, 0, 0, 0, "Choose space that target is evaluated in");        
+                                                                                                                       *xco+10, *yco-(66+yoffset), 100, 18, &ct->space, 0, 0, 0, 0, "Choose space that target is evaluated in");       
                                                }
                                                else {
                                                        uiDefButS(block, MENU, B_CONSTRAINT_TEST, "Target Space %t|World Space %x0|Local (Without Parent) Space %x1", 
-                                                                                                                       *xco+60, *yco-(66+yoffset), 55, 18, &ct->space, 0, 0, 0, 0, "Choose space that target is evaluated in");        
+                                                                                                                       *xco+10, *yco-(66+yoffset), 100, 18, &ct->space, 0, 0, 0, 0, "Choose space that target is evaluated in");       
                                                }
                                                
                                                uiBlockBeginAlign(block);
                                                        /* target object */
-                                                       uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-48, 150, 18, &ct->tar, "Target Object"); 
+                                                       uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-(48+yoffset), 150, 18, &ct->tar, "Target Object"); 
                                                        
                                                        /* subtarget */
                                                        if (is_armature_target(ct->tar)) {