From 8df1900cad164e0e6597edfa45c00359f9364f24 Mon Sep 17 00:00:00 2001 From: dbv Date: Fri, 28 Sep 2018 16:31:44 +0300 Subject: [PATCH] Issue #2650: Crash when create pipe Added validator to allow selection for pipe locations only vertices on path shape. --- src/FeaturesPlugin/CMakeLists.txt | 1 + src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp | 2 + .../FeaturesPlugin_Validators.cpp | 81 ++++++++++++++++++- .../FeaturesPlugin_Validators.h | 17 +++- src/FeaturesPlugin/Test/Test2650.py | 60 ++++++++++++++ src/FeaturesPlugin/pipe_widget.xml | 3 +- 6 files changed, 161 insertions(+), 3 deletions(-) create mode 100644 src/FeaturesPlugin/Test/Test2650.py diff --git a/src/FeaturesPlugin/CMakeLists.txt b/src/FeaturesPlugin/CMakeLists.txt index 07a31f551..fdad01eaa 100644 --- a/src/FeaturesPlugin/CMakeLists.txt +++ b/src/FeaturesPlugin/CMakeLists.txt @@ -367,4 +367,5 @@ ADD_UNIT_TESTS(TestExtrusion.py TestBooleanFuse_CompSolidCompound_CompSolidCompound.py Test1816.py Test2631.py + Test2650.py ) diff --git a/src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp b/src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp index f39e5fc1e..68b1001e9 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Plugin.cpp @@ -73,6 +73,8 @@ FeaturesPlugin_Plugin::FeaturesPlugin_Plugin() new FeaturesPlugin_ValidatorBaseForGenerationSketchOrSketchObjects); aFactory->registerValidator("FeaturesPlugin_ValidatorPipeLocations", new FeaturesPlugin_ValidatorPipeLocations); + aFactory->registerValidator("FeaturesPlugin_ValidatorPipeLocationsNumber", + new FeaturesPlugin_ValidatorPipeLocationsNumber); aFactory->registerValidator("FeaturesPlugin_ValidatorExtrusionDir", new FeaturesPlugin_ValidatorExtrusionDir); aFactory->registerValidator("FeaturesPlugin_ValidatorBooleanSelection", diff --git a/src/FeaturesPlugin/FeaturesPlugin_Validators.cpp b/src/FeaturesPlugin/FeaturesPlugin_Validators.cpp index bfb36543c..411a6470b 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Validators.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Validators.cpp @@ -24,6 +24,7 @@ #include "FeaturesPlugin_BooleanFuse.h" #include "FeaturesPlugin_BooleanCommon.h" #include "FeaturesPlugin_BooleanSmash.h" +#include "FeaturesPlugin_Pipe.h" #include "FeaturesPlugin_Union.h" #include @@ -88,7 +89,85 @@ bool FeaturesPlugin_ValidatorPipePath::isValid(const AttributePtr& theAttribute, } //================================================================================================== -bool FeaturesPlugin_ValidatorPipeLocations::isValid( +bool FeaturesPlugin_ValidatorPipeLocations::isValid(const AttributePtr& theAttribute, + const std::list& theArguments, + Events_InfoMessage& theError) const +{ + AttributeSelectionListPtr anAttrSelectionList = + std::dynamic_pointer_cast(theAttribute); + if(!anAttrSelectionList.get()) { + theError = + "Error: This validator can only work with selection list attributes in \"Pipe\" feature."; + return false; + } + std::shared_ptr aFeature = + std::dynamic_pointer_cast(theAttribute->owner()); + + AttributeSelectionPtr aPathSelection = aFeature->selection(FeaturesPlugin_Pipe::PATH_OBJECT_ID()); + if (!aPathSelection.get()) { + theError = "Error: Path not selected."; + return false; + } + + GeomShapePtr aPathShape = aPathSelection->value(); + if (!aPathShape.get()) { + ResultPtr aContext = aPathSelection->context(); + if (!aContext.get()) { + FeaturePtr aContFeat = aPathSelection->contextFeature(); + if (!aContFeat.get() || !aContFeat->results().size()) { + theError = "Error: Empty selection context."; + return false; + } + } + aPathShape = aContext->shape(); + } + + if (!aPathShape.get()) { + theError = "Error: Empty path shape."; + return false; + } + + for (int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) { + AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex); + if (!anAttrSelection.get()) { + theError = "Error: Empty attribute selection."; + return false; + } + ResultPtr aContext = anAttrSelection->context(); + if (!aContext.get()) { + FeaturePtr aContFeat = anAttrSelection->contextFeature(); + if (!aContFeat.get() || !aContFeat->results().size()) { + theError = "Error: Empty selection context."; + return false; + } + } + ResultConstructionPtr aResultConstruction = + std::dynamic_pointer_cast(aContext); + if (aResultConstruction.get()) { + theError = "Error: Result construction not allowed for selection."; + return false; + } + std::shared_ptr aShape = anAttrSelection->value(); + if (!aShape.get() && aContext.get()) { + GeomShapePtr aContextShape = aContext->shape(); + aShape = aContextShape; + } + if (!aShape.get()) { + theError = "Error: Empty shape."; + return false; + } + + if (!aPathShape->isSubShape(aShape)) { + theError = "Error: Location should be a vertex subshape from path shape."; + return false; + } + } + + return true; +} + +//================================================================================================== +bool FeaturesPlugin_ValidatorPipeLocationsNumber::isValid( const std::shared_ptr& theFeature, const std::list& theArguments, Events_InfoMessage& theError) const diff --git a/src/FeaturesPlugin/FeaturesPlugin_Validators.h b/src/FeaturesPlugin/FeaturesPlugin_Validators.h index 18e1c241d..7b81dfb47 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Validators.h +++ b/src/FeaturesPlugin/FeaturesPlugin_Validators.h @@ -41,8 +41,23 @@ public: /// \class FeaturesPlugin_ValidatorPipeLocations /// \ingroup Validators +/// \brief A validator for selection pipe locations. +class FeaturesPlugin_ValidatorPipeLocations: public ModelAPI_AttributeValidator +{ +public: + //! \return True if the attribute is valid. + //! \param[in] theAttribute the checked attribute. + //! \param[in] theArguments arguments of the attribute. + //! \param[out] theError error message. + virtual bool isValid(const AttributePtr& theAttribute, + const std::list& theArguments, + Events_InfoMessage& theError) const; +}; + +/// \class FeaturesPlugin_ValidatorPipeLocationsNumber +/// \ingroup Validators /// \brief Validator for the pipe locations. -class FeaturesPlugin_ValidatorPipeLocations: public ModelAPI_FeatureValidator +class FeaturesPlugin_ValidatorPipeLocationsNumber: public ModelAPI_FeatureValidator { public: //! \return true if number of selected locations the same as number of selected bases, or empty. diff --git a/src/FeaturesPlugin/Test/Test2650.py b/src/FeaturesPlugin/Test/Test2650.py new file mode 100644 index 000000000..e32141161 --- /dev/null +++ b/src/FeaturesPlugin/Test/Test2650.py @@ -0,0 +1,60 @@ +## 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() +Import_1 = model.addImport(Part_1_doc, "D:/rq_1.brep") +model.do() +Import_1.setName("rq_1") +Import_1.result().setName("rq_1_1") +Import_2 = model.addImport(Part_1_doc, "D:/rq2_1.brep") +model.do() +Import_2.setName("rq2_1") +Import_2.result().setName("rq2_1_1") +Import_3 = model.addImport(Part_1_doc, "D:/spine.brep") +model.do() +Import_3.setName("spine") +Import_3.result().setName("spine_1") +Import_4 = model.addImport(Part_1_doc, "D:/v1.brep") +model.do() +Import_4.setName("v1") +Import_4.result().setName("v1_1") +Import_5 = model.addImport(Part_1_doc, "D:/v2.brep") +model.do() +Import_5.setName("v2") +Import_5.result().setName("v2_1") +Pipe_1 = model.addPipe(Part_1_doc, [model.selection("WIRE", "rq_1_1"), model.selection("WIRE", "rq2_1_1")], model.selection("WIRE", "spine_1"), [model.selection("VERTEX", "spine_1/Shape2"), model.selection("VERTEX", "spine_1/Shape3")]) +model.do() +model.end() + +from GeomAPI import GeomAPI_Shape + +model.testNbResults(Pipe_1, 1) +model.testNbSubResults(Pipe_1, [0]) +model.testNbSubShapes(Pipe_1, GeomAPI_Shape.SOLID, [0]) +model.testNbSubShapes(Pipe_1, GeomAPI_Shape.FACE, [4]) +model.testNbSubShapes(Pipe_1, GeomAPI_Shape.EDGE, [16]) +model.testNbSubShapes(Pipe_1, GeomAPI_Shape.VERTEX, [32]) + +assert(model.checkPythonDump()) diff --git a/src/FeaturesPlugin/pipe_widget.xml b/src/FeaturesPlugin/pipe_widget.xml index a258e00fe..f472fb00e 100644 --- a/src/FeaturesPlugin/pipe_widget.xml +++ b/src/FeaturesPlugin/pipe_widget.xml @@ -49,9 +49,10 @@ email : webmaster.salome@opencascade.com + - + -- 2.39.2