star-enclosures-3d

Extract enclosures from 3D geometry
git clone git://git.meso-star.fr/star-enclosures-3d.git
Log | Files | Refs | README | LICENSE

commit d9d3d058541b10b5699e8f99dcba06e70dbcc713
parent fa5d58abf3133f8d53f3ac457a7bc890e0b6c2dd
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Sat,  4 Jul 2020 17:11:00 +0200

BugFix overlapping triangles where only collected on 1 thread

Diffstat:
Msrc/senc3d_scene_analyze.c | 69+++++++++++++++++++++++++++++++++++++++------------------------------
Msrc/senc3d_scene_c.h | 2+-
2 files changed, 40 insertions(+), 31 deletions(-)

diff --git a/src/senc3d_scene_analyze.c b/src/senc3d_scene_analyze.c @@ -526,7 +526,7 @@ extract_connex_components } ASSERT(!fst_nz); /* Determine if this component can be an inner part inside another - * component (creating a hole) as only these components will need + * component (substracting a volume) as only these components will need * to search for their possible outer component when grouping * components to create enclosures. * The inner/outer property comes from the normal orientation of the @@ -784,6 +784,7 @@ collect_and_link_neighbours struct trgside* trgsides, struct darray_triangle_tmp* triangles_tmp_array, struct darray_frontier_edge* frontiers, + struct htable_overlap* overlaps, /* Shared error status. * We accept to overwrite an error with a different error */ res_T* res) @@ -798,8 +799,6 @@ collect_and_link_neighbours const int front = ((scn->convention & SENC3D_CONVENTION_NORMAL_FRONT) != 0); /* Htable used to give an id to edges */ struct htable_edge_id edge_ids; - /* Htable used to store overlapping triangles */ - struct htable_overlap overlaps; /* Array to keep neighbourhood of edges * Resize/Push operations on neighbourhood_by_edge are valid in the * openmp block because a given neighbourhood is only processed @@ -816,7 +815,6 @@ collect_and_link_neighbours ASSERT((size_t)scn->nverts + (size_t)scn->ntris + 2 <= EDGE_MAX__); htable_edge_id_init(scn->dev->allocator, &edge_ids); - htable_overlap_init(scn->dev->allocator, &overlaps); darray_neighbourhood_init(scn->dev->allocator, &neighbourhood_by_edge); triangles_in = darray_triangle_in_cdata_get(&scn->triangles_in); @@ -995,9 +993,9 @@ collect_and_link_neighbours #pragma omp critical { char one = 1; - tmp_res = htable_overlap_set(&overlaps, &crt_id, &one); + tmp_res = htable_overlap_set(overlaps, &crt_id, &one); if(tmp_res == RES_OK) - tmp_res = htable_overlap_set(&overlaps, &prev_id, &one); + tmp_res = htable_overlap_set(overlaps, &prev_id, &one); } if(tmp_res != RES_OK) goto tmp_error; } @@ -1034,31 +1032,10 @@ collect_and_link_neighbours } } - #pragma omp barrier - #pragma omp single - { - /* Save all the overlapping triangles in a darray */ - struct htable_overlap_iterator it, end; - htable_overlap_begin(&overlaps, &it); - htable_overlap_end(&overlaps, &end); - darray_trg_id_reserve(&scn->analyze.overlapping_ids, - htable_overlap_size_get(&overlaps)); - while(!htable_overlap_iterator_eq(&it, &end)) { - darray_trg_id_push_back(&scn->analyze.overlapping_ids, - htable_overlap_iterator_key_get(&it)); - htable_overlap_iterator_next(&it); - } - qsort(darray_trg_id_data_get(&scn->analyze.overlapping_ids), - darray_trg_id_size_get(&scn->analyze.overlapping_ids), - sizeof(*darray_trg_id_cdata_get(&scn->analyze.overlapping_ids)), - cmp_trg_id); - } - tmp_error: if(tmp_res != RES_OK) *res = tmp_res; /* Threads are allowed to return whitout sync. */ htable_edge_id_release(&edge_ids); - htable_overlap_release(&overlaps); darray_neighbourhood_release(&neighbourhood_by_edge); } @@ -1319,6 +1296,9 @@ scene_analyze /* Array of frontiers edges */ struct darray_frontier_edge frontiers; char frontiers_initialized = 0; + /* Htable used to store overlapping segments */ + struct htable_overlap overlaps; + char overlaps_initialized = 0; /* Store by-triangle components */ struct darray_triangle_comp triangles_comp; char triangles_comp_initialized = 0; @@ -1340,6 +1320,8 @@ scene_analyze triangles_tmp_initialized = 1; darray_frontier_edge_init(scn->dev->allocator, &frontiers); frontiers_initialized = 1; + htable_overlap_init(scn->dev->allocator, &overlaps); + overlaps_initialized = 1; OK(darray_triangle_tmp_resize(&triangles_tmp, scn->ntris)); trgsides @@ -1363,7 +1345,7 @@ scene_analyze { /* Step 1: build neighbourhoods */ collect_and_link_neighbours(scn, trgsides, &triangles_tmp, &frontiers, - &res); + &overlaps, &res); /* No barrier at the end of step 1: data used in step 1 cannot be * released / data produced by step 1 cannot be used * until next sync point */ @@ -1387,6 +1369,33 @@ scene_analyze } /* Implicit barrier here: constraints on step 1 data are now met */ +#pragma omp single + { + res_T tmp_res = RES_OK; + /* Save all the overlapping segments in a darray */ + ASSERT(overlaps_initialized); + struct htable_overlap_iterator it, end; + htable_overlap_begin(&overlaps, &it); + htable_overlap_end(&overlaps, &end); + tmp_res = darray_trg_id_reserve(&scn->analyze.overlapping_ids, + htable_overlap_size_get(&overlaps)); + if(tmp_res != RES_OK) goto tmp_error2; + while (!htable_overlap_iterator_eq(&it, &end)) { + tmp_res = darray_trg_id_push_back(&scn->analyze.overlapping_ids, + htable_overlap_iterator_key_get(&it)); + if(tmp_res != RES_OK) goto tmp_error2; + htable_overlap_iterator_next(&it); + } + qsort(darray_trg_id_data_get(&scn->analyze.overlapping_ids), + darray_trg_id_size_get(&scn->analyze.overlapping_ids), + sizeof(*darray_trg_id_cdata_get(&scn->analyze.overlapping_ids)), + cmp_trg_id); + htable_overlap_release(&overlaps); + overlaps_initialized = 0; + tmp_error2: + if(tmp_res != RES_OK) res2 = tmp_res; + } + if(darray_trg_id_size_get(&scn->analyze.overlapping_ids)) { /* Stop analysis here as the model is ill-formed */ goto end_; @@ -1509,8 +1518,8 @@ exit: if(s3d_view) S3D(scene_view_ref_put(s3d_view)); if(triangles_tmp_initialized) darray_triangle_tmp_release(&triangles_tmp); if(triangles_comp_initialized) darray_triangle_comp_release(&triangles_comp); - if(frontiers_initialized) - darray_frontier_edge_release(&frontiers); + if(frontiers_initialized) darray_frontier_edge_release(&frontiers); + if(overlaps_initialized) htable_overlap_release(&overlaps); if(trgsides) MEM_RM(scn->dev->allocator, trgsides); return res; diff --git a/src/senc3d_scene_c.h b/src/senc3d_scene_c.h @@ -285,7 +285,7 @@ struct descriptor { struct darray_enc_ids_array enc_ids_array_by_medium; /* Store frontiers */ struct darray_frontier_edge frontiers; - /* Store overlying triangles */ + /* Store overlapping triangles */ struct darray_trg_id overlapping_ids; };