Salome HOME
Name generation in the selector
authormpv <mpv@opencascade.com>
Fri, 12 Oct 2018 15:06:34 +0000 (18:06 +0300)
committermpv <mpv@opencascade.com>
Mon, 19 Nov 2018 08:45:52 +0000 (11:45 +0300)
src/Model/Model_AttributeSelection.cpp
src/Model/Model_AttributeSelection.h
src/Model/Model_Document.cpp
src/Model/Model_Document.h
src/Model/Model_SelectionNaming.cpp
src/Selector/CMakeLists.txt
src/Selector/Selector_NameGenerator.cpp [new file with mode: 0644]
src/Selector/Selector_NameGenerator.h [new file with mode: 0644]
src/Selector/Selector_Selector.cpp
src/Selector/Selector_Selector.h

index 316413de84bd44da4aababd1682a449c6fec2f01..3aa4ffeaac701776dc79cf80798c01ae276fa86a 100644 (file)
@@ -843,7 +843,10 @@ void Model_AttributeSelection::selectBody(
     try {
       //aSel.Select(aNewSub, aNewContext);
       aSelectorOk = aSel.select(aNewContext, aNewSub);
-      aSel.store();
+      if (aSelectorOk) {
+        aSel.store();
+        aSelectorOk = aSel.solve(aNewContext);
+      }
     } catch(...) {
       aSelectorOk = false;
     }
@@ -968,9 +971,15 @@ std::string Model_AttributeSelection::namingName(const std::string& theDefaultNa
     return aNameStream.str();
   }
 
+  Selector_Selector aSelector(aSelLab);
+  std::string aResult;
+  if (aSelector.restore())
+    aResult = aSelector.name(this);
+  /*
   Model_SelectionNaming aSelNaming(aSelLab);
   std::string aResult = aSelNaming.namingName(
     aCont, aSubSh, theDefaultName, owner()->document() != aCont->document());
+    */
   if (aCenterType != NOT_CENTER) {
     aResult += centersMap()[aCenterType];
   }
@@ -1706,3 +1715,31 @@ bool Model_AttributeSelection::isWeakNaming()
 {
   return selectionLabel().IsAttribute(kWEAK_NAMING);
 }
+
+std::string Model_AttributeSelection::contextName(const TDF_Label theSelectionLab)
+{
+  DocumentPtr aMyDoc = owner()->document();
+  std::shared_ptr<Model_Document> aDoc = std::dynamic_pointer_cast<Model_Document>(aMyDoc);
+  FeaturePtr aFeatureOwner = aDoc->featureByLab(theSelectionLab);
+  if (aFeatureOwner.get()) {
+    // searching also for result - real context
+    ResultPtr aResult = aDoc->resultByLab(theSelectionLab);
+    if (aResult.get()) {
+      // this is to avoid duplicated names of results problem
+      std::string aContextName = aResult->data()->name();
+      // myLab corresponds to the current time
+      TDF_Label aCurrentLab = selectionLabel();
+      while(aCurrentLab.Depth() > 3)
+        aCurrentLab = aCurrentLab.Father();
+
+      int aNumInHistoryNames =
+        aDoc->numberOfNameInHistory(aResult, aCurrentLab);
+      while(aNumInHistoryNames > 1) { // add "_" before name the needed number of times
+        aContextName = "_" + aContextName;
+        aNumInHistoryNames--;
+      }
+      return aContextName;
+    }
+  }
+  return ""; // invalid case
+}
index 66f628ebb295069df51d7d450f77351b8b7f386a..b0c3034d663e2a6ffab73a7b55c4bc47e48f8d61 100644 (file)
@@ -24,6 +24,7 @@
 #include "Model.h"
 #include "Model_AttributeReference.h"
 #include <ModelAPI_AttributeSelection.h>
+#include <Selector_NameGenerator.h>
 #include <TDF_LabelMap.hxx>
 #include <TopoDS_Shape.hxx>
 #include <TopTools_ListOfShape.hxx>
@@ -35,7 +36,8 @@ class Model_Document;
  * \ingroup DataModel
  * \brief Attribute that contains reference to the sub-shape of some result, the selected shape.
  */
-class Model_AttributeSelection : public ModelAPI_AttributeSelection
+class Model_AttributeSelection : public ModelAPI_AttributeSelection,
+                                 public Selector_NameGenerator
 {
   Model_AttributeReference myRef;  ///< The reference functionality reusage
   TDF_LabelMap myScope; ///< the map of valid labels for naming selection solving
@@ -128,6 +130,9 @@ public:
   /// Returns true if the name was stored using weak naming principle
   MODEL_EXPORT virtual bool isWeakNaming();
 
+  // Implementation of the name generator method from the Selector package
+  // This method returns the context name by the label of the sub-selected shape
+  MODEL_EXPORT virtual std::string contextName(const TDF_Label theSelectionLab) override;
 
 protected:
   /// Objects are created for features automatically
index 7acdecde220b777596bc253df61c14321945cff3..86c89c4201be3ba83539e5cfab3d1e9de6386662 100755 (executable)
@@ -1334,7 +1334,6 @@ Standard_Boolean IsEqual(const TDF_Label& theLab1, const TDF_Label& theLab2)
   return TDF_LabelMapHasher::IsEqual(theLab1, theLab2);
 }
 
-// searches in this document feature that contains this label
 FeaturePtr Model_Document::featureByLab(const TDF_Label& theLab) {
   TDF_Label aCurrentLab = theLab;
   while(aCurrentLab.Depth() > 3)
@@ -1342,6 +1341,20 @@ FeaturePtr Model_Document::featureByLab(const TDF_Label& theLab) {
   return myObjs->feature(aCurrentLab);
 }
 
+ResultPtr Model_Document::resultByLab(const TDF_Label& theLab)
+{
+  TDF_Label aCurrentLab = theLab;
+  while(aCurrentLab.Depth() > 3) {
+    ObjectPtr aResultObj = myObjs->object(aCurrentLab);
+    if (aResultObj.get()) {
+      return std::dynamic_pointer_cast<ModelAPI_Result>(aResultObj); // this may be null if feature
+    }
+    aCurrentLab = aCurrentLab.Father();
+  }
+  return ResultPtr(); // not found
+}
+
+
 void Model_Document::addNamingName(const TDF_Label theLabel, std::string theName)
 {
   std::map<std::string, std::list<TDF_Label> >::iterator aFind = myNamingNames.find(theName);
index 0842d3d326b5b53fdf16b85cb584f0c060cb0efa..0e1c89a475478947d6ec1e10621fc355704aed18 100644 (file)
@@ -375,6 +375,8 @@ class Model_Document : public ModelAPI_Document
 
   /// searches in this document feature that contains this label
   FeaturePtr featureByLab(const TDF_Label& theLab);
+  /// searches in this document result that contains this label
+  ResultPtr resultByLab(const TDF_Label& theLab);
 
   /// returns true if theThis is later in the features trre and dependencies than theOther
   bool isLaterByDep(FeaturePtr theThis, FeaturePtr theOther);
index 802b13cfc8d2c07dbf50d81976ca5929808927eb..1075ef610d4de49dfd98307ff890ec4e49b3850a 100644 (file)
@@ -258,46 +258,6 @@ const TopoDS_Shape findCommonShape(
   return aSharedShape;
 }
 
-// searches theType shape that contains theConnectionType sub-shapes in each shape from the List,
-// so, implements the neighbours searching
-/*
-const TopoDS_Shape findCommonShapeByNB(const TopAbs_ShapeEnum theType,
-  const TopAbs_ShapeEnum theConnectionType, const TopTools_ListOfShape& theList)
-{
-TopTools_MapOfShape aCheckedShapes; // already checked shapes of type theType
-  TopoDS_Shape aResult; // theType result shape
-  for(TopTools_ListIteratorOfListOfShape anIt(theList); anIt.More(); anIt.Next()) { // iterate all
-    for(TopExp_Explorer anExp(anIt.ChangeValue(), theType); anExp.More(); anExp.Next()) {
-      if (aCheckedShapes.Contains(anExp.Current()))
-        continue; // already checked
-      aCheckedShapes.Add(anExp.Current());
-      TopTools_MapOfShape aConnectors; // all connectors of the checked theType shape
-      for(TopExp_Explorer aCExp(anExp.Current(), theConnectionType); aCExp.More(); aCExp.Next()) {
-        aConnectors.Add(aCExp.Current());
-      }
-      // check that all shapes from the List contain the connector sub-shapes
-      bool aFound = true;
-      for(TopTools_ListIteratorOfListOfShape anIt2(theList); anIt2.More() && aFound; anIt2.Next()) {
-        if (anIt2.Value().IsSame(anIt.Value()))
-          continue;
-        aFound = false;
-        for(TopExp_Explorer anE(anIt2.ChangeValue(), theConnectionType); anE.More(); anE.Next()) {
-          if (aConnectors.Contains(anE.Current())) {
-            aFound = true;
-            break;
-          }
-        }
-      }
-      if (aFound) {
-        if (!aResult.IsNull()) // more than one result
-          return TopoDS_Shape();
-        aResult = anExp.Current();
-      }
-    }
-  }
-  return aResult;
-}*/
-
 std::string Model_SelectionNaming::vertexNameByEdges(TopoDS_Shape theContext, TopoDS_Shape theSub,
   std::shared_ptr<Model_Document> theDoc, ResultPtr& theContextRes, const bool theAnotherDoc)
 {
index 67ae4371f9f13231c69b9e14a932905a784e853b..f3bf654eaf15b63714b991bda5d07f67ebd53d85 100644 (file)
@@ -23,10 +23,12 @@ INCLUDE(Common)
 SET(PROJECT_HEADERS
     Selector.h
     Selector_Selector.h
+    Selector_NameGenerator.h
 )
 
 SET(PROJECT_SOURCES
     Selector_Selector.cpp
+    Selector_NameGenerator.cpp
 )
 
 SET(PROJECT_LIBRARIES
diff --git a/src/Selector/Selector_NameGenerator.cpp b/src/Selector/Selector_NameGenerator.cpp
new file mode 100644 (file)
index 0000000..0c4ed03
--- /dev/null
@@ -0,0 +1 @@
+#include <Selector_NameGenerator.h>
diff --git a/src/Selector/Selector_NameGenerator.h b/src/Selector/Selector_NameGenerator.h
new file mode 100644 (file)
index 0000000..80fb865
--- /dev/null
@@ -0,0 +1,44 @@
+// Copyright (C) 2014-2017  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// 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
+//
+// See http://www.salome-platform.org/ or
+// email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+//
+
+#ifndef Selector_NameGenerator_H_
+#define Selector_NameGenerator_H_
+
+#include "Selector.h"
+
+#include <TDF_Label.hxx>
+
+/**\class Selector_NameGenerator
+ * \ingroup DataModel
+ * \brief An interface for generation of the naming name basing on the current selection and
+ * document information. This requires higher-level data access, so, the caller of "name" method
+ * of Selector must implement this helper-class abstract methods.
+ */
+class Selector_NameGenerator
+{
+public:
+  // empty constructor, nothing to add
+  Selector_NameGenerator() {};
+
+  // This method returns the context name by the label of the sub-selected shape
+  virtual std::string contextName(const TDF_Label theSelectionLab) = 0;
+};
+
+#endif
index c4b6539d15de652d258ad359b10ce610df76002d..f97d20c8c34d7d1e19ca5d82b26acc712c995605 100644 (file)
@@ -20,6 +20,8 @@
 
 #include <Selector_Selector.h>
 
+#include <Selector_NameGenerator.h>
+
 #include <TDF_ChildIDIterator.hxx>
 #include <TopoDS_Iterator.hxx>
 #include <TopoDS_Builder.hxx>
@@ -35,6 +37,7 @@
 #include <TDataStd_Integer.hxx>
 #include <TDataStd_ReferenceArray.hxx>
 #include <TDataStd_IntegerArray.hxx>
+#include <TDataStd_Name.hxx>
 
 #include <list>
 
@@ -253,16 +256,21 @@ bool Selector_Selector::select(const TopoDS_Shape theContext, const TopoDS_Shape
     }
 
     // try to find the shape of the higher level type in the context shape
-    while(aSelectionType != TopAbs_FACE) {
-      if (aSelectionType == TopAbs_VERTEX) aSelectionType = TopAbs_EDGE;
-      else if (aSelectionType == TopAbs_EDGE) aSelectionType = TopAbs_FACE;
+    bool aFacesTried = false; // for identification of vertices, faces are tried, then edges
+    while(aSelectionType != TopAbs_FACE || !aFacesTried) {
+      if (aSelectionType == TopAbs_FACE && theValue.ShapeType() == TopAbs_VERTEX) {
+        aFacesTried = true;
+        aSelectionType = TopAbs_EDGE;
+      } else
+        aSelectionType = TopAbs_FACE;
       TopTools_MapOfShape anIntersectors; // shapes of aSelectionType that contain theValue
       TopoDS_ListOfShape anIntList; // same as anIntersectors
       for(TopExp_Explorer aSelExp(theContext, aSelectionType); aSelExp.More(); aSelExp.Next()) {
         TopExp_Explorer aSubExp(aSelExp.Current(), theValue.ShapeType());
         for(; aSubExp.More(); aSubExp.Next()) {
           if (aSubExp.Current().IsSame(theValue)) {
-            anIntersectors.Add(aSelExp.Current());
+            if (anIntersectors.Add(aSelExp.Current()))
+              anIntList.Append(aSelExp.Current());
             break;
           }
         }
@@ -613,6 +621,7 @@ bool Selector_Selector::solve(const TopoDS_Shape& theContext)
     }
     if (aFinalsCommon.Extent() == 1) // only in this case result is valid: found only one shape
       aResult = aFinalsCommon.First();
+    break;
   }
   case SELTYPE_FILTER_BY_NEIGHBOR: {
     std::list<std::pair<TopoDS_Shape, int> > aNBs; /// neighbor sub-shape -> level of neighborhood
@@ -646,7 +655,67 @@ TopoDS_Shape Selector_Selector::value()
   return TopoDS_Shape(); // empty, error shape
 }
 
-bool Selector_Selector::selectBySubSelector(const TopoDS_Shape theContext, const TopoDS_Shape theValue)
+std::string Selector_Selector::name(Selector_NameGenerator* theNameGenerator) {
+  switch(myType) {
+  case SELTYPE_CONTAINER:
+  case SELTYPE_INTERSECT: {
+    std::string aResult;
+    // add names of sub-components one by one separated by "&"
+    std::list<Selector_Selector>::iterator aSubSel = mySubSelList.begin();
+    for(; aSubSel != mySubSelList.end(); aSubSel++) {
+      if (aSubSel != mySubSelList.begin())
+        aResult += "&";
+      aResult += aSubSel->name(theNameGenerator);
+    }
+    return aResult;
+  }
+  case SELTYPE_PRIMITIVE: {
+    Handle(TDataStd_Name) aName;
+    if (!myFinal.FindAttribute(TDataStd_Name::GetID(), aName))
+      return "";
+    return theNameGenerator->contextName(myFinal) + "/" +
+      std::string(TCollection_AsciiString(aName->Get()).ToCString());
+  }
+  case SELTYPE_MODIFICATION: {
+    // final&/base1&base2
+    std::string aResult;
+    Handle(TDataStd_Name) aName;
+    if (!myFinal.FindAttribute(TDataStd_Name::GetID(), aName))
+      return "";
+    aResult += theNameGenerator->contextName(myFinal) + "/" +
+      std::string(TCollection_AsciiString(aName->Get()).ToCString()) + "&/";
+    for(TDF_LabelList::iterator aBase = myBases.begin(); aBase != myBases.end(); aBase++) {
+      if (aBase != myBases.begin())
+        aResult += "&";
+      if (aBase->FindAttribute(TDataStd_Name::GetID(), aName))
+        return "";
+      aResult += theNameGenerator->contextName(*aBase) + "/" +
+        std::string(TCollection_AsciiString(aName->Get()).ToCString());
+    }
+    return aResult;
+  }
+  case SELTYPE_FILTER_BY_NEIGHBOR: {
+    // (nb1)level_if_more_than_1&(nb2)level_if_more_than_1&(nb3)level_if_more_than_1
+    std::string aResult;
+    std::list<int>::iterator aLevel = myNBLevel.begin();
+    std::list<Selector_Selector>::iterator aSubSel = mySubSelList.begin();
+    for(; aSubSel != mySubSelList.end(); aSubSel++, aLevel++) {
+      if (aSubSel != mySubSelList.begin())
+        aResult += "&";
+      aResult += "(" + aSubSel->name(theNameGenerator) + ")";
+      if (*aLevel > 1)
+        aResult += *aLevel;
+    }
+    return aResult;
+  }
+  default: { // unknown case
+  }
+  };
+  return "";
+}
+
+bool Selector_Selector::selectBySubSelector(
+  const TopoDS_Shape theContext, const TopoDS_Shape theValue)
 {
   mySubSelList.push_back(Selector_Selector(myLab.FindChild(int(mySubSelList.size()) + 1)));
   if (!mySubSelList.back().select(theContext, theValue)) {
index 225ab131f954b87d270165dddfa9ff4faf3536d3..cbed4c98376f0208d485cc03f8f89972cbc14861 100644 (file)
 #include <TopoDS_Shape.hxx>
 #include <list>
 
+class Selector_NameGenerator;
+
 /**\class Selector_Selector
  * \ingroup DataModel
  * \brief Main object for selection of the sub-shapes in the parametrically updated
  * shapes using topological naming mechanism.
  */
-
 class Selector_Selector
 {
   /// Type of a selector: on this type depends what is stored in this label and how to
@@ -77,9 +78,12 @@ class Selector_Selector
   /// Updates the current shape by the stored topological name
    SELECTOR_EXPORT bool solve(const TopoDS_Shape& theContext);
 
-  /// Returns the current sub-shape value (null if can not resolve)
+   /// Returns the current sub-shape value (null if can not resolve)
    SELECTOR_EXPORT TopoDS_Shape value();
 
+   /// Returns the naming name of the selection
+   SELECTOR_EXPORT std::string name(Selector_NameGenerator* theNameGenerator);
+
 private:
 
   /// Create and keep in the list the sub-sulector that select the given value.