[Bf-blender-cvs] [6bde9a5] master: Fix T39174 Bevel didn't maintain edge attributes.

Howard Trickey noreply at git.blender.org
Thu May 29 13:39:19 CEST 2014


Commit: 6bde9a52f9270841331c7762a5df9505894d962a
Author: Howard Trickey
Date:   Thu May 29 07:32:16 2014 -0400
https://developer.blender.org/rB6bde9a52f9270841331c7762a5df9505894d962a

Fix T39174 Bevel didn't maintain edge attributes.

When rebuilding the polygons that touch bevel-involved vertices,
need to copy the edge attributes from corresponding original edges.
Special treatment of corner segments, to maintain continuity of
smooth and seam attributes.
Another fix: if have four meeting edges, two opposite ones beveled
and the other two not, propgate the non-beveled-edges attributes
across the line that joins them (perpendicular to the bevel).

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

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 1f3002e..f436c1f 100644
--- a/source/blender/bmesh/tools/bmesh_bevel.c
+++ b/source/blender/bmesh/tools/bmesh_bevel.c
@@ -3082,19 +3082,24 @@ static bool bev_rebuild_polygon(BMesh *bm, BevelParams *bp, BMFace *f)
 	BoundVert *v, *vstart, *vend;
 	EdgeHalf *e, *eprev;
 	VMesh *vm;
-	int i, k;
+	int i, k, n;
 	bool do_rebuild = false;
 	BMVert *bmv;
+	BMEdge *bme, *bme_new, *bme_prev;
+	BMFace *f_new;
 	BMVert **vv = NULL;
 	BMVert **vv_fix = NULL;
+	BMEdge **ee = NULL;
 	BLI_array_staticdeclare(vv, BM_DEFAULT_NGON_STACK_SIZE);
 	BLI_array_staticdeclare(vv_fix, BM_DEFAULT_NGON_STACK_SIZE);
+	BLI_array_staticdeclare(ee, BM_DEFAULT_NGON_STACK_SIZE);
 
 	BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
 		if (BM_elem_flag_test(l->v, BM_ELEM_TAG)) {
 			lprev = l->prev;
 			bv = find_bevvert(bp, l->v);
 			e = find_edge_half(bv, l->e);
+			bme = e->e;
 			eprev = find_edge_half(bv, lprev->e);
 			BLI_assert(e != NULL && eprev != NULL);
 			vstart = eprev->leftv;
@@ -3105,6 +3110,7 @@ static bool bev_rebuild_polygon(BMesh *bm, BevelParams *bp, BMFace *f)
 			v = vstart;
 			vm = bv->vmesh;
 			BLI_array_append(vv, v->nv.v);
+			BLI_array_append(ee, bme);
 			while (v != vend) {
 				if (vm->mesh_kind == M_NONE && v->ebev && v->ebev->seg > 1 && v->ebev != e && v->ebev != eprev) {
 					/* case of 3rd face opposite a beveled edge, with no vmesh */
@@ -3113,6 +3119,7 @@ static bool bev_rebuild_polygon(BMesh *bm, BevelParams *bp, BMFace *f)
 					for (k = 1; k < e->seg; k++) {
 						bmv = mesh_vert(vm, i, 0, k)->v;
 						BLI_array_append(vv, bmv);
+						BLI_array_append(ee, bme);
 						/* may want to merge UVs of these later */
 						if (!e->is_seam)
 							BLI_array_append(vv_fix, bmv);
@@ -3124,25 +3131,57 @@ static bool bev_rebuild_polygon(BMesh *bm, BevelParams *bp, BMFace *f)
 					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);
 					}
 				}
 				v = v->prev;
 				BLI_array_append(vv, v->nv.v);
+				BLI_array_append(ee, bme);
 			}
 
 			do_rebuild = true;
 		}
 		else {
 			BLI_array_append(vv, l->v);
+			BLI_array_append(ee, l->e);
 		}
 	}
 	if (do_rebuild) {
-		BMFace *f_new = bev_create_ngon(bm, vv, BLI_array_count(vv), NULL, f, true);
+		n = BLI_array_count(vv);
+		f_new = bev_create_ngon(bm, vv, n, NULL, f, true);
 
 		for (k = 0; k < BLI_array_count(vv_fix); k++) {
 			bev_merge_uvs(bm, vv_fix[k]);
 		}
 
+		/* copy attributes from old edges */
+		BLI_assert(n == BLI_array_count(ee));
+		bme_prev = ee[n - 1];
+		for (k = 0; k < n; k++) {
+			bme_new = BM_edge_exists(vv[k], vv[(k + 1) % n]);
+			BLI_assert(ee[k] && bme_new);
+			if (ee[k] != bme_new) {
+				BM_elem_attrs_copy(bm, bm, ee[k], bme_new);
+				/* want to undo seam and smooth for corner segments
+				 * if those attrs aren't contiguous around face */
+				if (k < n - 1 && ee[k] == ee[k + 1]) {
+					if (BM_elem_flag_test(ee[k], BM_ELEM_SEAM) &&
+					    !BM_elem_flag_test(bme_prev, BM_ELEM_SEAM))
+					{
+						BM_elem_flag_disable(bme_new, BM_ELEM_SEAM);
+					}
+					/* actually want "sharp" to be contiguous, so reverse the test */
+					if (!BM_elem_flag_test(ee[k], BM_ELEM_SMOOTH) &&
+					    BM_elem_flag_test(bme_prev, BM_ELEM_SMOOTH))
+					{
+						BM_elem_flag_enable(bme_new, BM_ELEM_SMOOTH);
+					}
+				}
+				else
+					bme_prev = ee[k];
+			}
+		}
+
 		/* don't select newly created boundary faces... */
 		if (f_new) {
 			BM_elem_flag_disable(f_new, BM_ELEM_TAG);
@@ -3150,6 +3189,8 @@ static bool bev_rebuild_polygon(BMesh *bm, BevelParams *bp, BMFace *f)
 	}
 
 	BLI_array_free(vv);
+	BLI_array_free(vv_fix);
+	BLI_array_free(ee);
 	return do_rebuild;
 }
 
