star-enclosures-2d

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

commit 754e50e4b72eb81dc49c1132bc12a66b082814df
parent 8447e4fce7350aeaab70aa525bd1caf8dd51337a
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Sun, 15 Mar 2020 18:16:09 +0100

BugFix: mismatch medium id VS medium index

Diffstat:
Msrc/senc2d_descriptor.c | 4++--
Msrc/senc2d_enclosure_data.h | 8+++-----
Msrc/senc2d_internal_types.h | 12++++++++++++
Msrc/senc2d_scene.c | 2+-
Msrc/senc2d_scene_analyze.c | 28+++++++++++++---------------
Msrc/test_senc2d_unspecified_medium.c | 2+-
6 files changed, 32 insertions(+), 24 deletions(-)

diff --git a/src/senc2d_descriptor.c b/src/senc2d_descriptor.c @@ -58,7 +58,7 @@ senc2d_scene_get_enclosure_count_by_medium return RES_BAD_ARG; ASSERT(darray_enc_ids_array_size_get(&scn->analyze.enc_ids_array_by_medium) == 1 + scn->next_medium_idx); - m_idx = (imed == SENC2D_UNSPECIFIED_MEDIUM) ? 0 : imed + 1; + m_idx = medium_id_2_medium_idx(imed); enc_ids = darray_enc_ids_array_cdata_get(&scn->analyze.enc_ids_array_by_medium) + m_idx; tmp = darray_enc_id_size_get(enc_ids); @@ -98,7 +98,7 @@ senc2d_scene_get_enclosure_by_medium return RES_BAD_ARG; ASSERT(darray_enc_ids_array_size_get(&scn->analyze.enc_ids_array_by_medium) == 1 + scn->next_medium_idx); - m_idx = (imed == SENC2D_UNSPECIFIED_MEDIUM) ? 0 : imed + 1; + m_idx = medium_id_2_medium_idx(imed); enc_ids = darray_enc_ids_array_cdata_get(&scn->analyze.enc_ids_array_by_medium) + m_idx; if(idx >= darray_enc_id_size_get(enc_ids)) return RES_BAD_ARG; diff --git a/src/senc2d_enclosure_data.h b/src/senc2d_enclosure_data.h @@ -106,7 +106,7 @@ bool_array_of_media_to_darray_media const medium_id_t next_medium_idx) { res_T res = RES_OK; - size_t m_idx; + int64_t m_idx; const uchar* data; ASSERT(src && dst); @@ -116,11 +116,9 @@ bool_array_of_media_to_darray_media darray_media_clear(dst); if(res != RES_OK) goto error; ASSERT(next_medium_idx <= MEDIUM_MAX__ + 1); - FOR_EACH(m_idx, 0, next_medium_idx + 1) { - medium_id_t medium; - size_t mm = m_idx ? (medium_id_t)(m_idx - 1) : SENC2D_UNSPECIFIED_MEDIUM; + FOR_EACH(m_idx, 0, 1 + (int64_t)next_medium_idx) { + medium_id_t medium = medium_idx_2_medium_id(m_idx); if(!data[m_idx]) continue; - medium = (medium_id_t)mm; res = darray_media_push_back(dst, &medium); if(res != RES_OK) goto error; } diff --git a/src/senc2d_internal_types.h b/src/senc2d_internal_types.h @@ -82,6 +82,18 @@ typedef unsigned medium_id_t; #define MEDIUM_NULL__ UINT_MAX #define PRTF_MDM "%u" +static FINLINE medium_id_t +medium_idx_2_medium_id(int64_t m_idx) { + return m_idx ? (medium_id_t)(m_idx - 1) : SENC2D_UNSPECIFIED_MEDIUM; +} + +static FINLINE unsigned +medium_id_2_medium_idx(medium_id_t medium) { + uint64_t tmp = (medium == SENC2D_UNSPECIFIED_MEDIUM) ? 0 : medium + 1; + ASSERT(tmp <= UINT_MAX); + return (unsigned)tmp; +} + /* Enclosure IDs type */ typedef unsigned enclosure_id_t; #define ENCLOSURE_MAX__ (UINT_MAX-1) diff --git a/src/senc2d_scene.c b/src/senc2d_scene.c @@ -190,7 +190,7 @@ senc2d_scene_create OK(htable_seg_set(&unique_segments, &seg_key, &ns)); for(s = SENC2D_FRONT; s <= SENC2D_BACK; s += SENC2D_BACK - SENC2D_FRONT) { struct side_range* media_use; - size_t m_idx = (med[s] == SENC2D_UNSPECIFIED_MEDIUM) ? 0 : med[s] + 1; + size_t m_idx = medium_id_2_medium_idx(med[s]); tmp.medium[s] = med[s]; if(m_idx >= scn->next_medium_idx) { medium_id_t medium; diff --git a/src/senc2d_scene_analyze.c b/src/senc2d_scene_analyze.c @@ -190,7 +190,7 @@ extract_connex_components FOR_EACH(s, 0, 2) { const side_id_t side = SEGIDxSIDE_2_SEGSIDE(s_, s); medium_id_t medium = seg_in->medium[s]; - m_idx = (medium == SENC2D_UNSPECIFIED_MEDIUM) ? 0 : medium + 1; + m_idx = medium_id_2_medium_idx(medium); ASSERT(media_use[m_idx].first <= side && side <= media_use[m_idx].last); } @@ -202,7 +202,7 @@ extract_connex_components #pragma omp for schedule(dynamic) nowait /* Process all media, including undef */ for(m_idx = 0; m_idx < 1 + (int64_t)scn->next_medium_idx; m_idx++) { - const medium_id_t medium = m_idx ? (medium_id_t)(m_idx - 1) : SENC2D_UNSPECIFIED_MEDIUM; + const medium_id_t medium = medium_idx_2_medium_id(m_idx); /* media_use 0 is for SENC2D_UNSPECIFIED_MEDIUM, n+1 is for n */ const struct side_range* media_use = darray_side_range_cdata_get(&scn->media_use) + m_idx; @@ -320,13 +320,12 @@ extract_connex_components enum side_flag nbour_side_id = SEGSIDE_2_SIDEFLAG(neighbour_id); uchar* nbour_used = processed + nbour_seg_id; const struct segside* neighbour = segsides + neighbour_id; - medium_id_t nbour_med_idx = (neighbour->medium == SENC2D_UNSPECIFIED_MEDIUM) - ? 0 : neighbour->medium + 1; - if(neighbour->medium < medium + medium_id_t nbour_med_idx = medium_id_2_medium_idx(neighbour->medium); + if((int64_t)nbour_med_idx < m_idx || (*nbour_used & SIDE_CANCELED_FLAG(nbour_side_id))) { /* 1) Not the same medium. - * Neighbour's medium id is less than current medium: the whole + * Neighbour's medium idx is less than current medium: the whole * component is to be processed by another thread (possibly the one * associated with neighbour's medium). * 2) Neighbour was canceled: no need to replay the component @@ -381,7 +380,7 @@ extract_connex_components ASSERT(id <= COMPONENT_MAX__); cc->cc_id = (component_id_t)id; sz = darray_side_id_size_get(&current_component); - ASSERT(sz <= SIDE_MAX__); + ASSERT(sz > 0 && sz <= SIDE_MAX__); cc->side_count = (side_id_t)sz; cc->side_range.first = start_side_id; cc->side_range.last = last_side_id; @@ -401,7 +400,8 @@ extract_connex_components enum senc2d_side sid = SEGSIDE_2_SIDE(s); component_id_t* cmp = segments_comp[segid].component; ASSERT(cmp[sid] == COMPONENT_NULL__); - ASSERT(segsides[s].medium >= medium); + ASSERT(medium_id_2_medium_idx(segsides[s].medium) + >= medium_id_2_medium_idx(medium)); cmp[sid] = cc->cc_id; } @@ -544,7 +544,6 @@ extract_connex_components static void group_connex_components (struct senc2d_scene* scn, - struct segside* segsides, struct darray_segment_comp* segments_comp, struct darray_ptr_component_descriptor* connex_components, struct s2d_scene_view* s2d_view, @@ -561,9 +560,8 @@ group_connex_components component_id_t cc_count; int64_t ccc; - (void)segsides; - ASSERT(scn && segsides && segments_comp && connex_components - && s2d_view && next_enclosure_id && res); + ASSERT(scn && segments_comp && connex_components && s2d_view + && next_enclosure_id && res); ASSERT(scn->analyze.enclosures_count == 1); descriptors = darray_ptr_component_descriptor_data_get(connex_components); @@ -1021,7 +1019,7 @@ build_result /* Add this enclosure in relevant by-medium lists */ FOR_EACH(m, 0, enc->header.enclosed_media_count) { medium_id_t medium = darray_media_cdata_get(&enc->enclosed_media)[m]; - size_t m_idx = (medium == SENC2D_UNSPECIFIED_MEDIUM) ? 0 : medium + 1; + size_t m_idx = medium_id_2_medium_idx(medium); struct darray_enc_id* enc_ids_array_by_medium; ASSERT(medium == SENC2D_UNSPECIFIED_MEDIUM || medium < scn->next_medium_idx); ASSERT(darray_enc_ids_array_size_get(&scn->analyze.enc_ids_array_by_medium) @@ -1245,8 +1243,8 @@ scene_analyze } /* No barrier here */ /* Step 3: group components */ - group_connex_components(scn, segsides, &segments_comp, - &connex_components, s2d_view, &next_enclosure_id, &res); + group_connex_components(scn, &segments_comp, &connex_components, s2d_view, + &next_enclosure_id, &res); /* Barrier at the end of step 3: data used in step 3 can be released / * data produced by step 3 can be used */ diff --git a/src/test_senc2d_unspecified_medium.c b/src/test_senc2d_unspecified_medium.c @@ -143,7 +143,7 @@ test(const int convention) * if convention is front, front medium (undef) is outside, * that is medium 0's enclosure is infinite */ expected_external_medium = conv_front ? SENC2D_UNSPECIFIED_MEDIUM : 1; - expected_internal_medium = conv_front ? 1 :SENC2D_UNSPECIFIED_MEDIUM; + expected_internal_medium = conv_front ? 1 : SENC2D_UNSPECIFIED_MEDIUM; CHK(medium == (header.is_infinite ? expected_external_medium : expected_internal_medium));