[Bf-blender-cvs] [30d32fa602e] soc-2017-sculpting_improvements: Fillets now get generated. Almost feature complete.

Sebastian Witt noreply at git.blender.org
Sat Aug 19 00:37:57 CEST 2017


Commit: 30d32fa602e24525eb0f2441caa621b3ea597cb5
Author: Sebastian Witt
Date:   Sat Aug 19 00:35:53 2017 +0200
Branches: soc-2017-sculpting_improvements
https://developer.blender.org/rB30d32fa602e24525eb0f2441caa621b3ea597cb5

Fillets now get generated. Almost feature complete.

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

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 32526cac27c..1831faf014c 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -7861,7 +7861,7 @@ static int find_mvp(Mesh *me, int *a_verts, int a_size, int start, int tot)
 
 /* Recusiveley find a triangulation, connect the two closest points and split the rings in to subrings... 
  * a_data is bigger than b_data */
-static int *find_triangulation(Mesh *me, int *a_verts, int *b_verts, int a_size, int b_size, float *dist_a, float *dist_b, float tot_dist_a, float tot_dist_b, float *o_off_out)
+static int *find_triangulation(Mesh *me, int *a_verts, int *b_verts, int a_size, int b_size, float *dist_a, float *dist_b, float tot_dist_a, float tot_dist_b, float *o_off_out, bool *r_invert)
 {
 	int *map;
 	float d = FLT_MAX, d2;
@@ -7897,6 +7897,7 @@ static int *find_triangulation(Mesh *me, int *a_verts, int *b_verts, int a_size,
 	bl_debug_color_set(0x000000);
 #endif
 
+	*r_invert = invert;
 	if (invert) {
 		o_off = 1.0f + (dist_a[pas] / tot_dist_a) - (1.0f - (dist_b[pbs] / tot_dist_b));
 		*o_off_out = -o_off;
@@ -8017,6 +8018,177 @@ static int find_complement_ring(SilhouetteData *sil, int r)
 	}
 }
 
+/* TODO: Already exists? Move to Math_geom? */
+static float closest_seg_seg_v3(float r_close[3], const float e1[3], const float e2[3], const float l1[3], const float l2[3])
+{
+	float v[3], d1[3], d2[3], po[3], r[3];
+	float mat[3][3];
+	float lambd;
+
+	sub_v3_v3v3(d1, e2, e1);
+	sub_v3_v3v3(d2, l1, l2);
+	cross_v3_v3v3(v, d1, d2);
+
+	copy_v3_v3(mat[0], d1);
+	copy_v3_v3(mat[1], v);
+	copy_v3_v3(mat[2], d2);
+
+	sub_v3_v3v3(po, l1, e1);
+
+	invert_m3(mat);
+	mul_v3_m3v3(r, mat, po);
+
+	lambd = fmax(fmin(r[0], 1.0f), 0.0f);
+
+	mul_v3_fl(d1, lambd);
+	add_v3_v3v3(r_close, e1, d1);
+
+	return lambd;
+}
+
+static void find_closest_exact_p(float e1[3], float e2[3], float *exact_p, int tot, float r[3])
+{
+	float min_d = FLT_MAX, t_d;
+	int pf;
+	float p[3], p1[3], p2[3];
+
+	pf = 0;
+	for (int i = 0; i < tot; i++) {
+		t_d = len_v3v3(e2, &exact_p[i * 3]);
+		if (t_d < min_d) {
+			copy_v3_v3(p, e2);
+			min_d = t_d;
+			pf = i;
+		}
+	}
+
+	copy_v3_v3(p1, &exact_p[pf * 3]);
+
+	if (len_v3v3(p, &exact_p[((pf + 1) % tot) * 3]) > len_v3v3(p, &exact_p[((pf + tot - 1) % tot) * 3])) {
+		copy_v3_v3(p2, &exact_p[((pf + tot - 1) % tot) * 3]);
+	} else {
+		copy_v3_v3(p2, &exact_p[((pf + 1) % tot) * 3]);
+	}
+
+	closest_seg_seg_v3(r, p1, p2, e1, e2);
+}
+
+static void gen_fillet_velp(Mesh *me,
+							 float *exact_p, int exact_p_tot,
+							 int *a_verts, int *b_verts,
+							 int *a_edges, int *b_edges,
+							 int a_size, int b_size,
+							 int *map, bool inverse)
+{
+	/*If aligned exact points are aligned to a*/
+	float v1[3], v2[3];
+	int v_start, e_start, l_pos, p_start;
+	int holes = 0, next_i, aoff, boff;
+
+	aoff = me->medge[a_edges[0]].v1 == a_verts[0] ? 0 : 1;
+	boff = me->medge[b_edges[0]].v1 == b_verts[0] ? 0 : 1;
+
+	v_start = me->totvert;
+	e_start = me->totedge;
+	ED_mesh_vertices_add(me, NULL, a_size);
+	ED_mesh_edges_add(me, NULL, a_size * 3);
+
+	for(int i = 0; i < a_size; i++) {
+		if (map[i] != map[(i + 1) % a_size]) {
+			if ((map[i] + 1) % b_size != map[(i + 1) % a_size] && (map[i] + b_size - 1) % b_size != map[(i + 1) % a_size]) {
+				if (inverse) {
+					holes += (b_size + map[i] - map[(i + 1) % a_size]) % b_size - 1;
+				} else {
+					holes += (b_size + map[(i + 1) % a_size] - map[i]) % b_size - 1;
+				}
+			}
+		}
+		copy_v3_v3(v1, me->mvert[a_verts[i]].co);
+		find_closest_exact_p(v1, me->mvert[b_verts[map[i]]].co, exact_p, exact_p_tot, v2);
+		me->mvert[v_start + i].flag = 0;
+		me->mvert[v_start + i].bweight = 0;
+		copy_v3_v3(me->mvert[v_start + i].co, v2);
+
+		me->medge[e_start + 3 * i].v1 = a_verts[i];
+		me->medge[e_start + 3 * i].v2 = v_start + i;
+		me->medge[e_start + 3 * i].crease = 0;
+		me->medge[e_start + 3 * i].bweight = 0;
+		me->medge[e_start + 3 * i].flag = 0;
+
+		me->medge[e_start + 3 * i + 1].v1 = v_start + i;
+		me->medge[e_start + 3 * i + 1].v2 = v_start + (i + 1) % a_size;
+		me->medge[e_start + 3 * i + 1].crease = 0;
+		me->medge[e_start + 3 * i + 1].bweight = 0;
+		me->medge[e_start + 3 * i + 1].flag = 0;
+
+		me->medge[e_start + 3 * i + 2].v1 = v_start + i;
+		me->medge[e_start + 3 * i + 2].v2 = b_verts[map[i]];
+		me->medge[e_start + 3 * i + 2].crease = 0;
+		me->medge[e_start + 3 * i + 2].bweight = 0;
+		me->medge[e_start + 3 * i + 2].flag = 0;
+	}
+
+	l_pos = me->totloop;
+	p_start = me->totpoly;
+	ED_mesh_loops_add(me, NULL, a_size * 7 + (b_size - holes));
+	ED_mesh_polys_add(me, NULL, a_size * 2);
+	for (int i = 0; i < a_size; i++) {
+		next_i = (i + 1) % a_size;
+		me->mloop[l_pos].v = a_verts[i];
+		me->mloop[l_pos].e = e_start + 3 * i;
+		l_pos ++;
+		me->mloop[l_pos].v = v_start + i;
+		me->mloop[l_pos].e = e_start + 3 * i + 1;
+		l_pos ++;
+		me->mloop[l_pos].v = v_start + next_i;
+		me->mloop[l_pos].e = e_start + 3 * next_i;
+		l_pos ++;
+		me->mloop[l_pos].v = a_verts[next_i];
+		me->mloop[l_pos].e = a_edges[(i + aoff) % a_size];
+		l_pos ++;
+
+		me->mpoly[p_start + i * 2].loopstart = l_pos - 4;
+		me->mpoly[p_start + i * 2].totloop = 4;
+		me->mpoly[p_start + i * 2].mat_nr = 0;
+		me->mpoly[p_start + i * 2].flag = 0;
+
+		if (map[i] == map[next_i]) {
+			/*Triangle*/
+			me->mloop[l_pos].v = v_start + i;
+			me->mloop[l_pos].e = e_start + 3 * i + 2;
+			l_pos ++;
+			me->mloop[l_pos].v = b_verts[map[i]];
+			me->mloop[l_pos].e = e_start + 3 * next_i + 2;
+			l_pos ++;
+			me->mloop[l_pos].v = v_start + next_i;
+			me->mloop[l_pos].e = e_start + 3 * i + 1;
+			l_pos ++;
+
+			me->mpoly[p_start + i * 2 + 1].loopstart = l_pos - 3;
+			me->mpoly[p_start + i * 2 + 1].totloop = 3;
+		} else {
+			/* Quad */
+			me->mloop[l_pos].v = v_start + i;
+			me->mloop[l_pos].e = e_start + 3 * i + 2;
+			l_pos ++;
+			me->mloop[l_pos].v = b_verts[map[i]];
+			me->mloop[l_pos].e = b_edges[(map[i] + boff) % a_size];
+			l_pos ++;
+			me->mloop[l_pos].v = b_verts[map[next_i]];
+			me->mloop[l_pos].e = e_start + 3 * next_i + 2;
+			l_pos ++;
+			me->mloop[l_pos].v = v_start + next_i;
+			me->mloop[l_pos].e = e_start + 3 * i + 1;
+			l_pos ++;
+
+			me->mpoly[p_start + i * 2 + 1].loopstart = l_pos - 4;
+			me->mpoly[p_start + i * 2 + 1].totloop = 4;
+		}
+		me->mpoly[p_start + i * 2 + 1].mat_nr = 0;
+		me->mpoly[p_start + i * 2 + 1].flag = 0;
+	}
+}
+
 static void generate_fillet_topology(Mesh *me, SilhouetteData *sil)
 {
 	int r_start, r_size;
@@ -8031,6 +8203,10 @@ static void generate_fillet_topology(Mesh *me, SilhouetteData *sil)
 	int a_start_v, b_start_v;
 	float *dist_a, *dist_b;
 	float tot_dist_a, tot_dist_b;
+	float o_off;
+	bool invert;
+	int exact_p_start;
+	int exact_p_tot;
 	int r2;
 
 	/*Generate the fillets from the edgerings and the exact intersection points.*/
@@ -8105,12 +8281,20 @@ static void generate_fillet_topology(Mesh *me, SilhouetteData *sil)
 				}
 			}
 
