diff options
author | Germano Cavalcante <germano.costa@ig.com.br> | 2020-06-18 15:08:27 +0300 |
---|---|---|
committer | Germano Cavalcante <germano.costa@ig.com.br> | 2020-06-18 22:05:48 +0300 |
commit | b89898cbd381780394ca19f5204666f68a90d8b8 (patch) | |
tree | ed734ee0cf58f8f3b7361e51852299b55d7e697c /source/blender/editors | |
parent | d56444392f41e5115bb001af9fa50747f6295834 (diff) |
Cleanup: Move snap callbacks to their respective transform mode
These functions are very specific to the mode.
More modes can support snap, and there is no reason to keep all
callbacks for each mode in the transform_snap.c file.
Diffstat (limited to 'source/blender/editors')
4 files changed, 160 insertions, 217 deletions
diff --git a/source/blender/editors/transform/transform_mode_resize.c b/source/blender/editors/transform/transform_mode_resize.c index ebce32a598e..5fb46b30e0d 100644 --- a/source/blender/editors/transform/transform_mode_resize.c +++ b/source/blender/editors/transform/transform_mode_resize.c @@ -44,6 +44,39 @@ /** \name Transform Resize * \{ */ +static float ResizeBetween(TransInfo *t, const float p1[3], const float p2[3]) +{ + float d1[3], d2[3], len_d1; + + sub_v3_v3v3(d1, p1, t->center_global); + sub_v3_v3v3(d2, p2, t->center_global); + + if (t->con.applyRot != NULL && (t->con.mode & CON_APPLY)) { + mul_m3_v3(t->con.pmtx, d1); + mul_m3_v3(t->con.pmtx, d2); + } + + project_v3_v3v3(d1, d1, d2); + + len_d1 = len_v3(d1); + + /* Use 'invalid' dist when `center == p1` (after projecting), + * in this case scale will _never_ move the point in relation to the center, + * so it makes no sense to take it into account when scaling. see: T46503 */ + return len_d1 != 0.0f ? len_v3(d2) / len_d1 : TRANSFORM_DIST_INVALID; +} + +static void ApplySnapResize(TransInfo *t, float vec[3]) +{ + float point[3]; + getSnapPoint(t, point); + + float dist = ResizeBetween(t, t->tsnap.snapTarget, point); + if (dist != TRANSFORM_DIST_INVALID) { + copy_v3_fl(vec, dist); + } +} + static void applyResize(TransInfo *t, const int UNUSED(mval[2])) { float mat[3][3]; @@ -134,6 +167,8 @@ void initResize(TransInfo *t) { t->mode = TFM_RESIZE; t->transform = applyResize; + t->tsnap.applySnap = ApplySnapResize; + t->tsnap.distance = ResizeBetween; initMouseInputMode(t, &t->mouse, INPUT_SPRING_FLIP); diff --git a/source/blender/editors/transform/transform_mode_rotate.c b/source/blender/editors/transform/transform_mode_rotate.c index 6480cb6c30e..4fa5dffc473 100644 --- a/source/blender/editors/transform/transform_mode_rotate.c +++ b/source/blender/editors/transform/transform_mode_rotate.c @@ -42,6 +42,67 @@ /** \name Transform Rotation * \{ */ +static float RotationBetween(TransInfo *t, const float p1[3], const float p2[3]) +{ + float angle, start[3], end[3]; + + sub_v3_v3v3(start, p1, t->center_global); + sub_v3_v3v3(end, p2, t->center_global); + + // Angle around a constraint axis (error prone, will need debug) + if (t->con.applyRot != NULL && (t->con.mode & CON_APPLY)) { + float axis[3], tmp[3]; + + t->con.applyRot(t, NULL, NULL, axis, NULL); + + project_v3_v3v3(tmp, end, axis); + sub_v3_v3v3(end, end, tmp); + + project_v3_v3v3(tmp, start, axis); + sub_v3_v3v3(start, start, tmp); + + normalize_v3(end); + normalize_v3(start); + + cross_v3_v3v3(tmp, start, end); + + if (dot_v3v3(tmp, axis) < 0.0f) { + angle = -acosf(dot_v3v3(start, end)); + } + else { + angle = acosf(dot_v3v3(start, end)); + } + } + else { + float mtx[3][3]; + + copy_m3_m4(mtx, t->viewmat); + + mul_m3_v3(mtx, end); + mul_m3_v3(mtx, start); + + angle = atan2f(start[1], start[0]) - atan2f(end[1], end[0]); + } + + if (angle > (float)M_PI) { + angle = angle - 2 * (float)M_PI; + } + else if (angle < -((float)M_PI)) { + angle = 2.0f * (float)M_PI + angle; + } + + return angle; +} + +static void ApplySnapRotation(TransInfo *t, float *value) +{ + float point[3]; + getSnapPoint(t, point); + + float dist = RotationBetween(t, t->tsnap.snapTarget, point); + *value = dist; +} + static float large_rotation_limit(float angle) { /* Limit rotation to 1001 turns max @@ -173,6 +234,8 @@ void initRotation(TransInfo *t) { t->mode = TFM_ROTATION; t->transform = applyRotation; + t->tsnap.applySnap = ApplySnapRotation; + t->tsnap.distance = RotationBetween; setInputPostFct(&t->mouse, postInputRotation); initMouseInputMode(t, &t->mouse, INPUT_ANGLE); diff --git a/source/blender/editors/transform/transform_mode_translate.c b/source/blender/editors/transform/transform_mode_translate.c index 60caa257a40..84cfeea96b0 100644 --- a/source/blender/editors/transform/transform_mode_translate.c +++ b/source/blender/editors/transform/transform_mode_translate.c @@ -34,6 +34,7 @@ #include "BKE_report.h" #include "BKE_unit.h" +#include "ED_node.h" #include "ED_screen.h" #include "WM_api.h" @@ -214,6 +215,39 @@ static void headerTranslation(TransInfo *t, const float vec[3], char str[UI_MAX_ } } +static float TranslationBetween(TransInfo *UNUSED(t), const float p1[3], const float p2[3]) +{ + return len_squared_v3v3(p1, p2); +} + +static void ApplySnapTranslation(TransInfo *t, float vec[3]) +{ + float point[3]; + getSnapPoint(t, point); + + if (t->spacetype == SPACE_NODE) { + char border = t->tsnap.snapNodeBorder; + if (border & (NODE_LEFT | NODE_RIGHT)) { + vec[0] = point[0] - t->tsnap.snapTarget[0]; + } + if (border & (NODE_BOTTOM | NODE_TOP)) { + vec[1] = point[1] - t->tsnap.snapTarget[1]; + } + } + else { + if (t->spacetype == SPACE_VIEW3D) { + if (t->options & CTX_PAINT_CURVE) { + if (ED_view3d_project_float_global(t->region, point, point, V3D_PROJ_TEST_NOP) != + V3D_PROJ_RET_OK) { + zero_v3(point); /* no good answer here... */ + } + } + } + + sub_v3_v3v3(vec, point, t->tsnap.snapTarget); + } +} + static void applyTranslationValue(TransInfo *t, const float vec[3]) { const bool apply_snap_align_rotation = usingSnappingNormal( @@ -376,6 +410,8 @@ void initTranslation(TransInfo *t) } t->transform = applyTranslation; + t->tsnap.applySnap = ApplySnapTranslation; + t->tsnap.distance = TranslationBetween; initMouseInputMode(t, &t->mouse, INPUT_VECTOR); diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index b508507cd4e..2a34cb4860b 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -21,24 +21,15 @@ * \ingroup edtransform */ +/* clang-format off */ #include <float.h> -#include <math.h> -#include <stdio.h> -#include <stdlib.h> #include "PIL_time.h" -#include "DNA_node_types.h" -#include "DNA_object_types.h" -#include "DNA_scene_types.h" -#include "DNA_screen_types.h" -#include "DNA_space_types.h" -#include "DNA_view3d_types.h" #include "DNA_windowmanager_types.h" #include "BLI_blenlib.h" #include "BLI_math.h" -#include "BLI_utildefines.h" #include "GPU_immediate.h" #include "GPU_state.h" @@ -58,7 +49,6 @@ #include "ED_node.h" #include "ED_transform_snap_object_context.h" #include "ED_uvedit.h" -#include "ED_view3d.h" #include "UI_resources.h" #include "UI_view2d.h" @@ -80,10 +70,6 @@ static void setSnappingCallback(TransInfo *t); -static void ApplySnapTranslation(TransInfo *t, float vec[3]); -static void ApplySnapRotation(TransInfo *t, float *vec); -static void ApplySnapResize(TransInfo *t, float vec[2]); - /* static void CalcSnapGrid(TransInfo *t, float *vec); */ static void CalcSnapGeometry(TransInfo *t, float *vec); @@ -92,10 +78,6 @@ static void TargetSnapCenter(TransInfo *t); static void TargetSnapClosest(TransInfo *t); static void TargetSnapActive(TransInfo *t); -static float RotationBetween(TransInfo *t, const float p1[3], const float p2[3]); -static float TranslationBetween(TransInfo *t, const float p1[3], const float p2[3]); -static float ResizeBetween(TransInfo *t, const float p1[3], const float p2[3]); - /** \} */ /* -------------------------------------------------------------------- */ @@ -476,7 +458,6 @@ void resetSnapping(TransInfo *t) t->tsnap.modeSelect = 0; t->tsnap.target = 0; t->tsnap.last = 0; - t->tsnap.applySnap = NULL; t->tsnap.snapNormal[0] = 0; t->tsnap.snapNormal[1] = 0; @@ -557,35 +538,32 @@ static void initSnappingMode(TransInfo *t) t->tsnap.mode = ts->snap_mode; } - if ((t->spacetype == SPACE_VIEW3D || t->spacetype == SPACE_IMAGE) && /* Only 3D view or UV */ - (t->flag & T_CAMERA) == 0) /* Not with camera selected in camera view */ - { + if ((t->spacetype == SPACE_VIEW3D || t->spacetype == SPACE_IMAGE) && (t->flag & T_CAMERA) == 0) { + /* Only 3D view or UV. */ + /* Not with camera selected in camera view. */ + setSnappingCallback(t); - /* Edit mode */ - if (t->tsnap.applySnap != NULL && // A snapping function actually exist - ((obedit_type != -1) && - /* Temporary limited to edit mode meshes, armature, curves, metaballs. */ - ELEM(obedit_type, OB_MESH, OB_ARMATURE, OB_CURVE, OB_LATTICE, OB_MBALL))) { - /* Exclude editmesh if using proportional edit */ + if ((obedit_type != -1) && + ELEM(obedit_type, OB_MESH, OB_ARMATURE, OB_CURVE, OB_LATTICE, OB_MBALL)) { + /* Edit mode */ + /* Temporary limited to edit mode meshes, armature, curves, metaballs. */ + if ((obedit_type == OB_MESH) && (t->flag & T_PROP_EDIT)) { + /* Exclude editmesh if using proportional edit */ t->tsnap.modeSelect = SNAP_NOT_ACTIVE; } else { t->tsnap.modeSelect = t->tsnap.snap_self ? SNAP_ALL : SNAP_NOT_ACTIVE; } } - /* Particles edit mode*/ - else if (t->tsnap.applySnap != NULL && // A snapping function actually exist - ((obedit_type == -1) && base_act && base_act->object && - base_act->object->mode & OB_MODE_PARTICLE_EDIT)) { + else if ((obedit_type == -1) && base_act && base_act->object && + (base_act->object->mode & OB_MODE_PARTICLE_EDIT)) { + /* Particles edit mode. */ t->tsnap.modeSelect = SNAP_ALL; } - /* Object mode */ - else if (t->tsnap.applySnap != NULL && // A snapping function actually exist - (obedit_type == -1)) // Object Mode - { - + else if (obedit_type == -1) { + /* Object mode */ if (t->options & (CTX_GPENCIL_STROKES | CTX_CURSOR | CTX_OBMODE_XFORM_OBDATA)) { /* In "Edit Strokes" mode, * snap tool can perform snap to selected or active objects (see T49632) @@ -605,14 +583,7 @@ static void initSnappingMode(TransInfo *t) } else if (t->spacetype == SPACE_NODE) { setSnappingCallback(t); - - if (t->tsnap.applySnap != NULL) { - t->tsnap.modeSelect = SNAP_NOT_SELECTED; - } - else { - /* Grid if snap is not possible */ - t->tsnap.mode = SCE_SNAP_MODE_INCREMENT; - } + t->tsnap.modeSelect = SNAP_NOT_SELECTED; } else if (t->spacetype == SPACE_SEQ) { /* We do our own snapping currently, so nothing here */ @@ -720,8 +691,15 @@ static void setSnappingCallback(TransInfo *t) t->tsnap.targetSnap = TargetSnapClosest; break; case SCE_SNAP_TARGET_CENTER: - t->tsnap.targetSnap = TargetSnapCenter; - break; + if (ELEM(t->mode, TFM_ROTATION, TFM_RESIZE)) { + /* Can't do TARGET_CENTER with these modes, + * use TARGET_MEDIAN instead. */ + ATTR_FALLTHROUGH; + } + else { + t->tsnap.targetSnap = TargetSnapCenter; + break; + } case SCE_SNAP_TARGET_MEDIAN: t->tsnap.targetSnap = TargetSnapMedian; break; @@ -729,36 +707,6 @@ static void setSnappingCallback(TransInfo *t) t->tsnap.targetSnap = TargetSnapActive; break; } - - switch (t->mode) { - case TFM_TRANSLATION: - t->tsnap.applySnap = ApplySnapTranslation; - t->tsnap.distance = TranslationBetween; - break; - case TFM_ROTATION: - t->tsnap.applySnap = ApplySnapRotation; - t->tsnap.distance = RotationBetween; - - // Can't do TARGET_CENTER with rotation, use TARGET_MEDIAN instead - if (t->tsnap.target == SCE_SNAP_TARGET_CENTER) { - t->tsnap.target = SCE_SNAP_TARGET_MEDIAN; - t->tsnap.targetSnap = TargetSnapMedian; - } - break; - case TFM_RESIZE: - t->tsnap.applySnap = ApplySnapResize; - t->tsnap.distance = ResizeBetween; - - // Can't do TARGET_CENTER with resize, use TARGET_MEDIAN instead - if (t->tsnap.target == SCE_SNAP_TARGET_CENTER) { - t->tsnap.target = SCE_SNAP_TARGET_MEDIAN; - t->tsnap.targetSnap = TargetSnapMedian; - } - break; - default: - t->tsnap.applySnap = NULL; - break; - } } void addSnapPoint(TransInfo *t) @@ -859,145 +807,6 @@ void getSnapPoint(const TransInfo *t, float vec[3]) /** \} */ /* -------------------------------------------------------------------- */ -/** \name Apply Snap - * \{ */ - -static void ApplySnapTranslation(TransInfo *t, float vec[3]) -{ - float point[3]; - getSnapPoint(t, point); - - if (t->spacetype == SPACE_NODE) { - char border = t->tsnap.snapNodeBorder; - if (border & (NODE_LEFT | NODE_RIGHT)) { - vec[0] = point[0] - t->tsnap.snapTarget[0]; - } - if (border & (NODE_BOTTOM | NODE_TOP)) { - vec[1] = point[1] - t->tsnap.snapTarget[1]; - } - } - else { - if (t->spacetype == SPACE_VIEW3D) { - if (t->options & CTX_PAINT_CURVE) { - if (ED_view3d_project_float_global(t->region, point, point, V3D_PROJ_TEST_NOP) != - V3D_PROJ_RET_OK) { - zero_v3(point); /* no good answer here... */ - } - } - } - - sub_v3_v3v3(vec, point, t->tsnap.snapTarget); - } -} - -static void ApplySnapRotation(TransInfo *t, float *value) -{ - float point[3]; - getSnapPoint(t, point); - - float dist = RotationBetween(t, t->tsnap.snapTarget, point); - *value = dist; -} - -static void ApplySnapResize(TransInfo *t, float vec[3]) -{ - float point[3]; - getSnapPoint(t, point); - - float dist = ResizeBetween(t, t->tsnap.snapTarget, point); - if (dist != TRANSFORM_DIST_INVALID) { - copy_v3_fl(vec, dist); - } -} - -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name Distance - * \{ */ - -static float TranslationBetween(TransInfo *UNUSED(t), const float p1[3], const float p2[3]) -{ - return len_squared_v3v3(p1, p2); -} - -static float RotationBetween(TransInfo *t, const float p1[3], const float p2[3]) -{ - float angle, start[3], end[3]; - - sub_v3_v3v3(start, p1, t->center_global); - sub_v3_v3v3(end, p2, t->center_global); - - // Angle around a constraint axis (error prone, will need debug) - if (t->con.applyRot != NULL && (t->con.mode & CON_APPLY)) { - float axis[3], tmp[3]; - - t->con.applyRot(t, NULL, NULL, axis, NULL); - - project_v3_v3v3(tmp, end, axis); - sub_v3_v3v3(end, end, tmp); - - project_v3_v3v3(tmp, start, axis); - sub_v3_v3v3(start, start, tmp); - - normalize_v3(end); - normalize_v3(start); - - cross_v3_v3v3(tmp, start, end); - - if (dot_v3v3(tmp, axis) < 0.0f) { - angle = -acosf(dot_v3v3(start, end)); - } - else { - angle = acosf(dot_v3v3(start, end)); - } - } - else { - float mtx[3][3]; - - copy_m3_m4(mtx, t->viewmat); - - mul_m3_v3(mtx, end); - mul_m3_v3(mtx, start); - - angle = atan2f(start[1], start[0]) - atan2f(end[1], end[0]); - } - - if (angle > (float)M_PI) { - angle = angle - 2 * (float)M_PI; - } - else if (angle < -((float)M_PI)) { - angle = 2.0f * (float)M_PI + angle; - } - - return angle; -} - -static float ResizeBetween(TransInfo *t, const float p1[3], const float p2[3]) -{ - float d1[3], d2[3], len_d1; - - sub_v3_v3v3(d1, p1, t->center_global); - sub_v3_v3v3(d2, p2, t->center_global); - - if (t->con.applyRot != NULL && (t->con.mode & CON_APPLY)) { - mul_m3_v3(t->con.pmtx, d1); - mul_m3_v3(t->con.pmtx, d2); - } - - project_v3_v3v3(d1, d1, d2); - - len_d1 = len_v3(d1); - - /* Use 'invalid' dist when `center == p1` (after projecting), - * in this case scale will _never_ move the point in relation to the center, - * so it makes no sense to take it into account when scaling. see: T46503 */ - return len_d1 != 0.0f ? len_v3(d2) / len_d1 : TRANSFORM_DIST_INVALID; -} - -/** \} */ - -/* -------------------------------------------------------------------- */ /** \name Calc Snap (Generic) * \{ */ |