[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [51410] branches/soc-2012-sushi/source/ blender/bmesh/operators/bmo_bevel.c: Rework bevel to fix a bunch of bugs.

Howard Trickey howard.trickey at gmail.com
Thu Oct 18 18:22:23 CEST 2012


Revision: 51410
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=51410
Author:   howardt
Date:     2012-10-18 16:22:23 +0000 (Thu, 18 Oct 2012)
Log Message:
-----------
Rework bevel to fix a bunch of bugs.

Modified Paths:
--------------
    branches/soc-2012-sushi/source/blender/bmesh/operators/bmo_bevel.c

Modified: branches/soc-2012-sushi/source/blender/bmesh/operators/bmo_bevel.c
===================================================================
--- branches/soc-2012-sushi/source/blender/bmesh/operators/bmo_bevel.c	2012-10-18 15:54:24 UTC (rev 51409)
+++ branches/soc-2012-sushi/source/blender/bmesh/operators/bmo_bevel.c	2012-10-18 16:22:23 UTC (rev 51410)
@@ -15,7 +15,7 @@
  * along with this program; if not, write to the Free Software Foundation,
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  *
- * Contributor(s): Joseph Eagar.
+ * Contributor(s): Joseph Eagar, Aleksandr Mokhov, Howard Trickey
  *
  * ***** END GPL LICENSE BLOCK *****
  */
@@ -40,6 +40,8 @@
 
 
 #define BEVEL_FLAG	1
+
+#ifdef OLD_BEVEL
 #define BEVEL_DEL	2
 #define FACE_NEW	4
 #define EDGE_OLD	8
@@ -47,624 +49,386 @@
 #define VERT_OLD	32
 #define FACE_SPAN	64
 #define FACE_HOLE	128
+#endif
 
 #define EDGE_SELECTED 256
 
 #define BEVEL_EPSILON  1e-6
 
-typedef struct LoopTag {
-	BMVert *newv;
-} LoopTag;
-
-typedef struct EdgeTag {
-	BMVert *newv1, *newv2;
-} EdgeTag;
-
-/* this structure is item of new vertices list */
-typedef struct NewVertexItem {
-	struct NewVertexItem *next, *prev;
+/* Constructed vertex, sometimes later instantiated as BMVert */
+typedef struct NewVert {
+	enum {
+		V_ON_MEET,		/* on edge, meet with an offset line */
+		V_OFF_MEET, 		/* off edge, meet between two offset lines */
+		V_OFF,			/* offset bevel end, but not one of previous two cases */
+		V_ON_SLIDE,		/* on edge, slid along it a bit */
+		V_ORIG,			/* an original vertex */
+		V_EXTRA,		/* an extra vertex added in special cases */
+		V_PROFILE,		/* part of a bevel edge end profile */
+		V_VMESH			/* part of interior vmesh */
+	} vkind;
+	float co[3];
 	BMVert *v;
-} NewVertexItem;
+} NewVert;
 
+struct BoundVert;
 
+/* Data for one end of an edge involved in a bevel */
+typedef struct EdgeHalf {
+	struct EdgeHalf *next, *prev;	/* in CCW order */
+	BMEdge *e;			/* original mesh edge */
+	int isbev;			/* is this edge beveled? */
+	int isrev;			/* is e->v2 the vertex at this end? */
+	int seg;			/* how many segments for the bevel */
+	float offset;			/* offset for this edge */
+	BMFace *fprev;			/* face between this edge and previous, if any */
+	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 */
+} EdgeHalf;
 
-/* list of new vertices formed around v */
-typedef struct AdditionalVert {
-	struct AdditionalVert *next, *prev;
-	BMVert *v;			/* parent vertex */
-	ListBase vertices;  /* List of auxiliary vertices */
-	int count;			/* count input edges, alse count additional vertex */
-	int countSelect;	/* count input selection edges */
-} AdditionalVert;
+/* An element in a cyclic boundary of a Vertex Mesh (VMesh) */
+typedef struct BoundVert {
+	struct BoundVert *next, *prev;	/* in CCW order */
+	int index;			/* used for vmesh indexing */
+	NewVert nv;
+	EdgeHalf *efirst;		/* first of edges attached here: in CCW order */
+	EdgeHalf *elast;
+	EdgeHalf *ebev;		/* beveled edge whose left side is attached here, if any */
+} BoundVert;
 
+/* Mesh structure replacing a vertex */
+typedef struct VMesh {
+	enum {
+		M_NONE,			/* no polygon mesh needed */
+		M_POLY,			/* a simple polygon */
+		M_ADJ,			/* "adjacent edges" mesh pattern */
+		M_CROSS,		/* "cross edges" mesh pattern */
+	} mesh_kind;
+	int count;			/* number of vertices in the boundary */
+	int seg;			/* common # of segments for segmented edges */
+	BoundVert *boundstart;		/* start of boundary double-linked list */
+	NewVert *mesh;			/* allocated array - size and structure depends on kind */
+} VMesh;
 
+/* Data for a vertex involved in a bevel */
+typedef struct BevVert {
+	struct BevVert *next, *prev;
+	BMVert *v;			/* original mesh vertex */
+	int edgecount;			/* total number of edges around the vertex */
+	int selcount;			/* number of selected edges around the vertex */
+	EdgeHalf *edges;		/* array of size edgecount; CCW order from vertex normal side */
+	VMesh *vmesh;			/* mesh structure for replacing vertex */
+} BevVert;
 
-/* Item in the list of additional vertices */
-typedef struct VertexItem {
-	struct VertexItem *next, *prev;
-	BMVert *v;
-	int onEdge;		/*	1 if new vertex located on edge; edge1 = edge, edge2 = NULL
-					*	0 if new vert located betwen edge1 and edge2
-						3 additional vert for rounding case	*/
-	BMEdge *edge1;
-	BMEdge *edge2;
-	BMFace *f;
-	float hv[3];	/* coordinate of support vertex */
-	AdditionalVert *parent;
-} VertexItem;
-
-
-
 /*
-* struct with bevel parametrs
-*/
+ * Bevel parameters and state
+ */
 typedef struct BevelParams {
-	ListBase vertList;		/* list additional vertex */
-	ListBase newVertList;	/* list of creation vertices */
-	float offset;
-	int byPolygon;			/* 1 - make bevel on each polygon, 0 - ignore internal polygon */
-	int seg;				/* segmentation */
+	ListBase vertList;		/* list of BevVert for each vertex involved in bevel */
+	float offset;			/* blender units to offset each side of a beveled edge */
+	int seg;				/* number of segments in beveled edge profile */
+	int byPolygon;			/* UNUSED: 1 - make bevel on each polygon, 0 - ignore internal polygon */
 	int isMaxOffset;		/* flag	for control offset 0 - offset < max, 1 - offset > max*/
 	float maxOffset;		/* maximum allowable offset */
 
 	BMOperator *op;
 } BevelParams;
 
-
-typedef struct SurfaceEdgeData {
-	BMEdge *e;
-	BMVert *a, *b;
-	BMVert *boundaryA, *boundaryB;
-	ListBase vertexList;
-	int count;
-	float h[3];
-
-} SurfaceEdgeData;
-
-BMVert* bevel_create_unique_vertex(BMesh *bm, BevelParams *bp, float co[3]);
-
-static void calc_corner_co(BMLoop *l, const float fac, float r_co[3],
-                           const short do_dist, const short do_even)
+/* Make a new BoundVert of the given kind, insert it at the end of the circular linked
+ * list with entry point bv->boundstart, and return it. */
+static BoundVert * add_new_bound_vert(VMesh *vm, int kind, float co[3])
 {
-	float  no[3], l_vec_prev[3], l_vec_next[3], l_co_prev[3], l_co[3], l_co_next[3], co_ofs[3];
-	int is_concave;
-
-	/* first get the prev/next verts */
-	if (l->f->len > 2) {
-		copy_v3_v3(l_co_prev, l->prev->v->co);
-		copy_v3_v3(l_co, l->v->co);
-		copy_v3_v3(l_co_next, l->next->v->co);
-
-		/* calculate normal */
-		sub_v3_v3v3(l_vec_prev, l_co_prev, l_co);
-		sub_v3_v3v3(l_vec_next, l_co_next, l_co);
-
-		cross_v3_v3v3(no, l_vec_prev, l_vec_next);
-		is_concave = dot_v3v3(no, l->f->no) > 0.0f;
+	BoundVert *ans = (BoundVert*) MEM_callocN(sizeof(BoundVert), "BoundVert");
+	ans->nv.vkind = kind;
+	copy_v3_v3(ans->nv.co, co);
+	if (!vm->boundstart) {
+		ans->index = 0;
+		vm->boundstart = ans;
+		ans->next = ans->prev = ans;
 	}
 	else {
-		BMIter iter;
-		BMLoop *l2;
-		float up[3] = {0.0f, 0.0f, 1.0f};
-
-		copy_v3_v3(l_co_prev, l->prev->v->co);
-		copy_v3_v3(l_co, l->v->co);
-		
-		BM_ITER_ELEM (l2, &iter, l->v, BM_LOOPS_OF_VERT) {
-			if (l2->f != l->f) {
-				copy_v3_v3(l_co_next, BM_edge_other_vert(l2->e, l2->next->v)->co);
-				break;
-			}
-		}
-		
-		sub_v3_v3v3(l_vec_prev, l_co_prev, l_co);
-		sub_v3_v3v3(l_vec_next, l_co_next, l_co);
-
-		cross_v3_v3v3(no, l_vec_prev, l_vec_next);
-		if (dot_v3v3(no, no) == 0.0f) {
-			no[0] = no[1] = 0.0f; no[2] = -1.0f;
-		}
-		
-		is_concave = dot_v3v3(no, up) < 0.0f;
+		BoundVert *tail = vm->boundstart->prev;
+		ans->index = tail->index + 1;
+		ans->prev = tail;
+		ans->next = vm->boundstart;
+		tail->next = ans;
+		vm->boundstart->prev = ans;
 	}
-
-
-	/* now calculate the new location */
-	if (do_dist) { /* treat 'fac' as distance */
-
-		normalize_v3(l_vec_prev);
-		normalize_v3(l_vec_next);
-
-		add_v3_v3v3(co_ofs, l_vec_prev, l_vec_next);
-		if (UNLIKELY(normalize_v3(co_ofs) == 0.0f)) {  /* edges form a straight line */
-			cross_v3_v3v3(co_ofs, l_vec_prev, l->f->no);
-		}
-
-		if (do_even) {
-			negate_v3(l_vec_next);
-			mul_v3_fl(co_ofs, fac * shell_angle_to_dist(0.5f * angle_normalized_v3v3(l_vec_prev, l_vec_next)));
-			/* negate_v3(l_vec_next); */ /* no need unless we use again */
-		}
-		else {
-			mul_v3_fl(co_ofs, fac);
-		}
-	}
-	else { /* treat as 'fac' as a factor (0 - 1) */
-
-		/* not strictly necessary, balance vectors
-		 * so the longer edge doesn't skew the result,
-		 * gives nicer, move even output.
-		 *
-		 * Use the minimum rather then the middle value so skinny faces don't flip along the short axis */
-		float min_fac = minf(normalize_v3(l_vec_prev), normalize_v3(l_vec_next));
-		float angle;
-
-		if (do_even) {
-			negate_v3(l_vec_next);
-			angle = angle_normalized_v3v3(l_vec_prev, l_vec_next);
-			negate_v3(l_vec_next); /* no need unless we use again */
-		}
-		else {
-			angle = 0.0f;
-		}
-
-		mul_v3_fl(l_vec_prev, min_fac);
-		mul_v3_fl(l_vec_next, min_fac);
-
-		add_v3_v3v3(co_ofs, l_vec_prev, l_vec_next);
-
-		if (UNLIKELY(is_zero_v3(co_ofs))) {
-			cross_v3_v3v3(co_ofs, l_vec_prev, l->f->no);
-			normalize_v3(co_ofs);
-			mul_v3_fl(co_ofs, min_fac);
-		}
-
-		/* done */
-		if (do_even) {
-			mul_v3_fl(co_ofs, (fac * 0.5f) * shell_angle_to_dist(0.5f * angle));
-		}
-		else {
-			mul_v3_fl(co_ofs, fac * 0.5f);
-		}
-	}
-
-	/* apply delta vec */
-	if (is_concave)
-		negate_v3(co_ofs);
-
-	add_v3_v3v3(r_co, co_ofs, l->v->co);
+	vm->count++;
+	return ans;
 }
 
-
-#define ETAG_SET(e, v, nv)  (                                                 \
-	(v) == (e)->v1 ?                                                          \
-		(etags[BM_elem_index_get((e))].newv1 = (nv)) :                        \
-		(etags[BM_elem_index_get((e))].newv2 = (nv))                          \
-	)
-
-#define ETAG_GET(e, v)  (                                                     \
-	(v) == (e)->v1 ?                                                          \
-		(etags[BM_elem_index_get((e))].newv1) :                               \
-		(etags[BM_elem_index_get((e))].newv2)                                 \
-	)
-
-
-void recalculate_additional_vert(BMesh* bm, BevelParams* bp, VertexItem *vi, BMEdge* sEdge)
+/* Mesh verts are indexed (i, j, k) where
+ * i = boundvert index (0 <= i < nv)
+ * j = ring index (0 <= j <= ns2)
+ * k = segment index (0 <= k <= ns)
+ * Not all of these are used, and some will share BMVerts */
+static NewVert* mesh_vert(VMesh* vm, int i, int j, int k)
 {
-	/* get minimum clearance */
-	float ve[3], sve[3], angle, length, viLen, vie[3];
-	BMVert *v;
-	v = vi->parent->v;
+	int nj = (vm -> seg / 2) + 1;
+	int nk = vm->seg + 1;
 

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list