Salome HOME
Add tutorial help page.
[modules/shaper.git] / src / Model / Model_SelectionNaming.cpp
index 5dbe49d9e27abe5e05f0c00b5e61790278819c8f..1b1c51e9ec70901a076e22a19d15503fb263dae5 100644 (file)
@@ -47,6 +47,7 @@
 #include <TNaming_Tool.hxx>
 #include <TNaming_NamedShape.hxx>
 #include <TNaming_Localizer.hxx>
+#include <TNaming_SameShapeIterator.hxx>
 #include <TDataStd_Name.hxx>
 #include <TColStd_MapOfTransient.hxx>
 #include <algorithm>
@@ -61,6 +62,41 @@ Model_SelectionNaming::Model_SelectionNaming(TDF_Label theSelectionLab)
   myLab = theSelectionLab;
 }
 
+// searches named shape by the shape in the given document (identified by the label)
+// tries to find s shape nearest to the context-label
+static Handle(TNaming_NamedShape) shapeToNS(const TDF_Label theLabAccess,
+  const TopoDS_Shape& theShape, const TDF_Label& theContextLab)
+{
+  Handle(TNaming_NamedShape) aResult;
+  if (!TNaming_Tool::HasLabel(theLabAccess, theShape)) // no shape in the document
+    return aResult;
+  int aContextLabDepth = theContextLab.IsNull() ? 100 : theContextLab.Depth();
+  TNaming_SameShapeIterator aNSIter(theShape, theLabAccess);
+  for(; aNSIter.More(); aNSIter.Next()) {
+    TDF_Label aLabel = aNSIter.Label();
+    Handle(TNaming_NamedShape) aNS;
+    if (aLabel.FindAttribute(TNaming_NamedShape::GetID(), aNS)) {
+      if (aNS->Evolution() != TNaming_SELECTED && aNS->Evolution() != TNaming_DELETE) {
+        // check this is new shape in this named shape
+        bool aIsNew = false;
+        for(TNaming_Iterator aNSIter(aNS); aNSIter.More(); aNSIter.Next())
+          if (!aNSIter.NewShape().IsNull() && aNSIter.NewShape().IsSame(theShape))
+            aIsNew = true;
+        if (!aIsNew)
+          continue;
+        // check this is the context-shape
+        while(aLabel.Depth() > aContextLabDepth)
+          aLabel = aLabel.Father();
+        if (aLabel.IsEqual(theContextLab))
+          return aNS;
+        if (aResult.IsNull()) // take the first, otherwise it will get shapes from results, etc
+          aResult = aNS; // keep some result anyway - if there are no context labels return any
+      }
+    }
+  }
+  return aResult;
+}
+
 std::string Model_SelectionNaming::getShapeName(
   std::shared_ptr<Model_Document> theDoc, const TopoDS_Shape& theShape,
   ResultPtr& theContext, const bool theAnotherDoc, const bool theWholeContext)
