commit 7763ddef510072550d4111ea06ff8315a6792c4c
parent 98263846262da3b902622c5c53920e822eeb7961
Author: Benjamin Piaud <benjamin.piaud@meso-star.com>
Date: Mon, 18 Jul 2022 15:26:51 +0200
Add support to rectangle, disk and polygonal surface primitive
Diffstat:
| M | src/scad.h | | | 32 | ++++++++++++++++++++++++++++++++ |
| M | src/scad_geometry.c | | | 152 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
2 files changed, 184 insertions(+), 0 deletions(-)
diff --git a/src/scad.h b/src/scad.h
@@ -115,6 +115,38 @@ scad_scene_ref_put
* If provided, names must be unique by scene.
******************************************************************************/
+/* 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,
+ const char* name, /* Can be NULL */
+ const double xyz[3],
+ const double dxdy[2],
+ struct scad_geometry** rectangle); /* Can be NULL: no handler returned. */
+
+/* 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,
+ const char* name, /* Can be NULL */
+ const double xyz[3],
+ const double radius,
+ struct scad_geometry** disk); /* Can be NULL: no handler returned. */
+
+/* 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,
+ const char* name, /* Can be NULL */
+ const double* x,
+ const double* y,
+ const double z,
+ const size_t count, /* size of x and y arrays */
+ struct scad_geometry** polygon); /* Can be NULL: no handler returned. */
+
/* 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
diff --git a/src/scad_geometry.c b/src/scad_geometry.c
@@ -131,6 +131,158 @@ error:
* Exported functions
*****************************************************************************/
res_T
+scad_scene_add_rectangle
+ (struct scad_scene* scene,
+ const char* name,
+ const double xyz[3],
+ const double dxdy[2],
+ struct scad_geometry** out_geometry)
+{
+ int ierr, gmsh_ID;
+ struct scad_geometry* geom = NULL;
+ res_T res = RES_OK;
+
+ if(!scene || !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));
+ geom->gmsh_dimTags_n = 2;
+ geom->gmsh_dimTags = malloc(geom->gmsh_dimTags_n * sizeof(int));
+ if(! geom->gmsh_dimTags_n) {
+ res = RES_MEM_ERR;
+ goto error;
+ }
+ geom->gmsh_dimTags[0] = 2;
+ geom->gmsh_dimTags[1] = gmsh_ID;
+
+exit:
+ if(out_geometry) *out_geometry = geom;
+ return res;
+error:
+ if(geom) {
+ SCAD(geometry_release(geom));
+ geom = NULL;
+ }
+ goto exit;
+}
+
+res_T
+scad_scene_add_disk
+ (struct scad_scene* scene,
+ const char* name,
+ const double xyz[3],
+ const double radius,
+ struct scad_geometry** out_geometry)
+{
+ int ierr, gmsh_ID;
+ struct scad_geometry* geom = NULL;
+ res_T res = RES_OK;
+
+ if(!scene || !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));
+ geom->gmsh_dimTags_n = 2;
+ geom->gmsh_dimTags = malloc(geom->gmsh_dimTags_n * sizeof(int));
+ if(! geom->gmsh_dimTags_n) {
+ res = RES_MEM_ERR;
+ goto error;
+ }
+ geom->gmsh_dimTags[0] = 2;
+ geom->gmsh_dimTags[1] = gmsh_ID;
+
+exit:
+ if(out_geometry) *out_geometry = geom;
+ return res;
+error:
+ if(geom) {
+ SCAD(geometry_release(geom));
+ geom = NULL;
+ }
+ goto exit;
+}
+
+res_T
+scad_scene_add_polygon
+ (struct scad_scene* scene,
+ const char* name,
+ const double* x,
+ const double* y,
+ const double z,
+ const size_t count,
+ struct scad_geometry** out_geometry)
+{
+ int ierr, gmsh_ID;
+ struct scad_geometry* geom = NULL;
+ size_t i;
+ int* points = NULL;
+ int* lines = NULL;
+ int loop;
+ res_T res = RES_OK;
+
+ if(!scene || !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);
+ ERR(gmsh_err_to_res_T(ierr));
+ }
+
+ lines = malloc(count * sizeof(int));
+ for (i=0; i<count-1; ++i) {
+ lines[i] = gmshModelOccAddLine(points[i], points[i+1], -1, &ierr);
+ ERR(gmsh_err_to_res_T(ierr));
+ }
+ /*and the last line*/
+ lines[count-1] = gmshModelOccAddLine(points[count-1], points[0], -1, &ierr);
+ ERR(gmsh_err_to_res_T(ierr));
+
+ loop = gmshModelOccAddCurveLoop(lines, count, -1, &ierr);
+ ERR(gmsh_err_to_res_T(ierr));
+
+ gmsh_ID = gmshModelOccAddPlaneSurface(&loop, 1, -1, &ierr);
+ ERR(gmsh_err_to_res_T(ierr));
+
+ ERR(scad_geometry_create(scene, name, &geom));
+ geom->gmsh_dimTags_n = 2;
+ geom->gmsh_dimTags = malloc(geom->gmsh_dimTags_n * sizeof(int));
+ if(! geom->gmsh_dimTags_n) {
+ res = RES_MEM_ERR;
+ goto error;
+ }
+ geom->gmsh_dimTags[0] = 2;
+ geom->gmsh_dimTags[1] = gmsh_ID;
+
+exit:
+ if(out_geometry) *out_geometry = geom;
+ if(points) free(points);
+ if(lines) free(lines);
+ return res;
+error:
+ if(geom) {
+ SCAD(geometry_release(geom));
+ geom = NULL;
+ }
+ goto exit;
+}
+res_T
scad_scene_add_box
(struct scad_scene* scene,
const char* name,