[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [61221] trunk/blender/source/blender: Added options for how bevel amount is measured.

Howard Trickey howard.trickey at gmail.com
Sun Nov 10 13:31:57 CET 2013


Revision: 61221
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=61221
Author:   howardt
Date:     2013-11-10 12:31:57 +0000 (Sun, 10 Nov 2013)
Log Message:
-----------
Added options for how bevel amount is measured.
Now there is an 'Offset Type' dropdown on tool
shelf with types:
Offset - current method, offset of new edge
  from old along sliding face
Width - width of new bevel face (if segments=1)
Depth - amount a chamfering plane moves down
  from original edge
Percent - percent of way sliding edges move
  along their adjacent edges

The different options mainly are useful when
beveling more than one edge at once.

Leaving as a TODO to put these in the modifier,
as doing that has more permanent effects so
want to let users shake out problems with this
first.

Modified Paths:
--------------
    trunk/blender/source/blender/bmesh/intern/bmesh_opdefines.c
    trunk/blender/source/blender/bmesh/intern/bmesh_operators.h
    trunk/blender/source/blender/bmesh/operators/bmo_bevel.c
    trunk/blender/source/blender/bmesh/tools/bmesh_bevel.c
    trunk/blender/source/blender/bmesh/tools/bmesh_bevel.h
    trunk/blender/source/blender/editors/mesh/editmesh_bevel.c
    trunk/blender/source/blender/modifiers/intern/MOD_bevel.c

Modified: trunk/blender/source/blender/bmesh/intern/bmesh_opdefines.c
===================================================================
--- trunk/blender/source/blender/bmesh/intern/bmesh_opdefines.c	2013-11-10 12:29:15 UTC (rev 61220)
+++ trunk/blender/source/blender/bmesh/intern/bmesh_opdefines.c	2013-11-10 12:31:57 UTC (rev 61221)
@@ -1557,6 +1557,7 @@
 	/* slots_in */
 	{{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},     /* input edges and vertices */
 	 {"offset", BMO_OP_SLOT_FLT},           /* amount to offset beveled edge */
+	 {"offset_type", BMO_OP_SLOT_INT},      /* how to measure offset (enum) */
 	 {"segments", BMO_OP_SLOT_INT},         /* number of segments in bevel */
 	 {"vertex_only", BMO_OP_SLOT_BOOL},	/* only bevel vertices, not edges */
 	 {{'\0'}},

Modified: trunk/blender/source/blender/bmesh/intern/bmesh_operators.h
===================================================================
--- trunk/blender/source/blender/bmesh/intern/bmesh_operators.h	2013-11-10 12:29:15 UTC (rev 61220)
+++ trunk/blender/source/blender/bmesh/intern/bmesh_operators.h	2013-11-10 12:31:57 UTC (rev 61221)
@@ -117,6 +117,14 @@
 	BMOP_POKE_BOUNDS
 };
 
+/* Bevel offset_type slot values */
+enum {
+	BEVEL_AMT_OFFSET,
+	BEVEL_AMT_WIDTH,
+	BEVEL_AMT_DEPTH,
+	BEVEL_AMT_PERCENT
+};
+
 extern const BMOpDefine *bmo_opdefines[];
 extern const int         bmo_opdefines_total;
 

Modified: trunk/blender/source/blender/bmesh/operators/bmo_bevel.c
===================================================================
--- trunk/blender/source/blender/bmesh/operators/bmo_bevel.c	2013-11-10 12:29:15 UTC (rev 61220)
+++ trunk/blender/source/blender/bmesh/operators/bmo_bevel.c	2013-11-10 12:31:57 UTC (rev 61221)
@@ -35,9 +35,10 @@
 
 void bmo_bevel_exec(BMesh *bm, BMOperator *op)
 {
-	const float offset = BMO_slot_float_get(op->slots_in, "offset");
-	const int   seg    = BMO_slot_int_get(op->slots_in,   "segments");
-	const bool  vonly  = BMO_slot_bool_get(op->slots_in,  "vertex_only");
+	const float offset      = BMO_slot_float_get(op->slots_in, "offset");
+	const int   offset_type = BMO_slot_int_get(op->slots_in,   "offset_type");
+	const int   seg         = BMO_slot_int_get(op->slots_in,   "segments");
+	const bool  vonly       = BMO_slot_bool_get(op->slots_in,  "vertex_only");
 
 	if (offset > 0) {
 		BMOIter siter;
@@ -58,7 +59,7 @@
 			}
 		}
 
-		BM_mesh_bevel(bm, offset, seg, vonly, false, false, NULL, -1);
+		BM_mesh_bevel(bm, offset, offset_type, seg, vonly, false, false, NULL, -1);
 
 		BMO_slot_buffer_from_enabled_hflag(bm, op, op->slots_out, "faces.out", BM_FACE, BM_ELEM_TAG);
 	}

