commit 960e7c5329933d5640dd58084801a86c8bafb20b
parent cc06c7f53b665fa8d2bd643c6d05581f66441623
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Thu, 31 Aug 2023 09:48:04 +0200
Change geometry swap to allow to swap names and/or geometry
Diffstat:
2 files changed, 146 insertions(+), 43 deletions(-)
diff --git a/src/scad.h b/src/scad.h
@@ -121,6 +121,12 @@ struct scad_options {
static const struct scad_options SCAD_DEFAULT_OPTIONS = SCAD_DEFAULT_OPTIONS__;
+/* A type to specify what to swap in geometries_swap calls */
+enum scad_swap_elements {
+ Scad_swap_name = BIT(0),
+ Scad_swap_geometry = BIT(1)
+};
+
BEGIN_DECLS
/*******************************************************************************
@@ -184,11 +190,14 @@ scad_geometry_get_name
(const struct scad_geometry* geom,
const char** name);
-/* Swap names of `geom1' and `geom2' */
+/* Swap the internals of geometry pools (swap pool1[i] and pool2[i]); what is
+ * swapped is set usig flags. Pools must have the same count. */
SCAD_API res_T
-scad_geometry_swap_names
- (struct scad_geometry* geom1,
- struct scad_geometry* geom2);
+scad_geometries_swap
+ (struct scad_geometry** pool1,
+ struct scad_geometry** pool2,
+ 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. */
diff --git a/src/scad_geometry.c b/src/scad_geometry.c
@@ -410,45 +410,6 @@ error:
}
res_T
-scad_geometry_swap_names
- (struct scad_geometry* geom1,
- struct scad_geometry* geom2)
-{
- res_T res = RES_OK;
- int init = 0;
- struct str tmp;
- struct scad_device* dev = get_device();
- struct mem_allocator* allocator = NULL;
-
- if(!geom1 || !geom2) {
- res = RES_BAD_ARG;
- goto error;
- }
-
- ERR(check_device(FUNC_NAME));
- allocator = dev->allocator;
-
- if(!str_is_empty(&geom1->name)) {
- ERR(htable_names_set(&dev->geometry_names, &geom1->name, &geom2));
- }
- if(!str_is_empty(&geom2->name)) {
- ERR(htable_names_set(&dev->geometry_names, &geom2->name, &geom1));
- }
-
- str_init(allocator, & tmp);
- init = 1;
- ERR(str_copy(&tmp, &geom1->name));
- ERR(str_copy(&geom1->name, &geom2->name));
- ERR(str_copy(&geom2->name, &tmp));
-
-exit:
- if(init) str_release(&tmp);
- return res;
-error:
- goto exit;
-}
-
-res_T
scad_geometry_get_mass
(struct scad_geometry* geom,
double* mass)
@@ -1639,6 +1600,139 @@ error:
}
res_T
+scad_geometries_swap
+ (struct scad_geometry** pool1,
+ struct scad_geometry** pool2,
+ const size_t count,
+ const int flags)
+{
+ res_T res = RES_OK;
+ struct scad_device* dev = get_device();
+ size_t i;
+ struct mem_allocator* allocator = NULL;
+ struct str tmp, msg;
+
+ if(!pool1 || !pool2) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ allocator = dev->allocator;
+ if(flags & Scad_swap_name) str_init(allocator, &tmp);
+ if(flags & Scad_swap_geometry && dev->log) str_init(allocator, &msg);
+ for(i = 0; i < count; i++) {
+ struct scad_geometry *g1 = pool1[i], *g2 = pool2[i];
+ size_t c1 = g1->gmsh_dimTags_n, c2 = g2->gmsh_dimTags_n;
+ int *dt1 = g1->gmsh_dimTags, *dt2 = g2->gmsh_dimTags;
+ if(pool1[i] == pool2[i]) continue;
+ /* Swap content according to flags. Don't swap refcount! */
+ if(flags & Scad_swap_name) {
+ if(dev->log) {
+ if(str_is_empty(&g1->name) && str_is_empty(&g2->name)) {
+ /* Do nothing */
+ }
+ else if(str_is_empty(&g1->name)) {
+ logger_print(dev->logger, dev->log_type,
+ "Swapping names for geometry %p and geometry '%s'.\n",
+ (void*)g1, str_cget(&g2->name));
+ logger_print(dev->logger, dev->log_type,
+ "Geometry '%s' is now unnamed geometry %p.\n",
+ str_cget(&g2->name), (void*)g2);
+ }
+ else if(str_is_empty(&g2->name)) {
+ logger_print(dev->logger, dev->log_type,
+ "Swapping names for geometry %p and geometry '%s'.\n",
+ (void*)g2, str_cget(&g1->name));
+ logger_print(dev->logger, dev->log_type,
+ "Geometry '%s' is now unnamed geometry %p.\n",
+ str_cget(&g1->name), (void*)g1);
+ } else { /* Both named */
+ logger_print(dev->logger, dev->log_type,
+ "Swapping names for geometries '%s' and '%s'.\n",
+ str_cget(&g1->name), str_cget(&g1->name));
+ }
+ }
+ if(!str_is_empty(&g1->name)) {
+ ERR(htable_names_set(&dev->geometry_names, &g1->name, &g2));
+ }
+ if(!str_is_empty(&g2->name)) {
+ ERR(htable_names_set(&dev->geometry_names, &g2->name, &g1));
+ }
+ if(!str_is_empty(&g1->name) || !str_is_empty(&g2->name)) {
+ ERR(str_copy(&tmp, &g1->name));
+ ERR(str_copy(&g1->name, &g2->name));
+ ERR(str_copy(&g2->name, &tmp));
+ }
+ }
+ if(flags & Scad_swap_geometry) {
+ /* Swap in tag2geom tables */
+ size_t n;
+ if(dev->log) {
+ if(str_is_empty(&g1->name) && str_is_empty(&g2->name)) {
+ logger_print(dev->logger, dev->log_type,
+ "Swapping tags for unnamed geometries %p and %p.\n",
+ (void*)g1, (void*)g2);
+ }
+ else if(str_is_empty(&g1->name)) {
+ logger_print(dev->logger, dev->log_type,
+ "Swapping tags for unnamed geometry %p and geometry '%s'.\n",
+ (void*)g1, str_cget(&g2->name));
+ }
+ else if(str_is_empty(&g2->name)) {
+ logger_print(dev->logger, dev->log_type,
+ "Swapping tags for unnamed geometry %p and geometry '%s'.\n",
+ (void*)g2, str_cget(&g1->name));
+ }
+ else {
+ logger_print(dev->logger, dev->log_type,
+ "Swapping tags for geometries '%s' and '%s'.\n",
+ str_cget(&g1->name), str_cget(&g1->name));
+ }
+ if(str_is_empty(&g1->name)) {
+ ERR(str_printf(&msg,
+ "Tags now registered against unnamed geometry '%p': ",
+ (void*)g1));
+ } else {
+ ERR(str_printf(&msg, "Tags now registered against geometry '%s': ",
+ str_cget(&g1->name)));
+ }
+ for(n = 0; n < c2; n += 2) {
+ int dim = dt2[n];
+ int tag = dt2[n+1];
+ if(n) { ERR(str_append_printf(&msg, ",")); }
+ ERR(str_append_printf(&msg, " %d.%d", dim, tag));
+ }
+ logger_print(dev->logger, dev->log_type, "%s.\n", str_cget(&msg));
+ if(str_is_empty(&g2->name)) {
+ ERR(str_printf(&msg,
+ "Tags now registered against unnamed geometry '%p': ",
+ (void*)g2));
+ } else {
+ ERR(str_printf(&msg, "Tags now registered against geometry '%s': ",
+ str_cget(&g2->name)));
+ }
+ for(n = 0; n < c1; n += 2) {
+ int dim = dt1[n];
+ int tag = dt1[n+1];
+ ERR(str_append_printf(&msg, (n ? ", %d.%d" : "%d.%d"), dim, tag));
+ }
+ logger_print(dev->logger, dev->log_type, "%s.\n", str_cget(&msg));
+ }
+ /* Swap tags */
+ SWAP(int*, g1->gmsh_dimTags, g2->gmsh_dimTags);
+ SWAP(size_t, g1->gmsh_dimTags_n, g2->gmsh_dimTags_n);
+ }
+ }
+
+exit:
+ if(flags & Scad_swap_name) str_release(&tmp);
+ if(flags & Scad_swap_geometry && dev->log) str_release(&msg);
+ return res;
+error:
+ goto exit;
+}
+
+res_T
scad_geometry_boundary
(const char* name,
struct scad_geometry** geometries,