diff options
Diffstat (limited to 'source/blender/editors/transform')
10 files changed, 371 insertions, 142 deletions
diff --git a/source/blender/editors/transform/transform_convert.c b/source/blender/editors/transform/transform_convert.c index d68489759fe..70004d27dfc 100644 --- a/source/blender/editors/transform/transform_convert.c +++ b/source/blender/editors/transform/transform_convert.c @@ -27,6 +27,7 @@ #include "MEM_guardedalloc.h" #include "BLI_kdtree.h" +#include "BLI_linklist_stack.h" #include "BLI_listbase.h" #include "BLI_math.h" @@ -409,59 +410,66 @@ void transform_autoik_update(TransInfo *t, short mode) /** \name Curve Surface * \{ */ -void calc_distanceCurveVerts(TransData *head, TransData *tail) +void calc_distanceCurveVerts(TransData *head, TransData *tail, bool cyclic) { - TransData *td, *td_near = NULL; + TransData *td; + BLI_LINKSTACK_DECLARE(queue, TransData *); + BLI_LINKSTACK_INIT(queue); for (td = head; td <= tail; td++) { if (td->flag & TD_SELECTED) { - td_near = td; td->dist = 0.0f; + BLI_LINKSTACK_PUSH(queue, td); } - else if (td_near) { - float dist; - float vec[3]; + else { + td->dist = FLT_MAX; + } + } + + while ((td = BLI_LINKSTACK_POP(queue))) { + float dist; + float vec[3]; + + TransData *next_td = NULL; - sub_v3_v3v3(vec, td_near->center, td->center); + if (td + 1 <= tail) { + next_td = td + 1; + } + else if (cyclic) { + next_td = head; + } + + if (next_td != NULL && !(next_td->flag & TD_NOTCONNECTED)) { + sub_v3_v3v3(vec, next_td->center, td->center); mul_m3_v3(head->mtx, vec); - dist = len_v3(vec); + dist = len_v3(vec) + td->dist; - if (dist < (td - 1)->dist) { - td->dist = (td - 1)->dist; - } - else { - td->dist = dist; + if (dist < next_td->dist) { + next_td->dist = dist; + BLI_LINKSTACK_PUSH(queue, next_td); } } - else { - td->dist = FLT_MAX; - td->flag |= TD_NOTCONNECTED; + + next_td = NULL; + + if (td - 1 >= head) { + next_td = td - 1; } - } - td_near = NULL; - for (td = tail; td >= head; td--) { - if (td->flag & TD_SELECTED) { - td_near = td; - td->dist = 0.0f; + else if (cyclic) { + next_td = tail; } - else if (td_near) { - float dist; - float vec[3]; - sub_v3_v3v3(vec, td_near->center, td->center); + if (next_td != NULL && !(next_td->flag & TD_NOTCONNECTED)) { + sub_v3_v3v3(vec, next_td->center, td->center); mul_m3_v3(head->mtx, vec); - dist = len_v3(vec); + dist = len_v3(vec) + td->dist; - if (td->flag & TD_NOTCONNECTED || dist < td->dist || (td + 1)->dist < td->dist) { - td->flag &= ~TD_NOTCONNECTED; - if (dist < (td + 1)->dist) { - td->dist = (td + 1)->dist; - } - else { - td->dist = dist; - } + if (dist < next_td->dist) { + next_td->dist = dist; + BLI_LINKSTACK_PUSH(queue, next_td); } } } + BLI_LINKSTACK_FREE(queue); } /* Utility function for getting the handle data from bezier's */ @@ -1270,6 +1278,9 @@ void createTransData(bContext *C, TransInfo *t) set_prop_dist(t, false); } } + else if (convert_type == TC_MESH_UV && t->flag & T_PROP_CONNECTED) { + /* Already calculated by uv_set_connectivity_distance. */ + } else if (convert_type == TC_CURVE_VERTS && t->obedit_type == OB_CURVE) { set_prop_dist(t, false); } diff --git a/source/blender/editors/transform/transform_convert.h b/source/blender/editors/transform/transform_convert.h index f7eea286983..ee478ad8567 100644 --- a/source/blender/editors/transform/transform_convert.h +++ b/source/blender/editors/transform/transform_convert.h @@ -87,7 +87,7 @@ void transform_around_single_fallback_ex(TransInfo *t, int data_len_all); void transform_around_single_fallback(TransInfo *t); void posttrans_fcurve_clean(struct FCurve *fcu, const int sel_flag, const bool use_handle); bool constraints_list_needinv(TransInfo *t, ListBase *list); -void calc_distanceCurveVerts(TransData *head, TransData *tail); +void calc_distanceCurveVerts(TransData *head, TransData *tail, bool cyclic); struct TransDataCurveHandleFlags *initTransDataCurveHandles(TransData *td, struct BezTriple *bezt); char transform_convert_frame_side_dir_get(TransInfo *t, float cframe); bool FrameOnMouseSide(char side, float frame, float cframe); diff --git a/source/blender/editors/transform/transform_convert_curve.c b/source/blender/editors/transform/transform_convert_curve.c index 37e37072ed7..65b2c9f9382 100644 --- a/source/blender/editors/transform/transform_convert_curve.c +++ b/source/blender/editors/transform/transform_convert_curve.c @@ -350,12 +350,14 @@ void createTransCurveVerts(TransInfo *t) (void)hdata; /* quiet warning */ } else if (is_prop_edit && head != tail) { - calc_distanceCurveVerts(head, tail - 1); - head = tail; + tail->flag |= TD_NOTCONNECTED; + td++; + tail++; } } if (is_prop_edit && head != tail) { - calc_distanceCurveVerts(head, tail - 1); + bool cyclic = (nu->flagu & CU_NURB_CYCLIC) != 0; + calc_distanceCurveVerts(head, tail - 1, cyclic); } /* TODO - in the case of tilt and radius we can also avoid allocating the @@ -425,12 +427,14 @@ void createTransCurveVerts(TransInfo *t) } } else if (is_prop_edit && head != tail) { - calc_distanceCurveVerts(head, tail - 1); - head = tail; + tail->flag |= TD_NOTCONNECTED; + td++; + tail++; } } if (is_prop_edit && head != tail) { - calc_distanceCurveVerts(head, tail - 1); + bool cyclic = (nu->flagu & CU_NURB_CYCLIC) != 0; + calc_distanceCurveVerts(head, tail - 1, cyclic); } } } diff --git a/source/blender/editors/transform/transform_convert_gpencil.c b/source/blender/editors/transform/transform_convert_gpencil.c index 22261b9bbd8..0eb12aeabed 100644 --- a/source/blender/editors/transform/transform_convert_gpencil.c +++ b/source/blender/editors/transform/transform_convert_gpencil.c @@ -354,7 +354,7 @@ void createTransGPencil(bContext *C, TransInfo *t) /* March over these points, and calculate the proportional editing distances */ if (is_prop_edit && (head != tail)) { - calc_distanceCurveVerts(head, tail - 1); + calc_distanceCurveVerts(head, tail - 1, false); } } } diff --git a/source/blender/editors/transform/transform_convert_mesh.c b/source/blender/editors/transform/transform_convert_mesh.c index 90e45253afa..f067dd60c19 100644 --- a/source/blender/editors/transform/transform_convert_mesh.c +++ b/source/blender/editors/transform/transform_convert_mesh.c @@ -1067,7 +1067,7 @@ static void create_trans_vert_customdata_layer(BMVert *v, BLI_ghash_insert(tcld->origverts, v, r_tcld_vert); } -static void trans_mesh_customdata_correction_init_container(TransInfo *t, TransDataContainer *tc) +static void trans_mesh_customdata_correction_init_container(TransDataContainer *tc) { if (tc->custom.type.data) { /* Custom data correction has initiated before. */ @@ -1075,23 +1075,6 @@ static void trans_mesh_customdata_correction_init_container(TransInfo *t, TransD return; } - if (!ELEM(t->mode, - TFM_TRANSLATION, - TFM_ROTATION, - TFM_RESIZE, - TFM_TOSPHERE, - TFM_SHEAR, - TFM_BEND, - TFM_SHRINKFATTEN, - TFM_TRACKBALL, - TFM_PUSHPULL, - TFM_ALIGN, - TFM_EDGE_SLIDE, - TFM_VERT_SLIDE)) { - /* Currently only modes that change the position of vertices are supported. */ - return; - } - BMEditMesh *em = BKE_editmesh_from_object(tc->obedit); BMesh *bm = em->bm; @@ -1173,13 +1156,63 @@ static void trans_mesh_customdata_correction_init_container(TransInfo *t, TransD void trans_mesh_customdata_correction_init(TransInfo *t) { + if (!ELEM(t->mode, + TFM_TRANSLATION, + TFM_ROTATION, + TFM_RESIZE, + TFM_TOSPHERE, + TFM_SHEAR, + TFM_BEND, + TFM_SHRINKFATTEN, + TFM_TRACKBALL, + TFM_PUSHPULL, + TFM_ALIGN, + TFM_EDGE_SLIDE, + TFM_VERT_SLIDE)) { + /* Currently only modes that change the position of vertices are supported. */ + return; + } + const char uvcalc_correct_flag = ELEM(t->mode, TFM_VERT_SLIDE, TFM_EDGE_SLIDE) ? UVCALC_TRANSFORM_CORRECT_SLIDE : UVCALC_TRANSFORM_CORRECT; if (t->settings->uvcalc_flag & uvcalc_correct_flag) { FOREACH_TRANS_DATA_CONTAINER (t, tc) { - trans_mesh_customdata_correction_init_container(t, tc); + trans_mesh_customdata_correction_init_container(tc); + } + } +} + +static void trans_mesh_customdata_correction_restore(struct TransDataContainer *tc) +{ + struct TransCustomDataLayer *tcld = tc->custom.type.data; + if (!tcld) { + return; + } + + BMesh *bm = tcld->bm; + struct TransCustomDataLayerVert *tcld_vert_iter = &tcld->data[0]; + for (int i = tcld->data_len; i--; tcld_vert_iter++) { + BMLoop *l; + BMIter liter; + BMVert *v = tcld_vert_iter->v; + BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) { + /* Pop the key to not restore the face again. */ + BMFace *f_copy = BLI_ghash_popkey(tcld->origfaces, l->f, NULL); + if (f_copy) { + BMLoop *l_iter_a, *l_first_a; + BMLoop *l_iter_b, *l_first_b; + l_iter_a = l_first_a = BM_FACE_FIRST_LOOP(f_copy); + l_iter_b = l_first_b = BM_FACE_FIRST_LOOP(l->f); + do { + BM_elem_attrs_copy(tcld->bm_origfaces, bm, l_iter_a, l_iter_b); + } while (((l_iter_a = l_iter_a->next) != l_first_a) && + ((l_iter_b = l_iter_b->next) != l_first_b)); + + BM_elem_attrs_copy_ex( + tcld->bm_origfaces, bm, f_copy, l->f, BM_ELEM_SELECT, CD_MASK_NORMAL); + } } } } @@ -1195,7 +1228,7 @@ static const float *trans_vert_orig_co_get(struct TransCustomDataLayer *tcld, BM static void trans_mesh_customdata_correction_apply_vert(struct TransCustomDataLayer *tcld, struct TransCustomDataLayerVert *tcld_vert, - bool is_final) + bool do_loop_mdisps) { BMesh *bm = tcld->bm; BMVert *v = tcld_vert->v; @@ -1295,8 +1328,8 @@ static void trans_mesh_customdata_correction_apply_vert(struct TransCustomDataLa * Interpolate from every other loop (not ideal) * However values will only be taken from loops which overlap other mdisps. * */ - const bool do_loop_mdisps = is_moved && is_final && (tcld->cd_loop_mdisp_offset != -1); - if (do_loop_mdisps) { + const bool update_loop_mdisps = is_moved && do_loop_mdisps && (tcld->cd_loop_mdisp_offset != -1); + if (update_loop_mdisps) { float(*faces_center)[3] = BLI_array_alloca(faces_center, l_num); BMLoop *l; @@ -1332,12 +1365,12 @@ static void trans_mesh_customdata_correction_apply(struct TransDataContainer *tc return; } - const bool has_mdisps = (tcld->cd_loop_mdisp_offset != -1); + const bool do_loop_mdisps = is_final && (tcld->cd_loop_mdisp_offset != -1); struct TransCustomDataLayerVert *tcld_vert_iter = &tcld->data[0]; for (int i = tcld->data_len; i--; tcld_vert_iter++) { - if (tcld_vert_iter->cd_loop_groups || has_mdisps) { - trans_mesh_customdata_correction_apply_vert(tcld, tcld_vert_iter, is_final); + if (tcld_vert_iter->cd_loop_groups || do_loop_mdisps) { + trans_mesh_customdata_correction_apply_vert(tcld, tcld_vert_iter, do_loop_mdisps); } } } @@ -1388,8 +1421,9 @@ static void transform_apply_to_mirror(TransInfo *t) void recalcData_mesh(TransInfo *t) { + bool is_cancelling = t->state == TRANS_CANCEL; /* mirror modifier clipping? */ - if (t->state != TRANS_CANCEL) { + if (!is_cancelling) { /* apply clipping after so we never project past the clip plane [#25423] */ applyProject(t); clipMirrorModifier(t); @@ -1400,7 +1434,12 @@ void recalcData_mesh(TransInfo *t) } FOREACH_TRANS_DATA_CONTAINER (t, tc) { - trans_mesh_customdata_correction_apply(tc, false); + if (is_cancelling) { + trans_mesh_customdata_correction_restore(tc); + } + else { + trans_mesh_customdata_correction_apply(tc, false); + } DEG_id_tag_update(tc->obedit->data, 0); /* sets recalc flags */ BMEditMesh *em = BKE_editmesh_from_object(tc->obedit); @@ -1416,15 +1455,15 @@ void recalcData_mesh(TransInfo *t) void special_aftertrans_update__mesh(bContext *UNUSED(C), TransInfo *t) { - const bool canceled = (t->state == TRANS_CANCEL); - const bool use_automerge = !canceled && (t->flag & (T_AUTOMERGE | T_AUTOSPLIT)) != 0; + const bool is_cancelling = (t->state == TRANS_CANCEL); + const bool use_automerge = !is_cancelling && (t->flag & (T_AUTOMERGE | T_AUTOSPLIT)) != 0; - if (TRANS_DATA_CONTAINER_FIRST_OK(t)->custom.type.data != NULL) { + if (!is_cancelling && TRANS_DATA_CONTAINER_FIRST_OK(t)->custom.type.data != NULL) { /* Handle multires re-projection, done * on transform completion since it's * really slow -joeedh. */ FOREACH_TRANS_DATA_CONTAINER (t, tc) { - trans_mesh_customdata_correction_apply(tc, !canceled); + trans_mesh_customdata_correction_apply(tc, true); } } diff --git a/source/blender/editors/transform/transform_convert_mesh_uv.c b/source/blender/editors/transform/transform_convert_mesh_uv.c index 41c09cd8ea2..56fa2d90fb2 100644 --- a/source/blender/editors/transform/transform_convert_mesh_uv.c +++ b/source/blender/editors/transform/transform_convert_mesh_uv.c @@ -26,6 +26,7 @@ #include "MEM_guardedalloc.h" #include "BLI_bitmap.h" +#include "BLI_linklist_stack.h" #include "BLI_math.h" #include "BKE_context.h" @@ -51,12 +52,13 @@ static void UVsToTransData(const float aspect[2], TransData2D *td2d, float *uv, const float *center, + float calc_dist, bool selected) { - /* uv coords are scaled by aspects. this is needed for rotations and - * proportional editing to be consistent with the stretched uv coords - * that are displayed. this also means that for display and numinput, - * and when the uv coords are flushed, these are converted each time */ + /* UV coords are scaled by aspects. this is needed for rotations and + * proportional editing to be consistent with the stretched UV coords + * that are displayed. this also means that for display and number-input, + * and when the UV coords are flushed, these are converted each time. */ td2d->loc[0] = uv[0] * aspect[0]; td2d->loc[1] = uv[1] * aspect[1]; td2d->loc[2] = 0.0f; @@ -79,12 +81,182 @@ static void UVsToTransData(const float aspect[2], td->dist = 0.0; } else { - td->dist = FLT_MAX; + td->dist = calc_dist; } unit_m3(td->mtx); unit_m3(td->smtx); } +/** + * \param dists: Store the closest connected distance to selected vertices. + */ +static void uv_set_connectivity_distance(BMesh *bm, float *dists, const float aspect[2]) +{ + /* Mostly copied from editmesh_set_connectivity_distance. */ + BLI_LINKSTACK_DECLARE(queue, BMLoop *); + + /* Any BM_ELEM_TAG'd loop is added to 'queue_next', this makes sure that we don't add things + * twice. */ + BLI_LINKSTACK_DECLARE(queue_next, BMLoop *); + + BLI_LINKSTACK_INIT(queue); + BLI_LINKSTACK_INIT(queue_next); + + const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); + BMIter fiter, liter; + BMVert *f; + BMLoop *l; + + BM_mesh_elem_index_ensure(bm, BM_LOOP); + + BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) { + /* Visable faces was tagged in createTransUVs. */ + if (!BM_elem_flag_test(f, BM_ELEM_TAG)) { + continue; + } + + BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) { + float dist; + MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); + + bool uv_vert_sel = luv->flag & MLOOPUV_VERTSEL; + + if (uv_vert_sel) { + BLI_LINKSTACK_PUSH(queue, l); + dist = 0.0f; + } + else { + dist = FLT_MAX; + } + + /* Make sure all loops are in a clean tag state. */ + BLI_assert(BM_elem_flag_test(l, BM_ELEM_TAG) == 0); + + int loop_idx = BM_elem_index_get(l); + + dists[loop_idx] = dist; + } + } + + /* Need to be very careful of feedback loops here, store previous dist's to avoid feedback. */ + float *dists_prev = MEM_dupallocN(dists); + + do { + while ((l = BLI_LINKSTACK_POP(queue))) { + BLI_assert(dists[BM_elem_index_get(l)] != FLT_MAX); + + BMLoop *l_other, *l_connected; + BMIter l_connected_iter; + + MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); + float l_uv[2]; + + copy_v2_v2(l_uv, luv->uv); + mul_v2_v2(l_uv, aspect); + + BM_ITER_ELEM (l_other, &liter, l->f, BM_LOOPS_OF_FACE) { + if (l_other == l) { + continue; + } + float other_uv[2], edge_vec[2]; + MLoopUV *luv_other = BM_ELEM_CD_GET_VOID_P(l_other, cd_loop_uv_offset); + + copy_v2_v2(other_uv, luv_other->uv); + mul_v2_v2(other_uv, aspect); + + sub_v2_v2v2(edge_vec, l_uv, other_uv); + + const int i = BM_elem_index_get(l); + const int i_other = BM_elem_index_get(l_other); + float dist = len_v2(edge_vec) + dists_prev[i]; + + if (dist < dists[i_other]) { + dists[i_other] = dist; + } + else { + /* The face loop already has a shorter path to it. */ + continue; + } + + float connected_uv[2]; + float uvdiff[2]; + + bool other_vert_sel, connected_vert_sel; + + other_vert_sel = luv_other->flag & MLOOPUV_VERTSEL; + + BM_ITER_ELEM (l_connected, &l_connected_iter, l_other->v, BM_LOOPS_OF_VERT) { + if (l_connected == l_other) { + continue; + } + /* Visable faces was tagged in createTransUVs. */ + if (!BM_elem_flag_test(l_connected->f, BM_ELEM_TAG)) { + continue; + } + + MLoopUV *luv_connected = BM_ELEM_CD_GET_VOID_P(l_connected, cd_loop_uv_offset); + connected_vert_sel = luv_connected->flag & MLOOPUV_VERTSEL; + copy_v2_v2(connected_uv, luv_connected->uv); + mul_v2_v2(connected_uv, aspect); + + sub_v2_v2v2(uvdiff, connected_uv, other_uv); + /* Check if this loop is connected in UV space. + * If the uv loops share the same selection state (if not, they are not connected as + * they have been ripped or other edit commands have separated them). */ + bool connected = other_vert_sel == connected_vert_sel && + fabsf(uvdiff[0]) < STD_UV_CONNECT_LIMIT && + fabsf(uvdiff[1]) < STD_UV_CONNECT_LIMIT; + if (!connected) { + continue; + } + + /* The loop vert is occupying the same space, so it has the same distance. */ + const int i_connected = BM_elem_index_get(l_connected); + dists[i_connected] = dist; + + if (BM_elem_flag_test(l_connected, BM_ELEM_TAG) == 0) { + BM_elem_flag_enable(l_connected, BM_ELEM_TAG); + BLI_LINKSTACK_PUSH(queue_next, l_connected); + } + } + } + } + + /* Clear elem flags for the next loop. */ + for (LinkNode *lnk = queue_next; lnk; lnk = lnk->next) { + BMLoop *l_link = lnk->link; + const int i = BM_elem_index_get(l_link); + + BM_elem_flag_disable(l_link, BM_ELEM_TAG); + + /* Store all new dist values. */ + dists_prev[i] = dists[i]; + } + + BLI_LINKSTACK_SWAP(queue, queue_next); + + } while (BLI_LINKSTACK_SIZE(queue)); + +#ifndef NDEBUG + /* Check that we didn't leave any loops tagged */ + BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) { + /* Visable faces was tagged in createTransUVs. */ + if (!BM_elem_flag_test(f, BM_ELEM_TAG)) { + continue; + } + + BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) { + BLI_assert(BM_elem_flag_test(l, BM_ELEM_TAG) == 0); + } + } +#endif + + BLI_LINKSTACK_FREE(queue); + BLI_LINKSTACK_FREE(queue_next); + + MEM_freeN(dists_prev); +} + void createTransUVs(bContext *C, TransInfo *t) { SpaceImage *sima = CTX_wm_space_image(C); @@ -103,12 +275,11 @@ void createTransUVs(bContext *C, TransInfo *t) BMFace *efa; BMIter iter, liter; UvElementMap *elementmap = NULL; - BLI_bitmap *island_enabled = NULL; struct { float co[2]; int co_num; } *island_center = NULL; - int count = 0, countsel = 0, count_rejected = 0; + int count = 0, countsel = 0; const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); if (!ED_space_image_show_uvedit(sima, tc->obedit)) { @@ -116,22 +287,15 @@ void createTransUVs(bContext *C, TransInfo *t) } /* count */ - if (is_prop_connected || is_island_center) { + if (is_island_center) { /* create element map with island information */ const bool use_facesel = (ts->uv_flag & UV_SYNC_SELECTION) == 0; - const bool use_uvsel = !is_prop_connected; - elementmap = BM_uv_element_map_create(em->bm, scene, use_facesel, use_uvsel, false, true); + elementmap = BM_uv_element_map_create(em->bm, scene, use_facesel, true, false, true); if (elementmap == NULL) { continue; } - if (is_prop_connected) { - island_enabled = BLI_BITMAP_NEW(elementmap->totalIslands, "TransIslandData(UV Editing)"); - } - - if (is_island_center) { - island_center = MEM_callocN(sizeof(*island_center) * elementmap->totalIslands, __func__); - } + island_center = MEM_callocN(sizeof(*island_center) * elementmap->totalIslands, __func__); } BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { @@ -147,20 +311,14 @@ void createTransUVs(bContext *C, TransInfo *t) if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) { countsel++; - if (is_prop_connected || island_center) { + if (island_center) { UvElement *element = BM_uv_element_get(elementmap, efa, l); - if (is_prop_connected) { - BLI_BITMAP_ENABLE(island_enabled, element->island); - } - - if (is_island_center) { - if (element->flag == false) { - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - add_v2_v2(island_center[element->island].co, luv->uv); - island_center[element->island].co_num++; - element->flag = true; - } + if (element->flag == false) { + MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); + add_v2_v2(island_center[element->island].co, luv->uv); + island_center[element->island].co_num++; + element->flag = true; } } } @@ -198,6 +356,14 @@ void createTransUVs(bContext *C, TransInfo *t) td = tc->data; td2d = tc->data_2d; + float *prop_dists = NULL; + + if (is_prop_connected) { + prop_dists = MEM_callocN(em->bm->totloop * sizeof(float), "TransObPropDists(UV Editing)"); + + uv_set_connectivity_distance(em->bm, prop_dists, t->aspect); + } + BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { BMLoop *l; @@ -209,52 +375,41 @@ void createTransUVs(bContext *C, TransInfo *t) const bool selected = uvedit_uv_select_test(scene, l, cd_loop_uv_offset); MLoopUV *luv; const float *center = NULL; + float prop_distance = FLT_MAX; if (!is_prop_edit && !selected) { continue; } - if (is_prop_connected || is_island_center) { + if (is_prop_connected) { + const int idx = BM_elem_index_get(l); + prop_distance = prop_dists[idx]; + } + + if (is_island_center) { UvElement *element = BM_uv_element_get(elementmap, efa, l); if (element) { - if (is_prop_connected) { - if (!BLI_BITMAP_TEST(island_enabled, element->island)) { - count_rejected++; - continue; - } - } - - if (is_island_center) { - center = island_center[element->island].co; - } + center = island_center[element->island].co; } } - BM_elem_flag_enable(l, BM_ELEM_TAG); luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - UVsToTransData(t->aspect, td++, td2d++, luv->uv, center, selected); + UVsToTransData(t->aspect, td++, td2d++, luv->uv, center, prop_distance, selected); } } - if (is_prop_connected) { - tc->data_len -= count_rejected; - } - if (sima->flag & SI_LIVE_UNWRAP) { ED_uvedit_live_unwrap_begin(t->scene, tc->obedit); } finally: - if (is_prop_connected || is_island_center) { + if (is_prop_connected) { + MEM_freeN(prop_dists); + } + if (is_island_center) { BM_uv_element_map_free(elementmap); - if (is_prop_connected) { - MEM_freeN(island_enabled); - } - - if (island_center) { - MEM_freeN(island_center); - } + MEM_freeN(island_center); } } } diff --git a/source/blender/editors/transform/transform_convert_particle.c b/source/blender/editors/transform/transform_convert_particle.c index 3fa722d14cf..fbe9c07ebe9 100644 --- a/source/blender/editors/transform/transform_convert_particle.c +++ b/source/blender/editors/transform/transform_convert_particle.c @@ -183,7 +183,7 @@ void createTransParticleVerts(bContext *C, TransInfo *t) tail++; } if (is_prop_edit && head != tail) { - calc_distanceCurveVerts(head, tail - 1); + calc_distanceCurveVerts(head, tail - 1, false); } } } diff --git a/source/blender/editors/transform/transform_mode_translate.c b/source/blender/editors/transform/transform_mode_translate.c index aee05197f10..cde06a9eaac 100644 --- a/source/blender/editors/transform/transform_mode_translate.c +++ b/source/blender/editors/transform/transform_mode_translate.c @@ -67,15 +67,27 @@ static void headerTranslation(TransInfo *t, const float vec[3], char str[UI_MAX_ dist = len_v3(t->num.val); } else { + int i = 0; float dvec[3]; - - copy_v3_v3(dvec, vec); - applyAspectRatio(t, dvec); + if (!(t->flag & T_2D_EDIT) && t->con.mode & CON_APPLY) { + zero_v3(dvec); + if (t->con.mode & CON_AXIS0) { + dvec[i++] = vec[0]; + } + if (t->con.mode & CON_AXIS1) { + dvec[i++] = vec[1]; + } + if (t->con.mode & CON_AXIS2) { + dvec[i++] = vec[2]; + } + } + else { + copy_v3_v3(dvec, vec); + applyAspectRatio(t, dvec); + } dist = len_v3(vec); if (!(t->flag & T_2D_EDIT) && t->scene->unit.system) { - int i; - for (i = 0; i < 3; i++) { bUnit_AsString2(&tvec[NUM_STR_REP_LEN * i], NUM_STR_REP_LEN, diff --git a/source/blender/editors/transform/transform_mode_vert_slide.c b/source/blender/editors/transform/transform_mode_vert_slide.c index 9e810b9c629..4bcc4cc6383 100644 --- a/source/blender/editors/transform/transform_mode_vert_slide.c +++ b/source/blender/editors/transform/transform_mode_vert_slide.c @@ -500,6 +500,10 @@ static void doVertSlide(TransInfo *t, float perc) FOREACH_TRANS_DATA_CONTAINER (t, tc) { VertSlideData *sld = tc->custom.mode.data; + if (sld == NULL) { + continue; + } + TransDataVertSlideVert *svlist = sld->sv, *sv; int i; diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.c index 3af176f5aef..6dbf80ed4b9 100644 --- a/source/blender/editors/transform/transform_snap_object.c +++ b/source/blender/editors/transform/transform_snap_object.c @@ -1106,11 +1106,13 @@ static bool raycastObjects(SnapObjectContext *sctx, const float ray_start[3], const float ray_dir[3], /* read/write args */ - float *ray_depth, + /* Parameters below cannot be const, because they are assigned to a + * non-const variable (readability-non-const-parameter). */ + float *ray_depth /* NOLINT */, /* return args */ - float r_loc[3], - float r_no[3], - int *r_index, + float r_loc[3] /* NOLINT */, + float r_no[3] /* NOLINT */, + int *r_index /* NOLINT */, Object **r_ob, float r_obmat[4][4], ListBase *r_hit_list) @@ -2789,11 +2791,13 @@ static short snapObjectsRay(SnapObjectContext *sctx, SnapData *snapdata, const struct SnapObjectParams *params, /* read/write args */ - float *dist_px, + /* Parameters below cannot be const, because they are assigned to a + * non-const variable (readability-non-const-parameter). */ + float *dist_px /* NOLINT */, /* return args */ - float r_loc[3], - float r_no[3], - int *r_index, + float r_loc[3] /* NOLINT */, + float r_no[3] /* NOLINT */, + int *r_index /* NOLINT */, Object **r_ob, float r_obmat[4][4]) { |