diff options
Diffstat (limited to 'source/blender/editors/transform/transform_convert_mesh.c')
-rw-r--r-- | source/blender/editors/transform/transform_convert_mesh.c | 101 |
1 files changed, 70 insertions, 31 deletions
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); } } |