Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/transform/transform_convert_mesh.c')
-rw-r--r--source/blender/editors/transform/transform_convert_mesh.c101
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);
}
}