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