diff options
Diffstat (limited to 'src/others/mimesh/libg3d-0.0.8/plugins/import/imp_dxf/imp_dxf_callbacks.c')
-rw-r--r-- | src/others/mimesh/libg3d-0.0.8/plugins/import/imp_dxf/imp_dxf_callbacks.c | 349 |
1 files changed, 349 insertions, 0 deletions
diff --git a/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_dxf/imp_dxf_callbacks.c b/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_dxf/imp_dxf_callbacks.c new file mode 100644 index 0000000..c7a6e7c --- /dev/null +++ b/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_dxf/imp_dxf_callbacks.c | |||
@@ -0,0 +1,349 @@ | |||
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 <math.h> | ||
24 | |||
25 | /* need a way to detect non-set float values */ | ||
26 | #ifndef FP_NAN | ||
27 | # ifdef HUGE | ||
28 | # define FP_NAN HUGE | ||
29 | # else | ||
30 | # define FP_NAN 3.40282347e+38F | ||
31 | # endif | ||
32 | #endif | ||
33 | |||
34 | #include <g3d/face.h> | ||
35 | #include <g3d/object.h> | ||
36 | #include <g3d/matrix.h> | ||
37 | #include <g3d/primitive.h> | ||
38 | |||
39 | #include "imp_dxf.h" | ||
40 | #include "imp_dxf_callbacks.h" | ||
41 | #include "imp_dxf_vars.h" | ||
42 | #include "imp_dxf_def.h" | ||
43 | #include "imp_dxf_prop.h" | ||
44 | #include "imp_dxf_color.h" | ||
45 | |||
46 | static gboolean dxf_str_in_array(gchar **array, const gchar *needle) | ||
47 | { | ||
48 | gchar **p = array; | ||
49 | while(*p != NULL) { | ||
50 | if(strcmp(*p, needle) == 0) | ||
51 | return TRUE; | ||
52 | p ++; | ||
53 | } | ||
54 | return FALSE; | ||
55 | } | ||
56 | |||
57 | #define DXF_VAR_DEBUG 2 | ||
58 | |||
59 | gboolean dxf_debug_var(DxfGlobalData *global, DxfLocalData *local) | ||
60 | { | ||
61 | gint32 key; | ||
62 | gint16 i16; | ||
63 | gchar str[DXF_MAX_LINE + 1], strval[DXF_MAX_LINE + 1]; | ||
64 | gdouble x, y, z; | ||
65 | |||
66 | dxf_read_string(global, str); | ||
67 | if(dxf_str_in_array(dxf_vars_vector3d, str)) { | ||
68 | key = dxf_read_code(global); /* 10 */ | ||
69 | x = dxf_read_float64(global); | ||
70 | key = dxf_read_code(global); /* 20 */ | ||
71 | y = dxf_read_float64(global); | ||
72 | key = dxf_read_code(global); /* 30 */ | ||
73 | z = dxf_read_float64(global); | ||
74 | #if DEBUG > DXF_VAR_DEBUG | ||
75 | g_debug("DXF: [v3d] %s: %.2f, %.2f, %.2f", str, x, y, z); | ||
76 | #endif | ||
77 | } else if(dxf_str_in_array(dxf_vars_vector2d, str)) { | ||
78 | key = dxf_read_code(global); /* 10 */ | ||
79 | x = dxf_read_float64(global); | ||
80 | key = dxf_read_code(global); /* 20 */ | ||
81 | y = dxf_read_float64(global); | ||
82 | #if DEBUG > DXF_VAR_DEBUG | ||
83 | g_debug("DXF: [v2d] %s: %.2f, %.2f", str, x, y); | ||
84 | #endif | ||
85 | } else { | ||
86 | key = dxf_read_code(global); | ||
87 | switch(key) { | ||
88 | case 1: case 2: case 3: case 4: | ||
89 | case 5: case 6: case 7: case 8: | ||
90 | /* string */ | ||
91 | dxf_read_string(global, strval); | ||
92 | #if DEBUG > DXF_VAR_DEBUG | ||
93 | g_debug("DXF: [str] %s: %s", str, strval); | ||
94 | #endif | ||
95 | break; | ||
96 | case 40: | ||
97 | case 50: | ||
98 | x = dxf_read_float64(global); | ||
99 | #if DEBUG > DXF_VAR_DEBUG | ||
100 | g_debug("DXF: [dbl] %s: %.2f", str, x); | ||
101 | #endif | ||
102 | break; | ||
103 | case 62: | ||
104 | case 70: | ||
105 | case 280: | ||
106 | case 290: /* FIXME: boolean */ | ||
107 | case 370: | ||
108 | case 380: | ||
109 | /* 16-bit integer */ | ||
110 | i16 = dxf_read_int16(global); | ||
111 | #if DEBUG > DXF_VAR_DEBUG | ||
112 | g_debug("DXF: [i16] %s: %d", str, i16); | ||
113 | #endif | ||
114 | break; | ||
115 | default: | ||
116 | DXF_HANDLE_UNKNOWN(global, key, strval, "** VARIABLE **"); | ||
117 | break; | ||
118 | } | ||
119 | } | ||
120 | return TRUE; | ||
121 | } | ||
122 | |||
123 | static inline void dxf_object_append(DxfGlobalData *global, | ||
124 | DxfLocalData *local, G3DObject *object) | ||
125 | { | ||
126 | if(local->edata->block) | ||
127 | local->edata->block->objects = g_slist_append( | ||
128 | local->edata->block->objects, object); | ||
129 | else | ||
130 | global->model->objects = g_slist_append(global->model->objects, | ||
131 | object); | ||
132 | } | ||
133 | |||
134 | gboolean dxf_e_3DFACE(DxfGlobalData *global, DxfLocalData *local) | ||
135 | { | ||
136 | G3DObject *object; | ||
137 | G3DFace *face; | ||
138 | G3DMaterial *material; | ||
139 | gint32 key, i, j, col; | ||
140 | gboolean quad; | ||
141 | |||
142 | col = dxf_prop_get_int(local->eprop, 62, 254); | ||
143 | material = dxf_color_get_material(global->model, col); | ||
144 | if(material == NULL) | ||
145 | material = local->edata->material; | ||
146 | |||
147 | object = g_slist_nth_data(global->model->objects, 0); | ||
148 | local->edata->object = object; | ||
149 | local->edata->polyline_flags = 0; | ||
150 | |||
151 | quad = (dxf_prop_get_dbl(local->eprop, 13, FP_NAN) != FP_NAN); | ||
152 | |||
153 | face = g_new0(G3DFace, 1); | ||
154 | face->material = material; | ||
155 | face->vertex_count = quad ? 4 : 3; | ||
156 | face->vertex_indices = g_new0(guint32, face->vertex_count); | ||
157 | local->edata->vertex_offset = object->vertex_count; | ||
158 | for(i = 0; i < face->vertex_count; i ++) | ||
159 | face->vertex_indices[i] = local->edata->vertex_offset + i; | ||
160 | |||
161 | object->vertex_count += face->vertex_count; | ||
162 | object->vertex_data = g_realloc(object->vertex_data, | ||
163 | object->vertex_count * 3 * sizeof(G3DFloat)); | ||
164 | object->faces = g_slist_prepend(object->faces, face); | ||
165 | |||
166 | for(i = 0; i < face->vertex_count; i ++) { | ||
167 | for(j = 0; j < 3; j ++) { | ||
168 | key = (j + 1) * 10 + i; | ||
169 | object->vertex_data[(local->edata->vertex_offset + i) * 3 + j] = | ||
170 | dxf_prop_get_dbl(local->eprop, key, 0.0); | ||
171 | #if DEBUG > 2 | ||
172 | g_debug("| 3DFACE: data[%d = o + %d * 3 + %d] = prop[%d] = %.2f", | ||
173 | (local->edata->vertex_offset + i) * 3 + j, | ||
174 | i, j, key, | ||
175 | object->vertex_data[ | ||
176 | (local->edata->vertex_offset + i) * 3 + j]); | ||
177 | #endif | ||
178 | } | ||
179 | } | ||
180 | return TRUE; | ||
181 | } | ||
182 | |||
183 | gboolean dxf_e_BLOCK(DxfGlobalData *global, DxfLocalData *local) | ||
184 | { | ||
185 | G3DObject *object; | ||
186 | const gchar *name; | ||
187 | |||
188 | name = dxf_prop_get_str(local->eprop, 2, NULL); | ||
189 | if(local->sid == DXF_ID_BLOCKS) { | ||
190 | object = g_new0(G3DObject, 1); | ||
191 | object->hide = TRUE; | ||
192 | object->name = name ? g_strdup(name) : | ||
193 | g_strdup_printf("unnamed block @ line %d", | ||
194 | g3d_stream_line(global->stream)); | ||
195 | local->edata->block = object; | ||
196 | global->model->objects = g_slist_append(global->model->objects, | ||
197 | object); | ||
198 | if(name) | ||
199 | g_hash_table_insert(global->blocks, object->name, object); | ||
200 | } | ||
201 | return TRUE; | ||
202 | } | ||
203 | |||
204 | gboolean dxf_e_ENDBLK(DxfGlobalData *global, DxfLocalData *local) | ||
205 | { | ||
206 | local->edata->block = NULL; | ||
207 | return TRUE; | ||
208 | } | ||
209 | |||
210 | gboolean dxf_e_INSERT(DxfGlobalData *global, DxfLocalData *local) | ||
211 | { | ||
212 | G3DObject *block, *object, *subobject; | ||
213 | GSList *item; | ||
214 | const gchar *name; | ||
215 | G3DFloat matrix[16]; | ||
216 | |||
217 | name = dxf_prop_get_str(local->eprop, 2, "*** error ***"); | ||
218 | block = g_hash_table_lookup(global->blocks, name); | ||
219 | if(block) { | ||
220 | object = g_new0(G3DObject, 1); | ||
221 | object->name = g_strdup_printf("copy of %s", name); | ||
222 | for(item = block->objects; item != NULL; item = item->next) { | ||
223 | subobject = g3d_object_duplicate(item->data); | ||
224 | object->objects = g_slist_append(object->objects, subobject); | ||
225 | } | ||
226 | global->model->objects = g_slist_append(global->model->objects, | ||
227 | object); | ||
228 | local->edata->object = object; | ||
229 | local->edata->vertex_offset = 0; | ||
230 | |||
231 | /* scale */ | ||
232 | g3d_matrix_identity(matrix); | ||
233 | g3d_matrix_scale( | ||
234 | dxf_prop_get_dbl(local->eprop, 41, 1.0), | ||
235 | dxf_prop_get_dbl(local->eprop, 42, 1.0), | ||
236 | dxf_prop_get_dbl(local->eprop, 43, 1.0), | ||
237 | matrix); | ||
238 | g3d_object_transform(object, matrix); | ||
239 | |||
240 | /* rotate */ | ||
241 | g3d_matrix_identity(matrix); | ||
242 | g3d_matrix_rotate( | ||
243 | dxf_prop_get_dbl(local->eprop, 50, 0.0), | ||
244 | dxf_prop_get_dbl(local->eprop, 210, 0.0), | ||
245 | dxf_prop_get_dbl(local->eprop, 220, 0.0), | ||
246 | dxf_prop_get_dbl(local->eprop, 230, 1.0), | ||
247 | matrix); | ||
248 | g3d_object_transform(object, matrix); | ||
249 | |||
250 | /* translate */ | ||
251 | g3d_matrix_identity(matrix); | ||
252 | g3d_matrix_translate( | ||
253 | dxf_prop_get_dbl(local->eprop, 10, 0.0), | ||
254 | dxf_prop_get_dbl(local->eprop, 20, 0.0), | ||
255 | dxf_prop_get_dbl(local->eprop, 30, 0.0), | ||
256 | matrix); | ||
257 | g3d_object_transform(object, matrix); | ||
258 | } | ||
259 | return TRUE; | ||
260 | } | ||
261 | |||
262 | gboolean dxf_e_POLYLINE(DxfGlobalData *global, DxfLocalData *local) | ||
263 | { | ||
264 | G3DObject *object = NULL; | ||
265 | G3DMaterial *material; | ||
266 | guint32 flags; | ||
267 | gint32 m, n, col; | ||
268 | |||
269 | col = dxf_prop_get_int(local->eprop, 62, 254); | ||
270 | material = dxf_color_get_material(global->model, col); | ||
271 | if(material == NULL) | ||
272 | material = local->edata->material; | ||
273 | |||
274 | flags = dxf_prop_get_int(local->eprop, 70, 0); | ||
275 | if(flags & DXF_POLY_POLYFACE) { | ||
276 | object = g_new0(G3DObject, 1); | ||
277 | object->name = g_strdup_printf("POLYFACE @ line %d", | ||
278 | g3d_stream_line(global->stream)); | ||
279 | object->vertex_count = dxf_prop_get_int(local->eprop, 71, 0); | ||
280 | object->vertex_data = g_new0(G3DFloat, 3 * object->vertex_count); | ||
281 | } else if(flags & DXF_POLY_3D_POLYMESH) { | ||
282 | m = dxf_prop_get_int(local->eprop, 71, 0); | ||
283 | n = dxf_prop_get_int(local->eprop, 72, 0); | ||
284 | object = g3d_primitive_mesh(n, m, | ||
285 | (flags & DXF_POLY_CLOSED), | ||
286 | (flags & DXF_POLY_N_CLOSED), | ||
287 | material); | ||
288 | object->name = g_strdup_printf("3D POLYMESH %d x %d @ line %d", | ||
289 | m, n, g3d_stream_line(global->stream)); | ||
290 | } | ||
291 | |||
292 | if(object) | ||
293 | dxf_object_append(global, local, object); | ||
294 | |||
295 | local->edata->object = object; | ||
296 | local->edata->vertex_offset = 0; | ||
297 | local->edata->polyline_flags = flags; | ||
298 | local->edata->tmp_i1 = 0; | ||
299 | return TRUE; | ||
300 | } | ||
301 | |||
302 | gboolean dxf_e_VERTEX(DxfGlobalData *global, DxfLocalData *local) | ||
303 | { | ||
304 | G3DObject *object = local->edata->object; | ||
305 | G3DFace *face; | ||
306 | G3DMaterial *material; | ||
307 | guint32 index, flags; | ||
308 | gint32 i, col; | ||
309 | |||
310 | if(object == NULL) | ||
311 | return TRUE; | ||
312 | |||
313 | index = local->edata->vertex_offset + local->edata->tmp_i1; | ||
314 | |||
315 | if(local->edata->polyline_flags & DXF_POLY_3D_POLYMESH) { | ||
316 | g_return_val_if_fail(index < object->vertex_count, FALSE); | ||
317 | for(i = 0; i < 3; i ++) | ||
318 | object->vertex_data[index * 3 + i] = dxf_prop_get_dbl(local->eprop, | ||
319 | 10 * (i + 1), 0.0); | ||
320 | local->edata->tmp_i1 ++; | ||
321 | } else if(local->edata->polyline_flags & DXF_POLY_POLYFACE) { | ||
322 | flags = dxf_prop_get_int(local->eprop, 70, 0); | ||
323 | if(flags & 64) { /* vertex coords */ | ||
324 | g_return_val_if_fail(index < object->vertex_count, FALSE); | ||
325 | for(i = 0; i < 3; i ++) | ||
326 | object->vertex_data[index * 3 + i] = dxf_prop_get_dbl( | ||
327 | local->eprop, 10 * (i + 1), 0.0); | ||
328 | local->edata->tmp_i1 ++; | ||
329 | } | ||
330 | if(flags & 128) { | ||
331 | col = dxf_prop_get_int(local->eprop, 62, 254); | ||
332 | material = dxf_color_get_material(global->model, col); | ||
333 | if(material == NULL) | ||
334 | material = local->edata->material; | ||
335 | |||
336 | face = g_new0(G3DFace, 1); | ||
337 | face->material = material; | ||
338 | face->vertex_count = | ||
339 | dxf_prop_get_int(local->eprop, 74, 0) ? 4 : 3; | ||
340 | face->vertex_indices = g_new0(guint32, face->vertex_count); | ||
341 | for(i = 0; i < face->vertex_count; i ++) | ||
342 | face->vertex_indices[i] = | ||
343 | MAX(ABS(dxf_prop_get_int(local->eprop, 71 + i, 0)) - 1, 0); | ||
344 | object->faces = g_slist_prepend(object->faces, face); | ||
345 | } | ||
346 | } | ||
347 | |||
348 | return TRUE; | ||
349 | } | ||