From 868bf919fccfc68cc47e42fc7f18ab5447c3a896 Mon Sep 17 00:00:00 2001 From: mpv Date: Tue, 16 Feb 2021 11:52:00 +0300 Subject: [PATCH] Bos #23885 [CEA] OCCT 7.5 related regressions in SHAPER Fix for the first described regression: ExtrusionCut computes intersection of 2 solids in compound in the new and produces 3 solids instead of 2 (as it was before). --- src/FeaturesPlugin/CMakeLists.txt | 1 + .../FeaturesPlugin_CompositeBoolean.cpp | 30 ++++++-- src/FeaturesPlugin/Test/Test23885.py | 73 +++++++++++++++++++ 3 files changed, 97 insertions(+), 7 deletions(-) create mode 100644 src/FeaturesPlugin/Test/Test23885.py diff --git a/src/FeaturesPlugin/CMakeLists.txt b/src/FeaturesPlugin/CMakeLists.txt index e45e5136b..6d01dc466 100644 --- a/src/FeaturesPlugin/CMakeLists.txt +++ b/src/FeaturesPlugin/CMakeLists.txt @@ -708,4 +708,5 @@ ADD_UNIT_TESTS(TestExtrusion.py TestPointCoordinates.py TestGeometryCalculation.py TestBoundingBox.py + Test23885.py ) diff --git a/src/FeaturesPlugin/FeaturesPlugin_CompositeBoolean.cpp b/src/FeaturesPlugin/FeaturesPlugin_CompositeBoolean.cpp index db4917048..70ba0ddbd 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_CompositeBoolean.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_CompositeBoolean.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include @@ -125,6 +126,7 @@ bool FeaturesPlugin_CompositeBoolean::makeBoolean(const ListOfShape& theTools, // Getting objects. ListOfShape anObjects, anEdgesAndFaces, aCompSolids; std::map aCompSolidsObjects; + bool aCompoundsOnly = true; // if there are only compounds and no compsolids, do not use filler to restore compsolids AttributeSelectionListPtr anObjectsSelList = myFeature->selectionList(OBJECTS_ID()); for(int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) { AttributeSelectionPtr anObjectAttr = anObjectsSelList->value(anObjectsIndex); @@ -147,6 +149,8 @@ bool FeaturesPlugin_CompositeBoolean::makeBoolean(const ListOfShape& theTools, if(anIt == aCompSolidsObjects.end()) { aCompSolidsObjects[aContextShape].push_back(anObject); aCompSolids.push_back(aContextShape); + if (aContextShape->shapeType() != GeomAPI_Shape::COMPOUND) + aCompoundsOnly = false; } } else { if(anObject->shapeType() == GeomAPI_Shape::EDGE || @@ -228,14 +232,26 @@ bool FeaturesPlugin_CompositeBoolean::makeBoolean(const ListOfShape& theTools, GeomShapePtr aBoolRes = aBoolAlgo->shape(); if (!aShapesToAdd.empty()) { aShapesToAdd.push_back(aBoolRes); - std::shared_ptr aFillerAlgo( - new GeomAlgoAPI_PaveFiller(aShapesToAdd, true)); - if(!aFillerAlgo->isDone() || aFillerAlgo->shape()->isNull() || !aFillerAlgo->isValid()) { - myFeature->setError("Error: PaveFiller algorithm failed."); - return false; + if (aCompoundsOnly) // 23885: if there are no compsolids in input, do not use filler to make compsolids + { + aBoolRes = GeomAlgoAPI_CompoundBuilder::compound(aShapesToAdd); + std::shared_ptr aComp(new GeomAlgoAPI_MakeShapeCustom); + aComp->setResult(aBoolRes); + for(ListOfShape::iterator aComps = aCompSolids.begin(); aComps != aCompSolids.end(); aComps++) + aComp->addModified(*aComps, aBoolRes); + aMakeShapeList->appendAlgo(aComp); + } + else + { + std::shared_ptr aFillerAlgo( + new GeomAlgoAPI_PaveFiller(aShapesToAdd, true)); + if (!aFillerAlgo->isDone() || aFillerAlgo->shape()->isNull() || !aFillerAlgo->isValid()) { + myFeature->setError("Error: PaveFiller algorithm failed."); + return false; + } + aBoolRes = aFillerAlgo->shape(); + aMakeShapeList->appendAlgo(aFillerAlgo); } - aBoolRes = aFillerAlgo->shape(); - aMakeShapeList->appendAlgo(aFillerAlgo); } if(GeomAlgoAPI_ShapeTools::area(aBoolRes) > 1.e-27) { diff --git a/src/FeaturesPlugin/Test/Test23885.py b/src/FeaturesPlugin/Test/Test23885.py new file mode 100644 index 000000000..d811b1902 --- /dev/null +++ b/src/FeaturesPlugin/Test/Test23885.py @@ -0,0 +1,73 @@ +# 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() + +### Create Part +Part_1 = model.addPart(partSet) +Part_1_doc = Part_1.document() + +### Create Sketch +Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY")) + +### Create SketchCircle +SketchCircle_1 = Sketch_1.addCircle(45, 45, 28) +model.do() + +### Create Sketch +Sketch_2 = model.addSketch(Part_1_doc, model.defaultPlane("XOY")) + +### Create SketchCircle +SketchCircle_2 = Sketch_2.addCircle(79, 72, 29.30) +model.do() + +### Create Extrusion +Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchCircle_1_2r")], model.selection(), 10, 0, "Faces|Wires") + +### Create Extrusion +Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchCircle_2_2r")], model.selection(), 10, 0, "Faces|Wires") + +### Create Compound +Compound_1 = model.addCompound(Part_1_doc, [model.selection("SOLID", "Extrusion_1_1"), model.selection("SOLID", "Extrusion_2_1")]) + +### Create ExtrusionCut +ExtrusionCut_1 = model.addExtrusionCut(Part_1_doc, [], model.selection(), [model.selection("SOLID", "Compound_1_1_2")]) + +### Create Sketch +Sketch_3 = model.addSketch(Part_1_doc, model.selection("FACE", "Compound_1_1_2/Modified_Face&Extrusion_2_1/To_Face")) + +### Create SketchCircle +SketchCircle_3 = Sketch_3.addCircle(88, 78, 6) +ExtrusionCut_1.setNestedSketch(Sketch_3) + +model.end() + +from GeomAPI import GeomAPI_Shape + +model.testNbResults(ExtrusionCut_1, 1) +model.testNbSubResults(ExtrusionCut_1, [2]) +model.testNbSubShapes(ExtrusionCut_1, GeomAPI_Shape.SOLID, [2]) +model.testNbSubShapes(ExtrusionCut_1, GeomAPI_Shape.FACE, [7]) +model.testNbSubShapes(ExtrusionCut_1, GeomAPI_Shape.EDGE, [18]) +model.testNbSubShapes(ExtrusionCut_1, GeomAPI_Shape.VERTEX, [36]) +model.testResultsVolumes(ExtrusionCut_1, [50469.37182]) + +assert(model.checkPythonDump()) -- 2.39.2