commit 585e0360459e5b068afc5831c9a8f9c06f096832
parent 2efc0ac6009832e83f5399f085c6b2798122d998
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Fri, 10 Jan 2020 18:13:13 +0100
Add and improve tests
Diffstat:
11 files changed, 637 insertions(+), 31 deletions(-)
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -20,8 +20,15 @@ enable_testing()
include(CMakeDependentOption)
set(STAR_GEOM_SOURCE_DIR ${PROJECT_SOURCE_DIR}/../src)
-option(NO_TEST "Do not build tests" OFF)
-option(ADDITIONAL_TESTS "Build additional tests originally written for star-enclosures" OFF)
+option(NO_TEST
+ "Do not build tests"
+ OFF)
+option(SMALL_ADDITIONAL_TESTS
+ "Build small additional tests originally written for star-enclosures"
+ OFF)
+option(HUGE_ADDITIONAL_TESTS
+ "Build additional tests originally written for star-enclosures that involve millions of triangles"
+ OFF)
CMAKE_DEPENDENT_OPTION(ALL_TESTS
"Perform basic and advanced tests" OFF "NOT NO_TEST" OFF)
@@ -32,7 +39,7 @@ CMAKE_DEPENDENT_OPTION(ALL_TESTS
find_package(RCMake 0.4 REQUIRED)
find_package(RSys 0.8.1 REQUIRED)
-if(ADDITIONAL_TESTS)
+if(SMALL_ADDITIONAL_TESTS)
find_package(Star3DUT 0.3.1 REQUIRED)
endif()
@@ -44,7 +51,7 @@ include_directories(
${RSys_INCLUDE_DIR}
${StarEnc_INCLUDE_DIR})
-if(ADDITIONAL_TESTS)
+if(SMALL_ADDITIONAL_TESTS)
rcmake_append_runtime_dirs(_runtime_dirs RSys StarEnc Star3DUT)
else()
rcmake_append_runtime_dirs(_runtime_dirs RSys StarEnc)
@@ -131,15 +138,38 @@ if(NOT NO_TEST)
new_test(test_sg3_geometry)
new_test(test_sg3_geometry_2)
- if(ADDITIONAL_TESTS)
- new_test(test_sg3_cube_behind_cube)
- new_test(test_sg3_many_triangles)
- new_test(test_sg3_many_enclosures)
+ rcmake_copy_runtime_libraries(test_sg3_device)
+ rcmake_copy_runtime_libraries(test_sg3_geometry)
+ rcmake_copy_runtime_libraries(test_sg3_geometry_2)
+
+ if(SMALL_ADDITIONAL_TESTS)
+ new_test(test_sg3_cube_behind_cube)
+ new_test(test_sg3_cube_in_cube)
+ new_test(test_sg3_cube_on_cube)
+ new_test(test_sg3_some_enclosures)
+ new_test(test_sg3_some_triangles)
+ new_test(test_sg3_undefined_properties)
- target_link_libraries(test_sg3_many_triangles Star3DUT)
- target_link_libraries(test_sg3_many_enclosures Star3DUT)
- rcmake_copy_runtime_libraries(test_sg3_many_triangles)
- rcmake_copy_runtime_libraries(test_sg3_many_enclosures)
+ target_link_libraries(test_sg3_some_enclosures Star3DUT)
+ target_link_libraries(test_sg3_some_triangles Star3DUT)
+
+ rcmake_copy_runtime_libraries(test_sg3_cube_behind_cube)
+ rcmake_copy_runtime_libraries(test_sg3_cube_in_cube)
+ rcmake_copy_runtime_libraries(test_sg3_cube_on_cube)
+ rcmake_copy_runtime_libraries(test_sg3_some_enclosures)
+ rcmake_copy_runtime_libraries(test_sg3_some_triangles)
+ rcmake_copy_runtime_libraries(test_sg3_undefined_properties)
+ endif()
+
+ if(HUGE_ADDITIONAL_TESTS)
+ new_test(test_sg3_many_enclosures)
+ new_test(test_sg3_many_triangles)
+
+ target_link_libraries(test_sg3_many_enclosures Star3DUT)
+ target_link_libraries(test_sg3_many_triangles Star3DUT)
+
+ rcmake_copy_runtime_libraries(test_sg3_many_enclosures)
+ rcmake_copy_runtime_libraries(test_sg3_many_triangles)
endif()
endif()
diff --git a/src/test_sg3_cube_behind_cube.c b/src/test_sg3_cube_behind_cube.c
@@ -20,6 +20,33 @@
#include <stdio.h>
+/*
+ cube_2 cube_3
+
+ +-----------------------+
+ | 3
+ | |
+ m1 | m0 |
+ | |
+ | |
+ | |
+ | |--> N
+ | |
+ | |
+ +-----------------------+
+ +------------+ +------------+
+ | 2 | 2
+ m0 | m1 | m0 | m1 |
+ | | | |
+ | |--> N | |--> N
+ | | | |
+ +------------+ +------------+
+ +-----+ +-----+
+ m0 | m1 1 m0 | m1 1
+ | |--> N | |--> N
+ +-----+ +-----+
+ */
+
int
main(int argc, char** argv)
{
@@ -46,15 +73,13 @@ main(int argc, char** argv)
ctx.back_media = medium1;
ctx.intface = intface0;
- /* First cube */
+ /* First cube (front: 0, back: 1), right-handed normal outside */
OK(sg3_geometry_add(geom, ntriangles, nvertices, &callbacks, &ctx));
- /* +Z from the first cube,
- * big enough to prevent rays from the first cube to miss this one */
d3(ctx.offset, -2, -2, 20);
ctx.scale = 5;
- /* Second cube */
+ /* Second cube (front: 0, back: 1), right-handed normal outside */
OK(sg3_geometry_add(geom, ntriangles, nvertices, &callbacks, &ctx));
OK(sg3_geometry_get_merge_conflict_count(geom, &count));
@@ -66,14 +91,12 @@ main(int argc, char** argv)
OK(sg3_geometry_dump_as_C_code(geom, stdout, "cube_behind_cube_2",
SG3_CDUMP_CONST | SG3_CDUMP_STATIC));
- /* Even further in +Z, even bigger */
d3(ctx.offset, -3, -3, 30);
ctx.scale = 7;
- /* Front/back media have been exchanged: external enclosure shows 2 media */
ctx.front_media = medium1;
ctx.back_media = medium0;
- /* Third cube */
+ /* Third cube (front: 1, back: 0), right-handed normal outside */
OK(sg3_geometry_add(geom, ntriangles, nvertices, &callbacks, &ctx));
OK(sg3_geometry_get_merge_conflict_count(geom, &count));
diff --git a/src/test_sg3_cube_in_cube.c b/src/test_sg3_cube_in_cube.c
@@ -0,0 +1,110 @@
+/* Copyright (C) 2019-2020 |Meso|Star> (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 "sg3.h"
+#include "test_sg3_utils.h"
+
+#include <rsys/double3.h>
+
+#include <stdio.h>
+
+/*
+ cube_2 cube_3
+
+ +-------------------------+
+ | B
+ +-------------+ | +-------------+ |
+ m1 | m0 M m1 | m1 | m0 M |
+ | +------+ | | m0 | +------+ | |
+ | | m1 S | | | | m1 S | |
+ | | N <--| | | | | N <--| | |
+ | +------+ | | | +------+ | |
+ | N <--| | | N <--| |
+ +-------------+ | +-------------+ |
+ | N <--|
+ +-------------------------+
+ */
+
+int
+main(int argc, char** argv)
+{
+ struct mem_allocator allocator;
+ struct sg3_device* dev;
+ struct sg3_geometry* geom;
+ struct context ctx = CONTEXT_NULL__;
+ struct sg3_geometry_add_callbacks callbacks = SG3_ADD_CALLBACKS_NULL__;
+ unsigned count;
+ (void)argc, (void)argv;
+
+ OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator));
+ OK(sg3_device_create(NULL, &allocator, 1, &dev));
+ OK(sg3_geometry_create(dev, &geom));
+ SG3(device_ref_put(dev));
+
+ callbacks.get_indices = get_indices;
+ callbacks.get_properties = get_properties;
+ callbacks.get_position = get_position;
+
+ ctx.positions = box_vertices;
+ ctx.indices = cube_indices;
+ ctx.front_media = medium0;
+ ctx.back_media = medium1;
+ ctx.intface = intface0;
+
+ /* First cube (front: 0, back: 1), right-handed normal outside */
+ OK(sg3_geometry_add(geom, ntriangles, nvertices, &callbacks, &ctx));
+
+ d3(ctx.offset, -1, -1, -1);
+ ctx.scale = 3;
+ ctx.reverse_vrtx = 1;
+
+ /* Second cube (front: 0, back: 1), right-handed normal inside */
+ OK(sg3_geometry_add(geom, ntriangles, nvertices, &callbacks, &ctx));
+
+ OK(sg3_geometry_get_merge_conflict_count(geom, &count));
+ CHK(count == 0);
+ OK(sg3_geometry_get_triangle_with_undefined_interface_count(geom, &count));
+ CHK(count == 0);
+ OK(sg3_geometry_get_triangle_with_undefined_side_count(geom, &count));
+ CHK(count == 0);
+ OK(sg3_geometry_dump_as_C_code(geom, stdout, "cube_in_cube_2",
+ SG3_CDUMP_CONST | SG3_CDUMP_STATIC));
+
+ d3(ctx.offset, -4, -4, -4);
+ ctx.scale = 10;
+ ctx.reverse_vrtx = 1;
+ ctx.reverse_med = 1;
+ ctx.front_media = medium1;
+ ctx.back_media = medium0;
+
+ /* Third cube (front: 0, back: 1), right-handed normal inside */
+ OK(sg3_geometry_add(geom, ntriangles, nvertices, &callbacks, &ctx));
+
+ OK(sg3_geometry_get_merge_conflict_count(geom, &count));
+ CHK(count == 0);
+ OK(sg3_geometry_get_triangle_with_undefined_interface_count(geom, &count));
+ CHK(count == 0);
+ OK(sg3_geometry_get_triangle_with_undefined_side_count(geom, &count));
+ CHK(count == 0);
+ OK(sg3_geometry_dump_as_C_code(geom, stdout, "cube_in_cube_3",
+ SG3_CDUMP_CONST | SG3_CDUMP_STATIC));
+
+ SG3(geometry_ref_put(geom));
+
+ check_memory_allocator(&allocator);
+ mem_shutdown_proxy_allocator(&allocator);
+ CHK(mem_allocated_size() == 0);
+ return 0;
+}
+\ No newline at end of file
diff --git a/src/test_sg3_cube_on_cube.c b/src/test_sg3_cube_on_cube.c
@@ -0,0 +1,101 @@
+/* Copyright (C) 2019-2020 |Meso|Star> (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 "sg3.h"
+#include "test_sg3_utils.h"
+
+#include <rsys/double3.h>
+
+#include <stdio.h>
+
+/*
+ +-----------------------+
+ | 3
+ | +------+ |
+ m2 | m1 | m0 2 |
+ | | |--> N |
+ | +------+ |
+ | | m0 1 |
+ | | |--> N |
+ | +------+ |
+ |--> N |
+ +-----------------------+
+ */
+
+int
+main(int argc, char** argv)
+{
+ struct mem_allocator allocator;
+ struct sg3_device* dev;
+ struct sg3_geometry* geom;
+ struct context ctx = CONTEXT_NULL__;
+ struct sg3_geometry_add_callbacks callbacks = SG3_ADD_CALLBACKS_NULL__;
+ unsigned count;
+ (void)argc, (void)argv;
+
+ OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator));
+ OK(sg3_device_create(NULL, &allocator, 1, &dev));
+ OK(sg3_geometry_create(dev, &geom));
+ SG3(device_ref_put(dev));
+
+ callbacks.get_indices = get_indices;
+ callbacks.get_properties = get_properties;
+ callbacks.get_position = get_position;
+
+ ctx.positions = cube_vertices;
+ ctx.indices = cube_indices;
+ d3(ctx.offset, 1, 1, 2);
+ ctx.front_media = medium1_front0;
+ ctx.back_media = medium0;
+ ctx.intface = intface0;
+
+ /* First cube (front: 0 on top face, 1 elsewhere, back: 0),
+ * right-handed normal outside */
+ OK(sg3_geometry_add(geom, ntriangles, nvertices, &callbacks, &ctx));
+
+ d3(ctx.offset, 1, 1, 1);
+ ctx.front_media = medium1_back0;
+
+ /* Second cube (front: 0 on bottom face, 1 elsewhere, back: 0),
+ * right-handed normal outside */
+ OK(sg3_geometry_add(geom, ntriangles, nvertices, &callbacks, &ctx));
+
+ ctx.positions = box_vertices; /* Can use distorded cube for cube #3 */
+ d3(ctx.offset, 0, 0, 0);
+ ctx.scale = 4;
+ ctx.reverse_vrtx = 1;
+ ctx.reverse_med = 1;
+ ctx.front_media = medium2;
+ ctx.back_media = medium1;
+
+ /* Third cube (front: 2, back: 1), right-handed normal inside */
+ OK(sg3_geometry_add(geom, ntriangles, nvertices, &callbacks, &ctx));
+
+ OK(sg3_geometry_get_merge_conflict_count(geom, &count));
+ CHK(count == 0);
+ OK(sg3_geometry_get_triangle_with_undefined_interface_count(geom, &count));
+ CHK(count == 0);
+ OK(sg3_geometry_get_triangle_with_undefined_side_count(geom, &count));
+ CHK(count == 0);
+ OK(sg3_geometry_dump_as_C_code(geom, stdout, "cube_on_cube",
+ SG3_CDUMP_CONST | SG3_CDUMP_STATIC));
+
+ SG3(geometry_ref_put(geom));
+
+ check_memory_allocator(&allocator);
+ mem_shutdown_proxy_allocator(&allocator);
+ CHK(mem_allocated_size() == 0);
+ return 0;
+}
+\ No newline at end of file
diff --git a/src/test_sg3_geometry_2.c b/src/test_sg3_geometry_2.c
@@ -281,6 +281,12 @@ 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));
+ /* First half of second add was duplicated */
+ FOR_EACH(i, 0, ntriangles) {
+ unsigned id;
+ OK(sg3_geometry_get_unique_triangle_global_id(geom, i, &id));
+ ASSERT(i < ntriangles / 2 ? id == i : id == i + ntriangles / 2);
+ }
/* Clear geometry */
SG3(geometry_ref_put(geom));
diff --git a/src/test_sg3_many_enclosures.c b/src/test_sg3_many_enclosures.c
@@ -24,8 +24,10 @@
#include <stdio.h>
#include <limits.h>
-#define NB_CYL_1 64
-#define NB_CYL (NB_CYL_1 * NB_CYL_1 * NB_CYL_1)
+#define NB_CYL_X 64
+#define NB_CYL_Y 64
+#define NB_CYL_Z 64
+#define NB_CYL (NB_CYL_X * NB_CYL_Y * NB_CYL_Z)
int
main(int argc, char** argv)
@@ -64,19 +66,21 @@ main(int argc, char** argv)
cyl_trg_count = (unsigned)ctx.data.nprimitives;
cyl_vrtx_count = (unsigned)ctx.data.nvertices;
OK(sg3_geometry_reserve(geom, NB_CYL * cyl_vrtx_count, NB_CYL * cyl_trg_count, 0));
- FOR_EACH(i, 0, NB_CYL_1) {
- double center_x = 2 * (1 + NB_CYL_1) * (i - NB_CYL_1 / 2);
- FOR_EACH(j, 0, NB_CYL_1) {
- double misalignment = 0.01;
- FOR_EACH(k, 0, NB_CYL_1) {
- double center_y = 2 * (1 + NB_CYL_1) * (j - NB_CYL_1 / 2);
+ FOR_EACH(i, 0, NB_CYL_X) {
+ double center_x = 2 * (1 + NB_CYL_X) * (i - NB_CYL_X / 2);
+ FOR_EACH(j, 0, NB_CYL_Y) {
+ double misalignment = 0;
+ FOR_EACH(k, 0, NB_CYL_Z) {
+ double center_y = 2 * (1 + NB_CYL_Y) * (j - NB_CYL_Y / 2);
m_in = (unsigned)k;
m_out = (unsigned)(k + 1);
ctx.ctx.scale = k + 1;
+#ifdef MITIGATE_EMBREE_181
/* Mitigate Embree issue #181
* We cannot keep perfect alignment of cylinders
- * or some hits are missed */
- misalignment *= -1;
+ * or some hits are missed in some raytracing tasks */
+ misalignment = (k % 2) ? -0.01 : +0.01;
+#endif
d3(ctx.ctx.offset, center_x + misalignment, center_y + misalignment, 0);
OK(sg3_geometry_add(geom, cyl_trg_count, cyl_vrtx_count, &callbacks, &ctx));
}
diff --git a/src/test_sg3_many_triangles.c b/src/test_sg3_many_triangles.c
@@ -76,7 +76,7 @@ main(int argc, char** argv)
OK(sg3_geometry_get_triangle_with_undefined_side_count(geom, &count));
CHK(count == 0);
OK(sg3_geometry_dump_as_obj(geom, stdout, SG3_ALL_TRIANGLES));
-
+
SG3(geometry_ref_put(geom));
check_memory_allocator(&allocator);
diff --git a/src/test_sg3_some_enclosures.c b/src/test_sg3_some_enclosures.c
@@ -0,0 +1,106 @@
+/* Copyright (C) 2019-2020 |Meso|Star> (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 "sg3.h"
+#include "test_sg3_utils.h"
+#include "test_sg3_utils2.h"
+
+#include <rsys/double3.h>
+
+#include <star/s3dut.h>
+
+#include <stdio.h>
+#include <limits.h>
+
+#define NB_CYL_X 4
+#define NB_CYL_Y 4
+#define NB_CYL_Z 4
+#define NB_CYL (NB_CYL_X * NB_CYL_Y * NB_CYL_Z)
+
+int
+main(int argc, char** argv)
+{
+ struct mem_allocator allocator;
+ struct sg3_device* dev;
+ struct sg3_geometry* geom;
+ struct sg3_geometry_add_callbacks callbacks = SG3_ADD_CALLBACKS_NULL__;
+ unsigned cyl_trg_count, cyl_vrtx_count, count;
+ int i, j, k;
+ unsigned m_in, m_out, itf = 0;
+ struct s3dut_context ctx = { {NULL,NULL,0,0}, CONTEXT_NULL__ };
+ struct s3dut_mesh* cyl = NULL;
+ (void)argc, (void)argv;
+
+ OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator));
+ OK(sg3_device_create(NULL, &allocator, 1, &dev));
+ OK(sg3_geometry_create(dev, &geom));
+ SG3(device_ref_put(dev));
+
+ callbacks.get_indices = get_s3dut_indices;
+ callbacks.get_properties = get_s3dut_properties;
+ callbacks.get_position = get_s3dut_position;
+
+ ctx.ctx.positions = box_vertices;
+ ctx.ctx.indices = cube_indices;
+ ctx.ctx.front_media = &m_in;
+ ctx.ctx.back_media = &m_out;
+ ctx.ctx.intface = &itf;
+
+ /* A 20 triangles 12 vertices cylinder template */
+ S3DUT(create_cylinder(&allocator, 1, 1, 5, 1, &cyl));
+ S3DUT(mesh_get_data(cyl, &ctx.data));
+ ASSERT(ctx.data.nprimitives <= UINT_MAX);
+ ASSERT(ctx.data.nvertices <= UINT_MAX);
+ cyl_trg_count = (unsigned)ctx.data.nprimitives;
+ cyl_vrtx_count = (unsigned)ctx.data.nvertices;
+ OK(sg3_geometry_reserve(geom, NB_CYL * cyl_vrtx_count, NB_CYL * cyl_trg_count, 0));
+ FOR_EACH(i, 0, NB_CYL_X) {
+ double center_x = 2 * (1 + NB_CYL_X) * (i - NB_CYL_X / 2);
+ FOR_EACH(j, 0, NB_CYL_Y) {
+ double misalignment = 0;
+ FOR_EACH(k, 0, NB_CYL_Z) {
+ double center_y = 2 * (1 + NB_CYL_Y) * (j - NB_CYL_Y / 2);
+ m_in = (unsigned)k;
+ m_out = (unsigned)(k + 1);
+ ctx.ctx.scale = k + 1;
+#ifdef MITIGATE_EMBREE_181
+ /* Mitigate Embree issue #181
+ * We cannot keep perfect alignment of cylinders
+ * or some hits are missed in some raytracing tasks */
+ misalignment = (k % 2) ? -0.01 : +0.01;
+#endif
+ d3(ctx.ctx.offset, center_x + misalignment, center_y + misalignment, 0);
+ OK(sg3_geometry_add(geom, cyl_trg_count, cyl_vrtx_count, &callbacks, &ctx));
+ }
+ }
+ }
+ S3DUT(mesh_ref_put(cyl));
+
+ OK(sg3_geometry_get_merge_conflict_count(geom, &count));
+ CHK(count == 0);
+ OK(sg3_geometry_get_triangle_with_undefined_interface_count(geom, &count));
+ CHK(count == 0);
+ OK(sg3_geometry_get_triangle_with_undefined_side_count(geom, &count));
+ CHK(count == 0);
+ OK(sg3_geometry_dump_as_C_code(geom, stdout, "some_enclosures",
+ SG3_CDUMP_CONST | SG3_CDUMP_STATIC));
+
+ SG3(geometry_ref_put(geom));
+
+ check_memory_allocator(&allocator);
+ mem_shutdown_proxy_allocator(&allocator);
+ CHK(mem_allocated_size() == 0);
+ return 0;
+}
+\ No newline at end of file
diff --git a/src/test_sg3_some_triangles.c b/src/test_sg3_some_triangles.c
@@ -0,0 +1,89 @@
+/* Copyright (C) 2019-2020 |Meso|Star> (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 "sg3.h"
+#include "test_sg3_utils.h"
+#include "test_sg3_utils2.h"
+
+#include <rsys/double3.h>
+
+#include <star/s3dut.h>
+
+#include <stdio.h>
+#include <limits.h>
+
+#define NB_CYL 4
+
+int
+main(int argc, char** argv)
+{
+ struct mem_allocator allocator;
+ struct sg3_device* dev;
+ struct sg3_geometry* geom;
+ struct sg3_geometry_add_callbacks callbacks = SG3_ADD_CALLBACKS_NULL__;
+ unsigned cyl_trg_count, cyl_vrtx_count, i, count;
+ unsigned m0 = 0, m1, itf = 0;
+ struct s3dut_context ctx = { {NULL,NULL,0,0}, CONTEXT_NULL__ };
+ struct s3dut_mesh* cyl = NULL;
+ (void)argc, (void)argv;
+
+ OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator));
+ OK(sg3_device_create(NULL, &allocator, 1, &dev));
+ OK(sg3_geometry_create(dev, &geom));
+ SG3(device_ref_put(dev));
+
+ callbacks.get_indices = get_s3dut_indices;
+ callbacks.get_properties = get_s3dut_properties;
+ callbacks.get_position = get_s3dut_position;
+
+ ctx.ctx.positions = box_vertices;
+ ctx.ctx.indices = cube_indices;
+ ctx.ctx.front_media = &m1;
+ ctx.ctx.back_media = &m0;
+ ctx.ctx.intface = &itf;
+
+ /* A 264 triangles 134 vertices cylinder template */
+ S3DUT(create_cylinder(&allocator, 1, 2, 12, 10, &cyl));
+ S3DUT(mesh_get_data(cyl, &ctx.data));
+ ASSERT(ctx.data.nprimitives <= UINT_MAX);
+ ASSERT(ctx.data.nvertices <= UINT_MAX);
+ cyl_trg_count = (unsigned)ctx.data.nprimitives;
+ cyl_vrtx_count = (unsigned)ctx.data.nvertices;
+ OK(sg3_geometry_reserve(geom, NB_CYL * cyl_vrtx_count, NB_CYL * cyl_trg_count, 0));
+ FOR_EACH(i, 0, NB_CYL) {
+ m1 = i;
+ d3(ctx.ctx.offset, 0, 0, i * 10);
+ OK(sg3_geometry_add(geom, cyl_trg_count, cyl_vrtx_count, &callbacks, &ctx));
+ }
+ S3DUT(mesh_ref_put(cyl));
+
+ OK(sg3_geometry_get_merge_conflict_count(geom, &count));
+ CHK(count == 0);
+ OK(sg3_geometry_get_triangle_with_undefined_interface_count(geom, &count));
+ CHK(count == 0);
+ OK(sg3_geometry_get_triangle_with_undefined_side_count(geom, &count));
+ CHK(count == 0);
+ //OK(sg3_geometry_dump_as_obj(geom, stdout, SG3_ALL_TRIANGLES));
+
+ OK(sg3_geometry_dump_as_C_code(geom, stdout, "some_triangles",
+ SG3_CDUMP_CONST | SG3_CDUMP_STATIC));
+
+ SG3(geometry_ref_put(geom));
+
+ check_memory_allocator(&allocator);
+ mem_shutdown_proxy_allocator(&allocator);
+ CHK(mem_allocated_size() == 0);
+ return 0;
+}
+\ No newline at end of file
diff --git a/src/test_sg3_undefined_properties.c b/src/test_sg3_undefined_properties.c
@@ -0,0 +1,131 @@
+/* Copyright (C) 2019-2020 |Meso|Star> (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 "sg3.h"
+#include "test_sg3_utils.h"
+
+#include <stdio.h>
+
+int
+main(int argc, char** argv)
+{
+ struct mem_allocator allocator;
+ struct sg3_device* dev;
+ struct sg3_geometry* geom;
+ struct context ctx = CONTEXT_NULL__;
+ struct sg3_geometry_add_callbacks callbacks = SG3_ADD_CALLBACKS_NULL__;
+ unsigned property[12];
+ unsigned i;
+ const unsigned property_count = sizeof(property) / sizeof(*property);
+ unsigned count;
+ (void)argc, (void)argv;
+
+ OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator));
+ OK(sg3_device_create(NULL, &allocator, 1, &dev));
+ OK(sg3_geometry_create(dev, &geom));
+
+ FOR_EACH(i, 0, property_count) property[i] = SG3_UNDEFINED_PROPERTY;
+
+ callbacks.get_indices = get_indices;
+ callbacks.get_position = get_position;
+
+ /* A 3D cube.
+ * 2 enclosures (inside, outside) sharing the same triangles,
+ * but opposite sides */
+ ctx.positions = box_vertices;
+ ctx.indices = cube_indices;
+
+ /* Add geometry with no properties */
+ ctx.front_media = property;
+ ctx.back_media = medium1;
+ ctx.intface = property;
+ OK(sg3_geometry_add(geom, ntriangles, nvertices, &callbacks, &ctx));
+ OK(sg3_geometry_get_triangle_with_undefined_side_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_dump_as_C_code(geom, stdout, "front_undefined",
+ SG3_CDUMP_STATIC | SG3_CDUMP_CONST));
+
+ /* Add same geometry, front/intface properties are defined for odd triangles */
+ FOR_EACH(i, 0, sizeof(property) / sizeof(*property))
+ property[i] = (i % 2) ? 0 : SG3_UNDEFINED_PROPERTY;
+ 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_unique_vertices_count(geom, &count));
+ CHK(count == nvertices);
+ OK(sg3_geometry_get_unique_triangles_count(geom, &count));
+ CHK(count == ntriangles);
+ FOR_EACH(i, 0, count) {
+ unsigned prop[3];
+ OK(sg3_geometry_get_unique_triangle_properties(geom, i, prop));
+ CHK(prop[SG3_FRONT] == ((i % 2) ? 0 : SG3_UNDEFINED_PROPERTY)
+ && prop[SG3_BACK] == 1
+ && prop[SG3_INTFACE] == ((i % 2) ? 0 : SG3_UNDEFINED_PROPERTY));
+ }
+
+ /* Same information again, using a reversed box */
+ ctx.reverse_vrtx = 1;
+ SWAP(const unsigned*, ctx.front_media, ctx.back_media);
+ 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_dump_as_C_code(geom, stdout, "front_half_undefined",
+ SG3_CDUMP_STATIC | SG3_CDUMP_CONST));
+
+ /* Define properties for remaining triangles, using reversed box */
+ FOR_EACH(i, 0, sizeof(property) / sizeof(*property))
+ property[i] = (i % 2) ?SG3_UNDEFINED_PROPERTY : 0;
+ OK(sg3_geometry_add(geom, ntriangles, nvertices, &callbacks, &ctx));
+ OK(sg3_geometry_get_triangle_with_undefined_side_count(geom, &count));
+ CHK(count == 0);
+ OK(sg3_geometry_get_unique_vertices_count(geom, &count));
+ CHK(count == nvertices);
+ OK(sg3_geometry_get_unique_triangles_count(geom, &count));
+ CHK(count == ntriangles);
+ FOR_EACH(i, 0, count) {
+ unsigned prop[3];
+ OK(sg3_geometry_get_unique_triangle_properties(geom, i, prop));
+ CHK(prop[SG3_FRONT] == 0 && prop[SG3_BACK] == 1
+ && prop[SG3_INTFACE] == 0);
+ }
+
+ OK(sg3_geometry_dump_as_C_code(geom, stdout, "all_defined",
+ SG3_CDUMP_STATIC | SG3_CDUMP_CONST));
+
+ /* Define incoherent properties for some triangles */
+ FOR_EACH(i, 0, sizeof(property) / sizeof(*property))
+ property[i] = (i % 2);
+ OK(sg3_geometry_add(geom, ntriangles, nvertices, &callbacks, &ctx));
+ OK(sg3_geometry_get_merge_conflict_count(geom, &count));
+ CHK(count == ntriangles / 2);
+ OK(sg3_geometry_get_properties_conflict_count(geom, &count));
+ CHK(count == 0);
+
+ OK(sg3_geometry_ref_put(geom));
+ OK(sg3_device_ref_put(dev));
+
+ check_memory_allocator(&allocator);
+ mem_shutdown_proxy_allocator(&allocator);
+ CHK(mem_allocated_size() == 0);
+ return 0;
+}
diff --git a/src/test_sg3_utils.h b/src/test_sg3_utils.h
@@ -74,7 +74,9 @@ static const double box_vertices[8/*#vertices*/ * 3/*#coords per vertex*/] = {
* | ',|/,' |/,' | ,' o--X
* 4----5' 4----5' /
* Front, right Back, left and Z
- * and Top faces bottom faces */
+ * and Top faces bottom faces
+ *
+ * The right-handed geometrical normal is outside the cube */
static const unsigned
cube_indices[12/*#triangles*/ * 3/*#indices per triangle*/] = {
0, 2, 1, 1, 2, 3, /* Front face */