b20edf8b33
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@37166 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
681 lines
18 KiB
C++
681 lines
18 KiB
C++
/////////////////////////////////////////////////////////////////////////////
|
|
// Name: dxfrenderer.cpp
|
|
// Purpose: DXF reader and renderer
|
|
// Author: Sandro Sigala
|
|
// Modified by:
|
|
// Created: 2005-11-10
|
|
// RCS-ID: $Id$
|
|
// Copyright: (c) Sandro Sigala
|
|
// Licence: wxWindows licence
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
// For compilers that support precompilation, includes "wx/wx.h".
|
|
#include "wx/wxprec.h"
|
|
|
|
#ifdef __BORLANDC__
|
|
#pragma hdrstop
|
|
#endif
|
|
|
|
#ifndef WX_PRECOMP
|
|
#include "wx/wx.h"
|
|
#endif
|
|
|
|
#include "wx/wfstream.h"
|
|
#include "wx/txtstrm.h"
|
|
|
|
#if !wxUSE_GLCANVAS
|
|
#error "OpenGL required: set wxUSE_GLCANVAS to 1 and rebuild the library"
|
|
#endif
|
|
|
|
#ifdef __WXMAC__
|
|
# ifdef __DARWIN__
|
|
# include <OpenGL/glu.h>
|
|
# else
|
|
# include <glu.h>
|
|
# endif
|
|
#else
|
|
# include <GL/glu.h>
|
|
#endif
|
|
|
|
#include "dxfrenderer.h"
|
|
|
|
#include "wx/listimpl.cpp"
|
|
WX_DEFINE_LIST(DXFEntityList)
|
|
WX_DEFINE_LIST(DXFLayerList)
|
|
|
|
// 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;
|
|
{
|
|
for (DXFLayerList::Node *node = m_layers.GetFirst(); node; node = node->GetNext())
|
|
{
|
|
DXFLayer *current = node->GetData();
|
|
delete current;
|
|
}
|
|
}
|
|
m_layers.Clear();
|
|
{
|
|
for (DXFEntityList::Node *node = m_entities.GetFirst(); node; node = node->GetNext())
|
|
{
|
|
DXFEntity *current = node->GetData();
|
|
delete current;
|
|
}
|
|
m_entities.Clear();
|
|
}
|
|
}
|
|
|
|
int DXFRenderer::GetLayerColour(const wxString& layer) const
|
|
{
|
|
for (DXFLayerList::Node *node = m_layers.GetFirst(); node; node = node->GetNext())
|
|
{
|
|
DXFLayer *current = node->GetData();
|
|
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 == wxT("0") && line2 == wxT("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 == wxT("0") && inlayer)
|
|
{
|
|
// flush layer
|
|
if (!layer.name.IsEmpty() && layer.colour != -1)
|
|
{
|
|
DXFLayer *p = new DXFLayer;
|
|
p->name = layer.name;
|
|
p->colour = layer.colour;
|
|
m_layers.Append(p);
|
|
}
|
|
layer = DXFLayer();
|
|
inlayer = false;
|
|
}
|
|
if (line1 == wxT("0") && line2 == wxT("ENDSEC"))
|
|
return true;
|
|
else if (line1 == wxT("0") && line2 == wxT("LAYER"))
|
|
inlayer = true;
|
|
else if (inlayer)
|
|
{
|
|
if (line1 == wxT("2")) // layer name
|
|
layer.name = line2;
|
|
else if (line1 == wxT("62")) // ACI colour
|
|
{
|
|
long l;
|
|
line2.ToLong(&l);
|
|
layer.colour = l;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// 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 == wxT("0") && state > 0)
|
|
{
|
|
// flush entity
|
|
if (state == 1) // 3DFACE
|
|
{
|
|
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.Append(p);
|
|
colour = -1; layer = wxEmptyString;
|
|
v[0] = v[1] = v[2] = v[3] = DXFVector();
|
|
state = 0;
|
|
}
|
|
else if (state == 2) // LINE
|
|
{
|
|
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.Append(p);
|
|
colour = -1; layer = wxEmptyString;
|
|
v[0] = v[1] = v[2] = v[3] = DXFVector();
|
|
state = 0;
|
|
}
|
|
}
|
|
if (line1 == wxT("0") && line2 == wxT("ENDSEC"))
|
|
return true;
|
|
else if (line1 == wxT("0") && line2 == wxT("3DFACE"))
|
|
state = 1;
|
|
else if (line1 == wxT("0") && line2 == wxT("LINE"))
|
|
state = 2;
|
|
else if (state > 0)
|
|
{
|
|
double d;
|
|
line2.ToDouble(&d);
|
|
if (line1 == wxT("10"))
|
|
v[0].x = d;
|
|
else if (line1 == wxT("20"))
|
|
v[0].y = d;
|
|
else if (line1 == wxT("30"))
|
|
v[0].z = d;
|
|
else if (line1 == wxT("11"))
|
|
v[1].x = d;
|
|
else if (line1 == wxT("21"))
|
|
v[1].y = d;
|
|
else if (line1 == wxT("31"))
|
|
v[1].z = d;
|
|
else if (line1 == wxT("12"))
|
|
v[2].x = d;
|
|
else if (line1 == wxT("22"))
|
|
v[2].y = d;
|
|
else if (line1 == wxT("32"))
|
|
v[2].z = d;
|
|
else if (line1 == wxT("13"))
|
|
v[3].x = d;
|
|
else if (line1 == wxT("23"))
|
|
v[3].y = d;
|
|
else if (line1 == wxT("33"))
|
|
v[3].z = d;
|
|
else if (line1 == wxT("8")) // layer
|
|
layer = line2;
|
|
else if (line1 == wxT("62")) // colour
|
|
{
|
|
long l;
|
|
line2.ToLong(&l);
|
|
colour = l;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// parse and load a DXF file
|
|
// currently pretty limited, but knows enought do 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 == wxT("999")) // comment
|
|
continue;
|
|
else if (line1 == wxT("0") && line2 == wxT("SECTION"))
|
|
{
|
|
GetLines(text, line1, line2);
|
|
if (line1 == wxT("2"))
|
|
{
|
|
if (line2 == wxT("HEADER"))
|
|
{
|
|
if (!ParseHeader(stream))
|
|
return false;
|
|
}
|
|
else if (line2 == wxT("TABLES"))
|
|
{
|
|
if (!ParseTables(stream))
|
|
return false;
|
|
}
|
|
else if (line2 == wxT("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 (DXFEntityList::Node *node = m_entities.GetFirst(); node; node = node->GetNext())
|
|
{
|
|
DXFEntity *p = node->GetData();
|
|
if (p->type == DXFEntity::Line)
|
|
{
|
|
DXFLine *line = (DXFLine *)p;
|
|
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 (p->type == DXFEntity::Face)
|
|
{
|
|
DXFFace *face = (DXFFace *)p;
|
|
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 (DXFEntityList::Node *node2 = m_entities.GetFirst(); node2; node2 = node2->GetNext())
|
|
{
|
|
DXFEntity *p = node2->GetData();
|
|
if (p->type == DXFEntity::Line)
|
|
{
|
|
DXFLine *line = (DXFLine *)p;
|
|
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 (p->type == DXFEntity::Face)
|
|
{
|
|
DXFFace *face = (DXFFace *)p;
|
|
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 (DXFEntityList::Node *node = m_entities.GetFirst(); node; node = node->GetNext())
|
|
{
|
|
DXFEntity *p = node->GetData();
|
|
wxColour c = ACIColourToRGB(p->colour);
|
|
if (p->type == DXFEntity::Line)
|
|
{
|
|
DXFLine *line = (DXFLine *)p;
|
|
glBegin(GL_LINES);
|
|
glColor3f(c.Red()/255.0,c.Green()/255.0,c.Blue()/255.0);
|
|
glVertex3f(line->v0.x, line->v0.y, line->v0.z);
|
|
glVertex3f(line->v1.x, line->v1.y, line->v1.z);
|
|
glEnd();
|
|
}
|
|
else if (p->type == DXFEntity::Face)
|
|
{
|
|
DXFFace *face = (DXFFace *)p;
|
|
glBegin(GL_TRIANGLES);
|
|
glColor3f(c.Red()/255.0,c.Green()/255.0,c.Blue()/255.0);
|
|
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();
|
|
}
|
|
}
|
|
}
|