[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