From 7ae2d7e495f1342eee52d37009d0366cd208f13d Mon Sep 17 00:00:00 2001 From: wmayer Date: Thu, 27 Aug 2020 09:51:35 +0200 Subject: [PATCH] Mesh: [skip ci] support of asymptote export --- src/Mod/Mesh/App/Core/MeshIO.cpp | 77 ++++++++++++++++++++++++++++++++ src/Mod/Mesh/App/Core/MeshIO.h | 5 ++- src/Mod/Mesh/App/MeshPyImp.cpp | 2 + src/Mod/Mesh/Gui/Command.cpp | 1 + 4 files changed, 84 insertions(+), 1 deletion(-) diff --git a/src/Mod/Mesh/App/Core/MeshIO.cpp b/src/Mod/Mesh/App/Core/MeshIO.cpp index f780d03d6e..dc1f230d6a 100644 --- a/src/Mod/Mesh/App/Core/MeshIO.cpp +++ b/src/Mod/Mesh/App/Core/MeshIO.cpp @@ -1774,6 +1774,7 @@ std::vector MeshOutput::supportedMeshFormats() fmt.emplace_back("wrl"); fmt.emplace_back("wrz"); fmt.emplace_back("amf"); + fmt.emplace_back("asy"); return fmt; } @@ -1828,6 +1829,9 @@ MeshIO::Format MeshOutput::GetFormat(const char* FileName) else if (file.hasExtension("smf")) { return MeshIO::SMF; } + else if (file.hasExtension("asy")) { + return MeshIO::ASY; + } else { return MeshIO::Undefined; } @@ -1946,6 +1950,11 @@ bool MeshOutput::SaveAny(const char* FileName, MeshIO::Format format) const if (!SaveNastran(str)) throw Base::FileException("Export of NASTRAN mesh failed",FileName); } + else if (fileformat == MeshIO::ASY) { + // write file + if (!SaveAsymptote(str)) + throw Base::FileException("Export of ASY mesh failed",FileName); + } else { throw Base::FileException("File format not supported", FileName); } @@ -1990,6 +1999,8 @@ bool MeshOutput::SaveFormat(std::ostream &str, MeshIO::Format fmt) const return SaveAsciiPLY(str); case MeshIO::PY: return SavePython(str); + case MeshIO::ASY: + return SaveAsymptote(str); default: throw Base::FileException("Unsupported file format"); } @@ -2361,6 +2372,72 @@ bool MeshOutput::SaveSMF (std::ostream &out) const return true; } +/** Saves an Asymptote file. */ +bool MeshOutput::SaveAsymptote(std::ostream &out) const +{ + out << "/*\n" + " * Created by FreeCAD \n" + " */\n\n"; + + out << "import three;\n\n"; + + out << "size(500);\n\n"; + + Base::BoundBox3f bbox = _rclMesh.GetBoundBox(); + Base::Vector3f camera(bbox.GetCenter()); + camera.x += bbox.LengthX(); + Base::Vector3f target(bbox.GetCenter()); + Base::Vector3f upvec(0.0f, 0.0f, 1.0f); + + out << "// CA:Camera, OB:Camera\n" + << "currentprojection = perspective(camera = (" << camera.x << ", " + << camera.y << ", " + << camera.z << "),\n" + << " target = (" << target.x << ", " + << target.y << ", " + << target.z << "),\n" + " autoadjust = false,\n" + " showtarget = false,\n" + " up = (" << upvec.x << ", " + << upvec.y << ", " + << upvec.z << "));\n\n"; + + out << "// LA:Spot, OB:Lamp\n" + << "// WO:World\n" + << "currentlight = light(diffuse = rgb(1, 1, 1),\n" + " specular = rgb(1, 1, 1),\n" + " background = rgb(0.078281, 0.16041, 0.25),\n" + " 0.56639, 0.21839, 0.79467);\n\n"; + + out << "// ME:Mesh, OB:Mesh\n"; + + MeshFacetIterator clIter(_rclMesh), clEnd(_rclMesh); + clIter.Transform(this->_transform); + clIter.Begin(); + clEnd.End(); + + const MeshGeomFacet *pclFacet; + while (clIter < clEnd) { + pclFacet = &(*clIter); + + out << "draw(surface("; + + // vertices + for (int i = 0; i < 3; i++) { + out << '(' << pclFacet->_aclPoints[i].x << ", " + << pclFacet->_aclPoints[i].y << ", " + << pclFacet->_aclPoints[i].z << ")--"; + } + + out << "cycle),\n"; + out << " rgb(0.8, 0.8, 0.8));\n"; + + ++clIter; + } + + return true; +} + /** Saves an OFF file. */ bool MeshOutput::SaveOFF (std::ostream &out) const { diff --git a/src/Mod/Mesh/App/Core/MeshIO.h b/src/Mod/Mesh/App/Core/MeshIO.h index c2543f9ef8..e52c95e17e 100644 --- a/src/Mod/Mesh/App/Core/MeshIO.h +++ b/src/Mod/Mesh/App/Core/MeshIO.h @@ -57,7 +57,8 @@ namespace MeshIO { APLY, PY, AMF, - SMF + SMF, + ASY }; enum Binding { OVERALL, @@ -186,6 +187,8 @@ public: bool SaveBinaryPLY (std::ostream &rstrOut) const; /** Saves the mesh object into an ASCII PLY file. */ bool SaveAsciiPLY (std::ostream &rstrOut) const; + /** Saves the mesh object into an asymptote file. */ + bool SaveAsymptote (std::ostream &rstrOut) const; /** Saves the mesh object into an XML file. */ void SaveXML (Base::Writer &writer) const; /** Saves a node to an OpenInventor file. */ diff --git a/src/Mod/Mesh/App/MeshPyImp.cpp b/src/Mod/Mesh/App/MeshPyImp.cpp index b25e3b4122..170c05a6fd 100644 --- a/src/Mod/Mesh/App/MeshPyImp.cpp +++ b/src/Mod/Mesh/App/MeshPyImp.cpp @@ -177,6 +177,7 @@ PyObject* MeshPy::read(PyObject *args, PyObject *kwds) ext["PLY" ] = MeshCore::MeshIO::PLY; ext["APLY"] = MeshCore::MeshIO::APLY; ext["PY" ] = MeshCore::MeshIO::PY; + ext["ASY" ] = MeshCore::MeshIO::ASY; PyObject* input; char* Ext; @@ -228,6 +229,7 @@ PyObject* MeshPy::write(PyObject *args, PyObject *kwds) ext["PLY" ] = MeshCore::MeshIO::PLY; ext["APLY"] = MeshCore::MeshIO::APLY; ext["PY" ] = MeshCore::MeshIO::PY; + ext["ASY" ] = MeshCore::MeshIO::ASY; static char* keywords_path[] = {"Filename","Format","Name","Material",NULL}; if (PyArg_ParseTupleAndKeywords(args, kwds, "et|ssO", keywords_path, "utf-8", diff --git a/src/Mod/Mesh/Gui/Command.cpp b/src/Mod/Mesh/Gui/Command.cpp index 69d5e14ee9..3aa47f0f15 100644 --- a/src/Mod/Mesh/Gui/Command.cpp +++ b/src/Mod/Mesh/Gui/Command.cpp @@ -521,6 +521,7 @@ void CmdMeshExport::activated(int) ext << qMakePair(QString::fromLatin1("%1 (*.wrz)").arg(QObject::tr("Compressed VRML 2.0")), "WRZ"); ext << qMakePair(QString::fromLatin1("%1 (*.nas *.bdf)").arg(QObject::tr("Nastran")), "NAS"); ext << qMakePair(QString::fromLatin1("%1 (*.py)").arg(QObject::tr("Python module def")), "PY"); + ext << qMakePair(QString::fromLatin1("%1 (*.asy)").arg(QObject::tr("Asymptote Format")), "ASY"); ext << qMakePair(QString::fromLatin1("%1 (*.*)").arg(QObject::tr("All Files")), ""); // Undefined QStringList filter; for (QList >::iterator it = ext.begin(); it != ext.end(); ++it)