star-cad

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

scad.h (28607B)


      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 #ifndef SCAD_H
     17 #define SCAD_H
     18 
     19 #include <rsys/rsys.h>
     20 
     21 /* Library symbol management */
     22 #if defined(SCAD_SHARED_BUILD) /* Build shared library */
     23   #define SCAD_API extern EXPORT_SYM
     24 #elif defined(SCAD_STATIC) /* Use/build static library */
     25   #define SCAD_API extern LOCAL_SYM
     26 #else /* Use shared library */
     27   #define SCAD_API extern IMPORT_SYM
     28 #endif
     29 
     30 /* Helper macro that asserts if the invocation of the scad function `Func'
     31  * returns an error. One should use this macro on scad function calls for which
     32  * no explicit error checking is performed */
     33 #ifndef NDEBUG
     34   #define SCAD(Func) ASSERT(scad_ ## Func == RES_OK)
     35 #else
     36   #define SCAD(Func) scad_ ## Func
     37 #endif
     38 
     39 /* Forward declarations */
     40 struct mem_allocator;
     41 struct logger;
     42 struct str;
     43 struct darray_double;
     44 
     45 /* Forward declaration of scad opaque data types */
     46 struct scad_geometry; /* Wrapping of dimTags gmsh description */
     47 
     48 /* Verbosity levels */
     49 enum scad_verbosity_levels {
     50   SCAD_VERBOSITY_FATAL_ERRORS = 0,
     51   SCAD_VERBOSITY_ERRORS = 1,
     52   SCAD_VERBOSITY_WARNINGS = 2,
     53   SCAD_VERBOSITY_DIRECT = 3,
     54   SCAD_VERBOSITY_INFORMATION = 4,
     55   SCAD_VERBOSITY_STATUS = 5,
     56   SCAD_VERBOSITY_DEBUG = 99
     57 };
     58 
     59 /* Mesh algorithms */
     60 enum scad_mesh_algorithm {
     61   SCAD_MESHADAPT = 1,
     62   SCAD_AUTOMATIC = 2, /* Delaunay on planes, mesh adapt elsewhere */
     63   SCAD_INITIAL_MESH_ONLY = 3, /* Avoid new point creation */
     64   SCAD_DELAUNAY = 5,
     65   SCAD_FRONTAL_DELAUNAY = 6,
     66   SCAD_QUASI_STRUCTURED = 11
     67 };
     68 
     69 enum scad_sizes_extend_from_boundary {
     70   SCAD_NEVER = 0,
     71   SCAD_SURFACES_AND_VOLUMES = 1,
     72   SCAD_SURFACES_AND_VOLUMES_SMALLEST = 2,
     73   SCAD_SURFACES_ONLY = -2,
     74   SCAD_VOLUMES_ONLY = -3
     75 };
     76 
     77 enum scad_stl_solids {
     78   SCAD_SINGLE_SOLID = 0,
     79   SCAD_ONE_SOLID_PER_SURFACE = 1,
     80   SCAD_ONE_SOLID_PER_PHYSICAL_SURFACE = 2
     81 };
     82 
     83 enum scad_log_refcounting {
     84   SCAD_LOG_NONE = 0,
     85   SCAD_LOG_DIMTAGS_ONLY_UNDELETED = BIT(0),
     86   SCAD_LOG_DIMTAGS_ALL = BIT(1),
     87   SCAD_LOG_GEOMETRY = BIT(2)
     88 };
     89 
     90 /* A type to specify options for the gmsh library */
     91 struct scad_options {
     92   struct {
     93     double MeshSizeFactor;
     94     double MeshSizeFromCurvature;
     95     double MeshSizeMax;
     96     double MeshSizeMin;
     97     double Smoothing;
     98     int MeshSizeFromPoints;
     99     int MeshOnlyVisible;
    100     enum scad_mesh_algorithm Algorithm;
    101     enum scad_sizes_extend_from_boundary MeshSizeExtendFromBoundary;
    102     enum scad_stl_solids StlOneSolidPerSurface;
    103   } Mesh;
    104   struct {
    105     enum scad_verbosity_levels Verbosity;
    106     int ExpertMode; /* Avoid user interaction on some option combinations */
    107   } General;
    108   struct {
    109     int OCCParallel;
    110   } Geometry;
    111   struct {
    112     /* Run UI when entering any star-cad API call; requires a FLTK-enabled gmsh
    113      * build, possibly a local build of gmsh and OCC */
    114     int RunUIAtEachStep;
    115     /* Call synchronize first when run_ui is called */
    116     int SynchronizeOnRunUI;
    117     /* Log ref counting operations on geometries (lot of logs expected) */
    118     enum scad_log_refcounting LogRefCounting;
    119     /* Triggers a synchronize operation before any star-cad API call. If results
    120      * change, there is a bug in star-cad auto-synchronize mechanism.
    121      * This slows down star-cad a lot! */
    122     int DebugAutoSync;
    123     /* Check gmsh and OCC contexts are empty everytime star-cad context is
    124      * empty. As a side effect, triggers a synchronize operation. */
    125     int DebugEmptyContext;
    126   } Misc;
    127 };
    128 
    129 #define SCAD_DEFAULT_OPTIONS__ \
    130   { { 1, 36, 1e+22, 1e-6, 1, 1, 1, \
    131       SCAD_FRONTAL_DELAUNAY, \
    132       SCAD_SURFACES_AND_VOLUMES, \
    133       SCAD_ONE_SOLID_PER_PHYSICAL_SURFACE }, \
    134     { SCAD_VERBOSITY_ERRORS, 1 }, \
    135     { 1 }, \
    136     { 0, 0, SCAD_LOG_NONE, 0, 0 } \
    137   }
    138 
    139 static const struct scad_options SCAD_DEFAULT_OPTIONS = SCAD_DEFAULT_OPTIONS__;
    140 
    141 /* A type to specify the kind of mesh size specification set by a call to the
    142  * scad_geometries_set_mesh_size_modifier API call */
    143 enum scad_size_modifier_type {
    144   SCAD_ABSOLUTE_SIZE,
    145   SCAD_SIZE_FACTOR
    146 };
    147 
    148 /* A type to specify what to swap in geometries_swap calls */
    149 enum scad_swap_elements {
    150   SCAD_SWAP_NAME = BIT(0),
    151   SCAD_SWAP_GEOMETRY = BIT(1)
    152 };
    153 
    154 /* A type to specify normals' orientation when writing STL files. */
    155 enum scad_normals_orientation {
    156   SCAD_KEEP_NORMALS_UNCHANGED, /* The only one allowed with non closed shapes */
    157   SCAD_FORCE_NORMALS_OUTWARD,
    158   SCAD_FORCE_NORMALS_INWARD
    159 };
    160 
    161 /* A type to specify how partitioning is done. */
    162 enum scad_partition_flags {
    163   SCAD_ALLOW_OVERLAPPING = BIT(0),
    164   SCAD_DUMP_ON_OVERLAPPING_ERROR = BIT(1) /* Dump individual geometries to STL */
    165 };
    166 
    167 BEGIN_DECLS
    168 
    169 /*******************************************************************************
    170  * Init and Finalize calls.
    171  * All other API calls must be enclosed between Init and Finalize.
    172  ******************************************************************************/
    173 SCAD_API res_T
    174 scad_initialize
    175   (struct logger* logger, /* May be NULL <=> use default logger */
    176    struct mem_allocator* allocator, /* May be NULL <=> use default allocator */
    177    const int verbose); /* Define the level of verbosity:
    178                           0 = no logs,
    179                           1 = errors only,
    180                           2 = errors and warnings,
    181                           3 = errors, warnings, and informative messages */
    182 
    183 /* Close the session and release any geometry not yet released.
    184  * Once finalized, scad can be initialized again. */
    185 SCAD_API res_T
    186 scad_finalize
    187   (void);
    188 
    189 /* Set global options `options' for scad. */
    190 SCAD_API res_T
    191 scad_set_options
    192   (const struct scad_options* options); /* May be NULL: set default */
    193 
    194 /* Get global options for scad. */
    195 SCAD_API res_T
    196 scad_get_options
    197   (struct scad_options* options);
    198 
    199 /*******************************************************************************
    200  * Scene API -
    201  * All these calls process the scene (i.e. all the existing geomeries) at once.
    202  ******************************************************************************/
    203 
    204 /* Get the number of geometries in the scene */
    205 SCAD_API res_T
    206 scad_scene_count
    207   (size_t* count);
    208 
    209 /* Clear the scene from all its geometries */
    210 SCAD_API res_T
    211 scad_scene_clear
    212   (void);
    213 
    214 /* Write the whole scene in a format that depends on filename extension.
    215  * Available formats include "brep", "msh" (gmsh-specific format), "step",
    216  * "stl", "vtk", etc. */
    217 SCAD_API res_T
    218 scad_scene_write
    219   (const char* filename);
    220 
    221 /* Create the mesh of the whole scene.
    222  * Note that, due to gmsh capabilities, there is no way to mesh a given list of
    223  * geometries. To avoid meshing useless geometries you can either release them
    224  * using scad_geometry_ref_put before meshing, or turn them not-visible using
    225  * visibility API. */
    226 SCAD_API res_T
    227 scad_scene_mesh
    228   (void);
    229 
    230 /*******************************************************************************
    231  * Geometry API - A geometry is a primitive, a group of primitives, or the
    232  * result of an operation on geometries.
    233  ******************************************************************************/
    234 
    235 /* Add a rectangle to the scene, defined by a point `xyz' and
    236  * `dxdy' the extents along the x-, y-axes. */
    237 SCAD_API res_T
    238 scad_add_rectangle
    239   (const double xyz[3],
    240    const double dxdy[2],
    241    struct scad_geometry** rectangle);
    242 
    243 /* Add a disk in the (xy) plane to the scene, defined by its `center' and
    244  * `radius'. */
    245 SCAD_API res_T
    246 scad_add_disk
    247   (const double center[3],
    248    const double radius,
    249    struct scad_geometry** disk);
    250 
    251 /* Add a polygon in the (xy) plane to the scene.
    252  * The `polygon' has `count' vertice and is at elevation `z', the vertice are
    253  * defined by calls to user-provided function `get_position'. */
    254 SCAD_API res_T
    255 scad_add_polygon
    256   (void (*get_position)(const size_t ivert, double pos[2], void* data),
    257    void* data, /* Custom data; can be NULL if get_position don't use it */
    258    const double z,
    259    const size_t count,
    260    struct scad_geometry** polygon);
    261 
    262 /* Add a parallelepipedic `box' to the scene, defined by a point `xyz' and
    263  * `dxdydz' the extents along the x-, y- and z-axes. */
    264 SCAD_API res_T
    265 scad_add_box
    266   (const double xyz[3],
    267    const double dxdydz[3],
    268    struct scad_geometry** box);
    269 
    270 /* Add a `cylinder' to the scene, defined by the center `center' of its first
    271  * circular face, the vector `axis' defining its axis and its radius `radius'.
    272  * The `angle' argument defines the angular opening (from 0 to 2*PI). */
    273 SCAD_API res_T
    274 scad_add_cylinder
    275   (const double center[3],
    276    const double axis[3],
    277    const double radius,
    278    const double angle,
    279    struct scad_geometry** cylinder);
    280 
    281 /* Add a `sphere' of center `center' and radius `radius' to the scene. */
    282 SCAD_API res_T
    283 scad_add_sphere
    284   (const double center[3],
    285    const double radius,
    286    struct scad_geometry** sphere);
    287 
    288 /* Add a `cone' to the scene, defined by the center `center' of its first
    289  * circular face, the vector `axis' defining its axis and its 2 radii `radius1'
    290  * and `radius2'. Note that the 2 radii cannot be identical (one of them can be
    291  * zero).
    292  * The `angle' argument defines the angular opening (from 0 to 2*PI). */
    293 SCAD_API res_T
    294 scad_add_cone
    295   (const double center[3],
    296    const double axis[3],
    297    const double radius1,
    298    const double radius2,
    299    const double angle,
    300    struct scad_geometry** cone);
    301 
    302 /* Add a `torus' to the scene, defined by its `center', the vector `axis'
    303  * defining its axis and its 2 positive radii `radius1' and `radius2'.
    304  * The `angle' argument defines the angular opening (from 0 to 2*PI).
    305  * If `z_axis' is provided, it defines the Z axis of the torus. Otherwise the
    306  * absolute Z axis is used. */
    307 SCAD_API res_T
    308 scad_add_torus
    309   (const double center[3],
    310    const double radius1,
    311    const double radius2,
    312    const double angle,
    313    const double z_axis[3], /* Can be NULL */
    314    struct scad_geometry** torus);
    315 
    316 /* Scale the geometry `geometry' by factors `scale' along the three coordinate axes;
    317  * Use `center', as the center of the homothetic transformation. */
    318 SCAD_API res_T
    319 scad_geometry_dilate
    320   (const struct scad_geometry* geometry,
    321    const double center[3],
    322    const double scale[3],
    323    struct scad_geometry** out_geometry);
    324 
    325 /* Translate the geometry `geometry' along (`dx', `dy', `dz'). */
    326 SCAD_API res_T
    327 scad_geometry_translate
    328   (const struct scad_geometry* geometry,
    329    const double dxdydz[3],
    330    struct scad_geometry** out_geometry);
    331 
    332 /* Rotate the geometry `geometry' by `angle' radians around the axis of revolution
    333  * defined by the point `pt' and the direction `dir'. */
    334 SCAD_API res_T
    335 scad_geometry_rotate
    336   (const struct scad_geometry* geometry,
    337    const double pt[3],
    338    const double dir[3],
    339    const double angle,
    340    struct scad_geometry** out_geometry);
    341 
    342 /* Extrude the geometry `geometry' using a translation along (`dx', `dy', `dz'). */
    343 SCAD_API res_T
    344 scad_geometry_extrude
    345   (const struct scad_geometry* geometry,
    346    const double dxdydz[3],
    347    struct scad_geometry** out_geometry);
    348 
    349 /* Return a list of geometries which form the geometry `geometry'.
    350  * The output geometries are created unnamed.
    351  * Whatever the names, if defined they must be unique.
    352  * The result `out_geometries' being allocated using the allocator provided when
    353  * initializing star-cad, it should be freed accordingly. */
    354 SCAD_API res_T
    355 scad_geometry_explode
    356   (const struct scad_geometry* geometry,
    357    struct scad_geometry*** out_geometries,
    358    size_t* out_count);
    359 
    360 /* Ref counting of geometries: get a new reference to geometry `geometry'. */
    361 SCAD_API res_T
    362 scad_geometry_ref_get
    363   (struct scad_geometry* geometry);
    364 
    365 /* Ref counting of geometries: release a reference to geometry `geometry'. */
    366 SCAD_API res_T
    367 scad_geometry_ref_put
    368   (struct scad_geometry* geometry);
    369 
    370 /* Get the number of components of the geometry `geometry'. */
    371 SCAD_API res_T
    372 scad_geometry_get_count
    373   (const struct scad_geometry* geometry,
    374    size_t* count);
    375 
    376 /* Check if the geometry `geometry' is empty (has count 0). */
    377 SCAD_API res_T
    378 scad_geometry_is_empty
    379   (const struct scad_geometry* geometry,
    380    int* empty);
    381 
    382 /* Attach some custom data `data' to geometry `geometry'.
    383  * If provided, release() is called when `geometry' is released or if
    384  * set_custom_data is called again. */
    385 SCAD_API res_T
    386 scad_geometry_set_custom_data
    387   (struct scad_geometry* geometry,
    388    void (*release) (void* data), /* Can be NULL */
    389    void* data); /* Can be NULL */
    390 
    391 /* Get the custom data attached to geometry `geometry'.
    392  * If set_custom_data has not been called before, return NULL. */
    393 SCAD_API res_T
    394 scad_geometry_get_custom_data
    395   (struct scad_geometry* geometry,
    396    void** data);
    397 
    398 /* Set the name of geometry `geometry'.
    399  * If not NULL, names must be unique. */
    400 SCAD_API res_T
    401 scad_geometry_set_name
    402   (struct scad_geometry* geometry,
    403    const char* name); /* Can be NULL */
    404 
    405 /* Set the name of geometries in `geometries'.
    406  * If `prefix_name' is not NULL, the geometries are named <prefix_name>_<rank>,
    407  * <rank> counting from `from_rank'. Otherwise their names are set to NULL.
    408  * If not NULL, names must be unique. */
    409 SCAD_API res_T
    410 scad_geometries_set_name
    411   (struct scad_geometry** geometries,
    412    const size_t geometries_count,
    413    const char* prefix_name, /* Can be NULL */
    414    const size_t from_rank);
    415 
    416 /* Get a pointer to `geometry's name, NULL if unnamed.
    417  * Note that this reference is only valid during the lifetime of `geometry'
    418  * (don't use name after deleting `geometry'). */
    419 SCAD_API res_T
    420 scad_geometry_get_name
    421   (const struct scad_geometry* geometry,
    422    const char** name);
    423 
    424 /* Swap the internals of geometry pools `pool1' and `pool2'
    425  * (i.e. swap internals of pool1[i] and pool2[i]).
    426  * What is swapped is set using `flags'.
    427  * Pools must have the same `count'. */
    428 SCAD_API res_T
    429 scad_geometries_swap
    430   (struct scad_geometry** pool1,
    431    struct scad_geometry** pool2,
    432    const size_t count,
    433    const int flags);
    434 
    435 /* Get the `mass' of the geometry `geometry'. It means area for a 2D geometry
    436  * and volume for a 3D geometry. */
    437 SCAD_API res_T
    438 scad_geometry_get_mass
    439   (struct scad_geometry* geometry,
    440    double* mass);
    441 
    442 /* Get the center of mass of geometry `geometry' in `center'. */
    443 SCAD_API res_T
    444 scad_geometry_get_centerofmass
    445   (struct scad_geometry* geometry,
    446    double center[3]);
    447 
    448 /* Get the `closest' point on geometry `geometry' from point `from'.
    449  * Return the `closest' point and its `distance'.
    450  * The underlying 2D geometry on wich the closest point is located is returned
    451  * as a new geometry in `underlying_geometry' if it is not NULL.
    452  * If `geometry' is 3D, this underlying geometry is (a part of) its boundary. */
    453 SCAD_API res_T
    454 scad_geometry_get_closest_point
    455   (struct scad_geometry* geometry,
    456    const double from[3],
    457    double closest[3],
    458    double* distance,
    459    struct scad_geometry** underlying_geometry); /* Can be NULL */
    460 
    461 /* Get the normal of the geometry `geometry' at position `p'.
    462  * The normal is set in `N' and the underlying 2D geometry on which `p' is
    463  * located is returned as a new geometry in `underlying_geometry' if it is not
    464  * NULL.
    465  * If `geometry' is 3D, this underlying geometry is (a part of) its boundary.
    466  * Note that the position `p' is supposed to be close enough of `geometry', or
    467  * this operation is meaningless (as the normal is taken on a computed point on
    468  * the geometry that is the closest point from position `p'). */
    469 SCAD_API res_T
    470 scad_geometry_get_normal
    471   (struct scad_geometry* geometry,
    472    const double p[3],
    473    double N[3],
    474    struct scad_geometry** underlying_geometry); /* Can be NULL */
    475 
    476 /* Get the Boundig Box of geometry `geometry' in the form of `min' and `max'
    477  * vectors. */
    478 SCAD_API res_T
    479 scad_geometry_get_bounding_box
    480   (struct scad_geometry* geometry,
    481    double min[3],
    482    double max[3]);
    483 
    484 /* Check if geometries `geom1' and `geom2' share the same content.
    485  * Note that names are not compared, as they CANNOT be the same.
    486  * Also note that copied geometries (scad_geometry_copy) are not equal, as their
    487  * contents are not shared, but are copies.
    488  * On the other hand, collected content (scad_geometries_collect) is equal to
    489  * its source.
    490  * To check if 2 geometries are copies of one another, one as to apply boolean
    491  * operators (e.g. cut) and check the result accordingly (e.g. empty result). */
    492 SCAD_API res_T
    493 scad_geometry_equal
    494   (const struct scad_geometry* geom1,
    495    const struct scad_geometry* geom2,
    496    int* equal);
    497 
    498 /* Check if all the entities of `geometry' are part of one of the geometries in
    499  * `geometries'. */
    500 SCAD_API res_T
    501 scad_geometry_is_included
    502   (const struct scad_geometry* geometry,
    503    struct scad_geometry** geometries,
    504    const size_t geometries_count,
    505    int* included);
    506 
    507 /* Create a new geometry `out_geometry' sharing all the content of geometries in
    508  * `geometries'.
    509  * Note that, while copied geometries (scad_geometry_copy) are not equal as
    510  * their internals are copies (not shared content), collected content
    511  * (scad_geometries_collect) is equal to its source. */
    512 SCAD_API res_T
    513 scad_geometries_collect
    514   (struct scad_geometry** geometries,
    515    const size_t geometries_count,
    516    struct scad_geometry** out_geometry);
    517 
    518 /* Compute the boolean union (the fusion) of the geometries in `geometries' and
    519  * `tools'. */
    520 SCAD_API res_T
    521 scad_geometries_fuse
    522   (struct scad_geometry** geometries,
    523    const size_t geometries_count,
    524    struct scad_geometry** tools,
    525    const size_t tools_count,
    526    struct scad_geometry** out_geometry);
    527 
    528 /* Compute the boolean difference between the geometries in `geometries' and
    529  * `tools'.
    530  * Note that the resulting geometry can be empty. */
    531 SCAD_API res_T
    532 scad_geometries_cut
    533   (struct scad_geometry** geometries,
    534    const size_t geometries_count,
    535    struct scad_geometry** tools,
    536    const size_t tools_count,
    537    struct scad_geometry** out_geometry);
    538 
    539 /* Compute the boolean intersection (the common parts) of the geometries
    540  * in `geometries' and `tools'.
    541  * Note that the resulting geometry can be empty. */
    542 SCAD_API res_T
    543 scad_geometries_intersect
    544   (struct scad_geometry** geometries,
    545    const size_t geometries_count,
    546    struct scad_geometry** tools,
    547    const size_t tools_count,
    548    struct scad_geometry** out_geometry);
    549 
    550 /* Compute the boolean fragments (general fuse) resulting from the
    551  * intersection of the geometries in `geometries', making all interfaces
    552  * conformal.
    553  * `flags' should be made by ORing values from enum scad_partition_flags to
    554  * enable non default behaviours (default is to disallow overlapping).
    555  * The output geometries are created unnamed.
    556  * When applied to geometries of different dimensions, the lower dimensional
    557  * geometries will be automatically embedded in the higher dimensional
    558  * geometries if they are not on their boundary. */
    559 SCAD_API res_T
    560 scad_geometries_partition
    561   (struct scad_geometry** geometries,
    562    const size_t geometries_count,
    563    const int flags,
    564    struct scad_geometry** out_geometries);
    565 
    566 /* Compute boundaries' intersection (the common part) of the geometries in
    567  * `geometries' and `tools'.
    568  * The output geometries are created unnamed.
    569  * The result `out_boundaries' being allocated using the allocator provided when
    570  * initializing star-cad, it should be freed accordingly.
    571  * If there is no common boundary, `out_boundaries' is set to NULL and
    572  * `out_count' is set to 0.
    573  * Note that there is usually no common boundaries between geometries before
    574  * they have been partitioned. */
    575 SCAD_API res_T
    576 scad_geometries_common_boundaries
    577   (struct scad_geometry** geometries,
    578    const size_t geometries_count,
    579    struct scad_geometry** tools,
    580    const size_t tools_count,
    581    struct scad_geometry*** out_boundaries,
    582    size_t *out_count);
    583 
    584 /* Same as above, with the boundary entities collected in a single geometry.
    585  * Note that there is always an output geometry returned is `out_boundary', that
    586  * can be empty (scad_geometry_get_count = 0). */
    587 SCAD_API res_T
    588 scad_geometries_common_boundary
    589   (struct scad_geometry** geometries,
    590    const size_t geometries_count,
    591    struct scad_geometry** tools,
    592    const size_t tools_count,
    593    struct scad_geometry** out_boundary);
    594 
    595 /* Get the boundaries of the geometries in `geometries', considered as a whole.
    596  * The output geometries are created unnamed.
    597  * The result `out_boundaries' being allocated using the allocator provided when
    598  * initializing star-cad, it should be freed accordingly. */
    599 SCAD_API res_T
    600 scad_geometries_boundaries
    601   (struct scad_geometry** geometries,
    602    const size_t geometries_count,
    603    struct scad_geometry*** out_boundaries,
    604    size_t *out_count);
    605 
    606 /* Same as above, with the boundary entities collected in a single geometry.
    607  * Note that there is always an output geometry returned is `out_boundary', that
    608  * can be empty (scad_geometry_get_count = 0). */
    609 SCAD_API res_T
    610 scad_geometries_boundary
    611   (struct scad_geometry** geometries,
    612    const size_t geometries_count,
    613    struct scad_geometry** out_boundary);
    614 
    615 /* Copy the geometry `geometry', except for its name.
    616  * The new geometry remains unnamed. */
    617 SCAD_API res_T
    618 scad_geometry_copy
    619   (const struct scad_geometry* geometry,
    620    struct scad_geometry** out_copy);
    621 
    622 /* Change the visibility of the geometry `geometry'.
    623  * If `recursive' is set, constituents of `geometry' are recursively affected down
    624  * to dim 0 (vertices).
    625  * Can be used in conjunction with option MeshOnlyVisible. */
    626 SCAD_API res_T
    627 scad_geometry_set_visibility
    628   (const struct scad_geometry* geometry,
    629    int visible,
    630    int recursive);
    631 
    632 /* Flag `target' geometries as being the result of applying the `affine'
    633  * tranform to `source' geometries.
    634  * The result is that the mesh generated for `target' is the image on the mesh
    635  * generated for `source' through the `affine' transform.
    636  * Only meaningful for surfaces. If called on a volume, it applies to its 2D
    637  * constituents.
    638  * The two sets of surfaces must match topologically (same number of points,
    639  * etc.). */
    640 SCAD_API res_T
    641 scad_geometries_set_periodic
    642   (struct scad_geometry** source,
    643    const size_t source_count,
    644    struct scad_geometry** target,
    645    const size_t target_count,
    646    double affine[16]);
    647 
    648 /* Set a size modifier for geometries in `geometries'.
    649  * When meshing these geometries, triangles' size will be either size*modifier,
    650  * or modifier where size would be the size of the triangle in the absence of a
    651  * size modifier.
    652  * The size modifier is applied recursively down to dimension 0 (points).
    653  * If multiple size modifiers are applied, the order matters as the last applied
    654  * size modifier remains.
    655  * To reset a size modifier, just apply a new Scad_size_factor modifier of 1. */
    656 SCAD_API res_T
    657 scad_geometries_set_mesh_size_modifier
    658   (struct scad_geometry** geometries,
    659    const size_t geometries_count,
    660    enum scad_size_modifier_type type,
    661    double modifier);
    662 
    663 /* Set a specific mesh algorithm for geometries in `geometries'.
    664  * Only apply to surfaces (dimension 2). If called on a volume, it applies to
    665  * its 2D constituents. */
    666 SCAD_API res_T
    667 scad_geometries_set_mesh_algorithm
    668   (struct scad_geometry** geometries,
    669    const size_t geometries_count,
    670    enum scad_mesh_algorithm algorithm);
    671 
    672 /* Clear the mesh of the geometries in `geometries'.
    673  * Note that the mesh of a geometry can only be cleared if it is not on the
    674  * boundary of another geometry with a non-empty mesh. */
    675 SCAD_API res_T
    676 scad_geometries_clear_mesh
    677   (struct scad_geometry** geometries,
    678    const size_t geometries_count);
    679 
    680 /*******************************************************************************
    681  * I/O API
    682  ******************************************************************************/
    683 
    684 /* Import a step model from file `filename'.
    685  * The imported geometries are recorded in `out_geometries'.
    686  * The output geometries are created unnamed.
    687  * Note that `out_geometries' is allocated using the allocator provided when
    688  * initializing star-cad and should be freed accordingly. */
    689 SCAD_API res_T
    690 scad_step_import
    691   (const char* filename, /* name of step file */
    692    struct scad_geometry*** out_geometries,
    693    size_t* out_count);
    694 
    695 /* Export the mesh of geometry `geometry' to an STL file.
    696  * In order to get a mesh, one has to call scad_scene_mesh before calling this.
    697  * If `filename' is provided it is used to name the file (just adding .stl),
    698  * otherwise the geometry name is used instead (and it is an error if neither
    699  * filename nor the geometry name is defined). Mesh orientation can be forced
    700  * inward or outward only if it defines a closed volume. The file format is
    701  * either binary or ascii, depending on the value of the `binary' argument. */
    702 SCAD_API res_T
    703 scad_stl_export
    704   (struct scad_geometry* geometry,
    705    const char* filename, /* Can be NULL if geometry name is defined */
    706    const enum scad_normals_orientation orientation,
    707    const int binary);
    708 
    709 /* Same as previous, but geometries that are part of `exclude' are not exported. */
    710 SCAD_API res_T
    711 scad_stl_export_partial
    712   (struct scad_geometry* geometry,
    713    struct scad_geometry** exclude, /* Can be NULL */
    714    const size_t exclude_count,
    715    const char* filename, /* Can be NULL if geometry name is defined */
    716    const enum scad_normals_orientation orientation,
    717    const int binary);
    718 
    719 /* Export the geometry `geometry' in as many files than its count.
    720  * The files are named <base>_<rank>.stl, where <base> is either `filename_base'
    721  * (first choice) or `geometry's name, <rank> counting from 0. */
    722 SCAD_API res_T
    723 scad_stl_export_split
    724   (struct scad_geometry* geometry,
    725    const char* filename_base, /* Can be NULL if geometry name is defined */
    726    const enum scad_normals_orientation orientation,
    727    const int binary);
    728 
    729 /* Accumulate the mesh of the geometry `geometry' into `triangles', each triangle
    730  * being described by 9 doubles in a STL way.
    731  * In order to get a mesh, one has to call scad_scene_mesh first. */
    732 SCAD_API res_T
    733 scad_stl_get_data
    734   (struct scad_geometry* geometry,
    735    struct darray_double* triangles);
    736 
    737 /* Same as previous, but geometries in `exclude', that can be 2D and/or 3D, are
    738  * not collected. */
    739 SCAD_API res_T
    740 scad_stl_get_data_partial
    741   (struct scad_geometry* geometry,
    742    struct scad_geometry** exclude, /* Can be NULL */
    743    const size_t exclude_count,
    744    struct darray_double* triangles);
    745 
    746 /* Write a mesh the same way stl_export do, using `triangles' as returned by
    747  * stl_get_data[_partial]. */
    748 SCAD_API res_T
    749 scad_stl_data_write
    750   (const struct darray_double* triangles,
    751    const char* filename,
    752    const enum scad_normals_orientation orientation,
    753    const int binary);
    754 
    755 
    756 /*******************************************************************************
    757  * Debug API
    758  * The following API calls are meant for debugging purposes.
    759  * They can be called from gdb.
    760  ******************************************************************************/
    761 
    762 /* Open gmsh in GUI mode so that the model can be inspected and even modified.
    763  * To use it from gdb:
    764  * Requires a gmsh library (either release or debug version) with FLTK enabled.
    765  * (gdb) call scad_run_ui()
    766  * (then close gmsh and gdb is back to the breakpoint). */
    767 SCAD_API res_T
    768 scad_run_ui
    769   (void);
    770 
    771 /* Explicitly synchronize the current state with regard to recent geometry changes.
    772  * Note however that synchronize calls should be automatically triggered when
    773  * needed.
    774  * To use it from gdb:
    775  * (gdb) call scad_synchronize()
    776  * Only provided as a way to check for auto-synchronize bugs! */
    777 SCAD_API res_T
    778 scad_synchronize
    779   (void);
    780 
    781 /* Get the refcount, as managed by star-cad to trigger remove calls on dim.tag
    782  * OCC internal entities. Return SIZE_MAX if dim.tag is not valid in the OCC
    783  * context.
    784  * To use it from gdb:
    785  * (gdb) call scad_get_dimtag_refcount(3, 1)
    786  * $5 = 7
    787  */
    788 SCAD_API size_t
    789 scad_get_dimtag_refcount
    790   (const int dim,
    791    const int tag);
    792 
    793 /* Dump geometry `geometry' with address/name, ref count and its OCC internal
    794  * dim.tag list.
    795  * To use it from gdb:
    796  * (gdb) call scad_dump_geometry( <geom_ptr> )
    797  */
    798 SCAD_API res_T
    799 scad_dump_geometry
    800   (const struct scad_geometry* geometry);
    801 
    802 /* Dump all the geometries with address/name, ref count and and their OCC
    803  * internal dim.tag lists.
    804  * To use it from gdb:
    805  * (gdb) call scad_dump_geometries()
    806  */
    807 SCAD_API res_T
    808 scad_dump_geometries
    809   (void);
    810 
    811 END_DECLS
    812 
    813 #endif /* SCAD_H */