[Bf-blender-cvs] [b0b11017166] soc-2017-sculpting_improvements: Improved triangulation, working on ring assignments.

Sebastian Witt noreply at git.blender.org
Fri Aug 18 16:32:33 CEST 2017


Commit: b0b11017166fc379a0a6e7d3ecc097335e28580e
Author: Sebastian Witt
Date:   Fri Aug 18 16:31:22 2017 +0200
Branches: soc-2017-sculpting_improvements
https://developer.blender.org/rBb0b11017166fc379a0a6e7d3ecc097335e28580e

Improved triangulation, working on ring assignments.

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

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 601391a7931..32526cac27c 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -133,10 +133,10 @@
 #define SIL_FILLET_BLUR_MAX 0.3f
 #define SIL_FILLET_BLUR_MIN 0.001f
 #define SIL_FILLET_INTERSECTION_EPSILON 0.00001f
-#define SIL_TRIANGULATION_FACT 0.3 /* 1 = position dependent 0 = order dependent */
+#define SIL_TRIANGULATION_FACT 0.7f /* 1 = position dependent 0 = order dependent */
 /*#define USE_WATERTIGHT*/
 
-//#define DEBUG_DRAW
+#define DEBUG_DRAW
 #ifdef DEBUG_DRAW
 /* static void bl_debug_draw(void);*/
 /* add these locally when using these functions for testing */
