Fix T45458: Edge Slide Mirror doesn't preserve UVs

This commit is contained in:
Campbell Barton 2015-07-21 14:15:31 +10:00
parent 5e1a8055f4
commit 9dc9f84740
Notes: blender-bot 2023-02-14 08:53:17 +01:00
Referenced by issue #45916, Edge Slide crashes if you press R
Referenced by issue #45458, Edge Slide with X Mirror doesn't preserve UVs
3 changed files with 61 additions and 17 deletions

View File

@ -1001,9 +1001,9 @@ int transformEvent(TransInfo *t, const wmEvent *event)
case TFM_MODAL_TRANSLATE:
/* only switch when... */
if (ELEM(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL, TFM_EDGE_SLIDE, TFM_VERT_SLIDE)) {
restoreTransObjects(t);
resetTransModal(t);
resetTransRestrictions(t);
restoreTransObjects(t);
initTranslation(t);
initSnapping(t, NULL); // need to reinit after mode change
t->redraw |= TREDRAW_HARD;
@ -1018,9 +1018,9 @@ int transformEvent(TransInfo *t, const wmEvent *event)
else {
if (t->obedit && t->obedit->type == OB_MESH) {
if ((t->mode == TFM_TRANSLATION) && (t->spacetype == SPACE_VIEW3D)) {
restoreTransObjects(t);
resetTransModal(t);
resetTransRestrictions(t);
restoreTransObjects(t);
/* first try edge slide */
initEdgeSlide(t);
@ -1032,8 +1032,8 @@ int transformEvent(TransInfo *t, const wmEvent *event)
/* vert slide can fail on unconnected vertices (rare but possible) */
if (t->state == TRANS_CANCEL) {
t->state = TRANS_STARTING;
resetTransRestrictions(t);
restoreTransObjects(t);
resetTransRestrictions(t);
initTranslation(t);
}
initSnapping(t, NULL); // need to reinit after mode change
@ -1083,9 +1083,9 @@ int transformEvent(TransInfo *t, const wmEvent *event)
stopConstraint(t);
}
restoreTransObjects(t);
resetTransModal(t);
resetTransRestrictions(t);
restoreTransObjects(t);
initResize(t);
initSnapping(t, NULL); // need to reinit after mode change
t->redraw |= TREDRAW_HARD;
@ -1313,9 +1313,9 @@ int transformEvent(TransInfo *t, const wmEvent *event)
case GKEY:
/* only switch when... */
if (ELEM(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL)) {
restoreTransObjects(t);
resetTransModal(t);
resetTransRestrictions(t);
restoreTransObjects(t);
initTranslation(t);
initSnapping(t, NULL); // need to reinit after mode change
t->redraw |= TREDRAW_HARD;
@ -1325,9 +1325,9 @@ int transformEvent(TransInfo *t, const wmEvent *event)
case SKEY:
/* only switch when... */
if (ELEM(t->mode, TFM_ROTATION, TFM_TRANSLATION, TFM_TRACKBALL)) {
restoreTransObjects(t);
resetTransModal(t);
resetTransRestrictions(t);
restoreTransObjects(t);
initResize(t);
initSnapping(t, NULL); // need to reinit after mode change
t->redraw |= TREDRAW_HARD;
@ -5336,12 +5336,13 @@ static void slide_origdata_create_data_vert(
static void slide_origdata_create_data(
TransInfo *t, SlideOrigData *sod,
TransDataGenericSlideVert *sv, unsigned int v_stride, unsigned int v_num)
TransDataGenericSlideVert *sv_array, unsigned int v_stride, unsigned int v_num)
{
if (sod->use_origfaces) {
BMEditMesh *em = BKE_editmesh_from_object(t->obedit);
BMesh *bm = em->bm;
unsigned int i;
TransDataGenericSlideVert *sv;
int layer_index_dst;
int j;
@ -5361,9 +5362,38 @@ static void slide_origdata_create_data(
sod->origverts = BLI_ghash_ptr_new_ex(__func__, v_num);
for (i = 0; i < v_num; i++, sv = POINTER_OFFSET(sv, v_stride)) {
for (i = 0, sv = sv_array; i < v_num; i++, sv = POINTER_OFFSET(sv, v_stride)) {
slide_origdata_create_data_vert(bm, sod, sv);
}
if (t->flag & T_MIRROR) {
TransData *td = t->data;
TransDataGenericSlideVert *sv_mirror;
sod->sv_mirror = MEM_callocN(sizeof(*sv_mirror) * t->total, __func__);
sod->totsv_mirror = t->total;
sv_mirror = sod->sv_mirror;
for (i = 0; i < t->total; i++, td++) {
BMVert *eve = td->extra;
if (eve) {
sv_mirror->v = eve;
copy_v3_v3(sv_mirror->co_orig_3d, eve->co);
slide_origdata_create_data_vert(bm, sod, sv_mirror);
sv_mirror++;
}
else {
sod->totsv_mirror--;
}
}
if (sod->totsv_mirror == 0) {
MEM_freeN(sod->sv_mirror);
sod->sv_mirror = NULL;
}
}
}
}
@ -5480,6 +5510,15 @@ static void slide_origdata_interp_data(
slide_origdata_interp_data_vert(sod, bm, is_final, sv);
}
}
if (sod->sv_mirror) {
sv = sod->sv_mirror;
for (i = 0; i < v_num; i++, sv++) {
if (sv->cd_loop_groups) {
slide_origdata_interp_data_vert(sod, bm, is_final, sv);
}
}
}
}
}
@ -5508,6 +5547,8 @@ static void slide_origdata_free_date(
}
MEM_SAFE_FREE(sod->layer_math_map);
MEM_SAFE_FREE(sod->sv_mirror);
}
}
@ -6495,8 +6536,6 @@ void freeEdgeSlideVerts(TransInfo *t)
MEM_freeN(sld);
t->customData = NULL;
recalcData(t);
}
static void initEdgeSlide_ex(TransInfo *t, bool use_double_side)
@ -6785,8 +6824,6 @@ static void doEdgeSlide(TransInfo *t, float perc)
}
}
}
projectEdgeSlideData(t, 0);
}
static void applyEdgeSlide(TransInfo *t, const int UNUSED(mval[2]))
@ -7104,8 +7141,6 @@ void freeVertSlideVerts(TransInfo *t)
MEM_freeN(sld);
t->customData = NULL;
recalcData(t);
}
static void initVertSlide(TransInfo *t)
@ -7350,8 +7385,6 @@ static void doVertSlide(TransInfo *t, float perc)
}
}
}
projectVertSlideData(t, false);
}
static void applyVertSlide(TransInfo *t, const int UNUSED(mval[2]))

View File

@ -235,6 +235,10 @@ typedef struct SlideOrigData {
/* array size of 'layer_math_map_num'
* maps TransDataVertSlideVert.cd_group index to absolute CustomData layer index */
int *layer_math_map;
/* array of slide vert data especially for mirror verts */
TransDataGenericSlideVert *sv_mirror;
int totsv_mirror;
} SlideOrigData;
typedef struct EdgeSlideData {

View File

@ -758,7 +758,14 @@ static void recalcData_objects(TransInfo *t)
}
if ((t->options & CTX_NO_MIRROR) == 0 && (t->flag & T_MIRROR))
editbmesh_apply_to_mirror(t);
if (t->mode == TFM_EDGE_SLIDE) {
projectEdgeSlideData(t, false);
}
else if (t->mode == TFM_VERT_SLIDE) {
projectVertSlideData(t, false);
}
DAG_id_tag_update(t->obedit->data, 0); /* sets recalc flags */
EDBM_mesh_normals_update(em);