Root/solidify/face.c

1/*
2 * face.c - Data structure and handling of one face of a part
3 *
4 * Written 2010 by Werner Almesberger
5 * Copyright 2010 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
14#include <stdlib.h>
15#include <stdio.h>
16#include <unistd.h>
17#include <string.h>
18#include <math.h>
19#include <fcntl.h>
20#include <sys/wait.h>
21
22#include "util.h"
23#include "array.h"
24#include "histo.h"
25#include "face.h"
26
27
28#define CACHE_DIR ".cache"
29#define DEFAULT_STEP 1 /* 1 mm */
30#define MIN_STEP 0.005 /* 5 um */
31
32
33struct coord {
34    float x, y, z;
35};
36
37
38static struct coord *load_file(const char *name)
39{
40    FILE *file;
41    struct coord *v, *n;
42    int s;
43
44    if (!strcmp(name, "-")) {
45        file = stdin;
46    } else {
47        int len;
48
49        len = strlen(name);
50        if (len > 4 && !strcmp(name+len-4, ".bz2")) {
51            char tmp[1000]; /* @@@ enough */
52
53            sprintf(tmp, "bzcat \"%s\"", name);
54            file = popen(tmp, "r");
55            if (!file) {
56                perror(tmp);
57                exit(1);
58            }
59        } else {
60            file = fopen(name, "r");
61            if (!file) {
62                perror(name);
63                exit(1);
64            }
65        }
66    }
67
68    v = n = alloc_type(struct coord);
69    s = 1;
70
71    while (fscanf(file, "%f,%f,%f\r\n", &n->x, &n->y, &n->z) == 3) {
72        n++;
73        if (n-v == s) {
74            struct coord *tmp;
75
76            s += s;
77            tmp = realloc(v, sizeof(struct coord)*s);
78            if (!tmp) {
79                perror("realloc");
80                exit(1);
81            }
82            n = n-v+tmp;
83            v = tmp;
84        }
85    }
86    if (file != stdin)
87        (void) fclose(file);
88
89    n->x = n->y = n->z = 0;
90    return v;
91}
92
93
94static void adjust_step(double *step, double delta)
95{
96    double n = round(delta/MIN_STEP);
97    double s = n*MIN_STEP;
98
99    if (n && s < *step)
100        *step = s;
101}
102
103
104static struct face *read_file(const char *name)
105{
106    struct coord *v, *p;
107    struct face *f;
108    struct histo *h;
109    int xi, yi, zi;
110
111    v = load_file(name);
112
113    f = alloc_type(struct face);
114    f->a = new_array();
115
116    /*
117     * Hack: the MDX-15 measures bumps along the x axis with 25 um
118     * resolution, so we just ignore the x resultion we find and use the
119     * y resolution instead.
120     */
121    f->x_step = f->y_step =f->z_step = DEFAULT_STEP;
122    for (p = v; p[1].x || p[1].y || p[1].z; p++) {
123        adjust_step(&f->y_step, fabs(p[0].y-p[1].y));
124        adjust_step(&f->z_step, fabs(p[0].z-p[1].z));
125    }
126    f->x_step = f->y_step;
127
128    for (p = v; p->x || p->y || p->z; p++) {
129        xi = round(p->x/f->x_step);
130        yi = round(p->y/f->y_step);
131        zi = round(p->z/f->z_step);
132        set(f->a, xi, yi, zi);
133    }
134
135    free(v);
136
137    f->sx = f->a->max_x-f->a->min_x+1;
138    f->sy = f->a->max_y-f->a->min_y+1;
139    f->sz = f->a->max_z-f->a->min_z+1;
140
141    f->cx = (f->a->min_x+f->a->max_x)/2;
142    f->cy = (f->a->min_y+f->a->max_y)/2;
143
144    h = make_histo(f->a);
145    f->z_ref = f->a->min_z+median(h);
146    free_histo(h);
147    f->fx = f->fy = 0;
148
149    f->m.a[0][0] = f->m.a[1][1] = 1;
150    f->m.a[0][1] = f->m.a[1][0] = 0;
151    f->m.b[0] = f->m.b[1] = 0;
152
153    fprintf(stderr, "%g %g %g\n", f->x_step, f->y_step, f->z_step);
154    fprintf(stderr, "%d-%d / %d-%d / %d-%d\n",
155        f->a->min_x, f->a->max_x, f->a->min_y, f->a->max_y,
156        f->a->min_z, f->a->max_z);
157
158    return f;
159}
160
161
162struct face *read_face(const char *name)
163{
164    const char *p;
165    int cwd;
166    struct face *face;
167
168    if (strncmp(name, "http:", 5) && strncmp(name, "https:", 6))
169        return read_file(name);
170    p = strrchr(name, '/');
171    if (!p || !p[1]) {
172        fprintf(stderr, "malformed URL: \"%s\"\n", name);
173        exit(1);
174    }
175    cwd = open(".", O_RDONLY);
176    if (cwd < 0) {
177        perror(".");
178        exit(1);
179    }
180    if (chdir(CACHE_DIR) < 0) {
181        perror(CACHE_DIR);
182        exit(1);
183    }
184    if (access(p+1, R_OK) < 0) {
185        char tmp[1000]; /* @@@ enough */
186        int res;
187
188        sprintf(tmp, "wget '%s'", name);
189        res = system(tmp);
190        if (res < 0) {
191            perror("system");
192            exit(1);
193        }
194        if (!WIFEXITED(res) || WEXITSTATUS(res)) {
195            fprintf(stderr, "%s: status %d\n", tmp, res);
196            exit(1);
197        }
198    }
199    face = read_file(p+1);
200    if (fchdir(cwd) < 0) {
201        perror("fchdir");
202        exit(1);
203    }
204    return face;
205}
206

Archive Download this file

Branches:
master



interactive