From 9b6a87b9682bac46ee29a2c5f4b6b585243bb934 Mon Sep 17 00:00:00 2001 From: azv Date: Tue, 10 Oct 2017 12:20:29 +0300 Subject: [PATCH] Issue #2273: Error when reading HDF and Python dump Implemented validator which deny referring to generated features by Multi-Rotation, Multi-Translation and Mirror --- src/SketchPlugin/CMakeLists.txt | 1 + src/SketchPlugin/SketchPlugin_Plugin.cpp | 2 + src/SketchPlugin/SketchPlugin_Validators.cpp | 44 +++++++++ src/SketchPlugin/SketchPlugin_Validators.h | 17 ++++ src/SketchPlugin/Test/Test2273.py | 99 +++++++++++++++++++ src/SketchPlugin/plugin-Sketch.xml | 6 ++ .../SketchSolver_ConstraintMultiRotation.cpp | 21 +++- ...ketchSolver_ConstraintMultiTranslation.cpp | 38 ++++--- 8 files changed, 211 insertions(+), 17 deletions(-) create mode 100644 src/SketchPlugin/Test/Test2273.py diff --git a/src/SketchPlugin/CMakeLists.txt b/src/SketchPlugin/CMakeLists.txt index 7c89b5e5c..1fb666420 100644 --- a/src/SketchPlugin/CMakeLists.txt +++ b/src/SketchPlugin/CMakeLists.txt @@ -221,6 +221,7 @@ ADD_UNIT_TESTS(TestSketchPointLine.py TestDistanceSignedVsUnsigned05.py TestSignedDistancePointPoint.py TestSignedDistancePointLine.py + Test2273.py ) if(${SKETCHER_CHANGE_RADIUS_WHEN_MOVE}) diff --git a/src/SketchPlugin/SketchPlugin_Plugin.cpp b/src/SketchPlugin/SketchPlugin_Plugin.cpp index 8967c182d..ecc760c1e 100644 --- a/src/SketchPlugin/SketchPlugin_Plugin.cpp +++ b/src/SketchPlugin/SketchPlugin_Plugin.cpp @@ -134,6 +134,8 @@ SketchPlugin_Plugin::SketchPlugin_Plugin() aFactory->registerValidator("SketchPlugin_ArcEndPointIntersectionValidator", new SketchPlugin_ArcEndPointIntersectionValidator); aFactory->registerValidator("SketchPlugin_HasNoConstraint", new SketchPlugin_HasNoConstraint); + aFactory->registerValidator("SketchPlugin_ReplicationReference", + new SketchPlugin_ReplicationReferenceValidator); // register this plugin ModelAPI_Session::get()->registerPlugin(this); diff --git a/src/SketchPlugin/SketchPlugin_Validators.cpp b/src/SketchPlugin/SketchPlugin_Validators.cpp index ed22a6420..3c6fcc347 100755 --- a/src/SketchPlugin/SketchPlugin_Validators.cpp +++ b/src/SketchPlugin/SketchPlugin_Validators.cpp @@ -1565,3 +1565,47 @@ bool SketchPlugin_HasNoConstraint::isValid(const AttributePtr& theAttribute, } return true; } + +bool SketchPlugin_ReplicationReferenceValidator::isValid( + const AttributePtr& theAttribute, + const std::list& theArguments, + Events_InfoMessage& theError) const +{ + AttributeRefAttrPtr aRefAttr = + std::dynamic_pointer_cast(theAttribute); + if (!aRefAttr) + { + theError = "Incorrect attribute"; + return false; + } + + ObjectPtr anOwner; + if (aRefAttr->isObject()) + anOwner = aRefAttr->object(); + else + { + AttributePtr anAttr = aRefAttr->attr(); + anOwner = anAttr->owner(); + } + FeaturePtr anAttrOwnerFeature = ModelAPI_Feature::feature(anOwner); + if (!anAttrOwnerFeature) + return true; + AttributeBooleanPtr aCopyAttr = anAttrOwnerFeature->boolean(SketchPlugin_SketchEntity::COPY_ID()); + if (!aCopyAttr || !aCopyAttr->value()) + return true; // feature is not a copy, thus valid + + // check the copy feature is already referred by the "Multi" feature + FeaturePtr aMultiFeature = ModelAPI_Feature::feature(theAttribute->owner()); + AttributeRefListPtr aRefList = aMultiFeature->reflist(theArguments.front()); + for (int i = 0; i < aRefList->size(); ++i) + { + FeaturePtr aRefOwner = ModelAPI_Feature::feature(aRefList->object(i)); + if (aRefOwner == anAttrOwnerFeature) + { + theError = "Attribute refers to the object generated by this feature"; + return false; + } + } + + return true; +} diff --git a/src/SketchPlugin/SketchPlugin_Validators.h b/src/SketchPlugin/SketchPlugin_Validators.h index ccfe64328..d2cf26bbc 100644 --- a/src/SketchPlugin/SketchPlugin_Validators.h +++ b/src/SketchPlugin/SketchPlugin_Validators.h @@ -447,4 +447,21 @@ class SketchPlugin_HasNoConstraint: public ModelAPI_AttributeValidator Events_InfoMessage& theError) const; }; +/**\class SketchPlugin_ReplicationReferenceValidator + * \ingroup Validators + * \brief Validator checking that the replications features (Mirror, + * Multi-Rotation, Mutli-Translation) do not refer to the shapes they produce. + */ +class SketchPlugin_ReplicationReferenceValidator: public ModelAPI_AttributeValidator +{ + public: + //! returns true if attribute is valid + //! \param theAttribute the checked attribute + //! \param theArguments arguments of the attribute + //! \param theError error message + virtual bool isValid(const AttributePtr& theAttribute, + const std::list& theArguments, + Events_InfoMessage& theError) const; +}; + #endif diff --git a/src/SketchPlugin/Test/Test2273.py b/src/SketchPlugin/Test/Test2273.py new file mode 100644 index 000000000..399c9d2b3 --- /dev/null +++ b/src/SketchPlugin/Test/Test2273.py @@ -0,0 +1,99 @@ +## 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 +## + +""" + Test2273.py + Test case for issue #2273 "Error when reading HDF and Python dump" + (multi-rotation center refers to a feature produced by itself) +""" + +from salome.shaper import model +from SketchAPI import * + +model.begin() +partSet = model.moduleDocument() +Sketch_1 = model.addSketch(partSet, model.defaultPlane("XOY")) +SketchLine_1 = Sketch_1.addLine(-65.36884900412264, 10.74954405845571, -18.59380593895045, 62.75409504395774) +SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "Origin"), False) +SketchPoint_1 = SketchProjection_1.createdFeature() + + +# Test 1. Check MultiRotation error + +SketchMultiRotation_1 = Sketch_1.addRotation([SketchLine_1.result()], SketchAPI_Point(SketchPoint_1).coordinates(), 90, 3) +[SketchLine_2, SketchLine_3] = SketchMultiRotation_1.rotated() +model.do() +# check MultiRotation has NO error +assert(SketchMultiRotation_1.feature().error() == "") +# change center of MultiRotation to extremity of generated feature, check an error appears +SketchMultiRotation_1.center().setAttr(SketchAPI_Line(SketchLine_2).startPoint()) +model.do() +assert(SketchMultiRotation_1.feature().error() != "") +# revert changes => no error +SketchMultiRotation_1.center().setAttr(SketchAPI_Point(SketchPoint_1).coordinates()) +model.do() +assert(SketchMultiRotation_1.feature().error() == "") + + +# Test 2. Check MultiRotation error + +SketchMultiTranslation_1 = Sketch_1.addTranslation([SketchLine_1.result()], SketchLine_1.startPoint(), SketchAPI_Line(SketchLine_2).endPoint(), 2) +[SketchLine_4] = SketchMultiTranslation_1.translated() +model.do() +# check MultiTranslation has NO error +assert(SketchMultiTranslation_1.feature().error() == "") +# change start point to extremity of generated feature, check an error appears +SketchMultiTranslation_1.startPoint().setAttr(SketchAPI_Line(SketchLine_4).endPoint()) +model.do() +assert(SketchMultiTranslation_1.feature().error() != "") +# revert changes => no error +SketchMultiTranslation_1.startPoint().setAttr(SketchLine_1.startPoint()) +model.do() +assert(SketchMultiTranslation_1.feature().error() == "") +# change end point to extremity of generated feature, check an error appears +SketchMultiTranslation_1.endPoint().setAttr(SketchAPI_Line(SketchLine_4).endPoint()) +model.do() +assert(SketchMultiTranslation_1.feature().error() != "") +# revert changes => no error +SketchMultiTranslation_1.endPoint().setAttr(SketchAPI_Line(SketchLine_2).endPoint()) +model.do() +assert(SketchMultiTranslation_1.feature().error() == "") + + +# Test 3. Check Mirror error + +SketchConstraintMirror_1 = Sketch_1.addMirror(SketchLine_2.result(), [SketchLine_1.result(), SketchLine_3.result()]) +[SketchLine_5, SketchLine_6] = SketchConstraintMirror_1.mirrored() +model.do() +# check Mirror has NO error +assert(SketchConstraintMirror_1.feature().error() == "") +# change mirror line to generated feature, check an error appears +SketchConstraintMirror_1.mirrorLine().setObject(SketchLine_5.feature().firstResult()) +model.do() +assert(SketchConstraintMirror_1.feature().error() != "") +# revert changes => no error +SketchConstraintMirror_1.mirrorLine().setObject(SketchLine_2.feature().firstResult()) +model.do() +assert(SketchConstraintMirror_1.feature().error() == "") + +model.end() + + +assert(model.checkPythonDump()) diff --git a/src/SketchPlugin/plugin-Sketch.xml b/src/SketchPlugin/plugin-Sketch.xml index 0c03eb5ce..e5b3de339 100644 --- a/src/SketchPlugin/plugin-Sketch.xml +++ b/src/SketchPlugin/plugin-Sketch.xml @@ -499,6 +499,7 @@ email : webmaster.salome@opencascade.com + + + @@ -554,6 +557,7 @@ email : webmaster.salome@opencascade.com + + @@ -594,6 +599,7 @@ email : webmaster.salome@opencascade.com + diff --git a/src/SketchSolver/SketchSolver_ConstraintMultiRotation.cpp b/src/SketchSolver/SketchSolver_ConstraintMultiRotation.cpp index 25d1507a6..bd57785ef 100644 --- a/src/SketchSolver/SketchSolver_ConstraintMultiRotation.cpp +++ b/src/SketchSolver/SketchSolver_ConstraintMultiRotation.cpp @@ -125,12 +125,23 @@ void SketchSolver_ConstraintMultiRotation::adjustConstraint() } // Obtain coordinates of rotation center + AttributeRefAttrPtr aCenterAttr = + myBaseConstraint->refattr(SketchPlugin_MultiRotation::CENTER_ID()); std::shared_ptr aRotCenter = - std::dynamic_pointer_cast(myStorage->entity( - myBaseConstraint->attribute(SketchPlugin_MultiRotation::CENTER_ID()))); - GCSPointPtr aCenterPoint = aRotCenter->point(); - myCenterCoord[0] = *(aCenterPoint->x); - myCenterCoord[1] = *(aCenterPoint->y); + std::dynamic_pointer_cast(myStorage->entity(aCenterAttr)); + if (aRotCenter) + { + GCSPointPtr aCenterPoint = aRotCenter->point(); + myCenterCoord[0] = *(aCenterPoint->x); + myCenterCoord[1] = *(aCenterPoint->y); + } + else + { + AttributePoint2DPtr aCenterPnt = + std::dynamic_pointer_cast(aCenterAttr->attr()); + myCenterCoord[0] = aCenterPnt->x(); + myCenterCoord[1] = aCenterPnt->y(); + } if (myIsFullValue && myNumberOfCopies > 0) anAngleValue /= myNumberOfCopies; diff --git a/src/SketchSolver/SketchSolver_ConstraintMultiTranslation.cpp b/src/SketchSolver/SketchSolver_ConstraintMultiTranslation.cpp index 454d1e3aa..8028c1ddf 100644 --- a/src/SketchSolver/SketchSolver_ConstraintMultiTranslation.cpp +++ b/src/SketchSolver/SketchSolver_ConstraintMultiTranslation.cpp @@ -122,18 +122,32 @@ void SketchSolver_ConstraintMultiTranslation::adjustConstraint() return; // Obtain delta between start and end points of translation - std::shared_ptr aStartWrapper = - std::dynamic_pointer_cast(myStorage->entity( - myBaseConstraint->attribute(SketchPlugin_MultiTranslation::START_POINT_ID()))); - std::shared_ptr aEndWrapper = - std::dynamic_pointer_cast(myStorage->entity( - myBaseConstraint->attribute(SketchPlugin_MultiTranslation::END_POINT_ID()))); - - GCSPointPtr aStart = aStartWrapper->point(); - GCSPointPtr aEnd = aEndWrapper->point(); - - myDelta[0] = *(aEnd->x) - *(aStart->x); - myDelta[1] = *(aEnd->y) - *(aStart->y); + AttributeRefAttrPtr aStartEnd[2] = { + myBaseConstraint->refattr(SketchPlugin_MultiTranslation::START_POINT_ID()), + myBaseConstraint->refattr(SketchPlugin_MultiTranslation::END_POINT_ID()) + }; + double aCoords[2][2]; + for (int i = 0; i < 2; ++i) + { + std::shared_ptr aPointWrapper = + std::dynamic_pointer_cast(myStorage->entity(aStartEnd[i])); + if (aPointWrapper) + { + GCSPointPtr aPnt = aPointWrapper->point(); + aCoords[i][0] = *(aPnt->x); + aCoords[i][1] = *(aPnt->y); + } + else + { + AttributePoint2DPtr aPnt = + std::dynamic_pointer_cast(aStartEnd[i]->attr()); + aCoords[i][0] = aPnt->x(); + aCoords[i][1] = aPnt->y(); + } + } + + myDelta[0] = aCoords[1][0] - aCoords[0][0]; + myDelta[1] = aCoords[1][1] - aCoords[0][1]; if (myIsFullValue && myNumberOfCopies > 0) { myDelta[0] /= myNumberOfCopies; -- 2.39.2