From 05550fcdf010ebe04f4106d066d962d4e807f832 Mon Sep 17 00:00:00 2001 From: wmayer Date: Sat, 10 Nov 2018 19:02:50 +0100 Subject: [PATCH] fixes 0003680: Export (Ctrl+E) doesn't check to make sure that object being exported is a model at all --- src/Mod/Mesh/App/AppMeshPy.cpp | 36 +++++++++++++++++++++++++++------- src/Mod/Mesh/App/Exporter.cpp | 24 +++++++++++++++++++++++ src/Mod/Mesh/App/Exporter.h | 5 +++++ 3 files changed, 58 insertions(+), 7 deletions(-) diff --git a/src/Mod/Mesh/App/AppMeshPy.cpp b/src/Mod/Mesh/App/AppMeshPy.cpp index 79320ca27f..526419ef56 100644 --- a/src/Mod/Mesh/App/AppMeshPy.cpp +++ b/src/Mod/Mesh/App/AppMeshPy.cpp @@ -322,6 +322,33 @@ private: return Py::None(); } + // collect all object types that can be exported as mesh + std::vector objectList; + std::string label; + for (auto it : list) { + PyObject *item = it.ptr(); + if (PyObject_TypeCheck(item, &(App::DocumentObjectPy::Type))) { + auto obj( static_cast(item)->getDocumentObjectPtr() ); + label = obj->Label.getValue(); + if (Exporter::isSupported(obj)) + objectList.push_back(obj); + } + } + + if (objectList.empty()) { + std::string errorMessage; + if (list.length() == 1) { + std::stringstream str; + str << label << " cannot be exported to a mesh file"; + errorMessage = str.str(); + } + else { + errorMessage = "None of the objects can be exported to a mesh file"; + } + + throw Py::TypeError(errorMessage); + } + auto exportFormat( MeshOutput::GetFormat(outputFileName.c_str()) ); std::unique_ptr exporter; @@ -343,13 +370,8 @@ private: throw Py::Exception(Base::BaseExceptionFreeCADError, exStr.c_str()); } - for (auto it : list) { - PyObject *item = it.ptr(); - if (PyObject_TypeCheck(item, &(App::DocumentObjectPy::Type))) { - auto obj( static_cast(item)->getDocumentObjectPtr() ); - - exporter->addObject(obj, fTolerance); - } + for (auto it : objectList) { + exporter->addObject(it, fTolerance); } exporter.reset(); // deletes Exporter, mesh file is written by destructor diff --git a/src/Mod/Mesh/App/Exporter.cpp b/src/Mod/Mesh/App/Exporter.cpp index 34fb253413..8498a69160 100644 --- a/src/Mod/Mesh/App/Exporter.cpp +++ b/src/Mod/Mesh/App/Exporter.cpp @@ -63,6 +63,30 @@ std::string Exporter::xmlEscape(const std::string &input) return out; } +bool Exporter::isSupported(App::DocumentObject *obj) +{ + Base::Type meshFeatId(Base::Type::fromName("Mesh::Feature")); + Base::Type appPartId(Base::Type::fromName("Part::Feature")); + Base::Type groupExtensionId(App::GroupExtension::getExtensionClassTypeId()); + + if (obj->getTypeId().isDerivedFrom(meshFeatId)) { + return true; + } + else if (obj->getTypeId().isDerivedFrom(appPartId)) { + return true; + } + else if (obj->hasExtension(groupExtensionId)) { + auto groupEx( obj->getExtensionByType() ); + for (auto it : groupEx->Group.getValues()) { + bool ok = isSupported(it); + if (ok) + return true; + } + } + + return false; +} + bool Exporter::addAppGroup(App::DocumentObject *obj, float tol) { auto ret(true); diff --git a/src/Mod/Mesh/App/Exporter.h b/src/Mod/Mesh/App/Exporter.h index 72dba3387d..515d32cd93 100644 --- a/src/Mod/Mesh/App/Exporter.h +++ b/src/Mod/Mesh/App/Exporter.h @@ -52,6 +52,11 @@ class Exporter public: Exporter(); + /*! + * \return true if \a is an object that can be exported as mesh. + */ + static bool isSupported(App::DocumentObject *obj); + virtual bool addMeshFeat(App::DocumentObject *obj) = 0; virtual bool addPartFeat(App::DocumentObject *obj, float tol) = 0;