[Bf-blender-cvs] [1158c1f] master: Bevel Fix for nonplanar faces / reflex angles
Howard Trickey
noreply at git.blender.org
Wed Nov 20 13:30:23 CET 2013
Commit: 1158c1f7c0ec3f5d31989cb85207a08888d2c0d3
Author: Howard Trickey
Date: Wed Nov 20 07:10:35 2013 -0500
http://developer.blender.org/rB1158c1f7c0ec3f5d31989cb85207a08888d2c0d3
Bevel Fix for nonplanar faces / reflex angles
When beveling two adjacent edges, code used face normal instead
of the face-corner normal (these can be different for nonplanar
faces); the bevel may look uneven in such cases.
Switched to using corner normal, and needed to fix the case
where the edges meet at a reflex angle. Fixed a similar case
when beveling two edges with one non-beveled in between.
Also removed unnecessary argument from offset_meet.
===================================================================
M source/blender/bmesh/tools/bmesh_bevel.c
===================================================================
diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c
index af3160b..5e68e46 100644
--- a/source/blender/bmesh/tools/bmesh_bevel.c
+++ b/source/blender/bmesh/tools/bmesh_bevel.c
@@ -468,14 +468,12 @@ static void slide_dist(EdgeHalf *e, BMVert *v, float d, float slideco[3])
* Calculate the meeting point between the offset edges for e1 and e2, putting answer in meetco.
* e1 and e2 share vertex v and face f (may be NULL) and viewed from the normal side of
* the bevel vertex, e1 precedes e2 in CCW order.
- * If on_right is true, offset edge is on right of both edges, where e1 enters v and
- * e2 leave it. If on_right is false, then the offset edge is on the left.
+ * Offset edge is on right of both edges, where e1 enters v and e2 leave it.
* When offsets are equal, the new point is on the edge bisector, with length offset/sin(angle/2),
* but if the offsets are not equal (allowing for this, as bevel modifier has edge weights that may
* lead to different offsets) then meeting point can be found be intersecting offset lines.
*/
-static void offset_meet(EdgeHalf *e1, EdgeHalf *e2, BMVert *v, BMFace *f,
- int on_right, float meetco[3])
+static void offset_meet(EdgeHalf *e1, EdgeHalf *e2, BMVert *v, BMFace *f, float meetco[3])
{
float dir1[3], dir2[3], norm_v[3], norm_perp1[3], norm_perp2[3],
off1a[3], off1b[3], off2a[3], off2b[3], isect2[3], ang;
@@ -506,16 +504,15 @@ static void offset_meet(EdgeHalf *e1, EdgeHalf *e2, BMVert *v, BMFace *f,
slide_dist(e2, v, e2->offset_l, meetco);
}
else {
- /* get normal to plane where meet point should be */
+ /* Get normal to plane where meet point should be,
+ * using cross product instead of f->no in case f is non-planar.
+ * If e1-v-e2 is a reflex angle (viewed from vertex normal side), need to flip*/
cross_v3_v3v3(norm_v, dir2, dir1);
normalize_v3(norm_v);
- if (!on_right)
+ if (dot_v3v3(norm_v, v->no) < 0.0f)
negate_v3(norm_v);
/* get vectors perp to each edge, perp to norm_v, and pointing into face */
- if (f) {
- copy_v3_v3(norm_v, f->no);
- }
cross_v3_v3v3(norm_perp1, dir1, norm_v);
cross_v3_v3v3(norm_perp2, dir2, norm_v);
normalize_v3(norm_perp1);
@@ -551,12 +548,12 @@ static void offset_on_edge_between(BevelParams *bp, EdgeHalf *e1, EdgeHalf *e2,
* Prefer the one whose other end hasn't been constructed yet.
* Following will choose to change e2 if both have already been constructed. */
if (find_other_end_edge_half(bp, e1)) {
- offset_meet(e1, emid, v, e1->fnext, TRUE, meetco);
+ offset_meet(e1, emid, v, e1->fnext, meetco);
/* now e2's left offset is probably different */
e2->offset_l = dist_to_line_v3(meetco, v->co, BM_edge_other_vert(e2->e, v)->co);
}
else {
- offset_meet(emid, e2, v, emid->fnext, TRUE, meetco);
+ offset_meet(emid, e2, v, emid->fnext, meetco);
/* now e1's right offset is probably different */
e1->offset_r = dist_to_line_v3(meetco, v->co, BM_edge_other_vert(e1->e, v)->co);
}
@@ -585,6 +582,14 @@ static void offset_in_two_planes(BevelParams *bp, EdgeHalf *e1, EdgeHalf *e2, Ed
/* calculate face normals at corner in case faces are nonplanar */
cross_v3_v3v3(f1no, dirmid, dir1);
cross_v3_v3v3(f2no, dirmid, dir2);
+
+ /* if e1-v-emid or emid-v-e2 are reflex angles, need to flip corner normals */
+ if (dot_v3v3(f1no, v->no) < 0.0f)
+ negate_v3(f1no);
+ if (dot_v3v3(f2no, v->no) < 0.0f)
+ negate_v3(f2no);
+
+ /* get vectors perpendicular to e1 and e2, pointing into the proper faces */
cross_v3_v3v3(norm_perp1, dir1, f1no);
normalize_v3(norm_perp1);
cross_v3_v3v3(norm_perp2, dir2, f2no);
@@ -874,7 +879,7 @@ static void build_boundary(BevelParams *bp, BevVert *bv)
/* handle only left side of beveled edge e here: next iteration should do right side */
if (e->prev->is_bev) {
BLI_assert(e->prev != e); /* see: wire edge special case */
- offset_meet(e->prev, e, bv->v, e->fprev, TRUE, co);
+ offset_meet(e->prev, e, bv->v, e->fprev, co);
v = add_new_bound_vert(mem_arena, vm, co);
v->efirst = e->prev;
v->elast = v->ebev = e;
@@ -899,7 +904,7 @@ static void build_boundary(BevelParams *bp, BevVert *bv)
}
else {
/* neither e->prev nor e->prev->prev are beveled: make on-edge on e->prev */
- offset_meet(e->prev, e, bv->v, e->fprev, TRUE, co);
+ offset_meet(e->prev, e, bv->v, e->fprev, co);
v = add_new_bound_vert(mem_arena, vm, co);
v->efirst = e->prev;
v->elast = v->ebev = e;
@@ -917,7 +922,7 @@ static void build_boundary(BevelParams *bp, BevVert *bv)
}
else if (e->prev->is_bev) {
/* on-edge meet between e->prev and e */
- offset_meet(e->prev, e, bv->v, e->fprev, TRUE, co);
+ offset_meet(e->prev, e, bv->v, e->fprev, co);
v = add_new_bound_vert(mem_arena, vm, co);
v->efirst = e->prev;
v->elast = e;
More information about the Bf-blender-cvs
mailing list