[Bf-blender-cvs] [dec4f6d7ed9] master: Bevel: better attachment points for unbeveled edges, arc miter.

Howard Trickey noreply at git.blender.org
Thu Feb 7 16:43:22 CET 2019


Commit: dec4f6d7ed9886e36e76df2210bf50e6bb7bb799
Author: Howard Trickey
Date:   Thu Feb 7 10:42:28 2019 -0500
Branches: master
https://developer.blender.org/rBdec4f6d7ed9886e36e76df2210bf50e6bb7bb799

Bevel: better attachment points for unbeveled edges, arc miter.

===================================================================

M	source/blender/bmesh/tools/bmesh_bevel.c
M	source/blender/bmesh/tools/bmesh_bevel.h

===================================================================

diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c
index 5dea6da7b1d..5833e3427a4 100644
--- a/source/blender/bmesh/tools/bmesh_bevel.c
+++ b/source/blender/bmesh/tools/bmesh_bevel.c
@@ -14,7 +14,7 @@
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
 
-/** \file \ingroup bmesh
+/** \file bmesh_bevel.c
  *
  * Main functions for beveling a BMesh (used by the tool and modifier)
  */
@@ -76,6 +76,7 @@ typedef struct EdgeHalf {
 	BMFace *fnext;              /* face between this edge and next, if any */
 	struct BoundVert *leftv;    /* left boundary vert (looking along edge to end) */
 	struct BoundVert *rightv;   /* right boundary vert, if beveled */
+	int profile_index;          /* offset into profile to attach non-beveled edge */
 	int   seg;                  /* how many segments for the bevel */
 	float offset_l;             /* offset for this edge, on left side */
 	float offset_r;             /* offset for this edge, on right side */
@@ -2212,7 +2213,7 @@ static void adjust_miter_coords(BevelParams *bp, BevVert *bv, EdgeHalf *emiter)
 	adjust_bound_vert(v1, co1);
 
 	/* co3 is similar, but plane is through v3next and line is other side of miter edge */
-	emiter_other = v3->efirst;
+	emiter_other = v3->elast; /*v3->efirst;*/
 	vother = BM_edge_other_vert(emiter_other->e, bv->v);
 	sub_v3_v3v3(edge_dir, bv->v->co,  vother->co);
 	normalize_v3(edge_dir);
@@ -2366,17 +2367,33 @@ static void build_boundary(BevelParams *bp, BevVert *bv, bool construct)
 				e3->leftv = e3->rightv = v;
 			}
 			ang_kind = edges_angle_kind(e, e2, bv->v);
