diff options
author | Campbell Barton <ideasman42@gmail.com> | 2012-03-25 18:44:48 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2012-03-25 18:44:48 +0400 |
commit | fffe342d87548bc94f9258a1c8a2f7473b4bd8b2 (patch) | |
tree | f2bab2afcaddbb9a9560e8f2d94ecd63df6e89b3 /source/blender | |
parent | 105c282b9f59858f5438723c114eef316e554a04 (diff) |
bmesh inset: another small improvement - use the shared edge vector rather then the cross product between 2 faces if the faces infact share an edge - works best for non planer faces.
also added utility function - BM_loop_other_vert_loop
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/bmesh/intern/bmesh_queries.c | 50 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_queries.h | 1 | ||||
-rw-r--r-- | source/blender/bmesh/operators/bmo_inset.c | 27 |
3 files changed, 72 insertions, 6 deletions
diff --git a/source/blender/bmesh/intern/bmesh_queries.c b/source/blender/bmesh/intern/bmesh_queries.c index 8f1568119f8..24c60e22a90 100644 --- a/source/blender/bmesh/intern/bmesh_queries.c +++ b/source/blender/bmesh/intern/bmesh_queries.c @@ -152,6 +152,56 @@ BMLoop *BM_face_other_vert_loop(BMFace *f, BMVert *v_prev, BMVert *v) } /** + * \brief Other Loop in Face Sharing a Vert + * + * Finds the other loop that shares \a v with \a e loop in \a f. + * + * +----------+ <-- return the face loop of this vertex. + * | | + * | | + * | | + * +----------+ <-- This vertex defines the direction. + * l v + * ^ <------- This loop defines both the face to search + * and the edge, in combination with 'v' + * The faces loop direction is ignored. + */ + +BMLoop *BM_loop_other_vert_loop(BMLoop *l, BMVert *v) +{ +#if 0 /* works but slow */ + return BM_face_other_vert_loop(l->f, BM_edge_other_vert(l->e, v), v); +#else + BMEdge *e = l->e; + BMVert *v_prev = BM_edge_other_vert(e, v); + if (l->v == v) { + if (l->prev->v == v_prev) { + return l->next; + } + else { + BLI_assert(l->next->v == v_prev); + + return l->prev; + } + } + else { + BLI_assert(l->v == v_prev); + + if (l->prev->v == v) { + return l->prev->prev; + } + else { + BLI_assert(l->next->v == v); + return l->next->next; + } + } + + + +#endif +} + +/** * Returns TRUE if the vertex is used in a given face. */ diff --git a/source/blender/bmesh/intern/bmesh_queries.h b/source/blender/bmesh/intern/bmesh_queries.h index c2a718b49ce..f3dfa754f00 100644 --- a/source/blender/bmesh/intern/bmesh_queries.h +++ b/source/blender/bmesh/intern/bmesh_queries.h @@ -43,6 +43,7 @@ int BM_edge_loop_pair(BMEdge *e, BMLoop **r_la, BMLoop **r_lb); BMVert *BM_edge_other_vert(BMEdge *e, BMVert *v); BMLoop *BM_face_other_edge_loop(BMFace *f, BMEdge *e, BMVert *v); BMLoop *BM_face_other_vert_loop(BMFace *f, BMVert *v_prev, BMVert *v); +BMLoop *BM_loop_other_vert_loop(BMLoop *l, BMVert *v); int BM_vert_edge_count_nonwire(BMVert *v); int BM_vert_edge_count(BMVert *v); diff --git a/source/blender/bmesh/operators/bmo_inset.c b/source/blender/bmesh/operators/bmo_inset.c index 0cc0678c4ce..c8804877723 100644 --- a/source/blender/bmesh/operators/bmo_inset.c +++ b/source/blender/bmesh/operators/bmo_inset.c @@ -274,7 +274,7 @@ void bmo_inset_exec(BMesh *bm, BMOperator *op) * if both edges use the same face OR both faces have the same normal, * ...then we can calculate an edge that fits nicely between the 2 edge normals. * - * Otherwise use the corner defined by these 2 edge-face normals, + * Otherwise use the shared edge OR the corner defined by these 2 face normals, * when both edges faces are adjacent this works best but even when this vertex * fans out faces it should work ok. */ @@ -293,12 +293,27 @@ void bmo_inset_exec(BMesh *bm, BMOperator *op) normalize_v3(tvec); } else { - float tno[3]; - cross_v3_v3v3(tno, f_a->no, f_b->no); - if (dot_v3v3(tvec, tno) < 0.0f) { - negate_v3(tno); + /* these lookups are very quick */ + BMLoop *l_other_a = BM_loop_other_vert_loop(e_info_a->l, v_split); + BMLoop *l_other_b = BM_loop_other_vert_loop(e_info_b->l, v_split); + + if (l_other_a->v == l_other_b->v) { + /* both edges faces are adjacent, but we don't need to know the shared edge + * having both verts is enough. */ + sub_v3_v3v3(tvec, l_other_a->v->co, v_split->co); } - copy_v3_v3(tvec, tno); + else { + /* faces don't touch, + * just get cross product of their normals, its *good enough* + */ + float tno[3]; + cross_v3_v3v3(tno, f_a->no, f_b->no); + if (dot_v3v3(tvec, tno) < 0.0f) { + negate_v3(tno); + } + copy_v3_v3(tvec, tno); + } + normalize_v3(tvec); } |