[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [52344] trunk/blender/source/blender: improvements to bevel

Campbell Barton ideasman42 at gmail.com
Mon Nov 19 03:27:05 CET 2012


Revision: 52344
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=52344
Author:   campbellbarton
Date:     2012-11-19 02:26:59 +0000 (Mon, 19 Nov 2012)
Log Message:
-----------
improvements to bevel
- the resulting selection is now correct

internal details
- bev_rebuild_polygon() now only rebuilds polygons that are attached to a bevel vertex (was rebuilding ALL).
  ... need to take care we don't leave faces pointing to removed geometry, so far this works fine.

-  bev_rebuild_polygon() uses stack memory for <32 size ngons to reduce allocs.

- skip hash lookup when removing bevel verts (use tag instead).

Modified Paths:
--------------
    trunk/blender/source/blender/bmesh/intern/bmesh_opdefines.c
    trunk/blender/source/blender/bmesh/operators/bmo_bevel.c
    trunk/blender/source/blender/bmesh/tools/bmesh_bevel.c
    trunk/blender/source/blender/editors/mesh/editmesh_tools.c

Modified: trunk/blender/source/blender/bmesh/intern/bmesh_opdefines.c
===================================================================
--- trunk/blender/source/blender/bmesh/intern/bmesh_opdefines.c	2012-11-19 00:54:55 UTC (rev 52343)
+++ trunk/blender/source/blender/bmesh/intern/bmesh_opdefines.c	2012-11-19 02:26:59 UTC (rev 52344)
@@ -1076,6 +1076,7 @@
 	{{BMO_OP_SLOT_ELEMENT_BUF, "geom"}, /* input edges and vertices */
 	 {BMO_OP_SLOT_FLT, "offset"}, /* amount to offset beveled edge */
 	 {BMO_OP_SLOT_INT, "segments"}, /* number of segments in bevel */
+	 {BMO_OP_SLOT_ELEMENT_BUF, "faceout"}, /* output faces */
 	 {0} /* null-terminating sentinel */},
 #else
 	{{BMO_OP_SLOT_ELEMENT_BUF, "geom"}, /* input edges and vertices */

Modified: trunk/blender/source/blender/bmesh/operators/bmo_bevel.c
===================================================================
--- trunk/blender/source/blender/bmesh/operators/bmo_bevel.c	2012-11-19 00:54:55 UTC (rev 52343)
+++ trunk/blender/source/blender/bmesh/operators/bmo_bevel.c	2012-11-19 02:26:59 UTC (rev 52344)
@@ -40,8 +40,9 @@
 		BMEdge *e;
 		BMVert *v;
 
-		/* first flush 'geom' into flags, this makes it possible to check connected data */
-		BM_mesh_elem_hflag_disable_all(bm, BM_VERT | BM_EDGE, BM_ELEM_TAG, FALSE);
+		/* first flush 'geom' into flags, this makes it possible to check connected data,
+		 * BM_FACE is cleared so we can put newly created faces into a bmesh slot. */
+		BM_mesh_elem_hflag_disable_all(bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_TAG, FALSE);
 
 		BMO_ITER (v, &siter, bm, op, "geom", BM_VERT) {
 			BM_elem_flag_enable(v, BM_ELEM_TAG);
@@ -54,5 +55,7 @@
 		}
 
 		BM_mesh_bevel(bm, offset, seg);
+
+		BMO_slot_buffer_from_enabled_hflag(bm, op, "faceout", BM_FACE, BM_ELEM_TAG);
 	}
 }

Modified: trunk/blender/source/blender/bmesh/tools/bmesh_bevel.c
===================================================================
--- trunk/blender/source/blender/bmesh/tools/bmesh_bevel.c	2012-11-19 00:54:55 UTC (rev 52343)
+++ trunk/blender/source/blender/bmesh/tools/bmesh_bevel.c	2012-11-19 02:26:59 UTC (rev 52344)
@@ -242,20 +242,24 @@
 	return fans;
 }
 
-/* Make ngon from verts alone.
+/**
+ * Make ngon from verts alone.
  * Make sure to properly copy face attributes and do custom data interpolation from
- * example face, facerep. */
-static BMFace *bev_create_ngon(BMesh *bm, BMVert **vert_arr, int totv, BMFace *facerep)
+ * example face, facerep.
+ *
+ * \note ALL face creation goes through this function, this is important to keep!
+ */
+static BMFace *bev_create_ngon(BMesh *bm, BMVert **vert_arr, const int totv, BMFace *facerep)
 {
 	BMIter iter;
 	BMLoop *l;
 	BMFace *f;
 
 	if (totv == 3) {
-		f = BM_face_create_quad_tri_v(bm, vert_arr, 3, facerep, 0);
+		f = BM_face_create_quad_tri_v(bm, vert_arr, 3, facerep, FALSE);
 	}
 	else if (totv == 4) {
-		f = BM_face_create_quad_tri_v(bm, vert_arr, 4, facerep, 0);
+		f = BM_face_create_quad_tri_v(bm, vert_arr, 4, facerep, FALSE);
 	}
 	else {
 		int i;
@@ -278,6 +282,13 @@
 				BM_loop_interp_multires(bm, l, facerep);
 		}
 	}
