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:
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;
}