[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