=== Mirror Tool ===
authorMartin Poirier <theeth@yahoo.com>
Thu, 24 Jan 2008 20:11:54 +0000 (20:11 +0000)
committerMartin Poirier <theeth@yahoo.com>
Thu, 24 Jan 2008 20:11:54 +0000 (20:11 +0000)
Making the mirror tool axis selection interactive instead of using a popmenu.

Mirror is now just a constant -1 scaling transform, which enables you to choose the mirror axis through hotkeys (x,y,z) and with MMB. It also means it's easier to select the correct axis if you're not sure which is which and gives access to all the orientation supported in transform (including custom user orientations).

Mesh and Object header menus still have the individual axis as options but have an added "Interactive Mirror" which just enters transform and lets user pick the axis there. Ctrl-M enters "Interactive Mirror" too.

In a nutshell, this changes adds more possible mirroring axis and unifies the mirror axis selection process with transform constraint axis selection.

source/blender/include/BIF_transform.h
source/blender/include/transform.h
source/blender/src/editobject.c
source/blender/src/header_view3d.c
source/blender/src/transform.c

index c8e2a4832ab0724a1301b36b564083e11313c095..a0f991f2631aeabb3d22321199ad25a733147f93 100644 (file)
 #define CTX_NO_PET                     4
 #define CTX_TWEAK                      8
 #define CTX_NO_MIRROR          16
+#define CTX_AUTOCONFIRM                32
 
 void initTransform(int mode, int context);
 void Transform(void);
-void Mirror(short mode);
 
 /* Standalone call to get the transformation center corresponding to the current situation
  * returns 1 if successful, 0 otherwise (usually means there's no selection)
index 30b9bbf3f51ba945af7240fe6b84010febdad38e..48e840a7128dde94e315ebe29852a21f6d8c7282 100644 (file)
@@ -363,6 +363,9 @@ int TimeScale(TransInfo *t, short mval[2]);
 void initBakeTime(TransInfo *t);
 int BakeTime(TransInfo *t, short mval[2]);
 
+void initMirror(TransInfo *t);
+int Mirror(TransInfo *t, short mval[2]);
+
 /*********************** transform_conversions.c ********** */
 struct ListBase;
 void flushTransIpoData(TransInfo *t);
index 90b0e8c048eb89a74475e091f1b64bb850ea5fed..2e96ea464faf348e9518b38f3b63b4fe781fe2c4 100644 (file)
@@ -5574,17 +5574,9 @@ void mirrormenu(void)
        if(G.f & G_PARTICLEEDIT) {
                PE_mirror_x(0);
        }
-       else if (G.obedit==0) {
-               mode=pupmenu("Mirror Axis %t|X Local%x4|Y Local%x5|Z Local%x6|");
-
-               if (mode==-1) return; /* return */
-               Mirror(mode); /* separating functionality from interface | call*/
-       }
        else {
-               mode=pupmenu("Mirror Axis %t|X Global%x1|Y Global%x2|Z Global%x3|%l|X Local%x4|Y Local%x5|Z Local%x6|%l|X View%x7|Y View%x8|Z View%x9|");
-
-               if (mode==-1) return; /* return */
-               Mirror(mode); /* separating functionality from interface | call*/
+               initTransform(TFM_MIRROR, CTX_NO_PET);
+               Transform();
        }
 }
 
