/* * ptrude.c - Extrusion of a 2D path along a perpendicular 2D path * * Written 2011 by Werner Almesberger * Copyright 2011 by Werner Almesberger * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. */ #include #include #include #include #include #include "path.h" #include "extrude.h" #include "ptrude.h" int debug = 0; static FILE *open_file(const char *name, const char *mode) { FILE *file; if (!strcmp(name, "-")) return strcmp(mode, "r") ? stdout : stdin; file = fopen(name, mode); if (!file) { perror(name); exit(1); } return file; } static void close_file(FILE *file) { if (file == stdin || file == stdout) return; if (fclose(file) == EOF) { perror("fclose"); exit(1); } } static void do_face(void *data, struct point a, struct point b, struct point c) { FILE *file = data; fprintf(file, "facet normal 0 0 0\n"); fprintf(file, " outer loop\n"); fprintf(file, " vertex %f %f %f\n", a.x, a.y, a.z); fprintf(file, " vertex %f %f %f\n", b.x, b.y, b.z); fprintf(file, " vertex %f %f %f\n", c.x, c.y, c.z); fprintf(file, " endloop\nendfacet\n"); } static void do_extrude(const struct path *path, const struct path *shape) { FILE *file = stdout; fprintf(file, "solid ptrude\n"); extrude(path, shape, do_face, file); fprintf(file, "endsolid ptrude\n"); } static void usage(const char *name) { fprintf(stderr, "usage: %s shape radius tolerance\n" "%6s %s path shape radius tolerance\n", name, "", name); exit(1); } int main(int argc, char **argv) { FILE *file; const struct path *path = NULL, *shape; double r, d; char *end; int c; while ((c = getopt(argc, argv, "d")) != EOF) switch (c) { case 'd': debug = 1; break; default: usage(*argv); } switch (argc-optind) { case 3: break; case 4: file = open_file(argv[optind], "r"); path = load_path(file); close_file(file); break; default: usage(*argv); } file = open_file(argv[argc-3], "r"); shape = load_path(file); close_file(file); r = strtod(argv[argc-2], &end); if (*end || r <= 0) usage(*argv); d = strtod(argv[argc-1], &end); if (*end || d <= 0) usage (*argv); if (path) { /* * We split the error budget evenly between path and shape. */ path = round_path(path, r, sqrt(d)); shape = round_path(shape, r, sqrt(d)); do_extrude(path, shape); } else { shape = round_path(shape, r, d); save_path(stdout, shape); } return 0; }