Sculpt:
[blender.git] / source / blender / blenkernel / intern / constraint.c
index 6fce9a2..aff3bf0 100644 (file)
@@ -440,15 +440,14 @@ static void contarget_get_mesh_mat (Scene *scene, Object *ob, char *substring, f
        /* only continue if there's a valid DerivedMesh */
        if (dm) {
                MDeformVert *dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT);
-               int *index = (int *)dm->getVertDataArray(dm, CD_ORIGINDEX);
                int numVerts = dm->getNumVerts(dm);
                int i, j, count = 0;
                float co[3], nor[3];
                
-               /* check that dvert and index are valid pointers (just in case) */
-               if (dvert && index) {
+               /* check that dvert is a valid pointers (just in case) */
+               if (dvert) {
                        /* get the average of all verts with that are in the vertex-group */
-                       for (i = 0; i < numVerts; i++, index++) {       
+                       for (i = 0; i < numVerts; i++) {        
                                for (j = 0; j < dvert[i].totweight; j++) {
                                        /* does this vertex belong to nominated vertex group? */
                                        if (dvert[i].dw[j].def_nr == dgroup) {
@@ -1925,7 +1924,7 @@ static void actcon_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraint
                 */
                if (data->type < 10) {
                        /* extract rotation (is in whatever space target should be in) */
-                       mat4_to_eul( vec,tempmat);
+                       mat4_to_eul(vec, tempmat);
                        vec[0] *= (float)(180.0/M_PI);
                        vec[1] *= (float)(180.0/M_PI);
                        vec[2] *= (float)(180.0/M_PI);
@@ -1933,7 +1932,7 @@ static void actcon_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraint
                }
                else if (data->type < 20) {
                        /* extract scaling (is in whatever space target should be in) */
-                       mat4_to_size( vec,tempmat);
+                       mat4_to_size(vec, tempmat);
                        axis= data->type - 10;
                }
                else {
@@ -1945,7 +1944,7 @@ static void actcon_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraint
                /* Target defines the animation */
                s = (vec[axis]-data->min) / (data->max-data->min);
                CLAMP(s, 0, 1);
-               t = ( s * (data->end-data->start)) + data->start;
+               t = (s * (data->end-data->start)) + data->start;
                
                if (G.f & G_DEBUG)
                        printf("do Action Constraint %s - Ob %s Pchan %s \n", con->name, cob->ob->id.name+2, (cob->pchan)?cob->pchan->name:NULL);
@@ -1959,9 +1958,13 @@ static void actcon_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraint
                        /* make a temporary pose and evaluate using that */
                        pose = MEM_callocN(sizeof(bPose), "pose");
                        
-                       /* make a copy of the bone of interest in the temp pose before evaluating action, so that it can get set */
+                       /* make a copy of the bone of interest in the temp pose before evaluating action, so that it can get set 
+                        *      - we need to manually copy over a few settings, including rotation order, otherwise this fails
+                        */
                        pchan = cob->pchan;
+                       
                        tchan= verify_pose_channel(pose, pchan->name);
+                       tchan->rotmode= pchan->rotmode;
                        
                        /* evaluate action using workob (it will only set the PoseChannel in question) */
                        what_does_obaction(cob->scene, cob->ob, &workob, pose, data->act, pchan->name, t);
@@ -3601,125 +3604,155 @@ bConstraintTypeInfo *constraint_get_typeinfo (bConstraint *con)
                return NULL;
 }
 
-/* Creates a new constraint, initialises its data, and returns it */
-static bConstraint *add_new_constraint_internal(const char *name, short type)
+/* ************************* General Constraints API ************************** */
+/* The functions here are called by various parts of Blender. Very few (should be none if possible)
+ * constraint-specific code should occur here.
+ */
+/* ---------- Data Management ------- */
+
+/* Free data of a specific constraint if it has any info */
+void free_constraint_data (bConstraint *con)
+{
+       if (con->data) {
+               bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
+               
+               /* perform any special freeing constraint may have */
+               if (cti && cti->free_data)
+                       cti->free_data(con);
+               
+               /* free constraint data now */
+               MEM_freeN(con->data);
+       }
+}
+
+/* Free all constraints from a constraint-stack */
+void free_constraints (ListBase *list)
 {
        bConstraint *con;
-       bConstraintTypeInfo *cti;
+       
+       /* Free constraint data and also any extra data */
+       for (con= list->first; con; con= con->next)
+               free_constraint_data(con);
+       
+       /* Free the whole list */
+       BLI_freelistN(list);
+}
+
+
+/* Remove the specified constraint from the given constraint stack */
+int remove_constraint (ListBase *list, bConstraint *con)
+{
+       if (con) {
+               free_constraint_data(con);
+               BLI_freelinkN(list, con);
+               return 1;
+       }
+       else
+               return 0;
+}
+
+/* Remove the nth constraint from the given constraint stack */
+int remove_constraint_index (ListBase *list, int index)
+{
+       bConstraint *con= BLI_findlink(list, index);
+       
+       if (con)
+               return remove_constraint(list, con);
+       else 
+               return 0;
+}
 
-       con = MEM_callocN(sizeof(bConstraint), "Constraint");
+/* ......... */
+
+/* Creates a new constraint, initialises its data, and returns it */
+static bConstraint *add_new_constraint_internal (const char *name, short type)
+{
+       bConstraint *con= MEM_callocN(sizeof(bConstraint), "Constraint");
+       bConstraintTypeInfo *cti= get_constraint_typeinfo(type);
+       const char *newName;
 
        /* Set up a generic constraint datablock */
        con->type = type;
        con->flag |= CONSTRAINT_EXPAND;
        con->enforce = 1.0f;
 
-       /* Load the data for it */
-       cti = constraint_get_typeinfo(con);
+       /* Determine a basic name, and info */
        if (cti) {
+               /* initialise constraint data */
                con->data = MEM_callocN(cti->size, cti->structName);
-
+               
                /* only constraints that change any settings need this */
                if (cti->new_data)
                        cti->new_data(con->data);
-
-               /* set the name based on the type of constraint */
-               name= name ? name : cti->name;
+               
+               /* if no name is provided, use the type of the constraint as the name */
+               newName= (name && name[0]) ? name : cti->name;
        }
-       else
-               name= name ? name : "Const";
-
-       strcpy(con->name, name);
-
+       else {
+               /* if no name is provided, use the generic "Const" name */
+               // NOTE: any constraint type that gets here really shouldn't get added...
+               newName= (name && name[0]) ? name : "Const";
+       }
+       
+       /* copy the name */
+       BLI_strncpy(con->name, newName, sizeof(con->name));
+       
+       /* return the new constraint */
        return con;
 }
 
 /* if pchan is not NULL then assume we're adding a pose constraint */
-static bConstraint *add_new_constraint(Object *ob, bPoseChannel *pchan, const char *name, short type)
+static bConstraint *add_new_constraint (Object *ob, bPoseChannel *pchan, const char *name, short type)
 {
        bConstraint *con;
        ListBase *list;
-
+       
+       /* add the constraint */
        con= add_new_constraint_internal(name, type);
-
-       if(pchan)       list= &pchan->constraints;
-       else            list= &ob->constraints;
-
+       
+       /* find the constraint stack - bone or object? */
+       list = (pchan) ? (&pchan->constraints) : (&ob->constraints);
+       
        if (list) {
-               bConstraint *coniter;
-
                /* add new constraint to end of list of constraints before ensuring that it has a unique name
                 * (otherwise unique-naming code will fail, since it assumes element exists in list)
                 */
                BLI_addtail(list, con);
                unique_constraint_name(con, list);
-
+               
                /* if the target list is a list on some PoseChannel belonging to a proxy-protected
                 * Armature layer, we must tag newly added constraints with a flag which allows them
                 * to persist after proxy syncing has been done
                 */
                if (proxylocked_constraints_owner(ob, pchan))
                        con->flag |= CONSTRAINT_PROXY_LOCAL;
-
-               /* make this constraint the active one
-                *      - since constraint was added at end of stack, we can just go
-                *        through deactivating all previous ones
-                */
-               con->flag |= CONSTRAINT_ACTIVE;
-               for (coniter= con->prev; coniter; coniter= coniter->prev)
-                       coniter->flag &= ~CONSTRAINT_ACTIVE;
+               
+               /* make this constraint the active one */
+               constraints_set_active(list, con);
        }
-
+       
        return con;
 }
 
-bConstraint *add_pose_constraint(Object *ob, bPoseChannel *pchan, const char *name, short type)
+/* ......... */
+
+/* Add new constraint for the given bone */
+bConstraint *add_pose_constraint (Object *ob, bPoseChannel *pchan, const char *name, short type)
 {
-       if(pchan==NULL)
+       if (pchan == NULL)
                return NULL;
-
+       
        return add_new_constraint(ob, pchan, name, type);
 }
 
+/* Add new constraint for the given object */
 bConstraint *add_ob_constraint(Object *ob, const char *name, short type)
 {
        return add_new_constraint(ob, NULL, name, type);
 }
 
-/* ************************* General Constraints API ************************** */
-/* The functions here are called by various parts of Blender. Very few (should be none if possible)
- * constraint-specific code should occur here.
- */
-/* ---------- Data Management ------- */
-
-/* Free data of a specific constraint if it has any info */
-void free_constraint_data (bConstraint *con)
-{
-       if (con->data) {
-               bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
-               
-               /* perform any special freeing constraint may have */
-               if (cti && cti->free_data)
-                       cti->free_data(con);
-               
-               /* free constraint data now */
-               MEM_freeN(con->data);
-       }
-}
-
-/* Free all constraints from a constraint-stack */
-void free_constraints (ListBase *list)
-{
-       bConstraint *con;
-       
-       /* Free constraint data and also any extra data */
-       for (con= list->first; con; con= con->next)
-               free_constraint_data(con);
-       
-       /* Free the whole list */
-       BLI_freelistN(list);
-}
+/* ......... */
 
 /* Reassign links that constraints have to other data (called during file loading?) */
 void relink_constraints (ListBase *conlist)
@@ -3751,8 +3784,10 @@ void relink_constraints (ListBase *conlist)
        }
 }
 
+/* ......... */
+
 /* duplicate all of the constraints in a constraint stack */
-void copy_constraints (ListBase *dst, ListBase *src)
+void copy_constraints (ListBase *dst, const ListBase *src)
 {
        bConstraint *con, *srccon;
        
@@ -3765,6 +3800,7 @@ void copy_constraints (ListBase *dst, ListBase *src)
                /* make a new copy of the constraint's data */
                con->data = MEM_dupallocN(con->data);
                
+               // NOTE: depreceated... old animation system
                id_us_plus((ID *)con->ipo);
                
                /* only do specific constraints if required */
@@ -3773,6 +3809,8 @@ void copy_constraints (ListBase *dst, ListBase *src)
        }
 }
 
+/* ......... */
+
 /* finds the 'active' constraint in a constraint stack */
 bConstraint *constraints_get_active (ListBase *list)
 {
@@ -3790,6 +3828,19 @@ bConstraint *constraints_get_active (ListBase *list)
        return NULL;
 }
 
+/* Set the given constraint as the active one (clearing all the others) */
+void constraints_set_active (ListBase *list, bConstraint *con)
+{
+       bConstraint *c;
+       
+       for (c= list->first; c; c= c->next) {
+               if (c == con) 
+                       c->flag |= CONSTRAINT_ACTIVE;
+               else 
+                       c->flag &= ~CONSTRAINT_ACTIVE;
+       }
+}
+
 /* -------- Constraints and Proxies ------- */
 
 /* Rescue all constraints tagged as being CONSTRAINT_PROXY_LOCAL (i.e. added to bone that's proxy-synced in this file) */