[Bf-blender-cvs] [8ac93b54283] soc-2017-sculpting_improvements: Managed intersection data from multiprocess. Fixed ghash_pop workaround.
Sebastian Witt
noreply at git.blender.org
Fri Aug 11 14:16:03 CEST 2017
Commit: 8ac93b5428384ff7b0bd360be4c1f828add7fd44
Author: Sebastian Witt
Date: Fri Aug 11 14:14:48 2017 +0200
Branches: soc-2017-sculpting_improvements
https://developer.blender.org/rB8ac93b5428384ff7b0bd360be4c1f828add7fd44
Managed intersection data from multiprocess. Fixed ghash_pop workaround.
===================================================================
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 f613d4b4ee0..196300664b3 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -230,6 +230,11 @@ void bl_debug_draw_BB_add(BB *bb,const unsigned int col){
}
#endif
+typedef struct IntersectionData {
+ float *intersection_points; /* exact positions where the two shapes connect */
+ GHash *edge_hash;
+ int num_intersection_points; /* 3 times intersection point count*/
+} IntersectionData;
typedef enum {
SIL_INIT = 0,
@@ -271,7 +276,10 @@ typedef struct SilhouetteData {
int num_inter_nodes;
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; /* every ring gets a Bounding box to check intersection with branches */
+ IntersectionData *isect_chunk;
+ int num_isect_data;
+ int isect_chunk_tot;
} SilhouetteData;
/** \name Tool Capabilities
@@ -5241,8 +5249,8 @@ static SilhouetteData *silhouette_data_new(bContext *C)
/* 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->fillet_ring_orig = NULL;
+ sil->fillet_ring_orig_start = NULL;
sil->inter_edges = NULL;
sil->fillet_ring_bbs = NULL;
@@ -7110,6 +7118,47 @@ static bool calc_stroke_normal_ori(SilhouetteStroke *stroke, float z_vec[3]) {
return dot_v3v3(n, z_vec) <= 0;
}
+static IntersectionData *add_isect_chunk(SilhouetteData *sil)
+{
+ if (!sil->isect_chunk) {
+ sil->isect_chunk = MEM_callocN(sizeof(IntersectionData) * 10, "isect data");
+ sil->isect_chunk_tot = 10;
+ } else {
+ if (sil->num_isect_data >= sil->isect_chunk_tot) {
+ sil->isect_chunk_tot += 10;
+ sil->isect_chunk = MEM_reallocN(sizeof(IntersectionData) * sil->isect_chunk_tot, "isect data");
+ }
+ }
+ sil->num_isect_data ++;
+ return &sil->isect_chunk[sil->num_isect_data - 1];
+}
+
+static void prep_float_shared_mem(float **mem, int *r_num, int *r_start, int len, const char *str)
+{
+ if (!mem) {
+ *r_start = 0;
+ *mem = MEM_callocN(sizeof(float) * len, str);
+ *r_num = len;
+ } else {
+ *r_start = *r_num;
+ *r_num = *r_num + len;
+ *mem = MEM_reallocN(*mem, sizeof(float) * (*r_num));
+ }
+}
+
+static void prep_int_shared_mem(int **mem, int *r_num, int *r_start, int len, const char *str)
+{
+ if (!mem) {
+ *r_start = 0;
+ *mem = MEM_callocN(sizeof(int) * len, str);
+ *r_num = len;
+ } else {
+ *r_start = *r_num;
+ *r_num = *r_num + len;
+ *mem = MEM_reallocN(*mem, sizeof(int) * (*r_num));
+ }
+}
+
static void do_calc_sil_intersect_task_cb_ex(void *userdata, void *UNUSED(userdata_chunk), const int n, const int UNUSED(thread_id))
{
SculptThreadedTaskData *data = userdata;
@@ -7125,10 +7174,14 @@ static void do_calc_sil_intersect_task_cb_ex(void *userdata, void *UNUSED(userda
int tri_node_bind;
int tri_node_bind_tot;
float t_lambda;
- float t_uv[2];
const MLoopTri *ltris;
MLoopTri lt;
BKE_pbvh_get_tri(bvh, <ris);
+ GHash *edge_hash = BLI_ghash_int_new("edges within intersection");
+ float *int_points = NULL;
+ int int_points_shared_start;
+ IntersectionData *i_data;
+ BLI_array_declare(int_points);
for (int r = 0; r < sil->num_rings; r++) {
if (!branch || bb_intersect(&branch->bb, &sil->fillet_ring_bbs[r])) {
@@ -7148,21 +7201,43 @@ static void do_calc_sil_intersect_task_cb_ex(void *userdata, void *UNUSED(userda
lt = ltris[sil->inter_tris[tri_node_bind + tri_i]];
if (isect_line_segment_tri_v3(p1, p2,
me->mvert[me->mloop[lt.tri[0]].v].co, me->mvert[me->mloop[lt.tri[1]].v].co, me->mvert[me->mloop[lt.tri[2]].v].co,
- &t_lambda, t_uv))
+ &t_lambda, NULL))
{
+ BLI_ghash_insert(edge_hash, SET_INT_IN_POINTER(e_start + e), SET_INT_IN_POINTER(BLI_array_count(int_points)));
+ BLI_array_grow_items(int_points, 3);
+ interp_v3_v3v3(&int_points[BLI_array_count(int_points) - 3], p1, p2, t_lambda);
#ifdef DEBUG_DRAW
+ /*bl_debug_color_set(0x0000ff);
+ bl_debug_draw_point(&int_points[BLI_array_count(int_points) - 3], 0.05f);
bl_debug_color_set(0x000000);
bl_debug_draw_edge_add(p1, p2);
- bl_debug_color_set(0x000000);
+ bl_debug_color_set(0x000000);*/
#endif
break;
}
}
}
}
+ BLI_mutex_lock(&data->mutex);
+ if (BLI_array_count(int_points) > 0) {
+ i_data = add_isect_chunk(sil);
+ i_data->edge_hash = edge_hash;
+ i_data->intersection_points = MEM_callocN(sizeof(float) * BLI_array_count(int_points), "exact intersecting points");
+ i_data->num_intersection_points = BLI_array_count(int_points);
+ memcpy(i_data->intersection_points, int_points, BLI_array_count(int_points) * sizeof(float));
+ //if (sil->isect_chunk)
+ //prep_float_shared_mem((float**)&sil->intersection_points, &sil->num_intersection_points, &int_points_shared_start, BLI_array_count(int_points), "exact intersecting points");
+ //memcpy(&sil->intersection_points[int_points_shared_start], int_points, BLI_array_count(int_points) * sizeof(float));
+ }
+
+ BLI_mutex_unlock(&data->mutex);
+
+ BLI_array_free(int_points);
return;
}
}
+ BLI_array_free(int_points);
+ BLI_ghash_free(edge_hash, NULL, NULL);
}
static void check_preceding_intersecting_edges(Object *ob, SilhouetteData *sil, SpineBranch *branch, PBVHNode **nodes, int tot_edge)
@@ -7188,8 +7263,36 @@ static void check_preceding_intersecting_edges(Object *ob, SilhouetteData *sil,
#endif
}
+static void combine_intersection_data(Mesh *me, SilhouetteData *sil)
+{
+ IntersectionData *data = sil->isect_chunk;
+ MEdge *first_e = NULL;
+ GHashIterator gh_iter;
+
+ if (sil->num_isect_data > 0) {
+ for (int i = 0; i < sil->num_isect_data; i++) {
+ if (BLI_ghash_size(data[i].edge_hash) > 0) {
+ GHASH_ITER (gh_iter, data[i].edge_hash) {
+ first_e = &me->medge[(int)BLI_ghashIterator_getKey(&gh_iter)];
+#ifdef DEBUG_DRAW
+ bl_debug_color_set(0xffffff);
+ bl_debug_draw_medge_add(me, (int)BLI_ghashIterator_getKey(&gh_iter));
+ bl_debug_color_set(0x000000);
+#endif
+ break;
+ }
+ }
+ if(first_e) {
+ break;
+ }
+ }
+ }
+
+ /*TODO: detect which side is inside and which is outside of first_e ...*/
+}
+
/* Generates a 3D shape from a stroke. */
-static void silhouette_create_shape_mesh(bContext *C, Mesh *me, PBVH *bvh, SilhouetteData *sil, SilhouetteStroke *stroke, PBVHNode **nodes)
+static void silhouette_create_shape_mesh(bContext *C, Mesh *me, SilhouetteData *sil, SilhouetteStroke *stroke, PBVHNode **nodes)
{
Object *ob = CTX_data_active_object(C);
float z_vec[3] = {0.0f,0.0f,1.0f};
@@ -7253,6 +7356,21 @@ static void silhouette_create_shape_mesh(bContext *C, Mesh *me, PBVH *bvh, Silho
bridge_all_parts(me, spine, v_steps * 2 + w_steps, n_ori);
check_preceding_intersecting_edges(ob, sil, NULL, nodes, me->totedge - e_start);
+ combine_intersection_data(me, sil);
+ /*printf("Joining %i isect data.\n", sil->num_isect_data);
+ for (int i = 0; i < sil->num_isect_data; i++) {
+ IntersectionData *isect_data = &sil->isect_chunk[i];
+ GHash *i_edge_hash = isect_data->edge_hash;
+ GHashIterator gh_iter;
+ int e_key;
+ GHASH_ITER(gh_iter, i_edge_hash) {
+ e_key = BLI_ghashIterator_getKey(&gh_iter);
+ bl_debug_color_set(0x0000ff);
+ bl_debug_draw_medge_add(me, e_key);
+ bl_debug_color_set(0x000000);
+ }
+ }*/
+
free_spine(spine);
ED_mesh_update(me, C, 1, 1);
@@ -7577,11 +7695,11 @@ static void calc_ring_bbs(SilhouetteData *sil, Mesh *me)
sil->fillet_ring_bbs = MEM_callocN(sizeof(BB) * sil->num_rings, "ring bb mem");
for (int r = 0; r < sil->num_rings; r++) {
- len = r + 1 < sil->num_rings ? sil->fillet_ring_new_start[r + 1] - sil->fillet_ring_new_start[r] : sil->fillet_ring_tot - sil->fillet_ring_new_start[r];
+ len = r + 1 < sil->num_rings ? sil->fillet_ring_orig_start[r + 1] - sil->fillet_ring_orig_start[r] : sil->fillet_ring_tot - sil->fillet_ring_orig_start[r];
curr = &sil->fillet_ring_bbs[r];
BB_reset(curr);
for (int e = 0; e < len; e++) {
- edge = sil->fillet_ring_new[sil->fillet_ring_new_start[r] + e];
+ edge = sil->fillet_ring_orig[sil->fillet_ring_orig_start[r] + e];
BB_expand(curr, me->mvert[me->medge[edge].v1].co);
BB_expand(curr, me->mvert[me->medge[edge].v2].co);
}
@@ -7605,14 +7723,14 @@ static void order_positive_is_inside(Mesh *me, SilhouetteData *sil, MeshElemMap
}
center = r1_start + (*r11 + (dist_1 / 2)) % r1_tot;
- comp_v1 = me->medge[sil->fillet_ring_new[center]].v2;
+ comp_v1 = me->medge[sil->fillet_ring_orig[center]].v2;
for (int e = 0; e < emap[comp_v1].count; e++) {
comp_e = emap[comp_v1].indices[e];
- if (comp_e != sil->fillet_ring_new[center] && comp_e != sil->fillet_ring_new[center + 1] && comp_e != sil->fillet_ring_new[center - 1]) {
+ if (comp_e != sil->fillet_ring_orig[center] && comp_e != sil->fillet_ring_orig[center + 1] && comp_e != sil->fillet_ring_orig[center - 1]) {
comp_v2 = me->medge[comp_e].v1 == comp_v1 ? me->medge[comp_e].v2 : me->medge[comp_e].v1;
for (int e_l = 0; e_l < r2_tot; e_l ++) {
- if (me->medge[sil->fillet_ring_new[r2_start + e_l]].v2 == comp_v2) {
+ if (me->medge[sil->fillet_ring_orig[r2_start + e_l]].v2 == comp_v2) {
return;
}
}
@@ -7662,19 +7780,19 @@ static void join_node_separated_rings(SilhouetteData *sil, Mesh *me, MeshElemMap
for (int r1 = 0; r1 < sil->num_rings - 1; r1++) {
for (int r2 = r1 + 1; r2 < sil->num_rings; r2++) {
if (bb_intersect(&sil->fillet_ring_bbs[r1], &sil->fillet_ring_bbs[r2])) {
- t_m_info.r1_start = sil->fillet_ring_new_start[r1];
- t_m_info.r2_start = sil->fillet_ring_new_start[r2];
- t_m_info.r1_tot = sil->fillet_ring_new_start[r1 + 1] - t_m_info.r1_start;
- t_m_info.r2_tot = r2 + 1 < sil->num_rings ? sil->fillet_ring_new_start[r2 + 1] - t_m_info.r2_start : sil->fillet_ring_tot - t_m_info.r2_start;
+ t_m_info.r1_start = sil->fillet_ring_orig_start[r1];
+ t_m_info.r2_start = sil->fillet_ring_orig_start[r2];
+ t_m_info.r1_tot = sil->fillet_ring_orig_start[r1 + 1] - t_m
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list