diff options
author | Martin Poirier <theeth@yahoo.com> | 2009-12-01 21:26:18 +0300 |
---|---|---|
committer | Martin Poirier <theeth@yahoo.com> | 2009-12-01 21:26:18 +0300 |
commit | 9f251ce3016b5b37e294c35f695e2b6345937764 (patch) | |
tree | 3d5c44d8a22a480b187c1bebc36775e77c8805a7 | |
parent | d7877d360a12d3ad6497a80c4ab4522fe3a2665d (diff) |
Additive snap for Transform. Easy snapping between two vertices, in the middle of three faces, ...
A to add the current snapping point to the list
Alt-A to remove the last one
The resulting snapping point is the average of all snap points in the list (and the one under the mouse pointer, if valid).
Snapping between two verts is a matter of moving over the first, pressing A, moving over the other, confirming transform.
-rw-r--r-- | source/blender/editors/transform/transform.c | 15 | ||||
-rw-r--r-- | source/blender/editors/transform/transform.h | 13 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_generics.c | 2 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_snap.c | 82 |
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); } } |