/****************************************************************************** ** libDXFrw - Library to read/write DXF files (ascii & binary) ** ** ** ** Copyright (C) 2016-2022 A. Stebich (librecad@mail.lordofbikes.de) ** ** 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 . ** ******************************************************************************/ #include #include #include "drw_objects.h" #include "intern/dxfreader.h" #include "intern/dxfwriter.h" #include "intern/dwgbuffer.h" #include "intern/drw_dbg.h" #include "intern/drw_reserve.h" #include "intern/dwgutil.h" //! Base class for tables entries /*! * Base class for tables entries * * DXF Format reference: * https://documentation.help/AutoCAD-DXF * @author Rallaz */ bool DRW_TableEntry::parseCode(int code, dxfReader* reader) { switch (code) { case 5: handle = reader->getHandleId(); break; case 330: parentHandle = reader->getHandleId(); break; case 2: name = reader->getUtf8String(); break; case 70: flags = reader->getInt32(); break; case 1000: case 1001: case 1002: case 1003: case 1004: case 1005: extData.push_back(new DRW_Variant(code, reader->getString())); break; case 1010: case 1011: case 1012: case 1013: // don't trust in X, Y, Z order! if (nullptr != curr) { curr->setCoordX(reader->getDouble()); } else { curr = new DRW_Variant(code, DRW_Coord(reader->getDouble(), 0.0, 0.0)); extData.push_back(curr); } break; case 1020: case 1021: case 1022: case 1023: // don't trust in X, Y, Z order! if (nullptr != curr) { curr->setCoordY(reader->getDouble()); } else { curr = new DRW_Variant(code, DRW_Coord(0.0, reader->getDouble(), 0.0)); extData.push_back(curr); } break; case 1030: case 1031: case 1032: case 1033: // don't trust in X, Y, Z order! if (nullptr != curr) { curr->setCoordZ(reader->getDouble()); } else { curr = new DRW_Variant(code, DRW_Coord(0.0, 0.0, reader->getDouble())); extData.push_back(curr); } break; case 1040: case 1041: case 1042: extData.push_back(new DRW_Variant(code, reader->getDouble())); break; case 1070: case 1071: extData.push_back(new DRW_Variant(code, reader->getInt32())); break; default: break; } return true; } bool DRW_TableEntry::parseDwg(DRW::Version version, dwgBuffer* buf, dwgBuffer* strBuf, duint32 bs) { DRW_DBG("\n***************************** parsing table entry *********************************************\n"); objSize = 0; oType = buf->getObjType(version); DRW_DBG("Object type: "); DRW_DBG(oType); DRW_DBG(", "); DRW_DBGH(oType); if (version > DRW::AC1014 && version < DRW::AC1024) { //2000 to 2007 objSize = buf->getRawLong32(); //RL 32bits object size in bits DRW_DBG(" Object size: "); DRW_DBG(objSize); DRW_DBG("\n"); } if (version > DRW::AC1021) { //2010+ duint32 ms = buf->size(); objSize = ms * 8 - bs; DRW_DBG(" Object size: "); DRW_DBG(objSize); DRW_DBG("\n"); } if (strBuf != NULL && version > DRW::AC1018) { //2007+ strBuf->moveBitPos(objSize - 1); DRW_DBG(" strBuf strbit pos 2007: "); DRW_DBG(strBuf->getPosition()); DRW_DBG(" strBuf bpos 2007: "); DRW_DBG(strBuf->getBitPos()); DRW_DBG("\n"); if (strBuf->getBit() == 1) { DRW_DBG("DRW_TableEntry::parseDwg string bit is 1\n"); strBuf->moveBitPos(-17); duint16 strDataSize = strBuf->getRawShort16(); DRW_DBG("\nDRW_TableEntry::parseDwg string strDataSize: "); DRW_DBGH(strDataSize); DRW_DBG("\n"); if ((strDataSize & 0x8000) == 0x8000) { DRW_DBG("\nDRW_TableEntry::parseDwg string 0x8000 bit is set"); strBuf->moveBitPos(-33); //RLZ pending to verify duint16 hiSize = strBuf->getRawShort16(); strDataSize = ((strDataSize & 0x7fff) | (hiSize << 15)); } strBuf->moveBitPos(-strDataSize - 16); //-14 DRW_DBG("strBuf start strDataSize pos 2007: "); DRW_DBG(strBuf->getPosition()); DRW_DBG(" strBuf bpos 2007: "); DRW_DBG(strBuf->getBitPos()); DRW_DBG("\n"); } else DRW_DBG("\nDRW_TableEntry::parseDwg string bit is 0"); DRW_DBG("strBuf start pos 2007: "); DRW_DBG(strBuf->getPosition()); DRW_DBG(" strBuf bpos 2007: "); DRW_DBG(strBuf->getBitPos()); DRW_DBG("\n"); } dwgHandle ho = buf->getHandle(); handle = ho.ref; DRW_DBG("TableEntry Handle: "); DRW_DBGHL(ho.code, ho.size, ho.ref); dint16 extDataSize = buf->getBitShort(); //BS DRW_DBG(" ext data size: "); DRW_DBG(extDataSize); while (extDataSize > 0 && buf->isGood()) { /* RLZ: TODO */ dwgHandle ah = buf->getHandle(); DRW_DBG("App Handle: "); DRW_DBGHL(ah.code, ah.size, ah.ref); duint8* tmpExtData = new duint8[extDataSize]; buf->getBytes(tmpExtData, extDataSize); dwgBuffer tmpExtDataBuf(tmpExtData, extDataSize, buf->decoder); int pos = tmpExtDataBuf.getPosition(); int bpos = tmpExtDataBuf.getBitPos(); DRW_DBG("ext data pos: "); DRW_DBG(pos); DRW_DBG("."); DRW_DBG(bpos); DRW_DBG("\n"); duint8 dxfCode = tmpExtDataBuf.getRawChar8(); DRW_DBG(" dxfCode: "); DRW_DBG(dxfCode); switch (dxfCode) { case 0: { duint8 strLength = tmpExtDataBuf.getRawChar8(); DRW_DBG(" strLength: "); DRW_DBG(strLength); duint16 cp = tmpExtDataBuf.getBERawShort16(); DRW_DBG(" str codepage: "); DRW_DBG(cp); for (int i = 0; i < strLength + 1; i++) { //string length + null terminating char duint8 dxfChar = tmpExtDataBuf.getRawChar8(); DRW_DBG(" dxfChar: "); DRW_DBG(dxfChar); } break; } default: /* RLZ: TODO */ break; } DRW_DBG("ext data pos: "); DRW_DBG(tmpExtDataBuf.getPosition()); DRW_DBG("."); DRW_DBG(tmpExtDataBuf.getBitPos()); DRW_DBG("\n"); delete[]tmpExtData; extDataSize = buf->getBitShort(); //BS DRW_DBG(" ext data size: "); DRW_DBG(extDataSize); } //end parsing extData (EED) if (version < DRW::AC1015) { //14- objSize = buf->getRawLong32(); //RL 32bits size in bits } DRW_DBG(" objSize in bits: "); DRW_DBG(objSize); numReactors = buf->getBitLong(); //BL DRW_DBG(", numReactors: "); DRW_DBG(numReactors); DRW_DBG("\n"); if (version > DRW::AC1015) { //2004+ xDictFlag = buf->getBit(); DRW_DBG("xDictFlag: "); DRW_DBG(xDictFlag); } if (version > DRW::AC1024) { //2013+ duint8 bd = buf->getBit(); DRW_DBG(" Have binary data: "); DRW_DBG(bd); DRW_DBG("\n"); } return buf->isGood(); } bool DRW_Dimstyle::get(const std::string& key, ValueHolder& holder) const { auto pair = vars.find(key); if (pair == vars.end()) { holder.update(nullptr); return false; } holder.update(pair->second); return true; } bool DRW_Dimstyle::get(const std::string& key, double& var) const { auto pair = vars.find(key); if (pair == vars.end()) { return false; } var = pair->second->d_val(); return true; } bool DRW_Dimstyle::get(const std::string& key, int& var) const { auto pair = vars.find(key); if (pair == vars.end()) { return false; } var = pair->second->i_val(); return true; } bool DRW_Dimstyle::get(const std::string& key, std::string& var) const { auto pair = vars.find(key); if (pair == vars.end()) { return false; } var = pair->second->c_str(); return true; } void DRW_Dimstyle::add(const std::string& key, int code, int value) { vars[key] = new DRW_Variant(code, value); } void DRW_Dimstyle::add(const std::string& key, int code, double value) { vars[key] = new DRW_Variant(code, value); } void DRW_Dimstyle::add(const std::string& key, int code, std::string value) { vars[key] = new DRW_Variant(code, value); } //! Class to handle dimstyle entries /*! * Class to handle ldim style symbol table entries * @author Rallaz */ bool DRW_Dimstyle::parseCode(int code, dxfReader* reader) { int refHandle; switch (code) { case 105: handle = reader->getHandleId(); break; case 3: dimpost = reader->getUtf8String(); add("$DIMPOST", code, dimpost); break; case 4: dimapost = reader->getUtf8String(); add("$DIMAPOST", code, dimapost); break; case 5: dimblk = reader->getUtf8String(); add("$DIMBLK", code, dimblk); break; case 6: dimblk1 = reader->getUtf8String(); add("$DIMBLK1", code, dimblk1); break; case 7: dimblk2 = reader->getUtf8String(); add("$DIMBLK2", code, dimblk2); break; case 40: dimscale = reader->getDouble(); add("$DIMSCALE", code, dimscale); break; case 41: dimasz = reader->getDouble(); add("$DIMASZ", code, dimasz); break; case 42: dimexo = reader->getDouble(); add("$DIMEXO", code, dimexo); break; case 43: dimdli = reader->getDouble(); add("$DIMDLI", code, dimdli); break; case 44: dimexe = reader->getDouble(); add("$DIMEXE", code, dimexe); break; case 45: dimrnd = reader->getDouble(); add("$DIMRND", code, dimrnd); break; case 46: dimdle = reader->getDouble(); add("$DIMDLE", code, dimdle); break; case 47: dimtp = reader->getDouble(); add("$DIMTP", code, dimtp); break; case 48: dimtm = reader->getDouble(); add("$DIMTM", code, dimtm); break; case 49: dimfxl = reader->getDouble(); add("$DIMFXL", code, dimfxl); break; case 140: dimtxt = reader->getDouble(); add("$DIMTXT", code, dimtxt); break; case 141: dimcen = reader->getDouble(); add("$DIMCEN", code, dimcen); break; case 142: dimtsz = reader->getDouble(); add("$DIMTSZ", code, dimtsz); break; case 143: dimaltf = reader->getDouble(); add("$DIMALTF", code, dimaltf); break; case 144: dimlfac = reader->getDouble(); add("$DIMLFAC", code, dimlfac); break; case 145: dimtvp = reader->getDouble(); add("$DIMTVP", code, dimtvp); break; case 146: dimtfac = reader->getDouble(); add("$DIMTFAC", code, dimtfac); break; case 147: dimgap = reader->getDouble(); add("$DIMGAP", code, dimgap); break; case 148: dimaltrnd = reader->getDouble(); add("$DIMALTRND", code, dimaltrnd); break; case 69: dimtfill = reader->getInt32(); add("$DIMTFILL", code, dimtfill); break; case 70: dimtfillclr = reader->getInt32(); add("$DIMTFILLCLR", code, dimtfillclr); break; case 71: dimtol = reader->getInt32(); add("$DIMTOL", code, dimtol); break; case 72: dimlim = reader->getInt32(); add("$DIMLIM", code, dimlim); break; case 73: dimtih = reader->getInt32(); add("$DIMTIH", code, dimtih); break; case 74: dimtoh = reader->getInt32(); add("$DIMTOH", code, dimtoh); break; case 75: dimse1 = reader->getInt32(); add("$DIMSE1", code, dimse1); break; case 76: dimse2 = reader->getInt32(); add("$DIMSE2", code, dimse2); break; case 77: dimtad = reader->getInt32(); add("$DIMTAD", code, dimtad); break; case 78: dimzin = reader->getInt32(); add("$DIMZIN", code, dimzin); break; case 79: dimazin = reader->getInt32(); add("$DIMAZIN", code, dimazin); break; case 170: dimalt = reader->getInt32(); add("$DIMALT", code, dimalt); break; case 171: dimaltd = reader->getInt32(); add("$DIMALTD", code, dimaltd); break; case 172: dimtofl = reader->getInt32(); add("$DIMTOFL", code, dimtofl); break; case 173: dimsah = reader->getInt32(); add("$DIMSAH", code, dimsah); break; case 174: dimtix = reader->getInt32(); add("$DIMTIX", code, dimtix); break; case 175: dimsoxd = reader->getInt32(); add("$DIMSOXD", code, dimsoxd); break; case 176: dimclrd = reader->getInt32(); add("$DIMCLRD", code, dimclrd); break; case 177: dimclre = reader->getInt32(); add("$DIMCLRE", code, dimclre); break; case 178: dimclrt = reader->getInt32(); add("$DIMCLRT", code, dimclrt); break; case 179: dimadec = reader->getInt32(); add("$DIMADEC", code, dimadec); break; case 270: dimunit = reader->getInt32(); add("$DIMUNIT", code, dimunit); break; case 271: dimdec = reader->getInt32(); add("$DIMDEC", code, dimdec); break; case 272: dimtdec = reader->getInt32(); add("$DIMTDEC", code, dimtdec); break; case 273: dimaltu = reader->getInt32(); add("$DIMALTU", code, dimaltu); break; case 274: dimalttd = reader->getInt32(); add("$DIMALTTD", code, dimalttd); break; case 275: dimaunit = reader->getInt32(); add("$DIMAUNIT", code, dimaunit); break; case 276: dimfrac = reader->getInt32(); add("$DIMFRAC", code, dimfrac); break; case 277: dimlunit = reader->getInt32(); add("$DIMLUNIT", code, dimlunit); break; case 278: dimdsep = reader->getInt32(); add("$DIMDSEP", code, dimdsep); break; case 279: dimtmove = reader->getInt32(); add("$DIMTMOVE", code, dimtmove); break; case 280: dimjust = reader->getInt32(); add("$DIMJUST", code, dimjust); break; case 281: dimsd1 = reader->getInt32(); add("$DIMSD1", code, dimsd1); break; case 282: dimsd2 = reader->getInt32(); add("$DIMSD2", code, dimsd2); break; case 283: dimtolj = reader->getInt32(); add("$DIMTOLJ", code, dimtolj); break; case 284: dimtzin = reader->getInt32(); add("$DIMTZIN", code, dimtzin); break; case 285: dimaltz = reader->getInt32(); add("$DIMALTZ", code, dimaltz); break; case 286: dimaltttz = reader->getInt32(); add("$DIMALTTZ", code, dimaltttz); break; case 287: dimfit = reader->getInt32(); add("$DIMFIT", code, dimfit); break; case 288: dimupt = reader->getInt32(); add("$DIMUPT", code, dimupt); break; case 289: dimatfit = reader->getInt32(); add("$DIMATFIT", code, dimatfit); break; case 290: dimfxlon = reader->getInt32(); add("$DIMFXLON", code, dimfxlon); break; case 292: dimtxtdirection = reader->getInt32(); add("$DIMTXTDIRECTION", code, dimtxtdirection); break; case 340: /*dimtxsty = reader->getUtf8String(); add("$DIMTXSTY", code, dimtxsty);*/ refHandle = reader->getHandleId(); add("_$DIMTXSTY", code, refHandle); break; case 341: // fixme - DIMLDRBLK reading! refHandle = reader->getHandleId(); add("_$DIMLDRBLK", code, refHandle); break; case 342: // dimblk = reader->getHandleString(); refHandle = reader->getHandleId(); add("_$DIMBLK", code, refHandle); break; case 343: // dimblk1 = reader->getHandleString(); refHandle = reader->getHandleId(); add("_$DIMBLK1", code, refHandle); break; case 344: refHandle = reader->getHandleId(); add("_$DIMBLK2", code, refHandle); break; // case 345: // codes/// // fixme - may this code be used for DIMLDRBLK? // dimblk2 = reader->getUtf8String(); // add("$DIMBLK2", code, dimblk2); // break; // case 346: case 345: dimltype = reader->getHandleId(); add("_$DIMLTYPE", code, dimltype); break; case 347: dimltext1 = reader->getHandleId(); add("_$DIMLTEX1", code, dimltext1); break; case 348: dimltext2 = reader->getHandleId(); add("_$DIMLTEX2", code, dimltext2); break; case 371: dimlwd = reader->getInt32(); add("$DIMLWD", code, dimlwd); break; case 372: dimlwe = reader->getInt32(); add("$DIMLWE", code, dimlwe); break; case 90: dymarcsym = reader->getInt32(); add("$DIMARCSYM", code, dymarcsym); break; default: return DRW_TableEntry::parseCode(code, reader); } return true; } DRW_Dimstyle::~DRW_Dimstyle() { vars.clear(); } DRW_Variant* DRW_Dimstyle::get(const std::string& key) const { auto pair = vars.find(key); if (pair == vars.end()) { return nullptr; } return pair->second; } void DRW_Dimstyle::resolveBlockRecordNameByHandle(DRW_ParsingContext& ctx, const std::string& unresolvedKey, const std::string& resolvedKey, int code) { auto var = get(unresolvedKey); if (var != nullptr) { duint32 blockHandle = var->i_val(); auto name = ctx.resolveBlockRecordName(blockHandle); if (!name.empty()) { add(resolvedKey, code, name); } } } void DRW_Dimstyle::resolveTextStyleNameByHandle(DRW_ParsingContext& ctx, const std::string& unresolvedKey, const std::string& resolvedKey, int code) { auto var = get(unresolvedKey); if (var != nullptr) { duint32 blockHandle = var->i_val(); auto name = ctx.resolveTextStyleName(blockHandle); if (!name.empty()) { add(resolvedKey, code, name); } } } void DRW_Dimstyle::resolveLineTypeNameByHandle(DRW_ParsingContext& ctx, const std::string& unresolvedKey, const std::string& resolvedKey, int code) { auto var = get(unresolvedKey); if (var != nullptr) { duint32 blockHandle = var->i_val(); auto name = ctx.resolveLineTypeName(blockHandle); if (!name.empty()) { add(resolvedKey, code, name); } } } bool DRW_Dimstyle::resolveRefs(DRW_ParsingContext& ctx) { resolveTextStyleNameByHandle(ctx, "_$DIMTXSTY", "$DIMTXSTY", 340); resolveBlockRecordNameByHandle(ctx, "_$DIMLDRBLK", "$DIMLDRBLK", 341); resolveBlockRecordNameByHandle(ctx, "_$DIMBLK", "$DIMBLK", 342); resolveBlockRecordNameByHandle(ctx, "_$DIMBLK1", "$DIMBLK1", 343); resolveBlockRecordNameByHandle(ctx, "_$DIMBLK2", "$DIMBLK2", 344); resolveLineTypeNameByHandle(ctx, "_$DIMLTYPE", "$DIMLTYPE", 345); resolveLineTypeNameByHandle(ctx, "_$DIMLTEX1", "$DIMLTEX1", 347); resolveLineTypeNameByHandle(ctx, "_$DIMLTEX2", "$DIMLTEX2", 348); return false; } bool DRW_Dimstyle::parseDwg(DRW::Version version, dwgBuffer* buf, duint32 bs) { dwgBuffer sBuff = *buf; dwgBuffer* sBuf = buf; if (version > DRW::AC1018) { //2007+ sBuf = &sBuff; //separate buffer for strings } bool ret = DRW_TableEntry::parseDwg(version, buf, sBuf, bs); DRW_DBG("\n***************************** parsing dimension style **************************************\n"); if (!ret) return ret; name = sBuf->getVariableText(version, false); DRW_DBG("dimension style name: "); DRW_DBG(name.c_str()); DRW_DBG("\n"); // handleObj = shpControlH.ref; DRW_DBG("\n Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); // RS crc; //RS */ return buf->isGood(); } DRW_TableEntry* DRW_LType::newInstance() { return new DRW_LType(); } //! Class to handle line type entries /*! * Class to handle line type symbol table entries * @author Rallaz */ bool DRW_LType::parseCode(int code, dxfReader* reader) { switch (code) { case 3: desc = reader->getUtf8String(); break; case 73: size = reader->getInt32(); path.clear(); if (!DRW::reserve(path, size)) { return false; } break; case 40: length = reader->getDouble(); break; case 49: path.push_back(reader->getDouble()); pathIdx++; break; /* case 74: haveShape = reader->getInt32(); break;*/ default: return DRW_TableEntry::parseCode(code, reader); } return true; } //! Update line type /*! * Update the size and length of line type according to the path * @author Rallaz */ /*TODO: control max length permited */ void DRW_LType::update() { double d = 0; size = path.size(); for (int i = 0; i < size; i++) { d += fabs(path.at(i)); } length = d; } bool DRW_LType::parseDwg(DRW::Version version, dwgBuffer* buf, duint32 bs) { dwgBuffer sBuff = *buf; dwgBuffer* sBuf = buf; if (version > DRW::AC1018) { //2007+ sBuf = &sBuff; //separate buffer for strings } bool ret = DRW_TableEntry::parseDwg(version, buf, sBuf, bs); DRW_DBG("\n***************************** parsing line type *********************************************\n"); if (!ret) return ret; name = sBuf->getVariableText(version, false); DRW_DBG("linetype name: "); DRW_DBG(name.c_str()); DRW_DBG("\n"); flags = buf->getBit() << 6; DRW_DBG("flags: "); DRW_DBG(flags); if (version > DRW::AC1018) { //2007+ } else { //2004- //RLZ: verify in 2004, 2010 &2013 dint16 xrefindex = buf->getBitShort(); DRW_DBG(" xrefindex: "); DRW_DBG(xrefindex); } duint8 xdep = buf->getBit(); DRW_DBG(" xdep: "); DRW_DBG(xdep); flags |= xdep << 4; DRW_DBG(" flags: "); DRW_DBG(flags); desc = sBuf->getVariableText(version, false); DRW_DBG(" desc: "); DRW_DBG(desc.c_str()); length = buf->getBitDouble(); DRW_DBG(" pattern length: "); DRW_DBG(length); char align = buf->getRawChar8(); DRW_DBG(" align: "); DRW_DBG(std::string(&align, 1)); size = buf->getRawChar8(); DRW_DBG(" num dashes, size: "); DRW_DBG(size); DRW_DBG("\n dashes:\n"); bool haveStrArea = false; for (int i = 0; i < size; i++) { path.push_back(buf->getBitDouble()); /*int bs1 =*/ buf->getBitShort(); /*double d1= */ buf->getRawDouble(); /*double d2=*/ buf->getRawDouble(); /*double d3= */ buf->getBitDouble(); /*double d4= */ buf->getBitDouble(); int bs2 = buf->getBitShort(); if ((bs2 & 2) != 0) haveStrArea = true; } for (unsigned i = 0; i < path.size(); i++) { DRW_DBG(", "); DRW_DBG(path[i]); DRW_DBG("\n"); } DRW_DBG("\n Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); if (version < DRW::AC1021) { //2004- duint8 strarea[256]; buf->getBytes(strarea, 256); DRW_DBG("string area 256 bytes:\n"); DRW_DBG(reinterpret_cast(strarea)); DRW_DBG("\n"); } else { //2007+ //first verify flag if (haveStrArea) { duint8 strarea[512]; buf->getBytes(strarea, 512); DRW_DBG("string area 512 bytes:\n"); DRW_DBG(reinterpret_cast(strarea)); DRW_DBG("\n"); } else DRW_DBG("string area 512 bytes not present\n"); } if (version > DRW::AC1021) { //2007+ skip string area DRW_DBG(" ltype end of object data pos 2010: "); DRW_DBG(buf->getPosition()); DRW_DBG(" strBuf bpos 2007: "); DRW_DBG(buf->getBitPos()); DRW_DBG("\n"); } if (version > DRW::AC1018) { //2007+ skip string area buf->setPosition(objSize >> 3); buf->setBitPos(objSize & 7); } if (version > DRW::AC1021) { //2007+ skip string area DRW_DBG(" ltype start of handles data pos 2010: "); DRW_DBG(buf->getPosition()); DRW_DBG(" strBuf bpos 2007: "); DRW_DBG(buf->getBitPos()); DRW_DBG("\n"); } DRW_DBG("\n Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); dwgHandle ltControlH = buf->getHandle(); DRW_DBG("linetype control Handle: "); DRW_DBGHL(ltControlH.code, ltControlH.size, ltControlH.ref); parentHandle = ltControlH.ref; DRW_DBG("\n Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); for (int i = 0; i < numReactors; ++i) { dwgHandle reactorsH = buf->getHandle(); DRW_DBG(" reactorsH control Handle: "); DRW_DBGHL(reactorsH.code, reactorsH.size, reactorsH.ref); DRW_DBG("\n"); } if (xDictFlag != 1) { //linetype in 2004 seems not have XDicObjH or NULL handle dwgHandle XDicObjH = buf->getHandle(); DRW_DBG(" XDicObj control Handle: "); DRW_DBGHL(XDicObjH.code, XDicObjH.size, XDicObjH.ref); DRW_DBG("\n"); DRW_DBG("\n Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); } if (size > 0) { dwgHandle XRefH = buf->getHandle(); DRW_DBG(" XRefH control Handle: "); DRW_DBGHL(XRefH.code, XRefH.size, XRefH.ref); DRW_DBG("\n"); dwgHandle shpHandle = buf->getHandle(); DRW_DBG(" shapeFile Handle: "); DRW_DBGHL(shpHandle.code, shpHandle.size, shpHandle.ref); DRW_DBG("\n Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); } dwgHandle shpHandle = buf->getHandle(); DRW_DBG(" shapeFile +1 Handle ??: "); DRW_DBGHL(shpHandle.code, shpHandle.size, shpHandle.ref); DRW_DBG("\n"); DRW_DBG("\n Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); // RS crc; //RS */ return buf->isGood(); } //! Class to handle layer entries /*! * Class to handle layer symbol table entries * @author Rallaz */ bool DRW_Layer::parseCode(int code, dxfReader* reader) { switch (code) { case 6: lineType = reader->getUtf8String(); break; case 62: color = reader->getInt32(); break; case 290: plotF = reader->getBool(); break; case 370: lWeight = DRW_LW_Conv::dxfInt2lineWidth(reader->getInt32()); break; case 390: handlePlotS = reader->getString(); break; case 347: handleMaterialS = reader->getString(); break; case 420: color24 = reader->getInt32(); break; default: return DRW_TableEntry::parseCode(code, reader); } return true; } bool DRW_Layer::parseDwg(DRW::Version version, dwgBuffer* buf, duint32 bs) { dwgBuffer sBuff = *buf; dwgBuffer* sBuf = buf; if (version > DRW::AC1018) { //2007+ sBuf = &sBuff; //separate buffer for strings } bool ret = DRW_TableEntry::parseDwg(version, buf, sBuf, bs); DRW_DBG("\n***************************** parsing layer *********************************************\n"); if (!ret) return ret; name = sBuf->getVariableText(version, false); DRW_DBG("layer name: "); DRW_DBG(name.c_str()); flags |= buf->getBit() << 6; //layer have entity if (version < DRW::AC1021) { //2004- DRW_DBG(", xrefindex = "); DRW_DBG(buf->getBitShort()); DRW_DBG("\n"); //dint16 xrefindex = buf->getBitShort(); } flags |= buf->getBit() << 4; //is refx dependent if (version < DRW::AC1015) { //14- flags |= buf->getBit(); //layer frozen /*flags |=*/ buf->getBit(); //unused, negate the color flags |= buf->getBit() << 1; //frozen in new flags |= buf->getBit() << 3; //locked } if (version > DRW::AC1014) { //2000+ dint16 f = buf->getSBitShort(); //bit2 are layer on DRW_DBG(", flags 2000+: "); DRW_DBG(f); DRW_DBG("\n"); flags |= f & 0x0001; //layer frozen flags |= (f >> 1) & 0x0002; //frozen in new flags |= (f >> 1) & 0x0004; //locked plotF = (f >> 4) & 0x0001; lWeight = DRW_LW_Conv::dwgInt2lineWidth((f & 0x03E0) >> 5); } color = buf->getCmColor(version); //BS or CMC //ok for R14 or negate DRW_DBG(", entity color: "); DRW_DBG(color); DRW_DBG("\n"); if (version > DRW::AC1018) { //2007+ skip string area buf->setPosition(objSize >> 3); buf->setBitPos(objSize & 7); } dwgHandle layerControlH = buf->getHandle(); DRW_DBG("layer control Handle: "); DRW_DBGHL(layerControlH.code, layerControlH.size, layerControlH.ref); parentHandle = layerControlH.ref; if (xDictFlag != 1) { //linetype in 2004 seems not have XDicObjH or NULL handle dwgHandle XDicObjH = buf->getHandle(); DRW_DBG(" XDicObj control Handle: "); DRW_DBGHL(XDicObjH.code, XDicObjH.size, XDicObjH.ref); DRW_DBG("\n"); } dwgHandle XRefH = buf->getHandle(); DRW_DBG(" XRefH control Handle: "); DRW_DBGHL(XRefH.code, XRefH.size, XRefH.ref); DRW_DBG("\n"); if (version > DRW::AC1014) { //2000+ dwgHandle plotStyH = buf->getHandle(); DRW_DBG(" PLot style control Handle: "); DRW_DBGHL(plotStyH.code, plotStyH.size, plotStyH.ref); DRW_DBG("\n"); handlePlotS = DRW::toHexStr(plotStyH.ref); // std::string(plotStyH.ref);//RLZ: verify conversion } if (version > DRW::AC1018) { //2007+ dwgHandle materialH = buf->getHandle(); DRW_DBG(" Material control Handle: "); DRW_DBGHL(materialH.code, materialH.size, materialH.ref); DRW_DBG("\n"); handleMaterialS = DRW::toHexStr(materialH.ref); //RLZ: verify conversion } //lineType handle DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); lTypeH = buf->getHandle(); DRW_DBG("line type Handle: "); DRW_DBGHL(lTypeH.code, lTypeH.size, lTypeH.ref); DRW_DBG("\n Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); // RS crc; //RS */ return buf->isGood(); } DRW_TableEntry* DRW_Block_Record::newInstance() { return new DRW_Block_Record(); } bool DRW_Block_Record::parseDwg(DRW::Version version, dwgBuffer* buf, duint32 bs) { dwgBuffer sBuff = *buf; dwgBuffer* sBuf = buf; if (version > DRW::AC1018) { //2007+ sBuf = &sBuff; //separate buffer for strings } bool ret = DRW_TableEntry::parseDwg(version, buf, sBuf, bs); DRW_DBG("\n***************************** parsing block record ******************************************\n"); if (!ret) return ret; duint32 insertCount = 0; //only 2000+ duint32 objectCount = 0; //only 2004+ name = sBuf->getVariableText(version, false); DRW_DBG("block record name: "); DRW_DBG(name.c_str()); DRW_DBG("\n"); flags |= buf->getBit() << 6; //referenced external reference, block code 70, bit 7 (64) if (version > DRW::AC1018) { //2007+ } else { //2004- //RLZ: verify in 2004, 2010 &2013 dint16 xrefindex = buf->getBitShort(); DRW_DBG(" xrefindex: "); DRW_DBG(xrefindex); DRW_DBG("\n"); } flags |= buf->getBit() << 4; //is refx dependent, block code 70, bit 5 (16) flags |= buf->getBit(); //if is anonymous block (*U) block code 70, bit 1 (1) flags |= buf->getBit() << 1; //if block contains attdefs, block code 70, bit 2 (2) bool blockIsXref = buf->getBit(); //if is a Xref, block code 70, bit 3 (4) bool xrefOverlaid = buf->getBit(); //if is a overlaid Xref, block code 70, bit 4 (8) flags |= blockIsXref << 2; //if is a Xref, block code 70, bit 3 (4) flags |= xrefOverlaid << 3; //if is a overlaid Xref, block code 70, bit 4 (8) if (version > DRW::AC1014) { //2000+ flags |= buf->getBit() << 5; //if is a loaded Xref, block code 70, bit 6 (32) } DRW_DBG("flags: "); DRW_DBG(flags); DRW_DBG(", "); if (version > DRW::AC1015) { //2004+ fails in 2007 objectCount = buf->getBitLong(); //Number of objects owned by this block if (!DRW::reserve(entMap, objectCount)) { return false; } } basePoint.x = buf->getBitDouble(); basePoint.y = buf->getBitDouble(); basePoint.z = buf->getBitDouble(); DRW_DBG("insertion point: "); DRW_DBGPT(basePoint.x, basePoint.y, basePoint.z); DRW_DBG("\n"); UTF8STRING path = sBuf->getVariableText(version, false); DRW_DBG("XRef path name: "); DRW_DBG(path.c_str()); DRW_DBG("\n"); if (version > DRW::AC1014) { //2000+ insertCount = 0; while (duint8 i = buf->getRawChar8() != 0) insertCount += i; UTF8STRING bkdesc = sBuf->getVariableText(version, false); DRW_DBG("Block description: "); DRW_DBG(bkdesc.c_str()); DRW_DBG("\n"); duint32 prevData = buf->getBitLong(); for (unsigned int j = 0; j < prevData; ++j) buf->getRawChar8(); } if (version > DRW::AC1018) { //2007+ duint16 insUnits = buf->getBitShort(); bool canExplode = buf->getBit(); //if block can be exploded duint8 bkScaling = buf->getRawChar8(); DRW_UNUSED(insUnits); DRW_UNUSED(canExplode); DRW_UNUSED(bkScaling); } if (version > DRW::AC1018) { //2007+ skip string area buf->setPosition(objSize >> 3); buf->setBitPos(objSize & 7); } dwgHandle blockControlH = buf->getHandle(); DRW_DBG("block control Handle: "); DRW_DBGHL(blockControlH.code, blockControlH.size, blockControlH.ref); DRW_DBG("\n"); parentHandle = blockControlH.ref; for (int i = 0; i < numReactors; i++) { dwgHandle reactorH = buf->getHandle(); DRW_DBG(" reactor Handle #"); DRW_DBG(i); DRW_DBG(": "); DRW_DBGHL(reactorH.code, reactorH.size, reactorH.ref); DRW_DBG("\n"); } if (xDictFlag != 1) { //R14+ //seems present in 2000 dwgHandle XDicObjH = buf->getHandle(); DRW_DBG(" XDicObj control Handle: "); DRW_DBGHL(XDicObjH.code, XDicObjH.size, XDicObjH.ref); DRW_DBG("\n"); } if (version != DRW::AC1021) { //2007+ XDicObjH or NullH not present } dwgHandle NullH = buf->getHandle(); DRW_DBG(" NullH control Handle: "); DRW_DBGHL(NullH.code, NullH.size, NullH.ref); DRW_DBG("\n"); dwgHandle blockH = buf->getOffsetHandle(handle); DRW_DBG(" blockH Handle: "); DRW_DBGHL(blockH.code, blockH.size, blockH.ref); DRW_DBG("\n"); block = blockH.ref; if (version > DRW::AC1015) { //2004+ for (unsigned int i = 0; i < objectCount; i++) { dwgHandle entityH = buf->getHandle(); DRW_DBG(" entityH Handle #"); DRW_DBG(i); DRW_DBG(": "); DRW_DBGHL(entityH.code, entityH.size, entityH.ref); DRW_DBG("\n"); entMap.push_back(entityH.ref); } } else { //2000- if (!blockIsXref && !xrefOverlaid) { dwgHandle firstH = buf->getHandle(); DRW_DBG(" firstH entity Handle: "); DRW_DBGHL(firstH.code, firstH.size, firstH.ref); DRW_DBG("\n"); firstEH = firstH.ref; dwgHandle lastH = buf->getHandle(); DRW_DBG(" lastH entity Handle: "); DRW_DBGHL(lastH.code, lastH.size, lastH.ref); DRW_DBG("\n"); lastEH = lastH.ref; } } DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); dwgHandle endBlockH = buf->getOffsetHandle(handle); DRW_DBG(" endBlockH Handle: "); DRW_DBGHL(endBlockH.code, endBlockH.size, endBlockH.ref); DRW_DBG("\n"); endBlock = endBlockH.ref; if (version > DRW::AC1014) { //2000+ for (unsigned int i = 0; i < insertCount; i++) { dwgHandle insertsH = buf->getHandle(); DRW_DBG(" insertsH Handle #"); DRW_DBG(i); DRW_DBG(": "); DRW_DBGHL(insertsH.code, insertsH.size, insertsH.ref); DRW_DBG("\n"); } DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); dwgHandle layoutH = buf->getHandle(); DRW_DBG(" layoutH Handle: "); DRW_DBGHL(layoutH.code, layoutH.size, layoutH.ref); DRW_DBG("\n"); } DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n\n"); // RS crc; //RS */ return buf->isGood(); } //! Class to handle text style entries /*! * Class to handle text style symbol table entries * @author Rallaz */ bool DRW_Textstyle::parseCode(int code, dxfReader* reader) { switch (code) { case 3: font = reader->getUtf8String(); break; case 4: bigFont = reader->getUtf8String(); break; case 40: height = reader->getDouble(); break; case 41: width = reader->getDouble(); break; case 50: oblique = reader->getDouble(); break; case 42: lastHeight = reader->getDouble(); break; case 71: genFlag = reader->getInt32(); break; case 1071: fontFamily = reader->getInt32(); break; default: return DRW_TableEntry::parseCode(code, reader); } return true; } bool DRW_Textstyle::parseDwg(DRW::Version version, dwgBuffer* buf, duint32 bs) { dwgBuffer sBuff = *buf; dwgBuffer* sBuf = buf; if (version > DRW::AC1018) { //2007+ sBuf = &sBuff; //separate buffer for strings } bool ret = DRW_TableEntry::parseDwg(version, buf, sBuf, bs); DRW_DBG("\n***************************** parsing text style *********************************************\n"); if (!ret) return ret; name = sBuf->getVariableText(version, false); DRW_DBG("text style name: "); DRW_DBG(name.c_str()); DRW_DBG("\n"); flags |= buf->getBit() << 6; //style are referenced for a entity, style code 70, bit 7 (64) /*dint16 xrefindex =*/ buf->getBitShort(); flags |= buf->getBit() << 4; //is refx dependent, style code 70, bit 5 (16) flags |= buf->getBit() << 2; //vertical text, stile code 70, bit 3 (4) flags |= buf->getBit(); //if is a shape file instead of text, style code 70, bit 1 (1) height = buf->getBitDouble(); width = buf->getBitDouble(); oblique = buf->getBitDouble(); genFlag = buf->getRawChar8(); lastHeight = buf->getBitDouble(); font = sBuf->getVariableText(version, false); bigFont = sBuf->getVariableText(version, false); if (version > DRW::AC1018) { //2007+ skip string area buf->setPosition(objSize >> 3); buf->setBitPos(objSize & 7); } dwgHandle shpControlH = buf->getHandle(); DRW_DBG(" parentControlH Handle: "); DRW_DBGHL(shpControlH.code, shpControlH.size, shpControlH.ref); DRW_DBG("\n"); parentHandle = shpControlH.ref; DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); if (xDictFlag != 1) { //linetype in 2004 seems not have XDicObjH or NULL handle dwgHandle XDicObjH = buf->getHandle(); DRW_DBG(" XDicObj control Handle: "); DRW_DBGHL(XDicObjH.code, XDicObjH.size, XDicObjH.ref); DRW_DBG("\n"); DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); } /*RLZ: fails verify this part*/ dwgHandle XRefH = buf->getHandle(); DRW_DBG(" XRefH control Handle: "); DRW_DBGHL(XRefH.code, XRefH.size, XRefH.ref); DRW_DBG("\n"); DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n\n"); // RS crc; //RS */ return buf->isGood(); } //! Class to handle vport entries /*! * Class to handle vport symbol table entries * @author Rallaz */ bool DRW_Vport::parseCode(int code, dxfReader* reader) { switch (code) { case 10: lowerLeft.x = reader->getDouble(); break; case 20: lowerLeft.y = reader->getDouble(); break; case 11: UpperRight.x = reader->getDouble(); break; case 21: UpperRight.y = reader->getDouble(); break; case 12: center.x = reader->getDouble(); break; case 22: center.y = reader->getDouble(); break; case 13: snapBase.x = reader->getDouble(); break; case 23: snapBase.y = reader->getDouble(); break; case 14: snapSpacing.x = reader->getDouble(); break; case 24: snapSpacing.y = reader->getDouble(); break; case 15: gridSpacing.x = reader->getDouble(); break; case 25: gridSpacing.y = reader->getDouble(); break; case 16: viewDir.x = reader->getDouble(); break; case 26: viewDir.y = reader->getDouble(); break; case 36: viewDir.z = reader->getDouble(); break; case 17: viewTarget.x = reader->getDouble(); break; case 27: viewTarget.y = reader->getDouble(); break; case 37: viewTarget.z = reader->getDouble(); break; case 40: height = reader->getDouble(); break; case 41: ratio = reader->getDouble(); break; case 42: lensHeight = reader->getDouble(); break; case 43: frontClip = reader->getDouble(); break; case 44: backClip = reader->getDouble(); break; case 50: snapAngle = reader->getDouble(); break; case 51: twistAngle = reader->getDouble(); break; case 71: viewMode = reader->getInt32(); break; case 72: circleZoom = reader->getInt32(); break; case 73: fastZoom = reader->getInt32(); break; case 74: ucsIcon = reader->getInt32(); break; case 75: snap = reader->getInt32(); break; case 76: grid = reader->getInt32(); break; case 77: snapStyle = reader->getInt32(); break; case 78: snapIsopair = reader->getInt32(); break; default: return DRW_TableEntry::parseCode(code, reader); } return true; } bool DRW_Vport::parseDwg(DRW::Version version, dwgBuffer* buf, duint32 bs) { dwgBuffer sBuff = *buf; dwgBuffer* sBuf = buf; if (version > DRW::AC1018) { //2007+ sBuf = &sBuff; //separate buffer for strings } bool ret = DRW_TableEntry::parseDwg(version, buf, sBuf, bs); DRW_DBG("\n***************************** parsing VPort ************************************************\n"); if (!ret) return ret; name = sBuf->getVariableText(version, false); DRW_DBG("vport name: "); DRW_DBG(name.c_str()); DRW_DBG("\n"); flags |= buf->getBit() << 6; // code 70, bit 7 (64) if (version < DRW::AC1021) { //2004- /*dint16 xrefindex =*/ buf->getBitShort(); } flags |= buf->getBit() << 4; //is refx dependent, style code 70, bit 5 (16) height = buf->getBitDouble(); ratio = buf->getBitDouble(); DRW_DBG("flags: "); DRW_DBG(flags); DRW_DBG(" height: "); DRW_DBG(height); DRW_DBG(" ratio: "); DRW_DBG(ratio); center = buf->get2RawDouble(); DRW_DBG("\nview center: "); DRW_DBGPT(center.x, center.y, center.z); viewTarget.x = buf->getBitDouble(); viewTarget.y = buf->getBitDouble(); viewTarget.z = buf->getBitDouble(); DRW_DBG("\nview target: "); DRW_DBGPT(viewTarget.x, viewTarget.y, viewTarget.z); viewDir.x = buf->getBitDouble(); viewDir.y = buf->getBitDouble(); viewDir.z = buf->getBitDouble(); DRW_DBG("\nview dir: "); DRW_DBGPT(viewDir.x, viewDir.y, viewDir.z); twistAngle = buf->getBitDouble(); lensHeight = buf->getBitDouble(); frontClip = buf->getBitDouble(); backClip = buf->getBitDouble(); DRW_DBG("\ntwistAngle: "); DRW_DBG(twistAngle); DRW_DBG(" lensHeight: "); DRW_DBG(lensHeight); DRW_DBG(" frontClip: "); DRW_DBG(frontClip); DRW_DBG(" backClip: "); DRW_DBG(backClip); viewMode = buf->getBit(); //view mode, code 71, bit 0 (1) viewMode |= buf->getBit() << 1; //view mode, code 71, bit 1 (2) viewMode |= buf->getBit() << 2; //view mode, code 71, bit 2 (4) viewMode |= buf->getBit() << 4; //view mode, code 71, bit 4 (16) if (version > DRW::AC1014) { //2000+ //duint8 renderMode = buf->getRawChar8(); DRW_DBG("\n renderMode: "); DRW_DBG(buf->getRawChar8()); if (version > DRW::AC1018) { //2007+ DRW_DBG("\n use default lights: "); DRW_DBG(buf->getBit()); DRW_DBG(" default lighting type: "); DRW_DBG(buf->getRawChar8()); DRW_DBG(" brightness: "); DRW_DBG(buf->getBitDouble()); DRW_DBG("\n contrast: "); DRW_DBG(buf->getBitDouble()); DRW_DBG("\n"); DRW_DBG(" ambient color CMC: "); DRW_DBG(buf->getCmColor(version)); } } lowerLeft = buf->get2RawDouble(); DRW_DBG("\nlowerLeft: "); DRW_DBGPT(lowerLeft.x, lowerLeft.y, lowerLeft.z); UpperRight = buf->get2RawDouble(); DRW_DBG("\nUpperRight: "); DRW_DBGPT(UpperRight.x, UpperRight.y, UpperRight.z); viewMode |= buf->getBit() << 3; //UCSFOLLOW, view mode, code 71, bit 3 (8) circleZoom = buf->getBitShort(); fastZoom = buf->getBit(); DRW_DBG("\nviewMode: "); DRW_DBG(viewMode); DRW_DBG(" circleZoom: "); DRW_DBG(circleZoom); DRW_DBG(" fastZoom: "); DRW_DBG(fastZoom); ucsIcon = buf->getBit(); //ucs Icon, code 74, bit 0 (1) ucsIcon |= buf->getBit() << 1; //ucs Icon, code 74, bit 1 (2) grid = buf->getBit(); DRW_DBG("\nucsIcon: "); DRW_DBG(ucsIcon); DRW_DBG(" grid: "); DRW_DBG(grid); gridSpacing = buf->get2RawDouble(); DRW_DBG("\ngrid Spacing: "); DRW_DBGPT(gridSpacing.x, gridSpacing.y, gridSpacing.z); snap = buf->getBit(); snapStyle = buf->getBit(); DRW_DBG("\nsnap on/off: "); DRW_DBG(snap); DRW_DBG(" snap Style: "); DRW_DBG(snapStyle); snapIsopair = buf->getBitShort(); snapAngle = buf->getBitDouble(); DRW_DBG("\nsnap Isopair: "); DRW_DBG(snapIsopair); DRW_DBG(" snap Angle: "); DRW_DBG(snapAngle); snapBase = buf->get2RawDouble(); DRW_DBG("\nsnap Base: "); DRW_DBGPT(snapBase.x, snapBase.y, snapBase.z); snapSpacing = buf->get2RawDouble(); DRW_DBG("\nsnap Spacing: "); DRW_DBGPT(snapSpacing.x, snapSpacing.y, snapSpacing.z); if (version > DRW::AC1014) { //2000+ DRW_DBG("\n Unknown: "); DRW_DBG(buf->getBit()); DRW_DBG(" UCS per Viewport: "); DRW_DBG(buf->getBit()); DRW_DBG("\nUCS origin: "); DRW_DBGPT(buf->getBitDouble(), buf->getBitDouble(), buf->getBitDouble()); DRW_DBG("\nUCS X Axis: "); DRW_DBGPT(buf->getBitDouble(), buf->getBitDouble(), buf->getBitDouble()); DRW_DBG("\nUCS Y Axis: "); DRW_DBGPT(buf->getBitDouble(), buf->getBitDouble(), buf->getBitDouble()); DRW_DBG("\nUCS elevation: "); DRW_DBG(buf->getBitDouble()); DRW_DBG(" UCS Orthographic type: "); DRW_DBG(buf->getBitShort()); if (version > DRW::AC1018) { //2007+ gridBehavior = buf->getBitShort(); DRW_DBG(" gridBehavior (flags): "); DRW_DBG(gridBehavior); DRW_DBG(" Grid major: "); DRW_DBG(buf->getBitShort()); } } //common handles if (version > DRW::AC1018) { //2007+ skip string area buf->setPosition(objSize >> 3); buf->setBitPos(objSize & 7); } dwgHandle vpControlH = buf->getHandle(); DRW_DBG("\n parentControlH Handle: "); DRW_DBGHL(vpControlH.code, vpControlH.size, vpControlH.ref); DRW_DBG("\n"); parentHandle = vpControlH.ref; DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); if (xDictFlag != 1) { dwgHandle XDicObjH = buf->getHandle(); DRW_DBG(" XDicObj control Handle: "); DRW_DBGHL(XDicObjH.code, XDicObjH.size, XDicObjH.ref); DRW_DBG("\n"); DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); } /*RLZ: fails verify this part*/ dwgHandle XRefH = buf->getHandle(); DRW_DBG(" XRefH control Handle: "); DRW_DBGHL(XRefH.code, XRefH.size, XRefH.ref); if (version > DRW::AC1014) { //2000+ DRW_DBG("\nRemaining bytes: "); DRW_DBG(buf->numRemainingBytes()); if (version > DRW::AC1018) { //2007+ dwgHandle bkgrdH = buf->getHandle(); DRW_DBG(" background Handle: "); DRW_DBGHL(bkgrdH.code, bkgrdH.size, bkgrdH.ref); DRW_DBG("\nRemaining bytes: "); DRW_DBG(buf->numRemainingBytes()); dwgHandle visualStH = buf->getHandle(); DRW_DBG(" visual style Handle: "); DRW_DBGHL(visualStH.code, visualStH.size, visualStH.ref); DRW_DBG("\nRemaining bytes: "); DRW_DBG(buf->numRemainingBytes()); dwgHandle sunH = buf->getHandle(); DRW_DBG(" sun Handle: "); DRW_DBGHL(sunH.code, sunH.size, sunH.ref); DRW_DBG("\nRemaining bytes: "); DRW_DBG(buf->numRemainingBytes()); } dwgHandle namedUCSH = buf->getHandle(); DRW_DBG(" named UCS Handle: "); DRW_DBGHL(namedUCSH.code, namedUCSH.size, namedUCSH.ref); DRW_DBG("\nRemaining bytes: "); DRW_DBG(buf->numRemainingBytes()); dwgHandle baseUCSH = buf->getHandle(); DRW_DBG(" base UCS Handle: "); DRW_DBGHL(baseUCSH.code, baseUCSH.size, baseUCSH.ref); } DRW_DBG("\n Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); // RS crc; //RS */ return buf->isGood(); } bool DRW_ImageDef::parseCode(int code, dxfReader* reader) { switch (code) { case 1: name = reader->getUtf8String(); break; case 5: handle = reader->getHandleId(); break; case 10: u = reader->getDouble(); break; case 20: v = reader->getDouble(); break; case 11: up = reader->getDouble(); break; case 12: vp = reader->getDouble(); break; case 21: vp = reader->getDouble(); break; case 280: loaded = reader->getInt32(); break; case 281: resolution = reader->getInt32(); break; default: return DRW_TableEntry::parseCode(code, reader); } return true; } bool DRW_ImageDef::parseDwg(DRW::Version version, dwgBuffer* buf, duint32 bs) { dwgBuffer sBuff = *buf; dwgBuffer* sBuf = buf; if (version > DRW::AC1018) { //2007+ sBuf = &sBuff; //separate buffer for strings } bool ret = DRW_TableEntry::parseDwg(version, buf, sBuf, bs); DRW_DBG("\n***************************** parsing Image Def *********************************************\n"); if (!ret) return ret; dint32 imgVersion = buf->getBitLong(); DRW_DBG("class Version: "); DRW_DBG(imgVersion); DRW_Coord size = buf->get2RawDouble(); DRW_UNUSED(size); //RLZ: temporary, complete API name = sBuf->getVariableText(version, false); DRW_DBG("appId name: "); DRW_DBG(name.c_str()); DRW_DBG("\n"); loaded = buf->getBit(); resolution = buf->getRawChar8(); up = buf->getRawDouble(); vp = buf->getRawDouble(); dwgHandle parentH = buf->getHandle(); DRW_DBG(" parentH Handle: "); DRW_DBGHL(parentH.code, parentH.size, parentH.ref); DRW_DBG("\n"); parentHandle = parentH.ref; DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); //RLZ: Reactors handles if (xDictFlag != 1) { dwgHandle XDicObjH = buf->getHandle(); DRW_DBG(" XDicObj control Handle: "); DRW_DBGHL(XDicObjH.code, XDicObjH.size, XDicObjH.ref); DRW_DBG("\n"); DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); } /*RLZ: fails verify this part*/ dwgHandle XRefH = buf->getHandle(); DRW_DBG(" XRefH control Handle: "); DRW_DBGHL(XRefH.code, XRefH.size, XRefH.ref); DRW_DBG("\n"); DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n\n"); // RS crc; //RS */ return buf->isGood(); } bool DRW_PlotSettings::parseCode(int code, dxfReader* reader) { switch (code) { case 5: handle = reader->getHandleId(); break; case 6: plotViewName = reader->getUtf8String(); break; case 40: marginLeft = reader->getDouble(); break; case 41: marginBottom = reader->getDouble(); break; case 42: marginRight = reader->getDouble(); break; case 43: marginTop = reader->getDouble(); break; default: return DRW_TableEntry::parseCode(code, reader); } return true; } bool DRW_PlotSettings::parseDwg(DRW::Version version, dwgBuffer* buf, duint32 bs) { (void)version; (void)bs; DRW_DBG("\n********************** parsing Plot Settings not yet implemented **************************\n"); return buf->isGood(); } bool DRW_AppId::parseDwg(DRW::Version version, dwgBuffer* buf, duint32 bs) { dwgBuffer sBuff = *buf; dwgBuffer* sBuf = buf; if (version > DRW::AC1018) { //2007+ sBuf = &sBuff; //separate buffer for strings } bool ret = DRW_TableEntry::parseDwg(version, buf, sBuf, bs); DRW_DBG("\n***************************** parsing app Id *********************************************\n"); if (!ret) return ret; name = sBuf->getVariableText(version, false); DRW_DBG("appId name: "); DRW_DBG(name); DRW_DBG("\n"); flags |= buf->getBit() << 6; // code 70, bit 7 (64) /*dint16 xrefindex =*/ buf->getBitShort(); flags |= buf->getBit() << 4; //is refx dependent, style code 70, bit 5 (16) duint8 unknown = buf->getRawChar8(); // unknown code 71 DRW_DBG("unknown code 71: "); DRW_DBG(unknown); DRW_DBG("\n"); if (version > DRW::AC1018) { //2007+ skip string area buf->setPosition(objSize >> 3); buf->setBitPos(objSize & 7); } dwgHandle appIdControlH = buf->getHandle(); DRW_DBG(" parentControlH Handle: "); DRW_DBGHL(appIdControlH.code, appIdControlH.size, appIdControlH.ref); DRW_DBG("\n"); parentHandle = appIdControlH.ref; DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); if (xDictFlag != 1) { //linetype in 2004 seems not have XDicObjH or NULL handle dwgHandle XDicObjH = buf->getHandle(); DRW_DBG(" XDicObj control Handle: "); DRW_DBGHL(XDicObjH.code, XDicObjH.size, XDicObjH.ref); DRW_DBG("\n"); DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); } /*RLZ: fails verify this part*/ dwgHandle XRefH = buf->getHandle(); DRW_DBG(" XRefH control Handle: "); DRW_DBGHL(XRefH.code, XRefH.size, XRefH.ref); DRW_DBG("\n"); DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n\n"); // RS crc; //RS */ return buf->isGood(); } bool DRW_UCS::parseDwg([[maybe_unused]] DRW::Version version, dwgBuffer* buf, [[maybe_unused]] duint32 bs) { // fixme - sand - complete reading UCS from DWG DRW_DBG( "\n********************** parsing UCS Settings from DWG is not yet implemented **************************\n"); return buf->isGood(); } bool DRW_UCS::parseCode(int code, dxfReader* reader) { switch (code) { case 10: { origin.x = reader->getDouble(); break; } case 20: { origin.y = reader->getDouble(); break; } case 30: { origin.z = reader->getDouble(); break; } case 11: { xAxisDirection.x = reader->getDouble(); break; } case 21: { xAxisDirection.y = reader->getDouble(); break; } case 31: { xAxisDirection.z = reader->getDouble(); break; } case 12: { yAxisDirection.x = reader->getDouble(); break; } case 22: { yAxisDirection.y = reader->getDouble(); break; } case 32: { yAxisDirection.z = reader->getDouble(); break; } case 79: { // always 0 break; } case 146: { elevation = reader->getDouble(); break; } case 346: { // ID/handle of base UCS if this is an orthographic. This code is not present if the 79 code is 0. // If this code is not present and 79 code is non-zero, then base UCS is assumed to be WORLD break; } case 71: { // Orthographic type (optional; always appears in pairs with the 13, 23, 33 codes): // 1 = Top; 2 = Bottom // 3 = Front; 4 = Back // 5 = Left; 6 = Right orthoType = reader->getInt32(); break; } case 13: { orthoOrigin.x = reader->getDouble(); break; } case 23: { orthoOrigin.y = reader->getDouble(); break; } case 33: { orthoOrigin.z = reader->getDouble(); break; } default: return DRW_TableEntry::parseCode(code, reader); } return true; } bool DRW_View::parseCode(int code, dxfReader* reader) { switch (code) { case 40: { size.y = reader->getDouble(); break; } case 41: { size.x = reader->getDouble(); break; } case 10: { center.x = reader->getDouble(); break; } case 20: { center.y = reader->getDouble(); break; } case 11: { viewDirectionFromTarget.x = reader->getDouble(); break; } case 21: { viewDirectionFromTarget.y = reader->getDouble(); break; } case 31: { viewDirectionFromTarget.z = reader->getDouble(); break; } case 12: { targetPoint.x = reader->getDouble(); break; } case 22: { targetPoint.y = reader->getDouble(); break; } case 32: { targetPoint.z = reader->getDouble(); break; } case 42: { lensLen = reader->getDouble(); break; } case 43: { frontClippingPlaneOffset = reader->getDouble(); break; } case 44: { backClippingPlaneOffset = reader->getDouble(); break; } case 50: { twistAngle = reader->getDouble(); break; } case 71: { viewMode = reader->getInt32(); // tmp - check size to read break; } case 281: { renderMode = reader->getInt32(); // tmp - check size to read break; } case 72: { hasUCS = reader->getBool(); break; } case 73: { cameraPlottable = reader->getBool(); break; } case 110: { ucsOrigin.x = reader->getDouble(); break; } case 120: { ucsOrigin.y = reader->getDouble(); break; } case 130: { ucsOrigin.z = reader->getDouble(); break; } case 111: { ucsXAxis.x = reader->getDouble(); break; } case 121: { ucsXAxis.y = reader->getDouble(); break; } case 131: { ucsXAxis.z = reader->getDouble(); break; } case 112: { ucsYAxis.x = reader->getDouble(); break; } case 122: { ucsYAxis.y = reader->getDouble(); break; } case 132: { ucsYAxis.z = reader->getDouble(); break; } case 79: { ucsOrthoType = reader->getInt32(); break; } case 146: { ucsElevation = reader->getDouble(); break; } case 345: { namedUCS_ID = reader->getHandleId(); // ID/handle of AcDbUCSTableRecord if UCS is a named UCS. If not present, then UCS is unnamed, code 345 break; } case 346: { baseUCS_ID = reader->getHandleId(); // ID/handle of AcDbUCSTableRecord of base UCS if UCS is orthographic, If not present and 79 code is non-zero, then base UCS is taken to be WORLD, code 346 break; } default: return DRW_TableEntry::parseCode(code, reader); } return true; } bool DRW_View::parseDwg(DRW::Version /*version*/, dwgBuffer* buf, duint32 /*bs*/) { // fixme - sand - complete reading VIEW from DWG DRW_DBG( "\n********************** parsing VIEW Settings from DWG is not yet implemented **************************\n"); return buf->isGood(); } DRW_ParsingContext::~DRW_ParsingContext() { for (auto it=lineTypeMap.begin(); it!=lineTypeMap.end(); ++it) { delete it->second; } for (auto it=blockRecordMap.begin(); it!=blockRecordMap.end(); ++it) { delete it->second; } for (auto it=textStyles.begin(); it!=textStyles.end(); ++it) { delete it->second; } blockRecordMap.clear(); lineTypeMap.clear(); textStyles.clear(); } std::string DRW_ParsingContext::resolveBlockRecordName(int handle) { auto it = blockRecordMap.find(handle); if (it != blockRecordMap.end()) { DRW_Block_Record* blockRecord = it->second; std::string name = blockRecord->name; return name; } return {}; } std::string DRW_ParsingContext::resolveLineTypeName(int handle) { auto it = lineTypeMap.find(handle); if (it != lineTypeMap.end()) { DRW_LType* lineType = it->second; std::string name = lineType->name; return name; } return {}; } std::string DRW_ParsingContext::resolveTextStyleName(int handle) { auto it = textStyles.find(handle); if (it != textStyles.end()) { DRW_Textstyle* textStyle = it->second; std::string name = textStyle->name; return name; } return {}; } DRW_WritingContext::~DRW_WritingContext() { textStyleMap.clear(); blockMap.clear(); lineTypesMap.clear(); }