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 f8251cd039c94ebddbab1fe78d615476337ce546
parent fbf6bbb57d066d51279b9d1ff5c17e127d3ece8b
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Mon, 19 Feb 2018 18:49:32 +0100

Add a global id to triangles and the dedicated API.

Use it to improve/fix logs when deduplication occurs.

Diffstat:
Msrc/senc.h | 18+++++++++++++++++-
Msrc/senc_descriptor.c | 15+++++++++++++++
Msrc/senc_enclosure.c | 17+++++++++++++++++
Msrc/senc_scene.c | 33++++++++++++++++++++++++---------
Msrc/senc_scene_analyze.c | 43+++++++++++++++++++++----------------------
Msrc/senc_scene_c.h | 3+++
Msrc/test_senc_cube_behind_cube.c | 6+++---
Msrc/test_senc_cube_in_cube.c | 6+++---
Msrc/test_senc_cube_on_cube.c | 6+++---
Msrc/test_senc_descriptor.c | 6+++---
Msrc/test_senc_enclosure.c | 70++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
Msrc/test_senc_many_triangles.c | 16++++++++++------
Msrc/test_senc_sample_enclosure.c | 7++++---
Msrc/test_senc_scene.c | 59++++++++++++++++++++++++++++++++++++++++++++---------------
Msrc/test_senc_utils.h | 17+++++++++++++++--
15 files changed, 248 insertions(+), 74 deletions(-)

