diff options
author | Campbell Barton <ideasman42@gmail.com> | 2015-02-16 10:49:18 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2015-02-16 10:49:18 +0300 |
commit | 58652301dee685f67edf03c2bfcfbafe15a7cb6e (patch) | |
tree | 812b7cf32e5f0437355780078f44bf4830f504a4 /source/blender/editors/transform/transform.c | |
parent | 421d0f3bdea56ef056372476a24b1fc5e5ee06e5 (diff) |
Vert/Edge Slide: better UV interpolation
Ignore faces which the sliding vert is outside of.
Diffstat (limited to 'source/blender/editors/transform/transform.c')
-rw-r--r-- | source/blender/editors/transform/transform.c | 90 |
1 files changed, 68 insertions, 22 deletions
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 1740e54abbf..193bcbb3691 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -44,6 +44,7 @@ #include "DNA_movieclip_types.h" #include "DNA_scene_types.h" /* PET modes */ +#include "BLI_alloca.h" #include "BLI_utildefines.h" #include "BLI_math.h" #include "BLI_rect.h" @@ -5269,6 +5270,8 @@ static void slide_origdata_create_data( sod->arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__); + sod->origverts = BLI_ghash_ptr_new_ex(__func__, v_num); + for (i = 0; i < v_num; i++, sv = (void *)(((char *)sv) + v_stride)) { BMIter fiter; BMFace *f; @@ -5294,6 +5297,64 @@ static void slide_origdata_create_data( else { sv->cd_loop_groups = NULL; } + + BLI_ghash_insert(sod->origverts, sv->v, sv); + } + } +} + +/** + * If we're sliding the vert, return its original location, if not, the current location is good. + */ +static const float *slide_origdata_orig_vert_co(SlideOrigData *sod, BMVert *v) +{ + TransDataGenericSlideVert *sv = BLI_ghash_lookup(sod->origverts, v); + return sv ? sv->co_orig_3d : v->co; +} + +static void slide_origdata_interp_data_vert( + SlideOrigData *sod, BMesh *bm, bool is_final, + TransDataGenericSlideVert *sv) +{ + BMIter liter; + BMLoop *l; + int j; + float *loop_weights; + const bool do_loop_weight = (len_squared_v3v3(sv->v->co, sv->co_orig_3d) > FLT_EPSILON); + + // BM_ITER_ELEM (l, &liter, sv->v, BM_LOOPS_OF_VERT) { + l = BM_iter_new(&liter, bm, BM_LOOPS_OF_VERT, sv->v); + loop_weights = do_loop_weight ? BLI_array_alloca(loop_weights, liter.count) : NULL; + for (j = 0 ; l; l = BM_iter_step(&liter), j++) { + BMFace *f_copy; /* the copy of 'f' */ + + f_copy = BLI_ghash_lookup(sod->origfaces, l->f); + + /* 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(bm, l, f_copy, false, is_final); + + /* make sure face-attributes are correct (e.g. MTexPoly) */ + BM_elem_attrs_copy(sod->bm_origfaces, bm, f_copy, l->f); + + /* weight the loop */ + if (do_loop_weight) { + const float *v_prev = slide_origdata_orig_vert_co(sod, l->prev->v); + const float *v_next = slide_origdata_orig_vert_co(sod, l->next->v); + const float dist = dist_signed_squared_to_corner_v3v3v3(sv->v->co, v_prev, sv->co_orig_3d, v_next, f_copy->no); + const float eps = 0.00001f; + loop_weights[j] = (dist >= 0.0f) ? 1.0f : ((dist <= -eps) ? 0.0f : (1.0f + (dist / eps))); + } + } + + if (do_loop_weight) { + for (j = 0; j < sod->layer_math_map_num; j++) { + BM_vert_loop_groups_data_layer_merge_weights(bm, sv->cd_loop_groups[j], sod->layer_math_map[j], loop_weights); + } + } + else { + for (j = 0; j < sod->layer_math_map_num; j++) { + BM_vert_loop_groups_data_layer_merge(bm, sv->cd_loop_groups[j], sod->layer_math_map[j]); } } } @@ -5305,33 +5366,13 @@ static void slide_origdata_interp_data( { if (sod->use_origfaces) { BMEditMesh *em = BKE_editmesh_from_object(t->obedit); + BMesh *bm = em->bm; unsigned int i; - const int *layer_math_map = sod->layer_math_map; - for (i = 0; i < v_num; i++, sv = (void *)(((char *)sv) + v_stride)) { if (sv->cd_loop_groups) { - BMIter fiter; - BMLoop *l; - int j; - - BM_ITER_ELEM (l, &fiter, sv->v, BM_LOOPS_OF_VERT) { - BMFace *f_copy; /* the copy of 'f' */ - - f_copy = BLI_ghash_lookup(sod->origfaces, l->f); - - /* 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, false, is_final); - - /* make sure face-attributes are correct (e.g. MTexPoly) */ - BM_elem_attrs_copy(sod->bm_origfaces, em->bm, f_copy, l->f); - } - - for (j = 0; j < sod->layer_math_map_num; j++) { - BM_vert_loop_groups_data_layer_merge(em->bm, sv->cd_loop_groups[j], layer_math_map[j]); - } + slide_origdata_interp_data_vert(sod, bm, is_final, sv); } } } @@ -5351,6 +5392,11 @@ static void slide_origdata_free_date( sod->origfaces = NULL; } + if (sod->origverts) { + BLI_ghash_free(sod->origverts, NULL, NULL); + sod->origverts = NULL; + } + if (sod->arena) { BLI_memarena_free(sod->arena); sod->arena = NULL; |