diff --git a/src/Mod/Mesh/App/AppMeshPy.cpp b/src/Mod/Mesh/App/AppMeshPy.cpp index 749c1d4223..f2e272a6de 100644 --- a/src/Mod/Mesh/App/AppMeshPy.cpp +++ b/src/Mod/Mesh/App/AppMeshPy.cpp @@ -266,12 +266,14 @@ private: meta[App::Application::Config()["ExeName"] + "-buildRevisionHash"] = App::Application::Config()["BuildRevisionHash"]; - exporter.reset( new AmfExporter(outputFileName, meta, exportAmfCompressed) ); + exporter.reset( new ExporterAMF(outputFileName, meta, exportAmfCompressed) ); - } else if (exportFormat != MeshIO::Undefined) { + } + else if (exportFormat != MeshIO::Undefined) { exporter.reset( new MergeExporter(outputFileName, exportFormat) ); - } else { + } + else { std::string exStr("Can't determine mesh format from file name: '"); exStr += outputFileName + "'"; throw Py::ValueError(exStr.c_str()); @@ -280,6 +282,7 @@ private: for (auto it : objectList) { exporter->addObject(it, fTolerance); } + exporter.reset(); // deletes Exporter, mesh file is written by destructor return Py::None(); diff --git a/src/Mod/Mesh/App/Exporter.cpp b/src/Mod/Mesh/App/Exporter.cpp index 388b1a89bf..986558b055 100644 --- a/src/Mod/Mesh/App/Exporter.cpp +++ b/src/Mod/Mesh/App/Exporter.cpp @@ -141,12 +141,19 @@ int Exporter::addObject(App::DocumentObject *obj, float tol) return count; } +// ---------------------------------------------------------------------------- + MergeExporter::MergeExporter(std::string fileName, MeshIO::Format) :fName(fileName) { } MergeExporter::~MergeExporter() +{ + write(); +} + +void MergeExporter::write() { // if we have more than one segment set the 'save' flag if (mergingMesh.countSegments() > 1) { @@ -163,7 +170,6 @@ MergeExporter::~MergeExporter() } } - bool MergeExporter::addMesh(const char *name, const MeshObject & mesh) { const auto & kernel = mesh.getKernel(); @@ -209,7 +215,9 @@ bool MergeExporter::addMesh(const char *name, const MeshObject & mesh) return true; } -AmfExporter::AmfExporter( std::string fileName, +// ---------------------------------------------------------------------------- + +ExporterAMF::ExporterAMF( std::string fileName, const std::map &meta, bool compress ) : outputStreamPtr(nullptr), nextObjectIndex(0) @@ -246,7 +254,12 @@ AmfExporter::AmfExporter( std::string fileName, } } -AmfExporter::~AmfExporter() +ExporterAMF::~ExporterAMF() +{ + write(); +} + +void ExporterAMF::write() { if (outputStreamPtr) { *outputStreamPtr << "\t\n"; @@ -263,7 +276,28 @@ AmfExporter::~AmfExporter() } } -bool AmfExporter::addMesh(const char *name, const MeshObject & mesh) +class ExporterAMF::VertLess +{ +public: + bool operator()(const Base::Vector3f &a, const Base::Vector3f &b) const + { + if (a.x == b.x) { + if (a.y == b.y) { + if (a.z == b.z) { + return false; + } else { + return a.z < b.z; + } + } else { + return a.y < b.y; + } + } else { + return a.x < b.x; + } + } +}; + +bool ExporterAMF::addMesh(const char *name, const MeshObject & mesh) { const auto & kernel = mesh.getKernel(); @@ -292,8 +326,8 @@ bool AmfExporter::addMesh(const char *name, const MeshObject & mesh) // Iterate through all facets of the mesh, and construct a: // * Cache (map) of used vertices, outputting each new unique vertex to // the output stream as we find it - // * Vector of the vertices, referred to by the indices from 1 - std::map vertices; + // * Vector of the vertices, referred to by the indices from 1 + std::map vertices; auto vertItr(vertices.begin()); auto vertexCount(0UL); @@ -354,4 +388,3 @@ bool AmfExporter::addMesh(const char *name, const MeshObject & mesh) ++nextObjectIndex; return true; } - diff --git a/src/Mod/Mesh/App/Exporter.h b/src/Mod/Mesh/App/Exporter.h index 96e8000f61..951c068095 100644 --- a/src/Mod/Mesh/App/Exporter.h +++ b/src/Mod/Mesh/App/Exporter.h @@ -48,91 +48,81 @@ namespace Mesh */ class Exporter { - public: - Exporter(); - virtual ~Exporter() = default; +public: + Exporter(); + virtual ~Exporter() = default; - /// Add object and all subobjects and links etc. Returns the number of stuff added. - /*! - * @param obj The object to export. If this is a group like object, its - * sub-objects will be added. - * @param tol The tolerance/accuracy with which to generate the triangle mesh - * @return The number of objects/subobjects that was exported from the document. - See the parameter `accuracy` of ComplexGeoData::getFaces - */ - int addObject(App::DocumentObject *obj, float tol); + /// Add object and all subobjects and links etc. Returns the number of stuff added. + /*! + * @param obj The object to export. If this is a group like object, its + * sub-objects will be added. + * @param tol The tolerance/accuracy with which to generate the triangle mesh + * @return The number of objects/subobjects that was exported from the document. + See the parameter `accuracy` of ComplexGeoData::getFaces + */ + int addObject(App::DocumentObject *obj, float tol); - virtual bool addMesh(const char *name, const MeshObject & mesh) = 0; + virtual bool addMesh(const char *name, const MeshObject & mesh) = 0; - protected: - /// Does some simple escaping of characters for XML-type exports - static std::string xmlEscape(const std::string &input); +protected: + /// Does some simple escaping of characters for XML-type exports + static std::string xmlEscape(const std::string &input); - std::map > subObjectNameCache; - std::map meshCache; + std::map > subObjectNameCache; + std::map meshCache; }; /// Creates a single mesh, in a file, from one or more objects class MergeExporter : public Exporter { - public: - MergeExporter(std::string fileName, MeshCore::MeshIO::Format fmt); - ~MergeExporter() override; +public: + MergeExporter(std::string fileName, MeshCore::MeshIO::Format fmt); + ~MergeExporter() override; - bool addMesh(const char *name, const MeshObject & mesh) override; + bool addMesh(const char *name, const MeshObject & mesh) override; - protected: - MeshObject mergingMesh; - std::string fName; +private: + /// Write the meshes of the added objects to the output file + void write(); + +protected: + MeshObject mergingMesh; + std::string fName; }; /// Used for exporting to Additive Manufacturing File (AMF) format /*! * The constructor and destructor write the beginning and end of the AMF, - * add____() is used to add geometry + * addObject() is used to add geometry */ -class AmfExporter : public Exporter +class ExporterAMF : public Exporter { - public: - /// Writes AMF header - /*! - * meta information passed in is applied at the tag level - */ - AmfExporter(std::string fileName, - const std::map &meta, - bool compress = true); +public: + /// Writes AMF header + /*! + * meta information passed in is applied at the tag level + */ + ExporterAMF(std::string fileName, + const std::map &meta, + bool compress = true); - /// Writes AMF footer - ~AmfExporter() override; + /// Writes AMF footer + ~ExporterAMF() override; - bool addMesh(const char *name, const MeshObject & mesh) override; + bool addMesh(const char *name, const MeshObject & mesh) override; - private: - std::ostream *outputStreamPtr; - int nextObjectIndex; +private: + /// Write the meshes of the added objects to the output file + void write(); + +private: + std::ostream *outputStreamPtr; + int nextObjectIndex; /// Helper for putting Base::Vector3f objects into a std::map in addMesh() - class VertLess - { - public: - bool operator()(const Base::Vector3f &a, const Base::Vector3f &b) const - { - if (a.x == b.x) { - if (a.y == b.y) { - if (a.z == b.z) { - return false; - } else { - return a.z < b.z; - } - } else { - return a.y < b.y; - } - } else { - return a.x < b.x; - } - } - }; -}; // class AmfExporter + class VertLess; +}; // class ExporterAMF } // namespace Mesh + #endif // MESH_EXPORTER_H