From c5c451ec3d7b112e169d0e82dd5b7e8f8f05e16a Mon Sep 17 00:00:00 2001 From: azv Date: Sat, 25 Nov 2017 16:58:05 +0300 Subject: [PATCH] Dumping of the folders to Python --- src/Model/Model_Document.h | 2 + src/ModelAPI/ModelAPI_Document.h | 4 +- src/ModelAPI/Test/TestFolder_Stability.py | 26 ++++++++- src/ModelHighAPI/ModelHighAPI.i | 1 + src/ModelHighAPI/ModelHighAPI_Dumper.cpp | 64 ++++++++++++++++++----- src/ModelHighAPI/ModelHighAPI_Dumper.h | 13 ++++- src/ModelHighAPI/ModelHighAPI_Folder.cpp | 59 +++++++++++++++++++-- src/ModelHighAPI/ModelHighAPI_Folder.h | 44 ++++++++++++++-- src/PythonAPI/model/dump/DumpAssistant.py | 5 ++ 9 files changed, 193 insertions(+), 25 deletions(-) diff --git a/src/Model/Model_Document.h b/src/Model/Model_Document.h index 946025f73..d4c178103 100644 --- a/src/Model/Model_Document.h +++ b/src/Model/Model_Document.h @@ -207,6 +207,8 @@ class Model_Document : public ModelAPI_Document feature(const std::shared_ptr& theResult); //! Creates a folder (group of the features in the object browser) + //! \param theAddBefore a feature, the folder is added before + //! (if empty, the folder is added after the last feature) MODEL_EXPORT virtual std::shared_ptr addFolder( std::shared_ptr theAddBefore = std::shared_ptr()); //! Removes the folder from the document (all features in the folder will be kept). diff --git a/src/ModelAPI/ModelAPI_Document.h b/src/ModelAPI/ModelAPI_Document.h index 525805b1d..dc4160da4 100644 --- a/src/ModelAPI/ModelAPI_Document.h +++ b/src/ModelAPI/ModelAPI_Document.h @@ -182,8 +182,10 @@ public: virtual std::list > allObjects() = 0; //! Creates a folder (group of the features in the object browser) + //! \param theAddBefore a feature, the folder is added before + //! (if empty, the folder is added after the last feature) virtual std::shared_ptr addFolder( - std::shared_ptr theAddBefore) = 0; + std::shared_ptr theAddBefore = std::shared_ptr()) = 0; //! Removes the folder from the document (all features in the folder will be kept). virtual void removeFolder(std::shared_ptr theFolder) = 0; //! Search a folder above the list of features applicable to store them diff --git a/src/ModelAPI/Test/TestFolder_Stability.py b/src/ModelAPI/Test/TestFolder_Stability.py index 9ceb2ee3e..bbd867cd0 100644 --- a/src/ModelAPI/Test/TestFolder_Stability.py +++ b/src/ModelAPI/Test/TestFolder_Stability.py @@ -64,11 +64,35 @@ assert(aPartDoc.size("Features") == NB_FEATURES_FULL), "Wrong number of features #========================================================================= # Test 1. Check number of features out of folder -# and absense of the crash while getting size of incorrect groupd +# and absense of the crash while getting size of incorrect group #========================================================================= assert(aPartDoc.size("Features", True) == NB_FEATURES_OUT), "Wrong number of features: {}, expected: {}".format(aPartDoc.size("Features", True), NB_FEATURES_OUT) assert(aPartDoc.size("Construction", True) == 1), "Wrong size: {}".format(aPartDoc.size("Construction", True)) +#========================================================================= +# Test 2. Add a feature to the folder and check number of features once again +#========================================================================= +toFolder = FeatureList() +toFolder.append(aPoint1) + +aSession.startOperation() +aFolder2 = aPartDoc.addFolder(aPoint1) +aSession.finishOperation() + +NB_FEATURES_FULL += 1 +NB_FEATURES_OUT += 1 + +aSession.startOperation() +aFolder = aPartDoc.findFolderAbove(toFolder) +assert(aFolder is not None) +isAdded = aPartDoc.moveToFolder(toFolder, aFolder) +aSession.finishOperation() +assert(isAdded) + +NB_FEATURES_OUT -= 1 +assert(aPartDoc.size("Features", True) == NB_FEATURES_OUT), "Wrong number of features: {}, expected: {}".format(aPartDoc.size("Features", True), NB_FEATURES_OUT) +assert(aPartDoc.size("Construction", True) == 1), "Wrong size: {}".format(aPartDoc.size("Construction", True)) + from salome.shaper import model assert(model.checkPythonDump()) diff --git a/src/ModelHighAPI/ModelHighAPI.i b/src/ModelHighAPI/ModelHighAPI.i index 268c97635..0b49cf05c 100644 --- a/src/ModelHighAPI/ModelHighAPI.i +++ b/src/ModelHighAPI/ModelHighAPI.i @@ -57,6 +57,7 @@ // shared pointers %shared_ptr(ModelHighAPI_Interface) +%shared_ptr(ModelHighAPI_Folder) // typemaps diff --git a/src/ModelHighAPI/ModelHighAPI_Dumper.cpp b/src/ModelHighAPI/ModelHighAPI_Dumper.cpp index 84f4eb556..90b6655b7 100644 --- a/src/ModelHighAPI/ModelHighAPI_Dumper.cpp +++ b/src/ModelHighAPI/ModelHighAPI_Dumper.cpp @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -124,14 +125,27 @@ const std::string& ModelHighAPI_Dumper::name(const EntityPtr& theEntity, return aFound->second.myCurrentName; // entity is not found, store it - std::string aName; + std::string aName, aKind; bool isDefaultName = false; + bool isSaveNotDumped = theSaveNotDumped; std::ostringstream aDefaultName; FeaturePtr aFeature = std::dynamic_pointer_cast(theEntity); if (aFeature) { aName = aFeature->name(); - const std::string& aKind = aFeature->getKind(); - DocumentPtr aDoc = aFeature->document(); + aKind = aFeature->getKind(); + } else { + FolderPtr aFolder = std::dynamic_pointer_cast(theEntity); + if (aFolder) { + aName = aFolder->data()->name(); + aKind = ModelAPI_Folder::ID(); + isSaveNotDumped = false; + myNotDumpedFolders.insert(aFolder); + } + } + + ObjectPtr anObject = std::dynamic_pointer_cast(theEntity); + if (anObject) { + DocumentPtr aDoc = anObject->document(); int& aNbFeatures = myFeatureCount[aDoc][aKind]; aNbFeatures += 1; @@ -164,7 +178,7 @@ const std::string& ModelHighAPI_Dumper::name(const EntityPtr& theEntity, } myNames[theEntity] = EntityName(aDefaultName.str(), aName, isDefaultName); - if (theSaveNotDumped) + if (isSaveNotDumped) myNotDumpedEntities.insert(theEntity); // store names of results @@ -238,18 +252,30 @@ bool ModelHighAPI_Dumper::process(const std::shared_ptr& theD bool ModelHighAPI_Dumper::process(const std::shared_ptr& theDoc) { bool isOk = true; - std::list aFeatures = theDoc->allFeatures(); - std::list::const_iterator aFeatIt = aFeatures.begin(); + std::list anObjects = theDoc->allObjects(); + std::list::const_iterator anObjIt = anObjects.begin(); // firstly, dump all parameters - for (; aFeatIt != aFeatures.end(); ++ aFeatIt) - dumpParameter(*aFeatIt); + for (; anObjIt != anObjects.end(); ++ anObjIt) { + FeaturePtr aFeature = std::dynamic_pointer_cast(*anObjIt); + if (aFeature) + dumpParameter(aFeature); + } // dump all other features - for (aFeatIt = aFeatures.begin(); aFeatIt != aFeatures.end(); ++aFeatIt) { - CompositeFeaturePtr aCompFeat = std::dynamic_pointer_cast(*aFeatIt); + for (anObjIt = anObjects.begin(); anObjIt != anObjects.end(); ++anObjIt) { + CompositeFeaturePtr aCompFeat = std::dynamic_pointer_cast(*anObjIt); if (aCompFeat) // iteratively process composite features isOk = process(aCompFeat) && isOk; - else if (!isDumped(*aFeatIt)) // dump common feature - dumpFeature(*aFeatIt); + else if (!isDumped(*anObjIt)) { + // dump folder + FolderPtr aFolder = std::dynamic_pointer_cast(*anObjIt); + if (aFolder) + dumpFolder(aFolder); + else { + FeaturePtr aFeature = std::dynamic_pointer_cast(*anObjIt); + if (aFeature) // dump common feature + dumpFeature(aFeature); + } + } } return isOk; } @@ -659,6 +685,13 @@ ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<( return *this; } +ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(const FolderPtr& theFolder) +{ + myDumpBuffer << name(theFolder); + myNotDumpedFolders.erase(theFolder); + return *this; +} + ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(const FeaturePtr& theEntity) { myDumpBuffer << name(theEntity); @@ -985,5 +1018,12 @@ ModelHighAPI_Dumper& operator<<(ModelHighAPI_Dumper& theDumper, // then store currently dumped string theDumper.myFullDump << aBufCopy; + // now, store all not dumped folders + std::set::const_iterator aFolderIt = theDumper.myNotDumpedFolders.begin(); + while (aFolderIt != theDumper.myNotDumpedFolders.end()) { + FolderPtr aFolder = *aFolderIt++; + theDumper.dumpFolder(aFolder); + } + return theDumper; } diff --git a/src/ModelHighAPI/ModelHighAPI_Dumper.h b/src/ModelHighAPI/ModelHighAPI_Dumper.h index c2fe0cd54..5bba14168 100644 --- a/src/ModelHighAPI/ModelHighAPI_Dumper.h +++ b/src/ModelHighAPI/ModelHighAPI_Dumper.h @@ -54,12 +54,14 @@ class ModelAPI_CompositeFeature; class ModelAPI_Document; class ModelAPI_Entity; class ModelAPI_Feature; +class ModelAPI_Folder; class ModelAPI_Object; class ModelAPI_Result; typedef std::shared_ptr DocumentPtr; typedef std::shared_ptr EntityPtr; typedef std::shared_ptr FeaturePtr; +typedef std::shared_ptr FolderPtr; typedef std::shared_ptr ResultPtr; /**\class ModelHighAPI_Dumper @@ -116,6 +118,8 @@ public: virtual void dumpParameter(const FeaturePtr& theFeature) = 0; /// Dump given feature virtual void dumpFeature(const FeaturePtr& theFeature, const bool theForce = false) = 0; + /// Dump folder + virtual void dumpFolder(const FolderPtr& theFolder) = 0; /// Set a feature that should not be dumped anyway MODELHIGHAPI_EXPORT @@ -203,6 +207,10 @@ public: MODELHIGHAPI_EXPORT ModelHighAPI_Dumper& operator<<(const FeaturePtr& theEntity); + /// Dump folder + MODELHIGHAPI_EXPORT + ModelHighAPI_Dumper& operator<<(const FolderPtr& theFolder); + /// Dump result MODELHIGHAPI_EXPORT ModelHighAPI_Dumper& operator<<(const ResultPtr& theResult); @@ -330,10 +338,13 @@ private: std::set myFeaturesToSkip; protected: - /// list of entities, used by other features but not dumped yet + /// list of entities, used by other features but not dumped yet std::set myNotDumpedEntities; + /// list of folders which do not dumped yet + std::set myNotDumpedFolders; friend class SketchAPI_Sketch; + friend class ModelHighAPI_Folder; }; #endif diff --git a/src/ModelHighAPI/ModelHighAPI_Folder.cpp b/src/ModelHighAPI/ModelHighAPI_Folder.cpp index 7cfa3215b..cbb986198 100644 --- a/src/ModelHighAPI/ModelHighAPI_Folder.cpp +++ b/src/ModelHighAPI/ModelHighAPI_Folder.cpp @@ -19,26 +19,75 @@ // #include "ModelHighAPI_Folder.h" -#include +#include +#include +#include #include -#include //-------------------------------------------------------------------------------------- ModelHighAPI_Folder::ModelHighAPI_Folder(const std::shared_ptr & theFolder) + : ModelHighAPI_Interface(FeaturePtr()), + myFolder(theFolder) { + initialize(); } - ModelHighAPI_Folder::~ModelHighAPI_Folder() { } +bool ModelHighAPI_Folder::initialize() +{ + if (!myFolder) { + throwException(ID() + " exception: The folder is NULL."); + return false; + } + + SET_ATTRIBUTE(firstFeature, ModelAPI_AttributeReference, ModelAPI_Folder::FIRST_FEATURE_ID()); + SET_ATTRIBUTE(lastFeature, ModelAPI_AttributeReference, ModelAPI_Folder::LAST_FEATURE_ID()); + + return true; +} + +void ModelHighAPI_Folder::dump(ModelHighAPI_Dumper& theDumper) const +{ + const std::string& aDocName = theDumper.name(myFolder->document()); + + AttributeReferencePtr aStartRef = myFolder->reference(ModelAPI_Folder::FIRST_FEATURE_ID()); + AttributeReferencePtr aEndRef = myFolder->reference(ModelAPI_Folder::LAST_FEATURE_ID()); + + // Dump folder if it is empty or when its features have been already dumped. + // Otherwise, just store the name of the folder. + if (!aEndRef->value()) + theDumper << myFolder << " = model.addFolder(" << aDocName << ")" << std::endl; + else if (theDumper.isDumped(aEndRef->value())) + theDumper << myFolder << " = model.addFolder(" << aDocName << ", " + << aStartRef << ", " << aEndRef << ")" << std::endl; + else + theDumper.name(myFolder); +} + //-------------------------------------------------------------------------------------- -std::shared_ptr addFolder(const std::shared_ptr& thePart) +std::shared_ptr addFolder(const std::shared_ptr& theDoc) { - std::shared_ptr aFolder;//// = thePart->addFolder(); + std::shared_ptr aFolder = theDoc->addFolder(); + return std::shared_ptr(new ModelHighAPI_Folder(aFolder)); +} + +std::shared_ptr addFolder(const std::shared_ptr& theDoc, + const ModelHighAPI_Reference& theFirstFeature, + const ModelHighAPI_Reference& theLastFeature) +{ + std::shared_ptr aFolder = theDoc->addFolder(theFirstFeature.feature()); + + AttributeReferencePtr aFirstFeatAttr = aFolder->reference(ModelAPI_Folder::FIRST_FEATURE_ID()); + theFirstFeature.fillAttribute(aFirstFeatAttr); + + AttributeReferencePtr aLastFeatAttr = aFolder->reference(ModelAPI_Folder::LAST_FEATURE_ID()); + theLastFeature.fillAttribute(aLastFeatAttr); + return std::shared_ptr(new ModelHighAPI_Folder(aFolder)); } diff --git a/src/ModelHighAPI/ModelHighAPI_Folder.h b/src/ModelHighAPI/ModelHighAPI_Folder.h index 2c7bc45d9..6713ff0a0 100644 --- a/src/ModelHighAPI/ModelHighAPI_Folder.h +++ b/src/ModelHighAPI/ModelHighAPI_Folder.h @@ -23,32 +23,66 @@ //-------------------------------------------------------------------------------------- #include +#include + +#include #include //-------------------------------------------------------------------------------------- +class ModelAPI_AttributeReference; class ModelAPI_Document; -class ModelAPI_Folder; -class ModelHighAPI_Selection; +class ModelHighAPI_Reference; //-------------------------------------------------------------------------------------- /**\class ModelHighAPI_Folder * \ingroup CPPHighAPI * \brief Class for filling ModelAPI_Folder */ -class ModelHighAPI_Folder +class ModelHighAPI_Folder : public ModelHighAPI_Interface { public: /// Constructor for a folder MODELHIGHAPI_EXPORT - explicit ModelHighAPI_Folder(const std::shared_ptr & theFolder); + explicit ModelHighAPI_Folder(const std::shared_ptr& theFolder); /// Destructor MODELHIGHAPI_EXPORT virtual ~ModelHighAPI_Folder(); + + static std::string ID() { return ModelAPI_Folder::ID(); } + virtual std::string getID() { return ID(); } + + /// First feature reference + std::shared_ptr firstFeature() const + { return myfirstFeature; } + + /// Last feature reference + std::shared_ptr lastFeature() const + { return mylastFeature; } + + /// Dump wrapped feature + MODELHIGHAPI_EXPORT virtual void dump(ModelHighAPI_Dumper& theDumper) const; + +protected: + bool initialize(); + +private: + std::shared_ptr myFolder; + + std::shared_ptr myfirstFeature; + std::shared_ptr mylastFeature; }; //-------------------------------------------------------------------------------------- /**\ingroup CPPHighAPI - * \brief Create Folder feature + * \brief Create empty Folder feature */ MODELHIGHAPI_EXPORT std::shared_ptr addFolder(const std::shared_ptr& theDoc); + +/**\ingroup CPPHighAPI + * \brief Create Folder feature + */ +MODELHIGHAPI_EXPORT +std::shared_ptr addFolder(const std::shared_ptr& theDoc, + const ModelHighAPI_Reference& theFirstFeature, + const ModelHighAPI_Reference& theLastFeature); //-------------------------------------------------------------------------------------- #endif /* SRC_MODELHIGHAPI_MODELHIGHAPI_FOLDER_H_ */ diff --git a/src/PythonAPI/model/dump/DumpAssistant.py b/src/PythonAPI/model/dump/DumpAssistant.py index f56860b04..0cdebfdfe 100644 --- a/src/PythonAPI/model/dump/DumpAssistant.py +++ b/src/PythonAPI/model/dump/DumpAssistant.py @@ -72,6 +72,11 @@ class DumpAssistant(ModelHighAPI.ModelHighAPI_Dumper): # In case of theFeature is not a constraint, it will not be dumped. self.myFeatures[SketchAPI.SketchAPI_Constraint.ID()](theFeature).dump(self) + ## Create wrapper for a folder and dump it + def dumpFolder(self, theFolder): + if theFolder.ID() in self.myFeatures: + self.myFeatures[theFolder.ID()](theFolder).dump(self) + ## Dump all parameters def dumpParameter(self, theFeature): aFeatureKind = theFeature.getKind() -- 2.39.2