Commit: d0cb5c8fd964675b35e67a2db8c127b9086f1166
Author: Sebastian Witt
Date:   Thu Aug 17 16:39:47 2017 +0200
Branches: soc-2017-sculpting_improvements
https://developer.blender.org/rBd0cb5c8fd964675b35e67a2db8c127b9086f1166

Added first triangulation to generate the fillets. Still needs ring order and 
assignment though.

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

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 56a3adc9cd6..601391a7931 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -133,9 +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 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 */
@@ -7659,7 +7660,7 @@ static void combine_intersection_data(Mesh *me, 
SilhouetteData *sil)
        }
 
 #ifdef DEBUG_DRAW
-       for(int r = 0; r < BLI_array_count(ring_start); r++) {
+       /*for(int r = 0; r < BLI_array_count(ring_start); r++) {
                r_size = r < BLI_array_count(ring_start) - 1 ? ring_start[r + 
1] - ring_start[r] : BLI_array_count(edge_ring_fillet) - ring_start[r];
                for(int i = 0; i < r_size; i++) {
                        if(i == 0){
@@ -7670,9 +7671,10 @@ static void combine_intersection_data(Mesh *me, 
SilhouetteData *sil)
                        bl_debug_draw_medge_add(me, 
edge_ring_fillet[ring_start[r] + i]);
                        bl_debug_color_set(0x000000);
                }
-       }
+       }*/
 #endif
 
+       /*TODO: add bbs */
        sil->fillet_ring_new = MEM_callocN(sizeof(int) * 
BLI_array_count(edge_ring_fillet), "new edgerings");
        memcpy(sil->fillet_ring_new, edge_ring_fillet, sizeof(int) * 
BLI_array_count(edge_ring_fillet));
 
@@ -7685,7 +7687,7 @@ static void combine_intersection_data(Mesh *me, 
SilhouetteData *sil)
        order_exact_points(me, emap, data, sil, sil->num_isect_data);
 
 #ifdef DEBUG_DRAW
-       int trsize, trstart;
+       /*int trsize, trstart;
        float v1t[3], v2t[3];
        for(int i = 0; i < sil->num_rings_new; i++) {
                trstart = sil->exact_isect_points_start[i];
@@ -7697,7 +7699,7 @@ static void combine_intersection_data(Mesh *me, 
SilhouetteData *sil)
                        bl_debug_draw_edge_add(v1t, v2t);
                        bl_debug_color_set(0x000000);
                }
-       }
+       }*/
 #endif
 
        BLI_array_free(ring_start);
@@ -7715,6 +7717,313 @@ 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) {
+       float val;
+       float p1, p2;
+
+       p1 = (dist_a[pa] / tot_dist_a);
+       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;
+
+       /* Try quadratic falloff */
+       val = val * val;
+       val = val * (1.0f - SIL_TRIANGULATION_FACT) + SIL_TRIANGULATION_FACT;
+
+       return val;
+}
+
+static void find_triangulation_rec(Mesh *me, int *map,
+                                                                  int pas, int 
pae,
+                                                                  int pbs, int 
pbe,
+                                                                  int 
*a_verts, int *b_verts,
+                                                                  int a_size, 
int b_size,
+                                                                  float 
orient_off,
+                                                                  float 
*dist_a, float *dist_b,
+                                                                  float 
tot_dist_a, float tot_dist_b)
+{
+       int pas2, pbs2;
+       float min_d = FLT_MAX;
+       int min_b = 0;
+       int min_a = 0;
+       float v1[3];
+       float d;
+
+       if (pbs == pbe) {
+               while (pas != pae) {
+                       map[pas] = pbs;
+                       pas = (pas + 1) % a_size;
+               }
+       } else if (pas != pae) {
+               /* Find the vert in a which is closest to ring b */
+               pas2 = (pas + 1) % a_size;
+               while (pas2 != pae) {
+                       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);
+                               if (d < min_d) {
+                                       min_d = d;
+                                       min_b = pbs2;
+                                       min_a = pas2;
+                               }
+                               pbs2 = (pbs2 + 1) % b_size;
+                       } while (pbs2 != (pbe + 1) % b_size);
+                       pas2 = (pas2 + 1) % a_size;
+               }
+               map[min_a] = min_b;
+               if (min_a != (pas + 1) % a_size) {
+                       find_triangulation_rec(me, map,
+                                                                  pas, min_a,
+                                                                  pbs, min_b,
+                                                                  a_verts, 
b_verts,
+                                                                  a_size, 
b_size,
+                                                                  orient_off,
+                                                                  dist_a, 
dist_b,
+                                                                  tot_dist_a, 
tot_dist_b);
+               }
+               if ((min_a + 1) % a_size != pae) {
+                       find_triangulation_rec(me, map,
+                                                                  min_a, pae,
+                                                                  min_b, pbe,
+                                                                  a_verts, 
b_verts,
+                                                                  a_size, 
b_size,
+                                                                  orient_off,
+                                                                  dist_a, 
dist_b,
+                                                                  tot_dist_a, 
tot_dist_b);
+               }
+       }
+}
+
+static int find_mvp(Mesh *me, int *a_verts, int a_size, int start, int tot)
+{
+       float max_dot = - 2.0f;
+       int mvp = 0;
+       float e1[3], e2[3];
+       float dot;
+       int c_pos;
+
+       c_pos = (start + tot / 2) % a_size;
+       for (int v = 0; v < tot; v++) {
+               sub_v3_v3v3(e1, me->mvert[a_verts[c_pos]].co, 
me->mvert[a_verts[(c_pos + a_size - 1) % a_size]].co);
+               sub_v3_v3v3(e2, me->mvert[a_verts[c_pos]].co, 
me->mvert[a_verts[(c_pos + 1) % a_size]].co);
+               dot = dot_v3v3(e1,e2);
+               if (max_dot < dot) {
+                       max_dot = dot;
+                       mvp = c_pos;
+               }
+               c_pos = (start + ((c_pos - start + 1) % tot)) % a_size;
+       }
+
+       return mvp;
+}
+
+/* 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)
+{
+       int *map;
+       float d = FLT_MAX, d2;
+       float v1[3];
+       int pas, pbs;
+       float o_off;
+       int s_pos;
+
+       map = MEM_callocN(sizeof(int) * a_size, "triangulation map");
+
+       for (int i = 0; i < a_size; i++) {
+               for (int j = 0; j < b_size; j++) {
+                       sub_v3_v3v3(v1, me->mvert[a_verts[i]].co, 
me->mvert[b_verts[j]].co);
+                       d2 = len_v3(v1);
+                       if (d2 < d) {
+                               pas = i;
+                               pbs = j;
+                               d = d2;
+                       }
+               }
+       }
+#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
+
+       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,
+                                                  a_verts, b_verts,
+                                                  a_size, b_size,
+                                                  o_off,
+                                                  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;
+       int t_i;
+       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;
+                       active_block = map[active_block_start];
+                       active_block_count = 1;
+                       t_i = (active_block_start + 1) % a_size;
+                       for(int i = 0; i < a_size; i++) {
+                               if (map[t_i] == active_block) {
+                                       active_block_count ++;
+                                       t_i = (t_i + 1) % a_size;
+                               } else {
+                                       break;
+                               }
+                       }
+
+                       active_block_mvp = find_mvp(me, a_verts, a_size, 
active_block_start, active_block_count);
+                       //map[active_block_mvp] = -map[active_block_mvp];
+                       s_pos += active_block_count + 1;
+               } else {
+                       //map[s_pos] = -map[s_pos];
+                       s_pos ++;
+               }
+       }
+
+       return map;
+}
+
+static void generate_fillet_topology(Mesh *me, SilhouetteData *sil)
+{
+       int r_start, r_size;
+       int r_orig_start, r_orig_size;
+       int r_new_start, r_new_size;
+       int *a_data, *b_data; /* a_data is the bigger ring which gets decimate 
to the b_data ring*/
+       int a_size, b_size;
+       float v1[3], v2[3];
+       int *triangulation_map;
+       int *a_verts, *b_verts;
+       MEdge ce1, ce2;
+       int a_start_v, b_start_v;
+       int cv;
+       float *dist_a, *dist_b;
+       void *t_swap;
+       float tot_dist_a, tot_dist_b;
+
+       /*Generate the fillets from the edgerings and the exact intersection 
points.*/
+       if (sil->num_rings == sil->num_rings_new) {
+
+               /* Allocate a mempool to store the distances along the rings
+                * could be reallocated for every ring but once bigger should 
be faster. */
+               dist_a = MEM_callocN(sizeof(float) * sil->fillet_ring_tot, 
"distances orig");
+               dist_b = MEM_callocN(sizeof(float) * sil->fillet_ring_tot_new, 
"distances new");
+
+               /* TODO: check if ring order is implied and aligned between new 
and orig*/
+               for (int r = 0; r < sil->num_rings; r++) {
+                       r_orig_start = sil->fillet_ring_orig_start[r];
+                       r_orig_size = r + 1 < sil->num_rings ? 
sil->fillet_ring_orig_start[r + 1] - r_orig_start : sil->fillet_ring_tot - 
r_orig_start;
+                       r_new_start = sil->fillet_ring_new_start[r];
+                       r_new_size = r + 1 < sil->num_rings ? 
sil->fillet_ring_new_start[r + 1] - r_new_start : sil->fillet_ring_tot_new - 
r_new_start;
+
+                       if (r_new_size > r_orig_size) {
+                               a_data = &sil->fillet_ring_new[r_new_start];
+                               b_data = &sil->fillet_ring_orig[r_orig_start];
+                               a_size = r_new_size;
+                               b_size = r_orig_size;
+                               t_swap = dist_a;
+                               dist_a = dist_b;
+                               dist_b = t_swap;
+                       } else {
+                               a_data = &sil->fillet_ring_orig[r_orig_start];
+                               b_data = &sil->fillet_ring_new[r_new_start];
+                               a_size = r_orig_size;
+                               b_size = r_new_size;
+                       }
+
+                       a_verts = MEM_callocN(sizeof(int) * a_size, "verts in 
ring a");
+                       b_verts = MEM_callocN(sizeof(int) * b_size, "verts in 
ring b");
+
+                       ce1 = me->medge[a_data[0]];
+                       ce2 = me->medge[a_data[a_size - 1]];
+                       a_start_v = (ce1.v1 == ce2.v1 || ce1.v1 == ce2.v2) ? 
ce1.v2 : ce1.v1;
+                       ce1 = me->medge[b_data[0]];
+                       ce2 = me->medge[b_data[b_size - 1]];
+                       b_start_v = (ce1.v1 == ce2.v1 || ce1.v1 == ce2.v2) ? 
ce1.v2 : ce1.v1;
+
+                       a_verts[0] = a_start_v;
+                       for(int i = 1; i < a_size; i++) {
+                               ce1 = me->medge[a_data[i]];
+                               a_verts[i] = a_verts[i - 1] == ce1.v1 ? ce1.v2 
: ce1.v1;
+                       }
+                       b_verts[0] = b_start_v;
+                       for(int i = 1; i < b_size; i++) {
+                               ce1 = me->medge[b_data[i]];
+                               b_verts[i] = b_verts[i - 1] == ce1.v1 ? ce1.v2 
: ce1.v1;
+                       }
+
+                       dist_a[0] = 0.0f;
+                       for (int i = 0; i < a_size; i++) {
+                               ce1 = me->medge[a_data[i]];
+                               sub_v3_v3v3(v1, me->mvert[ce1.v1].co, 
me->mvert[ce1.v2].co);
+                               if (i < a_size - 1) {
+                                       dist_a[i + 1] = len_v3(v1) + dist_a[i];
+                               } else {
+                                       tot_dist_a = len_v3(v1) + dist_a[i];
+                               }
+                       }
+                       dist_b[0] = 0.0f;
+                       for (int i = 0; i < b_size; i++) {
+                               ce1 = me->medge[b_data[i]];
+                               sub_v3_v3v3(v1, me->mvert[ce1.v1].co, 
me->mvert[ce1.v2].co);
+                               if (i < b_size - 1) {
+                                       dist_b[i + 1] = len_v3(v1) + dist_b[i];
+                               } else {
+                               

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to