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