Commit: 58652301dee685f67edf03c2bfcfbafe15a7cb6e
Author: Campbell Barton
Date:   Mon Feb 16 18:49:18 2015 +1100
Branches: master
https://developer.blender.org/rB58652301dee685f67edf03c2bfcfbafe15a7cb6e

Vert/Edge Slide: better UV interpolation

Ignore faces which the sliding vert is outside of.

===================================================================

M       source/blender/bmesh/intern/bmesh_interp.c
M       source/blender/bmesh/intern/bmesh_interp.h
M       source/blender/editors/transform/transform.c
M       source/blender/editors/transform/transform.h

===================================================================

diff --git a/source/blender/bmesh/intern/bmesh_interp.c 
b/source/blender/bmesh/intern/bmesh_interp.c
index a88f38c..d60c01b 100644
--- a/source/blender/bmesh/intern/bmesh_interp.c
+++ b/source/blender/bmesh/intern/bmesh_interp.c
@@ -925,12 +925,15 @@ struct LoopWalkCtx {
        /* reference for this contiguous fan */
        const void *data_ref;
        int data_len;
+
+       /* accumulate 'LoopGroupCD.weight' to make unit length */
+       float weight_accum;
+
        /* both arrays the size of the 'BM_vert_face_count(v)'
         * each contiguous fan gets a slide of these arrays */
        void **data_array;
+       int *data_index_array;
        float *weight_array;
-       /* accumulate 'LoopGroupCD.weight' to make unit length */
-       float weight_accum;
 };
 
 /* Store vars to pass into 'CustomData_bmesh_interp' */
@@ -939,6 +942,8 @@ struct LoopGroupCD {
        void **data;
        /* weights (aligned with 'data') */
        float *data_weights;
+       /* index-in-face */
+       int *data_index;
        /* number of loops in the fan */
        int data_len;
 };
@@ -948,6 +953,7 @@ static void bm_loop_walk_add(struct LoopWalkCtx *lwc, 
BMLoop *l)
        const float w = BM_loop_calc_face_angle(l);
        BM_elem_flag_enable(l, BM_ELEM_INTERNAL_TAG);
        lwc->data_array[lwc->data_len] = BM_ELEM_CD_GET_VOID_P(l, 
lwc->cd_layer_offset);
+       lwc->data_index_array[lwc->data_len] = BM_elem_index_get(l);
        lwc->weight_array[lwc->data_len] = w;
        lwc->weight_accum += w;
 
@@ -1001,11 +1007,14 @@ LinkNode *BM_vert_loop_groups_data_layer_create(BMesh 
*bm, BMVert *v, int layer_
        loop_num = 0;
        BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) {
                BM_elem_flag_disable(l, BM_ELEM_INTERNAL_TAG);
+               BM_elem_index_set(l, loop_num);  /* set_dirty! */
                loop_num++;
        }
