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 7f866ca1f88fc69afd8c762464f89b3165359e81
parent 6d755b60eb576f85d9bf0a84d2527b74c60fa209
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Fri,  8 Nov 2019 14:59:43 +0100

Fix global id of triangles; reintroduce dedicated API

Diffstat:
Msrc/senc.h | 11++++++++++-
Msrc/senc_descriptor.c | 15+++++++++++++++
Msrc/senc_scene.c | 16++++++++++------
Msrc/senc_scene_analyze.c | 9+++++----
Msrc/senc_scene_c.h | 3+++
Msrc/test_senc_descriptor.c | 14++++++++++++--
Msrc/test_senc_enclosure.c | 2+-
Msrc/test_senc_scene.c | 20++++++++++++++++++++
8 files changed, 76 insertions(+), 14 deletions(-)

diff --git a/src/senc.h b/src/senc.h @@ -178,7 +178,8 @@ senc_scene_reserve * of SENC_UNDEFINED_MEDIUM that causes no error) and are deduplicated. * The special value SENC_UNDEFINED_MEDIUM denotes an undefined medium. * It can be used to define the 2 sides of a triangle at different times. - * When deduplicating triangles, the first occurence remains. + * When deduplicating triangles, the first occurence remains (with its + * original index in user world, regardless of deduplication). * The add_triangle and merge_triangle callbacks can be used for attributes * management including triangle IDs; they allow the client app to store * its own data. They can also fail and stop the add_geometry call. */ @@ -374,6 +375,14 @@ senc_descriptor_get_global_triangle_enclosures const unsigned itri, unsigned enclosures[2]); +/* Returns the global id of the itri_th global unique triangle, that is the + * triangle index in user world regardless of deduplication. */ +SENC_API res_T +senc_descriptor_get_global_triangle_global_id + (const struct senc_descriptor* descriptor, + const unsigned itri, + unsigned* gid); + /* Returns the number of segments that are frontier segments: * - that have arity 1 (single triangle using the segment) * - that connect 2 different media */ diff --git a/src/senc_descriptor.c b/src/senc_descriptor.c @@ -272,6 +272,21 @@ senc_descriptor_get_global_triangle_enclosures } res_T +senc_descriptor_get_global_triangle_global_id + (const struct senc_descriptor* desc, + const unsigned itri, + unsigned* gid) +{ + const struct triangle_in* trg; + if(!gid || !desc + || itri >= darray_triangle_in_size_get(&desc->scene->triangles_in)) + return RES_BAD_ARG; + trg = darray_triangle_in_cdata_get(&desc->scene->triangles_in) + itri; + *gid = trg->global_id; + return RES_OK; +} + +res_T senc_descriptor_get_frontier_segments_count (const struct senc_descriptor* desc, unsigned* count) diff --git a/src/senc_scene.c b/src/senc_scene.c @@ -200,6 +200,8 @@ senc_scene_add_geometry struct triangle_in tmp, *range_adjust_ptr = NULL; trg_id_t* p_trg; char reversed; + /* Triangle index in user world regardless of deduplication. */ + tmp.global_id = (unsigned)(scn->ntris + i); indices(i, ind, ctx); /* API: indices need unsigneds */ FOR_EACH(j, 0, 3) { if(ind[j] >= nverts) { @@ -216,7 +218,7 @@ senc_scene_add_geometry const union double3* positions = darray_position_cdata_get(&scn->vertices); log_err(scn->dev, "%s: triangle %lu is degenerate.\n", - FUNC_NAME, (unsigned long)(scn->ntris + i)); + FUNC_NAME, (unsigned long)tmp.global_id); log_err(scn->dev, " (%g %g %g)\n (%g %g %g)\n (%g %g %g)\n", SPLIT3(positions[trg[i].vertice_id[0]].vec), SPLIT3(positions[trg[i].vertice_id[1]].vec), @@ -254,10 +256,11 @@ senc_scene_add_geometry = darray_position_cdata_get(&scn->vertices); log_err(scn->dev, "%s: triangle %lu is a duplicate" " of triangle %lu with incoherent media.\n", - FUNC_NAME, (unsigned long)(scn->ntris + i), (unsigned long)*p_trg); + FUNC_NAME, (unsigned long)tmp.global_id, + (unsigned long)trg[*p_trg].global_id); log_err(scn->dev, "Triangle %lu:\n (%g %g %g)\n (%g %g %g)\n (%g %g %g)\n", - (unsigned long)*p_trg, + (unsigned long)trg[*p_trg].global_id, SPLIT3(positions[trg[*p_trg].vertice_id[0]].vec), SPLIT3(positions[trg[*p_trg].vertice_id[1]].vec), SPLIT3(positions[trg[*p_trg].vertice_id[2]].vec)); @@ -280,11 +283,12 @@ senc_scene_add_geometry } } if(merge_triangle) { - OK(merge_triangle((unsigned)*p_trg, i, same, ctx)); + OK(merge_triangle(trg[*p_trg].global_id, i, same, ctx)); } else { log_warn(scn->dev, "%s: triangle %lu is a duplicate of triangle %lu.\n", - FUNC_NAME, (unsigned long)(scn->ntris + i), (unsigned long)*p_trg); + FUNC_NAME, (unsigned long)tmp.global_id, + (unsigned long)trg[*p_trg].global_id); } } } else { @@ -299,7 +303,7 @@ senc_scene_add_geometry scn->sides_with_defined_medium_count++; } if(add_triangle) { - OK(add_triangle((unsigned)u, i, ctx)); + OK(add_triangle(tmp.global_id, i, ctx)); } ++actual_nutris; } diff --git a/src/senc_scene_analyze.c b/src/senc_scene_analyze.c @@ -913,7 +913,8 @@ collect_and_link_neighbours prev_id = previous->trg_id; log_err(scn->dev, "%s: found 2 overlying triangles (%lu & %lu).\n", FUNC_NAME, - (unsigned long)crt_id, (unsigned long)prev_id); + (unsigned long)triangles_in[crt_id].global_id, + (unsigned long)triangles_in[prev_id].global_id); tmp_res = RES_BAD_OP; goto tmp_error; } @@ -944,7 +945,7 @@ collect_and_link_neighbours struct trg_edge disc; log_warn(scn->dev, "%s: found frontier involving triangle %lu.\n", - FUNC_NAME, (unsigned long)crt_id); + FUNC_NAME, (unsigned long)triangles_in[crt_id].global_id); disc.vrtx0 = v0; disc.vrtx1 = v1; darray_frontier_edge_push_back(frontiers, &disc); @@ -1132,7 +1133,7 @@ build_result int ii = revert_triangle ? 2 - i : i; side_enc->vertice_id[i] = vertice_id[ii]; } - side_enc->side_id = TRGIDxSIDE_2_TRGSIDE(t, SENC_FRONT); + side_enc->side_id = TRGIDxSIDE_2_TRGSIDE(trg_in->global_id, SENC_FRONT); } if(triangles_enc[t].enclosure[SENC_BACK] == e) { /* Back side of the original triangle is member of the enclosure */ @@ -1146,7 +1147,7 @@ build_result int ii = revert_triangle ? 2 - i : i; side_enc->vertice_id[i] = vertice_id[ii]; } - side_enc->side_id = TRGIDxSIDE_2_TRGSIDE(t, SENC_BACK); + side_enc->side_id = TRGIDxSIDE_2_TRGSIDE(trg_in->global_id, SENC_BACK); } if(fst_idx == sgd_idx) break; } diff --git a/src/senc_scene_c.h b/src/senc_scene_c.h @@ -48,6 +48,8 @@ struct triangle_in { vrtx_id_t vertice_id[3]; /* Ids of this triangle's media */ medium_id_t medium[2]; + /* Triangle index in user world regardless of deduplication. */ + unsigned global_id; }; static FINLINE void @@ -57,6 +59,7 @@ triangle_in_init(struct mem_allocator* alloc, struct triangle_in* trg) { ASSERT(trg); FOR_EACH(i, 0, 3) trg->vertice_id[i] = VRTX_NULL__; FOR_EACH(i, 0, 2) trg->medium[i] = SENC_UNDEFINED_MEDIUM; + trg->global_id = 0; } #define DARRAY_NAME triangle_in diff --git a/src/test_senc_descriptor.c b/src/test_senc_descriptor.c @@ -161,8 +161,18 @@ main(int argc, char** argv) == RES_BAD_ARG); CHK(senc_descriptor_get_global_triangle_enclosures(desc, 0, enclosures) == RES_OK); - CHK(enclosures[0] == 0 - && enclosures[1] == 1); + CHK(enclosures[0] == 0 && enclosures[1] == 1); + + CHK(senc_descriptor_get_global_triangle_global_id(NULL, 0, indices) + == RES_BAD_ARG); + CHK(senc_descriptor_get_global_triangle_global_id(NULL, nvertices, indices) + == RES_BAD_ARG); + CHK(senc_descriptor_get_global_triangle_global_id(desc, 0, NULL) + == RES_BAD_ARG); + CHK(senc_descriptor_get_global_triangle_global_id(desc, 0, indices) + == RES_OK); + /* No duplicates: user id is unique vertex id */ + CHK(indices[0] == 0); /* Add valid duplicate geometry */ CHK(senc_descriptor_ref_put(desc) == RES_OK); diff --git a/src/test_senc_enclosure.c b/src/test_senc_enclosure.c @@ -249,7 +249,7 @@ test(const int convention) CHK(senc_enclosure_get_triangle_global_id(enclosure, t, &gid, &side) == RES_OK); /* The first unique_triangle_count triangles of an enclosure * are unique triangles */ - if (t < header.unique_triangle_count) CHK(gid == t); + if(t < header.unique_triangle_count) CHK(gid == t); CHK(side == (t < header.unique_triangle_count) ? SENC_FRONT : SENC_BACK); } diff --git a/src/test_senc_scene.c b/src/test_senc_scene.c @@ -173,6 +173,9 @@ main(int argc, char** argv) SENC_CONVENTION_NORMAL_BACK | SENC_CONVENTION_NORMAL_INSIDE, &scn) == RES_OK); CHK(senc_scene_get_convention(scn, &convention) == RES_OK); CHK(convention == (SENC_CONVENTION_NORMAL_BACK | SENC_CONVENTION_NORMAL_INSIDE)); + /* Add the first triangle twice to create a shift in numbering */ + CHK(senc_scene_add_geometry(scn, 1, get_indices, get_media, + nvertices, get_position, NULL, NULL, &ctx) == RES_OK); CHK(senc_scene_add_geometry(scn, ntriangles, get_indices, get_media, nvertices, get_position, NULL, NULL, &ctx) == RES_OK); CHK(senc_scene_analyze(scn, &desc) == RES_OK); @@ -182,6 +185,13 @@ main(int argc, char** argv) CHK(!header.is_infinite); CHK(senc_enclosure_ref_put(enc) == RES_OK); + FOR_EACH(i, 0, ntriangles) { + unsigned gid; + CHK(senc_descriptor_get_global_triangle_global_id(desc, i, &gid) == RES_OK); + /* Check numbering shift */ + CHK(gid == (i ? i + 1 : 0)); + } + CHK(senc_descriptor_get_global_triangle_media(desc, 0, medback) == RES_OK); ctx.front_media = medium1_3; CHK(senc_scene_ref_put(scn) == RES_OK); @@ -210,6 +220,9 @@ main(int argc, char** argv) CHK(senc_descriptor_ref_put(desc) == RES_OK); CHK(senc_scene_create(dev, SENC_CONVENTION_NORMAL_FRONT | SENC_CONVENTION_NORMAL_INSIDE, &scn) == RES_OK); + /* Add the first triangle twice to create a shift in numbering */ + CHK(senc_scene_add_geometry(scn, 1, get_indices, get_media, + nvertices, get_position, NULL, NULL, &ctx) == RES_OK); CHK(senc_scene_add_geometry(scn, ntriangles, get_indices, get_media, nvertices, get_position, NULL, NULL, &ctx) == RES_OK); CHK(senc_scene_analyze(scn, &desc) == RES_OK); @@ -219,6 +232,13 @@ main(int argc, char** argv) CHK(header.is_infinite); CHK(senc_enclosure_ref_put(enc) == RES_OK); + FOR_EACH(i, 0, ntriangles) { + unsigned gid; + CHK(senc_descriptor_get_global_triangle_global_id(desc, i, &gid) == RES_OK); + /* Check numbering shift */ + CHK(gid == (i ? i + 1 : 0)); + } + CHK(senc_descriptor_get_global_triangle_media(desc, 0, medfront) == RES_OK); FOR_EACH(i, 0, 2) CHK(medback[i] == medfront[i]);