From 000184db1e1855d7c7a644c9ba148b66fb586a06 Mon Sep 17 00:00:00 2001 From: mpv Date: Mon, 20 Aug 2018 09:01:24 +0300 Subject: [PATCH] Selection of features: added support of Construction features selection and two python unit-tests --- src/Model/Model_AttributeSelection.cpp | 34 +++++++--- src/ModelAPI/CMakeLists.txt | 2 + src/ModelAPI/Test/TestFeatureSelection_1.py | 38 +++++++++++ src/ModelAPI/Test/TestFeatureSelection_2.py | 74 +++++++++++++++++++++ 4 files changed, 137 insertions(+), 11 deletions(-) create mode 100644 src/ModelAPI/Test/TestFeatureSelection_1.py create mode 100644 src/ModelAPI/Test/TestFeatureSelection_2.py diff --git a/src/Model/Model_AttributeSelection.cpp b/src/Model/Model_AttributeSelection.cpp index 1be7f53ee..847380c44 100644 --- a/src/Model/Model_AttributeSelection.cpp +++ b/src/Model/Model_AttributeSelection.cpp @@ -448,19 +448,26 @@ ResultPtr Model_AttributeSelection::context() ResultPtr aResult = std::dynamic_pointer_cast(myRef.value()); // for parts there could be same-data result, so take the last enabled - if (aResult.get() && aResult->groupName() == ModelAPI_ResultPart::group()) { - int aSize = aResult->document()->size(ModelAPI_ResultPart::group()); - for(int a = aSize - 1; a >= 0; a--) { - ObjectPtr aPart = aResult->document()->object(ModelAPI_ResultPart::group(), a); - if (aPart.get() && aPart->data() == aResult->data()) { - ResultPtr aPartResult = std::dynamic_pointer_cast(aPart); - FeaturePtr anOwnerFeature = std::dynamic_pointer_cast(owner()); - // check that this result is not this-feature result (it is forbidden t oselect itself) - if (anOwnerFeature.get() && anOwnerFeature->firstResult() != aPartResult) { - return aPartResult; + if (aResult.get()) { + if(aResult->groupName() == ModelAPI_ResultPart::group()) { + int aSize = aResult->document()->size(ModelAPI_ResultPart::group()); + for(int a = aSize - 1; a >= 0; a--) { + ObjectPtr aPart = aResult->document()->object(ModelAPI_ResultPart::group(), a); + if(aPart.get() && aPart->data() == aResult->data()) { + ResultPtr aPartResult = std::dynamic_pointer_cast(aPart); + FeaturePtr anOwnerFeature = std::dynamic_pointer_cast(owner()); + // check that this result is not this-feature result (it is forbidden t oselect itself) + if(anOwnerFeature.get() && anOwnerFeature->firstResult() != aPartResult) { + return aPartResult; + } } } } + } else { // if feature - construction is selected, it has only one result, return this result + FeaturePtr aFeature = std::dynamic_pointer_cast(myRef.value()); + if (aFeature.get() && aFeature->results().size() == 1 && + aFeature->firstResult()->groupName() == ModelAPI_ResultConstruction::group()) + return aFeature->firstResult(); } return aResult; } @@ -587,6 +594,10 @@ void Model_AttributeSelection::split( bool Model_AttributeSelection::update() { + FeaturePtr aContextFeature = contextFeature(); + if (aContextFeature.get()) { + return true; + } TDF_Label aSelLab = selectionLabel(); ResultPtr aContext = context(); if (!aContext.get()) @@ -824,7 +835,8 @@ std::string Model_AttributeSelection::namingName(const std::string& theDefaultNa std::shared_ptr aSubSh = internalValue(aCenterType); ResultPtr aCont = context(); - if (!aCont.get()) { + if (!aCont.get() || + (aCont->groupName() == ModelAPI_ResultConstruction::group() && contextFeature().get())) { // selection of a full feature FeaturePtr aFeatureCont = contextFeature(); if (aFeatureCont.get()) { diff --git a/src/ModelAPI/CMakeLists.txt b/src/ModelAPI/CMakeLists.txt index 9fde2d5ab..16fb0c518 100644 --- a/src/ModelAPI/CMakeLists.txt +++ b/src/ModelAPI/CMakeLists.txt @@ -201,4 +201,6 @@ ADD_UNIT_TESTS(TestConstants.py Test2413.py Test2496.py Test2510.py + TestFeatureSelection_1.py + TestFeatureSelection_2.py ) diff --git a/src/ModelAPI/Test/TestFeatureSelection_1.py b/src/ModelAPI/Test/TestFeatureSelection_1.py new file mode 100644 index 000000000..35c8c741c --- /dev/null +++ b/src/ModelAPI/Test/TestFeatureSelection_1.py @@ -0,0 +1,38 @@ +## 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 +## + +# The test for correct selection of a whole feautre as argument of other feature: box and construction +# plane features as an argument of a Partition + +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/Top"), 5, True) +Partition_1 = model.addPartition(Part_1_doc, [model.selection("COMPOUND", "all-in-Box_1"), model.selection("FACE", "all-in-Plane_1")]) +model.end() + +assert(len(Partition_1.results()) == 1) +assert(Partition_1.result().numberOfSubs() == 2) + +assert(model.checkPythonDump()) diff --git a/src/ModelAPI/Test/TestFeatureSelection_2.py b/src/ModelAPI/Test/TestFeatureSelection_2.py new file mode 100644 index 000000000..c4ba30ff8 --- /dev/null +++ b/src/ModelAPI/Test/TestFeatureSelection_2.py @@ -0,0 +1,74 @@ +## 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 +## + +# The test for correct selection of a whole feautre as argument of other feature: select all extrusions +# produced from the scetch, then change the number of sketch contours, so, anytway all extrusions must +# still be selected in the Cut Boolean oepration + +from SketchAPI import * + +from salome.shaper import model + +model.begin() +partSet = model.moduleDocument() +Part_1 = model.addPart(partSet) +Part_1_doc = Part_1.document() +Param_N = model.addParameter(Part_1_doc, "n", "3") +Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY")) +SketchProjection_1 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OX"), False) +SketchLine_1 = SketchProjection_1.createdFeature() +SketchLine_1.result().setColor(170, 0, 225) +SketchCircle_1 = Sketch_1.addCircle(30, 0, 15) +SketchCircle_1.result().setColor(225, 0, 0) +SketchCircle_1.results()[1].setColor(225, 0, 0) +SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.result(), SketchCircle_1.center()) +SketchConstraintDistance_1 = Sketch_1.setDistance(SketchAPI_Line(SketchLine_1).startPoint(), SketchCircle_1.center(), 30, True) +SketchMultiRotation_1 = Sketch_1.addRotation([SketchCircle_1.results()[1]], SketchAPI_Line(SketchLine_1).startPoint(), 360, "n=", True) +[SketchCircle_2, SketchCircle_3] = SketchMultiRotation_1.rotated() +SketchCircle_3.result().setColor(225, 0, 0) +SketchCircle_3.results()[1].setColor(225, 0, 0) +SketchCircle_2.result().setColor(225, 0, 0) +SketchCircle_2.results()[1].setColor(225, 0, 0) +SketchConstraintRadius_1 = Sketch_1.setRadius(SketchCircle_1.results()[1], 15) +model.do() +Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "Sketch_1")], model.selection(), 10, 0) +Sketch_2 = model.addSketch(Part_1_doc, model.standardPlane("XOZ")) +SketchCircle_4 = Sketch_2.addCircle(25, 5, 4) +SketchCircle_4.result().setColor(225, 0, 0) +SketchCircle_4.results()[1].setColor(225, 0, 0) +SketchConstraintRadius_2 = Sketch_2.setRadius(SketchCircle_4.results()[1], 4) +SketchProjection_2 = Sketch_2.addProjection(model.selection("EDGE", "PartSet/OX"), False) +SketchLine_2 = SketchProjection_2.createdFeature() +SketchLine_2.result().setColor(170, 0, 225) +SketchConstraintDistance_2 = Sketch_2.setDistance(SketchLine_2.result(), SketchCircle_4.center(), 5, True) +SketchConstraintDistanceHorizontal_1 = Sketch_2.setHorizontalDistance(SketchAPI_Line(SketchLine_2).startPoint(), SketchCircle_4.center(), 25) +model.do() +Revolution_1 = model.addRevolution(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchCircle_4_2f")], model.selection("EDGE", "PartSet/OZ"), 360, 0) +Cut_1 = model.addCut(Part_1_doc, [model.selection("COMPOUND", "all-in-Extrusion_1")], [model.selection("COMPOUND", "all-in-Revolution_1")]) +model.do() + +# update the parameter N => number of sketch contours is changed +Param_N.setValue(4) +Part_1_doc.setCurrentFeature(Cut_1.feature(), False) +model.end() + +assert(Cut_1.result().numberOfSubs() == 4) + +assert(model.checkPythonDump()) -- 2.39.2