star-cad

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

commit 3af238bfe68a255d3a52c8bc940b4cba108b9865
parent cf82a42b497d7f8df78acbd0c5b38b0c91e2ddfe
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Fri, 20 Dec 2024 11:05:59 +0100

Rework the API call that changes mesh size by geometry

The new API call allows to either set an absolute size, or a
multiplicative factor as in the earlier version.

Diffstat:
Msrc/scad.h | 27++++++++++++++++++---------
Msrc/scad_device.c | 16++++++++--------
Msrc/scad_device.h | 4++--
Msrc/scad_geometry.c | 33++++++++++++++++++++-------------
4 files changed, 48 insertions(+), 32 deletions(-)

diff --git a/src/scad.h b/src/scad.h @@ -85,6 +85,13 @@ enum scad_log_refcounting { Scad_log_geometry = BIT(2) }; +/* A type to specify the kind of mesh size specification set by a call to the + * scad_geometries_set_mesh_size_modifier API call */ +enum scad_size_modifier_type { + Scad_absolute_size, + Scad_size_factor +}; + /* A type to specify options for the gmsh library */ struct scad_options { struct { @@ -548,18 +555,20 @@ SCAD_API res_T scad_scene_mesh (void); -/* Set a size factor for geometries in `geometries'. - * When meshing these geometries, triangles' size will be size*factor, where - * size would be the size of the triangle in the absence of a size factor. - * The size factor is applied recursively down to dimension 0 (points). - * If multiple size factors are applied, the order in which size factors are - * applied matters, as the last applied size factor remains. - * To reset a size factor, just apply a new factor of 1. */ +/* Set a size modifier for geometries in `geometries'. + * When meshing these geometries, triangles' size will be either size*modifier, + * or modifier where size would be the size of the triangle in the absence of a + * size modifier. + * The size modifier is applied recursively down to dimension 0 (points). + * If multiple size modifiers are applied, the order matters as the last applied + * size modifier remains. + * To reset a size modifier, just apply a new Scad_size_factor modifier of 1. */ SCAD_API res_T -scad_geometries_set_mesh_size_factor +scad_geometries_set_mesh_size_modifier (struct scad_geometry** geometries, const size_t geometries_count, - double factor); + enum scad_size_modifier_type type, + double modifier); /* Clear the mesh of the geometries in `geometries'. * Note that the mesh of a geometry can only be cleared if it is not on the diff --git a/src/scad_device.c b/src/scad_device.c @@ -120,10 +120,10 @@ device_release(struct scad_device* dev) htable_geometries_release(&dev->allgeom); device_release_tags_of_dim(dev, 2); device_release_tags_of_dim(dev, 3); - htable_size_factors_release(&dev->size_factors_by_dim[0]); - htable_size_factors_release(&dev->size_factors_by_dim[1]); - htable_size_factors_release(&dev->size_factors_by_dim[2]); - htable_size_factors_release(&dev->size_factors_by_dim[3]); + htable_size_modifiers_release(&dev->size_modifiers_by_dim[0]); + htable_size_modifiers_release(&dev->size_modifiers_by_dim[1]); + htable_size_modifiers_release(&dev->size_modifiers_by_dim[2]); + htable_size_modifiers_release(&dev->size_modifiers_by_dim[3]); if(log) { logger_print(dev->logger, log_type, "End finalizing scad.\n"); } @@ -601,10 +601,10 @@ scad_initialize htable_geometries_init(allocator, &g_device->allgeom); htable_tags2desc_init(allocator, &g_device->tags2desc[0]); htable_tags2desc_init(allocator, &g_device->tags2desc[1]); - htable_size_factors_init(allocator, &g_device->size_factors_by_dim[0]); - htable_size_factors_init(allocator, &g_device->size_factors_by_dim[1]); - htable_size_factors_init(allocator, &g_device->size_factors_by_dim[2]); - htable_size_factors_init(allocator, &g_device->size_factors_by_dim[3]); + htable_size_modifiers_init(allocator, &g_device->size_modifiers_by_dim[0]); + htable_size_modifiers_init(allocator, &g_device->size_modifiers_by_dim[1]); + htable_size_modifiers_init(allocator, &g_device->size_modifiers_by_dim[2]); + htable_size_modifiers_init(allocator, &g_device->size_modifiers_by_dim[3]); /* Init to default */ scad_set_options(NULL); diff --git a/src/scad_device.h b/src/scad_device.h @@ -115,7 +115,7 @@ tag_desc_copy_and_release #define HTABLE_DATA_FUNCTOR_COPY_AND_RELEASE tag_desc_copy_and_release #include <rsys/hash_table.h> -#define HTABLE_NAME size_factors +#define HTABLE_NAME size_modifiers #define HTABLE_KEY int #define HTABLE_DATA double #include <rsys/hash_table.h> @@ -127,7 +127,7 @@ struct scad_device { struct htable_names geometry_names; struct htable_geometries allgeom; struct htable_tags2desc tags2desc[2]; /* Only geoms for 2D and 3D tags for now */ - struct htable_size_factors size_factors_by_dim[4]; + struct htable_size_modifiers size_modifiers_by_dim[4]; int verbose; int need_synchro; diff --git a/src/scad_geometry.c b/src/scad_geometry.c @@ -355,9 +355,14 @@ static double size_callback (int dim, int tag, double x, double y, double z, double lc, void* data_) { struct scad_device* dev = get_device(); - double *factor = htable_size_factors_find(dev->size_factors_by_dim + dim, &tag); + double *modifier = + htable_size_modifiers_find(dev->size_modifiers_by_dim + dim, &tag); (void)x;(void)y;(void)z;(void)data_; - return (factor ? *factor * lc : lc); + if(!modifier) + return lc; /* No modifier defined */ + if(*modifier < 0) + return -(*modifier); /* Absolute size modifier */ + return (*modifier) * lc; /* Size factor modifier */ } /* gmsh documentation states that memory allocated by gmsh should be freed using @@ -1683,7 +1688,7 @@ scad_geometry_extrude ERR(gmsh_err_to_res_T(ierr)); get_device()->need_synchro = 1; - /* Output includes both the 3D result and its 2D constituants. + /* Output includes both the 3D result and its 2D constituents. * Keep only 3D entities. */ for(i = 0; i < tagoutn; i += 2) { int dim = tagout[i]; @@ -2690,10 +2695,11 @@ error: } res_T -scad_geometries_set_mesh_size_factor +scad_geometries_set_mesh_size_modifier (struct scad_geometry** geometries, const size_t geometries_count, - double factor) + enum scad_size_modifier_type type, + double modifier) { res_T res = RES_OK; struct scad_device* dev = get_device(); @@ -2701,7 +2707,7 @@ scad_geometries_set_mesh_size_factor int* tagout[4] = { NULL, NULL, NULL, NULL }; size_t tagoutn[4] = { 0, 0, 0, 0}, i; - if(!geometries || geometries_count == 0 || factor <= 0) { + if(!geometries || geometries_count == 0 || modifier <= 0) { res = RES_BAD_ARG; goto error; } @@ -2709,25 +2715,26 @@ scad_geometries_set_mesh_size_factor ERR(check_device(FUNC_NAME)); ERR(gather_tags_recursive(geometries, geometries_count, tagout, tagoutn)); + if(type == Scad_absolute_size) modifier = -modifier; for(dim = 0; dim < 4; dim++) { for(i = 0; i < tagoutn[dim]; i += 2) { int d = tagout[dim][i]; int tag = tagout[dim][i+1]; - struct htable_size_factors* factors = dev->size_factors_by_dim + dim; - double* f_ptr = htable_size_factors_find(factors, &tag); + struct htable_size_modifiers* modifiers = dev->size_modifiers_by_dim + dim; + double* f_ptr = htable_size_modifiers_find(modifiers, &tag); ASSERT(d == dim); - if(f_ptr && factor == 1) { - size_t c = htable_size_factors_erase(factors, &tag); + if(f_ptr && modifier == 1) { /* Size factor of 1 => no modifier */ + size_t c = htable_size_modifiers_erase(modifiers, &tag); ASSERT(c == 1); } else if(f_ptr) { - *f_ptr = factor; + *f_ptr = modifier; } else { - ERR(htable_size_factors_set(factors, &tag, &factor)); + ERR(htable_size_modifiers_set(modifiers, &tag, &modifier)); } } } for(dim = 0; dim < 4; dim++) { - if(htable_size_factors_size_get(dev->size_factors_by_dim + dim) > 0) { + if(htable_size_modifiers_size_get(dev->size_modifiers_by_dim + dim) > 0) { some = 1; break; }