[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [52268] trunk/blender/source/blender/bmesh /operators/bmo_bevel.c: wip - alternate bevel curve calculation ( still disabled)

Campbell Barton ideasman42 at gmail.com
Fri Nov 16 09:12:09 CET 2012


Revision: 52268
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=52268
Author:   campbellbarton
Date:     2012-11-16 08:12:06 +0000 (Fri, 16 Nov 2012)
Log Message:
-----------
wip - alternate bevel curve calculation (still disabled)

now USE_ALTERNATE_ADJ works, giving more stable corners that don't flicker and glitch out as the offset changes.

The shape is not a circle though and doesnt look quite as nice as the existing method.

Modified Paths:
--------------
    trunk/blender/source/blender/bmesh/operators/bmo_bevel.c

Modified: trunk/blender/source/blender/bmesh/operators/bmo_bevel.c
===================================================================
--- trunk/blender/source/blender/bmesh/operators/bmo_bevel.c	2012-11-16 07:56:47 UTC (rev 52267)
+++ trunk/blender/source/blender/bmesh/operators/bmo_bevel.c	2012-11-16 08:12:06 UTC (rev 52268)
@@ -437,7 +437,6 @@
 	madd_v3_v3fl(slideco, dir, -d);
 }
 
-#ifndef USE_ALTERNATE_ADJ
 /* Calculate the point on e where line (co_a, co_b) comes closest to and return it in projco */
 static void project_to_edge(BMEdge *e, const float co_a[3], const float co_b[3], float projco[3])
 {
@@ -448,7 +447,6 @@
 		copy_v3_v3(projco, e->v1->co);
 	}
 }
-#endif
 
 /* return 1 if a and b are in CCW order on the normal side of f,
  * and -1 if they are reversed, and 0 if there is no shared face f */
@@ -515,13 +513,26 @@
  *
  */
 
-static void get_point_on_round_edge(EdgeHalf *e, int ring, int k,
+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])
 {
-	const float n = e->seg;
-	const float uv[2] = {(ring / n) * 2.0f, (k / n) * 2.0f};
-
 	interp_bilinear_quad_v3(quad, uv[0], uv[1], r_co);
 }
 
@@ -763,9 +774,15 @@
 
 #ifdef USE_ALTERNATE_ADJ
 	/* ordered as follows (orig, prev, center, next)*/
-	float quad[4][3];
+	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[2]);
+	vmesh_cent(vm, quad_plane[2]);
+	copy_v3_v3(quad_orig[2], bv->v->co);
 #endif
 
 	n = vm->count;
@@ -805,15 +822,33 @@
 				nv->v = nvnext->v;
 
 #ifdef USE_ALTERNATE_ADJ
-				copy_v3_v3(quad[0], v->nv.co);
-				mid_v3_v3v3(quad[1], v->nv.co, v->prev->nv.co);
+				/* 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[3], v->nv.co, v->next->nv.co);
+				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++) {
-					get_point_on_round_edge(v->ebev, ring, k, quad, co);
+					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
@@ -1190,14 +1225,20 @@
 
 #ifdef USE_ALTERNATE_ADJ
 	/* ordered as follows (orig, prev, center, next)*/
-	float quad[4][3];
+	float quad_plane[4][3];
+	float quad_orig_a[4][3];
+	float quad_orig_b[4][3];
+	const int is_odd = (vm->seg % 2);
 #else
 	float midco[3];
 #endif
 
 #ifdef USE_ALTERNATE_ADJ
 	/* the rest are initialized inline, this remains the same for all */
-	vmesh_cent(vm, quad[2]);
+	/* NOTE; in this usage we only interpolate on the 'V' so cent and next points are unused (2,3)*/
+	vmesh_cent(vm, quad_plane[2]);
+	copy_v3_v3(quad_orig_a[2], bv->v->co);
+	copy_v3_v3(quad_orig_b[2], bv->v->co);
 #endif
 
 	n = vm->count;
@@ -1228,25 +1269,62 @@
 	/* copy other ends to (i, 0, ns) for all i, and fill in profiles for beveled edges */
 	v = vm->boundstart;
 	do {
-
-#ifdef USE_ALTERNATE_ADJ
-		copy_v3_v3(quad[0], v->nv.co);
-		mid_v3_v3v3(quad[1], v->nv.co, v->prev->nv.co);
-		/* quad[2] is set */
-		mid_v3_v3v3(quad[3], v->nv.co, v->next->nv.co);
-#endif
-
 		i = v->index;
 		copy_mesh_vert(vm, i, 0, ns, v->next->index, 0, 0);
 		if (v->ebev) {
+
 #ifdef USE_ALTERNATE_ADJ
+			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 'A' */
+			copy_v3_v3(quad_orig_a[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_a[1]);
+			project_to_edge(v->ebev->e,       v->nv.co, v->next->nv.co, quad_orig_a[3]);
+
+			/* orig 'B' */
+			copy_v3_v3(quad_orig_b[3], v->next->nv.co);  /* only shared location between 2 quads */
+			project_to_edge(v->ebev->prev->e, v->nv.co, v->prev->nv.co, quad_orig_b[1]);
+			project_to_edge(v->ebev->e,       v->nv.co, v->next->nv.co, quad_orig_b[0]);
+
+			//bl_debug_draw_quad_add(UNPACK4(quad_plane));
+			//bl_debug_draw_quad_add(UNPACK4(quad_orig_a));
+			//bl_debug_draw_quad_add(UNPACK4(quad_orig_b));
+#endif  /* USE_ALTERNATE_ADJ */
+
+#ifdef USE_ALTERNATE_ADJ
 			for (k = 1; k < ns; k++) {
-				get_point_on_round_edge(v->ebev, 0, k, quad, co);
+				float uv[2];
+				float fac;
+				float co_plane[3];
+				float co_orig[3];
+
+				/* quad_plane */
+				get_point_uv(uv, v->ebev->seg, 0, k);
+				get_point_on_round_edge(uv, quad_plane, co_plane);
+
+				/* quad_orig */
+				/* each half has different UV's */
+				if (k <= ns2) {
+					get_point_uv(uv, v->ebev->seg, 0, k);
+					get_point_on_round_edge(uv, quad_orig_a, co_orig);
+				}
+				else {
+					get_point_uv(uv, v->ebev->seg, 0, (k - ns2) - (is_odd ? 0.5f : 0.0f));
+					get_point_on_round_edge(uv, quad_orig_b, co_orig);
+					uv[1] = 1.0f - uv[1];  /* so we can get the factor */
+				}
+				fac = get_point_uv_factor(uv);
+
+				/* done. interp */
+				interp_v3_v3v3(co, co_plane, co_orig, fac);
 				copy_v3_v3(mesh_vert(vm, i, 0, k)->co, co);
 				if (!weld)
 					create_mesh_bmvert(bm, vm, i, 0, k, bv->v);
 			}
-#else
+#else  /* USE_ALTERNATE_ADJ */
 			va = mesh_vert(vm, i, 0, 0)->co;
 			vb = mesh_vert(vm, i, 0, ns)->co;
 			project_to_edge(v->ebev->e, va, vb, midco);
@@ -1256,7 +1334,7 @@
 				if (!weld)
 					create_mesh_bmvert(bm, vm, i, 0, k, bv->v);
 			}
-#endif
+#endif  /* !USE_ALTERNATE_ADJ */
 		}
 	} while ((v = v->next) != vm->boundstart);
 




More information about the Bf-blender-cvs mailing list