Salome HOME
Fix for the robinet model with partitions: final groups selection with neighbors...
authormpv <mpv@opencascade.com>
Fri, 21 Dec 2018 15:28:45 +0000 (18:28 +0300)
committermpv <mpv@opencascade.com>
Fri, 21 Dec 2018 15:28:45 +0000 (18:28 +0300)
src/Model/Model_BodyBuilder.cpp
src/Model/Model_BodyBuilder.h
src/Model/Model_Document.cpp
src/Model/Model_ResultBody.cpp
src/Model/Model_ResultBody.h
src/ModelAPI/ModelAPI_BodyBuilder.h
src/ModelAPI/ModelAPI_ResultBody.h
src/Selector/Selector_Algo.cpp
src/Selector/Selector_FilterByNeighbors.cpp
src/Selector/Selector_FilterByNeighbors.h

index fee31e5c48e8e1600af0e4dd2b60806cc0cd98c1..f22dfe5bde5b3b78b6050632cf3dbe36a5480317 100755 (executable)
@@ -267,6 +267,11 @@ void Model_BodyBuilder::clean()
   }
 }
 
+void Model_BodyBuilder::cleanCash()
+{
+  myPrimitivesNamesIndexMap.clear();
+}
+
 Model_BodyBuilder::~Model_BodyBuilder()
 {
   clean();
index 0689a0f52c6e22625a66bda0d0155e2e11e622ce..8487a6b818720f69e1c0efbe00a53abadb6b8c63 100755 (executable)
@@ -108,6 +108,8 @@ public:
   /// Removes the stored builders
   MODEL_EXPORT virtual ~Model_BodyBuilder();
 
+  /// Cleans cash related to the already stored elements
+  MODEL_EXPORT virtual void cleanCash() override;
 protected:
   /// Default constructor accessible only by Model_Objects
   Model_BodyBuilder(ModelAPI_Object* theOwner);
index a8a82e1af680f5f0dfbfc2c1897a32eed5e30013..bed5d345584cf0ec14bc9f99a607f457fbeab296 100755 (executable)
@@ -365,7 +365,10 @@ bool Model_Document::save(
   Handle(Model_Application) anApp = Model_Application::getApplication();
   if (isRoot()) {
 #ifdef WIN32
-    CreateDirectory((LPTSTR) theDirName, NULL);
+    size_t aDirLen = strlen(theDirName);
+    std::wstring aWStr(aDirLen, L'#');
+    mbstowcs(&aWStr[0], theDirName, aDirLen);
+    CreateDirectory(aWStr.c_str(), NULL);
 #else
     mkdir(theDirName, 0x1ff);
 #endif
index 8f8c218bb0bbc22529f54ddf102bd352c96c2066..4acd17d8fa0a3732d69c6da75779ca9ee9aea54a 100644 (file)
@@ -272,8 +272,8 @@ void Model_ResultBody::updateSubs(const std::shared_ptr<GeomAPI_Shape>& theThisS
         aSub = mySubs[aSubIndex];
       }
       GeomShapePtr anOldSubShape = aSub->shape();
-      aSub->store(aShape, false); // store even equal to call "clear": #2814
       if (!aShape->isEqual(anOldSubShape)) {
+        aSub->store(aShape, false);
         aECreator->sendUpdated(aSub, EVENT_DISP);
         aECreator->sendUpdated(aSub, EVENT_UPD);
       }
@@ -294,6 +294,7 @@ void Model_ResultBody::updateSubs(const std::shared_ptr<GeomAPI_Shape>& theThisS
       // redisplay this because result with and without subs are displayed differently
       aECreator->sendUpdated(data()->owner(), EVENT_DISP);
     }
+    cleanCash();
   } else if (!mySubs.empty()) { // erase all subs
     while(!mySubs.empty()) {
       ResultBodyPtr anErased = *(mySubs.rbegin());
@@ -327,3 +328,14 @@ bool Model_ResultBody::isConnectedTopology()
   }
   return false; // invalid case
 }
+
+void Model_ResultBody::cleanCash()
+{
+  myBuilder->cleanCash();
+  for (std::vector<ResultBodyPtr>::const_iterator aSubIter = mySubs.cbegin();
+    aSubIter != mySubs.cend(); ++aSubIter)
+  {
+    const ResultBodyPtr& aSub = *aSubIter;
+    aSub->cleanCash();
+  }
+}
index 721ad71f33402952dc1babfbcd68809d34efdc6d..09824971fb842b2d53223bde2e8ec6354c1b6227 100644 (file)
@@ -98,6 +98,9 @@ public:
   /// Returns true is the topology is connected.
   MODEL_EXPORT virtual bool isConnectedTopology();
 
+  /// Cleans cash related to the already stored elements
+  MODEL_EXPORT virtual void cleanCash() override;
+
 protected:
   /// Makes a body on the given feature
   Model_ResultBody();
index 6523241df7f2262654cd9f31e8fe5824153c6337..f72202360adc13f33d0ef7addd1e0fe45490dfdc 100755 (executable)
@@ -98,6 +98,9 @@ public:
   virtual void loadFirstLevel(GeomShapePtr theShape,
                               const std::string& theName) = 0;
 
+  /// Cleans cash related to the already stored elements
+  MODELAPI_EXPORT virtual void cleanCash() = 0;
+
 protected:
   /// Returns the data manager of this object: attributes
   MODELAPI_EXPORT virtual std::shared_ptr<ModelAPI_Data> data() const;
index c41854f9d081c6c82e9dd7a35ba1c0592c66b0d3..20e0879f24f880a48337e4a02acdb3e2b39b803c 100644 (file)
@@ -165,6 +165,9 @@ public:
   MODELAPI_EXPORT virtual void updateSubs(const GeomShapePtr& theThisShape,
     const bool theShapeChanged = true) = 0;
 
+  /// Cleans cash related to the already stored elements
+  MODELAPI_EXPORT virtual void cleanCash() = 0;
+
 protected:
   /// Default constructor accessible only from Model_Objects
   MODELAPI_EXPORT ModelAPI_ResultBody();
index ee31d00bd04b1e40a4759e71cc39c2cc8d107ba5..0ddc2ae56b0d84194900972fdfe74af83c0b93de 100644 (file)
@@ -67,6 +67,24 @@ Selector_Algo::Selector_Algo()
   myAlwaysGeometricalNaming = false;
 }
 
+static TDF_Label findGoodLabelWithShape(const TDF_Label theAccess, const TopoDS_Shape& theShape) {
+  TDF_Label aResult;
+  if (TNaming_Tool::HasLabel(theAccess, theShape)) { // selection and delete evolution are not used
+    for(TNaming_SameShapeIterator aShapes(theShape, theAccess); aShapes.More(); aShapes.Next())
+    {
+      Handle(TNaming_NamedShape) aNS;
+      if (aShapes.Label().FindAttribute(TNaming_NamedShape::GetID(), aNS)) {
+        if (aNS->Evolution() == TNaming_MODIFY || aNS->Evolution() == TNaming_GENERATED ||
+            aNS->Evolution() == TNaming_PRIMITIVE) {
+          aResult = aNS->Label();
+          break;
+        }
+      }
+    }
+  }
+  return aResult;
+}
+
 #define SET_ALGO_FLAGS(algo) \
   algo->myLab = theAccess; \
   algo->myBaseDocumentLab = theBaseDocument; \
@@ -86,37 +104,9 @@ Selector_Algo* Selector_Algo::select(const TopoDS_Shape theContext, const TopoDS
 
   // check the value shape can be named as it is, or it is needed to construct it from the
   // higher level shapes (like a box vertex by faces that form this vertex)
-  bool aIsFound = TNaming_Tool::HasLabel(theAccess, theValue);
-  if (aIsFound) { // additional check for selection and delete evolution only: also could not use
-    aIsFound = false;
-    for(TNaming_SameShapeIterator aShapes(theValue, theAccess); aShapes.More(); aShapes.Next())
-    {
-      Handle(TNaming_NamedShape) aNS;
-      if (aShapes.Label().FindAttribute(TNaming_NamedShape::GetID(), aNS)) {
-        if (aNS->Evolution() == TNaming_MODIFY || aNS->Evolution() == TNaming_GENERATED ||
-          aNS->Evolution() == TNaming_PRIMITIVE) {
-          aIsFound = true;
-          break;
-        }
-      }
-    }
-  }
-  // searching in the base document
-  if (!aIsFound && !theBaseDocument.IsNull() && TNaming_Tool::HasLabel(theBaseDocument, theValue))
-  {
-    TNaming_SameShapeIterator aShapes(theValue, theBaseDocument);
-    for(; aShapes.More(); aShapes.Next())
-    {
-      Handle(TNaming_NamedShape) aNS;
-      if (aShapes.Label().FindAttribute(TNaming_NamedShape::GetID(), aNS)) {
-        if (aNS->Evolution() == TNaming_MODIFY || aNS->Evolution() == TNaming_GENERATED ||
-          aNS->Evolution() == TNaming_PRIMITIVE) {
-          aIsFound = true;
-          break;
-        }
-      }
-    }
-  }
+  bool aIsFound = !findGoodLabelWithShape(theAccess, theValue).IsNull();
+  if (!aIsFound && !theBaseDocument.IsNull()) // searching in the base document
+    aIsFound = !findGoodLabelWithShape(theBaseDocument, theValue).IsNull();
   if (!aIsFound) {
     TopAbs_ShapeEnum aSelectionType = theValue.ShapeType();
     if (aSelectionType == TopAbs_COMPOUND || aSelectionType == TopAbs_COMPSOLID ||
@@ -144,7 +134,11 @@ Selector_Algo* Selector_Algo::select(const TopoDS_Shape theContext, const TopoDS
     // searching by neighbors
     Selector_FilterByNeighbors* aNBs = new Selector_FilterByNeighbors;
     SET_ALGO_FLAGS(aNBs);
-    if (aNBs->select(theContext, theValue)) {
+    // searching a context lab to store in NB algorithm
+    TDF_Label aContextLab = findGoodLabelWithShape(theAccess, theContext);
+    if (aContextLab.IsNull() && !theBaseDocument.IsNull()) // search also in the base document
+      aContextLab = findGoodLabelWithShape(theBaseDocument, theContext);
+    if (aNBs->select(aContextLab, theContext, theValue)) {
       delete anIntersect;
       return aNBs;
     }
@@ -213,7 +207,11 @@ Selector_Algo* Selector_Algo::select(const TopoDS_Shape theContext, const TopoDS
     // searching by neighbors
     Selector_FilterByNeighbors* aNBs = new Selector_FilterByNeighbors;
     SET_ALGO_FLAGS(aNBs);
-    if (aNBs->select(theContext, theValue)) {
+    // searching a context lab to store in NB algorithm
+    TDF_Label aContextLab = findGoodLabelWithShape(theAccess, theContext);
+    if (aContextLab.IsNull() && !theBaseDocument.IsNull()) // search also in the base document
+      aContextLab = findGoodLabelWithShape(theBaseDocument, theContext);
+    if (aNBs->select(aContextLab, theContext, theValue)) {
       delete aModify;
       return aNBs;
     }
@@ -472,9 +470,12 @@ bool Selector_Algo::findNewVersion(const TopoDS_Shape& theContext, TopoDS_Shape&
         if (aNextModification.IsNull())
           continue;
         if (isInContext(theContext, aNextModification))
-          aResultShapes.Add(aNextModification);
+          // don't add vertices generated from edges
+          if (aNextModification.ShapeType() <= theResult.ShapeType())
+            aResultShapes.Add(aNextModification);
         else if (findNewVersion(theContext, aNextModification))
-          aResultShapes.Add(aNextModification);
+          if (aNextModification.ShapeType() <= theResult.ShapeType())
+            aResultShapes.Add(aNextModification);
       }
     }
     if (aResultShapes.IsEmpty())
index 09e0ab314ec7c462988ee8a55258e8ed78a77ea7..908ca5fa1a24352286d5c9dfc364e70b78809181 100644 (file)
@@ -176,9 +176,11 @@ static const TopoDS_Shape findNeighbor(const TopoDS_Shape theContext,
   return aGoodCandidate;
 }
 
-bool Selector_FilterByNeighbors::select(const TopoDS_Shape theContext, const TopoDS_Shape theValue)
+bool Selector_FilterByNeighbors::select(
+  const TDF_Label theContextLab, const TopoDS_Shape theContext, const TopoDS_Shape theValue)
 {
   myShapeType = theValue.ShapeType();
+  myContext = theContextLab;
   // searching by neighbors
   std::list<std::pair<TopoDS_Shape, int> > aNBs; /// neighbor sub-shape -> level of neighborhood
   for(int aLevel = 1; true; aLevel++) {
@@ -237,6 +239,11 @@ void Selector_FilterByNeighbors::store()
   for(; aSubSel != list().cend(); aSubSel++) {
     (*aSubSel)->store();
   }
+  // store context reference if exists
+  if (!myContext.IsNull()) {
+    static const TDF_LabelList anEmptyRefList;
+    storeBaseArray(anEmptyRefList, myContext);
+  }
 }
 
 bool Selector_FilterByNeighbors::restore()
@@ -269,6 +276,10 @@ bool Selector_FilterByNeighbors::restore()
       }
     }
   }
+  // restore context reference if exists
+  static TDF_LabelList anEmptyRefList;
+  restoreBaseArray(anEmptyRefList, myContext);
+
   return myNBLevel.size() == list().size() && !myNBLevel.empty();
 }
 
@@ -277,6 +288,7 @@ TDF_Label Selector_FilterByNeighbors::restoreByName(std::string theName,
 {
   myShapeType = theShapeType;
   TDF_Label aContext;
+  std::string aLastLevel; // last level string (after '(' )  to check the context name in the end
   for (size_t aStart = 0; aStart != std::string::npos;
     aStart = theName.find('(', aStart + 1)) {
     size_t anEndPos = theName.find(')', aStart + 1);
@@ -310,7 +322,8 @@ TDF_Label Selector_FilterByNeighbors::restoreByName(std::string theName,
         anEndPos++) {
         aLevel += theName[anEndPos];
       }
-      if (aLevel.empty())
+      aLastLevel = aLevel;
+      if (aLevel.empty() || aLevel[0] == '_')
         myNBLevel.push_back(1); // by default it is 1
       else {
         int aNum = atoi(aLevel.c_str());
@@ -322,6 +335,20 @@ TDF_Label Selector_FilterByNeighbors::restoreByName(std::string theName,
     } else
       return TDF_Label(); // invalid parentheses
   }
+  if (!aLastLevel.empty()) { // get the context
+    size_t aLinePos = aLastLevel.find("_");
+    if (aLinePos != std::string::npos) {
+      std::string aContextName = aLastLevel.substr(aLinePos + 1);
+      if (!aContextName.empty()) {
+        TDF_Label aThisContext, aValue;
+        if (theNameGenerator->restoreContext(aContextName, aThisContext, aValue)) {
+          if (!aThisContext.IsNull())
+            aContext = aThisContext;
+        }
+      }
+    }
+  }
+  myContext = aContext;
   return aContext;
 }
 
@@ -352,18 +379,30 @@ bool Selector_FilterByNeighbors::solve(const TopoDS_Shape& theContext)
 std::string Selector_FilterByNeighbors::name(Selector_NameGenerator* theNameGenerator)
 {
   // (nb1)level_if_more_than_1(nb2)level_if_more_than_1(nb3)level_if_more_than_1
+  bool aThisContextNameNeeded = !myContext.IsNull();
+  std::string aContextName;
+  if (aThisContextNameNeeded)
+    aContextName = theNameGenerator->contextName(myContext);
   std::string aResult;
   std::list<int>::iterator aLevel = myNBLevel.begin();
   std::list<Selector_Algo*>::const_iterator aSubSel = list().cbegin();
   for(; aSubSel != list().cend(); aSubSel++, aLevel++) {
     if (!*aSubSel)
       continue;
-    aResult += "(" + (*aSubSel)->name(theNameGenerator) + ")";
+    std::string aSubName = (*aSubSel)->name(theNameGenerator);
+    aResult += "(" + aSubName + ")";
     if (*aLevel > 1) {
       std::ostringstream aLevelStr;
       aLevelStr<<*aLevel;
       aResult += aLevelStr.str();
     }
+    // sub-name already contains the needed context name, so, here it is not needed
+    if (aThisContextNameNeeded && (
+         aSubName.find(aContextName) == 0 || aSubName.substr(1).find(aContextName)) == 0)
+      aThisContextNameNeeded = false;
+  }
+  if (aThisContextNameNeeded) {
+    aResult = aResult + "_" + aContextName;
   }
   return aResult;
 }
index 721e4a923016ae531bb8a971a1398fedacec0f4f..9335344d399c9505c3dab32edccfaefa99ce1abd 100644 (file)
@@ -35,9 +35,11 @@ class Selector_FilterByNeighbors: public Selector_AlgoWithSubs
 {
   TopAbs_ShapeEnum myShapeType; ///< type of this shape
   std::list<int> myNBLevel; ///< list of integers corresponding to subs neighborhood level
+  TDF_Label myContext; ///< label where the context of filter is stored (needed for python name string)
 public:
   /// Initializes the selection of this kind
-  SELECTOR_EXPORT bool select(const TopoDS_Shape theContext, const TopoDS_Shape theValue);
+  SELECTOR_EXPORT bool select(
+    const TDF_Label theContextLab, const TopoDS_Shape theContext, const TopoDS_Shape theValue);
 
   /// Stores the name to the label and sub-labels tree
   SELECTOR_EXPORT virtual void store() override;