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
path: root/source
diff options
context:
space:
mode:
authorMartin Poirier <theeth@yahoo.com>2008-01-14 01:20:18 +0300
committerMartin Poirier <theeth@yahoo.com>2008-01-14 01:20:18 +0300
commite4e66c9aa429dde5b38985f54af9e1336c4b6fa0 (patch)
tree3feb5f5fd38e56eeb6c875b3d9f88cdf37f560ef /source
parentd660e293650d88e00009ad315fb00ade71239621 (diff)
=== Transform Snap ===
Snapping for object mode Changes: - Transform snap now working in object mode and not just mesh edit mode - Shift-Tab can be used to toggle snap on/off inside transform too (no more Esc,toggle,restart) - Object mode snap: Closest uses the bounding box corners of all selected objects, Median uses object center and Center uses transform center (same as edit mode). - Object mode snap: all visible meshes can be used to get the snapping point (unlike edit mode snap which is limited to selected mesh: this might be adjusted to make edit mode snap use all visible too). To Do: - Add "Active" snap target method: use active object (or mesh element) as snap target - Add snapping capabilities to Scale - (Maybe) Add "Near pointer" snap target method: use selected element that is closest to mouse pointer as snap target. Active could probably accomplish that already in a less confusing manner, so I might skip this.
Diffstat (limited to 'source')
-rw-r--r--source/blender/include/BIF_transform.h2
-rw-r--r--source/blender/include/transform.h2
-rw-r--r--source/blender/src/header_view3d.c4
-rw-r--r--source/blender/src/space.c4
-rw-r--r--source/blender/src/transform_conversions.c2
-rw-r--r--source/blender/src/transform_snap.c102
6 files changed, 91 insertions, 25 deletions
diff --git a/source/blender/include/BIF_transform.h b/source/blender/include/BIF_transform.h
index 98af3b84770..c8e2a4832ab 100644
--- a/source/blender/include/BIF_transform.h
+++ b/source/blender/include/BIF_transform.h
@@ -90,6 +90,8 @@ void BIF_setDualAxisConstraint(float vec1[3], float vec2[3], char *text);
void BIF_setLocalAxisConstraint(char axis, char *text);
void BIF_setLocalLockConstraint(char axis, char *text);
+int BIF_snappingSupported(void);
+
struct TransformOrientation;
void BIF_clearTransformOrientation(void);
diff --git a/source/blender/include/transform.h b/source/blender/include/transform.h
index ae8997a28ee..e9e82612721 100644
--- a/source/blender/include/transform.h
+++ b/source/blender/include/transform.h
@@ -122,7 +122,7 @@ typedef struct TransDataExtension {
float iquat[4]; /* Initial rotation quaternion */
float *size; /* Size of the data to transform (Faculative) */
float isize[3]; /* Initial size */
- float obmat[3][3]; /* Object matrix */
+ float obmat[4][4]; /* Object matrix */
} TransDataExtension;
typedef struct TransData2D {
diff --git a/source/blender/src/header_view3d.c b/source/blender/src/header_view3d.c
index dbfbaf9d30b..8102e60c7fb 100644
--- a/source/blender/src/header_view3d.c
+++ b/source/blender/src/header_view3d.c
@@ -1818,7 +1818,7 @@ 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)
+ if (BIF_snappingSupported())
{
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
@@ -5476,7 +5476,7 @@ void view3d_buttons(void)
}
/* Snap */
- if(G.obedit && (G.obedit->type == OB_MESH)) { // Only Mesh for now
+ if (BIF_snappingSupported()) {
uiBlockBeginAlign(block);
if (G.scene->snap_flag & SCE_SNAP) {
diff --git a/source/blender/src/space.c b/source/blender/src/space.c
index 775148582a8..9f3754f32da 100644
--- a/source/blender/src/space.c
+++ b/source/blender/src/space.c
@@ -1570,8 +1570,8 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
/* Shift-Tabe handling (other cases are in toets) */
if (G.qual == LR_SHIFTKEY)
{
- /* Snap toggle (only edit mesh right now) */
- if (G.obedit && G.obedit->type==OB_MESH)
+ /* Snap toggle only when supported */
+ if (BIF_snappingSupported())
{
G.scene->snap_flag ^= SCE_SNAP;
allqueue(REDRAWHEADERS, 0);
diff --git a/source/blender/src/transform_conversions.c b/source/blender/src/transform_conversions.c
index 77d9938f778..3f69316e373 100644
--- a/source/blender/src/transform_conversions.c
+++ b/source/blender/src/transform_conversions.c
@@ -2861,6 +2861,8 @@ static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob)
VECCOPY(td->ext->dsize, ob->dsize);
VECCOPY(td->center, ob->obmat[3]);
+
+ Mat4CpyMat4(td->ext->obmat, ob->obmat);
/* is there a need to set the global<->data space conversion matrices? */
if (ob->parent || constinv) {
diff --git a/source/blender/src/transform_snap.c b/source/blender/src/transform_snap.c
index 355c150657e..3aeb90bee32 100644
--- a/source/blender/src/transform_snap.c
+++ b/source/blender/src/transform_snap.c
@@ -90,10 +90,22 @@ float RotationBetween(TransInfo *t, float p1[3], float p2[3]);
float TranslationBetween(TransInfo *t, float p1[3], float p2[3]);
// Trickery
-int findNearestVertFromObjects(int *dist, float *loc);
+int findNearestVertFromObjects(int *dist, float *loc, int selected);
/****************** IMPLEMENTATIONS *********************/
+int BIF_snappingSupported(void)
+{
+ int status = 0;
+
+ if (G.obedit == NULL || G.obedit->type==OB_MESH) /* only support object or mesh */
+ {
+ status = 1;
+ }
+
+ return status;
+}
+
void drawSnapping(TransInfo *t)
{
if ((t->tsnap.status & (SNAP_ON|POINT_INIT|TARGET_INIT)) == (SNAP_ON|POINT_INIT|TARGET_INIT) &&
@@ -168,7 +180,13 @@ int handleSnapping(TransInfo *t, int event)
{
int status = 0;
- // Put keyhandling code here
+ if (BIF_snappingSupported() && event == TABKEY && (G.qual & LR_SHIFTKEY) == LR_SHIFTKEY)
+ {
+ /* toggle snap and reinit */
+ G.scene->snap_flag ^= SCE_SNAP;
+ initSnapping(t);
+ status = 1;
+ }
return status;
}
@@ -211,10 +229,19 @@ void initSnapping(TransInfo *t)
if (t->spacetype == SPACE_VIEW3D || t->spacetype == SPACE_IMAGE) { // Only 3D view or UV
setSnappingCallback(t);
+ /* Edit mode */
if (t->tsnap.applySnap != NULL && // A snapping function actually exist
+ (G.scene->snap_flag & SCE_SNAP) && // Only if the snap flag is on
(G.obedit != NULL && G.obedit->type==OB_MESH) && // Temporary limited to edit mode meshes
+ ((t->flag & T_PROP_EDIT) == 0) ) // No PET, obviously
+ {
+ t->tsnap.status |= SNAP_ON;
+ t->tsnap.modePoint = SNAP_GEO;
+ }
+ /* Object mode */
+ else if (t->tsnap.applySnap != NULL && // A snapping function actually exist
(G.scene->snap_flag & SCE_SNAP) && // Only if the snap flag is on
- (t->flag & T_PROP_EDIT) == 0) // No PET, obviously
+ (G.obedit == NULL) ) // Object Mode
{
t->tsnap.status |= SNAP_ON;
t->tsnap.modePoint = SNAP_GEO;
@@ -364,7 +391,28 @@ void CalcSnapGrid(TransInfo *t, float *vec)
void CalcSnapGeometry(TransInfo *t, float *vec)
{
- if (G.obedit != NULL && G.obedit->type==OB_MESH)
+ if (G.obedit == NULL)
+ {
+ if (t->spacetype == SPACE_VIEW3D)
+ {
+ float vec[3];
+ int found = 0;
+ int dist = 40; // Use a user defined value here
+
+ found = findNearestVertFromObjects(&dist, vec, 0);
+ if (found == 1)
+ {
+ VECCOPY(t->tsnap.snapPoint, vec);
+
+ t->tsnap.status |= POINT_INIT;
+ }
+ else
+ {
+ t->tsnap.status &= ~POINT_INIT;
+ }
+ }
+ }
+ else if (G.obedit != NULL && G.obedit->type==OB_MESH)
{
/*if (G.scene->selectmode & B_SEL_VERT)*/
@@ -378,7 +426,7 @@ void CalcSnapGeometry(TransInfo *t, float *vec)
// use findnearestverts in vert mode, others in other modes
nearest = findnearestvert(&dist, SELECT, 1);
- found = findNearestVertFromObjects(&dist, vec);
+ found = findNearestVertFromObjects(&dist, vec, SELECT);
if (found == 1)
{
VECCOPY(t->tsnap.snapPoint, vec);
@@ -479,7 +527,7 @@ void TargetSnapMedian(TransInfo *t)
for(td = t->data, i = 0 ; i < t->total && td->flag & TD_SELECTED ; i++, td++)
{
- VecAddf(t->tsnap.snapTarget, t->tsnap.snapTarget, td->iloc);
+ VecAddf(t->tsnap.snapTarget, t->tsnap.snapTarget, td->center);
}
VecMulf(t->tsnap.snapTarget, 1.0 / t->total);
@@ -500,28 +548,42 @@ void TargetSnapClosest(TransInfo *t)
{
TransData *closest = NULL, *td = NULL;
- // Base case, only one selected item
- if (t->total == 1)
+ /* Object mode */
+ if (t->flag & T_OBJECT)
{
- VECCOPY(t->tsnap.snapTarget, t->data[0].iloc);
-
- if(t->flag & (T_EDIT|T_POSE)) {
- Object *ob= G.obedit?G.obedit:t->poseobj;
- Mat4MulVecfl(ob->obmat, t->tsnap.snapTarget);
+ int i;
+ for(td = t->data, i = 0 ; i < t->total && td->flag & TD_SELECTED ; i++, td++)
+ {
+ struct BoundBox *bb = object_get_boundbox(td->ob);
+ int j;
+
+ for (j = 0; j < 8; j++) {
+ float loc[3];
+ float dist;
+
+ VECCOPY(loc, bb->vec[j]);
+ Mat4MulVecfl(td->ext->obmat, loc);
+
+ dist = t->tsnap.distance(t, loc, t->tsnap.snapPoint);
+
+ if (closest == NULL || fabs(dist) < fabs(t->tsnap.dist))
+ {
+ VECCOPY(t->tsnap.snapTarget, loc);
+ closest = td;
+ t->tsnap.dist = dist;
+ }
+ }
}
-
- t->tsnap.dist = t->tsnap.distance(t, t->tsnap.snapTarget, t->tsnap.snapPoint);
}
- // More than one selected item
else
- {
+ {
int i;
for(td = t->data, i = 0 ; i < t->total && td->flag & TD_SELECTED ; i++, td++)
{
float loc[3];
float dist;
- VECCOPY(loc, td->iloc);
+ VECCOPY(loc, td->center);
if(t->flag & (T_EDIT|T_POSE)) {
Object *ob= G.obedit?G.obedit:t->poseobj;
@@ -544,7 +606,7 @@ void TargetSnapClosest(TransInfo *t)
}
/*================================================================*/
-int findNearestVertFromObjects(int *dist, float *loc) {
+int findNearestVertFromObjects(int *dist, float *loc, int selected) {
Base *base;
int retval = 0;
short mval[2];
@@ -553,7 +615,7 @@ int findNearestVertFromObjects(int *dist, float *loc) {
base= FIRSTBASE;
for ( base = FIRSTBASE; base != NULL; base = base->next ) {
- if ( TESTBASE(base) && base != BASACT ) {
+ if ( base != BASACT && BASE_SELECTABLE(base) && (base->flag & SELECT) == selected ) {
Object *ob = base->object;
if (ob->type == OB_MESH) {