commit 9a8fff9b4d85a3b8d04620b4aca4d54ec2a72874
parent 1fae306affef7555d8e7b97c93793c68d6ea1cae
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Thu, 5 Jun 2025 16:46:56 +0200
Add a test on periodic meshes
Mesh a thin cylinder so that the internal and external meshes are
identical (through an affine transform).
Also show the use of different meshing algorithm on different faces of
the cylinder.
Diffstat:
2 files changed, 108 insertions(+), 1 deletion(-)
diff --git a/Makefile b/Makefile
@@ -130,7 +130,8 @@ TEST_SRC =\
src/test_export.c\
src/test_export2.c\
src/test_lifetime.c\
- src/test_partition.c
+ src/test_partition.c\
+ src/test_periodic.c
TEST_OBJ = $(TEST_SRC:.c=.o)
TEST_DEP = $(TEST_SRC:.c=.d)
@@ -183,5 +184,6 @@ test_export \
test_export2 \
test_lifetime \
test_partition \
+test_periodic \
: config.mk scad-local.pc $(LIBNAME)
$(CC) $(CFLAGS_EXE) -o $@ src/$@.o $(LDFLAGS_EXE) $(SCAD_LIBS) $(RSYS_LIBS) -lm
diff --git a/src/test_periodic.c b/src/test_periodic.c
@@ -0,0 +1,105 @@
+/* Copyright (C) 2022-2024 |Méso|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 "test_common.h"
+
+#include <rsys/rsys.h>
+#include <rsys/math.h>
+#include <rsys/double3.h>
+#include <rsys/mem_allocator.h>
+
+#define XR 1.5
+#define L 1
+
+int
+main(int argc, char* argv[])
+{
+ struct mem_allocator allocator;
+ struct scad_geometry *cyl1 = NULL, *cyl2 = NULL, *cyl = NULL;
+ struct scad_geometry *bound = NULL, **faces = NULL;
+ struct scad_geometry * internal = NULL, *external = NULL, *lat[2] = { NULL, NULL};
+ double p1[3] = { 0,0,0 }, p2[3], d2[3] = { L,0,0};
+ double r1 = 1, r2 = r1 * XR, len;
+ double cyl_affine[16] = { 1, 0, 0, 0, 0, XR, 0, 0, 0, 0, XR, 0, 0, 0, 0, 1 };
+ size_t i, facesn;
+
+ (void)argc; (void)argv;
+
+ OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator));
+
+ scad_initialize(NULL, &allocator, 2);
+ r2 = r1 * XR;
+ scad_add_cylinder(NULL, p1, d2, r1, 2*PI, &cyl1);
+ scad_add_cylinder(NULL, p1, d2, r2, 2*PI, &cyl2);
+ scad_cut_geometries("cylinder", &cyl2, 1, &cyl1, 1, &cyl);
+ scad_geometry_ref_put(cyl1);
+ scad_geometry_ref_put(cyl2);
+ scad_geometry_boundary(NULL, &cyl, 1, &bound);
+ scad_geometry_explode(bound, NULL, &faces, &facesn);
+ scad_geometry_ref_put(bound);
+ ASSERT(facesn == 4);
+ d3_add(p2, p1, d2);
+ len = d3_len(d2);
+ for(i = 0; i < facesn; i++) {
+ struct scad_geometry* f = faces[i];
+ double center[3], m;
+ scad_geometry_get_centerofmass(f, center);
+ if(fabs(center[0] - p1[0]) < FLT_EPSILON) {
+ ASSERT(lat[0] == NULL);
+ lat[0] = f;
+ scad_geometry_rename(f, "left_side");
+ continue;
+ }
+ if(fabs(center[0] - p2[0]) < FLT_EPSILON) {
+ ASSERT(lat[1] == NULL);
+ lat[1] = f;
+ scad_geometry_rename(f, "right_side");
+ continue;
+ }
+ scad_geometry_get_mass(f, &m);
+ if(fabs(m - len*2*PI*r1) < FLT_EPSILON) {
+ ASSERT(internal == NULL);
+ internal = f;
+ scad_geometry_rename(f, "internal");
+ continue;
+ }
+ if(fabs(m - len*2*PI*r2) < FLT_EPSILON) {
+ ASSERT(external == NULL);
+ external = f;
+ scad_geometry_rename(f, "external");
+ continue;
+ }
+ }
+ ASSERT(lat[0] && lat[1] && internal && external);
+ scad_geometries_set_periodic(&internal, 1, &external, 1, cyl_affine);
+ scad_geometries_set_mesh_algorithm(lat, 1, Scad_Initial_Mesh_Only);
+ for(i = 0; i < facesn; i++) {
+ scad_geometry_ref_put(faces[i]);
+ }
+ MEM_RM(&allocator, faces);
+ scad_scene_mesh();
+ scad_stl_export(cyl, "periodic", Scad_force_normals_outward, 1);
+ scad_geometry_ref_put(cyl);
+ scad_finalize();
+#undef XR
+
+ check_memory_allocator(&allocator);
+ mem_shutdown_proxy_allocator(&allocator);
+ CHK(mem_allocated_size() == 0);
+
+ return EXIT_SUCCESS;
+}