diff options
Diffstat (limited to 'src/others/mimesh/libg3d-0.0.8/plugins/import/imp_dxf/imp_dxf.c')
-rw-r--r-- | src/others/mimesh/libg3d-0.0.8/plugins/import/imp_dxf/imp_dxf.c | 291 |
1 files changed, 291 insertions, 0 deletions
diff --git a/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_dxf/imp_dxf.c b/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_dxf/imp_dxf.c new file mode 100644 index 0000000..1b08d6e --- /dev/null +++ b/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_dxf/imp_dxf.c | |||
@@ -0,0 +1,291 @@ | |||
1 | /* $Id: imp_dxf.c 256 2008-09-04 12:02:58Z mmmaddd $ */ | ||
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 <stdio.h> | ||
24 | #include <string.h> | ||
25 | #include <locale.h> | ||
26 | |||
27 | #include <g3d/types.h> | ||
28 | #include <g3d/stream.h> | ||
29 | #include <g3d/material.h> | ||
30 | #include <g3d/model.h> | ||
31 | #include <g3d/matrix.h> | ||
32 | |||
33 | #include "imp_dxf.h" | ||
34 | #include "imp_dxf_section.h" | ||
35 | #include "imp_dxf_def.h" | ||
36 | |||
37 | static void dxf_cleanup(DxfGlobalData *global); | ||
38 | |||
39 | EAPI | ||
40 | gboolean plugin_load_model_from_stream(G3DContext *context, G3DStream *stream, | ||
41 | G3DModel *model, gpointer user_data) | ||
42 | { | ||
43 | gchar binmagic[22]; | ||
44 | G3DObject *object; | ||
45 | G3DMaterial *material; | ||
46 | DxfGlobalData *global; | ||
47 | G3DMatrix rmatrix[16]; | ||
48 | |||
49 | global = g_new0(DxfGlobalData, 1); | ||
50 | global->context = context; | ||
51 | global->model = model; | ||
52 | global->stream = stream; | ||
53 | global->blocks = g_hash_table_new(g_str_hash, g_str_equal); | ||
54 | |||
55 | setlocale(LC_NUMERIC, "C"); | ||
56 | |||
57 | if((g3d_stream_read(stream, binmagic, 22) == 22) && | ||
58 | (strncmp(binmagic, "AutoCAD Binary DXF", 18) == 0)) | ||
59 | global->binary = TRUE; | ||
60 | else { | ||
61 | setlocale(LC_NUMERIC, "C"); | ||
62 | g3d_stream_seek(stream, 0, G_SEEK_SET); | ||
63 | } | ||
64 | |||
65 | object = g_new0(G3DObject, 1); | ||
66 | object->name = g_strdup("DXF Object"); | ||
67 | model->objects = g_slist_append(model->objects, object); | ||
68 | |||
69 | material = g3d_material_new(); | ||
70 | material->name = g_strdup("default material"); | ||
71 | material->flags |= G3D_FLAG_MAT_TWOSIDE; | ||
72 | object->materials = g_slist_append(object->materials, material); | ||
73 | |||
74 | while(!g3d_stream_eof(stream)) { | ||
75 | int retval = dxf_read_section(global, object); | ||
76 | if(retval != TRUE) { | ||
77 | if(retval == 0xE0F) { | ||
78 | g3d_matrix_identity(rmatrix); | ||
79 | g3d_matrix_rotate_xyz(G_PI * -90.0 / 180, 0.0, 0.0, rmatrix); | ||
80 | g3d_model_transform(model, rmatrix); | ||
81 | dxf_cleanup(global); | ||
82 | return TRUE; | ||
83 | } | ||
84 | g_printerr("error in section..\n"); | ||
85 | dxf_cleanup(global); | ||
86 | return FALSE; | ||
87 | } | ||
88 | } | ||
89 | |||
90 | g3d_matrix_identity(rmatrix); | ||
91 | g3d_matrix_rotate_xyz(G_PI * -90.0 / 180, 0.0, 0.0, rmatrix); | ||
92 | g3d_model_transform(model, rmatrix); | ||
93 | dxf_cleanup(global); | ||
94 | |||
95 | return TRUE; | ||
96 | } | ||
97 | |||
98 | EAPI | ||
99 | gchar *plugin_description(void) | ||
100 | { | ||
101 | return g_strdup("AutoCAD models."); | ||
102 | } | ||
103 | |||
104 | EAPI | ||
105 | gchar **plugin_extensions(void) | ||
106 | { | ||
107 | return g_strsplit("dxf", ":", 0); | ||
108 | } | ||
109 | |||
110 | /*****************************************************************************/ | ||
111 | |||
112 | static void dxf_cleanup(DxfGlobalData *global) | ||
113 | { | ||
114 | g_hash_table_destroy(global->blocks); | ||
115 | g_free(global); | ||
116 | } | ||
117 | |||
118 | gboolean dxf_read_section(DxfGlobalData *global, G3DObject *object) | ||
119 | { | ||
120 | gint grpcode; | ||
121 | gchar val_str[DXF_MAX_LINE + 1]; | ||
122 | |||
123 | grpcode = dxf_read_code(global); | ||
124 | if(grpcode != 0) { | ||
125 | #if DEBUG > 0 | ||
126 | g_printerr("unexpected group code: %d (0 expected)\n", grpcode); | ||
127 | #endif | ||
128 | return FALSE; | ||
129 | } | ||
130 | dxf_read_string(global, val_str); | ||
131 | if(strcmp("EOF", val_str) == 0) | ||
132 | return 0xE0F; | ||
133 | if(strcmp("SECTION", val_str) != 0) { | ||
134 | #if DEBUG > 0 | ||
135 | g_printerr("SECTION expected, found: %s\n", val_str); | ||
136 | #endif | ||
137 | return FALSE; | ||
138 | } | ||
139 | grpcode = dxf_read_code(global); | ||
140 | if(grpcode != 2) { | ||
141 | #if DEBUG > 0 | ||
142 | g_printerr("unexpected group code: %d (2 expected)\n", grpcode); | ||
143 | #endif | ||
144 | return FALSE; | ||
145 | } | ||
146 | dxf_read_string(global, val_str); | ||
147 | |||
148 | if(strcmp(val_str, "HEADER") == 0) | ||
149 | return dxf_section_HEADER(global); | ||
150 | else if(strcmp(val_str, "TABLES") == 0) | ||
151 | return dxf_section_TABLES(global); | ||
152 | else if(strcmp(val_str, "ENTITIES") == 0) | ||
153 | return dxf_section_ENTITIES(global); | ||
154 | else if(strcmp(val_str, "BLOCKS") == 0) | ||
155 | return dxf_section_BLOCKS(global); | ||
156 | else if(strcmp(val_str, "OBJECTS") == 0) | ||
157 | return dxf_section_OBJECTS(global); | ||
158 | else if(strcmp(val_str, "CLASSES") == 0) | ||
159 | return dxf_section_CLASSES(global); | ||
160 | else { | ||
161 | #if DEBUG > 0 | ||
162 | g_printerr("unknown section '%s', skipping...\n", val_str); | ||
163 | #endif | ||
164 | dxf_skip_section(global); | ||
165 | } | ||
166 | return TRUE; | ||
167 | } | ||
168 | |||
169 | gchar *dxf_read_string(DxfGlobalData *global, gchar *value) | ||
170 | { | ||
171 | if(global->binary) { | ||
172 | int pos = 0; | ||
173 | int c; | ||
174 | do | ||
175 | { | ||
176 | c = g3d_stream_read_int8(global->stream); | ||
177 | value[pos] = (char)c; | ||
178 | pos++; | ||
179 | } while(c != '\0'); | ||
180 | return value; | ||
181 | } else { | ||
182 | gchar line[DXF_MAX_LINE + 1]; | ||
183 | |||
184 | g3d_stream_read_line(global->stream, line, DXF_MAX_LINE); | ||
185 | line[DXF_MAX_LINE] = '\0'; | ||
186 | if(sscanf(line, "%s", value) == 1) | ||
187 | return g_strchomp(value); | ||
188 | if(sscanf(line, " %s", value) == 1) | ||
189 | return g_strchomp(value); | ||
190 | return NULL; | ||
191 | } | ||
192 | } | ||
193 | |||
194 | gint32 dxf_read_code(DxfGlobalData *global) | ||
195 | { | ||
196 | gint32 val = DXF_CODE_INVALID; | ||
197 | gchar line[DXF_MAX_LINE + 1]; | ||
198 | |||
199 | if(global->binary) | ||
200 | return g3d_stream_read_int8(global->stream); | ||
201 | else { | ||
202 | g3d_stream_read_line(global->stream, line, DXF_MAX_LINE); | ||
203 | if((sscanf(line, "%d", &val) != 1) && | ||
204 | (sscanf(line, " %d", &val) != 1)) | ||
205 | return DXF_CODE_INVALID; | ||
206 | if(val == 999) { /* comment */ | ||
207 | g3d_stream_read_line(global->stream, line, DXF_MAX_LINE); | ||
208 | return dxf_read_code(global); | ||
209 | } | ||
210 | return val; | ||
211 | } | ||
212 | } | ||
213 | |||
214 | gint32 dxf_read_int16(DxfGlobalData *global) | ||
215 | { | ||
216 | if(global->binary) | ||
217 | return g3d_stream_read_int16_le(global->stream); | ||
218 | else | ||
219 | { | ||
220 | gint32 val; | ||
221 | gchar line[DXF_MAX_LINE]; | ||
222 | |||
223 | g3d_stream_read_line(global->stream, line, DXF_MAX_LINE); | ||
224 | if(sscanf(line, "%i", &val) == 1) | ||
225 | return val; | ||
226 | if(sscanf(line, " %i", &val) == 1) | ||
227 | return val; | ||
228 | else | ||
229 | return DXF_CODE_INVALID; | ||
230 | } | ||
231 | } | ||
232 | |||
233 | gint32 dxf_read_int32(DxfGlobalData *global) | ||
234 | { | ||
235 | if(global->binary) | ||
236 | return g3d_stream_read_int32_le(global->stream); | ||
237 | else | ||
238 | { | ||
239 | gint32 val; | ||
240 | gchar line[DXF_MAX_LINE]; | ||
241 | |||
242 | g3d_stream_read_line(global->stream, line, DXF_MAX_LINE); | ||
243 | if(sscanf(line, "%i", &val) == 1) | ||
244 | return val; | ||
245 | if(sscanf(line, " %i", &val) == 1) | ||
246 | return val; | ||
247 | else | ||
248 | return DXF_CODE_INVALID; | ||
249 | } | ||
250 | } | ||
251 | |||
252 | gdouble dxf_read_float64(DxfGlobalData *global) | ||
253 | { | ||
254 | if(global->binary) | ||
255 | return g3d_stream_read_double_le(global->stream); | ||
256 | else | ||
257 | { | ||
258 | gdouble val; | ||
259 | gchar line[DXF_MAX_LINE]; | ||
260 | |||
261 | g3d_stream_read_line(global->stream, line, DXF_MAX_LINE); | ||
262 | if(sscanf(line, "%lf", &val) == 1) | ||
263 | return val; | ||
264 | if(sscanf(line, " %lf", &val) == 1) | ||
265 | return val; | ||
266 | else | ||
267 | return 0.0; | ||
268 | } | ||
269 | } | ||
270 | |||
271 | gboolean dxf_skip_section(DxfGlobalData *global) | ||
272 | { | ||
273 | gchar c, buf[7], line[DXF_MAX_LINE]; | ||
274 | gsize read; | ||
275 | |||
276 | while(!g3d_stream_eof(global->stream)) | ||
277 | if(global->binary) { | ||
278 | do { c = g3d_stream_read_int8(global->stream); } while(c != 0); | ||
279 | read = g3d_stream_read(global->stream, buf, 7); | ||
280 | if((read == 7) && (strncmp(buf, "ENDSEC", 6) == 0)) | ||
281 | return TRUE; | ||
282 | else | ||
283 | g3d_stream_seek(global->stream, -read, G_SEEK_CUR); | ||
284 | } else { | ||
285 | g3d_stream_read_line(global->stream, line, DXF_MAX_LINE); | ||
286 | if(strncmp(line, "ENDSEC", 6) == 0) | ||
287 | return TRUE; | ||
288 | } | ||
289 | return TRUE; | ||
290 | } | ||
291 | |||