commit bddeb3208562e7fef9fa17c95d177a9c6d2d0be3
parent 27330b38c2873efffd2ac9c52ce3fe7965813b5a
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Thu, 7 Apr 2022 17:15:48 +0200
Full review
Minor rewrites and fix coding style. Add review comments (TODO and FIXME)
Diffstat:
| M | src/scad.c | | | 623 | ++++++++++++++++++++++++++++++++++++++----------------------------------------- |
| M | src/scad.h | | | 177 | +++++++++++++++++++++++++++++++++++++++++++++++-------------------------------- |
2 files changed, 405 insertions(+), 395 deletions(-)
diff --git a/src/scad.c b/src/scad.c
@@ -13,45 +13,76 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
#include "scad.h"
+
+#include <gmshc.h>
+
+#include <rsys/cstr.h>
#include <rsys/str.h>
+#include <rsys/stretchy_array.h>
+
+#include <stdio.h>
+/******************************************************************************
+ * Helper functions
+ *****************************************************************************/
+static INLINE res_T
+gmsh_err_to_res_T(const int ierr)
+{
+ res_T res = RES_OK;
+
+ switch(ierr) {
+ /* TODO identify more precisely the gmsh errors */
+ case 0: res = RES_OK; break;
+ default: res = RES_UNKNOWN_ERR; break;
+ }
+ return res;
+}
+
+/******************************************************************************
+ * Exported functions
+ *****************************************************************************/
res_T
scad_init(void)
{
res_T res = RES_OK;
int ierr = 0;
- gmshInitialize(0, NULL, 1, 0, &ierr);
+
+ gmshInitialize(0, NULL, 1, 0, &ierr);
gmshModelAdd("model", &ierr);
gmshOptionSetNumber("Mesh.StlOneSolidPerSurface", 2, &ierr);
+ if((res = gmsh_err_to_res_T(ierr)) != RES_OK) goto error;
gmshOptionSetNumber("Mesh.MeshSizeFromPoints", 0, &ierr);
+ if((res = gmsh_err_to_res_T(ierr)) != RES_OK) goto error;
gmshOptionSetNumber("Mesh.MeshSizeFromCurvature", 1, &ierr);
+ if((res = gmsh_err_to_res_T(ierr)) != RES_OK) goto error;
gmshOptionSetNumber("Mesh.MinimumElementsPerTwoPi", 36, &ierr);
+ if((res = gmsh_err_to_res_T(ierr)) != RES_OK) goto error;
gmshOptionSetNumber("Mesh.MeshSizeExtendFromBoundary", 0, &ierr);
-
- if (ierr !=0) goto error;
+ if((res = gmsh_err_to_res_T(ierr)) != RES_OK) goto error;
exit:
return res;
error:
- fprintf(stderr,"Can't initialize gmsh !\n");
+ fprintf(stderr, "%s: can't initialize gmsh -- %s\n",
+ FUNC_NAME, res_to_cstr(res));
goto exit;
}
res_T
scad_release(void)
{
+ res_T res = RES_OK;
int ierr = 0;
- gmshFinalize(&ierr);
- if (ierr != 0) goto error;
+ gmshFinalize(&ierr);
+ if((res = gmsh_err_to_res_T(ierr)) != RES_OK) goto error;
exit:
- return ierr;
+ return res;
error:
- fprintf(stderr,"Can't release gmsh !\n");
+ fprintf(stderr, "%s: can't release gmsh -- %s\n", FUNC_NAME, res_to_cstr(res));
goto exit;
}
@@ -60,7 +91,7 @@ scad_synchronize(void)
{
int ierr;
gmshModelOccSynchronize(&ierr);
- return ierr;
+ return gmsh_err_to_res_T(ierr);
}
res_T
@@ -68,187 +99,186 @@ scad_run_ui(void)
{
int ierr;
gmshFltkRun(&ierr);
- return ierr;
+ return gmsh_err_to_res_T(ierr);
}
+res_T
+scad_geom_release(scad_geom_T geom)
+{
+ sa_release(geom);
+ return RES_OK;
+}
res_T
scad_concat(scad_geom_T* geom1, const scad_geom_T geom2)
-{
- int res = RES_OK;
- int i;
+{
+ res_T res = RES_OK;
+ size_t i;
- if (!geom2) {fprintf(stderr,"Can't concat \n"); res = RES_BAD_ARG; goto error;}
+ if(!geom1 || !geom2) {
+ fprintf(stderr, "%s: can't concat\n", FUNC_NAME);
+ res = RES_BAD_ARG;
+ goto error;
+ }
- for (i=0; i<(int)sa_size(geom2) ; ++i)
- {
- sa_push(*geom1, geom2[i]);
- }
+ FOR_EACH(i, 0, sa_size(geom2)) {
+ sa_push(*geom1, geom2[i]);
+ }
exit:
return res;
error:
- goto exit;
-}
-
+ goto exit;
+}
res_T
scad_addbox
-(const double xyz[3], const double dxdydz[3], scad_geom_T* geom)
+ (const double xyz[3],
+ const double dxdydz[3],
+ scad_geom_T* geom)
{
- res_T res = RES_OK;
int ierr = 0;
int tag = 0;
+ res_T res = RES_OK;
if(!xyz || !dxdydz) {
- fprintf(stderr,"Invalid data !\n");
- return RES_BAD_ARG;
+ fprintf(stderr, "%s: invalid data!\n", FUNC_NAME);
+ res = RES_BAD_ARG;
+ goto error;
}
- tag = gmshModelOccAddBox(xyz[0], xyz[1], xyz[2],
- dxdydz[0], dxdydz[1], dxdydz[2],
- -1,
- &ierr);
-
- if (ierr !=0) goto error;
+ tag = gmshModelOccAddBox(SPLIT3(xyz), SPLIT3(dxdydz), -1, &ierr);
+ if((res = gmsh_err_to_res_T(ierr)) != RES_OK) {
+ fprintf(stderr, "%s: can't create box -- %s\n", FUNC_NAME, res_to_cstr(res));
+ goto error;
+ }
- if (*geom != NULL) *geom = NULL;
+ if(*geom != NULL) *geom = NULL;
sa_push(*geom,3);
sa_push(*geom,tag);
exit:
return res;
error:
- res = ierr;
- fprintf(stderr,"Can't create box !\n");
goto exit;
-
}
-
res_T
scad_addcylinder
-(const double xyz[3], const double axis[3], const double rad, const double angle, scad_geom_T* geom)
+ (const double xyz[3],
+ const double axis[3],
+ const double rad,
+ const double angle,
+ scad_geom_T* geom)
{
- res_T res = RES_OK;
int ierr = 0;
int tag = 0;
+ res_T res = RES_OK;
if(!xyz || !axis) {
- fprintf(stderr,"Invalid data !\n");
- return RES_BAD_ARG;
+ fprintf(stderr, "%s: invalid data!\n", FUNC_NAME);
+ res = RES_BAD_ARG;
+ goto error;
}
- tag = gmshModelOccAddCylinder(xyz[0],
- xyz[1],
- xyz[2],
- axis[0],
- axis[1],
- axis[2],
- rad,
- -1,
- angle,
- &ierr);
-
- if (ierr !=0) goto error;
+ tag = gmshModelOccAddCylinder(SPLIT3(xyz), SPLIT3(axis), rad, -1, angle, &ierr);
+ if((res = gmsh_err_to_res_T(ierr)) != RES_OK) {
+ fprintf(stderr, "%s: can't create cylinder -- %s\n",
+ FUNC_NAME, res_to_cstr(res));
+ goto error;
+ }
- if (*geom != NULL) *geom = NULL;
+ if(*geom != NULL) *geom = NULL;
sa_push(*geom,3);
sa_push(*geom,tag);
exit:
return res;
error:
- res = ierr;
- fprintf(stderr,"Can't create cylinder !\n");
goto exit;
}
int
scad_addsphere
-(const double xyz[3], const double rad, scad_geom_T* geom)
+ (const double xyz[3],
+ const double rad,
+ scad_geom_T* geom)
{
- res_T res = RES_OK;
int ierr = 0;
int tag = 0;
+ res_T res = RES_OK;
if(!xyz) {
- fprintf(stderr,"Invalid data !\n");
- return RES_BAD_ARG;
+ fprintf(stderr,"%s: invalid data!\n", FUNC_NAME);
+ res = RES_BAD_ARG;
+ goto error;
}
- tag = gmshModelOccAddSphere(xyz[0],
- xyz[1],
- xyz[2],
- rad,
- -1,
- -PI/2,
- PI/2,
- 2*PI,
- &ierr);
-
- if (ierr !=0) goto error;
+ tag = gmshModelOccAddSphere(SPLIT3(xyz), rad, -1, -PI/2, PI/2, 2*PI, &ierr);
+ if((res = gmsh_err_to_res_T(ierr)) != RES_OK) {
+ fprintf(stderr, "%s: can't create sphere -- %s\n",
+ FUNC_NAME, res_to_cstr(res));
+ goto exit;
+ }
- if (*geom != NULL) *geom = NULL;
+ if(*geom != NULL) *geom = NULL;
sa_push(*geom,3);
sa_push(*geom,tag);
exit:
return res;
error:
- res = ierr;
- fprintf(stderr,"Can't create sphere !\n");
goto exit;
}
res_T
scad_remove(scad_geom_T geom)
{
- res_T res = RES_OK;
int ierr = 0;
+ res_T res = RES_OK;
gmshModelOccRemove(geom, sa_size(geom), 0, &ierr);
-
- if (ierr !=0) goto error;
-
+ if((res = gmsh_err_to_res_T(ierr)) != RES_OK) {
+ fprintf(stderr, "%s: can't remove geometry -- %s\n",
+ FUNC_NAME, res_to_cstr(res));
+ goto error;
+ }
+
exit:
return res;
error:
- res = ierr;
- fprintf(stderr,"Can't remove geometry !\n");
goto exit;
}
-
res_T
scad_fuse
-(const scad_geom_T geom1, const scad_geom_T geom2, scad_geom_T* out, const int remove)
+ (const scad_geom_T geom1,
+ const scad_geom_T geom2,
+ scad_geom_T* out,
+ const int remove)
{
- res_T res = RES_OK;
- int ierr, i;
- int* tagout;
+ int* tagout = NULL;
int** map = NULL;
- size_t tagoutn, *mapn, mapnn;
-
- gmshModelOccFuse(geom1, sa_size(geom1),
- geom2, sa_size(geom2),
- &tagout, &tagoutn,
- &map, &mapn, &mapnn,
- -1,
- remove,
- remove,
- &ierr);
+ size_t* mapn = NULL;
+ size_t tagoutn, mapnn, i;
+ int ierr = 0;
+ res_T res = RES_OK;
- if (ierr != 0 ) {fprintf(stderr,"Fuse not possible !\n"); goto error;}
+ gmshModelOccFuse(geom1, sa_size(geom1), geom2, sa_size(geom2), &tagout,
+ &tagoutn, &map, &mapn, &mapnn, -1, remove, remove, &ierr);
+ if((res = gmsh_err_to_res_T(ierr)) != RES_OK) {
+ fprintf(stderr, "%s: fuse not possible -- %s\n", FUNC_NAME, res_to_cstr(res));
+ goto error;
+ }
- for (i=0; i<(int)tagoutn; ++i){
+ FOR_EACH(i, 0, tagoutn) {
sa_push(*out, tagout[i]);
}
-
+
exit:
- if (tagout) free(tagout);
- if (mapn) free(mapn);
- if (map) free(map);
+ if(tagout) free(tagout);
+ if(mapn) free(mapn);
+ if(map) free(map);
return res;
error:
goto exit;
@@ -257,34 +287,34 @@ error:
res_T
scad_cut
-(const scad_geom_T geom1, const scad_geom_T geom2, scad_geom_T* out, const int remove)
+ (const scad_geom_T geom1,
+ const scad_geom_T geom2,
+ scad_geom_T* out,
+ const int remove)
{
- res_T res = RES_OK;
- int ierr, i;
- int* tagout;
+ int* tagout = NULL;
int** map = NULL;
- size_t tagoutn, *mapn, mapnn;
-
- gmshModelOccCut(geom1, sa_size(geom1),
- geom2, sa_size(geom2),
- &tagout, &tagoutn,
- &map, &mapn, &mapnn,
- -1,
- remove,
- remove,
- &ierr);
+ size_t* mapn = NULL;
+ size_t tagoutn, mapnn, i;
+ int ierr = 0;
+ res_T res = RES_OK;
- if (ierr != 0 ) {fprintf(stderr,"Cut not possible !\n"); goto error;}
+ gmshModelOccCut(geom1, sa_size(geom1), geom2, sa_size(geom2), &tagout,
+ &tagoutn, &map, &mapn, &mapnn, -1, remove, remove, &ierr);
+ if((res = gmsh_err_to_res_T(ierr)) != RES_OK) {
+ fprintf(stderr, "%s: cut not possible -- %s\n", FUNC_NAME, res_to_cstr(res));
+ goto error;
+ }
- if (*out) sa_clear(*out);
- for (i=0; i<(int)tagoutn; ++i){
+ if(*out) sa_clear(*out);
+ FOR_EACH(i, 0, tagoutn) {
sa_push(*out, tagout[i]);
}
exit:
- if (tagout) free(tagout);
- if (mapn) free(mapn);
- if (map) free(map);
+ if(tagout) free(tagout);
+ if(mapn) free(mapn);
+ if(map) free(map);
return res;
error:
goto exit;
@@ -292,70 +322,46 @@ error:
res_T
scad_intersect
-(const scad_geom_T geom1, const scad_geom_T geom2, scad_geom_T* out, const int remove)
+ (const scad_geom_T geom1,
+ const scad_geom_T geom2,
+ scad_geom_T* out,
+ const int remove)
{
- res_T res = RES_OK;
- int ierr, i;
- int* tagout;
+ int* tagout = NULL;
int** map = NULL;
- size_t tagoutn, *mapn, mapnn;
-
- gmshModelOccIntersect(geom1, sa_size(geom1),
- geom2, sa_size(geom2),
- &tagout, &tagoutn,
- &map, &mapn, &mapnn,
- -1,
- remove,
- remove,
- &ierr);
-
- if (ierr != 0 ) {fprintf(stderr,"Intersection not possible !\n"); goto error;}
+ size_t* mapn = NULL;
+ size_t tagoutn, mapnn, i;
+ int ierr = 0;
+ res_T res = RES_OK;
+ gmshModelOccIntersect(geom1, sa_size(geom1), geom2, sa_size(geom2), &tagout,
+ &tagoutn, &map, &mapn, &mapnn, -1, remove, remove, &ierr);
+ if((res = gmsh_err_to_res_T(ierr)) != RES_OK) {
+ fprintf(stderr, "%s: intersection not possible -- %s\n",
+ FUNC_NAME, res_to_cstr(res));
+ goto error;
+ }
tagoutn = 0;
- if (tagoutn == 0) { /* try instersect boundary to extract common face */
+ if(tagoutn == 0) { /* try instersect boundary to extract common face */
int* bound1;
int* bound2;
size_t n1, n2;
- gmshModelGetBoundary(geom1, sa_size(geom1),
- &bound1, &n1,
- 1,
- 0,
- 0,
- &ierr);
-
- /*if (ierr != 0) { */
- /*if (bound1) free(bound1};*/
- /*goto error:*/
- /*}*/
-
- gmshModelGetBoundary(geom2, sa_size(geom2),
- &bound2, &n2,
- 1,
- 0,
- 0,
- &ierr);
-
- gmshModelOccIntersect(bound1, n1,
- bound2, n2,
- &tagout, &tagoutn,
- &map, &mapn, &mapnn,
- -1,
- NODELETE,
- NODELETE,
- &ierr);
+ gmshModelGetBoundary(geom1, sa_size(geom1), &bound1, &n1, 1, 0, 0, &ierr);
+ gmshModelGetBoundary(geom2, sa_size(geom2), &bound2, &n2, 1, 0, 0, &ierr);
+ gmshModelOccIntersect(bound1, n1, bound2, n2, &tagout, &tagoutn, &map,
+ &mapn, &mapnn, -1, 0/*no delete*/, 0/*no delete*/, &ierr);
}
-
- for (i=0; i<(int)tagoutn; ++i){
+ FOR_EACH(i, 0, tagoutn) {
sa_push(*out, tagout[i]);
}
exit:
- if (tagout) free(tagout);
- if (mapn) free(mapn);
- if (map) free(map);
+ if(tagout) free(tagout);
+ if(mapn) free(mapn);
+ if(map) free(map);
return res;
error:
goto exit;
@@ -364,62 +370,60 @@ error:
res_T
scad_fragment
-(const scad_geom_T geom1, const scad_geom_T geom2, scad_geom_T* out, const int remove)
+ (const scad_geom_T geom1,
+ const scad_geom_T geom2,
+ scad_geom_T* out,
+ const int remove)
{
- res_T res = RES_OK;
- int ierr, i;
- int* tagout;
+ int* tagout = NULL;
int** map = NULL;
- size_t tagoutn, *mapn, mapnn;
-
- gmshModelOccFragment(geom1, sa_size(geom1),
- geom2, sa_size(geom2),
- &tagout, &tagoutn,
- &map, &mapn, &mapnn,
- -1,
- remove,
- remove,
- &ierr);
+ size_t* mapn = NULL;
+ size_t tagoutn, mapnn, i;
+ int ierr = 0;
+ res_T res = RES_OK;
- if (ierr != 0 ) {fprintf(stderr,"Fragment not possible !\n"); goto error;}
+ gmshModelOccFragment(geom1, sa_size(geom1), geom2, sa_size(geom2), &tagout,
+ &tagoutn, &map, &mapn, &mapnn, -1, remove, remove, &ierr);
+ if((res = gmsh_err_to_res_T(ierr)) != RES_OK) {
+ fprintf(stderr, "%s: fragment not possible -- %s\n",
+ FUNC_NAME, res_to_cstr(res));
+ goto error;
+ }
- for (i=0; i<(int)tagoutn; ++i){
+ FOR_EACH(i, 0, tagoutn) {
sa_push(*out, tagout[i]);
}
exit:
- if (tagout) free(tagout);
- if (mapn) free(mapn);
- if (map) free(map);
+ if(tagout) free(tagout);
+ if(mapn) free(mapn);
+ if(map) free(map);
return res;
error:
goto exit;
}
res_T
-scad_boundary
-(const scad_geom_T geom1, scad_geom_T* out)
+scad_boundary(const scad_geom_T geom1, scad_geom_T* out)
{
+ int* b = NULL;
+ size_t i, n;
+ int ierr = 0;
res_T res = RES_OK;
- int ierr,i;
- int* b;
- size_t n;
-
- gmshModelGetBoundary(geom1, sa_size(geom1),
- &b, &n,
- 1,
- 0,
- 0,
- &ierr);
- if (ierr != 0 ) {fprintf(stderr,"Get boundary not possible !\n"); goto error;}
+ gmshModelGetBoundary(geom1, sa_size(geom1), &b, &n, 1, 0, 0, &ierr);
+ if((res = gmsh_err_to_res_T(ierr)) != RES_OK) {
+ fprintf(stderr, "%s: get boundary not possible -- %s\n",
+ FUNC_NAME, res_to_cstr(res));
+ goto error;
+ }
- for (i=0; i<(int)n; ++i){
+ FOR_EACH(i, 0, n) {
sa_push(*out, b[i]);
}
exit:
- if (b) free(b);
+ if(b) free(b);
return res;
error:
goto exit;
@@ -429,234 +433,205 @@ res_T
scad_translate
(scad_geom_T geom, const double dxdydz[3])
{
+ int ierr = 0;
res_T res = RES_OK;
- int ierr;
- if (!geom || !dxdydz){
- fprintf(stderr,"Invalid data !\n");
- return RES_BAD_ARG;
+ if(!geom || !dxdydz){
+ fprintf(stderr,"%s: invalid data!\n", FUNC_NAME);
+ res = RES_BAD_ARG;
+ goto error;
}
- gmshModelOccTranslate(geom, sa_size(geom),
- dxdydz[0],
- dxdydz[1],
- dxdydz[2],
- &ierr);
-
- if (ierr != 0 ) {fprintf(stderr,"Translation not possible !\n"); goto error;}
+ gmshModelOccTranslate(geom, sa_size(geom), SPLIT3(dxdydz), &ierr);
+ if((res = gmsh_err_to_res_T(ierr)) != RES_OK) {
+ fprintf(stderr, "%s: translation not possible -- %s\n",
+ FUNC_NAME, res_to_cstr(res));
+ goto error;
+ }
exit:
return res;
error:
- res = ierr;
goto exit;
}
res_T
scad_rotate
-(scad_geom_T geom, const double pt[3], const double axis[3], const double angle)
+ (scad_geom_T geom,
+ const double pt[3],
+ const double axis[3],
+ const double angle)
{
+ int ierr = 0;
res_T res = RES_OK;
- int ierr;
- if (!geom || !pt || !axis){
- fprintf(stderr,"Invalid data !\n");
- return RES_BAD_ARG;
+ if(!geom || !pt || !axis){
+ fprintf(stderr, "%s: invalid data!\n", FUNC_NAME);
+ res = RES_BAD_ARG;
+ goto error;
}
- gmshModelOccRotate(geom, sa_size(geom),
- pt[0],
- pt[1],
- pt[2],
- axis[0],
- axis[1],
- axis[2],
- angle,
- &ierr);
-
- if (ierr != 0 ) {fprintf(stderr,"Rotation not possible !\n"); goto error;}
+ gmshModelOccRotate(geom, sa_size(geom), SPLIT3(pt), SPLIT3(axis), angle, &ierr);
+ if((res = gmsh_err_to_res_T(ierr)) != RES_OK) {
+ fprintf(stderr, "%s: rotation not possible -- %s\n",
+ FUNC_NAME, res_to_cstr(res));
+ goto error;
+ }
exit:
return res;
error:
- res = ierr;
goto exit;
}
-res_T
+res_T
scad_conformal_mesh(void)
{
- int ierr = 0;
- int* dimTags;
+ int* dimTags = NULL;
size_t dimTags_n;
+ int ierr = 0;
gmshModelOccSynchronize(&ierr);
gmshModelOccGetEntities(&dimTags, &dimTags_n, 3, &ierr);
- if ( ierr == 0 && dimTags_n > 2) gmshModelOccRemoveAllDuplicates(&ierr);
+ if( ierr == 0 && dimTags_n > 2) gmshModelOccRemoveAllDuplicates(&ierr);
gmshModelOccSynchronize(&ierr);
gmshModelMeshGenerate(2, &ierr);
-
- return ierr;
+ return gmsh_err_to_res_T(ierr);
}
-
res_T
scad_stl_export(const scad_geom_T geom, char *prefix)
{
- res_T res = RES_OK;
- int ierr;
- int i;
+ struct str filename;
int* tagout = NULL;
int* tags = NULL;
- size_t tagoutn;
- int group, dimtag[2];
- struct str filename;
+ size_t tagoutn, i;
+ int dimtag[2];
+ int group;
+ int ierr = 0;
+ res_T res = RES_OK;
str_init(NULL, &filename);
str_set(&filename, prefix);
str_append(&filename, ".stl");
- if (geom[0] == 2) {
+ if(geom[0] == 2) {
tagoutn = sa_size(geom);
- for(i=0; i<(int)tagoutn/2; ++i){
+ FOR_EACH(i, 0, tagoutn/2){
sa_push(tags, geom[2*i + 1]);
}
-
- group = gmshModelAddPhysicalGroup(2, tags, tagoutn/2,
- -1,
- &ierr);
- if (ierr !=0) goto error;
+ group = gmshModelAddPhysicalGroup(2, tags, tagoutn/2, -1, &ierr);
+ if((res = gmsh_err_to_res_T(ierr)) != RES_OK) goto error;
} else {
+ FOR_EACH(i, 0, sa_size(geom)/2) {
+ gmshModelMeshSetOutwardOrientation(geom[2*i+1], &ierr);
+ }
+
+ gmshModelGetBoundary(geom, sa_size(geom),&tagout, &tagoutn, 1, 0, 0, &ierr);
+ if((res = gmsh_err_to_res_T(ierr)) != RES_OK) goto error;
- for (i=0; i<(int)sa_size(geom)/2; ++i)
- {
- gmshModelMeshSetOutwardOrientation(geom[2*i+1], &ierr);
- }
-
- gmshModelGetBoundary(geom, sa_size(geom),
- &tagout, &tagoutn,
- 1,
- 0,
- 0,
- &ierr);
-
- if (ierr !=0) goto error;
-
- for(i=0; i<(int)tagoutn/2; ++i){
+ FOR_EACH(i, 0, tagoutn/2) {
sa_push(tags, tagout[2*i + 1]);
}
- group = gmshModelAddPhysicalGroup(2, tags, tagoutn/2,
- -1,
- &ierr);
- if (ierr !=0) goto error;
+ group = gmshModelAddPhysicalGroup(2, tags, tagoutn/2, -1, &ierr);
+ if((res = gmsh_err_to_res_T(ierr)) != RES_OK) goto error;
}
gmshWrite(str_get(&filename), &ierr);
- if (ierr !=0) goto error;
+ if((res = gmsh_err_to_res_T(ierr)) != RES_OK) goto error;
dimtag[0]=2;
dimtag[1]=group;
gmshModelRemovePhysicalGroups(dimtag, 2, &ierr);
- if (ierr !=0) goto error;
+ if((res = gmsh_err_to_res_T(ierr)) != RES_OK) goto error;
exit:
str_release(&filename);
- if (tagout) free(tagout);
- if (tags) sa_release(tags);
+ if(tagout) free(tagout);
+ if(tags) sa_release(tags);
return res;
error:
+ fprintf(stderr, "%s: could not export to STL -- %s\n",
+ FUNC_NAME, res_to_cstr(res));
goto exit;
}
res_T
scad_stl_export_split(const scad_geom_T geom, char *prefix)
{
- res_T res = RES_OK;
- int ierr;
- int i;
+ struct str filename;
int* tagout = NULL;
int* tags = NULL;
- size_t tagoutn;
- int group, dimtag[2];
+ size_t tagoutn, i;
+ int dimtag[2];
+ int group;
+ int ierr = 0;
+ res_T res = RES_OK;
- if (geom[0] == 2) {
+ str_init(NULL, &filename);
+
+ if(geom[0] == 2) {
tagoutn = sa_size(geom);
- for(i=0; i<(int)tagoutn/2; ++i){
- struct str filename;
+ FOR_EACH(i, 0, tagoutn/2) {
char num[32];
- group = gmshModelAddPhysicalGroup(2, &geom[2*i+1], 1,
- -1,
- &ierr);
- if (ierr !=0) goto error;
+ group = gmshModelAddPhysicalGroup(2, &geom[2*i+1], 1, -1, &ierr);
+ if((res = gmsh_err_to_res_T(ierr)) != RES_OK) goto error;
- str_init(NULL, &filename);
+ /* TODO move in a function
+ * TODO check the str return code */
str_set(&filename, prefix);
str_append_char(&filename, '_');
- sprintf(num, "%d", i);
+ sprintf(num, "%lu", (unsigned long)i); /* FIXME handle possible overflow */
str_append(&filename, num);
str_append(&filename, ".stl");
gmshWrite(str_get(&filename), &ierr);
- if (ierr !=0) {str_release(&filename); goto error;}
+ if((res = gmsh_err_to_res_T(ierr)) != RES_OK) goto error;
dimtag[0]=2;
dimtag[1]=group;
gmshModelRemovePhysicalGroups(dimtag, 2, &ierr);
- if (ierr !=0) {str_release(&filename); goto error;}
-
- str_release(&filename);
+ if((res = gmsh_err_to_res_T(ierr)) != RES_OK) goto error;
}
} else {
- for (i=0; i<(int)sa_size(geom)/2; ++i)
- {
- gmshModelMeshSetOutwardOrientation(geom[2*i+1], &ierr);
- }
-
- gmshModelGetBoundary(geom, sa_size(geom),
- &tagout, &tagoutn,
- 1,
- 0,
- 0,
- &ierr);
-
- if (ierr !=0) goto error;
-
- for(i=0; i<(int)tagoutn/2; ++i){
- struct str filename;
- char num[32];
+ FOR_EACH(i, 0, sa_size(geom)/2) {
+ gmshModelMeshSetOutwardOrientation(geom[2*i+1], &ierr);
+ }
+ gmshModelGetBoundary(geom, sa_size(geom), &tagout, &tagoutn, 1, 0, 0, &ierr);
+ if((res = gmsh_err_to_res_T(ierr)) != RES_OK) goto error;
+
+ FOR_EACH(i, 0, tagoutn/2){
+ char num[32];
- group = gmshModelAddPhysicalGroup(2, &tagout[2*i+1], 1,
- -1,
- &ierr);
- if (ierr !=0) goto error;
+ group = gmshModelAddPhysicalGroup(2, &tagout[2*i+1], 1, -1, &ierr);
+ if((res = gmsh_err_to_res_T(ierr)) != RES_OK) goto error;
- str_init(NULL, &filename);
+ /* TODO move in a function
+ * TODO check the str return code */
str_set(&filename, prefix);
str_append_char(&filename, '_');
- sprintf(num, "%d", i);
+ sprintf(num, "%lu", (unsigned long)i); /* FIXME handle possible overflow */
str_append(&filename, num);
str_append(&filename, ".stl");
gmshWrite(str_get(&filename), &ierr);
- if (ierr !=0) {str_release(&filename); goto error;}
+ if((res = gmsh_err_to_res_T(ierr)) != RES_OK) goto error;
dimtag[0]=2;
dimtag[1]=group;
gmshModelRemovePhysicalGroups(dimtag, 2, &ierr);
- if (ierr !=0) {str_release(&filename); goto error;}
-
- str_release(&filename);
+ if((res = gmsh_err_to_res_T(ierr)) != RES_OK) goto error;
}
}
-
exit:
- if (tagout) free(tagout);
- if (tags) sa_release(tags);
+ str_release(&filename);
+ if(tagout) free(tagout);
+ if(tags) sa_release(tags);
return res;
error:
goto exit;
diff --git a/src/scad.h b/src/scad.h
@@ -12,106 +12,141 @@
*
* 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_H
#define SCAD_H
-#include <stdio.h>
-#include <stdlib.h>
-#include <gmshc.h>
#include <rsys/rsys.h>
-#include <rsys/stretchy_array.h>
-#include <rsys/math.h>
-#include <string.h>
-/* wrapping of dimTags gmsh description */
+/* Library symbol management */
+#if defined(SCAD_SHARED_BUILD) /* Build shared library */
+ #define SCAD_API extern EXPORT_SYM
+#elif defined(SCAD_STATIC) /* Use/build static library */
+ #define SCAD_API extern LOCAL_SYM
+#else /* Use shared library */
+ #define SCAD_API extern IMPORT_SYM
+#endif
+
+/* Wrapping of dimTags gmsh description */
typedef int* scad_geom_T;
-#define SCAD_GEOM_NULL_ NULL
-static const scad_geom_T SCAD_GEOM_NULL = SCAD_GEOM_NULL_;
-
-/* remove the handler but not the geomtry */
-/* to remove geometry, use scad_geom_remove */
-static FINLINE
-res_T scad_geom_release(scad_geom_T geom)
-{
- sa_release(geom);
- return RES_OK;
-}
-
-/*****************************************************************************/
-/*****************************************************************************/
-/*****************************************************************************/
-res_T
-scad_init(void);
-
-res_T
-scad_release(void);
-
-res_T
-scad_synchronize(void);
-
-res_T
-scad_run_ui(void);
-
-res_T
+#define SCAD_GEOM_NULL__ NULL
+static const scad_geom_T SCAD_GEOM_NULL = SCAD_GEOM_NULL__;
+
+BEGIN_DECLS
+
+/******************************************************************************
+ * API
+ *****************************************************************************/
+SCAD_API res_T
+scad_init
+ (void);
+
+SCAD_API res_T
+scad_release
+ (void);
+
+SCAD_API res_T
+scad_synchronize
+ (void);
+
+SCAD_API res_T /* FIXME remove this */
+scad_run_ui
+ (void);
+
+/* Remove the handler but not the geometry. Use scad_geom_remove to remove it.
+ * TODO where is scad_geom_remove? */
+SCAD_API res_T
+scad_geom_release
+ (scad_geom_T geom);
+
+SCAD_API res_T
scad_addbox
-(const double xyz[3], const double dxdydz[3], scad_geom_T* geom);
+ (const double xyz[3],
+ const double dxdydz[3],
+ scad_geom_T* geom);
-res_T
+SCAD_API res_T
scad_addcylinder
-(const double xyz[3], const double axis[3], const double rad, const double angle, scad_geom_T* geom);
+ (const double xyz[3],
+ const double axis[3],
+ const double rad,
+ const double angle,
+ scad_geom_T* geom);
-res_T
+SCAD_API res_T
scad_addsphere
-(const double xyz[3], const double rad, scad_geom_T* geom);
+ (const double xyz[3],
+ const double rad,
+ scad_geom_T* geom);
-res_T
-scad_remove(scad_geom_T geom);
+SCAD_API res_T
+scad_remove
+ (scad_geom_T geom);
-res_T
-scad_concat(scad_geom_T* geom1, const scad_geom_T geom2);
+SCAD_API res_T
+scad_concat
+ (scad_geom_T* geom1,
+ const scad_geom_T geom2);
-#define DELETE 1
-#define NODELETE 0
-res_T
+SCAD_API res_T
scad_fuse
-(const scad_geom_T geom1, const scad_geom_T geom2, scad_geom_T* out, const int remove);
+ (const scad_geom_T geom1,
+ const scad_geom_T geom2,
+ scad_geom_T* out,
+ const int remove);
-res_T
+SCAD_API res_T
scad_cut
-(const scad_geom_T geom1, const scad_geom_T geom2, scad_geom_T* out, const int remove);
+ (const scad_geom_T geom1,
+ const scad_geom_T geom2,
+ scad_geom_T* out,
+ const int remove);
-res_T
+SCAD_API res_T
scad_intersect
-(const scad_geom_T geom1, const scad_geom_T geom2, scad_geom_T* out, const int remove);
+ (const scad_geom_T geom1,
+ const scad_geom_T geom2,
+ scad_geom_T* out,
+ const int remove);
-res_T
+SCAD_API res_T
scad_fragment
-(const scad_geom_T geom1, const scad_geom_T geom2, scad_geom_T* out, const int remove);
+ (const scad_geom_T geom1,
+ const scad_geom_T geom2,
+ scad_geom_T* out,
+ const int remove);
-res_T
+SCAD_API res_T
scad_boundary
-(const scad_geom_T geom1, scad_geom_T* out);
+ (const scad_geom_T geom1,
+ scad_geom_T* out);
-res_T
+SCAD_API res_T
scad_translate
-(scad_geom_T geom, const double dxdydz[3]);
+ (scad_geom_T geom,
+ const double dxdydz[3]);
-res_T
+SCAD_API res_T
scad_rotate
-(scad_geom_T geom, const double pt[3], const double axis[3], const double angle);
+ (scad_geom_T geom,
+ const double pt[3],
+ const double axis[3],
+ const double angle);
+
+SCAD_API res_T
+scad_conformal_mesh
+ (void);
-res_T
-scad_conformal_mesh(void);
+SCAD_API res_T
+scad_stl_export
+ (const scad_geom_T geom,
+ char* prefix);
-res_T
-scad_stl_export(const scad_geom_T geom, char *prefix);
+SCAD_API res_T
+scad_stl_export_split
+ (const scad_geom_T geom,
+ char* prefix);
-res_T
-scad_stl_export_split(const scad_geom_T geom, char *prefix);
-/*****************************************************************************/
-/*****************************************************************************/
-/*****************************************************************************/
+END_DECLS
-#endif /* SCAD_H */
+#endif /* SCAD_H */