@@ -70,20 +106,21 @@ std::string Model_SelectionNaming::getShapeName(
   // (it was in BodyBuilder, but did not work on Result rename)
   bool isNeedContextName = theContext->shape().get() != NULL;
   // check if the subShape is already in DF
-  Handle(TNaming_NamedShape) aNS = TNaming_Tool::NamedShape(theShape, myLab);
+  std::shared_ptr<Model_Data> aData =
+    std::dynamic_pointer_cast<Model_Data>(theContext->data());
+  TDF_Label aContextDataLab(aData.get() && aData->isValid() ? aData->label() : TDF_Label());
+  Handle(TNaming_NamedShape) aNS = shapeToNS(myLab, theShape, aContextDataLab);
   Handle(TDataStd_Name) anAttr;
   if(!aNS.IsNull() && !aNS->IsEmpty()) { // in the document
     if(aNS->Label().FindAttribute(TDataStd_Name::GetID(), anAttr)) {
-      std::shared_ptr<Model_Data> aData =
-        std::dynamic_pointer_cast<Model_Data>(theContext->data());
-      if (isNeedContextName && aData && aData->label().IsEqual(aNS->Label())) {
+      if (isNeedContextName && aData && aContextDataLab.IsEqual(aNS->Label())) {
         // do nothing because this context name will be added later in this method
       } else {
         aName = TCollection_AsciiString(anAttr->Get()).ToCString();
         // indexes are added to sub-shapes not primitives
         // (primitives must not be located at the same label)
         if(!aName.empty() && aNS->Evolution() != TNaming_PRIMITIVE && isNeedContextName) {
-          const TDF_Label& aLabel = aNS->Label();//theDoc->findNamingName(aName);
+          const TDF_Label& aLabel = aNS->Label();
           static const std::string aPostFix("_");
           TNaming_Iterator anItL(aNS);
           for(int i = 1; anItL.More(); anItL.Next(), i++) {
@@ -104,15 +141,29 @@ std::string Model_SelectionNaming::getShapeName(
             !aNS->Label().IsDescendant(aContextData->label())) {
           isNeedContextName = false;
           TDF_Label aNSDataLab = aNS->Label();
-          while(aNSDataLab.Depth() != 7 && aNSDataLab.Depth() > 5)
+          if (aNSDataLab.Depth() % 2 == 0)
             aNSDataLab = aNSDataLab.Father();
           ObjectPtr aNewContext = theDoc->objects()->object(aNSDataLab);
-          if (!aNewContext.get() && aNSDataLab.Depth() == 7) {
+          while(!aNewContext.get() && aNSDataLab.Depth() > 5) {
             aNSDataLab = aNSDataLab.Father().Father();
             aNewContext = theDoc->objects()->object(aNSDataLab);
           }
           if (aNewContext.get()) {
-            aName = aNewContext->data()->name() + "/" + aName;
+            // this is to avoid duplicated names of results problem
+            std::string aContextName = aNewContext->data()->name();
+            // myLab corresponds to the current time
+            TDF_Label aCurrentLab = myLab;
+            while(aCurrentLab.Depth() > 3)
+              aCurrentLab = aCurrentLab.Father();
+
+            int aNumInHistoryNames =
+              theDoc->numberOfNameInHistory(aNewContext, aCurrentLab);
+            while(aNumInHistoryNames > 1) { // add "_" before name the needed number of times
+              aContextName = "_" + aContextName;
+              aNumInHistoryNames--;
+            }
+
+            aName = aContextName + "/" + aName;
           }
         }
       }
@@ -205,6 +256,78 @@ 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)
+{
+  std::string aResult;
+  TopTools_IndexedDataMapOfShapeListOfShape aMap;
+  TopExp::MapShapesAndAncestors(theContext, TopAbs_VERTEX, TopAbs_EDGE, aMap);
+  const TopTools_ListOfShape& aList22  = aMap.FindFromKey(theSub);
+  if(aList22.Extent() >= 2)  { // regular solution
+    TopTools_MapOfShape aFMap;
+    TopTools_ListOfShape aListE;
+    TopTools_ListIteratorOfListOfShape itl2(aList22);
+    for (int i = 1;itl2.More();itl2.Next(),i++) {
+      if(aFMap.Add(itl2.Value()))
+        aListE.Append(itl2.Value());
+    }
+    TopTools_ListIteratorOfListOfShape itl(aListE);
+    for (int i = 1;itl.More();itl.Next(),i++) {
+      const TopoDS_Shape& anEdge = itl.Value();
+      std::string anEdgeName = getShapeName(theDoc, anEdge, theContextRes, theAnotherDoc, false);
+      if (anEdgeName.empty()) { // edge is not in DS
+        aResult.clear();
+        return aResult;
+      }
+      if(i == 1)
+        aResult = anEdgeName;
+      else
+        aResult += "&" + anEdgeName;
+    }
+  }
+  return aResult;
+}
+
 std::string Model_SelectionNaming::namingName(ResultPtr& theContext,
   std::shared_ptr<GeomAPI_Shape> theSubSh, const std::string& theDefaultName,
   const bool theAnotherDoc)
@@ -274,7 +397,7 @@ std::string Model_SelectionNaming::namingName(ResultPtr& theContext,
           }
         } else
           break;
-        TopTools_ListOfShape aListOfNbs;
+        TopTools_MapOfShape aNbs;
         if(!isTrivialCase) { // find Neighbors
           TNaming_Localizer aLocalizer;
           TopTools_MapOfShape aMap3;
@@ -288,25 +411,25 @@ std::string Model_SelectionNaming::namingName(ResultPtr& theContext,
             TopTools_ListIteratorOfListOfShape it2(aList);
             for(;it2.More();it2.Next()) {
               if(aSMap.Contains(it2.Value())) continue; // skip this Face
-              aListOfNbs.Append(it2.Value());
+              aNbs.Add(it2.Value());
             }
           }
         }  // else a trivial case
 
         // build name of the sub-shape Edge
-        for(int i=1; i <= aSMap.Extent(); i++) {
-          const TopoDS_Shape& aFace = aSMap.FindKey(i);
+        // iterate faces of the context to get stable order, not map-order
+        TopTools_MapOfShape aStoredFaces; // to avoid duplicates
+        for(TopExp_Explorer aContExp(aContext, TopAbs_FACE); aContExp.More(); aContExp.Next()) {
+          const TopoDS_Shape& aFace = aContExp.Current();
+          if (aStoredFaces.Contains(aFace) || !(aSMap.Contains(aFace) || aNbs.Contains(aFace)))
+            continue;
+          aStoredFaces.Add(aFace);
           std::string aFaceName = getShapeName(aDoc, aFace, theContext, theAnotherDoc, false);
-          if(i == 1)
+          if(aName.empty())
             aName = aFaceName;
           else
             aName += "&" + aFaceName;
         }
-        TopTools_ListIteratorOfListOfShape itl(aListOfNbs);
-        for (;itl.More();itl.Next()) {
-          std::string aFaceName = getShapeName(aDoc, itl.Value(), theContext, theAnotherDoc, false);
-          aName += "&" + aFaceName;
-        }
       }
       break;
 
@@ -341,40 +464,28 @@ std::string Model_SelectionNaming::namingName(ResultPtr& theContext,
           break;
         int n = aList.Extent();
         bool isByFaces = n >= 3;
+        if (isByFaces) { // check that by faces vertex is identified uniquly (2317)
+          TopoDS_Shape aVertex = findCommonShape(TopAbs_VERTEX, aList);
+          isByFaces = !aVertex.IsNull() && aVertex.ShapeType() == TopAbs_VERTEX;
+        }
+
         if(!isByFaces) { // open topology case or Compound case => via edges
-          TopTools_IndexedDataMapOfShapeListOfShape aMap;
-          TopExp::MapShapesAndAncestors(aContext, TopAbs_VERTEX, TopAbs_EDGE, aMap);
-          const TopTools_ListOfShape& aList22  = aMap.FindFromKey(aSubShape);
-          if(aList22.Extent() >= 2)  { // regular solution
-
-            // bug! duplication; fix is below
-            aFMap.Clear();
-            TopTools_ListOfShape aListE;
-            TopTools_ListIteratorOfListOfShape itl2(aList22);
-            for (int i = 1;itl2.More();itl2.Next(),i++) {
-              if(aFMap.Add(itl2.Value()))
-                aListE.Append(itl2.Value());
-            }
-            n = aListE.Extent();
-            TopTools_ListIteratorOfListOfShape itl(aListE);
-            for (int i = 1;itl.More();itl.Next(),i++) {
-              const TopoDS_Shape& anEdge = itl.Value();
-              std::string anEdgeName = getShapeName(aDoc, anEdge, theContext, theAnotherDoc, false);
-              if (anEdgeName.empty()) { // edge is not in DS, trying by faces anyway
-                isByFaces = true;
-                aName.clear();
-                break;
+          aName = vertexNameByEdges(aContext, aSubShape, aDoc, theContext, theAnotherDoc);
+          isByFaces = aName.empty();
+          if (isByFaces) { // try to find a vertex in sketch faces
+            ResultConstructionPtr aConstr =
+              std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(theContext);
+            if (aConstr.get() && aConstr->facesNum()) {
+              for(int aFace = aConstr->facesNum() - 1; isByFaces && aFace >= 0; aFace--) {
+                std::shared_ptr<GeomAPI_Face> aGFace = aConstr->face(aFace);
+                aName = vertexNameByEdges(aGFace->impl<TopoDS_Face>(), aSubShape,
+                  aDoc, theContext, theAnotherDoc);
+                isByFaces = aName.empty();
               }
-              if(i == 1)
-                aName = anEdgeName;
-              else
-                aName += "&" + anEdgeName;
             }
-          }//reg
-          else { // dangle vertex: if(aList22.Extent() == 1)
-            //it should be already in DF
           }
         }
+
         if (isByFaces) {
           TopTools_ListIteratorOfListOfShape itl(aList);
           for (int i = 1;itl.More();itl.Next(),i++) {
@@ -390,7 +501,6 @@ std::string Model_SelectionNaming::namingName(ResultPtr& theContext,
       break;
     }
   }
-
   return aName;
 }
 
@@ -469,20 +579,21 @@ const TopoDS_Shape getShapeFromNS(
 }
 
 const TopoDS_Shape findFaceByName(
-  const std::string& theSubShapeName, std::shared_ptr<Model_Document> theDoc)
+  const std::string& theSubShapeName, std::shared_ptr<Model_Document> theDoc,
+  const ResultPtr theDetectedContext, bool theContextIsUnique)
 {
   TopoDS_Shape aFace;
-  //std::string::size_type n, nb = theSubShapeName.rfind('/');
-  //if (nb == std::string::npos) nb = 0;
-  //std::string aSubString = theSubShapeName.substr(nb + 1);
   std::string aSubString = theSubShapeName;
 
-  TDF_Label aLabel = theDoc->findNamingName(aSubString);
+  static const ResultPtr anEmpty;
+  TDF_Label aLabel = theDoc->findNamingName(aSubString,
+    theContextIsUnique ? theDetectedContext : anEmpty);
   if (aLabel.IsNull()) { // try to remove additional artificial suffix
     std::string::size_type n = aSubString.rfind('_');
     if (n != std::string::npos) {
       aSubString = aSubString.substr(0, n);
-       aLabel = theDoc->findNamingName(aSubString);
+      aLabel = theDoc->findNamingName(aSubString,
+        theContextIsUnique ? theDetectedContext : anEmpty);
     }
   }
   if(aLabel.IsNull()) return aFace;
@@ -721,7 +832,8 @@ bool Model_SelectionNaming::selectSubShape(const std::string& theType,
 
   std::string aContName = getContextName(aSubShapeName);
   if(aContName.empty()) return false;
-  ResultPtr aCont = aDoc->findByName(aContName);
+  bool anUniqueContext = false;
+  ResultPtr aCont = aDoc->findByName(aContName, aSubShapeName, anUniqueContext);
    // possible this is body where postfix is added to distinguish several shapes on the same label
   int aSubShapeId = -1; // -1 means sub shape not found
   // for result body the name wihtout "_" has higher priority than with it: it is always added
@@ -729,8 +841,8 @@ bool Model_SelectionNaming::selectSubShape(const std::string& theType,
        aContName == aSubShapeName) {
     size_t aPostIndex = aContName.rfind('_');
     if (aPostIndex != std::string::npos) {
-      std::string aSubContName = aContName.substr(0, aPostIndex);
-      ResultPtr aSubCont = aDoc->findByName(aSubContName);
+      std::string anEmpty, aSubContName = aContName.substr(0, aPostIndex);
+      ResultPtr aSubCont = aDoc->findByName(aSubContName, anEmpty, anUniqueContext);
       if (aSubCont.get()) {
         try {
           std::string aNum = aContName.substr(aPostIndex + 1);
@@ -747,18 +859,20 @@ bool Model_SelectionNaming::selectSubShape(const std::string& theType,
   }
 
 
+  static const ResultPtr anEmpty;
   TopoDS_Shape aSelection;
   switch (aType)
   {
   case TopAbs_FACE:
   case TopAbs_WIRE:
     {
-      aSelection = findFaceByName(aSubShapeName, aDoc);
+      aSelection = findFaceByName(aSubShapeName, aDoc, aCont, anUniqueContext);
     }
     break;
   case TopAbs_EDGE:
     {
-      const TDF_Label& aLabel = aDoc->findNamingName(aSubShapeName);
+      const TDF_Label& aLabel =
+        aDoc->findNamingName(aSubShapeName, anUniqueContext ? aCont : anEmpty);
       if(!aLabel.IsNull()) {
         Handle(TNaming_NamedShape) aNS;
         if(aLabel.FindAttribute(TNaming_NamedShape::GetID(), aNS)) {
@@ -769,7 +883,8 @@ bool Model_SelectionNaming::selectSubShape(const std::string& theType,
     break;
   case TopAbs_VERTEX:
     {
-      const TDF_Label& aLabel = aDoc->findNamingName(aSubShapeName);
+      const TDF_Label& aLabel =
+        aDoc->findNamingName(aSubShapeName, anUniqueContext ? aCont : anEmpty);
       if(!aLabel.IsNull()) {
         Handle(TNaming_NamedShape) aNS;
         if(aLabel.FindAttribute(TNaming_NamedShape::GetID(), aNS)) {
@@ -817,21 +932,40 @@ bool Model_SelectionNaming::selectSubShape(const std::string& theType,
     if(aN >= 1) {
       TopTools_ListOfShape aList;
       std::list<std::string>::iterator it = aListofNames.begin();
-      for(; it != aListofNames.end(); it++){
-        const TopoDS_Shape aFace = findFaceByName(*it, aDoc);
+      for(; it != aListofNames.end(); it++) {
+        ResultPtr aFaceContext = aCont;
+        if (it != aListofNames.begin()) { // there may be other context for different sub-faces
+          std::string aContName = getContextName(*it);
+          if(!aContName.empty()) {
+            aFaceContext = aDoc->findByName(aContName, *it, anUniqueContext);
+          }
+        }
+        TopoDS_Shape aFace = findFaceByName(*it, aDoc, aFaceContext, anUniqueContext);
+        if (aFace.IsNull() && aFaceContext.get() &&
+            aFaceContext->groupName() == ModelAPI_ResultConstruction::group() ) {
+          // search the construction sub-elements for the intersection if they are in the tree
+          size_t aSlash = it->find("/");
+          if (aSlash != std::string::npos) {
+            std::string aSubShapeName = it->substr(aSlash + 1);
+            aFace = findFaceByName(aSubShapeName, aDoc, aFaceContext, true);
+          }
+        }
         if(!aFace.IsNull())
           aList.Append(aFace);
       }
       aSelection = findCommonShape(aType, aList);
+      //if (aSelection.IsNull() && aType == TopAbs_EDGE) { // try to find selection by neighbours
+      //  aSelection = findCommonShapeByNB(aType, TopAbs_VERTEX, aList);
+      //}
     }
   }
   // in case of construction, there is no registered names for all sub-elements,
   // even for the main element; so, trying to find them by name (without "&" intersections)
-  if (aN < 2) {
+  if (aSelection.IsNull() && aN < 2) {
     size_t aConstrNamePos = aSubShapeName.find("/");
     bool isFullName = aConstrNamePos == std::string::npos;
-    std::string aContrName = aContName;
-    ResultPtr aConstr = aDoc->findByName(aContrName);
+    std::string anEmpty, aContrName = aContName;
+    ResultPtr aConstr = aDoc->findByName(aContrName, anEmpty, anUniqueContext);
     if (aConstr.get() && aConstr->groupName() == ModelAPI_ResultConstruction::group()) {
       theCont = aConstr;
       if (isFullName) {
@@ -845,10 +979,17 @@ bool Model_SelectionNaming::selectSubShape(const std::string& theType,
       if (aComposite.get()) {
         if (aType == TopAbs_VERTEX || aType == TopAbs_EDGE) {
           // collect all IDs in the name
+          bool isVertexByEdge = false;
           std::map<int, int> anIDs;
           if (!parseSubIndices(aComposite, aSubShapeName,
-              aType == TopAbs_EDGE ? "Edge" : "Vertex", anIDs))
-            return false;
+              aType == TopAbs_EDGE ? "Edge" : "Vertex", anIDs)) {
+            // there is a case when vertex is identified by one circle-edge (2253)
+            if (aType == TopAbs_VERTEX &&
+                parseSubIndices(aComposite, aSubShapeName, "Edge", anIDs))
+              isVertexByEdge = true;
+            else
+              return false;
+          }
 
           const int aSubNum = aComposite->numberOfSubs();
           for(int a = 0; a < aSubNum; a++) {
@@ -865,9 +1006,22 @@ bool Model_SelectionNaming::selectSubShape(const std::string& theType,
                   int anOrientation = abs(anIDs[aCompID]);
                   TopoDS_Shape aShape = aRes->shape()->impl<TopoDS_Shape>();
                   if (anOrientation == 1) {
-                    if (aType == aShape.ShapeType()) {
+                    if (!isVertexByEdge && aType == aShape.ShapeType()) {
                       theShapeToBeSelected = aRes->shape();
                       return true;
+                    } else if (isVertexByEdge && aType != aShape.ShapeType()) {
+                      // check that there is only one vertex produces by and circular edge
+                      TopoDS_Shape aShape = aRes->shape()->impl<TopoDS_Shape>();
+                      TopExp_Explorer anExp(aShape, TopAbs_VERTEX);
+                      if (anExp.More())
+                        aShape = anExp.Current();
+                      anExp.Next();
+                      if (!anExp.More() || anExp.Current().IsSame(aShape)) {
+                        std::shared_ptr<GeomAPI_Shape> aShapeToBeSelected(new GeomAPI_Shape());
+                        aShapeToBeSelected->setImpl(new TopoDS_Shape(aShape));
+                        theShapeToBeSelected = aShapeToBeSelected;
+                        return true;
+                      }
                     }
                   } else { // take first or second vertex of the edge
                     TopoDS_Shape aShape = aRes->shape()->impl<TopoDS_Shape>();
@@ -962,6 +1116,21 @@ bool Model_SelectionNaming::selectSubShape(const std::string& theType,
         }
       }
     }
+  } else if (aSelection.IsNull() && aN >= 2 && aType == TopAbs_VERTEX) {
+    // support of shape name as intersection separated by "&"
+    static std::string anEdgeType = "edge"; // for now it works only with su-edges
+    std::list<std::string>::iterator aSubNames = aListofNames.begin();
+    TopTools_ListOfShape aSubsList;
+    for(; aSubNames != aListofNames.end(); aSubNames++) {
+      std::string aSubName = *aSubNames;
+      std::shared_ptr<GeomAPI_Shape> aSubShapeFound;
+      std::shared_ptr<ModelAPI_Result> aContextFound;
+      if (selectSubShape(anEdgeType, aSubName, theDoc, aSubShapeFound, aContextFound)) {
+        if (aSubShapeFound.get())
+          aSubsList.Append(aSubShapeFound->impl<TopoDS_Shape>());
+      }
+    }
+    aSelection = findCommonShape(TopAbs_VERTEX, aSubsList);
   }
   if (!aSelection.IsNull()) {
     // Select it (must be after N=0 checking,