[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [53937] trunk/blender/source/blender: Bevel vertex only (shortcut: control-shift-B) initial commit.

Howard Trickey howard.trickey at gmail.com
Mon Jan 21 02:52:28 CET 2013


Revision: 53937
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=53937
Author:   howardt
Date:     2013-01-21 01:52:23 +0000 (Mon, 21 Jan 2013)
Log Message:
-----------
Bevel vertex only (shortcut: control-shift-B) initial commit.

Modified Paths:
--------------
    trunk/blender/source/blender/bmesh/tools/bmesh_bevel.c
    trunk/blender/source/blender/editors/mesh/mesh_ops.c

Modified: trunk/blender/source/blender/bmesh/tools/bmesh_bevel.c
===================================================================
--- trunk/blender/source/blender/bmesh/tools/bmesh_bevel.c	2013-01-21 01:01:15 UTC (rev 53936)
+++ trunk/blender/source/blender/bmesh/tools/bmesh_bevel.c	2013-01-21 01:52:23 UTC (rev 53937)
@@ -41,9 +41,6 @@
 
 
 
-/* experemental - Campbell */
-// #define USE_ALTERNATE_ADJ
-
 #define BEVEL_EPSILON  1e-6
 
 /* for testing */
@@ -94,7 +91,7 @@
 		M_NONE,         /* no polygon mesh needed */
 		M_POLY,         /* a simple polygon */
 		M_ADJ,          /* "adjacent edges" mesh pattern */
-//		M_CROSS,        /* "cross edges" mesh pattern */
+		M_ADJ_SUBDIV,   /* like M_ADJ, but using subdivision */
 		M_TRI_FAN,      /* a simple polygon - fan filled */
 		M_QUAD_STRIP,   /* a simple polygon - cut into paralelle strips */
 	} mesh_kind;
@@ -124,7 +121,7 @@
 
 // #pragma GCC diagnostic ignored "-Wpadded"
 
-//#include "bevdebug.c"
+// #include "bevdebug.c"
 
 /* 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. */
@@ -501,79 +498,6 @@
 	return lb->next == la ? 1 : -1;
 }
 
-#ifdef USE_ALTERNATE_ADJ
-
-static void vmesh_cent(VMesh *vm, float r_cent[3])
-{
-	BoundVert *v;
-	zero_v3(r_cent);
-
-	v = vm->boundstart;
-	do {
-		add_v3_v3(r_cent, v->nv.co);
-	} while ((v = v->next) != vm->boundstart);
-	mul_v3_fl(r_cent, 1.0f / (float)vm->count);
-}
-
-/**
- *
- * This example shows a tri fan of quads,
- * but could be an NGon fan of quads too.
- * <pre>
- *      The whole triangle   X
- *      represents the      / \
- *      new bevel face.    /   \
- *                        /     \
- *       Split into      /       \
- *       a quad fan.    /         \
- *                     /           \
- *                    /             \
- *                   /               \
- *          co_prev +-.             .-+
- *                 /   `-._     _.-'   \
- *                / co_cent`-+-'        \
- *               /           |           \
- * Quad of      /            |            \
- * interest -- / ---> X      |             \
- *            /              |              \
- *           /               |               \
- *          /         co_next|                \
- * co_orig +-----------------+-----------------+
- *
- *         For each quad, calcualte UV's based on the following:
- *           U = k    / (vm->seg * 2)
- *           V = ring / (vm->seg * 2)
- *           quad = (co_orig, co_prev, co_cent, co_next)
- *           ... note that co_cent is the same for all quads in the fan.
- * </pre>
- *
- */
-
-static void get_point_uv(float uv[2],
-                         /* all these args are int's originally
-                          * but pass as floats to the function */
-                         const float seg, const float ring, const float k)
-{
-	uv[0] = (ring / seg) * 2.0f;
-	uv[1] = (k    / seg) * 2.0f;
-}
-
-/* TODO: make this a lot smarter!,
- * this is the main reason USE_ALTERNATE_ADJ isn't so good right now :S */
-static float get_point_uv_factor(const float uv[2])
-{
-	return sinf(1.0f - max_ff(uv[0], uv[1]) / 2.0f);
-}
-
-static void get_point_on_round_edge(const float uv[2],
-                                    float quad[4][3],
-                                    float r_co[3])
-{
-	interp_bilinear_quad_v3(quad, uv[0], uv[1], r_co);
-}
-
-#else  /* USE_ALTERNATE_ADJ */
-
 /* Fill matrix r_mat so that a point in the sheared parallelogram with corners
  * va, vmid, vb (and the 4th that is implied by it being a parallelogram)
  * is transformed to the unit square by multiplication with r_mat.
@@ -694,8 +618,6 @@
 	}
 }
 
-#endif  /* !USE_ALTERNATE_ADJ */
-
 /* Make a circular list of BoundVerts for bv, each of which has the coordinates
  * of a vertex on the the boundary of the beveled vertex bv->v.
  * Also decide on the mesh pattern that will be used inside the boundary.
@@ -811,7 +733,10 @@
 	} while ((e = e->next) != efirst);
 
 	BLI_assert(vm->count >= 2);
-	if (vm->count == 2 && bv->edgecount == 3) {
+	if (bp->vertex_only) {
+		vm->mesh_kind = bp->seg > 1 ? M_ADJ_SUBDIV : M_POLY;
+	}
+	else if (vm->count == 2 && bv->edgecount == 3) {
 		vm->mesh_kind = M_NONE;
 	}
 	else if (bv->selcount == 2) {
@@ -846,19 +771,6 @@
 	float co[3], coa[3], cob[3], midco[3];
 	float va_pipe[3], vb_pipe[3];
 
-#ifdef USE_ALTERNATE_ADJ
-	/* ordered as follows (orig, prev, center, next)*/
-	float quad_plane[4][3];
-	float quad_orig[4][3];
-#endif
-
-
-#ifdef USE_ALTERNATE_ADJ
-	/* the rest are initialized inline, this remains the same for all */
-	vmesh_cent(vm, quad_plane[2]);
-	copy_v3_v3(quad_orig[2], bv->v->co);
-#endif
-
 	n = vm->count;
 	ns = vm->seg;
 	ns2 = ns / 2;
