Ben NanoNote 3D scans
Sign in or create your account | Project List | Help
Ben NanoNote 3D scans Commit Details
Date: | 2010-09-25 02:01:59 (12 years 11 months ago) |
---|---|
Author: | Werner Almesberger |
Commit: | f6ed3bf762b63b950cf801c9282101a818c0ff8e |
Message: | solidify now stores the context of sessions in project description
files. - solidify/Makefile (OBJS): added project.o - solidify/Makefile (new): new target to create a new project - solidify/Makefile (run): changed to resume previously created project - solidify/util.h (stralloc): added stralloc (from fped) - solidify/project.h, solidify/project.c: create, load, and save project description files - solidify/solidify.c (clicked, gui_buttons, gui, main): updated to use project instead of solid - solidify/solidify.c (usage, main): new invocation: four arguments to start new project, one argument to resume old project |
Files: |
solidify/Makefile (2 diffs) solidify/project.c (1 diff) solidify/project.h (1 diff) solidify/solidify.c (5 diffs) solidify/util.h (2 diffs) |
Change Details
solidify/Makefile | ||
---|---|---|
12 | 12 | |
13 | 13 | SHELL = /bin/bash |
14 | 14 | |
15 | OBJS = array.o face.o histo.o level.o matrix.o overlap.o solid.o solidify.o \ | |
16 | style.o util.o | |
15 | OBJS = array.o face.o histo.o level.o matrix.o overlap.o project.o solid.o \ | |
16 | solidify.o style.o util.o | |
17 | 17 | |
18 | 18 | CFLAGS_WARN = -Wall -Wshadow -Wmissing-prototypes \ |
19 | 19 | -Wmissing-declarations -Wno-format-zero-length |
... | ... | |
59 | 59 | FACE_B=$(DIR)/ben-batcvr-inside-100um.txt.bz2 |
60 | 60 | D=1.16 |
61 | 61 | |
62 | .PHONY: run pov disp | |
62 | .PHONY: new run pov disp | |
63 | ||
64 | new: solidify | |
65 | rm -f batcvr.sfy | |
66 | ./solidify batcvr.sfy $(FACE_A) $(FACE_B) $(D) >batcvr.inc | |
63 | 67 | |
64 | 68 | run: solidify |
65 | ./solidify $(FACE_A) $(FACE_B) $(D) >batcvr.inc | |
69 | ./solidify batcvr.sfy >batcvr.inc | |
66 | 70 | |
67 | 71 | pov: |
68 | 72 | povray +A -W1280 -H1024 main.pov |
solidify/project.c | ||
---|---|---|
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 | } |
solidify/project.h | ||
---|---|---|
1 | /* | |
2 | * project.h - 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 | * Project file structure: | |
15 | * | |
16 | * line 1: file name of top face (required) | |
17 | * line 2: file name of bottom face (required) | |
18 | * line 3 and beyond, separated by whitespace: | |
19 | * - z distance between faces, in mm | |
20 | * - z distance of the z0 plane from the midpoint of the top face, in mm | |
21 | * - inclination of the x axis of the z0 plane of the top face, in degrees | |
22 | * - inclination of the y axis of the z0 plane of the top face, in degrees | |
23 | * - rotation of the top face, in degrees | |
24 | * - x shift of the top face, in mm | |
25 | * - y shift of the top face, in mm | |
26 | * - the above 6 fields for the bottom face | |
27 | */ | |
28 | ||
29 | #ifndef PROJECT_H | |
30 | #define PROJECT_H | |
31 | ||
32 | #include "solid.h" | |
33 | ||
34 | ||
35 | struct project { | |
36 | const char *name; | |
37 | const char *top; | |
38 | const char *bottom; | |
39 | struct solid s; | |
40 | }; | |
41 | ||
42 | ||
43 | struct project *new_project(const char *name, | |
44 | const char *top, const char *bottom, double dist_mm); | |
45 | struct project *load_project(const char *name); | |
46 | void save_project(const struct project *prj); | |
47 | ||
48 | #endif /* !PROJECT_H */ |
solidify/solidify.c | ||
---|---|---|
19 | 19 | |
20 | 20 | #include "face.h" |
21 | 21 | #include "solid.h" |
22 | #include "project.h" | |
22 | 23 | #include "style.h" |
23 | 24 | #include "level.h" |
24 | 25 | #include "overlap.h" |
25 | 26 | |
26 | 27 | |
27 | static struct solid solid; | |
28 | static const struct face *active; | |
28 | static struct project *prj; | |
29 | static const struct face *active; /* NULL if overlapping */ | |
29 | 30 | static GtkWidget *canvas; |
30 | 31 | |
31 | 32 | |
... | ... | |
41 | 42 | if (face) |
42 | 43 | level(canvas, face); |
43 | 44 | else |
44 | overlap(canvas, &solid); | |
45 | overlap(canvas, &prj->s); | |
45 | 46 | active = face; |
46 | 47 | |
47 | 48 | gtk_widget_show_all(canvas); |
... | ... | |
57 | 58 | but = gtk_button_new_with_label("A"); |
58 | 59 | gtk_box_pack_start(GTK_BOX(vbox), but, FALSE, FALSE, 0); |
59 | 60 | g_signal_connect(G_OBJECT(but), "clicked", |
60 | G_CALLBACK(clicked), solid.a); | |
61 | G_CALLBACK(clicked), prj->s.a); | |
61 | 62 | |
62 | 63 | but = gtk_button_new_with_label("B"); |
63 | 64 | gtk_box_pack_start(GTK_BOX(vbox), but, FALSE, FALSE, 0); |
64 | 65 | g_signal_connect(G_OBJECT(but), "clicked", |
65 | G_CALLBACK(clicked), solid.b); | |
66 | G_CALLBACK(clicked), prj->s.b); | |
66 | 67 | |
67 | 68 | but = gtk_button_new_with_label("A+B"); |
68 | 69 | gtk_box_pack_start(GTK_BOX(vbox), but, FALSE, FALSE, 0); |
... | ... | |
101 | 102 | buttons = gui_buttons(); |
102 | 103 | gtk_box_pack_start(GTK_BOX(hbox), buttons, FALSE, FALSE, 0); |
103 | 104 | |
104 | level(canvas, solid.a); | |
105 | active = solid.a; | |
105 | level(canvas, prj->s.a); | |
106 | active = prj->s.a; | |
106 | 107 | |
107 | 108 | init_style(root->window); |
108 | 109 | |
... | ... | |
119 | 120 | |
120 | 121 | static void usage(const char *name) |
121 | 122 | { |
122 | fprintf(stderr, "usage: %s top bottom dist\n", name); | |
123 | fprintf(stderr, "usage: %s project [top bottom dist]\n", name); | |
123 | 124 | exit(1); |
124 | 125 | } |
125 | 126 | |
126 | 127 | |
127 | 128 | int main(int argc, char **argv) |
128 | 129 | { |
130 | double dist; | |
131 | ||
129 | 132 | gtk_init(&argc, &argv); |
130 | 133 | setlocale(LC_ALL, "C"); /* damage control */ |
131 | 134 | |
132 | 135 | switch (argc) { |
133 | case 4: | |
136 | case 2: | |
137 | prj = load_project(argv[1]); | |
138 | break; | |
139 | case 5: | |
140 | dist = atof(argv[4]); | |
141 | prj = new_project(argv[1], argv[2], argv[3], dist); | |
134 | 142 | break; |
135 | 143 | default: |
136 | 144 | usage(*argv); |
137 | 145 | } |
138 | 146 | |
139 | solid.a = read_face(argv[1]); | |
140 | solid.b = read_face(argv[2]); | |
141 | if (solid.a->x_step != solid.a->x_step || | |
142 | solid.a->y_step != solid.a->y_step || | |
143 | solid.a->z_step != solid.a->z_step) { | |
144 | fprintf(stderr, "both faces must have the same resolution\n"); | |
145 | exit(1); | |
146 | } | |
147 | solid.dist = atof(argv[3])/solid.a->z_step; | |
148 | ||
149 | 147 | gui(); |
150 | 148 | |
149 | save_project(prj); | |
150 | ||
151 | 151 | if (!isatty(1)) |
152 | povray(&solid); | |
152 | povray(&prj->s); | |
153 | 153 | |
154 | 154 | return 0; |
155 | 155 | } |
solidify/util.h | ||
---|---|---|
14 | 14 | #define UTIL_H |
15 | 15 | |
16 | 16 | #include <stdlib.h> |
17 | #include <string.h> | |
17 | 18 | #include <gtk/gtk.h> |
18 | 19 | |
19 | 20 | |
... | ... | |
25 | 26 | |
26 | 27 | #define alloc_type(t) ((t *) alloc_size(sizeof(t))) |
27 | 28 | |
29 | #define stralloc(s) \ | |
30 | ({ char *stralloc_tmp = strdup(s); \ | |
31 | if (!stralloc_tmp) \ | |
32 | abort(); \ | |
33 | stralloc_tmp; }) | |
34 | ||
28 | 35 | |
29 | 36 | void draw_circle(GdkDrawable *da, GdkGC *gc, int x, int y, int r); |
30 | 37 |
Branches:
master