* Implement fourth mode of arc creation: by transversal line.
* Unit test for that mode.
* Documentation update.
#include <BRep_Tool.hxx>
#include <ElCLib.hxx>
+#include <GccAna_Circ2d2TanOn.hxx>
#include <GccAna_Circ2d2TanRad.hxx>
#include <GccAna_Circ2d3Tan.hxx>
#include <GccAna_Circ2dTanCen.hxx>
// Provide different mechanisms to create circle:
// * by passing points
// * by tangent edges
+// * by transversal line
// * with specified radius
// * etc.
class CircleBuilder
}
}
+ void setTransversalLine(const std::shared_ptr<GeomAPI_Shape>& theLine)
+ {
+ if (!theLine)
+ return;
+
+ const TopoDS_Edge& anEdge = TopoDS::Edge(theLine->impl<TopoDS_Shape>());
+
+ 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<GeomAPI_Pnt2d> >& thePoints)
{
std::vector< std::shared_ptr<GeomAPI_Pnt2d> >::const_iterator aPIt;
case 1:
aResult = circleByPointAndTwoTangentCurves();
break;
- case 2:
- aResult = circleByTwoPointsAndTangentCurve();
+ case 2: {
+ if (myTransversalLine)
+ aResult = circleByTwoPointsAndTransversalLine();
+ else
+ aResult = circleByTwoPointsAndTangentCurve();
break;
+ }
case 3:
aResult = circleByThreePassingPoints();
break;
}
+ 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;
std::shared_ptr<GeomAPI_Pnt2d> myCenter;
std::vector<gp_Pnt2d> myPassingPoints;
std::vector<CurveAdaptorPtr> myTangentShapes;
+ CurveAdaptorPtr myTransversalLine;
double myRadius;
std::shared_ptr<GeomAPI_Pnt2d> myClosestPoint;
};
myTangentShapes.push_back(theEdge);
}
+void GeomAlgoAPI_Circ2dBuilder::setTransversalLine(const std::shared_ptr<GeomAPI_Shape>& theEdge)
+{
+ if (theEdge->isEdge())
+ myTransversalLine = theEdge;
+}
+
void GeomAlgoAPI_Circ2dBuilder::addPassingPoint(const std::shared_ptr<GeomAPI_Pnt2d>& thePoint)
{
myPassingPoints.push_back(thePoint);
CircleBuilder aCircleBuilder(myPlane);
aCircleBuilder.setCenter(myCenter);
aCircleBuilder.setTangentCurves(myTangentShapes);
+ aCircleBuilder.setTransversalLine(myTransversalLine);
aCircleBuilder.setPassingPoints(myPassingPoints);
aCircleBuilder.setClosestPoint(myClosestPoint);
aCircleBuilder.setRadius(myRadius);
GEOMALGOAPI_EXPORT
void addTangentCurve(const std::shared_ptr<GeomAPI_Shape>& theEdge);
+ /// \brief Constrain circle to be orthogonal to the given edge
+ GEOMALGOAPI_EXPORT
+ void setTransversalLine(const std::shared_ptr<GeomAPI_Shape>& theEdge);
+
/// \brief Constrain circle to pass through the given point
GEOMALGOAPI_EXPORT
void addPassingPoint(const std::shared_ptr<GeomAPI_Pnt2d>& thePoint);
std::shared_ptr<GeomAPI_Pnt2d> myCenter;
std::vector< std::shared_ptr<GeomAPI_Pnt2d> > myPassingPoints;
std::vector< std::shared_ptr<GeomAPI_Shape> > myTangentShapes;
+ std::shared_ptr<GeomAPI_Shape> myTransversalLine;
std::shared_ptr<GeomAPI_Pnt2d> myClosestPoint;
double myRadius;
};
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<GeomAPI_Pnt2d>& theEnd,
+ bool theInversed)
+{
+ fillAttribute(SketchPlugin_MacroArc::ARC_TYPE_BY_TRANSVERSAL_LINE(), myarcType);
+ fillAttribute(theTransversalPoint, mytangentPoint);
+ fillAttribute(theEnd, myendPoint3);
+ fillAttribute(theInversed, myreversed);
+
+ execute();
+}
angle, SketchPlugin_MacroArc::ANGLE_ID(),
ModelAPI_AttributeDouble, /** Angle */)
-private:
-
/// Set by center and start, end point.
SKETCHAPI_EXPORT
void setByCenterStartEnd(double theCenterX, double theCenterY,
void setByTangent(const ModelHighAPI_RefAttr& theTangentPoint,
const std::shared_ptr<GeomAPI_Pnt2d>& 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<GeomAPI_Pnt2d>& theEnd,
+ bool theInversed);
};
/// Pointer on Arc object.
std::shared_ptr<SketchAPI_MacroArc> SketchAPI_Sketch::addArc(
const ModelHighAPI_RefAttr& theTangentPoint,
double theEndX, double theEndY,
- bool theInversed)
+ bool theInversed,
+ bool theTransversal)
{
std::shared_ptr<ModelAPI_Feature> 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_MacroArc> SketchAPI_Sketch::addArc(
const ModelHighAPI_RefAttr& theTangentPoint,
const std::shared_ptr<GeomAPI_Pnt2d>& theEnd,
- bool theInversed)
+ bool theInversed,
+ bool theTransversal)
{
std::shared_ptr<ModelAPI_Feature> 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_Arc> SketchAPI_Sketch::addArc(const ModelHighAPI_Selection & theExternal)
const std::shared_ptr<GeomAPI_Pnt2d>& theEnd,
const std::shared_ptr<GeomAPI_Pnt2d>& thePassed);
- /// Add arc
+ /// Add transversal/tangent arc
SKETCHAPI_EXPORT
std::shared_ptr<SketchAPI_MacroArc> 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<SketchAPI_MacroArc> addArc(
- const ModelHighAPI_RefAttr& theTangentPoint,
+ const ModelHighAPI_RefAttr& theConnectedPoint,
const std::shared_ptr<GeomAPI_Pnt2d>& theEnd,
- bool theInversed);
+ bool theInversed,
+ bool theTransversal = false);
/// Add arc
SKETCHAPI_EXPORT
TestCreateArcByCenterStartEnd.py
TestCreateArcByTangentEdge.py
TestCreateArcByThreePoints.py
+ TestCreateArcByTransversalLine.py
TestCreateArcChangeType.py
TestCreateCircleByCenterAndPassed.py
TestCreateCircleByThreePoints.py
#include "SketchPlugin_MacroArc.h"
#include "SketchPlugin_Arc.h"
+#include "SketchPlugin_ConstraintPerpendicular.h"
#include "SketchPlugin_ConstraintTangent.h"
#include "SketchPlugin_Sketch.h"
#include "SketchPlugin_Tools.h"
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;
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,
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<GeomDataAPI_Point2D>(aTangentAttr->attr());
- if (!aTangentPointAttr->isInitialized())
+ if (!aConnectionPointAttr->isInitialized())
return;
AttributePoint2DPtr anEndPointAttr =
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<GeomAPI_Shape> aTangentShape = aTangentFeature->lastResult()->shape();
+ FeaturePtr aConnectedFeature = ModelAPI_Feature::feature(aConnectionPointAttr->owner());
+ std::shared_ptr<GeomAPI_Shape> 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<GeomAPI_Circ2d> aCircle = aCircBuilder.circle();
if (!aCircle)
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()
{
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();
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",
return true;
}
+bool SketchPlugin_ArcTransversalPointValidator::isValid(
+ const AttributePtr& theAttribute,
+ const std::list<std::string>& /*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<ModelAPI_AttributeRefAttr>(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<ModelAPI_Feature>(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<std::string>& theArguments,
Events_InfoMessage& theError) const
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<std::string>& theArguments,
+ Events_InfoMessage& theError) const;
+};
+
+
/**\class SketchPlugin_SplitValidator
* \ingroup Validators
* \brief Validator for the entity of the following type:
--- /dev/null
+# 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())
#. 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
: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
""""""""""""""""""""""""
**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
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()
<validator id="SketchPlugin_ArcEndPointValidator" parameters="end_point_ref"/>
</sketch-2dpoint_selector>
</box>
+ <box id="by_transversal_line"
+ icon="icons/Sketch/arc_perp_32x32.png"
+ title="Perpendicular to line">
+ <sketch_shape_selector id="tangent_point"
+ label="Transversal point"
+ tooltip="Select point on line"
+ shape_types="vertex">
+ <validator id="SketchPlugin_ArcTransversalPoint"/>
+ </sketch_shape_selector>
+ <sketch-2dpoint_selector id="end_point_3"
+ reference_attribute="end_point_ref"
+ title="End point"
+ tooltip="End point"
+ accept_expressions="0"
+ enable_value="enable_by_preferences">
+ <validator id="SketchPlugin_ArcEndPointValidator" parameters="end_point_ref"/>
+ </sketch-2dpoint_selector>
+ </box>
</toolbox>
<labelvalue id="radius"
icon="icons/Sketch/radius.png"
void SketcherPrs_Perpendicular::drawLines(const Handle(Prs3d_Presentation)& thePrs,
Quantity_Color theColor) const
{
- Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup(thePrs);
-
- Handle(Graphic3d_AspectLine3d) aLineAspect =
- new Graphic3d_AspectLine3d(theColor, Aspect_TOL_SOLID, 2);
- aGroup->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);
+ }
}
-