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:
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;
+}