From fb487c9f05bad69b5091b2eefdf4c0ef019c46d6 Mon Sep 17 00:00:00 2001 From: azv Date: Fri, 19 Aug 2016 11:58:57 +0300 Subject: [PATCH] Dump Python in the High Level Parameterized Geometry API (issue #1648) * Store user-defined names for Result features --- src/ModelHighAPI/ModelHighAPI_Dumper.cpp | 99 ++++++++++++++++--- src/ModelHighAPI/ModelHighAPI_Dumper.h | 23 ++++- .../ModelHighAPI_FeatureStore.cpp | 3 + src/ModelHighAPI/ModelHighAPI_Selection.cpp | 8 ++ src/ModelHighAPI/ModelHighAPI_Selection.h | 4 + 5 files changed, 120 insertions(+), 17 deletions(-) diff --git a/src/ModelHighAPI/ModelHighAPI_Dumper.cpp b/src/ModelHighAPI/ModelHighAPI_Dumper.cpp index 79f01ab6b..4bfd11a38 100644 --- a/src/ModelHighAPI/ModelHighAPI_Dumper.cpp +++ b/src/ModelHighAPI/ModelHighAPI_Dumper.cpp @@ -71,7 +71,8 @@ void ModelHighAPI_Dumper::clear(bool bufferOnly) myNames.clear(); myModules.clear(); myFeatureCount.clear(); - myLastEntityWithName = EntityPtr(); + while (!myEntitiesStack.empty()) + myEntitiesStack.pop(); } } @@ -99,7 +100,7 @@ const std::string& ModelHighAPI_Dumper::name(const EntityPtr& theEntity, bool th size_t anIndex = aName.find(aKind); if (anIndex == 0 && aName[aKind.length()] == '_') { // name starts with "FeatureKind_" - std::string anIdStr = aName.substr(aKind.length() + 1, std::string::npos); + std::string anIdStr = aName.substr(aKind.length() + 1); int anId = std::stoi(anIdStr); // Check number of already registered objects of such kind. Index of current object @@ -119,6 +120,9 @@ const std::string& ModelHighAPI_Dumper::name(const EntityPtr& theEntity, bool th aFullIndex += aFound->second; } aDefaultName << aKind << "_" << aFullIndex; + + // store names of results + saveResultNames(aFeature); } myNames[theEntity] = std::pair(aDefaultName.str(), aName); @@ -142,6 +146,30 @@ const std::string& ModelHighAPI_Dumper::parentName(const FeaturePtr& theEntity) return DUMMY; } +void ModelHighAPI_Dumper::saveResultNames(const FeaturePtr& theFeature) +{ + std::string aFeatureName = theFeature->name(); + const std::list& aResults = theFeature->results(); + std::list::const_iterator aResIt = aResults.begin(); + for (int i = 1; aResIt != aResults.end(); ++aResIt, ++i) { + bool isUserDefined = true; + std::string aResName = (*aResIt)->data()->name(); + size_t anIndex = aResName.find(aFeatureName); + if (anIndex == 0) { + std::string aSuffix = aResName.substr(aFeatureName.length()); + if (aSuffix.empty() && i == 1) // first result may not constain index in the name + isUserDefined = false; + else { + if (aSuffix[0] == '_' && std::stoi(aSuffix.substr(1)) == i) + isUserDefined = false; + } + } + + myNames[*aResIt] = std::pair(aResName, + isUserDefined ? aResName : std::string()); + } +} + bool ModelHighAPI_Dumper::process(const std::shared_ptr& theDoc, const std::string& theFileName) { @@ -191,6 +219,8 @@ bool ModelHighAPI_Dumper::process(const std::shared_ptrpartDoc(); + if (!aSubDoc) + return false; // set name of document const std::string& aPartName = myNames[theComposite].first; std::string aDocName = aPartName + "_doc"; @@ -228,12 +258,20 @@ bool ModelHighAPI_Dumper::processSubs(const std::shared_ptr anEntityNames = myNames[aLastDumped.myEntity]; + if (!anEntityNames.second.empty()) + myDumpBuffer << anEntityNames.first << ".setName(\"" << anEntityNames.second << "\")" << std::endl; + anEntityNames.second.clear(); // don't dump "setName" for the entity twice + } + // dump "setName" for results + std::list::const_iterator aResIt = aLastDumped.myResultsWithName.begin(); + std::list::const_iterator aResEnd = aLastDumped.myResultsWithName.end(); + for (; aResIt != aResEnd; ++aResIt) { + std::pair anEntityNames = myNames[*aResIt]; + if (!anEntityNames.second.empty()) { + *this << *aResIt; + myDumpBuffer << ".result().data().setName(\"" << anEntityNames.second << "\")" << std::endl; + anEntityNames.second.clear(); // don't dump "setName" for the entity twice + } + } - std::pair anEntityNames = myNames[myLastEntityWithName]; - if (!anEntityNames.second.empty()) - myDumpBuffer << anEntityNames.first << ".setName(\"" << anEntityNames.second << "\")" << std::endl; - anEntityNames.second.clear(); // don't dump "setName" for the entity twice - myLastEntityWithName = EntityPtr(); + myEntitiesStack.pop(); } bool ModelHighAPI_Dumper::isDumped(const EntityPtr& theEntity) const @@ -433,8 +486,19 @@ ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<( ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(const FeaturePtr& theEntity) { myDumpBuffer << name(theEntity); - if (!myNames[theEntity].second.empty()) - myLastEntityWithName = theEntity; + + bool isUserDefindName = !myNames[theEntity].second.empty(); + // store results if they have user-defined names + std::list aResultsWithUserName; + const std::list& aResults = theEntity->results(); + std::list::const_iterator aResIt = aResults.begin(); + for (; aResIt != aResults.end(); ++aResIt) + if (!myNames[*aResIt].second.empty()) + aResultsWithUserName.push_back(*aResIt); + // store just dumped entity to stack + myEntitiesStack.push(LastDumpedEntity(theEntity, isUserDefindName, aResultsWithUserName)); + + // remove entity from the list of not dumped items myNotDumpedEntities.erase(theEntity); return *this; } @@ -616,7 +680,16 @@ ModelHighAPI_Dumper& operator<<(ModelHighAPI_Dumper& theDumper, std::basic_ostream& (*theEndl)(std::basic_ostream&)) { theDumper.myDumpBuffer << theEndl; - theDumper.dumpEntitySetName(); + + if (!theDumper.myEntitiesStack.empty()) { + // Name for composite feature is dumped when all sub-entities are dumped + // (see method ModelHighAPI_Dumper::processSubs). + const ModelHighAPI_Dumper::LastDumpedEntity& aLastDumped = theDumper.myEntitiesStack.top(); + CompositeFeaturePtr aComposite = + std::dynamic_pointer_cast(aLastDumped.myEntity); + if (!aComposite) + theDumper.dumpEntitySetName(); + } // store all not-dumped entities first std::set aNotDumped = theDumper.myNotDumpedEntities; diff --git a/src/ModelHighAPI/ModelHighAPI_Dumper.h b/src/ModelHighAPI/ModelHighAPI_Dumper.h index 79e6850e9..11b6775a8 100644 --- a/src/ModelHighAPI/ModelHighAPI_Dumper.h +++ b/src/ModelHighAPI/ModelHighAPI_Dumper.h @@ -14,6 +14,7 @@ #include #include #include +#include #include class GeomAPI_Pnt; @@ -44,7 +45,7 @@ class ModelAPI_Result; typedef std::shared_ptr DocumentPtr; typedef std::shared_ptr EntityPtr; typedef std::shared_ptr FeaturePtr; -typedef std::shared_ptr ResultPtr; +typedef std::shared_ptr ResultPtr; /**\class ModelHighAPI_Dumper * \ingroup CPPHighAPI @@ -227,10 +228,24 @@ private: /// Check the entity is already dumped bool isDumped(const EntityPtr& theEntity) const; + /// Stores names of results for the given feature + void saveResultNames(const FeaturePtr& theFeature); + private: typedef std::map > EntityNameMap; - typedef std::map > ModulesMap; - typedef std::map > NbFeaturesMap; + typedef std::map > ModulesMap; + typedef std::map > NbFeaturesMap; + + struct LastDumpedEntity { + EntityPtr myEntity; // last dumped entity + bool myUserName; // the entity hase user-defined name + std::list myResultsWithName; // results of this entity, which has user-defined names + + LastDumpedEntity(EntityPtr theEntity, bool theUserName, const std::list& theResults) + : myEntity(theEntity), myUserName(theUserName), myResultsWithName(theResults) + {} + }; + typedef std::stack DumpStack; static ModelHighAPI_Dumper* mySelf; @@ -239,7 +254,7 @@ private: 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 + DumpStack myEntitiesStack; ///< stack of dumped entities NbFeaturesMap myFeatureCount; ///< number of features of each kind diff --git a/src/ModelHighAPI/ModelHighAPI_FeatureStore.cpp b/src/ModelHighAPI/ModelHighAPI_FeatureStore.cpp index 0200b851e..7f4e3e58a 100644 --- a/src/ModelHighAPI/ModelHighAPI_FeatureStore.cpp +++ b/src/ModelHighAPI/ModelHighAPI_FeatureStore.cpp @@ -268,6 +268,9 @@ std::string ModelHighAPI_FeatureStore::dumpAttr(const AttributePtr& theAttr) { double aValues[3] = {anAttr->x(), anAttr->y(), anAttr->z()}; dumpArray(aResult, aValues, 3); } else if (aType == GeomDataAPI_Point2D::typeId()) { + // do not dump flyout point for constraints as it may be changed unexpectedly + if (theAttr->id() == "ConstraintFlyoutValuePnt") + return ""; AttributePoint2DPtr anAttr = std::dynamic_pointer_cast(theAttr); double aValues[2] = {anAttr->x(), anAttr->y()}; dumpArray(aResult, aValues, 2); diff --git a/src/ModelHighAPI/ModelHighAPI_Selection.cpp b/src/ModelHighAPI/ModelHighAPI_Selection.cpp index e45f008c0..265d0635f 100644 --- a/src/ModelHighAPI/ModelHighAPI_Selection.cpp +++ b/src/ModelHighAPI/ModelHighAPI_Selection.cpp @@ -90,3 +90,11 @@ std::string ModelHighAPI_Selection::shapeType() const return "SHAPE"; } + +//================================================================================================== +std::shared_ptr ModelHighAPI_Selection::result() const +{ + if (myVariantType == VT_ResultSubShapePair) + return myResultSubShapePair.first; + return ResultPtr(); +} diff --git a/src/ModelHighAPI/ModelHighAPI_Selection.h b/src/ModelHighAPI/ModelHighAPI_Selection.h index 2e1507ff1..fcea8f5a5 100644 --- a/src/ModelHighAPI/ModelHighAPI_Selection.h +++ b/src/ModelHighAPI/ModelHighAPI_Selection.h @@ -76,6 +76,10 @@ public: MODELHIGHAPI_EXPORT virtual std::string shapeType() const; + /// \return Result if exists. + MODELHIGHAPI_EXPORT + virtual std::shared_ptr result() const; + private: VariantType myVariantType; ResultSubShapePair myResultSubShapePair; -- 2.39.2