From 5fd6dc8864d08e1c453d7d8cea7d1dca5161e4bd Mon Sep 17 00:00:00 2001 From: dbv Date: Mon, 27 Nov 2017 19:11:49 +0300 Subject: [PATCH] Issue #2307: 1.1.2.5 Remove Sub-Shapes mode Added mode to select which sub-shapes should be removed. --- .../FeaturesAPI_RemoveSubShapes.cpp | 40 ++++- src/FeaturesAPI/FeaturesAPI_RemoveSubShapes.h | 14 +- src/FeaturesPlugin/CMakeLists.txt | 1 + .../FeaturesPlugin_RemoveSubShapes.cpp | 144 ++++++++++++++---- .../FeaturesPlugin_RemoveSubShapes.h | 38 ++++- .../FeaturesPlugin_Validators.cpp | 7 +- .../Test/TestRemoveSubShapes2.py | 47 ++++++ .../icons/keep_subshapes_32x32.png | Bin 0 -> 276 bytes .../icons/remove_subshapes_32x32.png | Bin 0 -> 275 bytes .../remove_subshapes_widget.xml | 31 +++- 10 files changed, 272 insertions(+), 50 deletions(-) create mode 100644 src/FeaturesPlugin/Test/TestRemoveSubShapes2.py create mode 100644 src/FeaturesPlugin/icons/keep_subshapes_32x32.png create mode 100644 src/FeaturesPlugin/icons/remove_subshapes_32x32.png diff --git a/src/FeaturesAPI/FeaturesAPI_RemoveSubShapes.cpp b/src/FeaturesAPI/FeaturesAPI_RemoveSubShapes.cpp index 24447bc00..4d5b40ba3 100644 --- a/src/FeaturesAPI/FeaturesAPI_RemoveSubShapes.cpp +++ b/src/FeaturesAPI/FeaturesAPI_RemoveSubShapes.cpp @@ -62,7 +62,20 @@ void FeaturesAPI_RemoveSubShapes::setBase(const ModelHighAPI_Selection& theBase) void FeaturesAPI_RemoveSubShapes::setSubShapesToKeep( const std::list& theSubShapes) { - fillAttribute(theSubShapes, mysubshapes); + fillAttribute(FeaturesPlugin_RemoveSubShapes::CREATION_METHOD_BY_KEEP_SUBSHAPES(), + mycreationMethod); + fillAttribute(theSubShapes, mysubshapesToKeep); + + execute(); +} + +//================================================================================================== +void FeaturesAPI_RemoveSubShapes::setSubShapesToRemove( + const std::list& theSubShapes) +{ + fillAttribute(FeaturesPlugin_RemoveSubShapes::CREATION_METHOD_BY_REMOVE_SUBSHAPES(), + mycreationMethod); + fillAttribute(theSubShapes, mysubshapesToRemove); execute(); } @@ -75,12 +88,27 @@ void FeaturesAPI_RemoveSubShapes::dump(ModelHighAPI_Dumper& theDumper) const AttributeSelectionPtr anAttrBaseShape = aBase->selection(FeaturesPlugin_RemoveSubShapes::BASE_SHAPE_ID()); - AttributeSelectionListPtr anAttrSubShapes = - aBase->selectionList(FeaturesPlugin_RemoveSubShapes::SUBSHAPES_ID()); - theDumper << aBase << " = model.addRemoveSubShapes(" << aDocName << - ", " << anAttrBaseShape << ")" << std::endl; - theDumper << aBase << ".setSubShapesToKeep(" << anAttrSubShapes << ")" << std::endl; + std::string aCreationMethod = + aBase->string(FeaturesPlugin_RemoveSubShapes::CREATION_METHOD())->value(); + + AttributeSelectionListPtr anAttrSubShapes; + + if (aCreationMethod == FeaturesPlugin_RemoveSubShapes::CREATION_METHOD_BY_KEEP_SUBSHAPES()) { + anAttrSubShapes = + aBase->selectionList(FeaturesPlugin_RemoveSubShapes::SUBSHAPES_TO_KEEP_ID()); + } + else { + anAttrSubShapes = + aBase->selectionList(FeaturesPlugin_RemoveSubShapes::SUBSHAPES_TO_REMOVE_ID()); + } + + theDumper << aBase << " = model.addRemoveSubShapes(" << aDocName << ", " << anAttrBaseShape << ")" + << std::endl; + theDumper << aBase + << (aCreationMethod == FeaturesPlugin_RemoveSubShapes::CREATION_METHOD_BY_KEEP_SUBSHAPES() ? + ".setSubShapesToKeep(" : ".setSubShapesToRemove(") + << anAttrSubShapes << ")" << std::endl; } //================================================================================================== diff --git a/src/FeaturesAPI/FeaturesAPI_RemoveSubShapes.h b/src/FeaturesAPI/FeaturesAPI_RemoveSubShapes.h index cabae5368..15a1d0495 100644 --- a/src/FeaturesAPI/FeaturesAPI_RemoveSubShapes.h +++ b/src/FeaturesAPI/FeaturesAPI_RemoveSubShapes.h @@ -50,11 +50,15 @@ public: FEATURESAPI_EXPORT virtual ~FeaturesAPI_RemoveSubShapes(); - INTERFACE_2(FeaturesPlugin_RemoveSubShapes::ID(), + INTERFACE_4(FeaturesPlugin_RemoveSubShapes::ID(), base, FeaturesPlugin_RemoveSubShapes::BASE_SHAPE_ID(), ModelAPI_AttributeSelection, /** Base */, - subshapes, FeaturesPlugin_RemoveSubShapes::SUBSHAPES_ID(), - ModelAPI_AttributeSelectionList, /** Subshapes */) + creationMethod, FeaturesPlugin_RemoveSubShapes::CREATION_METHOD(), + ModelAPI_AttributeString, /** Creation method */, + subshapesToKeep, FeaturesPlugin_RemoveSubShapes::SUBSHAPES_TO_KEEP_ID(), + ModelAPI_AttributeSelectionList, /** Subshapes to keep*/, + subshapesToRemove, FeaturesPlugin_RemoveSubShapes::SUBSHAPES_TO_REMOVE_ID(), + ModelAPI_AttributeSelectionList, /** Subshapes to remove*/) /// Modify objects attribute of the feature. FEATURESAPI_EXPORT @@ -64,6 +68,10 @@ public: FEATURESAPI_EXPORT void setSubShapesToKeep(const std::list& theSubShapes); + /// Modify tools attribute of the feature. + FEATURESAPI_EXPORT + void setSubShapesToRemove(const std::list& theSubShapes); + /// Dump wrapped feature FEATURESAPI_EXPORT virtual void dump(ModelHighAPI_Dumper& theDumper) const; diff --git a/src/FeaturesPlugin/CMakeLists.txt b/src/FeaturesPlugin/CMakeLists.txt index a828b1a94..81552dd4c 100644 --- a/src/FeaturesPlugin/CMakeLists.txt +++ b/src/FeaturesPlugin/CMakeLists.txt @@ -162,6 +162,7 @@ ADD_UNIT_TESTS(TestExtrusion.py TestIntersection.py TestUnion.py TestRemoveSubShapes.py + TestRemoveSubShapes2.py TestPipe.py TestRecover.py TestRecover1798.py diff --git a/src/FeaturesPlugin/FeaturesPlugin_RemoveSubShapes.cpp b/src/FeaturesPlugin/FeaturesPlugin_RemoveSubShapes.cpp index 53d02ab83..2f5412983 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_RemoveSubShapes.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_RemoveSubShapes.cpp @@ -21,6 +21,7 @@ #include "FeaturesPlugin_RemoveSubShapes.h" #include +#include #include #include #include @@ -38,6 +39,7 @@ //================================================================================================== FeaturesPlugin_RemoveSubShapes::FeaturesPlugin_RemoveSubShapes() +: myChangedInCode(false) { } @@ -46,59 +48,141 @@ void FeaturesPlugin_RemoveSubShapes::initAttributes() { data()->addAttribute(BASE_SHAPE_ID(), ModelAPI_AttributeSelection::typeId()); - data()->addAttribute(SUBSHAPES_ID(), ModelAPI_AttributeSelectionList::typeId()); + data()->addAttribute(CREATION_METHOD(), ModelAPI_AttributeString::typeId()); + + data()->addAttribute(SUBSHAPES_TO_KEEP_ID(), ModelAPI_AttributeSelectionList::typeId()); + + data()->addAttribute(SUBSHAPES_TO_REMOVE_ID(), ModelAPI_AttributeSelectionList::typeId()); } void FeaturesPlugin_RemoveSubShapes::attributeChanged(const std::string& theID) { ModelAPI_Feature::attributeChanged(theID); - if(theID == BASE_SHAPE_ID()) { - AttributeSelectionPtr aShapeAttrSelection = selection(BASE_SHAPE_ID()); - AttributeSelectionListPtr aSubShapesAttrList = selectionList(SUBSHAPES_ID()); - if(!aShapeAttrSelection.get() || !aSubShapesAttrList.get()) { - return; - } + if (myChangedInCode) return; - aSubShapesAttrList->clear(); + AttributeSelectionPtr aShapeAttrSelection = selection(BASE_SHAPE_ID()); + AttributeSelectionListPtr aSubShapesToKeepAttrList = selectionList(SUBSHAPES_TO_KEEP_ID()); + AttributeSelectionListPtr aSubShapesToRemoveAttrList = selectionList(SUBSHAPES_TO_REMOVE_ID()); + if (!aShapeAttrSelection.get() + || !aSubShapesToKeepAttrList.get() + || !aSubShapesToRemoveAttrList.get()) + { + return; + } - ResultPtr aContext = aShapeAttrSelection->context(); - ResultCompSolidPtr aResultCompSolid = - std::dynamic_pointer_cast(aContext); - if(!aResultCompSolid.get()) { - return; - } + ResultPtr aContext = aShapeAttrSelection->context(); + ResultCompSolidPtr aResultCompSolid = + std::dynamic_pointer_cast(aContext); + if(!aResultCompSolid.get()) { + aSubShapesToKeepAttrList->clear(); + aSubShapesToRemoveAttrList->clear(); + return; + } + const int aNumOfSubs = aResultCompSolid->numberOfSubs(); - GeomShapePtr aBaseShape = aShapeAttrSelection->value(); - if(!aBaseShape.get()) { - aBaseShape = aContext->shape(); - } - if(!aBaseShape.get()) { - return; - } - GeomAPI_Shape::ShapeType aShapeType = aBaseShape->shapeType(); - if(aShapeType != GeomAPI_Shape::WIRE - && aShapeType != GeomAPI_Shape::SHELL - && aShapeType != GeomAPI_Shape::COMPSOLID - && aShapeType != GeomAPI_Shape::COMPOUND) { + GeomShapePtr aBaseShape = aShapeAttrSelection->value(); + if(!aBaseShape.get()) { + aBaseShape = aContext->shape(); + } + + myChangedInCode = true; + + if(theID == BASE_SHAPE_ID()) { + aSubShapesToKeepAttrList->clear(); + aSubShapesToRemoveAttrList->clear(); + + if (!aBaseShape.get()) { return; } + for(GeomAPI_ShapeIterator anIt(aBaseShape); anIt.more(); anIt.next()) { GeomShapePtr aSubShape = anIt.current(); - const int aNumOfSubs = aResultCompSolid->numberOfSubs(); if(aNumOfSubs == 0) { - aSubShapesAttrList->append(aContext, aSubShape); + aSubShapesToKeepAttrList->append(aContext, aSubShape); } else { for(int anIndex = 0; anIndex < aResultCompSolid->numberOfSubs(); ++anIndex) { ResultBodyPtr aSubResult = aResultCompSolid->subResult(anIndex); if(aSubResult->shape()->isEqual(aSubShape)) { - aSubShapesAttrList->append(aSubResult, aSubShape); + aSubShapesToKeepAttrList->append(aSubResult, aSubShape); break; } } } } } + else if (theID == SUBSHAPES_TO_KEEP_ID()) + { + aSubShapesToRemoveAttrList->clear(); + + if (!aBaseShape.get()) { + return; + } + + int anIndex; + const int aSubsToKeepNb = aSubShapesToKeepAttrList->size(); + for(GeomAPI_ShapeIterator anIt(aBaseShape); anIt.more(); anIt.next()) { + GeomShapePtr aSubShape = anIt.current(); + for(anIndex = 0; anIndex < aSubsToKeepNb; ++anIndex) { + AttributeSelectionPtr anAttrSelectionInList = aSubShapesToKeepAttrList->value(anIndex); + GeomShapePtr aSubShapeToKeep = anAttrSelectionInList->value(); + if (aSubShapeToKeep.get() && aSubShapeToKeep->isEqual(aSubShape)) { + break; + } + } + + if (anIndex == aSubsToKeepNb) { + if(aNumOfSubs == 0) { + aSubShapesToRemoveAttrList->append(aContext, aSubShape); + } else { + for(int anIndex = 0; anIndex < aResultCompSolid->numberOfSubs(); ++anIndex) { + ResultBodyPtr aSubResult = aResultCompSolid->subResult(anIndex); + if(aSubResult->shape()->isEqual(aSubShape)) { + aSubShapesToRemoveAttrList->append(aSubResult, aSubShape); + break; + } + } + } + } + } + } + else if (theID == SUBSHAPES_TO_REMOVE_ID()) + { + aSubShapesToKeepAttrList->clear(); + + if (!aBaseShape.get()) { + return; + } + + int anIndex; + const int aSubsToRemoveNb = aSubShapesToRemoveAttrList->size(); + for(GeomAPI_ShapeIterator anIt(aBaseShape); anIt.more(); anIt.next()) { + GeomShapePtr aSubShape = anIt.current(); + for(anIndex = 0; anIndex < aSubsToRemoveNb; ++anIndex) { + AttributeSelectionPtr anAttrSelectionInList = aSubShapesToRemoveAttrList->value(anIndex); + GeomShapePtr aSubShapeToRemove = anAttrSelectionInList->value(); + if (aSubShapeToRemove.get() && aSubShapeToRemove->isEqual(aSubShape)) { + break; + } + } + + if (anIndex == aSubsToRemoveNb) { + if(aNumOfSubs == 0) { + aSubShapesToKeepAttrList->append(aContext, aSubShape); + } else { + for(int anIndex = 0; anIndex < aResultCompSolid->numberOfSubs(); ++anIndex) { + ResultBodyPtr aSubResult = aResultCompSolid->subResult(anIndex); + if(aSubResult->shape()->isEqual(aSubShape)) { + aSubShapesToKeepAttrList->append(aSubResult, aSubShape); + break; + } + } + } + } + } + } + + myChangedInCode = false; } //================================================================================================== @@ -106,7 +190,7 @@ void FeaturesPlugin_RemoveSubShapes::execute() { // Get base shape and sub-shapes list. AttributeSelectionPtr aShapeAttrSelection = selection(BASE_SHAPE_ID()); - AttributeSelectionListPtr aSubShapesAttrList = selectionList(SUBSHAPES_ID()); + AttributeSelectionListPtr aSubShapesAttrList = selectionList(SUBSHAPES_TO_KEEP_ID()); if(!aShapeAttrSelection.get() || !aSubShapesAttrList.get()) { return; } diff --git a/src/FeaturesPlugin/FeaturesPlugin_RemoveSubShapes.h b/src/FeaturesPlugin/FeaturesPlugin_RemoveSubShapes.h index 39cb6fabe..4bbe6a01c 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_RemoveSubShapes.h +++ b/src/FeaturesPlugin/FeaturesPlugin_RemoveSubShapes.h @@ -48,13 +48,42 @@ public: return MY_BASE_SHAPE_ID; } - /// Attribute name of sub-shapes. - inline static const std::string& SUBSHAPES_ID() + /// Attribute name for creation method. + inline static const std::string& CREATION_METHOD() { - static const std::string MY_SUBSHAPES_ID("subshapes"); + static const std::string MY_CREATION_METHOD_ID("creation_method"); + return MY_CREATION_METHOD_ID; + } + + /// Attribute name for creation method. + inline static const std::string& CREATION_METHOD_BY_KEEP_SUBSHAPES() + { + static const std::string MY_CREATION_METHOD_ID("by_keep_subshapes"); + return MY_CREATION_METHOD_ID; + } + + /// Attribute name for creation method. + inline static const std::string& CREATION_METHOD_BY_REMOVE_SUBSHAPES() + { + static const std::string MY_CREATION_METHOD_ID("by_remove_subshapes"); + return MY_CREATION_METHOD_ID; + } + + /// Attribute name of sub-shapes to keep. + inline static const std::string& SUBSHAPES_TO_KEEP_ID() + { + static const std::string MY_SUBSHAPES_ID("subshapes_to_keep"); return MY_SUBSHAPES_ID; } + /// Attribute name of sub-shapes to remove. + inline static const std::string& SUBSHAPES_TO_REMOVE_ID() + { + static const std::string MY_SUBSHAPES_ID("subshapes_to_remove"); + return MY_SUBSHAPES_ID; + } + + /// \return the kind of a feature. FEATURESPLUGIN_EXPORT virtual const std::string& getKind() { @@ -71,6 +100,9 @@ public: /// Creates a new part document if needed. FEATURESPLUGIN_EXPORT virtual void execute(); + +private: + bool myChangedInCode; }; #endif diff --git a/src/FeaturesPlugin/FeaturesPlugin_Validators.cpp b/src/FeaturesPlugin/FeaturesPlugin_Validators.cpp index fa2ab0695..ddcdfacf2 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Validators.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Validators.cpp @@ -771,7 +771,7 @@ bool FeaturesPlugin_ValidatorRemoveSubShapesResult::isValid( Events_InfoMessage& theError) const { static const std::string aBaseShapeID = "base_shape"; - static const std::string aSubShapesID = "subshapes"; + static const std::string aSubShapesID = "subshapes_to_keep"; if(theFeature->getKind() != "Remove_SubShapes") { theError = "Error: Feature \"%1\" does not supported by this validator."; @@ -801,6 +801,11 @@ bool FeaturesPlugin_ValidatorRemoveSubShapesResult::isValid( } GeomShapePtr aResultShape = aBaseShape->emptyCopied(); + if (aSubShapesAttrList->size() == 0) { + theError = "Error: Resulting shape is not valid."; + return false; + } + // Copy sub-shapes from list to new shape. for(int anIndex = 0; anIndex < aSubShapesAttrList->size(); ++anIndex) { AttributeSelectionPtr anAttrSelectionInList = aSubShapesAttrList->value(anIndex); diff --git a/src/FeaturesPlugin/Test/TestRemoveSubShapes2.py b/src/FeaturesPlugin/Test/TestRemoveSubShapes2.py new file mode 100644 index 000000000..f63005660 --- /dev/null +++ b/src/FeaturesPlugin/Test/TestRemoveSubShapes2.py @@ -0,0 +1,47 @@ +## Copyright (C) 2014-2017 CEA/DEN, EDF R&D +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +## +## See http:##www.salome-platform.org/ or +## email : webmaster.salome@opencascade.com +## + +from salome.shaper import model + +model.begin() +partSet = model.moduleDocument() +Part_1 = model.addPart(partSet) +Part_1_doc = Part_1.document() +Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY")) +SketchCircle_1 = Sketch_1.addCircle(-38.80617495711836, 0.1732418524871273, 42.63017006028262) +SketchCircle_2 = Sketch_1.addCircle(-117.8044596912521, -0.1732418524871385, 54.50817511994374) +model.do() +Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "Sketch_1")], model.selection(), 10, 0) +Remove_SubShapes_1 = model.addRemoveSubShapes(Part_1_doc, model.selection("COMPSOLID", "Extrusion_1_1")) +Remove_SubShapes_1.setSubShapesToRemove([model.selection("SOLID", "Extrusion_1_1_3")]) +model.do() +model.end() + +from GeomAPI import GeomAPI_Shape + +model.testNbResults(Remove_SubShapes_1, 1) +model.testNbSubResults(Remove_SubShapes_1, [2]) +model.testNbSubShapes(Remove_SubShapes_1, GeomAPI_Shape.SOLID, [2]) +model.testNbSubShapes(Remove_SubShapes_1, GeomAPI_Shape.FACE, [10]) +model.testNbSubShapes(Remove_SubShapes_1, GeomAPI_Shape.EDGE, [36]) +model.testNbSubShapes(Remove_SubShapes_1, GeomAPI_Shape.VERTEX, [72]) +model.testResultsVolumes(Remove_SubShapes_1, [136619.795923917088657617568969727]) + +assert(model.checkPythonDump()) diff --git a/src/FeaturesPlugin/icons/keep_subshapes_32x32.png b/src/FeaturesPlugin/icons/keep_subshapes_32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..45319ebe671524788d1eb7564b4d2e8a0b242460 GIT binary patch literal 276 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdzmUKs7M+SzC{oH>NS%G}c0*}aI z1_r(ZAk3I`t&aK z-@I#KmYxfT!vTAym_FIRvpy~Bf6wycf$mG=yk-U#1qMbn1+|wG&K_o*@NS%G}c0*}aI z1_r(ZAk3I`t&Cea?=9(U;Qiurq=*#yI$0Qk>t;?D010iPeC literal 0 HcmV?d00001 diff --git a/src/FeaturesPlugin/remove_subshapes_widget.xml b/src/FeaturesPlugin/remove_subshapes_widget.xml index 353881c45..4169fa587 100644 --- a/src/FeaturesPlugin/remove_subshapes_widget.xml +++ b/src/FeaturesPlugin/remove_subshapes_widget.xml @@ -29,12 +29,29 @@ email : webmaster.salome@opencascade.com - - - + + + + + + + + + + + + -- 2.39.2