- // 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(myLab, theValue);
- if (aIsFound) { // additional check for selection and delete evolution only: also could not use
- aIsFound = false;
- for(TNaming_SameShapeIterator aShapes(theValue, myLab); 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 && !myBaseDocumentLab.IsNull() &&
- TNaming_Tool::HasLabel(myBaseDocumentLab, theValue))
- {
- TNaming_SameShapeIterator aShapes(theValue, myBaseDocumentLab);
- 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;
- }
- }
- }
- }
- if (!aIsFound) {
- TopAbs_ShapeEnum aSelectionType = theValue.ShapeType();
- myShapeType = aSelectionType;
- if (aSelectionType == TopAbs_COMPOUND || aSelectionType == TopAbs_COMPSOLID ||
- aSelectionType == TopAbs_SHELL || aSelectionType == TopAbs_WIRE)
- { // iterate all sub-shapes and select them on sublabels
- for(TopoDS_Iterator aSubIter(theValue); aSubIter.More(); aSubIter.Next()) {
- if (!selectBySubSelector(
- theContext, aSubIter.Value(), theUseNeighbors, theUseIntersections)) {
- return false; // if some selector is failed, everything is failed
- }
- }
- myType = SELTYPE_CONTAINER;
- return true;
- }
-
- // try to find the shape of the higher level type in the context shape
- bool aFacesTried = false; // for identification of vertices, faces are tried, then edges
- TopoDS_ListOfShape aLastCommon; // to store the commons not good, but may be used for weak
- TopoDS_ListOfShape aLastIntersectors;
- while(theUseIntersections && (aSelectionType != TopAbs_FACE || !aFacesTried)) {
- if (aSelectionType == TopAbs_FACE) {
- if (theValue.ShapeType() != TopAbs_VERTEX)
- break;
- 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()) {
- if (aSelectionType == TopAbs_EDGE &&
- BRep_Tool::Degenerated(TopoDS::Edge(aSelExp.Current())))
- continue;
- TopExp_Explorer aSubExp(aSelExp.Current(), theValue.ShapeType());
- for(; aSubExp.More(); aSubExp.Next()) {
- if (aSubExp.Current().IsSame(theValue)) {
- if (anIntersectors.Add(aSelExp.Current()))
- anIntList.Append(aSelExp.Current());
- break;
- }
- }
- }
- // check that solution is only one
- TopoDS_ListOfShape aCommon;
- commonShapes(anIntList, theValue.ShapeType(), aCommon);
- if (aCommon.Extent() == 1 && aCommon.First().IsSame(theValue)) {
- // name the intersectors
- mySubSelList.clear();
- TopoDS_ListOfShape::Iterator anInt(anIntList);
- for (; anInt.More(); anInt.Next()) {
- if (!selectBySubSelector(theContext, anInt.Value(), theUseNeighbors, false)) {
- break; // if some selector is failed, stop and search another solution
- }
- }
- if (!anInt.More()) { // all intersectors were correctly named
- myType = SELTYPE_INTERSECT;
- return true;
- }
- } else if (aCommon.Extent() > 1 && aLastCommon.IsEmpty()) {
- aLastCommon = aCommon;
- aLastIntersectors = anIntList;
- }
- }
-
- if (!theUseNeighbors)
- return false;
-
- // searching by neighbors
- 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));
- aSelector.setBaseDocument(myBaseDocumentLab);
- if (aSelector.select(theContext, aNewNBShape, false, 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, false, false)) {
- return false; // something is wrong because before this selection was ok
- }
- myNBLevel.push_back(aNBIter->second);
-
- }
- 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, theUseIntersections)) {
- break; // if some selector is failed, stop and search another solution
- }
- }
- if (!anInt.More()) { // all intersectors were correctly named
- myType = SELTYPE_INTERSECT;
- return true;
- }
- }
- }