]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Dump Python in the High Level Parameterized Geometry API (issue #1648)
authorazv <azv@opencascade.com>
Fri, 19 Aug 2016 08:58:57 +0000 (11:58 +0300)
committerazv <azv@opencascade.com>
Fri, 19 Aug 2016 11:20:07 +0000 (14:20 +0300)
* Store user-defined names for Result features

src/ModelHighAPI/ModelHighAPI_Dumper.cpp
src/ModelHighAPI/ModelHighAPI_Dumper.h
src/ModelHighAPI/ModelHighAPI_FeatureStore.cpp
src/ModelHighAPI/ModelHighAPI_Selection.cpp
src/ModelHighAPI/ModelHighAPI_Selection.h

index 79f01ab6b5c0ceecdbf9df8496a853ed4b138755..4bfd11a38132c4ee088dd6ee41b1751db0814f07 100644 (file)
@@ -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<std::string, std::string>(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<ResultPtr>& aResults = theFeature->results();
+  std::list<ResultPtr>::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<std::string, std::string>(aResName,
+        isUserDefined ? aResName : std::string());
+  }
+}
+
 bool ModelHighAPI_Dumper::process(const std::shared_ptr<ModelAPI_Document>& theDoc,
                                   const std::string& theFileName)
 {
@@ -191,6 +219,8 @@ bool ModelHighAPI_Dumper::process(const std::shared_ptr<ModelAPI_CompositeFeatur
     if (!aPartResult)
       return false;
     DocumentPtr aSubDoc = aPartResult->partDoc();
+    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<ModelAPI_CompositeFe
       dumpFeature(aFeature, true);
   }
 
+  bool isDumpSetName = !myEntitiesStack.empty() &&
+      myEntitiesStack.top().myEntity == EntityPtr(theComposite);
+  bool isForceModelDo = isDumpSetName &&
+      (myEntitiesStack.top().myUserName || !myEntitiesStack.top().myResultsWithName.empty());
   // It is necessary for the sketch to create its result when complete (command "model.do()").
   // This option is set by flat theDumpModelDo.
   // However, nested sketches are rebuilt by parent feature, so, they do not need
   // explicit call of "model.do()". This will be controlled by the depth of the stack.
-  if (theDumpModelDo && gCompositeStackDepth <= 1)
+  if (isForceModelDo || (theDumpModelDo && gCompositeStackDepth <= 1))
     *this << "model.do()" << std::endl;
+
+  // dump "setName" for composite feature
+  if (isDumpSetName)
+    dumpEntitySetName();
   return isOk;
 }
 
@@ -268,6 +306,7 @@ bool ModelHighAPI_Dumper::exportTo(const std::string& theFileName)
 
   // dump collected data
   aFile << myFullDump.str();
+  aFile << myDumpBuffer.str();
 
   // standard footer
   aFile << "model.end()" << std::endl;
@@ -286,14 +325,28 @@ void ModelHighAPI_Dumper::importModule(const std::string& theModuleName,
 
 void ModelHighAPI_Dumper::dumpEntitySetName()
 {
-  if (!myLastEntityWithName)
-    return;
+  const LastDumpedEntity& aLastDumped = myEntitiesStack.top();
+
+  // dump "setName" for the entity
+  if (aLastDumped.myUserName) {
+    std::pair<std::string, std::string> 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<ResultPtr>::const_iterator aResIt = aLastDumped.myResultsWithName.begin();
+  std::list<ResultPtr>::const_iterator aResEnd = aLastDumped.myResultsWithName.end();
+  for (; aResIt != aResEnd; ++aResIt) {
+    std::pair<std::string, std::string> 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<std::string, std::string> 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<ResultPtr> aResultsWithUserName;
+  const std::list<ResultPtr>& aResults = theEntity->results();
+  std::list<ResultPtr>::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<char>& (*theEndl)(std::basic_ostream<char>&))
 {
   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<ModelAPI_CompositeFeature>(aLastDumped.myEntity);
+    if (!aComposite)
+      theDumper.dumpEntitySetName();
+  }
 
   // store all not-dumped entities first
   std::set<EntityPtr> aNotDumped = theDumper.myNotDumpedEntities;
index 79e6850e94ef9a844342ecc25039eed601491255..11b6775a8e7f4fd481a78219bfac9c7b0a5fdae2 100644 (file)
@@ -14,6 +14,7 @@
 #include <memory>
 #include <set>
 #include <sstream>
+#include <stack>
 #include <string>
 
 class GeomAPI_Pnt;
@@ -44,7 +45,7 @@ class ModelAPI_Result;
 typedef std::shared_ptr<ModelAPI_Document> DocumentPtr;
 typedef std::shared_ptr<ModelAPI_Entity>   EntityPtr;
 typedef std::shared_ptr<ModelAPI_Feature>  FeaturePtr;
-typedef std::shared_ptr<ModelAPI_Result> ResultPtr;
+typedef std::shared_ptr<ModelAPI_Result>   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<EntityPtr, std::pair<std::string, std::string> > EntityNameMap;
-  typedef std::map<std::string, std::set<std::string> >      ModulesMap;
-  typedef std::map<DocumentPtr, std::map<std::string, int> > NbFeaturesMap;
+  typedef std::map<std::string, std::set<std::string> >             ModulesMap;
+  typedef std::map<DocumentPtr, std::map<std::string, int> >        NbFeaturesMap;
+
+  struct LastDumpedEntity {
+    EntityPtr            myEntity; // last dumped entity
+    bool                 myUserName; // the entity hase user-defined name
+    std::list<ResultPtr> myResultsWithName; // results of this entity, which has user-defined names
+
+    LastDumpedEntity(EntityPtr theEntity, bool theUserName, const std::list<ResultPtr>& theResults)
+      : myEntity(theEntity), myUserName(theUserName), myResultsWithName(theResults)
+    {}
+  };
+  typedef std::stack<LastDumpedEntity>                              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
 
index 0200b851e476282a2d6554c821065972912d76cd..7f4e3e58ae1c8f63c1c246dee2e58203b11b0d27 100644 (file)
@@ -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<GeomDataAPI_Point2D>(theAttr);
     double aValues[2] = {anAttr->x(), anAttr->y()};
     dumpArray(aResult, aValues, 2);
index e45f008c08f94b0dfde904998e1dbd23e3f47c51..265d0635ffca2e69aa27b9fa92fb468bbd061a2f 100644 (file)
@@ -90,3 +90,11 @@ std::string ModelHighAPI_Selection::shapeType() const
 
   return "SHAPE";
 }
+
+//==================================================================================================
+std::shared_ptr<ModelAPI_Result> ModelHighAPI_Selection::result() const
+{
+  if (myVariantType == VT_ResultSubShapePair)
+    return myResultSubShapePair.first;
+  return ResultPtr();
+}
index 2e1507ff139ea8da3f44b367de3f1641728d3e3e..fcea8f5a5ea80863de017130dad00858e78f0841 100644 (file)
@@ -76,6 +76,10 @@ public:
   MODELHIGHAPI_EXPORT
   virtual std::string shapeType() const;
 
+  /// \return Result if exists.
+  MODELHIGHAPI_EXPORT
+  virtual std::shared_ptr<ModelAPI_Result> result() const;
+
 private:
   VariantType myVariantType;
   ResultSubShapePair myResultSubShapePair;