Root/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
26static 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->comment = NULL;
34    prj->top = stralloc(top);
35    prj->bottom = stralloc(bottom);
36    prj->s.a = read_face(top);
37    prj->s.b = read_face(bottom);
38
39    if (prj->s.a->x_step != prj->s.a->x_step ||
40        prj->s.a->y_step != prj->s.a->y_step ||
41        prj->s.a->z_step != prj->s.a->z_step) {
42        fprintf(stderr, "both faces must have the same resolution\n");
43        exit(1);
44        }
45
46    prj->s.dist = dist_mm/prj->s.a->z_step;
47    return prj;
48}
49
50
51struct project *new_project(const char *name,
52    const char *top, const char *bottom, double dist_mm)
53{
54    FILE *file;
55
56    file = fopen(name, "r");
57    if (file) {
58        fprintf(stderr, "%s: already exists\n", name);
59        exit(1);
60    }
61    return make_project(name, top, bottom, dist_mm);
62}
63
64
65static void read_face_data(FILE *file, struct face *f)
66{
67    float v;
68
69    if (fscanf(file, "%f", &v) != 1)
70        return;
71    f->z_ref = round(v/f->z_step);
72
73    if (fscanf(file, "%f", &v) != 1)
74        return;
75    fx_from_angle(f, v);
76
77    if (fscanf(file, "%f", &v) != 1)
78        return;
79    fy_from_angle(f, v);
80
81    if (fscanf(file, "%f", &v) != 1)
82        return;
83    v = v/180*M_PI;
84    f->m.a[0][0] = cos(v);
85    f->m.a[0][1] = -sin(v);
86    f->m.a[1][0] = sin(v);
87    f->m.a[1][1] = cos(v);
88
89    if (fscanf(file, "%f", &v) != 1)
90        return;
91    f->m.b[0] = v/f->x_step;
92    
93    if (fscanf(file, "%f", &v) != 1)
94        return;
95    f->m.b[1] = v/f->y_step;
96}
97
98
99static void read_optional(FILE *file, struct project *prj)
100{
101    float v;
102
103    if (fscanf(file, "%f", &v) != 1)
104        return;
105    prj->s.dist = v/prj->s.a->z_step;
106
107    read_face_data(file, prj->s.a);
108    read_face_data(file, prj->s.b);
109}
110
111
112struct project *load_project(const char *name)
113{
114    FILE *file;
115    char top[1000], bottom[1000]; /* @@@ enough */
116    char *comment;
117    struct project *prj;
118
119    file = fopen(name, "r");
120    if (!file) {
121        perror(name);
122        exit(1);
123    }
124
125    comment = stralloc("");
126
127    while (1) {
128        if (!fgets(top, sizeof(top), file)) {
129            fprintf(stderr, "%s: can't read name of top face\n",
130                name);
131            exit(1);
132        }
133        if (*top != '#')
134            break;
135        comment = realloc(comment, strlen(comment)+strlen(top)+1);
136        strcat(comment, top);
137    }
138    if (strchr(top, '\n'))
139        *strchr(top, '\n') = 0;
140
141    if (!fgets(bottom, sizeof(bottom), file)) {
142        fprintf(stderr, "%s: can't read name of bottom face\n",
143            bottom);
144        exit(1);
145    }
146    if (strchr(bottom, '\n'))
147        *strchr(bottom, '\n') = 0;
148
149    prj = make_project(name, top, bottom, 0);
150    prj->comment = comment;
151    read_optional(file, prj);
152
153    return prj;
154}
155
156
157static void save_face_data(FILE *file, const char *name, const struct face *f)
158{
159    double a;
160
161    a = asin(-f->m.a[0][1])/M_PI*180;
162    if (f->m.a[0][0] < 0)
163        a = 180-a;
164    if (fprintf(file, "%g %g %g\n%g %g %g\n",
165        f->z_ref*f->z_step,
166        fx_to_angle(f), fy_to_angle(f),
167        a, f->m.b[0]*f->x_step, f->m.b[1]*f->y_step) < 0) {
168        perror(name);
169        exit(1);
170    }
171}
172
173
174void save_project(const struct project *prj)
175{
176    char tmp[1000]; /* @@@ enough */
177    FILE *file;
178
179    sprintf(tmp, "%s~", prj->name);
180    file = fopen(tmp, "w");
181    if (!file) {
182        perror(tmp);
183        exit(1);
184    }
185    if (fprintf(file,
186        "%s%s\n%s\n%g\n", prj->comment ? prj->comment : "",
187        prj->top, prj->bottom, prj->s.dist*prj->s.a->z_step) < 0) {
188        perror(tmp);
189        exit(1);
190    }
191    save_face_data(file, tmp, prj->s.a);
192    save_face_data(file, tmp, prj->s.b);
193    if (fclose(file) < 0) {
194        perror(tmp);
195        exit(1);
196    }
197
198    if (rename(tmp, prj->name) < 0) {
199        fprintf(stderr, "rename %s to %s: %s\n", tmp, prj->name,
200            strerror(errno));
201        exit(1);
202    }
203}
204

Archive Download this file

Branches:
master



interactive