diff options
Diffstat (limited to 'source/blender/editors/transform')
-rw-r--r-- | source/blender/editors/transform/transform.c | 213 | ||||
-rw-r--r-- | source/blender/editors/transform/transform.h | 19 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_conversions.c | 6 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_ops.c | 2 |
4 files changed, 177 insertions, 63 deletions
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 2679cf1992e..14bbdebd138 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -93,8 +93,8 @@ #define MAX_INFO_LEN 256 static void drawTransformApply(const struct bContext *C, ARegion *ar, void *arg); -static int doEdgeSlide(TransInfo *t, float perc); -static int doVertSlide(TransInfo *t, float perc); +static void doEdgeSlide(TransInfo *t, float perc); +static void doVertSlide(TransInfo *t, float perc); static void drawEdgeSlide(const struct bContext *C, TransInfo *t); static void drawVertSlide(const struct bContext *C, TransInfo *t); @@ -671,8 +671,11 @@ static void viewRedrawPost(bContext *C, TransInfo *t) WM_main_add_notifier(NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL); /* redraw UV editor */ - if (t->mode == TFM_EDGE_SLIDE && (t->settings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT)) + if (ELEM(t->mode, TFM_VERT_SLIDE, TFM_EDGE_SLIDE) && + (t->settings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT)) + { WM_event_add_notifier(C, NC_GEOM | ND_DATA, NULL); + } /* XXX temp, first hack to get auto-render in compositor work (ton) */ WM_event_add_notifier(C, NC_SCENE | ND_TRANSFORM_DONE, CTX_data_scene(C)); @@ -5110,6 +5113,85 @@ static void applyBoneEnvelope(TransInfo *t, const int UNUSED(mval[2])) } /** \} */ +/* -------------------------------------------------------------------- */ +/* Original Data Store */ + +/** \name Orig-Data Store Utility Functions + * \{ */ + +static void slide_origdata_init_flag( + TransInfo *t, SlideOrigData *sod) +{ + BMEditMesh *em = BKE_editmesh_from_object(t->obedit); + BMesh *bm = em->bm; + + if ((t->settings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT) && + /* don't do this at all for non-basis shape keys, too easy to + * accidentally break uv maps or vertex colors then */ + (bm->shapenr <= 1)) + { + sod->use_origfaces = true; + } + else { + sod->use_origfaces = false; + } +} + +static void slide_origdata_init_data( + TransInfo *t, SlideOrigData *sod) +{ + if (sod->use_origfaces) { + BMEditMesh *em = BKE_editmesh_from_object(t->obedit); + BMesh *bm = em->bm; + + sod->origfaces = BLI_ghash_ptr_new(__func__); + sod->bm_origfaces = BM_mesh_create(&bm_mesh_allocsize_default); + /* we need to have matching customdata */ + BM_mesh_copy_init_customdata(sod->bm_origfaces, bm, NULL); + } +} + +static void slide_origdata_create_date( + TransInfo *t, SlideOrigData *sod, + BMVert **v_pt, 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; + for (i = 0; i < v_num; i++, v_pt = (void *)(((char *)v_pt) + v_stride)) { + BMIter fiter; + BMFace *f; + BMVert *v = *v_pt; + + BM_ITER_ELEM (f, &fiter, v, BM_FACES_OF_VERT) { + if (!BLI_ghash_haskey(sod->origfaces, f)) { + BMFace *f_copy = BM_face_copy(sod->bm_origfaces, bm, f, true, true); + BLI_ghash_insert(sod->origfaces, f, f_copy); + } + } + } + } +} + +static void slide_origdata_free_date( + SlideOrigData *sod) +{ + if (sod->use_origfaces) { + if (sod->bm_origfaces) { + BM_mesh_free(sod->bm_origfaces); + sod->bm_origfaces = NULL; + } + + if (sod->origfaces) { + BLI_ghash_free(sod->origfaces, NULL, NULL); + sod->origfaces = NULL; + } + } +} + +/** \} */ /* -------------------------------------------------------------------- */ /* Transform (Edge Slide) */ @@ -5368,16 +5450,7 @@ static bool createEdgeSlideVerts(TransInfo *t) rv3d = t->ar ? t->ar->regiondata : NULL; } - if ((t->settings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT) && - /* don't do this at all for non-basis shape keys, too easy to - * accidentally break uv maps or vertex colors then */ - (bm->shapenr <= 1)) - { - sld->use_origfaces = true; - } - else { - sld->use_origfaces = false; - } + slide_origdata_init_flag(t, &sld->orig_data); sld->is_proportional = true; sld->curr_sv_index = 0; @@ -5769,30 +5842,12 @@ static bool createEdgeSlideVerts(TransInfo *t) } bmesh_edit_begin(bm, BMO_OPTYPE_FLAG_UNTAN_MULTIRES); - - if (sld->use_origfaces) { - sld->origfaces = BLI_ghash_ptr_new(__func__); - sld->bm_origfaces = BM_mesh_create(&bm_mesh_allocsize_default); - /* we need to have matching customdata */ - BM_mesh_copy_init_customdata(sld->bm_origfaces, bm, NULL); - } + slide_origdata_init_data(t, &sld->orig_data); + slide_origdata_create_date(t, &sld->orig_data, &sld->sv->v, sizeof(*sld->sv), sld->totsv); /*create copies of faces for customdata projection*/ sv_array = sld->sv; for (i = 0; i < sld->totsv; i++, sv_array++) { - BMIter fiter; - BMFace *f; - - - if (sld->use_origfaces) { - BM_ITER_ELEM (f, &fiter, sv_array->v, BM_FACES_OF_VERT) { - if (!BLI_ghash_haskey(sld->origfaces, f)) { - BMFace *f_copy = BM_face_copy(sld->bm_origfaces, bm, f, true, true); - BLI_ghash_insert(sld->origfaces, f, f_copy); - } - } - } - /* switch a/b if loop direction is different from global direction */ l_nr = sv_array->loop_nr; if (dot_v3v3(loop_dir[l_nr], mval_dir) < 0.0f) { @@ -5836,11 +5891,12 @@ static bool createEdgeSlideVerts(TransInfo *t) void projectEdgeSlideData(TransInfo *t, bool is_final) { EdgeSlideData *sld = t->customData; + SlideOrigData *sod = &sld->orig_data; TransDataEdgeSlideVert *sv; BMEditMesh *em = sld->em; int i; - if (sld->use_origfaces == false) { + if (sod->use_origfaces == false) { return; } @@ -5852,7 +5908,7 @@ void projectEdgeSlideData(TransInfo *t, bool is_final) BMFace *f_copy; /* the copy of 'f' */ BMFace *f_copy_flip; /* the copy of 'f' or detect if we need to flip to the shorter side. */ - f_copy = BLI_ghash_lookup(sld->origfaces, l->f); + f_copy = BLI_ghash_lookup(sod->origfaces, l->f); /* project onto copied projection face */ f_copy_flip = f_copy; @@ -5866,12 +5922,12 @@ void projectEdgeSlideData(TransInfo *t, bool is_final) if (sld->perc < 0.0f) { if (BM_vert_in_face(sv->v_b, l_ed_sel->radial_next->f)) { - f_copy_flip = BLI_ghash_lookup(sld->origfaces, l_ed_sel->radial_next->f); + f_copy_flip = BLI_ghash_lookup(sod->origfaces, l_ed_sel->radial_next->f); } } else if (sld->perc > 0.0f) { if (BM_vert_in_face(sv->v_a, l_ed_sel->radial_next->f)) { - f_copy_flip = BLI_ghash_lookup(sld->origfaces, l_ed_sel->radial_next->f); + f_copy_flip = BLI_ghash_lookup(sod->origfaces, l_ed_sel->radial_next->f); } } @@ -5957,7 +6013,7 @@ void projectEdgeSlideData(TransInfo *t, bool is_final) l_adj = l; } - f_copy_flip = BLI_ghash_lookup(sld->origfaces, l_adj->f); + f_copy_flip = BLI_ghash_lookup(sod->origfaces, l_adj->f); } } } @@ -5974,34 +6030,23 @@ void projectEdgeSlideData(TransInfo *t, bool is_final) } /* make sure face-attributes are correct (e.g. MTexPoly) */ - BM_elem_attrs_copy(sld->bm_origfaces, em->bm, f_copy, l->f); + BM_elem_attrs_copy(sod->bm_origfaces, em->bm, f_copy, l->f); } } } void freeEdgeSlideTempFaces(EdgeSlideData *sld) { - if (sld->use_origfaces) { - if (sld->bm_origfaces) { - BM_mesh_free(sld->bm_origfaces); - sld->bm_origfaces = NULL; - } - - if (sld->origfaces) { - BLI_ghash_free(sld->origfaces, NULL, NULL); - sld->origfaces = NULL; - } - } + slide_origdata_free_date(&sld->orig_data); } - void freeEdgeSlideVerts(TransInfo *t) { EdgeSlideData *sld = t->customData; if (!sld) return; - + freeEdgeSlideTempFaces(sld); bmesh_edit_end(sld->em->bm, BMO_OPTYPE_FLAG_UNTAN_MULTIRES); @@ -6175,7 +6220,7 @@ static void drawEdgeSlide(const struct bContext *C, TransInfo *t) } } -static int doEdgeSlide(TransInfo *t, float perc) +static void doEdgeSlide(TransInfo *t, float perc) { EdgeSlideData *sld = t->customData; TransDataEdgeSlideVert *svlist = sld->sv, *sv; @@ -6232,8 +6277,6 @@ static int doEdgeSlide(TransInfo *t, float perc) } projectEdgeSlideData(t, 0); - - return 1; } static void applyEdgeSlide(TransInfo *t, const int UNUSED(mval[2])) @@ -6398,6 +6441,8 @@ static bool createVertSlideVerts(TransInfo *t) rv3d = ar ? ar->regiondata : NULL; } + slide_origdata_init_flag(t, &sld->orig_data); + sld->is_proportional = true; sld->curr_sv_index = 0; sld->flipped_vtx = false; @@ -6493,6 +6538,10 @@ static bool createVertSlideVerts(TransInfo *t) sld->sv = sv_array; sld->totsv = j; + bmesh_edit_begin(bm, BMO_OPTYPE_FLAG_UNTAN_MULTIRES); + slide_origdata_init_data(t, &sld->orig_data); + slide_origdata_create_date(t, &sld->orig_data, &sld->sv->v, sizeof(*sld->sv), sld->totsv); + sld->em = em; sld->perc = 0.0f; @@ -6507,6 +6556,53 @@ static bool createVertSlideVerts(TransInfo *t) return true; } +void projectVertSlideData(TransInfo *t, bool is_final) +{ + VertSlideData *sld = t->customData; + SlideOrigData *sod = &sld->orig_data; + TransDataVertSlideVert *sv; + BMEditMesh *em = sld->em; + int i; + + if (sod->use_origfaces == false) { + return; + } + + for (i = 0, sv = sld->sv; i < sld->totsv; sv++, i++) { + BMIter fiter; + BMLoop *l; + + BM_ITER_ELEM (l, &fiter, sv->v, BM_LOOPS_OF_VERT) { + BMFace *f_copy; /* the copy of 'f' */ + BMFace *f_copy_flip; /* the copy of 'f' or detect if we need to flip to the shorter side. */ + + f_copy = BLI_ghash_lookup(sod->origfaces, l->f); + + /* project onto copied projection face */ + f_copy_flip = f_copy; + + /* only loop data, no vertex data since that contains shape keys, + * and we do not want to mess up other shape keys */ + BM_loop_interp_from_face(em->bm, l, f_copy_flip, false, false); + + if (is_final) { + BM_loop_interp_multires(em->bm, l, f_copy_flip); + if (f_copy != f_copy_flip) { + BM_loop_interp_multires(em->bm, l, f_copy); + } + } + + /* make sure face-attributes are correct (e.g. MTexPoly) */ + BM_elem_attrs_copy(sod->bm_origfaces, em->bm, f_copy, l->f); + } + } +} + +void freeVertSlideTempFaces(VertSlideData *sld) +{ + slide_origdata_free_date(&sld->orig_data); +} + void freeVertSlideVerts(TransInfo *t) { VertSlideData *sld = t->customData; @@ -6514,6 +6610,9 @@ void freeVertSlideVerts(TransInfo *t) if (!sld) return; + freeVertSlideTempFaces(sld); + + bmesh_edit_end(sld->em->bm, BMO_OPTYPE_FLAG_UNTAN_MULTIRES); if (sld->totsv > 0) { TransDataVertSlideVert *sv = sld->sv; @@ -6710,7 +6809,7 @@ static void drawVertSlide(const struct bContext *C, TransInfo *t) } } -static int doVertSlide(TransInfo *t, float perc) +static void doVertSlide(TransInfo *t, float perc) { VertSlideData *sld = t->customData; TransDataVertSlideVert *svlist = sld->sv, *sv; @@ -6750,7 +6849,7 @@ static int doVertSlide(TransInfo *t, float perc) } } - return 1; + projectVertSlideData(t, false); } static void applyVertSlide(TransInfo *t, const int UNUSED(mval[2])) diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index 0d824be862e..2330ec6e79e 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -213,18 +213,23 @@ typedef struct TransDataEdgeSlideVert { int loop_nr; } TransDataEdgeSlideVert; + +/* store original data so we can correct UV's and similar when sliding */ +typedef struct SlideOrigData { + /* flag that is set when origfaces is initialized */ + bool use_origfaces; + struct GHash *origfaces; + struct BMesh *bm_origfaces; +} SlideOrigData; + typedef struct EdgeSlideData { TransDataEdgeSlideVert *sv; int totsv; - - struct GHash *origfaces; int mval_start[2], mval_end[2]; struct BMEditMesh *em; - /* flag that is set when origfaces is initialized */ - bool use_origfaces; - struct BMesh *bm_origfaces; + SlideOrigData orig_data; float perc; @@ -251,6 +256,8 @@ typedef struct VertSlideData { struct BMEditMesh *em; + SlideOrigData orig_data; + float perc; bool is_proportional; @@ -699,7 +706,9 @@ void freeEdgeSlideTempFaces(EdgeSlideData *sld); void freeEdgeSlideVerts(TransInfo *t); void projectEdgeSlideData(TransInfo *t, bool is_final); +void freeVertSlideTempFaces(VertSlideData *sld); void freeVertSlideVerts(TransInfo *t); +void projectVertSlideData(TransInfo *t, bool is_final); /* TODO. transform_queries.c */ diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index cf4f1b02832..5deb5ee9635 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -5597,6 +5597,12 @@ void special_aftertrans_update(bContext *C, TransInfo *t) * during cleanup - psy-fi */ freeEdgeSlideTempFaces(sld); } + else if (t->mode == TFM_VERT_SLIDE) { + /* as above */ + VertSlideData *sld = t->customData; + projectVertSlideData(t, true); + freeVertSlideTempFaces(sld); + } if (t->obedit->type == OB_MESH) { special_aftertrans_update__mesh(C, t); diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c index 25dee50a192..1498e2894d4 100644 --- a/source/blender/editors/transform/transform_ops.c +++ b/source/blender/editors/transform/transform_ops.c @@ -868,7 +868,7 @@ static void TRANSFORM_OT_vert_slide(struct wmOperatorType *ot) RNA_def_float_factor(ot->srna, "value", 0, -10.0f, 10.0f, "Factor", "", -1.0f, 1.0f); - Transform_Properties(ot, P_MIRROR | P_SNAP); + Transform_Properties(ot, P_MIRROR | P_SNAP | P_CORRECT_UV); } static void TRANSFORM_OT_edge_crease(struct wmOperatorType *ot) |