diff options
Diffstat (limited to 'src/others/mimesh/libg3d-0.0.8/plugins/import/imp_leocad/imp_leocad_library.c')
-rw-r--r-- | src/others/mimesh/libg3d-0.0.8/plugins/import/imp_leocad/imp_leocad_library.c | 633 |
1 files changed, 633 insertions, 0 deletions
diff --git a/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_leocad/imp_leocad_library.c b/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_leocad/imp_leocad_library.c new file mode 100644 index 0000000..7336336 --- /dev/null +++ b/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_leocad/imp_leocad_library.c | |||
@@ -0,0 +1,633 @@ | |||
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 | |||
23 | #include <g3d/config.h> | ||
24 | |||
25 | #include <string.h> | ||
26 | |||
27 | #include <glib.h> | ||
28 | |||
29 | #include <g3d/types.h> | ||
30 | #include <g3d/object.h> | ||
31 | #include <g3d/material.h> | ||
32 | #include <g3d/stream.h> | ||
33 | #include <g3d/primitive.h> | ||
34 | #include <g3d/matrix.h> | ||
35 | |||
36 | #include "imp_leocad_library.h" | ||
37 | |||
38 | #define LEOCAD_FLAG_PIECE_COUNT 0x01 | ||
39 | #define LEOCAD_FLAG_PIECE_LONGDATA 0x02 | ||
40 | #define LEOCAD_FLAG_PIECE_CCW 0x04 | ||
41 | #define LEOCAD_FLAG_PIECE_SMALL 0x10 | ||
42 | #define LEOCAD_FLAG_PIECE_MEDIUM 0x20 | ||
43 | #define LEOCAD_FLAG_LONGDATA_RUNTIME 0x40 | ||
44 | #define LEOCAD_FLAG_PIECE_RENAMED 0x80 | ||
45 | |||
46 | #define LEOCAD_TYPE_MESH 0x01 | ||
47 | #define LEOCAD_TYPE_STUD 0x02 | ||
48 | #define LEOCAD_TYPE_STUD2 0x03 | ||
49 | #define LEOCAD_TYPE_STUD3 0x04 | ||
50 | #define LEOCAD_TYPE_STUD4 0x05 | ||
51 | |||
52 | static gboolean leocad_library_read_pieces_idx(LeoCadLibrary *library, | ||
53 | G3DStream *idx); | ||
54 | static gboolean leocad_create_materials(LeoCadLibrary *library); | ||
55 | |||
56 | struct LeoCadConnection { | ||
57 | guint8 type; | ||
58 | G3DFloat center[3]; | ||
59 | G3DFloat normal[3]; | ||
60 | }; | ||
61 | |||
62 | LeoCadLibrary *leocad_library_load(const gchar *libdir) | ||
63 | { | ||
64 | LeoCadLibrary *library; | ||
65 | gchar filename[1025]; | ||
66 | G3DStream *idx, *bin; | ||
67 | |||
68 | library = g_new0(LeoCadLibrary, 1); | ||
69 | |||
70 | g_snprintf(filename, 1024, "%s/%s", libdir, "pieces.idx"); | ||
71 | idx = g3d_stream_open_file(filename, "rb"); | ||
72 | if(idx == NULL) { | ||
73 | #if DEBUG > 0 | ||
74 | g_warning("LeoCAD: failed to read '%s'", filename); | ||
75 | #endif | ||
76 | g_free(library); | ||
77 | return NULL; | ||
78 | } | ||
79 | |||
80 | g_snprintf(filename, 1024, "%s/%s", libdir, "pieces.bin"); | ||
81 | bin = g3d_stream_open_file(filename, "rb"); | ||
82 | if(bin == NULL) { | ||
83 | #if DEBUG > 0 | ||
84 | g_debug("LeoCAD: failed to read '%s'", filename); | ||
85 | #endif | ||
86 | g3d_stream_close(idx); | ||
87 | g_free(library); | ||
88 | return NULL; | ||
89 | } | ||
90 | |||
91 | library->pieces = g_hash_table_new(g_str_hash, g_str_equal); | ||
92 | library->pieces_bin = bin; | ||
93 | |||
94 | leocad_library_read_pieces_idx(library, idx); | ||
95 | g3d_stream_close(idx); | ||
96 | |||
97 | leocad_create_materials(library); | ||
98 | |||
99 | return library; | ||
100 | } | ||
101 | |||
102 | static gboolean leocad_free_piece_cb(gpointer key, gpointer value, | ||
103 | gpointer user_data) | ||
104 | { | ||
105 | LeoCadPiece *piece; | ||
106 | |||
107 | piece = (LeoCadPiece *)value; | ||
108 | |||
109 | #if DEBUG > 3 | ||
110 | g_debug("D: freeing piece %s", piece->name); | ||
111 | #endif | ||
112 | |||
113 | if(piece->name) g_free(piece->name); | ||
114 | if(piece->description) g_free(piece->description); | ||
115 | if(piece->moved_to) g_free(piece->moved_to); | ||
116 | |||
117 | if(!(piece->flags & LEOCAD_FLAG_PIECE_RENAMED)) | ||
118 | if(piece->object) g3d_object_free(piece->object); | ||
119 | |||
120 | g_free(piece); | ||
121 | |||
122 | return TRUE; | ||
123 | } | ||
124 | |||
125 | void leocad_library_free(LeoCadLibrary *library) | ||
126 | { | ||
127 | GSList *mlist; | ||
128 | G3DMaterial *material; | ||
129 | |||
130 | /* remove materials */ | ||
131 | mlist = library->materials; | ||
132 | while(mlist) | ||
133 | { | ||
134 | material = (G3DMaterial *)mlist->data; | ||
135 | mlist = g_slist_remove(mlist, material); | ||
136 | g3d_material_free(material); | ||
137 | } | ||
138 | |||
139 | /* remove pieces */ | ||
140 | g_hash_table_foreach_remove(library->pieces, leocad_free_piece_cb, NULL); | ||
141 | g_hash_table_destroy(library->pieces); | ||
142 | |||
143 | /* free library */ | ||
144 | g_free(library); | ||
145 | } | ||
146 | |||
147 | static G3DFloat leocad_read_scaled16(G3DStream *stream, G3DFloat scale) | ||
148 | { | ||
149 | gint16 x; | ||
150 | |||
151 | x = g3d_stream_read_int16_le(stream); | ||
152 | |||
153 | return (G3DFloat)(x / scale); | ||
154 | } | ||
155 | |||
156 | static gboolean leocad_create_materials(LeoCadLibrary *library) | ||
157 | { | ||
158 | const guint8 colors[] = { | ||
159 | 166, 25, 25, 255, /* 0 - Red */ | ||
160 | 255, 127, 51, 255, /* 1 - Orange */ | ||
161 | 25, 102, 25, 255, /* 2 - Green */ | ||
162 | 76, 153, 76, 255, /* 3 - Light Green */ | ||
163 | 0, 51, 178, 255, /* 4 - Blue */ | ||
164 | 51, 102, 229, 255, /* 5 - Light Blue */ | ||
165 | 204, 204, 0, 255, /* 6 - Yellow */ | ||
166 | 242, 242, 242, 255, /* 7 - White */ | ||
167 | 76, 76, 76, 255, /* 8 - Dark Gray */ | ||
168 | 25, 25, 25, 255, /* 9 - Black */ | ||
169 | 102, 51, 51, 255, /* 10 - Brown */ | ||
170 | 178, 76, 153, 255, /* 11 - Pink */ | ||
171 | 153, 51, 153, 255, /* 12 - Purple */ | ||
172 | 229, 178, 51, 255, /* 13 - Gold */ | ||
173 | 153, 25, 25, 153, /* 14 - Clear Red */ | ||
174 | 255, 153, 76, 153, /* 15 - Clear Orange */ | ||
175 | 25, 102, 25, 153, /* 16 - Clear Green */ | ||
176 | 153, 178, 76, 153, /* 17 - Clear Light Green */ | ||
177 | 0, 0, 127, 153, /* 18 - Clear Blue */ | ||
178 | 51, 102, 229, 153, /* 19 - Clear Light Blue */ | ||
179 | 229, 229, 0, 153, /* 20 - Clear Yellow */ | ||
180 | 229, 229, 229, 153, /* 21 - Clear White */ | ||
181 | 127, 127, 127, 255, /* 22 - Light Gray */ | ||
182 | 204, 204, 178, 255, /* 23 - Tan */ | ||
183 | 153, 102, 102, 255, /* 24 - Light Brown */ | ||
184 | 229, 178, 229, 255, /* 25 - Light Pink */ | ||
185 | 25, 178, 204, 255, /* 26 - Turquoise */ | ||
186 | 204, 204, 204, 255, /* 27 - Silver */ | ||
187 | 51, 51, 51, 255, /* 28 - Edges */ | ||
188 | 229, 76, 102, 255, /* 29 - Selected */ | ||
189 | 102, 76, 229, 255}; /* 30 - Focused */ | ||
190 | |||
191 | G3DMaterial *material; | ||
192 | guint32 i; | ||
193 | |||
194 | for(i = 0; i < 31; i ++) | ||
195 | { | ||
196 | material = g3d_material_new(); | ||
197 | material->r = (G3DFloat)colors[i * 4 + 0] / 255.0; | ||
198 | material->g = (G3DFloat)colors[i * 4 + 1] / 255.0; | ||
199 | material->b = (G3DFloat)colors[i * 4 + 2] / 255.0; | ||
200 | material->a = (G3DFloat)colors[i * 4 + 3] / 255.0; | ||
201 | |||
202 | library->materials = g_slist_append(library->materials, material); | ||
203 | } | ||
204 | |||
205 | return TRUE; | ||
206 | } | ||
207 | |||
208 | guint8 leocad_library_convert_color(guint8 n) | ||
209 | { | ||
210 | static guint8 converted_colors[20] = | ||
211 | { 0,2,4,9,7,6,22,8,10,11,14,16,18,9,21,20,22,8,10,11 }; | ||
212 | |||
213 | if(n >= 20) | ||
214 | return 0; | ||
215 | |||
216 | return converted_colors[n]; | ||
217 | } | ||
218 | |||
219 | G3DMaterial *leocad_library_get_nth_material(LeoCadLibrary *library, guint8 n) | ||
220 | { | ||
221 | return g_slist_nth_data(library->materials, n); | ||
222 | } | ||
223 | |||
224 | G3DObject *leocad_library_get_piece(LeoCadLibrary *library, const gchar *name) | ||
225 | { | ||
226 | LeoCadPiece *piece; | ||
227 | G3DObject *stud; | ||
228 | G3DFace *face; | ||
229 | guint32 i, j, k, nconn, ngrp, ntex, ngrpconn, ncol, nx, color = 0; | ||
230 | guint16 grp_type; | ||
231 | G3DFloat scale = 100.0; | ||
232 | G3DFloat matrix[16]; | ||
233 | G3DStream *bin; | ||
234 | struct LeoCadConnection *connections; | ||
235 | |||
236 | piece = g_hash_table_lookup(library->pieces, name); | ||
237 | |||
238 | if(piece == NULL) | ||
239 | { | ||
240 | g_warning("LeoCAD: failed to load piece '%s'", name); | ||
241 | return NULL; | ||
242 | } | ||
243 | |||
244 | bin = library->pieces_bin; | ||
245 | |||
246 | if(piece->object == NULL) | ||
247 | { | ||
248 | piece->object = g_new0(G3DObject, 1); | ||
249 | piece->object->name = g_strdup(piece->description); | ||
250 | |||
251 | g3d_stream_seek(bin, piece->offset_bin, G_SEEK_SET); | ||
252 | piece->object->vertex_count = g3d_stream_read_int32_le(bin); | ||
253 | piece->object->vertex_data = g_new0(G3DFloat, | ||
254 | piece->object->vertex_count * 3); | ||
255 | |||
256 | if(piece->flags & LEOCAD_FLAG_PIECE_SMALL) | ||
257 | scale = 10000.0; | ||
258 | else if(piece->flags & LEOCAD_FLAG_PIECE_MEDIUM) | ||
259 | scale = 1000.0; | ||
260 | |||
261 | for(i = 0; i < piece->object->vertex_count; i ++) | ||
262 | { | ||
263 | piece->object->vertex_data[i * 3 + 0] = | ||
264 | leocad_read_scaled16(bin, scale); | ||
265 | piece->object->vertex_data[i * 3 + 1] = | ||
266 | leocad_read_scaled16(bin, scale); | ||
267 | piece->object->vertex_data[i * 3 + 2] = | ||
268 | leocad_read_scaled16(bin, scale); | ||
269 | } | ||
270 | #if DEBUG > 1 | ||
271 | g_debug("LeoCAD: piece '%s': flags 0x%02X", name, piece->flags); | ||
272 | #endif | ||
273 | |||
274 | #if DEBUG > 1 | ||
275 | g_debug("LeoCAD: piece '%s': %d vertices", | ||
276 | name, piece->object->vertex_count); | ||
277 | #endif | ||
278 | |||
279 | /* connections */ | ||
280 | nconn = g3d_stream_read_int16_le(bin); | ||
281 | #if DEBUG > 1 | ||
282 | g_debug("LeoCAD: piece '%s': %d connections", name, nconn); | ||
283 | #endif | ||
284 | connections = g_new0(struct LeoCadConnection, nconn); | ||
285 | for(i = 0; i < nconn; i ++) | ||
286 | { | ||
287 | connections[i].type = g3d_stream_read_int8(bin); | ||
288 | |||
289 | /* center */ | ||
290 | connections[i].center[0] = leocad_read_scaled16(bin, scale); | ||
291 | connections[i].center[1] = leocad_read_scaled16(bin, scale); | ||
292 | connections[i].center[2] = leocad_read_scaled16(bin, scale); | ||
293 | |||
294 | /* normal */ | ||
295 | connections[i].normal[0] = g3d_stream_read_int16_le(bin) / (1 << 14); | ||
296 | connections[i].normal[1] = g3d_stream_read_int16_le(bin) / (1 << 14); | ||
297 | connections[i].normal[2] = g3d_stream_read_int16_le(bin) / (1 << 14); | ||
298 | } | ||
299 | |||
300 | /* textures */ | ||
301 | ntex = g3d_stream_read_int8(bin); | ||
302 | #if DEBUG > 0 | ||
303 | if(ntex > 0) | ||
304 | g_debug("LeoCAD: piece '%s': %d textures", name, ntex); | ||
305 | #endif | ||
306 | for(i = 0; i < ntex; i ++) | ||
307 | { | ||
308 | /* TODO: */ | ||
309 | } | ||
310 | |||
311 | /* groups */ | ||
312 | ngrp = g3d_stream_read_int16_le(bin); | ||
313 | #if DEBUG > 1 | ||
314 | g_debug("LeoCAD: piece '%s': %d groups @ 0x%08lx", | ||
315 | name, ngrp, ftell(bin)); | ||
316 | #endif | ||
317 | for(i = 0; i < ngrp; i ++) | ||
318 | { | ||
319 | /* group connections */ | ||
320 | ngrpconn = g3d_stream_read_int8(bin); | ||
321 | for(j = 0; j < ngrpconn; j ++) | ||
322 | { | ||
323 | g3d_stream_read_int16_le(bin); | ||
324 | } | ||
325 | |||
326 | #if 0 | ||
327 | while(1) | ||
328 | { | ||
329 | #endif | ||
330 | grp_type = g3d_stream_read_int8(bin); | ||
331 | if(grp_type == 0) | ||
332 | { | ||
333 | break; | ||
334 | } | ||
335 | #if DEBUG > 1 | ||
336 | g_debug("LeoCAD: piece '%s': grp %d: type 0x%02x @ 0x%08lx", | ||
337 | name, i, grp_type, ftell(bin)); | ||
338 | #endif | ||
339 | |||
340 | switch(grp_type) | ||
341 | { | ||
342 | case LEOCAD_TYPE_MESH: | ||
343 | ncol = g3d_stream_read_int16_le(bin); | ||
344 | #if DEBUG > 1 | ||
345 | g_debug("LeoCAD: piece '%s': grp %d: %d colors " | ||
346 | "(@ 0x%08lx)", name, i, ncol, ftell(bin)); | ||
347 | #endif | ||
348 | for(j = 0; j < ncol; j ++) | ||
349 | { | ||
350 | /* color code */ | ||
351 | color = g3d_stream_read_int16_le(bin); | ||
352 | #if DEBUG > 1 | ||
353 | g_debug("LeoCAD: piece '%s': grp %d: color 0x%04x", | ||
354 | name, i, color); | ||
355 | #endif | ||
356 | /* quads? */ | ||
357 | nx = g3d_stream_read_int16_le(bin); | ||
358 | for(k = 0; k < nx / 4; k ++) | ||
359 | { | ||
360 | face = g_new0(G3DFace, 1); | ||
361 | face->material = | ||
362 | g_slist_nth_data( | ||
363 | library->materials, color); | ||
364 | face->vertex_count = 4; | ||
365 | face->vertex_indices = g_new0(guint32, 4); | ||
366 | |||
367 | face->vertex_indices[0] = | ||
368 | g3d_stream_read_int16_le(bin); | ||
369 | face->vertex_indices[1] = | ||
370 | g3d_stream_read_int16_le(bin); | ||
371 | face->vertex_indices[2] = | ||
372 | g3d_stream_read_int16_le(bin); | ||
373 | face->vertex_indices[3] = | ||
374 | g3d_stream_read_int16_le(bin); | ||
375 | |||
376 | piece->object->faces = g_slist_prepend( | ||
377 | piece->object->faces, face); | ||
378 | } | ||
379 | #if DEBUG > 1 | ||
380 | g_debug("LeoCAD: piece '%s': grp %d: " | ||
381 | "quads: %d bytes", name, i, nx * 2); | ||
382 | #endif | ||
383 | nx = g3d_stream_read_int16_le(bin); | ||
384 | for(k = 0; k < nx / 3; k ++) | ||
385 | { | ||
386 | face = g_new0(G3DFace, 1); | ||
387 | face->material = | ||
388 | g_slist_nth_data( | ||
389 | library->materials, color); | ||
390 | face->vertex_count = 3; | ||
391 | face->vertex_indices = g_new0(guint32, 3); | ||
392 | |||
393 | face->vertex_indices[0] = | ||
394 | g3d_stream_read_int16_le(bin); | ||
395 | face->vertex_indices[1] = | ||
396 | g3d_stream_read_int16_le(bin); | ||
397 | face->vertex_indices[2] = | ||
398 | g3d_stream_read_int16_le(bin); | ||
399 | |||
400 | piece->object->faces = g_slist_prepend( | ||
401 | piece->object->faces, face); | ||
402 | } | ||
403 | |||
404 | #if DEBUG > 1 | ||
405 | g_debug("LeoCAD: piece '%s': grp %d: " | ||
406 | "triangles: %d bytes", | ||
407 | name, i, nx * 2); | ||
408 | #endif | ||
409 | nx = g3d_stream_read_int16_le(bin); | ||
410 | #if DEBUG > 1 | ||
411 | g_debug("LeoCAD: piece '%s': grp %d: " | ||
412 | "skipping %d bytes @ 0x%08lx", | ||
413 | name, i, nx * 2, ftell(bin)); | ||
414 | #endif | ||
415 | g3d_stream_skip(bin, nx * 2); | ||
416 | } | ||
417 | break; | ||
418 | |||
419 | case LEOCAD_TYPE_STUD: | ||
420 | case LEOCAD_TYPE_STUD2: | ||
421 | case LEOCAD_TYPE_STUD3: | ||
422 | case LEOCAD_TYPE_STUD4: | ||
423 | stud = NULL; | ||
424 | color = g3d_stream_read_int8(bin); | ||
425 | #if DEBUG > 0 | ||
426 | g_debug("LeoCAD: piece '%s': stud 0x%02x", | ||
427 | name, grp_type); | ||
428 | #endif | ||
429 | if(grp_type == LEOCAD_TYPE_STUD4) | ||
430 | stud = g3d_primitive_tube( | ||
431 | 0.24, /* inner radius */ | ||
432 | 0.32, /* outer radius */ | ||
433 | 0.16, /* height */ | ||
434 | 16, /* sides */ | ||
435 | TRUE, FALSE, /* top, bottom */ | ||
436 | leocad_library_get_nth_material( | ||
437 | library, color)); | ||
438 | |||
439 | g3d_matrix_identity(matrix); | ||
440 | for(j = 0; j < 12; j ++) | ||
441 | #if 1 | ||
442 | matrix[(j / 3) * 4 + (j % 3)] = | ||
443 | g3d_stream_read_float_le(bin); | ||
444 | #else | ||
445 | matrix[j] = g3d_stream_read_float_le(bin); | ||
446 | #endif | ||
447 | /* g3d_matrix_dump(matrix); */ | ||
448 | |||
449 | if(stud && piece->object) | ||
450 | { | ||
451 | g3d_object_transform(stud, matrix); | ||
452 | g3d_object_merge(piece->object, stud); | ||
453 | stud = NULL; | ||
454 | } | ||
455 | |||
456 | break; | ||
457 | |||
458 | default: | ||
459 | #if DEBUG > 1 | ||
460 | g_debug( | ||
461 | "LeoCAD: piece '%s': unhandled group type 0x%02x " | ||
462 | "@ 0x%08lx", | ||
463 | name, grp_type, ftell(bin)); | ||
464 | #endif | ||
465 | break; | ||
466 | } /* grp_type */ | ||
467 | #if 0 | ||
468 | } /* grp_type != 0 */ | ||
469 | #endif | ||
470 | g3d_stream_read_int8(bin); | ||
471 | } /* ngrp */ | ||
472 | |||
473 | /* generate studs */ | ||
474 | for(i = 0; i < nconn; i ++) | ||
475 | { | ||
476 | #if DEBUG > 4 | ||
477 | g_debug("LeoCAD: connection %d: type 0x%02x", | ||
478 | i, connections[i].type); | ||
479 | #endif | ||
480 | |||
481 | switch(connections[i].type) | ||
482 | { | ||
483 | case 0: | ||
484 | stud = g3d_primitive_cylinder( | ||
485 | 0.24, /* radius */ | ||
486 | 0.16, /* height */ | ||
487 | 16, /* sides */ | ||
488 | TRUE, FALSE, /* top, bottom */ | ||
489 | leocad_library_get_nth_material(library, color)); | ||
490 | break; | ||
491 | |||
492 | case 2: | ||
493 | stud = g3d_primitive_tube( | ||
494 | 0.24, /* inner radius */ | ||
495 | 0.32, /* outer radius */ | ||
496 | 0.16, /* height */ | ||
497 | 16, /* sides */ | ||
498 | FALSE, TRUE, /* top, bottom */ | ||
499 | leocad_library_get_nth_material(library, color)); | ||
500 | break; | ||
501 | |||
502 | default: | ||
503 | stud = NULL; | ||
504 | break; | ||
505 | } | ||
506 | |||
507 | if(stud) | ||
508 | { | ||
509 | #if DEBUG > 5 | ||
510 | g_debug("LeoCAD: stud"); | ||
511 | #endif | ||
512 | /* transform stud */ | ||
513 | for(j = 0; j < stud->vertex_count; j ++) | ||
514 | { | ||
515 | #if 0 | ||
516 | g3d_vector_transform( | ||
517 | &(stud->vertices[j * 3 + 0]), | ||
518 | &(stud->vertices[j * 3 + 1]), | ||
519 | &(stud->vertices[j * 3 + 2]), | ||
520 | matrix); | ||
521 | #endif | ||
522 | |||
523 | stud->vertex_data[j * 3 + 0] += connections[i].center[0]; | ||
524 | stud->vertex_data[j * 3 + 1] += connections[i].center[1]; | ||
525 | stud->vertex_data[j * 3 + 2] += connections[i].center[2]; | ||
526 | } | ||
527 | |||
528 | /* merge stud */ | ||
529 | g3d_object_merge(piece->object, stud); | ||
530 | } /* stud */ | ||
531 | } /* nconn */ | ||
532 | |||
533 | if(connections) | ||
534 | g_free(connections); | ||
535 | } | ||
536 | |||
537 | return g3d_object_duplicate(piece->object); | ||
538 | } | ||
539 | |||
540 | static gboolean leocad_library_read_piece(LeoCadLibrary *library, | ||
541 | G3DStream *idx) | ||
542 | { | ||
543 | gchar buffer[128]; | ||
544 | guint32 i; | ||
545 | LeoCadPiece *piece; | ||
546 | |||
547 | piece = g_new0(LeoCadPiece, 1); | ||
548 | |||
549 | g3d_stream_read(idx, buffer, 8); | ||
550 | buffer[8] = '\0'; | ||
551 | piece->name = g_strdup(buffer); | ||
552 | |||
553 | g3d_stream_read(idx, buffer, 64); | ||
554 | buffer[64] = '\0'; | ||
555 | piece->description = g_strdup(buffer); | ||
556 | |||
557 | for(i = 0; i < 6; i ++) | ||
558 | piece->bounding_box[i] = g3d_stream_read_int16_le(idx); | ||
559 | |||
560 | piece->flags = g3d_stream_read_int8(idx); | ||
561 | piece->default_group = g3d_stream_read_int32_le(idx); | ||
562 | piece->offset_bin = g3d_stream_read_int32_le(idx); | ||
563 | piece->info_size = g3d_stream_read_int32_le(idx); | ||
564 | |||
565 | #if DEBUG > 1 | ||
566 | g_debug("LeoCAD: %-8s: @ 0x%08x, %s", | ||
567 | piece->name, piece->offset_bin, piece->description); | ||
568 | #endif | ||
569 | |||
570 | g_hash_table_insert(library->pieces, piece->name, piece); | ||
571 | |||
572 | return TRUE; | ||
573 | } | ||
574 | |||
575 | static gboolean leocad_library_read_pieces_idx(LeoCadLibrary *library, | ||
576 | G3DStream *idx) | ||
577 | { | ||
578 | gchar magic[32], nameold[9], namenew[9]; | ||
579 | guint8 version, lastupdate; | ||
580 | guint32 nmoved, nbinsize, npieces, i; | ||
581 | LeoCadPiece *piece, *newpiece; | ||
582 | |||
583 | g3d_stream_read(idx, magic, 32); | ||
584 | if(strncmp(magic, "LeoCAD piece library index file", 31) != 0) | ||
585 | { | ||
586 | g_debug("LeoCAD: pieces.idx: wrong magic"); | ||
587 | return FALSE; | ||
588 | } | ||
589 | |||
590 | version = g3d_stream_read_int8(idx); | ||
591 | lastupdate = g3d_stream_read_int8(idx); | ||
592 | |||
593 | g3d_stream_seek(idx, -8, G_SEEK_END); | ||
594 | nmoved = g3d_stream_read_int16_le(idx); | ||
595 | nbinsize = g3d_stream_read_int32_le(idx); | ||
596 | npieces = g3d_stream_read_int16_le(idx); | ||
597 | |||
598 | g3d_stream_seek(idx, 34, G_SEEK_SET); | ||
599 | |||
600 | #if DEBUG > 0 | ||
601 | g_debug("LeoCAD: pieces.idx: version %d, last update %d", | ||
602 | version, lastupdate); | ||
603 | g_debug("LeoCAD: pieces.idx: %d pieces, %d moves, pieces.bin %d bytes", | ||
604 | npieces, nmoved, nbinsize); | ||
605 | #endif | ||
606 | |||
607 | for(i = 0; i < npieces; i ++) | ||
608 | leocad_library_read_piece(library, idx); | ||
609 | |||
610 | for(i = 0; i < nmoved; i ++) { | ||
611 | memset(nameold, 0, 9); | ||
612 | memset(namenew, 0, 9); | ||
613 | |||
614 | g3d_stream_read(idx, nameold, 8); | ||
615 | g3d_stream_read(idx, namenew, 8); | ||
616 | |||
617 | piece = g_hash_table_lookup(library->pieces, namenew); | ||
618 | if(piece) { | ||
619 | newpiece = g_new0(LeoCadPiece, 1); | ||
620 | memcpy(newpiece, piece, sizeof(LeoCadPiece)); | ||
621 | newpiece->name = g_strdup(nameold); | ||
622 | newpiece->description = g_strdup(piece->description); | ||
623 | newpiece->moved_to = g_strdup(namenew); | ||
624 | newpiece->object = piece->object; | ||
625 | newpiece->flags |= LEOCAD_FLAG_PIECE_RENAMED; | ||
626 | |||
627 | g_hash_table_insert(library->pieces, piece->name, newpiece); | ||
628 | } | ||
629 | } | ||
630 | |||
631 | return TRUE; | ||
632 | } | ||
633 | |||