+ return aParent;
+}
+
+void FeaturesPlugin_Boolean::ObjectHierarchy::ObjectsByType(
+ ListOfShape& theShapesByType,
+ ListOfShape& theOtherShapes,
+ const GeomAPI_Shape::ShapeType theMinType,
+ const GeomAPI_Shape::ShapeType theMaxType) const
+{
+ if (theMinType > theMaxType)
+ return ObjectsByType(theShapesByType, theOtherShapes, theMaxType, theMinType);
+
+ // no need to select objects if whole range is specified
+ if (theMinType == GeomAPI_Shape::COMPOUND && theMaxType == GeomAPI_Shape::SHAPE) {
+ theShapesByType.insert(theShapesByType.end(), myObjects.begin(), myObjects.end());
+ return;
+ }
+
+ for (ListOfShape::const_iterator anIt = myObjects.begin(); anIt != myObjects.end(); ++anIt) {
+ GeomAPI_Shape::ShapeType aType = (*anIt)->shapeType();
+ if (aType >= theMinType && aType <= theMaxType)
+ theShapesByType.push_back(*anIt);
+ else
+ theOtherShapes.push_back(*anIt);
+ }
+}
+
+
+void FeaturesPlugin_Boolean::ObjectHierarchy::SplitCompound(const GeomShapePtr& theCompShape,
+ ListOfShape& theUsed,
+ ListOfShape& theNotUsed) const
+{
+ theUsed.clear();
+ theNotUsed.clear();
+
+ const ListOfShape& aSubs = mySubshapes.find(theCompShape)->second;
+ SetOfShape aSubsSet;
+ aSubsSet.insert(aSubs.begin(), aSubs.end());
+
+ for (GeomAPI_ShapeExplorer anExp(theCompShape, GeomAPI_Shape::SOLID);
+ anExp.more(); anExp.next()) {
+ GeomShapePtr aCurrent = anExp.current();
+ if (aSubsSet.find(aCurrent) == aSubsSet.end())
+ theNotUsed.push_back(aCurrent);
+ else
+ theUsed.push_back(aCurrent);
+ }
+}
+
+bool FeaturesPlugin_Boolean::ObjectHierarchy::IsEmpty() const
+{
+ return myObjects.empty();
+}
+
+FeaturesPlugin_Boolean::ObjectHierarchy::Iterator FeaturesPlugin_Boolean::ObjectHierarchy::Begin()
+{
+ return Iterator(this);
+}
+
+FeaturesPlugin_Boolean::ObjectHierarchy::Iterator FeaturesPlugin_Boolean::ObjectHierarchy::End()
+{
+ return Iterator(this, false);
+}
+
+FeaturesPlugin_Boolean::ObjectHierarchy::Iterator::Iterator(
+ FeaturesPlugin_Boolean::ObjectHierarchy* theHierarchy, bool isBegin)
+ : myHierarchy(theHierarchy)
+{
+ if (isBegin) {
+ myObject = myHierarchy->myObjects.begin();
+ SkipAlreadyProcessed();
+ } else
+ myObject = myHierarchy->myObjects.end();
+}
+
+void FeaturesPlugin_Boolean::ObjectHierarchy::Iterator::SkipAlreadyProcessed()
+{
+ while (myObject != myHierarchy->myObjects.end() &&
+ myHierarchy->myProcessedObjects.find(*myObject) != myHierarchy->myProcessedObjects.end())
+ ++myObject;
+}
+
+bool FeaturesPlugin_Boolean::ObjectHierarchy::Iterator::operator==(const Iterator& theOther) const
+{
+ return myObject == theOther.myObject;
+}
+
+bool FeaturesPlugin_Boolean::ObjectHierarchy::Iterator::operator!=(const Iterator& theOther) const
+{
+ return !operator==(theOther);
+}
+
+FeaturesPlugin_Boolean::ObjectHierarchy::Iterator&
+FeaturesPlugin_Boolean::ObjectHierarchy::Iterator::operator++()
+{
+ ++myObject;
+ SkipAlreadyProcessed();
+ return *this;
+}
+
+FeaturesPlugin_Boolean::ObjectHierarchy::Iterator
+FeaturesPlugin_Boolean::ObjectHierarchy::Iterator::operator++(int)
+{
+ Iterator aCurrent;
+ aCurrent.myHierarchy = myHierarchy;
+ aCurrent.myObject = myObject;
+
+ // increase iterator
+ operator++();
+
+ return aCurrent;
+}
+
+GeomShapePtr FeaturesPlugin_Boolean::ObjectHierarchy::Iterator::operator*() const
+{
+ myHierarchy->myProcessedObjects.insert(*myObject);
+ return *myObject;