+
+			/* Are we doing special mitering?
+			 * ang_kind is -1, 0, 1 as angle is <, =, > 180 degrees.
+			 * There can only be one outer reflex angle, so only one outer miter,
+			 * and emiter will be set to the first edge of such an edge.
+			 * A miter kind of BEVEL_MITER_SHARP means no special miter */
+
 			if ((miter_outer != BEVEL_MITER_SHARP && !emiter && ang_kind == 1) ||
 			    (miter_inner != BEVEL_MITER_SHARP && ang_kind == -1))
 			{
 				if (ang_kind == 1)
-					emiter = e;  /* a reflex angle, i.e., the (only) outer miter, if any */
+					emiter = e;
 				/* make one or two more boundverts; for now all will have same co */
 				v1 = v;
 				v1->ebev = NULL;
+				if (ang_kind == 1 && miter_outer == BEVEL_MITER_PATCH)
+					v2 = add_new_bound_vert(mem_arena, vm, co);
+				else
+					v2 = NULL;
+				v3 = add_new_bound_vert(mem_arena, vm, co);
+				v3->ebev = e2;
+				v3->efirst = e2;
+				v3->elast = e2;
+				v3->eon = NULL;
+				e2->leftv = v3;
 				if (ang_kind == 1 && miter_outer == BEVEL_MITER_PATCH) {
 					v1->is_patch_start = true;
-					v2 = add_new_bound_vert(mem_arena, vm, co);
 					v2->eon = v1->eon;
 					v2->sinratio = v1->sinratio;
 					v2->ebev = NULL;
@@ -2398,22 +2415,29 @@ static void build_boundary(BevelParams *bp, BevVert *bv, bool construct)
 				else {
 					v1->is_arc_start = true;
 					copy_v3_v3(v1->profile.midco, co);
-					v2 = NULL;
 					if (e->next == e2) {
 						v1->elast = v1->efirst;
 					}
 					else {
+						int between = nip + nnip;
+						int bet2 = between / 2;
+						bool betodd = (between % 2) == 1;
+						int i = 0;
+						/* Put first half of in-between edges at index 0,
+						 * second half at index bp->seg.
+						 * If between is odd, put middle one at midindex */
 						for (e3 = e->next; e3 != e2; e3 = e3->next) {
 							v1->elast = e3;
+							if (i < bet2)
+								e3->profile_index = 0;
+							else if (betodd && i == bet2)
+								e3->profile_index = bp->seg / 2;
+							else
+								e3->profile_index = bp->seg;
+							i++;
 						}
 					}
 				}
-				v3 = add_new_bound_vert(mem_arena, vm, co);
-				v3->ebev = e2;
-				v3->efirst = e2;
-				v3->elast = e2;
-				v3->eon = NULL;
-				e2->leftv = v3;
 			}
 		}
 		else {
@@ -4933,6 +4957,8 @@ static BevVert *bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v)
 			e->seg = 0;
 		}
 		e->is_rev = (bme->v2 == v);
+		e->leftv = e->rightv = NULL;
+		e->profile_index = 0;
 	}
 
 	/* now done with tag flag */
@@ -5059,9 +5085,9 @@ static bool bev_rebuild_polygon(BMesh *bm, BevelParams *bp, BMFace *f)
 	BoundVert *v, *vstart, *vend;
 	EdgeHalf *e, *eprev;
 	VMesh *vm;
-	int i, k, n;
+	int i, k, n, kstart, kend;
 	bool do_rebuild = false;
-	bool go_ccw, corner3special, keep;
+	bool go_ccw, corner3special, keep, on_profile_start;
 	BMVert *bmv;
 	BMEdge *bme, *bme_new, *bme_prev;
 	BMFace *f_new, *f_other;
@@ -5108,56 +5134,85 @@ static bool bev_rebuild_polygon(BMesh *bm, BevelParams *bp, BMFace *f)
 					go_ccw = false;
 				}
 			}
+			on_profile_start = false;
 			if (go_ccw) {
 				vstart = eprev->rightv;
 				vend = e->leftv;
+				if (e->profile_index > 0) {
+					vstart = vstart->prev;
+					on_profile_start = true;
+				}
 			}
 			else {
 				vstart = eprev->leftv;
 				vend = e->rightv;
+				if (eprev->profile_index > 0) {
+					vstart = vstart->next;
+					on_profile_start = true;
+				}
 			}
 			BLI_assert(vstart != NULL && vend != NULL);
 			v = vstart;
