[Bf-blender-cvs] [323e34aa28b] soc-2017-sculpting_improvements: Reworked most of the vertex/edge/poly/loop generation. Added a unified interpolation method. Vertices are now subsequent so it will be easier to bridge the different parts. Removed dependency on the order of generation.

witt noreply at git.blender.org
Mon Jul 10 19:02:04 CEST 2017


Commit: 323e34aa28b06d91f0d94b81783a367f10a867cb
Author: witt
Date:   Mon Jul 10 18:56:27 2017 +0200
Branches: soc-2017-sculpting_improvements
https://developer.blender.org/rB323e34aa28b06d91f0d94b81783a367f10a867cb

Reworked most of the vertex/edge/poly/loop generation. Added a unified interpolation method. Vertices are now subsequent so it will be easier to bridge the different parts. Removed dependency on the order of generation.

===================================================================

M	source/blender/editors/sculpt_paint/sculpt.c

===================================================================

diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 9fb6a514ee7..29ee294258a 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -116,6 +116,7 @@
 #include "BLI_edgehash.h"
 #include "BLI_linklist.h"
 #include "BLI_alloca.h"
+#include "BLI_array.h"
 
 #define DEBUG_DRAW
 #ifdef DEBUG_DRAW
@@ -5164,8 +5165,7 @@ static void sculpt_silhouette_stroke_update(bContext *C, float mouse[2], Silhoue
 
 typedef enum {
 	BRANCH_INIT = 0,
-	BRANCH_VERT_GEN = 1,	/* Verts on the branch ends are stored */
-	BRANCH_EDGE_GEN = 2		/* Edges on the ends are stored (used primarly for bridging) */
+	BRANCH_EDGE_GEN = 1	/* Edges on the ends are stored (used primarly for bridging) */
 } BranchState;
 
 
@@ -5188,7 +5188,6 @@ typedef struct SpineBranch{
 	int idx;				/* Index in the Spine branches array */
 	int *terminal_points;	/* Description of the connected branches. Per fork 2 ints (point,branch_idx) */
 	BranchState flag;
-	int *gen_verts;			/* Verts on the branch ends are stored */
 	int *e_start_arr;		/* Edges on the ends are stored (used primarly for bridging) */
 }SpineBranch;
 
@@ -5288,9 +5287,6 @@ static void free_spine_branch(SpineBranch *branch)
 	if (branch->terminal_points) {
 		MEM_freeN(branch->terminal_points);
 	}
-	if (branch->flag & BRANCH_VERT_GEN) {
-		MEM_freeN(branch->gen_verts);
-	}
 	if (branch->flag & BRANCH_EDGE_GEN) {
 		MEM_freeN(branch->e_start_arr);
 	}
@@ -5533,6 +5529,91 @@ static Spine *silhouette_generate_spine(SilhouetteData *sil, SilhouetteStroke *s
 	return spine;
 }
 
+/*
+ *  d      ** | ******c
+ *      *     |       |
+ *    *       |       |
+ *   *        |       |
+ *  *         |       |
+ *  ---------- --------
+ *  *         |       |
+ *  *      smooth     |
+ * a _________|______ b
+ * Interpolate between the three points resulting in a vertex line between a and c.
+ * Smoothness regulates the cutoff to start a circular interpolation
+ */
+static void calc_vert_quarter(Mesh *me, float a[3], float b[3], float c[3], int v_steps, int w_h_steps, float smoothness, bool flip){
+	int v_start = me->totvert;
+	int v_pos = flip ? v_start + v_steps + w_h_steps - 1 : v_start;
+	float inv_smooth = 1.0f - smoothness;
+	float v1[3], v2[3], v3[3], v4[3], v5[3], up[3], side[3], d[3];
+	float f_sin, f_cos;
+	int s_steps_w = inv_smooth * (w_h_steps + 1);
+	int s_steps_v = inv_smooth * v_steps;
+	int s_steps_c = v_steps - s_steps_v + w_h_steps - s_steps_w;
+
+	ED_mesh_vertices_add(me, NULL, v_steps + w_h_steps);
+
+	sub_v3_v3v3(up, c, b);
+	add_v3_v3v3(d, a, up);
+	mul_v3_fl(up, 1.0f / (float)v_steps);
+	sub_v3_v3v3(side, a, b);
+	mul_v3_fl(side, 1.0f / (float)(w_h_steps + 1));
+	mul_v3_v3fl(v2, side, s_steps_w);
+	add_v3_v3(v2, c);
+
+	copy_v3_v3(v1, a);
+	for (int v = 0; v < s_steps_v; v++) {
+		copy_v3_v3(me->mvert[v_pos].co, v1);
+		me->mvert[v_pos].flag = 0;
+		me->mvert[v_pos].bweight = 0;
+		v_pos += flip ? - 1 : 1;
+		if (v < s_steps_v - 1) {
+			add_v3_v3(v1, up);
+		}
+	}
+
+	sub_v3_v3v3(v3, d, v1);
+	sub_v3_v3v3(v4, d, v2);
+	sub_v3_v3(v1, v4);
+
+	for (int c = 1; c < s_steps_c + 1; c++) {
+		f_sin = sin(((float)c / (float)(s_steps_c + 1)) * M_PI / 2);
+		f_cos = cos(((float)c / (float)(s_steps_c + 1)) * M_PI / 2);
+
+		mul_v3_v3fl(v2, v4, f_cos);
+		add_v3_v3v3(v5, v2, v1);
+		mul_v3_v3fl(v2, v3, f_sin);
+		add_v3_v3(v5, v2);
+
+		copy_v3_v3(me->mvert[v_pos].co, v5);
+		me->mvert[v_pos].flag = 0;
+		me->mvert[v_pos].bweight = 0;
+		v_pos += flip ? - 1 : 1;
+	}
+
+	add_v3_v3(v1, v3);
+	for (int w = 0; w < s_steps_w; w++) {
+		copy_v3_v3(me->mvert[v_pos].co, v1);
+		me->mvert[v_pos].flag = 0;
+		me->mvert[v_pos].bweight = 0;
+		sub_v3_v3(v1, side);
+		v_pos += flip ? - 1 : 1;
+	}
+}
+
+/* W_steps needs to be uneven! */
+static void calc_vert_half(Mesh *me, float left[3], float right[3], float center[3], float upper_center[3], int v_steps, int w_steps, float smoothness)
+{
+	int half_w = w_steps / 2;
+	calc_vert_quarter(me, left, center, upper_center, v_steps, half_w, smoothness, false);
+	ED_mesh_vertices_add(me, NULL, 1);
+	copy_v3_v3(me->mvert[me->totvert - 1].co, upper_center);
+	me->mvert[me->totvert - 1].flag = 0;
+	me->mvert[me->totvert - 1].bweight = 0;
+	calc_vert_quarter(me, right, center, upper_center, v_steps, half_w, smoothness, true);
+}
+
 /* Create standardised Mesh. Simple UxV rectangular grid. (Edges, Loops, Polys):*/
 static void generate_mesh_grid_f_e(Mesh *me, int u_steps, int v_steps, int v_start, bool n_flip)
 {
@@ -5662,45 +5743,6 @@ static void bridge_loops(Mesh *me, int e_start_a, int e_start_b, int totvert, bo
 	}
 }
 
-/* TODO: Redundant */
-static void bridge_loop_flip(Mesh *me, int v_start_a, int v_start_b, int totvert, bool flip, int l_start_a, int l_start_b, int l_stride)
-{
-	int e_start = me->totedge;
-	int l_start = me->totloop;
-	int p_start = me->totpoly;
-	ED_mesh_edges_add(me, NULL, totvert);
-	ED_mesh_loops_add(me, NULL, 4 * totvert - 4);
-	ED_mesh_polys_add(me, NULL, totvert - 1);
-
-	for (int i = 0; i < totvert; i++) {
-		me->medge[e_start + i].crease = 0;
-		me->medge[e_start + i].bweight = 0;
-		me->medge[e_start + i].flag = 0;
-		me->medge[e_start + i].v1 = v_start_a + i;
-		me->medge[e_start + i].v2 = v_start_b + (flip ? -i : i);
-
-		if (i < totvert - 1) {
-			me->mloop[l_start + i * 4 + 0].v = v_start_a + i;
-			me->mloop[l_start + i * 4 + 0].e = l_start_a + i * l_stride;
-
-			me->mloop[l_start + i * 4 + 1].v = v_start_a + i + 1;
-			me->mloop[l_start + i * 4 + 1].e = e_start + i + 1;
-
-			me->mloop[l_start + i * 4 + 2].v = v_start_b + (flip ? -i - 1 : i + 1);
-			me->mloop[l_start + i * 4 + 2].e = l_start_b + (flip ? -i : i) * l_stride;
-
-			me->mloop[l_start + i * 4 + 3].v = v_start_b + (flip ? -i : i);
-			me->mloop[l_start + i * 4 + 3].e = e_start + i;
-
-			me->mpoly[p_start + i].loopstart = l_start + i * 4;
-			me->mpoly[p_start + i].totloop = 4;
-			me->mpoly[p_start + i].mat_nr = 0;
-			me->mpoly[p_start + i].flag = 0;
-			me->mpoly[p_start + i].pad = 0;
-		}
-	}
-}
-
 /* TODO: is there a sort function already?*/
 static int cmpfunc (const void * a, const void * b)
 {
@@ -5708,162 +5750,63 @@ static int cmpfunc (const void * a, const void * b)
 }
 
 /* Generate the Tube shape for branches with two ends. */
-static void fill_tube(Mesh *me, float *left, float *right, int totl, int totr, int u_steps, float z_vec[3], int ss_steps, int w_steps, float w_fact, int *e_start_sides)
+static void fill_tube(Mesh *me, float *left, float *right, int totl, int totr, int u_steps, float z_vec[3], int v_steps, int w_steps, float smoothness, int *UNUSED(r_edge_loop_ends))
 {
-	int v_steps = ss_steps;
-	int square_ss_steps = u_steps * v_steps;
 	float step_l = left[totl * 4 - 1] / (float)u_steps;
 	float step_r = right[totr * 4 - 1] / (float)u_steps;
 	float a, b, f;
-	float v1[3], v2[3], v3[3], v4[3], z_vec_b[3];
-	int l_u_pos_i = 1, r_u_pos_i = totr - 1;
-	int v_pos_w = 0;
+	float v1[3], v2[3], v3[3], v4[3];
+	int l_u_pos_i = 1, r_u_pos_i = totr - 2;
 
-	int ve_start_a, ve_start_ar, ve_start_b;
 	const int v_start = me->totvert;
-	MVert ref_v;
-	ref_v.flag = 0; ref_v.bweight = 0;
-	ED_mesh_vertices_add(me, NULL, square_ss_steps * 2 + (w_steps - 1) * u_steps);
+	//const int e_start = me->totedge;
 
 	for (int u = 0; u < u_steps; u++) {
-		while (left[l_u_pos_i * 4 + 3] <= step_l * (float)u && l_u_pos_i < totl) {
+		while (l_u_pos_i < totl - 1 && left[l_u_pos_i * 4 + 3] <= step_l * (float)u) {
 			l_u_pos_i ++;
 		}
 
-		while (right[r_u_pos_i * 4 + 3] > step_r * (float)(u_steps - u - 1) && r_u_pos_i > 0) {
+		while (r_u_pos_i > 0 && right[r_u_pos_i * 4 + 3] > step_r * (float)(u_steps - u - 1)) {
 			r_u_pos_i --;
 		}
 
 		/* Interpolate over the points of each side. Interpolate an even point distribution along the line */
-		a = left[l_u_pos_i * 4 - 1];
-		b = left[l_u_pos_i * 4 + 3];
-		f = (step_l * (float)u - a) / (b - a);
-		interp_v3_v3v3(v1, &left[l_u_pos_i * 4 - 4], &left[l_u_pos_i * 4], f);
-
-		a = right[r_u_pos_i * 4 + 7];
-		b = right[r_u_pos_i * 4 + 3];
-		f = (step_r * (float)(u_steps - u - 1) - a) / (b - a);
-		interp_v3_v3v3(v2, &right[r_u_pos_i * 4 + 4], &right[r_u_pos_i * 4], f);
-
-		copy_v3_v3(z_vec_b, z_vec);
-
-		/*TODO: Different interpolation, different shapes, smoothness etc*/
-		/* Interpolate point position in z-direction. Smoothing etc is done here. Redundant?*/
-		for (int v = 0; v < ss_steps; v++) {
-			add_v3_v3(v1, z_vec_b);
-			add_v3_v3(v2, z_vec_b);
-			f = (float)v/(float)(v_steps * 2);
-			f = (sin(M_PI * f - M_PI * 0.5f) * 0.5f + 0.5f) * w_fact;
-			interp_v3_v3v3(v3, v1, v2, f);
-			me->mvert[v_start + u * v_steps + v].flag = 0;
-			me->mvert[v_start + u * v_steps + v].bweight = 0;
-			copy_v3_v3(me->mvert[v_start + u * v_steps + v].co,v3);
-			interp_v3_v3v3(v4, v2, v1, f);
-			me->mvert[v_start + u * v_steps + v + square_ss_steps].flag = 0;
-			me->mvert[v_start + u * v_steps + v + square_ss_steps].bweight = 0;
-			copy_v3_v3(me->mvert[v_start + u * v_steps + v + square_ss_steps].co,v4);
-			mul_v3_fl(z_vec_b, cos(0.5f * M_PI * ((float)v / (float)v_steps)));
-			if (v == ss_steps - 1) {
-				for (int w = 1; w < w_steps; w++) {
-					f = (float)w / (float)w_steps;
-					interp_v3_v3v3(v1, v3, v4, f);
-					v_pos_w = v_start + ss_steps * u_steps * 2 + u * (w_steps - 1) + (w - 1);
-					me->mvert[v_pos_w].flag = 0;
-					me->mvert[v_pos_w].bweight = 0;
-					copy_v3_v3(me->mvert[v_pos_w].co,v1);
-				}
-			}
+		if (totl > 1) {
+			a = left[l_u_pos_i * 4 - 1];
+			b = left[l_u_pos_i * 4 + 3];
+			f = (step_l * (float)u - a) / (b - a);
+			interp_v3_v3v3(v1, &left[l_u_pos_i * 4 - 4], &left[l_u_pos_i * 4], f);
+		} else {
+			copy_v3_v3(v1, &left[0]);
 		}
-	}
 
-	/* Generate the Mesh and store border edges for later */
-	ve_start_a = me->totedge + v_steps * 2 - 2;
-	e_start_sides[0] = me->totedge;
-	e_start_sides[1] = v_steps;
-	e_start_sides[2] = 2;
-	e_start_sides[9] = me->totedge + (v_steps * 2 - 1) * (u_steps - 1);
-	e_start_sides[10] = v_steps;
-	e_start_sides[11] = 1;
-	generate_mesh_grid_f_e(me, u_steps, v_steps, v_start, false);
-
-	ve_start_ar = me->totedge + v_steps * 2 - 2;
-	e_start_sides[6] = me->totedge;
-	e_start_sides[7]

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list