Salome HOME
Updated copyright comment
[modules/shaper.git] / src / Selector / Selector_Algo.cpp
index ee31d00bd04b1e40a4759e71cc39c2cc8d107ba5..1caf2428bcb1d77108921b1077e9a5196d88f35b 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2014-2017  CEA/DEN, EDF R&D
+// Copyright (C) 2014-2024  CEA, EDF
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 //
 // You should have received a copy of the GNU Lesser General Public
 // License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
-// See http://www.salome-platform.org/ or
-// email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 
 #include <Selector_Algo.h>
@@ -67,6 +66,42 @@ Selector_Algo::Selector_Algo()
   myAlwaysGeometricalNaming = false;
 }
 
+static TDF_Label findGoodLabelWithShape(const TDF_Label theAccess, const TopoDS_Shape& theShape) {
+  TDF_Label aResult;
+  TDF_Label aMyOpLab;
+  bool aMyOpLabIsComputed = false;
+  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) {
+          // getting label of this operation to avoid usage of ready shapes of this
+          if (!aMyOpLabIsComputed) {
+            aMyOpLab = theAccess;
+            if (!aMyOpLab.IsNull()) {
+              int aDepth = aMyOpLab.Depth();
+              if (aDepth < 3)
+                aMyOpLab.Nullify();
+              else {
+                for(; aDepth != 3; aDepth--)
+                  aMyOpLab = aMyOpLab.Father();
+              }
+            }
+            aMyOpLabIsComputed = true;
+          }
+          if (!aMyOpLab.IsNull() && aNS->Label().IsDescendant(aMyOpLab))
+            continue;
+          aResult = aNS->Label();
+          break;
+        }
+      }
+    }
+  }
+  return aResult;
+}
+
 #define SET_ALGO_FLAGS(algo) \
   algo->myLab = theAccess; \
   algo->myBaseDocumentLab = theBaseDocument; \
@@ -86,37 +121,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 +151,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;
     }
@@ -165,6 +176,17 @@ Selector_Algo* Selector_Algo::select(const TopoDS_Shape theContext, const TopoDS
     }
     return NULL; // not found value in the tree, not found context shape in the tree also
   }
+  // getting label of this operation to avoid usage of ready shapes of this
+  TDF_Label aMyOpLab = theAccess;
+  if (!aMyOpLab.IsNull()) {
+    int aDepth = aMyOpLab.Depth();
+    if (aDepth < 3)
+      aMyOpLab.Nullify();
+    else {
+      for(; aDepth != 3; aDepth--)
+        aMyOpLab = aMyOpLab.Father();
+    }
+  }
   // searching for the base shapes of the value
   Handle(TNaming_NamedShape) aPrimitiveNS;
   NCollection_List<Handle(TNaming_NamedShape)> aModifList;
@@ -177,6 +199,10 @@ Selector_Algo* Selector_Algo::select(const TopoDS_Shape theContext, const TopoDS
       Handle(TNaming_NamedShape) aNS;
       if (aShapes.Label().FindAttribute(TNaming_NamedShape::GetID(), aNS)) {
         TNaming_Evolution anEvolution = aNS->Evolution();
+        if (anEvolution == TNaming_SELECTED || anEvolution == TNaming_DELETE)
+          continue;
+        if (!aMyOpLab.IsNull() && aNS->Label().IsDescendant(aMyOpLab))
+          continue;
         if (anEvolution == TNaming_PRIMITIVE) { // the value shape is declared as PRIMITIVE
           aPrimitiveNS = aNS;
           break;
@@ -213,7 +239,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;
     }
@@ -380,11 +410,11 @@ Selector_Algo* Selector_Algo::restoreByLab(TDF_Label theLab, TDF_Label theBaseDo
 }
 
 Selector_Algo* Selector_Algo::restoreByName(TDF_Label theLab, TDF_Label theBaseDocLab,
-  std::string theName, const TopAbs_ShapeEnum theShapeType, const bool theGeomNaming,
+  std::wstring theName, const TopAbs_ShapeEnum theShapeType, const bool theGeomNaming,
   Selector_NameGenerator* theNameGenerator, TDF_Label& theContextLab)
 {
   Selector_Algo* aResult = NULL;
-  if (theName[0] == '[') { // intersection or container
+  if (theName[0] == L'[') { // intersection or container
     switch(theShapeType) {
     case TopAbs_COMPOUND:
     case TopAbs_COMPSOLID:
@@ -399,11 +429,12 @@ Selector_Algo* Selector_Algo::restoreByName(TDF_Label theLab, TDF_Label theBaseD
       break;
     default:;
     }
-  } else if (theName[0] == '(') { // filter by neighbors
+  } else if (theName[0] == L'(') { // filter by neighbors
     aResult = new Selector_FilterByNeighbors;
-  } else if (theName.find(pureWeakNameID()) == 0) { // weak naming identifier
+  } else if (theName.find(pureWeakNameID()) == 0 ||
+             theName.find(oldPureWeakNameID()) == 0) { // weak naming identifier
     aResult = new Selector_WeakName;
-  } else if (theName.find('&') != std::string::npos) { // modification
+  } else if (theName.find(L'&') != std::wstring::npos) { // modification
     aResult = new Selector_Modify;
   } else { // primitive
     aResult = new Selector_Primitive;
@@ -471,10 +502,15 @@ bool Selector_Algo::findNewVersion(const TopoDS_Shape& theContext, TopoDS_Shape&
         TopoDS_Shape aNextModification = aBaseIter.Shape();
         if (aNextModification.IsNull())
           continue;
-        if (isInContext(theContext, aNextModification))
-          aResultShapes.Add(aNextModification);
-        else if (findNewVersion(theContext, aNextModification))
-          aResultShapes.Add(aNextModification);
+        if (isInContext(theContext, aNextModification)) {
+          // don't add vertices generated from edges
+          if (aNextModification.ShapeType() <= theResult.ShapeType())
+            aResultShapes.Add(aNextModification);
+        }
+        else if (findNewVersion(theContext, aNextModification)) {
+          if (aNextModification.ShapeType() <= theResult.ShapeType())
+            aResultShapes.Add(aNextModification);
+        }
       }
     }
     if (aResultShapes.IsEmpty())