Commit: d684bdd139038d25bee6a583c6aa2b598062ffd0
Author: Sebastian Witt
Date:   Thu Aug 3 17:56:44 2017 +0200
Branches: soc-2017-sculpting_improvements
https://developer.blender.org/rBd684bdd139038d25bee6a583c6aa2b598062ffd0

Added memory and data to handle intersection rings. Still WIP unstable.

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

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 c9089fe5dd6..bc9788bc09e 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -119,6 +119,8 @@
 #include "BLI_array.h"
 
 #define SIL_STROKE_STORE_CHUNK 512
+/* Store bias is used to bias a close estimate since resizing is more 
expensive than bigger array on first allocate*/
+#define STORE_ESTIMATE_BIAS 0.1f
 /* Fillet Blur determines the fuzziness wether a vert is intersecting or not.
  * Important for example if two shapes with the same thickness intersect. */
 #define SIL_FILLET_BLUR_MAX 0.3f
@@ -162,6 +164,66 @@ typedef struct SilhouetteStroke {
        BB bb;
 } SilhouetteStroke;
 
+#ifdef DEBUG_DRAW
+void bl_debug_draw_BB_add(BB *bb,const unsigned int col){
+       float v1[3],v2[3],v3[3],v4[3];
+       float xd[3], yd[3], zd[3];
+
+       bl_debug_color_set(col);
+
+       xd[0] = bb->bmax[0]-bb->bmin[0];
+       xd[1] = 0.0f;
+       xd[2] = 0.0f;
+
+       yd[0] = 0.0f;
+       yd[1] = bb->bmax[1]-bb->bmin[1];
+       yd[2] = 0.0f;
+
+       zd[0] = 0.0f;
+       zd[1] = 0.0f;
+       zd[2] = bb->bmax[2]-bb->bmin[2];
+
+       copy_v3_v3(v1,bb->bmin);
+       copy_v3_v3(v2,bb->bmin);
+       add_v3_v3(v2,xd);
+       add_v3_v3v3(v3,v1,yd);
+       add_v3_v3v3(v4,v2,yd);
+
+       bl_debug_draw_edge_add(v1,v2);
+       bl_debug_draw_edge_add(v1,v3);
+       bl_debug_draw_edge_add(v2,v4);
+
+       copy_v3_v3(v1,v3);
+       copy_v3_v3(v2,v4);
+       add_v3_v3v3(v3,v1,zd);
+       add_v3_v3v3(v4,v2,zd);
+
+       bl_debug_draw_edge_add(v1,v2);
+       bl_debug_draw_edge_add(v1,v3);
+       bl_debug_draw_edge_add(v2,v4);
+
+       copy_v3_v3(v1,v3);
+       copy_v3_v3(v2,v4);
+       sub_v3_v3v3(v3,v1,yd);
+       sub_v3_v3v3(v4,v2,yd);
+
+       bl_debug_draw_edge_add(v1,v2);
+       bl_debug_draw_edge_add(v1,v3);
+       bl_debug_draw_edge_add(v2,v4);
+
+       copy_v3_v3(v1,v3);
+       copy_v3_v3(v2,v4);
+       sub_v3_v3v3(v3,v1,zd);
+       sub_v3_v3v3(v4,v2,zd);
+
+       bl_debug_draw_edge_add(v1,v2);
+       bl_debug_draw_edge_add(v1,v3);
+       bl_debug_draw_edge_add(v2,v4);
+       
+}
+#endif
+
+
 typedef enum {
        SIL_INIT = 0,
        SIL_DRAWING = 1,
@@ -182,12 +244,21 @@ typedef struct SilhouetteData {
 
        SilhouetteState state;  /* Operator state */
 
-       float depth;                    /* Depth or thickness of the generated 
shape */
-       float smoothness;               /* Smoothness of the generated shape */
-       int resolution;                 /* Subdivision of the shape*/
-       float anchor[3];                /* Origin point of the reference plane 
*/
-       float z_vec[3];                 /* Orientation of the reference plane */
-       MeshElemMap *emap;              /* Original Mesh vert -> edges map */
+       float depth;                                    /* Depth or thickness 
of the generated shape */
+       float smoothness;                               /* Smoothness of the 
generated shape */
+       int resolution;                                 /* Subdivision of the 
shape*/
+       float anchor[3];                                /* Origin point of the 
reference plane */
+       float z_vec[3];                                 /* Orientation of the 
reference plane */
+       MeshElemMap *emap;                              /* Original Mesh vert 
-> edges map */
+       GHash *i_edges;                                 /* Edges crossing the 
both shapes. (only orig mesh)*/
+       int *fillet_ring_orig;                  /* ring_edges to connect to in 
the orig mesh */
+       int *fillet_ring_orig_start;    /* start positions to each individual 
ring */
+       int *fillet_ring_new;                   /* ring_edges to connect to in 
the new mesh */
+       int *fillet_ring_new_start;             /* start positions to each 
individual ring */
+       int num_rings, fillet_ring_tot;
+       int *inter_edges;                               /* edges crossing the 
two shapes */
+       int num_inter_edges;                    /* number of edges crossing */
+       BB *fillet_ring_bbs;                            /* every ring gets a 
Bounding box to check intersection with branches */
 } SilhouetteData;
 
 /** \name Tool Capabilities
@@ -597,6 +668,8 @@ typedef struct SculptThreadedTaskData {
        bool smooth_mask;
        bool has_bm_orco;
        SilhouetteData *sil;
+       int *v_to_rm; /* Shared array handle access with mutex! */
+       int num_v_to_rm;
 
        SculptProjectVector *spvc;
        float *offset;
@@ -5091,6 +5164,19 @@ static void BB_reset(BB *bb)
        bb->bmax[0] = bb->bmax[1] = bb->bmax[2] = -FLT_MAX;
 }
 
