diff --git a/src/Mod/Import/App/AppImportPy.cpp b/src/Mod/Import/App/AppImportPy.cpp index b0a11bb3c3..8ae59ee3ad 100644 --- a/src/Mod/Import/App/AppImportPy.cpp +++ b/src/Mod/Import/App/AppImportPy.cpp @@ -68,6 +68,8 @@ #include #include #include +#include +#include #include "ImpExpDxf.h" @@ -93,7 +95,10 @@ public: "readDXF(filename,[document,ignore_errors]): Imports a DXF file into the given document. ignore_errors is True by default." ); add_varargs_method("writeDXFShape",&Module::writeDXFShape, - "writeDXFShape(shape,filename): Exports a Shape to a DXF file." + "writeDXFShape([shape],filename): Exports Shape(s) to a DXF file." + ); + add_varargs_method("writeDXFObject",&Module::writeDXFObject, + "writeDXFObject([objects],filename): Exports DocumentObject(s) to a DXF file." ); initialize("This module is the Import module."); // register with Python } @@ -328,8 +333,11 @@ private: { char* Name; const char* DocName=0; + const char* optionSource = nullptr; + char* defaultOptions = "User parameter:BaseApp/Preferences/Mod/Draft"; + char* useOptionSource = nullptr; bool IgnoreErrors=true; - if (!PyArg_ParseTuple(args.ptr(), "et|sb","utf-8",&Name,&DocName,&IgnoreErrors)) + if (!PyArg_ParseTuple(args.ptr(), "et|sbs","utf-8",&Name,&DocName,&IgnoreErrors,&optionSource)) throw Py::Exception(); std::string EncodedName = std::string(Name); @@ -339,6 +347,7 @@ private: if (!file.exists()) throw Py::RuntimeError("File doesn't exist"); + App::Document *pcDoc; if (DocName) pcDoc = App::GetApplication().getDocument(DocName); @@ -347,11 +356,17 @@ private: if (!pcDoc) pcDoc = App::GetApplication().newDocument(DocName); + if (optionSource) { + strcpy(useOptionSource,optionSource); + } else { + useOptionSource = defaultOptions; + } + try { // read the DXF file ImpExpDxfRead dxf_file(EncodedName,pcDoc); - //dxf_file.setOptionSource("myoptionpath"); - //dxf_file.setOptions(); + dxf_file.setOptionSource(useOptionSource); + dxf_file.setOptions(); dxf_file.DoRead(IgnoreErrors); pcDoc->recompute(); } @@ -364,29 +379,148 @@ private: Py::Object writeDXFShape(const Py::Tuple& args) { PyObject *shapeObj; - char* name; - if (!PyArg_ParseTuple(args.ptr(), "Oet", &shapeObj, "utf-8",&name)) { - throw Py::TypeError("expected (Page,path"); - } - - std::string filePath = std::string(name); - std::string layerName = "none"; - PyMem_Free(name); - try { - ImpExpDxfWrite writer(filePath); - //writer.setOptionSource("myoptionpath"); - //writer.setOptions(); - writer.setLayerName(layerName); - if (PyObject_TypeCheck(shapeObj, &(Part::TopoShapePy::Type))) { + char* fname; + std::string filePath; + std::string layerName; + const char* optionSource = nullptr; + char* defaultOptions = "User parameter:BaseApp/Preferences/Mod/Draft"; + char* useOptionSource = nullptr; + + + if (PyArg_ParseTuple(args.ptr(), "O!et|s", &(PyList_Type) ,&shapeObj, "utf-8",&fname, &optionSource)) { + filePath = std::string(fname); + layerName = "none"; + PyMem_Free(fname); + + if (optionSource) { + strcpy(useOptionSource,optionSource); + } else { + useOptionSource = defaultOptions; + } + try { + ImpExpDxfWrite writer(filePath); + writer.setOptionSource(useOptionSource); + writer.setOptions(); + writer.setLayerName(layerName); + Py::Sequence list(shapeObj); + for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) { + if (PyObject_TypeCheck((*it).ptr(), &(Part::TopoShapePy::Type))) { + const TopoDS_Shape& shape = static_cast((*it).ptr())->getTopoShapePtr()->getShape(); + writer.exportShape(shape); + } + } + } + catch (const Base::Exception& e) { + throw Py::RuntimeError(e.what()); + } + } else if (PyArg_ParseTuple(args.ptr(), "O!et|s", + &(Part::TopoShapePy::Type) , + &shapeObj, + "utf-8", + &fname, + &optionSource)) { + filePath = std::string(fname); + layerName = "none"; + PyMem_Free(fname); + + if (optionSource) { + strcpy(useOptionSource,optionSource); + } else { + useOptionSource = defaultOptions; + } + try { + ImpExpDxfWrite writer(filePath); + writer.setOptionSource(useOptionSource); + writer.setOptions(); + writer.setLayerName(layerName); Part::TopoShape* obj = static_cast(shapeObj)->getTopoShapePtr(); TopoDS_Shape shape = obj->getShape(); writer.exportShape(shape); } - } - catch (const Base::Exception& e) { - throw Py::RuntimeError(e.what()); - } + catch (const Base::Exception& e) { + throw Py::RuntimeError(e.what()); + } + } else { + throw Py::TypeError("expected ([Shape],path"); + } + return Py::None(); + } + Py::Object writeDXFObject(const Py::Tuple& args) + { + PyObject *docObj; + char* fname; + std::string filePath; + std::string layerName; + const char* optionSource = nullptr; + char* defaultOptions = "User parameter:BaseApp/Preferences/Mod/Draft"; + char* useOptionSource = nullptr; + + + if (PyArg_ParseTuple(args.ptr(), "O!et|s", &(PyList_Type) ,&docObj, "utf-8",&fname, &optionSource)) { + filePath = std::string(fname); + layerName = "none"; + PyMem_Free(fname); + + if (optionSource) { + strcpy(useOptionSource,optionSource); + } else { + useOptionSource = defaultOptions; + } + try { + ImpExpDxfWrite writer(filePath); + writer.setOptionSource(useOptionSource); + writer.setOptions(); + writer.setLayerName(layerName); + Py::Sequence list(docObj); + for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) { + if (PyObject_TypeCheck((*it).ptr(), &(Part::PartFeaturePy::Type))) { + PyObject* item = (*it).ptr(); + App::DocumentObject* obj = static_cast(item)->getDocumentObjectPtr(); + Part::Feature* part = static_cast(obj); + layerName = part->getNameInDocument(); + writer.setLayerName(layerName); + const TopoDS_Shape& shape = part->Shape.getValue(); + writer.exportShape(shape); + } + } + } + catch (const Base::Exception& e) { + throw Py::RuntimeError(e.what()); + } + } else if (PyArg_ParseTuple(args.ptr(), "O!et|s", + &(Part::PartFeaturePy::Type) , + &docObj, + "utf-8", + &fname, + &optionSource)) { + filePath = std::string(fname); + layerName = "none"; + PyMem_Free(fname); + + if (optionSource) { + strcpy(useOptionSource,optionSource); + } else { + useOptionSource = defaultOptions; + } + try { + ImpExpDxfWrite writer(filePath); + writer.setOptionSource(useOptionSource); + writer.setOptions(); + writer.setLayerName(layerName); + App::DocumentObject* obj = static_cast(docObj)->getDocumentObjectPtr(); + Part::Feature* part = static_cast(obj); + layerName = part->getNameInDocument(); + writer.setLayerName(layerName); + const TopoDS_Shape& shape = part->Shape.getValue(); + writer.exportShape(shape); + } + catch (const Base::Exception& e) { + throw Py::RuntimeError(e.what()); + } + } else { + throw Py::TypeError("expected ([DocObject],path"); + } return Py::None(); } diff --git a/src/Mod/Import/App/ImpExpDxf.cpp b/src/Mod/Import/App/ImpExpDxf.cpp index fbf0f0c9ab..eddffa9741 100644 --- a/src/Mod/Import/App/ImpExpDxf.cpp +++ b/src/Mod/Import/App/ImpExpDxf.cpp @@ -75,10 +75,6 @@ ImpExpDxfRead::ImpExpDxfRead(std::string filepath, App::Document *pcDoc) : CDxfR document = pcDoc; setOptionSource("User parameter:BaseApp/Preferences/Mod/Draft"); setOptions(); -// ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Draft"); -// optionGroupLayers = hGrp->GetBool("groupLayers",false); -// optionImportAnnotations = hGrp->GetBool("dxftext",false); -// optionScaling = hGrp->GetFloat("dxfScaling",1.0); } void ImpExpDxfRead::setOptions(void) @@ -340,7 +336,7 @@ ImpExpDxfWrite::ImpExpDxfWrite(std::string filepath) : void ImpExpDxfWrite::setOptions(void) { - ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Draft"); + ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(getOptionSource().c_str()); optionMaxLength = hGrp->GetFloat("maxsegmentlength",5.0); optionPolyLine = hGrp->GetBool("DiscretizeEllipses",true); } diff --git a/src/Mod/TechDraw/Gui/Command.cpp b/src/Mod/TechDraw/Gui/Command.cpp index fd2e2a9617..208921e6f9 100644 --- a/src/Mod/TechDraw/Gui/Command.cpp +++ b/src/Mod/TechDraw/Gui/Command.cpp @@ -1033,7 +1033,7 @@ bool CmdTechDrawSpreadsheet::isActive(void) //=========================================================================== -// TechDraw_ExportPage +// TechDraw_ExportPage (Svg) //=========================================================================== DEF_STD_CMD_A(CmdTechDrawExportPage); @@ -1076,6 +1076,57 @@ bool CmdTechDrawExportPage::isActive(void) return DrawGuiUtil::needPage(this); } +//=========================================================================== +// TechDraw_ExportPage (Dxf) +//=========================================================================== + +DEF_STD_CMD_A(CmdTechDrawExportPageDxf); + +CmdTechDrawExportPageDxf::CmdTechDrawExportPageDxf() + : Command("TechDraw_ExportPageDxf") +{ + sGroup = QT_TR_NOOP("File"); + sMenuText = QT_TR_NOOP("Export page as DXF"); + sToolTipText = QT_TR_NOOP("Export a page to a DXF file"); + sWhatsThis = "TechDraw_SaveDXF"; + sStatusTip = sToolTipText; + sPixmap = "actions/techdraw-saveDXF"; +} + +void CmdTechDrawExportPageDxf::activated(int iMsg) +{ + Q_UNUSED(iMsg); + TechDraw::DrawPage* page = DrawGuiUtil::findPage(this); + if (!page) { + return; + } + +//WF? allow more than one TD Page per Dxf file?? 1 TD page = 1 DXF file = 1 drawing? + QString defaultDir; + QString fileName = Gui::FileDialog::getSaveFileName(Gui::getMainWindow(), + QString::fromUtf8(QT_TR_NOOP("Save Dxf File ")), + defaultDir, + QString::fromUtf8(QT_TR_NOOP("Dxf (*.dxf)"))); + + if (fileName.isEmpty()) { + return; + } + + std::string PageName = page->getNameInDocument(); + openCommand("Save page to dxf"); + doCommand(Doc,"import TechDraw"); + doCommand(Doc,"TechDraw.writeDXFPage(App.activeDocument().%s,u\"%s\")",PageName.c_str(),(const char*)fileName.toUtf8()); + updateActive(); + commitCommand(); +} + + +bool CmdTechDrawExportPageDxf::isActive(void) +{ + return DrawGuiUtil::needPage(this); +} + + void CreateTechDrawCommands(void) { @@ -1094,6 +1145,7 @@ void CreateTechDrawCommands(void) rcCmdMgr.addCommand(new CmdTechDrawClipMinus()); rcCmdMgr.addCommand(new CmdTechDrawSymbol()); rcCmdMgr.addCommand(new CmdTechDrawExportPage()); + rcCmdMgr.addCommand(new CmdTechDrawExportPageDxf()); rcCmdMgr.addCommand(new CmdTechDrawDraftView()); rcCmdMgr.addCommand(new CmdTechDrawArchView()); rcCmdMgr.addCommand(new CmdTechDrawSpreadsheet()); diff --git a/src/Mod/TechDraw/Gui/Resources/TechDraw.qrc b/src/Mod/TechDraw/Gui/Resources/TechDraw.qrc index b958de0a72..5cf68d2370 100644 --- a/src/Mod/TechDraw/Gui/Resources/TechDraw.qrc +++ b/src/Mod/TechDraw/Gui/Resources/TechDraw.qrc @@ -49,6 +49,7 @@ icons/actions/techdraw-draft-view.svg icons/actions/techdraw-arch-view.svg icons/actions/techdraw-saveSVG.svg + icons/actions/techdraw-saveDXF.svg icons/actions/techdraw-viewsection.svg icons/actions/techdraw-hatch.svg icons/actions/techdraw-geomhatch.svg diff --git a/src/Mod/TechDraw/Gui/Resources/icons/actions/techdraw-saveDXF.svg b/src/Mod/TechDraw/Gui/Resources/icons/actions/techdraw-saveDXF.svg new file mode 100644 index 0000000000..f187bfc7ec --- /dev/null +++ b/src/Mod/TechDraw/Gui/Resources/icons/actions/techdraw-saveDXF.svg @@ -0,0 +1,349 @@ + + + + + + image/svg+xml + + + + + [WandererFan] + + + techdraw-symbol + 2016-01-14 + http://www.freecadweb.org/wiki/index.php?title=Artwork + + + FreeCAD + + + FreeCAD/src/Mod/TechDraw/Gui/Resources/icons/actions/techdraw-symbol.svg + + + FreeCAD LGPL2+ + + + https://www.gnu.org/copyleft/lesser.html + + + [agryson] Alexander Gryson + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + DXF + diff --git a/src/Mod/TechDraw/Gui/Workbench.cpp b/src/Mod/TechDraw/Gui/Workbench.cpp index 695cd05553..1e2ec261be 100644 --- a/src/Mod/TechDraw/Gui/Workbench.cpp +++ b/src/Mod/TechDraw/Gui/Workbench.cpp @@ -79,6 +79,7 @@ Gui::MenuItem* Workbench::setupMenuBar() const *draw << "TechDraw_LinkDimension"; *draw << "Separator"; *draw << "TechDraw_ExportPage"; + *draw << "TechDraw_ExportPageDxf"; *draw << "Separator"; *draw << "TechDraw_NewHatch"; *draw << "TechDraw_NewGeomHatch"; @@ -130,6 +131,7 @@ Gui::ToolBarItem* Workbench::setupToolBars() const Gui::ToolBarItem *file = new Gui::ToolBarItem(root); file->setCommand("TechDraw File Access"); *file << "TechDraw_ExportPage"; + *file << "TechDraw_ExportPageDxf"; Gui::ToolBarItem *decor = new Gui::ToolBarItem(root); decor->setCommand("TechDraw Decoration"); @@ -138,7 +140,7 @@ Gui::ToolBarItem* Workbench::setupToolBars() const *decor << "TechDraw_Symbol"; *decor << "TechDraw_Image"; *decor << "TechDraw_ToggleFrame"; - *decor << "TechDraw_RedrawPage"; +// *decor << "TechDraw_RedrawPage"; return root; } @@ -181,6 +183,7 @@ Gui::ToolBarItem* Workbench::setupCommandBars() const Gui::ToolBarItem *file = new Gui::ToolBarItem(root); file->setCommand("TechDraw File Access"); *file << "TechDraw_ExportPage"; + *file << "TechDraw_ExportPageDxf"; Gui::ToolBarItem *decor = new Gui::ToolBarItem(root); decor->setCommand("TechDraw Decoration"); @@ -189,7 +192,7 @@ Gui::ToolBarItem* Workbench::setupCommandBars() const *decor << "TechDraw_Symbol"; *decor << "TechDraw_Image"; *decor << "TechDraw_ToggleFrame"; - *decor << "TechDraw_RedrawPage"; +// *decor << "TechDraw_RedrawPage"; return root; }