star-cad

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

commit 236a298488e28830eaa8e98eb552f9e8789ebdd1
parent 27846f944494b5fff41bd2783896bb4e5038c6cd
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Wed,  6 Mar 2024 15:43:46 +0100

Change scad_geometries_partition

Replace the boolean int argument by a flags argument.
The two values 0 and 1 that where the basic values for this arg still
produce the same behaviour: API is not broken.
A new capability is to use the Scad_dump_on_overlapping_error which, as
the name implies, requests that overlapping geometries are dumped (as
STL files).

Diffstat:
Msrc/scad.h | 10+++++++++-
Msrc/scad_geometry.c | 65++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------
2 files changed, 63 insertions(+), 12 deletions(-)

diff --git a/src/scad.h b/src/scad.h @@ -135,6 +135,12 @@ enum scad_normals_orientation { Scad_force_normals_inward }; +/* A type to specify how partitioning is done. */ +enum scad_partition_flags { + Scad_allow_overlapping = BIT(0), + Scad_dump_on_overlapping_error = BIT(1) +}; + BEGIN_DECLS /******************************************************************************* @@ -363,6 +369,8 @@ scad_geometries_common_boundaries /* Compute the boolean fragments (general fuse) resulting from the * intersection of the geometries in `geometries', making all interfaces * conformal. + * `flags' should be made by Oring values from enum scad_partition_flags to + * enable non default behaviours (default is to disallow overlapping). * The output geometries are created unnamed. * When applied to geometries of different dimensions, the lower dimensional * geometries will be automatically embedded in the higher dimensional @@ -371,7 +379,7 @@ SCAD_API res_T scad_geometries_partition (struct scad_geometry** geometries, const size_t geometries_count, - const int allow_overlapping, + const int flags, struct scad_geometry** out_geometries); /* Get the boundary of the geometry `geom'. */ diff --git a/src/scad_geometry.c b/src/scad_geometry.c @@ -1794,7 +1794,7 @@ res_T scad_geometries_partition (struct scad_geometry** geometries, const size_t geometries_count, - const int allow_overlapping, + const int flags, struct scad_geometry** out_geometries) { res_T res = RES_OK; @@ -1810,18 +1810,25 @@ scad_geometries_partition struct scad_device* dev = get_device(); struct htable_tags t2, t3; struct htable_tags_iterator it, end; - int ht_initialized = 0; + int ht_initialized = 0, tmp_initialized = 0; struct mem_allocator* allocator = NULL; int dont_call_fragment = 0; char* overlap = NULL; + const int invalid_flags = + ~(Scad_allow_overlapping | Scad_dump_on_overlapping_error); + const int dump_overlapping_err = flags & Scad_dump_on_overlapping_error; + static size_t err_cpt = 0; + struct str tmp; - if(!geometries || !geometries_count || !out_geometries) { + if(!geometries || !geometries_count || !out_geometries || flags & invalid_flags) { res = RES_BAD_ARG; goto error; } ERR(check_device(FUNC_NAME)); allocator = dev->allocator; + str_init(allocator, &tmp); + tmp_initialized = 1; ERR(gather_tags(geometries, geometries_count, &data, &sz)); @@ -1861,7 +1868,7 @@ scad_geometries_partition get_device()->need_synchro = 1; /* Check first if there was an overlapping problem */ - if(!allow_overlapping) { + if(!(flags & Scad_allow_overlapping)) { /* No overlapping means that each tag in geometries is translated into a * single tag in map */ size_t ov = 0; @@ -1884,18 +1891,53 @@ scad_geometries_partition } } if(ov) { - size_t k; + size_t k, item_cpt = 0; + res_T tmp_err; + if(dump_overlapping_err) { + ERR(scad_scene_mesh()); + } for(k = 0; k < geometries_count; k++) { struct scad_geometry* g = geometries[k]; if(!overlap[k]) continue; - if(str_is_empty(&g->name)) { - log_error(get_device(), "Unnamed geometry '%p' overlapping.\n", - (void*)g); - } else { - log_error(get_device(), "Geometry '%s' overlapping.\n", - str_cget(&g->name)); + tmp_err = RES_BAD_OP; + if(dump_overlapping_err) { + if(str_is_empty(&g->name)) { + str_printf(&tmp, "unamed_partition_error_%lu_%lu.stl", + err_cpt, (long unsigned)item_cpt++); + tmp_err = + scad_stl_export(g, str_cget(&tmp), Scad_keep_normals_unchanged, 0); + if(tmp_err == RES_OK) { + log_error(get_device(), + "Unnamed geometry '%p' overlapping (dumped in '%s).\n", + (void*)g, str_cget(&tmp)); + } else { + log_error(get_device(), "Could not dump geoemtry.\n"); + } + } else { + str_printf(&tmp, "%s_partition_error_%lu_%lu.stl", + str_cget(&g->name), err_cpt, (long unsigned)item_cpt++); + tmp_err = + scad_stl_export(g, str_cget(&tmp), Scad_keep_normals_unchanged, 0); + if(tmp_err == RES_OK) { + log_error(get_device(), + "Geometry '%s' overlapping (dumped in '%s).\n", + str_cget(&g->name), str_cget(&tmp)); + } else { + log_error(get_device(), "Could not dump geoemtry.\n"); + } + } + } + if(tmp_err != RES_OK) { /* not dumped */ + if(str_is_empty(&g->name)) { + log_error(get_device(), "Unnamed geometry '%p' overlapping.\n", + (void*)g); + } else { + log_error(get_device(), "Geometry '%s' overlapping.\n", + str_cget(&g->name)); + } } } + err_cpt++; } if(ov) { res = RES_BAD_ARG; @@ -1986,6 +2028,7 @@ exit: htable_tags_release(&t2); htable_tags_release(&t3); } + if(tmp_initialized) str_release(&tmp); if(allocator) { MEM_RM(allocator, data); MEM_RM(allocator, geoms);