diff --git a/slicer/stl.c b/slicer/stl.c index 1590f50..074f6b1 100644 --- a/slicer/stl.c +++ b/slicer/stl.c @@ -11,6 +11,7 @@ */ +#include #include #include #include @@ -33,7 +34,53 @@ enum state { }; -void stl_load_file(FILE *file, void (*facet)(struct v f[3])) +static void stl_load_binary(FILE *file, void (*facet)(struct v f[3])) +{ + char discard[75]; + size_t n; + uint32_t nf; + uint16_t attr; + float tmp[4*3]; + struct v f[3]; + int i; + + n = fread(discard, 1, sizeof(discard), file); + if (n != sizeof(discard)) { + fprintf(stderr, "incomplete header\n"); + exit(1); + } + n = fread(&nf, 1, sizeof(nf), file); + if (n != sizeof(nf)) { + fprintf(stderr, "no number of facets\n"); + exit(1); + } +fprintf(stderr, "nf %u\n", (unsigned) nf); + while (nf--) { + n = fread(&tmp, 1, sizeof(tmp), file); + if (n != sizeof(tmp)) { + fprintf(stderr, "incomplete facet\n"); + exit(1); + } + for (i = 0; i != 3; i++) { + f[i].x = tmp[3 * i + 3]; + f[i].y = tmp[3 * i + 4]; + f[i].z = tmp[3 * i + 5]; + } + facet(f); + n = fread(&attr, 1, sizeof(attr), file); + if (n != sizeof(attr)) { + fprintf(stderr, "no attribute count\n"); + exit(1); + } + if (attr) { + fprintf(stderr, "non-zero attribute count\n"); + exit(1); + } + } +} + + +static void stl_load_text(FILE *file, void (*facet)(struct v f[3])) { char buf[MAX_LINE + 1]; enum state state = s_init; @@ -57,7 +104,7 @@ void stl_load_file(FILE *file, void (*facet)(struct v f[3])) switch (state) { case s_init: - sscanf(s, "solid %*s%n", &end); + sscanf(s, " %*s%n", &end); state = s_facet; break; case s_facet: @@ -102,6 +149,25 @@ void stl_load_file(FILE *file, void (*facet)(struct v f[3])) } +void stl_load_file(FILE *file, void (*facet)(struct v f[3])) +{ + char buf[5]; + size_t n; + + n = fread(buf, 1, sizeof(buf), file); + if (n != sizeof(buf)) { + fprintf(stderr, "file too short\n"); + exit(1); + } + + if (memcmp(buf, "solid", 5)) { + stl_load_binary(file, facet); + } else { + stl_load_text(file, facet); + } +} + + void stl_load(const char *name, void (*facet)(struct v f[3])) { FILE *file;