+
+	/* not essential for bevels own internal logic,
+	 * this is done so the operator can select newly created faces */
+	if (f) {
+		BM_elem_flag_enable(f, BM_ELEM_TAG);
+	}
+
 	return f;
 }
 
@@ -1416,8 +1427,11 @@
 		}
 	}
 
-	if (nsel == 0)
+	if (nsel == 0) {
+		/* signal this vert isn't being beveled */
+		BM_elem_flag_disable(v, BM_ELEM_TAG);
 		return;
+	}
 
 	ntot = BM_vert_edge_count(v);
 	bv = (BevVert *)BLI_memarena_alloc(bp->mem_arena, (sizeof(BevVert)));
@@ -1525,7 +1539,7 @@
 }
 
 /* Face f has at least one beveled vertex.  Rebuild f */
-static void rebuild_polygon(BMesh *bm, BevelParams *bp, BMFace *f)
+static int bev_rebuild_polygon(BMesh *bm, BevelParams *bp, BMFace *f)
 {
 	BMIter liter;
 	BMLoop *l, *lprev;
@@ -1534,9 +1548,10 @@
 	EdgeHalf *e, *eprev;
 	VMesh *vm;
 	int i, k;
+	int do_rebuild = FALSE;
 	BMVert *bmv;
 	BMVert **vv = NULL;
-	BLI_array_declare(vv);
+	BLI_array_staticdeclare(vv, BM_DEFAULT_NGON_STACK_SIZE);
 
 	BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
 		bv = find_bevvert(bp, l->v);
@@ -1566,13 +1581,24 @@
 				v = v->prev;
 				BLI_array_append(vv, v->nv.v);
 			}
+
+			do_rebuild = TRUE;
 		}
 		else {
 			BLI_array_append(vv, l->v);
 		}
 	}
-	bev_create_ngon(bm, vv, BLI_array_count(vv), f);
+	if (do_rebuild) {
+		BMFace *f_new = bev_create_ngon(bm, vv, BLI_array_count(vv), f);
+
+		/* don't select newly created boundary faces... */
+		if (f_new) {
+			BM_elem_flag_disable(f_new, BM_ELEM_TAG);
+		}
+	}
+
 	BLI_array_free(vv);
+	return do_rebuild;
 }
 
 /* All polygons touching v need rebuilding because beveling v has made new vertices */
@@ -1586,8 +1612,9 @@
 	if (LIKELY(faces != NULL)) {
 		for (f_index = 0; f_index < faces_len; f_index++) {
 			BMFace *f = faces[f_index];
-			rebuild_polygon(bm, bp, f);
-			BM_face_kill(bm, f);
+			if (bev_rebuild_polygon(bm, bp, f)) {
+				BM_face_kill(bm, f);
+			}
 		}
 
 		if (faces != (BMFace **)faces_stack) {
@@ -1664,8 +1691,13 @@
 }
 
 /**
- * currently only bevels BM_ELEM_TAG'd verts and edges
- * all tagged edges _must_ be manifold.
+ * - Currently only bevels BM_ELEM_TAG'd verts and edges.
+ *
+ * - Newly created faces are BM_ELEM_TAG'd too,
+ *   the caller needs to ensure this is cleared before calling
+ *   if its going to use this face tag.
+ *
+ * \warning all tagged edges _must_ be manifold.
  */
 void BM_mesh_bevel(BMesh *bm, const float offset, const float segments)
 {
@@ -1705,9 +1737,8 @@
 
 		BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
 			if (BM_elem_flag_test(v, BM_ELEM_TAG)) {
-				if (find_bevvert(&bp, v)) {
-					BM_vert_kill(bm, v);
-				}
+				BLI_assert(find_bevvert(&bp, v) != NULL);
+				BM_vert_kill(bm, v);
 			}
 		}
 

Modified: trunk/blender/source/blender/editors/mesh/editmesh_tools.c
===================================================================
--- trunk/blender/source/blender/editors/mesh/editmesh_tools.c	2012-11-19 00:54:55 UTC (rev 52343)
+++ trunk/blender/source/blender/editors/mesh/editmesh_tools.c	2012-11-19 02:26:59 UTC (rev 52344)
@@ -4757,13 +4757,23 @@
 	if (!EDBM_op_init(em, &bmop, op,
 		              "bevel geom=%hev offset=%f segments=%i",
 		              BM_ELEM_SELECT, offset, segments))
-		{
-			return 0;
-		}
-		
+	{
+		return 0;
+	}
+
 	BMO_op_exec(em->bm, &bmop);
+
+	/* no need to de-select existing geometry */
 	if (!EDBM_op_finish(em, &bmop, op, TRUE))
 		return 0;
+
+	if (offset != 0.0f) {
+		/* not essential, but we may have some loose geometry that
+		 * won't get bevel'd and better not leave it selected */
+		EDBM_flag_disable_all(em, BM_ELEM_SELECT);
+		BMO_slot_buffer_hflag_enable(em->bm, &bmop, "faceout", BM_FACE, BM_ELEM_SELECT, TRUE);
+	}
+
 #else
 	int i;
 




More information about the Bf-blender-cvs mailing list