Path: [ #2789 ] Add a "copy size" constraint
authorMartin Poirier <theeth@yahoo.com>
Sun, 19 Feb 2006 17:42:20 +0000 (17:42 +0000)
committerMartin Poirier <theeth@yahoo.com>
Sun, 19 Feb 2006 17:42:20 +0000 (17:42 +0000)
At long last!
This new constraint is pretty simple. Following in the footsteps of such giants as Copy Loc and Copy Rot, it lets you constrain the size of an object/bone to another object/bone, with per axis restrictions.

source/blender/blenkernel/intern/constraint.c
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/writefile.c
source/blender/include/butspace.h
source/blender/makesdna/DNA_constraint_types.h
source/blender/src/buttons_object.c
source/blender/src/editconstraint.c

index 7458a0230ddeccbe5b2d1b2b96e875a33ad30173..40bdeff646c8765273bd11bb2678fee98f384739 100644 (file)
@@ -181,6 +181,14 @@ void relink_constraints (struct ListBase *list)
                                ID_NEW(data->tar);
                        }
                                break;
+                       case CONSTRAINT_TYPE_SIZELIKE:
+                       {
+                               bSizeLikeConstraint *data;
+                               data = con->data;
+                               ID_NEW(data->tar);
+                       }
+                               break;
                        case CONSTRAINT_TYPE_FOLLOWPATH:
                        {
                                bFollowPathConstraint *data;
@@ -281,6 +289,13 @@ char constraint_has_target (bConstraint *con)
                                return 1;
                }
                break;
+       case CONSTRAINT_TYPE_SIZELIKE:
+               {
+                       bSizeLikeConstraint *data = con->data;
+                       if (data->tar)
+                               return 1;
+               }
+               break;
        case CONSTRAINT_TYPE_MINMAX:
                {
                        bMinMaxConstraint *data = con->data;
@@ -341,6 +356,12 @@ Object *get_constraint_target(bConstraint *con, char **subtarget)
                        return data->tar;
                }
                break;
+       case CONSTRAINT_TYPE_SIZELIKE:
+               {
+                       bSizeLikeConstraint *data = con->data;
+                       return data->tar;
+               }
+               break;
        case CONSTRAINT_TYPE_KINEMATIC:
                {
                        bKinematicConstraint *data = con->data;
@@ -418,6 +439,13 @@ void set_constraint_target(bConstraint *con, Object *ob, char *subtarget)
                        if(subtarget) BLI_strncpy(data->subtarget, subtarget, 32);
                }
                        break;
+               case CONSTRAINT_TYPE_SIZELIKE:
+               {
+                       bSizeLikeConstraint *data = con->data;
+                       data->tar= ob;
+                       if(subtarget) BLI_strncpy(data->subtarget, subtarget, 32);
+               }
+                       break;
                case CONSTRAINT_TYPE_KINEMATIC:
                {
                        bKinematicConstraint *data = con->data;
@@ -575,6 +603,15 @@ void *new_constraint_data (short type)
                        result = data;
                }
                break;
