reprap: c3 stl loader
[simavr] / examples / board_reprap / src / c3 / c3stl.c
1 /*
2         c3stl.c
3
4         Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
5
6         This file is part of simavr.
7
8         simavr is free software: you can redistribute it and/or modify
9         it under the terms of the GNU General Public License as published by
10         the Free Software Foundation, either version 3 of the License, or
11         (at your option) any later version.
12
13         simavr is distributed in the hope that it will be useful,
14         but WITHOUT ANY WARRANTY; without even the implied warranty of
15         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16         GNU General Public License for more details.
17
18         You should have received a copy of the GNU General Public License
19         along with simavr.  If not, see <http://www.gnu.org/licenses/>.
20  */
21
22 #include <stdio.h>
23 #include "c3/c3algebra.h"
24 #include "c3/c3geometry.h"
25 #include "c3/c3object.h"
26 #include "c3/c3stl.h"
27
28 enum {
29         vertex_None = -1,
30         vertex_Vertex,
31         vertex_Normal,
32 };
33
34 static int
35 _c3stl_read_vertex(
36                 char * vt,
37                 c3vec3 * out )
38 {
39         int res = 1;
40         char *l = vt;
41         /*char * key =*/ strsep(&l, " \t");
42         char * x = strsep(&l, " \t");
43         char * y = strsep(&l, " \t");
44         char * z = strsep(&l, " \t");
45
46         if (x) sscanf(x, "%f", out->n);
47         if (y) sscanf(y, "%f", out->n + 1);
48         if (z) sscanf(z, "%f", out->n + 2);
49 //      printf("'%s' '%s' '%s' '%s' = %.2f %.2f %.2f\n",
50 //                      key, x, y, z, out->n[0], out->n[1], out->n[2]);
51         return res;
52 }
53
54 struct c3object_t *
55 c3stl_load(
56                 const char * filename,
57                 c3object_p parent)
58 {
59         FILE *f = fopen(filename, "r");
60         if (!f) {
61                 perror(filename);
62                 return NULL;
63         }
64
65         c3object_p              o = c3object_new(parent);
66         c3geometry_p    current_g = NULL;
67
68         int state = 0;
69         while (!feof(f)) {
70                 char line[256];
71
72                 fgets(line, sizeof(line), f);
73
74                 int l = strlen(line);
75                 while (l && line[l-1] < ' ')
76                         line[--l] = 0;
77                 if (!l)
78                         continue;
79                 char * keyword = line;
80                 while (*keyword && *keyword <= ' ')
81                         keyword++;
82                 l = strlen(keyword);
83         //      printf("%d>'%s'\n", state, keyword);
84
85                 switch (state) {
86                         case 0: //
87                                 if (!strncmp(keyword, "solid ", 6)) {
88                                         char * n = keyword + 6;
89                                         current_g = c3geometry_new(c3geometry_type(C3_TRIANGLE_TYPE, 0), o);
90                                         current_g->name = str_new(n);
91
92                                         state = 1;
93                                 }
94                                 break;
95                         case 1: //
96                                 if (!strncmp(keyword, "facet ", 6)) {
97                                         c3vec3 normal;
98                                         _c3stl_read_vertex(keyword + 6, &normal);
99                                         c3vertex_array_add(&current_g->normals, normal);
100                                         c3vertex_array_add(&current_g->normals, normal);
101                                         c3vertex_array_add(&current_g->normals, normal);
102                                         state = 2;
103                                 } else if (!strncmp(keyword, "endsolid ", 9))
104                                         state = 0;
105                                 break;
106                         case 2:
107                                 if (!strncmp(keyword, "outer loop", 10))
108                                         state = 3;
109                                 else if (!strncmp(keyword, "endfacet", 8))
110                                         state = 1;
111                                 break;
112                         case 3:
113                                 if (!strncmp(keyword, "vertex ", 7)) {
114                                         c3vec3 v;
115                                         _c3stl_read_vertex(keyword, &v);
116                                         c3vertex_array_add(&current_g->vertice, v);
117                                         state = 3;
118                                 } else if (!strncmp(keyword, "endloop", 7))
119                                         state = 2;
120                                 break;
121                 }
122         }
123
124         fclose(f);
125         return o;
126 }