Salome HOME
updated copyright message
[modules/shaper.git] / src / SketchPlugin / Test / TestConstraintCoincidenceBSpline.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 B-spline curve 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__ = "2020-01-21"
33
34 class TestCoincidenceBSpline(unittest.TestCase):
35   def setUp(self):
36     model.begin()
37     self.myDocument = model.moduleDocument()
38     self.mySketch = model.addSketch(self.myDocument, model.defaultPlane("XOY"))
39
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])
45
46     self.myDOF = len(self.myPoles) * 2
47     self.myOrigin = self.mySketch.addPoint("Origin")
48     self.myOX = self.mySketch.addLine("OX")
49     model.do()
50     self.myExpectFailure = False
51     self.myNbPoints = len(self.myPoles) + 1
52     self.myNbLines = len(self.myPoles)
53     self.myNbBSplines = 1
54     self.myNbInternalConstraints = len(self.myPoles) * 3 - 2
55     self.myNbCoincidences = 1
56
57   def tearDown(self):
58     model.end()
59     if self.myExpectFailure:
60       assert(self.mySketch.solverError() != ""), "PlaneGCS limitation: if you see this message, then PlaneGCS has solved the set of constraints correctly"
61       model.undo()
62     else:
63       self.checkDOF()
64       model.testNbSubFeatures(self.mySketch, "SketchPoint", self.myNbPoints)
65       model.testNbSubFeatures(self.mySketch, "SketchLine", self.myNbLines)
66       model.testNbSubFeatures(self.mySketch, "SketchBSpline", self.myNbBSplines)
67       model.testNbSubFeatures(self.mySketch, "SketchConstraintCoincidenceInternal", self.myNbInternalConstraints)
68       model.testNbSubFeatures(self.mySketch, "SketchConstraintCoincidence", self.myNbCoincidences)
69
70
71   def checkDOF(self):
72     self.assertEqual(model.dof(self.mySketch), self.myDOF)
73
74   def setCoincidentWithOrigin(self, thePoint):
75     self.mySketch.setCoincident(thePoint, self.myOrigin.coordinates())
76     self.myDOF -= 2
77     model.do()
78
79   def setCoincidentWithOX(self, thePoint):
80     self.mySketch.setCoincident(thePoint, self.myOX.result())
81     self.myDOF -= 1
82     model.do()
83
84   def assertPoles(self):
85     poles = self.mySpline.poles()
86     assert(poles.size() == len(self.myPoles))
87     for index in range(0, len(self.myPoles)):
88       self.assertPoints(self.myPoles[index], poles.pnt(index))
89
90   def assertPoints(self, thePoint1, thePoint2):
91     self.assertAlmostEqual(thePoint1.x(), thePoint2.x())
92     self.assertAlmostEqual(thePoint1.y(), thePoint2.y())
93
94   def assertPointOnLine(self, thePoint, theLineStart, theLineEnd):
95     vecP = [thePoint.x() - theLineStart.x(), thePoint.y() - theLineStart.y()]
96     vecL = [theLineEnd.x() - theLineStart.x(), theLineEnd.y() - theLineStart.y()]
97     dist = math.fabs(vecP[0] * vecL[1] - vecP[1] * vecL[0]) / math.hypot(vecL[0], vecL[1])
98     self.assertAlmostEqual(dist, 0.0)
99
100   def assertPointOnSpline(self, thePoint, theSpline):
101     point = GeomAPI_Pnt(thePoint.x(), thePoint.y(), 0.0)
102     bspline = GeomAPI_Curve(theSpline.results()[-1].resultSubShapePair()[0].shape())
103     proj = bspline.project(point)
104     self.assertAlmostEqual(point.distance(proj), 0.0)
105
106
107   def test_origin_equal_start_point(self):
108     """ Test 1. Make start point of B-spline coincident with the Origin
109     """
110     self.setCoincidentWithOrigin(self.mySpline.startPoint())
111     self.myPoles[0].setX(0)
112     self.myPoles[0].setY(0)
113     self.assertPoles()
114
115   def test_origin_equal_end_point(self):
116     """ Test 2. Make end point of B-spline coincident with the Origin
117     """
118     self.setCoincidentWithOrigin(self.mySpline.endPoint())
119     self.myPoles[-1].setX(0)
120     self.myPoles[-1].setY(0)
121     self.assertPoles()
122
123   def test_origin_equal_pole(self):
124     """ Test 3. Make one of B-spline poles coincident with the Origin
125     """
126     self.setCoincidentWithOrigin(SketchAPI_Point(self.myControlPoles[1]).coordinates())
127     self.myPoles[1].setX(0)
128     self.myPoles[1].setY(0)
129     self.assertPoles()
130
131   def test_origin_on_bspline(self):
132     """ Test 4. (expected failure) Make Origin lying on the B-spline curve
133     """
134     self.mySketch.setCoincident(self.mySpline.defaultResult(), self.myOrigin.coordinates())
135     self.myDOF -= 1
136     model.do()
137     self.myExpectFailure = True
138
139   def test_point_on_bspline(self):
140     """ Test 5. Place free point on the B-spline curve
141     """
142     point = self.mySketch.addPoint(1, 0)
143     self.mySketch.setCoincident(self.myOX.defaultResult(), point.coordinates())
144     self.mySketch.setCoincident(self.mySpline.defaultResult(), point.coordinates())
145     model.do()
146     self.myNbPoints += 1
147     self.myNbCoincidences += 1
148     self.assertPointOnSpline(point.coordinates(), self.mySpline)
149
150
151   def test_start_point_on_axis(self):
152     """ Test 6. Make start point of B-spline coincident with the OX
153     """
154     self.setCoincidentWithOX(self.mySpline.startPoint())
155     self.myPoles[0].setY(0)
156     self.assertPoles()
157
158   def test_end_point_on_axis(self):
159     """ Test 7. Make end point of B-spline coincident with the OX
160     """
161     self.setCoincidentWithOX(self.mySpline.endPoint())
162     self.myPoles[-1].setY(0)
163     self.assertPoles()
164
165   def test_pole_on_axis(self):
166     """ Test 8. Make one of B-spline poles coincident with the OX
167     """
168     self.setCoincidentWithOX(SketchAPI_Point(self.myControlPoles[1]).coordinates())
169     self.myPoles[1].setY(0)
170     self.assertPoles()
171
172
173 if __name__ == "__main__":
174     test_program = unittest.main(exit=False)
175     assert test_program.result.wasSuccessful(), "Test failed"
176     assert model.checkPythonDump()