valentina/src/libs/vdxf/libdxfrw/libdxfrw.cpp

3101 lines
101 KiB
C++
Raw Normal View History

/******************************************************************************
** libDXFrw - Library to read/write DXF files (ascii & binary) **
** **
** Copyright (C) 2011-2015 José F. Soriano, 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 "libdxfrw.h"
#include <fstream>
#include <algorithm>
#include <sstream>
#include <cassert>
#include <QScopedPointer>
#include "intern/drw_textcodec.h"
#include "intern/dxfreader.h"
#include "intern/dxfwriter.h"
#include "intern/drw_dbg.h"
2022-08-22 10:34:02 +02:00
#if QT_VERSION < QT_VERSION_CHECK(5, 5, 0)
#include "../vmisc/diagnostic.h"
2022-08-22 10:34:02 +02:00
#endif // QT_VERSION < QT_VERSION_CHECK(5, 5, 0)
#define FIRSTHANDLE 48
/*enum sections {
secUnknown,
secHeader,
secTables,
secBlocks,
secEntities,
secObjects
};*/
2017-07-05 18:35:34 +02:00
dxfRW::dxfRW(const char* name)
: version(),
fileName(name),
codePage(),
binFile(),
reader(nullptr),
writer(nullptr),
iface(),
header(),
nextentity(),
entCount(),
wlayer0(),
dimstyleStd(),
applyExt(false),
writingBlock(),
elParts(128), //parts number when convert ellipse to polyline
2017-07-05 18:35:34 +02:00
blockMap(),
imageDef(),
currHandle()
{
2021-11-23 10:28:54 +01:00
DRW_DBGSL(DRW_dbg::Level::None);
}
2017-07-05 18:35:34 +02:00
dxfRW::~dxfRW(){
2017-07-05 18:35:34 +02:00
if (reader != nullptr)
delete reader;
2017-07-05 18:35:34 +02:00
if (writer != nullptr)
delete writer;
for (std::vector<DRW_ImageDef*>::iterator it=imageDef.begin(); it!=imageDef.end(); ++it)
delete *it;
imageDef.clear();
}
2021-11-23 10:28:54 +01:00
void dxfRW::setDebug(DRW::DebugLevel lvl){
switch (lvl){
2021-11-23 10:28:54 +01:00
case DRW::DebugLevel::Debug:
DRW_DBGSL(DRW_dbg::Level::Debug);
break;
default:
2021-11-23 10:28:54 +01:00
DRW_DBGSL(DRW_dbg::Level::None);
}
}
bool dxfRW::read(DRW_Interface *interface_, bool ext){
drw_assert(fileName.empty() == false);
applyExt = ext;
std::ifstream filestr;
if (nullptr == interface_) {
return setError(DRW::BAD_UNKNOWN);
}
DRW_DBG("dxfRW::read 1def\n");
filestr.open (fileName.c_str(), std::ios_base::in | std::ios::binary);
if (!filestr.is_open() || !filestr.good()) {
return setError(DRW::BAD_OPEN);
}
char line[22];
char line2[22] = "AutoCAD Binary DXF\r\n";
2017-07-05 18:35:34 +02:00
line2[20] = static_cast<char>(26);
line2[21] = '\0';
filestr.read (line, 22);
filestr.close();
iface = interface_;
DRW_DBG("dxfRW::read 2\n");
if (strcmp(line, line2) == 0) {
filestr.open (fileName.c_str(), std::ios_base::in | std::ios::binary);
binFile = true;
//skip sentinel
filestr.seekg (22, std::ios::beg);
reader = new dxfReaderBinary(&filestr);
DRW_DBG("dxfRW::read binary file\n");
} else {
binFile = false;
filestr.open (fileName.c_str(), std::ios_base::in);
reader = new dxfReaderAscii(&filestr);
}
bool isOk = processDxf();
filestr.close();
delete reader;
2017-07-05 18:35:34 +02:00
reader = nullptr;
return isOk;
}
bool dxfRW::write(DRW_Interface *interface_, DRW::Version ver, bool bin){
bool isOk = false;
std::ofstream filestr;
filestr.exceptions(std::ifstream::failbit | std::ifstream::badbit);
version = ver;
binFile = bin;
iface = interface_;
try
{
if (binFile) {
filestr.open (fileName.c_str(), std::ios_base::out | std::ios::binary | std::ios::trunc);
//write sentinel
filestr << "AutoCAD Binary DXF\r\n" << static_cast<char>(26) << '\0';
writer = new dxfWriterBinary(&filestr);
DRW_DBG("dxfRW::read binary file\n");
} else {
filestr.open (fileName.c_str(), std::ios_base::out | std::ios::trunc);
writer = new dxfWriterAscii(&filestr);
std::string comm = std::string("dxfrw ") + std::string(DRW_VERSION);
writer->writeString(999, comm);
}
this->header = DRW_Header();
iface->writeHeader(header);
writer->writeString(0, "SECTION");
entCount = FIRSTHANDLE;
header.write(writer, version);
writer->writeString(0, "ENDSEC");
if (ver > DRW::AC1009) {
writer->writeString(0, "SECTION");
writer->writeString(2, "CLASSES");
writer->writeString(0, "ENDSEC");
}
writer->writeString(0, "SECTION");
writer->writeString(2, "TABLES");
writeTables();
writer->writeString(0, "ENDSEC");
writer->writeString(0, "SECTION");
writer->writeString(2, "BLOCKS");
writeBlocks();
writer->writeString(0, "ENDSEC");
writer->writeString(0, "SECTION");
writer->writeString(2, "ENTITIES");
iface->writeEntities();
writer->writeString(0, "ENDSEC");
if (version > DRW::AC1009) {
writer->writeString(0, "SECTION");
writer->writeString(2, "OBJECTS");
writeObjects();
writer->writeString(0, "ENDSEC");
}
writer->writeString(0, "EOF");
filestr.flush();
filestr.close();
}
catch(std::ofstream::failure &writeErr)
{
errorString = writeErr.what();
delete writer;
writer = nullptr;
return isOk;
}
isOk = true;
delete writer;
2017-07-05 18:35:34 +02:00
writer = nullptr;
return isOk;
}
bool dxfRW::writeEntity(DRW_Entity *ent)
{
// A handle is an arbitrary but in your DXF file unique hex value as string like 10FF. It is common to to use
// uppercase letters for hex numbers. Handle can have up to 16 hexadecimal digits (8 bytes).
//
// For DXF R10 until R12 the usage of handles was optional. The header variable $HANDLING set to 1 indicate the
// usage of handles, else $HANDLING is 0 or missing.
//
// For DXF R13 and later the usage of handles is mandatory and the header variable $HANDLING was removed.
if (version < DRW::AC1012)
{
int varInt = 0;
if (header.getInt("$HANDLING", &varInt))
{
if (varInt != 0)
{
ent->handle = static_cast<duint32>(++entCount);
writer->writeString(5, toHexStr(static_cast<int>(ent->handle)));
}
}
}
else
{
ent->handle = static_cast<duint32>(++entCount);
writer->writeString(5, toHexStr(static_cast<int>(ent->handle)));
}
if (version > DRW::AC1009) {
writer->writeString(100, "AcDbEntity");
}
if (ent->space == 1)
writer->writeInt16(67, 1);
if (version > DRW::AC1009) {
writer->writeUtf8String(8, ent->layer);
writer->writeUtf8String(6, ent->lineType);
} else {
writer->writeUtf8Caps(8, ent->layer);
writer->writeUtf8Caps(6, ent->lineType);
}
writer->writeInt16(62, ent->color);
if (version > DRW::AC1015 && ent->color24 >= 0) {
writer->writeInt32(420, ent->color24);
}
if (version > DRW::AC1014) {
writer->writeInt16(370, DRW_LW_Conv::lineWidth2dxfInt(ent->lWeight));
}
if (version >= DRW::AC1014) {
writeAppData(ent->appData);
}
return true;
}
bool dxfRW::writeAppData(const std::list<std::list<DRW_Variant>>& appData) {
for(const auto& group : appData) {
//Search for application name
bool found = false;
for(const auto& data : group) {
if(data.code == 102 && data.type == DRW_Variant::STRING) {
writer->writeString(102, "{" + *(data.content.s));
found = true;
break;
}
}
if(found) {
for(const auto& data : group) {
if(data.code == 102) {
continue;
}
switch(data.type) {
case DRW_Variant::STRING:
writer->writeString(data.code, *(data.content.s));
break;
case DRW_Variant::INTEGER:
writer->writeInt32(data.code, data.content.i);
break;
case DRW_Variant::DOUBLE:
writer->writeDouble(data.code, data.content.i);
break;
default:
break;
}
}
writer->writeString(102, "}");
}
}
return true;
}
bool dxfRW::writeLineType(DRW_LType *ent){
std::string strname = ent->name;
transform(strname.begin(), strname.end(), strname.begin(),::toupper);
//do not write linetypes handled by library
if (strname == "BYLAYER" || strname == "BYBLOCK" || strname == "CONTINUOUS") {
return true;
}
writer->writeString(0, "LTYPE");
if (version > DRW::AC1009) {
writer->writeString(5, toHexStr(++entCount));
if (version > DRW::AC1012) {
writer->writeString(330, "5");
}
writer->writeString(100, "AcDbSymbolTableRecord");
writer->writeString(100, "AcDbLinetypeTableRecord");
writer->writeUtf8String(2, ent->name);
} else
writer->writeUtf8Caps(2, ent->name);
writer->writeInt16(70, ent->flags);
writer->writeUtf8String(3, ent->desc);
ent->update();
writer->writeInt16(72, 65);
writer->writeInt16(73, ent->size);
writer->writeDouble(40, ent->length);
for (unsigned int i = 0; i< ent->path.size(); i++){
writer->writeDouble(49, ent->path.at(i));
if (version > DRW::AC1009) {
writer->writeInt16(74, 0);
}
}
return true;
}
bool dxfRW::writeLayer(DRW_Layer *ent){
writer->writeString(0, "LAYER");
if (!wlayer0 && ent->name == "0") {
wlayer0 = true;
if (version > DRW::AC1009) {
writer->writeString(5, "10");
}
} else {
if (version > DRW::AC1009) {
writer->writeString(5, toHexStr(++entCount));
}
}
if (version > DRW::AC1012) {
writer->writeString(330, "2");
}
if (version > DRW::AC1009) {
writer->writeString(100, "AcDbSymbolTableRecord");
writer->writeString(100, "AcDbLayerTableRecord");
writer->writeUtf8String(2, ent->name);
} else {
writer->writeUtf8Caps(2, ent->name);
}
writer->writeInt16(70, ent->flags);
writer->writeInt16(62, ent->color);
if (version > DRW::AC1015 && ent->color24 >= 0) {
writer->writeInt32(420, ent->color24);
}
if (version > DRW::AC1009) {
writer->writeUtf8String(6, ent->lineType);
if (! ent->plotF)
writer->writeBool(290, ent->plotF);
writer->writeInt16(370, DRW_LW_Conv::lineWidth2dxfInt(ent->lWeight));
writer->writeString(390, "F");
} else
writer->writeUtf8Caps(6, ent->lineType);
if (!ent->extData.empty()){
writeExtData(ent->extData);
}
// writer->writeString(347, "10012");
return true;
}
bool dxfRW::writeTextstyle(DRW_Textstyle *ent){
writer->writeString(0, "STYLE");
if (!dimstyleStd) {
//stringstream cause crash in OS/X, bug#3597944
std::string name=ent->name;
transform(name.begin(), name.end(), name.begin(), toupper);
if (name == "STANDARD")
dimstyleStd = true;
}
if (version > DRW::AC1009) {
writer->writeString(5, toHexStr(++entCount));
}
if (version > DRW::AC1012) {
writer->writeString(330, "2");
}
if (version > DRW::AC1009) {
writer->writeString(100, "AcDbSymbolTableRecord");
writer->writeString(100, "AcDbTextStyleTableRecord");
writer->writeUtf8String(2, ent->name);
} else {
writer->writeUtf8Caps(2, ent->name);
}
writer->writeInt16(70, ent->flags);
writer->writeDouble(40, ent->height);
writer->writeDouble(41, ent->width);
writer->writeDouble(50, ent->oblique);
writer->writeInt16(71, ent->genFlag);
writer->writeDouble(42, ent->lastHeight);
if (version > DRW::AC1009) {
writer->writeUtf8String(3, ent->font);
writer->writeUtf8String(4, ent->bigFont);
writer->writeUtf8String(1001, "ACAD");
writer->writeUtf8String(1000, ent->font);
if (ent->fontFamily != 0)
writer->writeInt32(1071, ent->fontFamily);
} else {
writer->writeUtf8Caps(3, ent->font);
writer->writeUtf8Caps(4, ent->bigFont);
}
return true;
}
bool dxfRW::writeVport(DRW_Vport *ent){
if (!dimstyleStd) {
ent->name = "*ACTIVE";
dimstyleStd = true;
}
writer->writeString(0, "VPORT");
if (version > DRW::AC1009) {
writer->writeString(5, toHexStr(++entCount));
if (version > DRW::AC1012)
writer->writeString(330, "2");
writer->writeString(100, "AcDbSymbolTableRecord");
writer->writeString(100, "AcDbViewportTableRecord");
writer->writeUtf8String(2, ent->name);
} else
writer->writeUtf8Caps(2, ent->name);
writer->writeInt16(70, ent->flags);
writer->writeDouble(10, ent->lowerLeft.x);
writer->writeDouble(20, ent->lowerLeft.y);
writer->writeDouble(11, ent->UpperRight.x);
writer->writeDouble(21, ent->UpperRight.y);
writer->writeDouble(12, ent->center.x);
writer->writeDouble(22, ent->center.y);
writer->writeDouble(13, ent->snapBase.x);
writer->writeDouble(23, ent->snapBase.y);
writer->writeDouble(14, ent->snapSpacing.x);
writer->writeDouble(24, ent->snapSpacing.y);
writer->writeDouble(15, ent->gridSpacing.x);
writer->writeDouble(25, ent->gridSpacing.y);
writer->writeDouble(16, ent->viewDir.x);
writer->writeDouble(26, ent->viewDir.y);
writer->writeDouble(36, ent->viewDir.z);
2021-11-23 12:16:58 +01:00
writer->writeDouble(17, ent->viewTarget.x);
writer->writeDouble(27, ent->viewTarget.y);
writer->writeDouble(37, ent->viewTarget.z);
writer->writeDouble(40, ent->height);
writer->writeDouble(41, ent->width);
writer->writeDouble(42, ent->lensHeight);
writer->writeDouble(43, ent->frontClip);
writer->writeDouble(44, ent->backClip);
writer->writeDouble(50, ent->snapAngle);
writer->writeDouble(51, ent->twistAngle);
writer->writeInt16(71, ent->viewMode);
writer->writeInt16(72, ent->circleZoom);
writer->writeInt16(73, ent->fastZoom);
writer->writeInt16(74, ent->ucsIcon);
writer->writeInt16(75, ent->snap);
writer->writeInt16(76, ent->grid);
writer->writeInt16(77, ent->snapStyle);
writer->writeInt16(78, ent->snapIsopair);
if (version > DRW::AC1014) {
writer->writeInt16(281, 0);
writer->writeInt16(65, 1);
writer->writeDouble(110, 0.0);
writer->writeDouble(120, 0.0);
writer->writeDouble(130, 0.0);
writer->writeDouble(111, 1.0);
writer->writeDouble(121, 0.0);
writer->writeDouble(131, 0.0);
writer->writeDouble(112, 0.0);
writer->writeDouble(122, 1.0);
writer->writeDouble(132, 0.0);
writer->writeInt16(79, 0);
writer->writeDouble(146, 0.0);
if (version > DRW::AC1018) {
writer->writeString(348, "10020");
writer->writeInt16(60, ent->gridBehavior);//v2007 undocummented see DRW_Vport class
writer->writeInt16(61, 5);
writer->writeBool(292, 1);
writer->writeInt16(282, 1);
writer->writeDouble(141, 0.0);
writer->writeDouble(142, 0.0);
writer->writeInt16(63, 250);
writer->writeInt32(421, 3358443);
}
}
return true;
}
bool dxfRW::writeDimstyle(DRW_Dimstyle *ent){
writer->writeString(0, "DIMSTYLE");
if (!dimstyleStd) {
std::string name = ent->name;
std::transform(name.begin(), name.end(), name.begin(),::toupper);
if (name == "STANDARD")
dimstyleStd = true;
}
if (version > DRW::AC1009) {
writer->writeString(105, toHexStr(++entCount));
}
if (version > DRW::AC1012) {
writer->writeString(330, "A");
}
if (version > DRW::AC1009) {
writer->writeString(100, "AcDbSymbolTableRecord");
writer->writeString(100, "AcDbDimStyleTableRecord");
writer->writeUtf8String(2, ent->name);
} else
writer->writeUtf8Caps(2, ent->name);
writer->writeInt16(70, ent->flags);
if ( version <= DRW::AC1009 || !(ent->dimpost.empty()) )
writer->writeUtf8String(3, ent->dimpost);
if ( version <= DRW::AC1009 || !(ent->dimapost.empty()) )
writer->writeUtf8String(4, ent->dimapost);
if ( version <= DRW::AC1009 || !(ent->dimblk.empty()) )
writer->writeUtf8String(5, ent->dimblk);
if ( version <= DRW::AC1009 || !(ent->dimblk1.empty()) )
writer->writeUtf8String(6, ent->dimblk1);
if ( version <= DRW::AC1009 || !(ent->dimblk2.empty()) )
writer->writeUtf8String(7, ent->dimblk2);
writer->writeDouble(40, ent->dimscale);
writer->writeDouble(41, ent->dimasz);
writer->writeDouble(42, ent->dimexo);
writer->writeDouble(43, ent->dimdli);
writer->writeDouble(44, ent->dimexe);
writer->writeDouble(45, ent->dimrnd);
writer->writeDouble(46, ent->dimdle);
writer->writeDouble(47, ent->dimtp);
writer->writeDouble(48, ent->dimtm);
writer->writeDouble(140, ent->dimtxt);
writer->writeDouble(141, ent->dimcen);
writer->writeDouble(142, ent->dimtsz);
writer->writeDouble(143, ent->dimaltf);
writer->writeDouble(144, ent->dimlfac);
writer->writeDouble(145, ent->dimtvp);
writer->writeDouble(146, ent->dimtfac);
writer->writeDouble(147, ent->dimgap);
if (version > DRW::AC1014) {
writer->writeDouble(148, ent->dimaltrnd);
}
writer->writeInt16(71, ent->dimtol);
writer->writeInt16(72, ent->dimlim);
writer->writeInt16(73, ent->dimtih);
writer->writeInt16(74, ent->dimtoh);
writer->writeInt16(75, ent->dimse1);
writer->writeInt16(76, ent->dimse2);
writer->writeInt16(77, ent->dimtad);
writer->writeInt16(78, ent->dimzin);
if (version > DRW::AC1014) {
writer->writeInt16(79, ent->dimazin);
}
writer->writeInt16(170, ent->dimalt);
writer->writeInt16(171, ent->dimaltd);
writer->writeInt16(172, ent->dimtofl);
writer->writeInt16(173, ent->dimsah);
writer->writeInt16(174, ent->dimtix);
writer->writeInt16(175, ent->dimsoxd);
writer->writeInt16(176, ent->dimclrd);
writer->writeInt16(177, ent->dimclre);
writer->writeInt16(178, ent->dimclrt);
if (version > DRW::AC1014) {
writer->writeInt16(179, ent->dimadec);
}
if (version > DRW::AC1009) {
if (version < DRW::AC1015)
writer->writeInt16(270, ent->dimunit);
writer->writeInt16(271, ent->dimdec);
writer->writeInt16(272, ent->dimtdec);
writer->writeInt16(273, ent->dimaltu);
writer->writeInt16(274, ent->dimalttd);
writer->writeInt16(275, ent->dimaunit);
}
if (version > DRW::AC1014) {
writer->writeInt16(276, ent->dimfrac);
writer->writeInt16(277, ent->dimlunit);
writer->writeInt16(278, ent->dimdsep);
writer->writeInt16(279, ent->dimtmove);
}
if (version > DRW::AC1009) {
writer->writeInt16(280, ent->dimjust);
writer->writeInt16(281, ent->dimsd1);
writer->writeInt16(282, ent->dimsd2);
writer->writeInt16(283, ent->dimtolj);
writer->writeInt16(284, ent->dimtzin);
writer->writeInt16(285, ent->dimaltz);
writer->writeInt16(286, ent->dimaltttz);
if (version < DRW::AC1015)
writer->writeInt16(287, ent->dimfit);
writer->writeInt16(288, ent->dimupt);
}
if (version > DRW::AC1014) {
writer->writeInt16(289, ent->dimatfit);
}
if (version > DRW::AC1009 && !ent->dimtxsty.empty()) {
writer->writeUtf8String(340, ent->dimtxsty);
}
if (version > DRW::AC1014) {
writer->writeUtf8String(341, ent->dimldrblk);
writer->writeInt16(371, ent->dimlwd);
writer->writeInt16(372, ent->dimlwe);
}
return true;
}
bool dxfRW::writeAppId(DRW_AppId *ent){
std::string strname = ent->name;
transform(strname.begin(), strname.end(), strname.begin(),::toupper);
//do not write mandatory ACAD appId, handled by library
if (strname == "ACAD")
return true;
writer->writeString(0, "APPID");
if (version > DRW::AC1009) {
writer->writeString(5, toHexStr(++entCount));
if (version > DRW::AC1014) {
writer->writeString(330, "9");
}
writer->writeString(100, "AcDbSymbolTableRecord");
writer->writeString(100, "AcDbRegAppTableRecord");
writer->writeUtf8String(2, ent->name);
} else {
writer->writeUtf8Caps(2, ent->name);
}
writer->writeInt16(70, ent->flags);
return true;
}
bool dxfRW::writePoint(DRW_Point *ent) {
writer->writeString(0, "POINT");
writeEntity(ent);
if (version > DRW::AC1009) {
writer->writeString(100, "AcDbPoint");
}
writer->writeDouble(10, ent->basePoint.x);
writer->writeDouble(20, ent->basePoint.y);
2017-07-05 18:35:34 +02:00
if (not qFuzzyIsNull(ent->basePoint.z)) {
writer->writeDouble(30, ent->basePoint.z);
}
return true;
}
2020-03-15 12:35:31 +01:00
bool dxfRW::writeASTMNotch(DRW_ASTMNotch *ent)
{
writePoint(ent);
writer->writeDouble(50, ent->angle);
writer->writeDouble(39, ent->thickness); // Defined, but not used in point
return true;
}
bool dxfRW::writeLine(DRW_Line *ent) {
writer->writeString(0, "LINE");
writeEntity(ent);
if (version > DRW::AC1009) {
writer->writeString(100, "AcDbLine");
}
writer->writeDouble(10, ent->basePoint.x);
writer->writeDouble(20, ent->basePoint.y);
2017-07-05 18:35:34 +02:00
if (not qFuzzyIsNull(ent->basePoint.z) || not qFuzzyIsNull(ent->secPoint.z)) {
writer->writeDouble(30, ent->basePoint.z);
writer->writeDouble(11, ent->secPoint.x);
writer->writeDouble(21, ent->secPoint.y);
writer->writeDouble(31, ent->secPoint.z);
} else {
writer->writeDouble(11, ent->secPoint.x);
writer->writeDouble(21, ent->secPoint.y);
}
return true;
}
bool dxfRW::writeRay(DRW_Ray *ent) {
writer->writeString(0, "RAY");
writeEntity(ent);
if (version > DRW::AC1009) {
writer->writeString(100, "AcDbRay");
}
DRW_Coord crd = ent->secPoint;
crd.unitize();
writer->writeDouble(10, ent->basePoint.x);
writer->writeDouble(20, ent->basePoint.y);
2017-07-05 18:35:34 +02:00
if (not qFuzzyIsNull(ent->basePoint.z) || not qFuzzyIsNull(ent->secPoint.z)) {
writer->writeDouble(30, ent->basePoint.z);
writer->writeDouble(11, crd.x);
writer->writeDouble(21, crd.y);
writer->writeDouble(31, crd.z);
} else {
writer->writeDouble(11, crd.x);
writer->writeDouble(21, crd.y);
}
return true;
}
bool dxfRW::writeXline(DRW_Xline *ent) {
writer->writeString(0, "XLINE");
writeEntity(ent);
if (version > DRW::AC1009) {
writer->writeString(100, "AcDbXline");
}
DRW_Coord crd = ent->secPoint;
crd.unitize();
writer->writeDouble(10, ent->basePoint.x);
writer->writeDouble(20, ent->basePoint.y);
2017-07-05 18:35:34 +02:00
if (not qFuzzyIsNull(ent->basePoint.z) || not qFuzzyIsNull(ent->secPoint.z)) {
writer->writeDouble(30, ent->basePoint.z);
writer->writeDouble(11, crd.x);
writer->writeDouble(21, crd.y);
writer->writeDouble(31, crd.z);
} else {
writer->writeDouble(11, crd.x);
writer->writeDouble(21, crd.y);
}
return true;
}
bool dxfRW::writeCircle(DRW_Circle *ent) {
writer->writeString(0, "CIRCLE");
writeEntity(ent);
if (version > DRW::AC1009) {
writer->writeString(100, "AcDbCircle");
}
writer->writeDouble(10, ent->basePoint.x);
writer->writeDouble(20, ent->basePoint.y);
2017-07-05 18:35:34 +02:00
if (not qFuzzyIsNull(ent->basePoint.z)) {
writer->writeDouble(30, ent->basePoint.z);
}
writer->writeDouble(40, ent->radious);
return true;
}
bool dxfRW::writeArc(DRW_Arc *ent) {
writer->writeString(0, "ARC");
writeEntity(ent);
if (version > DRW::AC1009) {
writer->writeString(100, "AcDbCircle");
}
writer->writeDouble(10, ent->basePoint.x);
writer->writeDouble(20, ent->basePoint.y);
2017-07-05 18:35:34 +02:00
if (not qFuzzyIsNull(ent->basePoint.z)) {
writer->writeDouble(30, ent->basePoint.z);
}
writer->writeDouble(40, ent->radious);
if (version > DRW::AC1009) {
writer->writeString(100, "AcDbArc");
}
writer->writeDouble(50, ent->staangle*ARAD);
writer->writeDouble(51, ent->endangle*ARAD);
return true;
}
bool dxfRW::writeEllipse(DRW_Ellipse *ent){
//verify axis/ratio and params for full ellipse
ent->correctAxis();
if (version > DRW::AC1009) {
writer->writeString(0, "ELLIPSE");
writeEntity(ent);
if (version > DRW::AC1009) {
writer->writeString(100, "AcDbEllipse");
}
writer->writeDouble(10, ent->basePoint.x);
writer->writeDouble(20, ent->basePoint.y);
writer->writeDouble(30, ent->basePoint.z);
writer->writeDouble(11, ent->secPoint.x);
writer->writeDouble(21, ent->secPoint.y);
writer->writeDouble(31, ent->secPoint.z);
writer->writeDouble(40, ent->ratio);
writer->writeDouble(41, ent->staparam);
writer->writeDouble(42, ent->endparam);
} else {
DRW_Polyline pol;
//RLZ: copy properties
ent->toPolyline(&pol, elParts);
writePolyline(&pol);
}
return true;
}
bool dxfRW::writeTrace(DRW_Trace *ent){
writer->writeString(0, "TRACE");
writeEntity(ent);
if (version > DRW::AC1009) {
writer->writeString(100, "AcDbTrace");
}
writer->writeDouble(10, ent->basePoint.x);
writer->writeDouble(20, ent->basePoint.y);
writer->writeDouble(30, ent->basePoint.z);
writer->writeDouble(11, ent->secPoint.x);
writer->writeDouble(21, ent->secPoint.y);
writer->writeDouble(31, ent->secPoint.z);
writer->writeDouble(12, ent->thirdPoint.x);
writer->writeDouble(22, ent->thirdPoint.y);
writer->writeDouble(32, ent->thirdPoint.z);
writer->writeDouble(13, ent->fourPoint.x);
writer->writeDouble(23, ent->fourPoint.y);
writer->writeDouble(33, ent->fourPoint.z);
return true;
}
bool dxfRW::writeSolid(DRW_Solid *ent){
writer->writeString(0, "SOLID");
writeEntity(ent);
if (version > DRW::AC1009) {
writer->writeString(100, "AcDbTrace");
}
writer->writeDouble(10, ent->basePoint.x);
writer->writeDouble(20, ent->basePoint.y);
writer->writeDouble(30, ent->basePoint.z);
writer->writeDouble(11, ent->secPoint.x);
writer->writeDouble(21, ent->secPoint.y);
writer->writeDouble(31, ent->secPoint.z);
writer->writeDouble(12, ent->thirdPoint.x);
writer->writeDouble(22, ent->thirdPoint.y);
writer->writeDouble(32, ent->thirdPoint.z);
writer->writeDouble(13, ent->fourPoint.x);
writer->writeDouble(23, ent->fourPoint.y);
writer->writeDouble(33, ent->fourPoint.z);
return true;
}
bool dxfRW::write3dface(DRW_3Dface *ent){
writer->writeString(0, "3DFACE");
writeEntity(ent);
if (version > DRW::AC1009) {
writer->writeString(100, "AcDbFace");
}
writer->writeDouble(10, ent->basePoint.x);
writer->writeDouble(20, ent->basePoint.y);
writer->writeDouble(30, ent->basePoint.z);
writer->writeDouble(11, ent->secPoint.x);
writer->writeDouble(21, ent->secPoint.y);
writer->writeDouble(31, ent->secPoint.z);
writer->writeDouble(12, ent->thirdPoint.x);
writer->writeDouble(22, ent->thirdPoint.y);
writer->writeDouble(32, ent->thirdPoint.z);
writer->writeDouble(13, ent->fourPoint.x);
writer->writeDouble(23, ent->fourPoint.y);
writer->writeDouble(33, ent->fourPoint.z);
writer->writeInt16(70, ent->invisibleflag);
return true;
}
bool dxfRW::writeLWPolyline(DRW_LWPolyline *ent){
if (version > DRW::AC1009) {
writer->writeString(0, "LWPOLYLINE");
writeEntity(ent);
if (version > DRW::AC1009) {
writer->writeString(100, "AcDbPolyline");
}
2017-07-05 18:35:34 +02:00
ent->vertexnum = static_cast<int>(ent->vertlist.size());
writer->writeInt32(90, ent->vertexnum);
writer->writeInt16(70, ent->flags);
writer->writeDouble(43, ent->width);
2017-07-05 18:35:34 +02:00
if (not qFuzzyIsNull(ent->elevation))
writer->writeDouble(38, ent->elevation);
2017-07-05 18:35:34 +02:00
if (not qFuzzyIsNull(ent->thickness))
writer->writeDouble(39, ent->thickness);
for (int i = 0; i< ent->vertexnum; i++){
DRW_Vertex2D *v = ent->vertlist.at(static_cast<size_t>(i));
writer->writeDouble(10, v->x);
writer->writeDouble(20, v->y);
2017-07-05 18:35:34 +02:00
if (not qFuzzyIsNull(v->stawidth))
writer->writeDouble(40, v->stawidth);
2017-07-05 18:35:34 +02:00
if (not qFuzzyIsNull(v->endwidth))
writer->writeDouble(41, v->endwidth);
2017-07-05 18:35:34 +02:00
if (not qFuzzyIsNull(v->bulge))
writer->writeDouble(42, v->bulge);
}
} else {
//RLZ: TODO convert lwpolyline in polyline (not exist in acad 12)
}
return true;
}
bool dxfRW::writePolyline(DRW_Polyline *ent) {
writer->writeString(0, "POLYLINE");
writeEntity(ent);
bool is3d = false;
if (version > DRW::AC1009) {
if (ent->flags & 8 || ent->flags & 16) {
writer->writeString(100, "AcDb3dPolyline");
is3d = true;
} else {
writer->writeString(100, "AcDb2dPolyline");
}
} else
writer->writeInt16(66, 1);
writer->writeDouble(10, 0.0);
writer->writeDouble(20, 0.0);
writer->writeDouble(30, ent->basePoint.z);
2017-07-05 18:35:34 +02:00
if (not qFuzzyIsNull(ent->thickness)) {
writer->writeDouble(39, ent->thickness);
}
writer->writeInt16(70, ent->flags);
2017-07-05 18:35:34 +02:00
if (not qFuzzyIsNull(ent->defstawidth)) {
writer->writeDouble(40, ent->defstawidth);
}
2017-07-05 18:35:34 +02:00
if (not qFuzzyIsNull(ent->defendwidth)) {
writer->writeDouble(41, ent->defendwidth);
}
if (ent->flags & 16 || ent->flags & 32) {
writer->writeInt16(71, ent->vertexcount);
writer->writeInt16(72, ent->facecount);
}
if (ent->smoothM != 0) {
writer->writeInt16(73, ent->smoothM);
}
if (ent->smoothN != 0) {
writer->writeInt16(74, ent->smoothN);
}
if (ent->curvetype != 0) {
writer->writeInt16(75, ent->curvetype);
}
DRW_Coord crd = ent->extPoint;
2017-07-05 18:35:34 +02:00
if (not qFuzzyIsNull(crd.x) || not qFuzzyIsNull(crd.y) || not DRW_FuzzyComparePossibleNulls(crd.z, 1)) {
writer->writeDouble(210, crd.x);
writer->writeDouble(220, crd.y);
writer->writeDouble(230, crd.z);
}
size_t vertexnum = ent->vertlist.size();
for (size_t i = 0; i < vertexnum; i++) {
DRW_Vertex *v = ent->vertlist.at(i);
writer->writeString(0, "VERTEX");
writeEntity(ent);
if (version > DRW::AC1009)
{
writer->writeString(100, "AcDbVertex");
if(is3d) {
writer->writeString(100, "AcDb3dPolylineVertex");
} else {
writer->writeString(100, "AcDb2dVertex");
}
}
if ( (v->flags & 128) && !(v->flags & 64) ) {
writer->writeDouble(10, 0);
writer->writeDouble(20, 0);
writer->writeDouble(30, 0);
} else {
writer->writeDouble(10, v->basePoint.x);
writer->writeDouble(20, v->basePoint.y);
writer->writeDouble(30, v->basePoint.z);
}
2017-07-05 18:35:34 +02:00
if (not qFuzzyIsNull(v->stawidth))
writer->writeDouble(40, v->stawidth);
2017-07-05 18:35:34 +02:00
if (not qFuzzyIsNull(v->endwidth))
writer->writeDouble(41, v->endwidth);
2017-07-05 18:35:34 +02:00
if (not qFuzzyIsNull(v->bulge))
writer->writeDouble(42, v->bulge);
if (v->flags != 0) {
writer->writeInt16(70, ent->flags);
}
if (v->flags & 2) {
writer->writeDouble(50, v->tgdir);
}
if ( v->flags & 128 ) {
if (v->vindex1 != 0) {
writer->writeInt16(71, v->vindex1);
}
if (v->vindex2 != 0) {
writer->writeInt16(72, v->vindex2);
}
if (v->vindex3 != 0) {
writer->writeInt16(73, v->vindex3);
}
if (v->vindex4 != 0) {
writer->writeInt16(74, v->vindex4);
}
if ( !(v->flags & 64) ) {
writer->writeInt32(91, v->identifier);
}
}
}
writer->writeString(0, "SEQEND");
writeEntity(ent);
return true;
}
bool dxfRW::writeSpline(DRW_Spline *ent){
if (version > DRW::AC1009) {
writer->writeString(0, "SPLINE");
writeEntity(ent);
if (version > DRW::AC1009) {
writer->writeString(100, "AcDbSpline");
}
writer->writeDouble(210, ent->normalVec.x);
writer->writeDouble(220, ent->normalVec.y);
writer->writeDouble(230, ent->normalVec.z);
writer->writeInt16(70, ent->flags);
writer->writeInt16(71, ent->degree);
writer->writeInt16(72, ent->nknots);
writer->writeInt16(73, ent->ncontrol);
writer->writeInt16(74, ent->nfit);
writer->writeDouble(42, ent->tolknot);
writer->writeDouble(43, ent->tolcontrol);
//RLZ: warning check if nknots are correct and ncontrol
for (int i = 0; i< ent->nknots; i++){
writer->writeDouble(40, ent->knotslist.at(static_cast<size_t>(i)));
}
2017-07-05 18:35:34 +02:00
for (int i = 0; i< static_cast<int>(ent->weightlist.size()); i++) {
writer->writeDouble(41, ent->weightlist.at(static_cast<size_t>(i)));
}
for (int i = 0; i< ent->ncontrol; i++){
DRW_Coord *crd = ent->controllist.at(static_cast<size_t>(i));
writer->writeDouble(10, crd->x);
writer->writeDouble(20, crd->y);
writer->writeDouble(30, crd->z);
}
} else {
//RLZ: TODO convert spline in polyline (not exist in acad 12)
}
return true;
}
bool dxfRW::writeHatch(DRW_Hatch *ent){
if (version > DRW::AC1009) {
writer->writeString(0, "HATCH");
writeEntity(ent);
writer->writeString(100, "AcDbHatch");
writer->writeDouble(10, 0.0);
writer->writeDouble(20, 0.0);
writer->writeDouble(30, ent->basePoint.z);
writer->writeDouble(210, ent->extPoint.x);
writer->writeDouble(220, ent->extPoint.y);
writer->writeDouble(230, ent->extPoint.z);
writer->writeString(2, ent->name);
writer->writeInt16(70, ent->solid);
writer->writeInt16(71, ent->associative);
2017-07-05 18:35:34 +02:00
ent->loopsnum = static_cast<int>(ent->looplist.size());
writer->writeInt16(91, ent->loopsnum);
//write paths data
for (int i = 0; i< ent->loopsnum; i++){
DRW_HatchLoop *loop = ent->looplist.at(static_cast<size_t>(i));
writer->writeInt16(92, loop->type);
if ( (loop->type & 2) == 2){
//RLZ: polyline boundary writeme
} else {
//boundary path
loop->update();
writer->writeInt16(93, loop->numedges);
for (int j = 0; j<loop->numedges; ++j) {
switch ( (loop->objlist.at(static_cast<size_t>(j)))->eType) {
case DRW::LINE: {
writer->writeInt16(72, 1);
DRW_Line* l = static_cast<DRW_Line*>(loop->objlist.at(static_cast<size_t>(j)));
writer->writeDouble(10, l->basePoint.x);
writer->writeDouble(20, l->basePoint.y);
writer->writeDouble(11, l->secPoint.x);
writer->writeDouble(21, l->secPoint.y);
break; }
case DRW::ARC: {
writer->writeInt16(72, 2);
DRW_Arc* a = static_cast<DRW_Arc*>(loop->objlist.at(static_cast<size_t>(j)));
writer->writeDouble(10, a->basePoint.x);
writer->writeDouble(20, a->basePoint.y);
writer->writeDouble(40, a->radious);
writer->writeDouble(50, a->staangle*ARAD);
writer->writeDouble(51, a->endangle*ARAD);
writer->writeInt16(73, a->isccw);
break; }
case DRW::ELLIPSE: {
writer->writeInt16(72, 3);
DRW_Ellipse* a = static_cast<DRW_Ellipse*>(loop->objlist.at(static_cast<size_t>(j)));
a->correctAxis();
writer->writeDouble(10, a->basePoint.x);
writer->writeDouble(20, a->basePoint.y);
writer->writeDouble(11, a->secPoint.x);
writer->writeDouble(21, a->secPoint.y);
writer->writeDouble(40, a->ratio);
writer->writeDouble(50, a->staparam*ARAD);
writer->writeDouble(51, a->endparam*ARAD);
writer->writeInt16(73, a->isccw);
break; }
case DRW::SPLINE:
//RLZ: spline boundary writeme
// writer->writeInt16(72, 4);
break;
default:
break;
}
}
writer->writeInt16(97, 0);
}
}
writer->writeInt16(75, ent->hstyle);
writer->writeInt16(76, ent->hpattern);
if (!ent->solid){
writer->writeDouble(52, ent->angle);
writer->writeDouble(41, ent->scale);
writer->writeInt16(77, ent->doubleflag);
writer->writeInt16(78, ent->deflines);
}
/* if (ent->deflines > 0){
writer->writeInt16(78, ent->deflines);
}*/
writer->writeInt32(98, 0);
} else {
//RLZ: TODO verify in acad12
}
return true;
}
bool dxfRW::writeLeader(DRW_Leader *ent){
if (version > DRW::AC1009) {
writer->writeString(0, "LEADER");
writeEntity(ent);
writer->writeString(100, "AcDbLeader");
writer->writeUtf8String(3, ent->style);
writer->writeInt16(71, ent->arrow);
writer->writeInt16(72, ent->leadertype);
writer->writeInt16(73, ent->flag);
writer->writeInt16(74, ent->hookline);
writer->writeInt16(75, ent->hookflag);
writer->writeDouble(40, ent->textheight);
writer->writeDouble(41, ent->textwidth);
writer->writeDouble(76, ent->vertnum);
2017-07-05 18:35:34 +02:00
writer->writeDouble(76, static_cast<double>(ent->vertexlist.size()));
for (unsigned int i=0; i<ent->vertexlist.size(); i++) {
DRW_Coord *vert = ent->vertexlist.at(i);
writer->writeDouble(10, vert->x);
writer->writeDouble(20, vert->y);
writer->writeDouble(30, vert->z);
}
} else {
//RLZ: todo not supported by acad 12 saved as unnamed block
}
return true;
}
bool dxfRW::writeDimension(DRW_Dimension *ent) {
if (version > DRW::AC1009) {
writer->writeString(0, "DIMENSION");
writeEntity(ent);
writer->writeString(100, "AcDbDimension");
if (!ent->getName().empty()){
writer->writeString(2, ent->getName());
}
writer->writeDouble(10, ent->getDefPoint().x);
writer->writeDouble(20, ent->getDefPoint().y);
writer->writeDouble(30, ent->getDefPoint().z);
writer->writeDouble(11, ent->getTextPoint().x);
writer->writeDouble(21, ent->getTextPoint().y);
writer->writeDouble(31, ent->getTextPoint().z);
if ( !(ent->type & 32))
ent->type = ent->type +32;
writer->writeInt16(70, ent->type);
if ( !(ent->getText().empty()) )
writer->writeUtf8String(1, ent->getText());
writer->writeInt16(71, ent->getAlign());
if ( ent->getTextLineStyle() != 1)
writer->writeInt16(72, ent->getTextLineStyle());
2017-07-05 18:35:34 +02:00
if ( not DRW_FuzzyComparePossibleNulls(ent->getTextLineFactor(), 1))
writer->writeDouble(41, ent->getTextLineFactor());
writer->writeUtf8String(3, ent->getStyle());
2017-07-05 18:35:34 +02:00
if ( not qFuzzyIsNull(ent->getTextLineFactor()))
writer->writeDouble(53, ent->getDir());
writer->writeDouble(210, ent->getExtrusion().x);
writer->writeDouble(220, ent->getExtrusion().y);
writer->writeDouble(230, ent->getExtrusion().z);
if ( ent->hasActualMeasurement())
writer->writeDouble(42, ent->getActualMeasurement());
switch (ent->eType) {
case DRW::DIMALIGNED:
case DRW::DIMLINEAR: {
2017-07-05 18:35:34 +02:00
DRW_DimAligned * dd = static_cast<DRW_DimAligned*>(ent);
writer->writeString(100, "AcDbAlignedDimension");
DRW_Coord crd = dd->getClonepoint();
2017-07-05 18:35:34 +02:00
if (not qFuzzyIsNull(crd.x) || not qFuzzyIsNull(crd.y) || not qFuzzyIsNull(crd.z)) {
writer->writeDouble(12, crd.x);
writer->writeDouble(22, crd.y);
writer->writeDouble(32, crd.z);
}
writer->writeDouble(13, dd->getDef1Point().x);
writer->writeDouble(23, dd->getDef1Point().y);
writer->writeDouble(33, dd->getDef1Point().z);
writer->writeDouble(14, dd->getDef2Point().x);
writer->writeDouble(24, dd->getDef2Point().y);
writer->writeDouble(34, dd->getDef2Point().z);
if (ent->eType == DRW::DIMLINEAR) {
2017-07-05 18:35:34 +02:00
DRW_DimLinear * dl = static_cast<DRW_DimLinear*>(ent);
if (not qFuzzyIsNull(dl->getAngle()))
writer->writeDouble(50, dl->getAngle());
2017-07-05 18:35:34 +02:00
if (not qFuzzyIsNull(dl->getOblique()))
writer->writeDouble(52, dl->getOblique());
writer->writeString(100, "AcDbRotatedDimension");
}
break; }
case DRW::DIMRADIAL: {
2017-07-05 18:35:34 +02:00
DRW_DimRadial * dd = static_cast<DRW_DimRadial*>(ent);
writer->writeString(100, "AcDbRadialDimension");
writer->writeDouble(15, dd->getDiameterPoint().x);
writer->writeDouble(25, dd->getDiameterPoint().y);
writer->writeDouble(35, dd->getDiameterPoint().z);
writer->writeDouble(40, dd->getLeaderLength());
break; }
case DRW::DIMDIAMETRIC: {
2017-07-05 18:35:34 +02:00
DRW_DimDiametric * dd = static_cast<DRW_DimDiametric*>(ent);
writer->writeString(100, "AcDbDiametricDimension");
writer->writeDouble(15, dd->getDiameter1Point().x);
writer->writeDouble(25, dd->getDiameter1Point().y);
writer->writeDouble(35, dd->getDiameter1Point().z);
writer->writeDouble(40, dd->getLeaderLength());
break; }
case DRW::DIMANGULAR: {
2017-07-05 18:35:34 +02:00
DRW_DimAngular * dd = static_cast<DRW_DimAngular*>(ent);
writer->writeString(100, "AcDb2LineAngularDimension");
writer->writeDouble(13, dd->getFirstLine1().x);
writer->writeDouble(23, dd->getFirstLine1().y);
writer->writeDouble(33, dd->getFirstLine1().z);
writer->writeDouble(14, dd->getFirstLine2().x);
writer->writeDouble(24, dd->getFirstLine2().y);
writer->writeDouble(34, dd->getFirstLine2().z);
writer->writeDouble(15, dd->getSecondLine1().x);
writer->writeDouble(25, dd->getSecondLine1().y);
writer->writeDouble(35, dd->getSecondLine1().z);
writer->writeDouble(16, dd->getDimPoint().x);
writer->writeDouble(26, dd->getDimPoint().y);
writer->writeDouble(36, dd->getDimPoint().z);
break; }
case DRW::DIMANGULAR3P: {
2017-07-05 18:35:34 +02:00
DRW_DimAngular3p * dd = static_cast<DRW_DimAngular3p*>(ent);
writer->writeDouble(13, dd->getFirstLine().x);
writer->writeDouble(23, dd->getFirstLine().y);
writer->writeDouble(33, dd->getFirstLine().z);
writer->writeDouble(14, dd->getSecondLine().x);
writer->writeDouble(24, dd->getSecondLine().y);
writer->writeDouble(34, dd->getSecondLine().z);
writer->writeDouble(15, dd->getVertexPoint().x);
writer->writeDouble(25, dd->getVertexPoint().y);
writer->writeDouble(35, dd->getVertexPoint().z);
break; }
case DRW::DIMORDINATE: {
2017-07-05 18:35:34 +02:00
DRW_DimOrdinate * dd = static_cast<DRW_DimOrdinate*>(ent);
writer->writeString(100, "AcDbOrdinateDimension");
writer->writeDouble(13, dd->getFirstLine().x);
writer->writeDouble(23, dd->getFirstLine().y);
writer->writeDouble(33, dd->getFirstLine().z);
writer->writeDouble(14, dd->getSecondLine().x);
writer->writeDouble(24, dd->getSecondLine().y);
writer->writeDouble(34, dd->getSecondLine().z);
break; }
default:
break;
}
} else {
//RLZ: todo not supported by acad 12 saved as unnamed block
}
return true;
}
std::string dxfRW::ErrorString() const
{
return errorString;
}
bool dxfRW::writeInsert(DRW_Insert *ent){
writer->writeString(0, "INSERT");
writeEntity(ent);
if (version > DRW::AC1009) {
writer->writeString(100, "AcDbBlockReference");
writer->writeUtf8String(2, ent->name);
} else
writer->writeUtf8Caps(2, ent->name);
writer->writeDouble(10, ent->basePoint.x);
writer->writeDouble(20, ent->basePoint.y);
writer->writeDouble(30, ent->basePoint.z);
writer->writeDouble(41, ent->xscale);
writer->writeDouble(42, ent->yscale);
writer->writeDouble(43, ent->zscale);
writer->writeDouble(50, (ent->angle)*ARAD); //in dxf angle is writed in degrees
writer->writeInt16(70, ent->colcount);
writer->writeInt16(71, ent->rowcount);
writer->writeDouble(44, ent->colspace);
writer->writeDouble(45, ent->rowspace);
return true;
}
bool dxfRW::writeText(DRW_Text *ent){
writer->writeString(0, "TEXT");
writeEntity(ent);
if (version > DRW::AC1009) {
writer->writeString(100, "AcDbText");
}
// writer->writeDouble(39, ent->thickness);
writer->writeDouble(10, ent->basePoint.x);
writer->writeDouble(20, ent->basePoint.y);
writer->writeDouble(30, ent->basePoint.z);
writer->writeDouble(40, ent->height);
writer->writeUtf8String(1, ent->text);
writer->writeDouble(50, ent->angle);
writer->writeDouble(41, ent->widthscale);
writer->writeDouble(51, ent->oblique);
if (version > DRW::AC1009)
writer->writeUtf8String(7, ent->style);
else
writer->writeUtf8Caps(7, ent->style);
writer->writeInt16(71, ent->textgen);
if (ent->alignH != DRW_Text::HLeft) {
writer->writeInt16(72, ent->alignH);
}
if (ent->alignH != DRW_Text::HLeft || ent->alignV != DRW_Text::VBaseLine) {
writer->writeDouble(11, ent->secPoint.x);
writer->writeDouble(21, ent->secPoint.y);
writer->writeDouble(31, ent->secPoint.z);
}
writer->writeDouble(210, ent->extPoint.x);
writer->writeDouble(220, ent->extPoint.y);
writer->writeDouble(230, ent->extPoint.z);
if (version > DRW::AC1009) {
writer->writeString(100, "AcDbText");
}
if (ent->alignV != DRW_Text::VBaseLine) {
writer->writeInt16(73, ent->alignV);
}
return true;
}
bool dxfRW::writeMText(DRW_MText *ent){
if (version > DRW::AC1009) {
writer->writeString(0, "MTEXT");
writeEntity(ent);
writer->writeString(100, "AcDbMText");
writer->writeDouble(10, ent->basePoint.x);
writer->writeDouble(20, ent->basePoint.y);
writer->writeDouble(30, ent->basePoint.z);
writer->writeDouble(40, ent->height);
writer->writeDouble(41, ent->widthscale);
writer->writeInt16(71, ent->textgen);
writer->writeInt16(72, ent->alignH);
std::string text = writer->fromUtf8String(ent->text);
int i;
for(i =0; (text.size()-static_cast<size_t>(i)) > 250; ) {
writer->writeString(3, text.substr(static_cast<size_t>(i), 250));
i +=250;
}
writer->writeString(1, text.substr(static_cast<size_t>(i)));
writer->writeString(7, ent->style);
writer->writeDouble(210, ent->extPoint.x);
writer->writeDouble(220, ent->extPoint.y);
writer->writeDouble(230, ent->extPoint.z);
writer->writeDouble(50, ent->angle);
writer->writeInt16(73, ent->alignV);
writer->writeDouble(44, ent->interlin);
//RLZ ... 11, 21, 31 needed?
} else {
//RLZ: TODO convert mtext in text lines (not exist in acad 12)
}
return true;
}
bool dxfRW::writeViewport(DRW_Viewport *ent) {
writer->writeString(0, "VIEWPORT");
writeEntity(ent);
if (version > DRW::AC1009) {
writer->writeString(100, "AcDbViewport");
}
writer->writeDouble(10, ent->basePoint.x);
writer->writeDouble(20, ent->basePoint.y);
2017-07-05 18:35:34 +02:00
if (not qFuzzyIsNull(ent->basePoint.z))
writer->writeDouble(30, ent->basePoint.z);
writer->writeDouble(40, ent->pswidth);
writer->writeDouble(41, ent->psheight);
writer->writeInt16(68, ent->vpstatus);
writer->writeInt16(69, ent->vpID);
writer->writeDouble(12, ent->centerPX);//RLZ: verify if exist in V12
writer->writeDouble(22, ent->centerPY);//RLZ: verify if exist in V12
return true;
}
DRW_ImageDef* dxfRW::writeImage(DRW_Image *ent, const std::string &name){
if (version > DRW::AC1009) {
//search if exist imagedef with this mane (image inserted more than 1 time)
//RLZ: imagedef_reactor seem needed to read in acad
DRW_ImageDef *id = NULL;
for (unsigned int i=0; i<imageDef.size(); i++) {
if (imageDef.at(i)->name == name ) {
id = imageDef.at(i);
}
}
if (id == NULL) {
id = new DRW_ImageDef();
imageDef.push_back(id);
id->handle = static_cast<duint32>(++entCount);
}
id->fileName = name;
std::string idReactor = toHexStr(++entCount);
writer->writeString(0, "IMAGE");
writeEntity(ent);
writer->writeString(100, "AcDbRasterImage");
writer->writeDouble(10, ent->basePoint.x);
writer->writeDouble(20, ent->basePoint.y);
writer->writeDouble(30, ent->basePoint.z);
writer->writeDouble(11, ent->secPoint.x);
writer->writeDouble(21, ent->secPoint.y);
writer->writeDouble(31, ent->secPoint.z);
writer->writeDouble(12, ent->vVector.x);
writer->writeDouble(22, ent->vVector.y);
writer->writeDouble(32, ent->vVector.z);
writer->writeDouble(13, ent->sizeu);
writer->writeDouble(23, ent->sizev);
writer->writeString(340, toHexStr(static_cast<int>(id->handle)));
writer->writeInt16(70, 1);
writer->writeInt16(280, ent->clip);
writer->writeInt16(281, ent->brightness);
writer->writeInt16(282, ent->contrast);
writer->writeInt16(283, ent->fade);
writer->writeString(360, idReactor);
id->reactors[idReactor] = toHexStr(static_cast<int>(ent->handle));
return id;
}
return NULL; //not exist in acad 12
}
bool dxfRW::writeBlockRecord(std::string name){
if (version > DRW::AC1009) {
writer->writeString(0, "BLOCK_RECORD");
writer->writeString(5, toHexStr(++entCount));
blockMap[name] = entCount;
entCount = 2+entCount;//reserve 2 for BLOCK & ENDBLOCK
if (version > DRW::AC1014) {
writer->writeString(330, "1");
}
writer->writeString(100, "AcDbSymbolTableRecord");
writer->writeString(100, "AcDbBlockTableRecord");
writer->writeUtf8String(2, name);
if (version > DRW::AC1018) {
// writer->writeInt16(340, 22);
writer->writeInt16(70, 0);
writer->writeInt16(280, 1);
writer->writeInt16(281, 0);
}
}
return true;
}
bool dxfRW::writeBlock(DRW_Block *bk){
if (writingBlock) {
writer->writeString(0, "ENDBLK");
if (version > DRW::AC1009) {
writer->writeString(5, toHexStr(currHandle+2));
if (version > DRW::AC1014) {
writer->writeString(330, toHexStr(currHandle));
}
writer->writeString(100, "AcDbEntity");
}
writer->writeString(8, bk->layer);
if (version > DRW::AC1009) {
writer->writeString(100, "AcDbBlockEnd");
}
}
writingBlock = true;
writer->writeString(0, "BLOCK");
if (version > DRW::AC1009) {
currHandle = (*(blockMap.find(bk->name))).second;
writer->writeString(5, toHexStr(currHandle+1));
if (version > DRW::AC1014) {
writer->writeString(330, toHexStr(currHandle));
}
writer->writeString(100, "AcDbEntity");
}
writer->writeString(8, bk->layer);
if (version > DRW::AC1009) {
writer->writeString(100, "AcDbBlockBegin");
writer->writeUtf8String(2, bk->name);
} else
writer->writeUtf8Caps(2, bk->name);
writer->writeInt16(70, bk->flags);
writer->writeDouble(10, bk->basePoint.x);
writer->writeDouble(20, bk->basePoint.y);
2017-07-05 18:35:34 +02:00
if (not qFuzzyIsNull(bk->basePoint.z)) {
writer->writeDouble(30, bk->basePoint.z);
}
if (version > DRW::AC1009)
writer->writeUtf8String(3, bk->name);
else
writer->writeUtf8Caps(3, bk->name);
writer->writeString(1, "");
return true;
}
bool dxfRW::writeTables() {
writer->writeString(0, "TABLE");
writer->writeString(2, "VPORT");
if (version > DRW::AC1009) {
writer->writeString(5, "8");
if (version > DRW::AC1014) {
writer->writeString(330, "0");
}
writer->writeString(100, "AcDbSymbolTable");
}
writer->writeInt16(70, 1); //end table def
/*** VPORT ***/
dimstyleStd =false;
iface->writeVports();
if (!dimstyleStd) {
DRW_Vport portact;
portact.name = "*ACTIVE";
writeVport(&portact);
}
writer->writeString(0, "ENDTAB");
/*** LTYPE ***/
writer->writeString(0, "TABLE");
writer->writeString(2, "LTYPE");
if (version > DRW::AC1009) {
writer->writeString(5, "5");
if (version > DRW::AC1014) {
writer->writeString(330, "0");
}
writer->writeString(100, "AcDbSymbolTable");
}
writer->writeInt16(70, 4); //end table def
//Mandatory linetypes
writer->writeString(0, "LTYPE");
if (version > DRW::AC1009) {
writer->writeString(5, "14");
if (version > DRW::AC1014) {
writer->writeString(330, "5");
}
writer->writeString(100, "AcDbSymbolTableRecord");
writer->writeString(100, "AcDbLinetypeTableRecord");
writer->writeString(2, "ByBlock");
} else
writer->writeString(2, "BYBLOCK");
writer->writeInt16(70, 0);
writer->writeString(3, "");
writer->writeInt16(72, 65);
writer->writeInt16(73, 0);
writer->writeDouble(40, 0.0);
writer->writeString(0, "LTYPE");
if (version > DRW::AC1009) {
writer->writeString(5, "15");
if (version > DRW::AC1014) {
writer->writeString(330, "5");
}
writer->writeString(100, "AcDbSymbolTableRecord");
writer->writeString(100, "AcDbLinetypeTableRecord");
writer->writeString(2, "ByLayer");
} else
writer->writeString(2, "BYLAYER");
writer->writeInt16(70, 0);
writer->writeString(3, "");
writer->writeInt16(72, 65);
writer->writeInt16(73, 0);
writer->writeDouble(40, 0.0);
writer->writeString(0, "LTYPE");
if (version > DRW::AC1009) {
writer->writeString(5, "16");
if (version > DRW::AC1014) {
writer->writeString(330, "5");
}
writer->writeString(100, "AcDbSymbolTableRecord");
writer->writeString(100, "AcDbLinetypeTableRecord");
writer->writeString(2, "Continuous");
} else {
writer->writeString(2, "CONTINUOUS");
}
writer->writeInt16(70, 0);
writer->writeString(3, "Solid line");
writer->writeInt16(72, 65);
writer->writeInt16(73, 0);
writer->writeDouble(40, 0.0);
2021-11-22 17:44:44 +01:00
//Application linetypes
iface->writeLTypes();
writer->writeString(0, "ENDTAB");
/*** LAYER ***/
writer->writeString(0, "TABLE");
writer->writeString(2, "LAYER");
if (version > DRW::AC1009) {
writer->writeString(5, "2");
if (version > DRW::AC1014) {
writer->writeString(330, "0");
}
writer->writeString(100, "AcDbSymbolTable");
}
writer->writeInt16(70, 1); //end table def
wlayer0 =false;
iface->writeLayers();
if (!wlayer0 && version > DRW::AC1009) {
DRW_Layer lay0;
lay0.name = '0';
writeLayer(&lay0);
}
writer->writeString(0, "ENDTAB");
/*** STYLE ***/
writer->writeString(0, "TABLE");
writer->writeString(2, "STYLE");
if (version > DRW::AC1009) {
writer->writeString(5, "3");
if (version > DRW::AC1014) {
writer->writeString(330, "0");
}
writer->writeString(100, "AcDbSymbolTable");
}
writer->writeInt16(70, 3); //end table def
dimstyleStd =false;
iface->writeTextstyles();
if (!dimstyleStd) {
DRW_Textstyle tsty;
tsty.name = "Standard";
writeTextstyle(&tsty);
}
writer->writeString(0, "ENDTAB");
writer->writeString(0, "TABLE");
writer->writeString(2, "VIEW");
if (version > DRW::AC1009) {
writer->writeString(5, "6");
if (version > DRW::AC1014) {
writer->writeString(330, "0");
}
writer->writeString(100, "AcDbSymbolTable");
}
writer->writeInt16(70, 0); //end table def
writer->writeString(0, "ENDTAB");
writer->writeString(0, "TABLE");
writer->writeString(2, "UCS");
if (version > DRW::AC1009) {
writer->writeString(5, "7");
if (version > DRW::AC1014) {
writer->writeString(330, "0");
}
writer->writeString(100, "AcDbSymbolTable");
}
writer->writeInt16(70, 0); //end table def
writer->writeString(0, "ENDTAB");
writer->writeString(0, "TABLE");
writer->writeString(2, "APPID");
if (version > DRW::AC1009) {
writer->writeString(5, "9");
if (version > DRW::AC1014) {
writer->writeString(330, "0");
}
writer->writeString(100, "AcDbSymbolTable");
}
writer->writeInt16(70, 1); //end table def
writer->writeString(0, "APPID");
if (version > DRW::AC1009) {
writer->writeString(5, "12");
if (version > DRW::AC1014) {
writer->writeString(330, "9");
}
writer->writeString(100, "AcDbSymbolTableRecord");
writer->writeString(100, "AcDbRegAppTableRecord");
}
writer->writeString(2, "ACAD");
writer->writeInt16(70, 0);
iface->writeAppId();
writer->writeString(0, "ENDTAB");
writer->writeString(0, "TABLE");
writer->writeString(2, "DIMSTYLE");
if (version > DRW::AC1009) {
writer->writeString(5, "A");
if (version > DRW::AC1014) {
writer->writeString(330, "0");
}
writer->writeString(100, "AcDbSymbolTable");
}
writer->writeInt16(70, 1); //end table def
if (version > DRW::AC1014) {
writer->writeString(100, "AcDbDimStyleTable");
writer->writeInt16(71, 1); //end table def
}
dimstyleStd =false;
iface->writeDimstyles();
if (!dimstyleStd) {
DRW_Dimstyle dsty;
dsty.name = "Standard";
writeDimstyle(&dsty);
}
writer->writeString(0, "ENDTAB");
if (version > DRW::AC1009) {
writer->writeString(0, "TABLE");
writer->writeString(2, "BLOCK_RECORD");
writer->writeString(5, "1");
if (version > DRW::AC1014) {
writer->writeString(330, "0");
}
writer->writeString(100, "AcDbSymbolTable");
writer->writeInt16(70, 2); //end table def
writer->writeString(0, "BLOCK_RECORD");
writer->writeString(5, "1F");
if (version > DRW::AC1014) {
writer->writeString(330, "1");
}
writer->writeString(100, "AcDbSymbolTableRecord");
writer->writeString(100, "AcDbBlockTableRecord");
writer->writeString(2, "*Model_Space");
if (version > DRW::AC1018) {
// writer->writeInt16(340, 22);
writer->writeInt16(70, 0);
writer->writeInt16(280, 1);
writer->writeInt16(281, 0);
}
writer->writeString(0, "BLOCK_RECORD");
writer->writeString(5, "1E");
if (version > DRW::AC1014) {
writer->writeString(330, "1");
}
writer->writeString(100, "AcDbSymbolTableRecord");
writer->writeString(100, "AcDbBlockTableRecord");
writer->writeString(2, "*Paper_Space");
if (version > DRW::AC1018) {
// writer->writeInt16(340, 22);
writer->writeInt16(70, 0);
writer->writeInt16(280, 1);
writer->writeInt16(281, 0);
}
}
2021-11-22 17:44:44 +01:00
/* always call writeBlockRecords to iface for prepare unnamed blocks */
iface->writeBlockRecords();
if (version > DRW::AC1009) {
writer->writeString(0, "ENDTAB");
}
return true;
}
bool dxfRW::writeBlocks()
{
if (version > DRW::AC1009 || m_xSpaceBlock)
{
writer->writeString(0, "BLOCK");
if (version > DRW::AC1009)
{
writer->writeString(5, "20");
if (version > DRW::AC1014)
{
writer->writeString(330, "1F");
}
writer->writeString(100, "AcDbEntity");
}
writer->writeString(8, "0");
if (version > DRW::AC1009)
{
writer->writeString(100, "AcDbBlockBegin");
writer->writeString(2, "*Model_Space");
}
else
{
writer->writeString(2, "$MODEL_SPACE");
}
writer->writeInt16(70, 0);
writer->writeDouble(10, 0.0);
writer->writeDouble(20, 0.0);
writer->writeDouble(30, 0.0);
if (version > DRW::AC1009)
{
writer->writeString(3, "*Model_Space");
}
else
{
writer->writeString(3, "$MODEL_SPACE");
}
writer->writeString(1, "");
writer->writeString(0, "ENDBLK");
if (version > DRW::AC1009)
{
writer->writeString(5, "21");
if (version > DRW::AC1014)
{
writer->writeString(330, "1F");
}
writer->writeString(100, "AcDbEntity");
}
writer->writeString(8, "0");
if (version > DRW::AC1009)
{
writer->writeString(100, "AcDbBlockEnd");
}
writer->writeString(0, "BLOCK");
if (version > DRW::AC1009)
{
writer->writeString(5, "1C");
if (version > DRW::AC1014)
{
writer->writeString(330, "1B");
}
writer->writeString(100, "AcDbEntity");
}
writer->writeString(8, "0");
if (version > DRW::AC1009)
{
writer->writeString(100, "AcDbBlockBegin");
writer->writeString(2, "*Paper_Space");
}
else
{
writer->writeString(2, "$PAPER_SPACE");
}
writer->writeInt16(70, 0);
writer->writeDouble(10, 0.0);
writer->writeDouble(20, 0.0);
writer->writeDouble(30, 0.0);
if (version > DRW::AC1009)
{
writer->writeString(3, "*Paper_Space");
}
else
{
writer->writeString(3, "$PAPER_SPACE");
}
writer->writeString(1, "");
writer->writeString(0, "ENDBLK");
if (version > DRW::AC1009)
{
writer->writeString(5, "1D");
if (version > DRW::AC1014)
{
writer->writeString(330, "1F");
}
writer->writeString(100, "AcDbEntity");
}
writer->writeString(8, "0");
if (version > DRW::AC1009)
{
writer->writeString(100, "AcDbBlockEnd");
}
}
writingBlock = false;
iface->writeBlocks();
if (writingBlock)
{
writingBlock = false;
writer->writeString(0, "ENDBLK");
if (version > DRW::AC1009)
{
writer->writeString(5, toHexStr(currHandle+2));
// writer->writeString(5, "1D");
if (version > DRW::AC1014)
{
writer->writeString(330, toHexStr(currHandle));
}
writer->writeString(100, "AcDbEntity");
}
writer->writeString(8, "0");
if (version > DRW::AC1009)
{
writer->writeString(100, "AcDbBlockEnd");
}
}
return true;
}
bool dxfRW::writeObjects() {
writer->writeString(0, "DICTIONARY");
std::string imgDictH;
writer->writeString(5, "C");
if (version > DRW::AC1014) {
writer->writeString(330, "0");
}
writer->writeString(100, "AcDbDictionary");
writer->writeInt16(281, 1);
writer->writeString(3, "ACAD_GROUP");
writer->writeString(350, "D");
if (imageDef.size() != 0) {
writer->writeString(3, "ACAD_IMAGE_DICT");
imgDictH = toHexStr(++entCount);
writer->writeString(350, imgDictH);
}
writer->writeString(0, "DICTIONARY");
writer->writeString(5, "D");
writer->writeString(330, "C");
writer->writeString(100, "AcDbDictionary");
writer->writeInt16(281, 1);
//write IMAGEDEF_REACTOR
for (unsigned int i=0; i<imageDef.size(); i++) {
DRW_ImageDef *id = imageDef.at(i);
for (auto it=id->reactors.begin() ; it != id->reactors.end(); ++it ) {
writer->writeString(0, "IMAGEDEF_REACTOR");
writer->writeString(5, (*it).first);
writer->writeString(330, (*it).second);
writer->writeString(100, "AcDbRasterImageDefReactor");
writer->writeInt16(90, 2); //version 2=R14 to v2010
writer->writeString(330, (*it).second);
}
}
if (imageDef.size() != 0) {
writer->writeString(0, "DICTIONARY");
writer->writeString(5, imgDictH);
writer->writeString(330, "C");
writer->writeString(100, "AcDbDictionary");
writer->writeInt16(281, 1);
for (unsigned int i=0; i<imageDef.size(); i++) {
size_t f1, f2;
f1 = imageDef.at(i)->name.find_last_of("/\\");
f2 =imageDef.at(i)->name.find_last_of('.');
++f1;
writer->writeString(3, imageDef.at(i)->name.substr(f1,f2-f1));
writer->writeString(350, toHexStr(static_cast<int>(imageDef.at(i)->handle)) );
}
}
for (unsigned int i=0; i<imageDef.size(); i++) {
DRW_ImageDef *id = imageDef.at(i);
writer->writeString(0, "IMAGEDEF");
writer->writeString(5, toHexStr(static_cast<int>(id->handle)) );
if (version > DRW::AC1014) {
// writer->writeString(330, '0'); handle to DICTIONARY
}
writer->writeString(102, "{ACAD_REACTORS");
for (auto it=id->reactors.begin() ; it != id->reactors.end(); ++it ) {
writer->writeString(330, (*it).first);
}
writer->writeString(102, "}");
writer->writeString(100, "AcDbRasterImageDef");
writer->writeInt16(90, 0); //version 0=R14 to v2010
writer->writeUtf8String(1, id->fileName);
writer->writeDouble(10, id->u);
writer->writeDouble(20, id->v);
writer->writeDouble(11, id->up);
writer->writeDouble(21, id->vp);
writer->writeInt16(280, id->loaded);
writer->writeInt16(281, id->resolution);
}
//no more needed imageDef, delete it
while (!imageDef.empty()) {
imageDef.pop_back();
}
iface->writeObjects();
return true;
}
bool dxfRW::writeExtData(const std::vector<DRW_Variant*> &ed){
for (std::vector<DRW_Variant*>::const_iterator it=ed.begin(); it!=ed.end(); ++it){
switch ((*it)->code) {
case 1000:
case 1001:
case 1002:
case 1003:
case 1004:
case 1005:
{int cc = (*it)->code;
if ((*it)->type == DRW_Variant::STRING)
writer->writeUtf8String(cc, *(*it)->content.s);
// writer->writeUtf8String((*it)->code, (*it)->content.s);
break;}
case 1010:
case 1011:
case 1012:
case 1013:
if ((*it)->type == DRW_Variant::COORD) {
writer->writeDouble((*it)->code, (*it)->content.v->x);
writer->writeDouble((*it)->code+10 , (*it)->content.v->y);
writer->writeDouble((*it)->code+20 , (*it)->content.v->z);
}
break;
case 1040:
case 1041:
case 1042:
if ((*it)->type == DRW_Variant::DOUBLE)
writer->writeDouble((*it)->code, (*it)->content.d);
break;
case 1070:
if ((*it)->type == DRW_Variant::INTEGER)
writer->writeInt16((*it)->code, (*it)->content.i);
break;
case 1071:
if ((*it)->type == DRW_Variant::INTEGER)
writer->writeInt32((*it)->code, (*it)->content.i);
break;
default:
break;
}
}
return true;
}
/********* Reader Process *********/
bool dxfRW::processDxf() {
DRW_DBG("dxfRW::processDxf() start processing dxf\n");
int code = -1;
bool inSection = false;
reader->setIgnoreComments( false);
while (reader->readRec(&code)) {
DRW_DBG(code); DRW_DBG(" code\n");
/* at this level we should only get:
999 - Comment
0 - SECTION or EOF
2 - section name
everything else between "2 - section name" and "0 - ENDSEC" is handled in process() methods
*/
switch (code) {
case 999: // when DXF was created by libdxfrw, first record is a comment with dxfrw version info
header.addComment( reader->getString());
continue;
case 0:
// ignore further comments, as libdxfrw doesn't support comments in sections
reader->setIgnoreComments( true);
if (!inSection) {
std::string sectionstr {reader->getString()};
if ("SECTION" == sectionstr) {
DRW_DBG(sectionstr); DRW_DBG(" new section\n");
inSection = true;
continue;
}
if ("EOF" == sectionstr) {
return true; //found EOF terminate
}
}
else {
// in case SECTION was unknown or not supported
if ("ENDSEC" == reader->getString()) {
inSection = false;
}
}
break;
case 2:
if (inSection) {
bool processed {false};
std::string sectionname {reader->getString()};
DRW_DBG(sectionname); DRW_DBG(" process section\n");
if ("HEADER" == sectionname) {
processed = processHeader();
}
else if ("TABLES" == sectionname) {
processed = processTables();
}
else if ("BLOCKS" == sectionname) {
processed = processBlocks();
}
else if ("ENTITIES" == sectionname) {
processed = processEntities(false);
}
else if ("OBJECTS" == sectionname) {
processed = processObjects();
}
else {
//TODO handle CLASSES
DRW_DBG("section unknown or not supported\n");
continue;
}
if (!processed) {
DRW_DBG(" failed\n");
return setError(DRW::BAD_READ_SECTION);
}
inSection = false;
}
continue;
default:
// landing here means an unknown or not supported SECTION
inSection = false;
break;
}
/* if (!more)
return true;*/
}
if (0 == code && "EOF" == reader->getString()) {
// in case the final EOF has no newline we end up here!
// this is caused by filestr->good() which is false for missing newline on EOF
return true;
}
return setError(DRW::BAD_UNKNOWN);
}
/********* Header Section *********/
bool dxfRW::processHeader() {
DRW_DBG("dxfRW::processHeader\n");
int code;
std::string sectionstr;
while (reader->readRec(&code)) {
DRW_DBG(code); DRW_DBG(" processHeader\n");
if (code == 0) {
sectionstr = reader->getString();
DRW_DBG(sectionstr); DRW_DBG(" processHeader\n\n");
if (sectionstr == "ENDSEC") {
iface->addHeader(&header);
return true; //found ENDSEC terminate
}
DRW_DBG("unexpected 0 code in header!\n");
return setError(DRW::BAD_READ_HEADER);
}
if (!header.parseCode(code, reader)) {
return setError(DRW::BAD_CODE_PARSED);
}
}
return setError(DRW::BAD_READ_HEADER);
}
/********* Tables Section *********/
bool dxfRW::processTables() {
DRW_DBG("dxfRW::processTables\n");
int code;
std::string sectionstr;
bool more = true;
while (reader->readRec(&code)) {
DRW_DBG(code); DRW_DBG("\n");
if (code == 0) {
sectionstr = reader->getString();
DRW_DBG(sectionstr); DRW_DBG(" processHeader\n\n");
if (sectionstr == "TABLE") {
more = reader->readRec(&code);
DRW_DBG(code); DRW_DBG("\n");
if (!more) {
return setError(DRW::BAD_READ_TABLES); //wrong dxf file
}
if (code == 2) {
sectionstr = reader->getString();
DRW_DBG(sectionstr); DRW_DBG(" processHeader\n\n");
//found section, process it
if (sectionstr == "LTYPE") {
processLType();
} else if (sectionstr == "LAYER") {
processLayer();
} else if (sectionstr == "STYLE") {
processTextStyle();
} else if (sectionstr == "VPORT") {
processVports();
} else if (sectionstr == "VIEW") {
// processView();
} else if (sectionstr == "UCS") {
// processUCS();
} else if (sectionstr == "APPID") {
processAppId();
} else if (sectionstr == "DIMSTYLE") {
processDimStyle();
} else if (sectionstr == "BLOCK_RECORD") {
// processBlockRecord();
}
}
} else if (sectionstr == "ENDSEC") {
return true; //found ENDSEC terminate
}
}
}
return setError(DRW::BAD_READ_TABLES);
}
bool dxfRW::processLType() {
DRW_DBG("dxfRW::processLType\n");
int code;
std::string sectionstr;
bool reading = false;
DRW_LType ltype;
while (reader->readRec(&code)) {
DRW_DBG(code); DRW_DBG("\n");
if (code == 0) {
if (reading) {
ltype.update();
iface->addLType(ltype);
}
sectionstr = reader->getString();
DRW_DBG(sectionstr); DRW_DBG("\n");
if (sectionstr == "LTYPE") {
reading = true;
ltype.reset();
} else if (sectionstr == "ENDTAB") {
return true; //found ENDTAB terminate
}
} else if (reading) {
if (!ltype.parseCode(code, reader)) {
return setError( DRW::BAD_CODE_PARSED);
}
}
}
return setError(DRW::BAD_READ_TABLES);
}
bool dxfRW::processLayer() {
DRW_DBG("dxfRW::processLayer\n");
int code;
std::string sectionstr;
bool reading = false;
DRW_Layer layer;
while (reader->readRec(&code)) {
DRW_DBG(code); DRW_DBG("\n");
if (code == 0) {
if (reading)
iface->addLayer(layer);
sectionstr = reader->getString();
DRW_DBG(sectionstr); DRW_DBG("\n");
if (sectionstr == "LAYER") {
reading = true;
layer.reset();
} else if (sectionstr == "ENDTAB") {
return true; //found ENDTAB terminate
}
} else if (reading) {
if (!layer.parseCode(code, reader)) {
return setError( DRW::BAD_CODE_PARSED);
}
}
}
return setError(DRW::BAD_READ_TABLES);
}
bool dxfRW::processDimStyle() {
DRW_DBG("dxfRW::processDimStyle");
int code;
std::string sectionstr;
bool reading = false;
DRW_Dimstyle dimSty;
while (reader->readRec(&code)) {
DRW_DBG(code); DRW_DBG("\n");
if (code == 0) {
if (reading)
iface->addDimStyle(dimSty);
sectionstr = reader->getString();
DRW_DBG(sectionstr); DRW_DBG("\n");
if (sectionstr == "DIMSTYLE") {
reading = true;
dimSty.reset();
} else if (sectionstr == "ENDTAB") {
return true; //found ENDTAB terminate
}
} else if (reading) {
if (!dimSty.parseCode(code, reader)) {
return setError(DRW::BAD_CODE_PARSED);
}
}
}
return setError(DRW::BAD_READ_TABLES);
}
bool dxfRW::processTextStyle(){
DRW_DBG("dxfRW::processTextStyle");
int code;
std::string sectionstr;
bool reading = false;
DRW_Textstyle TxtSty;
while (reader->readRec(&code)) {
DRW_DBG(code); DRW_DBG("\n");
if (code == 0) {
if (reading)
iface->addTextStyle(TxtSty);
sectionstr = reader->getString();
DRW_DBG(sectionstr); DRW_DBG("\n");
if (sectionstr == "STYLE") {
reading = true;
TxtSty.reset();
} else if (sectionstr == "ENDTAB") {
return true; //found ENDTAB terminate
}
} else if (reading) {
if (!TxtSty.parseCode(code, reader)) {
return setError( DRW::BAD_CODE_PARSED);
}
}
}
return setError(DRW::BAD_READ_TABLES);
}
bool dxfRW::processVports(){
DRW_DBG("dxfRW::processVports");
int code;
std::string sectionstr;
bool reading = false;
DRW_Vport vp;
while (reader->readRec(&code)) {
DRW_DBG(code); DRW_DBG("\n");
if (code == 0) {
if (reading)
iface->addVport(vp);
sectionstr = reader->getString();
DRW_DBG(sectionstr); DRW_DBG("\n");
if (sectionstr == "VPORT") {
reading = true;
vp.reset();
} else if (sectionstr == "ENDTAB") {
return true; //found ENDTAB terminate
}
} else if (reading) {
if (!vp.parseCode(code, reader)) {
return setError( DRW::BAD_CODE_PARSED);
}
}
}
return setError(DRW::BAD_READ_TABLES);
}
bool dxfRW::processAppId(){
DRW_DBG("dxfRW::processAppId");
int code;
std::string sectionstr;
bool reading = false;
DRW_AppId vp;
while (reader->readRec(&code)) {
DRW_DBG(code); DRW_DBG("\n");
if (code == 0) {
if (reading)
iface->addAppId(vp);
sectionstr = reader->getString();
DRW_DBG(sectionstr); DRW_DBG("\n");
if (sectionstr == "APPID") {
reading = true;
vp.reset();
} else if (sectionstr == "ENDTAB") {
return true; //found ENDTAB terminate
}
} else if (reading) {
if (!vp.parseCode(code, reader)) {
return setError(DRW::BAD_CODE_PARSED);
}
}
}
return setError(DRW::BAD_READ_TABLES);
}
/********* Block Section *********/
bool dxfRW::processBlocks() {
DRW_DBG("dxfRW::processBlocks\n");
int code;
std::string sectionstr;
while (reader->readRec(&code)) {
DRW_DBG(code); DRW_DBG("\n");
if (code == 0) {
sectionstr = reader->getString();
DRW_DBG(sectionstr); DRW_DBG("\n");
if (sectionstr == "BLOCK") {
processBlock();
} else if (sectionstr == "ENDSEC") {
return true; //found ENDSEC terminate
}
}
}
return setError(DRW::BAD_READ_BLOCKS);
}
bool dxfRW::processBlock() {
DRW_DBG("dxfRW::processBlock");
int code;
DRW_Block block;
while (reader->readRec(&code)) {
DRW_DBG(code); DRW_DBG("\n");
if (0 == code) {
nextentity = reader->getString();
DRW_DBG(nextentity); DRW_DBG("\n");
iface->addBlock(block);
if (nextentity == "ENDBLK") {
iface->endBlock();
return true; //found ENDBLK, terminate
} else {
processEntities(true);
iface->endBlock();
return true; //found ENDBLK, terminate
}
}
if (!block.parseCode(code, reader)) {
return setError( DRW::BAD_CODE_PARSED);
}
}
return setError(DRW::BAD_READ_BLOCKS);
}
/********* Entities Section *********/
bool dxfRW::processEntities(bool isblock) {
DRW_DBG("dxfRW::processEntities\n");
int code;
if (!reader->readRec(&code)){
return setError(DRW::BAD_READ_ENTITIES);
}
2021-11-24 13:50:31 +01:00
if (code == 0) {
nextentity = reader->getString();
} else if (!isblock) {
return setError(DRW::BAD_READ_ENTITIES); //first record in entities is 0
}
2021-11-24 13:50:31 +01:00
bool processed {false};
do {
if (nextentity == "ENDSEC" || nextentity == "ENDBLK") {
return true; //found ENDSEC or ENDBLK terminate
} else if (nextentity == "POINT") {
processed = processPoint();
} else if (nextentity == "LINE") {
processed = processLine();
} else if (nextentity == "CIRCLE") {
processed = processCircle();
} else if (nextentity == "ARC") {
processed = processArc();
} else if (nextentity == "ELLIPSE") {
processed = processEllipse();
} else if (nextentity == "TRACE") {
processed = processTrace();
} else if (nextentity == "SOLID") {
processed = processSolid();
} else if (nextentity == "INSERT") {
processed = processInsert();
} else if (nextentity == "LWPOLYLINE") {
processed = processLWPolyline();
} else if (nextentity == "POLYLINE") {
processed = processPolyline();
} else if (nextentity == "TEXT") {
processed = processText();
} else if (nextentity == "MTEXT") {
processed = processMText();
} else if (nextentity == "HATCH") {
processed = processHatch();
} else if (nextentity == "SPLINE") {
processed = processSpline();
} else if (nextentity == "3DFACE") {
processed = process3dface();
} else if (nextentity == "VIEWPORT") {
processed = processViewport();
} else if (nextentity == "IMAGE") {
processed = processImage();
} else if (nextentity == "DIMENSION") {
processed = processDimension();
} else if (nextentity == "LEADER") {
processed = processLeader();
} else if (nextentity == "RAY") {
processed = processRay();
} else if (nextentity == "XLINE") {
processed = processXline();
} else {
if (!reader->readRec(&code)) {
return setError(DRW::BAD_READ_ENTITIES); //end of file without ENDSEC
}
if (code == 0) {
nextentity = reader->getString();
}
processed = true;
}
} while (processed);
return setError(DRW::BAD_READ_ENTITIES);
}
bool dxfRW::processEllipse() {
DRW_DBG("dxfRW::processEllipse");
int code;
DRW_Ellipse ellipse;
while (reader->readRec(&code)) {
DRW_DBG(code); DRW_DBG("\n");
if (0 == code) {
nextentity = reader->getString();
DRW_DBG(nextentity); DRW_DBG("\n");
if (applyExt)
ellipse.applyExtrusion();
iface->addEllipse(ellipse);
return true; //found new entity or ENDSEC, terminate
}
if (!ellipse.parseCode(code, reader)) {
return setError( DRW::BAD_CODE_PARSED);
}
}
return setError(DRW::BAD_READ_ENTITIES);
}
bool dxfRW::processTrace() {
DRW_DBG("dxfRW::processTrace");
int code;
DRW_Trace trace;
while (reader->readRec(&code)) {
DRW_DBG(code); DRW_DBG("\n");
if (0 == code) {
nextentity = reader->getString();
DRW_DBG(nextentity); DRW_DBG("\n");
if (applyExt)
trace.applyExtrusion();
iface->addTrace(trace);
return true; //found new entity or ENDSEC, terminate
}
if (!trace.parseCode(code, reader)) {
return setError( DRW::BAD_CODE_PARSED);
}
}
return setError(DRW::BAD_READ_ENTITIES);
}
bool dxfRW::processSolid() {
DRW_DBG("dxfRW::processSolid");
int code;
DRW_Solid solid;
while (reader->readRec(&code)) {
DRW_DBG(code); DRW_DBG("\n");
if (0 == code) {
nextentity = reader->getString();
DRW_DBG(nextentity); DRW_DBG("\n");
if (applyExt)
solid.applyExtrusion();
iface->addSolid(solid);
return true; //found new entity or ENDSEC, terminate
}
if (!solid.parseCode(code, reader)) {
return setError( DRW::BAD_CODE_PARSED);
}
}
return setError(DRW::BAD_READ_ENTITIES);
}
bool dxfRW::process3dface() {
DRW_DBG("dxfRW::process3dface");
int code;
DRW_3Dface face;
while (reader->readRec(&code)) {
DRW_DBG(code); DRW_DBG("\n");
if (0 == code) {
nextentity = reader->getString();
DRW_DBG(nextentity); DRW_DBG("\n");
iface->add3dFace(face);
return true; //found new entity or ENDSEC, terminate
}
if (!face.parseCode(code, reader)) {
return setError( DRW::BAD_CODE_PARSED);
}
}
return setError(DRW::BAD_READ_ENTITIES);
}
bool dxfRW::processViewport() {
DRW_DBG("dxfRW::processViewport");
int code;
DRW_Viewport vp;
while (reader->readRec(&code)) {
DRW_DBG(code); DRW_DBG("\n");
if (0 == code) {
nextentity = reader->getString();
DRW_DBG(nextentity); DRW_DBG("\n");
iface->addViewport(vp);
return true; //found new entity or ENDSEC, terminate
}
if (!vp.parseCode(code, reader)) {
return setError( DRW::BAD_CODE_PARSED);
}
}
return setError(DRW::BAD_READ_ENTITIES);
}
bool dxfRW::processPoint() {
DRW_DBG("dxfRW::processPoint\n");
int code;
DRW_Point point;
while (reader->readRec(&code)) {
DRW_DBG(code); DRW_DBG("\n");
if (0 == code) {
nextentity = reader->getString();
DRW_DBG(nextentity); DRW_DBG("\n");
iface->addPoint(point);
return true; //found new entity or ENDSEC, terminate
}
if (!point.parseCode(code, reader)) {
return setError( DRW::BAD_CODE_PARSED);
}
}
return setError(DRW::BAD_READ_ENTITIES);
}
bool dxfRW::processLine() {
DRW_DBG("dxfRW::processLine\n");
int code;
DRW_Line line;
while (reader->readRec(&code)) {
DRW_DBG(code); DRW_DBG("\n");
if (0 == code) {
nextentity = reader->getString();
DRW_DBG(nextentity); DRW_DBG("\n");
iface->addLine(line);
return true; //found new entity or ENDSEC, terminate
}
if (!line.parseCode(code, reader)) {
return setError( DRW::BAD_CODE_PARSED);
}
}
return setError(DRW::BAD_READ_ENTITIES);
}
bool dxfRW::processRay() {
DRW_DBG("dxfRW::processRay\n");
int code;
DRW_Ray line;
while (reader->readRec(&code)) {
DRW_DBG(code); DRW_DBG("\n");
if (0 == code) {
nextentity = reader->getString();
DRW_DBG(nextentity); DRW_DBG("\n");
iface->addRay(line);
return true; //found new entity or ENDSEC, terminate
}
if (!line.parseCode(code, reader)) {
return setError( DRW::BAD_CODE_PARSED);
}
}
return setError(DRW::BAD_READ_ENTITIES);
}
bool dxfRW::processXline() {
DRW_DBG("dxfRW::processXline\n");
int code;
DRW_Xline line;
while (reader->readRec(&code)) {
DRW_DBG(code); DRW_DBG("\n");
if (0 == code) {
nextentity = reader->getString();
DRW_DBG(nextentity); DRW_DBG("\n");
iface->addXline(line);
return true; //found new entity or ENDSEC, terminate
}
if (!line.parseCode(code, reader)) {
return setError( DRW::BAD_CODE_PARSED);
}
}
return setError(DRW::BAD_READ_ENTITIES);
}
bool dxfRW::processCircle() {
DRW_DBG("dxfRW::processPoint\n");
int code;
DRW_Circle circle;
while (reader->readRec(&code)) {
DRW_DBG(code); DRW_DBG("\n");
if (0 == code) {
nextentity = reader->getString();
DRW_DBG(nextentity); DRW_DBG("\n");
if (applyExt)
circle.applyExtrusion();
iface->addCircle(circle);
return true; //found new entity or ENDSEC, terminate
}
if (!circle.parseCode(code, reader)) {
return setError( DRW::BAD_CODE_PARSED);
}
}
return setError(DRW::BAD_READ_ENTITIES);
}
bool dxfRW::processArc() {
DRW_DBG("dxfRW::processPoint\n");
int code;
DRW_Arc arc;
while (reader->readRec(&code)) {
DRW_DBG(code); DRW_DBG("\n");
if (0 == code) {
nextentity = reader->getString();
DRW_DBG(nextentity); DRW_DBG("\n");
if (applyExt)
arc.applyExtrusion();
iface->addArc(arc);
return true; //found new entity or ENDSEC, terminate
}
if (!arc.parseCode(code, reader)) {
return setError( DRW::BAD_CODE_PARSED);
}
}
return setError(DRW::BAD_READ_ENTITIES);
}
bool dxfRW::processInsert() {
DRW_DBG("dxfRW::processInsert");
int code;
DRW_Insert insert;
while (reader->readRec(&code)) {
DRW_DBG(code); DRW_DBG("\n");
if (0 == code) {
nextentity = reader->getString();
DRW_DBG(nextentity); DRW_DBG("\n");
iface->addInsert(insert);
return true; //found new entity or ENDSEC, terminate
}
if (!insert.parseCode(code, reader)) {
return setError( DRW::BAD_CODE_PARSED);
}
}
return setError(DRW::BAD_READ_ENTITIES);
}
bool dxfRW::processLWPolyline() {
DRW_DBG("dxfRW::processLWPolyline");
int code;
DRW_LWPolyline pl;
while (reader->readRec(&code)) {
DRW_DBG(code); DRW_DBG("\n");
if (0 == code) {
nextentity = reader->getString();
DRW_DBG(nextentity); DRW_DBG("\n");
if (applyExt)
pl.applyExtrusion();
iface->addLWPolyline(pl);
return true; //found new entity or ENDSEC, terminate
}
if (!pl.parseCode(code, reader)) {
return setError( DRW::BAD_CODE_PARSED);
}
}
return setError(DRW::BAD_READ_ENTITIES);
}
bool dxfRW::processPolyline() {
DRW_DBG("dxfRW::processPolyline");
int code;
DRW_Polyline pl;
while (reader->readRec(&code)) {
DRW_DBG(code); DRW_DBG("\n");
if (0 == code) {
nextentity = reader->getString();
DRW_DBG(nextentity); DRW_DBG("\n");
if (nextentity != "VERTEX") {
2022-08-13 18:27:47 +02:00
iface->addPolyline(pl);
return true; //found new entity or ENDSEC, terminate
}
2022-08-13 18:27:47 +02:00
processVertex(&pl);
}
if (!pl.parseCode(code, reader)) { //parseCode just initialize the members of pl
return setError(DRW::BAD_CODE_PARSED);
}
}
return setError(DRW::BAD_READ_ENTITIES);
}
bool dxfRW::processVertex(DRW_Polyline *pl) {
DRW_DBG("dxfRW::processVertex");
int code;
std::unique_ptr<DRW_Vertex> v(new DRW_Vertex());
while (reader->readRec(&code)) {
DRW_DBG(code); DRW_DBG("\n");
if (0 == code) {
pl->appendVertex(v.release());
nextentity = reader->getString();
DRW_DBG(nextentity); DRW_DBG("\n");
if (nextentity == "SEQEND") {
2022-08-13 18:27:47 +02:00
return true; //found SEQEND no more vertex, terminate
}
if (nextentity == "VERTEX"){
v.reset(new DRW_Vertex()); //another vertex
}
}
if (!v->parseCode(code, reader)) { //the members of v are reinitialized here
return setError( DRW::BAD_CODE_PARSED);
}
}
return setError(DRW::BAD_READ_ENTITIES);
}
bool dxfRW::processText() {
DRW_DBG("dxfRW::processText");
int code;
DRW_Text txt;
while (reader->readRec(&code)) {
DRW_DBG(code); DRW_DBG("\n");
if (0 == code) {
nextentity = reader->getString();
DRW_DBG(nextentity); DRW_DBG("\n");
iface->addText(txt);
return true; //found new entity or ENDSEC, terminate
}
if (!txt.parseCode(code, reader)) {
return setError( DRW::BAD_CODE_PARSED);
}
}
return setError(DRW::BAD_READ_ENTITIES);
}
bool dxfRW::processMText() {
DRW_DBG("dxfRW::processMText");
int code;
DRW_MText txt;
while (reader->readRec(&code)) {
DRW_DBG(code); DRW_DBG("\n");
if (0 == code) {
nextentity = reader->getString();
DRW_DBG(nextentity); DRW_DBG("\n");
txt.updateAngle();
iface->addMText(txt);
return true; //found new entity or ENDSEC, terminate
}
if (!txt.parseCode(code, reader)) {
return setError( DRW::BAD_CODE_PARSED);
}
}
return setError(DRW::BAD_READ_ENTITIES);
}
bool dxfRW::processHatch() {
DRW_DBG("dxfRW::processHatch");
int code;
DRW_Hatch hatch;
while (reader->readRec(&code)) {
DRW_DBG(code); DRW_DBG("\n");
if (0 == code) {
nextentity = reader->getString();
DRW_DBG(nextentity); DRW_DBG("\n");
iface->addHatch(&hatch);
return true; //found new entity or ENDSEC, terminate
}
if (!hatch.parseCode(code, reader)) {
return setError( DRW::BAD_CODE_PARSED);
}
}
return setError(DRW::BAD_READ_ENTITIES);
}
bool dxfRW::processSpline() {
DRW_DBG("dxfRW::processSpline");
int code;
DRW_Spline sp;
while (reader->readRec(&code)) {
DRW_DBG(code); DRW_DBG("\n");
if (0 == code) {
nextentity = reader->getString();
DRW_DBG(nextentity); DRW_DBG("\n");
iface->addSpline(&sp);
return true; //found new entity or ENDSEC, terminate
}
if (!sp.parseCode(code, reader)) {
return setError( DRW::BAD_CODE_PARSED);
}
}
return setError(DRW::BAD_READ_ENTITIES);
}
bool dxfRW::processImage() {
DRW_DBG("dxfRW::processImage");
int code;
DRW_Image img;
while (reader->readRec(&code)) {
DRW_DBG(code); DRW_DBG("\n");
if (0 == code) {
nextentity = reader->getString();
DRW_DBG(nextentity); DRW_DBG("\n");
iface->addImage(&img);
return true; //found new entity or ENDSEC, terminate
}
if (!img.parseCode(code, reader)) {
return setError( DRW::BAD_CODE_PARSED);
}
}
return setError(DRW::BAD_READ_ENTITIES);
}
bool dxfRW::processDimension() {
DRW_DBG("dxfRW::processDimension");
int code;
DRW_Dimension dim;
while (reader->readRec(&code)) {
DRW_DBG(code); DRW_DBG("\n");
if (0 == code) {
nextentity = reader->getString();
DRW_DBG(nextentity); DRW_DBG("\n");
int type = dim.type & 0x0F;
2017-07-05 18:35:34 +02:00
QT_WARNING_PUSH
QT_WARNING_DISABLE_GCC("-Wswitch-default")
switch (type) {
case 0: {
DRW_DimLinear d(dim);
iface->addDimLinear(&d);
break; }
case 1: {
DRW_DimAligned d(dim);
iface->addDimAlign(&d);
break; }
case 2: {
DRW_DimAngular d(dim);
iface->addDimAngular(&d);
break;}
case 3: {
DRW_DimDiametric d(dim);
iface->addDimDiametric(&d);
break; }
case 4: {
DRW_DimRadial d(dim);
iface->addDimRadial(&d);
break; }
case 5: {
DRW_DimAngular3p d(dim);
iface->addDimAngular3P(&d);
break; }
case 6: {
DRW_DimOrdinate d(dim);
iface->addDimOrdinate(&d);
break; }
}
2017-07-05 18:35:34 +02:00
2022-08-08 14:25:14 +02:00
// cppcheck-suppress unknownMacro
2017-07-05 18:35:34 +02:00
QT_WARNING_POP
return true; //found new entity or ENDSEC, terminate
}
if (!dim.parseCode(code, reader)) {
return setError( DRW::BAD_CODE_PARSED);
}
}
return setError(DRW::BAD_READ_ENTITIES);
}
bool dxfRW::processLeader() {
DRW_DBG("dxfRW::processLeader");
int code;
DRW_Leader leader;
while (reader->readRec(&code)) {
DRW_DBG(code); DRW_DBG("\n");
if (0 == code) {
nextentity = reader->getString();
DRW_DBG(nextentity); DRW_DBG("\n");
iface->addLeader(&leader);
return true; //found new entity or ENDSEC, terminate
}
if (!leader.parseCode(code, reader)) {
return setError( DRW::BAD_CODE_PARSED);
}
}
return setError(DRW::BAD_READ_ENTITIES);
}
/********* Objects Section *********/
bool dxfRW::processObjects() {
DRW_DBG("dxfRW::processObjects\n");
int code;
if (!reader->readRec(&code) || 0 != code){
return setError(DRW::BAD_READ_OBJECTS); //first record in objects must be 0
}
bool processed = false;
nextentity = reader->getString();
do {
if ("ENDSEC" == nextentity) {
return true; //found ENDSEC terminate
}
if ("IMAGEDEF" == nextentity) {
processed = processImageDef();
}
else if ("PLOTSETTINGS" == nextentity) {
processed = processPlotSettings();
}
else {
if (!reader->readRec(&code)) {
return setError(DRW::BAD_READ_OBJECTS); //end of file without ENDSEC
}
if (code == 0) {
nextentity = reader->getString();
}
processed = true;
}
}
while (processed);
return setError(DRW::BAD_READ_OBJECTS);
}
bool dxfRW::processImageDef() {
DRW_DBG("dxfRW::processImageDef");
int code;
DRW_ImageDef img;
while (reader->readRec(&code)) {
DRW_DBG(code); DRW_DBG("\n");
if (0 == code) {
nextentity = reader->getString();
DRW_DBG(nextentity); DRW_DBG("\n");
iface->linkImage(&img);
return true; //found new entity or ENDSEC, terminate
}
if (!img.parseCode(code, reader)) {
return setError( DRW::BAD_CODE_PARSED);
}
}
return setError(DRW::BAD_READ_OBJECTS);
}
bool dxfRW::processPlotSettings() {
DRW_DBG("dxfRW::processPlotSettings");
int code;
DRW_PlotSettings ps;
while (reader->readRec(&code)) {
DRW_DBG(code); DRW_DBG("\n");
if (0 == code) {
nextentity = reader->getString();
DRW_DBG(nextentity); DRW_DBG("\n");
iface->addPlotSettings(&ps);
return true; //found new entity or ENDSEC, terminate
}
if (!ps.parseCode(code, reader)) {
return setError( DRW::BAD_CODE_PARSED);
}
}
return setError(DRW::BAD_READ_OBJECTS);
}
bool dxfRW::writePlotSettings(DRW_PlotSettings *ent) {
writer->writeString(0, "PLOTSETTINGS");
writer->writeString(5, toHexStr(++entCount));
writer->writeString(100, "AcDbPlotSettings");
writer->writeUtf8String(6, ent->plotViewName);
writer->writeDouble(40, ent->marginLeft);
writer->writeDouble(41, ent->marginBottom);
writer->writeDouble(42, ent->marginRight);
writer->writeDouble(43, ent->marginTop);
return true;
}
/** utility function
* convert a int to string in hex
**/
std::string dxfRW::toHexStr(int n){
#if defined(__APPLE__)
char buffer[9]= {'\0'};
snprintf(buffer,9, "%X", n);
return std::string(buffer);
#else
std::ostringstream Convert;
Convert << std::uppercase << std::hex << n;
return Convert.str();
#endif
}
DRW::Version dxfRW::getVersion() const {
return version;
}
DRW::error dxfRW::getError() const
{
return error;
}
bool dxfRW::setError(const DRW::error lastError)
{
error = lastError;
return (DRW::BAD_NONE == error);
}