[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