Modified: trunk/blender/source/blender/bmesh/tools/bmesh_bevel.c
===================================================================
--- trunk/blender/source/blender/bmesh/tools/bmesh_bevel.c	2013-11-10 12:29:15 UTC (rev 61220)
+++ trunk/blender/source/blender/bmesh/tools/bmesh_bevel.c	2013-11-10 12:31:57 UTC (rev 61221)
@@ -73,7 +73,8 @@
 	struct BoundVert *leftv;    /* left boundary vert (looking along edge to end) */
 	struct BoundVert *rightv;   /* right boundary vert, if beveled */
 	int   seg;                  /* how many segments for the bevel */
-	float offset;               /* offset for this edge */
+	float offset_l;             /* offset for this edge, on left side */
+	float offset_r;             /* offset for this edge, on right side */
 	bool is_bev;                /* is this edge beveled? */
 	bool is_rev;                /* is e->v2 the vertex at this end? */
 	bool is_seam;               /* is e a seam for custom loopdata (e.g., UVs)? */
@@ -128,6 +129,7 @@
 	MemArena *mem_arena;    /* use for all allocs while bevel runs, if we need to free we can switch to mempool */
 
 	float offset;           /* blender units to offset each side of a beveled edge */
+	int offset_type;        /* how offset is measured; enum defined in bmesh_operators.h */
 	int seg;                /* number of segments in beveled edge profile */
 	bool vertex_only;       /* bevel vertices only */
 	bool use_weights;       /* bevel amount affected by weights on edges or verts */
@@ -469,7 +471,7 @@
 	if (ang < 100.0f * BEVEL_EPSILON) {
 		/* special case: e1 and e2 are parallel; put offset point perp to both, from v.
 		 * need to find a suitable plane.
-		 * if offsets are different, we're out of luck: just use e1->offset */
+		 * if offsets are different, we're out of luck: just use e1->offset_r */
 		if (f)
 			copy_v3_v3(norm_v, f->no);
 		else
@@ -477,14 +479,14 @@
 		cross_v3_v3v3(norm_perp1, dir1, norm_v);
 		normalize_v3(norm_perp1);
 		copy_v3_v3(off1a, v->co);
-		madd_v3_v3fl(off1a, norm_perp1, e1->offset);
+		madd_v3_v3fl(off1a, norm_perp1, e1->offset_r);
 		copy_v3_v3(meetco, off1a);
 	}
 	else if (fabsf(ang - (float)M_PI) < 100.0f * BEVEL_EPSILON) {
 		/* special case e1 and e2 are antiparallel, so bevel is into
 		 * a zero-area face.  Just make the offset point on the
 		 * common line, at offset distance from v. */
-		slide_dist(e2, v, e2->offset, meetco);
+		slide_dist(e2, v, e2->offset_l, meetco);
 	}
 	else {
 		/* get normal to plane where meet point should be */
@@ -504,10 +506,10 @@
 
 		/* get points that are offset distances from each line, then another point on each line */
 		copy_v3_v3(off1a, v->co);
-		madd_v3_v3fl(off1a, norm_perp1, e1->offset);
+		madd_v3_v3fl(off1a, norm_perp1, e1->offset_r);
 		add_v3_v3v3(off1b, off1a, dir1);
 		copy_v3_v3(off2a, v->co);
-		madd_v3_v3fl(off2a, norm_perp2, e2->offset);
+		madd_v3_v3fl(off2a, norm_perp2, e2->offset_l);
 		add_v3_v3v3(off2b, off2a, dir2);
 
 		/* intersect the lines; by construction they should be on the same plane and not parallel */
@@ -552,10 +554,10 @@
 
 	/* get points that are offset distances from each line, then another point on each line */
 	copy_v3_v3(off1a, v->co);
-	madd_v3_v3fl(off1a, norm_perp1, e1->offset);
+	madd_v3_v3fl(off1a, norm_perp1, e1->offset_r);
 	sub_v3_v3v3(off1b, off1a, dir1);
 	copy_v3_v3(off2a, v->co);
-	madd_v3_v3fl(off2a, norm_perp2, e2->offset);
+	madd_v3_v3fl(off2a, norm_perp2, e2->offset_l);
 	add_v3_v3v3(off2b, off2a, dir2);
 
 	ang = angle_v3v3(dir1, dir2);
@@ -564,7 +566,7 @@
 		copy_v3_v3(meetco, off1a);
 	}
 	else if (fabsf(ang - (float)M_PI) < 100.0f * BEVEL_EPSILON) {
-		slide_dist(e2, v, e2->offset, meetco);
+		slide_dist(e2, v, e2->offset_l, meetco);
 	}
 	else {
 		iret = isect_line_line_v3(off1a, off1b, off2a, off2b, meetco, isect2);
@@ -612,7 +614,7 @@
 		cross_v3_v3v3(fdir, no, dir);
 	normalize_v3(fdir);
 	copy_v3_v3(r, v->co);
-	madd_v3_v3fl(r, fdir, e->offset);
+	madd_v3_v3fl(r, fdir, left? e->offset_l : e->offset_r);
 }
 
 /* Calculate the point on e where line (co_a, co_b) comes closest to and return it in projco */
@@ -818,7 +820,7 @@
 		v->efirst = v->elast = e;
 		e->rightv = v;
 		/* make artifical extra point along unbeveled edge, and form triangle */
