]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Support of all types of selection in python names import
authormpv <mpv@opencascade.com>
Thu, 18 Oct 2018 14:29:21 +0000 (17:29 +0300)
committermpv <mpv@opencascade.com>
Thu, 18 Oct 2018 14:29:21 +0000 (17:29 +0300)
src/Model/Model_AttributeSelection.cpp
src/Model/Model_AttributeSelection.h
src/Selector/Selector_NameGenerator.h
src/Selector/Selector_Selector.cpp
src/Selector/Selector_Selector.h

index 148dbb9b6e5e50af4ab54ee65e60f54fcbadf2d8..b1e9281c88ebf21ac9d907bbf35ffaf799d111c9 100644 (file)
@@ -342,8 +342,8 @@ std::shared_ptr<GeomAPI_Shape> Model_AttributeSelection::internalValue(CenterTyp
   if (myRef.isInitialized()) {
     if (aSelLab.IsAttribute(kSIMPLE_REF_ID)) { // it is just reference to shape, not sub-shape
       ResultPtr aContext = context();
-      if (!aContext.get())
-        return aResult; // empty result
+      if (!aContext.get() || aContext->groupName() == ModelAPI_ResultConstruction::group())
+        return aResult; // empty result, for whole construction selection also
       return aContext->shape();
     }
     if (aSelLab.IsAttribute(kPART_REF_ID)) {
@@ -955,6 +955,7 @@ void Model_AttributeSelection::selectSubShape(
   CenterType aCenterType = theType[0] == 'v' || theType[0] == 'V' ? // only for vertex-type
     centerTypeByName(aSubShapeName) : NOT_CENTER;
   std::string aType = aCenterType == NOT_CENTER ? theType : "EDGE"; // search for edge now
+  TopAbs_ShapeEnum aShapeType =  TopAbs_ShapeEnum(GeomAPI_Shape::shapeTypeByStr(theType));
   static const GeomShapePtr anEmptyShape;
 
   // first iteration is selection by name without center prefix, second - in case of problem,
@@ -1010,7 +1011,7 @@ void Model_AttributeSelection::selectSubShape(
 
     Selector_Selector aSelector(aDoc->generalLabel());
     myRestoreDocument = aDoc;
-    TDF_Label aContextLabel = aSelector.restoreByName(aSubShapeName, this);
+    TDF_Label aContextLabel = aSelector.restoreByName(aSubShapeName, aShapeType, this);
     myRestoreDocument.reset();
     if (!aContextLabel.IsNull()) {
       ResultPtr aContext = aDoc->resultByLab(aContextLabel); // any label for document access
@@ -1767,3 +1768,17 @@ bool Model_AttributeSelection::restoreContext(std::string theName,
   }
   return true;
 }
+
+bool Model_AttributeSelection::isLater(
+  const TDF_Label theResult1, const TDF_Label theResult2) const
+{
+  std::shared_ptr<Model_Document> aDoc = myRestoreDocument.get() ? myRestoreDocument :
+    std::dynamic_pointer_cast<Model_Document>(owner()->document());
+  FeaturePtr aFeat1 = aDoc->featureByLab(theResult1);
+  if (!aFeat1.get())
+    return false;
+  FeaturePtr aFeat2 = aDoc->featureByLab(theResult2);
+  if (!aFeat2.get())
+    return false;
+  return aDoc->isLater(aFeat1, aFeat2);
+}
index 187115e518b3a101ad8d83cbceb5c2fa10007e88..aaf50629501d9eddf787a323075c141b1cfc66f2 100644 (file)
@@ -141,6 +141,10 @@ public:
   MODEL_EXPORT virtual bool restoreContext(std::string theName,
     TDF_Label& theContext, TDF_Label& theValue) override;
 
+  /// Returns true if the first result is newer than the second one in the tree of features
+  MODEL_EXPORT virtual bool isLater(const TDF_Label theResult1, const TDF_Label theResult2)
+    const override;
+
 protected:
   /// Objects are created for features automatically
   MODEL_EXPORT Model_AttributeSelection(TDF_Label& theLabel);
index 079316afadc1f6a751f27c9e65bd6ea88a6abed0..4a06abc072e8adec7a1dcfff2496a78392cfdbc5 100644 (file)
@@ -44,6 +44,9 @@ public:
   /// sub-label where the value is. Returns true if it is valid.
   virtual bool restoreContext(std::string theName,
     TDF_Label& theContext, TDF_Label& theValue) = 0;
+
+  /// Returns true if the first result is older than the second one in the tree of features
+  virtual bool isLater(const TDF_Label theResult1, const TDF_Label theResult2) const = 0;
 };
 
 #endif
index 22238b81617c875c2b9d877e78239ff070cc8661..c1c86cda3c8b048ce4ae6741117667746f18c37c 100644 (file)
@@ -734,12 +734,12 @@ std::string Selector_Selector::name(Selector_NameGenerator* theNameGenerator) {
   case SELTYPE_CONTAINER:
   case SELTYPE_INTERSECT: {
     std::string aResult;
-    // add names of sub-components one by one separated by "&"
+    // add names of sub-components one by one in "[]"
     std::list<Selector_Selector>::iterator aSubSel = mySubSelList.begin();
     for(; aSubSel != mySubSelList.end(); aSubSel++) {
-      if (aSubSel != mySubSelList.begin())
-        aResult += "&";
+      aResult += '[';
       aResult += aSubSel->name(theNameGenerator);
+      aResult += ']';
     }
     return aResult;
   }
@@ -751,13 +751,13 @@ std::string Selector_Selector::name(Selector_NameGenerator* theNameGenerator) {
       std::string(TCollection_AsciiString(aName->Get()).ToCString());
   }
   case SELTYPE_MODIFICATION: {
-    // final&/base1&base2
+    // 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()) + "&/";
+      std::string(TCollection_AsciiString(aName->Get()).ToCString()) + "&";
     for(TDF_LabelList::iterator aBase = myBases.begin(); aBase != myBases.end(); aBase++) {
       if (aBase != myBases.begin())
         aResult += "&";
@@ -774,13 +774,11 @@ std::string Selector_Selector::name(Selector_NameGenerator* theNameGenerator) {
     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
+    // (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;
@@ -793,17 +791,112 @@ std::string Selector_Selector::name(Selector_NameGenerator* theNameGenerator) {
   return "";
 }
 
-TDF_Label Selector_Selector::restoreByName(std::string theName,
+TDF_Label Selector_Selector::restoreByName(
+  std::string theName, const TopAbs_ShapeEnum theShapeType,
   Selector_NameGenerator* theNameGenerator)
 {
-  if (theName.find('&') == std::string::npos) { // wihtout '&' it can be only primitive
+  if (theName[0] == '[') { // intersection or container
+    switch(theShapeType) {
+    case TopAbs_COMPOUND:
+    case TopAbs_COMPSOLID:
+    case TopAbs_SHELL:
+    case TopAbs_WIRE:
+      myType = SELTYPE_CONTAINER;
+      break;
+    case TopAbs_EDGE:
+    case TopAbs_FACE:
+      myType = SELTYPE_INTERSECT;
+      break;
+    default:
+      return TDF_Label(); // unknown case
+    }
+    myShapeType = theShapeType;
+    TDF_Label aContext;
+    for(size_t aStart = 0; aStart != std::string::npos;
+        aStart = theName.find('[', aStart + 1)) {
+      size_t anEndPos = theName.find(']', aStart + 1);
+      if (anEndPos != std::string::npos) {
+        std::string aSubStr = theName.substr(aStart + 1, anEndPos - aStart - 1);
+        mySubSelList.push_back(Selector_Selector(myLab.FindChild(int(mySubSelList.size()) + 1)));
+        TDF_Label aSubContext =
+          mySubSelList.back().restoreByName(aSubStr, theShapeType, theNameGenerator);
+        if (aSubContext.IsNull())
+          return aSubContext; // invalid sub-selection parsing
+        if (!aContext.IsNull() && !aContext.IsEqual(aSubContext)) {
+          if (theNameGenerator->isLater(aSubContext, aContext))
+            aContext = aSubContext;
+        } else {
+          aContext = aSubContext;
+        }
+      } else
+        return TDF_Label(); // invalid parentheses
+    }
+    return aContext;
+  } else if (theName[0] == '(') { // filter by neighbours
+    myType = SELTYPE_FILTER_BY_NEIGHBOR;
+    TDF_Label aContext;
+    for(size_t aStart = 0; aStart != std::string::npos;
+      aStart = theName.find('(', aStart + 1)) {
+      size_t anEndPos = theName.find(')', aStart + 1);
+      if (anEndPos != std::string::npos) {
+        std::string aSubStr = theName.substr(aStart + 1, anEndPos - aStart - 1);
+        mySubSelList.push_back(Selector_Selector(myLab.FindChild(int(mySubSelList.size()) + 1)));
+        TDF_Label aSubContext =
+          mySubSelList.back().restoreByName(aSubStr, theShapeType, theNameGenerator);
+        if (aSubContext.IsNull())
+          return aSubContext; // invalid sub-selection parsing
+        if (!aContext.IsNull() && !aContext.IsEqual(aSubContext)) {
+          if (theNameGenerator->isLater(aSubContext, aContext))
+            aContext = aSubContext;
+        } else {
+          aContext = aSubContext;
+        }
+        // searching for the level index
+        std::string aLevel;
+        for(anEndPos++; anEndPos != std::string::npos &&
+                        theName[anEndPos] != '(' && theName[anEndPos] != 0;
+            anEndPos++) {
+          aLevel += theName[anEndPos];
+        }
+        if (aLevel.empty())
+          myNBLevel.push_back(1); // by default it is 1
+        else {
+          int aNum = atoi(aLevel.c_str());
+          if (aNum > 0)
+            myNBLevel.push_back(aNum);
+          else
+            return TDF_Label(); // invalid number
+        }
+      } else
+        return TDF_Label(); // invalid parentheses
+    }
+    return aContext;
+  } else if (theName.find('&') == std::string::npos) { // wihtout '&' it can be only primitive
     myType = SELTYPE_PRIMITIVE;
     TDF_Label aContext;
     if (theNameGenerator->restoreContext(theName, aContext, myFinal)) {
       if (!myFinal.IsNull())
         return aContext;
     }
-  } else {
+  } else { // modification
+    myType = SELTYPE_MODIFICATION;
+    TDF_Label aContext;
+    for(size_t anEnd, aStart = 0; aStart != std::string::npos; aStart = anEnd) {
+      anEnd = theName.find('&', aStart + 1);
+      std::string aSubStr = theName.substr(aStart == 0 ? 0 : aStart + 1,
+        anEnd == std::string::npos ? anEnd : anEnd - aStart);
+      TDF_Label aSubContext, aValue;
+      if (!theNameGenerator->restoreContext(aSubStr, aSubContext, aValue))
+        return TDF_Label(); // can not restore
+      if(aSubContext.IsNull() || aValue.IsNull())
+        return TDF_Label(); // can not restore
+      if (myFinal.IsNull()) {
+        myFinal = aValue;
+        aContext = aSubContext;
+      } else
+        myBases.Append(aValue);
+    }
+    return aContext;
   }
   return TDF_Label();
 }
index 5836c28746cc9f2f5ddc9bb0936b79e8460c21a4..a91816c36367d43babe1251237102d9e50d45e11 100644 (file)
@@ -78,7 +78,8 @@ class Selector_Selector
 
    /// Restores the selected shape by the topological name string.
    /// Returns not empty label of the context.
-   SELECTOR_EXPORT TDF_Label restoreByName(std::string theName,
+   SELECTOR_EXPORT TDF_Label restoreByName(
+     std::string theName, const TopAbs_ShapeEnum theShapeType,
      Selector_NameGenerator* theNameGenerator);
 
   /// Updates the current shape by the stored topological name