aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_3dm/imp_3dm.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/others/mimesh/libg3d-0.0.8/plugins/import/imp_3dm/imp_3dm.c')
-rw-r--r--src/others/mimesh/libg3d-0.0.8/plugins/import/imp_3dm/imp_3dm.c169
1 files changed, 169 insertions, 0 deletions
diff --git a/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_3dm/imp_3dm.c b/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_3dm/imp_3dm.c
new file mode 100644
index 0000000..6273fd3
--- /dev/null
+++ b/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_3dm/imp_3dm.c
@@ -0,0 +1,169 @@
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 <ctype.h>
24#include <stdlib.h>
25#include <string.h>
26
27#include <g3d/types.h>
28#include <g3d/stream.h>
29#include <g3d/debug.h>
30
31#include "imp_3dm.h"
32#include "imp_3dm_chunks.h"
33
34static gboolean tdm_read_container(TdmGlobal *global, gpointer object,
35 goffset nb, guint32 level);
36
37EAPI
38gboolean plugin_load_model_from_stream(G3DContext *context, G3DStream *stream,
39 G3DModel *model, gpointer user_data)
40{
41 TdmGlobal *global;
42 G3DFloat version;
43 gchar magic[33], *pver;
44 gboolean retval;
45 guint32 max_len;
46
47 memset(magic, '\0', 33);
48 g3d_stream_read(stream, magic, 32);
49 if(strncmp(magic, "3D Geometry File Format ", 24) != 0) {
50 g_warning("%s is not an OpenNURBS 3dm file", stream->uri);
51 return FALSE;
52 }
53 pver = magic + 24;
54 while(isspace(*pver))
55 pver ++;
56 version = strtod(pver, NULL);
57#if DEBUG > 0
58 g_debug("loading %s, version %.1f", stream->uri, version);
59#endif
60
61 global = g_new0(TdmGlobal, 1);
62 global->context = context;
63 global->stream = stream;
64 global->model = model;
65 max_len = g3d_stream_size(stream);
66 if(!max_len)
67 max_len = (guint32) -1;
68 retval = tdm_read_container(global, NULL, max_len - 32, 0);
69 g_free(global);
70
71 return retval;
72}
73
74EAPI
75gchar *plugin_description(void)
76{
77 return g_strdup("OpenNURBS models.");
78}
79
80EAPI
81gchar **plugin_extensions(void)
82{
83 return g_strsplit("3dm", ":", 0);
84}
85
86/*****************************************************************************/
87
88static TdmChunkInfo *tdm_get_chunk_info(guint32 tcode)
89{
90 gint32 i;
91
92 for(i = 0; tdm_chunks[i].tcode <= tcode; i ++)
93 if(tdm_chunks[i].tcode == tcode)
94 return &(tdm_chunks[i]);
95 return NULL;
96}
97
98static gboolean tdm_read_container(TdmGlobal *global, gpointer object,
99 goffset nb, guint32 level)
100{
101 TdmChunkInfo *chunkinfo;
102 TdmLocal *local;
103 guint32 tcode;
104 guint32 len;
105 goffset off;
106
107 while(TRUE) {
108 off = g3d_stream_tell(global->stream);
109 tcode = g3d_stream_read_int32_le(global->stream);
110 len = g3d_stream_read_int32_le(global->stream);
111 nb -= 8;
112 if(tcode == 0)
113 return TRUE;
114
115 /* mask out DATA and CRC */
116 chunkinfo = tdm_get_chunk_info(tcode & 0x7FFF7FFF);
117
118#if DEBUG > 0
119 g_debug("\\%s[0x%08x][%c%c%c] %s (%d bytes @ 0x%08x)",
120 debug_pad(level), tcode,
121 (chunkinfo && chunkinfo->container) ? 'c' : ' ',
122 (chunkinfo && chunkinfo->endofcnt) ? 'e' : ' ',
123 (chunkinfo && chunkinfo->callback) ? 'f' : ' ',
124 chunkinfo ? chunkinfo->description : "unknown chunk",
125 (tcode & TCODE_DATA) ? 0 : len,
126 (guint32)off);
127#endif
128 if(chunkinfo && chunkinfo->endofcnt)
129 return TRUE;
130
131#if DEBUG > 0
132 if(tcode & TCODE_DATA)
133 g_debug("|%sdata: 0x%08x", debug_pad(level + 1), len);
134#endif
135
136 if(chunkinfo) {
137 if(chunkinfo->callback) {
138 local = g_new0(TdmLocal, 1);
139 local->tcode = tcode;
140 local->len = (tcode & TCODE_DATA) ? 0 : len;
141 local->data = (tcode & TCODE_DATA) ? len : 0;
142 local->level = level;
143 local->object = object;
144 chunkinfo->callback(global, local);
145 len = local->len;
146 object = local->object;
147 g_free(local);
148 }
149 if(chunkinfo->container) {
150 if(!tdm_read_container(global, object, len, level + 1))
151 return FALSE;
152 nb -= len;
153 len = 0;
154 if(tcode & TCODE_CRC) {
155 g3d_stream_read_int32_le(global->stream);
156 nb -= 4;
157 }
158 }
159 }
160
161 if(tcode & TCODE_DATA)
162 continue;
163
164 if(len > 0)
165 g3d_stream_skip(global->stream, len);
166 }
167
168 return TRUE;
169}