Ben NanoNote 3D scans
Sign in or create your account | Project List | Help
Ben NanoNote 3D scans Git Source Tree
Root/
Source at commit 01d8e411f34d448b83fdb1cbfa4b63b0ac95fe6b created 13 years 6 months ago. By Werner Almesberger, Use the project name to disambiguate names in POV-Ray output. | |
---|---|
1 | /* |
2 | * project.c - Load and save solidify project descriptions |
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 <string.h> |
17 | #include <errno.h> |
18 | #include <math.h> |
19 | |
20 | #include "util.h" |
21 | #include "face.h" |
22 | #include "solid.h" |
23 | #include "project.h" |
24 | |
25 | |
26 | static struct project *make_project(const char *name, |
27 | const char *top, const char *bottom, double dist_mm) |
28 | { |
29 | struct project *prj; |
30 | |
31 | prj = alloc_type(struct project); |
32 | prj->name = stralloc(name); |
33 | prj->top = stralloc(top); |
34 | prj->bottom = stralloc(bottom); |
35 | prj->s.a = read_face(top); |
36 | prj->s.b = read_face(bottom); |
37 | |
38 | if (prj->s.a->x_step != prj->s.a->x_step || |
39 | prj->s.a->y_step != prj->s.a->y_step || |
40 | prj->s.a->z_step != prj->s.a->z_step) { |
41 | fprintf(stderr, "both faces must have the same resolution\n"); |
42 | exit(1); |
43 | } |
44 | |
45 | prj->s.dist = dist_mm/prj->s.a->z_step; |
46 | return prj; |
47 | } |
48 | |
49 | |
50 | struct project *new_project(const char *name, |
51 | const char *top, const char *bottom, double dist_mm) |
52 | { |
53 | FILE *file; |
54 | |
55 | file = fopen(name, "r"); |
56 | if (file) { |
57 | fprintf(stderr, "%s: already exists\n", name); |
58 | exit(1); |
59 | } |
60 | return make_project(name, top, bottom, dist_mm); |
61 | } |
62 | |
63 | |
64 | static void read_face_data(FILE *file, struct face *f) |
65 | { |
66 | float v; |
67 | |
68 | if (fscanf(file, "%f", &v) != 1) |
69 | return; |
70 | f->z_ref = v/f->z_step; |
71 | |
72 | if (fscanf(file, "%f", &v) != 1) |
73 | return; |
74 | f->fx = sin(v/180*M_PI); |
75 | |
76 | if (fscanf(file, "%f", &v) != 1) |
77 | return; |
78 | f->fy = sin(v/180*M_PI); |
79 | |
80 | if (fscanf(file, "%f", &v) != 1) |
81 | return; |
82 | v = v/180*M_PI; |
83 | f->m.a[0][0] = cos(v); |
84 | f->m.a[0][1] = -sin(v); |
85 | f->m.a[1][0] = sin(v); |
86 | f->m.a[1][1] = cos(v); |
87 | |
88 | if (fscanf(file, "%f", &v) != 1) |
89 | return; |
90 | f->m.b[0] = v/f->x_step; |
91 | |
92 | if (fscanf(file, "%f", &v) != 1) |
93 | return; |
94 | f->m.b[1] = v/f->y_step; |
95 | } |
96 | |
97 | |
98 | static void read_optional(FILE *file, struct project *prj) |
99 | { |
100 | float v; |
101 | |
102 | if (fscanf(file, "%f", &v) != 1) |
103 | return; |
104 | prj->s.dist = v/prj->s.a->z_step; |
105 | |
106 | read_face_data(file, prj->s.a); |
107 | read_face_data(file, prj->s.b); |
108 | } |
109 | |
110 | |
111 | struct project *load_project(const char *name) |
112 | { |
113 | FILE *file; |
114 | char top[1000], bottom[1000]; /* @@@ enough */ |
115 | struct project *prj; |
116 | |
117 | file = fopen(name, "r"); |
118 | if (!file) { |
119 | perror(name); |
120 | exit(1); |
121 | } |
122 | |
123 | if (!fgets(top, sizeof(top), file)) { |
124 | fprintf(stderr, "%s: can't read name of top face\n", name); |
125 | exit(1); |
126 | } |
127 | if (strchr(top, '\n')) |
128 | *strchr(top, '\n') = 0; |
129 | |
130 | if (!fgets(bottom, sizeof(bottom), file)) { |
131 | fprintf(stderr, "%s: can't read name of bottom face\n", |
132 | bottom); |
133 | exit(1); |
134 | } |
135 | if (strchr(bottom, '\n')) |
136 | *strchr(bottom, '\n') = 0; |
137 | |
138 | prj = make_project(name, top, bottom, 0); |
139 | |
140 | read_optional(file, prj); |
141 | |
142 | return prj; |
143 | } |
144 | |
145 | |
146 | static void save_face_data(FILE *file, const char *name, const struct face *f) |
147 | { |
148 | double a; |
149 | |
150 | a = asin(-f->m.a[0][1])/M_PI*180; |
151 | if (f->m.a[0][0] < 0) |
152 | a = 180-a; |
153 | if (fprintf(file, "%g %g %g\n%g %g %g\n", |
154 | f->z_ref*f->z_step, |
155 | asin(f->fx)/M_PI*180, asin(f->fy)/M_PI*180, |
156 | a, f->m.b[0]*f->x_step, f->m.b[1]*f->y_step) < 0) { |
157 | perror(name); |
158 | exit(1); |
159 | } |
160 | } |
161 | |
162 | |
163 | void save_project(const struct project *prj) |
164 | { |
165 | char tmp[1000]; /* @@@ enough */ |
166 | FILE *file; |
167 | |
168 | sprintf(tmp, "%s~", prj->name); |
169 | file = fopen(tmp, "w"); |
170 | if (!file) { |
171 | perror(tmp); |
172 | exit(1); |
173 | } |
174 | if (fprintf(file, |
175 | "%s\n%s\n%g\n", prj->top, prj->bottom, |
176 | prj->s.dist*prj->s.a->z_step) < 0) { |
177 | perror(tmp); |
178 | exit(1); |
179 | } |
180 | save_face_data(file, tmp, prj->s.a); |
181 | save_face_data(file, tmp, prj->s.b); |
182 | if (fclose(file) < 0) { |
183 | perror(tmp); |
184 | exit(1); |
185 | } |
186 | |
187 | if (rename(tmp, prj->name) < 0) { |
188 | fprintf(stderr, "rename %s to %s: %s\n", tmp, prj->name, |
189 | strerror(errno)); |
190 | exit(1); |
191 | } |
192 | } |
193 |
Branches:
master