star-geometry-3d

Clean and decorate 3D geometries
git clone git://git.meso-star.fr/star-geometry-3d.git
Log | Files | Refs | README | LICENSE

commit e46c4e9f8710f7595d9c7524674ae8a8e9589352
parent 3d87f7cc9f0744b441255c13e195e00cdb52ea4e
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Wed, 15 Jan 2020 18:56:48 +0100

Fix code on triangle ids; improve naming and comments

Diffstat:
Msrc/sg3.h | 34++++++++++++++++++++++------------
Msrc/sg3_geometry.c | 42++++++++++++++++++++++++++++++++----------
Msrc/sg3_geometry.h | 2+-
Msrc/test_sg3_geometry.c | 37+++++++++++++++++++++++++------------
Msrc/test_sg3_geometry_2.c | 42+++++++++++++++++++++++++++++++++++-------
Msrc/test_sg3_undefined_properties.c | 12++++++++++++
6 files changed, 127 insertions(+), 42 deletions(-)

diff --git a/src/sg3.h b/src/sg3.h @@ -107,15 +107,16 @@ struct sg3_geometry_add_callbacks { /* User function that provides coordinates for added vertices */ void(*get_position) (const unsigned ivert, double pos[3], void* context); - /* Called for each new triangle so that the client app can manage its own + /* Called if the itri_th triangle of the current sg3_geometry_add is a new + * triangle (i.e. not a duplicate) so that the client app can manage its own * triangle data/properties/attributes. * If return is not RES_OK, sg3_geometry_add stops immediately and returns * whatever value add_triangle returned. */ res_T(*add_triangle) /* Can be NULL */ - (const unsigned global_id, const unsigned itri, void* context); - /* Called if the itri_th triangle of the current sg3_geometry_add is equal - * to the global_id_th global triangle so that the client app can merge - * its own triangle data, rule merge validity, and possibly change the + (const unsigned unique_id, const unsigned itri, void* context); + /* Called if the itri_th triangle of the current sg3_geometry_add is a + * duplicate of the unique_id_th unique triangle so that the client app can + * merge its own triangle data, rule merge validity, and possibly change the * recorded properties. * The reversed_triangle arg indicates if the triangle vertices' order is * the same it was when the triangle was first added. @@ -125,7 +126,7 @@ struct sg3_geometry_add_callbacks { * The triangle_properties and merged_properties args contain the involved * properties. */ res_T(*merge_triangle) /* Can be NULL */ - (const unsigned global_id, + (const unsigned unique_id, const unsigned itri, const int reversed_triangle, unsigned triangle_properties[SG3_PROP_TYPES_COUNT__], @@ -262,33 +263,42 @@ sg3_geometry_get_unique_vertex const unsigned ivtx, double coord[3]); +/* Get the number of triangles added to the geometry, regardless of unicity. */ +SG3_API res_T +sg3_geometry_get_added_triangles_count + (const struct sg3_geometry* geometry, + unsigned* count); + /* Get the number of unique triangles. */ SG3_API res_T sg3_geometry_get_unique_triangles_count (const struct sg3_geometry* geometry, unsigned* count); -/* Get the vertex indices of the itri_th triangle. */ +/* Get the vertex indices of the itri_th unique triangle. */ SG3_API res_T sg3_geometry_get_unique_triangle_vertices (const struct sg3_geometry* geometry, const unsigned itri, unsigned indices[3]); -/* Get the properties of the itri_th triangle. */ +/* Get the properties of the itri_th unique triangle. */ SG3_API res_T sg3_geometry_get_unique_triangle_properties (const struct sg3_geometry* geometry, const unsigned itri, unsigned properties[SG3_PROP_TYPES_COUNT__]); -/* Get the global ID of the itri_th triangle, that is its original index in - * user world. */ +/* Get the user ID of the itri_th unique triangle, that is the user world's + * index of the triangle that first created this unique triangle. + * User world index starts at 0 and increases for every triangle that is + * submitted to sg3_geometry_add calls, regardless of duplication or + * sg3_geometry_add failures (non-RES_OK return value). */ SG3_API res_T -sg3_geometry_get_unique_triangle_global_id +sg3_geometry_get_unique_triangle_user_id (const struct sg3_geometry* geometry, const unsigned itri, - unsigned* global_id); + unsigned* user_id); /* Get the number of triangle with (at least) one undefined side. */ SG3_API res_T diff --git a/src/sg3_geometry.c b/src/sg3_geometry.c @@ -473,9 +473,8 @@ sg3_geometry_add already_conflict = trg_descriptions[i].merge_conflict; if(callbacks->merge_triangle) { /* Let the client app rule. */ - ERR(callbacks->merge_triangle(trg[*p_trg].global_id, i, !same, - trg[*p_trg].properties, tmp.properties, ctx, - &trg_descriptions[i].merge_conflict)); + ERR(callbacks->merge_triangle(*p_trg, i, !same, trg[*p_trg].properties, + tmp.properties, ctx, &trg_descriptions[i].merge_conflict)); } else { FOR_EACH(j, 0, SG3_PROP_TYPES_COUNT__) { if(!sg3_compatible_property(trg[*p_trg].properties[j], @@ -501,9 +500,9 @@ sg3_geometry_add /* New triangle */ ASSERT(nutris + n_new_utris < UINT_MAX); unique_id = (unsigned)(nutris + n_new_utris); - tmp.global_id = unique_id; + tmp.user_id = geom->triangle_count_including_duplicates + i; if(callbacks->add_triangle) - ERR(callbacks->add_triangle(tmp.global_id, i, ctx)); + ERR(callbacks->add_triangle(unique_id, i, ctx)); ERR(geometry_enlarge_trg_descriptions(geom, 1 + unique_id)); trg_descriptions = darray_trg_descriptions_data_get(&geom->trg_descriptions); @@ -636,6 +635,23 @@ error: } res_T +sg3_geometry_get_added_triangles_count + (const struct sg3_geometry* geom, + unsigned* count) +{ + res_T res = RES_OK; + if (!geom || !count) { + res = RES_BAD_ARG; + goto error; + } + *count = geom->triangle_count_including_duplicates; +exit: + return res; +error: + goto exit; +} + +res_T sg3_geometry_get_unique_triangles_count (const struct sg3_geometry* geom, unsigned* count) @@ -703,21 +719,21 @@ error: } res_T -sg3_geometry_get_unique_triangle_global_id +sg3_geometry_get_unique_triangle_user_id (const struct sg3_geometry* geom, const unsigned itri, - unsigned* global_id) + unsigned* user_id) { res_T res = RES_OK; const struct triangle* triangles; - if(!geom || !global_id + if(!geom || !user_id || itri >= darray_triangle_size_get(&geom->unique_triangles)) { res = RES_BAD_ARG; goto error; } triangles = darray_triangle_cdata_get(&geom->unique_triangles); - *global_id = triangles[itri].global_id; + *user_id = triangles[itri].user_id; exit: return res; error: @@ -902,13 +918,19 @@ sg3_geometry_dump_as_vtk fprintf(stream, "LOOKUP_TABLE default\n"); dump_trg_property(geom, stream, SG3_INTFACE); + /* Dump user_id */ + fprintf(stream, "SCALARS User_ID int\n"); + fprintf(stream, "LOOKUP_TABLE default\n"); + FOR_EACH(i, 0, tsz) + fprintf(stream, "%u\n", triangles[i].user_id); + /* Dump merge conflict status */ fprintf(stream, "SCALARS Merge_conflict int\n"); fprintf(stream, "LOOKUP_TABLE default\n"); FOR_EACH(i, 0, tsz) fprintf(stream, "%d\n", descriptions[i].merge_conflict); - /* Dump property property status */ + /* Dump property conflict status */ fprintf(stream, "SCALARS Property_conflict int\n"); fprintf(stream, "LOOKUP_TABLE default\n"); FOR_EACH(i, 0, tsz) diff --git a/src/sg3_geometry.h b/src/sg3_geometry.h @@ -33,7 +33,7 @@ struct triangle { /* FRONT/BACK/INTERFACE property */ unsigned properties[SG3_PROP_TYPES_COUNT__]; /* ID of the triangle in user world, i.e. without deduplication */ - unsigned global_id; + unsigned user_id; }; #define TRG_UNDEF__ {\ { SG3_UNDEFINED_PROPERTY, SG3_UNDEFINED_PROPERTY, SG3_UNDEFINED_PROPERTY },\ diff --git a/src/test_sg3_geometry.c b/src/test_sg3_geometry.c @@ -32,7 +32,7 @@ validate static res_T merge_trg - (const unsigned global_id, + (const unsigned user_id, const unsigned itri, const int reversed_triangle, unsigned triangle_properties[3], @@ -41,7 +41,7 @@ merge_trg int* merge_conflict) { ASSERT(triangle_properties && merged_properties && merge_conflict); - (void)global_id; (void)reversed_triangle; (void)context; + (void)user_id; (void)reversed_triangle; (void)context; (void)triangle_properties; (void)merged_properties; (void)merge_conflict; *merge_conflict = (int)itri; return RES_OK; @@ -71,7 +71,7 @@ main(int argc, char** argv) const unsigned degenerated[3] = { 0 , 0, 0 }; unsigned properties[SG3_PROP_TYPES_COUNT__]; struct sg3_geometry_add_callbacks callbacks = SG3_ADD_CALLBACKS_NULL__; - unsigned global_id; + unsigned user_id; unsigned count, i; struct context ctx = CONTEXT_NULL__; (void)argc, (void)argv; @@ -102,6 +102,11 @@ main(int argc, char** argv) BA(sg3_geometry_get_unique_vertices_count(NULL, &count)); OK(sg3_geometry_get_unique_vertices_count(geom, &count)); + BA(sg3_geometry_get_added_triangles_count(NULL, NULL)); + BA(sg3_geometry_get_added_triangles_count(geom, NULL)); + BA(sg3_geometry_get_added_triangles_count(NULL, &count)); + OK(sg3_geometry_get_added_triangles_count(geom, &count)); + BA(sg3_geometry_get_unique_triangles_count(NULL, NULL)); BA(sg3_geometry_get_unique_triangles_count(geom, NULL)); BA(sg3_geometry_get_unique_triangles_count(NULL, &count)); @@ -154,7 +159,11 @@ main(int argc, char** argv) BA(sg3_geometry_dump_as_C_code(geom, stdout, "test", 0)); BA(sg3_geometry_add(NULL, 0, 0, &callbacks, NULL)); + OK(sg3_geometry_get_added_triangles_count(geom, &count)); + CHK(count == 0); BA(sg3_geometry_add(geom, ntriangles, nvertices, NULL, NULL)); + OK(sg3_geometry_get_added_triangles_count(geom, &count)); + CHK(count == ntriangles); /* Mandatory callbacks are NULL */ callbacks.get_indices = NULL; callbacks.get_position = get_position; @@ -169,6 +178,8 @@ main(int argc, char** argv) callbacks.get_indices = get_indices; callbacks.get_position = get_position; OK(sg3_geometry_add(geom, 0, 0, &callbacks, NULL)); + OK(sg3_geometry_get_added_triangles_count(geom, &count)); + CHK(count == ntriangles); /* A 3D cube. * 2 enclosures (inside, outside) sharing the same triangles, @@ -221,15 +232,17 @@ main(int argc, char** argv) CHK(medium1[0] == properties[SG3_BACK]); CHK(intface0[0] == properties[SG3_INTFACE]); - BA(sg3_geometry_get_unique_triangle_global_id(NULL, ntriangles, NULL)); - BA(sg3_geometry_get_unique_triangle_global_id(geom, ntriangles, NULL)); - BA(sg3_geometry_get_unique_triangle_global_id(NULL, 0, NULL)); - BA(sg3_geometry_get_unique_triangle_global_id(NULL, ntriangles, &global_id)); - BA(sg3_geometry_get_unique_triangle_global_id(geom, 0, NULL)); - BA(sg3_geometry_get_unique_triangle_global_id(geom, ntriangles, &global_id)); - BA(sg3_geometry_get_unique_triangle_global_id(NULL, 0, &global_id)); - OK(sg3_geometry_get_unique_triangle_global_id(geom, 0, &global_id)); - CHK(global_id == 0); + BA(sg3_geometry_get_unique_triangle_user_id(NULL, ntriangles, NULL)); + BA(sg3_geometry_get_unique_triangle_user_id(geom, ntriangles, NULL)); + BA(sg3_geometry_get_unique_triangle_user_id(NULL, 0, NULL)); + BA(sg3_geometry_get_unique_triangle_user_id(NULL, ntriangles, &user_id)); + BA(sg3_geometry_get_unique_triangle_user_id(geom, 0, NULL)); + BA(sg3_geometry_get_unique_triangle_user_id(geom, ntriangles, &user_id)); + BA(sg3_geometry_get_unique_triangle_user_id(NULL, 0, &user_id)); + OK(sg3_geometry_get_unique_triangle_user_id(geom, 0, &user_id)); + /* Due to a failed attempt to add ntriangles triangles, user_id for the + * first successfully added triangle is shifted */ + CHK(user_id == ntriangles); /* Conflicts with merge_trg callback */ callbacks.merge_triangle = merge_trg; diff --git a/src/test_sg3_geometry_2.c b/src/test_sg3_geometry_2.c @@ -26,13 +26,13 @@ struct add_geom_ctx { static res_T add_trg - (const unsigned global_id, + (const unsigned unique_id, const unsigned iseg, void* context) { struct context* ctx = context; struct add_geom_ctx* add_geom_ctx; - ASSERT(ctx); (void)global_id; (void)iseg; + ASSERT(ctx); (void)unique_id; (void)iseg; add_geom_ctx = ctx->custom; if(add_geom_ctx->add_res == RES_OK) ++add_geom_ctx->add_cpt; return add_geom_ctx->add_res; @@ -40,7 +40,7 @@ add_trg static res_T merge_trg - (const unsigned global_id, + (const unsigned unique_id, const unsigned itri, const int reversed_triangle, unsigned triangle_properties[3], @@ -52,7 +52,7 @@ merge_trg struct add_geom_ctx* add_geom_ctx; int i; ASSERT(ctx && triangle_properties && merged_properties && merge_conflict); - (void)global_id; (void)itri; (void)reversed_triangle; + (void)unique_id; (void)itri; (void)reversed_triangle; (void)triangle_properties; (void)merged_properties; add_geom_ctx = ctx->custom; if(add_geom_ctx->merge_res == RES_OK) ++add_geom_ctx->merge_cpt; @@ -134,12 +134,16 @@ main(int argc, char** argv) CHK(add_geom_ctx.add_cpt == 0); OK(sg3_geometry_get_unique_vertices_count(geom, &count)); CHK(count == nvertices); + OK(sg3_geometry_get_added_triangles_count(geom, &count)); + CHK(count == ntriangles); OK(sg3_geometry_get_unique_triangles_count(geom, &count)); CHK(count == 0); add_geom_ctx.add_res = RES_MEM_ERR; ME(sg3_geometry_add(geom, ntriangles, nvertices, &callbacks, &ctx)); CHK(add_geom_ctx.add_cpt == 0); CHK(count == 0); + OK(sg3_geometry_get_added_triangles_count(geom, &count)); + CHK(count == 2 * ntriangles); OK(sg3_geometry_get_unique_triangles_count(geom, &count)); CHK(count == 0); OK(sg3_geometry_get_triangle_with_undefined_side_count(geom, &count)); @@ -158,6 +162,8 @@ main(int argc, char** argv) CHK(add_geom_ctx.merge_cpt == 0); OK(sg3_geometry_get_unique_vertices_count(geom, &count)); CHK(count == nvertices); + OK(sg3_geometry_get_added_triangles_count(geom, &count)); + CHK(count == 3 * ntriangles); OK(sg3_geometry_get_unique_triangles_count(geom, &count)); CHK(count == ntriangles); OK(sg3_geometry_get_triangle_with_undefined_side_count(geom, &count)); @@ -184,6 +190,8 @@ main(int argc, char** argv) CHK(add_geom_ctx.merge_cpt == 0); OK(sg3_geometry_get_unique_vertices_count(geom, &count)); CHK(count == nvertices); + OK(sg3_geometry_get_added_triangles_count(geom, &count)); + CHK(count == ntriangles); OK(sg3_geometry_get_unique_triangles_count(geom, &count)); CHK(count == ntriangles); OK(sg3_geometry_get_triangle_with_undefined_side_count(geom, &count)); @@ -200,9 +208,13 @@ main(int argc, char** argv) callbacks.add_triangle = add_trg; BA(sg3_geometry_add(geom, ntriangles, nvertices, &callbacks, &ctx)); CHK(add_geom_ctx.merge_cpt == 0); + OK(sg3_geometry_get_added_triangles_count(geom, &count)); + CHK(count == 2 * ntriangles); add_geom_ctx.merge_res = RES_MEM_ERR; ME(sg3_geometry_add(geom, ntriangles, nvertices, &callbacks, &ctx)); CHK(add_geom_ctx.merge_cpt == 0); + OK(sg3_geometry_get_added_triangles_count(geom, &count)); + CHK(count == 3 * ntriangles); OK(sg3_geometry_get_unique_vertices_count(geom, &count)); CHK(count == nvertices); OK(sg3_geometry_get_unique_triangles_count(geom, &count)); @@ -222,6 +234,8 @@ main(int argc, char** argv) CHK(add_geom_ctx.merge_cpt == 0); OK(sg3_geometry_get_unique_vertices_count(geom, &count)); CHK(count == nvertices); + OK(sg3_geometry_get_added_triangles_count(geom, &count)); + CHK(count == 4 * ntriangles); OK(sg3_geometry_get_unique_triangles_count(geom, &count)); CHK(count == ntriangles); OK(sg3_geometry_get_triangle_with_undefined_side_count(geom, &count)); @@ -241,6 +255,8 @@ main(int argc, char** argv) add_geom_ctx.merge_cpt = 0; OK(sg3_geometry_get_unique_vertices_count(geom, &count)); CHK(count == nvertices); + OK(sg3_geometry_get_added_triangles_count(geom, &count)); + CHK(count == 5 * ntriangles); OK(sg3_geometry_get_unique_triangles_count(geom, &count)); CHK(count == ntriangles); OK(sg3_geometry_get_triangle_with_undefined_side_count(geom, &count)); @@ -264,10 +280,14 @@ main(int argc, char** argv) * First half of the triangles, then all of them */ add_geom_ctx.add_res = RES_OK; OK(sg3_geometry_add(geom, ntriangles / 2, nvertices, &callbacks, &ctx)); + OK(sg3_geometry_get_added_triangles_count(geom, &count)); + CHK(count == ntriangles / 2); OK(sg3_geometry_add(geom, ntriangles, nvertices, &callbacks, &ctx)); CHK(add_geom_ctx.add_cpt == ntriangles); CHK(add_geom_ctx.merge_cpt == ntriangles / 2); add_geom_ctx.add_cpt = 0; + OK(sg3_geometry_get_added_triangles_count(geom, &count)); + CHK(count == ntriangles + ntriangles / 2); OK(sg3_geometry_get_unique_vertices_count(geom, &count)); CHK(count == nvertices); OK(sg3_geometry_get_unique_triangles_count(geom, &count)); @@ -281,11 +301,11 @@ main(int argc, char** argv) OK(sg3_geometry_get_properties_conflict_count(geom, &count)); CHK(count == 0); OK(sg3_geometry_dump_as_vtk(geom, stdout)); - /* Second add was half duplicated, but numbering is continuous anyway */ + /* Second add was half duplicated, so numbering is shifted */ FOR_EACH(i, 0, ntriangles) { unsigned id; - OK(sg3_geometry_get_unique_triangle_global_id(geom, i, &id)); - CHK(id == i); + OK(sg3_geometry_get_unique_triangle_user_id(geom, i, &id)); + CHK(i < ntriangles / 2 ? id == i : id == i + ntriangles / 2); } /* Clear geometry */ @@ -302,6 +322,8 @@ main(int argc, char** argv) add_geom_ctx.add_cpt = 0; OK(sg3_geometry_get_unique_vertices_count(geom, &count)); CHK(count == nvertices); + OK(sg3_geometry_get_added_triangles_count(geom, &count)); + CHK(count == ntriangles); OK(sg3_geometry_get_unique_triangles_count(geom, &count)); CHK(count == ntriangles); OK(sg3_geometry_get_triangle_with_undefined_side_count(geom, &count)); @@ -324,6 +346,8 @@ main(int argc, char** argv) add_geom_ctx.merge_cpt = 0; OK(sg3_geometry_get_unique_vertices_count(geom, &count)); CHK(count == nvertices); + OK(sg3_geometry_get_added_triangles_count(geom, &count)); + CHK(count == 2 * ntriangles); OK(sg3_geometry_get_unique_triangles_count(geom, &count)); CHK(count == ntriangles); OK(sg3_geometry_get_triangle_with_undefined_side_count(geom, &count)); @@ -345,6 +369,8 @@ main(int argc, char** argv) CHK(add_geom_ctx.merge_cpt == 0); OK(sg3_geometry_get_unique_vertices_count(geom, &count)); CHK(count == nvertices); + OK(sg3_geometry_get_added_triangles_count(geom, &count)); + CHK(count == 3 * ntriangles); OK(sg3_geometry_get_unique_triangles_count(geom, &count)); CHK(count == ntriangles); OK(sg3_geometry_get_triangle_with_undefined_side_count(geom, &count)); @@ -367,6 +393,8 @@ main(int argc, char** argv) add_geom_ctx.merge_cpt = 0; OK(sg3_geometry_get_unique_vertices_count(geom, &count)); CHK(count == nvertices); + OK(sg3_geometry_get_added_triangles_count(geom, &count)); + CHK(count == 4 * ntriangles); OK(sg3_geometry_get_unique_triangles_count(geom, &count)); CHK(count == ntriangles); OK(sg3_geometry_get_triangle_with_undefined_side_count(geom, &count)); diff --git a/src/test_sg3_undefined_properties.c b/src/test_sg3_undefined_properties.c @@ -54,12 +54,16 @@ main(int argc, char** argv) OK(sg3_geometry_add(geom, ntriangles, nvertices, &callbacks, &ctx)); OK(sg3_geometry_get_triangle_with_undefined_side_count(geom, &count)); CHK(count == ntriangles); + OK(sg3_geometry_get_added_triangles_count(geom, &count)); + CHK(count == ntriangles); /* Add same geometry with no properties on front/intface */ callbacks.get_properties = get_properties; OK(sg3_geometry_add(geom, ntriangles, nvertices, &callbacks, &ctx)); OK(sg3_geometry_get_triangle_with_undefined_side_count(geom, &count)); CHK(count == ntriangles); + OK(sg3_geometry_get_added_triangles_count(geom, &count)); + CHK(count == 2 * ntriangles); OK(sg3_geometry_dump_as_C_code(geom, stdout, "front_undefined", SG3_CDUMP_STATIC | SG3_CDUMP_CONST)); @@ -72,6 +76,8 @@ main(int argc, char** argv) CHK(count == ntriangles / 2); OK(sg3_geometry_get_unique_vertices_count(geom, &count)); CHK(count == nvertices); + OK(sg3_geometry_get_added_triangles_count(geom, &count)); + CHK(count == 3 * ntriangles); OK(sg3_geometry_get_unique_triangles_count(geom, &count)); CHK(count == ntriangles); FOR_EACH(i, 0, count) { @@ -88,6 +94,8 @@ main(int argc, char** argv) OK(sg3_geometry_add(geom, ntriangles, nvertices, &callbacks, &ctx)); OK(sg3_geometry_get_triangle_with_undefined_side_count(geom, &count)); CHK(count == ntriangles / 2); + OK(sg3_geometry_get_added_triangles_count(geom, &count)); + CHK(count == 4 * ntriangles); OK(sg3_geometry_dump_as_C_code(geom, stdout, "front_half_undefined", SG3_CDUMP_STATIC | SG3_CDUMP_CONST)); @@ -100,6 +108,8 @@ main(int argc, char** argv) CHK(count == 0); OK(sg3_geometry_get_unique_vertices_count(geom, &count)); CHK(count == nvertices); + OK(sg3_geometry_get_added_triangles_count(geom, &count)); + CHK(count == 5 * ntriangles); OK(sg3_geometry_get_unique_triangles_count(geom, &count)); CHK(count == ntriangles); FOR_EACH(i, 0, count) { @@ -120,6 +130,8 @@ main(int argc, char** argv) CHK(count == ntriangles / 2); OK(sg3_geometry_get_properties_conflict_count(geom, &count)); CHK(count == 0); + OK(sg3_geometry_get_added_triangles_count(geom, &count)); + CHK(count == 6 * ntriangles); OK(sg3_geometry_ref_put(geom)); OK(sg3_device_ref_put(dev));