@@ -3243,6 +3284,70 @@ static void bev_merge_end_uvs(BMesh *bm, BevVert *bv, EdgeHalf *e)
 }
 
 /*
+ * Is this BevVert the special case of a weld (no vmesh) where there are
+ * four edges total, two are beveled, and the other two are on opposite sides?
+ */
+static bool bevvert_is_weld_cross(BevVert *bv)
+{
+	return (bv->edgecount == 4 && bv->selcount == 2 &&
+	        ((bv->edges[0].is_bev && bv->edges[2].is_bev) ||
+	         (bv->edges[1].is_bev && bv->edges[3].is_bev)));
+}
+
+/*
+ * Copy edge attribute data across the non-beveled crossing edges of a cross weld.
+ *
+ * Situation looks like this:
+ *
+ *      e->next
+ *        |
+ * -------3-------
+ * -------2-------
+ * -------1------- e
+ * -------0------
+ *        |
+ *      e->prev
+ *
+ * where e is the EdgeHalf of one of the beveled edges,
+ * e->next and e->prev are EdgeHalfs for the unbeveled edges of the cross
+ * and their attributes are to be copied to the edges 01, 12, 23.
+ * The vert i is mesh_vert(vm, vmindex, 0, i)->v
+ */
+static void weld_cross_attrs_copy(BMesh *bm, BevVert *bv, VMesh *vm, int vmindex, EdgeHalf *e)
+{
+	BMEdge *bme_prev, *bme_next, *bme;
+	int i, nseg;
+	bool disable_seam, enable_smooth;
+
+	bme_prev = bme_next = NULL;
+	for (i = 0; i < 4; i++) {
+		if (&bv->edges[i] == e) {
+			bme_prev = bv->edges[(i + 3) % 4].e;
+			bme_next = bv->edges[(i + 1) % 4].e;
+			break;
+		}
+	}
+	BLI_assert(bme_prev && bme_next);
+
+	/* want seams and sharp edges to cross only if that way on both sides */
+	disable_seam = BM_elem_flag_test(bme_prev, BM_ELEM_SEAM) != BM_elem_flag_test(bme_next, BM_ELEM_SEAM);
+	enable_smooth = BM_elem_flag_test(bme_prev, BM_ELEM_SMOOTH) != BM_elem_flag_test(bme_next, BM_ELEM_SMOOTH);
+
+	nseg = e->seg;
+	for (i = 0; i < nseg; i++) {
+		bme = BM_edge_exists(mesh_vert(vm, vmindex, 0, i)->v,
+		                     mesh_vert(vm, vmindex, 0, i + 1)->v);
+		BLI_assert(bme);
+		BM_elem_attrs_copy(bm, bm, bme_prev, bme);
+		if (disable_seam)
+			BM_elem_flag_disable(bme, BM_ELEM_SEAM);
+		if (enable_smooth)
+			BM_elem_flag_enable(bme, BM_ELEM_SMOOTH);
+	}
+}
+
+
+/*
  * Build the polygons along the selected Edge
  */
 static void bevel_build_edge_polygons(BMesh *bm, BevelParams *bp, BMEdge *bme)
@@ -3286,15 +3391,15 @@ static void bevel_build_edge_polygons(BMesh *bm, BevelParams *bp, BMEdge *bme)
 
 	f1 = e1->fprev;
 	f2 = e1->fnext;
+	i1 = e1->leftv->index;
+	i2 = e2->leftv->index;
+	vm1 = bv1->vmesh;
+	vm2 = bv2->vmesh;
 
 	if (nseg == 1) {
 		bev_create_quad_straddle(bm, bmv1, bmv2, bmv3, bmv4, f1, f2, e1->is_seam);
 	}
 	else {
-		i1 = e1->leftv->index;
-		i2 = e2->leftv->index;
-		vm1 = bv1->vmesh;
-		vm2 = bv2->vmesh;
 		bmv1i = bmv1;
 		bmv2i = bmv2;
 		odd = nseg % 2;
@@ -3330,6 +3435,14 @@ static void bevel_build_edge_polygons(BMesh *bm, BevelParams *bp, BMEdge *bme)
 	BLI_assert(bme1 && bme2);
 	BM_elem_attrs_copy(bm, bm, bme, bme1);
 	BM_elem_attrs_copy(bm, bm, bme, bme2);
+
+	/* If either end is a "weld cross", want continuity of edge attributes across end edge(s) */
+	if (bevvert_is_weld_cross(bv1)) {
+		weld_cross_attrs_copy(bm, bv1, vm1, i1, e1);
+	}
+	if (bevvert_is_weld_cross(bv2)) {
+		weld_cross_attrs_copy(bm, bv2, vm2, i2, e2);
+	}
 }
 
 /* Returns the square of the length of the chord from parameter u0 to parameter u1




More information about the Bf-blender-cvs mailing list