+       case CONSTRAINT_TYPE_SIZELIKE:
+               {
+                       bSizeLikeConstraint *data;
+                       data = MEM_callocN(sizeof(bLocateLikeConstraint), "sizelikeConstraint");
+
+                       data->flag |= SIZELIKE_X|SIZELIKE_Y|SIZELIKE_Z;
+                       result = data;
+               }
+               break;
        case CONSTRAINT_TYPE_ACTION:
                {
                        bActionConstraint *data;
@@ -890,6 +927,21 @@ short get_constraint_target_matrix (bConstraint *con, short ownertype, void* own
                                Mat4One (mat);
                } 
                break;
+       case CONSTRAINT_TYPE_SIZELIKE:
+               {
+                       bSizeLikeConstraint *data;
+                       data = (bSizeLikeConstraint*)con->data;
+
+                       if (data->tar){
+                               /*      Update the location of the target object */
+                               where_is_object_time (data->tar, ctime);        
+                               constraint_target_to_mat4(data->tar, data->subtarget, mat, size, ctime);
+                               valid=1;
+                       }
+                       else
+                               Mat4One (mat);
+               } 
+               break;
        case CONSTRAINT_TYPE_TRACKTO:
                {
                        bTrackToConstraint *data;
@@ -1101,6 +1153,24 @@ void evaluate_constraint (bConstraint *constraint, Object *ob, short ownertype,
                        ob->obmat[2][2] = tmat[2][2]*size[2];
                }
                break;
+       case CONSTRAINT_TYPE_SIZELIKE:
+               {
+                       float obsize[3], size[3];
+                       bSizeLikeConstraint *data;
+                       data = constraint->data;
+                       Mat4ToSize(targetmat, size);
+                       Mat4ToSize(ob->obmat, obsize);
+                       
+                       if (data->flag & SIZELIKE_X && obsize[0] != 0)
+                               VecMulf(ob->obmat[0], size[0] / obsize[0]);
+                       if (data->flag & SIZELIKE_Y && obsize[1] != 0)
+                               VecMulf(ob->obmat[1], size[1] / obsize[1]);
+                       if (data->flag & SIZELIKE_Z && obsize[2] != 0)
+                               VecMulf(ob->obmat[2], size[2] / obsize[2]);
+               }
+               break;
        case CONSTRAINT_TYPE_NULL:
                {
                }
index ba532cfdfe314fda0d3868d1fbca2048096aa0bb..a688effe8a77b340d8dc0557a838cf91aa3d6067 100644 (file)
@@ -1399,6 +1399,13 @@ static void lib_link_constraints(FileData *fd, ID *id, ListBase *conlist)
                                data->tar = newlibadr(fd, id->lib, data->tar);
                        };
                        break;
+               case CONSTRAINT_TYPE_SIZELIKE:
+                       {
+                               bSizeLikeConstraint *data;
+                               data= ((bSizeLikeConstraint*)con->data);
+                               data->tar = newlibadr(fd, id->lib, data->tar);
+                       };
+                       break;
                case CONSTRAINT_TYPE_KINEMATIC:
                        {
                                bKinematicConstraint *data;
@@ -5719,6 +5726,12 @@ static void expand_constraints(FileData *fd, Main *mainvar, ListBase *lb)
                                expand_doit(fd, mainvar, data->tar);
                                break;
                        }
+               case CONSTRAINT_TYPE_SIZELIKE:
+                       {
+                               bSizeLikeConstraint *data = (bSizeLikeConstraint*)curcon->data;
+                               expand_doit(fd, mainvar, data->tar);
+                               break;
+                       }
                case CONSTRAINT_TYPE_KINEMATIC:
                        {
                                bKinematicConstraint *data = (bKinematicConstraint*)curcon->data;
index cb2abd71ca0bcf8e96fe8e56f3df9c6b92a0d788..c1d8eda900741a4df5b26f6e583d360832d5c07f 100644 (file)
@@ -647,6 +647,9 @@ static void write_constraints(WriteData *wd, ListBase *conlist)
                case CONSTRAINT_TYPE_LOCLIKE:
                        writestruct(wd, DATA, "bLocateLikeConstraint", 1, con->data);
                        break;
+               case CONSTRAINT_TYPE_SIZELIKE:
+                       writestruct(wd, DATA, "bSizeLikeConstraint", 1, con->data);
+                       break;
                case CONSTRAINT_TYPE_ACTION:
                        writestruct(wd, DATA, "bActionConstraint", 1, con->data);
                        break;
index 999213083ca62041feed5d7d1bb032bad4b09b1d..82c9756f2b34909bb9b149112ae929ed12db1db0 100644 (file)
@@ -591,6 +591,7 @@ enum {
        B_CONSTRAINT_ADD_MINMAX,
        B_CONSTRAINT_ADD_ROTLIKE,
        B_CONSTRAINT_ADD_LOCLIKE,
+       B_CONSTRAINT_ADD_SIZELIKE,
        B_CONSTRAINT_ADD_ACTION,
        B_CONSTRAINT_ADD_LOCKTRACK,
        B_CONSTRAINT_ADD_FOLLOWPATH,
index cf1c510140710d8e13ab29b501c9aa5e1a909793..b7dcadd501c28b41d4b9b94d371b36853d428821 100644 (file)
@@ -105,6 +105,13 @@ typedef struct bMinMaxConstraint{
        char            subtarget[32];
 } bMinMaxConstraint;
 
+typedef struct bSizeLikeConstraint{
+       Object          *tar;
+       int                     flag;
+       int                     reserved1;
+       char            subtarget[32];
+} bSizeLikeConstraint;
+
 typedef struct bActionConstraint{
        Object          *tar;
        short           type;
@@ -174,7 +181,7 @@ typedef struct bStretchToConstraint{
 #define CONSTRAINT_TYPE_SIZELIMIT      7       /* Unimplemented */
 #define CONSTRAINT_TYPE_ROTLIKE                8       
 #define CONSTRAINT_TYPE_LOCLIKE                9       
-#define CONSTRAINT_TYPE_SIZELIKE       10      /* Unimplemented */
+#define CONSTRAINT_TYPE_SIZELIKE       10
 #define CONSTRAINT_TYPE_PYTHON         11      /* Unimplemented */
 #define CONSTRAINT_TYPE_ACTION         12
 #define CONSTRAINT_TYPE_LOCKTRACK      13      /* New Tracking constraint that locks an axis in place - theeth */
@@ -208,6 +215,12 @@ typedef struct bStretchToConstraint{
 #define LOCLIKE_Y              0x02
 #define LOCLIKE_Z              0x04
 #define LOCSPACE               0x08
+/* bSizeLikeConstraint.flag */
+#define SIZELIKE_X             0x01
+#define SIZELIKE_Y             0x02
+#define SIZELIKE_Z             0x04
+#define SIZESPACE              0x08
 
 /* Axis flags */
 #define LOCK_X         0x00
index a6906af245d3c55b96bb2355d53bf8b824a8d4d2..9f43e06926c1f8667c345f07a2e025b340d2a279 100644 (file)
@@ -334,6 +334,9 @@ static void get_constraint_typestring (char *str, bConstraint *con)
        case CONSTRAINT_TYPE_LOCLIKE:
                strcpy (str, "Copy Location");
                return;
+       case CONSTRAINT_TYPE_SIZELIKE:
+               strcpy (str, "Copy Size");
+               return;
        case CONSTRAINT_TYPE_ACTION:
                strcpy (str, "Action");
                return;
@@ -367,6 +370,8 @@ static int get_constraint_col(bConstraint *con)
                return TH_BUT_POPUP;
        case CONSTRAINT_TYPE_MINMAX:
                return TH_BUT_POPUP;
+       case CONSTRAINT_TYPE_SIZELIKE:
+               return TH_BUT_POPUP;
        case CONSTRAINT_TYPE_ACTION:
                return TH_BUT_ACTION;
        case CONSTRAINT_TYPE_LOCKTRACK:
@@ -686,6 +691,38 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
                                uiBlockEndAlign(block);
                        }
                        break;
+               case CONSTRAINT_TYPE_SIZELIKE:
+                       {
+                               bSizeLikeConstraint *data = con->data;
+                               bArmature *arm;
+                               height = 66;
+                       
+                               BIF_ThemeColor(curCol);
+                               glRects(*xco+3, *yco-height-39, *xco+width+30, *yco-18);
+
+                               uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
+
+                               /* Draw target parameters */
+                               uiBlockBeginAlign(block);
+                               uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object"); 
+                               
+                               arm = get_armature(data->tar);
+                               if (arm){
+                                       but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone");
+                                       uiButSetCompleteFunc(but, autocomplete_bone, (void *)data->tar);
+                               }
+                               else
+                                       strcpy (data->subtarget, "");
+                               uiBlockEndAlign(block);
+
+                               /* Draw XYZ toggles */
+                               uiBlockBeginAlign(block);
+                               but=uiDefButI(block, TOG|BIT|0, B_CONSTRAINT_TEST, "X", *xco+((width/2)-48), *yco-64, 32, 18, &data->flag, 0, 24, 0, 0, "Copy X component");
+                               but=uiDefButI(block, TOG|BIT|1, B_CONSTRAINT_TEST, "Y", *xco+((width/2)-16), *yco-64, 32, 18, &data->flag, 0, 24, 0, 0, "Copy Y component");
+                               but=uiDefButI(block, TOG|BIT|2, B_CONSTRAINT_TEST, "Z", *xco+((width/2)+16), *yco-64, 32, 18, &data->flag, 0, 24, 0, 0, "Copy Z component");
+                               uiBlockEndAlign(block);
+                       }
+                       break;
                case CONSTRAINT_TYPE_KINEMATIC:
                        {
                                bKinematicConstraint *data = con->data;
@@ -977,6 +1014,7 @@ static uiBlock *add_constraintmenu(void *arg_unused)
 
        uiDefBut(block, BUTM, B_CONSTRAINT_ADD_LOCLIKE,"Copy Location",         0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
        uiDefBut(block, BUTM, B_CONSTRAINT_ADD_ROTLIKE,"Copy Rotation",         0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
+       uiDefBut(block, BUTM, B_CONSTRAINT_ADD_SIZELIKE,"Copy Size",            0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
        
        uiDefBut(block, SEPR, 0, "",                                    0, yco-=6, 120, 6, NULL, 0.0, 0.0, 0, 0, "");
        
@@ -1083,6 +1121,16 @@ void do_constraintbuts(unsigned short event)
                        BIF_undo_push("Add constraint");
                }
                break;
+       case B_CONSTRAINT_ADD_SIZELIKE:
+               {
+                       bConstraint *con;
+                       con = add_new_constraint(CONSTRAINT_TYPE_SIZELIKE);
+                       add_constraint_to_active(ob, con);
+  
+                       BIF_undo_push("Add constraint");
+               }
+               break;
        case B_CONSTRAINT_ADD_ACTION:
                {
                        bConstraint *con;
index a85f0dd835d5b5aa34615de2f88527820343ba4b..b3f2ac07c0be24485434849145ed821a29afcf57 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))) {
@@ -629,21 +653,21 @@ void add_constraint(int only_IK)
        else {
                if(pchanact) {
                        if(pchansel)
-                               nr= pupmenu("Add Constraint to Active 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 Size%x8|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7");
                        else if(obsel && obsel->type==OB_CURVE)
-                               nr= pupmenu("Add Constraint to Active 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 Size%x8|Track To%x3|Floor%x4|Locked Track%x5|Follow Path%x6|Stretch To%x7");
                        else if(obsel)
-                               nr= pupmenu("Add Constraint to Active 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 Size%x8|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7");
                        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 Size%x8|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7");
                }
                else {
                        if(obsel && obsel->type==OB_CURVE)
-                               nr= pupmenu("Add Constraint to Active 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 Size%x8|Track To%x3|Floor%x4|Locked Track%x5|Follow Path%x6");
                        else if(obsel)
-                               nr= pupmenu("Add Constraint to Active 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 Size%x8|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 Size%x8|Track To%x3|Floor%x4|Locked Track%x5");
                }
        }
        
@@ -689,6 +713,7 @@ void add_constraint(int only_IK)
                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==7) con = add_new_constraint(CONSTRAINT_TYPE_STRETCHTO);
+               else if(nr==8) con = add_new_constraint(CONSTRAINT_TYPE_SIZELIKE);
                
                if(con==NULL) return;   /* paranoia */