@@ -918,37 +830,6 @@
 				copy_v3_v3(nv->co, cob);
 				nv->v = nvnext->v;
 
-#ifdef USE_ALTERNATE_ADJ
-				/* plane */
-				copy_v3_v3(quad_plane[0], v->nv.co);
-				mid_v3_v3v3(quad_plane[1], v->nv.co, v->prev->nv.co);
-				/* quad[2] is set */
-				mid_v3_v3v3(quad_plane[3], v->nv.co, v->next->nv.co);
-
-				/* orig */
-				copy_v3_v3(quad_orig[0], v->nv.co);  /* only shared location between 2 quads */
-				project_to_edge(v->ebev->prev->e, v->nv.co, v->prev->nv.co, quad_orig[1]);
-				project_to_edge(v->ebev->e,       v->nv.co, v->next->nv.co, quad_orig[3]);
-
-				//bl_debug_draw_quad_add(UNPACK4(quad_plane));
-				//bl_debug_draw_quad_add(UNPACK4(quad_orig));
-#endif
-
-#ifdef USE_ALTERNATE_ADJ
-				for (k = 1; k < ns; k++) {
-					float uv[2];
-					float fac;
-					float co_plane[3];
-					float co_orig[3];
-
-					get_point_uv(uv, v->ebev->seg, ring, k);
-					get_point_on_round_edge(uv, quad_plane, co_plane);
-					get_point_on_round_edge(uv, quad_orig,  co_orig);
-					fac = get_point_uv_factor(uv);
-					interp_v3_v3v3(co, co_plane, co_orig, fac);
-					copy_v3_v3(mesh_vert(vm, i, ring, k)->co, co);
-				}
-#else
 				/* TODO: better calculation of new midarc point? */
 				project_to_edge(v->ebev->e, coa, cob, midco);
 
@@ -962,7 +843,6 @@
 					copy_v3_v3(va_pipe, mesh_vert(vm, i, 0, 0)->co);
 					copy_v3_v3(vb_pipe, mesh_vert(vm, i, 0, ns)->co);
 				}
-#endif
 			}
 		} while ((v = v->next) != vm->boundstart);
 	}
@@ -990,9 +870,7 @@
 						if (epipe)
 							snap_to_edge_profile(epipe, va_pipe, vb_pipe, co);
 
-#ifndef USE_ALTERNATE_ADJ
 						copy_v3_v3(nv->co, co);
-#endif
 						BLI_assert(nv->v == NULL && nvprev->v == NULL);
 						create_mesh_bmvert(bm, vm, i, ring, k, bv->v);
 						copy_mesh_vert(vm, vprev->index, k, ns - ring, i, ring, k);
@@ -1041,9 +919,7 @@
 						mid_v3_v3v3v3(co, nvprev->co, nv->co, nvnext->co);
 						if (epipe)
 							snap_to_edge_profile(epipe, va_pipe, vb_pipe, co);
-#ifndef USE_ALTERNATE_ADJ
 						copy_v3_v3(nv->co, co);
-#endif
 						create_mesh_bmvert(bm, vm, i, k, ns2, bv->v);
 						copy_mesh_vert(vm, vprev->index, ns2, ns - k, i, k, ns2);
 						copy_mesh_vert(vm, vnext->index, ns2, k, i, k, ns2);
@@ -1053,9 +929,7 @@
 						mid_v3_v3v3(co, nvprev->co, nv->co);
 						if (epipe)
 							snap_to_edge_profile(epipe, va_pipe, vb_pipe, co);
-#ifndef USE_ALTERNATE_ADJ
 						copy_v3_v3(nv->co, co);
