From 9335daac2a368ad137156f6e656f3654b4db07b9 Mon Sep 17 00:00:00 2001 From: Germano Cavalcante Date: Mon, 22 Jun 2020 15:28:25 -0300 Subject: Trasnform: Support for other snapping types on Edge Slide This completes T66426. Since Vert Slide supports these other snapping types (since rBe2fc9a88bc), it would be easy to miss this on Edge Slide. So add support for Edge Slide too. --- .../editors/transform/transform_mode_edge_slide.c | 84 ++++++++++++++++++++-- source/blender/editors/transform/transform_snap.c | 3 + 2 files changed, 81 insertions(+), 6 deletions(-) (limited to 'source/blender/editors/transform') diff --git a/source/blender/editors/transform/transform_mode_edge_slide.c b/source/blender/editors/transform/transform_mode_edge_slide.c index 1972e1501b5..9a82296bfc0 100644 --- a/source/blender/editors/transform/transform_mode_edge_slide.c +++ b/source/blender/editors/transform/transform_mode_edge_slide.c @@ -96,24 +96,28 @@ typedef struct EdgeSlideParams { } EdgeSlideParams; /** - * Get the first valid EdgeSlideData. + * Get the first valid TransDataContainer *. * * Note we cannot trust TRANS_DATA_CONTAINER_FIRST_OK because of multi-object that * may leave items with invalid custom data in the transform data container. */ -static EdgeSlideData *edgeSlideFirstGet(TransInfo *t) +static TransDataContainer *edge_slide_container_first_ok(TransInfo *t) { FOREACH_TRANS_DATA_CONTAINER (t, tc) { - EdgeSlideData *sld = tc->custom.mode.data; - if (sld == NULL) { - continue; + if (tc->custom.mode.data) { + return tc; } - return sld; } BLI_assert(!"Should never happen, at least one EdgeSlideData should be valid"); return NULL; } +static EdgeSlideData *edgeSlideFirstGet(TransInfo *t) +{ + TransDataContainer *tc = edge_slide_container_first_ok(t); + return tc->custom.mode.data; +} + static void calcEdgeSlideCustomPoints(struct TransInfo *t) { EdgeSlideData *sld = edgeSlideFirstGet(t); @@ -1254,6 +1258,71 @@ void drawEdgeSlide(TransInfo *t) } } +static void edge_slide_snap_apply(TransInfo *t, float *value) +{ + TransDataContainer *tc = edge_slide_container_first_ok(t); + EdgeSlideParams *slp = t->custom.mode.data; + EdgeSlideData *sld_active = tc->custom.mode.data; + TransDataEdgeSlideVert *sv = &sld_active->sv[sld_active->curr_sv_index]; + float snap_point[3], co_orig[3], co_dest[2][3], dvec[3]; + + copy_v3_v3(co_orig, sv->v_co_orig); + add_v3_v3v3(co_dest[0], co_orig, sv->dir_side[0]); + add_v3_v3v3(co_dest[1], co_orig, sv->dir_side[1]); + if (tc->use_local_mat) { + mul_m4_v3(tc->mat, co_orig); + mul_m4_v3(tc->mat, co_dest[0]); + mul_m4_v3(tc->mat, co_dest[1]); + } + + getSnapPoint(t, dvec); + sub_v3_v3(dvec, t->tsnap.snapTarget); + add_v3_v3v3(snap_point, co_orig, dvec); + + float perc = *value; + int side_index; + if (slp->use_even == false) { + const bool is_clamp = !(t->flag & T_ALT_TRANSFORM); + if (is_clamp) { + side_index = perc < 0.0f; + } + else { + side_index = sld_active->curr_side_unclamp; + } + perc = line_point_factor_v3(snap_point, co_orig, co_dest[side_index]); + if (side_index) { + perc *= -1; + } + } + else { + /* Could be pre-calculated. */ + float t_mid = line_point_factor_v3( + (float[3]){0.0f, 0.0f, 0.0f}, sv->dir_side[0], sv->dir_side[1]); + + float t_snap = line_point_factor_v3(snap_point, co_dest[0], co_dest[1]); + side_index = t_snap >= t_mid; + perc = line_point_factor_v3(snap_point, co_orig, co_dest[side_index]); + if (!side_index) { + perc = (1.0f - perc) * t_mid; + } + else { + perc = perc * (1.0f - t_mid) + t_mid; + } + + if (slp->flipped) { + perc = 1.0f - perc; + } + + perc = (2 * perc) - 1.0f; + + if (!slp->flipped) { + perc *= -1; + } + } + + *value = perc; +} + void doEdgeSlide(TransInfo *t, float perc) { EdgeSlideParams *slp = t->custom.mode.data; @@ -1365,6 +1434,7 @@ static void applyEdgeSlide(TransInfo *t, const int UNUSED(mval[2])) final = t->values[0]; + applySnapping(t, &final); snapGridIncrement(t, &final); /* only do this so out of range values are not displayed */ @@ -1413,6 +1483,8 @@ void initEdgeSlide_ex( t->mode = TFM_EDGE_SLIDE; t->transform = applyEdgeSlide; t->handleEvent = handleEventEdgeSlide; + t->tsnap.applySnap = edge_slide_snap_apply; + t->tsnap.distance = transform_snap_distance_len_squared_fn; { EdgeSlideParams *slp = MEM_callocN(sizeof(*slp), __func__); diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index a9b3b7448ef..aaf5b55c4e3 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -127,6 +127,9 @@ bool transformModeUseSnap(const TransInfo *t) if (t->mode == TFM_VERT_SLIDE) { return true; } + if (t->mode == TFM_EDGE_SLIDE) { + return true; + } return false; } -- cgit v1.2.3