- }
- myType = SELTYPE_FILTER_BY_NEIGHBOR;
- return true;
- }
- }
-
- // weak naming to distinguish commons coming from intersection
- if (aLastCommon.Extent() > 1) {
- Selector_NExplode aNexp(aLastCommon);
- myWeakIndex = aNexp.index(theValue);
- if (myWeakIndex != -1) {
- // name the intersectors
- mySubSelList.clear();
- TopoDS_ListOfShape::Iterator anInt(aLastIntersectors);
- for (; anInt.More(); anInt.Next()) {
- if (!selectBySubSelector(theContext, anInt.Value(), theUseNeighbors)) {
- break; // if some selector is failed, stop and search another solution
- }
- }
- if (!anInt.More()) { // all intersectors were correctly named
- myType = SELTYPE_INTERSECT;
- return true;
- }
- }
- }
-
- // pure weak naming
- myType = SELTYPE_WEAK_NAMING;
- Selector_NExplode aNexp(theContext, theValue.ShapeType());
- myWeakIndex = aNexp.index(theValue);
- if (myWeakIndex != -1) {
- myShapeType = theValue.ShapeType();
- // searching for context shape label to store in myFinal
- myFinal.Nullify();
- if (TNaming_Tool::HasLabel(myLab, theContext)) {
- for(TNaming_SameShapeIterator aShapes(theContext, myLab); aShapes.More(); aShapes.Next())
- {
- Handle(TNaming_NamedShape) aNS;
- if (aShapes.Label().FindAttribute(TNaming_NamedShape::GetID(), aNS)) {
- TNaming_Evolution anEvolution = aNS->Evolution();
- if (anEvolution == TNaming_PRIMITIVE || anEvolution == TNaming_GENERATED ||
- anEvolution == TNaming_MODIFY) {
- // check this is a new shape
- for(TNaming_Iterator aNSIter(aNS); aNSIter.More(); aNSIter.Next()) {
- if (aNSIter.NewShape().IsSame(theContext)) {
- myFinal = aNS->Label();
- break;
- }
- }
- }
- }
- }
- }
- return true; // could be final empty (in case it is called recursively) or not
- }
-
- return false;
- }
- // searching for the base shapes of the value
- Handle(TNaming_NamedShape) aPrimitiveNS;
- NCollection_List<Handle(TNaming_NamedShape)> aModifList;
- for(TNaming_SameShapeIterator aShapes(theValue, myLab); aShapes.More(); aShapes.Next())
- {
- Handle(TNaming_NamedShape) aNS;
- if (aShapes.Label().FindAttribute(TNaming_NamedShape::GetID(), aNS)) {
- TNaming_Evolution anEvolution = aNS->Evolution();
- if (anEvolution == TNaming_PRIMITIVE) { // the value shape is declared as PRIMITIVE
- aPrimitiveNS = aNS;
- break;
- } else if (anEvolution == TNaming_GENERATED || anEvolution == TNaming_MODIFY) {
- // check this is a new shape
- TNaming_Iterator aNSIter(aNS);
- for(; aNSIter.More(); aNSIter.Next())
- if (aNSIter.NewShape().IsSame(theValue))
- break;
- if (aNSIter.More()) // new was found
- aModifList.Append(aNS);
- }
- }
- }
-
- if (!aPrimitiveNS.IsNull()) {
- myType = SELTYPE_PRIMITIVE;
- myFinal = aPrimitiveNS->Label();
- return true;
- }
-
- if (aModifList.Extent() > 1) { // searching for the best modification result: by context
- Handle(TNaming_NamedShape) aCandidate;
- NCollection_List<Handle(TNaming_NamedShape)>::Iterator aModIter(aModifList);
- for(; !aModifList.IsEmpty() && aModIter.More(); aModIter.Next()) {
- aCandidate = aModIter.Value();
- TDF_Label aFatherLab = aCandidate->Label().Father();
- Handle(TNaming_NamedShape) aFatherNS;
- if (aFatherLab.FindAttribute(TNaming_NamedShape::GetID(), aFatherNS)) {
- for(TNaming_Iterator anIter(aFatherNS); anIter.More(); anIter.Next()) {
- if (theContext.IsSame(anIter.NewShape())) { // found the best modification
- aModifList.Clear();
- break;
- }
- }
- }
- }
- // take the best candidate, or the last in the iteration
- aModifList.Clear();
- aModifList.Append(aCandidate);
- }
-
- if (!aModifList.IsEmpty()) {
- // searching for all the base shapes of this modification
- findBases(aModifList.First(), theValue, true, myBases);
- if (!myBases.IsEmpty()) {
- myFinal = aModifList.First()->Label();
- TopoDS_ListOfShape aCommon;
- findModificationResult(aCommon);
- // trying to search by neighbours
- if (aCommon.Extent() > 1) { // more complicated selection
- if (!theUseNeighbors)
- return false;
-
- // searching by neighbours
- std::list<std::pair<TopoDS_Shape, int> > aNBs;//neighbor sub-shape -> level of neighborhood
- for(int aLevel = 1; true; aLevel++) {
- TopTools_MapOfShape aNewNB;
- findNeighbors(theContext, theValue, aLevel, aNewNB);
- if (aNewNB.Extent() == 0) { // there are no neighbors of the given level, stop iteration
- break;
- }
- // iterate by the order in theContext to keep same naming names
- TopExp_Explorer anOrder(theContext, theValue.ShapeType());
- for (; anOrder.More(); anOrder.Next()) {
- if (aNewNB.Contains(anOrder.Current())) {
- TopoDS_Shape aNewNBShape = anOrder.Current();
- // check which can be named correctly, without "by neighbors" type
- Selector_Selector aSelector(myLab.FindChild(1));
- if (aSelector.select(theContext, aNewNBShape, false)) {// add to list of good NBs
- aNBs.push_back(std::pair<TopoDS_Shape, int>(aNewNBShape, aLevel));
- }
- }
- }
- TopoDS_Shape aResult = findNeighbor(theContext, aNBs);
- if (!aResult.IsNull() && aResult.IsSame(theValue)) {
- std::list<std::pair<TopoDS_Shape, int> >::iterator aNBIter = aNBs.begin();
- for(; aNBIter != aNBs.end(); aNBIter++) {
- if (!selectBySubSelector(theContext, aNBIter->first, theUseNeighbors)) {
- return false; // something is wrong because before this selection was ok
- }
- myNBLevel.push_back(aNBIter->second);
-
- }
- myType = SELTYPE_FILTER_BY_NEIGHBOR;
- return true;
- }
- }
- // filter by neighbours did not help
- if (aCommon.Extent() > 1) { // weak naming between the common results
- Selector_NExplode aNexp(aCommon);
- myWeakIndex = aNexp.index(theValue);
- if (myWeakIndex == -1)
- return false;
- }
- }
- }
- myType = SELTYPE_MODIFICATION;
- if (myBases.IsEmpty()) { // selection based on the external shape, weak name by finals compound
- TopoDS_ListOfShape aCommon;
- myFinal = aModifList.First()->Label();
- Handle(TNaming_NamedShape) aNS;
- myFinal.FindAttribute(TNaming_NamedShape::GetID(), aNS);
- for(TNaming_Iterator aFinalIter(aNS); aFinalIter.More(); aFinalIter.Next()) {
- const TopoDS_Shape& aNewShape = aFinalIter.NewShape();
- if (!aNewShape.IsNull())
- aCommon.Append(aNewShape);
- }
- Selector_NExplode aNexp(aCommon);
- myWeakIndex = aNexp.index(theValue);
- if (myWeakIndex == -1)
- return false;
- }
- return true;
- }
-
- // not found a good result
- return false;