[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