| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| |
|
| | #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); |
| | } |
| | } |
| |
|