1 # Copyright (C) 2019 CEA/DEN, EDF R&D
3 # This library is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU Lesser General Public
5 # License as published by the Free Software Foundation; either
6 # version 2.1 of the License, or (at your option) any later version.
8 # This library is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 # Lesser General Public License for more details.
13 # You should have received a copy of the GNU Lesser General Public
14 # License along with this library; if not, write to the Free Software
15 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 Test middle point on an elliptic arc
27 from salome.shaper import model
29 from SketchAPI import *
31 __updated__ = "2019-10-02"
33 class TestMiddlePointOnEllipticArc(unittest.TestCase):
36 self.myTestPassed = True
37 self.myDocument = model.moduleDocument()
38 self.mySketch = model.addSketch(self.myDocument, model.defaultPlane("XOY"))
39 self.myArc = self.mySketch.addEllipticArc(30, 20, 50, 30, 45, 40, 5, 6.11485435, False)
40 self.myLine = self.mySketch.addLine(10, 40, 40, 80)
47 self.assertArc(self.myArc)
48 self.checkMiddlePoint(self.myLine.startPoint(), self.myArc)
53 self.assertEqual(model.dof(self.mySketch), self.myDOF)
55 def toPeriod(self, theValue):
56 while theValue < -math.pi:
57 theValue += 2.0 * math.pi
58 while theValue >= math.pi:
59 theValue -= 2.0 * math.pi
62 def checkMiddlePoint(self, thePoint, theArc):
63 self.myTestPassed = False
64 anEllipse = theArc.defaultResult().shape().edge().ellipse()
65 # check point on ellipse
66 self.checkPointOnEllipse(thePoint, anEllipse)
69 startAngle = 0; startPoint = GeomAPI_Pnt(theArc.startPoint().x(), theArc.startPoint().y(), 0)
70 startAngle = anEllipse.parameter(startPoint, TOLERANCE, startAngle)
71 endAngle = 0; endPoint = GeomAPI_Pnt(theArc.endPoint().x(), theArc.endPoint().y(), 0)
72 endAngle = anEllipse.parameter(endPoint, TOLERANCE, endAngle)
73 midAngle = 0; midPoint = GeomAPI_Pnt(thePoint.x(), thePoint.y(), 0)
74 midAngle = anEllipse.parameter(midPoint, TOLERANCE, midAngle)
75 diffMS = self.toPeriod(midAngle - startAngle)
76 diffEM = self.toPeriod(endAngle - midAngle)
77 self.assertAlmostEqual(diffMS, diffEM)
78 self.assertEqual(diffMS < 0, theArc.reversed().value())
79 self.myTestPassed = True
81 def checkPointOnEllipse(self, theCoordinates, theEllipse):
82 point = GeomAPI_Pnt2d(theCoordinates.x(), theCoordinates.y())
83 firstFocus2d = GeomAPI_Pnt2d(theEllipse.firstFocus().x(), theEllipse.firstFocus().y())
84 distPF1 = model.distancePointPoint(firstFocus2d, point)
85 secondFocus2d = GeomAPI_Pnt2d(theEllipse.secondFocus().x(), theEllipse.secondFocus().y())
86 distPF2 = model.distancePointPoint(secondFocus2d, point)
87 if issubclass(type(theEllipse), SketchAPI_Ellipse):
88 majorRad = theEllipse.majorRadius().value()
90 majorRad = theEllipse.majorRadius()
91 NB_DIGITS = 7 - math.floor(math.log10(majorRad))
92 self.assertAlmostEqual(distPF1 + distPF2, 2.0 * majorRad, NB_DIGITS)
94 def assertArc(self, theArc):
95 anEllipse = theArc.defaultResult().shape().edge().ellipse()
96 self.checkPointOnEllipse(theArc.startPoint(), anEllipse)
97 self.checkPointOnEllipse(theArc.endPoint(), anEllipse)
99 def rotatePoint(self, thePoint, theCenter, theAngle):
100 dirX = thePoint.x() - theCenter.x()
101 dirY = thePoint.y() - theCenter.y()
102 newX = theCenter.x() + dirX * math.cos(theAngle) - dirY * math.sin(theAngle)
103 newY = theCenter.y() + dirX * math.sin(theAngle) + dirY * math.cos(theAngle)
104 self.mySketch.move(thePoint, newX, newY)
107 ANGLE_STEP = math.pi * 5.0 / 180.0
108 ANGLE_THRESHOLD = math.pi / 2.0
109 # move start point of the arc clockwise
111 while fullAngle < ANGLE_THRESHOLD:
112 self.rotatePoint(self.myArc.startPoint(), self.myArc.center(), -ANGLE_STEP)
114 self.checkMiddlePoint(self.myLine.startPoint(), self.myArc)
115 fullAngle += ANGLE_STEP
116 # move start point of the arc conterclockwise
118 while fullAngle < ANGLE_THRESHOLD:
119 self.rotatePoint(self.myArc.startPoint(), self.myArc.center(), ANGLE_STEP)
121 self.checkMiddlePoint(self.myLine.startPoint(), self.myArc)
122 fullAngle += ANGLE_STEP
124 # move end point of the arc clockwise
126 while fullAngle < ANGLE_THRESHOLD:
127 self.rotatePoint(self.myArc.endPoint(), self.myArc.center(), -ANGLE_STEP)
129 self.checkMiddlePoint(self.myLine.startPoint(), self.myArc)
130 fullAngle += ANGLE_STEP
131 # move end point of the arc conterclockwise
133 while fullAngle < ANGLE_THRESHOLD:
134 self.rotatePoint(self.myArc.endPoint(), self.myArc.center(), ANGLE_STEP)
136 self.checkMiddlePoint(self.myLine.startPoint(), self.myArc)
137 fullAngle += ANGLE_STEP
139 # move center of the arc
141 for i in range(0, 40):
142 if i == 10 or i == 30:
143 DELTA = [-DELTA[0], -DELTA[1]]
144 self.mySketch.move(self.myArc.center(), self.myArc.center().x() + DELTA[0], self.myArc.center().y() + DELTA[1])
146 self.checkMiddlePoint(self.myLine.startPoint(), self.myArc)
148 for i in range(0, 40):
149 if i == 10 or i == 30:
150 DELTA = [-DELTA[0], -DELTA[1]]
151 self.mySketch.move(self.myArc.center(), self.myArc.center().x() + DELTA[0], self.myArc.center().y() + DELTA[1])
153 self.checkMiddlePoint(self.myLine.startPoint(), self.myArc)
157 for i in range(0, 40):
158 if i == 10 or i == 30:
159 DELTA = [-DELTA[0], -DELTA[1]]
160 self.mySketch.move(self.myLine.startPoint(), self.myLine.startPoint().x() + DELTA[0], self.myLine.startPoint().y() + DELTA[1])
162 self.checkMiddlePoint(self.myLine.startPoint(), self.myArc)
164 for i in range(0, 40):
165 if i == 10 or i == 30:
166 DELTA = [-DELTA[0], -DELTA[1]]
167 self.mySketch.move(self.myLine.startPoint(), self.myLine.startPoint().x() + DELTA[0], self.myLine.startPoint().y() + DELTA[1])
169 self.checkMiddlePoint(self.myLine.startPoint(), self.myArc)
172 def test_middle_point_PA(self):
173 """ Test 1. Set middle point constraint (point is the first argument)
175 self.mySketch.setMiddlePoint(self.myLine.startPoint(), self.myArc.results()[-1])
179 def test_middle_point_AP(self):
180 """ Test 2. Set middle point constraint (point is the second argument)
182 self.mySketch.setMiddlePoint(self.myArc.results()[-1], self.myLine.startPoint())
186 def test_coincident_middle_point(self):
187 """ Test 3. Set middle point constraint for the point already coincident with the arc
189 self.mySketch.setCoincident(self.myLine.startPoint(), self.myArc.results()[-1])
191 self.mySketch.setMiddlePoint(self.myLine.startPoint(), self.myArc.results()[-1])
195 def test_middle_point_coincident(self):
196 """ Test 4. Set concidence of the point and the arc which are already constrained with middle point
198 self.mySketch.setMiddlePoint(self.myLine.startPoint(), self.myArc.results()[-1])
200 self.mySketch.setCoincident(self.myLine.startPoint(), self.myArc.results()[-1])
204 @unittest.expectedFailure
205 def test_middle_point_limitation(self):
206 """ Test 5. Check middle point fails if the point's coordinates are equal to the arc start point
208 self.myLine.startPoint().setValue(self.myArc.startPoint().pnt())
210 coincidence = self.mySketch.setCoincident(self.myLine.startPoint(), self.myArc.results()[-1])
211 self.mySketch.setMiddlePoint(self.myLine.startPoint(), self.myArc.results()[-1])
214 # this check will fail due to the limitation of PlanGCS
215 self.checkMiddlePoint(self.myLine.startPoint(), self.myArc)
217 def test_middle_point_equal_start(self):
218 """ Test 6. Check middle point does not fail if the point's coordinates are equal to the arc end point
220 self.myLine.startPoint().setValue(self.myArc.endPoint().pnt())
222 coincidence = self.mySketch.setCoincident(self.myLine.startPoint(), self.myArc.results()[-1])
223 self.mySketch.setMiddlePoint(self.myLine.startPoint(), self.myArc.results()[-1])
227 def test_middle_point_move_arc(self):
228 """ Test 7. Set middle point constraint and move arc
230 self.mySketch.setMiddlePoint(self.myLine.startPoint(), self.myArc.results()[-1])
233 self.checkMiddlePoint(self.myLine.startPoint(), self.myArc)
236 def test_middle_point_coincidence_move_arc(self):
237 """ Test 8. Set coincidence and middle point constraint and move arc
239 self.mySketch.setCoincident(self.myLine.startPoint(), self.myArc.results()[-1])
241 self.mySketch.setMiddlePoint(self.myLine.startPoint(), self.myArc.results()[-1])
244 self.checkMiddlePoint(self.myLine.startPoint(), self.myArc)
247 def test_middle_point_move_line(self):
248 """ Test 9. Set middle point constraint and move line
250 self.mySketch.setMiddlePoint(self.myLine.startPoint(), self.myArc.results()[-1])
253 self.checkMiddlePoint(self.myLine.startPoint(), self.myArc)
256 def test_middle_point_coincidence_move_line(self):
257 """ Test 10. Set coincidence and middle point constraint and move line
259 self.mySketch.setCoincident(self.myLine.startPoint(), self.myArc.results()[-1])
261 self.mySketch.setMiddlePoint(self.myLine.startPoint(), self.myArc.results()[-1])
264 self.checkMiddlePoint(self.myLine.startPoint(), self.myArc)
267 def test_remove_middle_point(self):
268 """ Test 11. Set and then remove middle point constraint
270 mp = self.mySketch.setMiddlePoint(self.myLine.startPoint(), self.myArc.results()[-1])
273 self.assertArc(self.myArc)
274 self.checkMiddlePoint(self.myLine.startPoint(), self.myArc)
276 # remove middle point
277 self.myDocument.removeFeature(mp.feature())
281 # set flag False to avoid checking middle point constraint in tearDown() method
282 self.myTestPassed = False
285 if __name__ == "__main__":
286 test_program = unittest.main(exit=False)
287 assert test_program.result.wasSuccessful(), "Test failed"
288 assert(model.checkPythonDump())