dxfrenderer.cpp 20 KB

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