+static bool bb_intersect(BB *bb1, BB *bb2) {
+       int i;
+
+       /* min is inclusive max is exclusive? BB*/
+       for (i = 0; i < 3; ++i) {
+               if(bb1->bmin[i] >= bb2->bmax[i] || bb1->bmax[i] < bb2->bmin[i]){
+                       return false;
+               }
+       }
+
+       return true;
+}
+
 static void silhouette_stroke_free(SilhouetteStroke *stroke)
 {
        if (stroke) {
@@ -5136,6 +5222,14 @@ static SilhouetteData *silhouette_data_new(bContext *C)
 
        copy_v3_v3(sil->anchor, fp);
 
+       /* Intersection variables */
+       sil->fillet_ring_orig = NULL;
+       sil->fillet_ring_orig_start = NULL;
+       sil->fillet_ring_new = NULL;
+       sil->fillet_ring_new_start = NULL;
+       sil->inter_edges = NULL;
+       sil->fillet_ring_bbs = NULL;
+
        sil->scene = scene;
        sil->ob = obedit;
        sil->state = SIL_INIT;
@@ -5148,6 +5242,25 @@ static void silhouette_data_free(struct wmOperator *op)
        data = op->customdata;
        if (data) {
                silhouette_stroke_free(data->current_stroke);
+
+               if (data->inter_edges) {
+                       MEM_freeN(data->inter_edges);
+               }
+               if (data->fillet_ring_orig) {
+                       MEM_freeN(data->fillet_ring_orig);
+               }
+               if (data->fillet_ring_orig_start) {
+                       MEM_freeN(data->fillet_ring_orig_start);
+               }
+               if (data->fillet_ring_new) {
+                       MEM_freeN(data->fillet_ring_new);
+               }
+               if (data->fillet_ring_new_start) {
+                       MEM_freeN(data->fillet_ring_new_start);
+               }
+               if (data->fillet_ring_bbs) {
+                       MEM_freeN(data->fillet_ring_bbs);
+               }
                MEM_SAFE_FREE(data);
        }
 }
@@ -5239,6 +5352,7 @@ typedef struct SpineBranch{
        int *e_start_arr;               /* Edges on the ends are stored (used 
primarly for bridging) */
        int fs_bs_offset;               /* Frontside edge offset to backside*/
        int *e_flip_side_ends;  /* Front and backside connecting edges of each 
part*/
+       bool intersecting;
 }SpineBranch;
 
 /* Main Tree Container */
@@ -7037,47 +7151,47 @@ static void stroke_smooth_cap(SilhouetteData *sil, 
SilhouetteStroke *stroke, flo
        }
 }
 
