+ TNaming_SameShapeIterator aLabIter(theValue, theFinal->Label());
+ for(; aLabIter.More(); aLabIter.Next()) {
+ Handle(TNaming_NamedShape) aNS;
+ aLabIter.Label().FindAttribute(TNaming_NamedShape::GetID(), aNS);
+ if (aMustBeAtFinal && aNS != theFinal)
+ continue; // looking for old at the same final label only
+ TNaming_Evolution anEvolution = aNS->Evolution();
+ if (anEvolution == TNaming_PRIMITIVE) {
+ // check that this is not in the results already
+ const TDF_Label aResult = aNS->Label();
+ TDF_LabelList::Iterator aResIter(theResult);
+ for(; aResIter.More(); aResIter.Next()) {
+ if (aResIter.Value().IsEqual(aResult))
+ break;
+ }
+ if (!aResIter.More()) // not found, so add this new
+ theResult.Append(aResult);
+ }
+ if (anEvolution == TNaming_GENERATED || anEvolution == TNaming_MODIFY) {
+ for(TNaming_Iterator aThisIter(aNS); aThisIter.More(); aThisIter.Next()) {
+ if (aThisIter.NewShape().IsSame(theValue)) {
+ // continue recursively, null NS means that any NS are ok
+ findBases(theFinal, aThisIter.OldShape(), false, theResult);
+ }
+ }
+ }
+ }
+}
+
+// returns the sub-shapes of theSubType which belong to all theShapes (so, common or intersection)
+static void commonShapes(const TopoDS_ListOfShape& theShapes, TopAbs_ShapeEnum theSubType,
+ TopoDS_ListOfShape& theResults)
+{
+ TopoDS_ListOfShape::iterator aSubSel = theShapes.begin();
+ for(; aSubSel != theShapes.end(); aSubSel++) {
+ TopTools_MapOfShape aCurrentMap;
+ for(TopExp_Explorer anExp(*aSubSel, theSubType); anExp.More(); anExp.Next()) {
+ if (aCurrentMap.Add(anExp.Current()) && aSubSel == theShapes.begin())
+ theResults.Append(anExp.Current());
+ }
+ if (aSubSel != theShapes.begin()) { // remove from common shapes not in aCurrentMap
+ for(TopoDS_ListOfShape::Iterator aComIter(theResults); aComIter.More(); ) {
+ if (aCurrentMap.Contains(aComIter.Value()))
+ aComIter.Next();
+ else
+ theResults.Remove(aComIter);
+ }
+ }
+ }
+}
+
+/// Searches neighbor of theLevel of neighborhood to theValue in theContex
+static void findNeighbors(const TopoDS_Shape theContext, const TopoDS_Shape theValue,
+ const int theLevel, TopTools_MapOfShape& theResult)
+{
+ TopAbs_ShapeEnum aConnectorType = TopAbs_VERTEX; // type of the connector sub-shapes
+ if (theValue.ShapeType() == TopAbs_FACE)
+ aConnectorType = TopAbs_EDGE;
+ TopTools_MapOfShape aNBConnectors; // connector shapes that already belong to neighbors
+ for(TopExp_Explorer aValExp(theValue, aConnectorType); aValExp.More(); aValExp.Next()) {
+ aNBConnectors.Add(aValExp.Current());
+ }
+
+ for(int aLevel = 1; aLevel <= theLevel; aLevel++) {
+ TopoDS_ListOfShape aGoodCandidates;
+ TopExp_Explorer aCandidate(theContext, theValue.ShapeType());
+ for(; aCandidate.More(); aCandidate.Next()) {
+ TopExp_Explorer aCandConnector(aCandidate.Current(), aConnectorType);
+ for(; aCandConnector.More(); aCandConnector.Next()) {
+ if (aNBConnectors.Contains(aCandConnector.Current())) // candidate is neighbor
+ break;
+ }
+ if (aCandConnector.More()) {
+ if (aLevel == theLevel) { // add a NB into result: it is connected to other neighbors
+ theResult.Add(aCandidate.Current());
+ } else { // add to the NB of the current level
+ aGoodCandidates.Append(aCandidate.Current());
+ }
+ }
+ }
+ if (aLevel != theLevel) { // good candidates are added to neighbor of this level by connectors
+ for(TopoDS_ListOfShape::Iterator aGood(aGoodCandidates); aGood.More(); aGood.Next()) {
+ TopExp_Explorer aGoodConnector(aGood.Value(), aConnectorType);
+ for(; aGoodConnector.More(); aGoodConnector.Next()) {
+ aNBConnectors.Add(aGoodConnector.Current());
+ }
+ }
+ }
+ }
+}
+
+/// Searches the neighbor shape by neighbors defined in theNB in theContext shape
+static const TopoDS_Shape findNeighbor(const TopoDS_Shape theContext,
+ const std::list<std::pair<TopoDS_Shape, int> >& theNB)
+{
+ // searching for neighbors with minimum level
+ int aMinLevel = 0;
+ std::list<std::pair<TopoDS_Shape, int> >::const_iterator aNBIter = theNB.cbegin();
+ for(; aNBIter != theNB.cend(); aNBIter++) {
+ if (aMinLevel == 0 || aNBIter->second < aMinLevel) {
+ aMinLevel = aNBIter->second;
+ }
+ }
+ // collect all neighbors which are neighbors of sub-shapes with minimum level
+ bool aFirst = true;
+ TopoDS_ListOfShape aMatches;
+ for(aNBIter = theNB.cbegin(); aNBIter != theNB.cend(); aNBIter++) {
+ if (aNBIter->second == aMinLevel) {
+ TopTools_MapOfShape aThisNBs;
+ findNeighbors(theContext, aNBIter->first, aMinLevel, aThisNBs);
+ // aMatches must contain common part of all NBs lists
+ for(TopTools_MapOfShape::Iterator aThisNB(aThisNBs); aThisNB.More(); aThisNB.Next()) {
+ if (aFirst) {
+ aMatches.Append(aThisNB.Value());
+ } else {
+ // remove all in aMatches which are not in this NBs
+ for(TopoDS_ListOfShape::Iterator aMatch(aMatches); aMatch.More(); ) {
+ if (aThisNBs.Contains(aMatch.Value())) {
+ aMatch.Next();
+ } else {
+ aMatches.Remove(aMatch);
+ }