1. Dumper base functionality.
2. Feature to dump model into Python script.
3. Dump parameters, parts, sketches and points on sketches.
4. Uncompleted dump for point from ConstructionPlugin.
#include <GeomAPI_Shape.h>
+#include <ModelHighAPI_Dumper.h>
#include <ModelHighAPI_Selection.h>
#include <ModelHighAPI_Tools.h>
execute();
}*/
+//==================================================================================================
+void ConstructionAPI_Point::dump(ModelHighAPI_Dumper& theDumper) const
+{
+ // TODO: all types of points
+
+ FeaturePtr aBase = feature();
+ const std::string& aDocName = theDumper.name(aBase->document());
+
+ AttributeDoublePtr anAttrX = aBase->real(ConstructionPlugin_Point::X());
+ AttributeDoublePtr anAttrY = aBase->real(ConstructionPlugin_Point::Y());
+ AttributeDoublePtr anAttrZ = aBase->real(ConstructionPlugin_Point::Z());
+ theDumper << aBase << " = model.addPoint(" << aDocName << ", "
+ << anAttrX << ", " << anAttrY << ", " << anAttrZ << ")" << std::endl;
+}
+
//==================================================================================================
PointPtr addPoint(const std::shared_ptr<ModelAPI_Document>& thePart,
const ModelHighAPI_Double& theX,
CONSTRUCTIONAPI_EXPORT
void setByLineAndPlaneIntersection(const ModelHighAPI_Selection& theEdge,
const ModelHighAPI_Selection& theFace);*/
+
+ /// Dump wrapped feature
+ CONSTRUCTIONAPI_EXPORT
+ virtual void dump(ModelHighAPI_Dumper& theDumper) const;
};
/// Pointer on Point object.
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/src/Events
${PROJECT_SOURCE_DIR}/src/Config
${PROJECT_SOURCE_DIR}/src/ModelAPI
+ ${PROJECT_SOURCE_DIR}/src/ModelHighAPI
${PROJECT_SOURCE_DIR}/src/GeomAPI
${PROJECT_SOURCE_DIR}/src/GeomAlgoAPI
${PROJECT_SOURCE_DIR}/src/XAO
ExchangePlugin_ExportFeature.h
ExchangePlugin_Validators.h
ExchangePlugin_Tools.h
+ ExchangePlugin_Dump.h
)
SET(PROJECT_SOURCES
ExchangePlugin_ExportFeature.cpp
ExchangePlugin_Validators.cpp
ExchangePlugin_Tools.cpp
+ ExchangePlugin_Dump.cpp
)
SET(XML_RESOURCES
Events
Config
ModelAPI
+ ModelHighAPI
GeomAPI
GeomAlgoAPI
XAO
--- /dev/null
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File: ExchangePlugin_ExportFeature.cpp
+// Created: May 14, 2015
+// Author: Sergey POKHODENKO
+
+#include <ExchangePlugin_Dump.h>
+
+#include <ModelAPI_AttributeString.h>
+#include <ModelAPI_Document.h>
+#include <ModelAPI_Session.h>
+
+#include <ModelHighAPI_Dumper.h>
+
+#include <Config_ModuleReader.h>
+
+
+ExchangePlugin_Dump::ExchangePlugin_Dump()
+{
+}
+
+ExchangePlugin_Dump::~ExchangePlugin_Dump()
+{
+}
+
+void ExchangePlugin_Dump::initAttributes()
+{
+ data()->addAttribute(ExchangePlugin_Dump::FILE_PATH_ID(), ModelAPI_AttributeString::typeId());
+ data()->addAttribute(ExchangePlugin_Dump::FILE_FORMAT_ID(), ModelAPI_AttributeString::typeId());
+}
+
+void ExchangePlugin_Dump::execute()
+{
+ AttributeStringPtr aFilePathAttr =
+ this->string(ExchangePlugin_Dump::FILE_PATH_ID());
+ std::string aFilePath = aFilePathAttr->value();
+ if (aFilePath.empty())
+ return;
+
+ dump(aFilePath);
+}
+
+void ExchangePlugin_Dump::dump(const std::string& theFileName)
+{
+ // load DumpAssistant from Python side
+ Config_ModuleReader::loadScript("model.dump");
+
+ ModelHighAPI_Dumper* aDumper = ModelHighAPI_Dumper::getInstance();
+ DocumentPtr aDoc = ModelAPI_Session::get()->moduleDocument();
+ if (!aDumper || !aDumper->process(aDoc, theFileName))
+ setError("An error occured while dumping to " + theFileName);
+}
--- /dev/null
+// Copyright (C) 2016-20xx CEA/DEN, EDF R&D
+
+// File: ExchangePlugin_Dump.h
+// Created: August 1, 2016
+// Author: Artem ZHIDKOV
+
+#ifndef EXCHANGEPLUGIN_DUMP_H_
+#define EXCHANGEPLUGIN_DUMP_H_
+
+#include <ExchangePlugin.h>
+
+#include <ModelAPI_Feature.h>
+
+/**
+ * \class ExchangePlugin_Dump
+ * \ingroup Plugins
+ * \brief Store full model as a Python script
+ */
+class ExchangePlugin_Dump : public ModelAPI_Feature
+{
+public:
+ /// Feature kind
+ inline static const std::string& ID()
+ {
+ static const std::string MY_DUMP_ID("Dump");
+ return MY_DUMP_ID;
+ }
+ /// attribute name of file path
+ inline static const std::string& FILE_PATH_ID()
+ {
+ static const std::string MY_FILE_PATH_ID("file_path");
+ return MY_FILE_PATH_ID;
+ }
+ /// attribute name of file format
+ inline static const std::string& FILE_FORMAT_ID()
+ {
+ static const std::string MY_FILE_FORMAT_ID("file_format");
+ return MY_FILE_FORMAT_ID;
+ }
+
+ /// Default constructor
+ EXCHANGEPLUGIN_EXPORT ExchangePlugin_Dump();
+ /// Default destructor
+ EXCHANGEPLUGIN_EXPORT virtual ~ExchangePlugin_Dump();
+
+ /// Returns the unique kind of a feature
+ EXCHANGEPLUGIN_EXPORT virtual const std::string& getKind()
+ {
+ return ExchangePlugin_Dump::ID();
+ }
+
+ /// Request for initialization of data model of the feature: adding all attributes
+ EXCHANGEPLUGIN_EXPORT virtual void initAttributes();
+
+ /// Computes or recomputes the results
+ EXCHANGEPLUGIN_EXPORT virtual void execute();
+
+ /// Reimplemented from ModelAPI_Feature::isMacro(). Returns true.
+ EXCHANGEPLUGIN_EXPORT virtual bool isMacro() const { return true; }
+
+ /// Reimplemented from ModelAPI_Feature::isPreviewNeeded(). Returns false.
+ EXCHANGEPLUGIN_EXPORT virtual bool isPreviewNeeded() const { return false; }
+
+protected:
+ /// Performs dump to the file
+ EXCHANGEPLUGIN_EXPORT void dump(const std::string& theFileName);
+};
+
+#endif
// Author: Sergey BELASH
#include <ExchangePlugin_Plugin.h>
+#include <ExchangePlugin_Dump.h>
#include <ExchangePlugin_ImportFeature.h>
#include <ExchangePlugin_ExportFeature.h>
#include <ExchangePlugin_Validators.h>
} else
if (theFeatureID == ExchangePlugin_ExportFeature::ID()) {
return FeaturePtr(new ExchangePlugin_ExportFeature);
+ } else
+ if (theFeatureID == ExchangePlugin_Dump::ID()) {
+ return FeaturePtr(new ExchangePlugin_Dump);
}
// feature of such kind is not found
return FeaturePtr();
<feature id="Export" title="Export" tooltip="Export to file" icon="icons/Exchange/export.png">
<source path="export_widget.xml" />
</feature>
+ <feature id="Dump" title="Dump" tooltip="Dump python script" icon="icons/Exchange/dump.png">
+ <export_file_selector id="file_path"
+ type="save"
+ title="Dump to file"
+ path="">
+ <validator id="ExchangePlugin_ExportFormat"
+ parameters="py:Python" />
+ </export_file_selector>
+ </feature>
</group>
</workbench>
</plugin>
\ No newline at end of file
SET(PROJECT_HEADERS
ModelHighAPI.h
ModelHighAPI_Double.h
+ ModelHighAPI_Dumper.h
ModelHighAPI_Integer.h
ModelHighAPI_Interface.h
ModelHighAPI_Macro.h
SET(PROJECT_SOURCES
ModelHighAPI_Double.cpp
+ ModelHighAPI_Dumper.cpp
ModelHighAPI_Integer.cpp
ModelHighAPI_Interface.cpp
ModelHighAPI_RefAttr.cpp
ModelAPI
)
-ADD_DEFINITIONS(-DMODELHIGHAPI_EXPORTS)
+ADD_DEFINITIONS(-DMODELHIGHAPI_EXPORTS -DWNT)
ADD_LIBRARY(ModelHighAPI SHARED ${PROJECT_SOURCES} ${PROJECT_HEADERS})
#TODO(spo): is it necessary?
SET_TARGET_PROPERTIES(ModelHighAPI PROPERTIES LINKER_LANGUAGE CXX)
${PROJECT_SOURCE_DIR}/src/GeomAPI
${PROJECT_SOURCE_DIR}/src/GeomDataAPI
${PROJECT_SOURCE_DIR}/src/ModelAPI
+ ${PROJECT_SOURCE_DIR}/src/PartSetPlugin
+ ${CAS_INCLUDE_DIRS}
)
set(SWIG_MODULE_ModelHighAPI_EXTRA_DEPS
/* ModelHighAPI.i */
-%module ModelHighAPI
+%module(directors="1") ModelHighAPI
+%feature("director:except") {
+ if ($error != NULL) {
+ PyErr_Print();
+ std::cerr << std::endl;
+ throw Swig::DirectorMethodException();
+ }
+}
%{
#include "ModelHighAPI_swig.h"
%include "std_string.i"
%include "std_shared_ptr.i"
+// directors
+%feature("director") ModelHighAPI_Dumper;
+
// shared pointers
%shared_ptr(ModelHighAPI_Interface)
// all supported interfaces
%include "ModelHighAPI_Double.h"
+%include "ModelHighAPI_Dumper.h"
%include "ModelHighAPI_Integer.h"
%include "ModelHighAPI_Interface.h"
%include "ModelHighAPI_RefAttr.h"
--- /dev/null
+// Copyright (C) 2016-20xx CEA/DEN, EDF R&D -->
+
+// File: ModelHighAPI_Dumper.cpp
+// Created: 1 August 2016
+// Author: Artem ZHIDKOV
+
+//--------------------------------------------------------------------------------------
+#include "ModelHighAPI_Dumper.h"
+
+#include <GeomAPI_Pnt.h>
+#include <GeomAPI_Dir.h>
+
+#include <GeomDataAPI_Dir.h>
+#include <GeomDataAPI_Point.h>
+#include <GeomDataAPI_Point2D.h>
+
+#include <ModelAPI_AttributeBoolean.h>
+#include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_AttributeInteger.h>
+#include <ModelAPI_AttributeSelection.h>
+#include <ModelAPI_AttributeString.h>
+#include <ModelAPI_CompositeFeature.h>
+#include <ModelAPI_Document.h>
+#include <ModelAPI_Entity.h>
+#include <ModelAPI_Feature.h>
+#include <ModelAPI_Result.h>
+#include <ModelAPI_ResultPart.h>
+
+#include <PartSetPlugin_Part.h>
+
+#include <OSD_OpenFile.hxx>
+
+#include <algorithm>
+#include <fstream>
+
+//#define DUMP_USER_DEFINED_NAMES
+
+ModelHighAPI_Dumper* ModelHighAPI_Dumper::mySelf = 0;
+
+ModelHighAPI_Dumper::ModelHighAPI_Dumper()
+{
+ clear();
+}
+
+void ModelHighAPI_Dumper::setInstance(ModelHighAPI_Dumper* theDumper)
+{
+ if (mySelf == 0)
+ mySelf = theDumper;
+}
+
+ModelHighAPI_Dumper* ModelHighAPI_Dumper::getInstance()
+{
+ return mySelf;
+}
+
+void ModelHighAPI_Dumper::clear()
+{
+ myDumpBuffer = std::ostringstream();
+ myDumpBuffer << std::setprecision(16);
+}
+
+const std::string& ModelHighAPI_Dumper::name(const EntityPtr& theEntity)
+{
+ EntityNameMap::const_iterator aFound = myNames.find(theEntity);
+ if (aFound != myNames.end())
+ return aFound->second.first;
+
+ // entity is not found, store it
+ std::string aName;
+ bool isNameDefined = false;
+ FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theEntity);
+ if (aFeature) {
+ aName = aFeature->name();
+ isNameDefined = !aName.empty();
+
+ if (!isNameDefined) {
+ static long anIndex = 0;
+ // set default name: feature ID + index
+ std::ostringstream aConverter;
+ aConverter << aFeature->getKind() << "_" << ++anIndex;
+ aName = aConverter.str();
+ std::transform(aName.begin(), aName.end(), aName.begin(), ::tolower);
+ }
+ }
+
+ myNames[theEntity] = std::pair<std::string, bool>(aName, isNameDefined);
+ return myNames[theEntity].first;
+}
+
+const std::string& ModelHighAPI_Dumper::parentName(const FeaturePtr& theEntity)
+{
+ const std::set<AttributePtr>& aRefs = theEntity->data()->refsToMe();
+ std::set<AttributePtr>::const_iterator aRefIt = aRefs.begin();
+ for (; aRefIt != aRefs.end(); ++aRefIt) {
+ CompositeFeaturePtr anOwner = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(
+ ModelAPI_Feature::feature((*aRefIt)->owner()));
+ if (anOwner)
+ return name(anOwner);
+ }
+
+ static const std::string DUMMY;
+ return DUMMY;
+}
+
+bool ModelHighAPI_Dumper::process(const std::shared_ptr<ModelAPI_Document>& theDoc,
+ const std::string& theFileName)
+{
+ // dump top level document feature
+ static const std::string aDocName("partSet");
+ myNames[theDoc] = std::pair<std::string, bool>(aDocName, false);
+ *this << aDocName << " = model.moduleDocument()" << std::endl;
+
+ // dump subfeatures and store result to file
+ return process(theDoc) && exportTo(theFileName);
+}
+
+bool ModelHighAPI_Dumper::process(const std::shared_ptr<ModelAPI_Document>& theDoc)
+{
+ bool isOk = true;
+ // dump all features
+ std::list<FeaturePtr> aFeatures = theDoc->allFeatures();
+ std::list<FeaturePtr>::const_iterator aFeatIt = aFeatures.begin();
+ for (; aFeatIt != aFeatures.end(); ++aFeatIt) {
+ dumpFeature(*aFeatIt);
+ // iteratively process composite features
+ CompositeFeaturePtr aCompFeat = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(*aFeatIt);
+ if (!aCompFeat)
+ continue;
+
+ // sub-part is processed independently, because it provides separate document
+ if ((*aFeatIt)->getKind() == PartSetPlugin_Part::ID()) {
+ ResultPartPtr aPartResult =
+ std::dynamic_pointer_cast<ModelAPI_ResultPart>((*aFeatIt)->lastResult());
+ if (!aPartResult)
+ continue;
+ DocumentPtr aSubDoc = aPartResult->partDoc();
+ // set name of document equal to part name
+ myNames[aSubDoc] = myNames[*aFeatIt];
+
+ isOk = process(aSubDoc) && isOk;
+ } else
+ isOk = process(aCompFeat) && isOk;
+ }
+ return isOk;
+}
+
+bool ModelHighAPI_Dumper::process(const std::shared_ptr<ModelAPI_CompositeFeature>& theComposite)
+{
+ // dump all sub-features;
+ int aNbSubs = theComposite->numberOfSubs();
+ for (int anIndex = 0; anIndex < aNbSubs; ++anIndex) {
+ FeaturePtr aFeature = theComposite->subFeature(anIndex);
+ dumpFeature(aFeature, true);
+ }
+ // dump command to update model
+ myDumpBuffer << "model.do()" << std::endl;
+ return true;
+}
+
+bool ModelHighAPI_Dumper::exportTo(const std::string& theFileName)
+{
+ std::ofstream aFile;
+ OSD_OpenStream(aFile, theFileName.c_str(), std::ofstream::out);
+ if (!aFile.is_open())
+ return false;
+
+ // standard header
+ for (ModulesMap::const_iterator aModIt = myModules.begin();
+ aModIt != myModules.end(); ++aModIt) {
+ aFile << "from " << aModIt->first << " import ";
+ if (aModIt->second.empty() ||
+ aModIt->second.find(std::string()) != aModIt->second.end())
+ aFile << "*"; // import whole module
+ else {
+ // import specific features
+ std::set<std::string>::const_iterator anObjIt = aModIt->second.begin();
+ aFile << *anObjIt;
+ for (++anObjIt; anObjIt != aModIt->second.end(); ++anObjIt)
+ aFile << ", " << *anObjIt;
+ }
+ aFile << std::endl;
+ }
+ if (!myModules.empty())
+ aFile << std::endl;
+
+ aFile << "import model" << std::endl << std::endl;
+ aFile << "model.begin()" << std::endl;
+
+ // dump collected data
+ aFile << myDumpBuffer.str();
+
+ // standard footer
+ aFile << "model.end()" << std::endl;
+
+ aFile.close();
+ clear();
+
+ return true;
+}
+
+void ModelHighAPI_Dumper::importModule(const std::string& theModuleName,
+ const std::string& theObject)
+{
+ myModules[theModuleName].insert(theObject);
+}
+
+void ModelHighAPI_Dumper::dumpEntitySetName()
+{
+ if (!myLastEntityWithName)
+ return;
+
+#ifdef DUMP_USER_DEFINED_NAMES
+ const std::string& aName = name(myLastEntityWithName);
+ myDumpBuffer << aName;
+ FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(myLastEntityWithName);
+ if (aFeature)
+ myDumpBuffer << ".feature()";
+ myDumpBuffer << ".data().setName(\"" << aName << "\")" << std::endl;
+#endif
+ myLastEntityWithName = EntityPtr();
+}
+
+ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(const char theChar)
+{
+ myDumpBuffer << theChar;
+ return *this;
+}
+
+ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(const char* theString)
+{
+ myDumpBuffer << theString;
+ return *this;
+}
+
+ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(const std::string& theString)
+{
+ myDumpBuffer << theString;
+ return *this;
+}
+
+ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(const int theValue)
+{
+ myDumpBuffer << theValue;
+ return *this;
+}
+
+ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(const double theValue)
+{
+ myDumpBuffer << theValue;
+ return *this;
+}
+
+ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(const std::shared_ptr<GeomAPI_Pnt>& thePoint)
+{
+ importModule("GeomAPI", "GeomAPI_Pnt");
+ myDumpBuffer << "GeomAPI_Pnt(" << thePoint->x() << ", "
+ << thePoint->y() << ", " << thePoint->z() << ")";
+ return *this;
+}
+
+ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(const std::shared_ptr<GeomAPI_Dir>& theDir)
+{
+ importModule("GeomAPI", "GeomAPI_Dir");
+ myDumpBuffer << "GeomAPI_Dir(" << theDir->x() << ", "
+ << theDir->y() << ", " << theDir->z() << ")";
+ return *this;
+}
+
+ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(
+ const std::shared_ptr<GeomDataAPI_Dir>& theDir)
+{
+ myDumpBuffer << theDir->x() << ", " << theDir->y() << ", " << theDir->z();
+ return *this;
+}
+
+static void dumpArray(std::ostringstream& theOutput, int theSize,
+ double* theValues, std::string* theTexts)
+{
+ for (int i = 0; i < theSize; ++i) {
+ if (i > 0)
+ theOutput << ", ";
+ if (theTexts[i].empty())
+ theOutput << theValues[i];
+ else
+ theOutput << "\"" << theTexts[i] << "\"";
+ }
+}
+
+ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(
+ const std::shared_ptr<GeomDataAPI_Point>& thePoint)
+{
+ static const int aSize = 3;
+ double aValues[aSize] = {thePoint->x(), thePoint->y(), thePoint->z()};
+ std::string aTexts[aSize] = {thePoint->textX(), thePoint->textY(), thePoint->textZ()};
+ dumpArray(myDumpBuffer, aSize, aValues, aTexts);
+ return *this;
+}
+
+ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(
+ const std::shared_ptr<GeomDataAPI_Point2D>& thePoint)
+{
+ static const int aSize = 2;
+ double aValues[aSize] = {thePoint->x(), thePoint->y()};
+ std::string aTexts[aSize] = {thePoint->textX(), thePoint->textY()};
+ dumpArray(myDumpBuffer, aSize, aValues, aTexts);
+ return *this;
+}
+
+ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(
+ const std::shared_ptr<ModelAPI_AttributeBoolean>& theAttrBool)
+{
+ myDumpBuffer << theAttrBool->value();
+ return *this;
+}
+
+ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(
+ const std::shared_ptr<ModelAPI_AttributeInteger>& theAttrInt)
+{
+ std::string aText = theAttrInt->text();
+ if (aText.empty())
+ myDumpBuffer << theAttrInt->value();
+ else
+ myDumpBuffer << "\"" << aText << "\"";
+ return *this;
+}
+
+ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(
+ const std::shared_ptr<ModelAPI_AttributeDouble>& theAttrReal)
+{
+ std::string aText = theAttrReal->text();
+ if (aText.empty())
+ myDumpBuffer << theAttrReal->value();
+ else
+ myDumpBuffer << "\"" << aText << "\"";
+ return *this;
+}
+
+ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(
+ const std::shared_ptr<ModelAPI_AttributeString>& theAttrStr)
+{
+ myDumpBuffer << "\"" << theAttrStr->value() << "\"";
+ return *this;
+}
+
+ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(const EntityPtr& theEntity)
+{
+ myDumpBuffer << name(theEntity);
+ if (myNames[theEntity].second)
+ myLastEntityWithName = theEntity;
+ return *this;
+}
+
+ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(
+ const std::shared_ptr<ModelAPI_AttributeSelection>& theAttrSelect)
+{
+ myDumpBuffer << "\"" << theAttrSelect->namingName() << "\"";
+ return *this;
+}
+
+/// Dump std::endl
+MODELHIGHAPI_EXPORT
+ModelHighAPI_Dumper& operator<<(ModelHighAPI_Dumper& theDumper,
+ std::basic_ostream<char>& (*theEndl)(std::basic_ostream<char>&))
+{
+ theDumper.myDumpBuffer << theEndl;
+ theDumper.dumpEntitySetName();
+ return theDumper;
+}
--- /dev/null
+// Copyright (C) 2016-20xx CEA/DEN, EDF R&D -->
+
+// File: ModelHighAPI_Dumper.h
+// Created: 1 August 2016
+// Author: Artem ZHIDKOV
+
+#ifndef ModelHighAPI_Dumper_H_
+#define ModelHighAPI_Dumper_H_
+
+#include "ModelHighAPI.h"
+
+#include <map>
+#include <memory>
+#include <set>
+#include <sstream>
+#include <string>
+
+class GeomAPI_Pnt;
+class GeomAPI_Dir;
+
+class GeomDataAPI_Dir;
+class GeomDataAPI_Point;
+class GeomDataAPI_Point2D;
+
+class ModelAPI_AttributeBoolean;
+class ModelAPI_AttributeDouble;
+class ModelAPI_AttributeInteger;
+class ModelAPI_AttributeSelection;
+class ModelAPI_AttributeString;
+class ModelAPI_CompositeFeature;
+class ModelAPI_Document;
+class ModelAPI_Entity;
+class ModelAPI_Feature;
+
+typedef std::shared_ptr<ModelAPI_Entity> EntityPtr;
+typedef std::shared_ptr<ModelAPI_Feature> FeaturePtr;
+
+/**\class ModelHighAPI_Dumper
+ * \ingroup CPPHighAPI
+ * \brief Dump engine for the model
+ */
+class ModelHighAPI_Dumper
+{
+public:
+ /// Default constructor
+ MODELHIGHAPI_EXPORT
+ ModelHighAPI_Dumper();
+
+ /// Sets instance of a dumper
+ MODELHIGHAPI_EXPORT
+ static void setInstance(ModelHighAPI_Dumper* theDumper);
+
+ /// Returns instance of a dumper
+ MODELHIGHAPI_EXPORT
+ static ModelHighAPI_Dumper* getInstance();
+
+ /// Destructor
+ virtual ~ModelHighAPI_Dumper() {}
+
+ /// Dump given document into the file
+ /// \return \c true, if succeed
+ MODELHIGHAPI_EXPORT
+ bool process(const std::shared_ptr<ModelAPI_Document>& theDoc, const std::string& theFileName);
+
+ /// Add module to list of imported modules
+ /// \param theModuleName name of the module to be imported
+ /// \param theObject name of the entity to be imported from the module (if empty, while module will be imported)
+ MODELHIGHAPI_EXPORT
+ void importModule(const std::string& theModuleName,
+ const std::string& theObject = std::string());
+
+ /// Returns name of specified entity
+ MODELHIGHAPI_EXPORT
+ const std::string& name(const EntityPtr& theEntity);
+
+ /// Returns name of parent composite feature for specified entity
+ MODELHIGHAPI_EXPORT
+ const std::string& parentName(const FeaturePtr& theFeature);
+
+ /// Dump given feature
+ virtual void dumpFeature(const FeaturePtr& theFeature, const bool theForce = false) = 0;
+
+ /// Save all dumps into specified file
+ MODELHIGHAPI_EXPORT
+ bool exportTo(const std::string& theFileName);
+
+ /// Dump character
+ MODELHIGHAPI_EXPORT
+ ModelHighAPI_Dumper& operator<<(const char theChar);
+ /// Dump string
+ MODELHIGHAPI_EXPORT
+ ModelHighAPI_Dumper& operator<<(const char* theString);
+ /// Dump string
+ MODELHIGHAPI_EXPORT
+ ModelHighAPI_Dumper& operator<<(const std::string& theString);
+ /// Dump integer
+ MODELHIGHAPI_EXPORT
+ ModelHighAPI_Dumper& operator<<(const int theValue);
+ /// Dump real
+ MODELHIGHAPI_EXPORT
+ ModelHighAPI_Dumper& operator<<(const double theValue);
+ /// Dump std::endl
+ friend
+ MODELHIGHAPI_EXPORT
+ ModelHighAPI_Dumper& operator<<(ModelHighAPI_Dumper& theDumper,
+ std::basic_ostream<char>& (*theEndl)(std::basic_ostream<char>&));
+
+ /// Dump GeomAPI_Pnt in the following form:
+ /// "GeomAPI_Pnt(X, Y, Z)"
+ MODELHIGHAPI_EXPORT
+ ModelHighAPI_Dumper& operator<<(const std::shared_ptr<GeomAPI_Pnt>& thePoint);
+ /// Dump GeomAPI_Dir
+ /// "GeomAPI_Dir(X, Y, Z)"
+ MODELHIGHAPI_EXPORT
+ ModelHighAPI_Dumper& operator<<(const std::shared_ptr<GeomAPI_Dir>& theDir);
+
+ /// Dump GeomDataAPI_Dir in the following form:
+ /// "X, Y, Z"
+ MODELHIGHAPI_EXPORT
+ ModelHighAPI_Dumper& operator<<(const std::shared_ptr<GeomDataAPI_Dir>& theDir);
+ /// Dump GeomDataAPI_Point in the following form:
+ /// "X, Y, Z"
+ MODELHIGHAPI_EXPORT
+ ModelHighAPI_Dumper& operator<<(const std::shared_ptr<GeomDataAPI_Point>& thePoint);
+ /// Dump GeomDataAPI_Point2D in the following form:
+ /// "X, Y"
+ MODELHIGHAPI_EXPORT
+ ModelHighAPI_Dumper& operator<<(const std::shared_ptr<GeomDataAPI_Point2D>& thePoint);
+
+ /// Dump AttributeBoolean
+ MODELHIGHAPI_EXPORT
+ ModelHighAPI_Dumper& operator<<(const std::shared_ptr<ModelAPI_AttributeBoolean>& theAttrBool);
+ /// Dump AttributeInteger
+ MODELHIGHAPI_EXPORT
+ ModelHighAPI_Dumper& operator<<(const std::shared_ptr<ModelAPI_AttributeInteger>& theAttrInt);
+ /// Dump AttributeDouble
+ MODELHIGHAPI_EXPORT
+ ModelHighAPI_Dumper& operator<<(const std::shared_ptr<ModelAPI_AttributeDouble>& theAttrReal);
+ /// Dump AttributeString
+ MODELHIGHAPI_EXPORT
+ ModelHighAPI_Dumper& operator<<(const std::shared_ptr<ModelAPI_AttributeString>& theAttrStr);
+ /// Dump name of entity and remember to dump "setName" if the entity has user-defined name
+ MODELHIGHAPI_EXPORT
+ ModelHighAPI_Dumper& operator<<(const EntityPtr& theEntity);
+
+ /// Dump AttributeSelection
+ MODELHIGHAPI_EXPORT
+ ModelHighAPI_Dumper& operator<<(const std::shared_ptr<ModelAPI_AttributeSelection>& theAttrSelect);
+
+protected:
+ /// Dump "setName" command if last entity had user-defined name
+ MODELHIGHAPI_EXPORT void dumpEntitySetName();
+
+ /// Clear dump buffer
+ void clear();
+
+private:
+ ModelHighAPI_Dumper(const ModelHighAPI_Dumper&);
+ const ModelHighAPI_Dumper& operator=(const ModelHighAPI_Dumper&);
+
+ /// Iterate all features in document and dump them into intermediate buffer
+ bool process(const std::shared_ptr<ModelAPI_Document>& theDoc);
+
+ /// Iterate all features in composite feature and dump them into intermediate buffer
+ bool process(const std::shared_ptr<ModelAPI_CompositeFeature>& theComposite);
+
+private:
+ typedef std::map<EntityPtr, std::pair<std::string, bool> > EntityNameMap;
+ typedef std::map<std::string, std::set<std::string> > ModulesMap;
+
+ static ModelHighAPI_Dumper* mySelf;
+
+ std::ostringstream myDumpBuffer; ///< intermediate buffer to store dumping data
+ ModulesMap myModules; ///< modules and entities to be imported
+ EntityNameMap myNames; ///< names of the entities
+ EntityPtr myLastEntityWithName; ///< not null, if last dumped entity had user defined name
+};
+
+#endif
class ModelAPI_Feature;
class ModelAPI_Result;
class ModelHighAPI_Selection;
+class ModelHighAPI_Dumper;
//--------------------------------------------------------------------------------------
/**\class ModelHighAPI_Interface
* \ingroup CPPHighAPI
MODELHIGHAPI_EXPORT
void throwException(const std::string & theDescription);
+ /// Dump wrapped feature
+ MODELHIGHAPI_EXPORT
+ virtual void dump(ModelHighAPI_Dumper& theDumper) const {}
+
protected:
std::shared_ptr<ModelAPI_Feature> myFeature;
};
#include <GeomAPI_Pnt.h>
#include <ModelAPI_Session.h>
+#include <cmath>
+
//--------------------------------------------------------------------------------------
std::shared_ptr<ModelAPI_Document> moduleDocument()
{
return std::shared_ptr<GeomAPI_Ax3>(new GeomAPI_Ax3(o, x, n));
}
+std::string defaultPlane(const std::shared_ptr<GeomAPI_Pnt>& theOrigin,
+ const std::shared_ptr<GeomAPI_Dir>& theNormal,
+ const std::shared_ptr<GeomAPI_Dir>& theDirX)
+{
+ static const double aTol = 1.e-10;
+
+ if (fabs(theOrigin->x()) > aTol || fabs(theOrigin->y()) > aTol || fabs(theOrigin->z()) > aTol)
+ return std::string();
+
+ // XOY or XOZ
+ if (fabs(theNormal->x()) < aTol &&
+ fabs(theDirX->x() - 1.0) < aTol && fabs(theDirX->y()) < aTol && fabs(theDirX->z()) < aTol) {
+ // XOY
+ if (fabs(theNormal->y()) < aTol && fabs(theNormal->z() - 1.0) < aTol)
+ return std::string("XOY");
+ else if (fabs(theNormal->y() + 1.0) < aTol && fabs(theNormal->z()) < aTol)
+ return std::string("XOZ");
+ }
+ // YOZ
+ else if (fabs(theNormal->x() - 1.0) < aTol && fabs(theNormal->y()) < aTol && fabs(theNormal->z()) < aTol &&
+ fabs(theDirX->x()) < aTol && fabs(theDirX->y() - 1.0) < aTol && fabs(theDirX->z()) < aTol)
+ return std::string("YOZ");
+
+ return std::string();
+}
+
//--------------------------------------------------------------------------------------
void begin()
{
#include <string>
//--------------------------------------------------------------------------------------
class GeomAPI_Ax3;
+class GeomAPI_Dir;
+class GeomAPI_Pnt;
class ModelAPI_Document;
//--------------------------------------------------------------------------------------
/// Return the main document (the Partset) created or open from the Modeler.
MODELHIGHAPI_EXPORT
std::shared_ptr<GeomAPI_Ax3> defaultPlane(const std::string & theName);
+/// Return name of coordinate plane ("XOY", "XOZ" or "YOZ") or empty string for other planes.
+MODELHIGHAPI_EXPORT
+std::string defaultPlane(const std::shared_ptr<GeomAPI_Pnt>& theOrigin,
+ const std::shared_ptr<GeomAPI_Dir>& theNormal,
+ const std::shared_ptr<GeomAPI_Dir>& theDirX);
+
/** Start a data structure transaction.
*
* Make a control point for being able to discard or undo
#include "ModelHighAPI.h"
#include "ModelHighAPI_Double.h"
+ #include "ModelHighAPI_Dumper.h"
#include "ModelHighAPI_Integer.h"
#include "ModelHighAPI_Interface.h"
#include "ModelHighAPI_Macro.h"
//--------------------------------------------------------------------------------------
#include "ParametersAPI_Parameter.h"
//--------------------------------------------------------------------------------------
+#include <ModelHighAPI_Dumper.h>
#include <ModelHighAPI_Tools.h>
//--------------------------------------------------------------------------------------
ParametersAPI_Parameter::ParametersAPI_Parameter(
{
}
+void ParametersAPI_Parameter::dump(ModelHighAPI_Dumper& theDumper) const
+{
+ FeaturePtr aBase = feature();
+ const std::string& aDocName = theDumper.name(aBase->document());
+ const std::string& aParamName = theDumper.name(aBase);
+
+ AttributeStringPtr anExpr = aBase->string(ParametersPlugin_Parameter::EXPRESSION_ID());
+ AttributeStringPtr aComment = aBase->string(ParametersPlugin_Parameter::COMMENT_ID());
+
+ theDumper << "model.addParameter(" << aDocName << ", \"" << aParamName << "\", " << anExpr;
+ if (aComment->isInitialized() && !aComment->value().empty())
+ theDumper << ", " << aComment;
+ theDumper << ")" << std::endl;
+}
+
//--------------------------------------------------------------------------------------
ParameterPtr addParameter(const std::shared_ptr<ModelAPI_Document> & thePart,
const std::string & theName,
comment, ParametersPlugin_Parameter::COMMENT_ID(), ModelAPI_AttributeString, /** Comment */
)
+ /// Dump wrapped feature
+ PARAMETERSAPI_EXPORT
+ virtual void dump(ModelHighAPI_Dumper& theDumper) const;
+
};
//! Pointer on Parameter object
#include "PartSetAPI_Part.h"
//--------------------------------------------------------------------------------------
#include <ModelAPI_ResultPart.h>
+#include <ModelHighAPI_Dumper.h>
//--------------------------------------------------------------------------------------
#include <PartSetPlugin_Duplicate.h>
#include <PartSetPlugin_Remove.h>
return std::dynamic_pointer_cast<ModelAPI_ResultPart>(defaultResult())->partDoc();
}
+void PartSetAPI_Part::dump(ModelHighAPI_Dumper& theDumper) const
+{
+ FeaturePtr aBase = feature();
+ const std::string& aDocName = theDumper.name(aBase->document());
+
+ theDumper << aBase << " = model.addPart(" << aDocName << ").document()" << std::endl;
+}
+
//--------------------------------------------------------------------------------------
PartPtr addPart(const std::shared_ptr<ModelAPI_Document> & thePart)
{
/// Return document
PARTSETAPI_EXPORT
std::shared_ptr<ModelAPI_Document> document() const;
+
+ /// Dump wrapped feature
+ PARTSETAPI_EXPORT
+ virtual void dump(ModelHighAPI_Dumper& theDumper) const;
};
//! Pointer on Part object
--- /dev/null
+"""Package for dumping purposes.
+"""
+
+import ModelHighAPI
+
+import ModelAPI
+
+import sys
+import inspect
+
+def singleton(cls):
+ instance = cls()
+ instance.__call__ = lambda: instance
+ return instance
+
+
+## @ingroup CPPHighAPI
+# Collect information about features that may be dumped and stores the model as a Python script
+@singleton
+class DumpAssistant(ModelHighAPI.ModelHighAPI_Dumper):
+
+ ## Constructor
+ def __init__(self):
+ ModelHighAPI.ModelHighAPI_Dumper.__init__(self)
+ ModelHighAPI.ModelHighAPI_Dumper.setInstance(self)
+ self.collectFeatures()
+
+ ## Collect feature wrappers, which allow dumping (have method dump)
+ def collectFeatures(self):
+ self.myFeatures = {}
+ for aModule in sys.modules:
+ for aName, anObj in inspect.getmembers(sys.modules[aModule], inspect.isclass):
+ if issubclass(anObj, ModelHighAPI.ModelHighAPI_Interface) and hasattr(anObj, "ID") and anObj.dump != ModelHighAPI.ModelHighAPI_Interface.dump:
+ self.myFeatures[anObj.ID()] = anObj
+
+ ## Create wrapper for a given feature and dump it
+ def dumpFeature(self, theFeature, theForce):
+ aFeatureKind = theFeature.getKind()
+ if aFeatureKind in self.myFeatures:
+ # Dump only feature created by user (in history).
+ # For all other features, just keep their name.
+ if theForce or aFeatureKind == "Parameter" or theFeature.isInHistory():
+ self.myFeatures[aFeatureKind](theFeature).dump(self)
+ else:
+ self.name(theFeature)
+
+
+# Instance of dumper
+dumper = DumpAssistant
\ No newline at end of file
--- /dev/null
+"""Package for dumping purposes.
+"""
+
+from DumpAssistant import *
//--------------------------------------------------------------------------------------
#include <GeomAPI_Pnt2d.h>
//--------------------------------------------------------------------------------------
+#include <ModelHighAPI_Dumper.h>
#include <ModelHighAPI_Selection.h>
#include <ModelHighAPI_Tools.h>
//--------------------------------------------------------------------------------------
}
//--------------------------------------------------------------------------------------
+
+void SketchAPI_Point::dump(ModelHighAPI_Dumper& theDumper) const
+{
+ FeaturePtr aBase = feature();
+ const std::string& aSketchName = theDumper.parentName(aBase);
+
+ AttributeSelectionPtr anExternal = aBase->selection(SketchPlugin_SketchEntity::EXTERNAL_ID());
+ if (anExternal->value()) {
+ // point is external
+ theDumper << aBase << " = " << aSketchName << ".addPoint(" << anExternal << ")" << std::endl;
+ } else {
+ // point given by coordinates
+ std::shared_ptr<GeomDataAPI_Point2D> aPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ aBase->attribute(SketchPlugin_Point::COORD_ID()));
+ theDumper << aBase << " = " << aSketchName << ".addPoint(" << aPoint << ")" << std::endl;
+ }
+}
/// Set by external name
SKETCHAPI_EXPORT
void setByExternalName(const std::string & theExternalName);
+
+ /// Dump wrapped feature
+ SKETCHAPI_EXPORT
+ virtual void dump(ModelHighAPI_Dumper& theDumper) const;
};
//! Pointer on Point object
//--------------------------------------------------------------------------------------
#include <ModelAPI_CompositeFeature.h>
#include <ModelAPI_ResultConstruction.h>
+#include <ModelHighAPI_Dumper.h>
#include <ModelHighAPI_RefAttr.h>
#include <ModelHighAPI_Selection.h>
+#include <ModelHighAPI_Services.h>
#include <ModelHighAPI_Tools.h>
//--------------------------------------------------------------------------------------
#include "SketchAPI_Arc.h"
}
//--------------------------------------------------------------------------------------
+
+void SketchAPI_Sketch::dump(ModelHighAPI_Dumper& theDumper) const
+{
+ FeaturePtr aBase = feature();
+ const std::string& aDocName = theDumper.name(aBase->document());
+
+ AttributeSelectionPtr anExternal = aBase->selection(SketchPlugin_SketchEntity::EXTERNAL_ID());
+ if (anExternal->value()) {
+ FeaturePtr aPlnFeature = ModelAPI_Feature::feature(anExternal->context()->data()->owner());
+ const std::string& aPlaneName = theDumper.name(aPlnFeature);
+ theDumper << aBase << " = model.addSketch(" << aDocName << ", \"" << aPlaneName << "\")" << std::endl;
+ } else {
+ // Sketch is base on a plane.
+ std::shared_ptr<GeomAPI_Pnt> anOrigin = std::dynamic_pointer_cast<GeomDataAPI_Point>(
+ aBase->attribute(SketchPlugin_Sketch::ORIGIN_ID()))->pnt();
+ std::shared_ptr<GeomAPI_Dir> aNormal = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
+ aBase->attribute(SketchPlugin_Sketch::NORM_ID()))->dir();
+ std::shared_ptr<GeomAPI_Dir> aDirX = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
+ aBase->attribute(SketchPlugin_Sketch::DIRX_ID()))->dir();
+
+ // Check the plane is coordinate plane
+ std::string aPlaneName = defaultPlane(anOrigin, aNormal, aDirX);
+ if (aPlaneName.empty()) {
+ // needs import additional module
+ theDumper.importModule("GeomAPI");
+ // dump plane parameters
+ const std::string& aSketchName = theDumper.name(aBase);
+ std::string anOriginName = aSketchName + "_origin";
+ std::string aNormalName = aSketchName + "_norm";
+ std::string aDirXName = aSketchName + "_dirx";
+ theDumper << anOriginName << " = " << anOrigin << std::endl
+ << aNormalName << " = " << aNormal << std::endl
+ << aDirXName << " = " << aDirX << std::endl;
+ // dump sketch based on arbitrary plane
+ theDumper << aBase << " = model.addSketch(" << aDocName << ", GeomAPI_Ax3("
+ << anOriginName << ", " << aDirXName << ", " << aNormalName << "))" << std::endl;
+ } else {
+ // dump sketch based on coordinate plane
+ theDumper << aBase << " = model.addSketch(" << aDocName
+ << ", model.defaultPlane(\"" << aPlaneName << "\"))" << std::endl;
+ }
+ }
+}
SKETCHAPI_EXPORT
std::list<ModelHighAPI_Selection> selectFace() const;
+ /// Dump wrapped feature
+ SKETCHAPI_EXPORT
+ virtual void dump(ModelHighAPI_Dumper& theDumper) const;
+
protected:
std::shared_ptr<ModelAPI_CompositeFeature> compositeFeature() const;