star-cad

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

commit 04e88342180afb389540eb50b59aae6b802ea109
parent 6119461920bf964bb00e14017df95fc23fac7a58
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Fri, 29 Sep 2023 17:18:04 +0200

Add new API calls

New calls are collect_geometries, equal, is_included that all deal with entities in a geometry

Diffstat:
Msrc/scad.h | 32+++++++++++++++++++++++++++++++-
Msrc/scad_geometry.c | 176+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 207 insertions(+), 1 deletion(-)

diff --git a/src/scad.h b/src/scad.h @@ -272,6 +272,34 @@ scad_add_sphere const double radius, struct scad_geometry** sphere); +/* Check if geometries `geom1' and `geom2' have the same content, that is: + * - are the same scad_geometries (trivial case), + * - contain the same internal entities. + * To check if 2 geometries are "equivalent", one as to apply boolean operators + * (e.g. cut) and check the result accordingly (e.g. empty result). */ +SCAD_API res_T +scad_geometries_equal + (struct scad_geometry* geom1, + struct scad_geometry* geom2, + int* equal); + +/* Check if all the entities of `geometry' are part of the geometries in + * `geometries'. */ +SCAD_API res_T +scad_geometry_is_included + (struct scad_geometry* geometry, + struct scad_geometry** geometries, + const size_t geometries_count, + int* included); + +/* Create a new geometry made from all the entities from `geometries'. */ +SCAD_API res_T +scad_collect_geometries + (const char* name, /* Can be NULL */ + struct scad_geometry** geometries, + const size_t geometries_count, + struct scad_geometry** out_geometry); + /* Compute the boolean union (the fusion) of the geometries in `geometries' and * `tools'. */ SCAD_API res_T @@ -390,7 +418,9 @@ scad_geometry_extrude /* Return a list of geometries which form the geometry `geom'. * The output geometries are named <base>_<rank>, where <base> is either - * prefix_name or geom's name, and <rank> counting from 0. */ + * prefix_name or geom's name, and <rank> counting from 0. + * The result `out_geometries' being allocated using the allocator provided when + * initializing star-cad, it should be freed accordingly. */ SCAD_API res_T scad_geometry_explode (const struct scad_geometry* geom, diff --git a/src/scad_geometry.c b/src/scad_geometry.c @@ -849,6 +849,144 @@ error: goto exit; } +SCAD_API res_T +scad_geometries_equal + (struct scad_geometry* geom1, + struct scad_geometry* geom2, + int* equal) +{ + res_T res = RES_OK; + struct scad_device* dev = get_device(); + struct mem_allocator* allocator = NULL; + struct htable_tags t2, t3; + int eq = 1, initialized = 0; + + if(!geom1 || !geom2 || !equal) { + res = RES_BAD_ARG; + goto error; + } + + ERR(check_device(FUNC_NAME)); + allocator = dev->allocator; + + /* Trivial cases */ + if(geom1 == geom2) { + eq = 1; + } + else if(geom1->gmsh_dimTags_n != geom2->gmsh_dimTags_n) { + eq = 0; + } else { + size_t i; + htable_tags_init(allocator, &t2); + htable_tags_init(allocator, &t3); + initialized = 1; + /* Create tables from geom1 tags */ + for(i = 0; i < geom1->gmsh_dimTags_n; i += 2) { + char one = 1; + int d = geom1->gmsh_dimTags[i]; + int t = geom1->gmsh_dimTags[i+1]; + struct htable_tags* tn = (d == 2) ? &t2 : &t3; + ERR(htable_tags_set(tn, &t, &one)); + } + ASSERT((htable_tags_size_get(&t2) + htable_tags_size_get(&t3)) * 2 + == geom1->gmsh_dimTags_n); + /* Check if tags from geom2 are included */ + for(i = 0; i < geom2->gmsh_dimTags_n; i += 2) { + char* found; + int d = geom2->gmsh_dimTags[i]; + int t = geom2->gmsh_dimTags[i+1]; + struct htable_tags* tn = (d == 2) ? &t2 : &t3; + found = htable_tags_find(tn, &t); + if(!found) { + eq = 0; + break; + } + } + } + + *equal = eq; + +exit: + if(initialized) { + htable_tags_release(&t2); + htable_tags_release(&t3); + } + return res; +error: + goto exit; +} + +SCAD_API res_T +scad_geometry_is_included + (struct scad_geometry* geometry, + struct scad_geometry** geometries, + const size_t geometries_count, + int* included) +{ + res_T res = RES_OK; + struct scad_device* dev = get_device(); + struct mem_allocator* allocator = NULL; + struct htable_tags t2, t3; + int initialized = 0; + size_t i, n; + + if(!geometry || !geometries || !included) { + res = RES_BAD_ARG; + goto error; + } + + ERR(check_device(FUNC_NAME)); + allocator = dev->allocator; + + /* Trivial case */ + for(i = 0; i < geometries_count; i++) { + if(geometry == geometries[i]) { + *included = 1; + goto exit; + } + } + + /* Create tables from geometries tags */ + htable_tags_init(allocator, &t2); + htable_tags_init(allocator, &t3); + initialized = 1; + for(n = 0; n < geometries_count; n++) { + const struct scad_geometry* geom = geometries[n]; + for(i = 0; i < geometries[n]->gmsh_dimTags_n; i += 2) { + char one = 1; + int d = geom->gmsh_dimTags[i]; + int t = geom->gmsh_dimTags[i+1]; + struct htable_tags* tn = (d == 2) ? &t2 : &t3; + ERR(htable_tags_set(tn, &t, &one)); + } + } + + /* Check if tags from geometry are included */ + for(i = 0; i < geometry->gmsh_dimTags_n; i += 2) { + char* found; + int d = geometry->gmsh_dimTags[i]; + int t = geometry->gmsh_dimTags[i+1]; + struct htable_tags* tn = (d == 2) ? &t2 : &t3; + found = htable_tags_find(tn, &t); + if(!found) { + *included = 0; + goto exit; + } + } + + /* If here, no not-included tag was found */ + *included = 1; + +exit: + if(initialized) { + htable_tags_release(&t2); + htable_tags_release(&t3); + } + return res; +error: + goto exit; +} + res_T scad_fuse_geometries (const char* name, @@ -918,6 +1056,44 @@ error: } res_T +scad_collect_geometries + (const char* name, + struct scad_geometry** geometries, + const size_t geometries_count, + struct scad_geometry** out_geometry) +{ + res_T res = RES_OK; + size_t sz; + int* data = NULL; + struct scad_geometry* geom = NULL; + + if(!geometries || !geometries_count || !out_geometry) { + res = RES_BAD_ARG; + goto error; + } + + ERR(check_device(FUNC_NAME)); + + ERR(gather_tags(geometries, geometries_count, &data, &sz)); + + ERR(geometry_create(name, &geom)); + geom->gmsh_dimTags_n = sz; + geom->gmsh_dimTags = data; + + ERR(device_register_tags(geom)); + +exit: + if(out_geometry) *out_geometry = geom; + return res; +error: + if(geom) { + SCAD(geometry_ref_put(geom)); + geom = NULL; + } + goto exit; +} + +res_T scad_cut_geometries (const char* name, /* Can be NULL */ struct scad_geometry** geometries,