libc3: remerged
[simavr] / examples / shared / libc3 / src / c3stl.c
1 /*
2         c3stl.c
3
4         Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
5
6         This file is part of libc3.
7
8         libc3 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         libc3 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 libc3.  If not, see <http://www.gnu.org/licenses/>.
20  */
21
22 #include <stdio.h>
23 #include "c3algebra.h"
24 #include "c3geometry.h"
25 #include "c3object.h"
26 #include "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         o->name = str_new(filename);
68
69         int state = 0;
70         while (!feof(f)) {
71                 char line[256];
72
73                 fgets(line, sizeof(line), f);
74
75                 int l = strlen(line);
76                 while (l && line[l-1] < ' ')
77                         line[--l] = 0;
78                 if (!l)
79                         continue;
80                 char * keyword = line;
81                 while (*keyword && *keyword <= ' ')
82                         keyword++;
83                 l = strlen(keyword);
84         //      printf("%d>'%s'\n", state, keyword);
85
86                 switch (state) {
87                         case 0: //
88                                 if (!strncmp(keyword, "solid ", 6)) {
89                                         char * n = keyword + 6;
90                                         current_g = c3geometry_new(c3geometry_type(C3_TRIANGLE_TYPE, 0), o);
91                                         current_g->name = str_new(n);
92
93                                         state = 1;
94                                 }
95                                 break;
96                         case 1: //
97                                 if (!strncmp(keyword, "facet ", 6)) {
98                                         c3vec3 normal;
99                                         _c3stl_read_vertex(keyword + 6, &normal);
100                                         normal = c3vec3_normalize(normal);
101                                         c3vertex_array_add(&current_g->normals, normal);
102                                         c3vertex_array_add(&current_g->normals, normal);
103                                         c3vertex_array_add(&current_g->normals, normal);
104                                         state = 2;
105                                 } else if (!strncmp(keyword, "endsolid ", 9))
106                                         state = 0;
107                                 break;
108                         case 2:
109                                 if (!strncmp(keyword, "outer loop", 10))
110                                         state = 3;
111                                 else if (!strncmp(keyword, "endfacet", 8))
112                                         state = 1;
113                                 break;
114                         case 3:
115                                 if (!strncmp(keyword, "vertex ", 7)) {
116                                         c3vec3 v;
117                                         _c3stl_read_vertex(keyword, &v);
118                                         c3vertex_array_add(&current_g->vertice, v);
119                                         state = 3;
120                                 } else if (!strncmp(keyword, "endloop", 7))
121                                         state = 2;
122                                 break;
123                 }
124         }
125
126         fclose(f);
127         return o;
128 }