index f7cf9dd22cd840c6ee914ee832bced41c2851f93..4cbad8a9758d6160e88bbd434f0bfdaa463cad81 100644 (file)
@@ -1881,10 +1881,24 @@ static uiBlock *view3d_transformmenu(void *arg_unused)
 void do_view3d_object_mirrormenu(void *arg, int event)
 {
        switch(event) {
+               case 0:
+                       initTransform(TFM_MIRROR, CTX_NO_PET);
+                       Transform();
+                       break;
                case 1:
+                       initTransform(TFM_MIRROR, CTX_NO_PET|CTX_AUTOCONFIRM);
+                       BIF_setLocalAxisConstraint('X', " on X axis");
+                       Transform();
+                       break;
                case 2:
+                       initTransform(TFM_MIRROR, CTX_NO_PET|CTX_AUTOCONFIRM);
+                       BIF_setLocalAxisConstraint('Y', " on Y axis");
+                       Transform();
+                       break;
                case 3:
-                       Mirror(event + 3); /* + 3 because the first three modes are global*/
+                       initTransform(TFM_MIRROR, CTX_NO_PET|CTX_AUTOCONFIRM);
+                       BIF_setLocalAxisConstraint('Z', " on Z axis");
+                       Transform();
                        break;
        }
        allqueue(REDRAWVIEW3D, 0);
@@ -1898,9 +1912,11 @@ static uiBlock *view3d_object_mirrormenu(void *arg_unused)
        block= uiNewBlock(&curarea->uiblocks, "view3d_object_mirrormenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
        uiBlockSetButmFunc(block, do_view3d_object_mirrormenu, NULL);
        
-       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "X Local|Ctrl M, 1",                      0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
-       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Y Local|Ctrl M, 2",                      0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
-       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Z Local|Ctrl M, 3",                      0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
+       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Interactive Mirror|Ctrl M",                      0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 0, "");
+       uiDefBut(block, SEPR, 0, "",                            0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "X Local|Ctrl M, X",                      0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
+       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Y Local|Ctrl M, Y",                      0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
+       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Z Local|Ctrl M, Z",                      0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
 
        uiBlockSetDirection(block, UI_RIGHT);
        uiTextBoundsBlock(block, 60);
@@ -2853,17 +2869,44 @@ static uiBlock *view3d_edit_mesh_normalsmenu(void *arg_unused)
 
 void do_view3d_edit_mirrormenu(void *arg, int event)
 {
+       float mat[3][3];
+       
+       Mat3One(mat);
+       
        switch(event) {
+               case 0:
+                       initTransform(TFM_MIRROR, CTX_NO_PET);
+                       Transform();
+                       break;
                case 1:
+                       initTransform(TFM_MIRROR, CTX_NO_PET|CTX_AUTOCONFIRM);
+                       BIF_setSingleAxisConstraint(mat[0], " on global X axis");
+                       Transform();
+                       break;
                case 2:
+                       initTransform(TFM_MIRROR, CTX_NO_PET|CTX_AUTOCONFIRM);
+                       BIF_setSingleAxisConstraint(mat[1], " on global Y axis");
+                       Transform();
+                       break;
                case 3:
+                       initTransform(TFM_MIRROR, CTX_NO_PET|CTX_AUTOCONFIRM);
+                       BIF_setSingleAxisConstraint(mat[2], "on global Z axis");
+                       Transform();
+                       break;
                case 4:
+                       initTransform(TFM_MIRROR, CTX_NO_PET|CTX_AUTOCONFIRM);
+                       BIF_setLocalAxisConstraint('X', " on local X axis");
+                       Transform();
+                       break;
                case 5:
+                       initTransform(TFM_MIRROR, CTX_NO_PET|CTX_AUTOCONFIRM);
+                       BIF_setLocalAxisConstraint('Y', " on local Y axis");
+                       Transform();
+                       break;
                case 6:
-               case 7:
-               case 8:
-               case 9:
-                       Mirror(event);
+                       initTransform(TFM_MIRROR, CTX_NO_PET|CTX_AUTOCONFIRM);
+                       BIF_setLocalAxisConstraint('Z', " on local Z axis");
+                       Transform();
                        break;
        }
        allqueue(REDRAWVIEW3D, 0);
@@ -2877,21 +2920,19 @@ static uiBlock *view3d_edit_mirrormenu(void *arg_unused)
        block= uiNewBlock(&curarea->uiblocks, "view3d_edit_mirrormenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
        uiBlockSetButmFunc(block, do_view3d_edit_mirrormenu, NULL);
        
-       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "X Global|Ctrl M, 1",                     0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
-       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Y Global|Ctrl M, 2",                     0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
-       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Z Global|Ctrl M, 3",                     0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
-       
+       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Interactive Mirror|Ctrl M",                      0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 0, "");
+
        uiDefBut(block, SEPR, 0, "",                            0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
        
-       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "X Local|Ctrl M, 4",                      0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, "");
-       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Y Local|Ctrl M, 5",                      0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, "");
-       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Z Local|Ctrl M, 6",                      0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 6, "");
+       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "X Global|Ctrl M, X",                     0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
+       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Y Global|Ctrl M, Y",                     0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
+       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Z Global|Ctrl M, Z",                     0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
        
        uiDefBut(block, SEPR, 0, "",                            0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
        
-       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "X View|Ctrl M, 7",                       0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 7, "");
-       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Y View|Ctrl M, 8",                       0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 8, "");
-       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Z View|Ctrl M, 9",                       0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 9, "");
+       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "X Local|Ctrl M, X X",                    0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, "");
+       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Y Local|Ctrl M, Y Y",                    0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, "");
+       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Z Local|Ctrl M, Z Z",                    0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 6, "");
 
        uiBlockSetDirection(block, UI_RIGHT);
        uiTextBoundsBlock(block, 60);
index bbb5e5149423fca29d74cad84443f5f2a0564dbe..498b546ba57adba314795eee874ab3ba1737bf0b 100644 (file)
@@ -888,6 +888,8 @@ static char *transform_to_undostr(TransInfo *t)
                        return "Time Slide";
                case TFM_BAKE_TIME:
                        return "Key Time";
+               case TFM_MIRROR:
+                       return "Mirror";
        }
        return "Transform";
 }
@@ -1323,6 +1325,9 @@ void initTransform(int mode, int context) {
        case TFM_BAKE_TIME:
                initBakeTime(&Trans);
                break;
+       case TFM_MIRROR:
+               initMirror(&Trans);
+               break;
        }
 }
 
@@ -1359,6 +1364,13 @@ void Transform()
                        }
                        Trans.redraw = 0;
                }
+
+               /* If auto confirm is on, break after one pass */               
+               if (Trans.context & CTX_AUTOCONFIRM)
+               {
+                       Trans.state = TRANS_CONFIRM;
+                       break;
+               }
                
                /* essential for idling subloop */
                if( qtest()==0) PIL_sleep_ms(2);
