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 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.

View file

@ -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()

View file

@ -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();

View file

@ -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;
}

View file

@ -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)

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);
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<duint32>(++entCount);
writer->writeString(5, toHexStr(static_cast<int>(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<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");
}
@ -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;
}

View file

@ -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;

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_varInsunits));
m_input->AddDefHeaderData();
m_input->AddQtLTypes();
m_input->AddDefLayers();
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->AddXSpaceBlock(false);
m_input->AddAAMAHeaderData();
if (m_version > DRW::AC1009)
{
@ -730,6 +732,7 @@ auto VDxfEngine::ExportToAAMA(const QVector<VLayoutPiece> &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<VLayoutPiece> &details) -> bool
m_input = QSharedPointer<dx_iface>(new dx_iface(GetFileNameForLocale(), m_version, m_varMeasurement,
m_varInsunits));
m_input->AddXSpaceBlock(false);
m_input->AddAAMAHeaderData();
if (m_version > DRW::AC1009)
{

View file

@ -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<dx_iface> m_input{};