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 349dd65012fbff2fa73ee28ad97c1e9af5d37831
parent 9fdd9f40c70952020b1a8d9b3279528bc18c3ca1
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Tue,  3 Mar 2020 12:25:47 +0100

Add a feature on frontier API

Diffstat:
Msrc/senc2d.h | 6+++---
Msrc/senc2d_descriptor.c | 16+++++++++-------
Msrc/senc2d_enclosure_data.h | 4+---
Msrc/senc2d_internal_types.h | 6++++--
Msrc/senc2d_scene.c | 4++--
Msrc/senc2d_scene_analyze.c | 26+++++++++++++++-----------
Msrc/senc2d_scene_c.h | 12+++++++++---
Msrc/test_senc2d_scene.c | 28++++++++++++++++++----------
8 files changed, 61 insertions(+), 41 deletions(-)

diff --git a/src/senc2d.h b/src/senc2d.h @@ -283,13 +283,13 @@ senc2d_scene_get_frontier_vertice_count (const struct senc2d_scene* scene, unsigned* count); -/* Returns the iver_th frontier vertex; the returned index is a global vertex - * index whose coordinates can be retrieved using senc2d_scene_get_vertex. */ +/* Returns the iver_th frontier vertex (segment and vertex global IDs). */ SENC2D_API res_T senc2d_scene_get_frontier_vertex (const struct senc2d_scene* scene, const unsigned iver, - unsigned vrtx_id[SENC2D_GEOMETRY_DIMENSION-1]); + unsigned vrtx_id[SENC2D_GEOMETRY_DIMENSION-1], + unsigned* seg_id); SENC2D_API res_T senc2d_scene_ref_get diff --git a/src/senc2d_descriptor.c b/src/senc2d_descriptor.c @@ -130,7 +130,7 @@ senc2d_scene_get_frontier_vertice_count size_t tmp; if(!scn || !count) return RES_BAD_ARG; - tmp = darray_vrtx_id_size_get(&scn->analyze.frontiers); + tmp = darray_frontier_vertex_size_get(&scn->analyze.frontiers); ASSERT(tmp <= VRTX_MAX__); *count = (vrtx_id_t)tmp; /* Back to API type */ return RES_OK; @@ -140,13 +140,15 @@ res_T senc2d_scene_get_frontier_vertex (const struct senc2d_scene* scn, const vrtx_id_t iver, - vrtx_id_t* vrtx_id) + vrtx_id_t* vrtx_id, + unsigned* seg_id) { - vrtx_id_t vrtx; - if(!vrtx_id || !scn - || iver >= darray_vrtx_id_size_get(&scn->analyze.frontiers)) + const struct frontier_vertex* vrtx; + if(!vrtx_id || !scn || !seg_id + || iver >= darray_frontier_vertex_size_get(&scn->analyze.frontiers)) return RES_BAD_ARG; - vrtx = darray_vrtx_id_cdata_get(&scn->analyze.frontiers)[iver]; - *vrtx_id = vrtx; + vrtx = darray_frontier_vertex_cdata_get(&scn->analyze.frontiers) + iver; + *vrtx_id = vrtx->vrtx; + *seg_id = vrtx->seg; return RES_OK; } diff --git a/src/senc2d_enclosure_data.h b/src/senc2d_enclosure_data.h @@ -88,7 +88,6 @@ bool_array_of_media_merge OK(darray_uchar_resize(dst, sz)); data_dst = darray_uchar_data_get(dst); - ASSERT(sz <= MEDIUM_MAX__); if(res != RES_OK) goto error; FOR_EACH(i, 0, sz) { if(!src[i]) continue; @@ -114,14 +113,13 @@ bool_array_of_media_to_darray_media data = darray_uchar_cdata_get(src); ASSERT(next_medium_idx + 1 == darray_uchar_size_get(src)); - ASSERT(next_medium_idx < MEDIUM_MAX__); 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; if(!data[m_idx]) continue; - ASSERT(mm <= MEDIUM_MAX__); 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 @@ -137,9 +137,11 @@ SIDE_CANCELED_FLAG(enum side_flag f) { static FINLINE side_id_t SEGIDxSIDE_2_SEGSIDE(seg_id_t s, enum senc2d_side i) { - ASSERT((((size_t)s << 1) | (i == SENC2D_BACK)) < SIDE_MAX__); + size_t r; ASSERT(i == SENC2D_FRONT || i == SENC2D_BACK); - return (side_id_t)((s << 1) | (i == SENC2D_BACK)); + r = (s << 1) | (i == SENC2D_BACK); + ASSERT(r <= SIDE_MAX__); + return (side_id_t)r; } static FINLINE side_id_t diff --git a/src/senc2d_scene.c b/src/senc2d_scene.c @@ -42,7 +42,7 @@ scene_release(ref_T * ref) darray_segment_enc_release(&scn->analyze.segments_enc); darray_enclosure_release(&scn->analyze.enclosures); darray_enc_ids_array_release(&scn->analyze.enc_ids_array_by_medium); - darray_vrtx_id_release(&scn->analyze.frontiers); + darray_frontier_vertex_release(&scn->analyze.frontiers); MEM_RM(dev->allocator, scn); SENC2D(device_ref_put(dev)); @@ -110,7 +110,7 @@ senc2d_scene_create darray_enclosure_init(scn->dev->allocator, &scn->analyze.enclosures); darray_enc_ids_array_init(scn->dev->allocator, &scn->analyze.enc_ids_array_by_medium); - darray_vrtx_id_init(scn->dev->allocator, &scn->analyze.frontiers); + darray_frontier_vertex_init(scn->dev->allocator, &scn->analyze.frontiers); /* Enclosure 0 is always defined for infinite */ OK(darray_enclosure_resize(&scn->analyze.enclosures, 1)); scn->analyze.enclosures_count = 1; diff --git a/src/senc2d_scene_analyze.c b/src/senc2d_scene_analyze.c @@ -500,8 +500,8 @@ extract_connex_components OK(s2d_shape_create_line_segments(s2d, &s2d_shp)); /* Back to s2d API type for nsegs and nverts */ - ASSERT(scn->nsegs < UINT_MAX); - ASSERT(scn->nverts < UINT_MAX); + ASSERT(scn->nsegs <= UINT_MAX); + ASSERT(scn->nverts <= UINT_MAX); OK(s2d_line_segments_setup_indexed_vertices(s2d_shp, (unsigned)scn->nsegs, get_scn_indices, (unsigned)scn->nverts, &attribs, 1, scn)); @@ -634,14 +634,15 @@ group_connex_components } } /* Implicit barrier here */ - ASSERT(ATOMIC_GET(next_enclosure_id) < ENCLOSURE_MAX__); if(*res != RES_OK) return; /* One thread post-processes links to group connex components */ #pragma omp single { res_T tmp_res = RES_OK; - scn->analyze.enclosures_count = (enclosure_id_t)ATOMIC_GET(next_enclosure_id); + size_t ec = ATOMIC_GET(next_enclosure_id); + ASSERT(ec <= ENCLOSURE_MAX__); + scn->analyze.enclosures_count = (enclosure_id_t)ec; tmp_res = darray_enclosure_resize(&scn->analyze.enclosures, scn->analyze.enclosures_count); if(tmp_res != RES_OK) { @@ -692,7 +693,7 @@ collect_and_link_neighbours (struct senc2d_scene* scn, struct segside* segsides, struct darray_segment_tmp* segments_tmp_array, - struct darray_vrtx_id* frontiers, + struct darray_frontier_vertex* frontiers, /* Shared error status. * We accept to overwrite an error with a different error */ res_T* res) @@ -902,10 +903,13 @@ collect_and_link_neighbours && p_crt_side->medium != p_ccw_side->medium) #pragma omp critical { + struct frontier_vertex frontier_vertex; log_warn(scn->dev, "%s: found frontier involving segment "PRTF_SEG".\n", FUNC_NAME, crt_id); - darray_vrtx_id_push_back(frontiers, &v); + frontier_vertex.seg = crt_id; + frontier_vertex.vrtx = v; + darray_frontier_vertex_push_back(frontiers, &frontier_vertex); } } } @@ -920,7 +924,7 @@ build_result (struct senc2d_scene* scn, const struct darray_ptr_component_descriptor* connex_components, const struct darray_segment_comp* segments_comp_array, - struct darray_vrtx_id* frontiers, + struct darray_frontier_vertex* frontiers, /* Shared error status. * We accept to overwrite an error with a different error */ res_T* res) @@ -1112,7 +1116,7 @@ build_result htable_vrtx_id_release(&vtable); /* The first thread here copies frontiers into descriptor */ #pragma omp single nowait - darray_vrtx_id_copy_and_clear(&scn->analyze.frontiers, frontiers); + darray_frontier_vertex_copy_and_clear(&scn->analyze.frontiers, frontiers); /* No barrier here */ } @@ -1131,7 +1135,7 @@ scene_analyze struct darray_ptr_component_descriptor connex_components; char connex_components_initialized = 0; /* Array of frontier vertices */ - struct darray_vrtx_id frontiers; + struct darray_frontier_vertex frontiers; char frontiers_initialized = 0; /* Store by-segment components */ struct darray_segment_comp segments_comp; @@ -1151,7 +1155,7 @@ scene_analyze darray_segment_tmp_init(scn->dev->allocator, &segments_tmp); segments_tmp_initialized = 1; - darray_vrtx_id_init(scn->dev->allocator, &frontiers); + darray_frontier_vertex_init(scn->dev->allocator, &frontiers); frontiers_initialized = 1; OK(darray_segment_tmp_resize(&segments_tmp, scn->nsegs)); @@ -1307,7 +1311,7 @@ exit: if(segments_tmp_initialized) darray_segment_tmp_release(&segments_tmp); if(segments_comp_initialized) darray_segment_comp_release(&segments_comp); if(frontiers_initialized) - darray_vrtx_id_release(&frontiers); + darray_frontier_vertex_release(&frontiers); if(segsides) MEM_RM(scn->dev->allocator, segsides); return res; diff --git a/src/senc2d_scene_c.h b/src/senc2d_scene_c.h @@ -121,8 +121,14 @@ struct segside { * front(seg_0), back(seg_0), front(seg_1), back(seg_1), ... */ }; -#define DARRAY_NAME frontier_edge -#define DARRAY_DATA struct seg_edge +/* Frontier vertex type */ +struct frontier_vertex { + seg_id_t seg; + vrtx_id_t vrtx; +}; + +#define DARRAY_NAME frontier_vertex +#define DARRAY_DATA struct frontier_vertex #include <rsys/dynamic_array.h> union double2 { @@ -219,7 +225,7 @@ struct descriptor { struct darray_enclosure enclosures; struct darray_enc_ids_array enc_ids_array_by_medium; /* Store frontiers */ - struct darray_vrtx_id frontiers; + struct darray_frontier_vertex frontiers; }; struct senc2d_scene { diff --git a/src/test_senc2d_scene.c b/src/test_senc2d_scene.c @@ -28,7 +28,7 @@ main(int argc, char** argv) struct senc2d_enclosure* enc = NULL; struct senc2d_enclosure_header header; struct context ctx = CONTEXT_NULL__; - unsigned medfront[2], medback[2], ind[2], ids[2]; + unsigned medfront[2], medback[2], ind[2], ids[2], seg; double vrtx[2]; unsigned count, i, maxm; int convention; @@ -194,13 +194,21 @@ main(int argc, char** argv) OK(senc2d_scene_get_frontier_vertice_count(scn, &count)); CHK(count == 0); - BA(senc2d_scene_get_frontier_vertex(NULL, 0, ids)); - BA(senc2d_scene_get_frontier_vertex(scn, UINT_MAX, ids)); - BA(senc2d_scene_get_frontier_vertex(scn, 0, NULL)); - BA(senc2d_scene_get_frontier_vertex(NULL, UINT_MAX, ids)); - BA(senc2d_scene_get_frontier_vertex(NULL, 0, NULL)); - BA(senc2d_scene_get_frontier_vertex(scn, UINT_MAX, NULL)); - BA(senc2d_scene_get_frontier_vertex(NULL, UINT_MAX, NULL)); + BA(senc2d_scene_get_frontier_vertex(NULL, 0, &ids[0], &seg)); + BA(senc2d_scene_get_frontier_vertex(scn, UINT_MAX, &ids[0], &seg)); + BA(senc2d_scene_get_frontier_vertex(scn, 0, NULL, &seg)); + BA(senc2d_scene_get_frontier_vertex(scn, 0, &ids[0], NULL)); + BA(senc2d_scene_get_frontier_vertex(NULL, UINT_MAX, &ids[0], &seg)); + BA(senc2d_scene_get_frontier_vertex(NULL, 0, NULL, &seg)); + BA(senc2d_scene_get_frontier_vertex(NULL, 0, &ids[0], NULL)); + BA(senc2d_scene_get_frontier_vertex(scn, UINT_MAX, NULL, &seg)); + BA(senc2d_scene_get_frontier_vertex(scn, UINT_MAX, &ids[0], NULL)); + BA(senc2d_scene_get_frontier_vertex(scn, 0, NULL, NULL)); + BA(senc2d_scene_get_frontier_vertex(NULL, UINT_MAX, NULL, &seg)); + BA(senc2d_scene_get_frontier_vertex(NULL, UINT_MAX, &ids[0], NULL)); + BA(senc2d_scene_get_frontier_vertex(NULL, 0, NULL, NULL)); + BA(senc2d_scene_get_frontier_vertex(scn, UINT_MAX, NULL, NULL)); + BA(senc2d_scene_get_frontier_vertex(NULL, UINT_MAX, NULL, NULL)); BA(senc2d_scene_ref_get(NULL)); OK(senc2d_scene_ref_get(scn)); @@ -229,8 +237,8 @@ main(int argc, char** argv) OK(senc2d_scene_get_frontier_vertice_count(scn, &count)); CHK(count == 2); - OK(senc2d_scene_get_frontier_vertex(scn, 0, ids)); - BA(senc2d_scene_get_frontier_vertex(scn, 3, ids)); + OK(senc2d_scene_get_frontier_vertex(scn, 0, &ids[0], &seg)); + BA(senc2d_scene_get_frontier_vertex(scn, 3, &ids[0], &seg)); OK(senc2d_scene_ref_put(scn));