| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
|
|
| #include "libdxfrw.h" |
| #include <fstream> |
| #include <algorithm> |
| #include <sstream> |
| #include <cassert> |
| #include <functional> |
|
|
| #include "intern/drw_textcodec.h" |
| #include "intern/dxfreader.h" |
| #include "intern/dxfwriter.h" |
| #include "intern/drw_dbg.h" |
| #include "intern/dwgutil.h" |
|
|
| #define FIRSTHANDLE 48 |
|
|
|
|
| dxfRW::dxfRW(const char* name){ |
| DRW_DBGSL(DRW_dbg::Level::None); |
| fileName = name; |
| reader = nullptr; |
| writer = nullptr; |
| applyExt = false; |
| elParts = 128; |
| } |
| dxfRW::~dxfRW(){ |
| delete reader; |
| delete writer; |
| for (auto it=imageDef.begin(); it!=imageDef.end(); ++it) { |
| delete *it; |
| } |
| imageDef.clear(); |
| } |
|
|
| void dxfRW::setDebug(DRW::DebugLevel lvl){ |
| switch (lvl){ |
| case DRW::DebugLevel::Debug: |
| DRW_DBGSL(DRW_dbg::Level::Debug); |
| break; |
| case DRW::DebugLevel::None: |
| DRW_DBGSL(DRW_dbg::Level::None); |
| } |
| } |
|
|
| #define ERR_UNKNOWN return setError(DRW::BAD_UNKNOWN); |
| #define ERR_TABLES return setError(DRW::BAD_READ_TABLES); |
| #define ERR_BAD_CODE return setError( DRW::BAD_CODE_PARSED); |
|
|
|
|
| bool dxfRW::readAscii(DRW_Interface *interface_, bool ext, std::string& content) { |
| if (nullptr == interface_) { |
| ERR_UNKNOWN; |
| } |
| applyExt = ext; |
| std::istringstream filestr(content); |
| iface = interface_; |
|
|
| reader = new dxfReaderAscii(&filestr); |
| bool isOk {processDxf()}; |
| setVersion((DRW::Version) reader->getVersion()); |
| delete reader; |
| reader = nullptr; |
| return isOk; |
| } |
|
|
| bool dxfRW::read(DRW_Interface *interface_, bool ext){ |
| drw_assert(fileName.empty() == false); |
| if (nullptr == interface_) { |
| ERR_UNKNOWN; |
| } |
| applyExt = ext; |
| std::ifstream filestr; |
| DRW_DBG("dxfRW::read 1def\n"); |
| filestr.open (fileName.c_str(), std::ios_base::in | std::ios::binary); |
| if (!filestr.is_open() || !filestr.good()) { |
| return setError(DRW::BAD_OPEN); |
| } |
|
|
| char line[22]; |
| char line2[22] = "AutoCAD Binary DXF\r\n"; |
| line2[20] = (char)26; |
| line2[21] = '\0'; |
| filestr.read (line, 22); |
| filestr.close(); |
| iface = interface_; |
| DRW_DBG("dxfRW::read 2\n"); |
| if (strncmp(line, line2, 21) == 0) { |
| filestr.open (fileName.c_str(), std::ios_base::in | std::ios::binary); |
| binFile = true; |
| |
| filestr.seekg (22, std::ios::beg); |
| reader = new dxfReaderBinary(&filestr); |
| DRW_DBG("dxfRW::read binary file\n"); |
| } else { |
| binFile = false; |
| filestr.open (fileName.c_str(), std::ios_base::in); |
| reader = new dxfReaderAscii(&filestr); |
| } |
|
|
| bool isOk {processDxf()}; |
| filestr.close(); |
| setVersion((DRW::Version) reader->getVersion()); |
| delete reader; |
| reader = nullptr; |
| return isOk; |
| } |
|
|
| bool dxfRW::write(DRW_Interface *interface_, DRW::Version ver, bool bin){ |
| bool isOk = false; |
| std::ofstream filestr; |
| setVersion(ver); |
| binFile = bin; |
| iface = interface_; |
| if (binFile) { |
| filestr.open (fileName.c_str(), std::ios_base::out | std::ios::binary | std::ios::trunc); |
| |
| filestr << "AutoCAD Binary DXF\r\n" << (char)26 << '\0'; |
| writer = new dxfWriterBinary(&filestr); |
| DRW_DBG("dxfRW::read binary file\n"); |
| } else { |
| filestr.open (fileName.c_str(), std::ios_base::out | std::ios::trunc); |
| writer = new dxfWriterAscii(&filestr); |
| std::string comm = std::string("dxfrw ") + std::string(DRW_VERSION); |
| writeString(999, comm); |
| } |
| |
| iface->writeHeader(header); |
| writeString(0, "SECTION"); |
| entCount = FIRSTHANDLE; |
| |
| writeHeader(); |
| writeSectionEnd(); |
|
|
| if (afterAC1009) { |
| writeSectionStart("CLASSES"); |
| writeSectionEnd(); |
| } |
| writeSectionStart("TABLES"); |
| writeTables(); |
| writeSectionEnd(); |
|
|
| writeSectionStart("BLOCKS"); |
| writeBlocks(); |
| writeSectionEnd(); |
|
|
| writeSectionStart("ENTITIES"); |
| iface->writeEntities(); |
| writeSectionEnd(); |
|
|
| if (afterAC1009) { |
| writeSectionStart("OBJECTS"); |
| writeObjects(); |
| writeSectionEnd(); |
| } |
| writeName("EOF"); |
|
|
| filestr.flush(); |
| filestr.close(); |
| isOk = true; |
| delete writer; |
| writer = nullptr; |
| return isOk; |
| } |
|
|
|
|
| void dxfRW::writeHeader() { |
| |
|
|
| int varInt; |
| std::string varStr; |
|
|
|
|
| writeString(2, "HEADER"); |
| writeString(9, "$ACADVER"); |
|
|
| switch (version) { |
| case DRW::AC1006: |
| case DRW::AC1009: |
| varStr = "AC1009"; |
| break; |
| case DRW::AC1012: |
| case DRW::AC1014: |
| varStr = "AC1014"; |
| break; |
| case DRW::AC1015: |
| varStr = "AC1015"; |
| break; |
| case DRW::AC1018: |
| varStr = "AC1018"; |
| break; |
| |
| |
| |
| case DRW::AC1024: |
| varStr = "AC1024"; |
| break; |
| case DRW::AC1027: |
| varStr = "AC1027"; |
| break; |
| default: |
| varStr = "AC1021"; |
| break; |
| } |
| writeString(1, varStr); |
| writer->setVersion(varStr, true); |
|
|
| header.getStr("$ACADVER", &varStr); |
| header.getStr("$ACADMAINTVER", &varStr); |
|
|
| if (!header.getStr("$DWGCODEPAGE", &varStr)) { |
| varStr = "ANSI_1252"; |
| } |
| writeString(9, "$DWGCODEPAGE"); |
| writer->setCodePage(varStr); |
| writeString(3, writer->getCodePage()); |
|
|
| DRW_Coord zeroCoord{0.0, 0.0, 0.0}; |
| DRW_Coord maxCoord{ |
| 1.0000000000000000E+020, |
| 1.0000000000000000E+020, 1.0000000000000000E+020 |
| }; |
|
|
|
|
| writeVar("$TITLE", ""); |
| writeVar("$SUBJECT", ""); |
| writeVar("$AUTHOR", ""); |
| writeVar("$KEYWORDS", ""); |
| writeVar("$COMMENTS", ""); |
|
|
|
|
| DRW_Coord xVectorCoord(1.0, 0.0, 0.0); |
| DRW_Coord yVectorCoord(0.0, 1.0, 0.0); |
|
|
| writeVar("$INSBASE", 10, zeroCoord); |
| writeVar("$EXTMIN", 10, maxCoord); |
| writeVar("$EXTMAX", 10, maxCoord); |
|
|
| writeVar2D("$LIMMIN", 10, zeroCoord); |
| writeVar2D("$LIMMAX", 10, {420.0,297.0, 0.0}); |
|
|
| writeVar("$ORTHOMODE", 0); |
| writeVar("$REGENMODE", 1); |
| writeVar("$FILLMODE", 1); |
| writeVar("$QTEXTMODE", 0); |
| writeVar("$MIRRTEXT", 0); |
|
|
| if (version == DRW::AC1009){ |
| writeVar("$DRAGMODE", 2, 70); |
| } |
|
|
| writeVar("$LTSCALE", 1.0, 40); |
| if (version == DRW::AC1009){ |
| writeVar("$OSMODE", 0, 70); |
| } |
|
|
| writeVar("$ATTMODE", 0, 70); |
| writeVar("$TEXTSIZE", 2.5, 40); |
| writeVar("$TRACEWID", 15.68, 40); |
| writeVar("$TEXTSTYLE", "STANDARD", 7); |
| writeVar("$CLAYER", "0", 8); |
| writeVar("$CELTYPE", "BYLAYER", 6); |
| writeVar("$CECOLOR", 256, 62); |
| if (afterAC1009){ |
| writeVar("$CELTSCALE", 1.0, 40); |
| writeVar("$DISPSILH", 9, 70); |
| } |
|
|
| |
| writeVar("$DIMSCALE", 2.5); |
| writeVar("$DIMASZ", 2.5); |
| writeVar("$DIMEXO", 0.625); |
| writeVar("$DIMDLI", 3.75); |
| writeVar("$DIMRND", 0.0); |
| writeVar("$DIMDLE", 0.0); |
| writeVar("$DIMEXE", 1.25); |
| writeVar("$DIMTP", 0.0); |
| writeVar("$DIMTM", 0.0); |
| writeVar("$DIMTXT", 2.5); |
| writeVar("$DIMCEN", 2.5); |
| writeVar("$DIMTSZ", 0.0); |
| writeVar("$DIMTOL", 0); |
| writeVar("$DIMLIM", 0); |
| writeVar("$DIMTIH", 0); |
| writeVar("$DIMTOH", 0); |
| writeVar("$DIMSE1", 0); |
| writeVar("$DIMSE2", 0); |
| writeVar("$DIMTAD", 1); |
| writeVar("$DIMZIN", 8); |
|
|
| writeVar("$DIMBLK", ""); |
|
|
| writeVar("$DIMASO", 1); |
| writeVar("$DIMSHO", 1); |
| writeVar( "$DIMPOST", ""); |
| writeVar( "$DIMAPOST", ""); |
|
|
| writeVar("$DIMALT", 0); |
| writeVar("$DIMALTD", 3); |
| writeVar("$DIMALTF", 0.03937); |
| writeVar("$DIMLFAC", 1.0); |
| writeVar("$DIMTOFL", 1); |
| writeVar("$DIMTVP", 0.0); |
| writeVar("$DIMTIX", 0); |
| writeVar("$DIMSOXD", 0); |
| writeVar("$DIMSAH", 0); |
|
|
| writeVar("$DIMBLK1", ""); |
| writeVar("$DIMBLK2", ""); |
| writeVar("$DIMSTYLE", "STANDARD", 2); |
|
|
| writeVar("$DIMCLRD", 0); |
| writeVar("$DIMCLRE", 0); |
| writeVar("$DIMCLRT", 0); |
| writeVar("$DIMTFAC", 1.0); |
| writeVar("$DIMGAP", 0.625); |
| |
| if (afterAC1009) { |
| writeVar("$DIMJUST", 0); |
| writeVar("$DIMSD1", 0); |
| writeVar("$DIMSD2", 0); |
| writeVar("$DIMTOLJ", 0); |
| writeVar("$DIMTZIN", 8); |
| writeVar("$DIMALTZ", 0); |
| writeVar("$DIMALTTZ", 0); |
| writeVar("$DIMUPT", 0); |
| writeVar("$DIMDEC", 2); |
| writeVar("$DIMTDEC", 2); |
| writeVar("$DIMALTU", 2); |
| writeVar("$DIMALTTD", 3); |
|
|
| writeVar("$DIMTXSTY", "STANDARD", 7); |
|
|
| writeVar("$DIMAUNIT", 0); |
| writeVar("$DIMADEC", 0); |
| writeVar("$DIMALTRND", 0.0); |
| writeVar("$DIMAZIN", 0); |
| writeVar("$DIMDSEP", 44); |
| writeVar("$DIMATFIT", 3); |
| writeVar("$DIMFRAC", 0); |
|
|
| writeVar("$DIMLDRBLK", "STANDARD"); |
|
|
| |
| int varInt; |
| if ( !header.getInt("$DIMLUNIT", &varInt) ){ |
| if (!header.getInt("$DIMUNIT", &varInt)) |
| varInt = 2; |
| } |
| |
| if (varInt < 1 || varInt > 6) { |
| varInt = 2; |
| } |
| if (afterAC1014) { |
| writeVarExp("$DIMLUNIT", varInt, 70); |
| } else { |
| writeVarExp("$DIMUNIT", varInt, 70); |
| } |
|
|
| writeVar("$DIMLWD", -2); |
| writeVar("$DIMLWE", -2); |
| writeVar("$DIMTMOVE", 0); |
|
|
| if (afterAC1018) { |
| writeVar("$DIMFXL", 1.0); |
| writeVar("$DIMFXLON", 0); |
| writeVar("$DIMJOGANG", 0.7854); |
| writeVar("$DIMTFILL", 0); |
| writeVar("$DIMTFILLCLR", 0); |
| writeVar("$DIMARCSYM", 0); |
|
|
| writeVar("$DIMLTYPE", "", 6); |
| writeVar("$DIMLTEX1", "", 6); |
| writeVar("$DIMLTEX2", "", 6); |
| if (version > DRW::AC1021) { |
| writeVar("$DIMTXTDIRECTION", 0); |
| } |
| } |
| } |
|
|
| writeVar("$LUNITS", 2, 70); |
| writeVar("$LUPREC", 4, 70); |
| writeVar("$SKETCHINC", 1.0, 40); |
| writeVar("$FILLETRAD", 0.0, 40); |
| writeVar("$AUNITS", 2, 70); |
| writeVar("$AUPREC", 0, 70); |
| writeVar("$MENU", ".", 1); |
|
|
| writeVar("$ELEVATION", 0.0, 40); |
| writeVar("$PELEVATION", 0.0, 40); |
| writeVar("$THICKNESS", 0.0, 40); |
| writeVar("$LIMCHECK", 0, 70); |
| if (version < DRW::AC1015) { |
| writeVar("$BLIPMODE", 0, 70); |
| } |
|
|
| writeVar("$CHAMFERA", 0.0, 40); |
| writeVar("$CHAMFERB", 0.0, 40); |
| if (afterAC1009) { |
| writeVar("$CHAMFERC", 0.0, 40); |
| writeVar("$CHAMFERD", 0.0, 40); |
| } |
|
|
| writeVar("$SKPOLY", 0, 70); |
| |
| writeVar("$USRTIMER", 1, 70); |
| writeVar("$ANGBASE", 0.0, 50); |
| writeVar("$ANGDIR", 0, 70); |
| writeVar("$PDMODE", 34, 70); |
|
|
| writeVar("$PDSIZE", 0.0, 40); |
| writeVar("$PLINEWID", 0.0, 40); |
|
|
| if (afterAC1012) { |
| writeVar("$COORDS", 2, 70); |
| } |
|
|
| writeVar("$SPLFRAME", 0, 70); |
| writeVar("$SPLINETYPE", 2, 70); |
| writeVar("$SPLINESEGS", 8, 70); |
| if (version < DRW::AC1012) { |
| writeVar("$ATTDIA", 1, 70); |
| writeVar("$ATTREQ", 1, 70); |
| writeVar("$HANDLING", 1, 70); |
| } |
| writeString(9, "$HANDSEED"); |
| |
| writer->writeString(5, "20000"); |
|
|
| writeVar("$SURFTAB1", 6, 70); |
| writeVar("$SURFTAB2", 6, 70); |
| writeVar("$SURFTYPE", 6, 70); |
| writeVar("$SURFU", 6, 70); |
| writeVar("$SURFV", 6, 70); |
| if (afterAC1009) { |
| writeVar("$UCSBASE", "", 2); |
| } |
|
|
| writeVar("$UCSNAME", "", 2); |
| writeVar("$UCSORG", 10, zeroCoord); |
| writeVar("$UCSXDIR", 10, xVectorCoord); |
| writeVar("$UCSYDIR", 10, yVectorCoord); |
|
|
| if (afterAC1009) { |
| writeVar("$UCSORTHOREF", "", 2); |
| writeVar("$UCSORTHOVIEW", 0, 70); |
| writeVar("$UCSORGTOP", 10, zeroCoord); |
| writeVar("$UCSORGBOTTOM", 10, zeroCoord); |
| writeVar("$UCSORGLEFT", 10, zeroCoord); |
| writeVar("$UCSORGRIGHT", 10, zeroCoord); |
| writeVar("$UCSORGFRONT", 10, zeroCoord); |
| writeVar("$UCSORGBACK", 10, zeroCoord); |
| writeVar("$PUCSBASE", "", 2); |
| } |
|
|
| writeVar("$PUCSNAME", "", 2); |
| writeVar("$PUCSORG", 10, zeroCoord); |
| writeVar("$PUCSXDIR", 10, xVectorCoord); |
| writeVar("$PUCSYDIR", 10, yVectorCoord); |
|
|
| if (afterAC1009) { |
| writeVar("$PUCSORTHOREF", "", 2); |
| writeVar("$PUCSORTHOVIEW", 0, 70); |
| writeVar("$PUCSORGTOP", 10, zeroCoord); |
| writeVar("$PUCSORGBOTTOM", 10, zeroCoord); |
| writeVar("$PUCSORGLEFT", 10, zeroCoord); |
| writeVar("$PUCSORGRIGHT", 10, zeroCoord); |
| writeVar("$PUCSORGFRONT", 10, zeroCoord); |
| writeVar("$PUCSORGBACK", 10, zeroCoord); |
| } |
|
|
| writeVar("$USERI1", 0, 70); |
| writeVar("$USERI2", 0, 70); |
| writeVar("$USERI3", 0, 70); |
| writeVar("$USERI4", 0, 70); |
| writeVar("$USERI5", 0, 70); |
|
|
| writeVar("$USERR1", 0.0, 40); |
| writeVar("$USERR2", 0.0, 40); |
| writeVar("$USERR3", 0.0, 40); |
| writeVar("$USERR4", 0.0, 40); |
| writeVar("$USERR5", 0.0, 40); |
|
|
| writeVar("$WORLDVIEW", 1, 70); |
| writeVar("$SHADEDGE", 3, 70); |
| writeVar("$SHADEDIF", 70, 70); |
| writeVar("$TILEMODE", 1, 70); |
| writeVar("$MAXACTVP", 64, 70); |
|
|
| if (afterAC1009) { |
| writeVar("$PINSBASE", 10, zeroCoord); |
| } |
|
|
| writeVar("$PLIMCHECK", 0, 70); |
| writeVar("$PEXTMIN", 10, zeroCoord); |
| writeVar("$PEXTMAX", 10, zeroCoord); |
|
|
| |
| writeVarOpt("$GRIDMODE", 70); |
| writeVarOpt("$SNAPSTYLE", 70); |
|
|
| writeVar2DOpt("$GRIDUNIT", 10); |
| writeVar2DOpt("$VIEWCTR", 10); |
|
|
| |
|
|
| writeVar2D("$PLIMMIN", 10, zeroCoord); |
| writeVar2D("$PLIMMAX", 10, {297.0, 210.0, 0.0}); |
| writeVar("$UNITMODE", 0, 70); |
| writeVar("$VISRETAIN", 1, 70); |
| writeVar("$PLINEGEN", 0, 70); |
| writeVar("$PSLTSCALE", 1, 70); |
|
|
| if (afterAC1009){ |
| writeVar("$TREEDEPTH", 3020, 70); |
| writeVar("$CMLSTYLE", "Standard", 2); |
| writeVar("$CMLJUST", 0, 70); |
| writeVar("$CMLSCALE", 20.0, 40); |
| writeVar("$PROXYGRAPHICS", 1, 70); |
|
|
| int insunits {DRW_Header::Units::None}; |
| header.getInt("$INSUNITS", &insunits); |
| header.getInt("$MEASUREMENT", &varInt); |
|
|
| writeVarExp("$MEASUREMENT", DRW_Header::measurement( insunits), 70); |
|
|
| writeVar("$CELWEIGHT", -1, 370); |
| writeVar("$ENDCAPS", 0, 280); |
| writeVar("$JOINSTYLE", 0, 280); |
| writeVar("$LWDISPLAY", 0, 290); |
| if (afterAC1014) { |
| writeVarExp("$INSUNITS", insunits, 70); |
| } |
| writeVar("$HYPERLINKBASE", "", 1); |
| writeVar("$STYLESHEET", "", 1); |
| writeVar("$XEDIT", 1, 290); |
| writeVar("$CEPSNTYPE", 0, 380); |
| writeVar("$PSTYLEMODE", 1, 290); |
|
|
| |
|
|
| writeVar("$EXTNAMES", 1, 290); |
| writeVar("$PSVPSCALE", 0.0, 40); |
| writeVar("$OLESTARTUP", 0, 290); |
| } |
| if (afterAC1018) { |
| writeVar("$CAMERADISPLAY", 0, 290); |
| writeVar("$LENSLENGTH", 50.0, 40); |
| writeVar("$CAMERAHEIGHT", 0.0, 40); |
| writeVar("$STEPSPERSEC", 2.0, 40); |
| writeVar("$STEPSIZE", 50.0, 40); |
| writeVar("$3DDWFPREC", 2.0, 40); |
| writeVar("$PSOLWIDTH", 5.0, 40); |
| writeVar("$PSOLHEIGHT", 80.0, 40); |
| writeVar("$LOFTANG1", M_PI_2, 40); |
| writeVar("$LOFTANG2", M_PI_2, 40); |
| writeVar("$LOFTMAG1", 0.0, 40); |
| writeVar("$LOFTMAG2", 0.0, 40); |
| writeVar("$LOFTPARAM", 7, 70); |
| writeVar("$LOFTNORMALS", 1, 280); |
|
|
| writeVar("$LATITUDE", 1.0); |
| writeVar("$LONGITUDE", 1.0); |
| writeVar("$NORTHDIRECTION", 0.0); |
|
|
| |
|
|
| writeVar("$TIMEZONE", -8000); |
| writeVar("$LIGHTGLYPHDISPLAY", 1, 280); |
| writeVar("$TILEMODELIGHTSYNCH", 1, 280); |
| writeVar("$SOLIDHIST", 1, 280); |
| writeVar("$SHOWHIST", 1, 280); |
| writeVar("$DWFFRAME", 2, 280); |
| writeVar("$DGNFRAME", 0, 280); |
|
|
| writeVar("$REALWORLDSCALE", 1, 290); |
| writeVar("$INTERFERECOLOR", 1, 62); |
|
|
| |
| |
|
|
| writeVar("$CSHADOW", 0, 280); |
| writeVar("$SHADOWPLANELOCATION", 0.0, 40); |
| } |
|
|
| for (auto it :header.customVars) { |
| std::string key = it.first; |
| DRW_Variant* var = it.second; |
| auto val = var->content.s; |
| if (!val->empty()) { |
| writeString(9, "$CUSTOMPROPERTYTAG"); |
| writeString(1, key); |
| writeString(9, "$CUSTOMPROPERTY"); |
| writeString(1, *val); |
| } |
| } |
| } |
|
|
| bool dxfRW::writeEntity(DRW_Entity *ent) { |
| ent->handle = ++entCount; |
| writeHandle(5, ent->handle); |
| writeSubClassOpt("Entity"); |
|
|
| if (ent->space == 1) { |
| writeInt16(67, 1); |
| } |
| if (afterAC1009) { |
| writeUtf8String(8, ent->layer); |
| writeUtf8String(6, ent->lineType); |
| } else { |
| writeUtf8Caps(8, ent->layer); |
| writeUtf8Caps(6, ent->lineType); |
| } |
| writeInt16(62, ent->color); |
| if (afterAC1015 && ent->color24 >= 0) { |
| writeInt32(420, ent->color24); |
| } |
| if (afterAC1014) { |
| writeInt16(370, DRW_LW_Conv::lineWidth2dxfInt(ent->lWeight)); |
| } |
| if (version >= DRW::AC1014) { |
| writeAppData(ent->appData); |
| } |
| return true; |
| } |
|
|
| bool dxfRW::writeAppData(const std::list<std::list<DRW_Variant>>& appData) { |
| for(const auto& group : appData) { |
| |
| bool found = false; |
|
|
| for(const auto& data : group) { |
| if(data.code() == 102 && data.type() == DRW_Variant::STRING) { |
| writeString(102, "{" + *(data.content.s)); |
| found = true; |
| break; |
| } |
| } |
|
|
| if (found) { |
| for (const auto& data : group) { |
| if (data.code() == 102) { |
| continue; |
| } |
| switch (data.type()) { |
| case DRW_Variant::STRING: |
| writeString(data.code(), *(data.content.s)); |
| break; |
|
|
| case DRW_Variant::INTEGER: |
| writeInt32(data.code(), data.content.i); |
| break; |
|
|
| case DRW_Variant::DOUBLE: |
| writeDouble(data.code(), data.content.i); |
| break; |
|
|
| default: |
| break; |
| } |
| } |
|
|
| writeString(102, "}"); |
| } |
| } |
| return true; |
| } |
|
|
| bool dxfRW::writeLineTypeGenerics(DRW_LType *ent, int handle) { |
| writeName("LTYPE"); |
| std::string strname = ent->name; |
| transform(strname.begin(), strname.end(), strname.begin(),::toupper); |
| if (afterAC1009) { |
| auto text = toHexStr(handle); |
| writeString(5, text); |
| if (afterAC1012) { |
| writeString(330, "5"); |
| } |
| writeSymTypeRecord("Linetype"); |
| writeUtf8String(2, ent->name); |
| m_writingContext.lineTypesMap.emplace_back(std::pair<std::string, int>(strname, handle)); |
| } else { |
| writeUtf8Caps(2, strname); |
| } |
| return true; |
| } |
|
|
| bool dxfRW::writeLineType(DRW_LType *ent){ |
| std::string strname = ent->name; |
|
|
| transform(strname.begin(), strname.end(), strname.begin(),::toupper); |
| |
| if (strname == "BYLAYER" || strname == "BYBLOCK" || strname == "CONTINUOUS") { |
| return true; |
| } |
| writeLineTypeGenerics(ent, ++entCount); |
| |
| writeInt16(70, ent->flags); |
| writeUtf8String(3, ent->desc); |
| ent->update(); |
| writeInt16(72, 65); |
| writeInt16(73, ent->size); |
| writeDouble(40, ent->length); |
|
|
| size_t size = ent->path.size(); |
| for (unsigned int i = 0; i< size; i++){ |
| writeDouble(49, ent->path.at(i)); |
| if (afterAC1009) { |
| writeInt16(74, 0); |
| } |
| } |
| return true; |
| } |
|
|
| bool dxfRW::writeLayer(DRW_Layer *ent){ |
| writeName("LAYER"); |
| if (!wlayer0 && ent->name == "0") { |
| wlayer0 = true; |
| if (afterAC1009) { |
| writeString(5, "10"); |
| } |
| } else { |
| if (afterAC1009) { |
| writeString(5, toHexStr(++entCount)); |
| } |
| } |
| if (afterAC1012) { |
| writeString(330, "2"); |
| } |
| if (afterAC1009) { |
| writeSymTypeRecord("Layer"); |
| writeUtf8String(2, ent->name); |
| } else { |
| writeUtf8Caps(2, ent->name); |
| } |
| writeInt16(70, ent->flags); |
| writeInt16(62, ent->color); |
| if (afterAC1015 && ent->color24 >= 0) { |
| writeInt32(420, ent->color24); |
| } |
| if (afterAC1009) { |
| writeUtf8String(6, ent->lineType); |
| if (!ent->plotF) { |
| writeBool(290, ent->plotF); |
| } |
| writeInt16(370, DRW_LW_Conv::lineWidth2dxfInt(ent->lWeight)); |
| writeString(390, "F"); |
| } else { |
| writeUtf8Caps(6, ent->lineType); |
| } |
| if (!ent->extData.empty()){ |
| writeExtData(ent->extData); |
| } |
| |
| return true; |
| } |
|
|
| bool dxfRW::writeUCS(DRW_UCS* ent){ |
| writeName("UCS"); |
| if (afterAC1009) { |
| writeString(5, toHexStr(++entCount)); |
| if (afterAC1012) { |
| writeString(330, "42"); |
| |
| } |
| writeSymTypeRecord("UCS"); |
| writeUtf8String(2, ent->name); |
| } |
| else { |
| writeUtf8Caps(2, ent->name); |
| } |
| writeInt16(70, ent->flags); |
| writeCoord(10, ent->origin); |
| writeCoord(11, ent->xAxisDirection); |
| writeCoord(12, ent->yAxisDirection); |
|
|
| writeInt16(79, 0); |
| |
| |
| |
| |
|
|
| writeDouble(146, ent->elevation); |
| writeDouble(71, ent->orthoType); |
|
|
| writeCoord(13, ent->orthoOrigin); |
| return true; |
| } |
|
|
| bool dxfRW::writeView(DRW_View *ent){ |
| writeName("VIEW"); |
| if (afterAC1009) { |
| writeString(5, toHexStr(++entCount)); |
| if (afterAC1012) { |
| writeString(330, "42"); |
| |
| } |
| writeSymTypeRecord("View"); |
| writeUtf8String(2, ent->name); |
| } |
| else { |
| writeUtf8Caps(2, ent->name); |
| } |
| writeInt16(70, ent->flags); |
|
|
| writeDouble(40, ent->size.y); |
| writeDouble(10, ent->center.x); |
| writeDouble(20, ent->center.y); |
| writeDouble(41, ent->size.x); |
|
|
| writeCoord(11, ent->viewDirectionFromTarget); |
| writeCoord(12, ent->targetPoint); |
|
|
| writeDouble(42, ent->lensLen); |
| writeDouble(43, ent->frontClippingPlaneOffset); |
| writeDouble(44, ent->backClippingPlaneOffset); |
| writeDouble(50, ent->twistAngle); |
| writeInt16(71, ent->viewMode); |
| writeInt16(281, ent->renderMode); |
|
|
| writeBool(72, ent->hasUCS); |
| writeBool(73, ent->cameraPlottable); |
|
|
| |
| |
| |
| |
| |
| |
|
|
| if (ent->hasUCS){ |
| writeCoord(110, ent->ucsOrigin); |
| writeCoord(111, ent->ucsXAxis); |
| writeCoord(112, ent->ucsYAxis); |
| writeInt16(79, ent->ucsOrthoType); |
| writeDouble(146, ent->ucsElevation); |
|
|
| |
| |
| |
| |
| |
| |
| |
| } |
| return true; |
| } |
|
|
| bool dxfRW::writeTextstyle(DRW_Textstyle *ent){ |
| writeName("STYLE"); |
| |
| std::string name=ent->name; |
| transform(name.begin(), name.end(), name.begin(), toupper); |
| if (!dimstyleStd) { |
| if (name == "STANDARD"){ |
| dimstyleStd = true; |
| } |
| } |
| if (afterAC1009) { |
| writeString(5, toHexStr(++entCount)); |
| m_writingContext.textStyleMap[name] = entCount; |
| if (afterAC1012) { |
| writeString(330, "2"); |
| } |
| writeSymTypeRecord("TextStyle"); |
| writeUtf8String(2, ent->name); |
| } else { |
| writeUtf8Caps(2, ent->name); |
| } |
| writeInt16(70, ent->flags); |
| writeDouble(40, ent->height); |
| writeDouble(41, ent->width); |
| writeDouble(50, ent->oblique); |
| writeInt16(71, ent->genFlag); |
| writeDouble(42, ent->lastHeight); |
| if (afterAC1009) { |
| writeUtf8String(3, ent->font); |
| writeUtf8String(4, ent->bigFont); |
| if (ent->fontFamily != 0) { |
| writeInt32(1071, ent->fontFamily); |
| } |
| } else { |
| writeUtf8Caps(3, ent->font); |
| writeUtf8Caps(4, ent->bigFont); |
| } |
| return true; |
| } |
|
|
| bool dxfRW::writeVport(DRW_Vport *ent){ |
| if (!dimstyleStd) { |
| ent->name = "*ACTIVE"; |
| dimstyleStd = true; |
| } |
| writeName( "VPORT"); |
| if (afterAC1009) { |
| writeString(5, toHexStr(++entCount)); |
| if (afterAC1012) { |
| writeString(330, "2"); |
| } |
| writeSymTypeRecord("Viewport"); |
| writeUtf8String(2, ent->name); |
| } |
| else { |
| writeUtf8Caps(2, ent->name); |
| } |
| writeInt16(70, ent->flags); |
| writeDouble(10, ent->lowerLeft.x); |
| writeDouble(20, ent->lowerLeft.y); |
| writeDouble(11, ent->UpperRight.x); |
| writeDouble(21, ent->UpperRight.y); |
| writeDouble(12, ent->center.x); |
| writeDouble(22, ent->center.y); |
| writeDouble(13, ent->snapBase.x); |
| writeDouble(23, ent->snapBase.y); |
| writeDouble(14, ent->snapSpacing.x); |
| writeDouble(24, ent->snapSpacing.y); |
| writeDouble(15, ent->gridSpacing.x); |
| writeDouble(25, ent->gridSpacing.y); |
| writeCoord(16, ent->viewDir); |
| writeCoord(17, ent->viewTarget); |
| writeDouble(40, ent->height); |
| writeDouble(41, ent->ratio); |
| writeDouble(42, ent->lensHeight); |
| writeDouble(43, ent->frontClip); |
| writeDouble(44, ent->backClip); |
| writeDouble(50, ent->snapAngle); |
| writeDouble(51, ent->twistAngle); |
| writeInt16(71, ent->viewMode); |
| writeInt16(72, ent->circleZoom); |
| writeInt16(73, ent->fastZoom); |
| writeInt16(74, ent->ucsIcon); |
| writeInt16(75, ent->snap); |
| writeInt16(76, ent->grid); |
| writeInt16(77, ent->snapStyle); |
| writeInt16(78, ent->snapIsopair); |
| if (afterAC1014) { |
| writeInt16(281, 0); |
| writeInt16(65, 1); |
| writeDouble(110, 0.0); |
| writeDouble(120, 0.0); |
| writeDouble(130, 0.0); |
| writeDouble(111, 1.0); |
| writeDouble(121, 0.0); |
| writeDouble(131, 0.0); |
| writeDouble(112, 0.0); |
| writeDouble(122, 1.0); |
| writeDouble(132, 0.0); |
| writeInt16(79, 0); |
| writeDouble(146, 0.0); |
| if (afterAC1018) { |
| writeString(348, "10020"); |
| writeInt16(60, ent->gridBehavior); |
| writeInt16(61, 5); |
| writeBool(292, 1); |
| writeInt16(282, 1); |
| writeDouble(141, 0.0); |
| writeDouble(142, 0.0); |
| writeInt16(63, 250); |
| writeInt32(421, 3358443); |
| } |
| } |
| return true; |
| } |
|
|
| bool dxfRW::writeDouble(int code, DRW_Dimstyle* ent, const std::string& name) { |
| double val; |
| if (ent->get(name, val)) { |
| writeDouble(code, val); |
| } |
| return true; |
| } |
|
|
| bool dxfRW::writeInt16(int code, DRW_Dimstyle* ent, const std::string& name) { |
| int val; |
| if (ent->get(name, val)) { |
| writeInt16(code, val); |
| } |
| return true; |
| } |
|
|
| bool dxfRW::writeUtf8String(int code, DRW_Dimstyle* ent, const std::string& name) { |
| std::string val; |
| if (ent->get(name, val)) { |
| writeUtf8String(code, val); |
| } |
| return true; |
| } |
|
|
| bool dxfRW::writeDimstyle(DRW_Dimstyle *ent) { |
| writeName("DIMSTYLE"); |
| |
| |
| |
| |
| |
| |
| if (afterAC1009) { |
| writeString(105, toHexStr(++entCount)); |
| if (afterAC1012) { |
| writeString(330, "A"); |
| } |
| writeSymTypeRecord("DimStyle"); |
| writeUtf8String(2, ent->name); |
| } |
| else { |
| writeUtf8Caps(2, ent->name); |
| } |
| writeInt16(70, ent->flags); |
|
|
| |
|
|
| writeUtf8String(3, ent, "$DIMPOST"); |
| writeUtf8String(4, ent, "$DIMAPOST"); |
|
|
| writeUtf8String(5, ent, "$DIMBLK"); |
| writeUtf8String(6, ent, "$DIMBLK1"); |
| writeUtf8String(7, ent, "$DIMBLK2"); |
|
|
|
|
| writeDouble(40, ent, "$DIMSCALE"); |
| writeDouble(41, ent, "$DIMASZ"); |
| writeDouble(42, ent, "$DIMEXO"); |
| writeDouble(43, ent, "$DIMDLI"); |
| writeDouble(44, ent, "$DIMEXE"); |
| writeDouble(45, ent, "$DIMRND"); |
| writeDouble(46, ent, "$DIMDLE"); |
| writeDouble(47, ent, "$DIMTP"); |
| writeDouble(48, ent, "$DIMTM"); |
|
|
| if (afterAC1018) { |
| writeDouble(49, ent, "$DIMFXL"); |
|
|
| writeInt16(69, ent, "$DIMTFILL"); |
| writeInt16(70, ent, "$DIMTFILLCLR"); |
| } |
|
|
| writeDouble(140, ent, "$DIMTXT"); |
| writeDouble(141, ent, "$DIMCEN"); |
| writeDouble(142, ent, "$DIMTSZ"); |
| writeDouble(143, ent, "$DIMALTF"); |
| writeDouble(144, ent, "$DIMLFAC"); |
| writeDouble(145, ent, "$DIMTVP"); |
| writeDouble(146, ent, "$DIMTFAC"); |
| writeDouble(147, ent, "$DIMGAP"); |
|
|
| if (afterAC1014) { |
| writeDouble(148, ent, "$DIMALTRND"); |
| } |
| writeInt16(71, ent, "$DIMTOL"); |
| writeInt16(72, ent, "$DIMLIM"); |
| writeInt16(72, ent, "$DIMLIM"); |
| writeInt16(73, ent, "$DIMTIH"); |
| writeInt16(74, ent, "$DIMTOH"); |
| writeInt16(75, ent, "$DIMSE1"); |
| writeInt16(76, ent, "$DIMSE2"); |
| writeInt16(77, ent, "$DIMTAD"); |
| writeInt16(78, ent, "$DIMZIN"); |
|
|
| if (afterAC1014) { |
| writeInt16(79, ent, "$DIMAZIN"); |
| } |
| writeInt16(170, ent, "$DIMALT"); |
| writeInt16(171, ent, "$DIMALTD"); |
| writeInt16(172, ent, "$DIMTOFL"); |
| writeInt16(173, ent, "$DIMSAH"); |
| writeInt16(174, ent, "$DIMTIX"); |
| writeInt16(175, ent, "$DIMSOXD"); |
| writeInt16(176, ent, "$DIMCLRD"); |
| writeInt16(177, ent, "$DIMCLRE"); |
| writeInt16(178, ent, "$DIMCLRT"); |
|
|
| if (afterAC1014) { |
| writeInt16(179, ent, "$DIMADEC"); |
| } |
| if (afterAC1009) { |
| if (version < DRW::AC1015) { |
| writeInt16(270, ent, "$DIMLUNIT"); |
| } |
| writeInt16(271, ent, "$DIMDEC"); |
| writeInt16(272, ent, "$DIMTDEC"); |
| writeInt16(273, ent, "$DIMALTU"); |
| writeInt16(274, ent, "$DIMALTTD"); |
| writeInt16(275, ent, "$DIMAUNIT"); |
| } |
| if (afterAC1014) { |
| writeInt16(276, ent, "$DIMFRAC"); |
| writeInt16(277, ent, "$DIMLUNIT"); |
| writeInt16(278, ent, "$DIMDSEP"); |
| writeInt16(279, ent, "$DIMTMOVE"); |
| } |
| if (afterAC1009) { |
| writeInt16(280, ent, "$DIMJUST"); |
| writeInt16(281, ent, "$DIMSD1"); |
| writeInt16(282, ent, "$DIMSD2"); |
| writeInt16(283, ent, "$DIMTOLJ"); |
| writeInt16(284, ent, "$DIMTZIN"); |
| writeInt16(285, ent, "$DIMALTZ"); |
| writeInt16(286, ent, "$DIMALTTZ"); |
|
|
| if (version < DRW::AC1015) { |
| writeInt16(287, ent, "$DIMATFIT"); |
| } |
| writeInt16(288, ent, "$DIMUPT"); |
| } |
| if (afterAC1014) { |
| writeInt16(289, ent, "$DIMATFIT"); |
| } |
| if (afterAC1018) { |
| writeInt16(290, ent, "$DIMFXLON"); |
| } |
| if (afterAC1009) { |
| writeInt16(292, ent, "$DIMTXTDIRECTION"); |
| writeUtf8String(340, ent, "$DIMTXSTY"); |
| } |
| if (afterAC1014) { |
| writeUtf8String(341, ent, "_$DIMLDRBLK"); |
|
|
| writeUtf8String(342, ent, "_$DIMBLK"); |
| writeUtf8String(343, ent, "_$DIMBLK1"); |
| writeUtf8String(344, ent, "_$DIMBLK2"); |
|
|
| writeUtf8String(345, ent, "$DIMLTYPE"); |
|
|
| |
| writeUtf8String(347, ent, "$DIMLTEX1"); |
| writeUtf8String(348, ent, "$DIMLTEX2"); |
|
|
| writeInt16(371, ent, "$DIMLWD"); |
| writeInt16(372, ent, "$DIMLWE"); |
| writeInt16(90, ent, "$DIMARCSYM"); |
| } |
|
|
| if (!ent->extData.empty()) { |
| writeExtData(ent->extData); |
| } |
| return true; |
| } |
|
|
| bool dxfRW::writeAppId(DRW_AppId *ent){ |
| std::string strname = ent->name; |
| transform(strname.begin(), strname.end(), strname.begin(),::toupper); |
| |
| if (strname == "ACAD") { |
| return true; |
| } |
| writeName("APPID"); |
| if (afterAC1009) { |
| writeString(5, toHexStr(++entCount)); |
| if (afterAC1014) { |
| writeString(330, "9"); |
| } |
| writeSymTypeRecord("RegApp"); |
| writeUtf8String(2, ent->name); |
| } else { |
| writeUtf8Caps(2, ent->name); |
| } |
| writeInt16(70, ent->flags); |
| return true; |
| } |
|
|
| bool dxfRW::writePoint(DRW_Point *ent) { |
| writeName( "POINT"); |
| writeEntity(ent); |
| writeSubClassOpt("Point"); |
| writeCoord(10, ent->basePoint); |
| return true; |
| } |
|
|
| bool dxfRW::writeLine(DRW_Line *ent) { |
| writeName("LINE"); |
| writeEntity(ent); |
| writeSubClassOpt("Line"); |
| writeCoord(10, ent->basePoint); |
| writeCoord(11, ent->secPoint); |
| return true; |
| } |
|
|
| bool dxfRW::writeRay(DRW_Ray *ent) { |
| writeName("RAY"); |
| writeEntity(ent); |
| writeSubClassOpt("Ray"); |
|
|
| DRW_Coord crd = ent->secPoint; |
| crd.unitize(); |
| writeCoord(10, ent->basePoint); |
| writeCoord(11, crd); |
| return true; |
| } |
|
|
| bool dxfRW::writeXline(DRW_Xline *ent) { |
| writeName("XLINE"); |
| writeEntity(ent); |
| writeSubClassOpt("Xline"); |
| DRW_Coord crd = ent->secPoint; |
| crd.unitize(); |
| writeCoord(10, ent->basePoint); |
| writeCoord(11, crd); |
| return true; |
| } |
|
|
| bool dxfRW::writeCircle(DRW_Circle *ent) { |
| writeName("CIRCLE"); |
| writeEntity(ent); |
| writeSubClassOpt("Circle"); |
| writeCoord(10, ent->basePoint); |
| writeDouble(40, ent->radious); |
| return true; |
| } |
|
|
| bool dxfRW::writeArc(DRW_Arc *ent) { |
| writeName("ARC"); |
| writeEntity(ent); |
|
|
| writeSubClassOpt("Circle"); |
| writeCoord(10, ent->basePoint); |
| writeDouble(40, ent->radious); |
|
|
| writeSubClassOpt("Arc"); |
| writeDouble(50, ent->staangle*ARAD); |
| writeDouble(51, ent->endangle*ARAD); |
| return true; |
| } |
|
|
| bool dxfRW::writeEllipse(DRW_Ellipse *ent){ |
| |
| ent->correctAxis(); |
| if (afterAC1009) { |
| writeName("ELLIPSE"); |
| writeEntity(ent); |
| writeSubClassOpt("Ellipse"); |
| writeCoord(10, ent->basePoint); |
| writeCoord(11, ent->secPoint); |
| writeDouble(40, ent->ratio); |
| writeDouble(41, ent->staparam); |
| writeDouble(42, ent->endparam); |
| } else { |
| DRW_Polyline pol; |
| |
| ent->toPolyline(&pol, elParts); |
| writePolyline(&pol); |
| } |
| return true; |
| } |
|
|
| bool dxfRW::writeTrace(DRW_Trace *ent){ |
| writeName("TRACE"); |
| writeEntity(ent); |
| writeSubClassOpt("Trace"); |
| writeCoord(10, ent->basePoint); |
| writeCoord(11, ent->secPoint); |
| writeCoord(12, ent->thirdPoint); |
| writeCoord(13, ent->fourPoint); |
| return true; |
| } |
|
|
| bool dxfRW::writeSolid(DRW_Solid *ent){ |
| writeName("SOLID"); |
| writeEntity(ent); |
| writeSubClassOpt("Trace"); |
| writeCoord(10, ent->basePoint); |
| writeCoord(11, ent->secPoint); |
| writeCoord(12, ent->thirdPoint); |
| writeCoord(13, ent->fourPoint); |
| return true; |
| } |
|
|
| bool dxfRW::write3dface(DRW_3Dface *ent){ |
| writeName( "3DFACE"); |
| writeEntity(ent); |
| writeSubClassOpt("Face"); |
| writeCoord(10, ent->basePoint); |
| writeCoord(11, ent->secPoint); |
| writeCoord(12, ent->thirdPoint); |
| writeCoord(13, ent->fourPoint); |
| writeInt16(70, ent->invisibleflag); |
| return true; |
| } |
|
|
| bool dxfRW::writeLWPolyline(DRW_LWPolyline *ent){ |
| if (afterAC1009) { |
| writeName("LWPOLYLINE"); |
| writeEntity(ent); |
| writeSubClassOpt("Polyline"); |
| ent->vertexnum = ent->vertlist.size(); |
| writeInt32(90, ent->vertexnum); |
| writeInt16(70, ent->flags); |
| writeDouble(43, ent->width); |
| writeDoubleOpt(38, ent->elevation); |
| writeDoubleOpt(39, ent->thickness); |
|
|
| for (int i = 0; i< ent->vertexnum; i++){ |
| auto& v = ent->vertlist.at(i); |
| writeDouble(10, v->x); |
| writeDouble(20, v->y); |
| writeDoubleOpt(40, v->stawidth); |
| writeDoubleOpt(41, v->endwidth); |
| writeDoubleOpt(42, v->bulge); |
| } |
| } else { |
| |
| } |
| return true; |
| } |
|
|
| bool dxfRW::writePolyline(DRW_Polyline *ent) { |
| writeName("POLYLINE"); |
| writeEntity(ent); |
| if (afterAC1009) { |
| if (ent->flags & 8 || ent->flags & 16) { |
| writeSubClass("3dPolyline"); |
| } |
| else { |
| writeSubClass("2dPolyline"); |
| } |
| } else { |
| writeInt16(66, 1); |
| } |
| DRW_Coord coord(0, 0, ent->basePoint.z); |
| writeCoord(10, coord); |
|
|
| writeDoubleOpt(39, ent->thickness); |
|
|
| writeInt16(70, ent->flags); |
| writeDoubleOpt(40, ent->defstawidth); |
| writeDoubleOpt(41, ent->defendwidth); |
|
|
| if (ent->flags & 16 || ent->flags & 32) { |
| writeInt16(71, ent->vertexcount); |
| writeInt16(72, ent->facecount); |
| } |
| if (ent->smoothM != 0) { |
| writeInt16(73, ent->smoothM); |
| } |
| if (ent->smoothN != 0) { |
| writeInt16(74, ent->smoothN); |
| } |
| if (ent->curvetype != 0) { |
| writeInt16(75, ent->curvetype); |
| } |
| DRW_Coord crd = ent->extPoint; |
| if (crd.x != 0 || crd.y != 0 || crd.z != 1) { |
| writeCoord(210, crd); |
| } |
|
|
| DRW_Coord zero(0,0,0); |
|
|
| int vertexnum = ent->vertlist.size(); |
| for (int i = 0; i< vertexnum; i++){ |
| DRW_Vertex *v = ent->vertlist.at(i).get(); |
| writeName( "VERTEX"); |
| writeEntity(ent); |
| writeSubClassOpt("Vertex"); |
| if ( (v->flags & 128) && !(v->flags & 64) ) { |
| writeCoord(10, zero); |
| } else { |
| writeCoord(10, v->basePoint); |
| } |
| writeDoubleOpt(40, v->stawidth); |
| writeDoubleOpt(41, v->endwidth); |
| writeDoubleOpt(42, v->bulge); |
|
|
| if (v->flags != 0) { |
| writeInt16(70, ent->flags); |
| } |
| if (v->flags & 2) { |
| writeDouble(50, v->tgdir); |
| } |
| if ( v->flags & 128 ) { |
| if (v->vindex1 != 0) { |
| writeInt16(71, v->vindex1); |
| } |
| if (v->vindex2 != 0) { |
| writeInt16(72, v->vindex2); |
| } |
| if (v->vindex3 != 0) { |
| writeInt16(73, v->vindex3); |
| } |
| if (v->vindex4 != 0) { |
| writeInt16(74, v->vindex4); |
| } |
| if ( !(v->flags & 64) ) { |
| writeInt32(91, v->identifier); |
| } |
| } |
| } |
| writeName("SEQEND"); |
| writeEntity(ent); |
| return true; |
| } |
|
|
| bool dxfRW::writeSpline(DRW_Spline *ent){ |
| if (afterAC1009) { |
| writeName("SPLINE"); |
| writeEntity(ent); |
| writeSubClassOpt("Spline"); |
| writeCoord(210, ent->normalVec); |
|
|
| writeInt16(70, ent->flags); |
| writeInt16(71, ent->degree); |
| writeInt16(72, ent->nknots); |
| writeInt16(73, ent->ncontrol); |
| writeInt16(74, ent->nfit); |
| writeDouble(42, ent->tolknot); |
| writeDouble(43, ent->tolcontrol); |
| writeDouble(44, ent->tolfit); |
| |
| for (int i = 0; i< ent->nknots; i++){ |
| writeDouble(40, ent->knotslist.at(i)); |
| } |
| size_t size = ent->weightlist.size(); |
| for (std::size_t i = 0; i< size; i++) { |
| writeDouble(41, ent->weightlist.at(i)); |
| } |
| for (int i = 0; i< ent->ncontrol; i++){ |
| auto crd = ent->controllist.at(i); |
| writeCoord(10, *crd); |
| } |
| for (int i = 0; i< ent->nfit; i++){ |
| auto crd = ent->fitlist.at(i); |
| writeCoord(11, *crd); |
| } |
| } else { |
| |
| } |
| return true; |
| } |
|
|
| bool dxfRW::writeHatch(DRW_Hatch *ent){ |
| if (afterAC1009) { |
| writeName("HATCH"); |
| writeEntity(ent); |
| writeSubClassOpt("Hatch"); |
| writeDouble(10, 0.0); |
| writeDouble(20, 0.0); |
| writeDouble(30, ent->basePoint.z); |
|
|
| writeCoord(210, ent->extPoint); |
|
|
| writeString(2, ent->name); |
| writeInt16(70, ent->solid); |
| writeInt16(71, ent->associative); |
| ent->loopsnum = ent->looplist.size(); |
| writeInt16(91, ent->loopsnum); |
| |
| for (int i = 0; i< ent->loopsnum; i++){ |
| DRW_HatchLoop *loop = ent->looplist.at(i).get(); |
| writeInt16(92, loop->type); |
| if ((loop->type & 2) == 2) { |
| |
| } |
| else { |
| |
| loop->update(); |
| writeInt16(93, loop->numedges); |
| for (int j = 0; j<loop->numedges; ++j) { |
| switch ((loop->objlist.at(j))->eType) { |
| case DRW::LINE: { |
| writeInt16(72, 1); |
| auto l = static_cast<DRW_Line*>(loop->objlist.at(j).get()); |
| writeDouble(10, l->basePoint.x); |
| writeDouble(20, l->basePoint.y); |
| writeDouble(11, l->secPoint.x); |
| writeDouble(21, l->secPoint.y); |
| break; |
| } |
| case DRW::ARC: { |
| writeInt16(72, 2); |
| auto a = static_cast<DRW_Arc*>(loop->objlist.at(j).get()); |
| writeDouble(10, a->basePoint.x); |
| writeDouble(20, a->basePoint.y); |
| writeDouble(40, a->radious); |
| writeDouble(50, a->staangle * ARAD); |
| writeDouble(51, a->endangle * ARAD); |
| writeInt16(73, a->isccw); |
| break; |
| } |
| case DRW::ELLIPSE: { |
| writeInt16(72, 3); |
| auto a = static_cast<DRW_Ellipse*>(loop->objlist.at(j).get()); |
| a->correctAxis(); |
| writeDouble(10, a->basePoint.x); |
| writeDouble(20, a->basePoint.y); |
| writeDouble(11, a->secPoint.x); |
| writeDouble(21, a->secPoint.y); |
| writeDouble(40, a->ratio); |
| writeDouble(50, a->staparam * ARAD); |
| writeDouble(51, a->endparam * ARAD); |
| writeInt16(73, a->isccw); |
| break; |
| } |
| case DRW::SPLINE: |
| |
| |
| break; |
| default: |
| break; |
| } |
| } |
| writeInt16(97, 0); |
| } |
| } |
| writeInt16(75, ent->hstyle); |
| writeInt16(76, ent->hpattern); |
| if (!ent->solid){ |
| writeDouble(52, ent->angle); |
| writeDouble(41, ent->scale); |
| writeInt16(77, ent->doubleflag); |
| writeInt16(78, ent->deflines); |
| } |
| |
| |
| |
| writeInt32(98, 0); |
| } else { |
| |
| } |
| return true; |
| } |
|
|
| bool dxfRW::writeLeader(DRW_Leader *ent){ |
| if (afterAC1009) { |
| writeName("LEADER"); |
| writeEntity(ent); |
| writeSubClass("Leader"); |
| writeUtf8String(3, ent->style); |
| writeInt16(71, ent->arrow); |
| writeInt16(72, ent->leadertype); |
| writeInt16(73, ent->flag); |
| writeInt16(74, ent->hookline); |
| writeInt16(75, ent->hookflag); |
| writeDouble(40, ent->textheight); |
| writeDouble(41, ent->textwidth); |
| writeDouble(76, ent->vertnum); |
| size_t size = ent->vertexlist.size(); |
| writeDouble(76, size); |
| for (unsigned int i=0; i<size; i++) { |
| auto vert = ent->vertexlist.at(i); |
| writeCoord(10, *vert); |
| } |
| } else { |
| |
| } |
| return true; |
| } |
| bool dxfRW::writeDimension(DRW_Dimension *ent) { |
| if (afterAC1009) { |
| writeName("DIMENSION"); |
| writeEntity(ent); |
| writeSubClass("Dimension"); |
| if (!ent->getName().empty()){ |
| writeString(2, ent->getName()); |
| } |
|
|
| writeCoord(10, ent->getDefPoint()); |
| writeCoord(11, ent->getTextPoint()); |
|
|
| if (!(ent->type & 32)) { |
| |
| ent->type = ent->type +32; |
| } |
| writeInt16(70, ent->type); |
| if (!(ent->getText().empty()) ) { |
| writeUtf8String(1, ent->getText()); |
| } |
| writeInt16(71, ent->getAlign()); |
| if (ent->getTextLineStyle() != 1) { |
| writeInt16(72, ent->getTextLineStyle()); |
| } |
| if (ent->getTextLineFactor() != 1){ |
| writeDouble(41, ent->getTextLineFactor()); |
| } |
| writeUtf8String(3, ent->getStyle()); |
| if (ent->getTextLineFactor() != 0){ |
| writeDouble(53, ent->getDir()); |
| } |
|
|
| writeDoubleOpt(51, ent->getHDir()); |
| writeCoord(210, ent->getExtrusion()); |
|
|
| if (ent->getFlipArrow1()) { |
| writeBool(74,true); |
| } |
| if (ent->getFlipArrow2()) { |
| writeBool(75,true); |
| } |
|
|
| switch (ent->eType) { |
| case DRW::DIMALIGNED: |
| case DRW::DIMLINEAR: { |
| auto* dd = static_cast<DRW_DimAligned*>(ent); |
| writeSubClass("AlignedDimension"); |
| DRW_Coord crd = dd->getClonepoint(); |
| if (crd.x != 0 || crd.y != 0 || crd.z != 0) { |
| writeCoord(12, crd); |
| } |
| writeCoord(13, dd->getDef1Point()); |
| writeCoord(14, dd->getDef2Point()); |
|
|
| if (ent->eType == DRW::DIMLINEAR) { |
| auto dl = static_cast<DRW_DimLinear*>(ent); |
| writeSubClass("RotatedDimension"); |
| |
| writeDoubleOpt(50, dl->getAngle()); |
| |
| writeDoubleOpt(52, dl->getOblique()); |
| } |
| break; |
| } |
| case DRW::DIMRADIAL: { |
| auto* dd = static_cast<DRW_DimRadial*>(ent); |
| writeSubClass("RadialDimension"); |
| writeCoord(15, dd->getDiameterPoint()); |
| writeDouble(40, dd->getLeaderLength()); |
| break; |
| } |
| case DRW::DIMDIAMETRIC: { |
| auto* dd = static_cast<DRW_DimDiametric*>(ent); |
| writeSubClass("DiametricDimension"); |
| writeCoord(15, dd->getDiameter1Point()); |
| writeDouble(40, dd->getLeaderLength()); |
| break; |
| } |
| case DRW::DIMANGULAR: { |
| auto* dd = static_cast<DRW_DimAngular*>(ent); |
| writeSubClass("2LineAngularDimension"); |
| writeCoord(13, dd->getFirstLine1()); |
| writeCoord(14, dd->getFirstLine2()); |
| writeCoord(15, dd->getSecondLine1()); |
| writeCoord(16, dd->getDimPoint()); |
| break; |
| } |
| case DRW::DIMANGULAR3P: { |
| auto* dd = static_cast<DRW_DimAngular3p*>(ent); |
| writeCoord(13, dd->getFirstLine()); |
| writeCoord(14, dd->getSecondLine()); |
| writeCoord(15, dd->getVertexPoint()); |
| break; |
| } |
| case DRW::DIMORDINATE: { |
| auto* dd = static_cast<DRW_DimOrdinate*>(ent); |
| writeSubClass("OrdinateDimension"); |
| writeCoord(13, dd->getFirstLine()); |
| writeCoord(14, dd->getSecondLine()); |
| break; |
| } |
| default: |
| break; |
| } |
|
|
| writeEntityExtData(ent); |
| } else { |
| |
| } |
| return true; |
| } |
|
|
| bool dxfRW::writeEntityExtData(DRW_Entity* ent) { |
| for (auto r: ent->extData) { |
| auto type = r->type(); |
| switch (type) { |
| case DRW_Variant::INTEGER: { |
| writeInt16(r->code(), r->i_val()); |
| break; |
| } |
| case DRW_Variant::DOUBLE: { |
| writeDouble(r->code(), r->d_val()); |
| break; |
| } |
| case DRW_Variant::STRING: { |
| writeString(r->code(), r->c_str()); |
| break; |
| } |
| case DRW_Variant::COORD: { |
| |
| |
| break; |
| } |
| default: |
| break; |
| } |
| } |
| return true; |
| } |
|
|
| bool dxfRW::writeInsert(DRW_Insert *ent){ |
| writeName("INSERT"); |
| writeEntity(ent); |
| if (afterAC1009) { |
| writeSubClass("BlockReference"); |
| writeUtf8String(2, ent->name); |
| } else { |
| writeUtf8Caps(2, ent->name); |
| } |
| writeCoord(10, ent->basePoint); |
| writeDouble(41, ent->xscale); |
| writeDouble(42, ent->yscale); |
| writeDouble(43, ent->zscale); |
| writeDouble(50, (ent->angle)*ARAD); |
| writeInt16(70, ent->colcount); |
| writeInt16(71, ent->rowcount); |
| writeDouble(44, ent->colspace); |
| writeDouble(45, ent->rowspace); |
| return true; |
| } |
|
|
| bool dxfRW::writeText(DRW_Text *ent) { |
| writeName("TEXT"); |
| writeEntity(ent); |
| writeSubClassOpt("Text"); |
|
|
| |
| writeCoord(10, ent->basePoint); |
|
|
| writeDouble(40, ent->height); |
| writeUtf8String(1, ent->text); |
| writeDouble(50, ent->angle); |
| writeDouble(41, ent->widthscale); |
| writeDouble(51, ent->oblique); |
| if (afterAC1009) { |
| writeUtf8String(7, ent->style); |
| } |
| else { |
| writeUtf8Caps(7, ent->style); |
| } |
| writeInt16(71, ent->textgen); |
| if (ent->alignH != DRW_Text::HLeft) { |
| writeInt16(72, ent->alignH); |
| } |
| if (ent->alignH != DRW_Text::HLeft || ent->alignV != DRW_Text::VBaseLine) { |
| writeCoord(11, ent->secPoint); |
| } |
| writeCoord(210, ent->extPoint); |
| if (afterAC1009) { |
| writeSubClass("Text"); |
| } |
| if (ent->alignV != DRW_Text::VBaseLine) { |
| writeInt16(73, ent->alignV); |
| } |
| return true; |
| } |
|
|
| bool dxfRW::writeMText(DRW_MText *ent){ |
| if (afterAC1009) { |
| writeName("MTEXT"); |
| writeEntity(ent); |
| writeSubClass("MText"); |
| writeCoord(10, ent->basePoint); |
| writeDouble(40, ent->height); |
| writeDouble(41, ent->widthscale); |
| writeInt16(71, ent->textgen); |
| writeInt16(72, ent->alignH); |
| std::string text = writer->fromUtf8String(ent->text); |
|
|
| int i; |
| for(i =0; (text.size()-i) > 250; ) { |
| writeString(3, text.substr(i, 250)); |
| i +=250; |
| } |
| writeString(1, text.substr(i)); |
| writeString(7, ent->style); |
| writeCoord(210, ent->extPoint); |
| writeDouble(50, ent->angle); |
| writeInt16(73, ent->alignV); |
| writeDouble(44, ent->interlin); |
| |
| } else { |
| |
| } |
| return true; |
| } |
|
|
| bool dxfRW::writeViewport(DRW_Viewport *ent) { |
| writeName( "VIEWPORT"); |
| writeEntity(ent); |
| writeSubClassOpt("Viewport"); |
|
|
| writeCoord(10, ent->basePoint); |
| writeDouble(40, ent->pswidth); |
| writeDouble(41, ent->psheight); |
| writeInt16(68, ent->vpstatus); |
| writeInt16(69, ent->vpID); |
| writeDouble(12, ent->centerPX); |
| writeDouble(22, ent->centerPY); |
| return true; |
| } |
|
|
| DRW_ImageDef* dxfRW::writeImage(DRW_Image *ent, std::string name){ |
| if (afterAC1009) { |
| |
| |
| DRW_ImageDef *id = nullptr; |
| size_t size = imageDef.size(); |
| for (unsigned int i=0; i<size; i++) { |
| auto image_def = imageDef.at(i); |
| if (image_def->name == name ) { |
| id = image_def; |
| continue; |
| } |
| } |
| if (id == nullptr) { |
| id = new DRW_ImageDef(); |
| imageDef.push_back(id); |
| id->handle = ++entCount; |
| } |
| id->name = name; |
| std::string idReactor = toHexStr(++entCount); |
|
|
| writeName("IMAGE"); |
| writeEntity(ent); |
| writeSubClass("RasterImage"); |
| writeCoord(10, ent->basePoint); |
| writeCoord(11, ent->secPoint); |
| writeCoord(12, ent->vVector); |
| writeDouble(13, ent->sizeu); |
| writeDouble(23, ent->sizev); |
| writeString(340, toHexStr(id->handle)); |
| writeInt16(70, 1); |
| writeInt16(280, ent->clip); |
| writeInt16(281, ent->brightness); |
| writeInt16(282, ent->contrast); |
| writeInt16(283, ent->fade); |
| writeString(360, idReactor); |
| id->reactors[idReactor] = toHexStr(ent->handle); |
| return id; |
| } |
| return nullptr; |
| } |
|
|
| bool dxfRW::writeBlockRecord(std::string name){ |
| if (afterAC1009) { |
| writeName("BLOCK_RECORD"); |
| writeString(5, toHexStr(++entCount)); |
|
|
| m_writingContext.blockMap[name] = entCount; |
| entCount = 2+entCount; |
| if (afterAC1014) { |
| writeString(330, "1"); |
| } |
| writeSymTypeRecord("Block"); |
| writeUtf8String(2, name); |
| if (afterAC1018) { |
| |
| writeInt16(70, 0); |
| writeInt16(280, 1); |
| writeInt16(281, 0); |
| } |
| } |
| return true; |
| } |
|
|
| bool dxfRW::writeBlock(DRW_Block *bk){ |
| if (writingBlock) { |
| writeName("ENDBLK"); |
| if (afterAC1009) { |
| writeString(5, toHexStr(currHandle+2)); |
| if (afterAC1014) { |
| writeString(330, toHexStr(currHandle)); |
| } |
| writeSubClass("Entity"); |
| } |
| writeString(8, "0"); |
| writeSubClassOpt("BlockEnd"); |
| } |
| writingBlock = true; |
| writeName("BLOCK"); |
| if (afterAC1009) { |
| currHandle = (*(m_writingContext.blockMap.find(bk->name))).second; |
| writeString(5, toHexStr(currHandle+1)); |
| if (afterAC1014) { |
| writeString(330, toHexStr(currHandle)); |
| } |
| writeSubClass("Entity"); |
| } |
| writeString(8, "0"); |
| if (afterAC1009) { |
| writeSubClass("BlockBegin"); |
| writeUtf8String(2, bk->name); |
| } else { |
| writeUtf8Caps(2, bk->name); |
| } |
| writeInt16(70, bk->flags); |
| writeCoord(10, bk->basePoint); |
|
|
| if (afterAC1009) { |
| writeUtf8String(3, bk->name); |
| } |
| else { |
| writeUtf8Caps(3, bk->name); |
| } |
| if(afterAC1014) { |
| writeAppData(bk->appData); |
| } |
| writeString(1, ""); |
| return true; |
| } |
|
|
| void dxfRW::writeViewPortTable() { |
| writeTableStart("VPORT", "8", 1); |
| dimstyleStd =false; |
| iface->writeVports(); |
| if (!dimstyleStd) { |
| DRW_Vport portact; |
| portact.name = "*ACTIVE"; |
| writeVport(&portact); |
| } |
| writeTableEnd(); |
| } |
|
|
| void dxfRW::writeLayerTable() { |
| writeTableStart("LAYER", "2", 1); |
| wlayer0 = false; |
| iface->writeLayers(); |
| if (!wlayer0) { |
| DRW_Layer lay0; |
| lay0.name = "0"; |
| writeLayer(&lay0); |
| } |
| writeTableEnd(); |
| } |
|
|
| void dxfRW::writeLineTypeTable() { |
| writeTableStart("LTYPE", "5", 4); |
| |
| DRW_LType lt; |
| lt.reset(); |
| lt.name = "ByBlock"; |
| writeLineTypeGenerics(<, 20); |
| writeInt16(70, 0); |
| writeString(3, ""); |
| writeInt16(72, 65); |
| writeInt16(73, 0); |
| writeDouble(40, 0.0); |
|
|
| lt.name = "ByLayer"; |
| writeLineTypeGenerics(<, 21); |
|
|
| writeInt16(70, 0); |
| writeString(3, ""); |
| writeInt16(72, 65); |
| writeInt16(73, 0); |
| writeDouble(40, 0.0); |
|
|
| lt.name = "Continuous"; |
| writeLineTypeGenerics(<, 22); |
|
|
| writeInt16(70, 0); |
| writeString(3, "Solid line"); |
| writeInt16(72, 65); |
| writeInt16(73, 0); |
| writeDouble(40, 0.0); |
| |
| iface->writeLTypes(); |
| writeTableEnd(); |
| } |
|
|
| void dxfRW::writeStyleTable() { |
| writeTableStart("STYLE", "3", 3); |
| dimstyleStd =false; |
| iface->writeTextstyles(); |
| if (!dimstyleStd) { |
| DRW_Textstyle tsty; |
| tsty.name = "Standard"; |
| writeTextstyle(&tsty); |
| } |
| writeTableEnd(); |
| } |
|
|
| void dxfRW::writeUCSTable() { |
| writeTableStart("UCS", "7", 0); |
| iface->writeUCSs(); |
| writeTableEnd(); |
| } |
|
|
| void dxfRW::writeViewTable() { |
| writeTableStart("VIEW", "6", 0); |
| iface->writeViews(); |
| writeTableEnd(); |
| } |
|
|
| void dxfRW::writeAppIdTable() { |
| writeTableStart("APPID", "9", 1); |
| writeName("APPID"); |
| if (afterAC1009) { |
| writeString(5, "12"); |
| if (afterAC1014) { |
| writeString(330, "9"); |
| } |
| writeSymTypeRecord("RegApp"); |
| } |
| writeString(2, "ACAD"); |
| writeInt16(70, 0); |
| iface->writeAppId(); |
| writeTableEnd(); |
| } |
|
|
| void dxfRW::writeBlockRecordTable() { |
| if (afterAC1009) { |
| writeTableName("BLOCK_RECORD"); |
| writeString(5, "1"); |
| if (afterAC1014) { |
| writeString(330, "0"); |
| } |
| writeSymTable(); |
| writeInt16(70, 2); |
| writeName("BLOCK_RECORD"); |
| writeString(5, "1F"); |
| if (afterAC1014) { |
| writeString(330, "1"); |
| } |
| writeSymTypeRecord("Block"); |
| writeString(2, "*Model_Space"); |
| if (afterAC1018) { |
| |
| writeInt16(70, 0); |
| writeInt16(280, 1); |
| writeInt16(281, 0); |
| } |
| writeName("BLOCK_RECORD"); |
| writeString(5, "1E"); |
| if (afterAC1014) { |
| writeString(330, "1"); |
| } |
|
|
| writeSymTypeRecord("Block"); |
| writeString(2, "*Paper_Space"); |
| if (afterAC1018) { |
| |
| writeInt16(70, 0); |
| writeInt16(280, 1); |
| writeInt16(281, 0); |
| } |
| } |
| |
| iface->writeBlockRecords(); |
| if (afterAC1009) { |
| writeTableEnd(); |
| } |
| } |
|
|
| void dxfRW::writeDimStyleTable() { |
| writeTableStart("DIMSTYLE", "A", 1); |
| if (afterAC1014) { |
| writeSubClass("DimStyleTable"); |
| writeInt16(71, 1); |
| } |
|
|
| |
| iface->writeDimstyles(); |
| writeTableEnd(); |
| } |
|
|
| bool dxfRW::writeTables() { |
| writeViewPortTable(); |
| writeLineTypeTable(); |
| writeLayerTable(); |
| writeStyleTable(); |
| writeUCSTable(); |
| writeViewTable(); |
| writeAppIdTable(); |
| writeBlockRecordTable(); |
| writeDimStyleTable(); |
| return true; |
| } |
|
|
| bool dxfRW::writeBlocks() { |
| writeName("BLOCK"); |
| if (afterAC1009) { |
| writeString(5, "20"); |
| if (afterAC1014) { |
| writeString(330, "1F"); |
| } |
| writeSubClass("Entity"); |
| } |
| writeString(8, "0"); |
| if (afterAC1009) { |
| writeSubClass("BlockBegin"); |
| writeString(2, "*Model_Space"); |
| } else |
| writeString(2, "$MODEL_SPACE"); |
| writeInt16(70, 0); |
| writeDouble(10, 0.0); |
| writeDouble(20, 0.0); |
| writeDouble(30, 0.0); |
| if (afterAC1009) |
| writeString(3, "*Model_Space"); |
| else |
| writeString(3, "$MODEL_SPACE"); |
| writeString(1, ""); |
| writeName("ENDBLK"); |
| if (afterAC1009) { |
| writeString(5, "21"); |
| if (afterAC1014) { |
| writeString(330, "1F"); |
| } |
| writeSubClass("Entity"); |
| } |
| writeString(8, "0"); |
| if (afterAC1009) |
| writeSubClass("BlockEnd"); |
|
|
| writeName("BLOCK"); |
| if (afterAC1009) { |
| writeString(5, "1C"); |
| if (afterAC1014) { |
| writeString(330, "1B"); |
| } |
| writeSubClass("Entity"); |
| } |
| writeString(8, "0"); |
| if (afterAC1009) { |
| writeSubClass("BlockBegin"); |
| writeString(2, "*Paper_Space"); |
| } else |
| writeString(2, "$PAPER_SPACE"); |
| writeInt16(70, 0); |
| writeDouble(10, 0.0); |
| writeDouble(20, 0.0); |
| writeDouble(30, 0.0); |
| if (afterAC1009) |
| writeString(3, "*Paper_Space"); |
| else |
| writeString(3, "$PAPER_SPACE"); |
| writeString(1, ""); |
| writeName( "ENDBLK"); |
| if (afterAC1009) { |
| writeString(5, "1D"); |
| if (afterAC1014) { |
| writeString(330, "1F"); |
| } |
| writeSubClass("Entity"); |
| } |
| writeString(8, "0"); |
| if (afterAC1009) |
| writeSubClass("BlockEnd"); |
| writingBlock = false; |
| iface->writeBlocks(); |
| if (writingBlock) { |
| writingBlock = false; |
| writeName( "ENDBLK"); |
| if (afterAC1009) { |
| writeString(5, toHexStr(currHandle+2)); |
| |
| if (afterAC1014) { |
| writeString(330, toHexStr(currHandle)); |
| } |
| writeSubClass("Entity"); |
| } |
| writeString(8, "0"); |
| if (afterAC1009) |
| writeSubClass("BlockEnd"); |
| } |
| return true; |
| } |
|
|
| bool dxfRW::writeObjects() { |
| writeName("DICTIONARY"); |
| std::string imgDictH; |
| writeString(5, "C"); |
| if (afterAC1014) { |
| writeString(330, "0"); |
| } |
| writeSubClass("Dictionary"); |
| writeInt16(281, 1); |
| writeString(3, "ACAD_GROUP"); |
| writeString(350, "D"); |
| if (!imageDef.empty()) { |
| writeString(3, "ACAD_IMAGE_DICT"); |
| imgDictH = toHexStr(++entCount); |
| writeString(350, imgDictH); |
| } |
| writeName("DICTIONARY"); |
| writeString(5, "D"); |
| writeString(330, "C"); |
| writeSubClass("Dictionary"); |
| writeInt16(281, 1); |
| |
| for (unsigned int i=0; i<imageDef.size(); i++) { |
| DRW_ImageDef *id = imageDef.at(i); |
| for (auto it=id->reactors.begin() ; it != id->reactors.end(); ++it ) { |
| writeName( "IMAGEDEF_REACTOR"); |
| writeString(5, (*it).first); |
| writeString(330, (*it).second); |
| writeSubClass("RasterImageDefReactor"); |
| writeInt16(90, 2); |
| writeString(330, (*it).second); |
| } |
| } |
| if (!imageDef.empty()) { |
| writeName("DICTIONARY"); |
| writeString(5, imgDictH); |
| writeString(330, "C"); |
| writeSubClass("Dictionary"); |
| writeInt16(281, 1); |
| for (unsigned int i=0; i<imageDef.size(); i++) { |
| size_t f1, f2; |
| f1 = imageDef.at(i)->name.find_last_of("/\\"); |
| f2 =imageDef.at(i)->name.find_last_of('.'); |
| ++f1; |
| writeString(3, imageDef.at(i)->name.substr(f1,f2-f1)); |
| writeString(350, toHexStr(imageDef.at(i)->handle) ); |
| } |
| } |
| for (unsigned int i=0; i<imageDef.size(); i++) { |
| DRW_ImageDef *id = imageDef.at(i); |
| writeName("IMAGEDEF"); |
| writeString(5, toHexStr(id->handle) ); |
| if (afterAC1014) { |
| |
| } |
| writeString(102, "{ACAD_REACTORS"); |
| for (auto it=id->reactors.begin() ; it != id->reactors.end(); ++it ) { |
| writeString(330, (*it).first); |
| } |
| writeString(102, "}"); |
| writeSubClass("RasterImageDef"); |
| writeInt16(90, 0); |
| writeUtf8String(1, id->name); |
| writeDouble(10, id->u); |
| writeDouble(20, id->v); |
| writeDouble(11, id->up); |
| writeDouble(21, id->vp); |
| writeInt16(280, id->loaded); |
| writeInt16(281, id->resolution); |
| } |
| |
| while (!imageDef.empty()) { |
| imageDef.pop_back(); |
| } |
|
|
| iface->writeObjects(); |
|
|
| return true; |
| } |
|
|
| bool dxfRW::writeExtData(const std::vector<DRW_Variant*> &ed){ |
| for (auto it=ed.begin(); it!=ed.end(); ++it){ |
| switch ((*it)->code()) { |
| case 1000: |
| case 1001: |
| case 1002: |
| case 1003: |
| case 1004: |
| case 1005: { |
| int cc = (*it)->code(); |
| if ((*it)->type() == DRW_Variant::STRING) |
| writeUtf8String(cc, *(*it)->content.s); |
| |
| break; |
| } |
| case 1010: |
| case 1011: |
| case 1012: |
| case 1013: |
| if ((*it)->type() == DRW_Variant::COORD) { |
| writeDouble((*it)->code(), (*it)->content.v->x); |
| writeDouble((*it)->code() + 10, (*it)->content.v->y); |
| writeDouble((*it)->code() + 20, (*it)->content.v->z); |
| } |
| break; |
| case 1040: |
| case 1041: |
| case 1042: |
| if ((*it)->type() == DRW_Variant::DOUBLE) |
| writeDouble((*it)->code(), (*it)->content.d); |
| break; |
| case 1070: |
| if ((*it)->type() == DRW_Variant::INTEGER) |
| writeInt16((*it)->code(), (*it)->content.i); |
| break; |
| case 1071: |
| if ((*it)->type() == DRW_Variant::INTEGER) |
| writeInt32((*it)->code(), (*it)->content.i); |
| break; |
| default: |
| break; |
| } |
| } |
| return true; |
| } |
|
|
| |
|
|
| bool dxfRW::processDxf() { |
| DRW_DBG("dxfRW::processDxf() start processing dxf\n"); |
| int code {-1}; |
| bool inSection {false}; |
|
|
| reader->setIgnoreComments( false); |
| while (readRec(&code)) { |
| DRW_DBG(code); DRW_DBG(" code\n"); |
| |
| |
| |
| |
| |
| |
| switch (code) { |
| case 999: { |
| |
| header.addComment(getString()); |
| continue; |
| } |
| case 0: { |
| |
| reader->setIgnoreComments(true); |
| if (!inSection) { |
| std::string sectionstr{getString()}; |
|
|
| if ("SECTION" == sectionstr) { |
| DRW_DBG(sectionstr); |
| DRW_DBG(" new section\n"); |
| inSection = true; |
| continue; |
| } |
| if ("EOF" == sectionstr) { |
| return true; |
| } |
| } |
| else { |
| |
| if ("ENDSEC" == getString()) { |
| inSection = false; |
| } |
| } |
| break; |
| } |
| case 2: { |
| if (inSection) { |
| bool processed{false}; |
| std::string sectionname{getString()}; |
|
|
| DRW_DBG(sectionname); |
| DRW_DBG(" process section\n"); |
| if ("HEADER" == sectionname) { |
| processed = processHeader(); |
| } |
| else if ("TABLES" == sectionname) { |
| processed = processTables(); |
| } |
| else if ("BLOCKS" == sectionname) { |
| processed = processBlocks(); |
| } |
| else if ("ENTITIES" == sectionname) { |
| processed = processEntities(false); |
| } |
| else if ("OBJECTS" == sectionname) { |
| processed = processObjects(); |
| } |
| else { |
| |
|
|
| DRW_DBG(sectionname); |
| DRW_DBG(" section unknown or not supported\n"); |
| continue; |
| } |
|
|
| if (!processed) { |
| DRW_DBG(" failed\n"); |
| return setError(DRW::BAD_READ_SECTION); |
| } |
|
|
| inSection = false; |
| } |
| continue; |
| } |
| default: |
| |
| inSection = false; |
| break; |
| } |
| } |
|
|
| if (0 == code && "EOF" == getString()) { |
| |
| |
| return true; |
| } |
|
|
| return setError(DRW::BAD_UNKNOWN); |
| } |
|
|
| |
|
|
| bool dxfRW::processHeader() { |
| DRW_DBG("dxfRW::processHeader\n"); |
| int code; |
| std::string sectionstr; |
| while (readRec(&code)) { |
| DRW_DBG(code); DRW_DBG(" processHeader\n"); |
| if (code == 0) { |
| sectionstr = getString(); |
| DRW_DBG(sectionstr); DRW_DBG(" processHeader\n\n"); |
| if (sectionstr == "ENDSEC") { |
| iface->addHeader(&header); |
| return true; |
| } |
|
|
| DRW_DBG("unexpected 0 code in header!\n"); |
| return setError(DRW::BAD_READ_HEADER); |
| } |
|
|
| if (!header.parseCode(code, reader)) { |
| return setError( DRW::BAD_CODE_PARSED); |
| } |
| } |
| return setError(DRW::BAD_READ_HEADER); |
| } |
|
|
| |
|
|
| bool dxfRW::processTables() { |
| DRW_DBG("dxfRW::processTables\n"); |
| int code; |
| std::string sectionstr; |
| bool more = true; |
|
|
| std::vector<DRW_Dimstyle> dimstyles; |
|
|
|
|
| while (readRec(&code)) { |
| DRW_DBG(code); DRW_DBG("\n"); |
| if (code == 0) { |
| sectionstr = getString(); |
| DRW_DBG(sectionstr); DRW_DBG(" processTables\n\n"); |
| if (sectionstr == "TABLE") { |
| more = readRec(&code); |
| DRW_DBG(code); DRW_DBG("\n"); |
| if (!more) { |
| return setError(DRW::BAD_READ_TABLES); |
| } |
| if (code == 2) { |
| sectionstr = getString(); |
| DRW_DBG(sectionstr); DRW_DBG(" processTables\n\n"); |
| |
| if (sectionstr == "LTYPE") { |
| processLType(); |
| } else if (sectionstr == "LAYER") { |
| processLayer(); |
| } else if (sectionstr == "STYLE") { |
| processTextStyle(); |
| } else if (sectionstr == "VPORT") { |
| processVports(); |
| } else if (sectionstr == "VIEW") { |
| processView(); |
| } else if (sectionstr == "UCS") { |
| processUCS(); |
| } else if (sectionstr == "APPID") { |
| processAppId(); |
| } else if (sectionstr == "DIMSTYLE") { |
| processDimStyle(dimstyles); |
| } else if (sectionstr == "BLOCK_RECORD") { |
| processBlockRecord(); |
| } |
| } |
| } else if (sectionstr == "ENDSEC") { |
| for (auto it=dimstyles.begin(); it!=dimstyles.end(); ++it) { |
| it->resolveRefs(m_readingContext); |
| iface->addDimStyle(*it); |
| } |
|
|
| return true; |
| } |
| } |
| } |
|
|
| return setError(DRW::BAD_READ_TABLES); |
| } |
|
|
| bool dxfRW::processBlockRecord() { |
| DRW_DBG("dxfRW::processBlockRecord"); |
| DRW_Block_Record blockRecord; |
| return doProcessTableEntry("BLOCK_RECORD", blockRecord, [this](DRW_TableEntry* r){ |
| auto br = static_cast<DRW_Block_Record*>(r); |
| duint32 handle = br->handle; |
| m_readingContext.blockRecordMap[handle] = br; |
| }, false); |
| } |
|
|
| bool dxfRW::processUCS(){ |
| DRW_DBG("dxfRW::processUCS\n"); |
| DRW_UCS ucs; |
| return doProcessTableEntry("UCS", ucs, [this](DRW_TableEntry* e){ |
| auto ent = static_cast<DRW_UCS*>(e); |
| iface->addUCS(*ent); |
| }); |
| } |
|
|
| bool dxfRW::processView() { |
| DRW_DBG("dxfRW::processView\n"); |
| DRW_View view; |
| return doProcessTableEntry("VIEW", view, [this](DRW_TableEntry* e){ |
| auto ent = static_cast<DRW_View*>(e); |
| iface->addView(*ent); |
| }); |
| } |
|
|
| bool dxfRW::processLType() { |
| DRW_DBG("dxfRW::processLType\n"); |
| DRW_LType ltype; |
| return doProcessTableEntry("LTYPE", ltype, [this](DRW_TableEntry* l){ |
| auto ltp = static_cast<DRW_LType*>(l); |
| ltp->update(); |
| int handle = ltp->handle; |
| m_readingContext.lineTypeMap[handle] = ltp; |
| iface->addLType(*ltp); |
| }, false); |
| } |
|
|
| bool dxfRW::processLayer() { |
| DRW_DBG("dxfRW::processLayer\n"); |
| DRW_Layer layer; |
| return doProcessTableEntry("LAYER", layer, [this](DRW_TableEntry* l){ |
| auto layer = static_cast<DRW_Layer*>(l); |
| iface->addLayer(*layer); |
| }); |
| } |
|
|
| bool dxfRW::processDimStyle(std::vector<DRW_Dimstyle>& styles) { |
| DRW_DBG("dxfRW::processDimStyle"); |
| DRW_Dimstyle dimSty; |
| return doProcessTableEntry("DIMSTYLE", dimSty, [&styles](DRW_TableEntry* e){ |
| auto ent = static_cast<DRW_Dimstyle*>(e); |
| styles.push_back(*ent); |
| }, false); |
| } |
|
|
| bool dxfRW::doProcessTableEntry(const std::string §ionName, DRW_TableEntry& startEntry, DRW_TableEntryFunc applyFunc, |
| bool reuseEntity) { |
| DRW_DBG("dxfRW::processLayer\n"); |
| int code; |
| std::string sectionstr; |
| bool reading = false; |
| DRW_TableEntry* entry; |
| if (reuseEntity) { |
| entry = &startEntry; |
| } |
| else { |
| entry = startEntry.newInstance(); |
| } |
| while (readRec(&code)) { |
| DRW_DBG(code); DRW_DBG("\n"); |
| if (code == 0) { |
| if (reading) { |
| applyFunc(entry); |
| } |
| sectionstr = getString(); |
| DRW_DBG(sectionstr); DRW_DBG("\n"); |
| if (sectionstr == sectionName) { |
| reading = true; |
| if (reuseEntity) { |
| entry->reset(); |
| } |
| else { |
| entry = entry->newInstance(); |
| } |
| } else if (sectionstr == "ENDTAB") { |
| return true; |
| } |
| } else if (reading) { |
| if (!entry->parseCode(code, reader)) { |
| if (!reuseEntity) { |
| delete entry; |
| } |
| return setError( DRW::BAD_CODE_PARSED); |
| } |
| } |
| } |
| return setError(DRW::BAD_READ_TABLES); |
| } |
|
|
| bool dxfRW::processTextStyle(){ |
| DRW_DBG("dxfRW::processTextStyle"); |
| int code; |
| std::string sectionstr; |
| bool reading = false; |
| auto* textStyle = new DRW_Textstyle; |
| while (readRec(&code)) { |
| DRW_DBG(code); DRW_DBG("\n"); |
| if (code == 0) { |
| if (reading) { |
| m_readingContext.textStyles[textStyle->handle] = textStyle; |
| iface->addTextStyle(*textStyle); |
| } |
| sectionstr = getString(); |
| DRW_DBG(sectionstr); DRW_DBG("\n"); |
| if (sectionstr == "STYLE") { |
| reading = true; |
| textStyle = new DRW_Textstyle(); |
| } else if (sectionstr == "ENDTAB") { |
| return true; |
| } |
| } else if (reading) { |
| if (!textStyle->parseCode(code, reader)) { |
| return setError( DRW::BAD_CODE_PARSED); |
| } |
| } |
| } |
|
|
| return setError(DRW::BAD_READ_TABLES); |
| } |
|
|
| bool dxfRW::processVports(){ |
| DRW_DBG("dxfRW::processVports"); |
| DRW_Vport vp; |
| return doProcessTableEntry("VPORT", vp, [this](DRW_TableEntry* e){ |
| auto ent = static_cast<DRW_Vport*>(e); |
| iface->addVport(*ent); |
| }); |
| } |
|
|
| bool dxfRW::processAppId(){ |
| DRW_DBG("dxfRW::processAppId"); |
| DRW_AppId vp; |
| return doProcessTableEntry("APPID", vp, [this](DRW_TableEntry* e){ |
| auto ent = static_cast<DRW_AppId*>(e); |
| iface->addAppId(*ent); |
| }); |
| } |
|
|
| |
|
|
| bool dxfRW::processBlocks() { |
| DRW_DBG("dxfRW::processBlocks\n"); |
| int code; |
| std::string sectionstr; |
| while (readRec(&code)) { |
| DRW_DBG(code); DRW_DBG("\n"); |
| if (code == 0) { |
| sectionstr = getString(); |
| DRW_DBG(sectionstr); DRW_DBG("\n"); |
| if (sectionstr == "BLOCK") { |
| processBlock(); |
| } else if (sectionstr == "ENDSEC") { |
| return true; |
| } |
| } |
| } |
|
|
| return setError(DRW::BAD_READ_BLOCKS); |
| } |
|
|
| bool dxfRW::processBlock() { |
| DRW_DBG("dxfRW::processBlock"); |
| DRW_Block block; |
| return doProcessParseable(block, [this](DRW_ParseableEntity* e) |
| { |
| auto ent = static_cast<DRW_Block*>(e); |
| iface->addBlock(*ent); |
| if (nextentity == "ENDBLK") { |
| iface->endBlock(); |
| } else { |
| processEntities(true); |
| iface->endBlock(); |
| } |
| },DRW::BAD_READ_BLOCKS); |
| } |
|
|
| |
|
|
| bool dxfRW::processEntities(bool isblock) { |
| DRW_DBG("dxfRW::processEntities\n"); |
| int code; |
| if (!readRec(&code)){ |
| return setError(DRW::BAD_READ_ENTITIES); |
| } |
|
|
| if (code == 0) { |
| nextentity = getString(); |
| } else if (!isblock) { |
| return setError(DRW::BAD_READ_ENTITIES); |
| } |
|
|
| bool processed {false}; |
| do { |
| if (nextentity == "ENDSEC" || nextentity == "ENDBLK") { |
| return true; |
| } |
| if (nextentity == "LINE") { |
| processed = processLine(); |
| } else if (nextentity == "CIRCLE") { |
| processed = processCircle(); |
| } else if (nextentity == "ARC") { |
| processed = processArc(); |
| } else if (nextentity == "POINT") { |
| processed = processPoint(); |
| } else if (nextentity == "LWPOLYLINE") { |
| processed = processLWPolyline(); |
| } else if (nextentity == "POLYLINE") { |
| processed = processPolyline(); |
| }else if (nextentity == "TEXT") { |
| processed = processText(); |
| } else if (nextentity == "MTEXT") { |
| processed = processMText(); |
| } else if (nextentity == "HATCH") { |
| processed = processHatch(); |
| } else if (nextentity == "DIMENSION") { |
| processed = processDimension(); |
| } else if (nextentity == "INSERT") { |
| processed = processInsert(); |
| } else if (nextentity == "TOLERANCE") { |
| processed = processTolerance(); |
| } else if (nextentity == "SOLID") { |
| processed = processSolid(); |
| }else if (nextentity == "SPLINE") { |
| processed = processSpline(); |
| }else if (nextentity == "LEADER") { |
| processed = processLeader(); |
| } else if (nextentity == "ELLIPSE") { |
| processed = processEllipse(); |
| } else if (nextentity == "VIEWPORT") { |
| processed = processViewport(); |
| } else if (nextentity == "IMAGE") { |
| processed = processImage(); |
| } else if (nextentity == "TRACE") { |
| processed = processTrace(); |
| } else if (nextentity == "3DFACE") { |
| processed = process3dface(); |
| } else if (nextentity == "RAY") { |
| processed = processRay(); |
| } else if (nextentity == "XLINE") { |
| processed = processXline(); |
| } else if (nextentity == "ARC_DIMENSION") { |
| processed = processArcDimension(); |
| } else { |
| if (!readRec(&code)) { |
| return setError(DRW::BAD_READ_ENTITIES); |
| } |
| if (code == 0) { |
| nextentity = getString(); |
| } |
| processed = true; |
| } |
| } while (processed); |
|
|
| return setError(DRW::BAD_READ_ENTITIES); |
| } |
|
|
| bool dxfRW::doProcessEntity(DRW_Entity& ent, DRW_EntityFunc applyFunc) { |
| int code; |
| while (readRec(&code)) { |
| DRW_DBG(code); DRW_DBG("\n"); |
| if (0 == code) { |
| nextentity = getString(); |
| DRW_DBG(nextentity); DRW_DBG("\n"); |
| if (applyExt) { |
| ent.applyExtrusion(); |
| } |
| applyFunc(&ent); |
| return true; |
| } |
| if (!ent.parseCode(code, reader)) { |
| return setError( DRW::BAD_CODE_PARSED); |
| } |
| } |
| return setError(DRW::BAD_READ_ENTITIES); |
| } |
|
|
| bool dxfRW::doProcessParseable(DRW_ParseableEntity &ent, DRW_ParseableFunc applyFunc, const DRW::error sectionError) { |
| int code; |
| while (readRec(&code)) { |
| DRW_DBG(code); DRW_DBG("\n"); |
| if (0 == code) { |
| nextentity = getString(); |
| DRW_DBG(nextentity); DRW_DBG("\n"); |
| applyFunc(&ent); |
| return true; |
| } |
| if (!ent.parseCode(code, reader)) { |
| return setError( DRW::BAD_CODE_PARSED); |
| } |
| } |
| return setError(sectionError); |
| } |
|
|
| bool dxfRW::processEllipse() { |
| DRW_DBG("dxfRW::processEllipse"); |
| DRW_Ellipse ellipse; |
| return doProcessEntity(ellipse, [this](DRW_Entity* e){ |
| auto ent = static_cast<DRW_Ellipse*>(e); |
| iface->addEllipse(*ent); |
| }); |
| } |
|
|
| bool dxfRW::processTrace() { |
| DRW_DBG("dxfRW::processTrace"); |
| DRW_Trace trace; |
| return doProcessEntity(trace,[this](DRW_Entity* e){ |
| auto ent = static_cast<DRW_Trace*>(e); |
| iface->addTrace(*ent); |
| }); |
| } |
|
|
| bool dxfRW::processSolid() { |
| DRW_DBG("dxfRW::processSolid"); |
| DRW_Solid solid; |
| return doProcessEntity(solid,[this](DRW_Entity* e){ |
| auto ent = static_cast<DRW_Solid*>(e); |
| iface->addSolid(*ent); |
| }); |
| } |
|
|
| bool dxfRW::process3dface() { |
| DRW_DBG("dxfRW::process3dface"); |
| DRW_3Dface face; |
| return doProcessParseable(face,[this](DRW_ParseableEntity* e){ |
| auto ent = static_cast<DRW_3Dface*>(e); |
| iface->add3dFace(*ent); |
| }); |
| } |
|
|
| bool dxfRW::processViewport() { |
| DRW_DBG("dxfRW::processViewport"); |
| DRW_Viewport vp; |
| return doProcessParseable(vp,[this](DRW_ParseableEntity* e){ |
| auto ent = static_cast<DRW_Viewport*>(e); |
| iface->addViewport(*ent); |
| }); |
| } |
|
|
| bool dxfRW::processPoint() { |
| DRW_DBG("dxfRW::processPoint\n"); |
| DRW_Point point; |
| return doProcessParseable(point,[this](DRW_ParseableEntity* e){ |
| auto ent = static_cast<DRW_Point*>(e); |
| iface->addPoint(*ent); |
| }); |
| } |
|
|
| bool dxfRW::processLine() { |
| DRW_DBG("dxfRW::processLine\n"); |
| DRW_Line line; |
| return doProcessParseable(line, [this](DRW_ParseableEntity* e){ |
| auto ent = static_cast<DRW_Line*>(e); |
| iface->addLine(*ent); |
| }); |
| } |
|
|
| bool dxfRW::processRay() { |
| DRW_DBG("dxfRW::processRay\n"); |
| DRW_Ray line; |
| return doProcessParseable(line,[this](DRW_ParseableEntity* e){ |
| auto ent = static_cast<DRW_Ray*>(e); |
| iface->addRay(*ent); |
| }); |
| } |
|
|
| bool dxfRW::processXline() { |
| DRW_DBG("dxfRW::processXline\n"); |
| DRW_Xline line; |
| return doProcessParseable(line,[this](DRW_ParseableEntity* e){ |
| auto ent = static_cast<DRW_Xline*>(e); |
| iface->addXline(*ent); |
| }); |
| } |
|
|
| bool dxfRW::processCircle() { |
| DRW_DBG("dxfRW::processPoint\n"); |
| DRW_Circle circle; |
| return doProcessEntity(circle, [this](DRW_Entity* e){ |
| auto ent = static_cast<DRW_Circle*>(e); |
| iface->addCircle(*ent); |
| }); |
| } |
|
|
| bool dxfRW::processArc() { |
| DRW_DBG("dxfRW::processPoint\n"); |
| DRW_Arc arc; |
| return doProcessEntity(arc, [this](DRW_Entity* e){ |
| auto ent = static_cast<DRW_Arc*>(e); |
| iface->addArc(*ent); |
| }); |
| } |
|
|
| bool dxfRW::processInsert() { |
| DRW_DBG("dxfRW::processInsert"); |
| DRW_Insert insert; |
| return doProcessParseable(insert,[this](DRW_ParseableEntity* e){ |
| auto ent = static_cast<DRW_Insert*>(e); |
| iface->addInsert(*ent); |
| }); |
| } |
|
|
| bool dxfRW::processLWPolyline() { |
| DRW_DBG("dxfRW::processLWPolyline"); |
| DRW_LWPolyline pl; |
| return doProcessEntity(pl, [this](DRW_Entity* e){ |
| auto ent = static_cast<DRW_LWPolyline*>(e); |
| iface->addLWPolyline(*ent); |
| }); |
| } |
|
|
| bool dxfRW::processPolyline() { |
| DRW_DBG("dxfRW::processPolyline"); |
| int code; |
| DRW_Polyline pl; |
| while (readRec(&code)) { |
| DRW_DBG(code); DRW_DBG("\n"); |
| if (0 == code) { |
| nextentity = getString(); |
| DRW_DBG(nextentity); DRW_DBG("\n"); |
| if (nextentity != "VERTEX") { |
| iface->addPolyline(pl); |
| return true; |
| } |
| if (!processVertex(&pl)) { |
| return false; |
| }; |
| } |
|
|
| if (!pl.parseCode(code, reader)) { |
| return setError(DRW::BAD_CODE_PARSED); |
| } |
| } |
|
|
| return setError(DRW::BAD_READ_ENTITIES); |
| } |
|
|
| bool dxfRW::processVertex(DRW_Polyline *pl) { |
| DRW_DBG("dxfRW::processVertex"); |
| int code; |
| auto v = std::make_shared<DRW_Vertex>(); |
| while (readRec(&code)) { |
| DRW_DBG(code); DRW_DBG("\n"); |
| if(0 == code) { |
| pl->appendVertex(v); |
| nextentity = getString(); |
| DRW_DBG(nextentity); DRW_DBG("\n"); |
| if (nextentity == "SEQEND") { |
| return true; |
| } |
| if (nextentity == "VERTEX"){ |
| v = std::make_shared<DRW_Vertex>(); |
| } |
| } |
|
|
| if (!v->parseCode(code, reader)) { |
| return setError(DRW::BAD_CODE_PARSED); |
| } |
| } |
|
|
| return setError(DRW::BAD_READ_ENTITIES); |
| } |
|
|
| bool dxfRW::processTolerance() { |
| DRW_DBG("dxfRW::processTolerance\n"); |
| DRW_Tolerance tol; |
| return doProcessParseable(tol,[this](DRW_ParseableEntity* e){ |
| auto ent = static_cast<DRW_Tolerance*>(e); |
| iface->addTolerance(*ent); |
| }); |
| } |
|
|
| bool dxfRW::processText() { |
| DRW_DBG("dxfRW::processText"); |
| DRW_Text txt; |
| return doProcessParseable(txt,[this](DRW_ParseableEntity* e){ |
| auto ent = static_cast<DRW_Text*>(e); |
| iface->addText(*ent); |
| }); |
| } |
|
|
| bool dxfRW::processMText() { |
| DRW_DBG("dxfRW::processMText"); |
| DRW_MText txt; |
| return doProcessParseable(txt,[this](DRW_ParseableEntity* e){ |
| auto ent = static_cast<DRW_MText*>(e); |
| ent->updateAngle(); |
| iface->addMText(*ent); |
| }); |
| } |
|
|
| bool dxfRW::processHatch() { |
| DRW_DBG("dxfRW::processHatch"); |
| DRW_Hatch hatch; |
| return doProcessParseable(hatch,[this](DRW_ParseableEntity* e){ |
| auto ent = static_cast<DRW_Hatch*>(e); |
| iface->addHatch(ent); |
| }); |
| } |
|
|
| bool dxfRW::processSpline() { |
| DRW_DBG("dxfRW::processSpline"); |
| DRW_Spline sp; |
| return doProcessParseable(sp,[this](DRW_ParseableEntity* e){ |
| auto ent = static_cast<DRW_Spline*>(e); |
| iface->addSpline(ent); |
| }); |
| } |
|
|
| bool dxfRW::processImage() { |
| DRW_DBG("dxfRW::processImage"); |
| DRW_Image img; |
| return doProcessParseable(img,[this](DRW_ParseableEntity* e){ |
| auto ent = static_cast<DRW_Image*>(e); |
| iface->addImage(ent); |
| }); |
| } |
|
|
| bool dxfRW::processArcDimension() { |
| DRW_DBG("dxfRW::processArcDimension"); |
| int code; |
| DRW_ArcDimension dim; |
| while (readRec(&code)) { |
| DRW_DBG(code); DRW_DBG("\n"); |
| if (0 == code) { |
| nextentity = getString(); |
| DRW_DBG(nextentity); DRW_DBG("\n"); |
| |
| |
| return true; |
| } |
|
|
| if (!dim.parseCode(code, reader)) { |
| return setError( DRW::BAD_CODE_PARSED); |
| } |
| } |
| return setError(DRW::BAD_READ_ENTITIES); |
| } |
|
|
| bool dxfRW::processDimension() { |
| DRW_DBG("dxfRW::processDimension"); |
| DRW_Dimension dim; |
| return doProcessParseable(dim,[this](DRW_ParseableEntity* e){ |
| auto ent = static_cast<DRW_Dimension*>(e); |
| int type = ent->type & 0x0F; |
| switch (type) { |
| case 0: { |
| DRW_DimLinear d(*ent); |
| iface->addDimLinear(&d); |
| break; |
| } |
| case 1: { |
| DRW_DimAligned d(*ent); |
| iface->addDimAlign(&d); |
| break; |
| } |
| case 2: { |
| DRW_DimAngular d(*ent); |
| iface->addDimAngular(&d); |
| break; |
| } |
| case 3: { |
| DRW_DimDiametric d(*ent); |
| iface->addDimDiametric(&d); |
| break; |
| } |
| case 4: { |
| DRW_DimRadial d(*ent); |
| iface->addDimRadial(&d); |
| break; |
| } |
| case 5: { |
| DRW_DimAngular3p d(*ent); |
| iface->addDimAngular3P(&d); |
| break; |
| } |
| case 6: { |
| DRW_DimOrdinate d(*ent); |
| iface->addDimOrdinate(&d); |
| break; |
| } |
| default: |
| break; |
| } |
| }); |
| } |
|
|
| bool dxfRW::processLeader() { |
| DRW_DBG("dxfRW::processLeader"); |
| DRW_Leader leader; |
| return doProcessParseable(leader,[this](DRW_ParseableEntity* e){ |
| auto ent = static_cast<DRW_Leader*>(e); |
| iface->addLeader(ent); |
| return true; |
| }); |
| } |
|
|
| |
|
|
| bool dxfRW::processObjects() { |
| DRW_DBG("dxfRW::processObjects\n"); |
| int code; |
| if (!readRec(&code) || 0 != code){ |
| return setError(DRW::BAD_READ_OBJECTS); |
| } |
|
|
| bool processed {false}; |
| nextentity = getString(); |
| do { |
| if ("ENDSEC" == nextentity) { |
| return true; |
| } |
| if ("IMAGEDEF" == nextentity) { |
| processed = processImageDef(); |
| } |
| else if ("PLOTSETTINGS" == nextentity) { |
| processed = processPlotSettings(); |
| } |
| else { |
| if (!readRec(&code)) { |
| return setError(DRW::BAD_READ_OBJECTS); |
| } |
| if (code == 0) { |
| nextentity = getString(); |
| } |
| processed = true; |
| } |
| } |
| while (processed); |
|
|
| return setError(DRW::BAD_READ_OBJECTS); |
| } |
|
|
| bool dxfRW::processImageDef() { |
| DRW_DBG("dxfRW::processImageDef"); |
| DRW_ImageDef img; |
| return doProcessParseable(img,[this](DRW_ParseableEntity* e){ |
| auto ent = static_cast<DRW_ImageDef*>(e); |
| iface->linkImage(ent); |
| }); |
| } |
|
|
| bool dxfRW::processPlotSettings() { |
| DRW_DBG("dxfRW::processPlotSettings"); |
| DRW_PlotSettings ps; |
| return doProcessParseable(ps,[this](DRW_ParseableEntity* e){ |
| auto ent = static_cast<DRW_PlotSettings*>(e); |
| iface->addPlotSettings(ent); |
| }); |
| } |
|
|
| bool dxfRW::writePlotSettings(DRW_PlotSettings *ent) { |
| writeName("PLOTSETTINGS"); |
| writeString(5, toHexStr(++entCount)); |
| writeSubClass("PlotSettings"); |
| writeUtf8String(6, ent->plotViewName); |
| writeDouble(40, ent->marginLeft); |
| writeDouble(41, ent->marginBottom); |
| writeDouble(42, ent->marginRight); |
| writeDouble(43, ent->marginTop); |
| return true; |
| } |
|
|
| |
| |
| |
| std::string dxfRW::toHexStr(int n){ |
| #if defined(__APPLE__) |
| char buffer[9]= {'\0'}; |
| snprintf(buffer,9, "%X", n); |
| return std::string(buffer); |
| #else |
| std::ostringstream Convert; |
| Convert << std::uppercase << std::hex << n; |
| return Convert.str(); |
| #endif |
| } |
|
|
| int dxfRW::getBlockRecordHandleToWrite(const std::string &blockName) const { |
| |
| |
| |
| |
| |
| |
|
|
| if(m_writingContext.blockMap.count(blockName) > 0) { |
| auto pair = m_writingContext.blockMap.find(blockName); |
| int blkHandle = pair->second; |
| return blkHandle; |
| } |
| return -1; |
| } |
|
|
| int dxfRW::getTextStyleHandle(const std::string &styleName) const { |
| if (!styleName.empty()) { |
| auto name = styleName; |
| std::transform(name.begin(), name.end(), name.begin(), toupper); |
| if(m_writingContext.textStyleMap.count(name) > 0) { |
| auto pair = m_writingContext.textStyleMap.find(name); |
| int blkHandle = pair->second; |
| return blkHandle; |
| } |
| } |
| return -1; |
| } |
|
|
| DRW::Version dxfRW::getVersion() const { |
| return version; |
| } |
|
|
| DRW::error dxfRW::getError() const{ |
| return error; |
| } |
|
|
| |
| bool dxfRW::setError(const DRW::error lastError){ |
| error = lastError; |
| return (DRW::BAD_NONE == error); |
| } |
|
|
| void dxfRW::setVersion(DRW::Version v) { |
| version = v; |
| afterAC1009 = v > DRW::AC1009; |
| afterAC1012 = v > DRW::AC1012; |
| afterAC1014 = v > DRW::AC1014; |
| afterAC1015 = v > DRW::AC1015; |
| afterAC1018 = v > DRW::AC1018; |
| } |
|
|
| bool dxfRW::writeString(int code, const std::string &text) { |
| return writer->writeString(code, text); |
| } |
|
|
| bool dxfRW::writeDouble(int code, double d) { |
| return writer->writeDouble(code, d); |
| } |
|
|
| bool dxfRW::writeDoubleOpt(int code, double d) { |
| if (d != 0.0) { |
| return writer->writeDouble(code, d); |
| } |
| return true; |
| } |
|
|
| bool dxfRW::writeUtf8String(int code, const std::string &text) { |
| return writer->writeUtf8String(code, text); |
| } |
|
|
| bool dxfRW::writeUtf8Caps(int code, const std::string &text) { |
| return writer->writeUtf8Caps(code, text); |
| } |
|
|
| bool dxfRW::writeHandle(int code, int handle) { |
| return writer->writeString(code, toHexStr(handle)); |
| } |
|
|
| bool dxfRW::writeInt16(int code, int val) { |
| return writer->writeInt16(code, val); |
| } |
|
|
| bool dxfRW::writeInt32(int code, int val) { |
| return writer->writeInt32(code, val); |
| } |
|
|
| bool dxfRW::writeBool(int code, bool val) { |
| return writer->writeBool(code, val); |
| } |
|
|
| bool dxfRW::readRec(int* codeData) { |
| return reader->readRec(codeData); |
| } |
|
|
| std::string dxfRW::getString() { |
| return reader->getString(); |
| } |
|
|
| void dxfRW::writeSectionStart(const std::string &name) { |
| writeString(0, "SECTION"); |
| writeString(2, name); |
| } |
|
|
| void dxfRW::writeSectionEnd() { |
| writeString(0, "ENDSEC"); |
| } |
|
|
| void dxfRW::writeSymTypeRecord(const std::string &typeName) { |
| writeString(100, "AcDbSymbolTableRecord"); |
| writeString(100, "AcDb"+typeName+"TableRecord"); |
| } |
|
|
| void dxfRW::writeSubClass(const std::string &typeName) { |
| writeString(100, "AcDb"+typeName); |
| } |
|
|
| void dxfRW::writeSubClassOpt(const std::string& name) { |
| if (afterAC1009) { |
| writeSubClass(name); |
| } |
| } |
|
|
| void dxfRW::writeTableStart(const std::string &name, const std::string handle, int maxEntriesNumber, int handleCode) { |
| writeTableName(name); |
| if (afterAC1009) { |
| writeString(handleCode, handle); |
| if (afterAC1014) { |
| writeString(330, "0"); |
| } |
| writeSymTable(); |
| } |
| writeInt16(70, maxEntriesNumber); |
| } |
|
|
| void dxfRW::writeTableName(const std::string &name) { |
| writeString(0, "TABLE"); |
| writeString(2, name); |
| } |
|
|
| void dxfRW::writeName(const std::string &name) { |
| writeString(0, name); |
| } |
|
|
| void dxfRW::writeTableEnd() { |
| writeString(0, "ENDTAB"); |
| } |
| void dxfRW::writeSymTable() { |
| writeString(100, "AcDbSymbolTable"); |
| } |
|
|
| void dxfRW::writeCoord(int startCode, const DRW_Coord& coord) { |
| writeDouble(startCode, coord.x); |
| writeDouble(startCode + 10, coord.y); |
| writeDoubleOpt(startCode + 20, coord.z); |
| } |
| |
| void dxfRW::writeVar( const std::string &name, double defaultValue, int varCode) { |
| double varDouble; |
| writeString(9, name); |
| if (header.getDouble(name, &varDouble)) { |
| writeDouble(varCode, varDouble); |
| } |
| else { |
| writeDouble(varCode, defaultValue); |
| } |
| } |
|
|
| |
| void dxfRW::writeVar( const std::string &name, int defaultValue, int varCode) { |
| int varInt; |
| writeString(9, name); |
| if (header.getInt(name, &varInt)) { |
| writeInt16(varCode, varInt); |
| } |
| else { |
| writeInt16(varCode, defaultValue); |
| } |
| } |
|
|
| void dxfRW::writeVarExp( const std::string &name, int value, int varCode) { |
| writeString(9, name); |
| writeInt16(varCode, value); |
| } |
|
|
| void dxfRW::writeVarOpt(const std::string& name, int varCode) { |
| int varInt; |
| if (header.getInt(name, &varInt)) { |
| writeString(9, name); |
| writeInt16(varCode, varInt); |
| } |
| } |
|
|
| |
| void dxfRW::writeVar(const std::string &name, const std::string &defaultValue, int varCode) { |
| std::string varStr; |
| writeString(9, name); |
| if (header.getStr(name, &varStr)) { |
| if (version == DRW::AC1009) { |
| writeUtf8Caps(varCode, varStr); |
| } |
| else { |
| writeUtf8String(varCode, varStr); |
| } |
| } |
| else { |
| writeString(varCode, defaultValue); |
| } |
| } |
|
|
| void dxfRW::writeVar(const std::string& name, int startCode,const DRW_Coord& defaultCoord) { |
| writer->writeString(9, name); |
| DRW_Coord varCoord; |
| if (header.getCoord(name, &varCoord)) { |
| writer->writeDouble(startCode, varCoord.x); |
| writer->writeDouble(startCode + 10, varCoord.y); |
| writer->writeDouble(startCode + 20, varCoord.z); |
| } else { |
| writer->writeDouble(startCode, defaultCoord.x); |
| writer->writeDouble(startCode + 10,defaultCoord.y); |
| writer->writeDouble(startCode + 20,defaultCoord.z); |
| } |
| } |
|
|
| void dxfRW::writeVar2D(const std::string& name, int startCode, const DRW_Coord& defaultCoord) { |
| writer->writeString(9, name); |
| DRW_Coord varCoord; |
| if (header.getCoord(name, &varCoord)) { |
| writer->writeDouble(startCode, varCoord.x); |
| writer->writeDouble(startCode + 10, varCoord.y); |
| } else { |
| writer->writeDouble(startCode, defaultCoord.x); |
| writer->writeDouble(startCode + 10,defaultCoord.y); |
| } |
| } |
|
|
| void dxfRW::writeVar2DOpt(const std::string& name, int startCode) { |
| DRW_Coord varCoord; |
| if (header.getCoord(name, &varCoord)) { |
| writer->writeString(9, name); |
| writer->writeDouble(startCode, varCoord.x); |
| writer->writeDouble(startCode + 10, varCoord.y); |
| } |
| } |
|
|