@@ -289,6 +289,7 @@ typedef struct SilhouetteData {
 	int *v_to_rm;
 	int num_v_to_rm;
 	BB *fillet_ring_bbs;			/* every ring gets a Bounding box to check intersection with branches */
+	BB *fillet_ring_bbs_new;
 	IntersectionData *isect_chunk;
 	int num_isect_data;
 	int isect_chunk_tot;
@@ -5186,6 +5187,24 @@ static void SCULPT_OT_set_persistent_base(wmOperatorType *ot)
 
 /* TODO: import BB functions */
 /* Expand the bounding box to include a new coordinate */
+static float BB_c_dist_bb(BB *bb1, BB *bb2)
+{
+	float v1[3], v2[3];
+
+	add_v3_v3v3(v1, bb1->bmin, bb1->bmax);
+	mul_v3_fl(v1, 0.5f);
+	add_v3_v3v3(v2, bb2->bmin, bb2->bmax);
+	mul_v3_fl(v2, 0.5f);
+	sub_v3_v3(v2, v1);
+
+	return len_v3(v2);
+}
+
+static float BB_get_volume(BB *bb)
+{
+	return (bb->bmax[0] - bb->bmin[0]) * (bb->bmax[1] - bb->bmin[1]) * (bb->bmax[2] - bb->bmin[2]);
+}
+
 static void BB_expand(BB *bb, const float co[3])
 {
 	for (int i = 0; i < 3; ++i) {
@@ -7595,6 +7614,9 @@ static void combine_intersection_data(Mesh *me, SilhouetteData *sil)
 
 	int *edge_ring_fillet = NULL;
 	int *ring_start = NULL;
+	BB *new_bbs = NULL;
+	BB a_bb;
+	BLI_array_declare(new_bbs);
 	BLI_array_declare(edge_ring_fillet);
 	BLI_array_declare(ring_start);
 
@@ -7627,8 +7649,11 @@ static void combine_intersection_data(Mesh *me, SilhouetteData *sil)
 				BLI_array_append(ring_start, BLI_array_count(edge_ring_fillet));
 				curr_edge = start_edge;
 				last_edge = -1;
+				BB_reset(&a_bb);
 				while(!(curr_edge == start_edge && last_edge != -1) && curr_edge != -1 && breaker > 0) {
 					BLI_array_append(edge_ring_fillet, curr_edge);
+					BB_expand(&a_bb, me->mvert[me->medge[curr_edge].v1].co);
+					BB_expand(&a_bb, me->mvert[me->medge[curr_edge].v2].co);
 					if(last_edge == -1) {
 						comp_v = me->medge[start_edge].v1;
 					} else {
@@ -7644,6 +7669,7 @@ static void combine_intersection_data(Mesh *me, SilhouetteData *sil)
 					curr_edge = tmp_curr_edge;
 					breaker --;
 				}
+				BLI_array_append(new_bbs, a_bb);
 				printf("Found a cut loop!\n");
 				BLI_assert(breaker > 0);
 				/* TODO: Bug shouldn't reach but does on some occasion.*/
@@ -7681,6 +7707,9 @@ static void combine_intersection_data(Mesh *me, SilhouetteData *sil)
 	sil->fillet_ring_new_start = MEM_callocN(sizeof(int) * BLI_array_count(ring_start), "new edgering starts");
 	memcpy(sil->fillet_ring_new_start, ring_start, sizeof(int) * BLI_array_count(ring_start));
 
+	sil->fillet_ring_bbs_new = MEM_callocN(sizeof(BB) * BLI_array_count(ring_start), "new ring bounding box");
+	memcpy(sil->fillet_ring_bbs_new, new_bbs, sizeof(BB) * BLI_array_count(ring_start));
+
 	sil->num_rings_new = BLI_array_count(ring_start);
 	sil->fillet_ring_tot_new = BLI_array_count(edge_ring_fillet);
 
@@ -7702,6 +7731,7 @@ static void combine_intersection_data(Mesh *me, SilhouetteData *sil)
 	}*/
 #endif
 
+	BLI_array_free(new_bbs);
 	BLI_array_free(ring_start);
 	BLI_array_free(edge_ring_fillet);
 
@@ -7717,12 +7747,17 @@ static void combine_intersection_data(Mesh *me, SilhouetteData *sil)
 	MEM_freeN(emap_mem);
 }
 
-static float orient_falloff(int pa, int pb, float o_off, float *dist_a, float *dist_b, float tot_dist_a, float tot_dist_b) {
+static float orient_falloff(int pa, int pb, float o_off, bool invert, float *dist_a, float *dist_b, float tot_dist_a, float tot_dist_b) {
 	float val;
 	float p1, p2;
 
 	p1 = (dist_a[pa] / tot_dist_a);
-	p2 = fmod((dist_b[pb] / tot_dist_b) + o_off, 1.0f);
+
+	if (invert) {
+		p2 = fmod(2.0f - (dist_b[pb] / tot_dist_b) + o_off, 1.0f);
+	} else {
+		p2 = fmod((dist_b[pb] / tot_dist_b) + o_off, 1.0f);
+	}
 
 	val = fabs(p2 - p1);
 	val = val > 0.5f ? (1.0f - val) * 2.0f : val * 2.0f;
@@ -7739,7 +7774,7 @@ static void find_triangulation_rec(Mesh *me, int *map,
 								   int pbs, int pbe,
 								   int *a_verts, int *b_verts,
 								   int a_size, int b_size,
-								   float orient_off,
+								   float orient_off, bool invert,
 								   float *dist_a, float *dist_b,
 								   float tot_dist_a, float tot_dist_b)
 {
@@ -7762,14 +7797,19 @@ static void find_triangulation_rec(Mesh *me, int *map,
 			pbs2 = pbs;
 			do {
 				sub_v3_v3v3(v1, me->mvert[a_verts[pas2]].co, me->mvert[b_verts[pbs2]].co);
-				d = len_v3(v1) * orient_falloff(pas2, pbs2, orient_off, dist_a, dist_b, tot_dist_a, tot_dist_b);
+				d = len_v3(v1) * orient_falloff(pas2, pbs2, orient_off, invert, dist_a, dist_b, tot_dist_a, tot_dist_b);
 				if (d < min_d) {
 					min_d = d;
 					min_b = pbs2;
 					min_a = pas2;
 				}
-				pbs2 = (pbs2 + 1) % b_size;
-			} while (pbs2 != (pbe + 1) % b_size);
+				if (invert) {
+					pbs2 = (pbs2 + b_size - 1) % b_size;
+				} else {
+					pbs2 = (pbs2 + 1) % b_size;
+				}
+			} while ((!invert && pbs2 != (pbe + 1) % b_size) ||
+					 (invert && pbs2 != (pbe + b_size - 1) % b_size));
 			pas2 = (pas2 + 1) % a_size;
 		}
 		map[min_a] = min_b;
@@ -7779,7 +7819,7 @@ static void find_triangulation_rec(Mesh *me, int *map,
 								   pbs, min_b,
 								   a_verts, b_verts,
 								   a_size, b_size,
-								   orient_off,
+								   orient_off, invert,
 								   dist_a, dist_b,
 								   tot_dist_a, tot_dist_b);
 		}
@@ -7789,7 +7829,7 @@ static void find_triangulation_rec(Mesh *me, int *map,
 								   min_b, pbe,
 								   a_verts, b_verts,
 								   a_size, b_size,
-								   orient_off,
+								   orient_off, invert,
 								   dist_a, dist_b,
 								   tot_dist_a, tot_dist_b);
 		}
@@ -7826,9 +7866,11 @@ static int *find_triangulation(Mesh *me, int *a_verts, int *b_verts, int a_size,
 	int *map;
 	float d = FLT_MAX, d2;
 	float v1[3];
+	float n1[3], n2[3];
 	int pas, pbs;
 	float o_off;
 	int s_pos;
+	bool invert;
 
 	map = MEM_callocN(sizeof(int) * a_size, "triangulation map");
 
@@ -7843,30 +7885,45 @@ static int *find_triangulation(Mesh *me, int *a_verts, int *b_verts, int a_size,
 			}
 		}
 	}
+
+	sub_v3_v3v3(n1, me->mvert[a_verts[(pas + (int)fmin(b_size, 3)) % a_size]].co, me->mvert[a_verts[pas]].co);
+	sub_v3_v3v3(n2, me->mvert[b_verts[(pbs + (int)fmin(b_size, 3)) % b_size]].co, me->mvert[b_verts[pbs]].co);
+
+	invert = dot_v3v3(n1, n2) < 0;
+
 #ifdef DEBUG_DRAW
 	bl_debug_color_set(0x0099ff);
 	bl_debug_draw_edge_add(me->mvert[a_verts[pas]].co, me->mvert[b_verts[pbs]].co);
 	bl_debug_color_set(0x000000);
 #endif
 
+	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;
+	} else {
+		o_off = 1.0f + (dist_a[pas] / tot_dist_a) - (dist_b[pbs] / tot_dist_b);
+		*o_off_out = o_off;
+	}
+	map[(pas + 1) % a_size] = pbs;
 	map[pas] = pbs;
