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:
| M | src/scad.h | | | 32 | +++++++++++++++++++++++++++++++- |
| M | src/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,