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 5f4b093037035e05e34e67641183a6c1d8560e14
parent f92bdf0c35353861377ff6209c2f93fe7e325402
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Thu, 31 Oct 2019 14:48:39 +0100

Add API calls to access scene geometry without prior analyze

Diffstat:
Msrc/senc2d.h | 26++++++++++++++++++++++++++
Msrc/senc2d_scene.c | 64+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
Msrc/senc2d_scene_analyze.c | 6+++---
Msrc/senc2d_scene_analyze_c.h | 2+-
Msrc/test_senc2d_inconsistant_square.c | 2+-
Msrc/test_senc2d_scene.c | 33++++++++++++++++++++++++++++++++-
Msrc/test_senc2d_utils.h | 2+-
7 files changed, 125 insertions(+), 10 deletions(-)

diff --git a/src/senc2d.h b/src/senc2d.h @@ -208,6 +208,24 @@ senc2d_scene_get_unique_segments_count (const struct senc2d_scene* scene, unsigned* count); +/* Returns the iseg_th unique segment; the returned indices are + * unique vertex indices. + * Can be called anytime, before or after a call to analyze. */ +SENC2D_API res_T +senc2d_scene_get_unique_segment + (const struct senc2d_scene* scene, + const unsigned iseg, + unsigned indices[2]); + +/* Returns the iseg_th unique segment; the returned indices are + * unique vertex indices. + * Can be called anytime, before or after a call to analyze. */ +SENC2D_API res_T +senc2d_scene_get_unique_segment_media + (const struct senc2d_scene* scene, + const unsigned iseg, + unsigned media[2]); + /* Returns the number of vertices in the scene. */ SENC2D_API res_T senc2d_scene_get_vertices_count @@ -221,6 +239,14 @@ senc2d_scene_get_unique_vertices_count (const struct senc2d_scene* scene, unsigned* count); +/* Returns the coordinates of the ivert_th unique vertex. + * Can be called anytime, before or after a call to analyze. */ +SENC2D_API res_T +senc2d_scene_get_unique_vertex + (const struct senc2d_scene* scene, + const unsigned ivert, + double coord[2]); + SENC2D_API res_T senc2d_scene_ref_get (struct senc2d_scene* scene); diff --git a/src/senc2d_scene.c b/src/senc2d_scene.c @@ -18,6 +18,7 @@ #include "senc2d_scene_c.h" #include <rsys/rsys.h> +#include <rsys/double2.h> #include <rsys/mem_allocator.h> #include <limits.h> @@ -107,16 +108,16 @@ res_T senc2d_scene_reserve (struct senc2d_scene* scn, const unsigned vertices_count, - const unsigned triangles_count, + const unsigned segments_count, const unsigned media_count) { res_T res = RES_OK; if(!scn) return RES_BAD_ARG; OK(darray_position_reserve(&scn->vertices, vertices_count)); - OK(darray_segment_in_reserve(&scn->segments_in, triangles_count)); + OK(darray_segment_in_reserve(&scn->segments_in, segments_count)); OK(htable_vrtx_reserve(&scn->unique_vertices, vertices_count)); - OK(htable_seg_reserve(&scn->unique_segments, triangles_count)); + OK(htable_seg_reserve(&scn->unique_segments, segments_count)); OK(darray_side_range_reserve(&scn->media_use, media_count)); end: @@ -363,6 +364,46 @@ senc2d_scene_get_unique_segments_count } res_T +senc2d_scene_get_unique_segment + (const struct senc2d_scene* scn, + const unsigned iseg, + unsigned indices[2]) +{ + const struct segment_in* seg; + int i; + if(!scn || !indices + || iseg >= darray_segment_in_size_get(&scn->segments_in)) + return RES_BAD_ARG; + seg = darray_segment_in_cdata_get(&scn->segments_in) + iseg; + + FOR_EACH(i, 0, 2) { + ASSERT(seg->vertice_id[i] < UINT_MAX); + indices[i] = (unsigned)seg->vertice_id[i]; /* Back to API type */ + } + return RES_OK; +} + +res_T +senc2d_scene_get_unique_segment_media + (const struct senc2d_scene* scn, + const unsigned iseg, + unsigned media[2]) +{ + const struct segment_in* seg; + int i; + if(!scn || !media + || iseg >= darray_segment_in_size_get(&scn->segments_in)) + return RES_BAD_ARG; + seg = darray_segment_in_cdata_get(&scn->segments_in) + iseg; + + FOR_EACH(i, 0, 2) { + ASSERT(seg->vertice_id[i] < UINT_MAX); + media[i] = (unsigned)seg->medium[i]; /* Back to API type */ + } + return RES_OK; +} + +res_T senc2d_scene_get_vertices_count (const struct senc2d_scene* scn, unsigned* count) @@ -383,6 +424,23 @@ senc2d_scene_get_unique_vertices_count } res_T +senc2d_scene_get_unique_vertex + (const struct senc2d_scene* scn, + const unsigned ivert, + double coord[2]) +{ + + const union double2* v; + if(!scn || !coord + || ivert >= darray_position_size_get(&scn->vertices)) + return RES_BAD_ARG; + + v = darray_position_cdata_get(&scn->vertices) + ivert; + d2_set(coord, v->vec); + return RES_OK; +} + +res_T senc2d_scene_ref_get(struct senc2d_scene* scn) { if(!scn) return RES_BAD_ARG; diff --git a/src/senc2d_scene_analyze.c b/src/senc2d_scene_analyze.c @@ -493,7 +493,7 @@ canceled: OK(s2d_scene_create(s2d, &s2d_scn)); OK(s2d_shape_create_line_segments(s2d, &s2d_shp)); - /* Back to API type for ntris and nverts */ + /* Back to API type for nsegs and nverts */ ASSERT(desc->scene->nusegs < UINT_MAX); ASSERT(desc->scene->nuverts < UINT_MAX); OK(s2d_line_segments_setup_indexed_vertices(s2d_shp, @@ -1058,7 +1058,7 @@ build_result ASSERT(segments_enc[s].enclosure[SIDE_FRONT] == e || segments_enc[s].enclosure[SIDE_BACK] == e); if(segments_enc[s].enclosure[SIDE_FRONT] == e) { - /* Front side of the original triangle is member of the enclosure */ + /* Front side of the original segment is member of the enclosure */ int input_normal_in = normals_front; int revert_segment = (input_normal_in != output_normal_in); ++enc->header.segment_count; @@ -1074,7 +1074,7 @@ build_result } } if(segments_enc[s].enclosure[SIDE_BACK] == e) { - /* Back side of the original triangle is member of the enclosure */ + /* Back side of the original segment is member of the enclosure */ int input_normal_in = normals_back; int revert_segment = (input_normal_in != output_normal_in); ++enc->header.segment_count; diff --git a/src/senc2d_scene_analyze_c.h b/src/senc2d_scene_analyze_c.h @@ -42,7 +42,7 @@ init_segside(struct mem_allocator* alloc, struct segside* data) { int i; ASSERT(data); (void)alloc; - FOR_EACH(i, 0, 3) data->facing_side_id[i] = SIDE_NULL__; + FOR_EACH(i, 0, 2) data->facing_side_id[i] = SIDE_NULL__; data->medium = MEDIUM_NULL__; } diff --git a/src/test_senc2d_inconsistant_square.c b/src/test_senc2d_inconsistant_square.c @@ -105,7 +105,7 @@ test(enum senc2d_convention convention) expected_medium = (header.is_infinite ? expected_external_medium : !expected_external_medium); CHK(medium == expected_medium); - /* Common media, for non input triangles */ + /* Common media, for non input segments */ front_inside = (conv_front == conv_in); expected_side = front_inside ? 0 : 1; diff --git a/src/test_senc2d_scene.c b/src/test_senc2d_scene.c @@ -29,7 +29,8 @@ main(int argc, char** argv) struct senc2d_enclosure* enc = NULL; struct senc2d_enclosure_header header; struct context ctx; - unsigned medfront[2], medback[2]; + unsigned medfront[2], medback[2], ind[2]; + double vrtx[2]; unsigned count, i, maxm; enum senc2d_convention convention; (void)argc, (void)argv; @@ -55,6 +56,9 @@ main(int argc, char** argv) SENC2D_CONVENTION_NORMAL_FRONT | SENC2D_CONVENTION_NORMAL_INSIDE, &scn) == RES_OK); + CHK(senc2d_scene_reserve(NULL, 0, 0, 0) == RES_BAD_ARG); + CHK(senc2d_scene_reserve(scn, 0, 0, 0) == RES_OK); + CHK(senc2d_scene_get_convention(NULL, &convention) == RES_BAD_ARG); CHK(senc2d_scene_get_convention(scn, NULL) == RES_BAD_ARG); CHK(senc2d_scene_get_convention(NULL, NULL) == RES_BAD_ARG); @@ -123,6 +127,33 @@ main(int argc, char** argv) CHK(senc2d_scene_get_unique_vertices_count(scn, &count) == RES_OK); CHK(count == nvertices); + CHK(senc2d_scene_get_unique_segment(NULL, 0, ind) == RES_BAD_ARG); + CHK(senc2d_scene_get_unique_segment(scn, UINT_MAX, ind) == RES_BAD_ARG); + CHK(senc2d_scene_get_unique_segment(scn, 0, NULL) == RES_BAD_ARG); + CHK(senc2d_scene_get_unique_segment(NULL, UINT_MAX, ind) == RES_BAD_ARG); + CHK(senc2d_scene_get_unique_segment(NULL, 0, NULL) == RES_BAD_ARG); + CHK(senc2d_scene_get_unique_segment(scn, UINT_MAX, NULL) == RES_BAD_ARG); + CHK(senc2d_scene_get_unique_segment(NULL, UINT_MAX, NULL) == RES_BAD_ARG); + CHK(senc2d_scene_get_unique_segment(scn, 0, ind) == RES_OK); + + CHK(senc2d_scene_get_unique_segment_media(NULL, 0, ind) == RES_BAD_ARG); + CHK(senc2d_scene_get_unique_segment_media(scn, UINT_MAX, ind) == RES_BAD_ARG); + CHK(senc2d_scene_get_unique_segment_media(scn, 0, NULL) == RES_BAD_ARG); + CHK(senc2d_scene_get_unique_segment_media(NULL, UINT_MAX, ind) == RES_BAD_ARG); + CHK(senc2d_scene_get_unique_segment_media(NULL, 0, NULL) == RES_BAD_ARG); + CHK(senc2d_scene_get_unique_segment_media(scn, UINT_MAX, NULL) == RES_BAD_ARG); + CHK(senc2d_scene_get_unique_segment_media(NULL, UINT_MAX, NULL) == RES_BAD_ARG); + CHK(senc2d_scene_get_unique_segment_media(scn, 0, ind) == RES_OK); + + CHK(senc2d_scene_get_unique_vertex(NULL, 0, vrtx) == RES_BAD_ARG); + CHK(senc2d_scene_get_unique_vertex(scn, UINT_MAX, vrtx) == RES_BAD_ARG); + CHK(senc2d_scene_get_unique_vertex(scn, 0, NULL) == RES_BAD_ARG); + CHK(senc2d_scene_get_unique_vertex(NULL, UINT_MAX, vrtx) == RES_BAD_ARG); + CHK(senc2d_scene_get_unique_vertex(NULL, 0, NULL) == RES_BAD_ARG); + CHK(senc2d_scene_get_unique_vertex(scn, UINT_MAX, NULL) == RES_BAD_ARG); + CHK(senc2d_scene_get_unique_vertex(NULL, UINT_MAX, NULL) == RES_BAD_ARG); + CHK(senc2d_scene_get_unique_vertex(scn, 0, vrtx) == RES_OK); + CHK(senc2d_scene_analyze(NULL, NULL) == RES_BAD_ARG); CHK(senc2d_scene_analyze(scn, NULL) == RES_BAD_ARG); CHK(senc2d_scene_analyze(NULL, &desc) == RES_BAD_ARG); diff --git a/src/test_senc2d_utils.h b/src/test_senc2d_utils.h @@ -278,7 +278,7 @@ static INLINE void check_desc(struct senc2d_descriptor* desc) ASSERT(e_cpt >= ecount); /* Every enc has been visited at least once */ } -/* Compare the itri-th segment of enclosure with a segment described by seg2 & vertices2 */ +/* Compare the iseg-th segment of enclosure with a segment described by seg2 & vertices2 */ static INLINE void cmp_seg (const unsigned iseg,