Commit: 1ddfe6676de1b382d2c9b06cc9c68f50659d13de
Author: Campbell Barton
Date:   Thu Nov 13 16:37:32 2014 +0100
Branches: master
https://developer.blender.org/rB1ddfe6676de1b382d2c9b06cc9c68f50659d13de

BMesh: shrink/fatten faces-normals in face mode

nice for solid-modeling, gives better results for partial selections.

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

M       source/blender/bmesh/intern/bmesh_polygon.c
M       source/blender/bmesh/intern/bmesh_polygon.h
M       source/blender/bmesh/intern/bmesh_queries.c
M       source/blender/bmesh/intern/bmesh_queries.h
M       source/blender/editors/transform/transform_conversions.c

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

diff --git a/source/blender/bmesh/intern/bmesh_polygon.c 
b/source/blender/bmesh/intern/bmesh_polygon.c
index a8e1acd..a5a7bc5 100644
--- a/source/blender/bmesh/intern/bmesh_polygon.c
+++ b/source/blender/bmesh/intern/bmesh_polygon.c
@@ -422,6 +422,43 @@ void BM_edge_normals_update(BMEdge *e)
        BM_vert_normal_update(e->v2);
 }
 
+bool BM_vert_normal_update_ex(BMVert *v, const char hflag, float r_no[3])
+{
+       /* TODO, we can normalize each edge only once, then compare with 
previous edge */
+
+       BMIter liter;
+       BMLoop *l;
+       int len = 0;
+
+       zero_v3(r_no);
+
+       BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) {
+               if (BM_elem_flag_test(l->f, hflag)) {
+                       float vec1[3], vec2[3], fac;
+
+                       /* Same calculation used in BM_mesh_normals_update */
+                       sub_v3_v3v3(vec1, l->v->co, l->prev->v->co);
+                       sub_v3_v3v3(vec2, l->next->v->co, l->v->co);
+                       normalize_v3(vec1);
+                       normalize_v3(vec2);
+
+                       fac = saacos(-dot_v3v3(vec1, vec2));
+
+                       madd_v3_v3fl(r_no, l->f->no, fac);
+
+                       len++;
+               }
+       }
+
+       if (len) {
+               normalize_v3(r_no);
+               return true;
+       }
+       else {
+               return false;
+       }
+}
+
 /**
  * update a vert normal (but not the faces incident on it)
  */
@@ -431,12 +468,13 @@ void BM_vert_normal_update(BMVert *v)
 
        BMIter liter;
        BMLoop *l;
-       float vec1[3], vec2[3], fac;
        int len = 0;
 
        zero_v3(v->no);
 
        BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) {
+               float vec1[3], vec2[3], fac;
+
                /* Same calculation used in BM_mesh_normals_update */
                sub_v3_v3v3(vec1, l->v->co, l->prev->v->co);
                sub_v3_v3v3(vec2, l->next->v->co, l->v->co);
diff --git a/source/blender/bmesh/intern/bmesh_polygon.h 
b/source/blender/bmesh/intern/bmesh_polygon.h
index 91e649e..d62c81c 100644
--- a/source/blender/bmesh/intern/bmesh_polygon.h
+++ b/source/blender/bmesh/intern/bmesh_polygon.h
@@ -49,6 +49,7 @@ void  BM_face_normal_update(BMFace *f) ATTR_NONNULL();
 
 void  BM_edge_normals_update(BMEdge *e) ATTR_NONNULL();
 
+bool BM_vert_normal_update_ex(BMVert *v, const char hflag, float r_no[3]);
 void  BM_vert_normal_update(BMVert *v) ATTR_NONNULL();
 void  BM_vert_normal_update_all(BMVert *v) ATTR_NONNULL();
 
diff --git a/source/blender/bmesh/intern/bmesh_queries.c 
b/source/blender/bmesh/intern/bmesh_queries.c
index ca40cf9..0792e95 100644
--- a/source/blender/bmesh/intern/bmesh_queries.c
+++ b/source/blender/bmesh/intern/bmesh_queries.c
@@ -1373,7 +1373,7 @@ float BM_vert_calc_shell_factor(BMVert *v)
 }
 /* alternate version of #BM_vert_calc_shell_factor which only
  * uses 'hflag' faces, but falls back to all if none found. */
