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 | |
parent | 421d0f3bdea56ef056372476a24b1fc5e5ee06e5 (diff) |
Vert/Edge Slide: better UV interpolation
Ignore faces which the sliding vert is outside of.
Diffstat (limited to 'source/blender/editors')
-rw-r--r-- | source/blender/editors/transform/transform.c | 90 | ||||
-rw-r--r-- | source/blender/editors/transform/transform.h | 10 |
2 files changed, 74 insertions, 26 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; diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index 84a81e8b3d8..8d6c693b14a 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -204,19 +204,20 @@ struct GHash; typedef struct TransDataGenericSlideVert { struct BMVert *v; struct LinkNode **cd_loop_groups; + float co_orig_3d[3]; } TransDataGenericSlideVert; typedef struct TransDataEdgeSlideVert { /* TransDataGenericSlideVert */ struct BMVert *v; struct LinkNode **cd_loop_groups; - /* end generic */ - - struct BMVert *v_a, *v_b; float v_co_orig[3]; + /* end generic */ float edge_len; + struct BMVert *v_a, *v_b; + /* add origvert.co to get the original locations */ float dir_a[3], dir_b[3]; @@ -228,6 +229,7 @@ typedef struct TransDataEdgeSlideVert { typedef struct SlideOrigData { /* flag that is set when origfaces is initialized */ bool use_origfaces; + struct GHash *origverts; /* map {BMVert: TransDataGenericSlideVert} */ struct GHash *origfaces; struct BMesh *bm_origfaces; @@ -261,9 +263,9 @@ typedef struct TransDataVertSlideVert { /* TransDataGenericSlideVert */ BMVert *v; struct LinkNode **cd_loop_groups; + float co_orig_3d[3]; /* end generic */ - float co_orig_3d[3]; float co_orig_2d[2]; float (*co_link_orig_3d)[3]; float (*co_link_orig_2d)[2]; |