1636 lines
39 KiB
C++
1636 lines
39 KiB
C++
// dxf.cpp
|
|
// dxf.cpp
|
|
// Copyright 2011, Dan Heeks
|
|
// This program is released under the BSD license. See the file COPYING for details.
|
|
|
|
#include "dxf.h"
|
|
|
|
using namespace std;
|
|
static const double Pi = 3.14159265358979323846264338327950288419716939937511;
|
|
|
|
CDxfWrite::CDxfWrite(const char* filepath)
|
|
{
|
|
// start the file
|
|
m_fail = false;
|
|
#ifdef __WXMSW__
|
|
m_ofs = new ofstream(filepath, ios::out);
|
|
#else
|
|
m_ofs = new ofstream(filepath, ios::out);
|
|
#endif
|
|
if(!(*m_ofs)){
|
|
m_fail = true;
|
|
return;
|
|
}
|
|
m_ofs->imbue(std::locale("C"));
|
|
|
|
// start
|
|
(*m_ofs) << 0 << endl;
|
|
(*m_ofs) << "SECTION" << endl;
|
|
(*m_ofs) << 2 << endl;
|
|
(*m_ofs) << "ENTITIES" << endl;
|
|
}
|
|
|
|
CDxfWrite::~CDxfWrite()
|
|
{
|
|
// end
|
|
(*m_ofs) << 0 << endl;
|
|
(*m_ofs) << "ENDSEC" << endl;
|
|
(*m_ofs) << 0 << endl;
|
|
(*m_ofs) << "EOF";
|
|
|
|
delete m_ofs;
|
|
}
|
|
|
|
void CDxfWrite::WriteLine(const double* s, const double* e, const char* layer_name)
|
|
{
|
|
(*m_ofs) << 0 << endl;
|
|
(*m_ofs) << "LINE" << endl;
|
|
(*m_ofs) << 8 << endl; // Group code for layer name
|
|
(*m_ofs) << layer_name << endl; // Layer number
|
|
(*m_ofs) << 10 << endl; // Start point of line
|
|
(*m_ofs) << s[0] << endl; // X in WCS coordinates
|
|
(*m_ofs) << 20 << endl;
|
|
(*m_ofs) << s[1] << endl; // Y in WCS coordinates
|
|
(*m_ofs) << 30 << endl;
|
|
(*m_ofs) << s[2] << endl; // Z in WCS coordinates
|
|
(*m_ofs) << 11 << endl; // End point of line
|
|
(*m_ofs) << e[0] << endl; // X in WCS coordinates
|
|
(*m_ofs) << 21 << endl;
|
|
(*m_ofs) << e[1] << endl; // Y in WCS coordinates
|
|
(*m_ofs) << 31 << endl;
|
|
(*m_ofs) << e[2] << endl; // Z in WCS coordinates
|
|
}
|
|
|
|
void CDxfWrite::WritePoint(const double* s, const char* layer_name)
|
|
{
|
|
(*m_ofs) << 0 << endl;
|
|
(*m_ofs) << "POINT" << endl;
|
|
(*m_ofs) << 8 << endl; // Group code for layer name
|
|
(*m_ofs) << layer_name << endl; // Layer number
|
|
(*m_ofs) << 10 << endl; // Start point of line
|
|
(*m_ofs) << s[0] << endl; // X in WCS coordinates
|
|
(*m_ofs) << 20 << endl;
|
|
(*m_ofs) << s[1] << endl; // Y in WCS coordinates
|
|
(*m_ofs) << 30 << endl;
|
|
(*m_ofs) << s[2] << endl; // Z in WCS coordinates
|
|
}
|
|
|
|
void CDxfWrite::WriteArc(const double* s, const double* e, const double* c, bool dir, const char* layer_name)
|
|
{
|
|
double ax = s[0] - c[0];
|
|
double ay = s[1] - c[1];
|
|
double bx = e[0] - c[0];
|
|
double by = e[1] - c[1];
|
|
|
|
double start_angle = atan2(ay, ax) * 180/Pi;
|
|
double end_angle = atan2(by, bx) * 180/Pi;
|
|
double radius = sqrt(ax*ax + ay*ay);
|
|
if(!dir){
|
|
double temp = start_angle;
|
|
start_angle = end_angle;
|
|
end_angle = temp;
|
|
}
|
|
(*m_ofs) << 0 << endl;
|
|
(*m_ofs) << "ARC" << endl;
|
|
(*m_ofs) << 8 << endl; // Group code for layer name
|
|
(*m_ofs) << layer_name << endl; // Layer number
|
|
(*m_ofs) << 10 << endl; // Centre X
|
|
(*m_ofs) << c[0] << endl; // X in WCS coordinates
|
|
(*m_ofs) << 20 << endl;
|
|
(*m_ofs) << c[1] << endl; // Y in WCS coordinates
|
|
(*m_ofs) << 30 << endl;
|
|
(*m_ofs) << c[2] << endl; // Z in WCS coordinates
|
|
(*m_ofs) << 40 << endl; //
|
|
(*m_ofs) << radius << endl; // Radius
|
|
(*m_ofs) << 50 << endl;
|
|
(*m_ofs) << start_angle << endl; // Start angle
|
|
(*m_ofs) << 51 << endl;
|
|
(*m_ofs) << end_angle << endl; // End angle
|
|
}
|
|
|
|
void CDxfWrite::WriteCircle(const double* c, double radius, const char* layer_name)
|
|
{
|
|
(*m_ofs) << 0 << endl;
|
|
(*m_ofs) << "CIRCLE" << endl;
|
|
(*m_ofs) << 8 << endl; // Group code for layer name
|
|
(*m_ofs) << layer_name << endl; // Layer number
|
|
(*m_ofs) << 10 << endl; // Centre X
|
|
(*m_ofs) << c[0] << endl; // X in WCS coordinates
|
|
(*m_ofs) << 20 << endl;
|
|
(*m_ofs) << c[1] << endl; // Y in WCS coordinates
|
|
(*m_ofs) << 30 << endl;
|
|
(*m_ofs) << c[2] << endl; // Z in WCS coordinates
|
|
(*m_ofs) << 40 << endl; //
|
|
(*m_ofs) << radius << endl; // Radius
|
|
}
|
|
|
|
void CDxfWrite::WriteEllipse(const double* c, double major_radius, double minor_radius, double rotation, double start_angle, double end_angle, bool dir, const char* layer_name )
|
|
{
|
|
double m[3];
|
|
m[2]=0;
|
|
m[0] = major_radius * sin(rotation);
|
|
m[1] = major_radius * cos(rotation);
|
|
|
|
double ratio = minor_radius/major_radius;
|
|
|
|
if(!dir){
|
|
double temp = start_angle;
|
|
start_angle = end_angle;
|
|
end_angle = temp;
|
|
}
|
|
(*m_ofs) << 0 << endl;
|
|
(*m_ofs) << "ELLIPSE" << endl;
|
|
(*m_ofs) << 8 << endl; // Group code for layer name
|
|
(*m_ofs) << layer_name << endl; // Layer number
|
|
(*m_ofs) << 10 << endl; // Centre X
|
|
(*m_ofs) << c[0] << endl; // X in WCS coordinates
|
|
(*m_ofs) << 20 << endl;
|
|
(*m_ofs) << c[1] << endl; // Y in WCS coordinates
|
|
(*m_ofs) << 30 << endl;
|
|
(*m_ofs) << c[2] << endl; // Z in WCS coordinates
|
|
(*m_ofs) << 40 << endl; //
|
|
(*m_ofs) << ratio << endl; // Ratio
|
|
(*m_ofs) << 11 << endl; //
|
|
(*m_ofs) << m[0] << endl; // Major X
|
|
(*m_ofs) << 21 << endl;
|
|
(*m_ofs) << m[1] << endl; // Major Y
|
|
(*m_ofs) << 31 << endl;
|
|
(*m_ofs) << m[2] << endl; // Major Z
|
|
(*m_ofs) << 41 << endl;
|
|
(*m_ofs) << start_angle << endl; // Start angle
|
|
(*m_ofs) << 42 << endl;
|
|
(*m_ofs) << end_angle << endl; // End angle
|
|
}
|
|
|
|
CDxfRead::CDxfRead(const char* filepath)
|
|
{
|
|
m_aci = 0;
|
|
// start the file
|
|
memset( m_str, '\0', sizeof(m_str) );
|
|
memset( m_unused_line, '\0', sizeof(m_unused_line) );
|
|
m_fail = false;
|
|
m_eUnits = eMillimeters;
|
|
strcpy(m_layer_name, "0"); // Default layer name
|
|
memset( m_section_name, '\0', sizeof(m_section_name) );
|
|
memset( m_block_name, '\0', sizeof(m_block_name) );
|
|
m_ignore_errors = true;
|
|
|
|
m_ifs = new ifstream(filepath);
|
|
if(!(*m_ifs)){
|
|
m_fail = true;
|
|
return;
|
|
}
|
|
m_ifs->imbue(std::locale("C"));
|
|
}
|
|
|
|
CDxfRead::~CDxfRead()
|
|
{
|
|
delete m_ifs;
|
|
}
|
|
|
|
double CDxfRead::mm( const double & value ) const
|
|
{
|
|
switch(m_eUnits)
|
|
{
|
|
case eUnspecified: return(value * 1.0); // We don't know any better.
|
|
case eInches: return(value * 25.4);
|
|
case eFeet: return(value * 25.4 * 12);
|
|
case eMiles: return(value * 1609344.0);
|
|
case eMillimeters: return(value * 1.0);
|
|
case eCentimeters: return(value * 10.0);
|
|
case eMeters: return(value * 1000.0);
|
|
case eKilometers: return(value * 1000000.0);
|
|
case eMicroinches: return(value * 25.4 / 1000.0);
|
|
case eMils: return(value * 25.4 / 1000.0);
|
|
case eYards: return(value * 3 * 12 * 25.4);
|
|
case eAngstroms: return(value * 0.0000001);
|
|
case eNanometers: return(value * 0.000001);
|
|
case eMicrons: return(value * 0.001);
|
|
case eDecimeters: return(value * 100.0);
|
|
case eDekameters: return(value * 10000.0);
|
|
case eHectometers: return(value * 100000.0);
|
|
case eGigameters: return(value * 1000000000000.0);
|
|
case eAstronomicalUnits: return(value * 149597870690000.0);
|
|
case eLightYears: return(value * 9454254955500000000.0);
|
|
case eParsecs: return(value * 30856774879000000000.0);
|
|
default: return(value * 1.0); // We don't know any better.
|
|
} // End switch
|
|
} // End mm() method
|
|
|
|
|
|
bool CDxfRead::ReadLine()
|
|
{
|
|
double s[3] = {0, 0, 0};
|
|
double e[3] = {0, 0, 0};
|
|
|
|
while(!((*m_ifs).eof()))
|
|
{
|
|
get_line();
|
|
int n;
|
|
|
|
if(sscanf(m_str, "%d", &n) != 1)
|
|
{
|
|
printf("CDxfRead::ReadLine() Failed to read integer from '%s'\n", m_str );
|
|
return false;
|
|
}
|
|
|
|
std::istringstream ss;
|
|
ss.imbue(std::locale("C"));
|
|
switch(n){
|
|
case 0:
|
|
// next item found, so finish with line
|
|
DerefACI();
|
|
OnReadLine(s, e);
|
|
return true;
|
|
|
|
case 8: // Layer name follows
|
|
get_line();
|
|
strcpy(m_layer_name, m_str);
|
|
break;
|
|
|
|
case 10:
|
|
// start x
|
|
get_line();
|
|
ss.str(m_str); ss >> s[0]; s[0] = mm(s[0]); if(ss.fail()) return false;
|
|
break;
|
|
case 20:
|
|
// start y
|
|
get_line();
|
|
ss.str(m_str); ss >> s[1]; s[1] = mm(s[1]); if(ss.fail()) return false;
|
|
break;
|
|
case 30:
|
|
// start z
|
|
get_line();
|
|
ss.str(m_str); ss >> s[2]; s[2] = mm(s[2]); if(ss.fail()) return false;
|
|
break;
|
|
case 11:
|
|
// end x
|
|
get_line();
|
|
ss.str(m_str); ss >> e[0]; e[0] = mm(e[0]); if(ss.fail()) return false;
|
|
break;
|
|
case 21:
|
|
// end y
|
|
get_line();
|
|
ss.str(m_str); ss >> e[1]; e[1] = mm(e[1]); if(ss.fail()) return false;
|
|
break;
|
|
case 31:
|
|
// end z
|
|
get_line();
|
|
ss.str(m_str); ss >> e[2]; e[2] = mm(e[2]); if(ss.fail()) return false;
|
|
break;
|
|
case 62:
|
|
// color index
|
|
get_line();
|
|
ss.str(m_str); ss >> m_aci; if(ss.fail()) return false;
|
|
break;
|
|
|
|
case 100:
|
|
case 39:
|
|
case 210:
|
|
case 220:
|
|
case 230:
|
|
// skip the next line
|
|
get_line();
|
|
break;
|
|
default:
|
|
// skip the next line
|
|
get_line();
|
|
break;
|
|
}
|
|
}
|
|
|
|
try {
|
|
DerefACI();
|
|
OnReadLine(s, e);
|
|
}
|
|
catch(...)
|
|
{
|
|
if (! IgnoreErrors()) throw; // Re-throw the exception.
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool CDxfRead::ReadPoint()
|
|
{
|
|
double s[3] = {0, 0, 0};
|
|
|
|
while(!((*m_ifs).eof()))
|
|
{
|
|
get_line();
|
|
int n;
|
|
|
|
if(sscanf(m_str, "%d", &n) != 1)
|
|
{
|
|
printf("CDxfRead::ReadPoint() Failed to read integer from '%s'\n", m_str );
|
|
return false;
|
|
}
|
|
|
|
std::istringstream ss;
|
|
ss.imbue(std::locale("C"));
|
|
switch(n){
|
|
case 0:
|
|
// next item found, so finish with line
|
|
DerefACI();
|
|
OnReadPoint(s);
|
|
return true;
|
|
|
|
case 8: // Layer name follows
|
|
get_line();
|
|
strcpy(m_layer_name, m_str);
|
|
break;
|
|
|
|
case 10:
|
|
// start x
|
|
get_line();
|
|
ss.str(m_str); ss >> s[0]; s[0] = mm(s[0]); if(ss.fail()) return false;
|
|
break;
|
|
case 20:
|
|
// start y
|
|
get_line();
|
|
ss.str(m_str); ss >> s[1]; s[1] = mm(s[1]); if(ss.fail()) return false;
|
|
break;
|
|
case 30:
|
|
// start z
|
|
get_line();
|
|
ss.str(m_str); ss >> s[2]; s[2] = mm(s[2]); if(ss.fail()) return false;
|
|
break;
|
|
|
|
case 62:
|
|
// color index
|
|
get_line();
|
|
ss.str(m_str); ss >> m_aci; if(ss.fail()) return false;
|
|
break;
|
|
|
|
case 100:
|
|
case 39:
|
|
case 210:
|
|
case 220:
|
|
case 230:
|
|
// skip the next line
|
|
get_line();
|
|
break;
|
|
default:
|
|
// skip the next line
|
|
get_line();
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
try {
|
|
DerefACI();
|
|
OnReadPoint(s);
|
|
}
|
|
catch(...)
|
|
{
|
|
if (! IgnoreErrors()) throw; // Re-throw the exception.
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool CDxfRead::ReadArc()
|
|
{
|
|
double start_angle = 0.0;// in degrees
|
|
double end_angle = 0.0;
|
|
double radius = 0.0;
|
|
double c[3] = {0,0,0}; // centre
|
|
|
|
while(!((*m_ifs).eof()))
|
|
{
|
|
get_line();
|
|
int n;
|
|
if(sscanf(m_str, "%d", &n) != 1)
|
|
{
|
|
printf("CDxfRead::ReadArc() Failed to read integer from '%s'\n", m_str);
|
|
return false;
|
|
}
|
|
|
|
std::istringstream ss;
|
|
ss.imbue(std::locale("C"));
|
|
switch(n){
|
|
case 0:
|
|
// next item found, so finish with arc
|
|
DerefACI();
|
|
OnReadArc(start_angle, end_angle, radius, c);
|
|
return true;
|
|
|
|
case 8: // Layer name follows
|
|
get_line();
|
|
strcpy(m_layer_name, m_str);
|
|
break;
|
|
|
|
case 10:
|
|
// centre x
|
|
get_line();
|
|
ss.str(m_str); ss >> c[0]; c[0] = mm(c[0]); if(ss.fail()) return false;
|
|
break;
|
|
case 20:
|
|
// centre y
|
|
get_line();
|
|
ss.str(m_str); ss >> c[1]; c[1] = mm(c[1]); if(ss.fail()) return false;
|
|
break;
|
|
case 30:
|
|
// centre z
|
|
get_line();
|
|
ss.str(m_str); ss >> c[2]; c[2] = mm(c[2]); if(ss.fail()) return false;
|
|
break;
|
|
case 40:
|
|
// radius
|
|
get_line();
|
|
ss.str(m_str); ss >> radius; radius = mm(radius); if(ss.fail()) return false;
|
|
break;
|
|
case 50:
|
|
// start angle
|
|
get_line();
|
|
ss.str(m_str); ss >> start_angle; if(ss.fail()) return false;
|
|
break;
|
|
case 51:
|
|
// end angle
|
|
get_line();
|
|
ss.str(m_str); ss >> end_angle; if(ss.fail()) return false;
|
|
break;
|
|
case 62:
|
|
// color index
|
|
get_line();
|
|
ss.str(m_str); ss >> m_aci; if(ss.fail()) return false;
|
|
break;
|
|
case 100:
|
|
case 39:
|
|
case 210:
|
|
case 220:
|
|
case 230:
|
|
// skip the next line
|
|
get_line();
|
|
break;
|
|
default:
|
|
// skip the next line
|
|
get_line();
|
|
break;
|
|
}
|
|
}
|
|
DerefACI();
|
|
OnReadArc(start_angle, end_angle, radius, c);
|
|
return false;
|
|
}
|
|
|
|
bool CDxfRead::ReadSpline()
|
|
{
|
|
struct SplineData sd;
|
|
sd.norm[0] = 0;
|
|
sd.norm[1] = 0;
|
|
sd.norm[2] = 1;
|
|
sd.degree = 0;
|
|
sd.knots = 0;
|
|
sd.flag = 0;
|
|
sd.control_points = 0;
|
|
sd.fit_points = 0;
|
|
|
|
double temp_double;
|
|
|
|
while(!((*m_ifs).eof()))
|
|
{
|
|
get_line();
|
|
int n;
|
|
if(sscanf(m_str, "%d", &n) != 1)
|
|
{
|
|
printf("CDxfRead::ReadSpline() Failed to read integer from '%s'\n", m_str);
|
|
return false;
|
|
}
|
|
std::istringstream ss;
|
|
ss.imbue(std::locale("C"));
|
|
switch(n){
|
|
case 0:
|
|
// next item found, so finish with Spline
|
|
DerefACI();
|
|
OnReadSpline(sd);
|
|
return true;
|
|
case 8: // Layer name follows
|
|
get_line();
|
|
strcpy(m_layer_name, m_str);
|
|
break;
|
|
case 62:
|
|
// color index
|
|
get_line();
|
|
ss.str(m_str); ss >> m_aci; if(ss.fail()) return false;
|
|
break;
|
|
case 210:
|
|
// normal x
|
|
get_line();
|
|
ss.str(m_str); ss >> sd.norm[0]; sd.norm[0] = mm(sd.norm[0]); if(ss.fail()) return false;
|
|
break;
|
|
case 220:
|
|
// normal y
|
|
get_line();
|
|
ss.str(m_str); ss >> sd.norm[1]; sd.norm[1] = mm(sd.norm[1]); if(ss.fail()) return false;
|
|
break;
|
|
case 230:
|
|
// normal z
|
|
get_line();
|
|
ss.str(m_str); ss >> sd.norm[2]; sd.norm[2] = mm(sd.norm[2]); if(ss.fail()) return false;
|
|
break;
|
|
case 70:
|
|
// flag
|
|
get_line();
|
|
ss.str(m_str); ss >> sd.flag; if(ss.fail()) return false;
|
|
break;
|
|
case 71:
|
|
// degree
|
|
get_line();
|
|
ss.str(m_str); ss >> sd.degree; if(ss.fail()) return false;
|
|
break;
|
|
case 72:
|
|
// knots
|
|
get_line();
|
|
ss.str(m_str); ss >> sd.knots; if(ss.fail()) return false;
|
|
break;
|
|
case 73:
|
|
// control points
|
|
get_line();
|
|
ss.str(m_str); ss >> sd.control_points; if(ss.fail()) return false;
|
|
break;
|
|
case 74:
|
|
// fit points
|
|
get_line();
|
|
ss.str(m_str); ss >> sd.fit_points; if(ss.fail()) return false;
|
|
break;
|
|
case 12:
|
|
// starttan x
|
|
get_line();
|
|
ss.str(m_str); ss >> temp_double; if(ss.fail()) return false;
|
|
sd.starttanx.push_back(temp_double);
|
|
break;
|
|
case 22:
|
|
// starttan y
|
|
get_line();
|
|
ss.str(m_str); ss >> temp_double; if(ss.fail()) return false;
|
|
sd.starttany.push_back(temp_double);
|
|
break;
|
|
case 32:
|
|
// starttan z
|
|
get_line();
|
|
ss.str(m_str); ss >> temp_double; if(ss.fail()) return false;
|
|
sd.starttanz.push_back(temp_double);
|
|
break;
|
|
case 13:
|
|
// endtan x
|
|
get_line();
|
|
ss.str(m_str); ss >> temp_double; if(ss.fail()) return false;
|
|
sd.endtanx.push_back(temp_double);
|
|
break;
|
|
case 23:
|
|
// endtan y
|
|
get_line();
|
|
ss.str(m_str); ss >> temp_double; if(ss.fail()) return false;
|
|
sd.endtany.push_back(temp_double);
|
|
break;
|
|
case 33:
|
|
// endtan z
|
|
get_line();
|
|
ss.str(m_str); ss >> temp_double; if(ss.fail()) return false;
|
|
sd.endtanz.push_back(temp_double);
|
|
break;
|
|
case 40:
|
|
// knot
|
|
get_line();
|
|
ss.str(m_str); ss >> temp_double; if(ss.fail()) return false;
|
|
sd.knot.push_back(temp_double);
|
|
break;
|
|
case 41:
|
|
// weight
|
|
get_line();
|
|
ss.str(m_str); ss >> temp_double; if(ss.fail()) return false;
|
|
sd.weight.push_back(temp_double);
|
|
break;
|
|
case 10:
|
|
// control x
|
|
get_line();
|
|
ss.str(m_str); ss >> temp_double; if(ss.fail()) return false;
|
|
sd.controlx.push_back(temp_double);
|
|
break;
|
|
case 20:
|
|
// control y
|
|
get_line();
|
|
ss.str(m_str); ss >> temp_double; if(ss.fail()) return false;
|
|
sd.controly.push_back(temp_double);
|
|
break;
|
|
case 30:
|
|
// control z
|
|
get_line();
|
|
ss.str(m_str); ss >> temp_double; if(ss.fail()) return false;
|
|
sd.controlz.push_back(temp_double);
|
|
break;
|
|
case 11:
|
|
// fit x
|
|
get_line();
|
|
ss.str(m_str); ss >> temp_double; if(ss.fail()) return false;
|
|
sd.fitx.push_back(temp_double);
|
|
break;
|
|
case 21:
|
|
// fit y
|
|
get_line();
|
|
ss.str(m_str); ss >> temp_double; if(ss.fail()) return false;
|
|
sd.fity.push_back(temp_double);
|
|
break;
|
|
case 31:
|
|
// fit z
|
|
get_line();
|
|
ss.str(m_str); ss >> temp_double; if(ss.fail()) return false;
|
|
sd.fitz.push_back(temp_double);
|
|
break;
|
|
case 42:
|
|
case 43:
|
|
case 44:
|
|
// skip the next line
|
|
get_line();
|
|
break;
|
|
default:
|
|
// skip the next line
|
|
get_line();
|
|
break;
|
|
}
|
|
}
|
|
DerefACI();
|
|
OnReadSpline(sd);
|
|
return false;
|
|
}
|
|
|
|
|
|
bool CDxfRead::ReadCircle()
|
|
{
|
|
double radius = 0.0;
|
|
double c[3] = {0,0,0}; // centre
|
|
|
|
while(!((*m_ifs).eof()))
|
|
{
|
|
get_line();
|
|
int n;
|
|
if(sscanf(m_str, "%d", &n) != 1)
|
|
{
|
|
printf("CDxfRead::ReadCircle() Failed to read integer from '%s'\n", m_str);
|
|
return false;
|
|
}
|
|
std::istringstream ss;
|
|
ss.imbue(std::locale("C"));
|
|
switch(n){
|
|
case 0:
|
|
// next item found, so finish with Circle
|
|
DerefACI();
|
|
OnReadCircle(c, radius);
|
|
return true;
|
|
case 8: // Layer name follows
|
|
get_line();
|
|
strcpy(m_layer_name, m_str);
|
|
break;
|
|
|
|
case 10:
|
|
// centre x
|
|
get_line();
|
|
ss.str(m_str); ss >> c[0]; c[0] = mm(c[0]); if(ss.fail()) return false;
|
|
break;
|
|
case 20:
|
|
// centre y
|
|
get_line();
|
|
ss.str(m_str); ss >> c[1]; c[1] = mm(c[1]); if(ss.fail()) return false;
|
|
break;
|
|
case 30:
|
|
// centre z
|
|
get_line();
|
|
ss.str(m_str); ss >> c[2]; c[2] = mm(c[2]); if(ss.fail()) return false;
|
|
break;
|
|
case 40:
|
|
// radius
|
|
get_line();
|
|
ss.str(m_str); ss >> radius; radius = mm(radius); if(ss.fail()) return false;
|
|
break;
|
|
case 62:
|
|
// color index
|
|
get_line();
|
|
ss.str(m_str); ss >> m_aci; if(ss.fail()) return false;
|
|
break;
|
|
|
|
case 100:
|
|
case 39:
|
|
case 210:
|
|
case 220:
|
|
case 230:
|
|
// skip the next line
|
|
get_line();
|
|
break;
|
|
default:
|
|
// skip the next line
|
|
get_line();
|
|
break;
|
|
}
|
|
}
|
|
DerefACI();
|
|
OnReadCircle(c, radius);
|
|
return false;
|
|
}
|
|
|
|
|
|
bool CDxfRead::ReadText()
|
|
{
|
|
double c[3]; // coordinate
|
|
double height = 0.03082;
|
|
|
|
memset( c, 0, sizeof(c) );
|
|
|
|
while(!((*m_ifs).eof()))
|
|
{
|
|
get_line();
|
|
int n;
|
|
if(sscanf(m_str, "%d", &n) != 1)
|
|
{
|
|
printf("CDxfRead::ReadText() Failed to read integer from '%s'\n", m_str);
|
|
return false;
|
|
}
|
|
std::istringstream ss;
|
|
ss.imbue(std::locale("C"));
|
|
switch(n){
|
|
case 0:
|
|
return false;
|
|
case 8: // Layer name follows
|
|
get_line();
|
|
strcpy(m_layer_name, m_str);
|
|
break;
|
|
|
|
case 10:
|
|
// centre x
|
|
get_line();
|
|
ss.str(m_str); ss >> c[0]; c[0] = mm(c[0]); if(ss.fail()) return false;
|
|
break;
|
|
case 20:
|
|
// centre y
|
|
get_line();
|
|
ss.str(m_str); ss >> c[1]; c[1] = mm(c[1]); if(ss.fail()) return false;
|
|
break;
|
|
case 30:
|
|
// centre z
|
|
get_line();
|
|
ss.str(m_str); ss >> c[2]; c[2] = mm(c[2]); if(ss.fail()) return false;
|
|
break;
|
|
case 40:
|
|
// text height
|
|
get_line();
|
|
ss.str(m_str); ss >> height; height = mm(height); if(ss.fail()) return false;
|
|
break;
|
|
case 1:
|
|
// text
|
|
get_line();
|
|
DerefACI();
|
|
OnReadText(c, height * 25.4 / 72.0, m_str);
|
|
return(true);
|
|
|
|
case 62:
|
|
// color index
|
|
get_line();
|
|
ss.str(m_str); ss >> m_aci; if(ss.fail()) return false;
|
|
break;
|
|
|
|
case 100:
|
|
case 39:
|
|
case 210:
|
|
case 220:
|
|
case 230:
|
|
// skip the next line
|
|
get_line();
|
|
break;
|
|
default:
|
|
// skip the next line
|
|
get_line();
|
|
break;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
bool CDxfRead::ReadEllipse()
|
|
{
|
|
double c[3]={0,0,0}; // centre
|
|
double m[3]={1,0,0}; //major axis point
|
|
double ratio=0; //ratio of major to minor axis
|
|
double start=0; //start of arc
|
|
double end=0; // end of arc
|
|
|
|
while(!((*m_ifs).eof()))
|
|
{
|
|
get_line();
|
|
int n;
|
|
if(sscanf(m_str, "%d", &n) != 1)
|
|
{
|
|
printf("CDxfRead::ReadEllipse() Failed to read integer from '%s'\n", m_str);
|
|
return false;
|
|
}
|
|
std::istringstream ss;
|
|
ss.imbue(std::locale("C"));
|
|
switch(n){
|
|
case 0:
|
|
// next item found, so finish with Ellipse
|
|
DerefACI();
|
|
OnReadEllipse(c, m, ratio, start, end);
|
|
return true;
|
|
case 8: // Layer name follows
|
|
get_line();
|
|
strcpy(m_layer_name, m_str);
|
|
break;
|
|
|
|
case 10:
|
|
// centre x
|
|
get_line();
|
|
ss.str(m_str); ss >> c[0]; c[0] = mm(c[0]); if(ss.fail()) return false;
|
|
break;
|
|
case 20:
|
|
// centre y
|
|
get_line();
|
|
ss.str(m_str); ss >> c[1]; c[1] = mm(c[1]); if(ss.fail()) return false;
|
|
break;
|
|
case 30:
|
|
// centre z
|
|
get_line();
|
|
ss.str(m_str); ss >> c[2]; c[2] = mm(c[2]); if(ss.fail()) return false;
|
|
break;
|
|
case 11:
|
|
// major x
|
|
get_line();
|
|
ss.str(m_str); ss >> m[0]; m[0] = mm(m[0]); if(ss.fail()) return false;
|
|
break;
|
|
case 21:
|
|
// major y
|
|
get_line();
|
|
ss.str(m_str); ss >> m[1]; m[1] = mm(m[1]); if(ss.fail()) return false;
|
|
break;
|
|
case 31:
|
|
// major z
|
|
get_line();
|
|
ss.str(m_str); ss >> m[2]; m[2] = mm(m[2]); if(ss.fail()) return false;
|
|
break;
|
|
case 40:
|
|
// ratio
|
|
get_line();
|
|
ss.str(m_str); ss >> ratio; if(ss.fail()) return false;
|
|
break;
|
|
case 41:
|
|
// start
|
|
get_line();
|
|
ss.str(m_str); ss >> start; if(ss.fail()) return false;
|
|
break;
|
|
case 42:
|
|
// end
|
|
get_line();
|
|
ss.str(m_str); ss >> end; if(ss.fail()) return false;
|
|
break;
|
|
case 62:
|
|
// color index
|
|
get_line();
|
|
ss.str(m_str); ss >> m_aci; if(ss.fail()) return false;
|
|
break;
|
|
case 100:
|
|
case 210:
|
|
case 220:
|
|
case 230:
|
|
// skip the next line
|
|
get_line();
|
|
break;
|
|
default:
|
|
// skip the next line
|
|
get_line();
|
|
break;
|
|
}
|
|
}
|
|
DerefACI();
|
|
OnReadEllipse(c, m, ratio, start, end);
|
|
return false;
|
|
}
|
|
|
|
|
|
static bool poly_prev_found = false;
|
|
static double poly_prev_x;
|
|
static double poly_prev_y;
|
|
static double poly_prev_z;
|
|
static bool poly_prev_bulge_found = false;
|
|
static double poly_prev_bulge;
|
|
static bool poly_first_found = false;
|
|
static double poly_first_x;
|
|
static double poly_first_y;
|
|
static double poly_first_z;
|
|
|
|
static void AddPolyLinePoint(CDxfRead* dxf_read, double x, double y, double z, bool bulge_found, double bulge)
|
|
{
|
|
|
|
try {
|
|
if(poly_prev_found)
|
|
{
|
|
bool arc_done = false;
|
|
if(poly_prev_bulge_found)
|
|
{
|
|
double cot = 0.5 * ((1.0 / poly_prev_bulge) - poly_prev_bulge);
|
|
double cx = ((poly_prev_x + x) - ((y - poly_prev_y) * cot)) / 2.0;
|
|
double cy = ((poly_prev_y + y) + ((x - poly_prev_x) * cot)) / 2.0;
|
|
double ps[3] = {poly_prev_x, poly_prev_y, poly_prev_z};
|
|
double pe[3] = {x, y, z};
|
|
double pc[3] = {cx, cy, (poly_prev_z + z)/2.0};
|
|
dxf_read->OnReadArc(ps, pe, pc, poly_prev_bulge >= 0);
|
|
arc_done = true;
|
|
}
|
|
|
|
if(!arc_done)
|
|
{
|
|
double s[3] = {poly_prev_x, poly_prev_y, poly_prev_z};
|
|
double e[3] = {x, y, z};
|
|
dxf_read->OnReadLine(s, e);
|
|
}
|
|
}
|
|
|
|
poly_prev_found = true;
|
|
poly_prev_x = x;
|
|
poly_prev_y = y;
|
|
poly_prev_z = z;
|
|
if(!poly_first_found)
|
|
{
|
|
poly_first_x = x;
|
|
poly_first_y = y;
|
|
poly_first_z = z;
|
|
poly_first_found = true;
|
|
}
|
|
poly_prev_bulge_found = bulge_found;
|
|
poly_prev_bulge = bulge;
|
|
}
|
|
catch(...)
|
|
{
|
|
if (! dxf_read->IgnoreErrors()) throw; // Re-throw it.
|
|
}
|
|
}
|
|
|
|
static void PolyLineStart()
|
|
{
|
|
poly_prev_found = false;
|
|
poly_first_found = false;
|
|
}
|
|
|
|
bool CDxfRead::ReadLwPolyLine()
|
|
{
|
|
PolyLineStart();
|
|
|
|
bool x_found = false;
|
|
bool y_found = false;
|
|
double x = 0.0;
|
|
double y = 0.0;
|
|
double z = 0.0;
|
|
bool bulge_found = false;
|
|
double bulge = 0.0;
|
|
bool closed = false;
|
|
int flags;
|
|
bool next_item_found = false;
|
|
|
|
while(!((*m_ifs).eof()) && !next_item_found)
|
|
{
|
|
get_line();
|
|
int n;
|
|
if(sscanf(m_str, "%d", &n) != 1)
|
|
{
|
|
printf("CDxfRead::ReadLwPolyLine() Failed to read integer from '%s'\n", m_str);
|
|
return false;
|
|
}
|
|
std::istringstream ss;
|
|
ss.imbue(std::locale("C"));
|
|
switch(n){
|
|
case 0:
|
|
// next item found
|
|
|
|
DerefACI();
|
|
if(x_found && y_found){
|
|
// add point
|
|
AddPolyLinePoint(this, x, y, z, bulge_found, bulge);
|
|
bulge_found = false;
|
|
x_found = false;
|
|
y_found = false;
|
|
}
|
|
next_item_found = true;
|
|
break;
|
|
case 8: // Layer name follows
|
|
get_line();
|
|
strcpy(m_layer_name, m_str);
|
|
break;
|
|
|
|
case 10:
|
|
// x
|
|
get_line();
|
|
if(x_found && y_found){
|
|
// add point
|
|
AddPolyLinePoint(this, x, y, z, bulge_found, bulge);
|
|
bulge_found = false;
|
|
x_found = false;
|
|
y_found = false;
|
|
}
|
|
ss.str(m_str); ss >> x; x = mm(x); if(ss.fail()) return false;
|
|
x_found = true;
|
|
break;
|
|
case 20:
|
|
// y
|
|
get_line();
|
|
ss.str(m_str); ss >> y; y = mm(y); if(ss.fail()) return false;
|
|
y_found = true;
|
|
break;
|
|
case 42:
|
|
// bulge
|
|
get_line();
|
|
ss.str(m_str); ss >> bulge; if(ss.fail()) return false;
|
|
bulge_found = true;
|
|
break;
|
|
case 70:
|
|
// flags
|
|
get_line();
|
|
if(sscanf(m_str, "%d", &flags) != 1)return false;
|
|
closed = ((flags & 1) != 0);
|
|
break;
|
|
case 62:
|
|
// color index
|
|
get_line();
|
|
ss.str(m_str); ss >> m_aci; if(ss.fail()) return false;
|
|
break;
|
|
default:
|
|
// skip the next line
|
|
get_line();
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(next_item_found)
|
|
{
|
|
if(closed && poly_first_found)
|
|
{
|
|
// repeat the first point
|
|
DerefACI();
|
|
AddPolyLinePoint(this, poly_first_x, poly_first_y, poly_first_z, false, 0.0);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
bool CDxfRead::ReadVertex(double *pVertex, bool *bulge_found, double *bulge)
|
|
{
|
|
bool x_found = false;
|
|
bool y_found = false;
|
|
|
|
double x = 0.0;
|
|
double y = 0.0;
|
|
double z = 0.0;
|
|
*bulge = 0.0;
|
|
*bulge_found = false;
|
|
|
|
pVertex[0] = 0.0;
|
|
pVertex[1] = 0.0;
|
|
pVertex[2] = 0.0;
|
|
|
|
while(!(*m_ifs).eof()) {
|
|
get_line();
|
|
int n;
|
|
if(sscanf(m_str, "%d", &n) != 1) {
|
|
printf("CDxfRead::ReadVertex() Failed to read integer from '%s'\n", m_str);
|
|
return false;
|
|
}
|
|
std::istringstream ss;
|
|
ss.imbue(std::locale("C"));
|
|
switch(n){
|
|
case 0:
|
|
DerefACI();
|
|
put_line(m_str); // read one line too many. put it back.
|
|
return(x_found && y_found);
|
|
break;
|
|
|
|
case 8: // Layer name follows
|
|
get_line();
|
|
strcpy(m_layer_name, m_str);
|
|
break;
|
|
|
|
case 10:
|
|
// x
|
|
get_line();
|
|
ss.str(m_str); ss >> x; pVertex[0] = mm(x); if(ss.fail()) return false;
|
|
x_found = true;
|
|
break;
|
|
case 20:
|
|
// y
|
|
get_line();
|
|
ss.str(m_str); ss >> y; pVertex[1] = mm(y); if(ss.fail()) return false;
|
|
y_found = true;
|
|
break;
|
|
case 30:
|
|
// z
|
|
get_line();
|
|
ss.str(m_str); ss >> z; pVertex[2] = mm(z); if(ss.fail()) return false;
|
|
break;
|
|
|
|
case 42:
|
|
get_line();
|
|
*bulge_found = true;
|
|
ss.str(m_str); ss >> *bulge; if(ss.fail()) return false;
|
|
break;
|
|
case 62:
|
|
// color index
|
|
get_line();
|
|
ss.str(m_str); ss >> m_aci; if(ss.fail()) return false;
|
|
break;
|
|
|
|
default:
|
|
// skip the next line
|
|
get_line();
|
|
break;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
|
|
bool CDxfRead::ReadPolyLine()
|
|
{
|
|
PolyLineStart();
|
|
|
|
bool closed = false;
|
|
int flags;
|
|
bool first_vertex_section_found = false;
|
|
double first_vertex[3] = {0};
|
|
bool bulge_found;
|
|
double bulge;
|
|
|
|
while(!(*m_ifs).eof())
|
|
{
|
|
get_line();
|
|
int n;
|
|
if(sscanf(m_str, "%d", &n) != 1)
|
|
{
|
|
printf("CDxfRead::ReadPolyLine() Failed to read integer from '%s'\n", m_str);
|
|
return false;
|
|
}
|
|
std::istringstream ss;
|
|
ss.imbue(std::locale("C"));
|
|
switch(n){
|
|
case 0:
|
|
// next item found
|
|
DerefACI();
|
|
get_line();
|
|
if (! strcmp(m_str,"VERTEX"))
|
|
{
|
|
double vertex[3];
|
|
if (CDxfRead::ReadVertex(vertex, &bulge_found, &bulge))
|
|
{
|
|
if(!first_vertex_section_found) {
|
|
first_vertex_section_found = true;
|
|
memcpy(first_vertex, vertex, 3*sizeof(double));
|
|
}
|
|
AddPolyLinePoint(this, vertex[0], vertex[1], vertex[2], bulge_found, bulge);
|
|
break;
|
|
}
|
|
}
|
|
if (! strcmp(m_str,"SEQEND"))
|
|
{
|
|
if(closed && first_vertex_section_found) {
|
|
AddPolyLinePoint(this, first_vertex[0], first_vertex[1], first_vertex[2], 0, 0);
|
|
}
|
|
first_vertex_section_found = false;
|
|
PolyLineStart();
|
|
return(true);
|
|
}
|
|
break;
|
|
case 70:
|
|
// flags
|
|
get_line();
|
|
if(sscanf(m_str, "%d", &flags) != 1)return false;
|
|
closed = ((flags & 1) != 0);
|
|
break;
|
|
case 62:
|
|
// color index
|
|
get_line();
|
|
ss.str(m_str); ss >> m_aci; if(ss.fail()) return false;
|
|
break;
|
|
default:
|
|
// skip the next line
|
|
get_line();
|
|
break;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void CDxfRead::OnReadArc(double start_angle, double end_angle, double radius, const double* c){
|
|
double s[3], e[3];
|
|
s[0] = c[0] + radius * cos(start_angle * Pi/180);
|
|
s[1] = c[1] + radius * sin(start_angle * Pi/180);
|
|
s[2] = c[2];
|
|
e[0] = c[0] + radius * cos(end_angle * Pi/180);
|
|
e[1] = c[1] + radius * sin(end_angle * Pi/180);
|
|
e[2] = c[2];
|
|
|
|
OnReadArc(s, e, c, true);
|
|
}
|
|
|
|
void CDxfRead::OnReadCircle(const double* c, double radius){
|
|
double s[3];
|
|
double start_angle = 0;
|
|
s[0] = c[0] + radius * cos(start_angle * Pi/180);
|
|
s[1] = c[1] + radius * sin(start_angle * Pi/180);
|
|
s[2] = c[2];
|
|
|
|
OnReadCircle(s, c, false); //false to change direction because otherwise the arc length is zero
|
|
}
|
|
|
|
void CDxfRead::OnReadEllipse(const double* c, const double* m, double ratio, double start_angle, double end_angle){
|
|
double major_radius = sqrt(m[0]*m[0] + m[1]*m[1] + m[2]*m[2]);
|
|
double minor_radius = major_radius * ratio;
|
|
|
|
//Since we only support 2d stuff, we can calculate the rotation from the major axis x and y value only,
|
|
//since z is zero, major_radius is the vector length
|
|
|
|
double rotation = atan2(m[1]/major_radius,m[0]/major_radius);
|
|
|
|
|
|
OnReadEllipse(c, major_radius, minor_radius, rotation, start_angle, end_angle, true);
|
|
}
|
|
|
|
bool CDxfRead::ReadInsert()
|
|
{
|
|
double c[3] = {0,0,0}; // coordinate
|
|
double s[3] = {1,1,1}; // scale
|
|
double rot = 0.0; // rotation
|
|
char name[1024] = {0};
|
|
|
|
while(!((*m_ifs).eof()))
|
|
{
|
|
get_line();
|
|
int n;
|
|
if(sscanf(m_str, "%d", &n) != 1)
|
|
{
|
|
printf("CDxfRead::ReadInsert() Failed to read integer from '%s'\n", m_str);
|
|
return false;
|
|
}
|
|
std::istringstream ss;
|
|
ss.imbue(std::locale("C"));
|
|
switch(n){
|
|
case 0:
|
|
// next item found
|
|
DerefACI();
|
|
OnReadInsert(c, s, name, rot * Pi/180);
|
|
return(true);
|
|
case 8:
|
|
// Layer name follows
|
|
get_line();
|
|
strcpy(m_layer_name, m_str);
|
|
break;
|
|
case 10:
|
|
// coord x
|
|
get_line();
|
|
ss.str(m_str); ss >> c[0]; c[0] = mm(c[0]); if(ss.fail()) return false;
|
|
break;
|
|
case 20:
|
|
// coord y
|
|
get_line();
|
|
ss.str(m_str); ss >> c[1]; c[1] = mm(c[1]); if(ss.fail()) return false;
|
|
break;
|
|
case 30:
|
|
// coord z
|
|
get_line();
|
|
ss.str(m_str); ss >> c[2]; c[2] = mm(c[2]); if(ss.fail()) return false;
|
|
break;
|
|
case 41:
|
|
// scale x
|
|
get_line();
|
|
ss.str(m_str); ss >> s[0]; if(ss.fail()) return false;
|
|
break;
|
|
case 42:
|
|
// scale y
|
|
get_line();
|
|
ss.str(m_str); ss >> s[1]; if(ss.fail()) return false;
|
|
break;
|
|
case 43:
|
|
// scale z
|
|
get_line();
|
|
ss.str(m_str); ss >> s[2]; if(ss.fail()) return false;
|
|
break;
|
|
case 50:
|
|
// rotation
|
|
get_line();
|
|
ss.str(m_str); ss >> rot; if(ss.fail()) return false;
|
|
break;
|
|
case 2:
|
|
// block name
|
|
get_line();
|
|
strcpy(name, m_str);
|
|
break;
|
|
case 62:
|
|
// color index
|
|
get_line();
|
|
ss.str(m_str); ss >> m_aci; if(ss.fail()) return false;
|
|
break;
|
|
case 100:
|
|
case 39:
|
|
case 210:
|
|
case 220:
|
|
case 230:
|
|
// skip the next line
|
|
get_line();
|
|
break;
|
|
default:
|
|
// skip the next line
|
|
get_line();
|
|
break;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void CDxfRead::get_line()
|
|
{
|
|
if (m_unused_line[0] != '\0')
|
|
{
|
|
strcpy(m_str, m_unused_line);
|
|
memset( m_unused_line, '\0', sizeof(m_unused_line));
|
|
return;
|
|
}
|
|
|
|
m_ifs->getline(m_str, 1024);
|
|
|
|
char str[1024];
|
|
std::size_t len = strlen(m_str);
|
|
std::size_t j = 0;
|
|
bool non_white_found = false;
|
|
for(std::size_t i = 0; i<len; i++){
|
|
if(non_white_found || (m_str[i] != ' ' && m_str[i] != '\t')){
|
|
#if wxUSE_UNICODE
|
|
if(m_str[i] != '\r')
|
|
#endif
|
|
{
|
|
str[j] = m_str[i]; j++;
|
|
}
|
|
non_white_found = true;
|
|
}
|
|
}
|
|
str[j] = 0;
|
|
strcpy(m_str, str);
|
|
}
|
|
|
|
void CDxfRead::put_line(const char *value)
|
|
{
|
|
strcpy( m_unused_line, value );
|
|
}
|
|
|
|
|
|
bool CDxfRead::ReadUnits()
|
|
{
|
|
get_line(); // Skip to next line.
|
|
get_line(); // Skip to next line.
|
|
int n = 0;
|
|
if(sscanf(m_str, "%d", &n) == 1)
|
|
{
|
|
m_eUnits = eDxfUnits_t( n );
|
|
return(true);
|
|
} // End if - then
|
|
else
|
|
{
|
|
printf("CDxfRead::ReadUnits() Failed to get integer from '%s'\n", m_str);
|
|
return(false);
|
|
}
|
|
}
|
|
|
|
|
|
bool CDxfRead::ReadLayer()
|
|
{
|
|
std::string layername;
|
|
int aci = -1;
|
|
|
|
while(!((*m_ifs).eof()))
|
|
{
|
|
get_line();
|
|
int n;
|
|
|
|
if(sscanf(m_str, "%d", &n) != 1)
|
|
{
|
|
printf("CDxfRead::ReadLayer() Failed to read integer from '%s'\n", m_str );
|
|
return false;
|
|
}
|
|
|
|
std::istringstream ss;
|
|
ss.imbue(std::locale("C"));
|
|
switch(n){
|
|
case 0: // next item found, so finish with line
|
|
if (layername.empty())
|
|
{
|
|
printf("CDxfRead::ReadLayer() - no layer name\n");
|
|
return false;
|
|
}
|
|
m_layer_aci[layername] = aci;
|
|
return true;
|
|
|
|
case 2: // Layer name follows
|
|
get_line();
|
|
layername = m_str;
|
|
break;
|
|
|
|
case 62:
|
|
// layer color ; if negative, layer is off
|
|
get_line();
|
|
if(sscanf(m_str, "%d", &aci) != 1)return false;
|
|
break;
|
|
|
|
case 6: // linetype name
|
|
case 70: // layer flags
|
|
case 100:
|
|
case 290:
|
|
case 370:
|
|
case 390:
|
|
// skip the next line
|
|
get_line();
|
|
break;
|
|
default:
|
|
// skip the next line
|
|
get_line();
|
|
break;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void CDxfRead::DoRead(const bool ignore_errors /* = false */ )
|
|
{
|
|
m_ignore_errors = ignore_errors;
|
|
if(m_fail)return;
|
|
|
|
get_line();
|
|
|
|
while(!((*m_ifs).eof()))
|
|
{
|
|
if (!strcmp( m_str, "$INSUNITS" )){
|
|
if (!ReadUnits())return;
|
|
continue;
|
|
} // End if - then
|
|
|
|
else if (!strcmp( m_str, "AcDbBlockBegin" )){
|
|
get_line();
|
|
|
|
if (! strcmp(m_str,"2"))
|
|
{
|
|
get_line();
|
|
strcpy(m_block_name, m_str);
|
|
}
|
|
} // End if - then
|
|
else if(!strcmp(m_str, "0"))
|
|
{
|
|
get_line();
|
|
if (!strcmp( m_str, "SECTION" )){
|
|
get_line();
|
|
get_line();
|
|
strcpy(m_section_name, m_str);
|
|
strcpy(m_block_name, "");
|
|
|
|
} // End if - then
|
|
else if (!strcmp( m_str, "TABLE" )){
|
|
get_line();
|
|
get_line();
|
|
}
|
|
|
|
else if (!strcmp( m_str, "LAYER" )){
|
|
get_line();
|
|
get_line();
|
|
if(!ReadLayer())
|
|
{
|
|
printf("CDxfRead::DoRead() Failed to read layer\n");
|
|
return;
|
|
}
|
|
continue; }
|
|
|
|
else if (!strcmp( m_str, "ENDSEC" )){
|
|
strcpy(m_section_name, "");
|
|
strcpy(m_block_name, "");
|
|
} // End if - then
|
|
else if(!strcmp(m_str, "LINE")){
|
|
if(!ReadLine())
|
|
{
|
|
printf("CDxfRead::DoRead() Failed to read line\n");
|
|
return;
|
|
}
|
|
continue;
|
|
}
|
|
else if(!strcmp(m_str, "ARC")){
|
|
if(!ReadArc())
|
|
{
|
|
printf("CDxfRead::DoRead() Failed to read arc\n");
|
|
return;
|
|
}
|
|
continue;
|
|
}
|
|
else if(!strcmp(m_str, "CIRCLE")){
|
|
if(!ReadCircle())
|
|
{
|
|
printf("CDxfRead::DoRead() Failed to read circle\n");
|
|
return;
|
|
}
|
|
continue;
|
|
}
|
|
else if(!strcmp(m_str, "MTEXT")){
|
|
if(!ReadText())
|
|
{
|
|
printf("CDxfRead::DoRead() Failed to read text\n");
|
|
return;
|
|
}
|
|
continue;
|
|
}
|
|
else if(!strcmp(m_str, "ELLIPSE")){
|
|
if(!ReadEllipse())
|
|
{
|
|
printf("CDxfRead::DoRead() Failed to read ellipse\n");
|
|
return;
|
|
}
|
|
continue;
|
|
}
|
|
else if(!strcmp(m_str, "SPLINE")){
|
|
if(!ReadSpline())
|
|
{
|
|
printf("CDxfRead::DoRead() Failed to read spline\n");
|
|
return;
|
|
}
|
|
continue;
|
|
}
|
|
else if (!strcmp(m_str, "LWPOLYLINE")) {
|
|
if(!ReadLwPolyLine())
|
|
{
|
|
printf("CDxfRead::DoRead() Failed to read LW Polyline\n");
|
|
return;
|
|
}
|
|
continue;
|
|
}
|
|
else if (!strcmp(m_str, "POLYLINE")) {
|
|
if(!ReadPolyLine())
|
|
{
|
|
printf("CDxfRead::DoRead() Failed to read Polyline\n");
|
|
return;
|
|
}
|
|
continue;
|
|
}
|
|
else if (!strcmp(m_str, "POINT")) {
|
|
if(!ReadPoint())
|
|
{
|
|
printf("CDxfRead::DoRead() Failed to read Point\n");
|
|
return;
|
|
}
|
|
continue;
|
|
}
|
|
else if (!strcmp(m_str, "INSERT")) {
|
|
if(!ReadInsert())
|
|
{
|
|
printf("CDxfRead::DoRead() Failed to read Insert\n");
|
|
return;
|
|
}
|
|
continue;
|
|
}
|
|
}
|
|
|
|
get_line();
|
|
}
|
|
|
|
AddGraphics();
|
|
}
|
|
|
|
|
|
void CDxfRead::DerefACI()
|
|
{
|
|
|
|
if (m_aci == 256) // if color = layer color, replace by color from layer
|
|
{
|
|
m_aci = m_layer_aci[std::string(m_layer_name)];
|
|
}
|
|
}
|
|
|
|
std::string CDxfRead::LayerName() const
|
|
{
|
|
std::string result;
|
|
|
|
if (strlen(m_section_name) > 0)
|
|
{
|
|
result.append(m_section_name);
|
|
}
|
|
|
|
if (strlen(m_block_name) > 0)
|
|
{
|
|
result.append(" ");
|
|
result.append(m_block_name);
|
|
}
|
|
|
|
if (strlen(m_layer_name) > 0)
|
|
{
|
|
result.append(" ");
|
|
result.append(m_layer_name);
|
|
}
|
|
|
|
return(result);
|
|
}
|
|
|