From c5a351512e0bf9a981b9dbdc53f4c8d18ac7d68c Mon Sep 17 00:00:00 2001 From: mpv Date: Fri, 21 Aug 2020 09:55:08 +0300 Subject: [PATCH] Fix for #19912 : Error in SHAPERSTUDY python dump in feature Face with 2 results Generate an error in case primitive selection returns sub-shape that does not belong to the context. --- src/Model/Model_AttributeSelection.cpp | 32 +++++++++++++-- src/ModelAPI/CMakeLists.txt | 1 + src/ModelAPI/Test/Test19912.py | 54 ++++++++++++++++++++++++++ 3 files changed, 83 insertions(+), 4 deletions(-) create mode 100644 src/ModelAPI/Test/Test19912.py diff --git a/src/Model/Model_AttributeSelection.cpp b/src/Model/Model_AttributeSelection.cpp index 9219aca4b..369fb52a7 100644 --- a/src/Model/Model_AttributeSelection.cpp +++ b/src/Model/Model_AttributeSelection.cpp @@ -609,6 +609,30 @@ bool Model_AttributeSelection::update() if (aSelLab.FindAttribute(TNaming_NamedShape::GetID(), aNS)) aNewShape = aNS->Get(); + // check the selected value is a part of the context + if (aResult && !aNewShape.IsNull() && !aContextShape.IsNull() && + !aContextShape.IsSame(aNewShape)) { + TopoDS_Shape aNewS = aNewShape; + // take only sub-shape of composite for checking + if (aNewS.ShapeType() == TopAbs_WIRE || aNewS.ShapeType() == TopAbs_SHELL || + aNewS.ShapeType() == TopAbs_COMPOUND || aNewS.ShapeType() == TopAbs_COMPSOLID) { + TopoDS_Iterator anIter(aNewS); + if (anIter.More()) + aNewS = anIter.Value(); + } + bool anIsInside = false; + TopExp_Explorer anExp(aContextShape, aNewS.ShapeType()); + for (; anExp.More() && !anIsInside; anExp.Next()) { + if (anExp.Current().IsSame(aNewS)) + anIsInside = true; + } + if (!anIsInside) { + aResult = false; + aNewShape.Nullify(); + setInvalidIfFalse(aSelLab, aResult); + } + } + if (anOldShape.IsNull() || aNewShape.IsNull() || !anOldShape.IsEqual(aNewShape) || aWasInvalid) { // shape type should not be changed: if shape becomes compound of such shapes, then split @@ -763,16 +787,16 @@ std::wstring Model_AttributeSelection::namingName(const std::wstring& theDefault GeomShapePtr aShape = value(); if (!aShape.get() && context().get()) aShape = context()->shape(); - std::wstring aName; + std::wstring aNotArgName; if (aShape.get()) { - aName = Locale::Convert::toWString(aShape->shapeTypeStr()); + aNotArgName = Locale::Convert::toWString(aShape->shapeTypeStr()); if (myParent) { std::wostringstream aStream; aStream << "_" << selectionLabel().Father().Tag(); - aName += aStream.str(); + aNotArgName += aStream.str(); } } - return aName; + return aNotArgName; } CenterType aCenterType = NOT_CENTER; diff --git a/src/ModelAPI/CMakeLists.txt b/src/ModelAPI/CMakeLists.txt index f2947fc56..4f8899641 100644 --- a/src/ModelAPI/CMakeLists.txt +++ b/src/ModelAPI/CMakeLists.txt @@ -264,4 +264,5 @@ ADD_UNIT_TESTS(TestConstants.py Test19217.py Test19707.py Test19726.py + Test19912.py ) diff --git a/src/ModelAPI/Test/Test19912.py b/src/ModelAPI/Test/Test19912.py new file mode 100644 index 000000000..d7824408f --- /dev/null +++ b/src/ModelAPI/Test/Test19912.py @@ -0,0 +1,54 @@ +# Copyright (C) 2014-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() + +Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY")) +SketchCircle_1 = Sketch_1.addCircle(50, 50, 25) +model.do() + +Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchCircle_1_2r")], model.selection(), 10, 0) + +Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/To_Face")) +SketchCircle_2 = Sketch_2.addCircle(40, 42, 5) +SketchCircle_3 = Sketch_2.addCircle(60, 60, 6) +model.do() + +Face_1 = model.addFace(Part_1_doc, [model.selection("COMPOUND", "Sketch_2")]) +Partition_1_objects = [model.selection("SOLID", "Extrusion_1_1"), + model.selection("FACE", "Face_1_1"), + model.selection("FACE", "Face_1_2")] +Partition_1 = model.addPartition(Part_1_doc, Partition_1_objects, keepSubResults = True) +Group_1 = model.addGroup(Part_1_doc, "Faces", [model.selection("FACE", "Face_1_1/Face_1_1")]) +model.end() + +assert(len(Group_1.results()) == 1) + +# remove Face_1_1 from the partition, so the group selection must become invalid +model.begin() +Partition_1.setBase([model.selection("SOLID", "Extrusion_1_1"), model.selection("FACE", "Face_1_2")]) +model.end() + +assert(len(Group_1.results()) == 0) -- 2.39.2