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.
This commit is contained in:
Germano Cavalcante 2020-06-22 15:28:25 -03:00
parent 73d3f51c16
commit 9335daac2a
2 changed files with 81 additions and 6 deletions

View File

@ -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__);

View File

@ -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;
}