commit 843b2f9ec4776950d8033f2617e47267568453f9
parent 6baf1b85f7bfe5571767da5e88069b1b38156e60
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Wed, 23 Nov 2022 17:18:15 +0100
Add tests
Diffstat:
5 files changed, 435 insertions(+), 1 deletion(-)
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -23,7 +23,7 @@ option(NO_TEST "Disable the test" OFF)
################################################################################
# Check dependencies
################################################################################
-find_package(gmsh 4.9.5 EXACT REQUIRED)
+find_package(gmsh 4.9.5 REQUIRED)
find_package(RCMake 0.4.1 REQUIRED)
find_package(RSys 0.12.1 REQUIRED)
@@ -92,6 +92,9 @@ if(NOT NO_TEST)
endfunction()
new_test(test1)
+ new_test(test_api)
+ new_test(test_export)
+ new_test(test_partition)
rcmake_copy_runtime_libraries(test)
diff --git a/src/test_api.c b/src/test_api.c
@@ -0,0 +1,252 @@
+/* Copyright (C) 2022 |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 "scad.h"
+#include "scad_geometry.h"
+#include "test_common.h"
+
+#include <rsys/rsys.h>
+#include <rsys/math.h>
+#include <rsys/mem_allocator.h>
+#include <rsys/logger.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+
+static void
+get_position
+ (const size_t ivert, double pos[2], void* data)
+{
+ double* coord = data;
+ ASSERT(pos && coord);
+ pos[0] = coord[2*ivert];
+ pos[1] = coord[1+2*ivert];
+
+}
+
+int
+main(int argc, char* argv[])
+{
+ res_T res = RES_OK;
+ double p1[3] = {0, 0, 0};
+ double p2[3] = {0.25, 0.25, 0.8};
+ double d1[3] = {1, 1, 1};
+ double coord[] = {0, 1.6, 0.5, 0.9, 0.8, 0.6};
+ struct scad_geometry* geom1 = NULL;
+ struct scad_geometry* geom2 = NULL;
+ struct scad_geometry* geom = NULL;
+ struct scad_geometry** geom_array = NULL;
+ struct scad_geometry* geoms[2];
+ struct mem_allocator allocator;
+ struct logger logger;
+ size_t c;
+
+ (void)argc; (void)argv;
+
+ OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator));
+ OK(logger_init(&allocator, &logger));
+
+ /* cannot call any API function before a successful call to scad_initialize */
+ BAD(scad_finalize());
+ BAD(scad_set_options(NULL));
+ BAD(scad_synchronize());
+ BAD(scad_scene_clear());
+ BAD(scad_add_rectangle(NULL, p1, d1, &geom));
+ BAD(scad_add_disk(NULL, p1, 1, &geom));
+ BAD(scad_add_polygon(NULL, get_position, coord, 0, 3, &geom));
+ BAD(scad_add_box(NULL, p1, d1, &geom));
+ BAD(scad_add_cylinder(NULL, p1, d1, 2, 1, &geom));
+ BAD(scad_add_sphere(NULL, p1, 1, &geom));
+ BAD(scad_step_import("test.step", NULL, &geom_array, &c));
+ BAD(scad_scene_mesh());
+ BAD(scad_run_ui());
+
+ /* cannot call any API function after a successful call to scad_finalize */
+ OK(scad_initialize(&logger, &allocator, 3));
+ OK(scad_finalize());
+
+ BAD(scad_finalize());
+ BAD(scad_set_options(NULL));
+ BAD(scad_synchronize());
+ BAD(scad_scene_clear());
+ BAD(scad_add_rectangle(NULL, p1, d1, &geom));
+ BAD(scad_add_disk(NULL, p1, 1, &geom));
+ BAD(scad_add_polygon(NULL, get_position, coord, 0, 3, &geom));
+ BAD(scad_add_box(NULL, p1, d1, &geom));
+ BAD(scad_add_cylinder(NULL, p1, d1, 2, 1, &geom));
+ BAD(scad_add_sphere(NULL, p1, 1, &geom));
+ BAD(scad_step_import("test.step", NULL, &geom_array, &c));
+ BAD(scad_scene_mesh());
+ BAD(scad_run_ui());
+
+ BAD(scad_initialize(&logger, &allocator, 4));
+ BAD(scad_initialize(&logger, &allocator, -1));
+
+ OK(scad_initialize(&logger, &allocator, 3));
+ OK(scad_add_sphere("sphere 1", p1, .1, &geom1));
+ OK(scad_add_sphere(NULL, p2, .2, &geom2));
+ geoms[0] = geom1;
+ geoms[1] = geom2;
+
+ OK(scad_add_sphere(NULL, p1, .1, &geom));
+ BAD(scad_geometry_delete(NULL));
+ OK(scad_geometry_delete(geom));
+
+ BAD(scad_geometry_get_count(NULL, &c));
+ BAD(scad_geometry_get_count(geom1, NULL));
+ OK(scad_geometry_get_count(geom1, &c));
+
+ BAD(scad_add_rectangle(NULL, NULL, d1, &geom));
+ BAD(scad_add_rectangle(NULL, p1, NULL, &geom));
+ BAD(scad_add_rectangle(NULL, p1, d1, NULL));
+ BAD(scad_add_rectangle("sphere 1", p1, d1, &geom)); /* Name already used */
+ OK(scad_add_rectangle(NULL, p1, d1, &geom));
+ OK(scad_geometry_delete(geom));
+
+ BAD(scad_add_disk(NULL, NULL, 1, &geom));
+ BAD(scad_add_disk(NULL, p1, 0, &geom));
+ BAD(scad_add_disk(NULL, p1, 1, NULL));
+ OK(scad_add_disk(NULL, p1, 1, &geom));
+ OK(scad_geometry_delete(geom));
+
+ BAD(scad_add_polygon(NULL, NULL, coord, 0, 3, &geom));
+ BAD(scad_add_polygon(NULL, get_position, coord, 0, 2, &geom));
+ BAD(scad_add_polygon(NULL, get_position, coord, 0, 2, &geom));
+ BAD(scad_add_polygon(NULL, get_position, coord, 0, 3, NULL));
+ OK(scad_add_polygon(NULL, get_position, coord, 0, 3, &geom));
+ OK(scad_geometry_delete(geom));
+
+ BAD(scad_add_box(NULL, NULL, d1, &geom));
+ BAD(scad_add_box(NULL, p1, NULL, &geom));
+ BAD(scad_add_box(NULL, p1, d1, NULL));
+ OK(scad_add_box(NULL, p1, d1, &geom));
+ OK(scad_geometry_delete(geom));
+
+ BAD(scad_add_cylinder(NULL, NULL, d1, 2, 1, &geom));
+ BAD(scad_add_cylinder(NULL, p1, NULL, 2, 1, &geom));
+ BAD(scad_add_cylinder(NULL, p1, d1, 0, 1, &geom));
+ BAD(scad_add_cylinder(NULL, p1, d1, 2, -1, &geom));
+ BAD(scad_add_cylinder(NULL, p1, d1, 2, 3*PI, &geom));
+ BAD(scad_add_cylinder(NULL, p1, d1, 2, 1, NULL));
+ OK(scad_add_cylinder(NULL, p1, d1, 2, 1, &geom));
+ OK(scad_geometry_delete(geom));
+
+ BAD(scad_add_sphere(NULL, NULL, 1, &geom));
+ BAD(scad_add_sphere(NULL, p1, 0, &geom));
+ BAD(scad_add_sphere(NULL, p1, 1, NULL));
+ OK(scad_add_sphere(NULL, p1, 1, &geom));
+ OK(scad_geometry_delete(geom));
+
+ /* BAD(scad_fuse_geometries(NULL, NULL, 0, geoms, 2, &geom)); */
+ BAD(scad_fuse_geometries(NULL, geoms, 2, NULL, 0, &geom));
+ BAD(scad_fuse_geometries(NULL, NULL, 1, &geom2, 1, &geom));
+ BAD(scad_fuse_geometries(NULL, &geom1, 1, NULL, 1, &geom));
+ BAD(scad_fuse_geometries(NULL, &geom1, 1, &geom2, 1, NULL));
+ OK(scad_fuse_geometries(NULL, &geom1, 1, &geom2, 1, &geom));
+ OK(scad_geometry_delete(geom));
+
+ /* BAD(scad_cut_geometries(NULL, NULL, 0, geoms, 2, &geom)); */
+ BAD(scad_cut_geometries(NULL, geoms, 2, NULL, 0, &geom));
+ BAD(scad_cut_geometries(NULL, NULL, 1, &geom2, 1, &geom));
+ BAD(scad_cut_geometries(NULL, &geom1, 1, NULL, 1, &geom));
+ BAD(scad_cut_geometries(NULL, &geom1, 1, &geom2, 1, NULL));
+ OK(scad_cut_geometries(NULL, &geom1, 1, &geom2, 1, &geom));
+ OK(scad_geometry_delete(geom));
+
+ /* BAD(scad_intersect_geometries(NULL, NULL, 0, geoms, 2, &geom)); */
+ BAD(scad_intersect_geometries(NULL, geoms, 2, NULL, 0, &geom));
+ BAD(scad_intersect_geometries(NULL, NULL, 1, &geom2, 1, &geom));
+ BAD(scad_intersect_geometries(NULL, &geom1, 1, NULL, 1, &geom));
+ BAD(scad_intersect_geometries(NULL, &geom1, 1, &geom2, 1, NULL));
+ OK(scad_intersect_geometries(NULL, &geom1, 1, &geom2, 1, &geom));
+ OK(scad_geometry_delete(geom));
+
+ /* BAD(scad_geometries_common_boundaries(NULL, NULL, 0, geoms, 2, &geom)); */
+ BAD(scad_geometries_common_boundaries(NULL, geoms, 2, NULL, 0, &geom));
+ BAD(scad_geometries_common_boundaries(NULL, NULL, 1, &geom2, 1, &geom));
+ BAD(scad_geometries_common_boundaries(NULL, &geom1, 1, NULL, 1, &geom));
+ BAD(scad_geometries_common_boundaries(NULL, &geom1, 1, &geom2, 1, NULL));
+ OK(scad_geometries_common_boundaries(NULL, &geom1, 1, &geom2, 1, &geom));
+ OK(scad_geometry_delete(geom));
+
+ BAD(scad_geometries_partition(NULL, NULL, 2, 1, geoms));
+ BAD(scad_geometries_partition(NULL, geoms, 0, 1, geoms));
+ BAD(scad_geometries_partition(NULL, geoms, 2, 1, NULL));
+ OK(scad_geometries_partition(NULL, geoms, 2, 1, geoms));
+ OK(scad_geometry_delete(geom));
+
+ BAD(scad_geometry_boundary(NULL, NULL, 0, &geom));
+ BAD(scad_geometry_boundary(NULL, &geom1, 1, NULL));
+ OK(scad_geometry_boundary(NULL, &geom1, 1, &geom));
+ OK(scad_geometry_delete(geom));
+
+ BAD(scad_geometry_copy(NULL, NULL, &geom));
+ BAD(scad_geometry_copy(geom1, NULL, NULL));
+ BAD(scad_geometry_copy(geom1, "sphere 1", NULL)); /* Name already in use */
+ OK(scad_geometry_copy(geom1, "Sphere 1", &geom));
+ OK(scad_geometry_delete(geom));
+
+ BAD(scad_geometry_rename(NULL, NULL));
+ BAD(scad_geometry_rename(geom2, "sphere 1")); /* Name already in use */
+ OK(scad_geometry_rename(geom2, NULL));
+
+ BAD(scad_geometry_translate(NULL, d1));
+ BAD(scad_geometry_translate(geom1, NULL));
+ OK(scad_geometry_translate(geom1, d1));
+
+ BAD(scad_geometry_rotate(NULL, p1, d1, 1));
+ BAD(scad_geometry_rotate(geom1, NULL, d1, 1));
+ BAD(scad_geometry_rotate(geom1, p1, NULL, 1));
+ OK(scad_geometry_rotate(geom1, p1, d1, 1));
+
+ BAD(scad_geometry_extrude(NULL, NULL, d1, &geom));
+ BAD(scad_geometry_extrude(geom1, NULL, NULL, &geom));
+ BAD(scad_geometry_extrude(geom1, NULL, d1, NULL));
+#if 0
+ /* Crash!? */
+ OK(scad_geometry_extrude(geom1, NULL, d1, &geom));
+ OK(scad_geometry_delete(geom));
+#endif
+
+ BAD(scad_scene_write(NULL));
+ ERR(scad_scene_write(""));
+ OK(scad_scene_write("/tmp/test.step"));
+
+ BAD(scad_step_import(NULL, "step", &geom_array, &c));
+ BAD(scad_step_import("/tmp/test.step", NULL, &geom_array, &c));
+ BAD(scad_step_import("/tmp/test.step", "step", NULL, &c));
+ BAD(scad_step_import("/tmp/test.step", "step", &geom_array, NULL));
+ ERR(scad_step_import("dont_exist.step", "step", &geom_array, &c));
+ OK(scad_step_import("/tmp/test.step", "step", &geom_array, &c));
+
+ BAD(scad_stl_export(NULL, NULL, 0));
+ BAD(scad_stl_export(geom2, NULL, 0)); /* geom2 has no name */
+ OK(scad_stl_export(geom2, "/tmp/test", 0));
+ OK(scad_stl_export(geom1, NULL, 0));
+
+ BAD(scad_stl_export_split(NULL, NULL, 0));
+ BAD(scad_stl_export_split(geom2, NULL, 0)); /* geom2 has no name */
+ OK(scad_stl_export_split(geom2, "/tmp/test", 0));
+ OK(scad_stl_export_split(geom1, NULL, 0));
+
+ logger_release(&logger);
+ OK(scad_finalize());
+
+ check_memory_allocator(&allocator);
+ mem_shutdown_proxy_allocator(&allocator);
+ CHK(mem_allocated_size() == 0);
+
+ return (res == RES_OK) ? EXIT_SUCCESS : EXIT_FAILURE;
+}
diff --git a/src/test_common.h b/src/test_common.h
@@ -24,6 +24,7 @@
#define OK(Expr) CHK(RES_OK == (Expr))
#define BAD(Expr) CHK(RES_BAD_ARG == (Expr))
+#define ERR(Expr) CHK(RES_OK != (Expr))
static void
check_memory_allocator(struct mem_allocator* allocator) {
diff --git a/src/test_export.c b/src/test_export.c
@@ -0,0 +1,73 @@
+/* Copyright (C) 2022 |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 "scad.h"
+#include "scad_geometry.h"
+#include "test_common.h"
+
+#include <rsys/rsys.h>
+#include <rsys/math.h>
+#include <rsys/mem_allocator.h>
+#include <rsys/logger.h>
+
+#include <stdlib.h>
+
+int
+main(int argc, char* argv[])
+{
+ res_T res = RES_OK;
+ double p1[3] = {0, 0, 0};
+ double p2[3] = {4.25, 4.25, 4.8};
+ double d1[3] = {1, 1, 1};
+ struct scad_geometry* rectangle = NULL;
+ struct scad_geometry* cube = NULL;
+ struct scad_geometry* cube2 = NULL;
+ struct scad_geometry* geoms[2];
+ struct mem_allocator allocator;
+ struct logger logger;
+
+ (void)argc; (void)argv;
+
+ OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator));
+ OK(logger_init(&allocator, &logger));
+ logger_release(&logger);
+ OK(scad_initialize(&logger, &allocator, 3));
+
+ OK(scad_add_rectangle("rectangle", p1, d1, &rectangle));
+ OK(scad_add_box("cube", p1, d1, &cube));
+ OK(scad_add_box(NULL, p2, d1, geoms+1));
+
+ geoms[0] = cube;
+ OK(scad_fuse_geometries("cube2", geoms, 1, geoms+1, 1, &cube2));
+
+ OK(scad_scene_mesh());
+
+ OK(scad_stl_export(rectangle, NULL, 0));
+ OK(scad_stl_export(rectangle, "bin_rectangle", 1));
+
+ OK(scad_stl_export(cube, NULL, 0));
+ OK(scad_stl_export(cube, "bin_cube", 1));
+
+ OK(scad_stl_export(cube2, NULL, 0));
+ OK(scad_stl_export(cube2, "bin_cube2", 1));
+
+ OK(scad_finalize());
+
+ check_memory_allocator(&allocator);
+ mem_shutdown_proxy_allocator(&allocator);
+ CHK(mem_allocated_size() == 0);
+
+ return (res == RES_OK) ? EXIT_SUCCESS : EXIT_FAILURE;
+}
diff --git a/src/test_partition.c b/src/test_partition.c
@@ -0,0 +1,105 @@
+/* Copyright (C) 2022 |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/>. */
+
+#define _POSIX_C_SOURCE 200112L
+
+#include "scad.h"
+#include "scad_geometry.h"
+#include "test_common.h"
+
+#include <rsys/rsys.h>
+#include <rsys/math.h>
+#include <rsys/mem_allocator.h>
+#include <rsys/logger.h>
+#include <rsys/double3.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+
+static res_T
+two_geoms
+ (double x,
+ const int allow_overlapping,
+ struct mem_allocator* allocator,
+ struct logger* logger)
+{
+ double p0[3] = {0, 0, 2};
+ double d0[3] = {1, 1, 1};
+ double p1[3] = {0, 0, 0};
+ double d1[3] = {1, 1, 1};
+ double p2[3];
+ double d2[3] = {0.5, 0.5, 0.5};
+ struct scad_geometry* geoms[2];
+ struct scad_geometry* tmp[2];
+ struct scad_geometry* pgeoms[2];
+ char name[64];
+ res_T res;
+
+ OK(scad_initialize(logger, allocator, 3));
+
+ /* set position for cube #2 */
+ d3(p2, x, 0.25, 0.25);
+
+ OK(scad_add_box("cube0", p0, d0, tmp));
+ OK(scad_add_box("cube1", p1, d1, tmp+1));
+
+ OK(scad_fuse_geometries("cubes", tmp, 1, tmp+1, 1, geoms));
+ OK(scad_add_box("cube2", p2, d2, geoms+1));
+
+ res = scad_geometries_partition(NULL, geoms, 2, allow_overlapping, pgeoms);
+ if(res != RES_OK) goto end;
+
+ OK(scad_scene_mesh());
+
+ snprintf(name, sizeof(name), "part_%g_1", x);
+ OK(scad_stl_export(pgeoms[0], name, 0));
+ snprintf(name, sizeof(name), "part_%g_2", x);
+ OK(scad_stl_export(pgeoms[1], name, 1));
+
+end:
+ OK(scad_finalize());
+ return res;
+}
+
+int
+main(int argc, char* argv[])
+{
+ struct mem_allocator allocator;
+ struct logger logger;
+ res_T res = RES_OK;
+
+ (void)argc; (void)argv;
+
+ OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator));
+ OK(logger_init(&allocator, &logger));
+
+ /* First with distant geometries */
+ OK(two_geoms(1.1, 0, &allocator, &logger));
+
+ /* First with contacting geometries */
+ OK(two_geoms(1, 0, &allocator, &logger));
+
+ /* First with overlapping geometries */
+ BAD(two_geoms(0.9, 0, &allocator, &logger));
+ OK(two_geoms(0.9, 1, &allocator, &logger));
+
+ logger_release(&logger);
+
+ check_memory_allocator(&allocator);
+ mem_shutdown_proxy_allocator(&allocator);
+ CHK(mem_allocated_size() == 0);
+
+ return (res == RES_OK) ? EXIT_SUCCESS : EXIT_FAILURE;
+}