]> SALOME platform Git repositories - modules/shaper.git/blob - src/GeomAPI/Test/TestCone.py
Salome HOME
[Code coverage GeomAPI]: Improve coverage quality
[modules/shaper.git] / src / GeomAPI / Test / TestCone.py
1 ## Copyright (C) 2018-20xx  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
18 ## email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
19 ##
20
21 from GeomAPI import *
22 from SketchAPI import *
23
24 from salome.shaper import model
25
26 import math
27
28 TOLERANCE = 1.e-7
29
30 def assertCircle(theEdge, theCenter, theRadius):
31     assert(theEdge.isCircle())
32     aCircle = theEdge.circle()
33     assert(aCircle.center().distance(theCenter) < TOLERANCE), "({}, {}, {}) != expected ({}, {}, {})".format(aCircle.center().x(), aCircle.center().y(), aCircle.center().z(), theCenter.x(), theCenter.y(), theCenter.z())
34     assert(math.fabs(aCircle.radius() - theRadius) < TOLERANCE), "Radius {} != {}".format(aCircle.radius(), theRadius)
35
36 def checkCircleEdge(theDocument, theEdgeName, theCenter, theRadius):
37     anEdge = model.addEdge(theDocument, [model.selection("EDGE", theEdgeName)])
38     aShape = anEdge.result().resultSubShapePair()[0].shape()
39     assert(aShape.isEdge())
40     assertCircle(aShape.edge(), theCenter, theRadius)
41     theDocument.removeFeature(anEdge.feature())
42
43 def checkCircleFace(theDocument, theFaceName, theCenter, theRadius):
44     aFaceFeature = model.addFace(theDocument, [model.selection("FACE", theFaceName)])
45     aShape = aFaceFeature.result().resultSubShapePair()[0].shape()
46     assert(aShape.isFace())
47     aFace = aShape.face();
48     aSubs = aFace.subShapes(GeomAPI.GeomAPI_Shape.EDGE)
49     assert(aSubs.size() == 1)
50     assertCircle(aSubs[0].edge(), theCenter, theRadius)
51     theDocument.removeFeature(aFaceFeature.feature())
52
53 def assertEllipse(theEdge, theFirstFocus, theSecondFocus, theMajorRadius, theMinorRadius):
54     assert(theEdge.isEllipse())
55     anEllipse = theEdge.ellipse()
56     assert(anEllipse.firstFocus().distance(theFirstFocus) < TOLERANCE), "({}, {}, {}) != expected ({}, {}, {})".format(anEllipse.firstFocus().x(), anEllipse.firstFocus().y(), anEllipse.firstFocus().z(), theFirstFocus.x(), theFirstFocus.y(), theFirstFocus.z())
57     assert(anEllipse.secondFocus().distance(theSecondFocus) < TOLERANCE), "({}, {}, {}) != expected ({}, {}, {})".format(anEllipse.secondFocus().x(), anEllipse.secondFocus().y(), anEllipse.secondFocus().z(), theSecondFocus.x(), theSecondFocus.y(), theSecondFocus.z())
58     assert(math.fabs(anEllipse.majorRadius() - theMajorRadius) < TOLERANCE), "Major radius {} != {}".format(anEllipse.majorRadius(), theMajorRadius)
59     assert(math.fabs(anEllipse.minorRadius() - theMinorRadius) < TOLERANCE), "Minor radius {} != {}".format(anEllipse.minorRadius(), theMinorRadius)
60
61 def checkEllipseEdge(theDocument, theEdgeName, theFirstFocus, theSecondFocus, theMajorRadius, theMinorRadius):
62     anEdge = model.addEdge(theDocument, [model.selection("EDGE", theEdgeName)])
63     aShape = anEdge.result().resultSubShapePair()[0].shape()
64     assert(aShape.isEdge())
65     assertEllipse(aShape.edge(), theFirstFocus, theSecondFocus, theMajorRadius, theMinorRadius)
66     theDocument.removeFeature(anEdge.feature())
67
68 def checkEllipseFace(theDocument, theFaceName, theFirstFocus, theSecondFocus, theMajorRadius, theMinorRadius):
69     aFaceFeature = model.addFace(theDocument, [model.selection("FACE", theFaceName)])
70     aShape = aFaceFeature.result().resultSubShapePair()[0].shape()
71     assert(aShape.isFace())
72     aFace = aShape.face();
73     aSubs = aFace.subShapes(GeomAPI.GeomAPI_Shape.EDGE)
74     assert(aSubs.size() == 1)
75     assertEllipse(aSubs[0].edge(), theFirstFocus, theSecondFocus, theMajorRadius, theMinorRadius)
76     theDocument.removeFeature(aFaceFeature.feature())
77
78 def assertCone(theCone, theApex, theAxis, theSemiAngle, theRadius1, theRadius2, theHeight):
79     assert(theCone is not None)
80     assert(theCone.isSemiInfinite() == False)
81     assert(theCone.isInfinite() == False)
82     anApex = theCone.apex()
83     anAxis = theCone.axis()
84     assert(anApex.distance(theApex) < TOLERANCE), "({}, {}, {}) != expected ({}, {}, {})".format(anApex.x(), anApex.y(), anApex.z(), theApex.x(), theApex.y(), theApex.z())
85     assert(anAxis.isParallel(theAxis, TOLERANCE)), "dir({}, {}, {}) is not parallel to dir({}, {}, {})".format(anAxis.x(), anAxis.y(), anAxis.z(), theAxis.x(), theAxis.y(), theAxis.z())
86     assert(math.fabs(theCone.semiAngle() - theSemiAngle) < TOLERANCE), "SemiAngle {} != {}".format(theCone.semiAngle(), theSemiAngle)
87     assert(math.fabs(theCone.radius1() - theRadius1) < TOLERANCE), "Radius1 {} != {}".format(theCone.radius1(), theRadius1)
88     assert(math.fabs(theCone.radius2() - theRadius2) < TOLERANCE), "Radius2 {} != {}".format(theCone.radius2(), theRadius2)
89     assert(math.fabs(theCone.height() - theHeight) < TOLERANCE), "Height {} != {}".format(theCone.height(), theHeight)
90
91 def checkConeFace(theDocument, theFaceName, theApex, theAxis, theSemiAngle, theRadius1, theRadius2, theHeight):
92     # check conical face
93     aFace = model.addFace(theDocument, [model.selection("FACE", theFaceName)])
94     aShape = aFace.result().resultSubShapePair()[0].shape()
95     assert(aShape.isFace())
96     assertCone(aShape.face().getCone(), theApex, theAxis, theSemiAngle, theRadius1, theRadius2, theHeight)
97     theDocument.removeFeature(aFace.feature())
98
99 def checkConeShell(theDocument, theFaceNames, theApex, theAxis, theSemiAngle, theRadius1, theRadius2, theHeight):
100     # check conical shell
101     aSelection = []
102     for name in theFaceNames:
103         aSelection.append(model.selection("FACE", name))
104     aShell = model.addShell(theDocument, aSelection)
105     aShape = aShell.result().resultSubShapePair()[0].shape()
106     assert(aShape.isShell())
107     assertCone(aShape.shell().getCone(), theApex, theAxis, theSemiAngle, theRadius1, theRadius2, theHeight)
108     theDocument.removeFeature(aShell.feature())
109
110 def checkConeAll(theDocument, theFeature, theFaceName, theApex, theAxis, theSemiAngle, theRadius1, theRadius2, theHeight):
111     # check solid
112     aShape = theFeature.result().resultSubShapePair()[0].shape()
113     assert(aShape.isSolid())
114     assertCone(aShape.solid().getCone(), theApex, theAxis, theSemiAngle, theRadius1, theRadius2, theHeight)
115
116     checkConeShell(theDocument, [theFaceName], theApex, theAxis, theSemiAngle, theRadius1, theRadius2, theHeight)
117     checkConeFace(theDocument, theFaceName, theApex, theAxis, theSemiAngle, theRadius1, theRadius2, theHeight)
118
119 def checkSegment(theDocument, theEdgeName, theStartPoint, theEndPoint):
120     anEdgeFeature = model.addEdge(theDocument, [model.selection("EDGE", theEdgeName)])
121     aShape = anEdgeFeature.result().resultSubShapePair()[0].shape()
122     assert(aShape.isEdge())
123     anEdge = aShape.edge()
124     assert(anEdge.isLine())
125     assert(anEdge.firstPoint().distance(theStartPoint) < TOLERANCE)
126     assert(anEdge.lastPoint().distance(theEndPoint) < TOLERANCE)
127     theDocument.removeFeature(anEdgeFeature.feature())
128
129 def checkVertex(theDocument, theVertexName, theCoordinates):
130     aVertex = model.addVertex(theDocument, [model.selection("VERTEX", theVertexName)])
131     aShape = aVertex.result().resultSubShapePair()[0].shape()
132     assert(aShape.isVertex())
133     assert(aShape.vertex().point().distance(theCoordinates) < TOLERANCE)
134     theDocument.removeFeature(aVertex.feature())
135
136 def semiAngle(theRadius1, theRadius2, theHeight):
137     return math.atan(math.fabs(theRadius1 - theRadius2) / theHeight)
138
139
140 model.begin()
141 partSet = model.moduleDocument()
142 Part_1 = model.addPart(partSet)
143 Part_1_doc = Part_1.document()
144 ParamR1 = model.addParameter(Part_1_doc, "R1", "50")
145 ParamR2 = model.addParameter(Part_1_doc, "R2", "5")
146 ParamH = model.addParameter(Part_1_doc, "H", "70")
147 ParamShift = model.addParameter(Part_1_doc, "Shift", "5")
148 ParamAngle = model.addParameter(Part_1_doc, "Angle", "60")
149 Cone_1 = model.addCone(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), "R1", "R2", "H")
150 model.do()
151
152 # Test 1. Check cone
153 aSemiAngle = semiAngle(ParamR1.value(), ParamR2.value(), ParamH.value())
154 anApex = GeomAPI.GeomAPI_Pnt(0, 0, ParamR1.value() / math.tan(aSemiAngle))
155 anAxis = GeomAPI.GeomAPI_Dir(0, 0, 1)
156 checkConeAll(Part_1_doc, Cone_1, "Cone_1_1/Face_1", anApex, anAxis, aSemiAngle, ParamR2.value(), ParamR1.value(), ParamH.value())
157 checkCircleFace(Part_1_doc, "Cone_1_1/Face_2", GeomAPI.GeomAPI_Pnt(0, 0, ParamH.value()), ParamR2.value())
158 checkCircleEdge(Part_1_doc, "[Cone_1_1/Face_1][Cone_1_1/Face_2]", GeomAPI.GeomAPI_Pnt(0, 0, ParamH.value()), ParamR2.value())
159 checkCircleFace(Part_1_doc, "Cone_1_1/Face_3", GeomAPI.GeomAPI_Pnt(0, 0, 0), ParamR1.value())
160 checkCircleEdge(Part_1_doc, "[Cone_1_1/Face_1][Cone_1_1/Face_3]", GeomAPI.GeomAPI_Pnt(0, 0, 0), ParamR1.value())
161 checkSegment(Part_1_doc, "[Cone_1_1/Face_1][weak_name_3]", GeomAPI.GeomAPI_Pnt(ParamR1.value(), 0, 0), GeomAPI.GeomAPI_Pnt(ParamR2.value(), 0, ParamH.value()))
162
163 # Test 2. Update cone radii
164 ParamR1.setValue(0)
165 model.do()
166 aSemiAngle = semiAngle(ParamR1.value(), ParamR2.value(), ParamH.value())
167 anApex.setZ(0)
168 checkConeAll(Part_1_doc, Cone_1, "Cone_1_1/Face_1", anApex, anAxis, aSemiAngle, ParamR1.value(), ParamR2.value(), ParamH.value())
169 checkCircleFace(Part_1_doc, "Cone_1_1/Face_2", GeomAPI.GeomAPI_Pnt(0, 0, ParamH.value()), ParamR2.value())
170 checkCircleEdge(Part_1_doc, "[Cone_1_1/Face_1][Cone_1_1/Face_2]", GeomAPI.GeomAPI_Pnt(0, 0, ParamH.value()), ParamR2.value())
171 checkSegment(Part_1_doc, "[Cone_1_1/Face_1][weak_name_3]", GeomAPI.GeomAPI_Pnt(0, 0, 0), GeomAPI.GeomAPI_Pnt(ParamR2.value(), 0, ParamH.value()))
172 checkVertex(Part_1_doc, "Cone_1_1/Vertex_2", GeomAPI.GeomAPI_Pnt(0, 0, 0))
173
174 ParamR2.setValue(50)
175 ParamR1.setValue(10)
176 model.do()
177 aSemiAngle = semiAngle(ParamR1.value(), ParamR2.value(), ParamH.value())
178 anApex.setZ(-ParamR1.value() / math.tan(aSemiAngle))
179 checkConeAll(Part_1_doc, Cone_1, "Cone_1_1/Face_1", anApex, anAxis, aSemiAngle, ParamR1.value(), ParamR2.value(), ParamH.value())
180 checkCircleFace(Part_1_doc, "Cone_1_1/Face_2", GeomAPI.GeomAPI_Pnt(0, 0, ParamH.value()), ParamR2.value())
181 checkCircleEdge(Part_1_doc, "[Cone_1_1/Face_1][Cone_1_1/Face_2]", GeomAPI.GeomAPI_Pnt(0, 0, ParamH.value()), ParamR2.value())
182 checkCircleFace(Part_1_doc, "Cone_1_1/Face_3", GeomAPI.GeomAPI_Pnt(0, 0, 0), ParamR1.value())
183 checkCircleEdge(Part_1_doc, "[Cone_1_1/Face_1][Cone_1_1/Face_3]", GeomAPI.GeomAPI_Pnt(0, 0, 0), ParamR1.value())
184 checkSegment(Part_1_doc, "[Cone_1_1/Face_1][weak_name_3]", GeomAPI.GeomAPI_Pnt(ParamR1.value(), 0, 0), GeomAPI.GeomAPI_Pnt(ParamR2.value(), 0, ParamH.value()))
185
186 # Test 3. Translate cone
187 Translation_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Cone_1_1")], model.selection("EDGE", "PartSet/OX"), "Shift")
188 anApex.setX(anApex.x() + ParamShift.value())
189 checkConeAll(Part_1_doc, Translation_1, "Translation_1_1/MF:Translated&Cone_1_1/Face_1", anApex, anAxis, aSemiAngle, ParamR1.value(), ParamR2.value(), ParamH.value())
190 checkCircleFace(Part_1_doc, "Translation_1_1/MF:Translated&Cone_1_1/Face_2", GeomAPI.GeomAPI_Pnt(ParamShift.value(), 0, ParamH.value()), ParamR2.value())
191 checkCircleEdge(Part_1_doc, "[Translation_1_1/MF:Translated&Cone_1_1/Face_1][Translation_1_1/MF:Translated&Cone_1_1/Face_2]", GeomAPI.GeomAPI_Pnt(ParamShift.value(), 0, ParamH.value()), ParamR2.value())
192 checkCircleFace(Part_1_doc, "Translation_1_1/MF:Translated&Cone_1_1/Face_3", GeomAPI.GeomAPI_Pnt(ParamShift.value(), 0, 0), ParamR1.value())
193 checkCircleEdge(Part_1_doc, "[Translation_1_1/MF:Translated&Cone_1_1/Face_1][Translation_1_1/MF:Translated&Cone_1_1/Face_3]", GeomAPI.GeomAPI_Pnt(ParamShift.value(), 0, 0), ParamR1.value())
194 checkSegment(Part_1_doc, "[Translation_1_1/MF:Translated&Cone_1_1/Face_1][weak_name_3]", GeomAPI.GeomAPI_Pnt(ParamR1.value() + ParamShift.value(), 0, 0), GeomAPI.GeomAPI_Pnt(ParamR2.value() + ParamShift.value(), 0, ParamH.value()))
195
196 # Test 4. Rotate cone
197 Rotation_1 = model.addRotation(Part_1_doc, [model.selection("SOLID", "Translation_1_1")], model.selection("EDGE", "PartSet/OY"), "Angle")
198 anAngle = ParamAngle.value() * math.pi / 180.0
199 anAxis = GeomAPI.GeomAPI_Dir(math.sin(anAngle), 0, math.cos(anAngle))
200 x, z = anApex.x(), anApex.z()
201 anApex.setX(x * math.cos(anAngle) + z * math.sin(anAngle))
202 anApex.setZ(-x * math.sin(anAngle) + z * math.cos(anAngle))
203 checkConeAll(Part_1_doc, Rotation_1, "Rotation_1_1/MF:Rotated&Cone_1_1/Face_1", anApex, anAxis, aSemiAngle, ParamR1.value(), ParamR2.value(), ParamH.value())
204 aCenter = GeomAPI.GeomAPI_Pnt(ParamShift.value() * math.cos(anAngle) + ParamH.value() * math.sin(anAngle), 0, -ParamShift.value() * math.sin(anAngle) + ParamH.value() * math.cos(anAngle))
205 checkCircleFace(Part_1_doc, "Rotation_1_1/MF:Rotated&Cone_1_1/Face_2", aCenter, ParamR2.value())
206 checkCircleEdge(Part_1_doc, "[Rotation_1_1/MF:Rotated&Cone_1_1/Face_1][Rotation_1_1/MF:Rotated&Cone_1_1/Face_2]", aCenter, ParamR2.value())
207 aCenter = GeomAPI.GeomAPI_Pnt(ParamShift.value() * math.cos(anAngle), 0, -ParamShift.value() * math.sin(anAngle))
208 checkCircleFace(Part_1_doc, "Rotation_1_1/MF:Rotated&Cone_1_1/Face_3", aCenter, ParamR1.value())
209 checkCircleEdge(Part_1_doc, "[Rotation_1_1/MF:Rotated&Cone_1_1/Face_1][Rotation_1_1/MF:Rotated&Cone_1_1/Face_3]", aCenter, ParamR1.value())
210
211 # Test 5. Split cone by plane and check conical shell and elliptic face
212 Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "PartSet/YOZ"), 20, False)
213 Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Rotation_1_1"), model.selection("FACE", "Plane_1")])
214 checkConeShell(Part_1_doc, ["Partition_1_1_1/Modified_Face&Cone_1_1/Face_1", "Partition_1_1_2/Modified_Face&Cone_1_1/Face_1"], anApex, anAxis, aSemiAngle, ParamR1.value(), ParamR2.value(), ParamH.value())
215
216 aFirstFocus = GeomAPI.GeomAPI_Pnt(20, 0, 31.062397266842858)
217 aSecondFocus = GeomAPI.GeomAPI_Pnt(20, 0, -1.0935246846933797)
218 aMajorRadius = 27.91915871311068
219 aMinorRadius = 22.824955511666207
220 checkEllipseFace(Part_1_doc, "_weak_name_1_Partition_1_1_2", aFirstFocus, aSecondFocus, aMajorRadius, aMinorRadius)
221 checkEllipseEdge(Part_1_doc, "Partition_1_1_1/Generated_Edge&Cone_1_1/Face_1", aFirstFocus, aSecondFocus, aMajorRadius, aMinorRadius)
222
223 model.end()