-	o_off = 1.0f + (dist_a[pas] / tot_dist_a) - (dist_b[pbs] / tot_dist_b);
-	*o_off_out = o_off;
 	find_triangulation_rec(me, map,
 						   (pas + 1) % a_size, pas,
-						   (pbs + 1) % b_size, pbs,
+						   (invert ? (pbs + b_size - 1) % b_size : (pbs + 1) % b_size), pbs,
 						   a_verts, b_verts,
 						   a_size, b_size,
-						   o_off,
+						   o_off, (dot_v3v3(n1, n2) < 0),
 						   dist_a, dist_b,
 						   tot_dist_a, tot_dist_b);
 
 	s_pos = 0;
+
 	int active_block_start;
 	int active_block;
 	int active_block_count;
 	int active_block_mvp;
+	float start_i, end_i;
 	int t_i;
+	float f;
 	while (s_pos < a_size) {
 		if (map[s_pos] != map[(s_pos + 1) % a_size] && map[(s_pos + 1) % a_size] == map[(s_pos + 2) % a_size]) {
 			active_block_start = (s_pos + 1) % a_size;
@@ -7877,7 +7934,26 @@ static int *find_triangulation(Mesh *me, int *a_verts, int *b_verts, int a_size,
 				if (map[t_i] == active_block) {
 					active_block_count ++;
 					t_i = (t_i + 1) % a_size;
+				} else if (map[t_i] == map[(t_i + 1) % a_size]){
+					active_block = map[t_i];
+					active_block_count ++;
+					t_i = (t_i + 1) % a_size;
 				} else {
+					start_i = map[(active_block_start + a_size - 1) % a_size];
+					end_i = map[(active_block_start + active_block_count) % a_size];
+					if (invert) {
+						if (start_i < end_i) {
+							start_i += b_size;
+						}
+					} else {
+						if (start_i > end_i) {
+							end_i += b_size;
+						}
+					}
+					for (int i = 0; i < active_block_count; i++) {
+						f = (float)i / (float)active_block_count;
+						map[(active_block_start + i) % a_size] = (int)lroundf(end_i * f + start_i * (1.0f - f)) % b_size;
+					}
 					break;
 				}
 			}
@@ -7894,6 +7970,53 @@ static int *find_triangulation(Mesh *me, int *a_verts, int *b_verts, int a_size,
 	return map;
 }
 
+static int find_complement_ring(SilhouetteData *sil, int r)
+{
+	float min_vol_d = FLT_MAX, min_d = FLT_MAX;
+	float avrg_vol = 0, avrg_d = 0;
+	int min_vol_r, min_d_r;
+	int tot = sil->num_rings;
+	float r_vol;
+	float c_vol_d, c_d;
+	BB *b1, *b2;
+
+	min_vol_r = r;
+	min_d_r = r;
+
+	b1 = &sil->fillet_ring_bbs[r];
+	r_vol = BB_get_volume(b1);
+
+	for (int i = 0; i < tot; i++) {
+		if (i != r) {
+			b2 = &sil->fillet_ring_bbs_new[i];
+			c_d = BB_c_dist_bb(b1,b2);
+			c_vol_d = fabs(BB_get_volume(b2) - r_vol);
+
+			if (min_vol_d > c_vol_d) {
+				min_vol_d = c_vol_d;
+				min_vol_r = i;
+			}
+
+			avrg_vol += c_vol_d / tot;
+
+			if (min_d > c_d) {
+				min_d = c_d;
+				min_d_r = i;
+			}
+
+			avrg_d += c_d / tot;
+		}
+	}
+
+	if (min_vol_r == min_d_r) {
+		return min_vol_r;
+	} else if ((min_vol_d / avrg_vol) > (min_d / avrg_d)){
+		return min_d_r;
+	} else {
+		return min_vol_r;
+	}
+}
+
 static void generate_fillet_topology(Mesh *me, SilhouetteData *sil)
 {
 	int r_start, r_size;
@@ -7906,34 +8029,33 @@ static void generate_fillet_topolo

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list