-float BM_vert_calc_shell_factor_ex(BMVert *v, const char hflag)
+float BM_vert_calc_shell_factor_ex(BMVert *v, const float no[3], const char 
hflag)
 {
        BMIter iter;
        BMLoop *l;
@@ -1384,7 +1384,7 @@ float BM_vert_calc_shell_factor_ex(BMVert *v, const char 
hflag)
        BM_ITER_ELEM (l, &iter, v, BM_LOOPS_OF_VERT) {
                if (BM_elem_flag_test(l->f, hflag)) {  /* <-- main difference 
to BM_vert_calc_shell_factor! */
                        const float face_angle = BM_loop_calc_face_angle(l);
-                       accum_shell += shell_v3v3_normalized_to_dist(v->no, 
l->f->no) * face_angle;
+                       accum_shell += shell_v3v3_normalized_to_dist(no, 
l->f->no) * face_angle;
                        accum_angle += face_angle;
                        tot_sel++;
                }
diff --git a/source/blender/bmesh/intern/bmesh_queries.h 
b/source/blender/bmesh/intern/bmesh_queries.h
index c8578a8..b5b423e 100644
--- a/source/blender/bmesh/intern/bmesh_queries.h
+++ b/source/blender/bmesh/intern/bmesh_queries.h
@@ -97,7 +97,7 @@ void    BM_edge_calc_face_tangent(const BMEdge *e, const 
BMLoop *e_loop, float r
 
 float   BM_vert_calc_edge_angle(BMVert *v) ATTR_WARN_UNUSED_RESULT 
ATTR_NONNULL();
 float   BM_vert_calc_shell_factor(BMVert *v) ATTR_WARN_UNUSED_RESULT 
ATTR_NONNULL();
-float   BM_vert_calc_shell_factor_ex(BMVert *v, const char hflag) 
ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+float   BM_vert_calc_shell_factor_ex(BMVert *v, const float no[3], const char 
hflag) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
 float   BM_vert_calc_mean_tagged_edge_length(BMVert *v) 
ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
 
 BMLoop *BM_face_find_shortest_loop(BMFace *f) ATTR_WARN_UNUSED_RESULT 
ATTR_NONNULL();
diff --git a/source/blender/editors/transform/transform_conversions.c 
b/source/blender/editors/transform/transform_conversions.c
index 903b8c3..dc0b840 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -2167,6 +2167,7 @@ static void VertsToTransData(TransInfo *t, TransData *td, 
TransDataExtension *tx
                              BMEditMesh *em, BMVert *eve, float *bweight,
                              struct TransIslandData *v_island)
 {
+       float *no, _no[3];
        BLI_assert(BM_elem_flag_test(eve, BM_ELEM_HIDDEN) == 0);
 
        td->flag = 0;
@@ -2176,19 +2177,30 @@ static void VertsToTransData(TransInfo *t, TransData 
*td, TransDataExtension *tx
        td->loc = eve->co;
        copy_v3_v3(td->iloc, td->loc);
 
+       if ((t->mode == TFM_SHRINKFATTEN) &&
+           (em->selectmode & SCE_SELECT_FACE) &&
+           BM_elem_flag_test(eve, BM_ELEM_SELECT) &&
+           (BM_vert_normal_update_ex(eve, BM_ELEM_SELECT, _no)))
+       {
+               no = _no;
+       }
+       else {
+               no = eve->no;
+       }
+
        if (v_island) {
                copy_v3_v3(td->center, v_island->co);
                copy_m3_m3(td->axismtx, v_island->axismtx);
        }
        else if (t->around == V3D_LOCAL) {
                copy_v3_v3(td->center, td->loc);
-               createSpaceNormal(td->axismtx, eve->no);
+               createSpaceNormal(td->axismtx, no);
        }
        else {
                copy_v3_v3(td->center, td->loc);
 
                /* Setting normals */
-               copy_v3_v3(td->axismtx[2], eve->no);
+               copy_v3_v3(td->axismtx[2], no);
                td->axismtx[0][0]        =
                    td->axismtx[0][1]    =
                    td->axismtx[0][2]    =
@@ -2217,7 +2229,7 @@ static void VertsToTransData(TransInfo *t, TransData *td, 
TransDataExtension *tx
        }
        else if (t->mode == TFM_SHRINKFATTEN) {
                td->ext = tx;
-               tx->isize[0] = BM_vert_calc_shell_factor_ex(eve, 
BM_ELEM_SELECT);
+               tx->isize[0] = BM_vert_calc_shell_factor_ex(eve, no, 
BM_ELEM_SELECT);
        }
 }

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

Reply via email to