aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_vrml2/imp_vrml_read.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/others/mimesh/libg3d-0.0.8/plugins/import/imp_vrml2/imp_vrml_read.c')
-rw-r--r--src/others/mimesh/libg3d-0.0.8/plugins/import/imp_vrml2/imp_vrml_read.c647
1 files changed, 647 insertions, 0 deletions
diff --git a/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_vrml2/imp_vrml_read.c b/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_vrml2/imp_vrml_read.c
new file mode 100644
index 0000000..580c5cd
--- /dev/null
+++ b/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_vrml2/imp_vrml_read.c
@@ -0,0 +1,647 @@
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 <string.h>
23#include <stdlib.h>
24
25#include "imp_vrml_types.h"
26#include "imp_vrml_read.h"
27
28#include "imp_vrml2_nodes.h"
29#include "imp_vrml2_types.h"
30
31gboolean vrml_read_check_buffer(VrmlReader *reader)
32{
33 if(reader->bufsize > 0)
34 return TRUE;
35 if(g3d_stream_eof(reader->stream))
36 return FALSE;
37 memset(reader->buffer, '\0', reader->max_bufsize);
38 g3d_stream_read_line(reader->stream, reader->buffer,
39 reader->max_bufsize - 1);
40 reader->line ++;
41 reader->bufsize = strlen(reader->buffer);
42 reader->bufp = reader->buffer;
43 return (reader->bufsize > 0);
44}
45
46gboolean vrml_read_skip_ws(VrmlReader *reader)
47{
48 if(!vrml_read_check_buffer(reader))
49 return FALSE;
50 while(g_ascii_isspace(*(reader->bufp))) {
51 vrml_read_dec(reader);
52 if(!vrml_read_check_buffer(reader))
53 return FALSE;
54 }
55 return TRUE;
56}
57
58gchar *vrml_read_token(VrmlReader *reader)
59{
60 gchar *s = NULL;
61 gsize len = 0;
62
63 if(!vrml_read_skip_ws(reader))
64 return NULL;
65 while(vrml_read_check_buffer(reader) &&
66 !g_ascii_isspace(*(reader->bufp)) &&
67 (*(reader->bufp) != ',')) {
68 len ++;
69 s = g_realloc(s, (len + 1) * sizeof(gchar));
70 s[len - 1] = *(reader->bufp);
71 s[len - 0] = '\0';
72 vrml_read_dec(reader);
73 }
74#if DEBUG > 3
75 g_debug("token: %s", s);
76#endif
77 return s;
78}
79
80gchar *vrml_read_numeric(VrmlReader *reader)
81{
82 gchar *s = NULL;
83 gsize len = 0;
84 gboolean first = TRUE;
85
86 if(!vrml_read_skip_ws(reader))
87 return NULL;
88 while(vrml_read_check_buffer(reader) &&
89 (g_ascii_isdigit(*(reader->bufp)) ||
90 strchr(".-e", *(reader->bufp)))) {
91
92 if(first) {
93 if(*(reader->bufp) == 'e')
94 return NULL;
95 first = FALSE;
96 }
97
98 len ++;
99 s = g_realloc(s, (len + 1) * sizeof(gchar));
100 s[len - 1] = *(reader->bufp);
101 s[len - 0] = '\0';
102 vrml_read_dec(reader);
103 }
104#if DEBUG > 3
105 g_debug("numeric: %s", s);
106#endif
107 return s;
108}
109
110gchar *vrml_read_id(VrmlReader *reader)
111{
112 gchar *buf;
113 gsize bufsize;
114
115 if(!vrml_read_skip_ws(reader))
116 return NULL;
117 if(!vrml_read_check_buffer(reader))
118 return NULL;
119 bufsize = 2;
120 buf = g_new(gchar, 2 * sizeof(gchar));
121 buf[0] = *(reader->bufp);
122 buf[1] = '\0';
123 if(!(g_ascii_isalpha(buf[0]) || strchr("_", buf[0]))) {
124 g_free(buf);
125 return NULL;
126 }
127 vrml_read_dec(reader);
128 if(!vrml_read_check_buffer(reader))
129 return buf;
130 while(g_ascii_isalnum(*(reader->bufp)) || strchr("_.", *(reader->bufp))) {
131 bufsize ++;
132 buf = g_realloc(buf, bufsize * sizeof(gchar));
133 buf[bufsize - 2] = *(reader->bufp);
134 buf[bufsize - 1] = '\0';
135 vrml_read_dec(reader);
136 if(!vrml_read_check_buffer(reader))
137 return buf;
138 }
139 return buf;
140}
141
142gchar *vrml_read_string(VrmlReader *reader)
143{
144 gchar *buf = NULL;
145 gsize bufsize = 0;
146
147 if(!vrml_read_check_buffer(reader))
148 return NULL;
149 while(*(reader->bufp) != '"') {
150 bufsize ++;
151 buf = g_realloc(buf, (bufsize + 1) * sizeof(gchar));
152 buf[bufsize - 1] = *(reader->bufp);
153 buf[bufsize] = '\0';
154 vrml_read_dec(reader);
155 if(!vrml_read_check_buffer(reader))
156 return buf;
157 }
158 vrml_read_dec(reader);
159 return buf;
160}
161
162gboolean vrml_read_skip_unknown(VrmlReader *reader)
163{
164 gchar c, *s;
165#if DEBUG > 0
166 g_debug("vrml: skipping unknown stuff in line %d", reader->line);
167#endif
168
169 while(vrml_read_check_buffer(reader)) {
170 c = *(reader->bufp);
171 vrml_read_dec(reader);
172 switch(c) {
173 case '"':
174 s = vrml_read_string(reader);
175 if(s) {
176 g_debug("found string '%s'", s);
177 g_free(s);
178 }
179 break;
180 case '{':
181 case '[':
182 vrml_read_skip_unknown(reader);
183 break;
184 case '}':
185 case ']':
186 return TRUE;
187 break;
188 default:
189 break;
190 }
191 }
192 return FALSE;
193}
194
195gchar *vrml_read_nodeid(VrmlReader *reader)
196{
197 gchar *id;
198 id = vrml_read_id(reader);
199 if(id == NULL)
200 return NULL;
201 if(!g_ascii_isupper(id[0])) {
202 g_free(id);
203 return NULL;
204 }
205 return id;
206}
207
208gboolean vrml_read_expect(VrmlReader *reader, const gchar c)
209{
210 gchar b;
211 if(!vrml_read_skip_ws(reader))
212 return FALSE;
213 if(!vrml_read_check_buffer(reader))
214 return FALSE;
215 b = *(reader->bufp);
216 vrml_read_dec(reader);
217 return (b == c);
218}
219
220gboolean vrml_read_list(VrmlReader *reader, vrml_read_list_item_callback cb,
221 gpointer user_data)
222{
223 if(!vrml_read_expect(reader, '['))
224 return FALSE;
225
226 while(vrml_read_skip_ws(reader)) {
227 if(*(reader->bufp) == ']') {
228 vrml_read_dec(reader);
229 return TRUE;
230 }
231 if(!cb(reader, user_data))
232 return FALSE;
233
234 if(!vrml_read_skip_ws(reader))
235 return FALSE;
236 if(*(reader->bufp) == ',')
237 vrml_read_dec(reader);
238 }
239 /* should not be reached */
240 return vrml_read_expect(reader, ']');
241}
242
243/*****************************************************************************/
244
245static VrmlObject *vrml_lookup_object(VrmlReader *reader, const gchar *id)
246{
247 VrmlObject *object;
248
249 object = g_new0(VrmlObject, 1);
250 object->defid = g_strdup(id);
251 object->name = g_strdup("object from library");
252
253 return object;
254}
255
256static gboolean vrml_read_float_n(VrmlReader *reader, G3DFloat *a, guint32 n)
257{
258 gint i;
259 gchar *s;
260
261 for(i = 0; i < n; i ++) {
262 s = vrml_read_numeric(reader);
263 if(s) {
264 a[i] = atof(s);
265 g_free(s);
266 } else
267 return FALSE;
268 }
269 return TRUE;
270}
271
272static gboolean vrml_read_token_n(VrmlReader *reader, VrmlProperty *property,
273 guint32 n)
274{
275 gchar *token;
276 gint32 i;
277
278 for(i = 0; i < n; i ++) {
279 token = vrml_read_token(reader);
280#if DEBUG > 2
281 g_debug("Token: %s", token);
282#endif
283 g_free(token);
284 }
285
286 return TRUE;
287}
288
289/* property list callbacks */
290
291gboolean vrml_read_list_object_cb(VrmlReader *reader, gpointer data)
292{
293 VrmlProperty *property = data;
294
295 property->n_items ++;
296 property->v_object = g_realloc(property->v_object,
297 property->n_items * sizeof(VrmlObject *));
298 property->v_object[property->n_items - 1] =
299 vrml_read_object(reader, property->level + 1);
300 return (property->v_object[property->n_items - 1] != NULL);
301}
302
303gboolean vrml_read_list_string_cb(VrmlReader *reader, gpointer data)
304{
305 VrmlProperty *property = data;
306
307 if(!vrml_read_expect(reader, '"'))
308 return FALSE;
309
310 property->n_items ++;
311 property->v_str = g_realloc(property->v_str,
312 property->n_items * sizeof(gchar *));
313 property->v_str[property->n_items - 1] =
314 vrml_read_string(reader);
315 return TRUE;
316}
317
318gboolean vrml_read_list_int_cb(VrmlReader *reader, gpointer data)
319{
320 VrmlProperty *property = data;
321 gchar *s;
322
323 s = vrml_read_numeric(reader);
324 if(s) {
325 property->n_items ++;
326 property->v_int = g_realloc(property->v_int,
327 property->n_items * sizeof(gint32));
328 property->v_int[property->n_items - 1] = atoi(s);
329 g_free(s);
330 return TRUE;
331 }
332 return FALSE;
333}
334
335gboolean vrml_read_list_float_cb(VrmlReader *reader, gpointer data)
336{
337 VrmlProperty *property = data;
338
339 property->n_items ++;
340 property->v_float = g_realloc(property->v_float,
341 property->n_items * sizeof(G3DFloat));
342 return vrml_read_float_n(reader,
343 property->v_float + (property->n_items - 1), 1);
344}
345
346gboolean vrml_read_list_float2_cb(VrmlReader *reader, gpointer data)
347{
348 VrmlProperty *property = data;
349
350 property->n_items += 2;
351 property->v_float = g_realloc(property->v_float,
352 property->n_items * sizeof(G3DFloat));
353 return vrml_read_float_n(reader,
354 property->v_float + (property->n_items - 2), 2);
355}
356
357gboolean vrml_read_list_float3_cb(VrmlReader *reader, gpointer data)
358{
359 VrmlProperty *property = data;
360
361 property->n_items += 3;
362 property->v_float = g_realloc(property->v_float,
363 property->n_items * sizeof(G3DFloat));
364 return vrml_read_float_n(reader,
365 property->v_float + (property->n_items - 3), 3);
366}
367
368gboolean vrml_read_list_float4_cb(VrmlReader *reader, gpointer data)
369{
370 VrmlProperty *property = data;
371
372 property->n_items += 4;
373 property->v_float = g_realloc(property->v_float,
374 property->n_items * sizeof(G3DFloat));
375 return vrml_read_float_n(reader,
376 property->v_float + (property->n_items - 4), 4);
377}
378
379gboolean vrml_read_list_floatx_cb(VrmlReader *reader, gpointer data)
380{
381 VrmlProperty *property = data;
382 gchar *s;
383
384 s = vrml_read_numeric(reader);
385 while(s) {
386 property->n_items ++;
387 property->v_float = g_realloc(property->v_float,
388 property->n_items * sizeof(G3DFloat));
389 property->v_float[property->n_items - 1] = atof(s);
390 g_free(s);
391 s = vrml_read_numeric(reader);
392 }
393 return TRUE;
394}
395
396/* property reader */
397
398VrmlProperty *vrml_read_property(VrmlReader *reader, guint32 level)
399{
400 VrmlProperty *property;
401 VrmlTypeDef *type = NULL;
402 gint i;
403 gchar *id, *s;
404
405 id = vrml_read_id(reader);
406 if(id == NULL)
407 return NULL;
408
409 /* look up object */
410 for(i = 0; vrml2_types[i].name != NULL; i ++)
411 if(strcmp(id, vrml2_types[i].name) == 0) {
412 type = &(vrml2_types[i]);
413 break;
414 }
415 if(type == NULL) {
416 g_warning("VRML: unknown type %s in line %d", id, reader->line);
417 return NULL;
418 }
419 property = g_new0(VrmlProperty, 1);
420 property->name = id;
421 if(type->detect != NULL)
422 property->id = type->detect(reader);
423 else
424 property->id = type->id;
425 property->level = level;
426
427#if DEBUG > 0
428 g_debug("\\%sproperty '%s', type %d",
429 vrml_read_padding + strlen(vrml_read_padding) - 1 - level,
430 id, property->id);
431#endif
432
433 switch(property->id) {
434 case T_OBJECT:
435 property->n_items = 1;
436 property->v_object = g_new0(VrmlObject *, 1);
437 property->v_object[0] = vrml_read_object(reader, level + 1);
438 break;
439 case T_TOKEN2:
440 vrml_read_token_n(reader, property, 2);
441 break;
442 case T_TOKEN3:
443 vrml_read_token_n(reader, property, 3);
444 break;
445 case T_STRING:
446 property->n_items = 1;
447 if(!vrml_read_expect(reader, '"'))
448 return FALSE;
449 property->v_str = g_new0(gchar *, 1);
450 property->v_str[0] = vrml_read_string(reader);
451 break;
452 case T_BOOLEAN:
453 s = vrml_read_token(reader);
454 if(s) {
455 if(strcmp(s, "TRUE") == 0)
456 property->v_boolean = TRUE;
457 g_free(s);
458 }
459 break;
460 case T_INT:
461 s = vrml_read_numeric(reader);
462 if(s) {
463 property->n_items = 1;
464 property->v_int = g_new0(gint32, 1);
465 property->v_int[0] = atoi(s);
466 g_free(s);
467 }
468 break;
469 case T_FLOAT:
470 property->n_items = 1;
471 property->v_float = g_new0(G3DFloat, 1);
472 vrml_read_float_n(reader, property->v_float, 1);
473 break;
474 case T_FLOAT2:
475 property->n_items = 2;
476 property->v_float = g_new0(G3DFloat, 2);
477 vrml_read_float_n(reader, property->v_float, 2);
478 break;
479 case T_FLOAT3:
480 property->n_items = 3;
481 property->v_float = g_new0(G3DFloat, 3);
482 vrml_read_float_n(reader, property->v_float, 3);
483 break;
484 case T_FLOAT4:
485 property->n_items = 4;
486 property->v_float = g_new0(G3DFloat, 4);
487 vrml_read_float_n(reader, property->v_float, 4);
488 break;
489 case T_FLOAT_X:
490 s = vrml_read_numeric(reader);
491 while(s) {
492 property->n_items ++;
493 property->v_float = g_realloc(property->v_float,
494 property->n_items * sizeof(G3DFloat));
495 property->v_float[property->n_items - 1] = atof(s);
496#if DEBUG > 2
497 g_debug("T_FLOAT_X: %i: %.2f", property->n_items,
498 property->v_float[property->n_items - 1]);
499#endif
500 g_free(s);
501 s = vrml_read_numeric(reader);
502 }
503 break;
504 case T_LIST_OBJECT:
505 vrml_read_list(reader, vrml_read_list_object_cb, property);
506 break;
507 case T_LIST_STRING:
508 vrml_read_list(reader, vrml_read_list_string_cb, property);
509 break;
510 case T_LIST_INT:
511 vrml_read_list(reader, vrml_read_list_int_cb, property);
512 break;
513 case T_LIST_FLOAT:
514 vrml_read_list(reader, vrml_read_list_float_cb, property);
515 break;
516 case T_LIST_FLOAT2:
517 vrml_read_list(reader, vrml_read_list_float2_cb, property);
518 break;
519 case T_LIST_FLOAT3:
520 vrml_read_list(reader, vrml_read_list_float3_cb, property);
521 break;
522 case T_LIST_FLOAT4:
523 vrml_read_list(reader, vrml_read_list_float4_cb, property);
524 break;
525 case T_LIST_FLOAT_X:
526 vrml_read_list(reader, vrml_read_list_floatx_cb, property);
527 break;
528
529 default:
530 g_free(property->name);
531 g_free(property);
532 return NULL;
533 break;
534 }
535
536 return property;
537}
538
539static VrmlObject *vrml_read_route_object(VrmlReader *reader, guint32 level)
540{
541 VrmlObject *object;
542 gchar *id;
543#if DEBUG > 2
544 g_debug("ROUTE object");
545#endif
546 id = vrml_read_id(reader); /* source */
547 if(id == NULL) {
548 g_warning("ROUTE: could not get source");
549 return NULL;
550 }
551 g_free(id);
552 id = vrml_read_id(reader); /* TO */
553 if(id == NULL) {
554 g_warning("ROUTE: could not get TO");
555 return NULL;
556 }
557 g_free(id);
558 id = vrml_read_id(reader); /* destination */
559 if(id == NULL) {
560 g_warning("ROUTE: could not get destination");
561 return NULL;
562 }
563 g_free(id);
564 object = g_new0(VrmlObject, 1);
565 object->name = g_strdup("ROUTE object");
566 object->level = level;
567 return object;
568}
569
570VrmlObject *vrml_read_object(VrmlReader *reader, guint32 level)
571{
572 VrmlObject *object;
573 VrmlProperty *property;
574 gchar *id, *defid = NULL;
575 gboolean define = FALSE;
576
577 id = vrml_read_id(reader);
578 if(id == NULL)
579 return NULL;
580 if(strcmp(id, "NULL") == 0) {
581 return NULL;
582 } else if(strcmp(id, "DEF") == 0) {
583 define = TRUE;
584 defid = vrml_read_id(reader);
585 if(defid == NULL)
586 return NULL;
587 id = vrml_read_id(reader);
588 if(id == NULL)
589 return NULL;
590 } else if(strcmp(id, "USE") == 0) {
591 defid = vrml_read_id(reader);
592#if DEBUG > 2
593 g_debug("looking up '%s'", defid);
594#endif
595 return vrml_lookup_object(reader, defid);
596 } else if(strcmp(id, "ROUTE") == 0) {
597 return vrml_read_route_object(reader, level);
598 }
599
600 if(!vrml_read_expect(reader, '{')) {
601 g_warning("vrml_read_object: expected '{' in line %d", reader->line);
602 g_free(id);
603 if(defid)
604 g_free(defid);
605 return FALSE;
606 }
607#if DEBUG > 0
608 g_debug("\\%sobject '%s'",
609 vrml_read_padding + strlen(vrml_read_padding) - 1 - level,
610 id);
611#endif
612
613 object = g_new0(VrmlObject, 1);
614 object->name = id;
615 object->defid = defid;
616 object->define = define;
617 object->level = level;
618
619 /* read properties */
620 while(vrml_read_skip_ws(reader)) {
621#if DEBUG > 2
622 g_debug("O: '%c'", *(reader->bufp));
623#endif
624 if(*(reader->bufp) == '}') {
625 vrml_read_dec(reader);
626 return object;
627 }
628 property = vrml_read_property(reader, level + 1);
629 if(property != NULL)
630 object->properties = g_slist_append(object->properties, property);
631 else {
632 vrml_read_skip_unknown(reader);
633 return object;
634 }
635 }
636 vrml_read_expect(reader, '}');
637 return object;
638}
639
640gboolean vrml_read_global(VrmlReader *reader)
641{
642 while(vrml_read_skip_ws(reader)) {
643 if(!vrml_read_object(reader, 0))
644 return FALSE;
645 }
646 return TRUE;
647}