+       bm->elem_index_dirty |= BM_LOOP;
 
        lwc.data_len = 0;
        lwc.data_array = BLI_memarena_alloc(lwc.arena, sizeof(void *) * 
loop_num);
+       lwc.data_index_array = BLI_memarena_alloc(lwc.arena, sizeof(int) * 
loop_num);
        lwc.weight_array = BLI_memarena_alloc(lwc.arena, sizeof(float) * 
loop_num);
 
        BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) {
@@ -1017,6 +1026,7 @@ LinkNode *BM_vert_loop_groups_data_layer_create(BMesh 
*bm, BMVert *v, int layer_
 
                        /* assign len-last */
                        lf->data         = &lwc.data_array[lwc.data_len];
+                       lf->data_index   = &lwc.data_index_array[lwc.data_len];
                        lf->data_weights = &lwc.weight_array[lwc.data_len];
                        lwc.weight_accum = 0.0f;
 
@@ -1040,12 +1050,48 @@ LinkNode *BM_vert_loop_groups_data_layer_create(BMesh 
*bm, BMVert *v, int layer_
        return groups;
 }
 
-static void bm_vert_loop_groups_data_layer_merge__single(BMesh *bm, void 
*lf_p, void *data, int type)
+static void bm_vert_loop_groups_data_layer_merge__single(
+        BMesh *bm, void *lf_p, void *data, int type)
+{
+       struct LoopGroupCD *lf = lf_p;
+       int i;
+       const float *data_weights;
+
+       data_weights = lf->data_weights;
+
+       CustomData_bmesh_interp(&bm->ldata, lf->data, data_weights, NULL, 
lf->data_len, data);
+
+       for (i = 0; i < lf->data_len; i++) {
+               CustomData_copy_elements(type, data, lf->data[i], 1);
+       }
+}
+
+static void bm_vert_loop_groups_data_layer_merge_weights__single(
+        BMesh *bm, void *lf_p, void *data, int type, const float *loop_weights)
 {
        struct LoopGroupCD *lf = lf_p;
        int i;
+       const float *data_weights;
+
+       /* re-weight */
+       float *temp_weights = BLI_array_alloca(temp_weights, lf->data_len);
+       float weight_accum = 0.0f;
 
-       CustomData_bmesh_interp(&bm->ldata, lf->data, lf->data_weights, NULL, 
lf->data_len, data);
+       for (i = 0; i < lf->data_len; i++) {
+               float w = loop_weights[lf->data_index[i]] * lf->data_weights[i];
+               temp_weights[i] = w;
+               weight_accum += w;
+       }
+
+       if (LIKELY(weight_accum != 0.0f)) {
+               mul_vn_fl(temp_weights, lf->data_len, 1.0f / weight_accum);
+               data_weights = temp_weights;
+       }
+       else {
+               data_weights = lf->data_weights;
+       }
+
+       CustomData_bmesh_interp(&bm->ldata, lf->data, data_weights, NULL, 
lf->data_len, data);
 
        for (i = 0; i < lf->data_len; i++) {
                CustomData_copy_elements(type, data, lf->data[i], 1);
@@ -1066,4 +1112,19 @@ void BM_vert_loop_groups_data_layer_merge(BMesh *bm, 
LinkNode *groups, int layer
        } while ((groups = groups->next));
 }
 
+/**
+ * A version of #BM_vert_loop_groups_data_layer_merge
+ * that takes an array of loop-weights (aligned with #BM_LOOPS_OF_VERT 
iterator)
+ */
+void BM_vert_loop_groups_data_layer_merge_weights(BMesh *bm, LinkNode *groups, 
int layer_n, const float *loop_weights)
+{
+       int type = bm->ldata.layers[layer_n].type;
+       int size = CustomData_sizeof(type);
+       void *data = alloca(size);
+
+       do {
+               bm_vert_loop_groups_data_layer_merge_weights__single(bm, 
groups->link, data, type, loop_weights);
+       } while ((groups = groups->next));
+}
+
 /** \} */
\ No newline at end of file
diff --git a/source/blender/bmesh/intern/bmesh_interp.h 
b/source/blender/bmesh/intern/bmesh_interp.h
index cd6d5e2..1c1c063 100644
--- a/source/blender/bmesh/intern/bmesh_interp.h
+++ b/source/blender/bmesh/intern/bmesh_interp.h
@@ -54,5 +54,6 @@ void  BM_loop_interp_from_face(BMesh *bm, BMLoop *target, 
BMFace *source,
 void  BM_face_multires_bounds_smooth(BMesh *bm, BMFace *f);
 struct LinkNode *BM_vert_loop_groups_data_layer_create(BMesh *bm, BMVert *v, 
int layer_n, struct MemArena *arena);
 void BM_vert_loop_groups_data_layer_merge(BMesh *bm, struct LinkNode *groups, 
int layer_n);
+void BM_vert_loop_groups_data_layer_merge_weights(BMesh *bm, struct LinkNode 
*groups, int layer_n, const float *loop_weights);
 
 #endif /* __BMESH_INTERP_H__ */
diff --git a/source/blender/editors/transform/transform.c 
b/source/blender/editors/transform/transform.c
index 1740e54..193bcbb 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 84a81e8..8d6c693 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_

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to