diff options
author | Martin Poirier <theeth@yahoo.com> | 2006-12-20 01:25:07 +0300 |
---|---|---|
committer | Martin Poirier <theeth@yahoo.com> | 2006-12-20 01:25:07 +0300 |
commit | f4a03182fbe1d3960c78e610e1659061f7e39482 (patch) | |
tree | c01c8850ae15571fb8b141c352183746840959d8 /source/blender/src/transform_snap.c | |
parent | 83e3545f9e5d34552bc6813fd208a039ea6da9aa (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.
Diffstat (limited to 'source/blender/src/transform_snap.c')
-rw-r--r-- | source/blender/src/transform_snap.c | 137 |
1 files changed, 113 insertions, 24 deletions
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; |