diff options
Diffstat (limited to '')
-rw-r--r-- | src/others/mimesh/libg3d-0.0.8/plugins/import/imp_3dm/imp_3dm.c | 169 |
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 | |||
34 | static gboolean tdm_read_container(TdmGlobal *global, gpointer object, | ||
35 | goffset nb, guint32 level); | ||
36 | |||
37 | EAPI | ||
38 | gboolean 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 | |||
74 | EAPI | ||
75 | gchar *plugin_description(void) | ||
76 | { | ||
77 | return g_strdup("OpenNURBS models."); | ||
78 | } | ||
79 | |||
80 | EAPI | ||
81 | gchar **plugin_extensions(void) | ||
82 | { | ||
83 | return g_strsplit("3dm", ":", 0); | ||
84 | } | ||
85 | |||
86 | /*****************************************************************************/ | ||
87 | |||
88 | static 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 | |||
98 | static 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 | } | ||