+ case BOOL_FUSE: {
+ // Set objects.
+ theObjects.insert(theObjects.end(), anEdgesAndFaces.begin(), anEdgesAndFaces.end());
+ theObjects.insert(theObjects.end(), anObjects.begin(), anObjects.end());
+ theObjects.insert(theObjects.end(), aCompSolids.begin(), aCompSolids.end());
+
+ // Filter edges and faces in tools.
+ ListOfShape aTools;
+ for(ListOfShape::const_iterator anIt = theTools.cbegin(); anIt != theTools.cend(); ++anIt) {
+ if((*anIt)->shapeType() == GeomAPI_Shape::EDGE ||
+ (*anIt)->shapeType() == GeomAPI_Shape::FACE) {
+ anEdgesAndFaces.push_back(*anIt);
+ } else {
+ aTools.push_back(*anIt);
+ }
+ }
+
+ if((anObjects.size() + aTools.size() + aCompSolidsObjects.size() + anEdgesAndFaces.size()) < 2) {
+ myFeature->setError("Error: Not enough objects for boolean operation.");
+ return false;
+ }
+
+ // Collecting all solids which will be fused.
+ ListOfShape aSolidsToFuse;
+ aSolidsToFuse.insert(aSolidsToFuse.end(), anObjects.begin(), anObjects.end());
+ aSolidsToFuse.insert(aSolidsToFuse.end(), aTools.begin(), aTools.end());
+
+ // Collecting solids from compsolids which will not be modified in boolean operation and will be added to result.
+ ListOfShape aShapesToAdd;
+ for(std::map<GeomShapePtr, ListOfShape>::iterator anIt = aCompSolidsObjects.begin();
+ anIt != aCompSolidsObjects.end(); anIt++) {
+ GeomShapePtr aCompSolid = anIt->first;
+ ListOfShape& aUsedShapes = anIt->second;
+ aSolidsToFuse.insert(aSolidsToFuse.end(), aUsedShapes.begin(), aUsedShapes.end());
+
+ // Collect solids from compsolid which will not be modified in boolean operation.
+ for(GeomAPI_ShapeExplorer anExp(aCompSolid, GeomAPI_Shape::SOLID); anExp.more(); anExp.next()) {
+ GeomShapePtr aSolidInCompSolid = anExp.current();
+ ListOfShape::iterator anIt = aUsedShapes.begin();
+ for(; anIt != aUsedShapes.end(); anIt++) {
+ if(aSolidInCompSolid->isEqual(*anIt)) {
+ break;
+ }
+ }
+ if(anIt == aUsedShapes.end()) {
+ aShapesToAdd.push_back(aSolidInCompSolid);
+ }
+ }
+ }
+
+ // Cut edges and faces(if we have any) with solids.
+ ListOfShape aCutTools;
+ aCutTools.insert(aCutTools.end(), anObjects.begin(), anObjects.end());
+ aCutTools.insert(aCutTools.end(), aCompSolids.begin(), aCompSolids.end());
+ aCutTools.insert(aCutTools.end(), aTools.begin(), aTools.end());
+
+ std::shared_ptr<GeomAlgoAPI_MakeShapeList> aMakeShapeList(new GeomAlgoAPI_MakeShapeList());
+ if(!anEdgesAndFaces.empty() && !aCutTools.empty()) {
+ std::shared_ptr<GeomAlgoAPI_Boolean> aCutAlgo(new GeomAlgoAPI_Boolean(anEdgesAndFaces,
+ aCutTools,
+ GeomAlgoAPI_Boolean::BOOL_CUT));
+ if(aCutAlgo->isDone() && !aCutAlgo->shape()->isNull() && aCutAlgo->isValid()) {
+ anEdgesAndFaces.clear();
+ anEdgesAndFaces.push_back(aCutAlgo->shape());
+ aMakeShapeList->appendAlgo(aCutAlgo);
+ }
+ }
+
+ // If we have compsolids then cut with not used solids all others.
+ if(!aShapesToAdd.empty()) {
+ std::shared_ptr<GeomAlgoAPI_Boolean> aCutAlgo(new GeomAlgoAPI_Boolean(aSolidsToFuse,
+ aShapesToAdd,
+ GeomAlgoAPI_Boolean::BOOL_CUT));
+ if(aCutAlgo->isDone() && GeomAlgoAPI_ShapeTools::volume(aCutAlgo->shape()) > 1.e-27) {
+ aSolidsToFuse.clear();
+ aSolidsToFuse.push_back(aCutAlgo->shape());
+ aMakeShapeList->appendAlgo(aCutAlgo);
+ }
+ }
+