Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Poirier <theeth@yahoo.com>2006-12-20 01:25:07 +0300
committerMartin Poirier <theeth@yahoo.com>2006-12-20 01:25:07 +0300
commitf4a03182fbe1d3960c78e610e1659061f7e39482 (patch)
treec01c8850ae15571fb8b141c352183746840959d8
parent83e3545f9e5d34552bc6813fd208a039ea6da9aa (diff)
=== Transform Snap ===
Draw a circle around the snapping point for visual aid. Different snapping target method, switchable in the 3d view header menu in the Transform menu. * Closest: Snaps the closest vertex to the point * Median: Snaps the median of the selection to the point * Center: Snaps the transform center to the point (this is different from median because you can use Cursor/Boundbox as center) Fix a bug with constraints/snap handling.
-rwxr-xr-xsource/blender/include/BIF_transform.h1
-rwxr-xr-xsource/blender/include/transform.h7
-rw-r--r--source/blender/makesdna/DNA_view3d_types.h5
-rw-r--r--source/blender/src/drawview.c1
-rw-r--r--source/blender/src/header_view3d.c60
-rwxr-xr-xsource/blender/src/transform.c10
-rwxr-xr-xsource/blender/src/transform_constraints.c37
-rw-r--r--source/blender/src/transform_snap.c137
8 files changed, 201 insertions, 57 deletions
diff --git a/source/blender/include/BIF_transform.h b/source/blender/include/BIF_transform.h
index ecc4ec248ad..e67789e9b23 100755
--- a/source/blender/include/BIF_transform.h
+++ b/source/blender/include/BIF_transform.h
@@ -76,6 +76,7 @@ void BIF_setLocalAxisConstraint(char axis, char *text);
void BIF_setLocalLockConstraint(char axis, char *text);
void BIF_drawConstraint(void);
void BIF_drawPropCircle(void);
+void BIF_drawSnap(void);
void BIF_getPropCenter(float *center);
void BIF_TransformSetUndo(char *str);
diff --git a/source/blender/include/transform.h b/source/blender/include/transform.h
index 7f12f765bbf..0a6a19a674d 100755
--- a/source/blender/include/transform.h
+++ b/source/blender/include/transform.h
@@ -251,6 +251,13 @@ typedef struct TransInfo {
#define TD_VERSE_VERT 64
#endif
+/* transsnap->status */
+#define SNAP_ON 0x1
+#define TARGET_INIT 0x2
+#define POINT_INIT 0x4
+
+
+
void checkFirstTime(void);
void setTransformViewMatrices(TransInfo *t);
diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h
index c174c975252..27ccc318067 100644
--- a/source/blender/makesdna/DNA_view3d_types.h
+++ b/source/blender/makesdna/DNA_view3d_types.h
@@ -167,6 +167,11 @@ typedef struct View3D {
#define V3D_OPP_DIRECTION_NAME 1
#define V3D_FLYMODE 2
#define V3D_TRANSFORM_SNAP 4
+#define V3D_SNAP_TARGET (8|16)
+#define V3D_SNAP_TARGET_CLOSEST 0
+#define V3D_SNAP_TARGET_CENTER 8
+#define V3D_SNAP_TARGET_MEDIAN 16
+
/* View3D->around */
#define V3D_CENTRE 0
diff --git a/source/blender/src/drawview.c b/source/blender/src/drawview.c
index 2ff4399dadd..d22408f02e3 100644
--- a/source/blender/src/drawview.c
+++ b/source/blender/src/drawview.c
@@ -2900,6 +2900,7 @@ void drawview3dspace(ScrArea *sa, void *spacedata)
if(G.moving) {
BIF_drawConstraint();
if(G.obedit) BIF_drawPropCircle(); // only editmode has proportional edit
+ BIF_drawSnap();
}
if(G.scene->radio) RAD_drawall(v3d->drawtype>=OB_SOLID);
diff --git a/source/blender/src/header_view3d.c b/source/blender/src/header_view3d.c
index e91929fa5f9..759a0085598 100644
--- a/source/blender/src/header_view3d.c
+++ b/source/blender/src/header_view3d.c
@@ -1696,6 +1696,21 @@ static void do_view3d_transformmenu(void *arg, int event)
initTransform(TFM_CURVE_SHRINKFATTEN, CTX_NONE);
Transform();
break;
+ case 15:
+ G.vd->flag2 ^= V3D_TRANSFORM_SNAP;
+ break;
+ case 16:
+ G.vd->flag2 &= ~V3D_SNAP_TARGET;
+ G.vd->flag2 |= V3D_SNAP_TARGET_CLOSEST;
+ break;
+ case 17:
+ G.vd->flag2 &= ~V3D_SNAP_TARGET;
+ G.vd->flag2 |= V3D_SNAP_TARGET_CENTER;
+ break;
+ case 18:
+ G.vd->flag2 &= ~V3D_SNAP_TARGET;
+ G.vd->flag2 |= V3D_SNAP_TARGET_MEDIAN;
+ break;
}
allqueue(REDRAWVIEW3D, 0);
}
@@ -1747,6 +1762,35 @@ static uiBlock *view3d_transformmenu(void *arg_unused)
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Center Cursor", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 12, "");
}
+ if (G.obedit != NULL && G.obedit->type==OB_MESH)
+ {
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+
+ 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, "");
+ else
+ uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Snap", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 15, "");
+
+ switch(G.vd->flag2 & V3D_SNAP_TARGET)
+ {
+ 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_DEHLT, "Snap Center", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 17, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Snap Median", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 18, "");
+ break;
+ 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_HLT, "Snap Center", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 17, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Snap Median", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 18, "");
+ break;
+ 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 Center", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 17, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Snap Median", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 18, "");
+ break;
+ }
+ }
+
uiBlockSetDirection(block, UI_RIGHT);
uiTextBoundsBlock(block, 60);
return block;
@@ -2262,9 +2306,6 @@ static void do_view3d_edit_objectmenu(void *arg, int event)
if(session) b_verse_push_object(session, ob);
break;
#endif
- case 17: /* Transform snap to grid */
- G.vd->flag2 ^= V3D_TRANSFORM_SNAP;
- break;
}
allqueue(REDRAWVIEW3D, 0);
}
@@ -2289,11 +2330,6 @@ static uiBlock *view3d_edit_objectmenu(void *arg_unused)
}
}
#endif
-
- if (G.vd->flag2 & V3D_TRANSFORM_SNAP)
- uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Transform Snap", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 17, "");
- else
- uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Transform Snap", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 17, "");
uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL, "Transform Properties|N", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 15, "");
@@ -2831,9 +2867,6 @@ static void do_view3d_edit_meshmenu(void *arg, int event)
if(session) b_verse_push_object(session, G.obedit);
break;
#endif
- case 17: /* Transform snap to grid */
- G.vd->flag2 ^= V3D_TRANSFORM_SNAP;
- break;
}
allqueue(REDRAWVIEW3D, 0);
}
@@ -2861,11 +2894,6 @@ static uiBlock *view3d_edit_meshmenu(void *arg_unused)
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
- if (G.vd->flag2 & V3D_TRANSFORM_SNAP)
- uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Transform Snap", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 17, "");
- else
- uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Transform Snap", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 17, "");
-
uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL, "Transform Properties...|N", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
uiDefIconTextBlockBut(block, view3d_transformmenu, NULL, ICON_RIGHTARROW_THIN, "Transform", 0, yco-=20, 120, 19, "");
uiDefIconTextBlockBut(block, view3d_edit_mirrormenu, NULL, ICON_RIGHTARROW_THIN, "Mirror", 0, yco-=20, 120, 19, "");
diff --git a/source/blender/src/transform.c b/source/blender/src/transform.c
index 59564ec83dd..7e406e9c61c 100755
--- a/source/blender/src/transform.c
+++ b/source/blender/src/transform.c
@@ -98,6 +98,14 @@
TransInfo Trans = {TFM_INIT, 0}; // enforce init on first usage
/******************************** Helper functions ************************************/
+
+/* GLOBAL Wrapper Fonctions */
+
+void BIF_drawSnap()
+{
+ drawSnapping(&Trans);
+}
+
/* ************************** Dashed help line **************************** */
@@ -2158,9 +2166,9 @@ int Translation(TransInfo *t, short mval[2])
if (t->con.mode & CON_APPLY) {
float pvec[3] = {0.0f, 0.0f, 0.0f};
+ applySnapping(t, t->vec);
t->con.applyVec(t, NULL, t->vec, tvec, pvec);
VECCOPY(t->vec, tvec);
- applySnapping(t, t->vec);
headerTranslation(t, pvec, str);
}
else {
diff --git a/source/blender/src/transform_constraints.c b/source/blender/src/transform_constraints.c
index be7a0bd2636..f67b3acff3a 100755
--- a/source/blender/src/transform_constraints.c
+++ b/source/blender/src/transform_constraints.c
@@ -241,24 +241,29 @@ static void applyAxisConstraintVec(TransInfo *t, TransData *td, float in[3], flo
VECCOPY(out, in);
if (!td && t->con.mode & CON_APPLY) {
Mat3MulVecfl(t->con.pmtx, out);
- if (getConstraintSpaceDimension(t) == 2) {
- if (out[0] != 0.0f || out[1] != 0.0f || out[2] != 0.0f) {
- planeProjection(t, in, out);
- }
- }
- else if (getConstraintSpaceDimension(t) == 1) {
- float c[3];
-
- if (t->con.mode & CON_AXIS0) {
- VECCOPY(c, t->con.mtx[0]);
- }
- else if (t->con.mode & CON_AXIS1) {
- VECCOPY(c, t->con.mtx[1]);
+
+ // With snap, a projection is alright, no need to correct for view alignment
+ if ((t->tsnap.status & SNAP_ON) == 0)
+ {
+ if (getConstraintSpaceDimension(t) == 2) {
+ if (out[0] != 0.0f || out[1] != 0.0f || out[2] != 0.0f) {
+ planeProjection(t, in, out);
+ }
}
- else if (t->con.mode & CON_AXIS2) {
- VECCOPY(c, t->con.mtx[2]);
+ else if (getConstraintSpaceDimension(t) == 1) {
+ float c[3];
+
+ if (t->con.mode & CON_AXIS0) {
+ VECCOPY(c, t->con.mtx[0]);
+ }
+ else if (t->con.mode & CON_AXIS1) {
+ VECCOPY(c, t->con.mtx[1]);
+ }
+ else if (t->con.mode & CON_AXIS2) {
+ VECCOPY(c, t->con.mtx[2]);
+ }
+ axisProjection(t, c, in, out);
}
- axisProjection(t, c, in, out);
}
postConstraintChecks(t, out, pvec);
}
diff --git a/source/blender/src/transform_snap.c b/source/blender/src/transform_snap.c
index ba2c3b7c316..cdd4fb793ba 100644
--- a/source/blender/src/transform_snap.c
+++ b/source/blender/src/transform_snap.c
@@ -37,6 +37,7 @@
#include "PIL_time.h"
#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
#include "DNA_space_types.h"
#include "DNA_userdef_types.h"
#include "DNA_view3d_types.h"
@@ -58,10 +59,7 @@
#include "transform.h"
#include "mydevice.h" /* for KEY defines */
-
-#define SNAP_ON 0x1
-#define TARGET_INIT 0x2
-#define POINT_INIT 0x4
+#include "blendef.h" /* for selection modes */
/********************* PROTOTYPES ***********************/
@@ -81,8 +79,23 @@ void TargetSnapClosest(TransInfo *t);
void drawSnapping(TransInfo *t)
{
- if (t->tsnap.status & SNAP_ON) {
- // Do something nice
+ if ((t->tsnap.status & (SNAP_ON|POINT_INIT|TARGET_INIT)) == (SNAP_ON|POINT_INIT|TARGET_INIT)) {
+ float unitmat[4][4];
+ char col[4];
+
+ BIF_GetThemeColor3ubv(TH_TRANSFORM, col);
+ glColor4ub(col[0], col[1], col[2], 128);
+
+ glPushMatrix();
+
+ glTranslatef(t->tsnap.snapPoint[0], t->tsnap.snapPoint[1], t->tsnap.snapPoint[2]);
+
+ /* sets view screen aligned */
+ glRotatef( -360.0f*saacos(G.vd->viewquat[0])/(float)M_PI, G.vd->viewquat[1], G.vd->viewquat[2], G.vd->viewquat[3]);
+
+ Mat4One(unitmat);
+ drawcircball(GL_LINE_LOOP, unitmat[3], 0.1f, unitmat);
+ glPopMatrix();
}
}
@@ -152,7 +165,6 @@ void setSnappingCallback(TransInfo *t)
case TFM_TRANSLATION:
t->tsnap.applySnap = ApplySnapTranslation;
t->tsnap.calcSnap = CalcSnapGeometry;
- t->tsnap.targetSnap = TargetSnapClosest;
break;
case TFM_ROTATION:
t->tsnap.applySnap = NULL;
@@ -164,6 +176,20 @@ void setSnappingCallback(TransInfo *t)
t->tsnap.applySnap = NULL;
break;
}
+
+ switch(G.vd->flag2 & V3D_SNAP_TARGET)
+ {
+ case V3D_SNAP_TARGET_CLOSEST:
+ t->tsnap.targetSnap = TargetSnapClosest;
+ break;
+ case V3D_SNAP_TARGET_CENTER:
+ t->tsnap.targetSnap = TargetSnapCenter;
+ break;
+ case V3D_SNAP_TARGET_MEDIAN:
+ t->tsnap.targetSnap = TargetSnapMedian;
+ break;
+ }
+
}
/********************** APPLY **************************/
@@ -171,11 +197,12 @@ void setSnappingCallback(TransInfo *t)
void ApplySnapTranslation(TransInfo *t, float vec[3])
{
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])
@@ -194,24 +221,52 @@ void CalcSnapGeometry(TransInfo *t, float *vec)
{
if (G.obedit != NULL && G.obedit->type==OB_MESH)
{
- EditVert *nearest=NULL;
- int dist = 50; // Use a user defined value here
-
- // use findnearestverts in vert mode, others in other modes
- nearest = findnearestvert(&dist, 0);
-
- if (nearest != NULL)
+ /*if (G.scene->selectmode & B_SEL_VERT)*/
{
- VECCOPY(t->tsnap.snapPoint, nearest->co);
+ EditVert *nearest=NULL;
+ int dist = 50; // Use a user defined value here
- Mat4MulVecfl(G.obedit->obmat, t->tsnap.snapPoint);
+ // use findnearestverts in vert mode, others in other modes
+ nearest = findnearestvert(&dist, 0);
- t->tsnap.status |= POINT_INIT;
+ if (nearest != NULL)
+ {
+ VECCOPY(t->tsnap.snapPoint, nearest->co);
+
+ Mat4MulVecfl(G.obedit->obmat, t->tsnap.snapPoint);
+
+ t->tsnap.status |= POINT_INIT;
+ }
+ else
+ {
+ t->tsnap.status &= ~POINT_INIT;
+ }
}
- else
+ /*
+ if (G.scene->selectmode & B_SEL_EDGE)
{
- t->tsnap.status &= ~POINT_INIT;
+ EditEdge *nearest=NULL;
+ int dist = 50; // Use a user defined value here
+
+ // use findnearestverts in vert mode, others in other modes
+ nearest = findnearestedge(&dist);
+
+ if (nearest != NULL)
+ {
+ VecAddf(t->tsnap.snapPoint, nearest->v1->co, nearest->v2->co);
+
+ VecMulf(t->tsnap.snapPoint, 0.5f);
+
+ Mat4MulVecfl(G.obedit->obmat, t->tsnap.snapPoint);
+
+ t->tsnap.status |= POINT_INIT;
+ }
+ else
+ {
+ t->tsnap.status &= ~POINT_INIT;
+ }
}
+ */
}
}
@@ -219,15 +274,49 @@ void CalcSnapGeometry(TransInfo *t, float *vec)
void TargetSnapCenter(TransInfo *t)
{
- VECCOPY(t->tsnap.snapTarget, t->center);
- if(t->flag & (T_EDIT|T_POSE)) {
- Object *ob= G.obedit?G.obedit:t->poseobj;
- Mat4MulVecfl(ob->obmat, t->tsnap.snapTarget);
+ // Only need to calculate once
+ if ((t->tsnap.status & TARGET_INIT) == 0)
+ {
+ VECCOPY(t->tsnap.snapTarget, t->center);
+ if(t->flag & (T_EDIT|T_POSE)) {
+ Object *ob= G.obedit?G.obedit:t->poseobj;
+ Mat4MulVecfl(ob->obmat, t->tsnap.snapTarget);
+ }
+
+ t->tsnap.status |= TARGET_INIT;
+ }
+}
+
+void TargetSnapMedian(TransInfo *t)
+{
+ // Only need to calculate once
+ if ((t->tsnap.status & TARGET_INIT) == 0)
+ {
+ TransData *td = NULL;
+
+ t->tsnap.snapTarget[0] = 0;
+ t->tsnap.snapTarget[1] = 0;
+ t->tsnap.snapTarget[2] = 0;
+
+ for (td = t->data; td != NULL && td->flag & TD_SELECTED ; td++)
+ {
+ VecAddf(t->tsnap.snapTarget, t->tsnap.snapTarget, td->iloc);
+ }
+
+ VecMulf(t->tsnap.snapTarget, 1.0 / t->total);
+
+ if(t->flag & (T_EDIT|T_POSE)) {
+ Object *ob= G.obedit?G.obedit:t->poseobj;
+ Mat4MulVecfl(ob->obmat, t->tsnap.snapTarget);
+ }
+
+ t->tsnap.status |= TARGET_INIT;
}
}
void TargetSnapClosest(TransInfo *t)
{
+ // Only valid if a snap point has been selected
if (t->tsnap.status & POINT_INIT)
{
TransData *closest = NULL, *td = NULL;