aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_ldraw/imp_ldraw_part.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/others/mimesh/libg3d-0.0.8/plugins/import/imp_ldraw/imp_ldraw_part.c')
-rw-r--r--src/others/mimesh/libg3d-0.0.8/plugins/import/imp_ldraw/imp_ldraw_part.c291
1 files changed, 291 insertions, 0 deletions
diff --git a/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_ldraw/imp_ldraw_part.c b/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_ldraw/imp_ldraw_part.c
new file mode 100644
index 0000000..9f7f608
--- /dev/null
+++ b/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_ldraw/imp_ldraw_part.c
@@ -0,0 +1,291 @@
1/* $Id$ */
2
3/*
4 libg3d - 3D object loading library
5
6 Copyright (C) 2005-2009 Markus Dahms <mad@automagically.de>
7
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public
10 License as published by the Free Software Foundation; either
11 version 2.1 of the License, or (at your option) any later version.
12
13 This library 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 GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public
19 License along with this library; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21*/
22#include <stdio.h>
23#include <string.h>
24
25#include <g3d/types.h>
26#include <g3d/context.h>
27#include <g3d/stream.h>
28#include <g3d/material.h>
29#include <g3d/matrix.h>
30#include <g3d/object.h>
31
32#include "imp_ldraw_types.h"
33#include "imp_ldraw_part.h"
34#include "imp_ldraw_library.h"
35#include "imp_ldraw_color.h"
36#include "imp_ldraw_misc.h"
37
38static gboolean ldraw_part_parse_meta(G3DObject *object, gchar *buffer)
39{
40 if(object->name == NULL) {
41 object->name = g_strdup(buffer);
42 return TRUE;
43 }
44#if DEBUG > 2
45 g_debug("META: %s", buffer);
46#endif
47 return TRUE;
48}
49
50static void ldraw_part_replace_material(G3DObject *object,
51 G3DMaterial *material)
52{
53 GSList *item;
54 G3DObject *sub;
55 G3DFace *face;
56
57 for(item = object->faces; item != NULL; item = item->next) {
58 face = item->data;
59 if(face->material == NULL)
60 face->material = material;
61 }
62 for(item = object->objects; item != NULL; item = item->next) {
63 sub = item->data;
64 ldraw_part_replace_material(sub, material);
65 }
66}
67
68static gboolean ldraw_part_parse_ref(G3DObject *object, gchar *buffer,
69 LDrawLibrary *lib)
70{
71 G3DObject *subobj;
72 G3DMaterial *material;
73 G3DFloat m[16], x, y, z;
74 guint32 colid;
75 gchar fname[256], *strp;
76
77 g3d_matrix_identity(m);
78 memset(fname, 0, 256);
79
80 if(sscanf(buffer, "%u "
81 G3D_SCANF_FLOAT " " G3D_SCANF_FLOAT " " G3D_SCANF_FLOAT " " G3D_SCANF_FLOAT " "
82 G3D_SCANF_FLOAT " " G3D_SCANF_FLOAT " " G3D_SCANF_FLOAT " " G3D_SCANF_FLOAT " "
83 G3D_SCANF_FLOAT " " G3D_SCANF_FLOAT " " G3D_SCANF_FLOAT " " G3D_SCANF_FLOAT " %255s",
84 &colid, &x, &y, &z,
85 m + 0 * 4 + 0, m + 1 * 4 + 0, m + 2 * 4 + 0,
86 m + 0 * 4 + 1, m + 1 * 4 + 1, m + 2 * 4 + 1,
87 m + 0 * 4 + 2, m + 1 * 4 + 2, m + 2 * 4 + 2,
88 fname) == 14) {
89
90 strp = path_sep(fname);
91 if(strp != NULL)
92 strp[0] = G_DIR_SEPARATOR;
93
94 subobj = ldraw_part_from_file(lib, fname);
95 if(!subobj)
96 subobj = ldraw_library_lookup(lib, fname);
97 if(subobj != NULL) {
98 g3d_object_transform(subobj, m);
99 g3d_matrix_identity(m);
100 g3d_matrix_translate(x, y, z, m);
101 g3d_object_transform(subobj, m);
102 if(colid != 16) {
103 material = ldraw_color_lookup(lib, colid);
104 ldraw_part_replace_material(subobj, material);
105 }
106 object->objects = g_slist_append(object->objects, subobj);
107 return TRUE;
108 }
109 }
110#if DEBUG > 1
111 g_warning("LDraw: failed to parse/process reference: %s", buffer);
112#endif
113 return FALSE;
114}
115
116static gboolean ldraw_part_parse_tri(G3DObject *object, gchar *buffer,
117 LDrawLibrary *lib)
118{
119 guint32 off, colid;
120 G3DFace *face;
121
122 off = object->vertex_count;
123 object->vertex_count += 3;
124 object->vertex_data = g_realloc(object->vertex_data,
125 object->vertex_count * 3 * sizeof(G3DFloat));
126 if(sscanf(buffer, "%u "
127 G3D_SCANF_FLOAT " " G3D_SCANF_FLOAT " " G3D_SCANF_FLOAT " "
128 G3D_SCANF_FLOAT " " G3D_SCANF_FLOAT " " G3D_SCANF_FLOAT " "
129 G3D_SCANF_FLOAT " " G3D_SCANF_FLOAT " " G3D_SCANF_FLOAT,
130 &colid,
131 object->vertex_data + (off + 0) * 3 + 0,
132 object->vertex_data + (off + 0) * 3 + 1,
133 object->vertex_data + (off + 0) * 3 + 2,
134 object->vertex_data + (off + 1) * 3 + 0,
135 object->vertex_data + (off + 1) * 3 + 1,
136 object->vertex_data + (off + 1) * 3 + 2,
137 object->vertex_data + (off + 2) * 3 + 0,
138 object->vertex_data + (off + 2) * 3 + 1,
139 object->vertex_data + (off + 2) * 3 + 2) == 10) {
140
141 face = g_new0(G3DFace, 1);
142 face->material = ldraw_color_lookup(lib, colid);
143 face->vertex_count = 3;
144 face->vertex_indices = g_new0(guint32, 3);
145 face->vertex_indices[0] = off + 0;
146 face->vertex_indices[1] = off + 1;
147 face->vertex_indices[2] = off + 2;
148 object->faces = g_slist_append(object->faces, face);
149 return TRUE;
150 }
151 return FALSE;
152}
153
154static gboolean ldraw_part_parse_quad(G3DObject *object, gchar *buffer,
155 LDrawLibrary *lib)
156{
157 guint32 off, colid;
158 G3DFace *face;
159
160 off = object->vertex_count;
161 object->vertex_count += 4;
162 object->vertex_data = g_realloc(object->vertex_data,
163 object->vertex_count * 3 * sizeof(G3DFloat));
164 if(sscanf(buffer, "%u "
165 G3D_SCANF_FLOAT " " G3D_SCANF_FLOAT " " G3D_SCANF_FLOAT " " G3D_SCANF_FLOAT " "
166 G3D_SCANF_FLOAT " " G3D_SCANF_FLOAT " " G3D_SCANF_FLOAT " " G3D_SCANF_FLOAT " "
167 G3D_SCANF_FLOAT " " G3D_SCANF_FLOAT " " G3D_SCANF_FLOAT " " G3D_SCANF_FLOAT,
168 &colid,
169 object->vertex_data + (off + 0) * 3 + 0,
170 object->vertex_data + (off + 0) * 3 + 1,
171 object->vertex_data + (off + 0) * 3 + 2,
172 object->vertex_data + (off + 1) * 3 + 0,
173 object->vertex_data + (off + 1) * 3 + 1,
174 object->vertex_data + (off + 1) * 3 + 2,
175 object->vertex_data + (off + 2) * 3 + 0,
176 object->vertex_data + (off + 2) * 3 + 1,
177 object->vertex_data + (off + 2) * 3 + 2,
178 object->vertex_data + (off + 3) * 3 + 0,
179 object->vertex_data + (off + 3) * 3 + 1,
180 object->vertex_data + (off + 3) * 3 + 2) == 13) {
181
182 face = g_new0(G3DFace, 1);
183 face->material = ldraw_color_lookup(lib, colid);
184 face->vertex_count = 4;
185 face->vertex_indices = g_new0(guint32, 4);
186 face->vertex_indices[0] = off + 0;
187 face->vertex_indices[1] = off + 1;
188 face->vertex_indices[2] = off + 2;
189 face->vertex_indices[3] = off + 3;
190 object->faces = g_slist_append(object->faces, face);
191 return TRUE;
192 }
193 return FALSE;
194}
195
196static inline G3DObject *ldraw_part_open_file(LDrawLibrary *lib,
197 const gchar *filename)
198{
199 LDrawPart *part;
200
201 part = g_new0(LDrawPart, 1);
202 part->name = g_strdup(filename);
203 part->stream = g3d_stream_open_file(filename, "r");
204 if(part->stream == NULL) {
205 g_free(part);
206 return NULL;
207 }
208 part->object = ldraw_part_get_object(part, lib);
209 g3d_stream_close(part->stream);
210 part->stream = NULL;
211
212 ldraw_library_insert(lib, part->name, part);
213
214 return part->object;
215}
216
217G3DObject *ldraw_part_from_file(LDrawLibrary *lib, const gchar *filename)
218{
219 G3DObject *object;
220 gchar *path;
221
222 if(g_file_test(filename, G_FILE_TEST_EXISTS))
223 return ldraw_part_open_file(lib, filename);
224 path = g_ascii_strdown(filename, -1);
225 if(g_file_test(path, G_FILE_TEST_EXISTS)) {
226 object = ldraw_part_open_file(lib, path);
227 g_free(path);
228 return object;
229 }
230 g_free(path);
231 return NULL;
232}
233
234G3DObject *ldraw_part_get_object(LDrawPart *part, LDrawLibrary *lib)
235{
236 G3DObject *object;
237 G3DMaterial *material;
238 gchar buffer[1024];
239
240 object = g_new0(G3DObject, 1);
241 material = g3d_material_new();
242 material->name = g_strdup("default material");
243 object->materials = g_slist_append(object->materials, material);
244
245 while(!g3d_stream_eof(part->stream)) {
246 memset(buffer, 0, 1024);
247 g3d_stream_read_line(part->stream, buffer, 1023);
248 g_strstrip(buffer);
249 if(strlen(buffer) == 0)
250 continue;
251 switch(buffer[0] - 0x30) {
252 case 0: /* meta data */
253 ldraw_part_parse_meta(object, buffer + 2);
254 break;
255 case 1: /* sub-file reference */
256 ldraw_part_parse_ref(object, buffer + 2, lib);
257 break;
258 case 2: /* line */
259 break;
260 case 3: /* triangle */
261 ldraw_part_parse_tri(object, buffer + 2, lib);
262 break;
263 case 4: /* quadrilateral */
264 ldraw_part_parse_quad(object, buffer + 2, lib);
265 break;
266 case 5: /* optional line */
267 break;
268 default:
269 g_warning("LDraw: unknown type of line: %s", buffer);
270 break;
271 }
272 if(part->master) {
273 g3d_context_update_progress_bar(lib->context,
274 (G3DFloat)g3d_stream_tell(part->stream) /
275 (G3DFloat)g3d_stream_size(part->stream), TRUE);
276 g3d_context_update_interface(lib->context);
277 }
278 }
279
280 return object;
281}
282
283void ldraw_part_free(LDrawPart *part)
284{
285 if(part->stream)
286 g3d_stream_close(part->stream);
287 if(part->filename)
288 g_free(part->filename);
289 g_free(part->name);
290 g_free(part);
291}