From: azv Date: Fri, 16 Aug 2019 05:49:58 +0000 (+0300) Subject: Task 2.2. New arcs creation mode: perpendicular to a straight edge X-Git-Tag: V9_4_0a2~4^2~143 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=50c00db30f94180aeccd1ae40c6d042e2f547f76;p=modules%2Fshaper.git Task 2.2. New arcs creation mode: perpendicular to a straight edge * Implement fourth mode of arc creation: by transversal line. * Unit test for that mode. * Documentation update. --- diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Circ2dBuilder.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Circ2dBuilder.cpp index 232a0d690..5b20ddb13 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Circ2dBuilder.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Circ2dBuilder.cpp @@ -26,6 +26,7 @@ #include #include +#include #include #include #include @@ -48,6 +49,7 @@ typedef std::vector< std::shared_ptr > VectorOfGccLine; // Provide different mechanisms to create circle: // * by passing points // * by tangent edges +// * by transversal line // * with specified radius // * etc. class CircleBuilder @@ -83,6 +85,19 @@ public: } } + void setTransversalLine(const std::shared_ptr& theLine) + { + if (!theLine) + return; + + const TopoDS_Edge& anEdge = TopoDS::Edge(theLine->impl()); + + double aFirst, aLast; + TopLoc_Location aLoc; + Handle(Geom2d_Curve) aCurve = BRep_Tool::CurveOnSurface(anEdge, myPlane, aLoc, aFirst, aLast); + myTransversalLine = CurveAdaptorPtr(new Geom2dAdaptor_Curve(aCurve, aFirst, aLast)); + } + void setPassingPoints(const std::vector< std::shared_ptr >& thePoints) { std::vector< std::shared_ptr >::const_iterator aPIt; @@ -115,9 +130,13 @@ public: case 1: aResult = circleByPointAndTwoTangentCurves(); break; - case 2: - aResult = circleByTwoPointsAndTangentCurve(); + case 2: { + if (myTransversalLine) + aResult = circleByTwoPointsAndTransversalLine(); + else + aResult = circleByTwoPointsAndTangentCurve(); break; + } case 3: aResult = circleByThreePassingPoints(); break; @@ -342,6 +361,22 @@ private: } + Circ2dPtr circleByTwoPointsAndTransversalLine() + { + const gp_Pnt2d& aPoint1 = myPassingPoints[0]; + const gp_Pnt2d& aPoint2 = myPassingPoints[1]; + + if (myTransversalLine && myTransversalLine->GetType() == GeomAbs_Line) { + GccAna_Circ2d2TanOn aCircleBuilder(aPoint1, aPoint2, myTransversalLine->Line(), + Precision::Confusion()); + if (aCircleBuilder.NbSolutions() > 0) + return Circ2dPtr(new gp_Circ2d(aCircleBuilder.ThisSolution(1))); + } + + return Circ2dPtr(); + } + + Circ2dPtr circleByRadiusAndTwoTangentCurves() { VectorOfGccCirc aTgCirc; @@ -467,6 +502,7 @@ private: std::shared_ptr myCenter; std::vector myPassingPoints; std::vector myTangentShapes; + CurveAdaptorPtr myTransversalLine; double myRadius; std::shared_ptr myClosestPoint; }; @@ -497,6 +533,12 @@ void GeomAlgoAPI_Circ2dBuilder::addTangentCurve(const std::shared_ptr& theEdge) +{ + if (theEdge->isEdge()) + myTransversalLine = theEdge; +} + void GeomAlgoAPI_Circ2dBuilder::addPassingPoint(const std::shared_ptr& thePoint) { myPassingPoints.push_back(thePoint); @@ -526,6 +568,7 @@ std::shared_ptr GeomAlgoAPI_Circ2dBuilder::circle() CircleBuilder aCircleBuilder(myPlane); aCircleBuilder.setCenter(myCenter); aCircleBuilder.setTangentCurves(myTangentShapes); + aCircleBuilder.setTransversalLine(myTransversalLine); aCircleBuilder.setPassingPoints(myPassingPoints); aCircleBuilder.setClosestPoint(myClosestPoint); aCircleBuilder.setRadius(myRadius); diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Circ2dBuilder.h b/src/GeomAlgoAPI/GeomAlgoAPI_Circ2dBuilder.h index c193e877d..3105b5047 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Circ2dBuilder.h +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Circ2dBuilder.h @@ -58,6 +58,10 @@ public: GEOMALGOAPI_EXPORT void addTangentCurve(const std::shared_ptr& theEdge); + /// \brief Constrain circle to be orthogonal to the given edge + GEOMALGOAPI_EXPORT + void setTransversalLine(const std::shared_ptr& theEdge); + /// \brief Constrain circle to pass through the given point GEOMALGOAPI_EXPORT void addPassingPoint(const std::shared_ptr& thePoint); @@ -82,6 +86,7 @@ private: std::shared_ptr myCenter; std::vector< std::shared_ptr > myPassingPoints; std::vector< std::shared_ptr > myTangentShapes; + std::shared_ptr myTransversalLine; std::shared_ptr myClosestPoint; double myRadius; }; diff --git a/src/SketchAPI/SketchAPI_MacroArc.cpp b/src/SketchAPI/SketchAPI_MacroArc.cpp index 4bad39fef..67dc5f0c7 100644 --- a/src/SketchAPI/SketchAPI_MacroArc.cpp +++ b/src/SketchAPI/SketchAPI_MacroArc.cpp @@ -201,3 +201,29 @@ void SketchAPI_MacroArc::setByTangent(const ModelHighAPI_RefAttr& theTangentPoin execute(); } + +//================================================================================================ +void SketchAPI_MacroArc::setByTransversal(const ModelHighAPI_RefAttr& theTransversalPoint, + double theEndX, double theEndY, + bool theInversed) +{ + fillAttribute(SketchPlugin_MacroArc::ARC_TYPE_BY_TRANSVERSAL_LINE(), myarcType); + fillAttribute(theTransversalPoint, mytangentPoint); + fillAttribute(endPoint3(), theEndX, theEndY); + fillAttribute(theInversed, myreversed); + + execute(); +} + +//================================================================================================ +void SketchAPI_MacroArc::setByTransversal(const ModelHighAPI_RefAttr& theTransversalPoint, + const std::shared_ptr& theEnd, + bool theInversed) +{ + fillAttribute(SketchPlugin_MacroArc::ARC_TYPE_BY_TRANSVERSAL_LINE(), myarcType); + fillAttribute(theTransversalPoint, mytangentPoint); + fillAttribute(theEnd, myendPoint3); + fillAttribute(theInversed, myreversed); + + execute(); +} diff --git a/src/SketchAPI/SketchAPI_MacroArc.h b/src/SketchAPI/SketchAPI_MacroArc.h index a4b51ccec..3a6ae5566 100644 --- a/src/SketchAPI/SketchAPI_MacroArc.h +++ b/src/SketchAPI/SketchAPI_MacroArc.h @@ -114,8 +114,6 @@ public: angle, SketchPlugin_MacroArc::ANGLE_ID(), ModelAPI_AttributeDouble, /** Angle */) -private: - /// Set by center and start, end point. SKETCHAPI_EXPORT void setByCenterStartEnd(double theCenterX, double theCenterY, @@ -153,6 +151,18 @@ private: void setByTangent(const ModelHighAPI_RefAttr& theTangentPoint, const std::shared_ptr& theEnd, bool theInversed); + + /// Set by tangent and end point. + SKETCHAPI_EXPORT + void setByTransversal(const ModelHighAPI_RefAttr& theTransversalPoint, + double theEndX, double theEndY, + bool theInversed); + + /// Set by tangent and end point. + SKETCHAPI_EXPORT + void setByTransversal(const ModelHighAPI_RefAttr& theTransversalPoint, + const std::shared_ptr& theEnd, + bool theInversed); }; /// Pointer on Arc object. diff --git a/src/SketchAPI/SketchAPI_Sketch.cpp b/src/SketchAPI/SketchAPI_Sketch.cpp index 66e043c1c..b4b43cbb3 100644 --- a/src/SketchAPI/SketchAPI_Sketch.cpp +++ b/src/SketchAPI/SketchAPI_Sketch.cpp @@ -460,22 +460,33 @@ std::shared_ptr SketchAPI_Sketch::addArc( std::shared_ptr SketchAPI_Sketch::addArc( const ModelHighAPI_RefAttr& theTangentPoint, double theEndX, double theEndY, - bool theInversed) + bool theInversed, + bool theTransversal) { std::shared_ptr aFeature = compositeFeature()->addFeature(SketchPlugin_MacroArc::ID()); - return MacroArcPtr(new SketchAPI_MacroArc( - aFeature, theTangentPoint, theEndX, theEndY, theInversed)); + MacroArcPtr aMacroArc(new SketchAPI_MacroArc(aFeature)); + if (theTransversal) + aMacroArc->setByTransversal(theTangentPoint, theEndX, theEndY, theInversed); + else + aMacroArc->setByTangent(theTangentPoint, theEndX, theEndY, theInversed); + return aMacroArc; } std::shared_ptr SketchAPI_Sketch::addArc( const ModelHighAPI_RefAttr& theTangentPoint, const std::shared_ptr& theEnd, - bool theInversed) + bool theInversed, + bool theTransversal) { std::shared_ptr aFeature = compositeFeature()->addFeature(SketchPlugin_MacroArc::ID()); - return MacroArcPtr(new SketchAPI_MacroArc(aFeature, theTangentPoint, theEnd, theInversed)); + MacroArcPtr aMacroArc(new SketchAPI_MacroArc(aFeature)); + if (theTransversal) + aMacroArc->setByTransversal(theTangentPoint, theEnd, theInversed); + else + aMacroArc->setByTangent(theTangentPoint, theEnd, theInversed); + return aMacroArc; } std::shared_ptr SketchAPI_Sketch::addArc(const ModelHighAPI_Selection & theExternal) diff --git a/src/SketchAPI/SketchAPI_Sketch.h b/src/SketchAPI/SketchAPI_Sketch.h index 8b3237f7f..27a5c543d 100644 --- a/src/SketchAPI/SketchAPI_Sketch.h +++ b/src/SketchAPI/SketchAPI_Sketch.h @@ -236,19 +236,21 @@ public: const std::shared_ptr& theEnd, const std::shared_ptr& thePassed); - /// Add arc + /// Add transversal/tangent arc SKETCHAPI_EXPORT std::shared_ptr addArc( - const ModelHighAPI_RefAttr& theTangentPoint, + const ModelHighAPI_RefAttr& theConnectedPoint, double theEndX, double theEndY, - bool theInversed); + bool theInversed, + bool theTransversal = false); - /// Add arc + /// Add transversal/tangent arc SKETCHAPI_EXPORT std::shared_ptr addArc( - const ModelHighAPI_RefAttr& theTangentPoint, + const ModelHighAPI_RefAttr& theConnectedPoint, const std::shared_ptr& theEnd, - bool theInversed); + bool theInversed, + bool theTransversal = false); /// Add arc SKETCHAPI_EXPORT diff --git a/src/SketchPlugin/CMakeLists.txt b/src/SketchPlugin/CMakeLists.txt index f11be7799..cd9bc43fb 100644 --- a/src/SketchPlugin/CMakeLists.txt +++ b/src/SketchPlugin/CMakeLists.txt @@ -222,6 +222,7 @@ ADD_UNIT_TESTS( TestCreateArcByCenterStartEnd.py TestCreateArcByTangentEdge.py TestCreateArcByThreePoints.py + TestCreateArcByTransversalLine.py TestCreateArcChangeType.py TestCreateCircleByCenterAndPassed.py TestCreateCircleByThreePoints.py diff --git a/src/SketchPlugin/SketchPlugin_MacroArc.cpp b/src/SketchPlugin/SketchPlugin_MacroArc.cpp index 3e6327e08..f0379c461 100644 --- a/src/SketchPlugin/SketchPlugin_MacroArc.cpp +++ b/src/SketchPlugin/SketchPlugin_MacroArc.cpp @@ -20,6 +20,7 @@ #include "SketchPlugin_MacroArc.h" #include "SketchPlugin_Arc.h" +#include "SketchPlugin_ConstraintPerpendicular.h" #include "SketchPlugin_ConstraintTangent.h" #include "SketchPlugin_Sketch.h" #include "SketchPlugin_Tools.h" @@ -209,7 +210,9 @@ void SketchPlugin_MacroArc::attributeChanged(const std::string& theID) else if(anArcType == ARC_TYPE_BY_THREE_POINTS()) fillByThreePassedPoints(); else if(anArcType == ARC_TYPE_BY_TANGENT_EDGE()) - fillByTangentEdge(); + fillByEdge(false); + else if (anArcType == ARC_TYPE_BY_TRANSVERSAL_LINE()) + fillByEdge(true); double aRadius = 0; double anAngle = 0; @@ -339,19 +342,27 @@ void SketchPlugin_MacroArc::execute() AttributePtr(), anArcFeature->lastResult(), true); - } else if(anArcType == ARC_TYPE_BY_TANGENT_EDGE()) { - // constraints for tangent arc + } else { + // coincident with connection point SketchPlugin_Tools::createCoincidenceOrTangency(this, TANGENT_POINT_ID(), anArcFeature->attribute(SketchPlugin_Arc::START_ID()), ObjectPtr(), false); - FeaturePtr aTangent = sketch()->addFeature(SketchPlugin_ConstraintTangent::ID()); - AttributeRefAttrPtr aRefAttrA = aTangent->refattr(SketchPlugin_Constraint::ENTITY_A()); + // tangent or perpendicular constraint + FeaturePtr aStartPointConstraint; + if (anArcType == ARC_TYPE_BY_TANGENT_EDGE()) + aStartPointConstraint = sketch()->addFeature(SketchPlugin_ConstraintTangent::ID()); + else + aStartPointConstraint = sketch()->addFeature(SketchPlugin_ConstraintPerpendicular::ID()); + // setting attributes of the start point constraint + AttributeRefAttrPtr aRefAttrA = + aStartPointConstraint->refattr(SketchPlugin_Constraint::ENTITY_A()); AttributeRefAttrPtr aTgPntRefAttr = refattr(TANGENT_POINT_ID()); FeaturePtr aTgFeature = ModelAPI_Feature::feature(aTgPntRefAttr->attr()->owner()); aRefAttrA->setObject(aTgFeature->lastResult()); - AttributeRefAttrPtr aRefAttrB = aTangent->refattr(SketchPlugin_Constraint::ENTITY_B()); + AttributeRefAttrPtr aRefAttrB = + aStartPointConstraint->refattr(SketchPlugin_Constraint::ENTITY_B()); aRefAttrB->setObject(anArcFeature->lastResult()); // constraint for end point SketchPlugin_Tools::createCoincidenceOrTangency(this, @@ -596,15 +607,15 @@ void SketchPlugin_MacroArc::recalculateReversedFlagByPassed( myParamBefore = aEndParam; } -void SketchPlugin_MacroArc::fillByTangentEdge() +void SketchPlugin_MacroArc::fillByEdge(bool theTransversal) { AttributeRefAttrPtr aTangentAttr = refattr(TANGENT_POINT_ID()); if (!aTangentAttr->isInitialized()) return; - AttributePoint2DPtr aTangentPointAttr = + AttributePoint2DPtr aConnectionPointAttr = std::dynamic_pointer_cast(aTangentAttr->attr()); - if (!aTangentPointAttr->isInitialized()) + if (!aConnectionPointAttr->isInitialized()) return; AttributePoint2DPtr anEndPointAttr = @@ -612,19 +623,22 @@ void SketchPlugin_MacroArc::fillByTangentEdge() if (!anEndPointAttr->isInitialized()) return; - myStart = aTangentPointAttr->pnt(); + myStart = aConnectionPointAttr->pnt(); myEnd = anEndPointAttr->pnt(); if (myStart->isEqual(myEnd)) return; // obtain a shape the tangent point belongs to - FeaturePtr aTangentFeature = ModelAPI_Feature::feature(aTangentPointAttr->owner()); - std::shared_ptr aTangentShape = aTangentFeature->lastResult()->shape(); + FeaturePtr aConnectedFeature = ModelAPI_Feature::feature(aConnectionPointAttr->owner()); + std::shared_ptr aTangentShape = aConnectedFeature->lastResult()->shape(); GeomAlgoAPI_Circ2dBuilder aCircBuilder(SketchPlugin_Sketch::plane(sketch())); aCircBuilder.addPassingPoint(myStart); aCircBuilder.addPassingPoint(myEnd); - aCircBuilder.addTangentCurve(aTangentShape); + if (theTransversal) + aCircBuilder.setTransversalLine(aTangentShape); + else + aCircBuilder.addTangentCurve(aTangentShape); std::shared_ptr aCircle = aCircBuilder.circle(); if (!aCircle) diff --git a/src/SketchPlugin/SketchPlugin_MacroArc.h b/src/SketchPlugin/SketchPlugin_MacroArc.h index 815cd7002..886f6efdc 100644 --- a/src/SketchPlugin/SketchPlugin_MacroArc.h +++ b/src/SketchPlugin/SketchPlugin_MacroArc.h @@ -72,6 +72,12 @@ class SketchPlugin_MacroArc: public SketchPlugin_SketchEntity, return ID; } + inline static const std::string& ARC_TYPE_BY_TRANSVERSAL_LINE() + { + static const std::string ID("by_transversal_line"); + return ID; + } + /// Central 2D point of the circle which contains the arc inline static const std::string& CENTER_POINT_ID() { @@ -220,8 +226,9 @@ private: void fillByCenterAndTwoPassed(); /// Set fields for center, start and end points by selected passed points void fillByThreePassedPoints(); - /// Set fields for center, start and end points by selected tangent edge - void fillByTangentEdge(); + /// Set fields for center, start and end points by selected tangent or transversal edge + /// \param theTransversal if \c true, builds transversal arc, otherwise builds tangential arc. + void fillByEdge(bool theTransversal); FeaturePtr createArcFeature(); diff --git a/src/SketchPlugin/SketchPlugin_Plugin.cpp b/src/SketchPlugin/SketchPlugin_Plugin.cpp index 5d1e9804e..67d4e4656 100644 --- a/src/SketchPlugin/SketchPlugin_Plugin.cpp +++ b/src/SketchPlugin/SketchPlugin_Plugin.cpp @@ -119,6 +119,8 @@ SketchPlugin_Plugin::SketchPlugin_Plugin() new SketchPlugin_MiddlePointAttrValidator); aFactory->registerValidator("SketchPlugin_ArcTangentPoint", new SketchPlugin_ArcTangentPointValidator); + aFactory->registerValidator("SketchPlugin_ArcTransversalPoint", + new SketchPlugin_ArcTransversalPointValidator); aFactory->registerValidator("SketchPlugin_IntersectionValidator", new SketchPlugin_IntersectionValidator); aFactory->registerValidator("SketchPlugin_ProjectionValidator", diff --git a/src/SketchPlugin/SketchPlugin_Validators.cpp b/src/SketchPlugin/SketchPlugin_Validators.cpp index e95372a35..a0cbf6805 100644 --- a/src/SketchPlugin/SketchPlugin_Validators.cpp +++ b/src/SketchPlugin/SketchPlugin_Validators.cpp @@ -836,6 +836,44 @@ bool SketchPlugin_ArcTangentPointValidator::isValid(const AttributePtr& theAttri return true; } +bool SketchPlugin_ArcTransversalPointValidator::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; + } + AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast(theAttribute); + AttributePtr anAttr = aRefAttr->attr(); + if (!anAttr) { + theError = "The attribute %1 should be a point"; + theError.arg(theAttribute->id()); + return false; + } + + FeaturePtr anAttrFeature = std::dynamic_pointer_cast(anAttr->owner()); + const std::string& aFeatureType = anAttrFeature->getKind(); + if (aFeatureType == SketchPlugin_Line::ID()) { + // selected point should be bound point of line + const std::string& aPntId = anAttr->id(); + if (aPntId != SketchPlugin_Line::START_ID() && aPntId != SketchPlugin_Line::END_ID()) { + theError = "The attribute %1 is not supported"; + theError.arg(aPntId); + return false; + } + } + else { + theError = "Unable to build transversal arc on %1"; + theError.arg(anAttrFeature->getKind()); + return false; + } + + return true; +} + bool SketchPlugin_IntersectionValidator::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 d988ac751..b3fe8f574 100644 --- a/src/SketchPlugin/SketchPlugin_Validators.h +++ b/src/SketchPlugin/SketchPlugin_Validators.h @@ -249,6 +249,25 @@ class SketchPlugin_ArcTangentPointValidator : public ModelAPI_AttributeValidator Events_InfoMessage& theError) const; }; +/**\class SketchPlugin_ArcTransversalPointValidator + * \ingroup Validators + * \brief Validator for the point where the transversal arc is building. + * + * Checks that the point is a start or end point just on line or arc. + */ +class SketchPlugin_ArcTransversalPointValidator : 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_SplitValidator * \ingroup Validators * \brief Validator for the entity of the following type: diff --git a/src/SketchPlugin/Test/TestCreateArcByTransversalLine.py b/src/SketchPlugin/Test/TestCreateArcByTransversalLine.py new file mode 100644 index 000000000..0250f952c --- /dev/null +++ b/src/SketchPlugin/Test/TestCreateArcByTransversalLine.py @@ -0,0 +1,163 @@ +# Copyright (C) 2014-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 +# + + +#========================================================================= +# Initialization of the test +#========================================================================= +from GeomDataAPI import * +from ModelAPI import * +from SketchAPI import SketchAPI_Sketch +import math +from salome.shaper import model + +__updated__ = "2019-08-16" + +TOLERANCE = 1.e-7 + +#========================================================================= +# Auxiliary functions +#========================================================================= + +def verifyLastArc(theSketch, theCenter, theStart, theEnd): + """ + subroutine to verify position of last arc in the sketch + """ + aLastArc = model.lastSubFeature(theSketch, "SketchArc") + model.assertArc(aLastArc, theCenter, theStart, theEnd) + +def verifyArcLineTransversal(theArc, theLine): + aCenter = geomDataAPI_Point2D(theArc.attribute("center_point")) + aDistCL = model.distancePointLine(aCenter, theLine) + assert aDistCL < TOLERANCE, "Arc and line are not orthogonal" + +def verifyPointOnArc(thePoint, theArc): + aCenter = geomDataAPI_Point2D(theArc.attribute("center_point")) + aStart = geomDataAPI_Point2D(theArc.attribute("start_point")) + aRadius = model.distancePointPoint(aStart, aCenter) + + aDistPP = model.distancePointPoint(aCenter, thePoint) + assert math.fabs(aRadius - aDistPP) < TOLERANCE, "Point is not on Circle, distance: {0}".format(aDistPP) + + + +aSession = ModelAPI_Session.get() +aDocument = aSession.moduleDocument() +#========================================================================= +# Creation of a sketch +#========================================================================= +aSession.startOperation() +aSketchCommonFeature = aDocument.addFeature("Sketch") +aSketchFeature = featureToCompositeFeature(aSketchCommonFeature) +origin = geomDataAPI_Point(aSketchFeature.attribute("Origin")) +origin.setValue(0, 0, 0) +dirx = geomDataAPI_Dir(aSketchFeature.attribute("DirX")) +dirx.setValue(1, 0, 0) +norm = geomDataAPI_Dir(aSketchFeature.attribute("Norm")) +norm.setValue(0, 0, 1) +aSession.finishOperation() +aSketch = SketchAPI_Sketch(aSketchFeature) + +# auxiliary line +aLineStartPnt = [0., 0.] +aLineEndPnt = [50., 0.] +aSession.startOperation() +aSketchLine = aSketchFeature.addFeature("SketchLine") +aLineStart = geomDataAPI_Point2D(aSketchLine.attribute("StartPoint")) +aLineEnd = geomDataAPI_Point2D(aSketchLine.attribute("EndPoint")) +aLineStart.setValue(aLineStartPnt[0], aLineStartPnt[1]) +aLineEnd.setValue(aLineEndPnt[0], aLineEndPnt[1]) +aSession.finishOperation() + +#========================================================================= +# Test 1. Create an arc, orthogonal to the line +#========================================================================= +anArcEndPnt = [80., 20.] +aSession.startOperation() +anArc = aSketchFeature.addFeature("SketchMacroArc") +assert (anArc.getKind() == "SketchMacroArc") +anArcTgPnt = anArc.refattr("tangent_point") +assert (not anArcTgPnt.isInitialized()) +anArcEnd = geomDataAPI_Point2D(anArc.attribute("end_point_3")) +assert (not anArcEnd.isInitialized()) +anArcType = anArc.string("arc_type") +assert (not anArcType.isInitialized()) +# initialize attributes +anArcType.setValue("by_transversal_line") +anArcTgPnt.setAttr(aLineEnd) +anArcEnd.setValue(anArcEndPnt[0], anArcEndPnt[1]) +aSession.finishOperation() +verifyLastArc(aSketchFeature, [], aLineEndPnt, anArcEndPnt) +aLastArc = model.lastSubFeature(aSketchFeature, "SketchArc") +verifyArcLineTransversal(aLastArc, aSketchLine) +model.testNbSubFeatures(aSketch, "SketchConstraintCoincidence", 1) +model.testNbSubFeatures(aSketch, "SketchConstraintPerpendicular", 1) + +#========================================================================= +# Test 2. Create an arc, orthogonal to the previous arc (expect an error) +#========================================================================= +aPrevArc = aLastArc +aPrevArcEnd = geomDataAPI_Point2D(aPrevArc.attribute("end_point")) +anArcEndPnt = [50., 100.] +aSession.startOperation() +anArc = aSketchFeature.addFeature("SketchMacroArc") +anArcTgPnt = anArc.refattr("tangent_point") +anArcEnd = geomDataAPI_Point2D(anArc.attribute("end_point_3")) +anArcType = anArc.string("arc_type") +# initialize attributes +anArcType.setValue("by_transversal_line") +anArcTgPnt.setAttr(aPrevArcEnd) +anArcEnd.setValue(anArcEndPnt[0], anArcEndPnt[1]) +aSession.finishOperation() +assert(anArc.error() != "") +# remove failed feature +aSession.startOperation() +aDocument.removeFeature(anArc) +aSession.finishOperation() + +#========================================================================= +# Test 3. Create an arc, orthogonal to the line with end point on the arc +#========================================================================= +aPrevArc = model.lastSubFeature(aSketchFeature, "SketchArc") +aPrevArcEnd = geomDataAPI_Point2D(aPrevArc.attribute("end_point")) +aSession.startOperation() +anArc = aSketchFeature.addFeature("SketchMacroArc") +anArcTgPnt = anArc.refattr("tangent_point") +anArcEnd = geomDataAPI_Point2D(anArc.attribute("end_point_3")) +anArcEndRef = anArc.refattr("end_point_ref") +anArcType = anArc.string("arc_type") +# initialize attributes +anArcType.setValue("by_transversal_line") +anArcTgPnt.setAttr(aLineStart) +anArcEndRef.setObject(aPrevArc.lastResult()) +anArcEnd.setValue(anArcEndPnt[0], anArcEndPnt[1]) +aSession.finishOperation() +verifyLastArc(aSketchFeature, [], [aLineStart.x(), aLineStart.y()], []) +aLastArc = model.lastSubFeature(aSketchFeature, "SketchArc") +verifyArcLineTransversal(aLastArc, aSketchLine) +aLastArcEnd = geomDataAPI_Point2D(aLastArc.attribute("end_point")) +verifyPointOnArc(aLastArcEnd, aPrevArc) +model.testNbSubFeatures(aSketch, "SketchConstraintCoincidence", 3) +model.testNbSubFeatures(aSketch, "SketchConstraintPerpendicular", 2) + +#========================================================================= +# End of test +#========================================================================= + +assert(model.checkPythonDump()) diff --git a/src/SketchPlugin/doc/arcFeature.rst b/src/SketchPlugin/doc/arcFeature.rst index 9139ea4db..b00034cbe 100644 --- a/src/SketchPlugin/doc/arcFeature.rst +++ b/src/SketchPlugin/doc/arcFeature.rst @@ -10,7 +10,7 @@ To add a new Arc to the Sketch: #. select in the Main Menu *Sketch - > Arc* item or #. click |arc.icon| **Arc** button in Sketch toolbar: -There are 3 algorithms for creation of an Arc: +There are 4 algorithms for creation of an Arc: .. image:: images/arc_base_32x32.png :align: left @@ -24,6 +24,10 @@ There are 3 algorithms for creation of an Arc: :align: left **By tangent point and end point** creates an arc segment with the tangent point and the end point. +.. image:: images/arc_perp_32x32.png + :align: left +**By transversal point and end point** creates an arc segment perpendicular to a straight line with the start point, connected with boundary of this line, and the end point. + By center and two points """""""""""""""""""""""" @@ -90,12 +94,36 @@ The tangent point by itself is a start point. The edge on which it lies will be **TUI Command**: -.. py:function:: Sketch_1.addArc(TangetPoint, EndX, EndY, Inversed) +.. py:function:: Sketch_1.addArc(TangentPoint, EndX, EndY, Inversed) + + :param object: Tangent Point. + :param real: End X. + :param real: End Y. + :param boolean: Is inversed. + :return: Result object. + +By transveral point and point +""""""""""""""""""""""""""""" + +.. image:: images/Arc_panel_perp.png + :align: center + +Select a point on a straight segment in the view to set the transversal point, then move the mouse and click to set the end point. +The transversal point by itself is a start point. The edge on which it lies will be perpendicular to the arc (the center of the arc is lying on the edge). + +- When entering a transversal point by selecting a point on segment, a Perpendicular constraint is created. +- When entering an end point by selecting a segment, a Coincident constraint is created. +- When entering an end point, only segments are selectable. + +**TUI Command**: + +.. py:function:: Sketch_1.addArc(TransversalPoint, EndX, EndY, Inversed, True) - :param object: Tanget Point. + :param object: Transversal Point. :param real: End X. :param real: End Y. :param boolean: Is inversed. + :param boolean: Arc is transversal (always True). :return: Result object. Result diff --git a/src/SketchPlugin/doc/examples/arc.py b/src/SketchPlugin/doc/examples/arc.py index 3d44a951d..cad2078bf 100644 --- a/src/SketchPlugin/doc/examples/arc.py +++ b/src/SketchPlugin/doc/examples/arc.py @@ -10,5 +10,6 @@ SketchArc_2 = Sketch_1.addArc(8.1, 56.7, 58.2, 6.6, 44.8, 69.2) SketchLine_3 = Sketch_1.addLine(25.0, 109.4, 68.1, 153.6) SketchLine_3.setAuxiliary(True) SketchArc_3 = Sketch_1.addArc(SketchLine_3.startPoint(), 92.1, 34.0, True) +SketchArc_4 = Sketch_1.addArc(SketchLine_3.endPoint(), 150.0, 10.0, True, True) model.do() model.end() diff --git a/src/SketchPlugin/doc/images/Arc_panel_3pt.png b/src/SketchPlugin/doc/images/Arc_panel_3pt.png index 089d50730..fd1b9aa82 100644 Binary files a/src/SketchPlugin/doc/images/Arc_panel_3pt.png and b/src/SketchPlugin/doc/images/Arc_panel_3pt.png differ diff --git a/src/SketchPlugin/doc/images/Arc_panel_base.png b/src/SketchPlugin/doc/images/Arc_panel_base.png index 9a5b9ed4a..f702ca8be 100644 Binary files a/src/SketchPlugin/doc/images/Arc_panel_base.png and b/src/SketchPlugin/doc/images/Arc_panel_base.png differ diff --git a/src/SketchPlugin/doc/images/Arc_panel_perp.png b/src/SketchPlugin/doc/images/Arc_panel_perp.png new file mode 100644 index 000000000..3e33cf9bf Binary files /dev/null and b/src/SketchPlugin/doc/images/Arc_panel_perp.png differ diff --git a/src/SketchPlugin/doc/images/Arc_panel_tang.png b/src/SketchPlugin/doc/images/Arc_panel_tang.png index ca0205401..a14b891ac 100644 Binary files a/src/SketchPlugin/doc/images/Arc_panel_tang.png and b/src/SketchPlugin/doc/images/Arc_panel_tang.png differ diff --git a/src/SketchPlugin/doc/images/Arc_res.png b/src/SketchPlugin/doc/images/Arc_res.png index b23a9022b..1772eda35 100644 Binary files a/src/SketchPlugin/doc/images/Arc_res.png and b/src/SketchPlugin/doc/images/Arc_res.png differ diff --git a/src/SketchPlugin/doc/images/arc_perp_32x32.png b/src/SketchPlugin/doc/images/arc_perp_32x32.png new file mode 100644 index 000000000..56f9f8388 Binary files /dev/null and b/src/SketchPlugin/doc/images/arc_perp_32x32.png differ diff --git a/src/SketchPlugin/icons/arc_perp_32x32.png b/src/SketchPlugin/icons/arc_perp_32x32.png new file mode 100644 index 000000000..56f9f8388 Binary files /dev/null and b/src/SketchPlugin/icons/arc_perp_32x32.png differ diff --git a/src/SketchPlugin/plugin-Sketch.xml b/src/SketchPlugin/plugin-Sketch.xml index e3b5511c9..76871ab1b 100644 --- a/src/SketchPlugin/plugin-Sketch.xml +++ b/src/SketchPlugin/plugin-Sketch.xml @@ -272,6 +272,24 @@ + + + + + + + + SetPrimitivesAspect(aLineAspect); - // Draw constrained lines - addLine(aGroup, SketchPlugin_Constraint::ENTITY_A()); - addLine(aGroup, SketchPlugin_Constraint::ENTITY_B()); + for (int i = 0; i < 2; ++i) { + ObjectPtr anObj = + SketcherPrs_Tools::getResult(myConstraint, SketchPlugin_Constraint::ATTRIBUTE(i)); + GeomShapePtr aShape = SketcherPrs_Tools::getShape(anObj); + if (!aShape) + return; + drawShape(aShape, thePrs, theColor); + } } -