-		slide_dist(e->next, bv->v, e->offset, co);
+		slide_dist(e->next, bv->v, e->offset_l, co);
 		v = add_new_bound_vert(mem_arena, vm, co);
 		v->efirst = v->elast = e->next;
 		e->next->leftv = e->next->rightv = v;
@@ -828,7 +830,7 @@
 		return;
 	}
 
-	lastd = bp->vertex_only ? bv->offset : e->offset;
+	lastd = bp->vertex_only ? bv->offset : e->offset_l;
 	vm->boundstart = NULL;
 	do {
 		if (e->is_bev) {
@@ -1921,6 +1923,18 @@
 	}
 }
 
+/* Return the angle between the two faces adjacent to e.
+ * If there are not two, return 0. */
+static float edge_face_angle(EdgeHalf *e) {
+	if (e->fprev && e->fnext) {
+		/* angle between faces is supplement of angle between face normals */
+		return (float)M_PI - angle_normalized_v3v3(e->fprev->no, e->fnext->no);
+	}
+	else {
+		return 0.0f;
+	}
+}
+
 /* take care, this flag isn't cleared before use, it just so happens that its not set */
 #define BM_BEVEL_EDGE_TAG_ENABLE(bme)  BM_ELEM_API_FLAG_ENABLE(  (bme), _FLAG_OVERLAP)
 #define BM_BEVEL_EDGE_TAG_DISABLE(bme) BM_ELEM_API_FLAG_DISABLE( (bme), _FLAG_OVERLAP)
@@ -1937,7 +1951,7 @@
 	BMFace *f;
 	BMIter iter, iter2;
 	EdgeHalf *e;
-	float weight;
+	float weight, z;
 	int i, found_shared_face, ccw_test_sum;
 	int nsel = 0;
 	int ntot = 0;
@@ -2053,16 +2067,6 @@
 			e->seg = 0;
 		}
 		e->is_rev = (bme->v2 == v);
-		if (e->is_bev) {
-			e->offset = bp->offset;
-			if (bp->use_weights) {
-				weight = BM_elem_float_data_get(&bm->edata, bme, CD_BWEIGHT);
-				e->offset *= weight;
-			}
-		}
-		else {
-			e->offset = 0.0f;
-		}
 	}
 	/* find wrap-around shared face */
 	BM_ITER_ELEM (f, &iter2, bme, BM_FACES_OF_EDGE) {
@@ -2098,6 +2102,50 @@
 	for (i = 0, e = bv->edges; i < ntot; i++, e++) {
 		e->next = &bv->edges[(i + 1) % ntot];
 		e->prev = &bv->edges[(i + ntot - 1) % ntot];
+
+		/* set offsets  */
+		if (e->is_bev) {
+			/* Convert distance as specified by user into offsets along
+			 * faces on left side and right side of this edgehalf.
+			 * Except for percent method, offset will be same on each side. */
+			switch (bp->offset_type) {
+			case BEVEL_AMT_OFFSET:
+				e->offset_l = bp->offset;
+				break;
+			case BEVEL_AMT_WIDTH:
+				z = fabs(2.0f * sinf(edge_face_angle(e) / 2.0f));
+				if (z < BEVEL_EPSILON)
+					e->offset_l = 0.01f * bp->offset; /* undefined behavior, so tiny bevel */
+				else
+					e->offset_l = bp->offset / z;
+				break;
+			case BEVEL_AMT_DEPTH:
+				z = fabs(cosf(edge_face_angle(e) / 2.0f));
+				if (z < BEVEL_EPSILON)
+					e->offset_l = 0.01f * bp->offset; /* undefined behavior, so tiny bevel */
+				else
+					e->offset_l = bp->offset / z;
+				break;
+			case BEVEL_AMT_PERCENT:
+				e->offset_l = BM_edge_calc_length(e->prev->e) * bp->offset / 100.0f;
+				e->offset_r = BM_edge_calc_length(e->next->e) * bp->offset / 100.0f;
+				break;
+			default:
+				BLI_assert(!"bad bevel offset kind");
+				e->offset_l = bp->offset;
+			}
+			if (bp->offset_type != BEVEL_AMT_PERCENT)
+				e->offset_r = e->offset_l;
+			if (bp->use_weights) {
+				weight = BM_elem_float_data_get(&bm->edata, bme, CD_BWEIGHT);
+				e->offset_l *= weight;
+				e->offset_r *= weight;
+			}
+		}
+		else {
+			e->offset_l = e->offset_r = 0.0f;
+		}
+
 		BM_BEVEL_EDGE_TAG_DISABLE(e->e);
 		if (e->fprev && e->fnext)
 			e->is_seam = !contig_ldata_across_edge(bm, e->e, e->fprev, e->fnext);
@@ -2370,7 +2418,7 @@
  *
  * \warning all tagged edges _must_ be manifold.
  */
-void BM_mesh_bevel(BMesh *bm, const float offset, const float segments,
+void BM_mesh_bevel(BMesh *bm, const float offset, const int offset_type, const float segments,

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list