1437 lines
29 KiB
C++
1437 lines
29 KiB
C++
/******************************************************************************
|
|
** libDXFrw - Library to read/write DXF files (ascii & binary) **
|
|
** **
|
|
** Copyright (C) 2011 Rallaz, rallazz@gmail.com **
|
|
** **
|
|
** This library is free software, licensed under the terms of the GNU **
|
|
** General Public License as published by the Free Software Foundation, **
|
|
** either version 2 of the License, or (at your option) any later version. **
|
|
** You should have received a copy of the GNU General Public License **
|
|
** along with this program. If not, see <http://www.gnu.org/licenses/>. **
|
|
******************************************************************************/
|
|
|
|
#include <iostream>
|
|
#include <utility>
|
|
#include <math.h>
|
|
#include "drw_objects.h"
|
|
#include "intern/dxfreader.h"
|
|
#include "intern/dxfwriter.h"
|
|
|
|
// ! Base class for tables entries
|
|
/*!
|
|
* Base class for tables entries
|
|
* @author Rallaz
|
|
*/
|
|
void DRW_TableEntry::parseCode( int code, dxfReader* reader )
|
|
{
|
|
switch( code )
|
|
{
|
|
case 5:
|
|
handle = reader->getHandleString();
|
|
break;
|
|
|
|
case 330:
|
|
handleBlock = reader->getHandleString();
|
|
break;
|
|
|
|
case 2:
|
|
name = reader->getUtf8String();
|
|
break;
|
|
|
|
case 70:
|
|
flags = reader->getInt32();
|
|
break;
|
|
|
|
case 1000:
|
|
case 1001:
|
|
case 1002:
|
|
case 1003:
|
|
case 1004:
|
|
case 1005:
|
|
extData.push_back( new DRW_Variant( code, reader->getString() ) );
|
|
break;
|
|
|
|
case 1010:
|
|
case 1011:
|
|
case 1012:
|
|
case 1013:
|
|
curr = new DRW_Variant();
|
|
curr->addCoord();
|
|
curr->setCoordX( reader->getDouble() );
|
|
curr->code = code;
|
|
extData.push_back( curr );
|
|
break;
|
|
|
|
case 1020:
|
|
case 1021:
|
|
case 1022:
|
|
case 1023:
|
|
|
|
if( curr )
|
|
curr->setCoordY( reader->getDouble() );
|
|
|
|
break;
|
|
|
|
case 1030:
|
|
case 1031:
|
|
case 1032:
|
|
case 1033:
|
|
|
|
if( curr )
|
|
curr->setCoordZ( reader->getDouble() );
|
|
|
|
curr = NULL;
|
|
break;
|
|
|
|
case 1040:
|
|
case 1041:
|
|
case 1042:
|
|
extData.push_back( new DRW_Variant( code, reader->getDouble() ) );
|
|
break;
|
|
|
|
case 1070:
|
|
case 1071:
|
|
extData.push_back( new DRW_Variant( code, reader->getInt32() ) );
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
// ! Class to handle dimstyle entries
|
|
/*!
|
|
* Class to handle ldim style symbol table entries
|
|
* @author Rallaz
|
|
*/
|
|
void DRW_Dimstyle::parseCode( int code, dxfReader* reader )
|
|
{
|
|
switch( code )
|
|
{
|
|
case 105:
|
|
handle = reader->getHandleString();
|
|
break;
|
|
|
|
case 3:
|
|
dimpost = reader->getUtf8String();
|
|
break;
|
|
|
|
case 4:
|
|
dimapost = reader->getUtf8String();
|
|
break;
|
|
|
|
case 5:
|
|
dimblk = reader->getUtf8String();
|
|
break;
|
|
|
|
case 6:
|
|
dimblk1 = reader->getUtf8String();
|
|
break;
|
|
|
|
case 7:
|
|
dimblk2 = reader->getUtf8String();
|
|
break;
|
|
|
|
case 40:
|
|
dimscale = reader->getDouble();
|
|
break;
|
|
|
|
case 41:
|
|
dimasz = reader->getDouble();
|
|
break;
|
|
|
|
case 42:
|
|
dimexo = reader->getDouble();
|
|
break;
|
|
|
|
case 43:
|
|
dimdli = reader->getDouble();
|
|
break;
|
|
|
|
case 44:
|
|
dimexe = reader->getDouble();
|
|
break;
|
|
|
|
case 45:
|
|
dimrnd = reader->getDouble();
|
|
break;
|
|
|
|
case 46:
|
|
dimdle = reader->getDouble();
|
|
break;
|
|
|
|
case 47:
|
|
dimtp = reader->getDouble();
|
|
break;
|
|
|
|
case 48:
|
|
dimtm = reader->getDouble();
|
|
break;
|
|
|
|
case 140:
|
|
dimtxt = reader->getDouble();
|
|
break;
|
|
|
|
case 141:
|
|
dimcen = reader->getDouble();
|
|
break;
|
|
|
|
case 142:
|
|
dimtsz = reader->getDouble();
|
|
break;
|
|
|
|
case 143:
|
|
dimaltf = reader->getDouble();
|
|
break;
|
|
|
|
case 144:
|
|
dimlfac = reader->getDouble();
|
|
break;
|
|
|
|
case 145:
|
|
dimtvp = reader->getDouble();
|
|
break;
|
|
|
|
case 146:
|
|
dimtfac = reader->getDouble();
|
|
break;
|
|
|
|
case 147:
|
|
dimgap = reader->getDouble();
|
|
break;
|
|
|
|
case 148:
|
|
dimaltrnd = reader->getDouble();
|
|
break;
|
|
|
|
case 71:
|
|
dimtol = reader->getInt32();
|
|
break;
|
|
|
|
case 72:
|
|
dimlim = reader->getInt32();
|
|
break;
|
|
|
|
case 73:
|
|
dimtih = reader->getInt32();
|
|
break;
|
|
|
|
case 74:
|
|
dimtoh = reader->getInt32();
|
|
break;
|
|
|
|
case 75:
|
|
dimse1 = reader->getInt32();
|
|
break;
|
|
|
|
case 76:
|
|
dimse2 = reader->getInt32();
|
|
break;
|
|
|
|
case 77:
|
|
dimtad = reader->getInt32();
|
|
break;
|
|
|
|
case 78:
|
|
dimzin = reader->getInt32();
|
|
break;
|
|
|
|
case 79:
|
|
dimazin = reader->getInt32();
|
|
break;
|
|
|
|
case 170:
|
|
dimalt = reader->getInt32();
|
|
break;
|
|
|
|
case 171:
|
|
dimaltd = reader->getInt32();
|
|
break;
|
|
|
|
case 172:
|
|
dimtofl = reader->getInt32();
|
|
break;
|
|
|
|
case 173:
|
|
dimsah = reader->getInt32();
|
|
break;
|
|
|
|
case 174:
|
|
dimtix = reader->getInt32();
|
|
break;
|
|
|
|
case 175:
|
|
dimsoxd = reader->getInt32();
|
|
break;
|
|
|
|
case 176:
|
|
dimclrd = reader->getInt32();
|
|
break;
|
|
|
|
case 177:
|
|
dimclre = reader->getInt32();
|
|
break;
|
|
|
|
case 178:
|
|
dimclrt = reader->getInt32();
|
|
break;
|
|
|
|
case 179:
|
|
dimadec = reader->getInt32();
|
|
break;
|
|
|
|
case 270:
|
|
dimunit = reader->getInt32();
|
|
break;
|
|
|
|
case 271:
|
|
dimdec = reader->getInt32();
|
|
break;
|
|
|
|
case 272:
|
|
dimtdec = reader->getInt32();
|
|
break;
|
|
|
|
case 273:
|
|
dimaltu = reader->getInt32();
|
|
break;
|
|
|
|
case 274:
|
|
dimalttd = reader->getInt32();
|
|
break;
|
|
|
|
case 275:
|
|
dimaunit = reader->getInt32();
|
|
break;
|
|
|
|
case 276:
|
|
dimfrac = reader->getInt32();
|
|
break;
|
|
|
|
case 277:
|
|
dimlunit = reader->getInt32();
|
|
break;
|
|
|
|
case 278:
|
|
dimdsep = reader->getInt32();
|
|
break;
|
|
|
|
case 279:
|
|
dimtmove = reader->getInt32();
|
|
break;
|
|
|
|
case 280:
|
|
dimjust = reader->getInt32();
|
|
break;
|
|
|
|
case 281:
|
|
dimsd1 = reader->getInt32();
|
|
break;
|
|
|
|
case 282:
|
|
dimsd2 = reader->getInt32();
|
|
break;
|
|
|
|
case 283:
|
|
dimtolj = reader->getInt32();
|
|
break;
|
|
|
|
case 284:
|
|
dimtzin = reader->getInt32();
|
|
break;
|
|
|
|
case 285:
|
|
dimaltz = reader->getInt32();
|
|
break;
|
|
|
|
case 286:
|
|
dimaltttz = reader->getInt32();
|
|
break;
|
|
|
|
case 287:
|
|
dimfit = reader->getInt32();
|
|
break;
|
|
|
|
case 288:
|
|
dimupt = reader->getInt32();
|
|
break;
|
|
|
|
case 289:
|
|
dimatfit = reader->getInt32();
|
|
break;
|
|
|
|
case 340:
|
|
dimtxsty = reader->getUtf8String();
|
|
break;
|
|
|
|
case 341:
|
|
dimldrblk = reader->getUtf8String();
|
|
break;
|
|
|
|
case 342:
|
|
dimblk = reader->getUtf8String();
|
|
break;
|
|
|
|
case 343:
|
|
dimblk1 = reader->getUtf8String();
|
|
break;
|
|
|
|
case 344:
|
|
dimblk2 = reader->getUtf8String();
|
|
break;
|
|
|
|
default:
|
|
DRW_TableEntry::parseCode( code, reader );
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
// ! Class to handle line type entries
|
|
/*!
|
|
* Class to handle line type symbol table entries
|
|
* @author Rallaz
|
|
*/
|
|
void DRW_LType::parseCode( int code, dxfReader* reader )
|
|
{
|
|
switch( code )
|
|
{
|
|
case 3:
|
|
desc = reader->getUtf8String();
|
|
break;
|
|
|
|
case 73:
|
|
size = reader->getInt32();
|
|
path.reserve( size );
|
|
break;
|
|
|
|
case 40:
|
|
length = reader->getDouble();
|
|
break;
|
|
|
|
case 49:
|
|
path.push_back( reader->getDouble() );
|
|
pathIdx++;
|
|
break;
|
|
|
|
/* case 74:
|
|
* haveShape = reader->getInt32();
|
|
* break;*/
|
|
default:
|
|
DRW_TableEntry::parseCode( code, reader );
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
// ! Update line type
|
|
/*!
|
|
* Update the size and length of line type acording to the path
|
|
* @author Rallaz
|
|
*/
|
|
/*TODO: control max length permited */
|
|
void DRW_LType::update()
|
|
{
|
|
double d = 0;
|
|
|
|
size = path.size();
|
|
|
|
for( int i = 0; i< size; i++ )
|
|
{
|
|
d += fabs( path.at( i ) );
|
|
}
|
|
|
|
length = d;
|
|
}
|
|
|
|
|
|
// ! Class to handle layer entries
|
|
/*!
|
|
* Class to handle layer symbol table entries
|
|
* @author Rallaz
|
|
*/
|
|
void DRW_Layer::parseCode( int code, dxfReader* reader )
|
|
{
|
|
switch( code )
|
|
{
|
|
case 6:
|
|
lineType = reader->getUtf8String();
|
|
break;
|
|
|
|
case 62:
|
|
color = reader->getInt32();
|
|
break;
|
|
|
|
case 290:
|
|
plotF = reader->getBool();
|
|
break;
|
|
|
|
case 370:
|
|
lWeight = DRW_LW_Conv::dxfInt2lineWidth( reader->getInt32() );
|
|
break;
|
|
|
|
case 390:
|
|
handlePlotS = reader->getString();
|
|
break;
|
|
|
|
case 347:
|
|
handlePlotM = reader->getString();
|
|
break;
|
|
|
|
case 420:
|
|
color24 = reader->getInt32();
|
|
break;
|
|
|
|
default:
|
|
DRW_TableEntry::parseCode( code, reader );
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
// ! Class to handle text style entries
|
|
/*!
|
|
* Class to handle text style symbol table entries
|
|
* @author Rallaz
|
|
*/
|
|
void DRW_Textstyle::parseCode( int code, dxfReader* reader )
|
|
{
|
|
switch( code )
|
|
{
|
|
case 3:
|
|
font = reader->getUtf8String();
|
|
break;
|
|
|
|
case 4:
|
|
bigFont = reader->getUtf8String();
|
|
break;
|
|
|
|
case 40:
|
|
height = reader->getDouble();
|
|
break;
|
|
|
|
case 41:
|
|
width = reader->getDouble();
|
|
break;
|
|
|
|
case 50:
|
|
oblique = reader->getDouble();
|
|
break;
|
|
|
|
case 42:
|
|
lastHeight = reader->getDouble();
|
|
break;
|
|
|
|
case 71:
|
|
genFlag = reader->getInt32();
|
|
break;
|
|
|
|
case 1071:
|
|
fontFamily = reader->getInt32();
|
|
break;
|
|
|
|
default:
|
|
DRW_TableEntry::parseCode( code, reader );
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
// ! Class to handle vport entries
|
|
/*!
|
|
* Class to handle vport symbol table entries
|
|
* @author Rallaz
|
|
*/
|
|
void DRW_Vport::parseCode( int code, dxfReader* reader )
|
|
{
|
|
switch( code )
|
|
{
|
|
case 10:
|
|
lowerLeft.x = reader->getDouble();
|
|
break;
|
|
|
|
case 20:
|
|
lowerLeft.y = reader->getDouble();
|
|
break;
|
|
|
|
case 11:
|
|
UpperRight.x = reader->getDouble();
|
|
break;
|
|
|
|
case 21:
|
|
UpperRight.y = reader->getDouble();
|
|
break;
|
|
|
|
case 12:
|
|
center.x = reader->getDouble();
|
|
break;
|
|
|
|
case 22:
|
|
center.y = reader->getDouble();
|
|
break;
|
|
|
|
case 13:
|
|
snapBase.x = reader->getDouble();
|
|
break;
|
|
|
|
case 23:
|
|
snapBase.y = reader->getDouble();
|
|
break;
|
|
|
|
case 14:
|
|
snapSpacing.x = reader->getDouble();
|
|
break;
|
|
|
|
case 24:
|
|
snapSpacing.y = reader->getDouble();
|
|
break;
|
|
|
|
case 15:
|
|
gridSpacing.x = reader->getDouble();
|
|
break;
|
|
|
|
case 25:
|
|
gridSpacing.y = reader->getDouble();
|
|
break;
|
|
|
|
case 16:
|
|
viewDir.x = reader->getDouble();
|
|
break;
|
|
|
|
case 26:
|
|
viewDir.y = reader->getDouble();
|
|
break;
|
|
|
|
case 36:
|
|
viewDir.z = reader->getDouble();
|
|
break;
|
|
|
|
case 17:
|
|
viewTarget.x = reader->getDouble();
|
|
break;
|
|
|
|
case 27:
|
|
viewTarget.y = reader->getDouble();
|
|
break;
|
|
|
|
case 37:
|
|
viewTarget.z = reader->getDouble();
|
|
break;
|
|
|
|
case 40:
|
|
height = reader->getDouble();
|
|
break;
|
|
|
|
case 41:
|
|
ratio = reader->getDouble();
|
|
break;
|
|
|
|
case 42:
|
|
lensHeight = reader->getDouble();
|
|
break;
|
|
|
|
case 43:
|
|
frontClip = reader->getDouble();
|
|
break;
|
|
|
|
case 44:
|
|
backClip = reader->getDouble();
|
|
break;
|
|
|
|
case 50:
|
|
snapAngle = reader->getDouble();
|
|
break;
|
|
|
|
case 51:
|
|
twistAngle = reader->getDouble();
|
|
break;
|
|
|
|
case 71:
|
|
viewMode = reader->getInt32();
|
|
break;
|
|
|
|
case 72:
|
|
circleZoom = reader->getInt32();
|
|
break;
|
|
|
|
case 73:
|
|
fastZoom = reader->getInt32();
|
|
break;
|
|
|
|
case 74:
|
|
ucsIcon = reader->getInt32();
|
|
break;
|
|
|
|
case 75:
|
|
snap = reader->getInt32();
|
|
break;
|
|
|
|
case 76:
|
|
grid = reader->getInt32();
|
|
break;
|
|
|
|
case 77:
|
|
snapStyle = reader->getInt32();
|
|
break;
|
|
|
|
case 78:
|
|
snapIsopair = reader->getInt32();
|
|
break;
|
|
|
|
default:
|
|
DRW_TableEntry::parseCode( code, reader );
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
void DRW_ImageDef::parseCode( int code, dxfReader* reader )
|
|
{
|
|
switch( code )
|
|
{
|
|
case 1:
|
|
name = reader->getUtf8String();
|
|
break;
|
|
|
|
case 5:
|
|
handle = reader->getString();
|
|
break;
|
|
|
|
case 10:
|
|
u = reader->getDouble();
|
|
break;
|
|
|
|
case 20:
|
|
v = reader->getDouble();
|
|
break;
|
|
|
|
case 11:
|
|
up = reader->getDouble();
|
|
break;
|
|
|
|
case 12:
|
|
vp = reader->getDouble();
|
|
break;
|
|
|
|
case 21:
|
|
vp = reader->getDouble();
|
|
break;
|
|
|
|
case 280:
|
|
loaded = reader->getInt32();
|
|
break;
|
|
|
|
case 281:
|
|
resolution = reader->getInt32();
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
void DRW_Header::addComment( const std::string& c )
|
|
{
|
|
if( !comments.empty() )
|
|
comments += '\n';
|
|
|
|
comments += c;
|
|
}
|
|
|
|
|
|
void DRW_Header::parseCode( int code, dxfReader* reader )
|
|
{
|
|
switch( code )
|
|
{
|
|
case 9:
|
|
curr = new DRW_Variant();
|
|
name = reader->getString();
|
|
|
|
if( version < DRW::AC1015 && name == "$DIMUNIT" )
|
|
name = "$DIMLUNIT";
|
|
|
|
vars[name] = curr;
|
|
break;
|
|
|
|
case 1:
|
|
curr->addString( reader->getUtf8String() );
|
|
|
|
if( name =="$ACADVER" )
|
|
{
|
|
reader->setVersion( curr->content.s );
|
|
version = reader->getVersion();
|
|
}
|
|
|
|
curr->code = code;
|
|
break;
|
|
|
|
case 2:
|
|
curr->addString( reader->getUtf8String() );
|
|
curr->code = code;
|
|
break;
|
|
|
|
case 3:
|
|
curr->addString( reader->getUtf8String() );
|
|
|
|
if( name =="$DWGCODEPAGE" )
|
|
{
|
|
reader->setCodePage( curr->content.s );
|
|
curr->addString( reader->getCodePage() );
|
|
}
|
|
|
|
curr->code = code;
|
|
break;
|
|
|
|
case 6:
|
|
curr->addString( reader->getUtf8String() );
|
|
curr->code = code;
|
|
break;
|
|
|
|
case 7:
|
|
curr->addString( reader->getUtf8String() );
|
|
curr->code = code;
|
|
break;
|
|
|
|
case 8:
|
|
curr->addString( reader->getUtf8String() );
|
|
curr->code = code;
|
|
break;
|
|
|
|
case 10:
|
|
curr->addCoord();
|
|
curr->setCoordX( reader->getDouble() );
|
|
curr->code = code;
|
|
break;
|
|
|
|
case 20:
|
|
curr->setCoordY( reader->getDouble() );
|
|
break;
|
|
|
|
case 30:
|
|
curr->setCoordZ( reader->getDouble() );
|
|
curr->code = code;
|
|
break;
|
|
|
|
case 40:
|
|
curr->addDouble( reader->getDouble() );
|
|
curr->code = code;
|
|
break;
|
|
|
|
case 50:
|
|
curr->addDouble( reader->getDouble() );
|
|
curr->code = code;
|
|
break;
|
|
|
|
case 62:
|
|
curr->addInt( reader->getInt32() );
|
|
curr->code = code;
|
|
break;
|
|
|
|
case 70:
|
|
curr->addInt( reader->getInt32() );
|
|
curr->code = code;
|
|
break;
|
|
|
|
case 280:
|
|
curr->addInt( reader->getInt32() );
|
|
curr->code = code;
|
|
break;
|
|
|
|
case 290:
|
|
curr->addInt( reader->getInt32() );
|
|
curr->code = code;
|
|
break;
|
|
|
|
case 370:
|
|
curr->addInt( reader->getInt32() );
|
|
curr->code = code;
|
|
break;
|
|
|
|
case 380:
|
|
curr->addInt( reader->getInt32() );
|
|
curr->code = code;
|
|
break;
|
|
|
|
case 390:
|
|
curr->addString( reader->getUtf8String() );
|
|
curr->code = code;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
void DRW_Header::write( dxfWriter* writer, DRW::Version ver )
|
|
{
|
|
/*RLZ: TODO complete all vars to AC1024*/
|
|
double varDouble;
|
|
int varInt;
|
|
std::string varStr;
|
|
DRW_Coord varCoord;
|
|
|
|
writer->writeString( 2, "HEADER" );
|
|
writer->writeString( 9, "$ACADVER" );
|
|
|
|
switch( ver )
|
|
{
|
|
case DRW::AC1006: // unsupported version acad 10
|
|
case DRW::AC1009: // acad 11 & 12
|
|
varStr = "AC1009";
|
|
break;
|
|
|
|
case DRW::AC1012: // unsupported version acad 13
|
|
case DRW::AC1014: // acad 14
|
|
varStr = "AC1014";
|
|
break;
|
|
|
|
case DRW::AC1015: // acad 2000
|
|
varStr = "AC1015";
|
|
break;
|
|
|
|
case DRW::AC1018: // acad 2004
|
|
varStr = "AC1018";
|
|
break;
|
|
|
|
/* case DRW::AC1021: //acad 2007
|
|
* varStr = "AC1021";
|
|
* break;*/
|
|
case DRW::AC1024: // acad 2010
|
|
varStr = "AC1024";
|
|
break;
|
|
|
|
default: // acad 2007 default version
|
|
varStr = "AC1021";
|
|
break;
|
|
}
|
|
|
|
writer->writeString( 1, varStr );
|
|
writer->setVersion( &varStr );
|
|
|
|
getStr( "$ACADVER", &varStr );
|
|
getStr( "$ACADMAINTVER", &varStr );
|
|
|
|
if( ver > DRW::AC1012 )
|
|
{
|
|
writer->writeString( 9, "$HANDSEED" );
|
|
// RLZ dxfHex(5, 0xFFFF);
|
|
writer->writeString( 5, "20000" );
|
|
}
|
|
|
|
if( !getStr( "$DWGCODEPAGE", &varStr ) )
|
|
{
|
|
varStr = "ANSI_1252";
|
|
}
|
|
|
|
writer->writeString( 9, "$DWGCODEPAGE" );
|
|
writer->setCodePage( &varStr );
|
|
writer->writeString( 3, writer->getCodePage() );
|
|
writer->writeString( 9, "$INSBASE" );
|
|
|
|
if( getCoord( "$INSBASE", &varCoord ) )
|
|
{
|
|
writer->writeDouble( 10, varCoord.x );
|
|
writer->writeDouble( 20, varCoord.y );
|
|
writer->writeDouble( 30, varCoord.z );
|
|
}
|
|
else
|
|
{
|
|
writer->writeDouble( 10, 0.0 );
|
|
writer->writeDouble( 20, 0.0 );
|
|
writer->writeDouble( 30, 0.0 );
|
|
}
|
|
|
|
writer->writeString( 9, "$EXTMIN" );
|
|
|
|
if( getCoord( "$EXTMIN", &varCoord ) )
|
|
{
|
|
writer->writeDouble( 10, varCoord.x );
|
|
writer->writeDouble( 20, varCoord.y );
|
|
writer->writeDouble( 30, varCoord.z );
|
|
}
|
|
else
|
|
{
|
|
writer->writeDouble( 10, 1.0000000000000000E+020 );
|
|
writer->writeDouble( 20, 1.0000000000000000E+020 );
|
|
writer->writeDouble( 30, 1.0000000000000000E+020 );
|
|
}
|
|
|
|
writer->writeString( 9, "$EXTMAX" );
|
|
|
|
if( getCoord( "$EXTMAX", &varCoord ) )
|
|
{
|
|
writer->writeDouble( 10, varCoord.x );
|
|
writer->writeDouble( 20, varCoord.y );
|
|
writer->writeDouble( 30, varCoord.z );
|
|
}
|
|
else
|
|
{
|
|
writer->writeDouble( 10, -1.0000000000000000E+020 );
|
|
writer->writeDouble( 20, -1.0000000000000000E+020 );
|
|
writer->writeDouble( 30, -1.0000000000000000E+020 );
|
|
}
|
|
|
|
writer->writeString( 9, "$LIMMIN" );
|
|
|
|
if( getCoord( "$LIMMIN", &varCoord ) )
|
|
{
|
|
writer->writeDouble( 10, varCoord.x );
|
|
writer->writeDouble( 20, varCoord.y );
|
|
}
|
|
else
|
|
{
|
|
writer->writeDouble( 10, 0.0 );
|
|
writer->writeDouble( 20, 0.0 );
|
|
}
|
|
|
|
writer->writeString( 9, "$LIMMAX" );
|
|
|
|
if( getCoord( "$LIMMAX", &varCoord ) )
|
|
{
|
|
writer->writeDouble( 10, varCoord.x );
|
|
writer->writeDouble( 20, varCoord.y );
|
|
}
|
|
else
|
|
{
|
|
writer->writeDouble( 10, 420.0 );
|
|
writer->writeDouble( 20, 297.0 );
|
|
}
|
|
|
|
writer->writeString( 9, "$ORTHOMODE" );
|
|
|
|
if( getInt( "$ORTHOMODE", &varInt ) )
|
|
writer->writeInt16( 70, varInt );
|
|
else
|
|
writer->writeInt16( 70, 0 );
|
|
|
|
writer->writeString( 9, "$LTSCALE" );
|
|
|
|
if( getDouble( "$LTSCALE", &varDouble ) )
|
|
writer->writeDouble( 40, varDouble );
|
|
else
|
|
writer->writeDouble( 40, 1.0 );
|
|
|
|
writer->writeString( 9, "$TEXTSTYLE" );
|
|
|
|
if( getStr( "$TEXTSTYLE", &varStr ) )
|
|
if( ver == DRW::AC1009 )
|
|
writer->writeUtf8Caps( 7, varStr );
|
|
else
|
|
writer->writeUtf8String( 7, varStr );
|
|
|
|
|
|
|
|
|
|
else
|
|
writer->writeString( 7, "STANDARD" );
|
|
|
|
writer->writeString( 9, "$CLAYER" );
|
|
|
|
if( getStr( "$CLAYER", &varStr ) )
|
|
if( ver == DRW::AC1009 )
|
|
writer->writeUtf8Caps( 8, varStr );
|
|
else
|
|
writer->writeUtf8String( 8, varStr );
|
|
|
|
|
|
|
|
|
|
else
|
|
writer->writeString( 8, "0" );
|
|
|
|
writer->writeString( 9, "$DIMASZ" );
|
|
|
|
if( getDouble( "$DIMASZ", &varDouble ) )
|
|
writer->writeDouble( 40, varDouble );
|
|
else
|
|
writer->writeDouble( 40, 2.5 );
|
|
|
|
writer->writeString( 9, "$DIMLFAC" );
|
|
|
|
if( getDouble( "$DIMLFAC", &varDouble ) )
|
|
writer->writeDouble( 40, varDouble );
|
|
else
|
|
writer->writeDouble( 40, 1.0 );
|
|
|
|
writer->writeString( 9, "$DIMSCALE" );
|
|
|
|
if( getDouble( "$DIMSCALE", &varDouble ) )
|
|
writer->writeDouble( 40, varDouble );
|
|
else
|
|
writer->writeDouble( 40, 1.0 );
|
|
|
|
writer->writeString( 9, "$DIMEXO" );
|
|
|
|
if( getDouble( "$DIMEXO", &varDouble ) )
|
|
writer->writeDouble( 40, varDouble );
|
|
else
|
|
writer->writeDouble( 40, 0.625 );
|
|
|
|
writer->writeString( 9, "$DIMEXE" );
|
|
|
|
if( getDouble( "$DIMEXE", &varDouble ) )
|
|
writer->writeDouble( 40, varDouble );
|
|
else
|
|
writer->writeDouble( 40, 1.25 );
|
|
|
|
writer->writeString( 9, "$DIMTXT" );
|
|
|
|
if( getDouble( "$DIMTXT", &varDouble ) )
|
|
writer->writeDouble( 40, varDouble );
|
|
else
|
|
writer->writeDouble( 40, 2.5 );
|
|
|
|
writer->writeString( 9, "$DIMTSZ" );
|
|
|
|
if( getDouble( "$DIMTSZ", &varDouble ) )
|
|
writer->writeDouble( 40, varDouble );
|
|
else
|
|
writer->writeDouble( 40, 0.0 );
|
|
|
|
if( ver > DRW::AC1009 )
|
|
{
|
|
writer->writeString( 9, "$DIMAUNIT" );
|
|
|
|
if( getInt( "$DIMAUNIT", &varInt ) )
|
|
writer->writeInt16( 70, varInt );
|
|
else
|
|
writer->writeInt16( 70, 0 );
|
|
|
|
writer->writeString( 9, "$DIMADEC" );
|
|
|
|
if( getInt( "$DIMADEC", &varInt ) )
|
|
writer->writeInt16( 70, varInt );
|
|
else
|
|
writer->writeInt16( 70, 0 );
|
|
}
|
|
|
|
// verify if exist "$DIMLUNIT" or obsolete "$DIMUNIT" (pre v2000)
|
|
if( !getInt( "$DIMLUNIT", &varInt ) )
|
|
{
|
|
if( !getInt( "$DIMUNIT", &varInt ) )
|
|
varInt = 2;
|
|
}
|
|
|
|
// verify valid values from 1 to 6
|
|
if( varInt<1 || varInt>6 )
|
|
varInt = 2;
|
|
|
|
if( ver > DRW::AC1014 )
|
|
{
|
|
writer->writeString( 9, "$DIMLUNIT" );
|
|
writer->writeInt16( 70, varInt );
|
|
}
|
|
else
|
|
{
|
|
writer->writeString( 9, "$DIMUNIT" );
|
|
writer->writeInt16( 70, varInt );
|
|
}
|
|
|
|
writer->writeString( 9, "$DIMSTYLE" );
|
|
|
|
if( getStr( "$DIMSTYLE", &varStr ) )
|
|
if( ver == DRW::AC1009 )
|
|
writer->writeUtf8Caps( 2, varStr );
|
|
else
|
|
writer->writeUtf8String( 2, varStr );
|
|
|
|
|
|
|
|
|
|
else
|
|
writer->writeString( 2, "STANDARD" );
|
|
|
|
writer->writeString( 9, "$DIMGAP" );
|
|
|
|
if( getDouble( "$DIMGAP", &varDouble ) )
|
|
writer->writeDouble( 40, varDouble );
|
|
else
|
|
writer->writeDouble( 40, 0.625 );
|
|
|
|
writer->writeString( 9, "$DIMTIH" );
|
|
|
|
if( getInt( "$DIMTIH", &varInt ) )
|
|
writer->writeInt16( 70, varInt );
|
|
else
|
|
writer->writeInt16( 70, 0 );
|
|
|
|
writer->writeString( 9, "$LUNITS" );
|
|
|
|
if( getInt( "$LUNITS", &varInt ) )
|
|
writer->writeInt16( 70, varInt );
|
|
else
|
|
writer->writeInt16( 70, 2 );
|
|
|
|
writer->writeString( 9, "$LUPREC" );
|
|
|
|
if( getInt( "$LUPREC", &varInt ) )
|
|
writer->writeInt16( 70, varInt );
|
|
else
|
|
writer->writeInt16( 70, 4 );
|
|
|
|
writer->writeString( 9, "$AUNITS" );
|
|
|
|
if( getInt( "$AUNITS", &varInt ) )
|
|
writer->writeInt16( 70, varInt );
|
|
else
|
|
writer->writeInt16( 70, 0 );
|
|
|
|
writer->writeString( 9, "$AUPREC" );
|
|
|
|
if( getInt( "$AUPREC", &varInt ) )
|
|
writer->writeInt16( 70, varInt );
|
|
else
|
|
writer->writeInt16( 70, 2 );
|
|
|
|
if( ver > DRW::AC1009 )
|
|
{
|
|
writer->writeString( 9, "$SPLINESEGS" );
|
|
|
|
if( getInt( "$SPLINESEGS", &varInt ) )
|
|
{
|
|
writer->writeInt16( 70, varInt );
|
|
}
|
|
else
|
|
writer->writeInt16( 70, 8 );
|
|
}
|
|
|
|
/* RLZ: moved to active VPORT, but can write in header if present*/
|
|
if( getInt( "$GRIDMODE", &varInt ) )
|
|
{
|
|
writer->writeString( 9, "$GRIDMODE" );
|
|
writer->writeInt16( 70, varInt );
|
|
}
|
|
|
|
if( getInt( "$SNAPSTYLE", &varInt ) )
|
|
{
|
|
writer->writeString( 9, "$SNAPSTYLE" );
|
|
writer->writeInt16( 70, varInt );
|
|
}
|
|
|
|
if( getCoord( "$GRIDUNIT", &varCoord ) )
|
|
{
|
|
writer->writeString( 9, "$GRIDUNIT" );
|
|
writer->writeDouble( 10, varCoord.x );
|
|
writer->writeDouble( 20, varCoord.y );
|
|
}
|
|
|
|
if( getCoord( "$VIEWCTR", &varCoord ) )
|
|
{
|
|
writer->writeString( 9, "$VIEWCTR" );
|
|
writer->writeDouble( 10, varCoord.x );
|
|
writer->writeDouble( 20, varCoord.y );
|
|
}
|
|
|
|
/* RLZ: moved to active VPORT, but can write in header if present*/
|
|
|
|
if( ver > DRW::AC1009 )
|
|
{
|
|
writer->writeString( 9, "$PINSBASE" );
|
|
|
|
if( getCoord( "$PINSBASE", &varCoord ) )
|
|
{
|
|
writer->writeDouble( 10, varCoord.x );
|
|
writer->writeDouble( 20, varCoord.y );
|
|
writer->writeDouble( 30, varCoord.z );
|
|
}
|
|
else
|
|
{
|
|
writer->writeDouble( 10, 0.0 );
|
|
writer->writeDouble( 20, 0.0 );
|
|
writer->writeDouble( 30, 0.0 );
|
|
}
|
|
}
|
|
|
|
writer->writeString( 9, "$PLIMMIN" );
|
|
|
|
if( getCoord( "$PLIMMIN", &varCoord ) )
|
|
{
|
|
writer->writeDouble( 10, varCoord.x );
|
|
writer->writeDouble( 20, varCoord.y );
|
|
}
|
|
else
|
|
{
|
|
writer->writeDouble( 10, 0.0 );
|
|
writer->writeDouble( 20, 0.0 );
|
|
}
|
|
|
|
writer->writeString( 9, "$PLIMMAX" );
|
|
|
|
if( getCoord( "$PLIMMAX", &varCoord ) )
|
|
{
|
|
writer->writeDouble( 10, varCoord.x );
|
|
writer->writeDouble( 20, varCoord.y );
|
|
}
|
|
else
|
|
{
|
|
writer->writeDouble( 10, 297.0 );
|
|
writer->writeDouble( 20, 210.0 );
|
|
}
|
|
|
|
if( ver > DRW::AC1014 )
|
|
{
|
|
writer->writeString( 9, "$INSUNITS" );
|
|
|
|
if( getInt( "$INSUNITS", &varInt ) )
|
|
writer->writeInt16( 70, varInt );
|
|
else
|
|
writer->writeInt16( 70, 0 );
|
|
}
|
|
|
|
if( ver > DRW::AC1009 )
|
|
{
|
|
writer->writeString( 9, "$PSVPSCALE" );
|
|
|
|
if( getDouble( "$PSVPSCALE", &varDouble ) )
|
|
writer->writeDouble( 40, varDouble );
|
|
else
|
|
writer->writeDouble( 40, 0.0 );
|
|
}
|
|
|
|
#ifdef DRW_DBG
|
|
std::map<std::string, DRW_Variant*>::const_iterator it;
|
|
|
|
for( it = vars.begin(); it != vars.end(); ++it )
|
|
{
|
|
// QString key = QString::fromStdString((*it).first);
|
|
std::cerr << (*it).first << std::endl;
|
|
}
|
|
|
|
#endif
|
|
}
|
|
|
|
|
|
void DRW_Header::addDouble( const std::string& key, double value, int code )
|
|
{
|
|
curr = new DRW_Variant();
|
|
curr->addDouble( value );
|
|
curr->code = code;
|
|
vars[key] = curr;
|
|
}
|
|
|
|
|
|
void DRW_Header::addInt( const std::string& key, int value, int code )
|
|
{
|
|
curr = new DRW_Variant();
|
|
curr->addInt( value );
|
|
curr->code = code;
|
|
vars[key] = curr;
|
|
}
|
|
|
|
|
|
void DRW_Header::addStr( const std::string& key, std::string value, int code )
|
|
{
|
|
curr = new DRW_Variant();
|
|
curr->addString( std::move(value) );
|
|
curr->code = code;
|
|
vars[key] = curr;
|
|
}
|
|
|
|
|
|
void DRW_Header::addCoord( const std::string& key, DRW_Coord value, int code )
|
|
{
|
|
curr = new DRW_Variant();
|
|
curr->addCoord( value );
|
|
curr->code = code;
|
|
vars[key] = curr;
|
|
}
|
|
|
|
|
|
bool DRW_Header::getDouble( const std::string& key, double* varDouble )
|
|
{
|
|
bool result = false;
|
|
std::map<std::string, DRW_Variant*>::iterator it;
|
|
|
|
it = vars.find( key );
|
|
|
|
if( it != vars.end() )
|
|
{
|
|
DRW_Variant* var = (*it).second;
|
|
|
|
if( var->type == DRW_Variant::DOUBLE )
|
|
{
|
|
*varDouble = var->content.d;
|
|
result = true;
|
|
}
|
|
|
|
vars.erase( it );
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
bool DRW_Header::getInt( const std::string& key, int* varInt )
|
|
{
|
|
bool result = false;
|
|
std::map<std::string, DRW_Variant*>::iterator it;
|
|
|
|
it = vars.find( key );
|
|
|
|
if( it != vars.end() )
|
|
{
|
|
DRW_Variant* var = (*it).second;
|
|
|
|
if( var->type == DRW_Variant::INTEGER )
|
|
{
|
|
*varInt = var->content.i;
|
|
result = true;
|
|
}
|
|
|
|
vars.erase( it );
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
bool DRW_Header::getStr( const std::string& key, std::string* varStr )
|
|
{
|
|
bool result = false;
|
|
std::map<std::string, DRW_Variant*>::iterator it;
|
|
|
|
it = vars.find( key );
|
|
|
|
if( it != vars.end() )
|
|
{
|
|
DRW_Variant* var = (*it).second;
|
|
|
|
if( var->type == DRW_Variant::STRING )
|
|
{
|
|
*varStr = *var->content.s;
|
|
result = true;
|
|
}
|
|
|
|
vars.erase( it );
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
bool DRW_Header::getCoord( const std::string& key, DRW_Coord* varCoord )
|
|
{
|
|
bool result = false;
|
|
std::map<std::string, DRW_Variant*>::iterator it;
|
|
|
|
it = vars.find( key );
|
|
|
|
if( it != vars.end() )
|
|
{
|
|
DRW_Variant* var = (*it).second;
|
|
|
|
if( var->type == DRW_Variant::COORD )
|
|
{
|
|
*varCoord = *var->content.v;
|
|
result = true;
|
|
}
|
|
|
|
vars.erase( it );
|
|
}
|
|
|
|
return result;
|
|
}
|