=== Transform Snap ===
(Implementing Matt's idea) Grid and Snap are now exclusively controlled by the Control key (pun intented). You can switch to Snap by selecting the snap option in the Transform menu (this option is only available in edit mode on a mesh. this option is per 3D view) (NOTE: There is currently no hotkey for that, anyone should feel free to add one). When Snap is selected, holding down Ctrl during translations (grab) snaps to vertex. All other situations which have no snapping code yet defaults to Grid.
This commit is contained in:
@@ -60,6 +60,7 @@ typedef struct NumInput {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct TransSnap {
|
typedef struct TransSnap {
|
||||||
|
int mode;
|
||||||
int status;
|
int status;
|
||||||
float snapPoint[3];
|
float snapPoint[3];
|
||||||
float snapTarget[3];
|
float snapTarget[3];
|
||||||
@@ -252,11 +253,13 @@ typedef struct TransInfo {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* transsnap->status */
|
/* transsnap->status */
|
||||||
#define SNAP_ON 0x1
|
#define SNAP_ON 1
|
||||||
#define TARGET_INIT 0x2
|
#define TARGET_INIT 2
|
||||||
#define POINT_INIT 0x4
|
#define POINT_INIT 4
|
||||||
|
|
||||||
|
|
||||||
|
/* transsnap->mode */
|
||||||
|
#define SNAP_GRID 1
|
||||||
|
#define SNAP_GEO 2
|
||||||
|
|
||||||
void checkFirstTime(void);
|
void checkFirstTime(void);
|
||||||
|
|
||||||
|
|||||||
@@ -1697,17 +1697,20 @@ static void do_view3d_transformmenu(void *arg, int event)
|
|||||||
Transform();
|
Transform();
|
||||||
break;
|
break;
|
||||||
case 15:
|
case 15:
|
||||||
G.vd->flag2 ^= V3D_TRANSFORM_SNAP;
|
G.vd->flag2 &= ~V3D_TRANSFORM_SNAP;
|
||||||
break;
|
break;
|
||||||
case 16:
|
case 16:
|
||||||
G.vd->flag2 &= ~V3D_SNAP_TARGET;
|
G.vd->flag2 |= V3D_TRANSFORM_SNAP;
|
||||||
G.vd->flag2 |= V3D_SNAP_TARGET_CLOSEST;
|
|
||||||
break;
|
break;
|
||||||
case 17:
|
case 17:
|
||||||
G.vd->flag2 &= ~V3D_SNAP_TARGET;
|
G.vd->flag2 &= ~V3D_SNAP_TARGET;
|
||||||
G.vd->flag2 |= V3D_SNAP_TARGET_CENTER;
|
G.vd->flag2 |= V3D_SNAP_TARGET_CLOSEST;
|
||||||
break;
|
break;
|
||||||
case 18:
|
case 18:
|
||||||
|
G.vd->flag2 &= ~V3D_SNAP_TARGET;
|
||||||
|
G.vd->flag2 |= V3D_SNAP_TARGET_CENTER;
|
||||||
|
break;
|
||||||
|
case 19:
|
||||||
G.vd->flag2 &= ~V3D_SNAP_TARGET;
|
G.vd->flag2 &= ~V3D_SNAP_TARGET;
|
||||||
G.vd->flag2 |= V3D_SNAP_TARGET_MEDIAN;
|
G.vd->flag2 |= V3D_SNAP_TARGET_MEDIAN;
|
||||||
break;
|
break;
|
||||||
@@ -1767,26 +1770,34 @@ static uiBlock *view3d_transformmenu(void *arg_unused)
|
|||||||
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
|
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
|
||||||
|
|
||||||
if (G.vd->flag2 & V3D_TRANSFORM_SNAP)
|
if (G.vd->flag2 & V3D_TRANSFORM_SNAP)
|
||||||
uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Snap", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 15, "");
|
{
|
||||||
|
uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Grid", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 15, "");
|
||||||
|
uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Snap", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 16, "");
|
||||||
|
}
|
||||||
else
|
else
|
||||||
uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Snap", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 15, "");
|
{
|
||||||
|
uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Grid", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 15, "");
|
||||||
|
uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Snap", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 16, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
|
||||||
|
|
||||||
switch(G.vd->flag2 & V3D_SNAP_TARGET)
|
switch(G.vd->flag2 & V3D_SNAP_TARGET)
|
||||||
{
|
{
|
||||||
case V3D_SNAP_TARGET_CLOSEST:
|
case V3D_SNAP_TARGET_CLOSEST:
|
||||||
uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Snap Closest", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 16, "");
|
uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Snap Closest", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 17, "");
|
||||||
uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Snap Center", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 17, "");
|
uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Snap Center", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 18, "");
|
||||||
uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Snap Median", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 18, "");
|
uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Snap Median", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 19, "");
|
||||||
break;
|
break;
|
||||||
case V3D_SNAP_TARGET_CENTER:
|
case V3D_SNAP_TARGET_CENTER:
|
||||||
uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Snap Closest", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 16, "");
|
uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Snap Closest", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 17, "");
|
||||||
uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Snap Center", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 17, "");
|
uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Snap Center", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 18, "");
|
||||||
uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Snap Median", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 18, "");
|
uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Snap Median", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 19, "");
|
||||||
break;
|
break;
|
||||||
case V3D_SNAP_TARGET_MEDIAN:
|
case V3D_SNAP_TARGET_MEDIAN:
|
||||||
uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Snap Closest", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 16, "");
|
uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Snap Closest", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 17, "");
|
||||||
uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Snap Center", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 17, "");
|
uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Snap Center", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 18, "");
|
||||||
uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Snap Median", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 18, "");
|
uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Snap Median", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 19, "");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2067,8 +2067,6 @@ void initTranslation(TransInfo *t)
|
|||||||
t->snap[0] = 0.0f;
|
t->snap[0] = 0.0f;
|
||||||
t->snap[1] = t->snap[2] = 1.0f;
|
t->snap[1] = t->snap[2] = 1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
initSnapping(t);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void headerTranslation(TransInfo *t, float vec[3], char *str) {
|
static void headerTranslation(TransInfo *t, float vec[3], char *str) {
|
||||||
|
|||||||
@@ -494,7 +494,7 @@ void initTrans (TransInfo *t)
|
|||||||
t->around = V3D_CENTRE;
|
t->around = V3D_CENTRE;
|
||||||
|
|
||||||
setTransformViewMatrices(t);
|
setTransformViewMatrices(t);
|
||||||
resetSnapping(t);
|
initSnapping(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Here I would suggest only TransInfo related issues, like free data & reset vars. Not redraws */
|
/* Here I would suggest only TransInfo related issues, like free data & reset vars. Not redraws */
|
||||||
|
|||||||
@@ -79,7 +79,8 @@ void TargetSnapClosest(TransInfo *t);
|
|||||||
|
|
||||||
void drawSnapping(TransInfo *t)
|
void drawSnapping(TransInfo *t)
|
||||||
{
|
{
|
||||||
if ((t->tsnap.status & (SNAP_ON|POINT_INIT|TARGET_INIT)) == (SNAP_ON|POINT_INIT|TARGET_INIT)) {
|
if ((t->tsnap.status & (SNAP_ON|POINT_INIT|TARGET_INIT)) == (SNAP_ON|POINT_INIT|TARGET_INIT) &&
|
||||||
|
(G.qual & LR_CTRLKEY)) {
|
||||||
float unitmat[4][4];
|
float unitmat[4][4];
|
||||||
char col[4];
|
char col[4];
|
||||||
|
|
||||||
@@ -103,21 +104,15 @@ int handleSnapping(TransInfo *t, int event)
|
|||||||
{
|
{
|
||||||
int status = 0;
|
int status = 0;
|
||||||
|
|
||||||
switch(event) {
|
// Put keyhandling code here
|
||||||
case ACCENTGRAVEKEY:
|
|
||||||
t->tsnap.status ^= SNAP_ON;
|
|
||||||
status = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
void applySnapping(TransInfo *t, float *vec)
|
void applySnapping(TransInfo *t, float *vec)
|
||||||
{
|
{
|
||||||
if ( (t->tsnap.status & SNAP_ON) &&
|
if ((t->tsnap.status & SNAP_ON) &&
|
||||||
t->tsnap.applySnap != NULL &&
|
(G.qual & LR_CTRLKEY))
|
||||||
(t->flag & T_PROP_EDIT) == 0)
|
|
||||||
{
|
{
|
||||||
double current = PIL_check_seconds_timer();
|
double current = PIL_check_seconds_timer();
|
||||||
|
|
||||||
@@ -148,13 +143,18 @@ void initSnapping(TransInfo *t)
|
|||||||
resetSnapping(t);
|
resetSnapping(t);
|
||||||
setSnappingCallback(t);
|
setSnappingCallback(t);
|
||||||
|
|
||||||
if ((t->spacetype==SPACE_VIEW3D) && (G.vd->flag2 & V3D_TRANSFORM_SNAP))
|
if (t->tsnap.applySnap != NULL && // A snapping function actually exist
|
||||||
|
(G.obedit != NULL && G.obedit->type==OB_MESH) && // Temporary limited to edit mode meshes
|
||||||
|
(t->spacetype==SPACE_VIEW3D) && // Only 3D view (not UV)
|
||||||
|
(G.vd->flag2 & V3D_TRANSFORM_SNAP) && // Only if the snap flag is on
|
||||||
|
(t->flag & T_PROP_EDIT) == 0) // No PET, obviously
|
||||||
{
|
{
|
||||||
t->tsnap.status |= SNAP_ON;
|
t->tsnap.status |= SNAP_ON;
|
||||||
|
t->tsnap.mode = SNAP_GEO;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
t->tsnap.status &= ~SNAP_ON;
|
t->tsnap.mode = SNAP_GRID;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,12 +197,6 @@ void setSnappingCallback(TransInfo *t)
|
|||||||
void ApplySnapTranslation(TransInfo *t, float vec[3])
|
void ApplySnapTranslation(TransInfo *t, float vec[3])
|
||||||
{
|
{
|
||||||
VecSubf(vec, t->tsnap.snapPoint, t->tsnap.snapTarget);
|
VecSubf(vec, t->tsnap.snapPoint, t->tsnap.snapTarget);
|
||||||
/*
|
|
||||||
if (t->con.mode & CON_APPLY)
|
|
||||||
{
|
|
||||||
Mat3MulVecfl(t->con.pmtx, vec);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApplySnapRotation(TransInfo *t, float vec[3])
|
void ApplySnapRotation(TransInfo *t, float vec[3])
|
||||||
@@ -387,6 +381,10 @@ void snapGridAction(TransInfo *t, float *val, GearsType action) {
|
|||||||
void snapGrid(TransInfo *t, float *val) {
|
void snapGrid(TransInfo *t, float *val) {
|
||||||
int invert;
|
int invert;
|
||||||
GearsType action;
|
GearsType action;
|
||||||
|
|
||||||
|
// Only do something if using Snap to Grid
|
||||||
|
if ((t->tsnap.mode & SNAP_GRID) == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
if(t->mode==TFM_ROTATION || t->mode==TFM_WARP || t->mode==TFM_TILT || t->mode==TFM_TRACKBALL || t->mode==TFM_BONE_ROLL)
|
if(t->mode==TFM_ROTATION || t->mode==TFM_WARP || t->mode==TFM_TILT || t->mode==TFM_TRACKBALL || t->mode==TFM_BONE_ROLL)
|
||||||
invert = U.flag & USER_AUTOROTGRID;
|
invert = U.flag & USER_AUTOROTGRID;
|
||||||
|
|||||||
Reference in New Issue
Block a user