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:
authorCampbell Barton <ideasman42@gmail.com>2015-01-11 18:18:20 +0300
committerCampbell Barton <ideasman42@gmail.com>2015-02-08 09:58:11 +0300
commit51b645a655eb41c5b73d8487ee7df9ba99fc692b (patch)
tree43927959e07be536c308fc6291ee78d40b8ce722 /source/blender/editors/transform
parent8ff099bc7b2ec563c56f1a4f518d3925bd730fbb (diff)
Initial vertex slide UV-correct support
Still need to adjust for contiguous UV's
Diffstat (limited to 'source/blender/editors/transform')
-rw-r--r--source/blender/editors/transform/transform.c213
-rw-r--r--source/blender/editors/transform/transform.h19
-rw-r--r--source/blender/editors/transform/transform_conversions.c6
-rw-r--r--source/blender/editors/transform/transform_ops.c2
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)