#include <GeomLib_Tool.hxx>
#include <gp_Ax22d.hxx>
#include <gp_Elips2d.hxx>
+#include <IntAna2d_AnaIntersection.hxx>
+#include <IntAna2d_Conic.hxx>
#include <Precision.hxx>
#define MY_ELLIPSE implPtr<gp_Elips2d>()
return MY_ELLIPSE->MajorRadius();
}
+// theArrangePoint is used to select the nearest solution point if intersection is detected
template <typename EXTREMAPTR>
-static double extrema(EXTREMAPTR theAlgo,
+static double extrema(IntAna2d_AnaIntersection* theIntersectionAlgo,
+ EXTREMAPTR theExtremaAlgo,
+ GeomPnt2dPtr theArrangePoint,
GeomPnt2dPtr& thePoint1,
GeomPnt2dPtr& thePoint2)
{
double aDistance = Precision::Infinite();
- if (theAlgo->IsDone() && theAlgo->NbExt() > 0) {
- Extrema_POnCurv2d aP1, aP2;
- for (int i = 1; i <= theAlgo->NbExt(); ++i)
- if (theAlgo->SquareDistance(i) < aDistance) {
- aDistance = Sqrt(theAlgo->SquareDistance(i));
- theAlgo->Points(i, aP1, aP2);
+ if (theIntersectionAlgo->IsDone() && theIntersectionAlgo->NbPoints() > 0) {
+ gp_Pnt2d anArrangePoint(theArrangePoint->x(), theArrangePoint->y());
+ gp_Pnt2d anInterPnt = theIntersectionAlgo->Point(1).Value();
+ aDistance = anArrangePoint.SquareDistance(anInterPnt);
+ // get solution nearest to theArrangePoint
+ for (int i = 2; i <= theIntersectionAlgo->NbPoints(); ++i) {
+ const IntAna2d_IntPoint& aPnt = theIntersectionAlgo->Point(i);
+ double aSqDist = aPnt.Value().SquareDistance(anArrangePoint);
+ if (aSqDist < aDistance) {
+ aDistance = aSqDist;
+ anInterPnt = aPnt.Value();
}
+ }
+ aDistance = 0.0; // curves are intersected
+ thePoint1 = GeomPnt2dPtr(new GeomAPI_Pnt2d(anInterPnt.X(), anInterPnt.Y()));
+ thePoint2 = GeomPnt2dPtr(new GeomAPI_Pnt2d(anInterPnt.X(), anInterPnt.Y()));
+ }
+ else if (theExtremaAlgo->IsDone() && theExtremaAlgo->NbExt() > 0) {
+ Extrema_POnCurv2d aP1, aP2;
+ for (int i = 1; i <= theExtremaAlgo->NbExt(); ++i) {
+ double aSqDist = theExtremaAlgo->SquareDistance(i);
+ if (aSqDist < aDistance) {
+ aDistance = aSqDist;
+ theExtremaAlgo->Points(i, aP1, aP2);
+ }
+ }
aDistance = Sqrt(aDistance);
thePoint1 = GeomPnt2dPtr(new GeomAPI_Pnt2d(aP1.Value().X(), aP1.Value().Y()));
thePoint2 = GeomPnt2dPtr(new GeomAPI_Pnt2d(aP2.Value().X(), aP2.Value().Y()));
std::shared_ptr<GeomAPI_Pnt2d>& thePointOnMe,
std::shared_ptr<GeomAPI_Pnt2d>& thePointOnLine)
{
+ IntAna2d_AnaIntersection anInter(theLine->impl<gp_Lin2d>(), IntAna2d_Conic(*MY_ELLIPSE));
Extrema_ExtElC2d anExtema(theLine->impl<gp_Lin2d>(), *MY_ELLIPSE);
- return extrema(&anExtema, thePointOnLine, thePointOnMe);
+ return extrema(&anInter, &anExtema, theLine->location(), thePointOnLine, thePointOnMe);
}
double GeomAPI_Ellipse2d::distance(const std::shared_ptr<GeomAPI_Circ2d>& theCircle,
std::shared_ptr<GeomAPI_Pnt2d>& thePointOnMe,
std::shared_ptr<GeomAPI_Pnt2d>& thePointOnCircle)
{
+ IntAna2d_AnaIntersection anInter(theCircle->impl<gp_Circ2d>(), IntAna2d_Conic(*MY_ELLIPSE));
Extrema_ExtElC2d anExtema(theCircle->impl<gp_Circ2d>(), *MY_ELLIPSE);
- return extrema(&anExtema, thePointOnCircle, thePointOnMe);
+ GeomPnt2dPtr aCircleStart;
+ theCircle->D0(0.0, aCircleStart);
+ return extrema(&anInter, &anExtema, aCircleStart, thePointOnCircle, thePointOnMe);
}
double GeomAPI_Ellipse2d::distance(const std::shared_ptr<GeomAPI_Ellipse2d>& theEllipse,
Handle(Geom2d_Ellipse) anEllipse1 = new Geom2d_Ellipse(theEllipse->impl<gp_Elips2d>());
Handle(Geom2d_Ellipse) anEllipse2 = new Geom2d_Ellipse(*MY_ELLIPSE);
+ IntAna2d_AnaIntersection anInter(theEllipse->impl<gp_Elips2d>(), IntAna2d_Conic(*MY_ELLIPSE));
Extrema_ExtCC2d* anExtema =
new Extrema_ExtCC2d(Geom2dAdaptor_Curve(anEllipse1), Geom2dAdaptor_Curve(anEllipse2));
- double aDistance = extrema(anExtema, thePointOnEllipse, thePointOnMe);
+ double aDistance = extrema(&anInter, anExtema, theEllipse->firstFocus(), thePointOnEllipse, thePointOnMe);
delete anExtema;
return aDistance;
}
#include <SketchPlugin_Line.h>
#include <SketchPlugin_Circle.h>
#include <SketchPlugin_Ellipse.h>
+#include <SketchPlugin_EllipticArc.h>
#include <SketchPlugin_Point.h>
#include <SketchAPI_Arc.h>
#include <SketchAPI_Circle.h>
#include <SketchAPI_Ellipse.h>
+#include <SketchAPI_EllipticArc.h>
#include <SketchAPI_Line.h>
#include <SketchAPI_Point.h>
anEntity.reset(new SketchAPI_Arc(aProjectedFeature));
else if (aProjectedFeature->getKind() == SketchPlugin_Ellipse::ID())
anEntity.reset(new SketchAPI_Ellipse(aProjectedFeature));
+ else if (aProjectedFeature->getKind() == SketchPlugin_EllipticArc::ID())
+ anEntity.reset(new SketchAPI_EllipticArc(aProjectedFeature));
else if (aProjectedFeature->getKind() == SketchPlugin_Point::ID())
anEntity.reset(new SketchAPI_Point(aProjectedFeature));
TestConstraintLength.py
TestConstraintMiddlePoint.py
TestConstraintMiddlePointOnArc.py
+ TestConstraintMiddlePointOnEllipticArc.py
TestConstraintParallel.py
TestConstraintPerpendicular.py
TestConstraintPerpendicularArcLine.py
+ TestConstraintPerpendicularEllipseLine.py
TestConstraintRadius.py
TestConstraintRadiusFailure.py
TestConstraintTangent.py
TestConstraintTangentEllipse.py
+ TestConstraintTangentEllipticArc.py
TestConstraintVertical.py
TestCreateArcByCenterStartEnd.py
TestCreateArcByTangentEdge.py
TestPresentation.py
TestProjection.py
TestProjectionEllipse.py
+ TestProjectionEllipticArc.py
TestProjectionIntoResult.py
TestProjectionUpdate.py
TestRectangle.py
TestSketchPointLine.py
TestSnowflake.py
TestSplit.py
+ TestSplitEllipse.py
TestSplitLine.py
TestSplitPreview.py
TestTrimArc01.py
TestTrimCircle04.py
TestTrimCircle05.py
TestTrimCircleAndArc01.py
+ TestTrimEllipse.py
TestTrimLine01.py
TestTrimLine02.py
TestTrimLine03.py
--- /dev/null
+# 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
+#
+
+"""
+ Test middle point on an elliptic arc
+"""
+
+import unittest
+import math
+
+from salome.shaper import model
+from GeomAPI import *
+from SketchAPI import *
+
+__updated__ = "2019-10-02"
+
+class TestMiddlePointOnEllipticArc(unittest.TestCase):
+ def setUp(self):
+ model.begin()
+ self.myTestPassed = True
+ self.myDocument = model.moduleDocument()
+ self.mySketch = model.addSketch(self.myDocument, model.defaultPlane("XOY"))
+ self.myArc = self.mySketch.addEllipticArc(30, 20, 50, 30, 45, 40, 5, 6.11485435, False)
+ self.myLine = self.mySketch.addLine(10, 40, 40, 80)
+ self.myDOF = 11
+ model.do()
+ self.checkDOF()
+
+ def tearDown(self):
+ if self.myTestPassed:
+ self.assertArc(self.myArc)
+ self.checkMiddlePoint(self.myLine.startPoint(), self.myArc)
+ self.checkDOF()
+ model.end()
+
+ def checkDOF(self):
+ self.assertEqual(model.dof(self.mySketch), self.myDOF)
+
+ def toPeriod(self, theValue):
+ while theValue < -math.pi:
+ theValue += 2.0 * math.pi
+ while theValue >= math.pi:
+ theValue -= 2.0 * math.pi
+ return theValue
+
+ def checkMiddlePoint(self, thePoint, theArc):
+ self.myTestPassed = False
+ anEllipse = theArc.defaultResult().shape().edge().ellipse()
+ # check point on ellipse
+ self.checkPointOnEllipse(thePoint, anEllipse)
+ # check angles
+ TOLERANCE = 1.e-5
+ startAngle = 0; startPoint = GeomAPI_Pnt(theArc.startPoint().x(), theArc.startPoint().y(), 0)
+ startAngle = anEllipse.parameter(startPoint, TOLERANCE, startAngle)
+ endAngle = 0; endPoint = GeomAPI_Pnt(theArc.endPoint().x(), theArc.endPoint().y(), 0)
+ endAngle = anEllipse.parameter(endPoint, TOLERANCE, endAngle)
+ midAngle = 0; midPoint = GeomAPI_Pnt(thePoint.x(), thePoint.y(), 0)
+ midAngle = anEllipse.parameter(midPoint, TOLERANCE, midAngle)
+ diffMS = self.toPeriod(midAngle - startAngle)
+ diffEM = self.toPeriod(endAngle - midAngle)
+ self.assertAlmostEqual(diffMS, diffEM)
+ self.assertEqual(diffMS < 0, theArc.reversed().value())
+ self.myTestPassed = True
+
+ def checkPointOnEllipse(self, theCoordinates, theEllipse):
+ point = GeomAPI_Pnt2d(theCoordinates.x(), theCoordinates.y())
+ firstFocus2d = GeomAPI_Pnt2d(theEllipse.firstFocus().x(), theEllipse.firstFocus().y())
+ distPF1 = model.distancePointPoint(firstFocus2d, point)
+ secondFocus2d = GeomAPI_Pnt2d(theEllipse.secondFocus().x(), theEllipse.secondFocus().y())
+ distPF2 = model.distancePointPoint(secondFocus2d, point)
+ if issubclass(type(theEllipse), SketchAPI_Ellipse):
+ majorRad = theEllipse.majorRadius().value()
+ else:
+ majorRad = theEllipse.majorRadius()
+ NB_DIGITS = 7 - math.floor(math.log10(majorRad))
+ self.assertAlmostEqual(distPF1 + distPF2, 2.0 * majorRad, NB_DIGITS)
+
+ def assertArc(self, theArc):
+ anEllipse = theArc.defaultResult().shape().edge().ellipse()
+ self.checkPointOnEllipse(theArc.startPoint(), anEllipse)
+ self.checkPointOnEllipse(theArc.endPoint(), anEllipse)
+
+ def rotatePoint(self, thePoint, theCenter, theAngle):
+ dirX = thePoint.x() - theCenter.x()
+ dirY = thePoint.y() - theCenter.y()
+ newX = theCenter.x() + dirX * math.cos(theAngle) - dirY * math.sin(theAngle)
+ newY = theCenter.y() + dirX * math.sin(theAngle) + dirY * math.cos(theAngle)
+ self.mySketch.move(thePoint, newX, newY)
+
+ def moveArc(self):
+ ANGLE_STEP = math.pi * 5.0 / 180.0
+ ANGLE_THRESHOLD = math.pi / 2.0
+ # move start point of the arc clockwise
+ fullAngle = 0.0
+ while fullAngle < ANGLE_THRESHOLD:
+ self.rotatePoint(self.myArc.startPoint(), self.myArc.center(), -ANGLE_STEP)
+ model.do()
+ self.checkMiddlePoint(self.myLine.startPoint(), self.myArc)
+ fullAngle += ANGLE_STEP
+ # move start point of the arc conterclockwise
+ fullAngle = 0.0
+ while fullAngle < ANGLE_THRESHOLD:
+ self.rotatePoint(self.myArc.startPoint(), self.myArc.center(), ANGLE_STEP)
+ model.do()
+ self.checkMiddlePoint(self.myLine.startPoint(), self.myArc)
+ fullAngle += ANGLE_STEP
+
+ # move end point of the arc clockwise
+ fullAngle = 0.0
+ while fullAngle < ANGLE_THRESHOLD:
+ self.rotatePoint(self.myArc.endPoint(), self.myArc.center(), -ANGLE_STEP)
+ model.do()
+ self.checkMiddlePoint(self.myLine.startPoint(), self.myArc)
+ fullAngle += ANGLE_STEP
+ # move end point of the arc conterclockwise
+ fullAngle = 0.0
+ while fullAngle < ANGLE_THRESHOLD:
+ self.rotatePoint(self.myArc.endPoint(), self.myArc.center(), ANGLE_STEP)
+ model.do()
+ self.checkMiddlePoint(self.myLine.startPoint(), self.myArc)
+ fullAngle += ANGLE_STEP
+
+ # move center of the arc
+ DELTA = [0.1, 0.1]
+ for i in range(0, 40):
+ if i == 10 or i == 30:
+ DELTA = [-DELTA[0], -DELTA[1]]
+ self.mySketch.move(self.myArc.center(), self.myArc.center().x() + DELTA[0], self.myArc.center().y() + DELTA[1])
+ model.do()
+ self.checkMiddlePoint(self.myLine.startPoint(), self.myArc)
+ DELTA = [-0.1, 0.1]
+ for i in range(0, 40):
+ if i == 10 or i == 30:
+ DELTA = [-DELTA[0], -DELTA[1]]
+ self.mySketch.move(self.myArc.center(), self.myArc.center().x() + DELTA[0], self.myArc.center().y() + DELTA[1])
+ model.do()
+ self.checkMiddlePoint(self.myLine.startPoint(), self.myArc)
+
+ def moveLine(self):
+ DELTA = [0.1, 0.0]
+ for i in range(0, 40):
+ if i == 10 or i == 30:
+ DELTA = [-DELTA[0], -DELTA[1]]
+ self.mySketch.move(self.myLine.startPoint(), self.myLine.startPoint().x() + DELTA[0], self.myLine.startPoint().y() + DELTA[1])
+ model.do()
+ self.checkMiddlePoint(self.myLine.startPoint(), self.myArc)
+ DELTA = [0.0, 0.1]
+ for i in range(0, 40):
+ if i == 10 or i == 30:
+ DELTA = [-DELTA[0], -DELTA[1]]
+ self.mySketch.move(self.myLine.startPoint(), self.myLine.startPoint().x() + DELTA[0], self.myLine.startPoint().y() + DELTA[1])
+ model.do()
+ self.checkMiddlePoint(self.myLine.startPoint(), self.myArc)
+
+
+ def test_middle_point_PA(self):
+ """ Test 1. Set middle point constraint (point is the first argument)
+ """
+ self.mySketch.setMiddlePoint(self.myLine.startPoint(), self.myArc.results()[-1])
+ self.myDOF -= 2
+ model.do()
+
+ def test_middle_point_AP(self):
+ """ Test 2. Set middle point constraint (point is the second argument)
+ """
+ self.mySketch.setMiddlePoint(self.myArc.results()[-1], self.myLine.startPoint())
+ self.myDOF -= 2
+ model.do()
+
+ def test_coincident_middle_point(self):
+ """ Test 3. Set middle point constraint for the point already coincident with the arc
+ """
+ self.mySketch.setCoincident(self.myLine.startPoint(), self.myArc.results()[-1])
+ model.do()
+ self.mySketch.setMiddlePoint(self.myLine.startPoint(), self.myArc.results()[-1])
+ self.myDOF -= 2
+ model.do()
+
+ def test_middle_point_coincident(self):
+ """ Test 4. Set concidence of the point and the arc which are already constrained with middle point
+ """
+ self.mySketch.setMiddlePoint(self.myLine.startPoint(), self.myArc.results()[-1])
+ model.do()
+ self.mySketch.setCoincident(self.myLine.startPoint(), self.myArc.results()[-1])
+ self.myDOF -= 2
+ model.do()
+
+ @unittest.expectedFailure
+ def test_middle_point_limitation(self):
+ """ Test 5. Check middle point fails if the point's coordinates are equal to the arc start point
+ """
+ self.myLine.startPoint().setValue(self.myArc.startPoint().pnt())
+ model.do()
+ coincidence = self.mySketch.setCoincident(self.myLine.startPoint(), self.myArc.results()[-1])
+ self.mySketch.setMiddlePoint(self.myLine.startPoint(), self.myArc.results()[-1])
+ self.myDOF -= 2
+ model.do()
+ # this check will fail due to the limitation of PlanGCS
+ self.checkMiddlePoint(self.myLine.startPoint(), self.myArc)
+
+ def test_middle_point_equal_start(self):
+ """ Test 6. Check middle point does not fail if the point's coordinates are equal to the arc end point
+ """
+ self.myLine.startPoint().setValue(self.myArc.endPoint().pnt())
+ model.do()
+ coincidence = self.mySketch.setCoincident(self.myLine.startPoint(), self.myArc.results()[-1])
+ self.mySketch.setMiddlePoint(self.myLine.startPoint(), self.myArc.results()[-1])
+ self.myDOF -= 2
+ model.do()
+
+ def test_middle_point_move_arc(self):
+ """ Test 7. Set middle point constraint and move arc
+ """
+ self.mySketch.setMiddlePoint(self.myLine.startPoint(), self.myArc.results()[-1])
+ self.myDOF -= 2
+ model.do()
+ self.checkMiddlePoint(self.myLine.startPoint(), self.myArc)
+ self.moveArc()
+
+ def test_middle_point_coincidence_move_arc(self):
+ """ Test 8. Set coincidence and middle point constraint and move arc
+ """
+ self.mySketch.setCoincident(self.myLine.startPoint(), self.myArc.results()[-1])
+ model.do()
+ self.mySketch.setMiddlePoint(self.myLine.startPoint(), self.myArc.results()[-1])
+ self.myDOF -= 2
+ model.do()
+ self.checkMiddlePoint(self.myLine.startPoint(), self.myArc)
+ self.moveArc()
+
+ def test_middle_point_move_line(self):
+ """ Test 9. Set middle point constraint and move line
+ """
+ self.mySketch.setMiddlePoint(self.myLine.startPoint(), self.myArc.results()[-1])
+ self.myDOF -= 2
+ model.do()
+ self.checkMiddlePoint(self.myLine.startPoint(), self.myArc)
+ self.moveLine()
+
+ def test_middle_point_coincidence_move_line(self):
+ """ Test 10. Set coincidence and middle point constraint and move line
+ """
+ self.mySketch.setCoincident(self.myLine.startPoint(), self.myArc.results()[-1])
+ model.do()
+ self.mySketch.setMiddlePoint(self.myLine.startPoint(), self.myArc.results()[-1])
+ self.myDOF -= 2
+ model.do()
+ self.checkMiddlePoint(self.myLine.startPoint(), self.myArc)
+ self.moveLine()
+
+ def test_remove_middle_point(self):
+ """ Test 11. Set and then remove middle point constraint
+ """
+ mp = self.mySketch.setMiddlePoint(self.myLine.startPoint(), self.myArc.results()[-1])
+ self.myDOF -= 2
+ model.do()
+ self.assertArc(self.myArc)
+ self.checkMiddlePoint(self.myLine.startPoint(), self.myArc)
+ self.checkDOF()
+ # remove middle point
+ self.myDocument.removeFeature(mp.feature())
+ self.myDOF += 2
+ model.do()
+ self.checkDOF()
+ # set flag False to avoid checking middle point constraint in tearDown() method
+ self.myTestPassed = False
+
+
+if __name__ == "__main__":
+ test_program = unittest.main(exit=False)
+ assert test_program.result.wasSuccessful(), "Test failed"
+ assert(model.checkPythonDump())
--- /dev/null
+# 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
+import math
+from GeomAPI import *
+
+TOLERANCE = 1.e-7
+
+def checkPerpendicular(theLine, theEllipse):
+ focus1 = theEllipse.firstFocus()
+ focus2 = theEllipse.secondFocus()
+ pf1 = theLine.project(focus1)
+ pf2 = theLine.project(focus2)
+ dist1 = focus1.distance(pf1)
+ dist2 = focus2.distance(pf2)
+ if math.fabs(dist1 - dist2) < TOLERANCE:
+ # no need further check, the line is equal to one of the ellipses axis
+ return
+ x = (dist2 * pf1.x() - dist1 * pf2.x()) / (dist2 - dist1)
+ y = (dist2 * pf1.y() - dist1 * pf2.y()) / (dist2 - dist1)
+ pnt = GeomAPI_Pnt(x, y, 0)
+ # check point on ellipse
+ majorRad = theEllipse.majorRadius()
+ assert(math.fabs(pnt.distance(focus1) + pnt.distance(focus2) - 2.0 * majorRad) < TOLERANCE * majorRad)
+
+
+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"))
+SketchLine_1 = Sketch_1.addLine(-40, 10, -20, 30)
+SketchArc_1 = Sketch_1.addArc(25, -30, 42, -34, 13, -17.31142245955048, False)
+SketchEllipse_1 = Sketch_1.addEllipse(-50, 0, -30, -5, 15)
+[SketchPoint_1, SketchPoint_2, SketchPoint_3, SketchPoint_4, SketchPoint_5, SketchPoint_6, SketchPoint_7, SketchLine_2, SketchLine_3] = SketchEllipse_1.construction(center = "aux", firstFocus = "aux", secondFocus = "aux", majorAxisStart = "aux", majorAxisEnd = "aux", minorAxisStart = "aux", minorAxisEnd = "aux", majorAxis = "aux", minorAxis = "aux")
+SketchEllipticArc_1 = Sketch_1.addEllipticArc(5, 30, -5, 45, -7, 47, 15, 33.68010611, False)
+[SketchPoint_8, SketchPoint_9, SketchPoint_10, SketchPoint_11, SketchPoint_12, SketchPoint_13, SketchPoint_14, SketchLine_4, SketchLine_5] = SketchEllipticArc_1.construction(center = "aux", firstFocus = "aux", secondFocus = "aux", majorAxisStart = "aux", majorAxisEnd = "aux", minorAxisStart = "aux", minorAxisEnd = "aux", majorAxis = "aux", minorAxis = "aux")
+model.do()
+
+# check error on perpendicularity of arc and elliptic arc
+SketchConstraintPerpendicular_1 = Sketch_1.setPerpendicular(SketchArc_1.results()[1], SketchEllipticArc_1.result())
+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(SketchEllipticArc_1.result(), SketchLine_1.result())
+SketchConstraintPerpendicular_3 = Sketch_1.setPerpendicular(SketchLine_1.result(), SketchEllipse_1.result())
+model.do()
+
+checkPerpendicular(SketchLine_1.defaultResult().shape().edge().line(), SketchEllipse_1.defaultResult().shape().edge().ellipse())
+checkPerpendicular(SketchLine_1.defaultResult().shape().edge().line(), SketchEllipticArc_1.defaultResult().shape().edge().ellipse())
+model.end()
+
+assert(model.checkPythonDump())
--- /dev/null
+# 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
+#
+
+"""
+ Test constraint "Tangent" applied to elliptic arc and another entity
+"""
+
+import unittest
+import math
+
+from salome.shaper import model
+
+from GeomAPI import *
+from SketchAPI import *
+
+__updated__ = "2019-10-04"
+
+class TestTangentEllipticArc(unittest.TestCase):
+ def setUp(self):
+ center = GeomAPI_Pnt2d(30., 20.)
+ axisEnd = GeomAPI_Pnt2d(50., 30.)
+ startPoint = GeomAPI_Pnt2d(45, 40)
+ endPoint = GeomAPI_Pnt2d(5, 6.11485435)
+
+ model.begin()
+ self.myDocument = model.moduleDocument()
+ self.mySketch = model.addSketch(self.myDocument, model.defaultPlane("XOY"))
+ macroEllipticArc = self.mySketch.addEllipticArc(center, axisEnd, startPoint, endPoint, False)
+ model.do()
+ self.myEllipticArc = SketchAPI_EllipticArc(model.lastSubFeature(self.mySketch, "SketchEllipticArc"))
+ self.myCenter = macroEllipticArc.center()
+ self.myFocus1 = macroEllipticArc.focus1()
+ self.myFocus2 = macroEllipticArc.focus2()
+ self.myMajorAxis = macroEllipticArc.majorAxis()
+ self.myMajorStart = macroEllipticArc.majorAxisStart()
+ self.myMajorEnd = macroEllipticArc.majorAxisEnd()
+ self.myMinorAxis = macroEllipticArc.minorAxis()
+ self.myMinorStart = macroEllipticArc.minorAxisStart()
+ self.myMinorEnd = macroEllipticArc.minorAxisEnd()
+
+ self.myDOF = 7
+ self.myNbPoints = 7
+ self.myNbLines = 2
+ self.myNbArcs = 0
+ self.myNbCircles = 0
+ self.myNbEllipses = 0
+ self.myNbEllipticArcs = 1
+ self.myNbInternals = 11
+ self.myNbCoincidence = 0
+ self.myNbTangency = 0
+
+ def tearDown(self):
+ model.end()
+ self.checkDOF()
+ self.assertPoints(self.myCenter.coordinates(), self.myEllipticArc.center())
+ self.assertPoints(self.myFocus1.coordinates(), self.myEllipticArc.firstFocus())
+ self.assertPoints(self.myFocus2.coordinates(), self.myEllipticArc.secondFocus())
+ self.assertPoints(self.myMajorStart.coordinates(), self.myEllipticArc.majorAxisNegative())
+ self.assertPoints(self.myMajorEnd.coordinates(), self.myEllipticArc.majorAxisPositive())
+ self.assertPoints(self.myMajorAxis.startPoint(), self.myEllipticArc.majorAxisNegative())
+ self.assertPoints(self.myMajorAxis.endPoint(), self.myEllipticArc.majorAxisPositive())
+ self.assertPoints(self.myMinorStart.coordinates(), self.myEllipticArc.minorAxisNegative())
+ self.assertPoints(self.myMinorEnd.coordinates(), self.myEllipticArc.minorAxisPositive())
+ self.assertPoints(self.myMinorAxis.startPoint(), self.myEllipticArc.minorAxisNegative())
+ self.assertPoints(self.myMinorAxis.endPoint(), self.myEllipticArc.minorAxisPositive())
+ model.testNbSubFeatures(self.mySketch, "SketchPoint", self.myNbPoints)
+ model.testNbSubFeatures(self.mySketch, "SketchLine", self.myNbLines)
+ model.testNbSubFeatures(self.mySketch, "SketchArc", self.myNbArcs)
+ model.testNbSubFeatures(self.mySketch, "SketchCircle", self.myNbCircles)
+ model.testNbSubFeatures(self.mySketch, "SketchEllipse", self.myNbEllipses)
+ model.testNbSubFeatures(self.mySketch, "SketchEllipticArc", self.myNbEllipticArcs)
+ model.testNbSubFeatures(self.mySketch, "SketchConstraintCoincidenceInternal", self.myNbInternals)
+ model.testNbSubFeatures(self.mySketch, "SketchConstraintCoincidence", self.myNbCoincidence)
+ model.testNbSubFeatures(self.mySketch, "SketchConstraintTangent", self.myNbTangency)
+
+
+ def checkDOF(self):
+ self.assertEqual(model.dof(self.mySketch), self.myDOF)
+
+ def assertTangentLineEllipse(self, theLine, theEllipticArc):
+ aLine = GeomAPI_Lin2d(theLine.startPoint().pnt(), theLine.endPoint().pnt())
+ projF1 = aLine.project(theEllipticArc.firstFocus().pnt())
+ projF2 = aLine.project(theEllipticArc.secondFocus().pnt())
+
+ distF1P1 = model.distancePointPoint(theEllipticArc.firstFocus(), projF1)
+ distF2P2 = model.distancePointPoint(theEllipticArc.secondFocus(), projF2)
+
+ tgPoint = GeomAPI_Pnt2d((projF1.x() * distF2P2 + projF2.x() * distF1P1) / (distF1P1 + distF2P2), (projF1.y() * distF2P2 + projF2.y() * distF1P1) / (distF1P1 + distF2P2))
+ distF1T = model.distancePointPoint(theEllipticArc.firstFocus(), tgPoint)
+ distF2T = model.distancePointPoint(theEllipticArc.secondFocus(), tgPoint)
+ NB_DIGITS = 7 - math.floor(math.log10(theEllipticArc.majorRadius().value()))
+ self.assertAlmostEqual(distF1T + distF2T, 2 * theEllipticArc.majorRadius().value(), NB_DIGITS)
+
+ def assertTangentCircleEllipse(self, theCircle, theEllipticArc):
+ axis = GeomAPI_Dir2d(theEllipticArc.firstFocus().x() - theEllipticArc.center().x(), theEllipticArc.firstFocus().y() - theEllipticArc.center().y())
+ anEllipticArc = GeomAPI_Ellipse2d(theEllipticArc.center().pnt(), axis, theEllipticArc.majorRadius().value(), theEllipticArc.minorRadius().value())
+ aCircle = GeomAPI_Circ2d(theCircle.center().pnt(), GeomAPI_Dir2d(1, 0), theCircle.radius().value())
+
+ pOnE = GeomAPI_Pnt2d(0, 0)
+ pOnC = GeomAPI_Pnt2d(0, 0)
+ anEllipticArc.distance(aCircle, pOnE, pOnC)
+ self.assertAlmostEqual(model.distancePointPoint(pOnE, theCircle.center()), theCircle.radius().value())
+
+ dist1 = model.distancePointPoint(pOnC, theEllipticArc.firstFocus())
+ dist2 = model.distancePointPoint(pOnC, theEllipticArc.secondFocus())
+ NB_DIGITS = 7 - math.floor(math.log10(theEllipticArc.majorRadius().value()))
+ self.assertAlmostEqual(dist1 + dist2, 2 * theEllipticArc.majorRadius().value(), NB_DIGITS)
+
+ def assertTangentEllipses(self, theEllipticArc1, theEllipticArc2):
+ axis1 = GeomAPI_Dir2d(theEllipticArc1.firstFocus().x() - theEllipticArc1.center().x(), theEllipticArc1.firstFocus().y() - theEllipticArc1.center().y())
+ anEllipticArc1 = GeomAPI_Ellipse2d(theEllipticArc1.center().pnt(), axis1, theEllipticArc1.majorRadius().value(), theEllipticArc1.minorRadius().value())
+ axis2 = GeomAPI_Dir2d(theEllipticArc2.firstFocus().x() - theEllipticArc2.center().x(), theEllipticArc2.firstFocus().y() - theEllipticArc2.center().y())
+ anEllipticArc2 = GeomAPI_Ellipse2d(theEllipticArc2.center().pnt(), axis2, theEllipticArc2.majorRadius().value(), theEllipticArc2.minorRadius().value())
+
+ p1 = GeomAPI_Pnt2d(0, 0)
+ p2 = GeomAPI_Pnt2d(0, 0)
+ anEllipticArc1.distance(anEllipticArc2, p1, p2)
+
+ dist1 = model.distancePointPoint(p2, theEllipticArc1.firstFocus())
+ dist2 = model.distancePointPoint(p2, theEllipticArc1.secondFocus())
+ NB_DIGITS = 7 - math.floor(math.log10(theEllipticArc1.majorRadius().value()))
+ self.assertAlmostEqual(dist1 + dist2, 2 * theEllipticArc1.majorRadius().value())
+
+ dist1 = model.distancePointPoint(p1, theEllipticArc2.firstFocus())
+ dist2 = model.distancePointPoint(p1, theEllipticArc2.secondFocus())
+ NB_DIGITS = 7 - math.floor(math.log10(theEllipticArc2.majorRadius().value()))
+ self.assertAlmostEqual(dist1 + dist2, 2 * theEllipticArc2.majorRadius().value(), NB_DIGITS)
+
+ def assertPoints(self, thePoint1, thePoint2):
+ self.assertAlmostEqual(thePoint1.x(), thePoint2.x(), 6)
+ self.assertAlmostEqual(thePoint1.y(), thePoint2.y(), 6)
+
+
+ def test_line_tangent(self):
+ """ Test 1. Set tangency between elliptic arc and a line
+ """
+ aLine = self.mySketch.addLine(10, -10, 90, 40)
+ self.myNbLines += 1
+ self.myDOF += 4
+ model.do()
+
+ self.mySketch.setTangent(self.myEllipticArc.result(), aLine.result())
+ self.myNbTangency += 1
+ self.myDOF -= 1
+ model.do()
+
+ self.assertTangentLineEllipse(aLine, self.myEllipticArc)
+
+
+ def test_line_coincident_then_tangent(self):
+ """ Test 2. Set tangency between elliptic arc and a line, if the extremity of the line is coincident with the elliptic arc
+ """
+ aLine = self.mySketch.addLine(10, -10, 90, 40)
+ self.mySketch.setCoincident(aLine.endPoint(), self.myEllipticArc.result())
+ self.myNbLines += 1
+ self.myNbCoincidence += 1
+ self.myDOF += 3
+ model.do()
+
+ self.mySketch.setTangent(self.myEllipticArc.result(), aLine.result())
+ self.myNbTangency += 1
+ self.myDOF -= 1
+ model.do()
+
+ self.assertTangentLineEllipse(aLine, self.myEllipticArc)
+
+
+ def test_line_tangent_then_coincident(self):
+ """ Test 3. Set tangency between elliptic arc and a line, after that apply coincidence of extremity of the line and the elliptic arc's curve
+ """
+ aLine = self.mySketch.addLine(10, -10, 90, 40)
+ self.myNbLines += 1
+ self.myDOF += 4
+ model.do()
+
+ self.mySketch.setTangent(self.myEllipticArc.result(), aLine.result())
+ self.myNbTangency += 1
+ self.myDOF -= 1
+ model.do()
+
+ self.mySketch.setCoincident(aLine.startPoint(), self.myEllipticArc.result())
+ self.myNbCoincidence += 1
+ self.myDOF -= 1
+ model.do()
+
+ self.assertTangentLineEllipse(aLine, self.myEllipticArc)
+
+
+ def test_line_tangent_then_remove_coincidence(self):
+ """ Test 4. Set tangency between elliptic arc and a line, which have a coincident point, then remove this coincidence
+ """
+ aLine = self.mySketch.addLine(10, -10, 90, 40)
+ aCoincidence = self.mySketch.setCoincident(aLine.endPoint(), self.myEllipticArc.result())
+ self.myNbLines += 1
+ self.myNbCoincidence += 1
+ self.myDOF += 3
+ model.do()
+
+ self.mySketch.setTangent(self.myEllipticArc.result(), aLine.result())
+ self.myNbTangency += 1
+ self.myDOF -= 1
+ model.do()
+
+ self.myDocument.removeFeature(aCoincidence.feature())
+ self.myNbCoincidence -= 1
+ self.myDOF += 1
+ model.do()
+
+ self.assertTangentLineEllipse(aLine, self.myEllipticArc)
+
+
+ def test_line_coincident_point_then_tangent(self):
+ """ Test 5. Set tangency between elliptic arc and a line, if the extremity of the line is coincident with the start point of elliptic arc
+ """
+ aLine = self.mySketch.addLine(10, -10, 90, 40)
+ self.mySketch.setCoincident(aLine.endPoint(), self.myEllipticArc.startPoint())
+ self.myNbLines += 1
+ self.myNbCoincidence += 1
+ self.myDOF += 2
+ model.do()
+
+ self.mySketch.setTangent(self.myEllipticArc.result(), aLine.result())
+ self.myNbTangency += 1
+ self.myDOF -= 1
+ model.do()
+
+ self.assertTangentLineEllipse(aLine, self.myEllipticArc)
+
+
+ def test_line_tangent_then_coincident_point(self):
+ """ Test 6. Set tangency between elliptic arc and a line, after that apply coincidence of extremities of the line and the elliptic arc
+ """
+ aLine = self.mySketch.addLine(10, -10, 90, 40)
+ self.myNbLines += 1
+ self.myDOF += 4
+ model.do()
+
+ self.mySketch.setTangent(self.myEllipticArc.result(), aLine.result())
+ self.myNbTangency += 1
+ self.myDOF -= 1
+ model.do()
+
+ self.assertTangentLineEllipse(aLine, self.myEllipticArc)
+
+ self.mySketch.setCoincident(aLine.startPoint(), self.myEllipticArc.startPoint())
+ self.myNbCoincidence += 1
+ self.myDOF -= 2
+ model.do()
+
+ self.assertTangentLineEllipse(aLine, self.myEllipticArc)
+
+
+ def test_line_tangent_then_remove_coincidence_on_extremity(self):
+ """ Test 7. Set tangency between elliptic arc and a line, which have a coincident boundary point, then remove this coincidence
+ """
+ aLine = self.mySketch.addLine(10, -10, 90, 40)
+ aCoincidence = self.mySketch.setCoincident(aLine.endPoint(), self.myEllipticArc.endPoint())
+ self.myNbLines += 1
+ self.myNbCoincidence += 1
+ self.myDOF += 2
+ model.do()
+
+ self.mySketch.setTangent(self.myEllipticArc.result(), aLine.result())
+ self.myNbTangency += 1
+ self.myDOF -= 1
+ model.do()
+
+ self.myDocument.removeFeature(aCoincidence.feature())
+ self.myNbCoincidence -= 1
+ self.myDOF += 2
+ model.do()
+
+ self.assertTangentLineEllipse(aLine, self.myEllipticArc)
+
+
+ def test_circle_tangent(self):
+ """ Test 8. Set tangency between elliptic arc and a circle
+ """
+ aCircle = self.mySketch.addCircle(30, 10, 20)
+ self.myNbCircles += 1
+ self.myDOF += 3
+ model.do()
+
+ self.mySketch.setTangent(self.myEllipticArc.result(), aCircle.defaultResult())
+ self.myNbTangency += 1
+ self.myDOF -= 1
+ model.do()
+
+ self.assertTangentCircleEllipse(aCircle, self.myEllipticArc)
+
+
+ def test_circle_coincident_then_tangent(self):
+ """ Test 9. Set tangency between elliptic arc and a circle, if the circle is coincident with start point of elliptic arc's minor axis
+ """
+ aCircle = self.mySketch.addCircle(30, 10, 20)
+ self.mySketch.setCoincident(self.myEllipticArc.startPoint(), aCircle.defaultResult())
+ self.myNbCircles += 1
+ self.myNbCoincidence += 1
+ self.myDOF += 2
+ model.do()
+
+ self.mySketch.setTangent(self.myEllipticArc.result(), aCircle.defaultResult())
+ self.myNbTangency += 1
+ self.myDOF -= 1
+ model.do()
+
+ self.assertTangentCircleEllipse(aCircle, self.myEllipticArc)
+ self.assertAlmostEqual(model.distancePointPoint(aCircle.center(), self.myEllipticArc.startPoint()), aCircle.radius().value())
+
+
+ def test_arc_tangent(self):
+ """ Test 10. Set tangency between elliptic arc and a circular arc
+ """
+ anArc = self.mySketch.addArc(30, -10, 40, -10, 20, -10, False)
+ self.myNbArcs += 1
+ self.myDOF += 5
+ model.do()
+
+ self.mySketch.setTangent(self.myEllipticArc.result(), anArc.results()[-1])
+ self.myNbTangency += 1
+ self.myDOF -= 1
+ model.do()
+
+ self.assertTangentCircleEllipse(anArc, self.myEllipticArc)
+
+
+ def test_arc_coincident_then_tangent(self):
+ """ Test 11. Set tangency between elliptic arc and an arc, if the extremities of the arcs are coincident
+ """
+ anArc = self.mySketch.addArc(30, -10, 40, -10, 20, -10, False)
+ self.mySketch.setCoincident(anArc.endPoint(), self.myEllipticArc.startPoint())
+ self.myNbArcs += 1
+ self.myNbCoincidence += 1
+ self.myDOF += 3
+ model.do()
+
+ self.mySketch.setTangent(self.myEllipticArc.result(), anArc.results()[-1])
+ self.myNbTangency += 1
+ self.myDOF -= 1
+ model.do()
+
+ self.assertTangentCircleEllipse(anArc, self.myEllipticArc)
+
+
+ def test_arc_tangent_then_coincident(self):
+ """ Test 12. Set tangency between elliptic arc and an arc, after that apply coincidence of extremities of the arcs
+ """
+ anArc = self.mySketch.addArc(30, -10, 40, -10, 20, -10, False)
+ self.myNbArcs += 1
+ self.myDOF += 5
+ model.do()
+
+ self.mySketch.setTangent(self.myEllipticArc.result(), anArc.results()[-1])
+ self.myNbTangency += 1
+ self.myDOF -= 1
+ model.do()
+
+ self.mySketch.setCoincident(anArc.startPoint(), self.myEllipticArc.startPoint())
+ self.myNbCoincidence += 1
+ self.myDOF -= 2
+ model.do()
+
+ self.assertTangentCircleEllipse(anArc, self.myEllipticArc)
+
+
+ def test_arc_tangent_then_remove_coincidence(self):
+ """ Test 13. Set tangency between elliptic arc and an arc, which have a coincident point, then remove this coincidence
+ """
+ anArc = self.mySketch.addArc(30, -10, 40, -10, 20, -10, False)
+ aCoincidence = self.mySketch.setCoincident(anArc.endPoint(), self.myEllipticArc.endPoint())
+ self.myNbArcs += 1
+ self.myNbCoincidence += 1
+ self.myDOF += 4
+ model.do()
+
+ self.mySketch.setTangent(self.myEllipticArc.result(), anArc.results()[-1])
+ self.myNbTangency += 1
+ self.myDOF -= 1
+ model.do()
+
+ self.myDocument.removeFeature(aCoincidence.feature())
+ self.myNbCoincidence -= 1
+ self.myDOF += 1
+ model.do()
+
+ self.assertTangentCircleEllipse(anArc, self.myEllipticArc)
+
+
+ def test_ellipse_tangent(self):
+ """ Test 14. Set tangency between ellipse and elliptic arc
+ """
+ anEllipse = self.mySketch.addEllipse(-30, 10, -10, 0, 20)
+ self.myNbEllipses += 1
+ self.myDOF += 5
+ model.do()
+
+ self.mySketch.setTangent(self.myEllipticArc.result(), anEllipse.result())
+ self.myNbTangency += 1
+ self.myDOF -= 1
+ model.do()
+
+ self.assertTangentEllipses(anEllipse, self.myEllipticArc)
+
+
+ def test_elliptic_arcs_tangent(self):
+ """ Test 15. Set tangency between two elliptic arcs
+ """
+ anEllipticArc = self.mySketch.addEllipticArc(35, 20, 60, 30, 40, 40, 20, -0.4890968089561491, True)
+ self.myNbEllipticArcs += 1
+ self.myDOF += 7
+ model.do()
+
+ self.mySketch.setTangent(self.myEllipticArc.result(), anEllipticArc.result())
+ self.myNbTangency += 1
+ self.myDOF -= 1
+ model.do()
+
+ self.assertTangentEllipses(anEllipticArc, self.myEllipticArc)
+
+
+ def test_elliptic_arcs_coincident_then_tangent(self):
+ """ Test 16. Set tangency between two elliptic arcs, if their extremities are coincident
+ """
+ anEllipticArc = self.mySketch.addEllipticArc(35, 20, 60, 30, 40, 40, 20, -0.4890968089561491, True)
+ self.mySketch.setCoincident(anEllipticArc.startPoint(), self.myEllipticArc.endPoint())
+ self.myNbEllipticArcs += 1
+ self.myNbCoincidence += 1
+ self.myDOF += 5
+ model.do()
+
+ self.mySketch.setTangent(self.myEllipticArc.result(), anEllipticArc.result())
+ self.myNbTangency += 1
+ self.myDOF -= 1
+ model.do()
+
+ self.assertTangentEllipses(anEllipticArc, self.myEllipticArc)
+
+
+
+if __name__ == "__main__":
+ test_program = unittest.main(exit=False)
+ assert test_program.result.wasSuccessful(), "Test failed"
assert(featureToPresentation(SketchMultiTranslation_1.feature()).getAISObject(None) is not None)
assert(featureToPresentation(SketchMultiRotation_1.feature()).getAISObject(None) is not None)
+model.end()
+
# Test presentation for Fillet on low-level
aSession = ModelAPI_Session.get()
aSketchFeature = featureToCompositeFeature(Sketch_1.feature())
assert(featureToPresentation(anArc).getAISObject(None) is not None)
aSession.finishOperation()
-model.end()
+# Test presentation for MacroEllipse on low-level
+aSession.startOperation()
+anEllipse = aSketchFeature.addFeature("SketchMacroEllipse")
+anEllipsePnt1 = geomDataAPI_Point2D(anEllipse.attribute("first_point"))
+anEllipsePnt2 = geomDataAPI_Point2D(anEllipse.attribute("second_point"))
+anEllipsePnt3 = geomDataAPI_Point2D(anEllipse.attribute("passed_point"))
+anEllipseType = anEllipse.string("ellipse_type")
+anEllipseType.setValue("by_center_axis_point")
+anEllipsePnt1.setValue(10, 0)
+anEllipsePnt2.setValue(-10, 0)
+anEllipsePnt3.setValue(0, 5)
+assert(featureToPresentation(anEllipse).getAISObject(None) is not None)
+aSession.finishOperation()
+
+# Test presentation for MacroEllipticArc on low-level
+aSession.startOperation()
+anEllipticArc = aSketchFeature.addFeature("SketchMacroEllipticArc")
+anEllipticArcPnt1 = geomDataAPI_Point2D(anEllipticArc.attribute("center"))
+anEllipticArcPnt2 = geomDataAPI_Point2D(anEllipticArc.attribute("major_axis_point"))
+anEllipticArcPnt3 = geomDataAPI_Point2D(anEllipticArc.attribute("start_point"))
+anEllipticArcPnt4 = geomDataAPI_Point2D(anEllipticArc.attribute("end_point"))
+anEllipticArcPnt1.setValue(0, 0)
+anEllipticArcPnt2.setValue(10, 0)
+anEllipticArcPnt3.setValue(0, 5)
+anEllipticArcPnt4.setValue(-10, 0)
+assert(featureToPresentation(anEllipticArc).getAISObject(None) is not None)
+aSession.finishOperation()
--- /dev/null
+# 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 SketchAPI import *
+
+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"))
+SketchProjection_1 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OY"), False)
+SketchLine_1 = SketchProjection_1.createdFeature()
+SketchLine_2 = Sketch_1.addLine(-17.32050807568878, -110, 0, -100)
+SketchLine_3 = Sketch_1.addLine(0, -100, 10, -117.3205080756888)
+SketchArc_1 = Sketch_1.addArc(0, -100, 10, -117.3205080756888, -17.32050807568878, -110, False)
+SketchConstraintRadius_1 = Sketch_1.setRadius(SketchArc_1.results()[1], 20)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchArc_1.center(), SketchLine_1.result())
+SketchConstraintDistance_1 = Sketch_1.setDistance(SketchArc_1.center(), SketchAPI_Line(SketchLine_1).startPoint(), 100, True)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchArc_1.center(), SketchLine_2.endPoint())
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchArc_1.center(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_2.startPoint(), SketchArc_1.endPoint())
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchArc_1.startPoint())
+SketchConstraintPerpendicular_1 = Sketch_1.setPerpendicular(SketchLine_2.result(), SketchLine_3.result())
+SketchConstraintAngle_1 = Sketch_1.setAngle(SketchLine_3.result(), SketchLine_1.result(), 150)
+model.do()
+Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "PartSet/XOZ"), model.selection("EDGE", "PartSet/OX"), 30)
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "Sketch_1")], model.selection(), model.selection("FACE", "Plane_1"), 0, model.selection(), 0)
+Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "Plane_1"))
+SketchProjection_2 = Sketch_2.addProjection(model.selection("EDGE", "[Extrusion_1_1/To_Face][Extrusion_1_1/Generated_Face&Sketch_1/SketchArc_1_2]"), True)
+SketchEllipticArc_1 = SketchProjection_2.createdFeature()
+SketchProjection_3 = Sketch_2.addProjection(model.selection("EDGE", "[Extrusion_1_1/From_Face][Extrusion_1_1/Generated_Face&Sketch_1/SketchArc_1_2]"), True)
+SketchEllipticArc_2 = SketchProjection_3.createdFeature()
+model.do()
+model.end()
+
+from GeomAPI import *
+
+ellipse1 = SketchEllipticArc_1.results()[-1].resultSubShapePair()[0].shape()
+assert(ellipse1.isEdge() and ellipse1.edge().isEllipse())
+ellipse2 = SketchEllipticArc_2.results()[-1].resultSubShapePair()[0].shape()
+assert(ellipse2.isEdge() and ellipse2.edge().isEllipse())
+
+assert(model.checkPythonDump())
--- /dev/null
+# 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
+from salome.shaper import geom
+import math
+
+from ModelAPI import *
+from SketchAPI import *
+
+CENTER = geom.Pnt2d(10, 10)
+MAJOR_RADIUS = 50
+MINOR_RADIUS = 30
+
+DOF = 10
+NB_LINES = 3
+NB_ELLIPSES = 1
+NB_ELLIPTIC_ARCS = 0
+NB_COINCIDENCES = 6
+
+TOLERANCE = 1.e-6
+
+def checkFeaturesQuantity(theSketch):
+ model.testNbSubFeatures(theSketch, "SketchLine", NB_LINES)
+ model.testNbSubFeatures(theSketch, "SketchEllipse", NB_ELLIPSES)
+ model.testNbSubFeatures(theSketch, "SketchEllipticArc", NB_ELLIPTIC_ARCS)
+ model.testNbSubFeatures(theSketch, "SketchConstraintCoincidence", NB_COINCIDENCES)
+ assert(model.dof(theSketch) == DOF)
+
+def checkEllipticArcs(theSketch):
+ for aSub in theSketch.features().list():
+ aFeature = ModelAPI_Feature.feature(aSub)
+ if aFeature is not None and aFeature.getKind() == "SketchEllipticArc":
+ assertEllipticArc(SketchAPI_EllipticArc(aFeature))
+
+def assertEllipticArc(theArc):
+ assertPoints(theArc.center(), CENTER)
+ assertPoints(theArc.majorAxisPositive(), geom.Pnt2d(CENTER.x() + MAJOR_RADIUS, CENTER.y()))
+ assertPoints(theArc.minorAxisPositive(), geom.Pnt2d(CENTER.x(), CENTER.y() + MINOR_RADIUS))
+
+def assertPoints(thePoint1, thePoint2):
+ assert(math.fabs(thePoint1.x() - thePoint2.x()) < TOLERANCE), "{} != {}".format(thePoint1.x(), thePoint2.x())
+ assert(math.fabs(thePoint1.y() - thePoint2.y()) < TOLERANCE), "{} != {}".format(thePoint1.y(), thePoint2.y())
+
+
+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"))
+SketchEllipse_1 = Sketch_1.addEllipse(CENTER.x(), CENTER.y(), CENTER.x() + math.sqrt(MAJOR_RADIUS**2 - MINOR_RADIUS**2), CENTER.y(), MINOR_RADIUS)
+SketchLine_1 = Sketch_1.addLine(-16.74176451428603, -15.34869012470842, -16.85909682653373, 35.30399198463829)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchEllipse_1.result())
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchEllipse_1.result())
+SketchLine_2 = Sketch_1.addLine(-16.85909682653373, 35.30399198463829, 20.9032928583277, -19.27802168426675)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchEllipse_1.result())
+SketchLine_3 = Sketch_1.addLine(34.69765676551338, 36.08465583643841, 35.0422024535432, -15.96612629290852)
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_3.startPoint(), SketchEllipse_1.result())
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchEllipse_1.result())
+model.do()
+
+checkFeaturesQuantity(Sketch_1)
+checkEllipticArcs(Sketch_1)
+
+# split the ellipse
+SketchSplit = Sketch_1.addSplit(SketchEllipse_1, geom.Pnt2d(CENTER.x() + MAJOR_RADIUS, CENTER.y()))
+model.do()
+NB_ELLIPSES -= 1
+NB_ELLIPTIC_ARCS += 2
+NB_COINCIDENCES += 4
+DOF += 3
+
+checkFeaturesQuantity(Sketch_1)
+checkEllipticArcs(Sketch_1)
+
+# split the middle arc of ellipse
+EllipticArc = SketchAPI_EllipticArc(model.lastSubFeature(Sketch_1, "SketchEllipticArc"))
+ANGLE = -math.pi/2 - math.pi/10
+SketchSplit = Sketch_1.addSplit(EllipticArc, geom.Pnt2d(CENTER.x() + MAJOR_RADIUS * math.cos(ANGLE), CENTER.y() + MINOR_RADIUS * math.sin(ANGLE)))
+model.do()
+NB_ELLIPTIC_ARCS += 2
+NB_COINCIDENCES += 4
+DOF += 8
+
+checkFeaturesQuantity(Sketch_1)
+checkEllipticArcs(Sketch_1)
+
+# try to split the boundary arc of ellipse,
+# it shoult fail, because there is no coincident points
+EllipticArc = SketchAPI_EllipticArc(model.lastSubFeature(Sketch_1, "SketchEllipticArc"))
+SketchSplit = Sketch_1.addSplit(EllipticArc, geom.Pnt2d(CENTER.x() - MAJOR_RADIUS, CENTER.y()))
+model.end()
+aValidators = ModelAPI_Session.get().validators()
+assert(not aValidators.validate(SketchSplit.feature()))
+
+# remove previous split and add coincidence
+model.undo()
+model.begin()
+Part_1_doc.removeFeature(SketchSplit.feature())
+model.do()
+Sketch_1.setCoincident(SketchLine_2.startPoint(), EllipticArc.result())
+model.do()
+NB_COINCIDENCES += 1
+DOF -= 1
+
+# split the boundary arc of ellipse
+SketchSplit = Sketch_1.addSplit(EllipticArc, geom.Pnt2d(CENTER.x() - MAJOR_RADIUS, CENTER.y()))
+model.do()
+NB_ELLIPTIC_ARCS += 1
+NB_COINCIDENCES += 2
+DOF += 4
+
+checkFeaturesQuantity(Sketch_1)
+checkEllipticArcs(Sketch_1)
+
+model.end()
+
+assert(model.checkPythonDump())
--- /dev/null
+# 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
+from salome.shaper import geom
+import math
+
+from ModelAPI import *
+from SketchAPI import *
+
+CENTER = geom.Pnt2d(10, 10)
+MAJOR_RADIUS = 50
+MINOR_RADIUS = 30
+
+DOF = 11
+NB_LINES = 3
+NB_ELLIPSES = 1
+NB_ELLIPTIC_ARCS = 0
+NB_COINCIDENCES = 5
+NB_EQUALS = 0
+
+TOLERANCE = 1.e-6
+
+def checkFeaturesQuantity(theSketch):
+ model.testNbSubFeatures(theSketch, "SketchLine", NB_LINES)
+ model.testNbSubFeatures(theSketch, "SketchEllipse", NB_ELLIPSES)
+ model.testNbSubFeatures(theSketch, "SketchEllipticArc", NB_ELLIPTIC_ARCS)
+ model.testNbSubFeatures(theSketch, "SketchConstraintCoincidence", NB_COINCIDENCES)
+ model.testNbSubFeatures(theSketch, "SketchConstraintEqual", NB_EQUALS)
+ assert(model.dof(theSketch) == DOF)
+
+def checkEllipticArcs(theSketch):
+ for aSub in theSketch.features().list():
+ aFeature = ModelAPI_Feature.feature(aSub)
+ if aFeature is not None and aFeature.getKind() == "SketchEllipticArc":
+ assertEllipticArc(SketchAPI_EllipticArc(aFeature))
+
+def assertEllipticArc(theArc):
+ assertPoints(theArc.center(), CENTER)
+ assertPoints(theArc.majorAxisPositive(), geom.Pnt2d(CENTER.x() + MAJOR_RADIUS, CENTER.y()))
+ assertPoints(theArc.minorAxisPositive(), geom.Pnt2d(CENTER.x(), CENTER.y() + MINOR_RADIUS))
+
+def assertPoints(thePoint1, thePoint2):
+ assert(math.fabs(thePoint1.x() - thePoint2.x()) < TOLERANCE), "{} != {}".format(thePoint1.x(), thePoint2.x())
+ assert(math.fabs(thePoint1.y() - thePoint2.y()) < TOLERANCE), "{} != {}".format(thePoint1.y(), thePoint2.y())
+
+
+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"))
+SketchEllipse_1 = Sketch_1.addEllipse(CENTER.x(), CENTER.y(), CENTER.x() + math.sqrt(MAJOR_RADIUS**2 - MINOR_RADIUS**2), CENTER.y(), MINOR_RADIUS)
+SketchLine_1 = Sketch_1.addLine(-16.74176451428603, -15.34869012470842, -16.85909682653373, 35.30399198463829)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchEllipse_1.result())
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchEllipse_1.result())
+SketchLine_2 = Sketch_1.addLine(-16.85909682653373, 35.30399198463829, 20.9032928583277, -19.27802168426675)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchEllipse_1.result())
+SketchLine_3 = Sketch_1.addLine(34.69765676551338, 36.08465583643841, 35.0422024535432, -17.96612629290852)
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_3.startPoint(), SketchEllipse_1.result())
+model.do()
+
+checkFeaturesQuantity(Sketch_1)
+checkEllipticArcs(Sketch_1)
+
+# trim the ellipse
+SketchSplit = Sketch_1.addTrim(SketchEllipse_1, geom.Pnt2d(CENTER.x() + MAJOR_RADIUS, CENTER.y()))
+model.do()
+NB_ELLIPSES -= 1
+NB_ELLIPTIC_ARCS += 1
+NB_COINCIDENCES += 1
+
+checkFeaturesQuantity(Sketch_1)
+checkEllipticArcs(Sketch_1)
+
+# trim the middle arc of ellipse
+EllipticArc = SketchAPI_EllipticArc(model.lastSubFeature(Sketch_1, "SketchEllipticArc"))
+ANGLE = -math.pi/2 - math.pi/10
+SketchSplit = Sketch_1.addTrim(EllipticArc, geom.Pnt2d(CENTER.x() + MAJOR_RADIUS * math.cos(ANGLE), CENTER.y() + MINOR_RADIUS * math.sin(ANGLE)))
+model.do()
+NB_ELLIPTIC_ARCS += 1
+NB_COINCIDENCES += 1
+NB_EQUALS += 1
+DOF += 1
+
+checkFeaturesQuantity(Sketch_1)
+checkEllipticArcs(Sketch_1)
+
+# trim the boundary arc of ellipse
+SketchSplit = Sketch_1.addTrim(EllipticArc, geom.Pnt2d(CENTER.x() - MAJOR_RADIUS, CENTER.y()))
+model.do()
+NB_COINCIDENCES -= 1
+DOF += 1
+
+checkFeaturesQuantity(Sketch_1)
+checkEllipticArcs(Sketch_1)
+
+model.end()
+
+assert(model.checkPythonDump())
/// \brief Update value
static bool updateValue(const double& theSource, double& theDest)
{
- static const double aTol = 1000. * tolerance;
+ static const double aTol = 1.e4 * tolerance;
bool isUpdated = fabs(theSource - theDest) > aTol;
if (isUpdated)
theDest = theSource;