From fe268de000b3e7890f6d7c1be565326d6602e857 Mon Sep 17 00:00:00 2001 From: azv Date: Tue, 25 Feb 2020 10:05:13 +0300 Subject: [PATCH] =?utf8?q?Task=203.2.=20To=20keep=20compounds=E2=80=99=20s?= =?utf8?q?ub-shapes=20for=20all=20operations=20(issue=20#3139)?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Refactor the Intersection feature. --- src/FeaturesAPI/FeaturesAPI.i | 1 + src/FeaturesAPI/FeaturesAPI_Intersection.cpp | 13 +++- src/FeaturesAPI/FeaturesAPI_Intersection.h | 5 +- src/FeaturesPlugin/CMakeLists.txt | 4 + .../FeaturesPlugin_Intersection.cpp | 75 ++++++++----------- .../FeaturesPlugin_Intersection.h | 14 +--- ...estIntersection_MultiLevelCompound_v0_1.py | 44 +++++++++++ ...estIntersection_MultiLevelCompound_v0_2.py | 43 +++++++++++ ...stIntersection_MultiLevelCompound_v95_1.py | 44 +++++++++++ ...stIntersection_MultiLevelCompound_v95_2.py | 43 +++++++++++ 10 files changed, 226 insertions(+), 60 deletions(-) create mode 100644 src/FeaturesPlugin/Test/TestIntersection_MultiLevelCompound_v0_1.py create mode 100644 src/FeaturesPlugin/Test/TestIntersection_MultiLevelCompound_v0_2.py create mode 100644 src/FeaturesPlugin/Test/TestIntersection_MultiLevelCompound_v95_1.py create mode 100644 src/FeaturesPlugin/Test/TestIntersection_MultiLevelCompound_v95_2.py diff --git a/src/FeaturesAPI/FeaturesAPI.i b/src/FeaturesAPI/FeaturesAPI.i index 7d1505907..c084ba96c 100644 --- a/src/FeaturesAPI/FeaturesAPI.i +++ b/src/FeaturesAPI/FeaturesAPI.i @@ -41,6 +41,7 @@ %feature("kwargs") addCommon; %feature("kwargs") addCut; %feature("kwargs") addFuse; +%feature("kwargs") addIntersection; %feature("kwargs") addMultiRotation; %feature("kwargs") addMultiTranslation; %feature("kwargs") addPartition; diff --git a/src/FeaturesAPI/FeaturesAPI_Intersection.cpp b/src/FeaturesAPI/FeaturesAPI_Intersection.cpp index 5e85db2d3..ee3b99583 100644 --- a/src/FeaturesAPI/FeaturesAPI_Intersection.cpp +++ b/src/FeaturesAPI/FeaturesAPI_Intersection.cpp @@ -66,14 +66,21 @@ void FeaturesAPI_Intersection::dump(ModelHighAPI_Dumper& theDumper) const AttributeSelectionListPtr anAttrObjects = aBase->selectionList(FeaturesPlugin_Intersection::OBJECT_LIST_ID()); - theDumper << aBase << " = model.addIntersection(" << aDocName << ", " - << anAttrObjects << ")" << std::endl; + theDumper << aBase << " = model.addIntersection(" << aDocName << ", " << anAttrObjects; + + if (!aBase->data()->version().empty()) + theDumper << ", keepSubResults = True"; + + theDumper << ")" << std::endl; } //================================================================================================== IntersectionPtr addIntersection(const std::shared_ptr& thePart, - const std::list& theObjects) + const std::list& theObjects, + const bool keepSubResults) { std::shared_ptr aFeature = thePart->addFeature(FeaturesAPI_Intersection::ID()); + if (!keepSubResults) + aFeature->data()->setVersion(""); return IntersectionPtr(new FeaturesAPI_Intersection(aFeature, theObjects)); } diff --git a/src/FeaturesAPI/FeaturesAPI_Intersection.h b/src/FeaturesAPI/FeaturesAPI_Intersection.h index 4135816c8..400c520df 100644 --- a/src/FeaturesAPI/FeaturesAPI_Intersection.h +++ b/src/FeaturesAPI/FeaturesAPI_Intersection.h @@ -68,7 +68,8 @@ typedef std::shared_ptr IntersectionPtr; /// \ingroup CPPHighAPI /// \brief Create Intersection feature. FEATURESAPI_EXPORT -IntersectionPtr addIntersection(const std::shared_ptr& thePart, - const std::list& theObjects); +IntersectionPtr addIntersection(const std::shared_ptr& part, + const std::list& objects, + const bool keepSubResults = false); #endif // FeaturesAPI_Intersection_H_ diff --git a/src/FeaturesPlugin/CMakeLists.txt b/src/FeaturesPlugin/CMakeLists.txt index 4aff68961..af203545b 100644 --- a/src/FeaturesPlugin/CMakeLists.txt +++ b/src/FeaturesPlugin/CMakeLists.txt @@ -633,4 +633,8 @@ ADD_UNIT_TESTS(TestExtrusion.py TestMultiRotation_MultiLevelCompound_v95_2.py TestMultiRotation_MultiLevelCompound_v95_3.py TestMultiRotation_MultiLevelCompound_v95_4.py + TestIntersection_MultiLevelCompound_v0_1.py + TestIntersection_MultiLevelCompound_v0_2.py + TestIntersection_MultiLevelCompound_v95_1.py + TestIntersection_MultiLevelCompound_v95_2.py ) diff --git a/src/FeaturesPlugin/FeaturesPlugin_Intersection.cpp b/src/FeaturesPlugin/FeaturesPlugin_Intersection.cpp index 1fa907924..23830042e 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Intersection.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Intersection.cpp @@ -26,11 +26,14 @@ #include #include +#include #include #include #include +static const std::string INTERSECTION_VERSION_1("v9.5"); + //================================================================================================= FeaturesPlugin_Intersection::FeaturesPlugin_Intersection() { @@ -39,28 +42,19 @@ FeaturesPlugin_Intersection::FeaturesPlugin_Intersection() //================================================================================================= void FeaturesPlugin_Intersection::initAttributes() { - data()->addAttribute(OBJECT_LIST_ID(), + AttributePtr anObjectsAttr = data()->addAttribute(OBJECT_LIST_ID(), ModelAPI_AttributeSelectionList::typeId()); + + initVersion(INTERSECTION_VERSION_1, anObjectsAttr, AttributePtr()); } //================================================================================================= void FeaturesPlugin_Intersection::execute() { - ListOfShape anObjects; - + GeomAPI_ShapeHierarchy anObjectsHierarchy; + ListOfShape aPlanes; // Getting objects. - AttributeSelectionListPtr anObjectsSelList = selectionList(OBJECT_LIST_ID()); - for (int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) { - std::shared_ptr anObjectAttr = - anObjectsSelList->value(anObjectsIndex); - std::shared_ptr anObject = anObjectAttr->value(); - if (!anObject.get()) { - return; - } - anObjects.push_back(anObject); - } - - if(anObjects.empty()) { + if (!processAttribute(OBJECT_LIST_ID(), anObjectsHierarchy, aPlanes)) { setError("Error: Objects or tools are empty."); return; } @@ -68,6 +62,7 @@ void FeaturesPlugin_Intersection::execute() int aResultIndex = 0; // Create result. + const ListOfShape& anObjects = anObjectsHierarchy.objects(); GeomMakeShapePtr anIntersectionAlgo(new GeomAlgoAPI_Intersection(anObjects)); // Checking that the algorithm worked properly. @@ -77,38 +72,32 @@ void FeaturesPlugin_Intersection::execute() return; } + std::shared_ptr aMakeShapeList(new GeomAlgoAPI_MakeShapeList); + aMakeShapeList->appendAlgo(anIntersectionAlgo); + + GeomShapePtr aResShape = anIntersectionAlgo->shape(); + if (data()->version() == INTERSECTION_VERSION_1) { + // merge hierarchies of compounds containing objects and tools + // and append the result of the FUSE operation + aResShape = keepUnusedSubsOfCompound(aResShape, anObjectsHierarchy, + GeomAPI_ShapeHierarchy(), aMakeShapeList); + } + std::shared_ptr aResultBody = document()->createBody(data(), aResultIndex); - loadNamingDS(aResultBody, anObjects, anIntersectionAlgo); + FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, + anObjects, + ListOfShape(), + aMakeShapeList, + aResShape); setResult(aResultBody, aResultIndex); aResultIndex++; + FeaturesPlugin_Tools::loadDeletedShapes(aResultBody, + GeomShapePtr(), + anObjects, + aMakeShapeList, + aResShape); + // remove the rest results if there were produced in the previous pass removeResults(aResultIndex); } - -//================================================================================================= -void FeaturesPlugin_Intersection::loadNamingDS(ResultBodyPtr theResultBody, - const ListOfShape& theObjects, - const GeomMakeShapePtr& theMakeShape) -{ - std::shared_ptr aResultShape = theMakeShape->shape(); - - if(theObjects.front()->isEqual(aResultShape)) { - theResultBody->store(aResultShape, false); - return; - } - - theResultBody->storeModified(theObjects, aResultShape, theMakeShape); - - const int aShapeTypesNb = 3; - const GeomAPI_Shape::ShapeType aShapeTypes[aShapeTypesNb] = {GeomAPI_Shape::VERTEX, - GeomAPI_Shape::EDGE, - GeomAPI_Shape::FACE }; - for (ListOfShape::const_iterator anIt = theObjects.cbegin(); anIt != theObjects.cend(); ++anIt) { - const GeomShapePtr aShape = *anIt; - for(int anIndex = 0; anIndex < aShapeTypesNb; ++anIndex) { - theResultBody->loadModifiedShapes(theMakeShape, aShape, aShapeTypes[anIndex]); - theResultBody->loadGeneratedShapes(theMakeShape, aShape, aShapeTypes[anIndex]); - } - } -} diff --git a/src/FeaturesPlugin/FeaturesPlugin_Intersection.h b/src/FeaturesPlugin/FeaturesPlugin_Intersection.h index 6d4d99cdf..af7181753 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Intersection.h +++ b/src/FeaturesPlugin/FeaturesPlugin_Intersection.h @@ -20,11 +20,7 @@ #ifndef FeaturesPlugin_Intersection_H_ #define FeaturesPlugin_Intersection_H_ -#include "FeaturesPlugin.h" - -#include - -#include +#include "FeaturesPlugin_VersionedBoolean.h" class GeomAlgoAPI_MakeShape; @@ -35,7 +31,7 @@ class GeomAlgoAPI_MakeShape; /// whole objects, compsoilds, solids, shells, faces or edges. /// The result is less than the minimal dimension from pair of intersection: /// for two solids or two faces it is wire, for the edge and face it is vertex, etc. -class FeaturesPlugin_Intersection : public ModelAPI_Feature +class FeaturesPlugin_Intersection : public FeaturesPlugin_VersionedBoolean { public: /// Feature kind. @@ -67,12 +63,6 @@ public: /// Use plugin manager for features creation. FeaturesPlugin_Intersection(); - -private: - /// Load Naming data structure of the feature to the document. - void loadNamingDS(std::shared_ptr theResultBody, - const ListOfShape& theObjects, - const std::shared_ptr& theMakeShape); }; #endif diff --git a/src/FeaturesPlugin/Test/TestIntersection_MultiLevelCompound_v0_1.py b/src/FeaturesPlugin/Test/TestIntersection_MultiLevelCompound_v0_1.py new file mode 100644 index 000000000..d3c0269c1 --- /dev/null +++ b/src/FeaturesPlugin/Test/TestIntersection_MultiLevelCompound_v0_1.py @@ -0,0 +1,44 @@ +# Copyright (C) 2020 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() +Box_1 = model.addBox(Part_1_doc, 10, 10, 10) +LinearCopy_1 = model.addMultiTranslation(Part_1_doc, [model.selection("SOLID", "Box_1_1")], model.selection("EDGE", "PartSet/OX"), 20, 2) +Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 5, 5) +Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "PartSet/XOY"), model.selection("EDGE", "PartSet/OX"), 30) +Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Cylinder_1_1"), model.selection("FACE", "Plane_1")]) +Intersection_1 = model.addIntersection(Part_1_doc, [model.selection("SOLID", "LinearCopy_1_1_1"), model.selection("SOLID", "Partition_1_1_1")]) +model.end() + +from GeomAPI import * + +model.testNbResults(Intersection_1, 1) +model.testNbSubResults(Intersection_1, [6]) +model.testNbSubShapes(Intersection_1, GeomAPI_Shape.SOLID, [0]) +model.testNbSubShapes(Intersection_1, GeomAPI_Shape.FACE, [0]) +model.testNbSubShapes(Intersection_1, GeomAPI_Shape.EDGE, [6]) +model.testNbSubShapes(Intersection_1, GeomAPI_Shape.VERTEX, [12]) +model.testResultsVolumes(Intersection_1, [0]) + +assert(model.checkPythonDump()) diff --git a/src/FeaturesPlugin/Test/TestIntersection_MultiLevelCompound_v0_2.py b/src/FeaturesPlugin/Test/TestIntersection_MultiLevelCompound_v0_2.py new file mode 100644 index 000000000..7c7384e6b --- /dev/null +++ b/src/FeaturesPlugin/Test/TestIntersection_MultiLevelCompound_v0_2.py @@ -0,0 +1,43 @@ +# Copyright (C) 2020 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() +Box_1 = model.addBox(Part_1_doc, 10, 10, 10) +LinearCopy_1 = model.addMultiTranslation(Part_1_doc, [model.selection("SOLID", "Box_1_1")], model.selection("EDGE", "PartSet/OX"), 20, 2) +Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 5, 10) +LinearCopy_2 = model.addMultiTranslation(Part_1_doc, [model.selection("SOLID", "Cylinder_1_1")], model.selection("EDGE", "PartSet/OY"), 20, 3) +Intersection_1 = model.addIntersection(Part_1_doc, [model.selection("SOLID", "LinearCopy_1_1_1"), model.selection("SOLID", "LinearCopy_2_1_1")]) +model.end() + +from GeomAPI import * + +model.testNbResults(Intersection_1, 1) +model.testNbSubResults(Intersection_1, [8]) +model.testNbSubShapes(Intersection_1, GeomAPI_Shape.SOLID, [0]) +model.testNbSubShapes(Intersection_1, GeomAPI_Shape.FACE, [0]) +model.testNbSubShapes(Intersection_1, GeomAPI_Shape.EDGE, [8]) +model.testNbSubShapes(Intersection_1, GeomAPI_Shape.VERTEX, [16]) +model.testResultsVolumes(Intersection_1, [0]) + +assert(model.checkPythonDump()) diff --git a/src/FeaturesPlugin/Test/TestIntersection_MultiLevelCompound_v95_1.py b/src/FeaturesPlugin/Test/TestIntersection_MultiLevelCompound_v95_1.py new file mode 100644 index 000000000..e2a5d638e --- /dev/null +++ b/src/FeaturesPlugin/Test/TestIntersection_MultiLevelCompound_v95_1.py @@ -0,0 +1,44 @@ +# Copyright (C) 2020 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() +Box_1 = model.addBox(Part_1_doc, 10, 10, 10) +LinearCopy_1 = model.addMultiTranslation(Part_1_doc, [model.selection("SOLID", "Box_1_1")], model.selection("EDGE", "PartSet/OX"), 20, 2, keepSubResults = True) +Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 5, 5) +Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "PartSet/XOY"), model.selection("EDGE", "PartSet/OX"), 30) +Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Cylinder_1_1"), model.selection("FACE", "Plane_1")], keepSubResults = True) +Intersection_1 = model.addIntersection(Part_1_doc, [model.selection("SOLID", "LinearCopy_1_1_1"), model.selection("SOLID", "Partition_1_1_1")], keepSubResults = True) +model.end() + +from GeomAPI import * + +model.testNbResults(Intersection_1, 1) +model.testNbSubResults(Intersection_1, [2]) +model.testNbSubShapes(Intersection_1, GeomAPI_Shape.SOLID, [1]) +model.testNbSubShapes(Intersection_1, GeomAPI_Shape.FACE, [6]) +model.testNbSubShapes(Intersection_1, GeomAPI_Shape.EDGE, [30]) +model.testNbSubShapes(Intersection_1, GeomAPI_Shape.VERTEX, [60]) +model.testResultsVolumes(Intersection_1, [1000]) + +assert(model.checkPythonDump()) diff --git a/src/FeaturesPlugin/Test/TestIntersection_MultiLevelCompound_v95_2.py b/src/FeaturesPlugin/Test/TestIntersection_MultiLevelCompound_v95_2.py new file mode 100644 index 000000000..9b1cc3bce --- /dev/null +++ b/src/FeaturesPlugin/Test/TestIntersection_MultiLevelCompound_v95_2.py @@ -0,0 +1,43 @@ +# Copyright (C) 2020 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() +Box_1 = model.addBox(Part_1_doc, 10, 10, 10) +LinearCopy_1 = model.addMultiTranslation(Part_1_doc, [model.selection("SOLID", "Box_1_1")], model.selection("EDGE", "PartSet/OX"), 20, 2, keepSubResults = True) +Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 5, 10) +LinearCopy_2 = model.addMultiTranslation(Part_1_doc, [model.selection("SOLID", "Cylinder_1_1")], model.selection("EDGE", "PartSet/OY"), 20, 3, keepSubResults = True) +Intersection_1 = model.addIntersection(Part_1_doc, [model.selection("SOLID", "LinearCopy_1_1_1"), model.selection("SOLID", "LinearCopy_2_1_1")], keepSubResults = True) +model.end() + +from GeomAPI import * + +model.testNbResults(Intersection_1, 1) +model.testNbSubResults(Intersection_1, [3]) +model.testNbSubShapes(Intersection_1, GeomAPI_Shape.SOLID, [3]) +model.testNbSubShapes(Intersection_1, GeomAPI_Shape.FACE, [12]) +model.testNbSubShapes(Intersection_1, GeomAPI_Shape.EDGE, [44]) +model.testNbSubShapes(Intersection_1, GeomAPI_Shape.VERTEX, [88]) +model.testResultsVolumes(Intersection_1, [2570.79632679489714]) + +assert(model.checkPythonDump()) -- 2.39.2