Root/ptrude/ptrude.c

1/*
2 * ptrude.c - Extrusion of a 2D path along a perpendicular 2D path
3 *
4 * Written 2011 by Werner Almesberger
5 * Copyright 2011 by Werner Almesberger
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <stdlib.h>
14#include <stdio.h>
15#include <unistd.h>
16#include <string.h>
17#include <math.h>
18
19#include "path.h"
20#include "extrude.h"
21#include "ptrude.h"
22
23
24int debug = 0;
25
26
27static FILE *open_file(const char *name, const char *mode)
28{
29    FILE *file;
30
31    if (!strcmp(name, "-"))
32        return strcmp(mode, "r") ? stdout : stdin;
33
34    file = fopen(name, mode);
35    if (!file) {
36        perror(name);
37        exit(1);
38    }
39    return file;
40}
41
42
43static void close_file(FILE *file)
44{
45    if (file == stdin || file == stdout)
46        return;
47    if (fclose(file) == EOF) {
48        perror("fclose");
49        exit(1);
50    }
51}
52
53
54static void do_face(void *data, struct point a, struct point b, struct point c)
55{
56    FILE *file = data;
57
58    fprintf(file, "facet normal 0 0 0\n");
59    fprintf(file, " outer loop\n");
60    fprintf(file, " vertex %f %f %f\n", a.x, a.y, a.z);
61    fprintf(file, " vertex %f %f %f\n", b.x, b.y, b.z);
62    fprintf(file, " vertex %f %f %f\n", c.x, c.y, c.z);
63    fprintf(file, " endloop\nendfacet\n");
64}
65
66
67static void do_extrude(const struct path *path, const struct path *shape,
68    double r, double d)
69{
70    FILE *file = stdout;
71
72    fprintf(file, "solid ptrude\n");
73    extrude(path, shape, r, d, do_face, file);
74    fprintf(file, "endsolid ptrude\n");
75}
76
77
78static void usage(const char *name)
79{
80    fprintf(stderr,
81"usage: %s shape radius tolerance\n"
82"%6s %s path shape radius tolerance\n",
83        name, "", name);
84    exit(1);
85}
86
87
88int main(int argc, char **argv)
89{
90    FILE *file;
91    struct path *path = NULL;
92    const struct path *shape;
93    double r, d;
94    char *end;
95    int c;
96
97    while ((c = getopt(argc, argv, "d")) != EOF)
98        switch (c) {
99        case 'd':
100            debug = 1;
101            break;
102        default:
103            usage(*argv);
104        }
105
106    switch (argc-optind) {
107    case 3:
108        break;
109    case 4:
110        file = open_file(argv[optind], "r");
111        path = load_path(file);
112        close_file(file);
113        break;
114    default:
115        usage(*argv);
116    }
117
118    file = open_file(argv[argc-3], "r");
119    shape = load_path(file);
120    close_file(file);
121
122    r = strtod(argv[argc-2], &end);
123    if (*end || r <= 0)
124        usage(*argv);
125    d = strtod(argv[argc-1], &end);
126    if (*end || d <= 0)
127        usage (*argv);
128
129    if (path) {
130        /*
131         * We split the error budget evenly between path and shape.
132         */
133        path_set_length(path);
134        shape = round_path(shape, r, sqrt(d));
135        do_extrude(path, shape, r, sqrt(d));
136    } else {
137        shape = round_path(shape, r, d);
138        save_path(stdout, shape);
139    }
140
141    return 0;
142}
143

Archive Download this file

Branches:
master



interactive