[Bf-blender-cvs] [d684bdd1390] soc-2017-sculpting_improvements: Added memory and data to handle intersection rings. Still WIP unstable.

Sebastian Witt noreply at git.blender.org
Thu Aug 3 17:59:00 CEST 2017


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




More information about the Bf-blender-cvs mailing list