star-cad

Geometric operators for computer-aided design
git clone git://git.meso-star.fr/star-cad.git
Log | Files | Refs | README | LICENSE

test_partition.c (4444B)


      1 /* Copyright (C) 2022-2024 |Méso|Star> (contact@meso-star.com)
      2  *
      3  * This program is free software: you can redistribute it and/or modify
      4  * it under the terms of the GNU General Public License as published by
      5  * the Free Software Foundation, either version 3 of the License, or
      6  * (at your option) any later version.
      7  *
      8  * This program is distributed in the hope that it will be useful,
      9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     11  * GNU General Public License for more details.
     12  *
     13  * You should have received a copy of the GNU General Public License
     14  * along with this program. If not, see <http://www.gnu.org/licenses/>. */
     15 
     16 #define _POSIX_C_SOURCE 200112L
     17 
     18 #include "scad.h"
     19 #include "scad_geometry.h"
     20 #include "test_common.h"
     21 
     22 #include <rsys/rsys.h>
     23 #include <rsys/math.h>
     24 #include <rsys/mem_allocator.h>
     25 #include <rsys/double3.h>
     26 
     27 #include <stdlib.h>
     28 #include <stdio.h>
     29 
     30 /*
     31  * +-------+              +-------+            +------+
     32  * |       | +----+       |       +----+       |     +----+
     33  * |       | |    |       |       |    |       |     ||   |
     34  * |       | +----+       |       +----+       |     +----+
     35  * +-------+              +-------+            +------+
     36  *    x = 1.1                  x = 1             x = 0.9
     37  */
     38 
     39 static res_T
     40 two_geoms
     41   (double x,
     42    const int allow_overlapping,
     43    struct mem_allocator* allocator)
     44 {
     45   double p1[3] = {0, 0, 0};
     46   double d1[3] = {1, 1, 1};
     47   double p2[3];
     48   double d2[3] = {0.5, 0.5, 0.5};
     49   struct scad_geometry* geoms[2] = {NULL, NULL};
     50   struct scad_geometry* out_geoms[2] = {NULL, NULL};
     51   char name[64];
     52   struct scad_options options = SCAD_DEFAULT_OPTIONS;
     53   res_T res;
     54 
     55   OK(scad_initialize(NULL, allocator, 3));
     56   options.Misc.LogRefCounting = SCAD_LOG_DIMTAGS_ALL | SCAD_LOG_GEOMETRY;
     57   OK(scad_set_options(&options));
     58 
     59   /* set position for cube #2 */
     60   d3(p2, x, 0.25, 0.25);
     61 
     62   OK(scad_add_box(p1, d1, geoms+0));
     63   OK(scad_add_box(p2, d2, geoms+1));
     64 
     65   /* Try to partition.
     66    * Fails if the 2 cubes overlap and overlapping is not allowed. */
     67   res = scad_geometries_partition(geoms, 2, allow_overlapping, out_geoms);
     68   if(res != RES_OK) goto end;
     69 
     70   /* Try to export the partitioned geometry in STL files.
     71    * If normal are forced, it fails when the geometry does not properly define
     72    * an inside / outside. */
     73   OK(scad_scene_mesh());
     74 
     75   if(allow_overlapping) {
     76     snprintf(name, sizeof(name), "part_%g_1o", x);
     77     /* If x==0.9, cubes 1 & 2 intersect. As a consequence, the partitioned
     78      * geometry of both cubes does not define and inside/outside and the
     79      * partitioned geometry cannot have its normals forced */
     80     if(x == 0.9) {
     81       BAD(scad_stl_export(out_geoms[0], name, SCAD_FORCE_NORMALS_OUTWARD, 0));
     82       OK(scad_stl_export(out_geoms[0], name, SCAD_KEEP_NORMALS_UNCHANGED, 0));
     83     } else {
     84       OK(scad_stl_export(out_geoms[0], name, SCAD_FORCE_NORMALS_OUTWARD, 1));
     85     }
     86     snprintf(name, sizeof(name), "part_%g_2o", x);
     87     if(x == 0.9) {
     88       BAD(scad_stl_export(out_geoms[1], name, SCAD_FORCE_NORMALS_OUTWARD, 1));
     89       OK(scad_stl_export(out_geoms[1], name, SCAD_KEEP_NORMALS_UNCHANGED, 1));
     90     } else {
     91       OK(scad_stl_export(out_geoms[1], name, SCAD_FORCE_NORMALS_OUTWARD, 1));
     92     }
     93   } else {
     94     snprintf(name, sizeof(name), "part_%g_1", x);
     95     OK(scad_stl_export(geoms[0], name, SCAD_FORCE_NORMALS_OUTWARD, 0));
     96     snprintf(name, sizeof(name), "part_%g_2", x);
     97     OK(scad_stl_export(geoms[1], name, SCAD_FORCE_NORMALS_OUTWARD, 1));
     98   }
     99 
    100 end:
    101   if(geoms[0]) OK(scad_geometry_ref_put(geoms[0]));
    102   if(geoms[1]) OK(scad_geometry_ref_put(geoms[1]));
    103   if(out_geoms[0]) OK(scad_geometry_ref_put(out_geoms[0]));
    104   if(out_geoms[1]) OK(scad_geometry_ref_put(out_geoms[1]));
    105   OK(scad_finalize());
    106   return res;
    107 }
    108 
    109 int
    110 main(int argc, char* argv[])
    111 {
    112   struct mem_allocator allocator;
    113 
    114   (void)argc; (void)argv;
    115 
    116   OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator));
    117 
    118   /* With distant geometries */
    119   OK(two_geoms(1.1, 0, &allocator));
    120   OK(two_geoms(1.1, 1, &allocator));
    121 
    122   /* With contacting geometries */
    123   OK(two_geoms(1, 0, &allocator));
    124   OK(two_geoms(1, 1, &allocator));
    125 
    126   /* With overlapping geometries */
    127   BAD(two_geoms(0.9, 0, &allocator));
    128   OK(two_geoms(0.9, 1, &allocator));
    129 
    130   check_memory_allocator(&allocator);
    131   mem_shutdown_proxy_allocator(&allocator);
    132   CHK(mem_allocated_size() == 0);
    133 
    134   return EXIT_SUCCESS;
    135 }