From 5f2dd854a118fb9dffec8658d1d234e6587c539f Mon Sep 17 00:00:00 2001 From: dbv Date: Wed, 18 May 2016 12:25:10 +0300 Subject: [PATCH] Issue #1367: Fill feature. --- src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp | 35 ++++++- src/FeaturesPlugin/FeaturesPlugin_Boolean.h | 1 + src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp | 2 + .../FeaturesPlugin_Validators.cpp | 86 +++++++++++++++--- .../FeaturesPlugin_Validators.h | 21 ++++- src/FeaturesPlugin/boolean_widget.xml | 10 +- src/FeaturesPlugin/icons/bool_common.png | Bin 403 -> 276 bytes src/FeaturesPlugin/icons/bool_cut.png | Bin 279 -> 266 bytes src/FeaturesPlugin/icons/bool_fill.png | Bin 0 -> 269 bytes src/FeaturesPlugin/icons/bool_fuse.png | Bin 300 -> 251 bytes src/FeaturesPlugin/icons/bool_smash.png | Bin 263 -> 262 bytes src/GeomAlgoAPI/GeomAlgoAPI_Boolean.cpp | 11 +++ src/GeomAlgoAPI/GeomAlgoAPI_Partition.cpp | 24 ++--- src/GeomAlgoAPI/GeomAlgoAPI_PaveFiller.cpp | 24 ++--- src/GeomAlgoAPI/GeomAlgoAPI_Prism.cpp | 24 ++--- src/GeomAlgoAPI/GeomAlgoAPI_Revolution.cpp | 48 +++------- src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.cpp | 33 +++++-- src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.h | 8 +- src/GeomValidators/CMakeLists.txt | 2 - .../GeomValidators_BooleanSelection.cpp | 79 ---------------- .../GeomValidators_BooleanSelection.h | 31 ------- src/GeomValidators/GeomValidators_Plugin.cpp | 2 - 22 files changed, 206 insertions(+), 235 deletions(-) create mode 100644 src/FeaturesPlugin/icons/bool_fill.png delete mode 100644 src/GeomValidators/GeomValidators_BooleanSelection.cpp delete mode 100644 src/GeomValidators/GeomValidators_BooleanSelection.h 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 99812c5462d3b982f58000b90fb47f0fd3bc62c9..c8f86a1a3affb83365a20df6f61dab961249b6c6 100644 GIT binary patch delta 227 zcmV<9038351C#=gB#|)~f589%4#5Gqk!$S$000V(`#$05KS57Pev>7an!Mr~^hFFzNuf1E`6yS%eD@ dumk=x004n@0&^&1_&@*v002ovPDHLkV1lv+Sj7MU delta 326 zcmV-M0lEH^0+R!fBnkm@Qb$4nuFf3kks%uj!vFvd!vV){sAQ2wAAdIdjAP#b009I^ zL_t(oN9~or4#7|q#yy26@&I0gAQ21Rf;QS%)W3)Yn}J;uUck`7YBfo4+;6zja4wft z1b6r)XK26gmwVIG1QBVIsdn%ma2p9n)@YMo=J73W~xWa2L z0&>t~Cpc8S32~H~Lx0NIT`dWjsU?uDxBWt+zscLZV=|SddqCnP0q&tN2(7fnY-t#r z#M=ZA&XtDwZGp<)3w-P;QMVXLU{@>mUeZ?jy7XfHPZ? zBSa*SlCw4Sspt;&A`9E{rbxw80*}DPL>BiSQ4yNS%G}c0*}aI z1_r)^Ak4U9V)k30phSslL`iUdT1k0gQ7S`0VrE{6US4X6f{C7io@I`4ogYw5x2KC^ zNQ8UxkN^MeFIp5oYI=O-ScLAO){T-5n#ZyP^>{9C`TK13|0$0G*?X)Kt}rgVVuJ70kBo)KVrfRT~f=3-N>VQ!P(8K{vE4F_JnguGXz-AJIsp^38d27D{ z%^EldfJ#h|S=j0kT$rj3fSHBOB3yXX0izBWbpYG})Wp~LSeCu(%F ULAU3wv;Y7A07*qoM6N<$f>UiTBLDyZ delta 115 zcmV-(0F3{J0*3;SJPN`901m +#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); -- 2.30.2