/****************************************************************************** ** ** ** Copyright (C) 2015 José F. Soriano, rallazz@gmail.com ** ** ** ** This library is free software, licensed under the terms of the GNU ** ** General Public License as published by the Free Software Foundation, ** ** either version 2 of the License, or (at your option) any later version. ** ** You should have received a copy of the GNU General Public License ** ** along with this program. If not, see . ** ******************************************************************************/ #include "dxiface.h" #include "libdxfrw/libdxfrw.h" #include "../vmisc/vabstractapplication.h" #include #include #include #include #include dx_iface::dx_iface(const std::string &file, DRW::Version v, VarMeasurement varMeasurement, VarInsunits varInsunits) : dxfW(new dxfRW(file.c_str())), cData(), version(v) { InitHeader(varMeasurement, varInsunits); InitTextstyles(); InitVPorts(); InitAppId(); } dx_iface::~dx_iface() { delete dxfW; } bool dx_iface::fileExport(bool binary) { bool success = dxfW->write(this, version, binary); return success; } void dx_iface::writeEntity(DRW_Entity* e){ switch (e->eType) { case DRW::POINT: dxfW->writePoint(static_cast(e)); break; case DRW::ASTMNOTCH: dxfW->writeASTMNotch(static_cast(e)); break; case DRW::LINE: dxfW->writeLine(static_cast(e)); break; case DRW::CIRCLE: dxfW->writeCircle(static_cast(e)); break; case DRW::ARC: dxfW->writeArc(static_cast(e)); break; case DRW::SOLID: dxfW->writeSolid(static_cast(e)); break; case DRW::ELLIPSE: dxfW->writeEllipse(static_cast(e)); break; case DRW::LWPOLYLINE: dxfW->writeLWPolyline(static_cast(e)); break; case DRW::POLYLINE: dxfW->writePolyline(static_cast(e)); break; case DRW::SPLINE: dxfW->writeSpline(static_cast(e)); break; // case RS2::EntitySplinePoints: // writeSplinePoints(static_cast(e)); // break; // case RS2::EntityVertex: // break; case DRW::INSERT: dxfW->writeInsert(static_cast(e)); break; case DRW::MTEXT: dxfW->writeMText(static_cast(e)); break; case DRW::TEXT: dxfW->writeText(static_cast(e)); break; case DRW::DIMLINEAR: case DRW::DIMALIGNED: case DRW::DIMANGULAR: case DRW::DIMANGULAR3P: case DRW::DIMRADIAL: case DRW::DIMDIAMETRIC: case DRW::DIMORDINATE: dxfW->writeDimension(static_cast(e)); break; case DRW::LEADER: dxfW->writeLeader(static_cast(e)); break; case DRW::HATCH: dxfW->writeHatch(static_cast(e)); break; case DRW::IMAGE: dxfW->writeImage(static_cast(e), static_cast(e)->path); break; default: break; } } std::string dx_iface::ErrorString() const { return dxfW->ErrorString(); } void dx_iface::writeHeader(DRW_Header &data){ //complete copy of header vars: data = cData.headerC; //or copy one by one: // for (auto it=cData->headerC.vars.begin(); it != cData->headerC.vars.end(); ++it) // data.vars[it->first] = new DRW_Variant( *(it->second) ); } void dx_iface::writeBlocks(){ //write each block for (auto *bk : cData.blocks){ dxfW->writeBlock(bk); //and write each entity in block for (std::list::const_iterator it=bk->ent.begin(); it!=bk->ent.end(); ++it) writeEntity(*it); } } void dx_iface::writeBlockRecords(){ for (std::list::iterator it=cData.blocks.begin(); it != cData.blocks.end(); ++it) dxfW->writeBlockRecord((*it)->name); } void dx_iface::writeEntities(){ for (std::list::const_iterator it=cData.mBlock->ent.begin(); it!=cData.mBlock->ent.end(); ++it) writeEntity(*it); } void dx_iface::writeLTypes(){ for (std::list::iterator it=cData.lineTypes.begin(); it != cData.lineTypes.end(); ++it) dxfW->writeLineType(&(*it)); } void dx_iface::writeLayers(){ for (std::list::iterator it=cData.layers.begin(); it != cData.layers.end(); ++it) dxfW->writeLayer(&(*it)); } void dx_iface::writeTextstyles(){ for (std::list::iterator it=cData.textStyles.begin(); it != cData.textStyles.end(); ++it) dxfW->writeTextstyle(&(*it)); } void dx_iface::writeVports(){ for (std::list::iterator it=cData.VPorts.begin(); it != cData.VPorts.end(); ++it) dxfW->writeVport(&(*it)); } void dx_iface::writeDimstyles(){ for (std::list::iterator it=cData.dimStyles.begin(); it != cData.dimStyles.end(); ++it) dxfW->writeDimstyle(&(*it)); } void dx_iface::writeObjects() { // default implementation for new DRW_Interface method } void dx_iface::writeAppId(){ for (auto it=cData.appIds.begin(); it != cData.appIds.end(); ++it) dxfW->writeAppId(&(*it)); } void dx_iface::InitHeader(VarMeasurement varMeasurement, VarInsunits varInsunits) { cData.headerC.addComment("Valentina DXF File"); // 1 = Clockwise angles, 0 = Counterclockwise cData.headerC.addInt("$ANGDIR", 0, 70);// Qt use counterclockwise // Sets drawing units: 0 = English; 1 = Metric cData.headerC.addInt("$MEASUREMENT", static_cast(varMeasurement), 70); cData.headerC.addInt("$INSUNITS", static_cast(varInsunits), 70); QString dateTime = QDateTime::currentDateTime().toString("yyyyMMdd.HHmmsszzz"); dateTime.chop(1);// we need hundredths of a second cData.headerC.addStr("$TDCREATE", dateTime.toStdString(), 40); if (version >= DRW::AC1021) { // Full support Unicode cData.headerC.addStr("$DWGCODEPAGE", "UTF-8", 3); } else { cData.headerC.addStr("$DWGCODEPAGE", LocaleToISO(), 3); } } void dx_iface::AddQtLTypes() { DRW_LType ltype; ltype.name = "DOT"; ltype.desc = "Dot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ."; ltype.size = 2; ltype.length = 0.125; ltype.path.push_back(0.0); ltype.path.push_back(-0.125); cData.lineTypes.push_back(ltype); ltype.path.clear(); ltype.name = "DASHED"; ltype.desc = "Dashed _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _"; ltype.size = 2; ltype.length = 0.375; ltype.path.push_back(0.25); ltype.path.push_back(-0.125); cData.lineTypes.push_back(ltype); ltype.path.clear(); ltype.name = "DASHDOT2"; ltype.desc = "Dash dot2 _._._._._._._._._._._._._._._._._._._._._._._._._._._._._._."; ltype.size = 4; ltype.length = 0.5; ltype.path.push_back(0.25); ltype.path.push_back(-0.125); ltype.path.push_back(0.0); ltype.path.push_back(-0.125); cData.lineTypes.push_back(ltype); ltype.path.clear(); ltype.name = "DIVIDE2"; ltype.desc = "Divide2 __..__..__..__..__..__..__..__..__..__..__..__..__..__..__..__.."; ltype.size = 6; ltype.length = 0.625; ltype.path.push_back(0.25); ltype.path.push_back(-0.125); ltype.path.push_back(0.0); ltype.path.push_back(-0.125); ltype.path.push_back(0.0); ltype.path.push_back(-0.125); cData.lineTypes.push_back(ltype); } void dx_iface::AddAAMALayers() { DRW_Layer layer; layer.name = '1';// CUT, OUTLINE layer.color = DRW::black; cData.layers.push_back(layer); layer.name = '8';// DRAW, INK layer.color = DRW::black; cData.layers.push_back(layer); layer.name = '7';// GRAINLINE layer.color = DRW::black; cData.layers.push_back(layer); // layer.name = '6';// MIRROR LINES // layer.color = DRW::black; // cData.layers.push_back(layer); layer.name = "11";// INTCUT layer.color = DRW::black; cData.layers.push_back(layer); layer.name = "13";// DRILL layer.color = DRW::black; cData.layers.push_back(layer); layer.name = '4';// NOTCH layer.color = DRW::black; cData.layers.push_back(layer); // Optitex doesn't like this layer // layer.name = "19";// TEXT // layer.color = DRW::black; // cData.layers.push_back(layer); // layer.name = "26";// REF // layer.color = DRW::black; // cData.layers.push_back(layer); } void dx_iface::AddDefHeaderData() { cData.headerC.addInt("$HANDLING", 1, 70); // Enabled by default for flat version. } void dx_iface::AddAAMAHeaderData() { cData.headerC.addStr("$CLAYER", "1", 8); // Current layer name // Looks like doesn't work with handling enabled. // Missing or 0 for $HANDLING value disables handling. } void dx_iface::AddASTMLayers() { DRW_Layer layer; layer.name = '1';// piece boundary layer.color = DRW::black; cData.layers.push_back(layer); // Do not support // layer.name = '2';// turn points // layer.color = DRW::black; // cData.layers.push_back(layer); // Do not support // layer.name = '3';// curve points // layer.color = DRW::black; // cData.layers.push_back(layer); layer.name = '4';// V-notch and slit notch layer.color = DRW::black; cData.layers.push_back(layer); // Do not support // layer.name = '5';// grade reference and alternate grade reference line(s) // layer.color = DRW::black; // cData.layers.push_back(layer); // Do not support // layer.name = '6';// mirror line // layer.color = DRW::black; // cData.layers.push_back(layer); layer.name = '7';// grainline layer.color = DRW::black; cData.layers.push_back(layer); layer.name = '8';// internal line(s) layer.color = DRW::black; cData.layers.push_back(layer); // Do not support // layer.name = '9';// stripe reference line(s) // layer.color = DRW::black; // cData.layers.push_back(layer); // Do not support // layer.name = '10';// plaid reference line(s) // layer.color = DRW::black; // cData.layers.push_back(layer); layer.name = "11";// internal cutout(s) layer.color = DRW::black; cData.layers.push_back(layer); // Layer 12 intentionally left blank by the standard layer.name = "13";// drill holes layer.color = DRW::black; cData.layers.push_back(layer); layer.name = "14";// sew line(s) layer.color = DRW::black; cData.layers.push_back(layer); layer.name = "15";// annotation text layer.color = DRW::black; cData.layers.push_back(layer); layer.name = "80";// T-notch layer.color = DRW::black; cData.layers.push_back(layer); layer.name = "81";// castle notch layer.color = DRW::black; cData.layers.push_back(layer); layer.name = "82";// check notch layer.color = DRW::black; cData.layers.push_back(layer); layer.name = "83";// U-notch layer.color = DRW::black; cData.layers.push_back(layer); layer.name = "84";// piece boundary quality validation curves layer.color = DRW::black; cData.layers.push_back(layer); layer.name = "85";// internal lines quality validation curves layer.color = DRW::black; cData.layers.push_back(layer); layer.name = "86";// internal cutouts quality validation curves layer.color = DRW::black; cData.layers.push_back(layer); layer.name = "87";// sew lines quality validation curves layer.color = DRW::black; cData.layers.push_back(layer); } void dx_iface::AddDefLayers() { DRW_Layer defLayer; defLayer.name = '0'; defLayer.color = DRW::black; // default color defLayer.lWeight = DRW_LW_Conv::width03; // default width cData.layers.push_back(defLayer); } void dx_iface::InitTextstyles() { DRW_Textstyle style; style.name = "Standard"; style.lastHeight = 2.5; style.font = "txt"; cData.textStyles.push_back(style); } void dx_iface::InitVPorts() { DRW_Vport vport; vport.name = "*ACTIVE"; vport.height = 297.0; cData.VPorts.push_back(vport); } void dx_iface::InitAppId() { DRW_AppId ai; ai.name = "Valentina"; cData.appIds.push_back(ai); } void dx_iface::AddEntity(DRW_Entity *e) { cData.mBlock->ent.push_back(e); } UTF8STRING dx_iface::AddFont(const QFont &f) { DRW_Textstyle ts; ts.name = f.family().toUpper().toStdString(); // Idea source https://stackoverflow.com/questions/20111522/writing-text-styles-into-dxf-from-a-delphi-application if (f.bold()) { ts.name += "_BOLD"; ts.fontFamily += 0x2000000; } if (f.italic()) { ts.name += "_ITALIC"; ts.fontFamily += 0x1000000; } for (auto it = cData.textStyles.begin() ; it !=cData.textStyles.end() ; ++it) { if ((*it).name == ts.name) { return ts.name; } } ts.font = f.family().toStdString(); cData.textStyles.push_back(ts); return ts.name; } void dx_iface::AddBlock(dx_ifaceBlock *block) { cData.blocks.push_back(block); } std::string dx_iface::LocaleToISO() { QMap locMap = LocaleMap(); return locMap.value(QLocale(VAbstractApplication::VApp()->Settings()->GetLocale()).name(), "ISO8859-1").toStdString(); }