diff options
author | Campbell Barton <ideasman42@gmail.com> | 2014-11-13 18:37:32 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2014-11-13 18:41:56 +0300 |
commit | 1ddfe6676de1b382d2c9b06cc9c68f50659d13de (patch) | |
tree | dbf6e2344cf842287c887e79ce3ee82d077ae7c1 | |
parent | 96ca64629d3373293b083540e593f500cb9a4e7d (diff) |
BMesh: shrink/fatten faces-normals in face mode
nice for solid-modeling, gives better results for partial selections.
-rw-r--r-- | source/blender/bmesh/intern/bmesh_polygon.c | 40 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_polygon.h | 1 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_queries.c | 4 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_queries.h | 2 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_conversions.c | 18 |
5 files changed, 58 insertions, 7 deletions
diff --git a/source/blender/bmesh/intern/bmesh_polygon.c b/source/blender/bmesh/intern/bmesh_polygon.c index a8e1acd9c71..a5a7bc5189e 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 91e649edb16..d62c81c4052 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 ca40cf9e6c8..0792e956e5b 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 c8578a8b093..b5b423ed58f 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 903b8c36e3f..dc0b8403e4f 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); } } |