Salome HOME
Updated copyright comment
[modules/shaper.git] / src / SketchPlugin / Test / TestCurveFitting2.py
1 # Copyright (C) 2020-2024  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 creation of B-spline curve passing through the list of points
22 """
23
24 import math
25 import unittest
26
27 from salome.shaper import model
28
29 from GeomAPI import *
30 from ModelAPI import *
31 from ModelHighAPI import *
32 from SketchAPI import *
33 from GeomAlgoAPI import GeomAlgoAPI_ShapeTools as shapetools
34
35 __updated__ = "2020-06-27"
36
37 TOLERANCE = 1.e-7
38 POINT_NAMES = []
39
40 class TestInterpolationExternal(unittest.TestCase):
41   def setUp(self):
42     model.begin()
43     self.myDocument = model.moduleDocument()
44     self.mySketch = model.addSketch(self.myDocument, model.defaultPlane("XOY"))
45     self.myPoints = []
46     self.myPointRefs = []
47     for name in POINT_NAMES:
48       proj = self.mySketch.addProjection(model.selection("VERTEX", name), False)
49       self.myPoints.append(SketchAPI_Point(proj.createdFeature()))
50       self.myPointRefs.append(self.myPoints[-1].coordinates())
51     self.myDOF = 0
52     self.myNbPoints = len(self.myPoints)
53     self.myNbLines = 0
54     self.myNbSplines = 0
55     self.myNbPeriodicSplines = 0
56
57   def tearDown(self):
58     self.checkDOF()
59     model.end()
60     model.testNbSubFeatures(self.mySketch, "SketchPoint", self.myNbPoints)
61     model.testNbSubFeatures(self.mySketch, "SketchLine", self.myNbLines)
62     model.testNbSubFeatures(self.mySketch, "SketchBSpline", self.myNbSplines)
63     model.testNbSubFeatures(self.mySketch, "SketchBSplinePeriodic", self.myNbPeriodicSplines)
64
65
66   def checkDOF(self):
67     self.assertEqual(model.dof(self.mySketch), self.myDOF)
68
69   def checkPointsOnCurve(self, theCurve):
70     for p in self.myPoints:
71       shape = p.defaultResult().shape()
72       self.assertTrue(shapetools.minimalDistance(shape, theCurve) < TOLERANCE)
73
74
75   def test_interpolation(self):
76     """ Test 1. Create B-spline curve by set of points
77     """
78     self.mySpline = self.mySketch.addInterpolation(self.myPointRefs)
79     edge = GeomAPI_Edge(self.mySpline.defaultResult().shape())
80     curve = GeomAPI_BSpline(GeomAPI_Curve(edge))
81     self.myDOF += len(curve.poles()) * 2 - len(self.myPointRefs) - 2
82     self.myNbSplines += 1
83     model.do()
84
85     self.assertTrue(self.mySpline.feature())
86     self.assertTrue(self.mySpline.feature().error() == "")
87     self.assertTrue(self.mySpline.degree().value() == 3)
88     self.assertTrue(curve.isPeriodic() == False)
89     EXPECTED_LEN = 172.237458
90     self.assertTrue(math.fabs(edge.length() - EXPECTED_LEN) < TOLERANCE, "Curve length: {}; expected: {}".format(edge.length(), EXPECTED_LEN))
91     # check points lying of the created curve
92     self.checkPointsOnCurve(edge)
93
94   def test_interpolation_periodic(self):
95     """ Test 2. Create periodic B-spline curve by set of points
96     """
97     self.mySpline = self.mySketch.addInterpolation(self.myPointRefs, periodic = True)
98     edge = GeomAPI_Edge(self.mySpline.defaultResult().shape())
99     curve = GeomAPI_BSpline(GeomAPI_Curve(edge))
100     self.myDOF += len(curve.poles()) * 2 - len(self.myPointRefs)
101     self.myNbPeriodicSplines += 1
102     model.do()
103
104     self.assertTrue(self.mySpline.feature())
105     self.assertTrue(self.mySpline.feature().error() == "")
106     self.assertTrue(self.mySpline.degree().value() == 3)
107     self.assertTrue(curve.isPeriodic() == True)
108     EXPECTED_LEN = 262.60929483
109     self.assertTrue(math.fabs(edge.length() - EXPECTED_LEN) < TOLERANCE, "Curve length: {}; expected: {}".format(edge.length(), EXPECTED_LEN))
110     # check points lying of the created curve
111     self.checkPointsOnCurve(edge)
112
113   def test_interpolation_closed(self):
114     """ Test 3. Create closed but not periodic B-spline curve by set of points
115     """
116     self.mySpline = self.mySketch.addInterpolation(self.myPointRefs, closed = True)
117     edge = GeomAPI_Edge(self.mySpline.defaultResult().shape())
118     curve = GeomAPI_BSpline(GeomAPI_Curve(edge))
119     self.myDOF += len(curve.poles()) * 2 - len(self.myPointRefs) - 3
120     self.myNbSplines += 1
121     model.do()
122
123     self.assertTrue(self.mySpline.feature())
124     self.assertTrue(self.mySpline.feature().error() == "")
125     self.assertTrue(self.mySpline.degree().value() == 3)
126     self.assertTrue(curve.isPeriodic() == False)
127     self.assertTrue(curve.poles()[0].distance(curve.poles()[-1]) < TOLERANCE)
128     EXPECTED_LEN = 274.25674928
129     self.assertTrue(math.fabs(edge.length() - EXPECTED_LEN) < TOLERANCE, "Curve length: {}; expected: {}".format(edge.length(), EXPECTED_LEN))
130     # check points lying of the created curve
131     self.checkPointsOnCurve(edge)
132
133   def test_interpolation_reorder(self):
134     """ Test 4. Check reordering of points works properly
135     """
136     model.do()
137     # use low-level API to create feature
138     curveFitting = featureToCompositeFeature(self.mySketch.feature()).addFeature("SketchCurveFitting")
139     curveFitting.string("type").setValue("interpolation_type")
140     curveFitting.boolean("periodic").setValue(False)
141     curveFitting.boolean("closed").setValue(False)
142     pointsAttr = curveFitting.refattrlist("points")
143     for ind in [0, 3, 4, 2, 1]:
144       pointsAttr.append(self.myPointRefs[ind])
145     # perform reordering
146     curveFitting.customAction("reorder_points")
147     model.do()
148
149     self.mySpline = SketchAPI_BSpline(model.lastSubFeature(self.mySketch, "SketchBSpline"))
150     edge = GeomAPI_Edge(self.mySpline.defaultResult().shape())
151     curve = GeomAPI_BSpline(GeomAPI_Curve(edge))
152     self.myDOF += len(curve.poles()) * 2 - len(self.myPointRefs) - 2
153     self.myNbSplines += 1
154     model.do()
155
156     self.assertTrue(self.mySpline.feature())
157     self.assertTrue(self.mySpline.feature().error() == "")
158     self.assertTrue(self.mySpline.degree().value() == 3)
159     self.assertTrue(curve.isPeriodic() == False)
160     EXPECTED_LEN = 172.237458
161     self.assertTrue(math.fabs(edge.length() - EXPECTED_LEN) < TOLERANCE, "Curve length: {}; expected: {}".format(edge.length(), EXPECTED_LEN))
162     # check points lying of the created curve
163     self.checkPointsOnCurve(edge)
164
165
166 if __name__ == "__main__":
167     # Create a sketch with the external points
168     model.begin()
169     document = model.moduleDocument()
170     coordinates = [(50., 50.), (70., 70.), (80., 30.), (50., 10.), (10., -30.)]
171     for p in coordinates:
172       point3D = model.addPoint(document, p[0], p[1], 0)
173       POINT_NAMES.append(point3D.name())
174     model.end()
175
176     # Run testing
177     test_program = unittest.main(exit=False)
178     assert test_program.result.wasSuccessful(), "Test failed"
179     assert model.checkPythonDump()