aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/others/mimesh/libg3d-0.0.8/plugins/import/imp_dxf/imp_dxf_callbacks.c
diff options
context:
space:
mode:
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.c349
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
46static 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
59gboolean 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
123static 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
134gboolean 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
183gboolean 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
204gboolean dxf_e_ENDBLK(DxfGlobalData *global, DxfLocalData *local)
205{
206 local->edata->block = NULL;
207 return TRUE;
208}
209
210gboolean 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
262gboolean 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
302gboolean 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}