]> git.saurik.com Git - wxWidgets.git/blob - samples/opengl/penguin/dxfrenderer.cpp
applied patch #1356901 "Yet another removal of extra semicolons", also fixed remainin...
[wxWidgets.git] / samples / opengl / penguin / dxfrenderer.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: dxfrenderer.cpp
3 // Purpose: DXF reader and renderer
4 // Author: Sandro Sigala
5 // Modified by:
6 // Created: 2005-11-10
7 // RCS-ID: $Id$
8 // Copyright: (c) Sandro Sigala
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // For compilers that support precompilation, includes "wx/wx.h".
13 #include "wx/wxprec.h"
14
15 #ifdef __BORLANDC__
16 #pragma hdrstop
17 #endif
18
19 #ifndef WX_PRECOMP
20 #include "wx/wx.h"
21 #endif
22
23 #include "wx/wfstream.h"
24 #include "wx/txtstrm.h"
25
26 #if !wxUSE_GLCANVAS
27 #error "OpenGL required: set wxUSE_GLCANVAS to 1 and rebuild the library"
28 #endif
29
30 #ifdef __WXMAC__
31 # ifdef __DARWIN__
32 # include <OpenGL/glu.h>
33 # else
34 # include <glu.h>
35 # endif
36 #else
37 # include <GL/glu.h>
38 #endif
39
40 #include "dxfrenderer.h"
41
42 #include <wx/listimpl.cpp>
43 WX_DEFINE_LIST(DXFEntityList)
44 WX_DEFINE_LIST(DXFLayerList)
45
46 // Conversion table from AutoCAD ACI colours to RGB values
47 static const struct { unsigned char r, g, b; } aci_to_rgb[256] = {
48 /* 0 */ 255, 255, 255,
49 /* 1 */ 255, 0, 0,
50 /* 2 */ 255, 255, 0,
51 /* 3 */ 0, 255, 0,
52 /* 4 */ 0, 255, 255,
53 /* 5 */ 0, 0, 255,
54 /* 6 */ 255, 0, 255,
55 /* 7 */ 255, 255, 255,
56 /* 8 */ 128, 128, 128,
57 /* 9 */ 192, 192, 192,
58 /* 10 */ 255, 0, 0,
59 /* 11 */ 255, 127, 127,
60 /* 12 */ 204, 0, 0,
61 /* 13 */ 204, 102, 102,
62 /* 14 */ 153, 0, 0,
63 /* 15 */ 153, 76, 76,
64 /* 16 */ 127, 0, 0,
65 /* 17 */ 127, 63, 63,
66 /* 18 */ 76, 0, 0,
67 /* 19 */ 76, 38, 38,
68 /* 20 */ 255, 63, 0,
69 /* 21 */ 255, 159, 127,
70 /* 22 */ 204, 51, 0,
71 /* 23 */ 204, 127, 102,
72 /* 24 */ 153, 38, 0,
73 /* 25 */ 153, 95, 76,
74 /* 26 */ 127, 31, 0,
75 /* 27 */ 127, 79, 63,
76 /* 28 */ 76, 19, 0,
77 /* 29 */ 76, 47, 38,
78 /* 30 */ 255, 127, 0,
79 /* 31 */ 255, 191, 127,
80 /* 32 */ 204, 102, 0,
81 /* 33 */ 204, 153, 102,
82 /* 34 */ 153, 76, 0,
83 /* 35 */ 153, 114, 76,
84 /* 36 */ 127, 63, 0,
85 /* 37 */ 127, 95, 63,
86 /* 38 */ 76, 38, 0,
87 /* 39 */ 76, 57, 38,
88 /* 40 */ 255, 191, 0,
89 /* 41 */ 255, 223, 127,
90 /* 42 */ 204, 153, 0,
91 /* 43 */ 204, 178, 102,
92 /* 44 */ 153, 114, 0,
93 /* 45 */ 153, 133, 76,
94 /* 46 */ 127, 95, 0,
95 /* 47 */ 127, 111, 63,
96 /* 48 */ 76, 57, 0,
97 /* 49 */ 76, 66, 38,
98 /* 50 */ 255, 255, 0,
99 /* 51 */ 255, 255, 127,
100 /* 52 */ 204, 204, 0,
101 /* 53 */ 204, 204, 102,
102 /* 54 */ 153, 153, 0,
103 /* 55 */ 153, 153, 76,
104 /* 56 */ 127, 127, 0,
105 /* 57 */ 127, 127, 63,
106 /* 58 */ 76, 76, 0,
107 /* 59 */ 76, 76, 38,
108 /* 60 */ 191, 255, 0,
109 /* 61 */ 223, 255, 127,
110 /* 62 */ 153, 204, 0,
111 /* 63 */ 178, 204, 102,
112 /* 64 */ 114, 153, 0,
113 /* 65 */ 133, 153, 76,
114 /* 66 */ 95, 127, 0,
115 /* 67 */ 111, 127, 63,
116 /* 68 */ 57, 76, 0,
117 /* 69 */ 66, 76, 38,
118 /* 70 */ 127, 255, 0,
119 /* 71 */ 191, 255, 127,
120 /* 72 */ 102, 204, 0,
121 /* 73 */ 153, 204, 102,
122 /* 74 */ 76, 153, 0,
123 /* 75 */ 114, 153, 76,
124 /* 76 */ 63, 127, 0,
125 /* 77 */ 95, 127, 63,
126 /* 78 */ 38, 76, 0,
127 /* 79 */ 57, 76, 38,
128 /* 80 */ 63, 255, 0,
129 /* 81 */ 159, 255, 127,
130 /* 82 */ 51, 204, 0,
131 /* 83 */ 127, 204, 102,
132 /* 84 */ 38, 153, 0,
133 /* 85 */ 95, 153, 76,
134 /* 86 */ 31, 127, 0,
135 /* 87 */ 79, 127, 63,
136 /* 88 */ 19, 76, 0,
137 /* 89 */ 47, 76, 38,
138 /* 90 */ 0, 255, 0,
139 /* 91 */ 127, 255, 127,
140 /* 92 */ 0, 204, 0,
141 /* 93 */ 102, 204, 102,
142 /* 94 */ 0, 153, 0,
143 /* 95 */ 76, 153, 76,
144 /* 96 */ 0, 127, 0,
145 /* 97 */ 63, 127, 63,
146 /* 98 */ 0, 76, 0,
147 /* 99 */ 38, 76, 38,
148 /* 100 */ 0, 255, 63,
149 /* 101 */ 127, 255, 159,
150 /* 102 */ 0, 204, 51,
151 /* 103 */ 102, 204, 127,
152 /* 104 */ 0, 153, 38,
153 /* 105 */ 76, 153, 95,
154 /* 106 */ 0, 127, 31,
155 /* 107 */ 63, 127, 79,
156 /* 108 */ 0, 76, 19,
157 /* 109 */ 38, 76, 47,
158 /* 110 */ 0, 255, 127,
159 /* 111 */ 127, 255, 191,
160 /* 112 */ 0, 204, 102,
161 /* 113 */ 102, 204, 153,
162 /* 114 */ 0, 153, 76,
163 /* 115 */ 76, 153, 114,
164 /* 116 */ 0, 127, 63,
165 /* 117 */ 63, 127, 95,
166 /* 118 */ 0, 76, 38,
167 /* 119 */ 38, 76, 57,
168 /* 120 */ 0, 255, 191,
169 /* 121 */ 127, 255, 223,
170 /* 122 */ 0, 204, 153,
171 /* 123 */ 102, 204, 178,
172 /* 124 */ 0, 153, 114,
173 /* 125 */ 76, 153, 133,
174 /* 126 */ 0, 127, 95,
175 /* 127 */ 63, 127, 111,
176 /* 128 */ 0, 76, 57,
177 /* 129 */ 38, 76, 66,
178 /* 130 */ 0, 255, 255,
179 /* 131 */ 127, 255, 255,
180 /* 132 */ 0, 204, 204,
181 /* 133 */ 102, 204, 204,
182 /* 134 */ 0, 153, 153,
183 /* 135 */ 76, 153, 153,
184 /* 136 */ 0, 127, 127,
185 /* 137 */ 63, 127, 127,
186 /* 138 */ 0, 76, 76,
187 /* 139 */ 38, 76, 76,
188 /* 140 */ 0, 191, 255,
189 /* 141 */ 127, 223, 255,
190 /* 142 */ 0, 153, 204,
191 /* 143 */ 102, 178, 204,
192 /* 144 */ 0, 114, 153,
193 /* 145 */ 76, 133, 153,
194 /* 146 */ 0, 95, 127,
195 /* 147 */ 63, 111, 127,
196 /* 148 */ 0, 57, 76,
197 /* 149 */ 38, 66, 76,
198 /* 150 */ 0, 127, 255,
199 /* 151 */ 127, 191, 255,
200 /* 152 */ 0, 102, 204,
201 /* 153 */ 102, 153, 204,
202 /* 154 */ 0, 76, 153,
203 /* 155 */ 76, 114, 153,
204 /* 156 */ 0, 63, 127,
205 /* 157 */ 63, 95, 127,
206 /* 158 */ 0, 38, 76,
207 /* 159 */ 38, 57, 76,
208 /* 160 */ 0, 63, 255,
209 /* 161 */ 127, 159, 255,
210 /* 162 */ 0, 51, 204,
211 /* 163 */ 102, 127, 204,
212 /* 164 */ 0, 38, 153,
213 /* 165 */ 76, 95, 153,
214 /* 166 */ 0, 31, 127,
215 /* 167 */ 63, 79, 127,
216 /* 168 */ 0, 19, 76,
217 /* 169 */ 38, 47, 76,
218 /* 170 */ 0, 0, 255,
219 /* 171 */ 127, 127, 255,
220 /* 172 */ 0, 0, 204,
221 /* 173 */ 102, 102, 204,
222 /* 174 */ 0, 0, 153,
223 /* 175 */ 76, 76, 153,
224 /* 176 */ 0, 0, 127,
225 /* 177 */ 63, 63, 127,
226 /* 178 */ 0, 0, 76,
227 /* 179 */ 38, 38, 76,
228 /* 180 */ 63, 0, 255,
229 /* 181 */ 159, 127, 255,
230 /* 182 */ 51, 0, 204,
231 /* 183 */ 127, 102, 204,
232 /* 184 */ 38, 0, 153,
233 /* 185 */ 95, 76, 153,
234 /* 186 */ 31, 0, 127,
235 /* 187 */ 79, 63, 127,
236 /* 188 */ 19, 0, 76,
237 /* 189 */ 47, 38, 76,
238 /* 190 */ 127, 0, 255,
239 /* 191 */ 191, 127, 255,
240 /* 192 */ 102, 0, 204,
241 /* 193 */ 153, 102, 204,
242 /* 194 */ 76, 0, 153,
243 /* 195 */ 114, 76, 153,
244 /* 196 */ 63, 0, 127,
245 /* 197 */ 95, 63, 127,
246 /* 198 */ 38, 0, 76,
247 /* 199 */ 57, 38, 76,
248 /* 200 */ 191, 0, 255,
249 /* 201 */ 223, 127, 255,
250 /* 202 */ 153, 0, 204,
251 /* 203 */ 178, 102, 204,
252 /* 204 */ 114, 0, 153,
253 /* 205 */ 133, 76, 153,
254 /* 206 */ 95, 0, 127,
255 /* 207 */ 111, 63, 127,
256 /* 208 */ 57, 0, 76,
257 /* 209 */ 66, 38, 76,
258 /* 210 */ 255, 0, 255,
259 /* 211 */ 255, 127, 255,
260 /* 212 */ 204, 0, 204,
261 /* 213 */ 204, 102, 204,
262 /* 214 */ 153, 0, 153,
263 /* 215 */ 153, 76, 153,
264 /* 216 */ 127, 0, 127,
265 /* 217 */ 127, 63, 127,
266 /* 218 */ 76, 0, 76,
267 /* 219 */ 76, 38, 76,
268 /* 220 */ 255, 0, 191,
269 /* 221 */ 255, 127, 223,
270 /* 222 */ 204, 0, 153,
271 /* 223 */ 204, 102, 178,
272 /* 224 */ 153, 0, 114,
273 /* 225 */ 153, 76, 133,
274 /* 226 */ 127, 0, 95,
275 /* 227 */ 127, 63, 111,
276 /* 228 */ 76, 0, 57,
277 /* 229 */ 76, 38, 66,
278 /* 230 */ 255, 0, 127,
279 /* 231 */ 255, 127, 191,
280 /* 232 */ 204, 0, 102,
281 /* 233 */ 204, 102, 153,
282 /* 234 */ 153, 0, 76,
283 /* 235 */ 153, 76, 114,
284 /* 236 */ 127, 0, 63,
285 /* 237 */ 127, 63, 95,
286 /* 238 */ 76, 0, 38,
287 /* 239 */ 76, 38, 57,
288 /* 240 */ 255, 0, 63,
289 /* 241 */ 255, 127, 159,
290 /* 242 */ 204, 0, 51,
291 /* 243 */ 204, 102, 127,
292 /* 244 */ 153, 0, 38,
293 /* 245 */ 153, 76, 95,
294 /* 246 */ 127, 0, 31,
295 /* 247 */ 127, 63, 79,
296 /* 248 */ 76, 0, 19,
297 /* 249 */ 76, 38, 47,
298 /* 250 */ 51, 51, 51,
299 /* 251 */ 91, 91, 91,
300 /* 252 */ 132, 132, 132,
301 /* 253 */ 173, 173, 173,
302 /* 254 */ 214, 214, 214,
303 /* 255 */ 255, 255, 255,
304 };
305
306 inline DXFVector Cross(const DXFVector& v1, const DXFVector& v2)
307 {
308 return DXFVector(v1.y*v2.z - v1.z*v2.y, v1.z*v2.x - v1.x*v2.z, v1.x*v2.y - v1.y*v2.x);
309 }
310
311 void DXFFace::CalculateNormal()
312 {
313 DXFVector v01, v02;
314 v01.x = v0.x - v1.x;
315 v01.y = v0.y - v1.y;
316 v01.z = v0.z - v1.z;
317 v02.x = v0.x - v2.x;
318 v02.y = v0.y - v2.y;
319 v02.z = v0.z - v2.z;
320 n = Cross(v01, v02);
321 float mod = sqrt(n.x*n.x + n.y*n.y + n.z*n.z);
322 n.x /= mod;
323 n.y /= mod;
324 n.z /= mod;
325 }
326
327 // convert an AutoCAD ACI colour to wxWidgets RGB colour
328 inline wxColour ACIColourToRGB(int col)
329 {
330 wxASSERT(col >= 0 && col <= 255);
331 return wxColour(aci_to_rgb[col].r, aci_to_rgb[col].g, aci_to_rgb[col].b);
332 }
333
334 // DXFReader constructor
335 DXFRenderer::DXFRenderer()
336 {
337 m_loaded = false;
338 }
339
340 // DXFReader destructor
341 DXFRenderer::~DXFRenderer()
342 {
343 Clear();
344 }
345
346 // deallocate all the dynamic data
347 void DXFRenderer::Clear()
348 {
349 m_loaded = false;
350 {
351 for (DXFLayerList::Node *node = m_layers.GetFirst(); node; node = node->GetNext())
352 {
353 DXFLayer *current = node->GetData();
354 delete current;
355 }
356 }
357 m_layers.Clear();
358 {
359 for (DXFEntityList::Node *node = m_entities.GetFirst(); node; node = node->GetNext())
360 {
361 DXFEntity *current = node->GetData();
362 delete current;
363 }
364 m_entities.Clear();
365 }
366 }
367
368 int DXFRenderer::GetLayerColour(const wxString& layer) const
369 {
370 for (DXFLayerList::Node *node = m_layers.GetFirst(); node; node = node->GetNext())
371 {
372 DXFLayer *current = node->GetData();
373 if (current->name == layer)
374 return current->colour;
375 }
376 return 7; // white
377 }
378
379 // read two sequential lines
380 inline void GetLines(wxTextInputStream& text, wxString& line1, wxString& line2)
381 {
382 line1 = text.ReadLine().Trim().Trim(false);
383 line2 = text.ReadLine().Trim().Trim(false);
384 }
385
386 // parse header section: just skip everything
387 bool DXFRenderer::ParseHeader(wxInputStream& stream)
388 {
389 wxTextInputStream text(stream);
390 wxString line1, line2;
391 while (stream.CanRead())
392 {
393 GetLines(text, line1, line2);
394 if (line1 == wxT("0") && line2 == wxT("ENDSEC"))
395 return true;
396 }
397 return false;
398 }
399
400 // parse tables section: save layers name and colour
401 bool DXFRenderer::ParseTables(wxInputStream& stream)
402 {
403 wxTextInputStream text(stream);
404 wxString line1, line2;
405 bool inlayer=false;
406 DXFLayer layer;
407 while (stream.CanRead())
408 {
409 GetLines(text, line1, line2);
410 if (line1 == wxT("0") && inlayer)
411 {
412 // flush layer
413 if (!layer.name.IsEmpty() && layer.colour != -1)
414 {
415 DXFLayer *p = new DXFLayer;
416 p->name = layer.name;
417 p->colour = layer.colour;
418 m_layers.Append(p);
419 }
420 layer = DXFLayer();
421 inlayer = false;
422 }
423 if (line1 == wxT("0") && line2 == wxT("ENDSEC"))
424 return true;
425 else if (line1 == wxT("0") && line2 == wxT("LAYER"))
426 inlayer = true;
427 else if (inlayer)
428 {
429 if (line1 == wxT("2")) // layer name
430 layer.name = line2;
431 else if (line1 == wxT("62")) // ACI colour
432 {
433 long l;
434 line2.ToLong(&l);
435 layer.colour = l;
436 }
437 }
438 }
439 return false;
440 }
441
442 // parse entities section: save 3DFACE and LINE entities
443 bool DXFRenderer::ParseEntities(wxInputStream& stream)
444 {
445 wxTextInputStream text(stream);
446 wxString line1, line2;
447 int state = 0; // 0: none, 1: 3DFACE, 2: LINE
448 DXFVector v[4];
449 int colour = -1;
450 wxString layer;
451 while (stream.CanRead())
452 {
453 GetLines(text, line1, line2);
454 if (line1 == wxT("0") && state > 0)
455 {
456 // flush entity
457 if (state == 1) // 3DFACE
458 {
459 DXFFace *p = new DXFFace;
460 p->v0 = v[0];
461 p->v1 = v[1];
462 p->v2 = v[2];
463 p->v3 = v[3];
464 p->CalculateNormal();
465 if (colour != -1)
466 p->colour = colour;
467 else
468 p->colour = GetLayerColour(layer);
469 m_entities.Append(p);
470 colour = -1; layer = wxEmptyString;
471 v[0] = v[1] = v[2] = v[3] = DXFVector();
472 state = 0;
473 }
474 else if (state == 2) // LINE
475 {
476 DXFLine *p = new DXFLine;
477 p->v0 = v[0];
478 p->v1 = v[1];
479 if (colour != -1)
480 p->colour = colour;
481 else
482 p->colour = GetLayerColour(layer);
483 m_entities.Append(p);
484 colour = -1; layer = wxEmptyString;
485 v[0] = v[1] = v[2] = v[3] = DXFVector();
486 state = 0;
487 }
488 }
489 if (line1 == wxT("0") && line2 == wxT("ENDSEC"))
490 return true;
491 else if (line1 == wxT("0") && line2 == wxT("3DFACE"))
492 state = 1;
493 else if (line1 == wxT("0") && line2 == wxT("LINE"))
494 state = 2;
495 else if (state > 0)
496 {
497 double d;
498 line2.ToDouble(&d);
499 if (line1 == wxT("10"))
500 v[0].x = d;
501 else if (line1 == wxT("20"))
502 v[0].y = d;
503 else if (line1 == wxT("30"))
504 v[0].z = d;
505 else if (line1 == wxT("11"))
506 v[1].x = d;
507 else if (line1 == wxT("21"))
508 v[1].y = d;
509 else if (line1 == wxT("31"))
510 v[1].z = d;
511 else if (line1 == wxT("12"))
512 v[2].x = d;
513 else if (line1 == wxT("22"))
514 v[2].y = d;
515 else if (line1 == wxT("32"))
516 v[2].z = d;
517 else if (line1 == wxT("13"))
518 v[3].x = d;
519 else if (line1 == wxT("23"))
520 v[3].y = d;
521 else if (line1 == wxT("33"))
522 v[3].z = d;
523 else if (line1 == wxT("8")) // layer
524 layer = line2;
525 else if (line1 == wxT("62")) // colour
526 {
527 long l;
528 line2.ToLong(&l);
529 colour = l;
530 }
531 }
532 }
533 return false;
534 }
535
536 // parse and load a DXF file
537 // currently pretty limited, but knows enought do handle 3DFACEs and LINEs
538 bool DXFRenderer::Load(wxInputStream& stream)
539 {
540 Clear();
541 wxTextInputStream text(stream);
542
543 wxString line1, line2;
544 while (stream.CanRead())
545 {
546 GetLines(text, line1, line2);
547 if (line1 == wxT("999")) // comment
548 continue;
549 else if (line1 == wxT("0") && line2 == wxT("SECTION"))
550 {
551 GetLines(text, line1, line2);
552 if (line1 == wxT("2"))
553 {
554 if (line2 == wxT("HEADER"))
555 {
556 if (!ParseHeader(stream))
557 return false;
558 }
559 else if (line2 == wxT("TABLES"))
560 {
561 if (!ParseTables(stream))
562 return false;
563 }
564 else if (line2 == wxT("ENTITIES"))
565 {
566 if (!ParseEntities(stream))
567 return false;
568 }
569 }
570 }
571 }
572
573 NormalizeEntities();
574 m_loaded = true;
575 return true;
576 }
577
578 inline float mymin(float x, float y) { return x < y ? x : y; }
579 inline float mymax(float x, float y) { return x > y ? x : y; }
580
581 // Scale object boundings to [-5,5]
582 void DXFRenderer::NormalizeEntities()
583 {
584 // calculate current min and max boundings of object
585 DXFVector minv(10e20f, 10e20f, 10e20f);
586 DXFVector maxv(-10e20f, -10e20f, -10e20f);
587 for (DXFEntityList::Node *node = m_entities.GetFirst(); node; node = node->GetNext())
588 {
589 DXFEntity *p = node->GetData();
590 if (p->type == DXFEntity::Line)
591 {
592 DXFLine *line = (DXFLine *)p;
593 const DXFVector *v[2] = { &line->v0, &line->v1 };
594 for (int i = 0; i < 2; ++i)
595 {
596 minv.x = mymin(v[i]->x, minv.x);
597 minv.y = mymin(v[i]->y, minv.y);
598 minv.z = mymin(v[i]->z, minv.z);
599 maxv.x = mymax(v[i]->x, maxv.x);
600 maxv.y = mymax(v[i]->y, maxv.y);
601 maxv.z = mymax(v[i]->z, maxv.z);
602 }
603 } else if (p->type == DXFEntity::Face)
604 {
605 DXFFace *face = (DXFFace *)p;
606 const DXFVector *v[4] = { &face->v0, &face->v1, &face->v2, &face->v3 };
607 for (int i = 0; i < 4; ++i)
608 {
609 minv.x = mymin(v[i]->x, minv.x);
610 minv.y = mymin(v[i]->y, minv.y);
611 minv.z = mymin(v[i]->z, minv.z);
612 maxv.x = mymax(v[i]->x, maxv.x);
613 maxv.y = mymax(v[i]->y, maxv.y);
614 maxv.z = mymax(v[i]->z, maxv.z);
615 }
616 }
617 }
618
619 // rescale object down to [-5,5]
620 DXFVector span(maxv.x - minv.x, maxv.y - minv.y, maxv.z - minv.z);
621 float factor = mymin(mymin(10.0f / span.x, 10.0f / span.y), 10.0f / span.z);
622 for (DXFEntityList::Node *node2 = m_entities.GetFirst(); node2; node2 = node2->GetNext())
623 {
624 DXFEntity *p = node2->GetData();
625 if (p->type == DXFEntity::Line)
626 {
627 DXFLine *line = (DXFLine *)p;
628 DXFVector *v[2] = { &line->v0, &line->v1 };
629 for (int i = 0; i < 2; ++i)
630 {
631 v[i]->x -= minv.x + span.x/2; v[i]->x *= factor;
632 v[i]->y -= minv.y + span.y/2; v[i]->y *= factor;
633 v[i]->z -= minv.z + span.z/2; v[i]->z *= factor;
634 }
635 } else if (p->type == DXFEntity::Face)
636 {
637 DXFFace *face = (DXFFace *)p;
638 DXFVector *v[4] = { &face->v0, &face->v1, &face->v2, &face->v3 };
639 for (int i = 0; i < 4; ++i)
640 {
641 v[i]->x -= minv.x + span.x/2; v[i]->x *= factor;
642 v[i]->y -= minv.y + span.y/2; v[i]->y *= factor;
643 v[i]->z -= minv.z + span.z/2; v[i]->z *= factor;
644 }
645 }
646 }
647 }
648
649 // OpenGL renderer for DXF entities
650 void DXFRenderer::Render() const
651 {
652 if (!m_loaded)
653 return;
654
655 for (DXFEntityList::Node *node = m_entities.GetFirst(); node; node = node->GetNext())
656 {
657 DXFEntity *p = node->GetData();
658 wxColour c = ACIColourToRGB(p->colour);
659 if (p->type == DXFEntity::Line)
660 {
661 DXFLine *line = (DXFLine *)p;
662 glBegin(GL_LINES);
663 glColor3f(c.Red()/255.0,c.Green()/255.0,c.Blue()/255.0);
664 glVertex3f(line->v0.x, line->v0.y, line->v0.z);
665 glVertex3f(line->v1.x, line->v1.y, line->v1.z);
666 glEnd();
667 }
668 else if (p->type == DXFEntity::Face)
669 {
670 DXFFace *face = (DXFFace *)p;
671 glBegin(GL_TRIANGLES);
672 glColor3f(c.Red()/255.0,c.Green()/255.0,c.Blue()/255.0);
673 glNormal3f(face->n.x, face->n.y, face->n.z);
674 glVertex3f(face->v0.x, face->v0.y, face->v0.z);
675 glVertex3f(face->v1.x, face->v1.y, face->v1.z);
676 glVertex3f(face->v2.x, face->v2.y, face->v2.z);
677 glEnd();
678 }
679 }
680 }