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 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:
Mcmake/CMakeLists.txt | 54++++++++++++++++++++++++++++++++++++++++++------------
Msrc/test_sg3_cube_behind_cube.c | 37++++++++++++++++++++++++++++++-------
Asrc/test_sg3_cube_in_cube.c | 111+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/test_sg3_cube_on_cube.c | 102+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/test_sg3_geometry_2.c | 6++++++
Msrc/test_sg3_many_enclosures.c | 24++++++++++++++----------
Msrc/test_sg3_many_triangles.c | 2+-
Asrc/test_sg3_some_enclosures.c | 107+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/test_sg3_some_triangles.c | 90+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/test_sg3_undefined_properties.c | 131+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/test_sg3_utils.h | 4+++-
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 */