star-cad

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

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:
Msrc/scad.h | 17+++++++++++++----
Msrc/scad_geometry.c | 172+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------
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,