-#endif
 						create_mesh_bmvert(bm, vm, i, k, ns2, bv->v);
 						copy_mesh_vert(vm, vprev->index, ns2, ns - k, i, k, ns2);
 
@@ -1065,9 +939,7 @@
 						mid_v3_v3v3(co, nv->co, nvnext->co);
 						if (epipe)
 							snap_to_edge_profile(epipe, va_pipe, vb_pipe, co);
-#ifndef USE_ALTERNATE_ADJ
 						copy_v3_v3(nv->co, co);
-#endif
 						create_mesh_bmvert(bm, vm, i, k, ns2, bv->v);
 						copy_mesh_vert(vm, vnext->index, ns2, k, i, k, ns2);
 
@@ -1220,6 +1092,385 @@
 	}
 }
 
+static VMesh* new_adj_subdiv_vmesh(MemArena *mem_arena, int count, int seg)
+{
+	VMesh *vm;
+
+	vm = (VMesh *)BLI_memarena_alloc(mem_arena, sizeof(VMesh));
+	vm->count = count;
+	vm->seg = seg;
+	vm->mesh = (NewVert *)BLI_memarena_alloc(mem_arena, count * (1 + seg/2) * (1 + seg) * sizeof(NewVert));
+	vm->mesh_kind = M_ADJ_SUBDIV;
+	return vm;
+}
+
+/* VMesh verts for vertex i have data for (i, 0 <= j <= ns2, 0 <= k <= ns), where ns2 = floor(nseg / 2).
+ * But these overlap data from previous and next i: there are some forced equivalences.
+ * Let's call these indices the canonical ones: we will just calculate data for these
+ *    0 <= j <= ns2, 0 <= k < ns2  (for odd ns2)
+ *    0 <= j < ns2, 0 <= k <= ns2  (for even ns2)
+ *        also (j=ns2, k=ns2) at i=0 (for even ns2)
+ * This function returns the canonical one for any i, j, k in [0,n],[0,ns],[0,ns] */
+static NewVert* mesh_vert_canon(VMesh *vm, int i, int j, int k)
+{
+	int n, ns, ns2, odd;
+	NewVert *ans;
+
+	n = vm->count;
+	ns = vm->seg;
+	ns2 = ns / 2;
+	odd = ns % 2;
+	BLI_assert(0 <= i && i <= n && 0 <= j && j <= ns && 0 <= k && k <= ns);
+
+	if (!odd && j == ns2 && k == ns2)
+		ans = mesh_vert(vm, 0, j, k);
+	else if (j <= ns2 - 1 + odd && k <= ns2)
+		ans = mesh_vert(vm, i, j, k);
+	else if (k <= ns2)
+		ans = mesh_vert(vm, (i + n - 1) % n, k, ns - j);
+	else
+		ans = mesh_vert(vm, (i + 1) % n, ns - k, j);
+	return ans;
+}
+
+static int is_canon(VMesh *vm, int i, int j, int k)
+{
+	int ns2 = vm->seg / 2;
+	if (vm->seg % 2 == 1)
+		return (j <= ns2 && k <= ns2);
+	else
+		return ((j < ns2 && k <= ns2) || (j == ns2 && k == ns2 && i == 0));
+}
+
+/* Copy the vertex data to all of vm verts from canonical ones */
+static void vmesh_copy_equiv_verts(VMesh *vm)
+{
+	int n, ns, ns2, i, j, k;
+	NewVert *v0, *v1;
+
+	n = vm->count;
+	ns = vm->seg;
+	ns2 = ns / 2;
+	for (i = 0; i < n; i++) {
+		for (j = 0; j <= ns2; j++) {
+			for (k = 0; k <= ns; k++) {
+				if (is_canon(vm, i, j, k))
+					continue;
+				v1 = mesh_vert(vm, i, j, k);
+				v0 = mesh_vert_canon(vm, i, j, k);
+				copy_v3_v3(v1->co, v0->co);
+				v1->v = v0->v;
+			}
+		}
+	}
+}
+
+/* Calculate and return in r_cent the centroid of the center poly */
+static void vmesh_center(VMesh *vm, float r_cent[3])
+{
+	int n, ns2, i;
+
+	n = vm->count;
+	ns2 = vm->seg / 2;
+	if (vm->seg % 2) {
+		zero_v3(r_cent);
+		for (i = 0; i < n; i++) {
+			add_v3_v3(r_cent, mesh_vert(vm, i, ns2, ns2)->co);
+		}
+		mul_v3_fl(r_cent, 1.0f / (float) n);
+	}
+	else {
+		copy_v3_v3(r_cent, mesh_vert(vm, 0, ns2, ns2)->co);
+	}
+}
+
+/* Do one step of quadratic subdivision (Doo-Sabin), with special rules at boundaries.
+ * For now, this is written assuming vm0->nseg is odd.
+ * See Hwang-Chuang 2003 paper: "N-sided hole filling and vertex blending using subdivision surfaces"  */
+static VMesh* quadratic_subdiv(MemArena *mem_arena, VMesh *vm0)
+{

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list