1 ## Copyright (C) 2014-2017 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
18 ## email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
21 from GeomAlgoAPI import *
23 from GeomDataAPI import *
24 from ModelAPI import ModelAPI_Feature
26 from salome.shaper.model import sketcher
31 GeomAPI_Shape.SOLID: "GeomAPI_Shape.SOLID",
32 GeomAPI_Shape.FACE: "GeomAPI_Shape.FACE",
33 GeomAPI_Shape.EDGE: "GeomAPI_Shape.EDGE",
34 GeomAPI_Shape.VERTEX: "GeomAPI_Shape.VERTEX"}
37 def generateTests(theFeature, theFeatureName, theTestsList = []):
38 """ Generates tests for theFeature.
39 :param theFeature: feature to test. Should be ModelHighAPI_Interface.
40 :param theFeatureName: feature name to put in test commands.
41 :param theTestsList: list of test to be generated. If empty generates all tests.
43 if "testNbResults" in theTestsList or len(theTestsList) == 0:
44 aNbResults = len(theFeature.results())
45 print "model.testNbResults({}, {})".format(theFeatureName, aNbResults)
47 if "testNbSubResults" in theTestsList or len(theTestsList) == 0:
48 aNbResults = len(theFeature.results())
50 for anIndex in range(0, aNbResults):
51 aNbSubResults.append(theFeature.results()[anIndex].numberOfSubs())
52 print "model.testNbSubResults({}, {})".format(theFeatureName, aNbSubResults)
54 if "testNbSubShapes" in theTestsList or len(theTestsList) == 0:
55 aNbResults = len(theFeature.results())
56 for aShapeType in aShapeTypes:
58 for anIndex in range(0, aNbResults):
59 aShape = theFeature.results()[anIndex].resultSubShapePair()[0].shape()
60 aNbResultSubShapes = 0
61 aShapeExplorer = GeomAPI_ShapeExplorer(aShape, aShapeType)
62 while aShapeExplorer.more():
63 aNbResultSubShapes += 1
64 aShapeExplorer.next();
65 aNbSubShapes.append(aNbResultSubShapes)
66 print "model.testNbSubShapes({}, {}, {})".format(theFeatureName, aShapeTypes[aShapeType], aNbSubShapes)
68 if "testResultsVolumes" in theTestsList or len(theTestsList) == 0:
69 aNbResults = len(theFeature.results())
71 for anIndex in range(0, aNbResults):
72 aResultsVolumes.append(GeomAlgoAPI_ShapeTools_volume(theFeature.results()[anIndex].resultSubShapePair()[0].shape()))
73 print "model.testResultsVolumes({}, [{}])".format(theFeatureName, ", ".join("{:0.27f}".format(i) for i in aResultsVolumes))
76 def testNbResults(theFeature, theExpectedNbResults):
77 """ Tests number of feature results.
78 :param theFeature: feature to test.
79 :param theExpectedNbResults: expected number of results.
81 aNbResults = len(theFeature.results())
82 assert (aNbResults == theExpectedNbResults), "Number of results: {}. Expected: {}.".format(aNbResults, theExpectedNbResults)
85 def testNbSubResults(theFeature, theExpectedNbSubResults):
86 """ Tests number of feature sub-results for each result.
87 :param theFeature: feature to test.
88 :param theExpectedNbSubResults: list of sub-results numbers. Size of list should be equal to len(theFeature.results()).
90 aNbResults = len(theFeature.results())
91 aListSize = len(theExpectedNbSubResults)
92 assert (aNbResults == aListSize), "Number of results: {} not equal to list size: {}.".format(aNbResults, aListSize)
93 for anIndex in range(0, aNbResults):
94 aNbSubResults = theFeature.results()[anIndex].numberOfSubs()
95 anExpectedNbSubResults = theExpectedNbSubResults[anIndex]
96 assert (aNbSubResults == anExpectedNbSubResults), "Number of sub-results for result[{}]: {}. Expected: {}.".format(anIndex, aNbSubResults, anExpectedNbSubResults)
99 def testNbSubShapes(theFeature, theShapeType, theExpectedNbSubShapes):
100 """ Tests number of feature sub-shapes of passed type for each result.
101 :param theFeature: feature to test.
102 :param theShapeType: shape type of sub-shapes to test.
103 :param theExpectedNbSubShapes: list of sub-shapes numbers. Size of list should be equal to len(theFeature.results()).
105 aNbResults = len(theFeature.results())
106 aListSize = len(theExpectedNbSubShapes)
107 assert (aNbResults == aListSize), "Number of results: {} not equal to list size: {}.".format(aNbResults, aListSize)
108 for anIndex in range(0, aNbResults):
109 aNbResultSubShapes = 0
110 anExpectedNbSubShapes = theExpectedNbSubShapes[anIndex]
111 aShape = theFeature.results()[anIndex].resultSubShapePair()[0].shape()
112 aShapeExplorer = GeomAPI_ShapeExplorer(aShape, theShapeType)
113 while aShapeExplorer.more():
114 aNbResultSubShapes += 1
115 aShapeExplorer.next();
116 assert (aNbResultSubShapes == anExpectedNbSubShapes), "Number of sub-shapes of type {} for result[{}]: {}. Expected: {}.".format(aShapeTypes[theShapeType], anIndex, aNbResultSubShapes, anExpectedNbSubShapes)
119 def testResultsVolumes(theFeature, theExpectedResultsVolumes, theNbSignificantDigits = 7):
120 """ Tests results volumes.
121 :param theFeature: feature to test.
122 :param theExpectedResultsVolumes: list of results volumes. Size of list should be equal to len(theFeature.results()).
124 aTolerance = 10**(-theNbSignificantDigits)
125 aNbResults = len(theFeature.results())
126 aListSize = len(theExpectedResultsVolumes)
127 assert (aNbResults == aListSize), "Number of results: {} not equal to list size: {}.".format(aNbResults, aListSize)
128 for anIndex in range(0, aNbResults):
129 aResultVolume = GeomAlgoAPI_ShapeTools_volume(theFeature.results()[anIndex].resultSubShapePair()[0].shape())
130 aResultVolumeStr = "{:0.27f}".format(aResultVolume).lstrip("0").lstrip(".").lstrip("0")
131 anExpectedResultVolume = theExpectedResultsVolumes[anIndex]
132 anExpectedResultVolumeStr = "{:0.27f}".format(anExpectedResultVolume).lstrip("0").lstrip(".").lstrip("0")
133 assert math.fabs(aResultVolume - anExpectedResultVolume) < aTolerance * anExpectedResultVolume, "Volume of result[{}]: {:0.27f}. Expected: {:0.27f}. The first {} significant digits not equal.".format(anIndex, aResultVolume, anExpectedResultVolume, theNbSignificantDigits)
135 def testHaveNamingFaces(theFeature, theModel, thePartDoc) :
136 """ Tests if all faces of result have a name
137 :param theFeature: feature to test.
139 # open transaction since all the checking are performed in tests after model.end() call
141 # Get feature result/sub-result
142 aResult = theFeature.results()[0].resultSubShapePair()[0]
143 # Get result/sub-result shape
144 shape = aResult.shape()
145 # Create shape explorer with desired shape type
146 shapeExplorer = GeomAPI_ShapeExplorer(shape, GeomAPI_Shape.FACE)
147 # Create list, and store selections in it
149 while shapeExplorer.more():
150 selection = theModel.selection(aResult, shapeExplorer.current()) # First argument should be result/sub-result, second is sub-shape on this result/sub-result
151 selectionList.append(selection)
153 # Create group with this selection list
154 Group_1 = theModel.addGroup(thePartDoc, selectionList)
157 # Now you can check that all selected shapes in group have right shape type and name.
158 groupFeature = Group_1.feature()
159 groupSelectionList = groupFeature.selectionList("group_list")
160 assert(groupSelectionList.size() == len(selectionList))
161 for index in range(0, groupSelectionList.size()):
162 attrSelection = groupSelectionList.value(index)
163 shape = attrSelection.value()
164 name = attrSelection.namingName()
165 assert(shape.isFace())
166 assert(name != ""), "String empty"
168 def testHaveNamingEdges(theFeature, theModel, thePartDoc) :
169 """ Tests if all edges of result have a name
170 :param theFeature: feature to test.
172 # Get feature result/sub-result
173 aResult = theFeature.results()[0].resultSubShapePair()[0]
174 # Get result/sub-result shape
175 shape = aResult.shape()
176 # Create shape explorer with desired shape type
177 shapeExplorer = GeomAPI_ShapeExplorer(shape, GeomAPI_Shape.EDGE)
178 # Create list, and store selections in it
180 while shapeExplorer.more():
181 selection = theModel.selection(aResult, shapeExplorer.current()) # First argument should be result/sub-result, second is sub-shape on this result/sub-result
182 selectionList.append(selection)
184 # Create group with this selection list
185 Group_1 = theModel.addGroup(thePartDoc, selectionList)
189 # Now you can check that all selected shapes in group have right shape type and name.
190 groupFeature = Group_1.feature()
191 groupSelectionList = groupFeature.selectionList("group_list")
193 assert(groupSelectionList.size() == len(selectionList))
194 for index in range(0, groupSelectionList.size()):
195 attrSelection = groupSelectionList.value(index)
196 shape = attrSelection.value()
197 name = attrSelection.namingName()
198 assert(shape.isEdge())
199 assert(name != ""), "String empty"
201 def testHaveNamingByType(theFeature, theModel, thePartDoc, theSubshapeType) :
202 """ Tests if all sub-shapes of result have a unique name
203 :param theFeature: feature to test.
204 :param theSubshapeType: type of sub-shape
206 aFirstRes = theFeature.results()[0]
207 # Get number of sub-results
209 nbSubs = aFirstRes.numberOfSubs()
211 # no sub-results => treat current result as a sub
216 shapesList = [] # to append only unique shapes (not isSame)
217 for sub in range(0, nbSubs):
218 # Get feature result/sub-result
220 aResult = aFirstRes.subResult(sub).resultSubShapePair()[0]
222 aResult = aFirstRes.resultSubShapePair()[0]
223 # Get result/sub-result shape
224 shape = aResult.shape()
225 # Create shape explorer with desired shape type
226 shapeExplorer = GeomAPI_ShapeExplorer(shape, theSubshapeType)
227 # Create list, and store selections in it
228 while shapeExplorer.more():
229 current = shapeExplorer.current()
230 if current.isEdge() and GeomAPI.GeomAPI_Edge(current).isDegenerated(): # skip degenerative edges because they are not selected
234 for alreadyThere in shapesList:
235 if alreadyThere.isSame(current):
240 shapesList.append(current)
241 selection = theModel.selection(aResult, current) # First argument should be result/sub-result, second is sub-shape on this result/sub-result
242 selectionList.append(selection)
244 # Create group with this selection list
245 # (do not create group if nothing is selected)
246 if (len(selectionList) == 0):
248 Group_1 = theModel.addGroup(thePartDoc, selectionList)
251 groupSelectionList = Group_1.feature().selectionList("group_list")
252 assert(groupSelectionList.size() == len(selectionList))
254 # Check that all selected shapes in group have right shape type and unique name.
255 checkGroup(Group_1, theSubshapeType)
257 def testHaveNamingSubshapes(theFeature, theModel, thePartDoc) :
258 """ Tests if all vertices/edges/faces of result have a unique name
259 :param theFeature: feature to test.
261 testHaveNamingByType(theFeature, theModel, thePartDoc, GeomAPI_Shape.VERTEX)
262 testHaveNamingByType(theFeature, theModel, thePartDoc, GeomAPI_Shape.EDGE)
263 testHaveNamingByType(theFeature, theModel, thePartDoc, GeomAPI_Shape.FACE)
265 def testNbSubFeatures(theComposite, theKindOfSub, theExpectedCount):
266 """ Tests number of sub-features of the given type
267 :param theComposite composite feature to check its subs
268 :param theKindOfSub kind of sub-feature to calculate count
269 :param theExpectedCount expected number of sub-features
272 for aSub in theComposite.features().list():
273 aFeature = ModelAPI_Feature.feature(aSub)
274 if aFeature is not None and aFeature.getKind() == theKindOfSub:
276 assert (count == theExpectedCount), "Number of sub-features of type {}: {}, expected {}".format(theKindOfSub, count, theExpectedCount)
278 def assertSketchArc(theArcFeature):
279 """ Tests whether the arc is correctly defined
281 aCenterPnt = geomDataAPI_Point2D(theArcFeature.attribute("center_point"))
282 aStartPnt = geomDataAPI_Point2D(theArcFeature.attribute("start_point"))
283 aEndPnt = geomDataAPI_Point2D(theArcFeature.attribute("end_point"))
284 aRadius = theArcFeature.real("radius")
285 aDistCS = sketcher.tools.distancePointPoint(aCenterPnt, aStartPnt)
286 aDistCE = sketcher.tools.distancePointPoint(aCenterPnt, aEndPnt)
287 assert math.fabs(aDistCS - aDistCE) < TOLERANCE, "Wrong arc: center-start distance {}, center-end distance {}".format(aDistCS, aDistCE)
288 assert math.fabs(aRadius.value() -aDistCS) < TOLERANCE, "Wrong arc: radius is {0}, expected {1}".format(aRadius.value(), aDistCS)
290 def checkResult(theFeature,theModel,NbRes,NbSubRes,NbSolid,NbFace,NbEdge,NbVertex):
291 """ Tests numbers of sub-shapes in results
293 theModel.testNbResults(theFeature, NbRes)
294 theModel.testNbSubResults(theFeature, NbSubRes)
295 theModel.testNbSubShapes(theFeature, GeomAPI_Shape.SOLID, NbSolid)
296 theModel.testNbSubShapes(theFeature, GeomAPI_Shape.FACE, NbFace)
297 theModel.testNbSubShapes(theFeature, GeomAPI_Shape.EDGE, NbEdge)
298 theModel.testNbSubShapes(theFeature, GeomAPI_Shape.VERTEX, NbVertex)
300 def checkSketch(theSketch, theDOF = -1):
301 """ Tests the sketch is valid and DoF is equal to the given
303 assert(theSketch.feature().error() == ""), "Sketch failed: {}".format(theSketch.feature().error())
304 assert(theSketch.solverError().value() == ""), "Sketch solver failed: {}".format(theSketch.solverError().value())
306 aDOF = sketcher.tools.dof(theSketch)
307 assert(aDOF == theDOF), "Sketch DoF {} is wrong. Expected {}".format(aDOF, theDOF)
309 def checkGroup(theGroup, theShapeType):
310 """ Check that all selected shapes in group have correct shape type and unique name
312 groupFeature = theGroup.feature()
313 groupSelectionList = groupFeature.selectionList("group_list")
314 presented_names = set()
315 for index in range(0, groupSelectionList.size()):
316 attrSelection = groupSelectionList.value(index)
317 shape = attrSelection.value()
318 name = attrSelection.namingName()
319 if theShapeType == GeomAPI_Shape.VERTEX:
320 assert(shape.isVertex())
321 elif theShapeType == GeomAPI_Shape.EDGE:
322 assert(shape.isEdge())
323 elif theShapeType == GeomAPI_Shape.FACE:
324 assert(shape.isFace())
325 assert(name != ""), "String empty"
326 presented_names.add(name)
327 assert(len(presented_names) == groupSelectionList.size()), "Some names are not unique"