Salome HOME
Copyright update 2022
[modules/shaper.git] / src / SketchPlugin / Test / TestConstraintTangentEllipticArc.py
1 # Copyright (C) 2019-2022  CEA/DEN, EDF R&D
2 #
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.
7 #
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.
12 #
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
16 #
17 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 #
19
20 """
21     Test constraint "Tangent" applied to elliptic arc and another entity
22 """
23
24 import unittest
25 import math
26
27 from salome.shaper import model
28
29 from GeomAPI import *
30 from SketchAPI import *
31
32 __updated__ = "2019-10-04"
33
34 class TestTangentEllipticArc(unittest.TestCase):
35   def setUp(self):
36     center = GeomAPI_Pnt2d(30., 20.)
37     axisEnd = GeomAPI_Pnt2d(50., 30.)
38     startPoint = GeomAPI_Pnt2d(45, 40)
39     endPoint = GeomAPI_Pnt2d(5, 6.11485435)
40
41     model.begin()
42     self.myDocument = model.moduleDocument()
43     self.mySketch = model.addSketch(self.myDocument, model.defaultPlane("XOY"))
44     macroEllipticArc = self.mySketch.addEllipticArc(center, axisEnd, startPoint, endPoint, False)
45     model.do()
46     self.myEllipticArc = SketchAPI_EllipticArc(model.lastSubFeature(self.mySketch, "SketchEllipticArc"))
47     self.myCenter = macroEllipticArc.center()
48     self.myFocus1 = macroEllipticArc.focus1()
49     self.myFocus2 = macroEllipticArc.focus2()
50     self.myMajorAxis = macroEllipticArc.majorAxis()
51     self.myMajorStart = macroEllipticArc.majorAxisStart()
52     self.myMajorEnd = macroEllipticArc.majorAxisEnd()
53     self.myMinorAxis = macroEllipticArc.minorAxis()
54     self.myMinorStart = macroEllipticArc.minorAxisStart()
55     self.myMinorEnd = macroEllipticArc.minorAxisEnd()
56
57     self.myDOF = 7
58     self.myNbPoints = 7
59     self.myNbLines = 2
60     self.myNbArcs = 0
61     self.myNbCircles = 0
62     self.myNbEllipses = 0
63     self.myNbEllipticArcs = 1
64     self.myNbInternals = 11
65     self.myNbCoincidence = 0
66     self.myNbTangency = 0
67
68   def tearDown(self):
69     model.end()
70     self.checkDOF()
71     self.assertPoints(self.myCenter.coordinates(), self.myEllipticArc.center())
72     self.assertPoints(self.myFocus1.coordinates(), self.myEllipticArc.firstFocus())
73     self.assertPoints(self.myFocus2.coordinates(), self.myEllipticArc.secondFocus())
74     self.assertPoints(self.myMajorStart.coordinates(), self.myEllipticArc.majorAxisNegative())
75     self.assertPoints(self.myMajorEnd.coordinates(), self.myEllipticArc.majorAxisPositive())
76     self.assertPoints(self.myMajorAxis.startPoint(), self.myEllipticArc.majorAxisNegative())
77     self.assertPoints(self.myMajorAxis.endPoint(), self.myEllipticArc.majorAxisPositive())
78     self.assertPoints(self.myMinorStart.coordinates(), self.myEllipticArc.minorAxisNegative())
79     self.assertPoints(self.myMinorEnd.coordinates(), self.myEllipticArc.minorAxisPositive())
80     self.assertPoints(self.myMinorAxis.startPoint(), self.myEllipticArc.minorAxisNegative())
81     self.assertPoints(self.myMinorAxis.endPoint(), self.myEllipticArc.minorAxisPositive())
82     model.testNbSubFeatures(self.mySketch, "SketchPoint", self.myNbPoints)
83     model.testNbSubFeatures(self.mySketch, "SketchLine", self.myNbLines)
84     model.testNbSubFeatures(self.mySketch, "SketchArc", self.myNbArcs)
85     model.testNbSubFeatures(self.mySketch, "SketchCircle", self.myNbCircles)
86     model.testNbSubFeatures(self.mySketch, "SketchEllipse", self.myNbEllipses)
87     model.testNbSubFeatures(self.mySketch, "SketchEllipticArc", self.myNbEllipticArcs)
88     model.testNbSubFeatures(self.mySketch, "SketchConstraintCoincidenceInternal", self.myNbInternals)
89     model.testNbSubFeatures(self.mySketch, "SketchConstraintCoincidence", self.myNbCoincidence)
90     model.testNbSubFeatures(self.mySketch, "SketchConstraintTangent", self.myNbTangency)
91
92
93   def checkDOF(self):
94     self.assertEqual(model.dof(self.mySketch), self.myDOF)
95
96   def assertTangentLineEllipse(self, theLine, theEllipticArc):
97     aLine = GeomAPI_Lin2d(theLine.startPoint().pnt(), theLine.endPoint().pnt())
98     projF1 = aLine.project(theEllipticArc.firstFocus().pnt())
99     projF2 = aLine.project(theEllipticArc.secondFocus().pnt())
100
101     distF1P1 = model.distancePointPoint(theEllipticArc.firstFocus(), projF1)
102     distF2P2 = model.distancePointPoint(theEllipticArc.secondFocus(), projF2)
103
104     tgPoint = GeomAPI_Pnt2d((projF1.x() * distF2P2 + projF2.x() * distF1P1) / (distF1P1 + distF2P2), (projF1.y() * distF2P2 + projF2.y() * distF1P1) / (distF1P1 + distF2P2))
105     distF1T = model.distancePointPoint(theEllipticArc.firstFocus(), tgPoint)
106     distF2T = model.distancePointPoint(theEllipticArc.secondFocus(), tgPoint)
107     NB_DIGITS = 7 - math.floor(math.log10(theEllipticArc.majorRadius().value()))
108     self.assertAlmostEqual(distF1T + distF2T, 2 * theEllipticArc.majorRadius().value(), NB_DIGITS)
109
110   def assertTangentCircleEllipse(self, theCircle, theEllipticArc):
111     axis = GeomAPI_Dir2d(theEllipticArc.firstFocus().x() - theEllipticArc.center().x(), theEllipticArc.firstFocus().y() - theEllipticArc.center().y())
112     anEllipticArc = GeomAPI_Ellipse2d(theEllipticArc.center().pnt(), axis, theEllipticArc.majorRadius().value(), theEllipticArc.minorRadius().value())
113     aCircle = GeomAPI_Circ2d(theCircle.center().pnt(), GeomAPI_Dir2d(1, 0), theCircle.radius().value())
114
115     pOnE = GeomAPI_Pnt2d(0, 0)
116     pOnC = GeomAPI_Pnt2d(0, 0)
117     anEllipticArc.distance(aCircle, pOnE, pOnC)
118     self.assertAlmostEqual(model.distancePointPoint(pOnE, theCircle.center()), theCircle.radius().value())
119
120     dist1 = model.distancePointPoint(pOnC, theEllipticArc.firstFocus())
121     dist2 = model.distancePointPoint(pOnC, theEllipticArc.secondFocus())
122     NB_DIGITS = 7 - math.floor(math.log10(theEllipticArc.majorRadius().value()))
123     self.assertAlmostEqual(dist1 + dist2, 2 * theEllipticArc.majorRadius().value(), NB_DIGITS)
124
125   def assertTangentEllipses(self, theEllipticArc1, theEllipticArc2):
126     axis1 = GeomAPI_Dir2d(theEllipticArc1.firstFocus().x() - theEllipticArc1.center().x(), theEllipticArc1.firstFocus().y() - theEllipticArc1.center().y())
127     anEllipticArc1 = GeomAPI_Ellipse2d(theEllipticArc1.center().pnt(), axis1, theEllipticArc1.majorRadius().value(), theEllipticArc1.minorRadius().value())
128     axis2 = GeomAPI_Dir2d(theEllipticArc2.firstFocus().x() - theEllipticArc2.center().x(), theEllipticArc2.firstFocus().y() - theEllipticArc2.center().y())
129     anEllipticArc2 = GeomAPI_Ellipse2d(theEllipticArc2.center().pnt(), axis2, theEllipticArc2.majorRadius().value(), theEllipticArc2.minorRadius().value())
130
131     p1 = GeomAPI_Pnt2d(0, 0)
132     p2 = GeomAPI_Pnt2d(0, 0)
133     anEllipticArc1.distance(anEllipticArc2, p1, p2)
134
135     dist1 = model.distancePointPoint(p2, theEllipticArc1.firstFocus())
136     dist2 = model.distancePointPoint(p2, theEllipticArc1.secondFocus())
137     NB_DIGITS = 7 - math.floor(math.log10(theEllipticArc1.majorRadius().value()))
138     self.assertAlmostEqual(dist1 + dist2, 2 * theEllipticArc1.majorRadius().value())
139
140     dist1 = model.distancePointPoint(p1, theEllipticArc2.firstFocus())
141     dist2 = model.distancePointPoint(p1, theEllipticArc2.secondFocus())
142     NB_DIGITS = 7 - math.floor(math.log10(theEllipticArc2.majorRadius().value()))
143     self.assertAlmostEqual(dist1 + dist2, 2 * theEllipticArc2.majorRadius().value(), NB_DIGITS)
144
145   def assertPoints(self, thePoint1, thePoint2):
146     self.assertAlmostEqual(thePoint1.x(), thePoint2.x(), 6)
147     self.assertAlmostEqual(thePoint1.y(), thePoint2.y(), 6)
148
149
150   def test_line_tangent(self):
151     """ Test 1. Set tangency between elliptic arc and a line
152     """
153     aLine = self.mySketch.addLine(10, -10, 90, 40)
154     self.myNbLines += 1
155     self.myDOF += 4
156     model.do()
157
158     self.mySketch.setTangent(self.myEllipticArc.result(), aLine.result())
159     self.myNbTangency += 1
160     self.myDOF -= 1
161     model.do()
162
163     self.assertTangentLineEllipse(aLine, self.myEllipticArc)
164
165
166   def test_line_coincident_then_tangent(self):
167     """ Test 2. Set tangency between elliptic arc and a line, if the extremity of the line is coincident with the elliptic arc
168     """
169     aLine = self.mySketch.addLine(10, -10, 90, 40)
170     self.mySketch.setCoincident(aLine.endPoint(), self.myEllipticArc.result())
171     self.myNbLines += 1
172     self.myNbCoincidence += 1
173     self.myDOF += 3
174     model.do()
175
176     self.mySketch.setTangent(self.myEllipticArc.result(), aLine.result())
177     self.myNbTangency += 1
178     self.myDOF -= 1
179     model.do()
180
181     self.assertTangentLineEllipse(aLine, self.myEllipticArc)
182
183
184   def test_line_tangent_then_coincident(self):
185     """ 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
186     """
187     aLine = self.mySketch.addLine(10, -10, 90, 40)
188     self.myNbLines += 1
189     self.myDOF += 4
190     model.do()
191
192     self.mySketch.setTangent(aLine.result(), self.myEllipticArc.result())
193     self.myNbTangency += 1
194     self.myDOF -= 1
195     model.do()
196
197     self.mySketch.setCoincident(aLine.startPoint(), self.myEllipticArc.result())
198     self.myNbCoincidence += 1
199     self.myDOF -= 1
200     model.do()
201
202     self.assertTangentLineEllipse(aLine, self.myEllipticArc)
203
204
205   def test_line_tangent_then_remove_coincidence(self):
206     """ Test 4. Set tangency between elliptic arc and a line, which have a coincident point, then remove this coincidence
207     """
208     aLine = self.mySketch.addLine(10, -10, 90, 40)
209     aCoincidence = self.mySketch.setCoincident(aLine.endPoint(), self.myEllipticArc.result())
210     self.myNbLines += 1
211     self.myNbCoincidence += 1
212     self.myDOF += 3
213     model.do()
214
215     self.mySketch.setTangent(self.myEllipticArc.result(), aLine.result())
216     self.myNbTangency += 1
217     self.myDOF -= 1
218     model.do()
219
220     self.myDocument.removeFeature(aCoincidence.feature())
221     self.myNbCoincidence -= 1
222     self.myDOF += 1
223     model.do()
224
225     self.assertTangentLineEllipse(aLine, self.myEllipticArc)
226
227
228   def test_line_coincident_point_then_tangent(self):
229     """ 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
230     """
231     aLine = self.mySketch.addLine(10, -10, 90, 40)
232     self.mySketch.setCoincident(aLine.endPoint(), self.myEllipticArc.startPoint())
233     self.myNbLines += 1
234     self.myNbCoincidence += 1
235     self.myDOF += 2
236     model.do()
237
238     self.mySketch.setTangent(self.myEllipticArc.result(), aLine.result())
239     self.myNbTangency += 1
240     self.myDOF -= 1
241     model.do()
242
243     self.assertTangentLineEllipse(aLine, self.myEllipticArc)
244
245
246   def test_line_tangent_then_coincident_point(self):
247     """ Test 6. Set tangency between elliptic arc and a line, after that apply coincidence of extremities of the line and the elliptic arc
248     """
249     aLine = self.mySketch.addLine(10, -10, 90, 40)
250     self.myNbLines += 1
251     self.myDOF += 4
252     model.do()
253
254     self.mySketch.setTangent(self.myEllipticArc.result(), aLine.result())
255     self.myNbTangency += 1
256     self.myDOF -= 1
257     model.do()
258
259     self.assertTangentLineEllipse(aLine, self.myEllipticArc)
260
261     self.mySketch.setCoincident(aLine.startPoint(), self.myEllipticArc.startPoint())
262     self.myNbCoincidence += 1
263     self.myDOF -= 2
264     model.do()
265
266     self.assertTangentLineEllipse(aLine, self.myEllipticArc)
267
268
269   def test_line_tangent_then_remove_coincidence_on_extremity(self):
270     """ Test 7. Set tangency between elliptic arc and a line, which have a coincident boundary point, then remove this coincidence
271     """
272     aLine = self.mySketch.addLine(10, -10, 90, 40)
273     aCoincidence = self.mySketch.setCoincident(aLine.endPoint(), self.myEllipticArc.endPoint())
274     self.myNbLines += 1
275     self.myNbCoincidence += 1
276     self.myDOF += 2
277     model.do()
278
279     self.mySketch.setTangent(self.myEllipticArc.result(), aLine.result())
280     self.myNbTangency += 1
281     self.myDOF -= 1
282     model.do()
283
284     self.myDocument.removeFeature(aCoincidence.feature())
285     self.myNbCoincidence -= 1
286     self.myDOF += 2
287     model.do()
288
289     self.assertTangentLineEllipse(aLine, self.myEllipticArc)
290
291
292   def test_circle_tangent(self):
293     """ Test 8. Set tangency between elliptic arc and a circle
294     """
295     aCircle = self.mySketch.addCircle(30, 10, 20)
296     self.myNbCircles += 1
297     self.myDOF += 3
298     model.do()
299
300     self.mySketch.setTangent(self.myEllipticArc.result(), aCircle.defaultResult())
301     self.myNbTangency += 1
302     self.myDOF -= 1
303     model.do()
304
305     self.assertTangentCircleEllipse(aCircle, self.myEllipticArc)
306
307
308   def test_circle_coincident_then_tangent(self):
309     """ Test 9. Set tangency between elliptic arc and a circle, if the circle is coincident with start point of elliptic arc's minor axis
310     """
311     aCircle = self.mySketch.addCircle(30, 10, 20)
312     self.mySketch.setCoincident(self.myEllipticArc.startPoint(), aCircle.defaultResult())
313     self.myNbCircles += 1
314     self.myNbCoincidence += 1
315     self.myDOF += 2
316     model.do()
317
318     self.mySketch.setTangent(self.myEllipticArc.result(), aCircle.defaultResult())
319     self.myNbTangency += 1
320     self.myDOF -= 1
321     model.do()
322
323     self.assertTangentCircleEllipse(aCircle, self.myEllipticArc)
324     self.assertAlmostEqual(model.distancePointPoint(aCircle.center(), self.myEllipticArc.startPoint()), aCircle.radius().value())
325
326
327   def test_arc_tangent(self):
328     """ Test 10. Set tangency between elliptic arc and a circular arc
329     """
330     anArc = self.mySketch.addArc(30, -10, 40, -10, 20, -10, False)
331     self.myNbArcs += 1
332     self.myDOF += 5
333     model.do()
334
335     self.mySketch.setTangent(self.myEllipticArc.result(), anArc.results()[-1])
336     self.myNbTangency += 1
337     self.myDOF -= 1
338     model.do()
339
340     self.assertTangentCircleEllipse(anArc, self.myEllipticArc)
341
342
343   def test_arc_coincident_then_tangent(self):
344     """ Test 11. Set tangency between elliptic arc and an arc, if the extremities of the arcs are coincident
345     """
346     anArc = self.mySketch.addArc(30, -10, 40, -10, 20, -10, False)
347     self.mySketch.setCoincident(anArc.endPoint(), self.myEllipticArc.startPoint())
348     self.myNbArcs += 1
349     self.myNbCoincidence += 1
350     self.myDOF += 3
351     model.do()
352
353     self.mySketch.setTangent(self.myEllipticArc.result(), anArc.results()[-1])
354     self.myNbTangency += 1
355     self.myDOF -= 1
356     model.do()
357
358     self.assertTangentCircleEllipse(anArc, self.myEllipticArc)
359
360
361   def test_arc_tangent_then_coincident(self):
362     """ Test 12. Set tangency between elliptic arc and an arc, after that apply coincidence of extremities of the arcs
363     """
364     anArc = self.mySketch.addArc(30, -10, 40, -10, 20, -10, False)
365     self.myNbArcs += 1
366     self.myDOF += 5
367     model.do()
368
369     self.mySketch.setTangent(self.myEllipticArc.result(), anArc.results()[-1])
370     self.myNbTangency += 1
371     self.myDOF -= 1
372     model.do()
373
374     self.mySketch.setCoincident(anArc.startPoint(), self.myEllipticArc.startPoint())
375     self.myNbCoincidence += 1
376     self.myDOF -= 2
377     model.do()
378
379     self.assertTangentCircleEllipse(anArc, self.myEllipticArc)
380
381
382   def test_arc_tangent_then_remove_coincidence(self):
383     """ Test 13. Set tangency between elliptic arc and an arc, which have a coincident point, then remove this coincidence
384     """
385     anArc = self.mySketch.addArc(30, -10, 40, -10, 20, -10, False)
386     aCoincidence = self.mySketch.setCoincident(anArc.endPoint(), self.myEllipticArc.endPoint())
387     self.myNbArcs += 1
388     self.myNbCoincidence += 1
389     self.myDOF += 4
390     model.do()
391
392     self.mySketch.setTangent(self.myEllipticArc.result(), anArc.results()[-1])
393     self.myNbTangency += 1
394     self.myDOF -= 1
395     model.do()
396
397     self.myDocument.removeFeature(aCoincidence.feature())
398     self.myNbCoincidence -= 1
399     self.myDOF += 1
400     model.do()
401
402     self.assertTangentCircleEllipse(anArc, self.myEllipticArc)
403
404
405   def test_ellipse_tangent(self):
406     """ Test 14. Set tangency between ellipse and elliptic arc
407     """
408     anEllipse = self.mySketch.addEllipse(-30, 10, -10, 0, 20)
409     self.myNbEllipses += 1
410     self.myDOF += 5
411     model.do()
412
413     self.mySketch.setTangent(self.myEllipticArc.result(), anEllipse.result())
414     self.myNbTangency += 1
415     self.myDOF -= 1
416     model.do()
417
418     self.assertTangentEllipses(anEllipse, self.myEllipticArc)
419
420
421   def test_elliptic_arcs_tangent(self):
422     """ Test 15. Set tangency between two elliptic arcs
423     """
424     anEllipticArc = self.mySketch.addEllipticArc(35, 20, 60, 30, 40, 40, 20, -0.4890968089561491, True)
425     self.myNbEllipticArcs += 1
426     self.myDOF += 7
427     model.do()
428
429     self.mySketch.setTangent(self.myEllipticArc.result(), anEllipticArc.result())
430     self.myNbTangency += 1
431     self.myDOF -= 1
432     model.do()
433
434     self.assertTangentEllipses(anEllipticArc, self.myEllipticArc)
435
436
437   def test_elliptic_arcs_coincident_then_tangent(self):
438     """ Test 16. Set tangency between two elliptic arcs, if their extremities are coincident
439     """
440     anEllipticArc = self.mySketch.addEllipticArc(35, 20, 60, 30, 40, 40, 20, -0.4890968089561491, True)
441     self.mySketch.setCoincident(anEllipticArc.startPoint(), self.myEllipticArc.startPoint())
442     self.myNbEllipticArcs += 1
443     self.myNbCoincidence += 1
444     self.myDOF += 5
445     model.do()
446
447     self.mySketch.setTangent(self.myEllipticArc.result(), anEllipticArc.result())
448     self.myNbTangency += 1
449     self.myDOF -= 1
450     model.do()
451
452     self.assertTangentEllipses(anEllipticArc, self.myEllipticArc)
453
454
455
456 if __name__ == "__main__":
457     test_program = unittest.main(exit=False)
458     assert test_program.result.wasSuccessful(), "Test failed"