star-cad

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

commit de81ea794f6c4dd0e35c83debf9b58051e32ec27
parent 9851bba0078c59829c7c40193c7c00b7004a8f9f
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Fri,  9 Dec 2022 11:19:00 +0100

Add option to log OpenCascade tags ref counting

Diffstat:
Msrc/scad.h | 3++-
Msrc/scad_device.c | 75+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------
Msrc/scad_geometry.c | 25+++++++++++++++++++++++++
3 files changed, 96 insertions(+), 7 deletions(-)

diff --git a/src/scad.h b/src/scad.h @@ -95,6 +95,7 @@ struct scad_options { struct { int Step; /* Run UI when entering any scad API function; requires a FLTK-enabled gmsh build */ int SynchronizeOnRunUI; + int LogOpenCascadeTagsRefCounting; } Misc; }; @@ -102,7 +103,7 @@ struct scad_options { { { Scad_frontal_Delaunay, Scad_surfaces_and_volumes, 1, 36, 1, 1e+22, 0, \ 1, Scad_one_solid_per_physical_surface }, \ { Scad_verbosity_errors, 1 }, \ - { 0, 0 } \ + { 0, 0, 0 } \ } static const struct scad_options SCAD_DEFAULT_OPTIONS = SCAD_DEFAULT_OPTIONS__; diff --git a/src/scad_device.c b/src/scad_device.c @@ -13,6 +13,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "rsys/str.h" #include "scad.h" #include "scad_c.h" #include "scad_device.h" @@ -34,8 +35,10 @@ device_release(struct scad_device* dev) { struct htable_geometries tmp; struct htable_geometries_iterator it, end; + int log; ASSERT(dev); + log = dev->options.Misc.LogOpenCascadeTagsRefCounting; /* Duplicate the htable we iterate on as dev->allgeom will be altered during * the process (through calls to geometry_release) */ @@ -43,6 +46,9 @@ device_release(struct scad_device* dev) CHK(RES_OK == htable_geometries_copy(&tmp, &dev->allgeom)); htable_geometries_begin(&tmp, &it); htable_geometries_end(&tmp, &end); + if(log && htable_geometries_iterator_eq(&it, &end)) { + log_message(dev, "No scad geometry.\n"); + } while(!htable_geometries_iterator_eq(&it, &end)) { struct scad_geometry* geom = *htable_geometries_iterator_key_get(&it); CHK(RES_OK == geometry_release(geom)); @@ -52,6 +58,9 @@ device_release(struct scad_device* dev) htable_tags2geom_release(&dev->tags2geom[0]); htable_tags2geom_release(&dev->tags2geom[1]); htable_geometries_release(&dev->allgeom); + if(log) { + log_message(dev, "End finalizing scad.\n"); + } MEM_RM(dev->allocator, dev); htable_geometries_release(&tmp); } @@ -137,14 +146,24 @@ device_register_tags { res_T res = RES_OK; int* dimTags; - size_t count; - - size_t i; + size_t count, i; + struct scad_device* dev = get_device(); + int log = dev->options.Misc.LogOpenCascadeTagsRefCounting; ASSERT(geom); dimTags = geom->gmsh_dimTags; count = geom->gmsh_dimTags_n; + if(log) { + if(str_is_empty(&geom->name)) { + log_message(dev, "Registering tags for unnamed geometry %p.\n", + (void*)geom); + } else { + log_message(dev, "Registering tags for geometry '%s'.\n", + str_cget(&geom->name)); + } + } + for(i = 0; i < count; i += 2) { int dim = dimTags[i]; int tag = dimTags[i+1]; @@ -166,9 +185,23 @@ device_register_tags ERR(htable_tags2geom_set(t2g, &tag, &g)); geoms = htable_tags2geom_find(t2g, &tag); ASSERT(geoms); + if(log) { + log_message(dev, "New dim %d tag %d (count set to 1).\n", dim, tag); + } + } else { + if(log) { + size_t n = htable_geometries_size_get(geoms); + if(n > 0) { + log_message(dev, "Dim %d tag %d (count increased to %lu).\n", + dim, tag, n+1); + } else { + log_message(dev, "Reuse dim %d tag %d (count set to 1).\n", dim, tag); + } + } } ASSERT(!htable_geometries_find(geoms, &geom)); ERR(htable_geometries_set(geoms, &geom, &one)); + ASSERT(htable_geometries_size_get(geoms) >= 1); } end: @@ -183,14 +216,25 @@ device_unregister_tags { res_T res = RES_OK; int* dimTags; - size_t count; - size_t i; + size_t count, i; + struct scad_device* dev = get_device(); + int log = dev->options.Misc.LogOpenCascadeTagsRefCounting; ASSERT(geom); dimTags = geom->gmsh_dimTags; count = geom->gmsh_dimTags_n; + if(log) { + if(str_is_empty(&geom->name)) { + log_message(dev, "Unregistering tags for unnamed geometry %p.\n", + (void*)geom); + } else { + log_message(dev, "Unregistering tags for geometry '%s'.\n", + str_cget(&geom->name)); + } + } + for(i = 0; i < count; i += 2) { int dim = dimTags[i]; int tag = dimTags[i+1]; @@ -207,8 +251,18 @@ device_unregister_tags geoms = htable_tags2geom_find(t2g, &tag); n = htable_geometries_erase(geoms, &geom); ASSERT(geoms && n == 1); (void)n; - if(htable_geometries_size_get(geoms) > 0) continue; + n = htable_geometries_size_get(geoms); + if(n > 0) { + if(log) { + log_message(dev, "Dim %d tag %d (count decreased to %lu).\n", + dim, tag, (unsigned long)n); + } + continue; + } /* The gmsh geometry with tag 'tag' is not in use anymore: release it */ + if(log) { + log_message(dev, "Dim %d tag %d removed.\n", dim, tag); + } gmshModelOccRemove(dimTags+i, 2, 1, &ierr); ERR(gmsh_err_to_res_T(ierr)); } @@ -278,10 +332,18 @@ scad_finalize (void) { res_T res = RES_OK; + struct scad_device* dev = get_device(); + int log; int ierr; ERR(check_device(FUNC_NAME)); + log = dev->options.Misc.LogOpenCascadeTagsRefCounting; + if(log) { + log_message(dev, + "Finalizing scad; undeleted tags will be automatically unregistered.\n"); + } + device_release(g_device); g_device = NULL; gmshFinalize(&ierr); @@ -344,6 +406,7 @@ scad_set_options /* Check non-gmsh option validity if user-provided */ (void)actual_options->Misc.Step; /* int boolean: always OK */ (void)actual_options->Misc.SynchronizeOnRunUI; /* int boolean: always OK */ + (void)actual_options->Misc.LogOpenCascadeTagsRefCounting; /* int boolean: always OK */ } dev->options = *actual_options; diff --git a/src/scad_geometry.c b/src/scad_geometry.c @@ -270,9 +270,34 @@ scad_scene_clear { res_T res = RES_OK; int ierr; + struct htable_geometries tmp; + struct htable_geometries_iterator it, end; + struct scad_device* dev = get_device(); + int log; ERR(check_device(FUNC_NAME)); + log = dev->options.Misc.LogOpenCascadeTagsRefCounting; + htable_geometries_init(dev->allocator, &tmp); + CHK(RES_OK == htable_geometries_copy(&tmp, &dev->allgeom)); + htable_geometries_begin(&tmp, &it); + htable_geometries_end(&tmp, &end); + if(log) { + log_message(dev, "Clearing scene.\n"); + if(htable_geometries_iterator_eq(&it, &end)) { + log_message(dev, "scene is empty.\n"); + } + } + while(!htable_geometries_iterator_eq(&it, &end)) { + struct scad_geometry* geom = *htable_geometries_iterator_key_get(&it); + CHK(RES_OK == geometry_release(geom)); + htable_geometries_iterator_next(&it); + } + if(log) { + log_message(dev, "End clearing scene.\n"); + } + + /* Ensure clear is complete (not scad-registered tags) */ gmshClear(&ierr); ERR(gmsh_err_to_res_T(ierr));