star-cad

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

commit 6f3f53d6e9035f53f8000bd578b7a5188abe47e2
parent 8e1bb60c82bd3ef91ba6250f94d67770149277af
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Mon, 16 Jun 2025 09:45:17 +0200

Some more changes in scad.h

Some more renaming, moves and comments improvements

Diffstat:
Msrc/scad.h | 352+++++++++++++++++++++++++++++++++++++++++--------------------------------------
Msrc/scad_geometry.c | 6+++---
Msrc/test_api.c | 8++++----
Msrc/test_export.c | 6+++---
Msrc/test_export2.c | 6+++---
Msrc/test_lifetime.c | 2+-
Msrc/test_periodic.c | 8++++----
7 files changed, 202 insertions(+), 186 deletions(-)

diff --git a/src/scad.h b/src/scad.h @@ -116,10 +116,14 @@ struct scad_options { int OCCParallel; } Geometry; struct { - int Step; /* Run UI when entering any scad API function; requires a FLTK-enabled gmsh build */ + /* Run UI when entering any scad API function; requires a FLTK-enabled gmsh build */ + int Step; + /* Call synchronize first when runui is called */ int SynchronizeOnRunUI; + /* Log ref counting operations on geometries (lot of logs expected) */ enum scad_log_refcounting LogRefCounting; - int DebugOpenCascadeSync; /* Systematic call to synchronize; if results change there is a sync bug in star-cad! */ + /* Systematic call to synchronize; if results change there is a sync bug in star-cad! */ + int DebugOpenCascadeSync; } Misc; }; @@ -205,8 +209,9 @@ scad_scene_write /* Create the mesh of the whole scene. * Note that, due to gmsh capabilities, there is no way to mesh a given list of - * geometries. To avoid meshing useless geometries you can release them using - * scad_geometry_ref_put before meshing. */ + * geometries. To avoid meshing useless geometries you can either release them + * using scad_geometry_ref_put before meshing, or turn them not-visible using + * visibility API. */ SCAD_API res_T scad_scene_mesh (void); @@ -216,44 +221,151 @@ scad_scene_mesh * result of an operation on geometries. ******************************************************************************/ -/* Ref counting of geometries: get a new reference to goemetry `geom'. */ +/* Add a rectangle to the scene, defined by a point `xyz' and + * `dxdy' the extents along the x-, y-axes. */ +SCAD_API res_T +scad_add_rectangle + (const double xyz[3], + const double dxdy[2], + struct scad_geometry** rectangle); + +/* Add a disk in (xy) plane to the scene, defined by a the center `xyz' and + * `radius'. */ +SCAD_API res_T +scad_add_disk + (const double xyz[3], + const double radius, + struct scad_geometry** disk); + +/* Add a polygon in the (xy) plane to the scene. + * The `polygon' has `count' vertice and is at elevation `z', the vertice are + * defined by calls to user-provided function `get_position'. */ +SCAD_API res_T +scad_add_polygon + (void (*get_position)(const size_t ivert, double pos[2], void* data), + void* data, /* Custom data; can be NULL if get_position don't use it */ + const double z, + const size_t count, + struct scad_geometry** polygon); + +/* Add a parallelepipedic `box' to the scene, defined by a point `xyz' and + * `dxdydz' the extents along the x-, y- and z-axes. */ +SCAD_API res_T +scad_add_box + (const double xyz[3], + const double dxdydz[3], + struct scad_geometry** box); + +/* Add a `cylinder' to the scene, defined by the center `xyz' of its first + * circular face, the vector `axis' defining its axis and its radius `rad'. The + * `angle' argument defines the angular opening (from 0 to 2*PI). */ +SCAD_API res_T +scad_add_cylinder + (const double xyz[3], + const double axis[3], + const double radius, + const double angle, + struct scad_geometry** cylinder); + +/* Add a `sphere' of center `xyz' and radius `rad' to the scene. */ +SCAD_API res_T +scad_add_sphere + (const double xyz[3], + const double radius, + struct scad_geometry** sphere); + +/* Scale the geometry `geometry' by factors `scale' along the three coordinate axes; + * Use `center', as the center of the homothetic transformation. */ +SCAD_API res_T +scad_geometry_dilate + (const struct scad_geometry* geometry, + const double center[3], + const double scale[3], + struct scad_geometry** out_geometry); + +/* Translate the geometry `geometry' along (`dx', `dy', `dz'). */ +SCAD_API res_T +scad_geometry_translate + (const struct scad_geometry* geometry, + const double dxdydz[3], + struct scad_geometry** out_geometry); + +/* Rotate the geometry `geometry' by `angle' radians around the axis of revolution + * defined by the point `pt' and the direction `dir'. */ +SCAD_API res_T +scad_geometry_rotate + (const struct scad_geometry* geometry, + const double pt[3], + const double dir[3], + const double angle, + struct scad_geometry** out_geometry); + +/* Extrude the geometry `geometry' using a translation along (`dx', `dy', `dz'). */ +SCAD_API res_T +scad_geometry_extrude + (const struct scad_geometry* geometry, + const double dxdydz[3], + struct scad_geometry** out_geometry); + +/* Return a list of geometries which form the geometry `geometry'. + * The output geometries are named <base>_<rank>, where <base> is either + * prefix_name (first choice) or geom's name, <rank> counting from 0. Otherwise + * they remain unnamed. + * Whatever the names, if defined they must be unique. + * The result `out_geometries' being allocated using the allocator provided when + * initializing star-cad, it should be freed accordingly. */ +SCAD_API res_T +scad_geometry_explode + (const char* prefix_name, /* Can be NULL */ + const struct scad_geometry* geometry, + struct scad_geometry*** out_geometries, + size_t* out_count); + +/* Ref counting of geometries: get a new reference to goemetry `geometry'. */ SCAD_API res_T scad_geometry_ref_get - (struct scad_geometry* geom); + (struct scad_geometry* geometry); -/* Ref counting of geometries: release a reference to goemetry `geom'. */ +/* Ref counting of geometries: release a reference to goemetry `geometry'. */ SCAD_API res_T scad_geometry_ref_put - (struct scad_geometry* geom); + (struct scad_geometry* geometry); -/* Get the number of components of the geometry `geom'. */ +/* Get the number of components of the geometry `geometry'. */ SCAD_API res_T scad_geometry_get_count - (const struct scad_geometry* geom, + (const struct scad_geometry* geometry, size_t* count); -/* Attach some custom data `data' to geometry `geom'. - * If provided, release() is called when `geom' is released or if +/* Attach some custom data `data' to geometry `geometry'. + * If provided, release() is called when `geometry' is released or if * set_custom_data is called again. */ SCAD_API res_T scad_geometry_set_custom_data - (struct scad_geometry* geom, + (struct scad_geometry* geometry, void (*release) (void* data), /* Can be NULL */ void* data); /* Can be NULL */ -/* Get the custom data attached to geometry `geom'. +/* Get the custom data attached to geometry `geometry'. * If set_custom_data has not been called before, return NULL. */ SCAD_API res_T scad_geometry_get_custom_data - (struct scad_geometry* geom, + (struct scad_geometry* geometry, void** data); -/* Get a pointer to `geom's name, NULL if unnamed. - * Note that this reference is only valid during the lifetime of `geom' (don't - * use name after deleting `geom'). */ +/* Set the name of geometry `geometry'. + * If not NULL, names must be unique. */ +SCAD_API res_T +scad_geometry_set_name + (struct scad_geometry* geometry, + const char* name); /* Can be NULL */ + +/* Get a pointer to `geometry's name, NULL if unnamed. + * Note that this reference is only valid during the lifetime of `geometry' + * (don't use name after deleting `geometry'). */ SCAD_API res_T scad_geometry_get_name - (const struct scad_geometry* geom, + (const struct scad_geometry* geometry, const char** name); /* Swap the internals of geometry pools `pool1' and `pool2' @@ -267,98 +379,58 @@ scad_geometries_swap const size_t count, const int flags); -/* Get the `mass' of the geometry `geom'. It means area for a 2D geometry and - * volume for a 3D geometry. */ +/* Get the `mass' of the geometry `geometry'. It means area for a 2D geometry + * and volume for a 3D geometry. */ SCAD_API res_T scad_geometry_get_mass - (struct scad_geometry* geom, + (struct scad_geometry* geometry, double* mass); -/* Get the center of mass of the various components of geometry `geom'. +/* Get the center of mass of the various components of geometry `geometry'. * Note that `center' must be allocated by the caller with enough room for (at * least) 3 times the count of geom (scad_geometry_get_count) doubles. */ SCAD_API res_T scad_geometry_get_centerofmass - (struct scad_geometry* geom, + (struct scad_geometry* geometry, double* center); -/* Get the `closest- point on geometry `geom' from point `from' and its +/* Get the `closest- point on geometry `geometry' from point `from' and its * `distance'. */ SCAD_API res_T scad_geometry_get_closest_point - (struct scad_geometry* geom, + (struct scad_geometry* geometry, const double from[3], double closest[3], double* distance); -/* Get the Boundig Box of geometry `geom' in the form of `min' and `max' +/* Get the normal of the geometry `geometry' at position `p'. + * The normal is set in `N' and the underlying 2D entity to which `p' belongs is + * returned as a new geometry in `out_geometry'. */ +SCAD_API res_T +scad_geometry_get_normal + (struct scad_geometry* geometry, + double p[3], + double N[3], + struct scad_geometry** out_geometry); + +/* Get the Boundig Box of geometry `geometry' in the form of `min' and `max' * vectors. */ SCAD_API res_T scad_geometry_get_bounding_box - (struct scad_geometry* geom, + (struct scad_geometry* geometry, double min[3], double max[3]); -/* Add a rectangle to the scene, defined by a point `xyz' and - * `dxdy' the extents along the x-, y-axes. */ +/* Check if geometries `geom1' and `geom2' share the same content. + * Note that names are not compared, as they CANNOT be the same. + * Also note that copied geometries (scad_geometry_copy) are not equal, as their + * contents are not shared, but are copies. + * On the other hand, collected content (scad_geometries_collect) is equal to + * its source. + * To check if 2 geometries are copies of one another, one as to apply boolean + * operators (e.g. cut) and check the result accordingly (e.g. empty result). */ SCAD_API res_T -scad_add_rectangle - (const double xyz[3], - const double dxdy[2], - struct scad_geometry** rectangle); - -/* Add a disk in (xy) plane to the scene, defined by a the center `xyz' and - * `radius'. */ -SCAD_API res_T -scad_add_disk - (const double xyz[3], - const double radius, - struct scad_geometry** disk); - -/* Add a polygon in the (xy) plane to the scene. - * The `polygon' has `count' vertice and is at elevation `z', the vertice are - * defined by calls to user-provided function `get_position'. */ -SCAD_API res_T -scad_add_polygon - (void (*get_position)(const size_t ivert, double pos[2], void* data), - void* data, /* Custom data; can be NULL if get_position don't use it */ - const double z, - const size_t count, - struct scad_geometry** polygon); - -/* Add a parallelepipedic `box' to the scene, defined by a point `xyz' and - * `dxdydz' the extents along the x-, y- and z-axes. */ -SCAD_API res_T -scad_add_box - (const double xyz[3], - const double dxdydz[3], - struct scad_geometry** box); - -/* Add a `cylinder' to the scene, defined by the center `xyz' of its first - * circular face, the vector `axis' defining its axis and its radius `rad'. The - * `angle' argument defines the angular opening (from 0 to 2*PI). */ -SCAD_API res_T -scad_add_cylinder - (const double xyz[3], - const double axis[3], - const double radius, - const double angle, - struct scad_geometry** cylinder); - -/* Add a `sphere' of center `xyz' and radius `rad' to the scene. */ -SCAD_API res_T -scad_add_sphere - (const double xyz[3], - const double radius, - struct scad_geometry** sphere); - -/* Check if geometries `geom1' and `geom2' have the same content, that is - * are the same scad_geometries (trivial case), or contain the same internal - * entities. - * To check if 2 geometries are "equivalent", one as to apply boolean operators - * (e.g. cut) and check the result accordingly (e.g. empty result). */ -SCAD_API res_T -scad_geometries_equal +scad_geometry_equal (const struct scad_geometry* geom1, const struct scad_geometry* geom2, int* equal); @@ -372,8 +444,12 @@ scad_geometry_is_included const size_t geometries_count, int* included); -/* Create a new geometry `out_geometry' made from all the entities from - * `geometries'. */ + +/* Create a new geometry `out_geometry' sharing all the content of geometries in + * `geometries'. + * Note that, while copied geometries (scad_geometry_copy) are not equal as + * their internals are copies (not shared content), collected content + * (scad_geometries_collect) is equal to its source. */ SCAD_API res_T scad_geometries_collect (struct scad_geometry** geometries, @@ -461,77 +537,23 @@ scad_geometries_boundary struct scad_geometry*** out_boundaries, size_t *out_count); -/* Copy the geometry `geom', except for its name. +/* Copy the geometry `geometry', except for its name. * The new geometry remains unnamed. */ SCAD_API res_T scad_geometry_copy - (const struct scad_geometry* geom, + (const struct scad_geometry* geometry, struct scad_geometry** out_copy); -/* Change the visibility of the geometry `geom'. - * If `recursive' is set, constituents of `geom' are recursively affected down +/* Change the visibility of the geometry `geometry'. + * If `recursive' is set, constituents of `geometry' are recursively affected down * to dim 0 (vertices). * Can be used in conjunction with option MeshOnlyVisible. */ SCAD_API res_T scad_geometry_set_visibility - (const struct scad_geometry* geom, + (const struct scad_geometry* geometry, int visible, int recursive); -/* Rename geometry `geom'. - * If not NULL, names must be unique. */ -SCAD_API res_T -scad_geometry_rename - (struct scad_geometry* geom, - const char* name); /* Can be NULL */ - -/* Scale the geometry `geom' by factors `scale' along the three coordinate axes; - * Use `center', as the center of the homothetic transformation. */ -SCAD_API res_T -scad_geometry_dilate - (const struct scad_geometry* geom, - const double center[3], - const double scale[3], - struct scad_geometry** out_geometry); - -/* Translate the geometry `geom' along (`dx', `dy', `dz'). */ -SCAD_API res_T -scad_geometry_translate - (const struct scad_geometry* geom, - const double dxdydz[3], - struct scad_geometry** out_geometry); - -/* Rotate the geometry `geom' by `angle' radians around the axis of revolution - * defined by the point `pt' and the direction `dir'. */ -SCAD_API res_T -scad_geometry_rotate - (const struct scad_geometry* geom, - const double pt[3], - const double dir[3], - const double angle, - struct scad_geometry** out_geometry); - -/* Extrude the geometry `geom' using a translation along (`dx', `dy', `dz'). */ -SCAD_API res_T -scad_geometry_extrude - (const struct scad_geometry* geom, - const double dxdydz[3], - struct scad_geometry** out_geometry); - -/* Return a list of geometries which form the geometry `geom'. - * The output geometries are named <base>_<rank>, where <base> is either - * prefix_name (first choice) or geom's name, <rank> counting from 0. Otherwise - * they remain unnamed. - * Whatever the names, if defined they must be unique. - * The result `out_geometries' being allocated using the allocator provided when - * initializing star-cad, it should be freed accordingly. */ -SCAD_API res_T -scad_geometry_explode - (const char* prefix_name, /* Can be NULL */ - const struct scad_geometry* geom, - struct scad_geometry*** out_geometries, - size_t* out_count); - /* Flag `target' geometries as being the result of applying the `affine' * tranform to `source' geometries. * The result is that the mesh generated for `target' is the image on the mesh @@ -580,16 +602,6 @@ scad_geometries_clear_mesh (struct scad_geometry** geometries, const size_t geometries_count); -/* Get the normal of the geometry `geom' at position `p'. - * The normal is set in `N' and the underlying 2D entity to which `p' belongs is - * returned as a new geometry in `out_geometry'. */ -SCAD_API res_T -scad_geometry_normal - (struct scad_geometry* geom, - double p[3], - double N[3], - struct scad_geometry** out_geometry); - /******************************************************************************* * I/O API ******************************************************************************/ @@ -608,7 +620,7 @@ scad_step_import struct scad_geometry*** out_geometries, size_t* out_count); -/* Export the mesh of geometry `geom' to an STL file. +/* Export the mesh of geometry `geometry' to an STL file. * In order to get a mesh, one has to call scad_scene_mesh before calling this. * If `filename' is provided it is used to name the file (just adding .stl), * otherwise the geometry name is used instead (and it is an error if neither @@ -617,7 +629,7 @@ scad_step_import * either binary or ascii, depending on the value of the `binary' argument. */ SCAD_API res_T scad_stl_export - (struct scad_geometry* geom, + (struct scad_geometry* geometry, const char* filename, const enum scad_normals_orientation orientation, const int binary); /* File format */ @@ -632,22 +644,22 @@ scad_stl_export_partial const enum scad_normals_orientation orientation, const int binary); -/* Export the geometry `geom' in as many files than its count. +/* Export the geometry `geometry' in as many files than its count. * The files are named <base>_<rank>.stl, where <base> is either filename (first * choice) or geom's name, <rank> counting from 0. */ SCAD_API res_T scad_stl_export_split - (struct scad_geometry* geom, + (struct scad_geometry* geometry, const char* filename, const enum scad_normals_orientation orientation, const int binary); /* File format */ -/* Accumulate the mesh of the geometry `geom' into `triangles', each triangle +/* Accumulate the mesh of the geometry `geometry' into `triangles', each triangle * being described by 9 doubles in a STL way. * In order to get a mesh, one has to call scad_scene_mesh first. */ SCAD_API res_T scad_stl_get_data - (struct scad_geometry* geom, + (struct scad_geometry* geometry, struct darray_double* triangles); /* Same as previous, but geometries in `exclude', that can be 2D and/or 3D, are @@ -668,8 +680,12 @@ scad_stl_data_write const enum scad_normals_orientation orientation, const int binary); -/* The following API calls are meant for debugging purposes. - * They can be called from gdb. */ + +/******************************************************************************* + * Debug API + * The following API calls are meant for debugging purposes. + * They can be called from gdb. + ******************************************************************************/ /* Open gmsh in GUI mode so that the model can be inspected and even modified. * To use it from gdb: @@ -702,14 +718,14 @@ scad_get_dimtag_refcount (const int dim, const int tag); -/* Dump geometry `geom' with address/name, ref count and its OCC internal +/* Dump geometry `geometry' with address/name, ref count and its OCC internal * dim.tag list. * To use it from gdb: * (gdb) call scad_dump_geometry( <geom_ptr> ) */ SCAD_API res_T scad_dump_geometry - (const struct scad_geometry* geom); + (const struct scad_geometry* geometry); /* Dump all the geometries with address/name, ref count and and their OCC * internal dim.tag lists. diff --git a/src/scad_geometry.c b/src/scad_geometry.c @@ -1162,7 +1162,7 @@ error: } SCAD_API res_T -scad_geometries_equal +scad_geometry_equal (const struct scad_geometry* geom1, const struct scad_geometry* geom2, int* equal) @@ -1994,7 +1994,7 @@ error: } res_T -scad_geometry_rename +scad_geometry_set_name (struct scad_geometry* geom, const char* name) /* Can be NULL */ { @@ -2670,7 +2670,7 @@ error: } res_T -scad_geometry_normal +scad_geometry_get_normal (struct scad_geometry* geom, double p[3], double N[3], diff --git a/src/test_api.c b/src/test_api.c @@ -218,10 +218,10 @@ main(int argc, char* argv[]) OK(scad_geometry_copy(geom1, &geom)); OK(scad_geometry_ref_put(geom)); - BAD(scad_geometry_rename(NULL, NULL)); - OK(scad_geometry_rename(geom1, "sphere 1")); - BAD(scad_geometry_rename(geom2, "sphere 1")); /* Name already in use */ - OK(scad_geometry_rename(geom2, NULL)); + BAD(scad_geometry_set_name(NULL, NULL)); + OK(scad_geometry_set_name(geom1, "sphere 1")); + BAD(scad_geometry_set_name(geom2, "sphere 1")); /* Name already in use */ + OK(scad_geometry_set_name(geom2, NULL)); BAD(scad_geometry_translate(NULL, NULL, NULL)); BAD(scad_geometry_translate(NULL, NULL, &geom)); diff --git a/src/test_export.c b/src/test_export.c @@ -42,14 +42,14 @@ main(int argc, char* argv[]) OK(scad_initialize(NULL, &allocator, 3)); OK(scad_add_rectangle(p1, d1, &rectangle)); - OK(scad_geometry_rename(rectangle, "rectangle")); + OK(scad_geometry_set_name(rectangle, "rectangle")); OK(scad_add_box(p1, d1, &cube)); - OK(scad_geometry_rename(cube, "cube")); + OK(scad_geometry_set_name(cube, "cube")); OK(scad_add_cylinder(p2, d1, 0.5, 2*PI, geoms+1)); geoms[0] = cube; OK(scad_geometries_fuse(geoms, 1, geoms+1, 1, &fused)); - OK(scad_geometry_rename(fused, "fused")); + OK(scad_geometry_set_name(fused, "fused")); OK(scad_scene_mesh()); diff --git a/src/test_export2.c b/src/test_export2.c @@ -63,11 +63,11 @@ main(int argc, char* argv[]) OK(scad_initialize(NULL, &allocator, 3)); OK(scad_add_box(p1, d1, &cube1)); - OK(scad_geometry_rename(cube1, "cube1")); + OK(scad_geometry_set_name(cube1, "cube1")); OK(scad_add_box(p2, d2, &cube2)); - OK(scad_geometry_rename(cube2, "cube2")); + OK(scad_geometry_set_name(cube2, "cube2")); OK(scad_add_box(p3, d3, &cube3)); - OK(scad_geometry_rename(cube3, "cube3")); + OK(scad_geometry_set_name(cube3, "cube3")); OK(scad_scene_mesh()); diff --git a/src/test_lifetime.c b/src/test_lifetime.c @@ -107,7 +107,7 @@ main(int argc, char* argv[]) OK(scad_geometry_get_count(list[i], &center_n)); ASSERT(center_n == 1); OK(scad_geometry_get_centerofmass(list[i], center)); - OK(scad_geometry_normal(list[i], center, N, &geom)); + OK(scad_geometry_get_normal(list[i], center, N, &geom)); } OK(scad_geometry_ref_put(geom)); for(i = 0; i < list_n; i++) { diff --git a/src/test_periodic.c b/src/test_periodic.c @@ -59,26 +59,26 @@ main(int argc, char* argv[]) if(fabs(center[0] - p1[0]) < FLT_EPSILON) { ASSERT(lat[0] == NULL); lat[0] = f; - OK(scad_geometry_rename(f, "left_side")); + OK(scad_geometry_set_name(f, "left_side")); continue; } if(fabs(center[0] - p2[0]) < FLT_EPSILON) { ASSERT(lat[1] == NULL); lat[1] = f; - OK(scad_geometry_rename(f, "right_side")); + OK(scad_geometry_set_name(f, "right_side")); continue; } scad_geometry_get_mass(f, &m); if(fabs(m - len*2*PI*r1) < FLT_EPSILON) { ASSERT(internal == NULL); internal = f; - OK(scad_geometry_rename(f, "internal")); + OK(scad_geometry_set_name(f, "internal")); continue; } if(fabs(m - len*2*PI*r2) < FLT_EPSILON) { ASSERT(external == NULL); external = f; - OK(scad_geometry_rename(f, "external")); + OK(scad_geometry_set_name(f, "external")); continue; } }