-			BLI_array_append(vv, v->nv.v);
-			BLI_array_append(ee, bme);
-			/* check for special case: multisegment 3rd face opposite a beveled edge with no vmesh */
-			corner3special = (vm->mesh_kind == M_NONE && v->ebev != e && v->ebev != eprev);
+			if (!on_profile_start) {
+				BLI_array_append(vv, v->nv.v);
+				BLI_array_append(ee, bme);
+			}
 			while (v != vend) {
+				/* check for special case: multisegment 3rd face opposite a beveled edge with no vmesh */
+				corner3special = (vm->mesh_kind == M_NONE && v->ebev != e && v->ebev != eprev);
 				if (go_ccw) {
-					if (vm->seg > 1) {
-						if (vm->mesh_kind == M_ADJ || bp->vertex_only || corner3special) {
-							i = v->index;
-							for (k = 1; k < vm->seg; k++) {
-								bmv = mesh_vert(vm, i, 0, k)->v;
-								BLI_array_append(vv, bmv);
-								BLI_array_append(ee, bme); /* TODO: maybe better edge here */
-								if (corner3special && v->ebev && !v->ebev->is_seam)
-									BLI_array_append(vv_fix, bmv);
-							}
+					i = v->index;
+					if (on_profile_start) {
+						kstart = e->profile_index;
+						on_profile_start = false;
+					}
+					else {
+						kstart = 1;
+					}
+					if (eprev->rightv == v && eprev->profile_index > 0) {
+						kend = eprev->profile_index;
+					}
+					else {
+						kend = vm->seg;
+					}
+					for (k = kstart; k <= kend; k++) {
+						bmv = mesh_vert(vm, i, 0, k)->v;
+						if (bmv) {
+							BLI_array_append(vv, bmv);
+							BLI_array_append(ee, bme); /* TODO: maybe better edge here */
+							if (corner3special && v->ebev && !v->ebev->is_seam && k != vm->seg)
+								BLI_array_append(vv_fix, bmv);
 						}
 					}
 					v = v->next;
 				}
 				else {
 					/* going cw */
-					if (vm->seg > 1) {
-						if (vm->mesh_kind == M_ADJ || bp->vertex_only ||
-						    (vm->mesh_kind == M_NONE && v->ebev != e && v->ebev != eprev))
-						{
-							i = v->prev->index;
-							for (k = vm->seg - 1; k > 0; k--) {
-								bmv = mesh_vert(vm, i, 0, k)->v;
-								BLI_array_append(vv, bmv);
-								BLI_array_append(ee, bme);
-								if (corner3special && v->ebev && !v->ebev->is_seam)
-									BLI_array_append(vv_fix, bmv);
-							}
+					i = v->prev->index;
+					if (on_profile_start) {
+						kstart = eprev->profile_index;
+						on_profile_start = false;
+					}
+					else {
+						kstart = vm->seg - 1;
+					}
+					if (e->rightv == v->prev && e->profile_index > 0) {
+						kend = e->profile_index;
+					}
+					else {
+						kend = 0;
+					}
+					for (k = kstart; k >= kend; k--) {
+						bmv = mesh_vert(vm, i, 0, k)->v;
+						if (bmv) {
+							BLI_array_append(vv, bmv);
+							BLI_array_append(ee, bme);
+							if (corner3special && v->ebev && !v->ebev->is_seam && k != 0)
+								BLI_array_append(vv_fix, bmv);
 						}
 					}
 					v = v->prev;
 				}
-				BLI_array_append(vv, v->nv.v);
-				BLI_array_append(ee, bme);
 			}
 			do_rebuild = true;
 		}
@@ -6047,7 +6102,7 @@ void BM_mesh_bevel(
 	bp.use_weights = use_weights;
 	bp.loop_slide = loop_slide;
 	bp.limit_offset = limit_offset;
-	bp.offset_adjust = false; // DEBUG true;
+	bp.offset_adjust = false;
 	bp.dvert = dvert;
 	bp.vertex_group = vertex_group;
 	bp.mat_nr = mat;
diff --git a/source/blender/bmesh/tools/bmesh_bevel.h b/source/blender/bmesh/tools/bmesh_bevel.h
index 9d8e4de2772..bb4c3191c4b 100644
--- a/source/blender/bmesh/tools/bmesh_bevel.h
+++ b/source/blender/bmesh/tools/bmesh_bevel.h
@@ -17,7 +17,7 @@
 #ifndef __BMESH_BEVEL_H__
 #define __BMESH_BEVEL_H__
 
-/** \file \ingroup bmesh
+/** \file bmesh_bevel.h
  */
 
 struct MDeformVert;



More information about the Bf-blender-cvs mailing list