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 051843e1a9032660bf2a7ff35030e39bbaa9d5c3
parent 89b83bee0801f0b36c17f56ea5d3e099f11af7d4
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Fri,  1 May 2020 16:46:25 +0200

Make enclosure IDs reproducible

Diffstat:
Msrc/senc3d_scene_analyze.c | 62++++++++++++++++++++++++++++++++++++++++++++++++++++----------
1 file changed, 52 insertions(+), 10 deletions(-)

diff --git a/src/senc3d_scene_analyze.c b/src/senc3d_scene_analyze.c @@ -616,7 +616,7 @@ group_connex_components *res = s3d_scene_view_get_aabb(s3d_view, lower, upper); if(*res != RES_OK) return; /* Cast rays to find links between connex components */ - #pragma omp for + #pragma omp for schedule(dynamic) for(ccc = 0; ccc < (int64_t)cc_count; ccc++) { res_T tmp_res = RES_OK; component_id_t c = (component_id_t)ccc; @@ -981,12 +981,23 @@ tmp_error: darray_neighbourhood_release(&neighbourhood_by_edge); } +static int +compare_enclosures + (const void* ptr1, const void* ptr2) +{ + const struct enclosure_data* e1 = ptr1; + const struct enclosure_data* e2 = ptr2; + ASSERT(e1->side_range.first != e2->side_range.first); + return (e1->side_range.first - e2->side_range.first); +} + static void build_result (struct senc3d_scene* scn, const struct darray_ptr_component_descriptor* connex_components, const struct darray_triangle_comp* triangles_comp_array, struct darray_frontier_edge* frontiers, + enclosure_id_t* ordered_ids, /* Shared error status. * We accept to overwrite an error with a different error */ res_T* res) @@ -1022,11 +1033,33 @@ build_result #pragma omp single { + enclosure_id_t e; + size_t d; res_T tmp_res = darray_triangle_enc_resize(&scn->analyze.triangles_enc, scn->ntris); - if(tmp_res != RES_OK) *res = tmp_res; + if(tmp_res != RES_OK) { + *res = tmp_res; + goto single_err; + } + /* Store initial enclosure order */ + FOR_EACH(e, 0, scn->analyze.enclosures_count) + enclosures[e].header.enclosure_id = e; + /* Move enclosures by first side while keeping enclosure 0 + * at rank 0 (its a convention) */ + qsort(enclosures + 1, scn->analyze.enclosures_count - 1, + sizeof(*enclosures), compare_enclosures); + /* Make conversion table */ + FOR_EACH(e, 0, scn->analyze.enclosures_count) { + enclosure_id_t rank = enclosures[e].header.enclosure_id; + ordered_ids[rank] = e; + } + /* Rewrite cc_descriptors */ + FOR_EACH(d, 0, darray_ptr_component_descriptor_size_get(connex_components)) + cc_descriptors[d]->enclosure_id = + ordered_ids[cc_descriptors[d]->enclosure_id]; + single_err: (void)0; }/* Implicit barrier here. */ - if(*res != RES_OK) return; + if(*res != RES_OK) goto exit; triangles_enc = darray_triangle_enc_data_get(&scn->analyze.triangles_enc); /* Build global enclosure information */ @@ -1054,7 +1087,7 @@ build_result #pragma omp for schedule(dynamic) nowait for(ee = 0; ee < (int64_t)scn->analyze.enclosures_count; ee++) { const enclosure_id_t e = (enclosure_id_t)ee; - struct enclosure_data* enc = enclosures + e; + struct enclosure_data* enc = enclosures + ee; trg_id_t fst_idx = 0; trg_id_t sgd_idx = enc->side_count; trg_id_t t; @@ -1067,7 +1100,7 @@ build_result if(*res != RES_OK) continue; ASSERT(e <= ENCLOSURE_MAX__); - enc->header.enclosure_id = (enclosure_id_t)e; /* Back to API type */ + enc->header.enclosure_id = (unsigned)ee; /* Back to API type */ ASSERT(cc_descriptors[enc->first_component]->enclosure_id == enc->header.enclosure_id); enc->header.is_infinite = (e == 0); @@ -1180,6 +1213,8 @@ build_result #pragma omp single nowait darray_frontier_edge_copy_and_clear(&scn->analyze.frontiers, frontiers); /* No barrier here */ +exit: + return; } /****************************************************************************** @@ -1208,6 +1243,7 @@ scene_analyze /* Atomic counters to share beetwen threads */ ATOMIC component_count = 0; ATOMIC next_enclosure_id = 1; + enclosure_id_t* ordered_ids = NULL; res_T res = RES_OK; res_T res2 = RES_OK; @@ -1321,16 +1357,21 @@ scene_analyze goto error_; } - /* One thread releases some data before going to step 4, - * the others go to step 4 without sync */ - #pragma omp single nowait + /* One thread releases some data and allocate other data before going to + * step 4, the others waiting for alloced data */ + #pragma omp single { if(s3d_view) S3D(scene_view_ref_put(s3d_view)); s3d_view = NULL; - } /* No barrier here */ + ordered_ids = MEM_ALLOC(scn->dev->allocator, + sizeof(*ordered_ids) * scn->analyze.enclosures_count); + if(!ordered_ids) res = RES_MEM_ERR; + } /* Implicit barrier here */ + if(res != RES_OK) goto error_; /* Step 4: Build result */ - build_result(scn, &connex_components, &triangles_comp, &frontiers, &res); + build_result(scn, &connex_components, &triangles_comp, &frontiers, + ordered_ids, &res); /* No barrier at the end of step 4: data used in step 4 cannot be * released / data produced by step 4 cannot be used * until next sync point */ @@ -1351,6 +1392,7 @@ scene_analyze { #pragma omp section { + MEM_RM(scn->dev->allocator, ordered_ids); custom_darray_ptr_component_descriptor_release(&connex_components); connex_components_initialized = 0; }