From: dbv Date: Wed, 18 May 2016 09:25:10 +0000 (+0300) Subject: Issue #1367: Fill feature. X-Git-Tag: V_2.3.1~84 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=5f2dd854a118fb9dffec8658d1d234e6587c539f;p=modules%2Fshaper.git Issue #1367: Fill feature. --- diff --git a/src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp b/src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp index 6e0d65be1..065e065fc 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -129,7 +130,8 @@ void FeaturesPlugin_Boolean::execute() switch(aType) { case BOOL_CUT: - case BOOL_COMMON:{ + case BOOL_COMMON: + case BOOL_FILL: { if((anObjects.empty() && aCompSolidsObjects.empty()) || aTools.empty()) { std::string aFeatureError = "Error: Not enough objects for boolean operation."; setError(aFeatureError); @@ -141,7 +143,13 @@ void FeaturesPlugin_Boolean::execute() std::shared_ptr anObject = *anObjectsIt; ListOfShape aListWithObject; aListWithObject.push_back(anObject); - GeomAlgoAPI_Boolean aBoolAlgo(aListWithObject, aTools, (GeomAlgoAPI_Boolean::OperationType)aType); + GeomAlgoAPI_MakeShape aBoolAlgo; (aListWithObject, aTools, (GeomAlgoAPI_Boolean::OperationType)aType); + + switch(aType) { + case BOOL_CUT: aBoolAlgo = GeomAlgoAPI_Boolean(aListWithObject, aTools, GeomAlgoAPI_Boolean::BOOL_CUT); break; + case BOOL_COMMON: aBoolAlgo = GeomAlgoAPI_Boolean(aListWithObject, aTools, GeomAlgoAPI_Boolean::BOOL_COMMON); break; + case BOOL_FILL: aBoolAlgo = GeomAlgoAPI_Partition(aListWithObject, aTools); break; + } // Checking that the algorithm worked properly. if(!aBoolAlgo.isDone()) { @@ -189,9 +197,26 @@ void FeaturesPlugin_Boolean::execute() } } - std::shared_ptr aBoolAlgo(new GeomAlgoAPI_Boolean(aUsedInOperationSolids, - aTools, - (GeomAlgoAPI_Boolean::OperationType)aType)); + std::shared_ptr aBoolAlgo; + + switch(aType) { + case BOOL_CUT: { + aBoolAlgo.reset(new GeomAlgoAPI_Boolean(aUsedInOperationSolids, + aTools, + GeomAlgoAPI_Boolean::BOOL_CUT)); + break; + } + case BOOL_COMMON: { + aBoolAlgo.reset(new GeomAlgoAPI_Boolean(aUsedInOperationSolids, + aTools, + GeomAlgoAPI_Boolean::BOOL_COMMON)); + break; + } + case BOOL_FILL: { + aBoolAlgo.reset(new GeomAlgoAPI_Partition(aUsedInOperationSolids, aTools)); + break; + } + } // Checking that the algorithm worked properly. if(!aBoolAlgo->isDone()) { diff --git a/src/FeaturesPlugin/FeaturesPlugin_Boolean.h b/src/FeaturesPlugin/FeaturesPlugin_Boolean.h index fd25cff88..79d703174 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Boolean.h +++ b/src/FeaturesPlugin/FeaturesPlugin_Boolean.h @@ -24,6 +24,7 @@ public: BOOL_CUT, BOOL_FUSE, BOOL_COMMON, + BOOL_FILL, BOOL_SMASH }; diff --git a/src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp b/src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp index efb079e15..4bea20fc2 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp @@ -44,6 +44,8 @@ FeaturesPlugin_Plugin::FeaturesPlugin_Plugin() new FeaturesPlugin_ValidatorPipeLocations); aFactory->registerValidator("FeaturesPlugin_ValidatorCanBeEmpty", new FeaturesPlugin_ValidatorCanBeEmpty); + aFactory->registerValidator("FeaturesPlugin_BooleanSelection", + new FeaturesPlugin_BooleanSelection); // register this plugin ModelAPI_Session::get()->registerPlugin(this); diff --git a/src/FeaturesPlugin/FeaturesPlugin_Validators.cpp b/src/FeaturesPlugin/FeaturesPlugin_Validators.cpp index 83ab5ed75..37d03e3a9 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Validators.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Validators.cpp @@ -7,10 +7,12 @@ #include "FeaturesPlugin_Validators.h" #include +#include #include #include -#include #include +#include +#include #include @@ -22,7 +24,7 @@ #include #include -//================================================================================================= +//================================================================================================== bool FeaturesPlugin_ValidatorPipeLocations::isValid(const std::shared_ptr& theFeature, const std::list& theArguments, std::string& theError) const @@ -66,13 +68,13 @@ bool FeaturesPlugin_ValidatorPipeLocations::isValid(const std::shared_ptr& theArguments, std::string& theError) const @@ -143,7 +145,7 @@ bool FeaturesPlugin_ValidatorBaseForGeneration::isValid(const AttributePtr& theA return true; } -//================================================================================================= +//================================================================================================== bool FeaturesPlugin_ValidatorBaseForGeneration::isValidAttribute(const AttributePtr& theAttribute, const std::list& theArguments, std::string& theError) const @@ -231,7 +233,7 @@ bool FeaturesPlugin_ValidatorBaseForGeneration::isValidAttribute(const Attribute return true; } -//================================================================================================= +//================================================================================================== bool FeaturesPlugin_ValidatorCompositeLauncher::isValid(const AttributePtr& theAttribute, const std::list& theArguments, std::string& theError) const @@ -276,7 +278,7 @@ bool FeaturesPlugin_ValidatorCompositeLauncher::isValid(const AttributePtr& theA return aValid; } -//================================================================================================= +//================================================================================================== bool FeaturesPlugin_ValidatorCanBeEmpty::isValid(const std::shared_ptr& theFeature, const std::list& theArguments, std::string& theError) const @@ -322,13 +324,13 @@ bool FeaturesPlugin_ValidatorCanBeEmpty::isValid(const std::shared_ptr& theArguments, std::string& theError) const @@ -456,4 +458,66 @@ bool FeaturesPlugin_ValidatorBaseForWire::isValid(const AttributePtr& theAttribu } return true; -} \ No newline at end of file +} + +//================================================================================================== +bool FeaturesPlugin_BooleanSelection::isValid(const AttributePtr& theAttribute, + const std::list& theArguments, + std::string& theError) const +{ + AttributeSelectionListPtr anAttrSelectionList = std::dynamic_pointer_cast(theAttribute); + if(!anAttrSelectionList.get()) { + theError = "Error: this validator can only work with selection list attributes in Boolean feature."; + return false; + } + FeaturePtr aFeature = std::dynamic_pointer_cast(theAttribute->owner()); + int anOperationType = aFeature->integer("bool_type")->value(); + + for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) { + AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex); + if(!anAttrSelection.get()) { + theError = "Error: empty attribute selection."; + return false; + } + ResultPtr aContext = anAttrSelection->context(); + if(!aContext.get()) { + theError = "Error: empty selection context."; + return false; + } + ResultConstructionPtr aResultConstruction = + std::dynamic_pointer_cast(aContext); + if(aResultConstruction.get()) { + theError = "Error: Result construction not allowed for selection."; + return false; + } + std::shared_ptr aShape = anAttrSelection->value(); + if(!aShape.get()) { + aShape = aContext->shape(); + } + if(!aShape.get()) { + theError = "Error: empty shape."; + return false; + } + int aShapeType = aShape->shapeType(); + if(anOperationType == 1) { + // Fuse operation. Allow to select edges, faces and solids. + if(aShapeType != GeomAPI_Shape::EDGE && + aShapeType != GeomAPI_Shape::FACE && + aShapeType != GeomAPI_Shape::SOLID && + aShapeType != GeomAPI_Shape::COMPSOLID && + aShapeType != GeomAPI_Shape::COMPOUND) { + theError = "Error: selected shape has the wrong type."; + return false; + } + } else { + if(aShapeType != GeomAPI_Shape::SOLID && + aShapeType != GeomAPI_Shape::COMPSOLID && + aShapeType != GeomAPI_Shape::COMPOUND) { + theError = "Error: selected shape has the wrong type."; + return false; + } + } + } + + return true; +} diff --git a/src/FeaturesPlugin/FeaturesPlugin_Validators.h b/src/FeaturesPlugin/FeaturesPlugin_Validators.h index 66006583f..1b957a777 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Validators.h +++ b/src/FeaturesPlugin/FeaturesPlugin_Validators.h @@ -66,9 +66,8 @@ public: /// \class FeaturesPlugin_ValidatorCanBeEmpty /// \ingroup Validators -/// \brief A validator for extrusion direction attribute and bounding planes for extrusion and -/// revolution. Allows them to be empty if base objects are planar and do not contain -/// vertices and edges. +/// \brief A validator for extrusion direction attribute. Allows it to be empty if base objects are +/// planar and do not contain vertices and edges. class FeaturesPlugin_ValidatorCanBeEmpty: public ModelAPI_FeatureValidator { public: @@ -104,4 +103,20 @@ public: std::string& theError) const; }; +/// \class FeaturesPlugin_BooleanSelection +/// \ingroup Validators +/// \brief Validates selection for boolean operation. +class FeaturesPlugin_BooleanSelection: public ModelAPI_AttributeValidator +{ +public: + /// \return True if the attribute is valid. It checks whether the selection + /// is acceptable for boolean operation. + /// \param[in] theAttribute an attribute to check. + /// \param[in] theArguments a filter parameters. + /// \param[out] theError error message. + virtual bool isValid(const AttributePtr& theAttribute, + const std::list& theArguments, + std::string& theError) const; +}; + #endif diff --git a/src/FeaturesPlugin/boolean_widget.xml b/src/FeaturesPlugin/boolean_widget.xml index 53a10a97b..3d1a0ac58 100644 --- a/src/FeaturesPlugin/boolean_widget.xml +++ b/src/FeaturesPlugin/boolean_widget.xml @@ -6,9 +6,9 @@ buttons_dir="horizontal" label="Operation type" tooltip="Type of boolean operation" - string_list="Cut Fuse Common Smash" + string_list="Cut Fuse Common Fill Smash" use_in_title="true" - icons_list="icons/Features/bool_cut.png icons/Features/bool_fuse.png icons/Features/bool_common.png icons/Features/bool_smash.png" + icons_list="icons/Features/bool_cut.png icons/Features/bool_fuse.png icons/Features/bool_common.png icons/Features/bool_fill.png icons/Features/bool_smash.png" default="0" /> - - + - - + diff --git a/src/FeaturesPlugin/icons/bool_common.png b/src/FeaturesPlugin/icons/bool_common.png index 99812c546..c8f86a1a3 100644 Binary files a/src/FeaturesPlugin/icons/bool_common.png and b/src/FeaturesPlugin/icons/bool_common.png differ diff --git a/src/FeaturesPlugin/icons/bool_cut.png b/src/FeaturesPlugin/icons/bool_cut.png index dd494d7d8..8f52d3aac 100644 Binary files a/src/FeaturesPlugin/icons/bool_cut.png and b/src/FeaturesPlugin/icons/bool_cut.png differ diff --git a/src/FeaturesPlugin/icons/bool_fill.png b/src/FeaturesPlugin/icons/bool_fill.png new file mode 100644 index 000000000..5e03aa25e Binary files /dev/null and b/src/FeaturesPlugin/icons/bool_fill.png differ diff --git a/src/FeaturesPlugin/icons/bool_fuse.png b/src/FeaturesPlugin/icons/bool_fuse.png index 5369a50a5..b005af12d 100644 Binary files a/src/FeaturesPlugin/icons/bool_fuse.png and b/src/FeaturesPlugin/icons/bool_fuse.png differ diff --git a/src/FeaturesPlugin/icons/bool_smash.png b/src/FeaturesPlugin/icons/bool_smash.png index bf82ac272..6a12a0a76 100644 Binary files a/src/FeaturesPlugin/icons/bool_smash.png and b/src/FeaturesPlugin/icons/bool_smash.png differ diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Boolean.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Boolean.cpp index 2fa01fadd..21458a9ce 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Boolean.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Boolean.cpp @@ -7,6 +7,7 @@ #include "GeomAlgoAPI_Boolean.h" #include +#include #include #include @@ -77,6 +78,16 @@ void GeomAlgoAPI_Boolean::build(const ListOfShape& theObjects, if(aResult.ShapeType() == TopAbs_COMPOUND) { aResult = GeomAlgoAPI_DFLoader::refineResult(aResult); } + if(aResult.ShapeType() == TopAbs_COMPOUND) { + std::shared_ptr aGeomShape(new GeomAPI_Shape); + aGeomShape->setImpl(new TopoDS_Shape(aResult)); + ListOfShape aCompSolids, aFreeSolids; + aGeomShape = GeomAlgoAPI_ShapeTools::combineShapes(aGeomShape, + GeomAPI_Shape::COMPSOLID, + aCompSolids, + aFreeSolids); + aResult = aGeomShape->impl(); + } std::shared_ptr aShape(new GeomAPI_Shape()); aShape->setImpl(new TopoDS_Shape(aResult)); diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Partition.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Partition.cpp index 55455220c..7034f9d4c 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Partition.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Partition.cpp @@ -69,24 +69,14 @@ void GeomAlgoAPI_Partition::build(const ListOfShape& theObjects, aResult = GeomAlgoAPI_DFLoader::refineResult(aResult); } if(aResult.ShapeType() == TopAbs_COMPOUND) { - std::shared_ptr aCompound(new GeomAPI_Shape); - aCompound->setImpl(new TopoDS_Shape(aResult)); + std::shared_ptr aGeomShape(new GeomAPI_Shape); + aGeomShape->setImpl(new TopoDS_Shape(aResult)); ListOfShape aCompSolids, aFreeSolids; - GeomAlgoAPI_ShapeTools::combineShapes(aCompound, GeomAPI_Shape::COMPSOLID, aCompSolids, aFreeSolids); - if(aCompSolids.size() == 1 && aFreeSolids.size() == 0) { - aResult = aCompSolids.front()->impl(); - } else if (aCompSolids.size() > 1 || (aCompSolids.size() >= 1 && aFreeSolids.size() >= 1)) { - TopoDS_Compound aResultComp; - TopoDS_Builder aBuilder; - aBuilder.MakeCompound(aResultComp); - for(ListOfShape::const_iterator anIter = aCompSolids.cbegin(); anIter != aCompSolids.cend(); anIter++) { - aBuilder.Add(aResultComp, (*anIter)->impl()); - } - for(ListOfShape::const_iterator anIter = aFreeSolids.cbegin(); anIter != aFreeSolids.cend(); anIter++) { - aBuilder.Add(aResultComp, (*anIter)->impl()); - } - aResult = aResultComp; - } + aGeomShape = GeomAlgoAPI_ShapeTools::combineShapes(aGeomShape, + GeomAPI_Shape::COMPSOLID, + aCompSolids, + aFreeSolids); + aResult = aGeomShape->impl(); } // Setting result. diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_PaveFiller.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_PaveFiller.cpp index 3dd1cb0b0..6f9d183aa 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_PaveFiller.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_PaveFiller.cpp @@ -58,24 +58,14 @@ void GeomAlgoAPI_PaveFiller::build(const ListOfShape& theListOfShape, const bool aResult = GeomAlgoAPI_DFLoader::refineResult(aResult); } if(theIsMakeCompSolids && aResult.ShapeType() == TopAbs_COMPOUND) { - std::shared_ptr aCompound(new GeomAPI_Shape); - aCompound->setImpl(new TopoDS_Shape(aResult)); + std::shared_ptr aGeomShape(new GeomAPI_Shape); + aGeomShape->setImpl(new TopoDS_Shape(aResult)); ListOfShape aCompSolids, aFreeSolids; - GeomAlgoAPI_ShapeTools::combineShapes(aCompound, GeomAPI_Shape::COMPSOLID, aCompSolids, aFreeSolids); - if(aCompSolids.size() == 1 && aFreeSolids.size() == 0) { - aResult = aCompSolids.front()->impl(); - } else if (aCompSolids.size() > 1 || (aCompSolids.size() >= 1 && aFreeSolids.size() >= 1)) { - TopoDS_Compound aResultComp; - TopoDS_Builder aBuilder; - aBuilder.MakeCompound(aResultComp); - for(ListOfShape::const_iterator anIter = aCompSolids.cbegin(); anIter != aCompSolids.cend(); anIter++) { - aBuilder.Add(aResultComp, (*anIter)->impl()); - } - for(ListOfShape::const_iterator anIter = aFreeSolids.cbegin(); anIter != aFreeSolids.cend(); anIter++) { - aBuilder.Add(aResultComp, (*anIter)->impl()); - } - aResult = aResultComp; - } + aGeomShape = GeomAlgoAPI_ShapeTools::combineShapes(aGeomShape, + GeomAPI_Shape::COMPSOLID, + aCompSolids, + aFreeSolids); + aResult = aGeomShape->impl(); } std::shared_ptr aShape(new GeomAPI_Shape()); diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Prism.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Prism.cpp index 7f2bd0b49..0c0136f17 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Prism.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Prism.cpp @@ -417,24 +417,14 @@ void GeomAlgoAPI_Prism::build(const GeomShapePtr& theBaseShape, } if(aResult.ShapeType() == TopAbs_COMPOUND) { - GeomShapePtr aCompound(new GeomAPI_Shape); - aCompound->setImpl(new TopoDS_Shape(aResult)); + std::shared_ptr aGeomShape(new GeomAPI_Shape); + aGeomShape->setImpl(new TopoDS_Shape(aResult)); ListOfShape aCompSolids, aFreeSolids; - GeomAlgoAPI_ShapeTools::combineShapes(aCompound, GeomAPI_Shape::COMPSOLID, aCompSolids, aFreeSolids); - if(aCompSolids.size() == 1 && aFreeSolids.size() == 0) { - aResult = aCompSolids.front()->impl(); - } else if (aCompSolids.size() > 1 || (aCompSolids.size() >= 1 && aFreeSolids.size() >= 1)) { - TopoDS_Compound aResultComp; - TopoDS_Builder aBuilder; - aBuilder.MakeCompound(aResultComp); - for(ListOfShape::const_iterator anIter = aCompSolids.cbegin(); anIter != aCompSolids.cend(); anIter++) { - aBuilder.Add(aResultComp, (*anIter)->impl()); - } - for(ListOfShape::const_iterator anIter = aFreeSolids.cbegin(); anIter != aFreeSolids.cend(); anIter++) { - aBuilder.Add(aResultComp, (*anIter)->impl()); - } - aResult = aResultComp; - } + aGeomShape = GeomAlgoAPI_ShapeTools::combineShapes(aGeomShape, + GeomAPI_Shape::COMPSOLID, + aCompSolids, + aFreeSolids); + aResult = aGeomShape->impl(); } } diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Revolution.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Revolution.cpp index 889cce352..50f49e2f9 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Revolution.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Revolution.cpp @@ -271,24 +271,14 @@ void GeomAlgoAPI_Revolution::build(const GeomShapePtr& theBaseSh aResult = GeomAlgoAPI_DFLoader::refineResult(aResult); } if(aResult.ShapeType() == TopAbs_COMPOUND) { - GeomShapePtr aCompound(new GeomAPI_Shape); - aCompound->setImpl(new TopoDS_Shape(aResult)); + std::shared_ptr aGeomShape(new GeomAPI_Shape); + aGeomShape->setImpl(new TopoDS_Shape(aResult)); ListOfShape aCompSolids, aFreeSolids; - GeomAlgoAPI_ShapeTools::combineShapes(aCompound, GeomAPI_Shape::COMPSOLID, aCompSolids, aFreeSolids); - if(aCompSolids.size() == 1 && aFreeSolids.size() == 0) { - aResult = aCompSolids.front()->impl(); - } else if (aCompSolids.size() > 1 || (aCompSolids.size() >= 1 && aFreeSolids.size() >= 1)) { - TopoDS_Compound aResultComp; - TopoDS_Builder aBuilder; - aBuilder.MakeCompound(aResultComp); - for(ListOfShape::const_iterator anIter = aCompSolids.cbegin(); anIter != aCompSolids.cend(); anIter++) { - aBuilder.Add(aResultComp, (*anIter)->impl()); - } - for(ListOfShape::const_iterator anIter = aFreeSolids.cbegin(); anIter != aFreeSolids.cend(); anIter++) { - aBuilder.Add(aResultComp, (*anIter)->impl()); - } - aResult = aResultComp; - } + aGeomShape = GeomAlgoAPI_ShapeTools::combineShapes(aGeomShape, + GeomAPI_Shape::COMPSOLID, + aCompSolids, + aFreeSolids); + aResult = aGeomShape->impl(); } // If after cut we got more than one solids then take closest to the center of mass of the base face. @@ -477,24 +467,14 @@ void GeomAlgoAPI_Revolution::build(const GeomShapePtr& theBaseSh } if(aResult.ShapeType() == TopAbs_COMPOUND) { - GeomShapePtr aCompound(new GeomAPI_Shape); - aCompound->setImpl(new TopoDS_Shape(aResult)); + std::shared_ptr aGeomShape(new GeomAPI_Shape); + aGeomShape->setImpl(new TopoDS_Shape(aResult)); ListOfShape aCompSolids, aFreeSolids; - GeomAlgoAPI_ShapeTools::combineShapes(aCompound, GeomAPI_Shape::COMPSOLID, aCompSolids, aFreeSolids); - if(aCompSolids.size() == 1 && aFreeSolids.size() == 0) { - aResult = aCompSolids.front()->impl(); - } else if (aCompSolids.size() > 1 || (aCompSolids.size() >= 1 && aFreeSolids.size() >= 1)) { - TopoDS_Compound aResultComp; - TopoDS_Builder aBuilder; - aBuilder.MakeCompound(aResultComp); - for(ListOfShape::const_iterator anIter = aCompSolids.cbegin(); anIter != aCompSolids.cend(); anIter++) { - aBuilder.Add(aResultComp, (*anIter)->impl()); - } - for(ListOfShape::const_iterator anIter = aFreeSolids.cbegin(); anIter != aFreeSolids.cend(); anIter++) { - aBuilder.Add(aResultComp, (*anIter)->impl()); - } - aResult = aResultComp; - } + aGeomShape = GeomAlgoAPI_ShapeTools::combineShapes(aGeomShape, + GeomAPI_Shape::COMPSOLID, + aCompSolids, + aFreeSolids); + aResult = aGeomShape->impl(); } // If after cut we got more than one solids then take closest to the center of mass of the base face. diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.cpp index 4ce4640ef..87e6d83c2 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.cpp @@ -90,17 +90,19 @@ std::shared_ptr GeomAlgoAPI_ShapeTools::centreOfMass(const std::sha } //================================================================================================= -void GeomAlgoAPI_ShapeTools::combineShapes(const std::shared_ptr theCompound, - const GeomAPI_Shape::ShapeType theType, - ListOfShape& theCombinedShapes, - ListOfShape& theFreeShapes) +std::shared_ptr GeomAlgoAPI_ShapeTools::combineShapes(const std::shared_ptr theCompound, + const GeomAPI_Shape::ShapeType theType, + ListOfShape& theCombinedShapes, + ListOfShape& theFreeShapes) { + GeomShapePtr aResult = theCompound; + if(!theCompound.get()) { - return; + return aResult; } if(theType != GeomAPI_Shape::SHELL && theType != GeomAPI_Shape::COMPSOLID) { - return; + return aResult; } TopAbs_ShapeEnum aTS = TopAbs_EDGE; @@ -125,7 +127,7 @@ void GeomAlgoAPI_ShapeTools::combineShapes(const std::shared_ptr BOPCol_IndexedDataMapOfShapeListOfShape aMapSA; BOPTools::MapShapesAndAncestors(aShapesComp, aTS, aTA, aMapSA); if(aMapSA.IsEmpty()) { - return; + return aResult; } // Get all shapes with common subshapes and free shapes. @@ -213,6 +215,23 @@ void GeomAlgoAPI_ShapeTools::combineShapes(const std::shared_ptr theFreeShapes.push_back(aGeomShape); } } + + if(theCombinedShapes.size() == 1 && theFreeShapes.size() == 0) { + aResult = theCombinedShapes.front(); + } else if (theCombinedShapes.size() > 1 || (theCombinedShapes.size() >= 1 && theFreeShapes.size() >= 1)) { + TopoDS_Compound aResultComp; + TopoDS_Builder aBuilder; + aBuilder.MakeCompound(aResultComp); + for(ListOfShape::const_iterator anIter = theCombinedShapes.cbegin(); anIter != theCombinedShapes.cend(); anIter++) { + aBuilder.Add(aResultComp, (*anIter)->impl()); + } + for(ListOfShape::const_iterator anIter = theFreeShapes.cbegin(); anIter != theFreeShapes.cend(); anIter++) { + aBuilder.Add(aResultComp, (*anIter)->impl()); + } + aResult->setImpl(new TopoDS_Shape(aResultComp)); + } + + return aResult; } //================================================================================================= diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.h b/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.h index 3fdee67c5..9b08fe8a1 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.h +++ b/src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.h @@ -35,10 +35,10 @@ public: /// \param[in] theType type of combine. /// \param[out] theCombinedShapes resulting shapes. /// \param[out] theFreeShapes shapes that does not have common subshapes. - static void combineShapes(const std::shared_ptr theCompound, - const GeomAPI_Shape::ShapeType theType, - ListOfShape& theCombinedShapes, - ListOfShape& theFreeShapes); + static std::shared_ptr combineShapes(const std::shared_ptr theCompound, + const GeomAPI_Shape::ShapeType theType, + ListOfShape& theCombinedShapes, + ListOfShape& theFreeShapes); /// \brief Calculates bounding box for theShapes /// \return list of eight points. diff --git a/src/GeomValidators/CMakeLists.txt b/src/GeomValidators/CMakeLists.txt index c64d2a557..03b6952b6 100644 --- a/src/GeomValidators/CMakeLists.txt +++ b/src/GeomValidators/CMakeLists.txt @@ -18,7 +18,6 @@ SET(PROJECT_HEADERS GeomValidators_Tools.h GeomValidators_ZeroOffset.h GeomValidators_Different.h - GeomValidators_BooleanSelection.h GeomValidators_IntersectionSelection.h ) @@ -37,7 +36,6 @@ SET(PROJECT_SOURCES GeomValidators_Tools.cpp GeomValidators_ZeroOffset.cpp GeomValidators_Different.cpp - GeomValidators_BooleanSelection.cpp GeomValidators_IntersectionSelection.cpp ) diff --git a/src/GeomValidators/GeomValidators_BooleanSelection.cpp b/src/GeomValidators/GeomValidators_BooleanSelection.cpp deleted file mode 100644 index cc8823fed..000000000 --- a/src/GeomValidators/GeomValidators_BooleanSelection.cpp +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (C) 2014-20xx CEA/DEN, EDF R&D - -// File: GeomValidators_BooleanSelection.cpp -// Created: 3 Feb 2016 -// Author: Dmitry Bobylev - -#include "GeomValidators_BooleanSelection.h" - -#include -#include -#include - -bool GeomValidators_BooleanSelection::isValid(const AttributePtr& theAttribute, - const std::list& theArguments, - std::string& theError) const -{ - if(!theAttribute.get()) { - theError = "Error: empty selection."; - return false; - } - FeaturePtr aFeature = std::dynamic_pointer_cast(theAttribute->owner()); - int anOperationType = aFeature->integer("bool_type")->value(); - AttributeSelectionListPtr anAttrSelectionList = std::dynamic_pointer_cast(theAttribute); - for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) { - AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex); - if(!anAttrSelection.get()) { - theError = "Error: empty attribute selection."; - return false; - } - ResultPtr aContext = anAttrSelection->context(); - if(!aContext.get()) { - theError = "Error: empty selection context."; - return false; - } - FeaturePtr aFeature = ModelAPI_Feature::feature(aContext); - if(!aFeature.get()) { - theError = "Error: empty feature."; - return false; - } - std::string aFeatureKind = aFeature->getKind(); - if(aFeatureKind == "Sketch" || - aFeatureKind == "Plane" || - aFeatureKind == "Axis") { - theError = "Error: "; - theError += aFeatureKind; - theError += " shape is not allowed for selection."; - return false; - } - std::shared_ptr aShape = anAttrSelection->value(); - if(!aShape.get()) { - aShape = aContext->shape(); - } - if(!aShape.get()) { - theError = "Error: empty shape."; - return false; - } - int aShapeType = aShape->shapeType(); - if(anOperationType == 1) { - // Fuse operation. Allow to select edges, faces and solids. - if(aShapeType != GeomAPI_Shape::EDGE && - aShapeType != GeomAPI_Shape::FACE && - aShapeType != GeomAPI_Shape::SOLID && - aShapeType != GeomAPI_Shape::COMPSOLID && - aShapeType != GeomAPI_Shape::COMPOUND) { - theError = "Error: selected shape has the wrong type."; - return false; - } - } else { - if(aShapeType != GeomAPI_Shape::SOLID && - aShapeType != GeomAPI_Shape::COMPSOLID && - aShapeType != GeomAPI_Shape::COMPOUND) { - theError = "Error: selected shape has the wrong type."; - return false; - } - } - } - - return true; -} diff --git a/src/GeomValidators/GeomValidators_BooleanSelection.h b/src/GeomValidators/GeomValidators_BooleanSelection.h deleted file mode 100644 index 8271288ee..000000000 --- a/src/GeomValidators/GeomValidators_BooleanSelection.h +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (C) 2014-20xx CEA/DEN, EDF R&D - -// File: GeomValidators_BooleanSelection.h -// Created: 3 Feb 2016 -// Author: Dmitry Bobylev - -#ifndef GeomValidators_BooleanSelection_H -#define GeomValidators_BooleanSelection_H - -#include - -#include -#include - -/// \class GeomValidators_BooleanSelection -/// \ingroup Validators -/// \brief Validates selection for boolean operation. -class GeomValidators_BooleanSelection: public ModelAPI_AttributeValidator -{ -public: - /// \return True if the attribute is valid. It checks whether the selection - /// is acceptable for boolean operation. - /// \param[in] theAttribute an attribute to check. - /// \param[in] theArguments a filter parameters. - /// \param[out] theError error message. - GEOMVALIDATORS_EXPORT virtual bool isValid(const AttributePtr& theAttribute, - const std::list& theArguments, - std::string& theError) const; -}; - -#endif diff --git a/src/GeomValidators/GeomValidators_Plugin.cpp b/src/GeomValidators/GeomValidators_Plugin.cpp index 831ad0dc9..fcdd134e1 100644 --- a/src/GeomValidators/GeomValidators_Plugin.cpp +++ b/src/GeomValidators/GeomValidators_Plugin.cpp @@ -4,7 +4,6 @@ #include #include -#include #include #include #include @@ -38,7 +37,6 @@ GeomValidators_Plugin::GeomValidators_Plugin() aFactory->registerValidator("GeomValidators_PartitionArguments", new GeomValidators_PartitionArguments); aFactory->registerValidator("GeomValidators_ShapeType", new GeomValidators_ShapeType); aFactory->registerValidator("GeomValidators_ZeroOffset", new GeomValidators_ZeroOffset); - aFactory->registerValidator("GeomValidators_BooleanSelection", new GeomValidators_BooleanSelection); aFactory->registerValidator("GeomValidators_IntersectionSelection", new GeomValidators_IntersectionSelection); aFactory->registerValidator("GeomValidators_FeatureKind", new GeomValidators_FeatureKind);