Salome HOME
updated copyright message
[modules/shaper.git] / src / SketchPlugin / Test / TestConstraintCoincidenceEllipticArc.py
1 # Copyright (C) 2019-2023  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 coincidence applied for elliptic arc and its sub-results
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-02"
33
34 class TestCoincidenceEllipticArc(unittest.TestCase):
35   def setUp(self):
36     center = GeomAPI_Pnt2d(-10., 5.)
37     axisEnd = GeomAPI_Pnt2d(40., -5.)
38     startPoint = GeomAPI_Pnt2d(20., 5.)
39     endPoint = GeomAPI_Pnt2d(-40., 5.)
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     self.myDOF = 7
46     self.myOrigin = self.mySketch.addPoint("Origin")
47     self.myOX = self.mySketch.addLine("OX")
48     model.do()
49     self.myEllipticArc = SketchAPI_EllipticArc(model.lastSubFeature(self.mySketch, "SketchEllipticArc"))
50     self.myCenter = macroEllipticArc.center()
51     self.myFocus1 = macroEllipticArc.focus1()
52     self.myFocus2 = macroEllipticArc.focus2()
53     self.myMajorAxis = macroEllipticArc.majorAxis()
54     self.myMajorStart = macroEllipticArc.majorAxisStart()
55     self.myMajorEnd = macroEllipticArc.majorAxisEnd()
56     self.myMinorAxis = macroEllipticArc.minorAxis()
57     self.myMinorStart = macroEllipticArc.minorAxisStart()
58     self.myMinorEnd = macroEllipticArc.minorAxisEnd()
59     self.myExpectFailure = False
60
61   def tearDown(self):
62     model.end()
63     if self.myExpectFailure:
64       assert(self.mySketch.solverError() != ""), "PlaneGCS limitation: if you see this message, then PlaneGCS has solved the set of constraints correctly"
65       model.undo()
66     else:
67       self.checkDOF()
68       self.assertPoints(self.myCenter.coordinates(), self.myEllipticArc.center())
69       self.assertPoints(self.myFocus1.coordinates(), self.myEllipticArc.firstFocus())
70       self.assertPoints(self.myFocus2.coordinates(), self.myEllipticArc.secondFocus())
71       self.assertPoints(self.myMajorStart.coordinates(), self.myEllipticArc.majorAxisNegative())
72       self.assertPoints(self.myMajorEnd.coordinates(), self.myEllipticArc.majorAxisPositive())
73       self.assertPoints(self.myMajorAxis.startPoint(), self.myEllipticArc.majorAxisNegative())
74       self.assertPoints(self.myMajorAxis.endPoint(), self.myEllipticArc.majorAxisPositive())
75       self.assertPoints(self.myMinorStart.coordinates(), self.myEllipticArc.minorAxisNegative())
76       self.assertPoints(self.myMinorEnd.coordinates(), self.myEllipticArc.minorAxisPositive())
77       self.assertPoints(self.myMinorAxis.startPoint(), self.myEllipticArc.minorAxisNegative())
78       self.assertPoints(self.myMinorAxis.endPoint(), self.myEllipticArc.minorAxisPositive())
79       model.testNbSubFeatures(self.mySketch, "SketchPoint", 8)
80       model.testNbSubFeatures(self.mySketch, "SketchLine", 3)
81       model.testNbSubFeatures(self.mySketch, "SketchEllipticArc", 1)
82       model.testNbSubFeatures(self.mySketch, "SketchConstraintCoincidenceInternal", 11)
83       model.testNbSubFeatures(self.mySketch, "SketchConstraintCoincidence", 1)
84
85
86   def checkDOF(self):
87     self.assertEqual(model.dof(self.mySketch), self.myDOF)
88
89   def checkPointFixing(self, thePoint):
90     self.mySketch.setCoincident(thePoint, self.myOrigin.coordinates())
91     self.myDOF -= 2
92     model.do()
93     if not self.myExpectFailure:
94       self.assertPoints(thePoint, self.myOrigin.coordinates())
95       self.assertGreater(self.myEllipticArc.majorRadius().value(), 0.0)
96       self.assertGreater(self.myEllipticArc.minorRadius().value(), 0.0)
97
98   def assertPoints(self, thePoint1, thePoint2):
99     self.assertAlmostEqual(thePoint1.x(), thePoint2.x())
100     self.assertAlmostEqual(thePoint1.y(), thePoint2.y())
101
102   def checkPointOnAxis(self, thePoint):
103     self.mySketch.setCoincident(thePoint, self.myOX.result())
104     self.myDOF -= 1
105     model.do()
106     if not self.myExpectFailure:
107       self.assertAlmostEqual(thePoint.y(), 0.0)
108       self.assertGreater(self.myEllipticArc.majorRadius().value(), 0.0)
109       self.assertGreater(self.myEllipticArc.minorRadius().value(), 0.0)
110
111   def checkPointOnLine(self, thePoint, theLineStart, theLineEnd):
112     vecP = [thePoint.x() - theLineStart.x(), thePoint.y() - theLineStart.y()]
113     vecL = [theLineEnd.x() - theLineStart.x(), theLineEnd.y() - theLineStart.y()]
114     dist = math.fabs(vecP[0] * vecL[1] - vecP[1] * vecL[0]) / math.hypot(vecL[0], vecL[1])
115
116     self.assertAlmostEqual(dist, 0.0)
117     self.assertGreater(self.myEllipticArc.majorRadius().value(), 0.0)
118     self.assertGreater(self.myEllipticArc.minorRadius().value(), 0.0)
119
120   def checkPointOnEllipse(self, thePoint, theEllipse):
121     firstFocus2d = GeomAPI_Pnt2d(theEllipse.firstFocus().x(), theEllipse.firstFocus().y())
122     distPF1 = model.distancePointPoint(firstFocus2d,  thePoint)
123     secondFocus2d = GeomAPI_Pnt2d(theEllipse.secondFocus().x(), theEllipse.secondFocus().y())
124     distPF2 = model.distancePointPoint(secondFocus2d,  thePoint)
125     self.assertAlmostEqual(distPF1 + distPF2, 2.0 * theEllipse.majorRadius().value(), 7)
126
127
128   def test_concident_center(self):
129     """ Test 1. Make center of elliptic arc coincident with the Origin
130     """
131     self.checkPointFixing(self.myCenter.coordinates())
132
133   def test_coincident_first_focus(self):
134     """ Test 2. Make first focus of elliptic arc coincident with the Origin
135     """
136     self.checkPointFixing(self.myFocus1.coordinates())
137
138   def test_coincident_second_focus(self):
139     """ Test 3. Make second focus of elliptic arc coincident with the Origin
140     """
141     self.checkPointFixing(self.myFocus2.coordinates())
142
143   def test_coincident_major_axis_start(self):
144     """ Test 4. Make start point on the major axis of elliptic arc coincident with the Origin
145     """
146     self.checkPointFixing(self.myMajorStart.coordinates())
147
148   def test_coincident_major_axis_end(self):
149     """ Test 5. Make end point on the major axis of elliptic arc coincident with the Origin
150     """
151     self.checkPointFixing(self.myMajorEnd.coordinates())
152
153   def test_coincident_minor_axis_start(self):
154     """ Test 6. Make start point on the minor axis of elliptic arc coincident with the Origin
155     """
156     self.checkPointFixing(self.myMinorStart.coordinates())
157
158   def test_coincident_minor_axis_end(self):
159     """ Test 7. Make end point on the minor axis of elliptic arc coincident with the Origin.
160                 Check solver is failed to compute the coincidence.
161     """
162     self.myExpectFailure = True
163     self.checkPointFixing(self.myMinorEnd.coordinates())
164
165   def test_coincident_start(self):
166     """ Test 8. Make start point of elliptic arc coincident with the Origin.
167                 Check solver is failed to compute the coincidence.
168     """
169     self.myExpectFailure = True
170     self.checkPointFixing(self.myEllipticArc.startPoint())
171
172   def test_coincident_end(self):
173     """ Test 9. Make end point of elliptic arc coincident with the Origin
174     """
175     self.checkPointFixing(self.myEllipticArc.endPoint())
176
177
178   def test_center_on_line(self):
179     """ Test 10. Make center of elliptic arc coincident with the OX
180     """
181     self.checkPointOnAxis(self.myCenter.coordinates())
182
183   def test_first_focus_on_line(self):
184     """ Test 11. Make first focus of elliptic arc coincident with the OX
185     """
186     self.checkPointOnAxis(self.myFocus1.coordinates())
187
188   def test_second_focus_on_line(self):
189     """ Test 12. Make second focus of elliptic arc coincident with the OX
190     """
191     self.checkPointOnAxis(self.myFocus2.coordinates())
192
193   def test_major_axis_start_on_line(self):
194     """ Test 13. Make start point on the major axis of elliptic arc coincident with the OX
195     """
196     self.checkPointOnAxis(self.myMajorStart.coordinates())
197
198   def test_major_axis_end_on_line(self):
199     """ Test 14. Make end point on the major axis of elliptic arc coincident with the OX
200     """
201     self.checkPointOnAxis(self.myMajorEnd.coordinates())
202
203   def test_minor_axis_start_on_line(self):
204     """ Test 15. Make start point on the minor axis of elliptic arc coincident with the OX
205     """
206     self.checkPointOnAxis(self.myMinorStart.coordinates())
207
208   def test_minor_axis_end_on_line(self):
209     """ Test 16. Make end point on the minor axis of elliptic arc coincident with the OX
210     """
211     self.myExpectFailure = True
212     self.checkPointOnAxis(self.myMinorEnd.coordinates())
213
214   def test_coincident_start_on_line(self):
215     """ Test 17. Make start point of elliptic arc coincident with the OX
216     """
217     self.checkPointOnAxis(self.myEllipticArc.startPoint())
218
219   def test_coincident_end_on_line(self):
220     """ Test 18. Make end point of elliptic arc coincident with the OX
221     """
222     self.checkPointOnAxis(self.myEllipticArc.endPoint())
223
224
225   def test_origin_on_major_axis(self):
226     """ Test 19. Make origin coincident with the major axis of the elliptic arc
227     """
228     self.mySketch.setCoincident(self.myMajorAxis.result(), self.myOrigin.coordinates())
229     self.myDOF -= 1
230     model.do()
231     self.checkPointOnLine(self.myOrigin.coordinates(), self.myMajorStart.coordinates(), self.myMajorEnd.coordinates())
232
233   def test_origin_on_minor_axis(self):
234     """ Test 20. Make origin coincident with the minor axis of the elliptic arc
235     """
236     self.mySketch.setCoincident(self.myMinorAxis.result(), self.myOrigin.coordinates())
237     self.myDOF -= 1
238     model.end()
239     # solver shows wrong result
240     assert(self.mySketch.solverError() != ""), "PlaneGCS limitation: if you see this message, then PlaneGCS has solved the set of constraints correctly"
241     model.undo()
242
243     # move elliptic arc and set coincidence once again
244     model.begin()
245     self.mySketch.move(self.myMinorStart, 20, 10)
246     model.do()
247     self.mySketch.setCoincident(self.myMinorAxis.results()[-1], self.myOrigin.coordinates())
248     model.do()
249     self.checkPointOnLine(self.myOrigin.coordinates(), self.myMinorStart.coordinates(), self.myMinorEnd.coordinates())
250
251
252   def test_origin_on_ellipse(self):
253     """ Test 21. Make origin coincident with the elliptic arc
254     """
255     self.mySketch.setCoincident(self.myEllipticArc.results()[-1], self.myOrigin.coordinates())
256     self.myDOF -= 1
257     model.do()
258     self.checkPointOnEllipse(self.myOrigin.coordinates(), self.myEllipticArc)
259
260
261   def test_start_on_major_axis(self):
262     """ Test 22. Make coincident the start point of the arc and the end of its major axis
263     """
264     self.myEllipticArc.startPoint().setValue(38, -2)
265     model.do()
266     self.mySketch.setCoincident(self.myEllipticArc.startPoint(), self.myMajorAxis.endPoint())
267     self.myDOF -= 1
268     model.do()
269     self.assertPoints(self.myMajorAxis.endPoint(), self.myEllipticArc.startPoint())
270
271   def test_end_on_major_axis(self):
272     """ Test 23. Make coincident the end point of the arc and the start of its major axis
273     """
274     self.myEllipticArc.endPoint().setValue(-58, 12)
275     model.do()
276     self.mySketch.setCoincident(self.myMajorAxis.startPoint(), self.myEllipticArc.endPoint())
277     self.myDOF -= 1
278     model.do()
279     self.assertPoints(self.myMajorAxis.startPoint(), self.myEllipticArc.endPoint())
280
281   def test_start_on_minor_axis(self):
282     """ Test 22. Make coincident the start point of the arc and the end of its minor axis
283     """
284     self.mySketch.setCoincident(self.myMinorAxis.endPoint(), self.myEllipticArc.startPoint())
285     self.myDOF -= 1
286     model.do()
287     self.assertPoints(self.myMinorAxis.endPoint(), self.myEllipticArc.startPoint())
288
289   def test_end_on_minor_axis(self):
290     """ Test 23. Make coincident the end point of the arc and the start of its minor axis
291     """
292     self.mySketch.setCoincident(self.myEllipticArc.endPoint(), self.myMinorAxis.startPoint())
293     self.myDOF -= 1
294     model.do()
295     self.assertPoints(self.myMinorAxis.startPoint(), self.myEllipticArc.endPoint())
296
297
298 if __name__ == "__main__":
299     test_program = unittest.main(exit=False)
300     assert test_program.result.wasSuccessful(), "Test failed"
301     assert model.checkPythonDump()