From 224dc78ebd769bad5d95e5cef9a97b3561212bbd Mon Sep 17 00:00:00 2001 From: mpv Date: Mon, 15 Jan 2018 16:37:31 +0300 Subject: [PATCH] Fix of the problem of naming name parse if results are referenced in not direct way (sub-results are selected). Based on the test TestUnionOfUnion.py --- src/FeaturesPlugin/CMakeLists.txt | 1 + src/FeaturesPlugin/Test/TestUnionOfUnion.py | 40 ++++++++++ src/Model/Model_AttributeSelection.cpp | 85 ++++++++++++--------- src/Model/Model_Document.cpp | 2 + 4 files changed, 90 insertions(+), 38 deletions(-) create mode 100644 src/FeaturesPlugin/Test/TestUnionOfUnion.py diff --git a/src/FeaturesPlugin/CMakeLists.txt b/src/FeaturesPlugin/CMakeLists.txt index 3cf60b9c5..4050130bc 100644 --- a/src/FeaturesPlugin/CMakeLists.txt +++ b/src/FeaturesPlugin/CMakeLists.txt @@ -218,6 +218,7 @@ ADD_UNIT_TESTS(TestExtrusion.py TestPartitionWireFaceSolid.py TestUnion4CurvedFaces.py TestUnion4Faces.py + TestUnionOfUnion.py Test1922.py Test1942.py Test1915.py diff --git a/src/FeaturesPlugin/Test/TestUnionOfUnion.py b/src/FeaturesPlugin/Test/TestUnionOfUnion.py new file mode 100644 index 000000000..a681118ea --- /dev/null +++ b/src/FeaturesPlugin/Test/TestUnionOfUnion.py @@ -0,0 +1,40 @@ +## 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() +Box_1 = model.addBox(Part_1_doc, 10, 10, 10) +Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "Box_1_1/Left"), 5, True) +Plane_5 = model.addPlane(Part_1_doc, model.selection("FACE", "Box_1_1/Front"), 5, True) +Partition_1_objects = [model.selection("FACE", "Plane_1"), model.selection("FACE", "Plane_2"), model.selection("SOLID", "Box_1_1")] +Partition_1 = model.addPartition(Part_1_doc, Partition_1_objects) +Union_1 = model.addUnion(Part_1_doc, [model.selection("SOLID", "Partition_1_1_3"), model.selection("SOLID", "Partition_1_1_1")]) +Union_2 = model.addUnion(Part_1_doc, [model.selection("SOLID", "Partition_1_1_4/Partition_1_1_4"), model.selection("SOLID", "Partition_1_1_2/Partition_1_1_2")]) +model.end() + +from GeomAPI import GeomAPI_Shape +assert(Part_1_doc.size("Bodies") == 1) +model.testNbSubShapes(Union_2, GeomAPI_Shape.SOLID, [2]) + +assert(model.checkPythonDump()) diff --git a/src/Model/Model_AttributeSelection.cpp b/src/Model/Model_AttributeSelection.cpp index 418186066..7572dab51 100644 --- a/src/Model/Model_AttributeSelection.cpp +++ b/src/Model/Model_AttributeSelection.cpp @@ -881,47 +881,56 @@ void Model_AttributeSelection::selectSubShape( // try to find the latest active result that must be used instead of the selected // to set the active context (like in GUI selection), not concealed one bool aFindNewContext = true; - while(aFindNewContext && aCont.get() && aShapeToBeSelected.get()) { + while(aFindNewContext && aCont.get()) { aFindNewContext = false; - const std::set& aRefs = aCont->data()->refsToMe(); - std::set::const_iterator aRef = aRefs.begin(); - for(; !aFindNewContext && aRef != aRefs.end(); aRef++) { - if (!aRef->get() || !(*aRef)->owner().get()) - continue; - // concealed attribute only - FeaturePtr aRefFeat = std::dynamic_pointer_cast((*aRef)->owner()); - if (!ModelAPI_Session::get()->validators()->isConcealed( - aRefFeat->getKind(), (*aRef)->id())) - continue; - // search the feature result that contains sub-shape selected - std::list > aResults; - - // take all sub-results or one result - const std::list >& aFResults = aRefFeat->results(); - std::list >::const_iterator aRIter = aFResults.begin(); - for (; aRIter != aFResults.cend(); aRIter++) { - // iterate sub-bodies of compsolid - ResultCompSolidPtr aComp = std::dynamic_pointer_cast(*aRIter); - if (aComp.get() && aComp->numberOfSubs() > 0) { - int aNumSub = aComp->numberOfSubs(); - for(int a = 0; a < aNumSub; a++) { - aResults.push_back(aComp->subResult(a)); + // take references to all results: root one, any sub + ResultCompSolidPtr aCompContext = ModelAPI_Tools::compSolidOwner(aCont); + int aSubsSize = (aCompContext.get() ? aCompContext->numberOfSubs() : 0) + 1; + for(int aResultNum = 0; aResultNum < aSubsSize; aResultNum++) { + ResultPtr aResCont = aCompContext.get() ? (aResultNum == aSubsSize - 1 ? + aCompContext : aCompContext->subResult(aResultNum)) : aCont; + const std::set& aRefs = aResCont->data()->refsToMe(); + std::set::const_iterator aRef = aRefs.begin(); + for(; !aFindNewContext && aRef != aRefs.end(); aRef++) { + if (!aRef->get() || !(*aRef)->owner().get()) + continue; + // concealed attribute only + FeaturePtr aRefFeat = std::dynamic_pointer_cast((*aRef)->owner()); + if (!ModelAPI_Session::get()->validators()->isConcealed( + aRefFeat->getKind(), (*aRef)->id())) + continue; + // search the feature result that contains sub-shape selected + std::list > aResults; + + // take all sub-results or one result + const std::list >& aFResults = aRefFeat->results(); + std::list >::const_iterator aRIter = aFResults.begin(); + for (; aRIter != aFResults.cend(); aRIter++) { + // iterate sub-bodies of compsolid + ResultCompSolidPtr aComp = std::dynamic_pointer_cast(*aRIter); + if (aComp.get() && aComp->numberOfSubs() > 0) { + int aNumSub = aComp->numberOfSubs(); + for(int a = 0; a < aNumSub; a++) { + aResults.push_back(aComp->subResult(a)); + } + } else { + aResults.push_back(*aRIter); } - } else { - aResults.push_back(*aRIter); } - } - std::list >::iterator aResIter = aResults.begin(); - for(; aResIter != aResults.end(); aResIter++) { - if (!aResIter->get() || !(*aResIter)->data()->isValid() || (*aResIter)->isDisabled()) - continue; - GeomShapePtr aShape = (*aResIter)->shape(); - if (aShape.get() && aShape->isSubShape(aShapeToBeSelected, false)) { - aCont = *aResIter; // found new context (produced from this) with same subshape - //if (!aShape->isSubShape(aShapeToBeSelected, true)) // take context orientation - // aShapeToBeSelected->setOrientation(); - aFindNewContext = true; // continue searching futher - break; + std::list >::iterator aResIter = aResults.begin(); + for(; aResIter != aResults.end(); aResIter++) { + if (!aResIter->get() || !(*aResIter)->data()->isValid() || (*aResIter)->isDisabled()) + continue; + GeomShapePtr aShape = (*aResIter)->shape(); + GeomShapePtr aSelectedShape = + aShapeToBeSelected.get() ? aShapeToBeSelected : aCont->shape(); + if (aShape.get() && aShape->isSubShape(aSelectedShape, false)) { + aCont = *aResIter; // found new context (produced from this) with same subshape + //if (!aShape->isSubShape(aShapeToBeSelected, true)) // take context orientation + // aShapeToBeSelected->setOrientation(); + aFindNewContext = true; // continue searching futher + break; + } } } } diff --git a/src/Model/Model_Document.cpp b/src/Model/Model_Document.cpp index f37533c07..78afb82aa 100755 --- a/src/Model/Model_Document.cpp +++ b/src/Model/Model_Document.cpp @@ -1306,6 +1306,8 @@ bool Model_Document::removeFromFolder( std::shared_ptr Model_Document::feature( const std::shared_ptr& theResult) { + if (myObjs == 0) // may be on close + return std::shared_ptr(); return myObjs->feature(theResult); } -- 2.39.2