commit 04d4f68ac87fccb2f8819e581a0dadd646760755
parent 455ce14a7685428dbc584f567c22407bc33272c4
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Thu, 25 Aug 2022 10:44:59 +0200
Remove the scad_scene type from user space: there is a single implicit scene
Diffstat:
10 files changed, 234 insertions(+), 447 deletions(-)
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -43,12 +43,10 @@ set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH})
set(SCAD_FILES_SRC
scad.c
- scad_scene.c
scad_device.c
scad_geometry.c)
set(SCAD_FILES_INC_API scad.h)
set(SCAD_FILES_INC
- scad_scene.h
scad_device.h
scad_geometry.h)
set(SCAD_FILES_DOC COPYING README.md)
diff --git a/src/scad.c b/src/scad.c
@@ -16,7 +16,6 @@
#include "scad.h"
#include "scad_c.h"
#include "scad_device.h"
-#include "scad_scene.h"
#include "scad_geometry.h"
#include <gmshc.h>
@@ -230,17 +229,15 @@ scad_stl_export
goto error;
}
- if(geometry->scene->device->need_synchro) {
- ERR(scad_device_synchronize(geometry->scene->device));
+ if(geometry->device->need_synchro) {
+ ERR(scad_device_synchronize(geometry->device));
}
- ERR(device_set_current_scene(geometry->scene));
-
sz = geometry->gmsh_dimTags_n;
data = geometry->gmsh_dimTags;
ASSERT(sz > 0 && sz % 2 == 0);
- str_init(geometry->scene->device->allocator, &filename);
+ str_init(geometry->device->allocator, &filename);
str_initialized = 1;
if(prefix) {
ERR(str_set(&filename, prefix));
@@ -257,7 +254,7 @@ scad_stl_export
size_t dimTags_n;
size_t tcount;
- ERR(scad_device_synchronize(geometry->scene->device));
+ ERR(scad_device_synchronize(geometry->device));
gmshModelOccGetEntities(&dimTags, &dimTags_n, 3, &ierr);
ERR(gmsh_err_to_res_T(ierr));
if(dimTags_n > 100000) {
@@ -280,13 +277,13 @@ scad_stl_export
#endif
}
/* WARNING : an export may be prohibited without a prior conformal mesh*/
- if (!geometry->scene->is_meshed) {
- ERR(scad_device_synchronize(geometry->scene->device));
+ if (!geometry->device->is_meshed) {
+ ERR(scad_device_synchronize(geometry->device));
gmshModelMeshGenerate(2, &ierr);
ERR(gmsh_err_to_res_T(ierr));
- geometry->scene->is_meshed = 1;
+ geometry->device->is_meshed = 1;
}
- ERR(scad_device_synchronize(geometry->scene->device));
+ ERR(scad_device_synchronize(geometry->device));
gmshModelGetBoundary(data, sz, &tagout, &tagoutn, 1, 0, 0, &ierr);
ERR(gmsh_err_to_res_T(ierr));
@@ -392,18 +389,16 @@ scad_stl_export_split
goto error;
}
- if(geometry->scene->device->need_synchro) {
- ERR(scad_device_synchronize(geometry->scene->device));
+ if(geometry->device->need_synchro) {
+ ERR(scad_device_synchronize(geometry->device));
}
- ERR(device_set_current_scene(geometry->scene));
-
sz = geometry->gmsh_dimTags_n;
data = geometry->gmsh_dimTags;
ASSERT(sz % 2 == 0);
- str_init(geometry->scene->device->allocator, &filename_root);
- str_init(geometry->scene->device->allocator, &filename);
+ str_init(geometry->device->allocator, &filename_root);
+ str_init(geometry->device->allocator, &filename);
str_initialized = 1;
if(prefix) {
ERR(str_set(&filename_root, prefix));
@@ -466,3 +461,39 @@ exit:
error:
goto exit;
}
+
+res_T
+scad_conformal_mesh
+ (struct scad_device* device)
+{
+ int* dimTags = NULL;
+ size_t dimTags_n;
+ int ierr = 0;
+ res_T res = RES_OK;
+
+ device->need_synchro = 1;
+ gmshModelOccSynchronize(&ierr);
+ ERR(gmsh_err_to_res_T(ierr));
+ gmshModelOccGetEntities(&dimTags, &dimTags_n, 3, &ierr);
+ ERR(gmsh_err_to_res_T(ierr));
+ if(dimTags_n > 2) {
+ /* Remove all duplicate entities in the OpenCASCADE CAD representation
+ * (different entities at the same geometrical location) after intersecting
+ * (using boolean fragments) all highest dimensional entities. */
+ gmshModelOccRemoveAllDuplicates(&ierr);
+ ERR(gmsh_err_to_res_T(ierr));
+ }
+ gmshModelOccSynchronize(&ierr);
+ ERR(gmsh_err_to_res_T(ierr));
+ gmshModelMeshGenerate(2, &ierr);
+ ERR(gmsh_err_to_res_T(ierr));
+ device->is_meshed = 1;
+
+exit:
+ if(dimTags) free(dimTags);
+ return res;
+error:
+ goto exit;
+}
+
+
diff --git a/src/scad.h b/src/scad.h
@@ -42,7 +42,6 @@ struct logger;
/* Forward declaration of scad opaque data types */
struct scad_device; /* Entry point of the library */
-struct scad_scene; /* Collection of geometry items */
struct scad_geometry; /* Wrapping of dimTags gmsh description */
/* A type to specify options for devices */
@@ -94,25 +93,9 @@ scad_device_ref_put
(struct scad_device* dev);
/*******************************************************************************
- * Scene API - A scene is a collection of geometries.
- ******************************************************************************/
-SCAD_API res_T
-scad_scene_create
- (struct scad_device* device,
- struct scad_scene** out_scene);
-
-SCAD_API res_T
-scad_scene_ref_get
- (struct scad_scene* scene);
-
-SCAD_API res_T
-scad_scene_ref_put
- (struct scad_scene* scene);
-
-/*******************************************************************************
* Geometry API - A geometry is a primitive, a group of primitives, or the
* result of an operation on geometries.
- * If provided, names must be unique by scene.
+ * If provided, names must be unique by device.
******************************************************************************/
/* `size' is the number of primitives of the geometry `geom' */
@@ -124,8 +107,8 @@ scad_geometry_get_size
/* Add a rectangle to the scene, defined by a point `xyz' and
* `dxdy' the extents along the x-, y-axes. */
SCAD_API res_T
-scad_scene_add_rectangle
- (struct scad_scene* scene,
+scad_add_rectangle
+ (struct scad_device* device,
const char* name, /* Can be NULL */
const double xyz[3],
const double dxdy[2],
@@ -134,8 +117,8 @@ scad_scene_add_rectangle
/* Add a disk in (xy) plane to the scene, defined by a the center `xyz' and
* `radius'. */
SCAD_API res_T
-scad_scene_add_disk
- (struct scad_scene* scene,
+scad_add_disk
+ (struct scad_device* device,
const char* name, /* Can be NULL */
const double xyz[3],
const double radius,
@@ -144,8 +127,8 @@ scad_scene_add_disk
/* Add a polygonal surface in (xy) plane to the scene at elevation z, defined by
* the list of points of coordinates x, y.*/
SCAD_API res_T
-scad_scene_add_polygon
- (struct scad_scene* scene,
+scad_add_polygon
+ (struct scad_device* device,
const char* name, /* Can be NULL */
const double* x,
const double* y,
@@ -156,8 +139,8 @@ scad_scene_add_polygon
/* Add a parallelepipedic box to the scene, defined by a point `xyz' and
* `dxdydz' the extents along the x-, y- and z-axes. */
SCAD_API res_T
-scad_scene_add_box
- (struct scad_scene* scene,
+scad_add_box
+ (struct scad_device* device,
const char* name, /* Can be NULL */
const double xyz[3],
const double dxdydz[3],
@@ -167,8 +150,8 @@ scad_scene_add_box
* circular face, the vector `axis' defining its axis and its radius `rad'. The
* `angle' argument defines the angular opening (from 0 to 2*Pi). */
SCAD_API res_T
-scad_scene_add_cylinder
- (struct scad_scene* scene,
+scad_add_cylinder
+ (struct scad_device* device,
const char* name, /* Can be NULL */
const double xyz[3],
const double axis[3],
@@ -178,8 +161,8 @@ scad_scene_add_cylinder
/* Add a sphere of center `xyz' and radius `rad' to the scene. */
SCAD_API res_T
-scad_scene_add_sphere
- (struct scad_scene* scene,
+scad_add_sphere
+ (struct scad_device* device,
const char* name, /* Can be NULL */
const double xyz[3],
const double rad,
@@ -189,8 +172,8 @@ scad_scene_add_sphere
* All of the geometries must have been added to scene and must have dimension
* dim. */
SCAD_API res_T
-scad_scene_create_group
- (struct scad_scene* scene,
+scad_create_group
+ (struct scad_device* device,
const char* name, /* Can be NULL */
const int dim,
struct scad_geometry** geometries,
@@ -198,14 +181,14 @@ scad_scene_create_group
struct scad_geometry** group);
SCAD_API res_T
-scad_scene_conformal_mesh
- (struct scad_scene* scene);
+scad_conformal_mesh
+ (struct scad_device* device);
/* Compute the boolean union (the fusion) of the geometries `geom1' and `geom2'.
* Remove geom1 and geom2 from scene if `remove' is set. */
SCAD_API res_T
-scad_scene_fuse_geometries
- (struct scad_scene* scene,
+scad_fuse_geometries
+ (struct scad_device* device,
const char* name, /* Can be NULL */
struct scad_geometry* geom1,
struct scad_geometry* geom2,
@@ -215,8 +198,8 @@ scad_scene_fuse_geometries
/* Compute the boolean difference between the geometries `geom1' and `geom2'.
* Remove geom1 and geom2 from scene if `remove' is set. */
SCAD_API res_T
-scad_scene_cut_geometries
- (struct scad_scene* scene,
+scad_cut_geometries
+ (struct scad_device* device,
const char* name, /* Can be NULL */
struct scad_geometry* geom1,
struct scad_geometry* geom2,
@@ -227,8 +210,8 @@ scad_scene_cut_geometries
* `geom1' and `geom2'.
* Remove geom1 and geom2 from scene if `remove' is set. */
SCAD_API res_T
-scad_scene_intersect_geometries
- (struct scad_scene* scene,
+scad_intersect_geometries
+ (struct scad_device* device,
const char* name, /* Can be NULL */
struct scad_geometry* geom1,
struct scad_geometry* geom2,
@@ -238,8 +221,8 @@ scad_scene_intersect_geometries
/* compute boundary intersection (the common part) of geom1 and geom2
* Remove geom1 and geom2 from scene if `remove' is set. */
SCAD_API res_T
-scad_scene_geometries_common_boundaries
- (struct scad_scene* scene,
+scad_geometries_common_boundaries
+ (struct scad_device* device,
const char* name, /* Can be NULL */
struct scad_geometry* geom1,
struct scad_geometry* geom2,
@@ -253,8 +236,8 @@ scad_scene_geometries_common_boundaries
* dimensional geometries if they are not on their boundary.
* Remove geom1 and geom2 from scene if `remove' is set. */
SCAD_API res_T
-scad_scene_geometries_fragment
- (struct scad_scene* scene,
+scad_geometries_fragment
+ (struct scad_device* device,
const char* name, /* Can be NULL */
struct scad_geometry* geom1,
struct scad_geometry* geom2,
@@ -263,8 +246,8 @@ scad_scene_geometries_fragment
/* Get the boundary of the geometry `geom'. */
SCAD_API res_T
-scad_scene_geometry_boundary
- (struct scad_scene* scene,
+scad_geometry_boundary
+ (struct scad_device* device,
const char* name, /* Can be NULL */
struct scad_geometry* geom,
struct scad_geometry** out);
@@ -303,8 +286,8 @@ scad_geometry_extrude
/* Import a step model (`filename'). The imported geometries are recorded in
* `out_geometry' handler. */
SCAD_API res_T
-scad_scene_step_import
- (struct scad_scene* scene,
+scad_step_import
+ (struct scad_device* device,
const char* filename, /* name of step file */
const char* name, /* Can be NULL */
struct scad_geometry*** out_geometry,
diff --git a/src/scad_device.c b/src/scad_device.c
@@ -16,7 +16,6 @@
#include "scad.h"
#include "scad_c.h"
#include "scad_device.h"
-#include "scad_scene.h"
#include <rsys/logger.h>
#include <rsys/mem_allocator.h>
@@ -35,9 +34,18 @@ static void
device_release(ref_T* ref)
{
struct scad_device* dev;
+ struct htable_names_iterator it, end;
int ierr = 0;
ASSERT(ref);
dev = CONTAINER_OF(ref, struct scad_device, ref);
+ htable_names_begin(&dev->geometry_names, &it);
+ htable_names_end(&dev->geometry_names, &end);
+ while(!htable_names_iterator_eq(&it, &end)) {
+ struct scad_geometry* geom = *htable_names_iterator_data_get(&it);
+ SCAD(geometry_release(geom));
+ htable_names_iterator_next(&it);
+ }
+ htable_names_release(&dev->geometry_names);
MEM_RM(dev->allocator, dev);
if(--device_count == 0) {
gmshFinalize(&ierr);
@@ -67,18 +75,6 @@ log_warning(struct scad_device* dev, const char* msg, ...)
va_end(vargs_list);
}
-res_T
-device_set_current_scene(struct scad_scene* scene)
-{
- int ierr = 0;
- ASSERT(scene);
- if(scene->device->current_scene == scene) return RES_OK;
- gmshModelSetCurrent(scene->name, &ierr);
- if(ierr) scene->device->current_scene = NULL;
- else scene->device->current_scene = scene;
- return gmsh_err_to_res_T(ierr);
-}
-
/*******************************************************************************
* Exported scad_device functions
******************************************************************************/
@@ -124,6 +120,7 @@ scad_device_create
}
dev->logger = logger ? logger : LOGGER_DEFAULT;
dev->allocator = allocator;
+ htable_names_init(allocator, &dev->geometry_names);
dev->verbose = verbose;
ref_init(&dev->ref);
device_count++;
diff --git a/src/scad_device.h b/src/scad_device.h
@@ -22,13 +22,39 @@
#include <rsys/rsys.h>
#include <rsys/ref_count.h>
#include <rsys/logger.h>
+#include <rsys/hash_table.h>
+#include <rsys/str.h>
+
+static INLINE char
+eq_str(const struct str* a, const struct str* b)
+{
+ return !strcmp(str_cget(a), str_cget(b));
+}
+
+static INLINE size_t
+hash_str(const struct str* a)
+{
+ return hash_fnv32(str_cget(a), str_len(a));
+}
+
+#define HTABLE_NAME names
+#define HTABLE_DATA struct scad_geometry*
+#define HTABLE_KEY struct str
+#define HTABLE_KEY_FUNCTOR_INIT str_init
+#define HTABLE_KEY_FUNCTOR_RELEASE str_release
+#define HTABLE_KEY_FUNCTOR_COPY str_copy
+#define HTABLE_KEY_FUNCTOR_COPY_AND_RELEASE str_copy_and_release
+#define HTABLE_KEY_FUNCTOR_EQ eq_str
+#define HTABLE_KEY_FUNCTOR_HASH hash_str
+
+#include <rsys/hash_table.h>
struct scad_device {
struct logger* logger;
struct mem_allocator* allocator;
- struct scad_scene* current_scene;
- unsigned next_scene_id;
+ struct htable_names geometry_names;
int verbose;
+ int is_meshed;
int need_synchro;
ref_T ref;
@@ -76,7 +102,4 @@ log_msg
}
}
-extern LOCAL_SYM res_T
-device_set_current_scene(struct scad_scene* scene);
-
#endif
diff --git a/src/scad_geometry.c b/src/scad_geometry.c
@@ -15,7 +15,6 @@
#include "scad.h"
#include "scad_c.h"
-#include "scad_scene.h"
#include "scad_device.h"
#include "scad_geometry.h"
@@ -32,20 +31,20 @@
******************************************************************************/
static res_T
scad_geometry_create
- (struct scad_scene* scene,
+ (struct scad_device* device,
const char* name,
struct scad_geometry** out_geometry)
{
res_T res = RES_OK;
struct scad_geometry* geom = NULL;
- ASSERT(scene && out_geometry);
+ ASSERT(device && out_geometry);
if (name) {
struct str str_name;
- str_init(scene->device->allocator, &str_name);
+ str_init(device->allocator, &str_name);
ERR(str_set(&str_name, name));
- if(name && htable_names_find(&scene->geometry_names, &str_name)) {
+ if(name && htable_names_find(&device->geometry_names, &str_name)) {
/* if defined, names must be unique */
res = RES_BAD_ARG;
goto error;
@@ -53,23 +52,23 @@ scad_geometry_create
str_release(&str_name);
}
- geom = (struct scad_geometry*)MEM_CALLOC(scene->device->allocator, 1,
+ geom = (struct scad_geometry*)MEM_CALLOC(device->allocator, 1,
sizeof(*geom));
if(!geom) {
res = RES_MEM_ERR;
goto error;
}
- str_init(scene->device->allocator, &geom->name);
- geom->scene = scene;
- scene->device->need_synchro = 1;
+ str_init(device->allocator, &geom->name);
+ geom->device = device;
+ device->need_synchro = 1;
if(name) {
struct str str_name;
- str_init(scene->device->allocator, &str_name);
+ str_init(device->allocator, &str_name);
ERR(str_set(&str_name, name));
ERR(str_copy(&geom->name, &str_name));
- ERR(htable_names_set(&scene->geometry_names, &str_name, &geom));
+ ERR(htable_names_set(&device->geometry_names, &str_name, &geom));
str_release(&str_name);
}
@@ -108,8 +107,8 @@ scad_geometry_release
int ierr;
res_T res = RES_OK;
ASSERT(geom);
- allocator = geom->scene->device->allocator;
- geom->scene->device->need_synchro = 1;
+ allocator = geom->device->allocator;
+ geom->device->need_synchro = 1;
sz = geom->gmsh_dimTags_n;
data = geom->gmsh_dimTags;
@@ -164,8 +163,8 @@ error:
res_T
-scad_scene_add_rectangle
- (struct scad_scene* scene,
+scad_add_rectangle
+ (struct scad_device* device,
const char* name,
const double xyz[3],
const double dxdy[2],
@@ -175,16 +174,15 @@ scad_scene_add_rectangle
struct scad_geometry* geom = NULL;
res_T res = RES_OK;
- if(!scene || !xyz || !dxdy) {
+ if(!device || !xyz || !dxdy) {
res = RES_BAD_ARG;
goto error;
}
- ERR(device_set_current_scene(scene));
gmsh_ID = gmshModelOccAddRectangle(SPLIT3(xyz), SPLIT2(dxdy), -1, 0, &ierr);
ERR(gmsh_err_to_res_T(ierr));
- ERR(scad_geometry_create(scene, name, &geom));
+ ERR(scad_geometry_create(device, name, &geom));
geom->gmsh_dimTags_n = 2;
geom->gmsh_dimTags = malloc(geom->gmsh_dimTags_n * sizeof(int));
if(! geom->gmsh_dimTags_n) {
@@ -206,8 +204,8 @@ error:
}
res_T
-scad_scene_add_disk
- (struct scad_scene* scene,
+scad_add_disk
+ (struct scad_device* device,
const char* name,
const double xyz[3],
const double radius,
@@ -217,16 +215,15 @@ scad_scene_add_disk
struct scad_geometry* geom = NULL;
res_T res = RES_OK;
- if(!scene || !xyz || radius <= 0) {
+ if(!device || !xyz || radius <= 0) {
res = RES_BAD_ARG;
goto error;
}
- ERR(device_set_current_scene(scene));
gmsh_ID = gmshModelOccAddDisk(SPLIT3(xyz), radius, radius, -1, &ierr);
ERR(gmsh_err_to_res_T(ierr));
- ERR(scad_geometry_create(scene, name, &geom));
+ ERR(scad_geometry_create(device, name, &geom));
geom->gmsh_dimTags_n = 2;
geom->gmsh_dimTags = malloc(geom->gmsh_dimTags_n * sizeof(int));
if(! geom->gmsh_dimTags_n) {
@@ -248,8 +245,8 @@ error:
}
res_T
-scad_scene_add_polygon
- (struct scad_scene* scene,
+scad_add_polygon
+ (struct scad_device* device,
const char* name,
const double* x,
const double* y,
@@ -265,13 +262,11 @@ scad_scene_add_polygon
int loop;
res_T res = RES_OK;
- if(!scene || !x || !y || count < 3) {
+ if(!device || !x || !y || count < 3) {
res = RES_BAD_ARG;
goto error;
}
- ERR(device_set_current_scene(scene));
-
points = malloc(count * sizeof(int));
for (i=0; i<count; ++i) {
points[i] = gmshModelOccAddPoint(x[i], y[i], z, -1, -1, &ierr);
@@ -293,7 +288,7 @@ scad_scene_add_polygon
gmsh_ID = gmshModelOccAddPlaneSurface(&loop, 1, -1, &ierr);
ERR(gmsh_err_to_res_T(ierr));
- ERR(scad_geometry_create(scene, name, &geom));
+ ERR(scad_geometry_create(device, name, &geom));
geom->gmsh_dimTags_n = 2;
geom->gmsh_dimTags = malloc(geom->gmsh_dimTags_n * sizeof(int));
if(! geom->gmsh_dimTags_n) {
@@ -316,8 +311,8 @@ error:
goto exit;
}
res_T
-scad_scene_add_box
- (struct scad_scene* scene,
+scad_add_box
+ (struct scad_device* device,
const char* name,
const double xyz[3],
const double dxdydz[3],
@@ -327,16 +322,15 @@ scad_scene_add_box
struct scad_geometry* geom = NULL;
res_T res = RES_OK;
- if(!scene || !xyz || !dxdydz) {
+ if(!device || !xyz || !dxdydz) {
res = RES_BAD_ARG;
goto error;
}
- ERR(device_set_current_scene(scene));
gmsh_ID = gmshModelOccAddBox(SPLIT3(xyz), SPLIT3(dxdydz), -1, &ierr);
ERR(gmsh_err_to_res_T(ierr));
- ERR(scad_geometry_create(scene, name, &geom));
+ ERR(scad_geometry_create(device, name, &geom));
geom->gmsh_dimTags_n = 2;
geom->gmsh_dimTags = malloc(geom->gmsh_dimTags_n * sizeof(int));
if(! geom->gmsh_dimTags_n) {
@@ -358,8 +352,8 @@ error:
}
res_T
-scad_scene_add_cylinder
- (struct scad_scene* scene,
+scad_add_cylinder
+ (struct scad_device* device,
const char* name,
const double xyz[3],
const double axis[3],
@@ -371,17 +365,16 @@ scad_scene_add_cylinder
struct scad_geometry* geom = NULL;
res_T res = RES_OK;
- if(!scene || !xyz || !axis || rad <= 0 || angle < 0 || angle > 2*PI) {
+ if(!device || !xyz || !axis || rad <= 0 || angle < 0 || angle > 2*PI) {
res = RES_BAD_ARG;
goto error;
}
- ERR(device_set_current_scene(scene));
gmsh_ID = gmshModelOccAddCylinder(SPLIT3(xyz), SPLIT3(axis), rad, -1, angle,
&ierr);
ERR(gmsh_err_to_res_T(ierr));
- ERR(scad_geometry_create(scene, name, &geom));
+ ERR(scad_geometry_create(device, name, &geom));
geom->gmsh_dimTags_n = 2;
geom->gmsh_dimTags = malloc(geom->gmsh_dimTags_n * sizeof(int));
if(! geom->gmsh_dimTags_n) {
@@ -403,8 +396,8 @@ error:
}
int
-scad_scene_add_sphere
- (struct scad_scene* scene,
+scad_add_sphere
+ (struct scad_device* device,
const char* name,
const double xyz[3],
const double rad,
@@ -414,16 +407,15 @@ scad_scene_add_sphere
struct scad_geometry* geom = NULL;
res_T res = RES_OK;
- if(!scene || !xyz || rad <= 0) {
+ if(!device || !xyz || rad <= 0) {
res = RES_BAD_ARG;
goto error;
}
- ERR(device_set_current_scene(scene));
gmsh_ID = gmshModelOccAddSphere(SPLIT3(xyz), rad, -1, -PI/2, PI/2, 2*PI, &ierr);
ERR(gmsh_err_to_res_T(ierr));
- ERR(scad_geometry_create(scene, name, &geom));
+ ERR(scad_geometry_create(device, name, &geom));
geom->gmsh_dimTags_n = 2;
geom->gmsh_dimTags = malloc(geom->gmsh_dimTags_n * sizeof(int));
if(! geom->gmsh_dimTags_n) {
@@ -445,8 +437,8 @@ error:
}
res_T
-scad_scene_create_group
- (struct scad_scene* scene,
+scad_create_group
+ (struct scad_device* device,
const char* name,
const int dim,
struct scad_geometry** geometries,
@@ -459,13 +451,13 @@ scad_scene_create_group
int* ids = NULL;
res_T res = RES_OK;
- if(!scene || !geometries || (count == 0) || !out_geometry) {
+ if(!device || !geometries || (count == 0) || !out_geometry) {
res = RES_BAD_ARG;
goto error;
}
- if(scene->device->need_synchro) {
- ERR(scad_device_synchronize(scene->device));
+ if(device->need_synchro) {
+ ERR(scad_device_synchronize(device));
}
sz = 0;
@@ -485,12 +477,11 @@ scad_scene_create_group
}
}
ASSERT(n == sz);
- ERR(device_set_current_scene(scene));
gid = gmshModelAddPhysicalGroup(dim, ids, count, -1, &ierr);
ASSERT(gid > 0);
ERR(gmsh_err_to_res_T(ierr));
- ERR(scad_geometry_create(scene, name, &geom));
+ ERR(scad_geometry_create(device, name, &geom));
geom->is_group = gid;
geom->group_dim = dim;
geom->gmsh_dimTags_n = 2 * sz;
@@ -521,8 +512,8 @@ error:
}
res_T
-scad_scene_fuse_geometries
- (struct scad_scene* scene,
+scad_fuse_geometries
+ (struct scad_device* device,
const char* name,
struct scad_geometry* geom1,
struct scad_geometry* geom2,
@@ -539,15 +530,15 @@ scad_scene_fuse_geometries
struct scad_geometry* geom = NULL;
res_T res = RES_OK;
- if(!scene || !geom1 || !geom2 || !out_geometry
- || geom1->scene != scene || geom2->scene != scene)
+ if(!device || !geom1 || !geom2 || !out_geometry
+ || geom1->device != device || geom2->device != device)
{
res = RES_BAD_ARG;
goto error;
}
- if(scene->device->need_synchro) {
- ERR(scad_device_synchronize(scene->device));
+ if(device->need_synchro) {
+ ERR(scad_device_synchronize(device));
}
sz1 = geom1->gmsh_dimTags_n;
@@ -558,7 +549,7 @@ scad_scene_fuse_geometries
&mapnn, -1, remove, remove, &ierr);
ERR(gmsh_err_to_res_T(ierr));
- ERR(scad_geometry_create(scene, name, &geom));
+ ERR(scad_geometry_create(device, name, &geom));
geom->gmsh_dimTags_n = tagoutn;
geom->gmsh_dimTags = tagout;
if(remove) { /* FIXME: not sure of this! */
@@ -580,8 +571,8 @@ error:
}
res_T
-scad_scene_cut_geometries
- (struct scad_scene* scene,
+scad_cut_geometries
+ (struct scad_device* device,
const char* name, /* Can be NULL */
struct scad_geometry* geom1,
struct scad_geometry* geom2,
@@ -598,15 +589,15 @@ scad_scene_cut_geometries
struct scad_geometry* geom = NULL;
res_T res = RES_OK;
- if(!scene || !geom1 || !geom2 || !out_geometry
- || geom1->scene != scene || geom2->scene != scene)
+ if(!device || !geom1 || !geom2 || !out_geometry
+ || geom1->device != device || geom2->device != device)
{
res = RES_BAD_ARG;
goto error;
}
- if(scene->device->need_synchro) {
- ERR(scad_device_synchronize(scene->device));
+ if(device->need_synchro) {
+ ERR(scad_device_synchronize(device));
}
sz1 = geom1->gmsh_dimTags_n;
@@ -617,7 +608,7 @@ scad_scene_cut_geometries
&mapnn, -1, remove, remove, &ierr);
ERR(gmsh_err_to_res_T(ierr));
- ERR(scad_geometry_create(scene, name, &geom));
+ ERR(scad_geometry_create(device, name, &geom));
geom->gmsh_dimTags_n = tagoutn;
geom->gmsh_dimTags = tagout;
if(remove) { /* FIXME: not sure of this! */
@@ -639,8 +630,8 @@ error:
}
res_T
-scad_scene_intersect_geometries
- (struct scad_scene* scene,
+scad_intersect_geometries
+ (struct scad_device* device,
const char* name, /* Can be NULL */
struct scad_geometry* geom1,
struct scad_geometry* geom2,
@@ -657,15 +648,15 @@ scad_scene_intersect_geometries
struct scad_geometry* geom = NULL;
res_T res = RES_OK;
- if(!scene || !geom1 || !geom2 || !out_geometry
- || geom1->scene != scene || geom2->scene != scene)
+ if(!device || !geom1 || !geom2 || !out_geometry
+ || geom1->device != device || geom2->device != device)
{
res = RES_BAD_ARG;
goto error;
}
- if(scene->device->need_synchro) {
- ERR(scad_device_synchronize(scene->device));
+ if(device->need_synchro) {
+ ERR(scad_device_synchronize(device));
}
sz1 = geom1->gmsh_dimTags_n;
@@ -676,7 +667,7 @@ scad_scene_intersect_geometries
&mapnn, -1, remove, remove, &ierr);
ERR(gmsh_err_to_res_T(ierr));
- ERR(scad_geometry_create(scene, name, &geom));
+ ERR(scad_geometry_create(device, name, &geom));
geom->gmsh_dimTags_n = tagoutn;
geom->gmsh_dimTags = tagout;
if(remove) { /* FIXME: not sure of this! */
@@ -698,8 +689,8 @@ error:
}
res_T
-scad_scene_geometries_common_boundaries
- (struct scad_scene* scene,
+scad_geometries_common_boundaries
+ (struct scad_device* device,
const char* name, /* Can be NULL */
struct scad_geometry* geom1,
struct scad_geometry* geom2,
@@ -719,15 +710,15 @@ scad_scene_geometries_common_boundaries
struct scad_geometry* geom = NULL;
res_T res = RES_OK;
- if(!scene || !geom1 || !geom2 || !out_geometry
- || geom1->scene != scene || geom2->scene != scene)
+ if(!device || !geom1 || !geom2 || !out_geometry
+ || geom1->device != device || geom2->device != device)
{
res = RES_BAD_ARG;
goto error;
}
- if(scene->device->need_synchro) {
- ERR(scad_device_synchronize(scene->device));
+ if(device->need_synchro) {
+ ERR(scad_device_synchronize(device));
}
sz1 = geom1->gmsh_dimTags_n;
@@ -742,7 +733,7 @@ scad_scene_geometries_common_boundaries
&mapn, &mapnn, -1, 0/*no delete*/, 0/*no delete*/, &ierr);
ERR(gmsh_err_to_res_T(ierr));
- ERR(scad_geometry_create(scene, name, &geom));
+ ERR(scad_geometry_create(device, name, &geom));
geom->gmsh_dimTags_n = tagoutn;
geom->gmsh_dimTags = tagout;
if(remove) { /* FIXME: not sure of this! */
@@ -782,14 +773,14 @@ scad_geometry_rotate
goto error;
}
- if(geom->scene->device->need_synchro) {
- ERR(scad_device_synchronize(geom->scene->device));
+ if(geom->device->need_synchro) {
+ ERR(scad_device_synchronize(geom->device));
}
sz = geom->gmsh_dimTags_n;
data = geom->gmsh_dimTags;
gmshModelOccRotate(data, sz, SPLIT3(pt), SPLIT3(axis), angle, &ierr);
- geom->scene->device->need_synchro = 1;
+ geom->device->need_synchro = 1;
ERR(gmsh_err_to_res_T(ierr));
exit:
@@ -820,18 +811,18 @@ scad_geometry_extrude
goto error;
}
- if(geom->scene->device->need_synchro) {
- ERR(scad_device_synchronize(geom->scene->device));
+ if(geom->device->need_synchro) {
+ ERR(scad_device_synchronize(geom->device));
}
sz = geom->gmsh_dimTags_n;
data = geom->gmsh_dimTags;
gmshModelOccExtrude(data, sz, SPLIT3(dxdydz), &tagout, &tagoutn,
NULL, 0, NULL, 0, 0 , &ierr);
- geom->scene->device->need_synchro = 1;
+ geom->device->need_synchro = 1;
ERR(gmsh_err_to_res_T(ierr));
- ERR(scad_geometry_create(geom->scene, name, &extrude_geom));
+ ERR(scad_geometry_create(geom->device, name, &extrude_geom));
/* keep only 3D entities */
/* TODO : NOT SURE OF THE CONCEPT */
for (i=0; i<tagoutn/2; ++i) {
@@ -878,17 +869,17 @@ scad_geometry_copy
goto error;
}
- if(geom->scene->device->need_synchro) {
- ERR(scad_device_synchronize(geom->scene->device));
+ if(geom->device->need_synchro) {
+ ERR(scad_device_synchronize(geom->device));
}
sz1 = geom->gmsh_dimTags_n;
data1 = geom->gmsh_dimTags;
gmshModelOccCopy(data1, sz1, &data2, &sz2, &ierr);
- geom->scene->device->need_synchro = 1;
+ geom->device->need_synchro = 1;
ERR(gmsh_err_to_res_T(ierr));
- ERR(scad_geometry_create(geom->scene, name, copy));
+ ERR(scad_geometry_create(geom->device, name, copy));
(*copy)->gmsh_dimTags_n = sz2;
(*copy)->gmsh_dimTags = data2;
@@ -913,14 +904,14 @@ scad_geometry_translate
goto error;
}
- if(geom->scene->device->need_synchro) {
- ERR(scad_device_synchronize(geom->scene->device));
+ if(geom->device->need_synchro) {
+ ERR(scad_device_synchronize(geom->device));
}
sz = geom->gmsh_dimTags_n;
data = geom->gmsh_dimTags;
gmshModelOccTranslate(data, sz, SPLIT3(dxdydz), &ierr);
- geom->scene->device->need_synchro = 1;
+ geom->device->need_synchro = 1;
ERR(gmsh_err_to_res_T(ierr));
exit:
@@ -930,8 +921,8 @@ error:
}
res_T
-scad_scene_geometries_fragment
- (struct scad_scene* scene,
+scad_geometries_fragment
+ (struct scad_device* device,
const char* name,
struct scad_geometry* geom1,
struct scad_geometry* geom2,
@@ -948,15 +939,15 @@ scad_scene_geometries_fragment
struct scad_geometry* geom = NULL;
res_T res = RES_OK;
- if(!scene || !geom1 || !geom2 || !out_geometry
- || geom1->scene != scene || geom2->scene != scene)
+ if(!device || !geom1 || !geom2 || !out_geometry
+ || geom1->device != device || geom2->device != device)
{
res = RES_BAD_ARG;
goto error;
}
- if(scene->device->need_synchro) {
- ERR(scad_device_synchronize(scene->device));
+ if(device->need_synchro) {
+ ERR(scad_device_synchronize(device));
}
sz1 = geom1->gmsh_dimTags_n;
@@ -967,7 +958,7 @@ scad_scene_geometries_fragment
&mapnn, -1, remove, remove, &ierr);
ERR(gmsh_err_to_res_T(ierr));
- ERR(scad_geometry_create(scene, name, &geom));
+ ERR(scad_geometry_create(device, name, &geom));
geom->gmsh_dimTags_n = tagoutn;
geom->gmsh_dimTags = tagout;
if(remove) { /* FIXME: not sure of this! */
@@ -985,8 +976,8 @@ error:
}
res_T
-scad_scene_geometry_boundary
- (struct scad_scene* scene,
+scad_geometry_boundary
+ (struct scad_device* device,
const char* name,
struct scad_geometry* geom,
struct scad_geometry** out_geometry)
@@ -997,13 +988,13 @@ scad_scene_geometry_boundary
int ierr = 0;
res_T res = RES_OK;
- if(!scene || !geom || !out_geometry || geom->scene != scene) {
+ if(!device || !geom || !out_geometry || geom->device != device) {
res = RES_BAD_ARG;
goto error;
}
- if(scene->device->need_synchro) {
- ERR(scad_device_synchronize(scene->device));
+ if(device->need_synchro) {
+ ERR(scad_device_synchronize(device));
}
sz = geom->gmsh_dimTags_n;
@@ -1011,7 +1002,7 @@ scad_scene_geometry_boundary
gmshModelGetBoundary(data, sz, &tagout, &tagoutn, 1, 0, 0, &ierr);
ERR(gmsh_err_to_res_T(ierr));
- ERR(scad_geometry_create(scene, name, &geom));
+ ERR(scad_geometry_create(device, name, &geom));
geom->gmsh_dimTags_n = tagoutn;
geom->gmsh_dimTags = tagout;
@@ -1023,8 +1014,8 @@ error:
}
res_T
-scad_scene_step_import
- (struct scad_scene* scene,
+scad_step_import
+ (struct scad_device* device,
const char* filename,
const char* name,
struct scad_geometry*** out_geometry,
@@ -1035,13 +1026,13 @@ scad_scene_step_import
size_t tagoutn, i;
res_T res = RES_OK;
- if(!scene || !filename) {
+ if(!device || !filename) {
res = RES_BAD_ARG;
goto error;
}
- if(scene->device->need_synchro) {
- ERR(scad_device_synchronize(scene->device));
+ if(device->need_synchro) {
+ ERR(scad_device_synchronize(device));
}
gmshModelOccImportShapes(filename,
@@ -1056,11 +1047,11 @@ scad_scene_step_import
for (i=0; i<tagoutn/2; ++i) {
struct str strname;
- str_init(scene->device->allocator, &strname);
+ str_init(device->allocator, &strname);
ERR(str_set(&strname, name));
ERR(str_append_printf(&strname,"_%lu", (unsigned long)i));
- ERR(scad_geometry_create(scene, str_cget(&strname), &(*out_geometry)[i]));
+ ERR(scad_geometry_create(device, str_cget(&strname), &(*out_geometry)[i]));
(*out_geometry)[i]->gmsh_dimTags_n = 2;
(*out_geometry)[i]->gmsh_dimTags = malloc(2 * sizeof(int));
(*out_geometry)[i]->gmsh_dimTags[0] = tagout[2*i];
diff --git a/src/scad_geometry.h b/src/scad_geometry.h
@@ -21,12 +21,12 @@
#include <rsys/rsys.h>
#include <rsys/str.h>
-struct scad_scene;
+struct scad_device;
struct scad_geometry {
int* gmsh_dimTags;
size_t gmsh_dimTags_n;
- struct scad_scene* scene;
+ struct scad_device* device;
struct str name;
int is_group, group_dim;
};
diff --git a/src/scad_scene.c b/src/scad_scene.c
@@ -1,172 +0,0 @@
-/* Copyright (C) 2022 |Meso|Star> (contact@meso-star.com)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#define _POSIX_C_SOURCE 200112L /* snprintf */
-
-#include "scad.h"
-#include "scad_c.h"
-#include "scad_scene.h"
-#include "scad_device.h"
-
-#include <rsys/rsys.h>
-
-#include <stdio.h>
-#include <gmshc.h>
-
-/*******************************************************************************
- * Helper functions
- ******************************************************************************/
-static res_T
-set_name
- (struct scad_scene* scene)
-{
- int n;
- ASSERT(scene);
- n = snprintf(scene->name, sizeof(scene->name), "%x",
- scene->device->next_scene_id++);
- if((size_t)n >= sizeof(scene->name)) return RES_BAD_ARG;
- return RES_OK;
-}
-
-static void
-scene_release(ref_T* ref)
-{
- struct scad_scene* scn;
- struct mem_allocator* allocator;
- struct htable_names_iterator it, end;
- int ierr = 0;
- res_T res;
- ASSERT(ref);
- scn = CONTAINER_OF(ref, struct scad_scene, ref);
- allocator = scn->device->allocator;
- htable_names_begin(&scn->geometry_names, &it);
- htable_names_end(&scn->geometry_names, &end);
- while(!htable_names_iterator_eq(&it, &end)) {
- struct scad_geometry* geom = *htable_names_iterator_data_get(&it);
- ASSERT(geom->scene == scn);
- SCAD(geometry_release(geom));
- htable_names_iterator_next(&it);
- }
- htable_names_release(&scn->geometry_names);
- res = device_set_current_scene(scn);
- ASSERT(res == RES_OK); (void)res;
- gmshModelRemove(&ierr);
- ASSERT(!ierr); (void)ierr;
- scn->device->current_scene = NULL;
- SCAD(device_ref_put(scn->device));
- MEM_RM(allocator, scn);
-}
-
-/*******************************************************************************
- * Local functions
- ******************************************************************************/
-
-/*******************************************************************************
- * Exported scad_scene functions
- ******************************************************************************/
-res_T
-scad_scene_create
- (struct scad_device* device,
- struct scad_scene** out_scene)
-{
- struct scad_scene* scn = NULL;
- int ierr = 0;
- res_T res = RES_OK;
-
- if(!out_scene || !device) {
- res = RES_BAD_ARG;
- goto error;
- }
-
- scn = (struct scad_scene*)MEM_CALLOC(device->allocator, 1,
- sizeof(struct scad_scene));
- if(!scn) {
- res = RES_MEM_ERR;
- goto error;
- }
- htable_names_init(device->allocator, &scn->geometry_names);
- scn->device = device;
- set_name(scn);
- scn->is_meshed = 0;
- ref_init(&scn->ref);
- SCAD(device_ref_get(scn->device));
-
- gmshModelAdd(scn->name, &ierr);
- ERR(gmsh_err_to_res_T(ierr));
-
- device->current_scene = scn;
-
-exit:
- if(out_scene) *out_scene = scn;
- return res;
-error:
- if(scn) {
- SCAD(scene_ref_put(scn));
- scn = NULL;
- }
- goto exit;
-}
-
-res_T
-scad_scene_conformal_mesh
- (struct scad_scene* scene)
-{
- int* dimTags = NULL;
- size_t dimTags_n;
- int ierr = 0;
- res_T res = RES_OK;
-
- scene->device->need_synchro = 1;
- device_set_current_scene(scene);
- gmshModelOccSynchronize(&ierr);
- ERR(gmsh_err_to_res_T(ierr));
- gmshModelOccGetEntities(&dimTags, &dimTags_n, 3, &ierr);
- ERR(gmsh_err_to_res_T(ierr));
- if(dimTags_n > 2) {
- /* Remove all duplicate entities in the OpenCASCADE CAD representation
- * (different entities at the same geometrical location) after intersecting
- * (using boolean fragments) all highest dimensional entities. */
- gmshModelOccRemoveAllDuplicates(&ierr);
- ERR(gmsh_err_to_res_T(ierr));
- }
- gmshModelOccSynchronize(&ierr);
- ERR(gmsh_err_to_res_T(ierr));
- gmshModelMeshGenerate(2, &ierr);
- ERR(gmsh_err_to_res_T(ierr));
- scene->is_meshed = 1;
-
-exit:
- if(dimTags) free(dimTags);
- return res;
-error:
- goto exit;
-}
-
-
-res_T
-scad_scene_ref_get(struct scad_scene* scene)
-{
- if(!scene) return RES_BAD_ARG;
- ref_get(&scene->ref);
- return RES_OK;
-}
-
-res_T
-scad_scene_ref_put(struct scad_scene* scene)
-{
- if(!scene) return RES_BAD_ARG;
- ref_put(&scene->ref, scene_release);
- return RES_OK;
-}
diff --git a/src/scad_scene.h b/src/scad_scene.h
@@ -1,61 +0,0 @@
-/* Copyright (C) 2022 |Meso|Star> (contact@meso-star.com)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#ifndef SCAD_SCENE_H
-#define SCAD_SCENE_H
-
-#include "scad.h"
-
-struct scad_device;
-struct scad_geometry;
-
-#include <rsys/ref_count.h>
-#include <rsys/hash_table.h>
-#include <rsys/str.h>
-
-static INLINE char
-eq_str(const struct str* a, const struct str* b)
-{
- return !strcmp(str_cget(a), str_cget(b));
-}
-
-static INLINE size_t
-hash_str(const struct str* a)
-{
- return hash_fnv32(str_cget(a), str_len(a));
-}
-
-#define HTABLE_NAME names
-#define HTABLE_DATA struct scad_geometry*
-#define HTABLE_KEY struct str
-#define HTABLE_KEY_FUNCTOR_INIT str_init
-#define HTABLE_KEY_FUNCTOR_RELEASE str_release
-#define HTABLE_KEY_FUNCTOR_COPY str_copy
-#define HTABLE_KEY_FUNCTOR_COPY_AND_RELEASE str_copy_and_release
-#define HTABLE_KEY_FUNCTOR_EQ eq_str
-#define HTABLE_KEY_FUNCTOR_HASH hash_str
-
-#include <rsys/hash_table.h>
-
-struct scad_scene {
- struct scad_device* device;
- struct htable_names geometry_names;
- char name[8];
- int is_meshed;
-
- ref_T ref;
-};
-
-#endif
diff --git a/src/test1.c b/src/test1.c
@@ -51,41 +51,38 @@ main(int argc, char* argv[])
struct scad_geometry* f2 = NULL;
struct scad_geometry* sphere = NULL;
struct scad_geometry* geoms[2];
- struct scad_device* dev = NULL;
- struct scad_scene* scene = NULL;
+ struct scad_device* device = NULL;
struct mem_allocator allocator;
(void)argc; (void)argv;
OK(mem_init_proxy_allocator(&allocator, &mem_default_allocator));
- OK(scad_device_create(NULL, &allocator, 1, &dev));
- OK(scad_scene_create(dev, &scene));
+ OK(scad_device_create(NULL, &allocator, 1, &device));
- OK(scad_scene_add_cylinder(scene, "c1", p1, d1, 2, PI, &geom1));
- OK(scad_scene_add_box(scene, "b1", p2, d2, &geom2));
+ OK(scad_add_cylinder(device, "c1", p1, d1, 2, PI, &geom1));
+ OK(scad_add_box(device, "b1", p2, d2, &geom2));
OK(scad_stl_export(geom1, NULL, 1));
OK(scad_stl_export(geom2, NULL, 1));
geoms[0] = geom1;
geoms[1] = geom2;
- OK(scad_scene_create_group(scene, "g1", 3, geoms, 2, &group1));
+ OK(scad_create_group(device, "g1", 3, geoms, 2, &group1));
OK(scad_stl_export(group1, NULL, 1));
- OK(scad_scene_conformal_mesh(scene));
+ OK(scad_conformal_mesh(device));
OK(scad_stl_export_split(group1, "conformal", 1));
- OK(scad_scene_add_cylinder(scene, "cyl", p1, d1, 1, 2*PI, &cyl));
+ OK(scad_add_cylinder(device, "cyl", p1, d1, 1, 2*PI, &cyl));
OK(scad_stl_export(cyl, NULL, 1));
- OK(scad_scene_fuse_geometries(scene, "fused1", geom1, cyl, &f1, 0));
+ OK(scad_fuse_geometries(device, "fused1", geom1, cyl, &f1, 0));
OK(scad_stl_export(f1, NULL, 1));
- OK(scad_scene_add_sphere(scene, "s1", p1, 1, &sphere));
- OK(scad_scene_fuse_geometries(scene, "fused2", group1, sphere, &f2, 0));
+ OK(scad_add_sphere(device, "s1", p1, 1, &sphere));
+ OK(scad_fuse_geometries(device, "fused2", group1, sphere, &f2, 0));
OK(scad_stl_export(f2, NULL, 0));
exit:
- if(dev) SCAD(device_ref_put(dev));
- if(scene) SCAD(scene_ref_put(scene));
+ if(device) SCAD(device_ref_put(device));
check_memory_allocator(&allocator);
mem_shutdown_proxy_allocator(&allocator);