-static void remove_connected_from_edgehash(MeshElemMap *emap, GHash *edgeHash, 
int v) {
+static void remove_connected_from_edgehash(MeshElemMap *emap, GHash 
*edge_hash, int v) {
        for (int e = 0; e < emap[v].count; e++) {
-               BLI_ghash_remove(edgeHash, emap[v].indices[e], NULL, NULL);
+               BLI_ghash_remove(edge_hash, emap[v].indices[e], NULL, NULL);
        }
 }
 
-static bool has_cross_border_neighbour(Mesh *me, GHash *vertHash, GHash 
*edgeHash, MeshElemMap *emap, int edge, int l_v_edge, int depth) {
+static bool has_cross_border_neighbour(Mesh *me, GHash *vert_hash, GHash 
*edge_hash, MeshElemMap *emap, int edge, int l_v_edge, int depth) {
        int v_edge;
 
        v_edge = me->medge[edge].v1 == l_v_edge ? me->medge[edge].v2 : 
me->medge[edge].v1;
 
        if (depth == 0) {
-               return BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(v_edge));
+               return BLI_ghash_haskey(vert_hash, SET_INT_IN_POINTER(v_edge));
        } else {
-               if(!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(v_edge))){
+               if(!BLI_ghash_haskey(vert_hash, SET_INT_IN_POINTER(v_edge))){
                        for (int e = 0; e < emap[v_edge].count; e++) {
                                if(emap[v_edge].indices[e] != edge) {
-                                       if(has_cross_border_neighbour(me, 
vertHash, edgeHash, emap, emap[v_edge].indices[e], v_edge, depth - 1)){
+                                       if(has_cross_border_neighbour(me, 
vert_hash, edge_hash, emap, emap[v_edge].indices[e], v_edge, depth - 1)){
                                                return true;
                                        }
                                }
                        }
                } else {
-                       BLI_ghash_remove(edgeHash, edge, NULL, NULL);
+                       BLI_ghash_remove(edge_hash, edge, NULL, NULL);
                }
        }
        return false;
 }
 
-/* Get the adjacent edge which connects the edges within the edgeHash. Used to 
create multiple ordered loops
+/* Get the adjacent edge which connects the edges within the edge_hash. Used 
to create multiple ordered loops
  * v_edge is the endpoint off curr_edge from which to branch off
  * TODO: One wide strips might get cutoff */
-static int get_adjacent_edge(Mesh *me, MeshElemMap *emap, int curr_edge, int 
v_edge, GHash *edgeHash, GHash *vertHash)
+static int get_adjacent_edge(Mesh *me, MeshElemMap *emap, int curr_edge, int 
v_edge, GHash *edge_hash, GHash *vert_hash)
 {
        for (int e = 0; e < emap[v_edge].count; e++) {
-               if(emap[v_edge].indices[e] != curr_edge && 
has_cross_border_neighbour(me, vertHash, edgeHash, emap, 
emap[v_edge].indices[e], v_edge, 1)) {
+               if(emap[v_edge].indices[e] != curr_edge && 
has_cross_border_neighbour(me, vert_hash, edge_hash, emap, 
emap[v_edge].indices[e], v_edge, 1)) {
                        return emap[v_edge].indices[e];
                }
        }
        for (int e = 0; e < emap[v_edge].count; e++) {
-               if(emap[v_edge].indices[e] != curr_edge && 
has_cross_border_neighbour(me, vertHash, edgeHash, emap, 
emap[v_edge].indices[e], v_edge, 2)) {
+               if(emap[v_edge].indices[e] != curr_edge && 
has_cross_border_neighbour(me, vert_hash, edge_hash, emap, 
emap[v_edge].indices[e], v_edge, 2)) {
                        return emap[v_edge].indices[e];
                }
        }
@@ -7085,6 +7199,174 @@ static int get_adjacent_edge(Mesh *me, MeshElemMap 
*emap, int curr_edge, int v_e
        return -1;
 }
 
+#if 0
+/*static void add_from_map(const int v, MeshElemMap *map, int *data, int *num, 
int *max)
+{
+       int count = map[v].count;
+       if (count > 0) {
+               if (num + count > max) {
+                       *max += fmax(STORE_ESTIMATE_RESIZE, count);
+                       data = MEM_reallocN(data, sizeof(int) * (*max));
+               }
+               for (int i = 0; i < count; i++) {
+                       data[(*num)] = map[v].indices[i];
+                       *num = *num + 1;
+               }
+       }
+}
+
+static int *allocate_estimate(int r_num, const int count, float factor)
+{
+       r_num = (int)(count * (factor + STORE_ESTIMATE_BIAS));
+       return MEM_callocN(sizeof(int) * r_num, __func__);
+}*/
+
+/* Doesn't work external pointers to the vert/edge/loop/poly structure break 
+ * Is there another way than converting to bmesh?
+ */
+
+static void remove_verts_from_mesh(Mesh *me, int *v_to_rm, int num_v_to_rm, 
MeshElemMap *emap, MeshElemMap *lmap, MeshElemMap *pmap){
+       int *v_rd_table, *e_rd_table, *l_rd_table, *p_rd_table;
+       int sum = 0, next_del = 0, next_del_pos = 0;
+
+       v_rd_table = MEM_callocN(sizeof(int) * me->totvert, "Vertex redirect 
table");
+
+       /* Prefix Sum / Scan to calculate new positions for vertices. 
Multithreading?*/
+       next_del = v_to_rm[0];
+       for (int i = 0; i < me->totvert; i++) {
+               if (i == next_del) {
+                       if (next_del_pos + 1 < num_v_to_rm) {
+                               next_del_pos ++;
+                               next_del = v_to_rm[next_del_pos];
+                       }
+                       v_rd_table[i] = -1;
+               } else {
+                       v_rd_table[i] = sum;
+                       sum ++;
+               }
+       }
+
+       /*int *e_to_rm = NULL, *l_to_rm = NULL, *p_to_rm = NULL;
+       int num_e_to_rm = 

@@ 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