Two in one:
[blender.git] / source / blender / src / editconstraint.c
index 777c88dbbf397d8980f6253321fd1824fd21e2fe..bb921906d55bfe28541746a5ad9fb34eb5a34eb5 100644 (file)
@@ -266,6 +266,12 @@ char *get_con_subtarget_name(bConstraint *con, Object *target)
                        if (data->tar==target) return data->subtarget;
                }
                break;
+               case CONSTRAINT_TYPE_SIZELIKE:
+               {
+                       bSizeLikeConstraint *data = con->data;
+                       if (data->tar==target) return data->subtarget;
+               }
+               break;
                case CONSTRAINT_TYPE_KINEMATIC:
                {
                        bKinematicConstraint *data = con->data;
@@ -428,6 +434,24 @@ static void test_constraints (Object *owner, const char* substring)
                                                break;
                                        }
                                        
+                                       if ( (data->tar == owner) &&
+                                                (!get_named_bone(get_armature(owner), 
+                                                                                 data->subtarget))) {
+                                               curcon->flag |= CONSTRAINT_DISABLE;
+                                               break;
+                                       }
+                               }
+                                       break;
+                               case CONSTRAINT_TYPE_SIZELIKE:
+                               {
+                                       bSizeLikeConstraint *data = curcon->data;
+                               
+                                       if (!exist_object(data->tar)){
+                                               data->tar = NULL;
+                                               curcon->flag |= CONSTRAINT_DISABLE;
+                                               break;
+                                       }
+                                       
                                        if ( (data->tar == owner) &&
                                                 (!get_named_bone(get_armature(owner), 
                                                                                  data->subtarget))) {
@@ -595,6 +619,12 @@ void add_constraint(int only_IK)
                pchanact= get_active_posechannel(ob);
                if(pchanact==NULL) return;
        
+               /* check protection */
+               if(ob->proxy && (pchanact->bone->layer & arm->layer_protected)) {
+                       error("Bone is Proxy protected");
+                       return;
+               }
+               
                /* find selected bone */
                for(pchansel= ob->pose->chanbase.first; pchansel; pchansel= pchansel->next) {
                        if(pchansel!=pchanact)
@@ -620,30 +650,30 @@ void add_constraint(int only_IK)
                }
                
                if(pchansel)
-                       nr= pupmenu("Add IK Constraint%t|To Selected Bone%x10");
+                       nr= pupmenu("Add IK Constraint%t|To Active Bone%x10");
                else if(obsel)
-                       nr= pupmenu("Add IK Constraint%t|To Selected Object%x10");
+                       nr= pupmenu("Add IK Constraint%t|To Active Object%x10");
                else 
                        nr= pupmenu("Add IK Constraint%t|To New Empty Object%x10|Without Target%x11");
        }
        else {
                if(pchanact) {
                        if(pchansel)
-                               nr= pupmenu("Add Constraint to selected Bone%t|Copy Location%x1|Copy Rotation%x2|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7");
+                               nr= pupmenu("Add Constraint to Active Bone%t|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7|Action%x16");
                        else if(obsel && obsel->type==OB_CURVE)
-                               nr= pupmenu("Add Constraint to selected Object%t|Copy Location%x1|Copy Rotation%x2|Track To%x3|Floor%x4|Locked Track%x5|Follow Path%x6|Stretch To%x7");
+                               nr= pupmenu("Add Constraint to Active Object%t|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|Track To%x3|Floor%x4|Locked Track%x5|Follow Path%x6|Stretch To%x7|Action%x16");
                        else if(obsel)
-                               nr= pupmenu("Add Constraint to selected Object%t|Copy Location%x1|Copy Rotation%x2|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7");
+                               nr= pupmenu("Add Constraint to Active Object%t|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7|Action%x16");
                        else
-                               nr= pupmenu("Add Constraint to New Empty Object%t|Copy Location%x1|Copy Rotation%x2|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7");
+                               nr= pupmenu("Add Constraint to New Empty Object%t|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7");
                }
                else {
                        if(obsel && obsel->type==OB_CURVE)
-                               nr= pupmenu("Add Constraint to selected Object%t|Copy Location%x1|Copy Rotation%x2|Track To%x3|Floor%x4|Locked Track%x5|Follow Path%x6");
+                               nr= pupmenu("Add Constraint to Active Object%t|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|Track To%x3|Floor%x4|Locked Track%x5|Follow Path%x6");
                        else if(obsel)
-                               nr= pupmenu("Add Constraint to selected Object%t|Copy Location%x1|Copy Rotation%x2|Track To%x3|Floor%x4|Locked Track%x5");
+                               nr= pupmenu("Add Constraint to Active Object%t|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|Track To%x3|Floor%x4|Locked Track%x5");
                        else
-                               nr= pupmenu("Add Constraint to New Empty Object%t|Copy Location%x1|Copy Rotation%x2|Track To%x3|Floor%x4|Locked Track%x5");
+                               nr= pupmenu("Add Constraint to New Empty Object%t|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|Track To%x3|Floor%x4|Locked Track%x5");
                }
        }
        
@@ -687,8 +717,17 @@ void add_constraint(int only_IK)
                else if(nr==3) con = add_new_constraint(CONSTRAINT_TYPE_TRACKTO);
                else if(nr==4) con = add_new_constraint(CONSTRAINT_TYPE_MINMAX);
                else if(nr==5) con = add_new_constraint(CONSTRAINT_TYPE_LOCKTRACK);
-               else if(nr==6) con = add_new_constraint(CONSTRAINT_TYPE_FOLLOWPATH);
+               else if(nr==6) {
+                       Curve *cu= obsel->data;
+                       cu->flag |= CU_PATH;
+                       con = add_new_constraint(CONSTRAINT_TYPE_FOLLOWPATH);
+               }
                else if(nr==7) con = add_new_constraint(CONSTRAINT_TYPE_STRETCHTO);
+               else if(nr==8) con = add_new_constraint(CONSTRAINT_TYPE_SIZELIKE);
+               else if(nr==13) con = add_new_constraint(CONSTRAINT_TYPE_LOCLIMIT);
+               else if(nr==14) con = add_new_constraint(CONSTRAINT_TYPE_ROTLIMIT);
+               else if(nr==15) con = add_new_constraint(CONSTRAINT_TYPE_SIZELIMIT);
+               else if(nr==16) con = add_new_constraint(CONSTRAINT_TYPE_ACTION);
                
                if(con==NULL) return;   /* paranoia */
                
@@ -710,7 +749,7 @@ void add_constraint(int only_IK)
        else if(obsel) {
                set_constraint_target(con, obsel, NULL);
        }
-       else if(nr!=11) {       /* add new empty as target */
+       else if(ELEM4(nr, 11, 13, 14, 15)==0) { /* add new empty as target */
                Base *base= BASACT, *newbase;
                Object *obt;
                
@@ -763,4 +802,88 @@ void add_constraint(int only_IK)
 
 }
 
+void ob_clear_constraints(void)
+{
+       Object *ob= OBACT;
+       
+       /* paranoia checks */
+       if(!ob) return;
+       if(ob==G.obedit || (ob->flag & OB_POSEMODE)) return;
+       
+       if(okee("Clear Constraints")==0) return;
+       
+       free_constraints(&ob->constraints);
+       
+       DAG_object_flush_update(G.scene, ob, OB_RECALC_OB);
+       
+       allqueue (REDRAWVIEW3D, 0);
+       allqueue (REDRAWBUTSOBJECT, 0);
+       allqueue (REDRAWOOPS, 0);
+       
+       BIF_undo_push("Clear Constraint(s)");
+       
+}
+
+/* con already has the new name */
+void rename_constraint(Object *ob, bConstraint *con, char *oldname)
+{
+       bConstraint *tcon;
+       bConstraintChannel *conchan;
+       ListBase *conlist= NULL;
+       int from_object= 0;
+       char *channame="";
+       
+       /* get context by searching for con (primitive...) */
+       for(tcon= ob->constraints.first; tcon; tcon= tcon->next)
+               if(tcon==con)
+                       break;
+       
+       if(tcon) {
+               conlist= &ob->constraints;
+               channame= "Object";
+               from_object= 1;
+       }
+       else if(ob->pose) {
+               bPoseChannel *pchan;
+               
+               for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
+                       for(tcon= pchan->constraints.first; tcon; tcon= tcon->next) {
+                               if(tcon==con)
+                                       break;
+                       }
+                       if(tcon)
+                               break;
+               }
+               if(tcon) {
+                       conlist= &pchan->constraints;
+                       channame= pchan->name;
+               }
+       }
+       
+       if(conlist==NULL) {
+               printf("rename constraint failed\n");   /* should not happen in UI */
+               return;
+       }
+       
+       /* first make sure it's a unique name within context */
+       unique_constraint_name (con, conlist);
+
+       /* own channels */
+       if(from_object) {
+               for(conchan= ob->constraintChannels.first; conchan; conchan= conchan->next) {
+                       if( strcmp(oldname, conchan->name)==0 )
+                               BLI_strncpy(conchan->name, con->name, sizeof(conchan->name));
+               }
+       }
+       /* own action */
+       if(ob->action) {
+               bActionChannel *achan= get_action_channel(ob->action, channame);
+               if(achan) {
+                       conchan= get_constraint_channel(&achan->constraintChannels, oldname);
+                       if(conchan)
+                               BLI_strncpy(conchan->name, con->name, sizeof(conchan->name));
+               }
+       }
+       
+}