1 # Copyright (C) 2019-2020 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 "Tangent" applied to B-spline and another entity
27 from salome.shaper import model
30 from GeomAlgoAPI import *
31 from SketchAPI import *
33 __updated__ = "2020-01-22"
35 class TestTangentBSpline(unittest.TestCase):
38 self.myDocument = model.moduleDocument()
39 self.mySketch = model.addSketch(self.myDocument, model.defaultPlane("XOY"))
40 self.myPoles = [GeomAPI_Pnt2d(-10, -30), GeomAPI_Pnt2d(20, -15), GeomAPI_Pnt2d(-10, 0), GeomAPI_Pnt2d(20, 15), GeomAPI_Pnt2d(-10, 30)]
41 self.myWeights = [1, 3, 5, 3, 1]
42 self.mySpline = self.mySketch.addSpline(poles = self.myPoles, weights = self.myWeights)
43 self.myControlPoles = self.mySpline.controlPoles(auxiliary = [0, 1, 2, 3, 4])
44 self.myControlLines = self.mySpline.controlPolygon(auxiliary = [0, 1, 2, 3])
47 self.myExpectedFailure = False
48 self.myDOF = len(self.myPoles) * 2
49 self.myNbPoints = len(self.myPoles)
50 self.myNbLines = len(self.myPoles) - 1
54 self.myNbEllipticArcs = 0
56 self.myNbInternals = len(self.myPoles) * 3 - 2
57 self.myNbCoincidence = 0
62 if self.myExpectedFailure:
63 assert(self.mySketch.solverError() != ""), "PlaneGCS limitation: if you see this message, then PlaneGCS has solved the set of constraints correctly"
67 model.testNbSubFeatures(self.mySketch, "SketchPoint", self.myNbPoints)
68 model.testNbSubFeatures(self.mySketch, "SketchLine", self.myNbLines)
69 model.testNbSubFeatures(self.mySketch, "SketchArc", self.myNbArcs)
70 model.testNbSubFeatures(self.mySketch, "SketchCircle", self.myNbCircles)
71 model.testNbSubFeatures(self.mySketch, "SketchEllipse", self.myNbEllipses)
72 model.testNbSubFeatures(self.mySketch, "SketchEllipticArc", self.myNbEllipticArcs)
73 model.testNbSubFeatures(self.mySketch, "SketchBSpline", self.myNbBSplines)
74 model.testNbSubFeatures(self.mySketch, "SketchConstraintCoincidenceInternal", self.myNbInternals)
75 model.testNbSubFeatures(self.mySketch, "SketchConstraintCoincidence", self.myNbCoincidence)
76 model.testNbSubFeatures(self.mySketch, "SketchConstraintTangent", self.myNbTangency)
80 self.assertEqual(model.dof(self.mySketch), self.myDOF)
82 def assertTangentFeatures(self, theFeature1, theFeature2):
83 shapes = [theFeature1.results()[-1].resultSubShapePair()[0].shape(),
84 theFeature2.results()[-1].resultSubShapePair()[0].shape()]
87 if e.isLine() or e.isArc() or e.isEllipse():
89 e.setRange(params[0] - 100, params[1] + 100)
90 # TODO (azv): complete checking the tangent curves
92 def assertPointLineDistance(self, thePoint, theLine, theExpectedDistance = 0):
93 dist = model.distancePointLine(thePoint, theLine)
94 self.assertAlmostEqual(dist, theExpectedDistance)
96 def assertTangentLineCircle(self, theLine, theCircle):
97 self.assertPointLineDistance(theCircle.center(), theLine, theCircle.radius().value())
99 def assertTangentLineEllipse(self, theLine, theEllipse):
100 aLine = GeomAPI_Lin2d(theLine.startPoint().pnt(), theLine.endPoint().pnt())
101 projF1 = aLine.project(theEllipse.firstFocus().pnt())
102 projF2 = aLine.project(theEllipse.secondFocus().pnt())
104 distF1P1 = model.distancePointPoint(theEllipse.firstFocus(), projF1)
105 distF2P2 = model.distancePointPoint(theEllipse.secondFocus(), projF2)
107 tgPoint = GeomAPI_Pnt2d((projF1.x() * distF2P2 + projF2.x() * distF1P1) / (distF1P1 + distF2P2), (projF1.y() * distF2P2 + projF2.y() * distF1P1) / (distF1P1 + distF2P2))
108 distF1T = model.distancePointPoint(theEllipse.firstFocus(), tgPoint)
109 distF2T = model.distancePointPoint(theEllipse.secondFocus(), tgPoint)
110 self.assertAlmostEqual(distF1T + distF2T, 2 * theEllipse.majorRadius().value())
113 def test_line_tangent(self):
114 """ Test 1. Set tangency between B-spline and a line
116 aLine = self.mySketch.addLine(10, -10, 90, 40)
121 self.mySketch.setTangent(self.mySpline.result(), aLine.result())
122 self.myNbTangency += 1
126 self.assertTangentFeatures(aLine, self.mySpline)
128 def test_circle_tangent(self):
129 """ Test 2. Set tangency between B-spline and a circle
131 aCircle = self.mySketch.addCircle(10, 10, 20)
132 self.myNbCircles += 1
136 self.mySketch.setTangent(self.mySpline.result(), aCircle.defaultResult())
137 self.myNbTangency += 1
141 self.assertTangentFeatures(aCircle, self.mySpline)
143 def test_arc_tangent(self):
144 """ Test 3. Set tangency between B-spline and an arc
146 anArc = self.mySketch.addArc(10, 10, 20, 10, 10, 20, False)
151 self.mySketch.setTangent(self.mySpline.result(), anArc.defaultResult())
152 self.myNbTangency += 1
156 self.assertTangentFeatures(anArc, self.mySpline)
158 def test_ellipse_tangent(self):
159 """ Test 4. Set tangency between B-spline and an ellipse
161 anEllipse = self.mySketch.addEllipse(10, 10, 20, 10, 7)
162 self.myNbEllipses += 1
166 self.mySketch.setTangent(self.mySpline.result(), anEllipse.defaultResult())
167 self.myNbTangency += 1
171 self.assertTangentFeatures(anEllipse, self.mySpline)
173 def test_elliptic_arc_tangent(self):
174 """ Test 5. Set tangency between B-spline and an elliptic arc
176 anEllipticArc = self.mySketch.addEllipticArc(10, 10, 20, 10, 22.2065556157337, 10, 10, 17, True)
177 self.myNbEllipticArcs += 1
181 self.mySketch.setTangent(self.mySpline.result(), anEllipticArc.defaultResult())
182 self.myNbTangency += 1
186 self.assertTangentFeatures(anEllipticArc, self.mySpline)
188 def test_spline_tangent(self):
189 """ Test 6. Set tangency between two B-spline curves
191 aSpline = self.mySketch.addSpline(poles = [(50, -20), (40, 0), (50, 20)])
192 self.myNbBSplines += 1
193 self.myDOF += aSpline.poles().size() * 2
196 self.mySketch.setTangent(self.mySpline.result(), aSpline.result())
197 self.myNbTangency += 1
201 #self.assertTangentFeatures(aSpline, self.mySpline)
202 self.myExpectedFailure = True
205 def test_line_tangent_coincident_by_pole(self):
206 """ Test 7. Set tangency between B-spline and a line coincident with B-spline start point
208 aLine = self.mySketch.addLine(10, -10, 90, 40)
213 self.mySketch.setCoincident(self.mySpline.startPoint(), aLine.result())
214 self.myNbCoincidence += 1
218 self.mySketch.setTangent(self.mySpline.result(), aLine.result())
219 self.myNbTangency += 1
223 self.assertPointLineDistance(aLine.startPoint(), self.myControlLines[0])
224 self.assertPointLineDistance(aLine.endPoint(), self.myControlLines[0])
226 def test_circle_tangent_coincident_by_pole(self):
227 """ Test 8. Set tangency between B-spline and a circle coincident with B-spline end point
229 aCircle = self.mySketch.addCircle(10, 10, 20)
230 self.myNbCircles += 1
234 self.mySketch.setCoincident(self.mySpline.startPoint(), aCircle.defaultResult())
235 self.myNbCoincidence += 1
239 self.mySketch.setTangent(self.mySpline.result(), aCircle.defaultResult())
240 self.myNbTangency += 1
244 self.assertTangentLineCircle(SketchAPI_Line(self.myControlLines[0]), aCircle)
246 def test_arc_tangent_coincident_by_pole(self):
247 """ Test 9. Set tangency between B-spline and an arc coincident with B-spline end point
249 anArc = self.mySketch.addArc(10, 10, 20, 10, 10, 20, False)
254 self.mySketch.setCoincident(self.mySpline.endPoint(), anArc.defaultResult())
255 self.myNbCoincidence += 1
259 self.mySketch.setTangent(self.mySpline.result(), anArc.defaultResult())
260 self.myNbTangency += 1
264 self.assertTangentLineCircle(SketchAPI_Line(self.myControlLines[-1]), anArc)
266 def test_ellipse_tangent_coincident_by_pole(self):
267 """ Test 10. Set tangency between B-spline and an ellipse coincident with B-spline start point
269 anEllipse = self.mySketch.addEllipse(10, 10, 20, 10, 7)
270 self.myNbEllipses += 1
274 self.mySketch.setCoincident(self.mySpline.startPoint(), anEllipse.defaultResult())
275 self.myNbCoincidence += 1
279 self.mySketch.setTangent(self.mySpline.result(), anEllipse.defaultResult())
280 self.myNbTangency += 1
284 self.assertTangentLineEllipse(SketchAPI_Line(self.myControlLines[0]), anEllipse)
286 def test_elliptic_arc_tangent_coincident_by_pole(self):
287 """ Test 11. Set tangency between B-spline and an elliptic arc coincident with B-spline start point
289 anEllipticArc = self.mySketch.addEllipticArc(10, 10, 20, 10, 22.2065556157337, 10, 10, 17, True)
290 self.myNbEllipticArcs += 1
294 self.mySketch.setCoincident(self.mySpline.startPoint(), anEllipticArc.defaultResult())
295 self.myNbCoincidence += 1
299 self.mySketch.setTangent(self.mySpline.result(), anEllipticArc.defaultResult())
300 self.myNbTangency += 1
304 self.assertTangentLineEllipse(SketchAPI_Line(self.myControlLines[0]), anEllipticArc)
307 def test_line_tangent_coincident_by_boundaries(self):
308 """ Test 12. Set tangency between B-spline and a line, coincident by their start points
310 aLine = self.mySketch.addLine(10, -10, 90, 40)
315 self.mySketch.setCoincident(self.mySpline.startPoint(), aLine.startPoint())
316 self.myNbCoincidence += 1
320 self.mySketch.setTangent(self.mySpline.result(), aLine.result())
321 self.myNbTangency += 1
325 self.assertPointLineDistance(aLine.endPoint(), self.myControlLines[0])
327 def test_arc_tangent_coincident_by_boundaries(self):
328 """ Test 13. Set tangency between B-spline and an arc, coincident by their start points
330 anArc = self.mySketch.addArc(10, 10, 20, 10, 10, 20, False)
335 self.mySketch.setCoincident(self.mySpline.startPoint(), anArc.startPoint())
336 self.myNbCoincidence += 1
340 self.mySketch.setTangent(self.mySpline.result(), anArc.defaultResult())
341 self.myNbTangency += 1
345 self.assertTangentLineCircle(SketchAPI_Line(self.myControlLines[0]), anArc)
347 def test_elliptic_arc_tangent_coincident_by_boundaries(self):
348 """ Test 14. Set tangency between B-spline and an elliptic arc, coincident by their start points
350 anEllipticArc = self.mySketch.addEllipticArc(10, -10, 20, -10, 22.2065556157337, -10, 10, 3, True)
351 self.myNbEllipticArcs += 1
355 self.mySketch.setCoincident(self.mySpline.startPoint(), anEllipticArc.startPoint())
356 self.myNbCoincidence += 1
360 self.mySketch.setTangent(self.mySpline.result(), anEllipticArc.defaultResult())
361 self.myNbTangency += 1
365 self.assertTangentLineEllipse(SketchAPI_Line(self.myControlLines[0]), anEllipticArc)
367 def test_spline_tangent_coincident_by_boundaries(self):
368 """ Test 15. Set tangency between two B-spline curves coincident with B-spline start point
370 aSpline = self.mySketch.addSpline(poles = [(50, -20), (40, 0), (50, 20)])
371 self.myNbBSplines += 1
372 self.myDOF += aSpline.poles().size() * 2
375 self.mySketch.setCoincident(self.mySpline.startPoint(), aSpline.startPoint())
376 self.myNbCoincidence += 1
380 self.mySketch.setTangent(self.mySpline.result(), aSpline.result())
381 self.myNbTangency += 1
385 #self.assertPointLineDistance(aSpline.poles()[1], self.myControlLines[0])
386 self.myExpectedFailure = True
389 def test_line_tangent_coincident_by_aux(self):
390 """ Test 16. Set tangency between B-spline and a line, coincident by their start points
392 aLine = self.mySketch.addLine(10, -10, 90, 40)
397 self.mySketch.setCoincident(SketchAPI_Point(self.myControlPoles[0]).coordinates(), aLine.startPoint())
398 self.myNbCoincidence += 1
402 self.mySketch.setTangent(self.mySpline.result(), aLine.result())
403 self.myNbTangency += 1
407 self.assertPointLineDistance(aLine.endPoint(), self.myControlLines[0])
409 def test_arc_tangent_coincident_by_aux(self):
410 """ Test 17. Set tangency between B-spline and an arc, coincident by their start points
412 anArc = self.mySketch.addArc(10, 10, 20, 10, 10, 20, False)
417 self.mySketch.setCoincident(SketchAPI_Point(self.myControlPoles[0]).coordinates(), anArc.startPoint())
418 self.myNbCoincidence += 1
422 self.mySketch.setTangent(self.mySpline.result(), anArc.defaultResult())
423 self.myNbTangency += 1
427 self.assertTangentLineCircle(SketchAPI_Line(self.myControlLines[0]), anArc)
429 def test_elliptic_arc_tangent_coincident_by_aux(self):
430 """ Test 18. Set tangency between B-spline and an elliptic arc, coincident by their start points
432 anEllipticArc = self.mySketch.addEllipticArc(10, 10, 20, 10, 22.2065556157337, 10, 10, 17, True)
433 self.myNbEllipticArcs += 1
437 self.mySketch.setCoincident(SketchAPI_Point(self.myControlPoles[0]).coordinates(), anEllipticArc.startPoint())
438 self.myNbCoincidence += 1
442 self.mySketch.setTangent(self.mySpline.result(), anEllipticArc.defaultResult())
443 self.myNbTangency += 1
447 self.assertTangentLineEllipse(SketchAPI_Line(self.myControlLines[0]), anEllipticArc)
449 def test_spline_tangent_coincident_by_aux(self):
450 """ Test 19. Set tangency between two B-spline curves coincident with B-spline start point
452 aSpline = self.mySketch.addSpline(poles = [(50, -20), (40, 0), (50, 20)])
453 self.myNbBSplines += 1
454 self.myDOF += aSpline.poles().size() * 2
457 self.mySketch.setCoincident(SketchAPI_Point(self.myControlPoles[0]).coordinates(), aSpline.startPoint())
458 self.myNbCoincidence += 1
462 self.mySketch.setTangent(self.mySpline.result(), aSpline.result())
463 self.myNbTangency += 1
467 #self.assertPointLineDistance(aSpline.poles().pnt(1), self.myControlLines[0])
468 self.myExpectedFailure = True
472 if __name__ == "__main__":
473 test_program = unittest.main(exit=False)
474 assert test_program.result.wasSuccessful(), "Test failed"
475 #assert model.checkPythonDump()