Fix compatibility with Richpeace DXF-AAMA/ASTM R12.

This commit is contained in:
Roman Telezhynskyi 2023-04-01 15:03:34 +03:00
parent b1470053f7
commit 944d9e71e0
9 changed files with 220 additions and 130 deletions

View File

@ -18,6 +18,7 @@
- Fix QT issue on MacOS version 11.0 "Big Sur". - Fix QT issue on MacOS version 11.0 "Big Sur".
- Fix excluding objects in internal path. - Fix excluding objects in internal path.
- Fix float-point accuracy issue in multisize measurements dimensions. - Fix float-point accuracy issue in multisize measurements dimensions.
- Fix compatibility with Richpeace DXF-AAMA/ASTM R12.
# Valentina 0.7.52 September 12, 2022 # Valentina 0.7.52 September 12, 2022
- Fix crash when default locale is ru. - Fix crash when default locale is ru.

View File

@ -287,12 +287,19 @@ void dx_iface::AddAAMALayers()
// layer.name = "26";// REF // layer.name = "26";// REF
// layer.color = DRW::black; // 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() void dx_iface::AddAAMAHeaderData()
{ {
cData.headerC.addStr("$CLAYER", "1", 8); // Current layer name 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() void dx_iface::AddASTMLayers()

View File

@ -101,6 +101,8 @@ public:
bool fileExport(bool binary); bool fileExport(bool binary);
void writeEntity(DRW_Entity* e); void writeEntity(DRW_Entity* e);
void AddXSpaceBlock(bool add) {dxfW->AddXSpaceBlock(add);}
std::string ErrorString() const; std::string ErrorString() const;
//reimplement virtual DRW_Interface functions //reimplement virtual DRW_Interface functions
@ -126,6 +128,7 @@ public:
void AddQtLTypes(); void AddQtLTypes();
void AddDefLayers(); void AddDefLayers();
void AddAAMALayers(); void AddAAMALayers();
void AddDefHeaderData();
void AddAAMAHeaderData(); void AddAAMAHeaderData();
void AddASTMLayers(); void AddASTMLayers();

View File

@ -120,31 +120,32 @@ void DRW_Header::write(dxfWriter *writer, DRW::Version ver){
DRW_Coord varCoord; DRW_Coord varCoord;
writer->writeString(2, "HEADER"); writer->writeString(2, "HEADER");
writer->writeString(9, "$ACADVER"); writer->writeString(9, "$ACADVER");
switch (ver) { switch (ver)
case DRW::AC1006: //unsupported version acad 10 {
case DRW::AC1009: //acad 11 & 12 case DRW::AC1006: //unsupported version acad 10
varStr = "AC1009"; case DRW::AC1009: //acad 11 & 12
break; varStr = "AC1009";
case DRW::AC1012: //unsupported version acad 13 break;
case DRW::AC1014: //acad 14 case DRW::AC1012: //unsupported version acad 13
varStr = "AC1014"; case DRW::AC1014: //acad 14
break; varStr = "AC1014";
case DRW::AC1015: //acad 2000 break;
varStr = "AC1015"; case DRW::AC1015: //acad 2000
break; varStr = "AC1015";
case DRW::AC1018: //acad 2004 break;
varStr = "AC1018"; case DRW::AC1018: //acad 2004
break; varStr = "AC1018";
case DRW::AC1024: //acad 2010 break;
varStr = "AC1024"; case DRW::AC1024: //acad 2010
break; varStr = "AC1024";
case DRW::AC1027: //acad 2013 break;
varStr = "AC1027"; case DRW::AC1027: //acad 2013
break; varStr = "AC1027";
case DRW::AC1021: //acad 2007 break;
default: //acad 2007 default version case DRW::AC1021: //acad 2007
varStr = "AC1021"; default: //acad 2007 default version
break; varStr = "AC1021";
break;
} }
writer->writeString(1, varStr); writer->writeString(1, varStr);
writer->setVersion(varStr, true); writer->setVersion(varStr, true);
@ -271,14 +272,15 @@ void DRW_Header::write(dxfWriter *writer, DRW::Version ver){
writer->writeUtf8String(7, varStr); writer->writeUtf8String(7, varStr);
else else
writer->writeString(7, "STANDARD"); writer->writeString(7, "STANDARD");
writer->writeString(9, "$CLAYER");
if (getStr("$CLAYER", &varStr)) if (getStr("$CLAYER", &varStr))
{
writer->writeString(9, "$CLAYER");
if (ver == DRW::AC1009) if (ver == DRW::AC1009)
writer->writeUtf8Caps(8, varStr); writer->writeUtf8Caps(8, varStr);
else else
writer->writeUtf8String(8, varStr); writer->writeUtf8String(8, varStr);
else }
writer->writeString(8, "0");
writer->writeString(9, "$CELTYPE"); writer->writeString(9, "$CELTYPE");
if (getStr("$CELTYPE", &varStr)) if (getStr("$CELTYPE", &varStr))
if (ver == DRW::AC1009) if (ver == DRW::AC1009)
@ -878,7 +880,8 @@ void DRW_Header::write(dxfWriter *writer, DRW::Version ver){
writer->writeInt16(70, varInt); writer->writeInt16(70, varInt);
} else } else
writer->writeInt16(70, 8); writer->writeInt16(70, 8);
if (ver < DRW::AC1012) { if (ver < DRW::AC1012)
{
writer->writeString(9, "$ATTDIA"); writer->writeString(9, "$ATTDIA");
if (getInt("$ATTDIA", &varInt)) { if (getInt("$ATTDIA", &varInt)) {
writer->writeInt16(70, varInt); writer->writeInt16(70, varInt);
@ -889,11 +892,19 @@ void DRW_Header::write(dxfWriter *writer, DRW::Version ver){
writer->writeInt16(70, varInt); writer->writeInt16(70, varInt);
} else } else
writer->writeInt16(70, 1); 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); writer->writeInt16(70, varInt);
} else }
writer->writeInt16(70, 1);
} }
writer->writeString(9, "$HANDSEED"); writer->writeString(9, "$HANDSEED");
//RLZ dxfHex(5, 0xFFFF); //RLZ dxfHex(5, 0xFFFF);
@ -1694,37 +1705,39 @@ void DRW_Header::addCoord(std::string key, const DRW_Coord &value, int code){
vars[key] =curr; 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; bool result = false;
auto it=vars.find( key); auto it=vars.find( key);
if (it != vars.end()) { if (it != vars.end())
{
DRW_Variant *var = (*it).second; DRW_Variant *var = (*it).second;
if (var->type == DRW_Variant::DOUBLE) { if (var->type == DRW_Variant::DOUBLE)
{
*varDouble = var->content.d; *varDouble = var->content.d;
result = true; result = true;
} }
delete var;
vars.erase (it);
} }
return result; 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; bool result = false;
auto it=vars.find( key); auto it=vars.find( key);
if (it != vars.end()) { if (it != vars.end())
{
DRW_Variant *var = (*it).second; DRW_Variant *var = (*it).second;
if (var->type == DRW_Variant::INTEGER) { if (var->type == DRW_Variant::INTEGER)
{
*varInt = var->content.i; *varInt = var->content.i;
result = true; result = true;
} }
delete var;
vars.erase (it);
} }
return result; 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; bool result = false;
auto it=vars.find( key); auto it=vars.find( key);
if (it != vars.end()) { if (it != vars.end()) {
@ -1733,23 +1746,22 @@ bool DRW_Header::getStr(const std::string &key, std::string *varStr){
*varStr = *var->content.s; *varStr = *var->content.s;
result = true; result = true;
} }
delete var;
vars.erase (it);
} }
return result; 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; bool result = false;
auto it=vars.find( key); auto it=vars.find( key);
if (it != vars.end()) { if (it != vars.end())
{
DRW_Variant *var = (*it).second; DRW_Variant *var = (*it).second;
if (var->type == DRW_Variant::COORD) { if (var->type == DRW_Variant::COORD)
{
*varCoord = *var->content.v; *varCoord = *var->content.v;
result = true; result = true;
} }
delete var;
vars.erase (it);
} }
return result; return result;
} }

