initial commit
Signed-off-by: Peter Siegmund <mars3142@noreply.mars3142.dev>
This commit is contained in:
662
libs/wxWidgets-3.3.1/samples/opengl/penguin/dxfrenderer.cpp
Normal file
662
libs/wxWidgets-3.3.1/samples/opengl/penguin/dxfrenderer.cpp
Normal file
@@ -0,0 +1,662 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Name: dxfrenderer.cpp
|
||||
// Purpose: DXF reader and renderer
|
||||
// Author: Sandro Sigala
|
||||
// Created: 2005-11-10
|
||||
// Copyright: (c) Sandro Sigala
|
||||
// Licence: wxWindows licence
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// For compilers that support precompilation, includes "wx/wx.h".
|
||||
#include "wx/wxprec.h"
|
||||
|
||||
|
||||
#ifndef WX_PRECOMP
|
||||
#include "wx/wx.h"
|
||||
#endif
|
||||
|
||||
#include "wx/wfstream.h"
|
||||
#include "wx/txtstrm.h"
|
||||
#include "wx/glcanvas.h"
|
||||
|
||||
#if !wxUSE_GLCANVAS
|
||||
#error "OpenGL required: set wxUSE_GLCANVAS to 1 and rebuild the library"
|
||||
#endif
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include "dxfrenderer.h"
|
||||
|
||||
// Conversion table from AutoCAD ACI colours to RGB values
|
||||
static const struct { unsigned char r, g, b; } aci_to_rgb[256] = {
|
||||
/* 0 */ {255, 255, 255},
|
||||
/* 1 */ {255, 0, 0},
|
||||
/* 2 */ {255, 255, 0},
|
||||
/* 3 */ { 0, 255, 0},
|
||||
/* 4 */ { 0, 255, 255},
|
||||
/* 5 */ { 0, 0, 255},
|
||||
/* 6 */ {255, 0, 255},
|
||||
/* 7 */ {255, 255, 255},
|
||||
/* 8 */ {128, 128, 128},
|
||||
/* 9 */ {192, 192, 192},
|
||||
/* 10 */ {255, 0, 0},
|
||||
/* 11 */ {255, 127, 127},
|
||||
/* 12 */ {204, 0, 0},
|
||||
/* 13 */ {204, 102, 102},
|
||||
/* 14 */ {153, 0, 0},
|
||||
/* 15 */ {153, 76, 76},
|
||||
/* 16 */ {127, 0, 0},
|
||||
/* 17 */ {127, 63, 63},
|
||||
/* 18 */ { 76, 0, 0},
|
||||
/* 19 */ { 76, 38, 38},
|
||||
/* 20 */ {255, 63, 0},
|
||||
/* 21 */ {255, 159, 127},
|
||||
/* 22 */ {204, 51, 0},
|
||||
/* 23 */ {204, 127, 102},
|
||||
/* 24 */ {153, 38, 0},
|
||||
/* 25 */ {153, 95, 76},
|
||||
/* 26 */ {127, 31, 0},
|
||||
/* 27 */ {127, 79, 63},
|
||||
/* 28 */ { 76, 19, 0},
|
||||
/* 29 */ { 76, 47, 38},
|
||||
/* 30 */ {255, 127, 0},
|
||||
/* 31 */ {255, 191, 127},
|
||||
/* 32 */ {204, 102, 0},
|
||||
/* 33 */ {204, 153, 102},
|
||||
/* 34 */ {153, 76, 0},
|
||||
/* 35 */ {153, 114, 76},
|
||||
/* 36 */ {127, 63, 0},
|
||||
/* 37 */ {127, 95, 63},
|
||||
/* 38 */ { 76, 38, 0},
|
||||
/* 39 */ { 76, 57, 38},
|
||||
/* 40 */ {255, 191, 0},
|
||||
/* 41 */ {255, 223, 127},
|
||||
/* 42 */ {204, 153, 0},
|
||||
/* 43 */ {204, 178, 102},
|
||||
/* 44 */ {153, 114, 0},
|
||||
/* 45 */ {153, 133, 76},
|
||||
/* 46 */ {127, 95, 0},
|
||||
/* 47 */ {127, 111, 63},
|
||||
/* 48 */ { 76, 57, 0},
|
||||
/* 49 */ { 76, 66, 38},
|
||||
/* 50 */ {255, 255, 0},
|
||||
/* 51 */ {255, 255, 127},
|
||||
/* 52 */ {204, 204, 0},
|
||||
/* 53 */ {204, 204, 102},
|
||||
/* 54 */ {153, 153, 0},
|
||||
/* 55 */ {153, 153, 76},
|
||||
/* 56 */ {127, 127, 0},
|
||||
/* 57 */ {127, 127, 63},
|
||||
/* 58 */ { 76, 76, 0},
|
||||
/* 59 */ { 76, 76, 38},
|
||||
/* 60 */ {191, 255, 0},
|
||||
/* 61 */ {223, 255, 127},
|
||||
/* 62 */ {153, 204, 0},
|
||||
/* 63 */ {178, 204, 102},
|
||||
/* 64 */ {114, 153, 0},
|
||||
/* 65 */ {133, 153, 76},
|
||||
/* 66 */ { 95, 127, 0},
|
||||
/* 67 */ {111, 127, 63},
|
||||
/* 68 */ { 57, 76, 0},
|
||||
/* 69 */ { 66, 76, 38},
|
||||
/* 70 */ {127, 255, 0},
|
||||
/* 71 */ {191, 255, 127},
|
||||
/* 72 */ {102, 204, 0},
|
||||
/* 73 */ {153, 204, 102},
|
||||
/* 74 */ { 76, 153, 0},
|
||||
/* 75 */ {114, 153, 76},
|
||||
/* 76 */ { 63, 127, 0},
|
||||
/* 77 */ { 95, 127, 63},
|
||||
/* 78 */ { 38, 76, 0},
|
||||
/* 79 */ { 57, 76, 38},
|
||||
/* 80 */ { 63, 255, 0},
|
||||
/* 81 */ {159, 255, 127},
|
||||
/* 82 */ { 51, 204, 0},
|
||||
/* 83 */ {127, 204, 102},
|
||||
/* 84 */ { 38, 153, 0},
|
||||
/* 85 */ { 95, 153, 76},
|
||||
/* 86 */ { 31, 127, 0},
|
||||
/* 87 */ { 79, 127, 63},
|
||||
/* 88 */ { 19, 76, 0},
|
||||
/* 89 */ { 47, 76, 38},
|
||||
/* 90 */ { 0, 255, 0},
|
||||
/* 91 */ {127, 255, 127},
|
||||
/* 92 */ { 0, 204, 0},
|
||||
/* 93 */ {102, 204, 102},
|
||||
/* 94 */ { 0, 153, 0},
|
||||
/* 95 */ { 76, 153, 76},
|
||||
/* 96 */ { 0, 127, 0},
|
||||
/* 97 */ { 63, 127, 63},
|
||||
/* 98 */ { 0, 76, 0},
|
||||
/* 99 */ { 38, 76, 38},
|
||||
/* 100 */ { 0, 255, 63},
|
||||
/* 101 */ {127, 255, 159},
|
||||
/* 102 */ { 0, 204, 51},
|
||||
/* 103 */ {102, 204, 127},
|
||||
/* 104 */ { 0, 153, 38},
|
||||
/* 105 */ { 76, 153, 95},
|
||||
/* 106 */ { 0, 127, 31},
|
||||
/* 107 */ { 63, 127, 79},
|
||||
/* 108 */ { 0, 76, 19},
|
||||
/* 109 */ { 38, 76, 47},
|
||||
/* 110 */ { 0, 255, 127},
|
||||
/* 111 */ {127, 255, 191},
|
||||
/* 112 */ { 0, 204, 102},
|
||||
/* 113 */ {102, 204, 153},
|
||||
/* 114 */ { 0, 153, 76},
|
||||
/* 115 */ { 76, 153, 114},
|
||||
/* 116 */ { 0, 127, 63},
|
||||
/* 117 */ { 63, 127, 95},
|
||||
/* 118 */ { 0, 76, 38},
|
||||
/* 119 */ { 38, 76, 57},
|
||||
/* 120 */ { 0, 255, 191},
|
||||
/* 121 */ {127, 255, 223},
|
||||
/* 122 */ { 0, 204, 153},
|
||||
/* 123 */ {102, 204, 178},
|
||||
/* 124 */ { 0, 153, 114},
|
||||
/* 125 */ { 76, 153, 133},
|
||||
/* 126 */ { 0, 127, 95},
|
||||
/* 127 */ { 63, 127, 111},
|
||||
/* 128 */ { 0, 76, 57},
|
||||
/* 129 */ { 38, 76, 66},
|
||||
/* 130 */ { 0, 255, 255},
|
||||
/* 131 */ {127, 255, 255},
|
||||
/* 132 */ { 0, 204, 204},
|
||||
/* 133 */ {102, 204, 204},
|
||||
/* 134 */ { 0, 153, 153},
|
||||
/* 135 */ { 76, 153, 153},
|
||||
/* 136 */ { 0, 127, 127},
|
||||
/* 137 */ { 63, 127, 127},
|
||||
/* 138 */ { 0, 76, 76},
|
||||
/* 139 */ { 38, 76, 76},
|
||||
/* 140 */ { 0, 191, 255},
|
||||
/* 141 */ {127, 223, 255},
|
||||
/* 142 */ { 0, 153, 204},
|
||||
/* 143 */ {102, 178, 204},
|
||||
/* 144 */ { 0, 114, 153},
|
||||
/* 145 */ { 76, 133, 153},
|
||||
/* 146 */ { 0, 95, 127},
|
||||
/* 147 */ { 63, 111, 127},
|
||||
/* 148 */ { 0, 57, 76},
|
||||
/* 149 */ { 38, 66, 76},
|
||||
/* 150 */ { 0, 127, 255},
|
||||
/* 151 */ {127, 191, 255},
|
||||
/* 152 */ { 0, 102, 204},
|
||||
/* 153 */ {102, 153, 204},
|
||||
/* 154 */ { 0, 76, 153},
|
||||
/* 155 */ { 76, 114, 153},
|
||||
/* 156 */ { 0, 63, 127},
|
||||
/* 157 */ { 63, 95, 127},
|
||||
/* 158 */ { 0, 38, 76},
|
||||
/* 159 */ { 38, 57, 76},
|
||||
/* 160 */ { 0, 63, 255},
|
||||
/* 161 */ {127, 159, 255},
|
||||
/* 162 */ { 0, 51, 204},
|
||||
/* 163 */ {102, 127, 204},
|
||||
/* 164 */ { 0, 38, 153},
|
||||
/* 165 */ { 76, 95, 153},
|
||||
/* 166 */ { 0, 31, 127},
|
||||
/* 167 */ { 63, 79, 127},
|
||||
/* 168 */ { 0, 19, 76},
|
||||
/* 169 */ { 38, 47, 76},
|
||||
/* 170 */ { 0, 0, 255},
|
||||
/* 171 */ {127, 127, 255},
|
||||
/* 172 */ { 0, 0, 204},
|
||||
/* 173 */ {102, 102, 204},
|
||||
/* 174 */ { 0, 0, 153},
|
||||
/* 175 */ { 76, 76, 153},
|
||||
/* 176 */ { 0, 0, 127},
|
||||
/* 177 */ { 63, 63, 127},
|
||||
/* 178 */ { 0, 0, 76},
|
||||
/* 179 */ { 38, 38, 76},
|
||||
/* 180 */ { 63, 0, 255},
|
||||
/* 181 */ {159, 127, 255},
|
||||
/* 182 */ { 51, 0, 204},
|
||||
/* 183 */ {127, 102, 204},
|
||||
/* 184 */ { 38, 0, 153},
|
||||
/* 185 */ { 95, 76, 153},
|
||||
/* 186 */ { 31, 0, 127},
|
||||
/* 187 */ { 79, 63, 127},
|
||||
/* 188 */ { 19, 0, 76},
|
||||
/* 189 */ { 47, 38, 76},
|
||||
/* 190 */ {127, 0, 255},
|
||||
/* 191 */ {191, 127, 255},
|
||||
/* 192 */ {102, 0, 204},
|
||||
/* 193 */ {153, 102, 204},
|
||||
/* 194 */ { 76, 0, 153},
|
||||
/* 195 */ {114, 76, 153},
|
||||
/* 196 */ { 63, 0, 127},
|
||||
/* 197 */ { 95, 63, 127},
|
||||
/* 198 */ { 38, 0, 76},
|
||||
/* 199 */ { 57, 38, 76},
|
||||
/* 200 */ {191, 0, 255},
|
||||
/* 201 */ {223, 127, 255},
|
||||
/* 202 */ {153, 0, 204},
|
||||
/* 203 */ {178, 102, 204},
|
||||
/* 204 */ {114, 0, 153},
|
||||
/* 205 */ {133, 76, 153},
|
||||
/* 206 */ { 95, 0, 127},
|
||||
/* 207 */ {111, 63, 127},
|
||||
/* 208 */ { 57, 0, 76},
|
||||
/* 209 */ { 66, 38, 76},
|
||||
/* 210 */ {255, 0, 255},
|
||||
/* 211 */ {255, 127, 255},
|
||||
/* 212 */ {204, 0, 204},
|
||||
/* 213 */ {204, 102, 204},
|
||||
/* 214 */ {153, 0, 153},
|
||||
/* 215 */ {153, 76, 153},
|
||||
/* 216 */ {127, 0, 127},
|
||||
/* 217 */ {127, 63, 127},
|
||||
/* 218 */ { 76, 0, 76},
|
||||
/* 219 */ { 76, 38, 76},
|
||||
/* 220 */ {255, 0, 191},
|
||||
/* 221 */ {255, 127, 223},
|
||||
/* 222 */ {204, 0, 153},
|
||||
/* 223 */ {204, 102, 178},
|
||||
/* 224 */ {153, 0, 114},
|
||||
/* 225 */ {153, 76, 133},
|
||||
/* 226 */ {127, 0, 95},
|
||||
/* 227 */ {127, 63, 111},
|
||||
/* 228 */ { 76, 0, 57},
|
||||
/* 229 */ { 76, 38, 66},
|
||||
/* 230 */ {255, 0, 127},
|
||||
/* 231 */ {255, 127, 191},
|
||||
/* 232 */ {204, 0, 102},
|
||||
/* 233 */ {204, 102, 153},
|
||||
/* 234 */ {153, 0, 76},
|
||||
/* 235 */ {153, 76, 114},
|
||||
/* 236 */ {127, 0, 63},
|
||||
/* 237 */ {127, 63, 95},
|
||||
/* 238 */ { 76, 0, 38},
|
||||
/* 239 */ { 76, 38, 57},
|
||||
/* 240 */ {255, 0, 63},
|
||||
/* 241 */ {255, 127, 159},
|
||||
/* 242 */ {204, 0, 51},
|
||||
/* 243 */ {204, 102, 127},
|
||||
/* 244 */ {153, 0, 38},
|
||||
/* 245 */ {153, 76, 95},
|
||||
/* 246 */ {127, 0, 31},
|
||||
/* 247 */ {127, 63, 79},
|
||||
/* 248 */ { 76, 0, 19},
|
||||
/* 249 */ { 76, 38, 47},
|
||||
/* 250 */ { 51, 51, 51},
|
||||
/* 251 */ { 91, 91, 91},
|
||||
/* 252 */ {132, 132, 132},
|
||||
/* 253 */ {173, 173, 173},
|
||||
/* 254 */ {214, 214, 214},
|
||||
/* 255 */ {255, 255, 255}
|
||||
};
|
||||
|
||||
inline DXFVector Cross(const DXFVector& v1, const DXFVector& v2)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
void DXFFace::CalculateNormal()
|
||||
{
|
||||
DXFVector v01, v02;
|
||||
v01.x = v0.x - v1.x;
|
||||
v01.y = v0.y - v1.y;
|
||||
v01.z = v0.z - v1.z;
|
||||
v02.x = v0.x - v2.x;
|
||||
v02.y = v0.y - v2.y;
|
||||
v02.z = v0.z - v2.z;
|
||||
n = Cross(v01, v02);
|
||||
float mod = sqrt(n.x*n.x + n.y*n.y + n.z*n.z);
|
||||
n.x /= mod;
|
||||
n.y /= mod;
|
||||
n.z /= mod;
|
||||
}
|
||||
|
||||
// convert an AutoCAD ACI colour to wxWidgets RGB colour
|
||||
inline wxColour ACIColourToRGB(int col)
|
||||
{
|
||||
wxASSERT(col >= 0 && col <= 255);
|
||||
return wxColour(aci_to_rgb[col].r, aci_to_rgb[col].g, aci_to_rgb[col].b);
|
||||
}
|
||||
|
||||
// DXFReader constructor
|
||||
DXFRenderer::DXFRenderer()
|
||||
{
|
||||
m_loaded = false;
|
||||
}
|
||||
|
||||
// DXFReader destructor
|
||||
DXFRenderer::~DXFRenderer()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
// deallocate all the dynamic data
|
||||
void DXFRenderer::Clear()
|
||||
{
|
||||
m_loaded = false;
|
||||
m_layers.clear();
|
||||
m_entities.clear();
|
||||
}
|
||||
|
||||
int DXFRenderer::GetLayerColour(const wxString& layer) const
|
||||
{
|
||||
for (const auto& current : m_layers)
|
||||
{
|
||||
if (current.name == layer)
|
||||
return current.colour;
|
||||
}
|
||||
return 7; // white
|
||||
}
|
||||
|
||||
// read two sequential lines
|
||||
inline void GetLines(wxTextInputStream& text, wxString& line1, wxString& line2)
|
||||
{
|
||||
line1 = text.ReadLine().Trim().Trim(false);
|
||||
line2 = text.ReadLine().Trim().Trim(false);
|
||||
}
|
||||
|
||||
// parse header section: just skip everything
|
||||
bool DXFRenderer::ParseHeader(wxInputStream& stream)
|
||||
{
|
||||
wxTextInputStream text(stream);
|
||||
wxString line1, line2;
|
||||
while (stream.CanRead())
|
||||
{
|
||||
GetLines(text, line1, line2);
|
||||
if (line1 == "0" && line2 == "ENDSEC")
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// parse tables section: save layers name and colour
|
||||
bool DXFRenderer::ParseTables(wxInputStream& stream)
|
||||
{
|
||||
wxTextInputStream text(stream);
|
||||
wxString line1, line2;
|
||||
bool inlayer=false;
|
||||
DXFLayer layer;
|
||||
while (stream.CanRead())
|
||||
{
|
||||
GetLines(text, line1, line2);
|
||||
if (line1 == "0" && inlayer)
|
||||
{
|
||||
// flush layer
|
||||
if (!layer.name.IsEmpty() && layer.colour != -1)
|
||||
{
|
||||
DXFLayer p;
|
||||
p.name = layer.name;
|
||||
p.colour = layer.colour;
|
||||
m_layers.push_back(p);
|
||||
}
|
||||
layer = DXFLayer();
|
||||
inlayer = false;
|
||||
}
|
||||
if (line1 == "0" && line2 == "ENDSEC")
|
||||
return true;
|
||||
else if (line1 == "0" && line2 == "LAYER")
|
||||
inlayer = true;
|
||||
else if (inlayer)
|
||||
{
|
||||
if (line1 == "2") // layer name
|
||||
layer.name = line2;
|
||||
else if (line1 == "62") // ACI colour
|
||||
{
|
||||
long l;
|
||||
line2.ToLong(&l);
|
||||
layer.colour = l;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// This method is used instead of numStr.ToDouble(d) because the latter
|
||||
// (wxString::ToDouble()) takes the systems proper locale into account,
|
||||
// whereas the implementation below works with the default locale.
|
||||
// (Converting numbers that are formatted in the default locale can fail
|
||||
// with system locales that use e.g. the comma as the decimal separator.)
|
||||
static double ToDouble(const wxString& numStr)
|
||||
{
|
||||
double d;
|
||||
std::string numStr_(numStr.c_str());
|
||||
std::istringstream iss(numStr_);
|
||||
|
||||
iss >> d;
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
// parse entities section: save 3DFACE and LINE entities
|
||||
bool DXFRenderer::ParseEntities(wxInputStream& stream)
|
||||
{
|
||||
wxTextInputStream text(stream);
|
||||
wxString line1, line2;
|
||||
int state = 0; // 0: none, 1: 3DFACE, 2: LINE
|
||||
DXFVector v[4];
|
||||
int colour = -1;
|
||||
wxString layer;
|
||||
while (stream.CanRead())
|
||||
{
|
||||
GetLines(text, line1, line2);
|
||||
if (line1 == "0" && state > 0)
|
||||
{
|
||||
// flush entity
|
||||
if (state == 1) // 3DFACE
|
||||
{
|
||||
std::unique_ptr<DXFFace> p(new DXFFace);
|
||||
p->v0 = v[0];
|
||||
p->v1 = v[1];
|
||||
p->v2 = v[2];
|
||||
p->v3 = v[3];
|
||||
p->CalculateNormal();
|
||||
if (colour != -1)
|
||||
p->colour = colour;
|
||||
else
|
||||
p->colour = GetLayerColour(layer);
|
||||
m_entities.push_back(std::move(p));
|
||||
colour = -1; layer.clear();
|
||||
v[0] = v[1] = v[2] = v[3] = DXFVector();
|
||||
state = 0;
|
||||
}
|
||||
else if (state == 2) // LINE
|
||||
{
|
||||
std::unique_ptr<DXFLine> p(new DXFLine);
|
||||
p->v0 = v[0];
|
||||
p->v1 = v[1];
|
||||
if (colour != -1)
|
||||
p->colour = colour;
|
||||
else
|
||||
p->colour = GetLayerColour(layer);
|
||||
m_entities.push_back(std::move(p));
|
||||
colour = -1; layer.clear();
|
||||
v[0] = v[1] = v[2] = v[3] = DXFVector();
|
||||
state = 0;
|
||||
}
|
||||
}
|
||||
if (line1 == "0" && line2 == "ENDSEC")
|
||||
return true;
|
||||
else if (line1 == "0" && line2 == "3DFACE")
|
||||
state = 1;
|
||||
else if (line1 == "0" && line2 == "LINE")
|
||||
state = 2;
|
||||
else if (state > 0)
|
||||
{
|
||||
const float d = float(ToDouble(line2));
|
||||
|
||||
if (line1 == "10")
|
||||
v[0].x = d;
|
||||
else if (line1 == "20")
|
||||
v[0].y = d;
|
||||
else if (line1 == "30")
|
||||
v[0].z = d;
|
||||
else if (line1 == "11")
|
||||
v[1].x = d;
|
||||
else if (line1 == "21")
|
||||
v[1].y = d;
|
||||
else if (line1 == "31")
|
||||
v[1].z = d;
|
||||
else if (line1 == "12")
|
||||
v[2].x = d;
|
||||
else if (line1 == "22")
|
||||
v[2].y = d;
|
||||
else if (line1 == "32")
|
||||
v[2].z = d;
|
||||
else if (line1 == "13")
|
||||
v[3].x = d;
|
||||
else if (line1 == "23")
|
||||
v[3].y = d;
|
||||
else if (line1 == "33")
|
||||
v[3].z = d;
|
||||
else if (line1 == "8") // layer
|
||||
layer = line2;
|
||||
else if (line1 == "62") // colour
|
||||
{
|
||||
long l;
|
||||
line2.ToLong(&l);
|
||||
colour = l;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// parse and load a DXF file
|
||||
// currently pretty limited, but knows enough to handle 3DFACEs and LINEs
|
||||
bool DXFRenderer::Load(wxInputStream& stream)
|
||||
{
|
||||
Clear();
|
||||
wxTextInputStream text(stream);
|
||||
|
||||
wxString line1, line2;
|
||||
while (stream.CanRead())
|
||||
{
|
||||
GetLines(text, line1, line2);
|
||||
if (line1 == "999") // comment
|
||||
continue;
|
||||
else if (line1 == "0" && line2 == "SECTION")
|
||||
{
|
||||
GetLines(text, line1, line2);
|
||||
if (line1 == "2")
|
||||
{
|
||||
if (line2 == "HEADER")
|
||||
{
|
||||
if (!ParseHeader(stream))
|
||||
return false;
|
||||
}
|
||||
else if (line2 == "TABLES")
|
||||
{
|
||||
if (!ParseTables(stream))
|
||||
return false;
|
||||
}
|
||||
else if (line2 == "ENTITIES")
|
||||
{
|
||||
if (!ParseEntities(stream))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NormalizeEntities();
|
||||
m_loaded = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline float mymin(float x, float y) { return x < y ? x : y; }
|
||||
inline float mymax(float x, float y) { return x > y ? x : y; }
|
||||
|
||||
// Scale object boundings to [-5,5]
|
||||
void DXFRenderer::NormalizeEntities()
|
||||
{
|
||||
// calculate current min and max boundings of object
|
||||
DXFVector minv(10e20f, 10e20f, 10e20f);
|
||||
DXFVector maxv(-10e20f, -10e20f, -10e20f);
|
||||
for (auto& entity : m_entities)
|
||||
{
|
||||
if (entity->type == DXFEntity::Line)
|
||||
{
|
||||
DXFLine *line = (DXFLine *)entity.get();
|
||||
const DXFVector *v[2] = { &line->v0, &line->v1 };
|
||||
for (int i = 0; i < 2; ++i)
|
||||
{
|
||||
minv.x = mymin(v[i]->x, minv.x);
|
||||
minv.y = mymin(v[i]->y, minv.y);
|
||||
minv.z = mymin(v[i]->z, minv.z);
|
||||
maxv.x = mymax(v[i]->x, maxv.x);
|
||||
maxv.y = mymax(v[i]->y, maxv.y);
|
||||
maxv.z = mymax(v[i]->z, maxv.z);
|
||||
}
|
||||
} else if (entity->type == DXFEntity::Face)
|
||||
{
|
||||
DXFFace *face = (DXFFace *)entity.get();
|
||||
const DXFVector *v[4] = { &face->v0, &face->v1, &face->v2, &face->v3 };
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
minv.x = mymin(v[i]->x, minv.x);
|
||||
minv.y = mymin(v[i]->y, minv.y);
|
||||
minv.z = mymin(v[i]->z, minv.z);
|
||||
maxv.x = mymax(v[i]->x, maxv.x);
|
||||
maxv.y = mymax(v[i]->y, maxv.y);
|
||||
maxv.z = mymax(v[i]->z, maxv.z);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// rescale object down to [-5,5]
|
||||
DXFVector span(maxv.x - minv.x, maxv.y - minv.y, maxv.z - minv.z);
|
||||
float factor = mymin(mymin(10.0f / span.x, 10.0f / span.y), 10.0f / span.z);
|
||||
for (auto& entity : m_entities)
|
||||
{
|
||||
if (entity->type == DXFEntity::Line)
|
||||
{
|
||||
DXFLine *line = (DXFLine *)entity.get();
|
||||
DXFVector *v[2] = { &line->v0, &line->v1 };
|
||||
for (int i = 0; i < 2; ++i)
|
||||
{
|
||||
v[i]->x -= minv.x + span.x/2; v[i]->x *= factor;
|
||||
v[i]->y -= minv.y + span.y/2; v[i]->y *= factor;
|
||||
v[i]->z -= minv.z + span.z/2; v[i]->z *= factor;
|
||||
}
|
||||
} else if (entity->type == DXFEntity::Face)
|
||||
{
|
||||
DXFFace *face = (DXFFace *)entity.get();
|
||||
DXFVector *v[4] = { &face->v0, &face->v1, &face->v2, &face->v3 };
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
v[i]->x -= minv.x + span.x/2; v[i]->x *= factor;
|
||||
v[i]->y -= minv.y + span.y/2; v[i]->y *= factor;
|
||||
v[i]->z -= minv.z + span.z/2; v[i]->z *= factor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// OpenGL renderer for DXF entities
|
||||
void DXFRenderer::Render() const
|
||||
{
|
||||
if (!m_loaded)
|
||||
return;
|
||||
|
||||
for (const auto& entity : m_entities)
|
||||
{
|
||||
wxColour c = ACIColourToRGB(entity->colour);
|
||||
if (entity->type == DXFEntity::Line)
|
||||
{
|
||||
DXFLine *line = (DXFLine *)entity.get();
|
||||
glBegin(GL_LINES);
|
||||
glColor3f(c.Red()/255.0f, c.Green()/255.0f, c.Blue()/255.0f);
|
||||
glVertex3f(line->v0.x, line->v0.y, line->v0.z);
|
||||
glVertex3f(line->v1.x, line->v1.y, line->v1.z);
|
||||
glEnd();
|
||||
}
|
||||
else if (entity->type == DXFEntity::Face)
|
||||
{
|
||||
DXFFace *face = (DXFFace *)entity.get();
|
||||
glBegin(GL_TRIANGLES);
|
||||
glColor3f(c.Red()/255.0f, c.Green()/255.0f, c.Blue()/255.0f);
|
||||
glNormal3f(face->n.x, face->n.y, face->n.z);
|
||||
glVertex3f(face->v0.x, face->v0.y, face->v0.z);
|
||||
glVertex3f(face->v1.x, face->v1.y, face->v1.z);
|
||||
glVertex3f(face->v2.x, face->v2.y, face->v2.z);
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user