diff --git a/ChangeLog.txt b/ChangeLog.txt index 0c10913ef..bf4ace27f 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -18,6 +18,7 @@ - Fix QT issue on MacOS version 11.0 "Big Sur". - Fix excluding objects in internal path. - Fix float-point accuracy issue in multisize measurements dimensions. +- Fix compatibility with Richpeace DXF-AAMA/ASTM R12. # Valentina 0.7.52 September 12, 2022 - Fix crash when default locale is ru. diff --git a/src/libs/vdxf/dxiface.cpp b/src/libs/vdxf/dxiface.cpp index 1fa4c4887..c51b813b6 100644 --- a/src/libs/vdxf/dxiface.cpp +++ b/src/libs/vdxf/dxiface.cpp @@ -287,12 +287,19 @@ void dx_iface::AddAAMALayers() // layer.name = "26";// REF // layer.color = DRW::black; -// cData.layers.push_back(layer); + // cData.layers.push_back(layer); +} + +void dx_iface::AddDefHeaderData() +{ + cData.headerC.addInt("$HANDLING", 1, 70); // Enabled by default for flat version. } void dx_iface::AddAAMAHeaderData() { cData.headerC.addStr("$CLAYER", "1", 8); // Current layer name + // Looks like doesn't work with handling enabled. + // Missing or 0 for $HANDLING value disables handling. } void dx_iface::AddASTMLayers() diff --git a/src/libs/vdxf/dxiface.h b/src/libs/vdxf/dxiface.h index 023d7a3c2..83c0347a6 100644 --- a/src/libs/vdxf/dxiface.h +++ b/src/libs/vdxf/dxiface.h @@ -101,6 +101,8 @@ public: bool fileExport(bool binary); void writeEntity(DRW_Entity* e); + void AddXSpaceBlock(bool add) {dxfW->AddXSpaceBlock(add);} + std::string ErrorString() const; //reimplement virtual DRW_Interface functions @@ -126,6 +128,7 @@ public: void AddQtLTypes(); void AddDefLayers(); void AddAAMALayers(); + void AddDefHeaderData(); void AddAAMAHeaderData(); void AddASTMLayers(); diff --git a/src/libs/vdxf/libdxfrw/drw_header.cpp b/src/libs/vdxf/libdxfrw/drw_header.cpp index b95432368..4076ed34a 100644 --- a/src/libs/vdxf/libdxfrw/drw_header.cpp +++ b/src/libs/vdxf/libdxfrw/drw_header.cpp @@ -120,31 +120,32 @@ void DRW_Header::write(dxfWriter *writer, DRW::Version ver){ 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::AC1024: //acad 2010 - varStr = "AC1024"; - break; - case DRW::AC1027: //acad 2013 - varStr = "AC1027"; - break; - case DRW::AC1021: //acad 2007 - default: //acad 2007 default version - varStr = "AC1021"; - break; + 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::AC1024: //acad 2010 + varStr = "AC1024"; + break; + case DRW::AC1027: //acad 2013 + varStr = "AC1027"; + break; + case DRW::AC1021: //acad 2007 + default: //acad 2007 default version + varStr = "AC1021"; + break; } writer->writeString(1, varStr); writer->setVersion(varStr, true); @@ -271,14 +272,15 @@ void DRW_Header::write(dxfWriter *writer, DRW::Version ver){ writer->writeUtf8String(7, varStr); else writer->writeString(7, "STANDARD"); - writer->writeString(9, "$CLAYER"); + if (getStr("$CLAYER", &varStr)) + { + writer->writeString(9, "$CLAYER"); if (ver == DRW::AC1009) writer->writeUtf8Caps(8, varStr); else writer->writeUtf8String(8, varStr); - else - writer->writeString(8, "0"); + } writer->writeString(9, "$CELTYPE"); if (getStr("$CELTYPE", &varStr)) if (ver == DRW::AC1009) @@ -878,7 +880,8 @@ void DRW_Header::write(dxfWriter *writer, DRW::Version ver){ writer->writeInt16(70, varInt); } else writer->writeInt16(70, 8); - if (ver < DRW::AC1012) { + if (ver < DRW::AC1012) + { writer->writeString(9, "$ATTDIA"); if (getInt("$ATTDIA", &varInt)) { writer->writeInt16(70, varInt); @@ -889,11 +892,19 @@ void DRW_Header::write(dxfWriter *writer, DRW::Version ver){ writer->writeInt16(70, varInt); } else writer->writeInt16(70, 1); - writer->writeString(9, "$HANDLING"); - if (getInt("$HANDLING", &varInt)) { + + // 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 (getInt("$HANDLING", &varInt)) + { + writer->writeString(9, "$HANDLING"); writer->writeInt16(70, varInt); - } else - writer->writeInt16(70, 1); + } } writer->writeString(9, "$HANDSEED"); //RLZ dxfHex(5, 0xFFFF); @@ -1694,37 +1705,39 @@ void DRW_Header::addCoord(std::string key, const DRW_Coord &value, int code){ vars[key] =curr; } -bool DRW_Header::getDouble(const std::string &key, double *varDouble){ +bool DRW_Header::getDouble(const std::string &key, double *varDouble) const +{ bool result = false; auto it=vars.find( key); - if (it != vars.end()) { + if (it != vars.end()) + { DRW_Variant *var = (*it).second; - if (var->type == DRW_Variant::DOUBLE) { + if (var->type == DRW_Variant::DOUBLE) + { *varDouble = var->content.d; result = true; } - delete var; - vars.erase (it); } return result; } -bool DRW_Header::getInt(const std::string &key, int *varInt){ +bool DRW_Header::getInt(const std::string &key, int *varInt) const +{ bool result = false; auto it=vars.find( key); - if (it != vars.end()) { + if (it != vars.end()) + { DRW_Variant *var = (*it).second; - if (var->type == DRW_Variant::INTEGER) { + if (var->type == DRW_Variant::INTEGER) + { *varInt = var->content.i; result = true; } - delete var; - vars.erase (it); } return result; } -bool DRW_Header::getStr(const std::string &key, std::string *varStr){ +bool DRW_Header::getStr(const std::string &key, std::string *varStr) const{ bool result = false; auto it=vars.find( key); if (it != vars.end()) { @@ -1733,23 +1746,22 @@ bool DRW_Header::getStr(const std::string &key, std::string *varStr){ *varStr = *var->content.s; result = true; } - delete var; - vars.erase (it); } return result; } -bool DRW_Header::getCoord(const std::string &key, DRW_Coord *varCoord){ +bool DRW_Header::getCoord(const std::string &key, DRW_Coord *varCoord) const +{ bool result = false; auto it=vars.find( key); - if (it != vars.end()) { + if (it != vars.end()) + { DRW_Variant *var = (*it).second; - if (var->type == DRW_Variant::COORD) { + if (var->type == DRW_Variant::COORD) + { *varCoord = *var->content.v; result = true; } - delete var; - vars.erase (it); } return result; } diff --git a/src/libs/vdxf/libdxfrw/drw_header.h b/src/libs/vdxf/libdxfrw/drw_header.h index f2c453e4b..ac98207ec 100644 --- a/src/libs/vdxf/libdxfrw/drw_header.h +++ b/src/libs/vdxf/libdxfrw/drw_header.h @@ -117,10 +117,10 @@ public: protected: bool parseCode(int code, dxfReader *reader); private: - bool getDouble(const std::string &key, double *varDouble); - bool getInt(const std::string &key, int *varInt); - bool getStr(const std::string &key, std::string *varStr); - bool getCoord(const std::string &key, DRW_Coord *varCoord); + bool getDouble(const std::string &key, double *varDouble) const; + bool getInt(const std::string &key, int *varInt) const; + bool getStr(const std::string &key, std::string *varStr) const; + bool getCoord(const std::string &key, DRW_Coord *varCoord) const; void clearVars() { for (auto it=vars.begin(); it!=vars.end(); ++it) diff --git a/src/libs/vdxf/libdxfrw/libdxfrw.cpp b/src/libs/vdxf/libdxfrw/libdxfrw.cpp index 2a8bc6bb5..580d77b51 100644 --- a/src/libs/vdxf/libdxfrw/libdxfrw.cpp +++ b/src/libs/vdxf/libdxfrw/libdxfrw.cpp @@ -142,10 +142,10 @@ bool dxfRW::write(DRW_Interface *interface_, DRW::Version ver, bool bin){ std::string comm = std::string("dxfrw ") + std::string(DRW_VERSION); writer->writeString(999, comm); } - DRW_Header header; + this->header = DRW_Header(); iface->writeHeader(header); writer->writeString(0, "SECTION"); - entCount =FIRSTHANDLE; + entCount = FIRSTHANDLE; header.write(writer, version); writer->writeString(0, "ENDSEC"); if (ver > DRW::AC1009) { @@ -190,9 +190,33 @@ bool dxfRW::write(DRW_Interface *interface_, DRW::Version ver, bool bin){ return isOk; } -bool dxfRW::writeEntity(DRW_Entity *ent) { - ent->handle = static_cast(++entCount); - writer->writeString(5, toHexStr(static_cast(ent->handle))); +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(++entCount); + writer->writeString(5, toHexStr(static_cast(ent->handle))); + } + } + } + else + { + ent->handle = static_cast(++entCount); + writer->writeString(5, toHexStr(static_cast(ent->handle))); + } + if (version > DRW::AC1009) { writer->writeString(100, "AcDbEntity"); } @@ -467,6 +491,7 @@ bool dxfRW::writeDimstyle(DRW_Dimstyle *ent){ if (name == "STANDARD") dimstyleStd = true; } + if (version > DRW::AC1009) { writer->writeString(105, toHexStr(++entCount)); } @@ -1694,92 +1719,129 @@ bool dxfRW::writeTables() { return true; } -bool dxfRW::writeBlocks() { - writer->writeString(0, "BLOCK"); - if (version > DRW::AC1009) { - writer->writeString(5, "20"); - if (version > DRW::AC1014) { - writer->writeString(330, "1F"); +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(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(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(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(0, "BLOCK"); + if (version > DRW::AC1009) + { + writer->writeString(5, "1C"); + if (version > DRW::AC1014) + { + writer->writeString(330, "1B"); + } + writer->writeString(100, "AcDbEntity"); } - 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(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"); } - writer->writeString(100, "AcDbEntity"); } - writer->writeString(8, "0"); - if (version > DRW::AC1009) - writer->writeString(100, "AcDbBlockEnd"); writingBlock = false; iface->writeBlocks(); - if (writingBlock) { + if (writingBlock) + { writingBlock = false; writer->writeString(0, "ENDBLK"); - if (version > DRW::AC1009) { + if (version > DRW::AC1009) + { writer->writeString(5, toHexStr(currHandle+2)); // writer->writeString(5, "1D"); - if (version > DRW::AC1014) { + 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; } diff --git a/src/libs/vdxf/libdxfrw/libdxfrw.h b/src/libs/vdxf/libdxfrw/libdxfrw.h index 59e10a2ca..0dee6a8c3 100644 --- a/src/libs/vdxf/libdxfrw/libdxfrw.h +++ b/src/libs/vdxf/libdxfrw/libdxfrw.h @@ -39,6 +39,7 @@ public: */ bool read(DRW_Interface *interface_, bool ext); void setBinary(bool b) {binFile = b;} + void AddXSpaceBlock(bool add) {m_xSpaceBlock = add;} bool write(DRW_Interface *interface_, DRW::Version ver, bool bin); bool writeLineType(DRW_LType *ent); @@ -138,6 +139,7 @@ private: std::string fileName; std::string codePage; bool binFile; + bool m_xSpaceBlock{true}; dxfReader *reader; dxfWriter *writer; DRW_Interface *iface; diff --git a/src/libs/vdxf/vdxfengine.cpp b/src/libs/vdxf/vdxfengine.cpp index c8944ec0a..178cc9ec7 100644 --- a/src/libs/vdxf/vdxfengine.cpp +++ b/src/libs/vdxf/vdxfengine.cpp @@ -157,6 +157,7 @@ auto VDxfEngine::begin(QPaintDevice *pdev) -> bool m_input = QSharedPointer(new dx_iface(GetFileNameForLocale(), m_version, m_varMeasurement, m_varInsunits)); + m_input->AddDefHeaderData(); m_input->AddQtLTypes(); m_input->AddDefLayers(); return true; @@ -700,6 +701,7 @@ auto VDxfEngine::ExportToAAMA(const QVector &details) -> bool } m_input = QSharedPointer::create(GetFileNameForLocale(), m_version, m_varMeasurement, m_varInsunits); + m_input->AddXSpaceBlock(false); m_input->AddAAMAHeaderData(); if (m_version > DRW::AC1009) { @@ -730,6 +732,7 @@ auto VDxfEngine::ExportToAAMA(const QVector &details) -> bool } detailBlock->name = blockName.toStdString(); + detailBlock->flags = 64; detailBlock->layer = *layer1; detail.Scale(m_xscale, m_yscale); @@ -928,7 +931,7 @@ auto VDxfEngine::ExportToASTM(const QVector &details) -> bool m_input = QSharedPointer(new dx_iface(GetFileNameForLocale(), m_version, m_varMeasurement, m_varInsunits)); - + m_input->AddXSpaceBlock(false); m_input->AddAAMAHeaderData(); if (m_version > DRW::AC1009) { diff --git a/src/libs/vdxf/vdxfengine.h b/src/libs/vdxf/vdxfengine.h index 525350f63..8c7e31f10 100644 --- a/src/libs/vdxf/vdxfengine.h +++ b/src/libs/vdxf/vdxfengine.h @@ -115,7 +115,7 @@ private: QSize m_size{}; double m_resolution{PrintDPI}; QString m_fileName{}; - DRW::Version m_version{DRW::AC1014}; + DRW::Version m_version{DRW::AC1009}; bool m_binary{false}; QTransform m_matrix{}; QSharedPointer m_input{};