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 a80c486f5551891a4ec2e513c274a1822f4c4974
parent 1848419c9fd6d58ffc53f1920c828be60eee6ef8
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Fri, 11 Oct 2019 15:01:59 +0200

Fix enum VS int mismatch when using enum mebers as flags

Diffstat:
Msrc/senc.h | 4++--
Msrc/senc_scene.c | 4++--
Msrc/senc_scene_c.h | 2+-
Msrc/test_senc_enclosure.c | 4++--
Msrc/test_senc_inconsistant_cube.c | 4++--
Msrc/test_senc_scene.c | 2+-
Asrc/test_senc_undefined_medium.c | 282+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
7 files changed, 292 insertions(+), 10 deletions(-)

diff --git a/src/senc.h b/src/senc.h @@ -148,7 +148,7 @@ senc_device_ref_put SENC_API res_T senc_scene_create (struct senc_device* device, - const enum senc_convention convention, + const int convention, struct senc_scene** scene); /* Reserve memory according to anticipated scene size. */ @@ -188,7 +188,7 @@ senc_scene_analyze SENC_API res_T senc_scene_get_convention (const struct senc_scene* scene, - enum senc_convention* convention); + int* convention); /* Returns the number of triangles in the scene. */ SENC_API res_T diff --git a/src/senc_scene.c b/src/senc_scene.c @@ -48,7 +48,7 @@ scene_release(ref_T * ref) res_T senc_scene_create (struct senc_device* dev, - const enum senc_convention conv, + const int conv, struct senc_scene** out_scn) { struct senc_scene* scn = NULL; @@ -310,7 +310,7 @@ error: res_T senc_scene_get_convention (const struct senc_scene* scn, - enum senc_convention* convention) + int* convention) { if(!scn || !convention) return RES_BAD_ARG; *convention = scn->convention; diff --git a/src/senc_scene_c.h b/src/senc_scene_c.h @@ -197,7 +197,7 @@ side_range_init(struct mem_allocator* alloc, struct side_range* data) struct senc_scene { /* Front / Back sides convention */ - enum senc_convention convention; + int convention; /* Triangle information as given by user; no duplicates here */ struct darray_triangle_in triangles_in; diff --git a/src/test_senc_enclosure.c b/src/test_senc_enclosure.c @@ -22,7 +22,7 @@ #include <star/s3d.h> static void -test(enum senc_convention convention) +test(int convention) { struct mem_allocator allocator; struct senc_descriptor* desc = NULL; @@ -41,7 +41,7 @@ test(enum senc_convention convention) double vrtx[3]; struct context ctx; unsigned i, n, t, ecount; - enum senc_convention conv; + int conv; int is_front, is_in; CHK(mem_init_proxy_allocator(&allocator, &mem_default_allocator) == RES_OK); diff --git a/src/test_senc_inconsistant_cube.c b/src/test_senc_inconsistant_cube.c @@ -49,7 +49,7 @@ static const unsigned inconsistant_medium_back[12] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; static void -test(enum senc_convention convention) +test(int convention) { struct mem_allocator allocator; struct senc_descriptor* desc = NULL; @@ -57,7 +57,7 @@ test(enum senc_convention convention) struct senc_scene* scn = NULL; struct senc_enclosure* enclosure; struct senc_enclosure_header header; - enum senc_convention conv; + int conv; int conv_front, conv_in; struct context ctx; unsigned i, e, ecount; diff --git a/src/test_senc_scene.c b/src/test_senc_scene.c @@ -31,7 +31,7 @@ main(int argc, char** argv) struct context ctx; unsigned medfront[2], medback[2]; unsigned count, i, maxm; - enum senc_convention convention; + int convention; (void)argc, (void)argv; CHK(mem_init_proxy_allocator(&allocator, &mem_default_allocator) == RES_OK); diff --git a/src/test_senc_undefined_medium.c b/src/test_senc_undefined_medium.c @@ -0,0 +1,282 @@ +/* Copyright (C) |Meso|Star> 2016-2018 (contact@meso-star.com) +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "senc.h" +#include "senc_s3d_wrapper.h" +#include "test_senc_utils.h" + +#include <rsys/double3.h> + +#include <star/s3d.h> + +static void +test(int convention) +{ + struct mem_allocator allocator; + struct senc_descriptor* desc = NULL; + struct senc_device* dev = NULL; + struct senc_scene* scn = NULL; + struct senc_enclosure* enclosure; + struct senc_enclosure_header header; + unsigned medium, expected_external_medium, expected_internal_medium; + unsigned gid; + struct context ctx; + unsigned i, t, ecount, vcount, tcount, scount; + int is_front, is_in; + unsigned media[12]; + unsigned rev_box_indices[sizeof(box_indices) / sizeof(*box_indices)]; + int conv_front, conv_in; + + conv_front = (convention & SENC_CONVENTION_NORMAL_FRONT) != 0; + conv_in = (convention & SENC_CONVENTION_NORMAL_INSIDE) != 0; + + /* Create the box with reversed triangles */ + FOR_EACH(i, 0, sizeof(rev_box_indices) / sizeof(*rev_box_indices)) { + switch (i % 3) { + case 0: rev_box_indices[i] = box_indices[i]; break; + case 1: rev_box_indices[i] = box_indices[i + 1]; break; + case 2: rev_box_indices[i] = box_indices[i - 1]; break; + } + } + OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator)); + OK(senc_device_create(NULL, &allocator, SENC_NTHREADS_DEFAULT, 1, &dev)); + + OK(senc_scene_create(dev, convention, &scn)); + is_front = (convention & SENC_CONVENTION_NORMAL_FRONT) != 0; + is_in = (convention & SENC_CONVENTION_NORMAL_INSIDE) != 0; + + /* A 3D cube. + * 2 enclosures (inside, outside) sharing the same triangles, + * but opposite sides */ + ctx.positions = box_vertices; + ctx.indices = box_indices; + ctx.scale = 1; + ctx.reverse_vrtx = 0; + ctx.reverse_med = 0; + d3(ctx.offset, 0, 0, 0); + ctx.front_media = media; + ctx.back_media = medium1; + + /* Can add the same triangles again defined/undefined media in any order */ + + /* Add geometry with no media information on both sides */ + for (i = 0; i < sizeof(media) / sizeof(*media); i++) + media[i] = SENC_UNDEFINED_MEDIUM; + OK(senc_scene_add_geometry(scn, ntriangles, get_indices, NULL, + NULL, nvertices, get_position, &ctx)); + OK(senc_scene_get_unique_sides_without_medium_count(scn, &scount)); + CHK(scount == 2 * ntriangles); + + /* Add geometry with no media information on the front sides */ + OK(senc_scene_add_geometry(scn, ntriangles, get_indices, get_media, + NULL, nvertices, get_position, &ctx)); + OK(senc_scene_get_unique_sides_without_medium_count(scn, &scount)); + CHK(scount == ntriangles); + + /* Analyze with undefined media on the front sides */ + OK(senc_scene_analyze(scn, &desc)); + OK(senc_descriptor_get_enclosure_count(desc, &ecount)); + CHK(ecount == 2); + + FOR_EACH(i, 0, ecount) { + struct senc_enclosure* ee; + struct senc_enclosure_header hh; + unsigned cc; + OK(senc_descriptor_get_enclosure(desc, i, &enclosure)); + OK(senc_enclosure_get_header(enclosure, &header)); + + CHK(header.enclosure_id == i); + CHK(header.enclosed_media_count == 1); + + OK(senc_enclosure_get_medium(enclosure, 0, &medium)); + /* Geometrical normals point outside the cube in input triangles: + * if convention is front, front medium (undef) is outside, + * that is medium 0's enclosure is infinite */ + expected_external_medium = conv_front ? SENC_UNDEFINED_MEDIUM : 1; + expected_internal_medium = conv_front ? 1 :SENC_UNDEFINED_MEDIUM; + + CHK(medium == (header.is_infinite + ? expected_external_medium : expected_internal_medium)); + CHK(header.triangle_count == ntriangles); + CHK(header.unique_triangle_count == ntriangles); + CHK(header.vertices_count == nvertices); + CHK(header.is_infinite == (i == 0)); + + OK(senc_descriptor_get_enclosure_count_by_medium(desc, medium, &cc)); + CHK(cc == 1); + OK(senc_descriptor_get_enclosure_by_medium(desc, medium, 0, &ee)); + OK(senc_enclosure_get_header(ee, &hh)); + CHK(header.enclosure_id == hh.enclosure_id); + OK(senc_enclosure_ref_put(ee)); + + FOR_EACH(t, 0, header.triangle_count) { + unsigned ind[3]; + OK(senc_enclosure_get_triangle_global_id(enclosure, t, &gid)); + CHK(gid == t); + OK(senc_enclosure_get_triangle(enclosure, t, ind)); + } + OK(senc_enclosure_ref_put(enclosure)); + } + OK(senc_descriptor_ref_put(desc)); + + /* Same geometry, front media are defined for odd triangles */ + for (i = 0; i < sizeof(media) / sizeof(*media); i++) + media[i] = (i % 2) ? 0 : SENC_UNDEFINED_MEDIUM; + OK(senc_scene_add_geometry(scn, ntriangles, get_indices, get_media, + NULL, nvertices, get_position, &ctx)); + OK(senc_scene_get_unique_sides_without_medium_count(scn, &scount)); + CHK(scount == ntriangles / 2); + + /* Analyze with undefined media */ + OK(senc_scene_analyze(scn, &desc)); + OK(senc_descriptor_ref_put(desc)); + + /* Get the deduplicated geometry without (successful) analyze */ + OK(senc_scene_get_unique_vertices_count(scn, &vcount)); + CHK(vcount == nvertices); + OK(senc_scene_get_unique_triangles_count(scn, &tcount)); + CHK(tcount == ntriangles); + FOR_EACH(i, 0, tcount) { + int j; + unsigned med[2], ids[3]; + OK(senc_scene_get_unique_triangle(scn, i, ids)); + OK(senc_scene_get_unique_triangle_media(scn, i, med)); + CHK(med[0] == ((i % 2) ? 0 : SENC_UNDEFINED_MEDIUM) && med[1] == 1); + FOR_EACH(j, 0, 3) { + double pos[3]; + CHK(ids[j] < vcount); + OK(senc_scene_get_unique_vertex(scn, ids[j], pos)); + } + } + + /* Same information again, using a reversed box */ + ctx.indices = rev_box_indices; + SWAP(const unsigned*, ctx.front_media, ctx.back_media); + OK(senc_scene_add_geometry(scn, ntriangles, get_indices, get_media, + NULL, nvertices, get_position, &ctx)); + OK(senc_scene_get_unique_sides_without_medium_count(scn, &scount)); + CHK(scount == ntriangles / 2); + + /* Analyze with undefined media */ + OK(senc_scene_analyze(scn, &desc)); + OK(senc_descriptor_ref_put(desc)); + + /* Define media for remaining triangles, using reversed box */ + for (i = 0; i < sizeof(media) / sizeof(*media); i++) + media[i] = (i % 2) ? SENC_UNDEFINED_MEDIUM : 0; + OK(senc_scene_add_geometry(scn, ntriangles, get_indices, get_media, + NULL, nvertices, get_position, &ctx)); + OK(senc_scene_get_unique_sides_without_medium_count(scn, &scount)); + CHK(scount == 0); + + /* Get the deduplicated geometry without (successful) analyze */ + OK(senc_scene_get_unique_vertices_count(scn, &vcount)); + CHK(vcount == nvertices); + OK(senc_scene_get_unique_triangles_count(scn, &tcount)); + CHK(tcount == ntriangles); + FOR_EACH(i, 0, tcount) { + int j; + unsigned med[2], ids[3]; + OK(senc_scene_get_unique_triangle(scn, i, ids)); + OK(senc_scene_get_unique_triangle_media(scn, i, med)); + CHK(med[0] == 0 && med[1] == 1); + FOR_EACH(j, 0, 3) { + double pos[3]; + CHK(ids[j] < vcount); + OK(senc_scene_get_unique_vertex(scn, ids[j], pos)); + } + } + + /* Analyze with all media defined */ + OK(senc_scene_analyze(scn, &desc)); + OK(senc_descriptor_ref_put(desc)); + + /* Define media for all triangles, nothing new here */ + for (i = 0; i < sizeof(media) / sizeof(*media); i++) + media[i] = 0; + OK(senc_scene_add_geometry(scn, ntriangles, get_indices, get_media, + NULL, nvertices, get_position, &ctx)); + OK(senc_scene_get_unique_sides_without_medium_count(scn, &scount)); + CHK(scount == 0); + + /* Define incoherent media for some triangles */ + for (i = 0; i < sizeof(media) / sizeof(*media); i++) + media[i] = (i % 2); + BA(senc_scene_add_geometry(scn, ntriangles, get_indices, get_media, + NULL, nvertices, get_position, &ctx)); + OK(senc_scene_get_unique_sides_without_medium_count(scn, &scount)); + CHK(scount == 0); + + /* Scene is still OK and can be analyzed */ + OK(senc_scene_analyze(scn, &desc)); + + OK(senc_descriptor_get_global_triangles_count(desc, &tcount)); + CHK(tcount == sizeof(media) / sizeof(*media)); + + OK(senc_descriptor_get_enclosure_count(desc, &ecount)); + CHK(ecount == 2); + + FOR_EACH(i, 0, ecount) { + struct senc_enclosure* ee; + struct senc_enclosure_header hh; + unsigned cc; + OK(senc_descriptor_get_enclosure(desc, i, &enclosure)); + OK(senc_enclosure_get_header(enclosure, &header)); + + CHK(header.enclosure_id == i); + CHK(header.enclosed_media_count == 1); + OK(senc_enclosure_get_medium(enclosure, 0, &medium)); + /* Geometrical normals point outside the cube in input triangles: + * if convention is front, front medium (0) is outside, + * that is medium 0's enclosure is infinite */ + CHK(is_front == ((medium == 0) == header.is_infinite)); + CHK(header.triangle_count == ntriangles); + CHK(header.unique_triangle_count == ntriangles); + CHK(header.vertices_count == nvertices); + CHK(header.is_infinite == (i == 0)); + + OK(senc_descriptor_get_enclosure_count_by_medium(desc, medium, &cc)); + CHK(cc == 1); + OK(senc_descriptor_get_enclosure_by_medium(desc, medium, 0, &ee)); + OK(senc_enclosure_get_header(ee, &hh)); + CHK(header.enclosure_id == hh.enclosure_id); + OK(senc_enclosure_ref_put(ee)); + + FOR_EACH(t, 0, header.triangle_count) { + OK(senc_enclosure_get_triangle_global_id(enclosure, t, &gid)); + CHK(gid == t); + } + OK(senc_enclosure_ref_put(enclosure)); + } + + SENC(scene_ref_put(scn)); + SENC(device_ref_put(dev)); + SENC(descriptor_ref_put(desc)); + + check_memory_allocator(&allocator); + mem_shutdown_proxy_allocator(&allocator); + CHK(mem_allocated_size() == 0); +} + +int +main(int argc, char** argv) +{ + (void) argc, (void) argv; + test(SENC_CONVENTION_NORMAL_FRONT | SENC_CONVENTION_NORMAL_INSIDE); + test(SENC_CONVENTION_NORMAL_BACK | SENC_CONVENTION_NORMAL_INSIDE); + test(SENC_CONVENTION_NORMAL_FRONT | SENC_CONVENTION_NORMAL_OUTSIDE); + test(SENC_CONVENTION_NORMAL_BACK | SENC_CONVENTION_NORMAL_OUTSIDE); + return 0; +}