star-cad

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

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:
Msrc/scad.c | 623++++++++++++++++++++++++++++++++++++++-----------------------------------------
Msrc/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 */