diff --git a/src/senc.h b/src/senc.h @@ -108,13 +108,17 @@ senc_scene_create /* Add a new set of vertices and triangles to the scene. * Vertices can be duplicates and are deduplicated on the fly. * Triangles can be duplicates as long as they constantly define the same - * medium on both sides (or an error will be reported) and are deduplicated. */ + * medium on both sides (or an error will be reported) and are deduplicated. + * When deduplicating triangles, the first occurence is kept (with it original + * global_id). */ SENC_API res_T senc_scene_add_geometry (struct senc_scene* scene, const unsigned triangles_count, void(*indices)(const unsigned itri, unsigned ids[3], void* context), void(*media)(const unsigned itri, unsigned med[2], void* context), + void(*global_id) /* May be NULL <=> use triangle rank */ + (const unsigned itri, unsigned* gid, void* context), const unsigned vertices_count, void(*position)(const unsigned ivert, double pos[3], void* context), void* context); @@ -201,6 +205,12 @@ senc_descriptor_get_global_triangle_enclosures unsigned enclosures[2]); SENC_API res_T +senc_descriptor_get_global_triangle_global_id + (const struct senc_descriptor* descriptor, + const unsigned itri, + unsigned* gid); + +SENC_API res_T senc_descriptor_ref_get (struct senc_descriptor* descriptor); @@ -243,6 +253,12 @@ senc_enclosure_get_triangle_media unsigned medium[2]); SENC_API res_T +senc_enclosure_get_triangle_global_id + (const struct senc_enclosure* enclosure, + const unsigned itri, + unsigned* gid); + +SENC_API res_T senc_enclosure_ref_get (struct senc_enclosure* enclosure); diff --git a/src/senc_descriptor.c b/src/senc_descriptor.c @@ -201,6 +201,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_ref_get(struct senc_descriptor* desc) { if(!desc) return RES_BAD_ARG; diff --git a/src/senc_enclosure.c b/src/senc_enclosure.c @@ -133,6 +133,23 @@ senc_enclosure_get_triangle_media } res_T +senc_enclosure_get_triangle_global_id + (const struct senc_enclosure* enclosure, + const unsigned itri, + unsigned* gid) +{ + const struct triangle_in* triangle; + if(!enclosure || !gid + || itri >= enclosure->data->header.triangle_count) + return RES_BAD_ARG; + ASSERT(darray_triangle_in_size_get(&enclosure->data->sides) + == enclosure->data->header.triangle_count); + triangle = darray_triangle_in_cdata_get(&enclosure->data->sides) + itri; + *gid = triangle->global_id; + return RES_OK; +} + +res_T senc_enclosure_ref_get(struct senc_enclosure* enc) { if(!enc) return RES_BAD_ARG; diff --git a/src/senc_scene.c b/src/senc_scene.c @@ -93,6 +93,7 @@ senc_scene_add_geometry const unsigned ntris, void(*indices)(const unsigned itri, unsigned ids[3], void* ctx), void(*media)(const unsigned itri, unsigned med[2], void* ctx), + void(*global_id)(const unsigned itri, unsigned* gid, void* context), const unsigned nverts, void(*position)(const unsigned ivert, double pos[3], void* ctx), void* ctx) @@ -132,6 +133,10 @@ senc_scene_add_geometry p_vrtx = htable_vrtx_find(&scn->unique_vertices, &tmp); if(p_vrtx) { /* Duplicate vertex */ + log_warn(scn->dev, "%s: vertex %lu is a duplicate of unique vertex %lu.\n", + FUNC_NAME, (unsigned long)(scn->nverts + i), (unsigned long)*p_vrtx); + log_warn(scn->dev, "%s: vertex %lu: (%g %g %g).\n", + FUNC_NAME, (unsigned long)(scn->nverts + i), SPLIT3(tmp.vec)); unique_v = *p_vrtx; } else { /* New vertex */ @@ -155,8 +160,12 @@ senc_scene_add_geometry union vrtx_id3 trg_key; struct triangle_in tmp; trg_id_t* p_trg; - trg_id_t tr; char reversed; + if(global_id) { + global_id(i, &tmp.global_id, ctx); + } else { + tmp.global_id = (unsigned)(scn->ntris + i); + } indices(i, ind, ctx); /* API: indices needs an unsigned */ FOR_EACH(j, 0, 3) { if(ind[j] >= nverts) { @@ -172,8 +181,8 @@ senc_scene_add_geometry || tmp.vertice_id[1] == tmp.vertice_id[2]) { const union double3* positions = darray_position_cdata_get(&scn->vertices); - log_err(scn->dev, "%s: triangle %lu is degenerate.\n", - FUNC_NAME, (unsigned long)i); + log_err(scn->dev, "%s: triangle %u is degenerate.\n", + 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), @@ -189,7 +198,7 @@ senc_scene_add_geometry log_err(scn->dev, "%s: triangle %lu %s side references invalid medium: %lu.\n", FUNC_NAME, - (unsigned long)i, + (unsigned long)tmp.global_id, (j ? "back" : "front"), (unsigned long)med[j]); res = RES_BAD_ARG; @@ -213,10 +222,13 @@ senc_scene_add_geometry /* Same triangles with different media: invalid! */ const union double3* positions = darray_position_cdata_get(&scn->vertices); - log_err(scn->dev, "%s: triangle %lu is a duplicate with incoherent media.\n", - FUNC_NAME, (unsigned long)*p_trg); - log_err(scn->dev, "Triangle %lu:\n (%g %g %g)\n (%g %g %g)\n (%g %g %g)\n", - (unsigned long)*p_trg, + log_err(scn->dev, "%s: triangle %lu is a duplicate" + " of triangle %lu with incoherent media.\n", + 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)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)); @@ -226,6 +238,10 @@ senc_scene_add_geometry res = RES_BAD_ARG; goto error; } else { + /* Legit duplicate */ + log_warn(scn->dev, "%s: triangle %lu is a duplicate of triangle %lu.\n", + FUNC_NAME, (unsigned long)tmp.global_id, + (unsigned long)trg[*p_trg].global_id); if(!same) { FOR_EACH(j, 0, 2) { tmp.medium[j] = (medium_id_t) med[1-j]; @@ -241,7 +257,6 @@ senc_scene_add_geometry OK(darray_triangle_in_push_back(&scn->triangles_in, &tmp)); ++actual_nutris; } - tr = scn->nutris + i; ++actual_ntris; } diff --git a/src/senc_scene_analyze.c b/src/senc_scene_analyze.c @@ -374,33 +374,33 @@ extract_connex_components /* Store neighbour sides in a waiting stack */ FOR_EACH(i, 0, 3) { side_id_t neighbour_id = crt_side->facing_side_id[i]; + trg_id_t nbour_trg_id = TRGSIDE_2_TRG(neighbour_id); struct trgside* neighbour = trgsides + neighbour_id; if(neighbour->medium != crt_side->medium) { - /* Found medium discontinuity! - * Model topology is broken. */ + /* Found medium discontinuity! Model topology is broken. */ const struct triangle_in* triangles_in = darray_triangle_in_cdata_get(&scn->triangles_in); const union double3* positions = darray_position_cdata_get(&scn->vertices); log_err(scn->dev, - "Medium mismatch found between triangle %lu %s" - " side and triangle %u %s side.\n", - (unsigned long)crt_trg_id, + "Medium mismatch found between neighbour triangles %lu %s" + " side and %u %s side.\n", + (unsigned long)triangles_in[crt_trg_id].global_id, TRGSIDE_IS_FRONT(crt_side_id) ? "front": "back", - TRGSIDE_2_TRG(neighbour_id), + triangles_in[nbour_trg_id].global_id, TRGSIDE_IS_FRONT(neighbour_id) ? "front" : "back"); log_err(scn->dev, "Triangle %lu:\n (%g %g %g)\n (%g %g %g)\n (%g %g %g)\n", - (unsigned long)crt_trg_id, + (unsigned long)triangles_in[crt_trg_id].global_id, SPLIT3(positions[triangles_in[crt_trg_id].vertice_id[0]].vec), SPLIT3(positions[triangles_in[crt_trg_id].vertice_id[1]].vec), SPLIT3(positions[triangles_in[crt_trg_id].vertice_id[2]].vec)); log_err(scn->dev, "Triangle %lu:\n (%g %g %g)\n (%g %g %g)\n (%g %g %g)\n", - (unsigned long)neighbour_id, - SPLIT3(positions[triangles_in[neighbour_id].vertice_id[0]].vec), - SPLIT3(positions[triangles_in[neighbour_id].vertice_id[1]].vec), - SPLIT3(positions[triangles_in[neighbour_id].vertice_id[2]].vec)); + (unsigned long)triangles_in[nbour_trg_id].global_id, + SPLIT3(positions[triangles_in[nbour_trg_id].vertice_id[0]].vec), + SPLIT3(positions[triangles_in[nbour_trg_id].vertice_id[1]].vec), + SPLIT3(positions[triangles_in[nbour_trg_id].vertice_id[2]].vec)); log_err(desc->scene->dev, "Media: %lu VS %lu\n", neighbour->medium, crt_side->medium); res = RES_BAD_ARG; @@ -600,19 +600,19 @@ group_connex_components log_err(desc->scene->dev, "Medium mismatch found between triangle %lu %s side and triangle" " %lu %s side, both facing infinite.\n", - t1, + (unsigned long)triangles_in[t1].global_id, TRGSIDE_IS_FRONT(infinite_medium_first_side) ? "front" : "back", - TRGSIDE_2_TRG(cc->max_z_side_id), + (unsigned long)triangles_in[t2].global_id, TRGSIDE_IS_FRONT(cc->max_z_side_id) ? "front" : "back"); log_err(desc->scene->dev, "Triangle %lu:\n (%g %g %g)\n (%g %g %g)\n (%g %g %g)\n", - (unsigned long)t1, + (unsigned long)triangles_in[t1].global_id, SPLIT3(positions[triangles_in[t1].vertice_id[0]].vec), SPLIT3(positions[triangles_in[t1].vertice_id[1]].vec), SPLIT3(positions[triangles_in[t1].vertice_id[2]].vec)); log_err(desc->scene->dev, "Triangle %lu:\n (%g %g %g)\n (%g %g %g)\n (%g %g %g)\n", - (unsigned long)t2, + (unsigned long)triangles_in[t2].global_id, SPLIT3(positions[triangles_in[t2].vertice_id[0]].vec), SPLIT3(positions[triangles_in[t2].vertice_id[1]].vec), SPLIT3(positions[triangles_in[t2].vertice_id[2]].vec)); @@ -661,19 +661,19 @@ group_connex_components log_err(desc->scene->dev, "Medium mismatch found between triangle %lu %s side and triangle" " %u %s side facing each other.\n", - (unsigned long)t1, + (unsigned long)triangles_in[t1].global_id, TRGSIDE_IS_FRONT(hit_side) ? "front" : "back", - (unsigned long)t2, + (unsigned long)triangles_in[t2].global_id, TRGSIDE_IS_FRONT(cc->max_z_side_id) ? "front" : "back"); log_err(desc->scene->dev, "Triangle %lu:\n (%g %g %g)\n (%g %g %g)\n (%g %g %g)\n", - (unsigned long)t1, + (unsigned long)triangles_in[t1].global_id, SPLIT3(positions[triangles_in[t1].vertice_id[0]].vec), SPLIT3(positions[triangles_in[t1].vertice_id[1]].vec), SPLIT3(positions[triangles_in[t1].vertice_id[2]].vec)); log_err(desc->scene->dev, "Triangle %lu:\n (%g %g %g)\n (%g %g %g)\n (%g %g %g)\n", - (unsigned long)t2, + (unsigned long)triangles_in[t2].global_id, SPLIT3(positions[triangles_in[t2].vertice_id[0]].vec), SPLIT3(positions[triangles_in[t2].vertice_id[1]].vec), SPLIT3(positions[triangles_in[t2].vertice_id[2]].vec)); @@ -854,10 +854,9 @@ link_neighbours } /* Compute the actual vertex id * as vertices are not in the v0 v1 v2 order in the actual triangle */ - if (mz_vid == 2) { + if(mz_vid == 2) { actual_vid = (2 + neighbour_info->edge_rank) % 3; - } - else { + } else { int is_r = neighbour->reversed_edge[neighbour_info->edge_rank]; ASSERT(mz_vid == 0 || mz_vid == 1); actual_vid = ((is_r ? 1 - mz_vid : mz_vid) + neighbour_info->edge_rank) % 3; diff --git a/src/senc_scene_c.h b/src/senc_scene_c.h @@ -43,6 +43,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 (that is regardless of deduplication). */ + unsigned global_id; }; #ifndef NDEBUG @@ -53,6 +55,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] = MEDIUM_NULL__; + trg->global_id = 0; } #define DARRAY_FUNCTOR_INIT triangle_in_init #endif diff --git a/src/test_senc_cube_behind_cube.c b/src/test_senc_cube_behind_cube.c @@ -45,7 +45,7 @@ main(int argc, char** argv) ctx.back_media = medium1; /* First cube */ - CHK(senc_scene_add_geometry(scn, box_ntriangles, get_indices, get_media, + CHK(senc_scene_add_geometry(scn, box_ntriangles, get_indices, get_media, NULL, box_nvertices, get_position, &ctx) == RES_OK); /* +Z from the first cube, @@ -54,7 +54,7 @@ main(int argc, char** argv) ctx.scale = 5; /* Second cube */ - CHK(senc_scene_add_geometry(scn, box_ntriangles, get_indices, get_media, + CHK(senc_scene_add_geometry(scn, box_ntriangles, get_indices, get_media, NULL, box_nvertices, get_position, &ctx) == RES_OK); CHK(senc_scene_analyze(scn, &desc) == RES_OK); @@ -66,7 +66,7 @@ main(int argc, char** argv) ctx.back_media = medium0; /* Third cube */ - CHK(senc_scene_add_geometry(scn, box_ntriangles, get_indices, get_media, + CHK(senc_scene_add_geometry(scn, box_ntriangles, get_indices, get_media, NULL, box_nvertices, get_position, &ctx) == RES_OK); if(desc) CHK(senc_descriptor_ref_put(desc) == RES_OK); diff --git a/src/test_senc_cube_in_cube.c b/src/test_senc_cube_in_cube.c @@ -47,7 +47,7 @@ main(int argc, char** argv) ctx.back_media = medium1; /* First cube */ - CHK(senc_scene_add_geometry(scn, box_ntriangles, get_indices, get_media, + CHK(senc_scene_add_geometry(scn, box_ntriangles, get_indices, get_media, NULL, box_nvertices, get_position, &ctx) == RES_OK); d3(ctx.offset, -1, -1, -1); @@ -57,7 +57,7 @@ main(int argc, char** argv) ctx.reverse_vrtx = 1; /* Second cube */ - CHK(senc_scene_add_geometry(scn, box_ntriangles, get_indices, get_media, + CHK(senc_scene_add_geometry(scn, box_ntriangles, get_indices, get_media, NULL, box_nvertices, get_position, &ctx) == RES_OK); CHK(senc_scene_analyze(scn, &desc) == RES_OK); @@ -72,7 +72,7 @@ main(int argc, char** argv) ctx.back_media = medium0; /* mismatch with cube 2 */ /* Third cube */ - CHK(senc_scene_add_geometry(scn, box_ntriangles, get_indices, get_media, + CHK(senc_scene_add_geometry(scn, box_ntriangles, get_indices, get_media, NULL, box_nvertices, get_position, &ctx) == RES_OK); if(desc) CHK(senc_descriptor_ref_put(desc) == RES_OK); diff --git a/src/test_senc_cube_on_cube.c b/src/test_senc_cube_on_cube.c @@ -69,7 +69,7 @@ main(int argc, char** argv) /* Add cube #1 */ CHK(senc_scene_add_geometry(scn, box_ntriangles, get_indices, get_media, - box_nvertices, get_position, &ctx) == RES_OK); + NULL, box_nvertices, get_position, &ctx) == RES_OK); d3(ctx.offset, 1, 1, 1); ctx.scale = 1; @@ -81,7 +81,7 @@ main(int argc, char** argv) /* Add cube #2 (has a duplicate face with cube #1) */ CHK(senc_scene_add_geometry(scn, box_ntriangles, get_indices, get_media, - box_nvertices, get_position, &ctx) == RES_OK); + NULL, box_nvertices, get_position, &ctx) == RES_OK); d3(ctx.offset, 0, 0, 0); ctx.scale = 4; @@ -94,7 +94,7 @@ main(int argc, char** argv) /* Add cube #3 */ CHK(senc_scene_add_geometry(scn, box_ntriangles, get_indices, get_media, - box_nvertices, get_position, &ctx) == RES_OK); + NULL, box_nvertices, get_position, &ctx) == RES_OK); CHK(senc_scene_analyze(scn, &desc) == RES_OK); diff --git a/src/test_senc_descriptor.c b/src/test_senc_descriptor.c @@ -53,7 +53,7 @@ main(int argc, char** argv) ctx.front_media = medium0; ctx.back_media = medium1; - CHK(senc_scene_add_geometry(scn, box_ntriangles, get_indices, get_media, + CHK(senc_scene_add_geometry(scn, box_ntriangles, get_indices, get_media, NULL, box_nvertices, get_position, &ctx) == RES_OK); CHK(senc_scene_analyze(scn, &desc) == RES_OK); @@ -132,7 +132,7 @@ main(int argc, char** argv) CHK(senc_descriptor_ref_put(desc) == RES_OK); desc = NULL; CHK(senc_scene_add_geometry(scn, box_ntriangles, get_indices, get_media, - box_nvertices, get_position, &ctx) == RES_OK); + NULL, box_nvertices, get_position, &ctx) == RES_OK); CHK(senc_scene_analyze(scn, &desc) == RES_OK); CHK(senc_descriptor_get_global_vertices_count(desc, &count) == RES_OK); @@ -148,7 +148,7 @@ main(int argc, char** argv) desc = NULL; ctx.front_media = medium1; ctx.back_media = medium0; - CHK(senc_scene_add_geometry(scn, box_ntriangles, get_indices, get_media, + CHK(senc_scene_add_geometry(scn, box_ntriangles, get_indices, get_media, NULL, box_nvertices, get_position, &ctx) == RES_BAD_ARG); CHK(senc_scene_ref_put(scn) == RES_OK); diff --git a/src/test_senc_enclosure.c b/src/test_senc_enclosure.c @@ -36,6 +36,10 @@ main(int argc, char** argv) struct s3d_scene* s3d_scn = NULL; struct s3d_shape* s3d_shp = NULL; struct s3d_vertex_data s3d_attribs; + unsigned indices[2][3]; + unsigned medium[2]; + unsigned gid; + double vrtx[3]; struct context ctx; unsigned i, n, count; (void) argc, (void) argv; @@ -55,7 +59,8 @@ main(int argc, char** argv) CHK(s3d_scene_create(s3d, &s3d_scn) == RES_OK); /* A 3D cube. - * 2 enclosures (inside, outside) sharing the same triangles, but opposite sides */ + * 2 enclosures (inside, outside) sharing the same triangles, + * but opposite sides */ ctx.positions = box_vertices; ctx.indices = box_indices; ctx.scale = 1; @@ -66,13 +71,71 @@ main(int argc, char** argv) ctx.back_media = medium1; CHK(senc_scene_add_geometry(scn, box_ntriangles, get_indices, get_media, - box_nvertices, get_position, &ctx) == RES_OK); + NULL, box_nvertices, get_position, &ctx) == RES_OK); CHK(senc_scene_analyze(scn, &desc) == RES_OK); CHK(senc_descriptor_get_enclosure_count(desc, &count) == RES_OK); CHK(count == 2); + CHK(senc_descriptor_get_enclosure(desc, 0, &enclosure) == RES_OK); + CHK(senc_enclosure_ref_get(NULL) == RES_BAD_ARG); + CHK(senc_enclosure_ref_get(enclosure) == RES_OK); + CHK(senc_enclosure_ref_put(NULL) == RES_BAD_ARG); + CHK(senc_enclosure_ref_put(enclosure) == RES_OK); + + CHK(senc_enclosure_get_triangle(NULL, 0, indices[0]) == RES_BAD_ARG); + CHK(senc_enclosure_get_triangle(enclosure, box_ntriangles, indices[0]) + == RES_BAD_ARG); + CHK(senc_enclosure_get_triangle(enclosure, 0, NULL) == RES_BAD_ARG); + CHK(senc_enclosure_get_triangle(NULL, box_ntriangles, indices[0]) + == RES_BAD_ARG); + CHK(senc_enclosure_get_triangle(NULL, 0, NULL) == RES_BAD_ARG); + CHK(senc_enclosure_get_triangle(enclosure, box_ntriangles, NULL) + == RES_BAD_ARG); + CHK(senc_enclosure_get_triangle(NULL, box_ntriangles, NULL) == RES_BAD_ARG); + CHK(senc_enclosure_get_triangle(enclosure, 0, indices[0]) == RES_OK); + + CHK(senc_enclosure_get_vertex(NULL, 0, vrtx) == RES_BAD_ARG); + CHK(senc_enclosure_get_vertex(enclosure, box_nvertices, vrtx) + == RES_BAD_ARG); + CHK(senc_enclosure_get_vertex(enclosure, 0, NULL) == RES_BAD_ARG); + CHK(senc_enclosure_get_vertex(NULL, box_nvertices, vrtx) == RES_BAD_ARG); + CHK(senc_enclosure_get_vertex(NULL, 0, NULL) == RES_BAD_ARG); + CHK(senc_enclosure_get_vertex(enclosure, box_nvertices, NULL) + == RES_BAD_ARG); + CHK(senc_enclosure_get_vertex(NULL, box_nvertices, NULL) == RES_BAD_ARG); + CHK(senc_enclosure_get_vertex(enclosure, 0, vrtx) == RES_OK); + + CHK(senc_enclosure_get_triangle_media(NULL, 0, medium) == RES_BAD_ARG); + CHK(senc_enclosure_get_triangle_media(enclosure, box_ntriangles, medium) + == RES_BAD_ARG); + CHK(senc_enclosure_get_triangle_media(enclosure, 0, NULL) == RES_BAD_ARG); + CHK(senc_enclosure_get_triangle_media(NULL, box_ntriangles, medium) + == RES_BAD_ARG); + CHK(senc_enclosure_get_triangle_media(NULL, 0, NULL) == RES_BAD_ARG); + CHK(senc_enclosure_get_triangle_media(enclosure, box_ntriangles, NULL) + == RES_BAD_ARG); + CHK(senc_enclosure_get_triangle_media(NULL, box_ntriangles, NULL) + == RES_BAD_ARG); + CHK(senc_enclosure_get_triangle_media(enclosure, 0, medium) == RES_OK); + + CHK(senc_enclosure_get_triangle_global_id(NULL, 0, &gid) == RES_BAD_ARG); + CHK(senc_enclosure_get_triangle_global_id(enclosure, box_ntriangles, &gid) + == RES_BAD_ARG); + CHK(senc_enclosure_get_triangle_global_id(enclosure, 0, NULL) + == RES_BAD_ARG); + CHK(senc_enclosure_get_triangle_global_id(NULL, box_ntriangles, &gid) + == RES_BAD_ARG); + CHK(senc_enclosure_get_triangle_global_id(NULL, 0, NULL) == RES_BAD_ARG); + CHK(senc_enclosure_get_triangle_global_id(enclosure, box_ntriangles, NULL) + == RES_BAD_ARG); + CHK(senc_enclosure_get_triangle_global_id(NULL, box_ntriangles, NULL) + == RES_BAD_ARG); + CHK(senc_enclosure_get_triangle_global_id(enclosure, 0, &gid) == RES_OK); + + CHK(senc_enclosure_ref_put(enclosure) == RES_OK); + FOR_EACH(i, 0, count) { CHK(senc_descriptor_get_enclosure(desc, i, &enclosure) == RES_OK); @@ -94,7 +157,6 @@ main(int argc, char** argv) FOR_EACH(i, 0, 2) CHK(senc_descriptor_get_enclosure(desc, i, enclosures + i) == RES_OK); FOR_EACH(n, 0, box_ntriangles) { - unsigned indices[2][3]; /* Read same triangles in both enclosures */ FOR_EACH(i, 0, 2) CHK(senc_enclosure_get_triangle(enclosures[i], n, indices[i]) == RES_OK); @@ -122,7 +184,7 @@ main(int argc, char** argv) ctx.back_media = medium0; CHK(senc_scene_add_geometry(scn, box_ntriangles - 1, get_indices, get_media, - box_nvertices, get_position, &ctx) == RES_OK); + NULL, box_nvertices, get_position, &ctx) == RES_OK); CHK(senc_scene_analyze(scn, &desc) == RES_OK); diff --git a/src/test_senc_many_triangles.c b/src/test_senc_many_triangles.c @@ -35,8 +35,8 @@ get_s3dut_indices(const unsigned itri, unsigned ids[3], void* context) && ctx->data.indices[itri * 3 + 1] < UINT_MAX && ctx->data.indices[itri * 3 + 2] < UINT_MAX); ids[0] = (unsigned) ctx->data.indices[itri * 3 + 0]; - ids[ctx->ctx.reverse_vrtx ? 2 : 1] = (unsigned) ctx->data.indices[itri * 3 + 1]; - ids[ctx->ctx.reverse_vrtx ? 1 : 2] = (unsigned) ctx->data.indices[itri * 3 + 2]; + ids[ctx->ctx.reverse_vrtx ? 2 : 1] = (unsigned)ctx->data.indices[itri * 3 + 1]; + ids[ctx->ctx.reverse_vrtx ? 1 : 2] = (unsigned)ctx->data.indices[itri * 3 + 2]; } static void @@ -45,9 +45,12 @@ get_s3dut_position(const unsigned ivert, double pos[3], void* context) struct s3dut_context* ctx = context; ASSERT(pos && ctx); ASSERT(ivert < ctx->data.nvertices); - pos[0] = ctx->data.positions[ivert * 3 + 0] * ctx->ctx.scale + ctx->ctx.offset[0]; - pos[1] = ctx->data.positions[ivert * 3 + 1] * ctx->ctx.scale + ctx->ctx.offset[1]; - pos[2] = ctx->data.positions[ivert * 3 + 2] * ctx->ctx.scale + ctx->ctx.offset[2]; + pos[0] + = ctx->data.positions[ivert * 3 + 0] * ctx->ctx.scale + ctx->ctx.offset[0]; + pos[1] + = ctx->data.positions[ivert * 3 + 1] * ctx->ctx.scale + ctx->ctx.offset[1]; + pos[2] + = ctx->data.positions[ivert * 3 + 2] * ctx->ctx.scale + ctx->ctx.offset[2]; } static void @@ -99,7 +102,8 @@ main(int argc, char** argv) FOR_EACH(i, 0, NB_CYL) { d3(ctx.ctx.offset, 0, 0, i * 10); CHK(senc_scene_add_geometry(scn, cyl_trg_count, get_s3dut_indices, - get_s3dut_media, cyl_vrtx_count, get_s3dut_position, &ctx) == RES_OK); + get_s3dut_media, NULL, cyl_vrtx_count, get_s3dut_position, &ctx) + == RES_OK); } S3DUT(mesh_ref_put(cyl)); CHK(senc_scene_analyze(scn, &desc) == RES_OK); diff --git a/src/test_senc_sample_enclosure.c b/src/test_senc_sample_enclosure.c @@ -70,8 +70,8 @@ main(int argc, char** argv) ctx.front_media = medium0; ctx.back_media = medium0; - CHK(senc_scene_add_geometry(scn, box_ntriangles - 1, get_indices, get_media, - box_nvertices, get_position, &ctx) == RES_OK); + CHK(senc_scene_add_geometry(scn, box_ntriangles - 1, get_indices, + get_media, NULL, box_nvertices, get_position, &ctx) == RES_OK); CHK(senc_scene_analyze(scn, &desc) == RES_OK); @@ -81,7 +81,8 @@ main(int argc, char** argv) /* Put enclosure in a 3D view... */ CHK(s3d_shape_create_mesh(s3d, &s3d_shp) == RES_OK); CHK(s3d_mesh_setup_indexed_vertices(s3d_shp, header->triangle_count, - senc_enclosure_get_triangle__, header->vertices_count, &vrtx_get, 1, enclosure) + senc_enclosure_get_triangle__, header->vertices_count, &vrtx_get, 1, + enclosure) == RES_OK); CHK(s3d_scene_attach_shape(s3d_scn, s3d_shp) == RES_OK); diff --git a/src/test_senc_scene.c b/src/test_senc_scene.c @@ -29,7 +29,7 @@ main(int argc, char** argv) struct senc_scene* scn = NULL; struct senc_descriptor* desc = NULL; struct context ctx; - unsigned count; + unsigned count, i; (void)argc, (void)argv; CHK(mem_init_proxy_allocator(&allocator, &mem_default_allocator) == RES_OK); @@ -79,21 +79,22 @@ main(int argc, char** argv) d3(ctx.offset, 0, 0, 0); ctx.front_media = medium0; ctx.back_media = medium1; + ctx.global_ids = gid_face; CHK(senc_scene_add_geometry(NULL, box_ntriangles, get_indices, get_media, - box_nvertices, get_position, &ctx) == RES_BAD_ARG); - CHK(senc_scene_add_geometry(scn, 0, get_indices, get_media, + get_global_id, box_nvertices, get_position, &ctx) == RES_BAD_ARG); + CHK(senc_scene_add_geometry(scn, 0, get_indices, get_media, get_global_id, box_nvertices, get_position, &ctx) == RES_BAD_ARG); CHK(senc_scene_add_geometry(scn, box_ntriangles, NULL, get_media, - box_nvertices, get_position, &ctx) == RES_BAD_ARG); + get_global_id, box_nvertices, get_position, &ctx) == RES_BAD_ARG); CHK(senc_scene_add_geometry(scn, box_ntriangles, get_indices, NULL, - box_nvertices, get_position, &ctx) == RES_BAD_ARG); + get_global_id, box_nvertices, get_position, &ctx) == RES_BAD_ARG); CHK(senc_scene_add_geometry(scn, box_ntriangles, get_indices, get_media, - 0, get_position, &ctx) == RES_BAD_ARG); + get_global_id, 0, get_position, &ctx) == RES_BAD_ARG); CHK(senc_scene_add_geometry(scn, box_ntriangles, get_indices, get_media, - box_nvertices, NULL, &ctx) == RES_BAD_ARG); + get_global_id, box_nvertices, NULL, &ctx) == RES_BAD_ARG); CHK(senc_scene_add_geometry(scn, box_ntriangles, get_indices, get_media, - box_nvertices, get_position, &ctx) == RES_OK); + get_global_id, box_nvertices, get_position, &ctx) == RES_OK); CHK(senc_scene_get_triangles_count(scn, &count) == RES_OK); CHK(count == box_ntriangles); @@ -115,42 +116,70 @@ main(int argc, char** argv) CHK(senc_scene_ref_put(NULL) == RES_BAD_ARG); CHK(senc_scene_ref_put(scn) == RES_OK); + CHK(senc_scene_ref_put(scn) == RES_OK); + CHK(senc_descriptor_ref_put(desc) == RES_OK); + CHK(senc_scene_create(dev, 4, &scn) == RES_OK); + CHK(senc_scene_add_geometry(scn, box_ntriangles, get_indices, get_media, + get_global_id, box_nvertices, get_position, &ctx) == RES_OK); + CHK(senc_scene_analyze(scn, &desc) == RES_OK); + + FOR_EACH(i, 0, box_ntriangles) { + unsigned gid; + CHK(senc_descriptor_get_global_triangle_global_id(desc, i, &gid) == RES_OK); + /* gid has been set to gid_face. */ + CHK(gid == gid_face[i]); + } + + CHK(senc_scene_ref_put(scn) == RES_OK); + CHK(senc_descriptor_ref_put(desc) == RES_OK); + CHK(senc_scene_create(dev, 4, &scn) == RES_OK); + CHK(senc_scene_add_geometry(scn, box_ntriangles, get_indices, get_media, NULL, + box_nvertices, get_position, &ctx) == RES_OK); + CHK(senc_scene_analyze(scn, &desc) == RES_OK); + + FOR_EACH(i, 0, box_ntriangles) { + unsigned gid; + CHK(senc_descriptor_get_global_triangle_global_id(desc, i, &gid) == RES_OK); + /* Default gid: triangle rank. */ + CHK(gid == i); + } + /* Invalid medium ID */ ctx.back_media = medium1_12; - CHK(senc_scene_add_geometry(scn, box_ntriangles, get_indices, get_media, + CHK(senc_scene_add_geometry(scn, box_ntriangles, get_indices, get_media, NULL, box_nvertices, get_position, &ctx) == RES_BAD_ARG); ctx.back_media = medium1; /* Invalid vertex ID */ - CHK(senc_scene_add_geometry(scn, box_ntriangles, get_indices, get_media, + CHK(senc_scene_add_geometry(scn, box_ntriangles, get_indices, get_media, NULL, box_nvertices - 1, get_position, &ctx) == RES_BAD_ARG); /* Incoherent medium on a duplicate triangle */ ctx.back_media = medium1_3; - CHK(senc_scene_add_geometry(scn, box_ntriangles, get_indices, get_media, + CHK(senc_scene_add_geometry(scn, box_ntriangles, get_indices, get_media, NULL, box_nvertices, get_position, &ctx) == RES_BAD_ARG); /* It is OK dd geometry after a failed add */ ctx.back_media = medium1; - CHK(senc_scene_add_geometry(scn, box_ntriangles, get_indices, get_media, + CHK(senc_scene_add_geometry(scn, box_ntriangles, get_indices, get_media, NULL, box_nvertices, get_position, &ctx) == RES_OK); /* Coherent medium on duplicate triangle */ ctx.back_media = medium1; - CHK(senc_scene_add_geometry(scn, box_ntriangles, get_indices, get_media, + CHK(senc_scene_add_geometry(scn, box_ntriangles, get_indices, get_media, NULL, box_nvertices, get_position, &ctx) == RES_OK); /* Coherent medium on duplicate triangle V2 */ ctx.reverse_med = 1; ctx.front_media = medium1; ctx.back_media = medium0; - CHK(senc_scene_add_geometry(scn, box_ntriangles, get_indices, get_media, + CHK(senc_scene_add_geometry(scn, box_ntriangles, get_indices, get_media, NULL, box_nvertices, get_position, &ctx) == RES_OK); /* Coherent medium on duplicate triangle V3 */ ctx.reverse_med = 0; ctx.reverse_vrtx = 1; - CHK(senc_scene_add_geometry(scn, box_ntriangles, get_indices, get_media, + CHK(senc_scene_add_geometry(scn, box_ntriangles, get_indices, get_media, NULL, box_nvertices, get_position, &ctx) == RES_OK); CHK(senc_scene_ref_put(scn) == RES_OK); diff --git a/src/test_senc_utils.h b/src/test_senc_utils.h @@ -44,7 +44,8 @@ static const unsigned box_nvertices = sizeof(box_vertices) / sizeof(double[3]); * 0----1' 0----1' * Front, right Back, left and * and Top faces bottom faces */ -static const unsigned box_indices[12/*#triangles*/*3/*#indices per triangle*/] = { +static const unsigned +box_indices[12/*#triangles*/*3/*#indices per triangle*/] = { 0, 2, 1, 1, 2, 3, /* Front face */ 0, 4, 2, 2, 4, 6, /* Left face*/ 4, 5, 6, 6, 5, 7, /* Back face */ @@ -52,13 +53,15 @@ static const unsigned box_indices[12/*#triangles*/*3/*#indices per triangle*/] = 2, 6, 3, 3, 6, 7, /* Top face */ 0, 1, 4, 4, 1, 5 /* Bottom face */ }; -static const unsigned box_ntriangles = sizeof(box_indices) / (3 * sizeof(*box_indices)); +static const unsigned +box_ntriangles = sizeof(box_indices) / (3 * sizeof(*box_indices)); struct context { const double* positions; const unsigned* indices; const unsigned* front_media; const unsigned* back_media; + const unsigned* global_ids; double offset[3]; double scale; char reverse_vrtx, reverse_med; @@ -72,6 +75,8 @@ static const unsigned medium1_12[12] = { 1, 1, 1, 1, 1, 1, 1, 1, 12, 1, 1, 1 }; static const unsigned medium1_back0[12] = { 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1 }; static const unsigned medium1_front0[12] = { 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; +static const unsigned gid_face[12] = { 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5 }; + static void get_indices(const unsigned itri, unsigned ids[3], void* context) { @@ -101,6 +106,14 @@ get_media(const unsigned itri, unsigned medium[2], void* context) medium[ctx->reverse_med ? 0 : 1] = ctx->back_media[itri]; } +static void +get_global_id(const unsigned itri, unsigned* gid, void* context) +{ + struct context* ctx = context; + ASSERT(gid && context); + *gid = ctx->global_ids[itri]; +} + /******************************************************************************* * Miscellaneous ******************************************************************************/