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 540f554e72d993c378c2234abaf9e51c6cad8d79
parent 39229d66530452f2981389409df646172141cdad
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Mon, 11 Feb 2019 15:45:04 +0100

Add API calls to access to geometry frontiers

Diffstat:
Msrc/senc2d.h | 11+++++++++++
Msrc/senc2d_descriptor.c | 31+++++++++++++++++++++++++++++++
Msrc/senc2d_descriptor_c.h | 2++
Msrc/senc2d_scene_analyze.c | 32+++++++++++++++++++++++---------
Msrc/test_senc2d_descriptor.c | 50+++++++++++++++++++++++++++++++++++++++++++++-----
5 files changed, 112 insertions(+), 14 deletions(-)

diff --git a/src/senc2d.h b/src/senc2d.h @@ -278,6 +278,17 @@ senc2d_descriptor_get_global_segment_global_id unsigned* gid); SENC2D_API res_T +senc2d_descriptor_get_frontier_vertices_count + (const struct senc2d_descriptor* descriptor, + unsigned* count); /* Number of frontier vertices. */ + +SENC2D_API res_T +senc2d_descriptor_get_frontier_vertex + (const struct senc2d_descriptor* descriptor, + const unsigned iver, + unsigned* vrtx_id); + +SENC2D_API res_T senc2d_descriptor_ref_get (struct senc2d_descriptor* descriptor); diff --git a/src/senc2d_descriptor.c b/src/senc2d_descriptor.c @@ -37,6 +37,7 @@ descriptor_release(ref_T * ref) darray_segment_enc_release(&desc->segments_enc); darray_enclosure_release(&desc->enclosures); darray_enc_ids_array_release(&desc->enc_ids_array_by_medium); + darray_vrtx_id_release(&desc->frontiers); MEM_RM(scn->dev->allocator, desc); SENC2D(scene_ref_put(scn)); @@ -61,6 +62,7 @@ descriptor_create(struct senc2d_scene* scn) darray_enc_ids_array_init(scn->dev->allocator, &desc->enc_ids_array_by_medium); OK(darray_enc_ids_array_resize(&desc->enc_ids_array_by_medium, scn->nmeds)); + darray_vrtx_id_init(scn->dev->allocator, &desc->frontiers); /* Enclosure 0 is always defined for infinite */ OK(darray_enclosure_resize(&desc->enclosures, 1)); desc->enclosures_count = 1; @@ -276,6 +278,35 @@ senc2d_descriptor_get_global_segment_global_id } res_T +senc2d_descriptor_get_frontier_vertices_count + (const struct senc2d_descriptor* desc, + unsigned* count) +{ + size_t tmp; + if(!desc || !count) + return RES_BAD_ARG; + tmp = darray_vrtx_id_size_get(&desc->frontiers); + ASSERT(tmp < UINT_MAX); + *count = (unsigned)tmp; + return RES_OK; +} + +res_T +senc2d_descriptor_get_frontier_vertex + (const struct senc2d_descriptor* desc, + const unsigned iver, + unsigned* vrtx_id) +{ + vrtx_id_t vrtx; + if(!vrtx_id || !desc + || iver >= darray_vrtx_id_size_get(&desc->frontiers)) + return RES_BAD_ARG; + vrtx = darray_vrtx_id_cdata_get(&desc->frontiers)[iver]; + *vrtx_id = (unsigned)vrtx; /* Back to API type */ + return RES_OK; +} + +res_T senc2d_descriptor_ref_get(struct senc2d_descriptor* desc) { if(!desc) return RES_BAD_ARG; diff --git a/src/senc2d_descriptor_c.h b/src/senc2d_descriptor_c.h @@ -94,6 +94,8 @@ struct senc2d_descriptor { struct darray_enc_ids_array enc_ids_array_by_medium; seg_id_t segment_count; vrtx_id_t vertices_count; + /* Store frontiers */ + struct darray_vrtx_id frontiers; ref_T ref; }; diff --git a/src/senc2d_scene_analyze.c b/src/senc2d_scene_analyze.c @@ -669,6 +669,7 @@ collect_and_link_neighbours struct segside* segsides, struct darray_segment_tmp* segments_tmp_array, struct darray_neighbourhood* neighbourhood_by_vertex, + struct darray_vrtx_id* frontiers, /* Shared error status. * We accept to overwrite an error with a different error */ res_T* res) @@ -686,7 +687,7 @@ collect_and_link_neighbours seg_id_t s; ASSERT(scn && segsides && segments_tmp_array - && neighbourhood_by_vertex && res); + && neighbourhood_by_vertex && frontiers && res); ASSERT((size_t)scn->nuverts + (size_t)scn->nusegs + 2 <= EDGE_MAX__); segments_in = darray_segment_in_cdata_get(&scn->segments_in); @@ -875,12 +876,12 @@ collect_and_link_neighbours * - different media on its sides */ if(neighbour_count == 1 && p_crt_side->medium != p_ccw_side->medium) +#pragma omp critical { log_warn(scn->dev, - "%s: found possible hole involving segment %lu.\n" - " Vertex: %g %g %g\n", - FUNC_NAME, (unsigned long)segments_in[crt_id].global_id, - SPLIT3(vertices[v].vec)); + "%s: found possible frontier involving segment %lu.\n", + FUNC_NAME, (unsigned long)segments_in[crt_id].global_id); + darray_vrtx_id_push_back(frontiers, &v); } } } @@ -892,6 +893,7 @@ build_result (struct senc2d_descriptor* desc, const struct darray_ptr_component_descriptor* connex_components, const struct darray_segment_comp* segments_comp_array, + struct darray_vrtx_id* frontiers, /* Shared error status. * We accept to overwrite an error with a different error */ res_T* res) @@ -910,7 +912,7 @@ build_result int64_t sg; int64_t ee; - ASSERT(desc && connex_components && segments_comp_array && res); + ASSERT(desc && connex_components && segments_comp_array && frontiers && res); alloc = descriptor_get_allocator(desc); scn = desc->scene; @@ -918,7 +920,8 @@ build_result normals_front = (scn->convention & SENC2D_CONVENTION_NORMAL_FRONT) != 0; normals_back = (scn->convention & SENC2D_CONVENTION_NORMAL_BACK) != 0; ASSERT(normals_back != normals_front); - ASSERT(output_normal_in != ((scn->convention & SENC2D_CONVENTION_NORMAL_OUTSIDE) != 0)); + ASSERT(output_normal_in != + ((scn->convention & SENC2D_CONVENTION_NORMAL_OUTSIDE) != 0)); ASSERT(darray_ptr_component_descriptor_size_get(connex_components) <= COMPONENT_MAX__); cc_descriptors = darray_ptr_component_descriptor_cdata_get(connex_components); @@ -1083,6 +1086,10 @@ build_result *res = tmp_res; } /* No barrier here */ htable_vrtx_id_release(&vtable); + /* The first thread here copies frontiers into descriptor */ +#pragma omp single nowait + darray_vrtx_id_copy_and_clear(&desc->frontiers, frontiers); + /* No barrier here */ } /******************************************************************************* @@ -1101,6 +1108,9 @@ senc2d_scene_analyze * They are refered to by arrays of ids. */ struct darray_ptr_component_descriptor connex_components; char connex_components_initialized = 0; + /* Array of frontiers vertices */ + struct darray_vrtx_id frontiers; + char frontiers_initialized = 0; /* Store by-segment components */ struct darray_segment_comp segments_comp; char segments_comp_initialized = 0; @@ -1129,6 +1139,8 @@ senc2d_scene_analyze darray_segment_tmp_init(scn->dev->allocator, &segments_tmp); segments_tmp_initialized = 1; + darray_vrtx_id_init(scn->dev->allocator, &frontiers); + frontiers_initialized = 1; OK(darray_segment_tmp_resize(&segments_tmp, scn->nusegs)); segsides @@ -1160,7 +1172,7 @@ senc2d_scene_analyze { /* Step 1: build neighbourhoods */ collect_and_link_neighbours(scn, segsides, &segments_tmp, - &neighbourhood_by_vertex, &res); + &neighbourhood_by_vertex, &frontiers, &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 */ @@ -1257,7 +1269,8 @@ senc2d_scene_analyze } /* No barrier here */ /* Step 4: Build result */ - build_result(desc, &connex_components, &segments_comp, &res); + build_result(desc, &connex_components, &segments_comp, &frontiers, + &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 */ @@ -1300,6 +1313,7 @@ exit: darray_neighbourhood_release(&neighbourhood_by_vertex); 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); if(segsides) MEM_RM(scn->dev->allocator, segsides); if(desc) *out_desc = desc; diff --git a/src/test_senc2d_descriptor.c b/src/test_senc2d_descriptor.c @@ -157,10 +157,10 @@ main(int argc, char** argv) CHK(senc2d_descriptor_get_global_segment_media(desc, 0, media) == RES_OK); CHK(media[0] == ctx.front_media[0] && media[1] == ctx.back_media[1]); - CHK(senc2d_descriptor_get_global_segment_enclosures( - NULL, 0, enclosures) == RES_BAD_ARG); - CHK(senc2d_descriptor_get_global_segment_enclosures( - NULL, nvertices, enclosures) == RES_BAD_ARG); + CHK(senc2d_descriptor_get_global_segment_enclosures(NULL, 0, enclosures) + == RES_BAD_ARG); + CHK(senc2d_descriptor_get_global_segment_enclosures(NULL, nvertices, enclosures) + == RES_BAD_ARG); CHK(senc2d_descriptor_get_global_segment_enclosures(desc, 0, NULL) == RES_BAD_ARG); CHK(senc2d_descriptor_get_global_segment_enclosures(desc, 0, enclosures) @@ -191,10 +191,50 @@ main(int argc, char** argv) nvertices, get_position, &ctx) == RES_BAD_ARG); CHK(senc2d_scene_ref_put(scn) == RES_OK); - CHK(senc2d_device_ref_put(dev) == RES_OK); if(desc) CHK(senc2d_descriptor_ref_put(desc) == RES_OK); + desc = NULL; CHK(senc2d_enclosure_ref_put(enc) == RES_OK); + /* Same square with a hole (last segment is missing) */ + CHK(senc2d_scene_create(dev, + SENC2D_CONVENTION_NORMAL_FRONT | SENC2D_CONVENTION_NORMAL_INSIDE, &scn) + == RES_OK); + + CHK(senc2d_scene_add_geometry(scn, nsegments - 1, get_indices, get_media, + NULL, nvertices, get_position, &ctx) == RES_OK); + + CHK(senc2d_scene_analyze(scn, &desc) == RES_OK); + + CHK(senc2d_descriptor_get_frontier_vertices_count(NULL, NULL) + == RES_BAD_ARG); + CHK(senc2d_descriptor_get_frontier_vertices_count(desc, NULL) + == RES_BAD_ARG); + CHK(senc2d_descriptor_get_frontier_vertices_count(NULL, &count) + == RES_BAD_ARG); + CHK(senc2d_descriptor_get_frontier_vertices_count(desc, &count) + == RES_OK); + + CHK(senc2d_descriptor_get_frontier_vertex(NULL, count, NULL) + == RES_BAD_ARG); + CHK(senc2d_descriptor_get_frontier_vertex(desc, count, NULL) + == RES_BAD_ARG); + CHK(senc2d_descriptor_get_frontier_vertex(NULL, 0, NULL) + == RES_BAD_ARG); + CHK(senc2d_descriptor_get_frontier_vertex(NULL, count, indices) + == RES_BAD_ARG); + CHK(senc2d_descriptor_get_frontier_vertex(desc, 0, NULL) + == RES_BAD_ARG); + CHK(senc2d_descriptor_get_frontier_vertex(desc, count, indices) + == RES_BAD_ARG); + CHK(senc2d_descriptor_get_frontier_vertex(NULL, 0, indices) + == RES_BAD_ARG); + CHK(senc2d_descriptor_get_frontier_vertex(desc, 0, indices) + == RES_OK); + + CHK(senc2d_scene_ref_put(scn) == RES_OK); + CHK(senc2d_device_ref_put(dev) == RES_OK); + if(desc) CHK(senc2d_descriptor_ref_put(desc) == RES_OK); + check_memory_allocator(&allocator); mem_shutdown_proxy_allocator(&allocator); CHK(mem_allocated_size() == 0);