diff options
author | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2012-04-01 02:09:43 +0400 |
---|---|---|
committer | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2012-04-01 02:09:43 +0400 |
commit | 4c36a26af5d1093badc88401bfebf8454fdf0f34 (patch) | |
tree | 2e82fc5ff893651982d20ffdd15d4c69bfcbe7b8 /source/blender/bmesh/operators/bmo_inset.c | |
parent | 3b711a6ed009b35bb69cd0ca878eeb8d55fa0e77 (diff) | |
parent | 8f949dd58decac45fd49f9a93152f2cddc98d901 (diff) |
Merged changes in the trunk up to revision 45308.
Conflicts resolved:
source/blender/editors/interface/resources.c
source/blender/editors/mesh/editmesh_select.c
source/blender/editors/space_view3d/drawobject.c
Diffstat (limited to 'source/blender/bmesh/operators/bmo_inset.c')
-rw-r--r-- | source/blender/bmesh/operators/bmo_inset.c | 54 |
1 files changed, 48 insertions, 6 deletions
diff --git a/source/blender/bmesh/operators/bmo_inset.c b/source/blender/bmesh/operators/bmo_inset.c index d64edada06d..4a426b40995 100644 --- a/source/blender/bmesh/operators/bmo_inset.c +++ b/source/blender/bmesh/operators/bmo_inset.c @@ -269,15 +269,57 @@ void bmo_inset_exec(BMesh *bm, BMOperator *op) float tvec[3]; if (vert_edge_tag_tot >= 2) { /* 2 edge users - common case */ - const float *e_no_a = edge_info[vecpair[0]].no; - const float *e_no_b = edge_info[vecpair[1]].no; + /* now there are 2 cases to check for, + * + * 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 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. + */ + + SplitEdgeInfo *e_info_a = &edge_info[vecpair[0]]; + SplitEdgeInfo *e_info_b = &edge_info[vecpair[1]]; + + BMFace *f_a = e_info_a->l->f; + BMFace *f_b = e_info_b->l->f; + + /* we use this as either the normal OR to find the right direction for the + * crpss product between both face normals */ + add_v3_v3v3(tvec, e_info_a->no, e_info_b->no); + + if ((f_a == f_b) || compare_v3v3(f_a->no, f_b->no, 0.00001f)) { + normalize_v3(tvec); + } + else { + /* 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); + } + 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); + } - add_v3_v3v3(tvec, e_no_a, e_no_b); - normalize_v3(tvec); + normalize_v3(tvec); + } /* scale by edge angle */ if (use_even_offset) { - mul_v3_fl(tvec, shell_angle_to_dist(angle_normalized_v3v3(e_no_a, e_no_b) / 2.0f)); + mul_v3_fl(tvec, shell_angle_to_dist(angle_normalized_v3v3(e_info_a->no, e_info_b->no) / 2.0f)); } /* scale relative to edge lengths */ @@ -440,5 +482,5 @@ void bmo_inset_exec(BMesh *bm, BMOperator *op) MEM_freeN(edge_info); /* we could flag new edges/verts too, is it useful? */ - BMO_slot_buffer_from_flag(bm, op, "faceout", BM_FACE, ELE_NEW); + BMO_slot_buffer_from_enabled_flag(bm, op, "faceout", BM_FACE, ELE_NEW); } |