Salome HOME
updated copyright message
[modules/shaper.git] / src / SketchPlugin / Test / TestConstraintTangentEllipse.py
1 # Copyright (C) 2019-2023  CEA, EDF
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 ellipse 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-09-20"
33
34 class TestTangentEllipse(unittest.TestCase):
35   def setUp(self):
36     axisStart = GeomAPI_Pnt2d(20., 60.)
37     axisEnd = GeomAPI_Pnt2d(80., 50.)
38     passedPoint = GeomAPI_Pnt2d(60., 70.)
39
40     model.begin()
41     self.myDocument = model.moduleDocument()
42     self.mySketch = model.addSketch(self.myDocument, model.defaultPlane("XOY"))
43     macroEllipse = self.mySketch.addEllipse(axisStart, axisEnd, passedPoint, False)
44     model.do()
45     self.myEllipse = SketchAPI_Ellipse(model.lastSubFeature(self.mySketch, "SketchEllipse"))
46     self.myCenter = macroEllipse.center()
47     self.myFocus1 = macroEllipse.focus1()
48     self.myFocus2 = macroEllipse.focus2()
49     self.myMajorAxis = macroEllipse.majorAxis()
50     self.myMajorStart = macroEllipse.majorAxisStart()
51     self.myMajorEnd = macroEllipse.majorAxisEnd()
52     self.myMinorAxis = macroEllipse.minorAxis()
53     self.myMinorStart = macroEllipse.minorAxisStart()
54     self.myMinorEnd = macroEllipse.minorAxisEnd()
55
56     self.myDOF = 5
57     self.myNbPoints = 7
58     self.myNbLines = 2
59     self.myNbArcs = 0
60     self.myNbCircles = 0
61     self.myNbEllipses = 1
62     self.myNbInternals = 11
63     self.myNbCoincidence = 0
64     self.myNbTangency = 0
65
66   def tearDown(self):
67     model.end()
68     self.checkDOF()
69     self.assertPoints(self.myCenter.coordinates(), self.myEllipse.center())
70     self.assertPoints(self.myFocus1.coordinates(), self.myEllipse.firstFocus())
71     self.assertPoints(self.myFocus2.coordinates(), self.myEllipse.secondFocus())
72     self.assertPoints(self.myMajorStart.coordinates(), self.myEllipse.majorAxisNegative())
73     self.assertPoints(self.myMajorEnd.coordinates(), self.myEllipse.majorAxisPositive())
74     self.assertPoints(self.myMajorAxis.startPoint(), self.myEllipse.majorAxisNegative())
75     self.assertPoints(self.myMajorAxis.endPoint(), self.myEllipse.majorAxisPositive())
76     self.assertPoints(self.myMinorStart.coordinates(), self.myEllipse.minorAxisNegative())
77     self.assertPoints(self.myMinorEnd.coordinates(), self.myEllipse.minorAxisPositive())
78     self.assertPoints(self.myMinorAxis.startPoint(), self.myEllipse.minorAxisNegative())
79     self.assertPoints(self.myMinorAxis.endPoint(), self.myEllipse.minorAxisPositive())
80     model.testNbSubFeatures(self.mySketch, "SketchPoint", self.myNbPoints)
81     model.testNbSubFeatures(self.mySketch, "SketchLine", self.myNbLines)
82     model.testNbSubFeatures(self.mySketch, "SketchArc", self.myNbArcs)
83     model.testNbSubFeatures(self.mySketch, "SketchCircle", self.myNbCircles)
84     model.testNbSubFeatures(self.mySketch, "SketchEllipse", self.myNbEllipses)
85     model.testNbSubFeatures(self.mySketch, "SketchConstraintCoincidenceInternal", self.myNbInternals)
86     model.testNbSubFeatures(self.mySketch, "SketchConstraintCoincidence", self.myNbCoincidence)
87     model.testNbSubFeatures(self.mySketch, "SketchConstraintTangent", self.myNbTangency)
88
89
90   def checkDOF(self):
91     self.assertEqual(model.dof(self.mySketch), self.myDOF)
92
93   def assertTangentLineEllipse(self, theLine, theEllipse):
94     aLine = GeomAPI_Lin2d(theLine.startPoint().pnt(), theLine.endPoint().pnt())
95     projF1 = aLine.project(theEllipse.firstFocus().pnt())
96     projF2 = aLine.project(theEllipse.secondFocus().pnt())
97
98     distF1P1 = model.distancePointPoint(theEllipse.firstFocus(), projF1)
99     distF2P2 = model.distancePointPoint(theEllipse.secondFocus(), projF2)
100
101     tgPoint = GeomAPI_Pnt2d((projF1.x() * distF2P2 + projF2.x() * distF1P1) / (distF1P1 + distF2P2), (projF1.y() * distF2P2 + projF2.y() * distF1P1) / (distF1P1 + distF2P2))
102     distF1T = model.distancePointPoint(theEllipse.firstFocus(), tgPoint)
103     distF2T = model.distancePointPoint(theEllipse.secondFocus(), tgPoint)
104     self.assertAlmostEqual(distF1T + distF2T, 2 * theEllipse.majorRadius().value())
105
106   def assertTangentCircleEllipse(self, theCircle, theEllipse):
107     axis = GeomAPI_Dir2d(theEllipse.firstFocus().x() - theEllipse.center().x(), theEllipse.firstFocus().y() - theEllipse.center().y())
108     anEllipse = GeomAPI_Ellipse2d(theEllipse.center().pnt(), axis, theEllipse.majorRadius().value(), theEllipse.minorRadius().value())
109     aCircle = GeomAPI_Circ2d(theCircle.center().pnt(), GeomAPI_Dir2d(1, 0), theCircle.radius().value())
110
111     pOnE = GeomAPI_Pnt2d(0, 0)
112     pOnC = GeomAPI_Pnt2d(0, 0)
113     anEllipse.distance(aCircle, pOnE, pOnC)
114     self.assertAlmostEqual(model.distancePointPoint(pOnE, theCircle.center()), theCircle.radius().value())
115
116     dist1 = model.distancePointPoint(pOnC, theEllipse.firstFocus())
117     dist2 = model.distancePointPoint(pOnC, theEllipse.secondFocus())
118     self.assertAlmostEqual(dist1 + dist2, 2 * theEllipse.majorRadius().value())
119
120   def assertTangentEllipses(self, theEllipse1, theEllipse2):
121     axis1 = GeomAPI_Dir2d(theEllipse1.firstFocus().x() - theEllipse1.center().x(), theEllipse1.firstFocus().y() - theEllipse1.center().y())
122     anEllipse1 = GeomAPI_Ellipse2d(theEllipse1.center().pnt(), axis1, theEllipse1.majorRadius().value(), theEllipse1.minorRadius().value())
123     axis2 = GeomAPI_Dir2d(theEllipse2.firstFocus().x() - theEllipse2.center().x(), theEllipse2.firstFocus().y() - theEllipse2.center().y())
124     anEllipse2 = GeomAPI_Ellipse2d(theEllipse2.center().pnt(), axis2, theEllipse2.majorRadius().value(), theEllipse2.minorRadius().value())
125
126     p1 = GeomAPI_Pnt2d(0, 0)
127     p2 = GeomAPI_Pnt2d(0, 0)
128     anEllipse1.distance(anEllipse2, p1, p2)
129
130     dist1 = model.distancePointPoint(p2, theEllipse1.firstFocus())
131     dist2 = model.distancePointPoint(p2, theEllipse1.secondFocus())
132     self.assertAlmostEqual(dist1 + dist2, 2 * theEllipse1.majorRadius().value())
133
134     dist1 = model.distancePointPoint(p1, theEllipse2.firstFocus())
135     dist2 = model.distancePointPoint(p1, theEllipse2.secondFocus())
136     self.assertAlmostEqual(dist1 + dist2, 2 * theEllipse2.majorRadius().value())
137
138   def assertPoints(self, thePoint1, thePoint2):
139     self.assertAlmostEqual(thePoint1.x(), thePoint2.x())
140     self.assertAlmostEqual(thePoint1.y(), thePoint2.y())
141
142
143   def test_line_tangent(self):
144     """ Test 1. Set tangency between ellipse and a line
145     """
146     aLine = self.mySketch.addLine(10, 10, 90, 40)
147     self.myNbLines += 1
148     self.myDOF += 4
149     model.do()
150
151     self.mySketch.setTangent(self.myEllipse.result(), aLine.result())
152     self.myNbTangency += 1
153     self.myDOF -= 1
154     model.do()
155
156     self.assertTangentLineEllipse(aLine, self.myEllipse)
157
158
159   def test_line_coincident_then_tangent(self):
160     """ Test 2. Set tangency between ellipse and a line, if the extremity of the line is coincident with the ellipse
161     """
162     aLine = self.mySketch.addLine(10, 10, 90, 40)
163     self.mySketch.setCoincident(aLine.endPoint(), self.myEllipse.result())
164     self.myNbLines += 1
165     self.myNbCoincidence += 1
166     self.myDOF += 3
167     model.do()
168
169     self.mySketch.setTangent(self.myEllipse.result(), aLine.result())
170     self.myNbTangency += 1
171     self.myDOF -= 1
172     model.do()
173
174     self.assertTangentLineEllipse(aLine, self.myEllipse)
175
176
177   def test_line_tangent_then_coincident(self):
178     """ Test 3. Set tangency between ellipse and a line, after that apply coincidence of extremity of the line and the ellipse's curve
179     """
180     aLine = self.mySketch.addLine(10, 10, 90, 40)
181     self.myNbLines += 1
182     self.myDOF += 4
183     model.do()
184
185     self.mySketch.setTangent(self.myEllipse.result(), aLine.result())
186     self.myNbTangency += 1
187     self.myDOF -= 1
188     model.do()
189
190     self.mySketch.setCoincident(aLine.startPoint(), self.myEllipse.result())
191     self.myNbCoincidence += 1
192     self.myDOF -= 1
193     model.do()
194
195     self.assertTangentLineEllipse(aLine, self.myEllipse)
196
197
198   def test_line_tangent_then_remove_coincidence(self):
199     """ Test 4. Set tangency between ellipse and a line, which have a coincident point, then remove this coincidence
200     """
201     aLine = self.mySketch.addLine(10, 10, 90, 40)
202     aCoincidence = self.mySketch.setCoincident(aLine.endPoint(), self.myEllipse.result())
203     self.myNbLines += 1
204     self.myNbCoincidence += 1
205     self.myDOF += 3
206     model.do()
207
208     self.mySketch.setTangent(self.myEllipse.result(), aLine.result())
209     self.myNbTangency += 1
210     self.myDOF -= 1
211     model.do()
212
213     self.myDocument.removeFeature(aCoincidence.feature())
214     self.myNbCoincidence -= 1
215     self.myDOF += 1
216     model.do()
217
218     self.assertTangentLineEllipse(aLine, self.myEllipse)
219
220
221   def test_circle_tangent(self):
222     """ Test 5. Set tangency between ellipse and a circle
223     """
224     aCircle = self.mySketch.addCircle(30, 10, 20)
225     self.myNbCircles += 1
226     self.myDOF += 3
227     model.do()
228
229     self.mySketch.setTangent(self.myEllipse.result(), aCircle.defaultResult())
230     self.myNbTangency += 1
231     self.myDOF -= 1
232     model.do()
233
234     self.assertTangentCircleEllipse(aCircle, self.myEllipse)
235
236
237   def test_circle_coincident_then_tangent(self):
238     """ Test 6. Set tangency between ellipse and a circle, if the circle is coincident with start point of ellipse's minor axis
239     """
240     aCircle = self.mySketch.addCircle(30, 10, 20)
241     self.mySketch.setCoincident(self.myMinorStart.coordinates(), aCircle.defaultResult())
242     self.myNbCircles += 1
243     self.myNbCoincidence += 1
244     self.myDOF += 2
245     model.do()
246
247     self.mySketch.setTangent(self.myEllipse.result(), aCircle.defaultResult())
248     self.myNbTangency += 1
249     self.myDOF -= 1
250     model.do()
251
252     self.assertTangentCircleEllipse(aCircle, self.myEllipse)
253     self.assertAlmostEqual(model.distancePointPoint(aCircle.center(), self.myMinorStart.coordinates()), aCircle.radius().value())
254
255
256   def test_arc_tangent(self):
257     """ Test 7. Set tangency between ellipse and a circular arc
258     """
259     anArc = self.mySketch.addArc(30, 10, 20, 10, 40, 10, False)
260     self.myNbArcs += 1
261     self.myDOF += 5
262     model.do()
263
264     self.mySketch.setTangent(self.myEllipse.result(), anArc.results()[-1])
265     self.myNbTangency += 1
266     self.myDOF -= 1
267     model.do()
268
269     self.assertTangentCircleEllipse(anArc, self.myEllipse)
270
271
272   def test_arc_coincident_then_tangent(self):
273     """ Test 8. Set tangency between ellipse and an arc, if the extremity of the arc is coincident with the ellipse
274     """
275     anArc = self.mySketch.addArc(30, 10, 20, 10, 40, 10, False)
276     self.mySketch.setCoincident(anArc.endPoint(), self.myEllipse.result())
277     self.myNbArcs += 1
278     self.myNbCoincidence += 1
279     self.myDOF += 4
280     model.do()
281
282     self.mySketch.setTangent(self.myEllipse.result(), anArc.results()[-1])
283     self.myNbTangency += 1
284     self.myDOF -= 1
285     model.do()
286
287     self.assertTangentCircleEllipse(anArc, self.myEllipse)
288
289
290   def test_arc_tangent_then_coincident(self):
291     """ Test 9. Set tangency between ellipse and an arc, after that apply coincidence of extremity of the arc and the ellipse's curve
292     """
293     anArc = self.mySketch.addArc(30, 10, 20, 10, 40, 10, False)
294     self.myNbArcs += 1
295     self.myDOF += 5
296     model.do()
297
298     self.mySketch.setTangent(self.myEllipse.result(), anArc.results()[-1])
299     self.myNbTangency += 1
300     self.myDOF -= 1
301     model.do()
302
303     self.mySketch.setCoincident(anArc.startPoint(), self.myEllipse.result())
304     self.myNbCoincidence += 1
305     self.myDOF -= 1
306     model.do()
307
308     self.assertTangentCircleEllipse(anArc, self.myEllipse)
309
310
311   def test_arc_tangent_then_remove_coincidence(self):
312     """ Test 10. Set tangency between ellipse and an arc, which have a coincident point, then remove this coincidence
313     """
314     anArc = self.mySketch.addArc(30, 10, 20, 10, 40, 10, False)
315     aCoincidence = self.mySketch.setCoincident(anArc.endPoint(), self.myEllipse.result())
316     self.myNbArcs += 1
317     self.myNbCoincidence += 1
318     self.myDOF += 4
319     model.do()
320
321     self.mySketch.setTangent(self.myEllipse.result(), anArc.results()[-1])
322     self.myNbTangency += 1
323     self.myDOF -= 1
324     model.do()
325
326     self.myDocument.removeFeature(aCoincidence.feature())
327     self.myNbCoincidence -= 1
328     self.myDOF += 1
329     model.do()
330
331     self.assertTangentCircleEllipse(anArc, self.myEllipse)
332
333
334   def test_ellipse_tangent(self):
335     """ Test 11. Set tangency between two ellipses
336     """
337     anEllipse = self.mySketch.addEllipse(10, 10, 20, -50, 20)
338     self.myNbEllipses += 1
339     self.myDOF += 5
340     model.do()
341
342     self.mySketch.setTangent(self.myEllipse.result(), anEllipse.result())
343     self.myNbTangency += 1
344     self.myDOF -= 1
345     model.do()
346
347     self.assertTangentEllipses(anEllipse, self.myEllipse)
348
349
350
351 if __name__ == "__main__":
352     test_program = unittest.main(exit=False)
353     assert test_program.result.wasSuccessful(), "Test failed"
354     assert model.checkPythonDump()