From 19d86ac992480629a9f1865886f112724a157564 Mon Sep 17 00:00:00 2001 From: azv Date: Wed, 14 Aug 2019 15:56:58 +0300 Subject: [PATCH] Task 2.1. To be able to put an orthogonality constraint between an arc and a line Extend Perpendicular constraint to make orthogonal arc and line. --- src/SketchPlugin/CMakeLists.txt | 1 + src/SketchPlugin/SketchPlugin_Plugin.cpp | 2 + src/SketchPlugin/SketchPlugin_Validators.cpp | 44 +++++++++++++++ src/SketchPlugin/SketchPlugin_Validators.h | 18 +++++++ .../TestConstraintPerpendicularArcLine.py | 54 +++++++++++++++++++ src/SketchPlugin/plugin-Sketch.xml | 14 ++--- .../PlaneGCSSolver/PlaneGCSSolver_Tools.cpp | 18 ++++++- src/SketcherPrs/SketcherPrs_Perpendicular.cpp | 21 ++------ 8 files changed, 149 insertions(+), 23 deletions(-) create mode 100644 src/SketchPlugin/Test/TestConstraintPerpendicularArcLine.py diff --git a/src/SketchPlugin/CMakeLists.txt b/src/SketchPlugin/CMakeLists.txt index d72e0c56b..f11be7799 100644 --- a/src/SketchPlugin/CMakeLists.txt +++ b/src/SketchPlugin/CMakeLists.txt @@ -214,6 +214,7 @@ ADD_UNIT_TESTS( TestConstraintMiddlePoint.py TestConstraintParallel.py TestConstraintPerpendicular.py + TestConstraintPerpendicularArcLine.py TestConstraintRadius.py TestConstraintRadiusFailure.py TestConstraintTangent.py diff --git a/src/SketchPlugin/SketchPlugin_Plugin.cpp b/src/SketchPlugin/SketchPlugin_Plugin.cpp index c9a10a82b..5d1e9804e 100644 --- a/src/SketchPlugin/SketchPlugin_Plugin.cpp +++ b/src/SketchPlugin/SketchPlugin_Plugin.cpp @@ -95,6 +95,8 @@ SketchPlugin_Plugin::SketchPlugin_Plugin() new SketchPlugin_ExternalValidator); aFactory->registerValidator("SketchPlugin_TangentAttr", new SketchPlugin_TangentAttrValidator); + aFactory->registerValidator("SketchPlugin_PerpendicularAttr", + new SketchPlugin_PerpendicularAttrValidator); aFactory->registerValidator("SketchPlugin_NotFixed", new SketchPlugin_NotFixedValidator); aFactory->registerValidator("SketchPlugin_EqualAttr", diff --git a/src/SketchPlugin/SketchPlugin_Validators.cpp b/src/SketchPlugin/SketchPlugin_Validators.cpp index 8962cf083..e95372a35 100644 --- a/src/SketchPlugin/SketchPlugin_Validators.cpp +++ b/src/SketchPlugin/SketchPlugin_Validators.cpp @@ -198,6 +198,50 @@ bool SketchPlugin_TangentAttrValidator::isValid(const AttributePtr& theAttribute return true; } +bool SketchPlugin_PerpendicularAttrValidator::isValid(const AttributePtr& theAttribute, + const std::list& theArguments, + Events_InfoMessage& theError) const +{ + if (theAttribute->attributeType() != ModelAPI_AttributeRefAttr::typeId()) { + theError = "The attribute with the %1 type is not processed"; + theError.arg(theAttribute->attributeType()); + return false; + } + + std::string aParamA = theArguments.front(); + SessionPtr aMgr = ModelAPI_Session::get(); + ModelAPI_ValidatorsFactory* aFactory = aMgr->validators(); + + FeaturePtr anOwner = std::dynamic_pointer_cast(theAttribute->owner()); + AttributeRefAttrPtr aRefAttr = + std::dynamic_pointer_cast(theAttribute); + + bool isObject = aRefAttr->isObject(); + ObjectPtr anObject = aRefAttr->object(); + if (isObject && anObject.get()) { + FeaturePtr aRefFea = ModelAPI_Feature::feature(anObject); + + AttributeRefAttrPtr aOtherAttr = anOwner->refattr(aParamA); + ObjectPtr aOtherObject = aOtherAttr->object(); + FeaturePtr aOtherFea = ModelAPI_Feature::feature(aOtherObject); + if (!aOtherFea) + return true; + + // at least one feature should be a line + if (aRefFea->getKind() != SketchPlugin_Line::ID() && + aOtherFea->getKind() != SketchPlugin_Line::ID()) { + theError = "At least one feature should be a line"; + return false; + } + } + else { + theError = "It uses an empty object"; + return false; + } + + return true; +} + bool SketchPlugin_NotFixedValidator::isValid(const AttributePtr& theAttribute, const std::list& theArguments, Events_InfoMessage& theError) const diff --git a/src/SketchPlugin/SketchPlugin_Validators.h b/src/SketchPlugin/SketchPlugin_Validators.h index 4a7bd0525..d988ac751 100644 --- a/src/SketchPlugin/SketchPlugin_Validators.h +++ b/src/SketchPlugin/SketchPlugin_Validators.h @@ -60,6 +60,24 @@ class SketchPlugin_TangentAttrValidator : public ModelAPI_AttributeValidator Events_InfoMessage& theError) const; }; +/**\class SketchPlugin_PerpendicularAttrValidator + * \ingroup Validators + * \brief Validator for the perpendicular constraint input. + * + * Checks that two arcs are not selected for perpendicular. + */ +class SketchPlugin_PerpendicularAttrValidator : 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; +}; + /**\class SketchPlugin_NotFixedValidator * \ingroup Validators diff --git a/src/SketchPlugin/Test/TestConstraintPerpendicularArcLine.py b/src/SketchPlugin/Test/TestConstraintPerpendicularArcLine.py new file mode 100644 index 000000000..c0fd9b343 --- /dev/null +++ b/src/SketchPlugin/Test/TestConstraintPerpendicularArcLine.py @@ -0,0 +1,54 @@ +# Copyright (C) 2019 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(-35, -10, 20) +SketchLine_1 = Sketch_1.addLine(-21, 2, 24, 21) +SketchLine_2 = Sketch_1.addLine(24, 21, 20, -30) +SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint()) +SketchArc_1 = Sketch_1.addArc(25, -30, 42, -34, 13, -17.31142245955048, False) +model.do() + +# check error on perpendicularity of circle and arc +SketchConstraintPerpendicular_1 = Sketch_1.setPerpendicular(SketchCircle_1.results()[1], SketchArc_1.results()[1]) +model.do() +assert(SketchConstraintPerpendicular_1.feature().error() != "") + +# avoid the failure +Part_1_doc.removeFeature(SketchConstraintPerpendicular_1.feature()) +model.do() +assert(Sketch_1.feature().error() == "") + +# set correct constraints +SketchConstraintPerpendicular_2 = Sketch_1.setPerpendicular(SketchCircle_1.results()[1], SketchLine_1.result()) +SketchConstraintPerpendicular_3 = Sketch_1.setPerpendicular(SketchLine_2.result(), SketchArc_1.results()[1]) +model.do() + +TOLERANCE = 1.e-7 +assert(model.distancePointLine(SketchCircle_1.center(), SketchLine_1) < TOLERANCE) +assert(model.distancePointLine(SketchArc_1.center(), SketchLine_2) < TOLERANCE) +model.end() + +assert(model.checkPythonDump()) diff --git a/src/SketchPlugin/plugin-Sketch.xml b/src/SketchPlugin/plugin-Sketch.xml index 336d8af5f..e3b5511c9 100644 --- a/src/SketchPlugin/plugin-Sketch.xml +++ b/src/SketchPlugin/plugin-Sketch.xml @@ -925,23 +925,25 @@ - + + - + - + + diff --git a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Tools.cpp b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Tools.cpp index ac112699d..9c6cd276d 100644 --- a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Tools.cpp +++ b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Tools.cpp @@ -496,7 +496,23 @@ ConstraintWrapperPtr createConstraintPerpendicular( { std::shared_ptr aLine1 = std::dynamic_pointer_cast(theEntity1->entity()); std::shared_ptr aLine2 = std::dynamic_pointer_cast(theEntity2->entity()); - GCSConstraintPtr aNewConstr(new GCS::ConstraintPerpendicular(*(aLine1), *(aLine2))); + + std::shared_ptr aCirc1 = + std::dynamic_pointer_cast(theEntity1->entity()); + std::shared_ptr aCirc2 = + std::dynamic_pointer_cast(theEntity2->entity()); + + GCSConstraintPtr aNewConstr; + if (aLine1 && aLine2) + aNewConstr.reset(new GCS::ConstraintPerpendicular(*(aLine1), *(aLine2))); + else { + if (aLine1 && aCirc2) + aCirc1 = aCirc2; + else if (aLine2 && aCirc1) + aLine1 = aLine2; + + aNewConstr.reset(new GCS::ConstraintPointOnLine(aCirc1->center, *aLine1)); + } return ConstraintWrapperPtr( new PlaneGCSSolver_ConstraintWrapper(aNewConstr, CONSTRAINT_PERPENDICULAR)); diff --git a/src/SketcherPrs/SketcherPrs_Perpendicular.cpp b/src/SketcherPrs/SketcherPrs_Perpendicular.cpp index 314c74cb2..6ef12df79 100644 --- a/src/SketcherPrs/SketcherPrs_Perpendicular.cpp +++ b/src/SketcherPrs/SketcherPrs_Perpendicular.cpp @@ -29,6 +29,7 @@ #include #include #include +#include IMPLEMENT_STANDARD_RTTIEXT(SketcherPrs_Perpendicular, SketcherPrs_SymbolPrs); @@ -72,22 +73,10 @@ bool SketcherPrs_Perpendicular::updateIfReadyToDisplay(double theStep, bool with GeomEdgePtr aEdge1(new GeomAPI_Edge(aShp1)); GeomEdgePtr aEdge2(new GeomAPI_Edge(aShp2)); - std::shared_ptr aLin1 = aEdge1->line(); - std::shared_ptr aLin2 = aEdge2->line(); - - std::shared_ptr aPnt = aLin1->intersect(aLin2); - double aParam1 = aLin1->projParam(aPnt); - double aParam2 = aLin2->projParam(aPnt); - - GeomAPI_Curve aCurve1(aShp1); - GeomAPI_Curve aCurve2(aShp2); - bool isInside1 = (aParam1 >= (aCurve1.startParam() - Precision::Confusion())) && - (aParam1 <= (aCurve1.endParam() + Precision::Confusion())); - bool isInside2 = (aParam2 >= (aCurve2.startParam() - Precision::Confusion())) && - (aParam2 <= (aCurve2.endParam() + Precision::Confusion())); - - if (!(isInside1 && isInside2)) - aPnt = std::shared_ptr(); + GeomShapePtr anInter = aEdge1->intersect(aEdge2); + std::shared_ptr aPnt; + if (anInter && anInter->isVertex()) + aPnt = anInter->vertex()->point(); // Compute position of symbols SketcherPrs_PositionMgr* aMgr = SketcherPrs_PositionMgr::get(); -- 2.39.2