Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/transform/transform_mode_edge_slide.c
| Show First 20 Lines • Show All 1,330 Lines • ▼ Show 20 Lines | else { | ||||
| if (!slp->flipped) { | if (!slp->flipped) { | ||||
| perc *= -1; | perc *= -1; | ||||
| } | } | ||||
| } | } | ||||
| *value = perc; | *value = perc; | ||||
| } | } | ||||
| static void doEdgeSlide(TransInfo *t, float perc) | static void edge_slide_apply_elem(const EdgeSlideData *sld_active, | ||||
| const TransDataEdgeSlideVert *sv, | |||||
| const float perc, | |||||
| const bool use_clamp, | |||||
| const bool use_even, | |||||
| const bool use_flip, | |||||
| float r_co[3]) | |||||
| { | { | ||||
| EdgeSlideParams *slp = t->custom.mode.data; | copy_v3_v3(r_co, sv->v_co_orig); | ||||
| EdgeSlideData *sld_active = edgeSlideFirstGet(t); | |||||
| slp->perc = perc; | |||||
| if (slp->use_even == false) { | if (use_even == false) { | ||||
| const bool is_clamp = !(t->flag & T_ALT_TRANSFORM); | if (use_clamp) { | ||||
| if (is_clamp) { | |||||
| const int side_index = (perc < 0.0f); | const int side_index = (perc < 0.0f); | ||||
| const float perc_final = fabsf(perc); | const float perc_final = fabsf(perc); | ||||
| FOREACH_TRANS_DATA_CONTAINER (t, tc) { | madd_v3_v3fl(r_co, sv->dir_side[side_index], perc_final); | ||||
| EdgeSlideData *sld = tc->custom.mode.data; | |||||
| if (sld == NULL) { | |||||
| continue; | |||||
| } | |||||
| TransDataEdgeSlideVert *sv = sld->sv; | |||||
| for (int i = 0; i < sld->totsv; i++, sv++) { | |||||
| madd_v3_v3v3fl(sv->v->co, sv->v_co_orig, sv->dir_side[side_index], perc_final); | |||||
| } | |||||
| sld->curr_side_unclamp = side_index; | |||||
| } | |||||
| } | } | ||||
| else { | else { | ||||
| const float perc_init = fabsf(perc) * | const float perc_init = fabsf(perc) * | ||||
| ((sld_active->curr_side_unclamp == (perc < 0.0f)) ? 1 : -1); | ((sld_active->curr_side_unclamp == (perc < 0.0f)) ? 1 : -1); | ||||
| const int side_index = sld_active->curr_side_unclamp; | const int side_index = sld_active->curr_side_unclamp; | ||||
| FOREACH_TRANS_DATA_CONTAINER (t, tc) { | |||||
| EdgeSlideData *sld = tc->custom.mode.data; | |||||
| if (sld == NULL) { | |||||
| continue; | |||||
| } | |||||
| TransDataEdgeSlideVert *sv = sld->sv; | |||||
| for (int i = 0; i < sld->totsv; i++, sv++) { | |||||
| float dir_flip[3]; | float dir_flip[3]; | ||||
| float perc_final = perc_init; | float perc_final = perc_init; | ||||
| if (!is_zero_v3(sv->dir_side[side_index])) { | if (!is_zero_v3(sv->dir_side[side_index])) { | ||||
| copy_v3_v3(dir_flip, sv->dir_side[side_index]); | copy_v3_v3(dir_flip, sv->dir_side[side_index]); | ||||
| } | } | ||||
| else { | else { | ||||
| copy_v3_v3(dir_flip, sv->dir_side[!side_index]); | copy_v3_v3(dir_flip, sv->dir_side[!side_index]); | ||||
| perc_final *= -1; | perc_final *= -1; | ||||
| } | } | ||||
| madd_v3_v3v3fl(sv->v->co, sv->v_co_orig, dir_flip, perc_final); | madd_v3_v3fl(r_co, dir_flip, perc_final); | ||||
| } | |||||
| } | } | ||||
| } | } | ||||
| else { | |||||
| const float curr_length_perc = sv->edge_len * (((use_flip ? perc : -perc) + 1.0f) / 2.0f); | |||||
| if (sv->edge_len > FLT_EPSILON) { | |||||
| float co_a[3], co_b[3]; | |||||
| const float fac = min_ff(sv->edge_len, curr_length_perc) / sv->edge_len; | |||||
| add_v3_v3v3(co_a, sv->v_co_orig, sv->dir_side[0]); | |||||
| add_v3_v3v3(co_b, sv->v_co_orig, sv->dir_side[1]); | |||||
| if (use_flip) { | |||||
| interp_line_v3_v3v3v3(r_co, co_b, sv->v_co_orig, co_a, fac); | |||||
| } | } | ||||
| else { | else { | ||||
| /** | interp_line_v3_v3v3v3(r_co, co_a, sv->v_co_orig, co_b, fac); | ||||
| * Implementation note, even mode ignores the starting positions and uses | } | ||||
| * only the a/b verts, this could be changed/improved so the distance is | } | ||||
| * still met but the verts are moved along their original path (which may not be straight), | } | ||||
| * however how it works now is OK and matches 2.4x - Campbell | } | ||||
| * | |||||
| * \note `len_v3v3(curr_sv->dir_side[0], curr_sv->dir_side[1])` | static void doEdgeSlide(TransInfo *t, float perc) | ||||
| * is the same as the distance between the original vert locations, | { | ||||
| * same goes for the lines below. | EdgeSlideParams *slp = t->custom.mode.data; | ||||
| */ | EdgeSlideData *sld_active = edgeSlideFirstGet(t); | ||||
| TransDataEdgeSlideVert *curr_sv = &sld_active->sv[sld_active->curr_sv_index]; | |||||
| const float curr_length_perc = curr_sv->edge_len * | |||||
| (((slp->flipped ? perc : -perc) + 1.0f) / 2.0f); | |||||
| float co_a[3]; | slp->perc = perc; | ||||
| float co_b[3]; | |||||
| const bool use_clamp = !(t->flag & T_ALT_TRANSFORM); | |||||
| const bool use_even = slp->use_even; | |||||
| FOREACH_TRANS_DATA_CONTAINER (t, tc) { | FOREACH_TRANS_DATA_CONTAINER (t, tc) { | ||||
| EdgeSlideData *sld = tc->custom.mode.data; | EdgeSlideData *sld = tc->custom.mode.data; | ||||
| if (sld == NULL) { | if (sld == NULL) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| TransDataEdgeSlideVert *sv = sld->sv; | TransDataEdgeSlideVert *sv = sld->sv; | ||||
| for (int i = 0; i < sld->totsv; i++, sv++) { | for (int i = 0; i < sld->totsv; i++, sv++) { | ||||
| if (sv->edge_len > FLT_EPSILON) { | edge_slide_apply_elem(sld_active, sv, perc, use_clamp, use_even, slp->flipped, sv->v->co); | ||||
| const float fac = min_ff(sv->edge_len, curr_length_perc) / sv->edge_len; | |||||
| add_v3_v3v3(co_a, sv->v_co_orig, sv->dir_side[0]); | |||||
| add_v3_v3v3(co_b, sv->v_co_orig, sv->dir_side[1]); | |||||
| if (slp->flipped) { | |||||
| interp_line_v3_v3v3v3(sv->v->co, co_b, sv->v_co_orig, co_a, fac); | |||||
| } | |||||
| else { | |||||
| interp_line_v3_v3v3v3(sv->v->co, co_a, sv->v_co_orig, co_b, fac); | |||||
| } | |||||
| } | |||||
| } | } | ||||
| if (use_even == false && use_clamp) { | |||||
| const int side_index = (perc < 0.0f); | |||||
| sld->curr_side_unclamp = side_index; | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| static void applyEdgeSlide(TransInfo *t, const int UNUSED(mval[2])) | static void applyEdgeSlide(TransInfo *t, const int UNUSED(mval[2])) | ||||
| { | { | ||||
| char str[UI_MAX_DRAW_STR]; | char str[UI_MAX_DRAW_STR]; | ||||
| size_t ofs = 0; | size_t ofs = 0; | ||||
| ▲ Show 20 Lines • Show All 43 Lines • ▼ Show 20 Lines | static void applyEdgeSlide(TransInfo *t, const int UNUSED(mval[2])) | ||||
| /* do stuff here */ | /* do stuff here */ | ||||
| doEdgeSlide(t, final); | doEdgeSlide(t, final); | ||||
| recalcData(t); | recalcData(t); | ||||
| ED_area_status_text(t->area, str); | ED_area_status_text(t->area, str); | ||||
| } | } | ||||
| static void edge_slide_transform_matrix_fn(struct TransInfo *t, float mat_xform[4][4]) | |||||
| { | |||||
| float delta[3], orig_co[3], final_co[3]; | |||||
| EdgeSlideParams *slp = t->custom.mode.data; | |||||
| TransDataContainer *tc = edge_slide_container_first_ok(t); | |||||
| EdgeSlideData *sld_active = tc->custom.mode.data; | |||||
| TransDataEdgeSlideVert *sv_active = &sld_active->sv[sld_active->curr_sv_index]; | |||||
| copy_v3_v3(orig_co, sv_active->v_co_orig); | |||||
| edge_slide_apply_elem(sld_active, | |||||
| sv_active, | |||||
| t->values_final[0], | |||||
| !(t->flag & T_ALT_TRANSFORM), | |||||
| slp->use_even, | |||||
| slp->flipped, | |||||
| final_co); | |||||
| if (tc->use_local_mat) { | |||||
| mul_m4_v3(tc->mat, orig_co); | |||||
| mul_m4_v3(tc->mat, final_co); | |||||
| } | |||||
| sub_v3_v3v3(delta, final_co, orig_co); | |||||
| add_v3_v3(mat_xform[3], delta); | |||||
| } | |||||
| void initEdgeSlide_ex( | void initEdgeSlide_ex( | ||||
| TransInfo *t, bool use_double_side, bool use_even, bool flipped, bool use_clamp) | TransInfo *t, bool use_double_side, bool use_even, bool flipped, bool use_clamp) | ||||
| { | { | ||||
| EdgeSlideData *sld; | EdgeSlideData *sld; | ||||
| bool ok = false; | bool ok = false; | ||||
| t->mode = TFM_EDGE_SLIDE; | t->mode = TFM_EDGE_SLIDE; | ||||
| t->transform = applyEdgeSlide; | t->transform = applyEdgeSlide; | ||||
| t->handleEvent = handleEventEdgeSlide; | t->handleEvent = handleEventEdgeSlide; | ||||
| t->transform_matrix = NULL; | t->transform_matrix = edge_slide_transform_matrix_fn; | ||||
| t->tsnap.snap_mode_apply_fn = edge_slide_snap_apply; | t->tsnap.snap_mode_apply_fn = edge_slide_snap_apply; | ||||
| t->tsnap.snap_mode_distance_fn = transform_snap_distance_len_squared_fn; | t->tsnap.snap_mode_distance_fn = transform_snap_distance_len_squared_fn; | ||||
| { | { | ||||
| EdgeSlideParams *slp = MEM_callocN(sizeof(*slp), __func__); | EdgeSlideParams *slp = MEM_callocN(sizeof(*slp), __func__); | ||||
| slp->use_even = use_even; | slp->use_even = use_even; | ||||
| slp->flipped = flipped; | slp->flipped = flipped; | ||||
| /* happens to be best for single-sided */ | /* happens to be best for single-sided */ | ||||
| ▲ Show 20 Lines • Show All 79 Lines • Show Last 20 Lines | |||||