+ // Get base objects list.
+ AttributeSelectionListPtr aSelectionList = theFeature->selectionList(theArguments.front());
+ if (!aSelectionList.get()) {
+ theError = "Could not get selection list.";
+ return false;
+ }
+ if (aSelectionList->size() == 0) {
+ theError = "Empty selection list.";
+ return false;
+ }
+
+ if (theFeature->getKind() == BuildPlugin_Solid::ID()) {
+ /// remove objects of sub-type if ojects of correct type is in List, in some cases :
+ /// Solid builder: faces and shapes shells or solids seleted
+ /// --> remove faces
+
+ std::set<int> aRemove;
+ for (int anIndex = 0; anIndex < aSelectionList->size(); ++anIndex) {
+ AttributeSelectionPtr aSelection = aSelectionList->value(anIndex);
+ GeomShapePtr aShape = aSelection->value();
+ if (aShape.get()) {
+ GeomAPI_Shape::ShapeType aType = aShape->shapeType();
+ if ((aType == GeomAPI_Shape::SHAPE) ||
+ (aType == GeomAPI_Shape::SOLID) ||
+ (aType == GeomAPI_Shape::SHELL)) {
+
+ GeomAPI_ShapeExplorer anExp(aShape, GeomAPI_Shape::FACE);
+ for (; anExp.more(); anExp.next()) {
+ GeomShapePtr aFace = anExp.current();
+ for (int i = 0; i < aSelectionList->size(); ++i) {
+ AttributeSelectionPtr aSel = aSelectionList->value(i);
+ GeomShapePtr aShp = aSel->value();
+ if (aShp.get()) {
+ if (aShp->shapeType() == GeomAPI_Shape::FACE) {
+ if (aShp->isEqual(aFace))
+ aRemove.insert(i);
+ }
+ }
+ else {
+ aRemove.insert(anIndex);
+ }
+ }
+ }
+ }
+ }
+ }
+ if (aRemove.size() > 0)
+ aSelectionList->remove(aRemove);
+ }
+
+ // Collect base shapes.
+ ListOfShape anOriginalShapes;
+ for (int anIndex = 0; anIndex < aSelectionList->size(); ++anIndex) {
+ AttributeSelectionPtr aSelection = aSelectionList->value(anIndex);
+ if (!aSelection->context().get()) {
+ theError = "Invalid selection.";
+ return false;
+ }
+ GeomShapePtr aShape = aSelection->value();
+ if (!aShape.get())
+ aShape = aSelection->context()->shape();
+ anOriginalShapes.push_back(aShape);
+ }
+
+ std::shared_ptr<GeomAlgoAPI_MakeVolume> anAlgorithm(
+ new GeomAlgoAPI_MakeVolume(anOriginalShapes, false));
+
+ std::string anErr;
+ if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(anAlgorithm, "MakeVolume", anErr)) {
+ theError = anErr;
+ return false;
+ }
+
+ // set of allowed types of results
+ std::set<GeomAPI_Shape::ShapeType> aResultType;
+ std::string aType = theArguments.back();
+ if (aType == "solid")
+ aResultType.insert(GeomAPI_Shape::SOLID);
+ else if (aType == "compsolid") {
+ aResultType.insert(GeomAPI_Shape::COMPSOLID);
+ aResultType.insert(GeomAPI_Shape::SOLID);
+ }
+
+ GeomShapePtr aCompound = anAlgorithm->shape();
+ if (aCompound->shapeType() == GeomAPI_Shape::COMPOUND) {
+ GeomAPI_ShapeIterator anIt(aCompound);
+ GeomShapePtr aFoundSub;
+ for (; anIt.more() && !aFoundSub; anIt.next()) {
+ aFoundSub = anIt.current();
+ if (aResultType.count(aFoundSub->shapeType()) == 0) {
+ theError = "Unable to build a solid";
+ return false;
+ }
+ }
+ if (anIt.more() || !aFoundSub.get()) {
+ theError = "Unable to build a solid";
+ return false;
+ }
+ } else if (aResultType.count(aCompound->shapeType()) == 0) {
+ theError = "Unable to build a solid";
+ return false;
+ }
+ // check the internal faces presence
+ for(GeomAPI_ShapeExplorer aFaces(aCompound, GeomAPI_Shape::FACE); aFaces.more(); aFaces.next()) {
+ if (aFaces.current()->orientation() == GeomAPI_Shape::INTERNAL) {
+ theError = "Internal faces are not allowed in the resulting solid";
+ return false;
+ }
+ }
+
+ return true;