View File

@ -117,10 +117,10 @@ public:
protected: protected:
bool parseCode(int code, dxfReader *reader); bool parseCode(int code, dxfReader *reader);
private: private:
bool getDouble(const std::string &key, double *varDouble); bool getDouble(const std::string &key, double *varDouble) const;
bool getInt(const std::string &key, int *varInt); bool getInt(const std::string &key, int *varInt) const;
bool getStr(const std::string &key, std::string *varStr); bool getStr(const std::string &key, std::string *varStr) const;
bool getCoord(const std::string &key, DRW_Coord *varCoord); bool getCoord(const std::string &key, DRW_Coord *varCoord) const;
void clearVars() void clearVars()
{ {
for (auto it=vars.begin(); it!=vars.end(); ++it) for (auto it=vars.begin(); it!=vars.end(); ++it)

View File

@ -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); std::string comm = std::string("dxfrw ") + std::string(DRW_VERSION);
writer->writeString(999, comm); writer->writeString(999, comm);
} }
DRW_Header header; this->header = DRW_Header();
iface->writeHeader(header); iface->writeHeader(header);
writer->writeString(0, "SECTION"); writer->writeString(0, "SECTION");
entCount =FIRSTHANDLE; entCount = FIRSTHANDLE;
header.write(writer, version); header.write(writer, version);
writer->writeString(0, "ENDSEC"); writer->writeString(0, "ENDSEC");
if (ver > DRW::AC1009) { if (ver > DRW::AC1009) {
@ -190,9 +190,33 @@ bool dxfRW::write(DRW_Interface *interface_, DRW::Version ver, bool bin){
return isOk; return isOk;
} }
bool dxfRW::writeEntity(DRW_Entity *ent) { bool dxfRW::writeEntity(DRW_Entity *ent)
ent->handle = static_cast<duint32>(++entCount); {
writer->writeString(5, toHexStr(static_cast<int>(ent->handle))); // 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) { if (version > DRW::AC1009) {
writer->writeString(100, "AcDbEntity"); writer->writeString(100, "AcDbEntity");
} }
@ -467,6 +491,7 @@ bool dxfRW::writeDimstyle(DRW_Dimstyle *ent){
if (name == "STANDARD") if (name == "STANDARD")
dimstyleStd = true; dimstyleStd = true;
} }
if (version > DRW::AC1009) { if (version > DRW::AC1009) {
writer->writeString(105, toHexStr(++entCount)); writer->writeString(105, toHexStr(++entCount));
} }
@ -1694,92 +1719,129 @@ bool dxfRW::writeTables() {
return true; return true;
} }
bool dxfRW::writeBlocks() { bool dxfRW::writeBlocks()
writer->writeString(0, "BLOCK"); {
if (version > DRW::AC1009) { if (version > DRW::AC1009 || m_xSpaceBlock)
writer->writeString(5, "20"); {
if (version > DRW::AC1014) { writer->writeString(0, "BLOCK");
writer->writeString(330, "1F"); 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(8, "0"); {
if (version > DRW::AC1009) { writer->writeString(100, "AcDbBlockBegin");
writer->writeString(100, "AcDbBlockBegin"); writer->writeString(2, "*Model_Space");
writer->writeString(2, "*Model_Space"); }
} else else
writer->writeString(2, "$MODEL_SPACE"); {
writer->writeInt16(70, 0); writer->writeString(2, "$MODEL_SPACE");
writer->writeDouble(10, 0.0); }
writer->writeDouble(20, 0.0); writer->writeInt16(70, 0);
writer->writeDouble(30, 0.0); writer->writeDouble(10, 0.0);
if (version > DRW::AC1009) writer->writeDouble(20, 0.0);
writer->writeString(3, "*Model_Space"); writer->writeDouble(30, 0.0);
else if (version > DRW::AC1009)
writer->writeString(3, "$MODEL_SPACE"); {
writer->writeString(1, ""); writer->writeString(3, "*Model_Space");
writer->writeString(0, "ENDBLK"); }
if (version > DRW::AC1009) { else
writer->writeString(5, "21"); {
if (version > DRW::AC1014) { writer->writeString(3, "$MODEL_SPACE");
writer->writeString(330, "1F"); }
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"); writer->writeString(0, "BLOCK");
if (version > DRW::AC1009) { if (version > DRW::AC1009)
writer->writeString(5, "1C"); {
if (version > DRW::AC1014) { writer->writeString(5, "1C");
writer->writeString(330, "1B"); 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(8, "0"); {
if (version > DRW::AC1009) { writer->writeString(100, "AcDbBlockBegin");
writer->writeString(100, "AcDbBlockBegin"); writer->writeString(2, "*Paper_Space");
writer->writeString(2, "*Paper_Space"); }
} else else
writer->writeString(2, "$PAPER_SPACE"); {
writer->writeInt16(70, 0); writer->writeString(2, "$PAPER_SPACE");
writer->writeDouble(10, 0.0); }
writer->writeDouble(20, 0.0); writer->writeInt16(70, 0);
writer->writeDouble(30, 0.0); writer->writeDouble(10, 0.0);
if (version > DRW::AC1009) writer->writeDouble(20, 0.0);
writer->writeString(3, "*Paper_Space"); writer->writeDouble(30, 0.0);
else if (version > DRW::AC1009)
writer->writeString(3, "$PAPER_SPACE"); {
writer->writeString(1, ""); writer->writeString(3, "*Paper_Space");
writer->writeString(0, "ENDBLK"); }
if (version > DRW::AC1009) { else
writer->writeString(5, "1D"); {
if (version > DRW::AC1014) { writer->writeString(3, "$PAPER_SPACE");
writer->writeString(330, "1F"); }
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; writingBlock = false;
iface->writeBlocks(); iface->writeBlocks();
if (writingBlock) { if (writingBlock)
{
writingBlock = false; writingBlock = false;
writer->writeString(0, "ENDBLK"); writer->writeString(0, "ENDBLK");
if (version > DRW::AC1009) { if (version > DRW::AC1009)
{
writer->writeString(5, toHexStr(currHandle+2)); writer->writeString(5, toHexStr(currHandle+2));
// writer->writeString(5, "1D"); // writer->writeString(5, "1D");
if (version > DRW::AC1014) { if (version > DRW::AC1014)
{
writer->writeString(330, toHexStr(currHandle)); writer->writeString(330, toHexStr(currHandle));
} }
writer->writeString(100, "AcDbEntity"); writer->writeString(100, "AcDbEntity");
} }
writer->writeString(8, "0"); writer->writeString(8, "0");
if (version > DRW::AC1009) if (version > DRW::AC1009)
{
writer->writeString(100, "AcDbBlockEnd"); writer->writeString(100, "AcDbBlockEnd");
}
} }
return true; return true;
} }

View File

@ -39,6 +39,7 @@ public:
*/ */
bool read(DRW_Interface *interface_, bool ext); bool read(DRW_Interface *interface_, bool ext);
void setBinary(bool b) {binFile = b;} void setBinary(bool b) {binFile = b;}
void AddXSpaceBlock(bool add) {m_xSpaceBlock = add;}
bool write(DRW_Interface *interface_, DRW::Version ver, bool bin); bool write(DRW_Interface *interface_, DRW::Version ver, bool bin);
bool writeLineType(DRW_LType *ent); bool writeLineType(DRW_LType *ent);
@ -138,6 +139,7 @@ private:
std::string fileName; std::string fileName;
std::string codePage; std::string codePage;
bool binFile; bool binFile;
bool m_xSpaceBlock{true};
dxfReader *reader; dxfReader *reader;
dxfWriter *writer; dxfWriter *writer;
DRW_Interface *iface; DRW_Interface *iface;

View File

@ -157,6 +157,7 @@ auto VDxfEngine::begin(QPaintDevice *pdev) -> bool
m_input = QSharedPointer<dx_iface>(new dx_iface(GetFileNameForLocale(), m_version, m_varMeasurement, m_input = QSharedPointer<dx_iface>(new dx_iface(GetFileNameForLocale(), m_version, m_varMeasurement,
m_varInsunits)); m_varInsunits));
m_input->AddDefHeaderData();
m_input->AddQtLTypes(); m_input->AddQtLTypes();
m_input->AddDefLayers(); m_input->AddDefLayers();
return true; return true;
@ -700,6 +701,7 @@ auto VDxfEngine::ExportToAAMA(const QVector<VLayoutPiece> &details) -> bool
} }
m_input = QSharedPointer<dx_iface>::create(GetFileNameForLocale(), m_version, m_varMeasurement, m_varInsunits); m_input = QSharedPointer<dx_iface>::create(GetFileNameForLocale(), m_version, m_varMeasurement, m_varInsunits);
m_input->AddXSpaceBlock(false);
m_input->AddAAMAHeaderData(); m_input->AddAAMAHeaderData();
if (m_version > DRW::AC1009) if (m_version > DRW::AC1009)
{ {
@ -730,6 +732,7 @@ auto VDxfEngine::ExportToAAMA(const QVector<VLayoutPiece> &details) -> bool
} }
detailBlock->name = blockName.toStdString(); detailBlock->name = blockName.toStdString();
detailBlock->flags = 64;
detailBlock->layer = *layer1; detailBlock->layer = *layer1;
detail.Scale(m_xscale, m_yscale); detail.Scale(m_xscale, m_yscale);
@ -928,7 +931,7 @@ auto VDxfEngine::ExportToASTM(const QVector<VLayoutPiece> &details) -> bool
m_input = QSharedPointer<dx_iface>(new dx_iface(GetFileNameForLocale(), m_version, m_varMeasurement, m_input = QSharedPointer<dx_iface>(new dx_iface(GetFileNameForLocale(), m_version, m_varMeasurement,
m_varInsunits)); m_varInsunits));
m_input->AddXSpaceBlock(false);
m_input->AddAAMAHeaderData(); m_input->AddAAMAHeaderData();
if (m_version > DRW::AC1009) if (m_version > DRW::AC1009)
{ {

View File

@ -115,7 +115,7 @@ private:
QSize m_size{}; QSize m_size{};
double m_resolution{PrintDPI}; double m_resolution{PrintDPI};
QString m_fileName{}; QString m_fileName{};
DRW::Version m_version{DRW::AC1014}; DRW::Version m_version{DRW::AC1009};
bool m_binary{false}; bool m_binary{false};
QTransform m_matrix{}; QTransform m_matrix{};
QSharedPointer<dx_iface> m_input{}; QSharedPointer<dx_iface> m_input{};