-			float o_off;
-			triangulation_map = find_triangulation(me, a_verts, b_verts, a_size, b_size, dist_a, dist_b, tot_dist_a, tot_dist_b, &o_off);
+			triangulation_map = find_triangulation(me, a_verts, b_verts, a_size, b_size, dist_a, dist_b, tot_dist_a, tot_dist_b, &o_off, &invert);
 
+			exact_p_start = sil->exact_isect_points_start[r2];
+			exact_p_tot = r2 + 1 < sil->num_rings_new ? sil->exact_isect_points_start[r2 + 1] - exact_p_start : sil->exact_points_tot - exact_p_start;
+
+			gen_fillet_velp(me, &sil->exact_isect_points[exact_p_start * 3], exact_p_tot,
+							 a_verts, b_verts,
+							 a_data, b_data,
+							 a_size, b_size,
+							 triangulation_map, invert);
+			
 #ifdef DEBUG_DRAW
 
-			bl_debug_color_set(0xFFCC33);
+			/*bl_debug_color_set(0xFFCC33);
 			for(int e = 0; e < a_size; e++) {
 				printf("TMap %i [%i]\n", e, triangulation_map[e]);
 				bl_debug_draw_edge_add(me->mvert[a_verts[e]].co, me->mvert[b_verts[triangulation_map[e]]].co);
@@ -8125,10 +8309,10 @@ static void generate_fillet_topology(Mesh *me, SilhouetteData *sil)
 			}
 			for (int i = 0; i < b_size; i++) {
 				float fact;
-				if (o_off >= 0) {
+				if (invert) {
 					fact = fmod((dist_b[i] / tot_dist_b) + o_off,1.0f);
 				} else {
-					fact = fmod(2.0f - (dist_b[i] / tot_dist_b) - o_off,1.0f);
+					fact = fmod(2.0f - (dist_b[i] / tot_dist_b) + o_off,1.0f);
 				}
 				bl_debug_color_set((int)((0x0000ff) * fact));
 				bl_debug_draw_medge_add(me, b_data[i]);
@@ -8142,7 +8326,7 @@ static void generate_fillet_topology(Mesh *me, SilhouetteData *sil)
 				copy_v3_v3(v2, (i + 1 < r_size ? &sil->exact_isect_points[(r_start + i) * 3 + 3] : &sil->exact_isect_points[r_start * 3]));
 				bl_debug_draw_edge_add(v1, v2);
 				bl_debug_color_set(0x000000);
-			}
+			}*/
 #endif
 		}
 	} else {
@@ -8217,7 +8401,6 @@ static void silhouette_create_shape_mesh(bContext *C, Mesh *me, SilhouetteData *
 	if (sil->num_inter_nodes) {
 		check_preceding_intersecting_edges(ob, sil, NULL, nodes, me->totedge - e_start);
 		combine_intersection_data(me, sil);
-
 		generate_fillet_topology(me, sil);
 	}
 	/*printf("Joining %i isect data.\n", sil->num_isect_data);



More information about the Bf-blender-cvs mailing list