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:
-rw-r--r--source/blender/include/transform.h22
-rw-r--r--source/blender/makesdna/DNA_scene_types.h1
-rw-r--r--source/blender/src/header_view3d.c20
-rw-r--r--source/blender/src/transform_conversions.c24
-rw-r--r--source/blender/src/transform_snap.c61
5 files changed, 107 insertions, 21 deletions
diff --git a/source/blender/include/transform.h b/source/blender/include/transform.h
index e9e82612721..30b9bbf3f51 100644
--- a/source/blender/include/transform.h
+++ b/source/blender/include/transform.h
@@ -265,18 +265,19 @@ typedef struct TransInfo {
/* transdata->flag */
#define TD_SELECTED 1
-#define TD_NOACTION 2
-#define TD_USEQUAT 4
-#define TD_NOTCONNECTED 8
-#define TD_SINGLESIZE 16 /* used for scaling of MetaElem->rad */
+#define TD_ACTIVE (1 << 1)
+#define TD_NOACTION (1 << 2)
+#define TD_USEQUAT (1 << 3)
+#define TD_NOTCONNECTED (1 << 4)
+#define TD_SINGLESIZE (1 << 5) /* used for scaling of MetaElem->rad */
#ifdef WITH_VERSE
- #define TD_VERSE_OBJECT 32
- #define TD_VERSE_VERT 64
+ #define TD_VERSE_OBJECT (1 << 6)
+ #define TD_VERSE_VERT (1 << 7)
#endif
-#define TD_TIMEONLY 128
-#define TD_NOCENTER 256
-#define TD_NO_EXT 512 /* ext abused for particle key timing */
-#define TD_SKIP 1024 /* don't transform this data */
+#define TD_TIMEONLY (1 << 8)
+#define TD_NOCENTER (1 << 9)
+#define TD_NO_EXT (1 << 10) /* ext abused for particle key timing */
+#define TD_SKIP (1 << 11) /* don't transform this data */
/* transsnap->status */
#define SNAP_ON 1
@@ -291,6 +292,7 @@ typedef struct TransInfo {
#define SNAP_CLOSEST 0
#define SNAP_CENTER 1
#define SNAP_MEDIAN 2
+#define SNAP_ACTIVE 3
void checkFirstTime(void);
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index 200e904bc88..b342bc5afe8 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -663,6 +663,7 @@ typedef struct Scene {
#define SCE_SNAP_TARGET_CLOSEST 0
#define SCE_SNAP_TARGET_CENTER 1
#define SCE_SNAP_TARGET_MEDIAN 2
+#define SCE_SNAP_TARGET_ACTIVE 3
/* sce->selectmode */
#define SCE_SELECT_VERTEX 1 /* for mesh */
diff --git a/source/blender/src/header_view3d.c b/source/blender/src/header_view3d.c
index b476bb6c944..1c39d286989 100644
--- a/source/blender/src/header_view3d.c
+++ b/source/blender/src/header_view3d.c
@@ -1768,6 +1768,9 @@ static void do_view3d_transformmenu(void *arg, int event)
case 19:
G.scene->snap_target = SCE_SNAP_TARGET_MEDIAN;
break;
+ case 20:
+ G.scene->snap_target = SCE_SNAP_TARGET_ACTIVE;
+ break;
}
allqueue(REDRAWVIEW3D, 0);
}
@@ -1839,19 +1842,28 @@ static uiBlock *view3d_transformmenu(void *arg_unused)
switch(G.scene->snap_target)
{
case SCE_SNAP_TARGET_CLOSEST:
- 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_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, 18, "");
uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Snap Median", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 19, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Snap Active", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 20, "");
break;
case SCE_SNAP_TARGET_CENTER:
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, 18, "");
+ 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, 19, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Snap Active", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 20, "");
break;
case SCE_SNAP_TARGET_MEDIAN:
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, 18, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Snap Median", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 19, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Snap Median", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 19, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Snap Active", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 20, "");
+ break;
+ case SCE_SNAP_TARGET_ACTIVE:
+ 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, 18, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Snap Median", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 19, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Snap Active", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 20, "");
break;
}
}
@@ -5484,7 +5496,7 @@ void view3d_buttons(void)
if (G.scene->snap_flag & SCE_SNAP) {
uiDefIconButBitS(block, TOG, SCE_SNAP, B_REDR, ICON_SNAP_GEO,xco,0,XIC,YIC, &G.scene->snap_flag, 0, 0, 0, 0, "Use Snap or Grid (Shift Tab)");
xco+= XIC;
- uiDefButS(block, MENU, B_NOP, "Mode%t|Closest%x0|Center%x1|Median%x2",xco,0,70,YIC, &G.scene->snap_target, 0, 0, 0, 0, "Snap Target Mode");
+ uiDefButS(block, MENU, B_NOP, "Mode%t|Closest%x0|Center%x1|Median%x2|Active%x3",xco,0,70,YIC, &G.scene->snap_target, 0, 0, 0, 0, "Snap Target Mode");
xco+= 70;
} else {
uiDefIconButBitS(block, TOG, SCE_SNAP, B_REDR, ICON_SNAP_GEAR,xco,0,XIC,YIC, &G.scene->snap_flag, 0, 0, 0, 0, "Snap while Ctrl is held during transform (Shift Tab)");
diff --git a/source/blender/src/transform_conversions.c b/source/blender/src/transform_conversions.c
index 3f69316e373..de3e9988f8d 100644
--- a/source/blender/src/transform_conversions.c
+++ b/source/blender/src/transform_conversions.c
@@ -1952,6 +1952,7 @@ static void createTransEditVerts(TransInfo *t)
EditMesh *em = G.editMesh;
EditVert *eve;
EditVert **nears = NULL;
+ EditVert *eve_act = NULL;
float *vectors = NULL, *mappedcos = NULL, *quats= NULL;
float mtx[3][3], smtx[3][3], (*defmats)[3][3] = NULL, (*defcos)[3] = NULL;
int count=0, countsel=0, a, totleft;
@@ -2002,6 +2003,15 @@ static void createTransEditVerts(TransInfo *t)
/* note: in prop mode we need at least 1 selected */
if (countsel==0) return;
+ /* check active */
+ if (G.editMesh->selected.last) {
+ EditSelection *ese = G.editMesh->selected.last;
+ if ( ese->type == EDITVERT ) {
+ eve_act = (EditVert *)ese->data;
+ }
+ }
+
+
if(propmode) {
t->total = count;
@@ -2057,8 +2067,13 @@ static void createTransEditVerts(TransInfo *t)
if(eve->h==0) {
if(propmode || eve->f1) {
VertsToTransData(tob, eve);
-
+
+ /* selected */
if(eve->f1) tob->flag |= TD_SELECTED;
+
+ /* active */
+ if(eve == eve_act) tob->flag |= TD_ACTIVE;
+
if(propmode) {
if (eve->f2) {
float vec[3];
@@ -2883,6 +2898,13 @@ static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob)
Mat3One(td->smtx);
Mat3One(td->mtx);
}
+
+ /* set active flag */
+ if (BASACT && BASACT->object == ob)
+ {
+ td->flag |= TD_ACTIVE;
+ }
+
#ifdef WITH_VERSE
if(ob->vnode) {
td->verse = (void*)ob;
diff --git a/source/blender/src/transform_snap.c b/source/blender/src/transform_snap.c
index 3279e6e6f09..c0f634a3f67 100644
--- a/source/blender/src/transform_snap.c
+++ b/source/blender/src/transform_snap.c
@@ -85,12 +85,15 @@ void CalcSnapGeometry(TransInfo *t, float *vec);
void TargetSnapMedian(TransInfo *t);
void TargetSnapCenter(TransInfo *t);
void TargetSnapClosest(TransInfo *t);
+void TargetSnapActive(TransInfo *t);
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 selected);
+/* Modes */
+#define NOT_SELECTED 0
+#define NOT_ACTIVE 1
+int findNearestVertFromObjects(int *dist, float *loc, int mode);
/****************** IMPLEMENTATIONS *********************/
@@ -277,6 +280,11 @@ void setSnappingCallback(TransInfo *t)
t->tsnap.modeTarget = SNAP_MEDIAN;
t->tsnap.targetSnap = TargetSnapMedian;
break;
+ case SCE_SNAP_TARGET_ACTIVE:
+ t->tsnap.modeTarget = SNAP_ACTIVE;
+ t->tsnap.targetSnap = TargetSnapActive;
+ break;
+
}
switch (t->mode)
@@ -391,6 +399,7 @@ void CalcSnapGrid(TransInfo *t, float *vec)
void CalcSnapGeometry(TransInfo *t, float *vec)
{
+ /* Object mode */
if (G.obedit == NULL)
{
if (t->spacetype == SPACE_VIEW3D)
@@ -399,7 +408,7 @@ void CalcSnapGeometry(TransInfo *t, float *vec)
int found = 0;
int dist = 40; // Use a user defined value here
- found = findNearestVertFromObjects(&dist, vec, 0);
+ found = findNearestVertFromObjects(&dist, vec, NOT_SELECTED);
if (found == 1)
{
VECCOPY(t->tsnap.snapPoint, vec);
@@ -412,6 +421,7 @@ void CalcSnapGeometry(TransInfo *t, float *vec)
}
}
}
+ /* Mesh edit mode */
else if (G.obedit != NULL && G.obedit->type==OB_MESH)
{
/*if (G.scene->selectmode & B_SEL_VERT)*/
@@ -426,7 +436,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, SELECT);
+ found = findNearestVertFromObjects(&dist, vec, NOT_ACTIVE);
if (found == 1)
{
VECCOPY(t->tsnap.snapPoint, vec);
@@ -513,6 +523,45 @@ void TargetSnapCenter(TransInfo *t)
}
}
+void TargetSnapActive(TransInfo *t)
+{
+ // Only need to calculate once
+ if ((t->tsnap.status & TARGET_INIT) == 0)
+ {
+ TransData *td = NULL;
+ TransData *active_td = NULL;
+ int i;
+
+ for(td = t->data, i = 0 ; i < t->total && td->flag & TD_SELECTED ; i++, td++)
+ {
+ if (td->flag & TD_ACTIVE)
+ {
+ active_td = td;
+ break;
+ }
+ }
+
+ if (active_td)
+ {
+ VECCOPY(t->tsnap.snapTarget, active_td->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;
+ }
+ /* No active, default to median */
+ else
+ {
+ t->tsnap.modeTarget = SNAP_MEDIAN;
+ t->tsnap.targetSnap = TargetSnapMedian;
+ TargetSnapMedian(t);
+ }
+ }
+}
+
void TargetSnapMedian(TransInfo *t)
{
// Only need to calculate once
@@ -628,7 +677,7 @@ void TargetSnapClosest(TransInfo *t)
}
/*================================================================*/
-int findNearestVertFromObjects(int *dist, float *loc, int selected) {
+int findNearestVertFromObjects(int *dist, float *loc, int mode) {
Base *base;
int retval = 0;
short mval[2];
@@ -637,7 +686,7 @@ int findNearestVertFromObjects(int *dist, float *loc, int selected) {
base= FIRSTBASE;
for ( base = FIRSTBASE; base != NULL; base = base->next ) {
- if ( base != BASACT && BASE_SELECTABLE(base) && (base->flag & SELECT) == selected ) {
+ if ( BASE_SELECTABLE(base) && ((mode == NOT_SELECTED && (base->flag & SELECT) == 0) || (mode == NOT_ACTIVE && base != BASACT)) ) {
Object *ob = base->object;
if (ob->type == OB_MESH) {