diff --git a/cameo/stl.c b/cameo/stl.c index ef56445..f9b1fb7 100644 --- a/cameo/stl.c +++ b/cameo/stl.c @@ -11,7 +11,9 @@ */ +#include #include +#include #include "poly2d.h" @@ -19,20 +21,79 @@ #include "stl.h" -void stl(const char *name, const struct path *paths) +static void facet(FILE *file, const struct f2d *f, int a, int b, int c, + double za, double zb, double zc, double nx, double ny, double nz) +{ + double d; + + d = sqrt(nx*nx+ny*ny+nz*nz); + if (!d) + d = 1; + + fprintf(file, "facet normal %e %e %e\n", nx/d, ny/d, nz/d); + fprintf(file, "\touter loop\n"); + fprintf(file, "\t\tvertex %e %e %e\n", f->x[a], f->y[a], za); + fprintf(file, "\t\tvertex %e %e %e\n", f->x[b], f->y[b], zb); + fprintf(file, "\t\tvertex %e %e %e\n", f->x[c], f->y[c], zc); + fprintf(file, "\tendloop\n"); + fprintf(file, "endfacet\n"); +} + + +static void surface(FILE *file, const struct f2d *f) +{ + facet(file, f, 0, 1, 2, 1, 1, 1, 0, 0, 1); + facet(file, f, 2, 1, 0, 0, 0, 0, 0, 0, -1); +} + + +static void side(FILE *file, const struct f2d *f, int a, int b) +{ + double nx, ny; + + nx = f->y[b]-f->y[a]; + ny = f->x[a]-f->x[b]; + facet(file, f, a, b, b, 0, 0, 1, nx, ny, 0); + facet(file, f, b, a, a, 1, 1, 0, nx, ny, 0); +} + + +static void stl_write(FILE *file, const struct path *paths) { struct p2d *polys; struct f2d *faces; const struct f2d *f; + int i; + fprintf(file, "solid cameo\n"); polys = paths_to_polys(paths); faces = f2d_tri(polys); - for (f = faces; f; f = f->next) - printf("%f/%f %f/%f %f/%f (%d %d %d)\n", - f->x[0], f->y[0], - f->x[1], f->y[1], - f->x[2], f->y[2], - f->side[0], f->side[1], f->side[2]); + for (f = faces; f; f = f->next) { + surface(file, f); + for (i = 0; i != 3; i++) + if (f->side[i]) + side(file, f, i, (i+1) % 3); + } p2d_free_all(polys); f2d_free_all(faces); + fprintf(file, "endsolid cameo\n"); +} + + +void stl(const char *name, const struct path *paths) +{ + FILE *file = stdout; + + if (name) { + file = fopen(name, "w"); + if (!file) { + perror(name); + exit(1); + } + } + stl_write(file, paths); + if (name && fclose(file)) { + perror(name); + exit(1); + } }