+ case BOOL_FUSE: {
+ if((anObjects.size() + aTools.size() + aCompSolidsObjects.size() + anEdgesAndFaces.size()) < 2) {
+ std::string aFeatureError = "Error: Not enough objects for boolean operation.";
+ setError(aFeatureError);
+ return;
+ }
+
+ // 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<std::shared_ptr<GeomAPI_Shape>, ListOfShape>::iterator anIt = aCompSolidsObjects.begin();
+ anIt != aCompSolidsObjects.end(); anIt++) {
+ std::shared_ptr<GeomAPI_Shape> aCompSolid = anIt->first;
+ ListOfShape& aUsedInOperationSolids = anIt->second;
+ aSolidsToFuse.insert(aSolidsToFuse.end(), aUsedInOperationSolids.begin(), aUsedInOperationSolids.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()) {
+ std::shared_ptr<GeomAPI_Shape> aSolidInCompSolid = anExp.current();
+ ListOfShape::iterator anIt = aUsedInOperationSolids.begin();
+ for(; anIt != aUsedInOperationSolids.end(); anIt++) {
+ if(aSolidInCompSolid->isEqual(*anIt)) {
+ break;
+ }
+ }
+ if(anIt == aUsedInOperationSolids.end()) {
+ aShapesToAdd.push_back(aSolidInCompSolid);
+ }
+ }
+ }
+
+ ListOfShape anOriginalShapes = aSolidsToFuse;
+ anOriginalShapes.insert(anOriginalShapes.end(), aShapesToAdd.begin(), aShapesToAdd.end());
+
+ // Cut edges and faces(if we have any) with solids.
+ GeomAlgoAPI_MakeShapeList aMakeShapeList;
+ GeomAPI_DataMapOfShapeShape aMapOfShapes;
+ std::shared_ptr<GeomAPI_Shape> aCuttedEdgesAndFaces;
+ if(!anEdgesAndFaces.empty()) {
+ std::shared_ptr<GeomAlgoAPI_Boolean> aCutAlgo(new GeomAlgoAPI_Boolean(anEdgesAndFaces, anOriginalShapes, GeomAlgoAPI_Boolean::BOOL_CUT));
+ if(aCutAlgo->isDone()) {
+ aCuttedEdgesAndFaces = aCutAlgo->shape();
+ aMakeShapeList.appendAlgo(aCutAlgo);
+ aMapOfShapes.merge(aCutAlgo->mapOfSubShapes());
+ }
+ }
+ anOriginalShapes.insert(anOriginalShapes.end(), anEdgesAndFaces.begin(), anEdgesAndFaces.end());
+
+ // If we have compsolids then cut with not used solids all others.
+ if(!aShapesToAdd.empty()) {
+ aSolidsToFuse.clear();
+ for(ListOfShape::iterator anIt = anOriginalShapes.begin(); anIt != anOriginalShapes.end(); anIt++) {
+ ListOfShape aOneObjectList;
+ aOneObjectList.push_back(*anIt);
+ std::shared_ptr<GeomAlgoAPI_Boolean> aCutAlgo(new GeomAlgoAPI_Boolean(aOneObjectList, aShapesToAdd, GeomAlgoAPI_Boolean::BOOL_CUT));
+
+ if(GeomAlgoAPI_ShapeTools::volume(aCutAlgo->shape()) > 1.e-7) {
+ aSolidsToFuse.push_back(aCutAlgo->shape());
+ aMakeShapeList.appendAlgo(aCutAlgo);
+ aMapOfShapes.merge(aCutAlgo->mapOfSubShapes());
+ }
+ }
+ }
+
+ if(!aSolidsToFuse.empty()) {
+ anObjects.clear();
+ anObjects.push_back(aSolidsToFuse.back());
+ aSolidsToFuse.pop_back();
+ aTools = aSolidsToFuse;
+ }
+
+ // Fuse all objects and all tools.
+ std::shared_ptr<GeomAPI_Shape> aShape;
+ if(anObjects.size() == 1 && aTools.empty()) {
+ aShape = anObjects.front();
+ } else if(anObjects.empty() && aTools.size() == 1) {
+ aShape = aTools.front();
+ } else if((anObjects.size() + aTools.size()) > 1){
+ std::shared_ptr<GeomAlgoAPI_Boolean> aFuseAlgo(new GeomAlgoAPI_Boolean(anObjects,
+ aTools,
+ (GeomAlgoAPI_Boolean::OperationType)aType));
+
+ // Checking that the algorithm worked properly.
+ if(!aFuseAlgo->isDone()) {
+ static const std::string aFeatureError = "Error: Boolean algorithm failed.";
+ setError(aFeatureError);
+ return;
+ }
+ if(aFuseAlgo->shape()->isNull()) {
+ static const std::string aShapeError = "Error: Resulting shape is Null.";
+ setError(aShapeError);
+ return;
+ }
+ if(!aFuseAlgo->isValid()) {
+ std::string aFeatureError = "Error: Resulting shape is not valid.";
+ setError(aFeatureError);
+ return;
+ }
+
+ aShape = aFuseAlgo->shape();
+ aMakeShapeList.appendAlgo(aFuseAlgo);
+ aMapOfShapes.merge(aFuseAlgo->mapOfSubShapes());