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/editors/transform/transform.c15
-rw-r--r--source/blender/editors/transform/transform.h13
-rw-r--r--source/blender/editors/transform/transform_generics.c2
-rw-r--r--source/blender/editors/transform/transform_snap.c82
4 files changed, 102 insertions, 10 deletions
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index 2e1922d8a07..cbcb3953f49 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -517,6 +517,8 @@ static char *transform_to_undostr(TransInfo *t)
#define TFM_MODAL_PLANE_Y 13
#define TFM_MODAL_PLANE_Z 14
#define TFM_MODAL_CONS_OFF 15
+#define TFM_MODAL_ADD_SNAP 16
+#define TFM_MODAL_REMOVE_SNAP 17
/* called in transform_ops.c, on each regeneration of keymaps */
void transform_modal_keymap(wmKeyConfig *keyconf)
@@ -537,6 +539,8 @@ void transform_modal_keymap(wmKeyConfig *keyconf)
{TFM_MODAL_PLANE_Y, "PLANE_Y", 0, "Orientation Y plane", ""},
{TFM_MODAL_PLANE_Z, "PLANE_Z", 0, "Orientation Z plane", ""},
{TFM_MODAL_CONS_OFF, "CONS_OFF", 0, "Remove Constraints", ""},
+ {TFM_MODAL_ADD_SNAP, "ADD_SNAP", 0, "Add Snap Point", ""},
+ {TFM_MODAL_REMOVE_SNAP, "REMOVE_SNAP", 0, "Remove Last Snap Point", ""},
{0, NULL, 0, NULL, NULL}};
wmKeyMap *keymap= WM_modalkeymap_get(keyconf, "Transform Modal Map");
@@ -558,6 +562,9 @@ void transform_modal_keymap(wmKeyConfig *keyconf)
WM_modalkeymap_add_item(keymap, LEFTCTRLKEY, KM_CLICK, KM_ANY, 0, TFM_MODAL_SNAP_TOGGLE);
+ WM_modalkeymap_add_item(keymap, AKEY, KM_PRESS, 0, 0, TFM_MODAL_ADD_SNAP);
+ WM_modalkeymap_add_item(keymap, AKEY, KM_PRESS, KM_ALT, 0, TFM_MODAL_REMOVE_SNAP);
+
/* assign map to operators */
WM_modalkeymap_assign(keymap, "TFM_OT_transform");
WM_modalkeymap_assign(keymap, "TFM_OT_translate");
@@ -743,6 +750,14 @@ int transformEvent(TransInfo *t, wmEvent *event)
t->redraw = 1;
}
break;
+ case TFM_MODAL_ADD_SNAP:
+ addSnapPoint(t);
+ t->redraw = 1;
+ break;
+ case TFM_MODAL_REMOVE_SNAP:
+ removeSnapPoint(t);
+ t->redraw = 1;
+ break;
default:
handled = 0;
break;
diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h
index 4b7d24dc1fa..1577c05cc88 100644
--- a/source/blender/editors/transform/transform.h
+++ b/source/blender/editors/transform/transform.h
@@ -32,6 +32,8 @@
#include "ED_transform.h"
+#include "DNA_listBase.h"
+
#include "BLI_editVert.h"
/* ************************** Types ***************************** */
@@ -82,6 +84,11 @@ typedef struct NumInput {
Negative : number is negative
*/
+typedef struct TransSnapPoint {
+ struct TransSnapPoint *next,*prev;
+ float co[3];
+} TransSnapPoint;
+
typedef struct TransSnap {
short mode;
short modePoint;
@@ -95,6 +102,7 @@ typedef struct TransSnap {
float snapTarget[3]; /* to this point */
float snapNormal[3];
float snapTangent[3];
+ ListBase points;
float dist; // Distance from snapPoint to snapTarget
double last;
void (*applySnap)(struct TransInfo *, float *);
@@ -417,6 +425,7 @@ typedef struct TransInfo {
#define SNAP_FORCED 1
#define TARGET_INIT 2
#define POINT_INIT 4
+#define MULTI_POINTS 8
/* transsnap->modeTarget */
#define SNAP_CLOSEST 0
@@ -597,6 +606,10 @@ void drawSnapping(const struct bContext *C, TransInfo *t);
int usingSnappingNormal(TransInfo *t);
int validSnappingNormal(TransInfo *t);
+void getSnapPoint(TransInfo *t, float vec[3]);
+void addSnapPoint(TransInfo *t);
+void removeSnapPoint(TransInfo *t);
+
/********************** Mouse Input ******************************/
typedef enum {
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index 8b7c4b7503b..71a5affb573 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -1095,6 +1095,8 @@ void postTrans (TransInfo *t)
MEM_freeN(t->data);
}
+ BLI_freelistN(&t->tsnap.points);
+
if (t->ext) MEM_freeN(t->ext);
if (t->data2d) {
MEM_freeN(t->data2d);
diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c
index d36b7c9b903..7f1e67b62ac 100644
--- a/source/blender/editors/transform/transform_snap.c
+++ b/source/blender/editors/transform/transform_snap.c
@@ -123,9 +123,14 @@ int BIF_snappingSupported(Object *obedit)
return status;
}
+int validSnap(TransInfo *t) {
+ return (t->tsnap.status & (POINT_INIT|TARGET_INIT)) == (POINT_INIT|TARGET_INIT) ||
+ (t->tsnap.status & (MULTI_POINTS|TARGET_INIT)) == (MULTI_POINTS|TARGET_INIT);
+}
+
void drawSnapping(const struct bContext *C, TransInfo *t)
{
- if ((t->tsnap.status & (POINT_INIT|TARGET_INIT)) == (POINT_INIT|TARGET_INIT) &&
+ if (validSnap(t) &&
(t->modifiers & MOD_SNAP))
{
@@ -134,6 +139,7 @@ void drawSnapping(const struct bContext *C, TransInfo *t)
glColor4ub(col[0], col[1], col[2], 128);
if (t->spacetype == SPACE_VIEW3D) {
+ TransSnapPoint *p;
View3D *v3d = CTX_wm_view3d(C);
RegionView3D *rv3d = CTX_wm_region_view3d(C);
float tmat[4][4], imat[4][4];
@@ -141,14 +147,18 @@ void drawSnapping(const struct bContext *C, TransInfo *t)
glDisable(GL_DEPTH_TEST);
- size = get_drawsize(t->ar, t->tsnap.snapPoint);
-
- size *= 0.5f * UI_GetThemeValuef(TH_VERTEX_SIZE);
+ size = 0.5f * UI_GetThemeValuef(TH_VERTEX_SIZE);
copy_m4_m4(tmat, rv3d->viewmat);
invert_m4_m4(imat, tmat);
- drawcircball(GL_LINE_LOOP, t->tsnap.snapPoint, size, imat);
+ for (p = t->tsnap.points.first; p; p = p->next) {
+ drawcircball(GL_LINE_LOOP, p->co, size * get_drawsize(t->ar, p->co), imat);
+ }
+
+ if (t->tsnap.status & POINT_INIT) {
+ drawcircball(GL_LINE_LOOP, t->tsnap.snapPoint, size * get_drawsize(t->ar, t->tsnap.snapPoint), imat);
+ }
/* draw normal if needed */
if (usingSnappingNormal(t) && validSnappingNormal(t))
@@ -302,7 +312,7 @@ void applySnapping(TransInfo *t, float *vec)
t->tsnap.last = current;
}
- if ((t->tsnap.status & (POINT_INIT|TARGET_INIT)) == (POINT_INIT|TARGET_INIT))
+ if (validSnap(t))
{
t->tsnap.applySnap(t, vec);
}
@@ -331,7 +341,7 @@ int usingSnappingNormal(TransInfo *t)
int validSnappingNormal(TransInfo *t)
{
- if ((t->tsnap.status & (POINT_INIT|TARGET_INIT)) == (POINT_INIT|TARGET_INIT))
+ if (validSnap(t))
{
if (dot_v3v3(t->tsnap.snapNormal, t->tsnap.snapNormal) > 0)
{
@@ -502,11 +512,59 @@ void setSnappingCallback(TransInfo *t, short snap_target)
}
}
+void addSnapPoint(TransInfo *t)
+{
+ if (t->tsnap.status & POINT_INIT) {
+ TransSnapPoint *p = MEM_callocN(sizeof(TransSnapPoint), "SnapPoint");
+
+ VECCOPY(p->co, t->tsnap.snapPoint);
+
+ BLI_addtail(&t->tsnap.points, p);
+
+ t->tsnap.status |= MULTI_POINTS;
+ }
+}
+
+void removeSnapPoint(TransInfo *t)
+{
+ if (t->tsnap.status & MULTI_POINTS) {
+ BLI_freelinkN(&t->tsnap.points, t->tsnap.points.last);
+
+ if (t->tsnap.points.first == NULL)
+ t->tsnap.status &= ~MULTI_POINTS;
+ }
+}
+
+void getSnapPoint(TransInfo *t, float vec[3])
+{
+ if (t->tsnap.points.first) {
+ TransSnapPoint *p;
+ int total = 0;
+
+ vec[0] = vec[1] = vec[2] = 0;
+
+ for (p = t->tsnap.points.first; p; p = p->next, total++) {
+ add_v3_v3(vec, p->co);
+ }
+
+ if (t->tsnap.status & POINT_INIT) {
+ add_v3_v3(vec, t->tsnap.snapPoint);
+ total++;
+ }
+
+ mul_v3_fl(vec, 1.0f / total);
+ } else {
+ VECCOPY(vec, t->tsnap.snapPoint)
+ }
+}
+
/********************** APPLY **************************/
void ApplySnapTranslation(TransInfo *t, float vec[3])
{
- sub_v3_v3v3(vec, t->tsnap.snapPoint, t->tsnap.snapTarget);
+ float point[3];
+ getSnapPoint(t, point);
+ sub_v3_v3v3(vec, point, t->tsnap.snapTarget);
}
void ApplySnapRotation(TransInfo *t, float *vec)
@@ -515,7 +573,9 @@ void ApplySnapRotation(TransInfo *t, float *vec)
*vec = t->tsnap.dist;
}
else {
- *vec = RotationBetween(t, t->tsnap.snapTarget, t->tsnap.snapPoint);
+ float point[3];
+ getSnapPoint(t, point);
+ *vec = RotationBetween(t, t->tsnap.snapTarget, point);
}
}
@@ -525,7 +585,9 @@ void ApplySnapResize(TransInfo *t, float vec[3])
vec[0] = vec[1] = vec[2] = t->tsnap.dist;
}
else {
- vec[0] = vec[1] = vec[2] = ResizeBetween(t, t->tsnap.snapTarget, t->tsnap.snapPoint);
+ float point[3];
+ getSnapPoint(t, point);
+ vec[0] = vec[1] = vec[2] = ResizeBetween(t, t->tsnap.snapTarget, point);
}
}