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 constraint coincidence applied for ellipse and its sub-results
27 from salome.shaper import model
30 from SketchAPI import *
32 __updated__ = "2019-09-12"
34 class TestCoincidenceEllipse(unittest.TestCase):
36 axisStart = GeomAPI_Pnt2d(30., 60.)
37 axisEnd = GeomAPI_Pnt2d(80., 50.)
38 passedPoint = GeomAPI_Pnt2d(60., 60.)
41 self.myDocument = model.moduleDocument()
42 self.mySketch = model.addSketch(self.myDocument, model.defaultPlane("XOY"))
43 macroEllipse = self.mySketch.addEllipse(axisStart, axisEnd, passedPoint, False)
45 self.myOrigin = self.mySketch.addPoint("Origin")
46 self.myOX = self.mySketch.addLine("OX")
48 self.myEllipse = SketchAPI_Ellipse(model.lastSubFeature(self.mySketch, "SketchEllipse"))
49 self.myCenter = macroEllipse.center()
50 self.myFocus1 = macroEllipse.focus1()
51 self.myFocus2 = macroEllipse.focus2()
52 self.myMajorAxis = macroEllipse.majorAxis()
53 self.myMajorStart = macroEllipse.majorAxisStart()
54 self.myMajorEnd = macroEllipse.majorAxisEnd()
55 self.myMinorAxis = macroEllipse.minorAxis()
56 self.myMinorStart = macroEllipse.minorAxisStart()
57 self.myMinorEnd = macroEllipse.minorAxisEnd()
58 self.myExpectFailure = False
62 if self.myExpectFailure:
63 assert(self.mySketch.solverError() != ""), "PlaneGCS limitation: if you see this message, then PlaneGCS has solved the set of constraints correctly"
67 self.assertPoints(self.myCenter.coordinates(), self.myEllipse.center())
68 self.assertPoints(self.myFocus1.coordinates(), self.myEllipse.firstFocus())
69 self.assertPoints(self.myFocus2.coordinates(), self.myEllipse.secondFocus())
70 self.assertPoints(self.myMajorStart.coordinates(), self.myEllipse.majorAxisNegative())
71 self.assertPoints(self.myMajorEnd.coordinates(), self.myEllipse.majorAxisPositive())
72 self.assertPoints(self.myMajorAxis.startPoint(), self.myEllipse.majorAxisNegative())
73 self.assertPoints(self.myMajorAxis.endPoint(), self.myEllipse.majorAxisPositive())
74 self.assertPoints(self.myMinorStart.coordinates(), self.myEllipse.minorAxisNegative())
75 self.assertPoints(self.myMinorEnd.coordinates(), self.myEllipse.minorAxisPositive())
76 self.assertPoints(self.myMinorAxis.startPoint(), self.myEllipse.minorAxisNegative())
77 self.assertPoints(self.myMinorAxis.endPoint(), self.myEllipse.minorAxisPositive())
78 model.testNbSubFeatures(self.mySketch, "SketchPoint", 8)
79 model.testNbSubFeatures(self.mySketch, "SketchLine", 3)
80 model.testNbSubFeatures(self.mySketch, "SketchEllipse", 1)
81 model.testNbSubFeatures(self.mySketch, "SketchConstraintCoincidenceInternal", 11)
82 model.testNbSubFeatures(self.mySketch, "SketchConstraintCoincidence", 1)
86 self.assertEqual(model.dof(self.mySketch), self.myDOF)
88 def checkPointFixing(self, thePoint):
89 self.mySketch.setCoincident(thePoint, self.myOrigin.coordinates())
92 if not self.myExpectFailure:
93 self.assertPoints(thePoint, self.myOrigin.coordinates())
94 self.assertGreater(self.myEllipse.majorRadius().value(), 0.0)
95 self.assertGreater(self.myEllipse.minorRadius().value(), 0.0)
97 def assertPoints(self, thePoint1, thePoint2):
98 self.assertAlmostEqual(thePoint1.x(), thePoint2.x())
99 self.assertAlmostEqual(thePoint1.y(), thePoint2.y())
101 def checkPointOnAxis(self, thePoint):
102 self.mySketch.setCoincident(thePoint, self.myOX.result())
105 if not self.myExpectFailure:
106 self.assertAlmostEqual(thePoint.y(), 0.0)
107 self.assertGreater(self.myEllipse.majorRadius().value(), 0.0)
108 self.assertGreater(self.myEllipse.minorRadius().value(), 0.0)
110 def checkPointOnLine(self, thePoint, theLineStart, theLineEnd):
111 vecP = [thePoint.x() - theLineStart.x(), thePoint.y() - theLineStart.y()]
112 vecL = [theLineEnd.x() - theLineStart.x(), theLineEnd.y() - theLineStart.y()]
113 dist = math.fabs(vecP[0] * vecL[1] - vecP[1] * vecL[0]) / math.hypot(vecL[0], vecL[1])
115 self.assertAlmostEqual(dist, 0.0)
116 self.assertGreater(self.myEllipse.majorRadius().value(), 0.0)
117 self.assertGreater(self.myEllipse.minorRadius().value(), 0.0)
119 def checkPointOnEllipse(self, thePoint, theEllipse):
120 firstFocus2d = GeomAPI_Pnt2d(theEllipse.firstFocus().x(), theEllipse.firstFocus().y())
121 distPF1 = model.distancePointPoint(firstFocus2d, thePoint)
122 secondFocus2d = GeomAPI_Pnt2d(theEllipse.secondFocus().x(), theEllipse.secondFocus().y())
123 distPF2 = model.distancePointPoint(secondFocus2d, thePoint)
124 self.assertAlmostEqual(distPF1 + distPF2, 2.0 * theEllipse.majorRadius().value(), 7)
127 def test_concident_center(self):
128 """ Test 1. Make center of ellipse coincident with the Origin
130 self.checkPointFixing(self.myCenter.coordinates())
132 def test_coincident_first_focus(self):
133 """ Test 2. Make first focus of ellipse coincident with the Origin
135 self.checkPointFixing(self.myFocus1.coordinates())
137 def test_coincident_second_focus(self):
138 """ Test 3. Make second focus of ellipse coincident with the Origin
140 self.checkPointFixing(self.myFocus2.coordinates())
142 def test_coincident_major_axis_start(self):
143 """ Test 4. Make start point on the major axis of ellipse coincident with the Origin
145 self.checkPointFixing(self.myMajorStart.coordinates())
147 def test_coincident_major_axis_end(self):
148 """ Test 5. Make end point on the major axis of ellipse coincident with the Origin
150 self.checkPointFixing(self.myMajorEnd.coordinates())
152 def test_coincident_minor_axis_start(self):
153 """ Test 6. Make start point on the minor axis of ellipse coincident with the Origin
155 self.checkPointFixing(self.myMinorStart.coordinates())
157 def test_coincident_minor_axis_end(self):
158 """ Test 7. Make end point on the minor axis of ellipse coincident with the Origin.
159 Check solver is failed to compute the coincidence.
161 self.myExpectFailure = True
162 self.checkPointFixing(self.myMinorEnd.coordinates())
165 def test_center_on_line(self):
166 """ Test 8. Make center of ellipse coincident with the OX
168 self.checkPointOnAxis(self.myCenter.coordinates())
170 def test_first_focus_on_line(self):
171 """ Test 9. Make first focus of ellipse coincident with the OX
173 self.checkPointOnAxis(self.myFocus1.coordinates())
175 def test_second_focus_on_line(self):
176 """ Test 10. Make second focus of ellipse coincident with the OX
178 self.checkPointOnAxis(self.myFocus2.coordinates())
180 def test_major_axis_start_on_line(self):
181 """ Test 11. Make start point on the major axis of ellipse coincident with the OX
183 self.checkPointOnAxis(self.myMajorStart.coordinates())
185 def test_major_axis_end_on_line(self):
186 """ Test 12. Make end point on the major axis of ellipse coincident with the OX
188 self.checkPointOnAxis(self.myMajorEnd.coordinates())
190 def test_minor_axis_start_on_line(self):
191 """ Test 13. Make start point on the minor axis of ellipse coincident with the OX
193 self.checkPointOnAxis(self.myMinorStart.coordinates())
195 def test_minor_axis_end_on_line(self):
196 """ Test 14. Make end point on the minor axis of ellipse coincident with the OX
198 self.myExpectFailure = True
199 self.checkPointOnAxis(self.myMinorEnd.coordinates())
202 def test_origin_on_major_axis(self):
203 """ Test 15. Make origin coincident with the major axis of the ellipse
205 self.mySketch.setCoincident(self.myMajorAxis.result(), self.myOrigin.coordinates())
208 self.checkPointOnLine(self.myOrigin.coordinates(), self.myMajorStart.coordinates(), self.myMajorEnd.coordinates())
210 def test_origin_on_minor_axis(self):
211 """ Test 16. Make origin coincident with the minor axis of the ellipse
213 self.mySketch.setCoincident(self.myMinorAxis.result(), self.myOrigin.coordinates())
216 # solver shows wrong result
217 assert(self.mySketch.solverError() != ""), "PlaneGCS limitation: if you see this message, then PlaneGCS has solved the set of constraints correctly"
220 # move ellipse and set coincidence once again
222 self.mySketch.move(self.myMinorStart, 20, 10)
224 self.mySketch.setCoincident(self.myMinorAxis.results()[-1], self.myOrigin.coordinates())
226 self.checkPointOnLine(self.myOrigin.coordinates(), self.myMinorStart.coordinates(), self.myMinorEnd.coordinates())
229 def test_origin_on_ellipse(self):
230 """ Test 17. Make origin coincident with the ellipse
232 self.mySketch.setCoincident(self.myEllipse.results()[-1], self.myOrigin.coordinates())
235 self.checkPointOnEllipse(self.myOrigin.coordinates(), self.myEllipse)
238 if __name__ == "__main__":
239 test_program = unittest.main(exit=False)
240 assert test_program.result.wasSuccessful(), "Test failed"
241 assert model.checkPythonDump()