@@ -4033,105 +4045,84 @@ int BakeTime(TransInfo *t, short mval[2])
        return 1;
 }
 
-
 /* ************************** MIRROR *************************** */
 
-void Mirror(short mode
+void initMirror(TransInfo *t
 {
-       TransData *td;
-       float mati[3][3], matview[3][3], mat[3][3];
-       float size[3];
-       int i;
-
-       Trans.context = CTX_NO_PET;
-
-       initTrans(&Trans);              // internal data, mouse, vectors
-
-       Mat3One(mati);
-       Mat3CpyMat4(matview, Trans.viewinv); // t->viewinv was set in initTrans
-       Mat3Ortho(matview);
-
-       createTransData(&Trans);        // make TransData structs from selection
-
-       calculatePropRatio(&Trans);
-       calculateCenter(&Trans);
-
-       initResize(&Trans);
-
-       if (Trans.total == 0) {
-               postTrans(&Trans);
-               return;
-       }
-
-       size[0] = size[1] = size[2] = 1.0f;
-       td = Trans.data;
-
-       switch (mode) {
-       case 1:
-               size[0] = -1.0f;
-               setConstraint(&Trans, mati, (CON_AXIS0), "");
-               break;
-       case 2:
-               size[1] = -1.0f;
-               setConstraint(&Trans, mati, (CON_AXIS1), "");
-               break;
-       case 3:
-               size[2] = -1.0f;
-               setConstraint(&Trans, mati, (CON_AXIS2), "");
-               break;
-       case 4:
-               size[0] = -1.0f;
-               setLocalConstraint(&Trans, (CON_AXIS0), "");
-               break;
-       case 5:
-               size[1] = -1.0f;
-               setLocalConstraint(&Trans, (CON_AXIS1), "");
-               break;
-       case 6:
-               size[2] = -1.0f;
-               setLocalConstraint(&Trans, (CON_AXIS2), "");
-               break;
-       case 7:
-               size[0] = -1.0f;
-               setConstraint(&Trans, matview, (CON_AXIS0), "");
-               break;
-       case 8:
-               size[1] = -1.0f;
-               setConstraint(&Trans, matview, (CON_AXIS1), "");
-               break;
-       case 9:
-               size[2] = -1.0f;
-               setConstraint(&Trans, matview, (CON_AXIS2), "");
-               break;
-       default:
-               return;
+       t->flag |= T_NULL_ONE;
+       if (!G.obedit) {
+               t->flag |= T_NO_ZERO;
        }
+       
+       t->transform = Mirror;
+       t->fac = 0.1f;
+}
 
-       SizeToMat3(size, mat);
-
-       if (Trans.con.applySize) {
-               Trans.con.applySize(&Trans, NULL, mat);
-       }
+int Mirror(TransInfo *t, short mval[2]) 
+{
+       TransData *td;
+       float size[3], mat[3][3];
+       int i;
+       char str[200];
 
-       for(i = 0 ; i < Trans.total; i++, td++) {
-               if (td->flag & TD_NOACTION)
-                       break;
+       /*
+        * OPTIMISATION:
+        * This still recalcs transformation on mouse move
+        * while it should only recalc on constraint change
+        * */
 
-               if (td->flag & TD_SKIP)
-                       continue;
+       /* if an axis has been selected */
+       if (t->con.mode & CON_APPLY) {
+               if (t->con.applySize) {
+                       t->con.applySize(t, NULL, mat);
+               }
                
-               ElementResize(&Trans, td, mat);
+               sprintf(str, "Mirror%s", t->con.text);
+       
+               size[0] = size[1] = size[2] = -1;
+       
+               SizeToMat3(size, mat);
+               
+               for(i = 0, td=t->data; i < t->total; i++, td++) {
+                       if (td->flag & TD_NOACTION)
+                               break;
+       
+                       if (td->flag & TD_SKIP)
+                               continue;
+                       
+                       ElementResize(t, td, mat);
+               }
+       
+               recalcData(t);
+       
+               headerprint(str);
+       
+               viewRedrawForce(t);
        }
-
-       recalcData(&Trans);
+       else
+       {
+               size[0] = size[1] = size[2] = 1;
        
-       BIF_undo_push("Mirror");
-
-       /* free data, reset vars */
-       postTrans(&Trans);
+               SizeToMat3(size, mat);
+               
+               for(i = 0, td=t->data; i < t->total; i++, td++) {
+                       if (td->flag & TD_NOACTION)
+                               break;
+       
+                       if (td->flag & TD_SKIP)
+                               continue;
+                       
+                       ElementResize(t, td, mat);
+               }
+       
+               recalcData(t);
+       
+               headerprint("Select a mirror axis (X, Y, Z)");
+       
+               viewRedrawForce(t);
+       }
 
-       /* send events out for redraws */
-       viewRedrawPost(&Trans);
+       return 1;
 }
 
 /* ************************** ANIM EDITORS - TRANSFORM TOOLS *************************** */