2 TestFilletInteracting.py
3 Unit test of SketchPlugin_Fillet feature.
4 In scope of interaction with another constraints applied to filleted features.
8 from GeomDataAPI import *
12 from salome.shaper import model
14 __updated__ = "2017-03-06"
16 def isArcLineSmooth(theArc, theLine, theTolerance):
17 aCenter = geomDataAPI_Point2D(theArc.attribute("center_point"))
18 aDistance = distancePointLine(aCenter, theLine)
19 aRadius = arcRadius(theArc)
20 return math.fabs(aRadius - aDistance) < theTolerance
22 def isArcArcSmooth(theArc1, theArc2, theTolerance):
23 aCenter1 = geomDataAPI_Point2D(theArc1.attribute("center_point"))
24 aCenter2 = geomDataAPI_Point2D(theArc2.attribute("center_point"))
25 aDistance = model.distancePointPoint(aCenter1, aCenter2)
26 aRadius1 = arcRadius(theArc1)
27 aRadius2 = arcRadius(theArc2)
28 aRadSum = aRadius1 + aRadius2
29 aRadDiff = math.fabs(aRadius1 - aRadius2)
30 return math.fabs(aDistance - aRadSum) < theTolerance or math.fabs(aDistance - aRadDiff) < theTolerance
32 def arcRadius(theArc):
33 aCenter = geomDataAPI_Point2D(theArc.attribute("center_point"))
34 aStart = geomDataAPI_Point2D(theArc.attribute("start_point"))
35 return model.distancePointPoint(aCenter, aStart)
37 def distancePointLine(thePoint, theLine):
38 aLineStart = geomDataAPI_Point2D(theLine.attribute("StartPoint"))
39 aLineEnd = geomDataAPI_Point2D(theLine.attribute("EndPoint"))
40 aLength = model.distancePointPoint(aLineStart, aLineEnd)
41 aDir1x, aDir1y = aLineEnd.x() - aLineStart.x(), aLineEnd.y() - aLineStart.y()
42 aDir2x, aDir2y = thePoint.x() - aLineStart.x(), thePoint.y() - aLineStart.y()
43 aCross = aDir1x * aDir2y - aDir1y * aDir2x
44 return math.fabs(aCross) / aLength
48 class TestFilletInteracting(unittest.TestCase):
51 self.myDocument = model.moduleDocument()
52 self.mySketch = model.addSketch(self.myDocument, model.defaultPlane("XOY"))
53 self.myTolerance = 1.e-6
58 self.assertTrue(model.checkPythonDump())
63 self.assertEqual(model.dof(self.mySketch), self.myDOF)
65 def collectFeatures(self):
67 for aSubObj in self.mySketch.features().list():
68 aFeature = ModelAPI.ModelAPI_Feature.feature(aSubObj)
69 if aFeature is not None:
70 if self.myFeatures.get(aFeature.getKind()) == None:
71 self.myFeatures[aFeature.getKind()] = 1
73 self.myFeatures[aFeature.getKind()] += 1
75 def checkNbFeatures(self, theFeatureKind, theFeatureCount):
76 if theFeatureCount == 0:
77 self.assertIsNone(self.myFeatures.get(theFeatureKind))
79 self.assertIsNotNone(self.myFeatures.get(theFeatureKind), "No features of kind {0} but expected {1}".format(theFeatureKind, theFeatureCount))
80 self.assertEqual(self.myFeatures[theFeatureKind], theFeatureCount, "Observed number of {0} is {1} but expected {2}".format(theFeatureKind, self.myFeatures[theFeatureKind], theFeatureCount))
82 def checkFillet(self):
83 aPtPtCoincidences = self.getCoincidences()
84 for coinc in aPtPtCoincidences:
85 aConnectedFeatures = self.connectedFeatures(coinc)
86 self.assertEqual(len(aConnectedFeatures), 2)
87 if aConnectedFeatures[0].getKind() == "SketchArc":
88 if aConnectedFeatures[1].getKind() == "SketchArc":
89 self.assertTrue(isArcArcSmooth(aConnectedFeatures[0], aConnectedFeatures[1], self.myTolerance))
90 elif aConnectedFeatures[1].getKind() == "SketchLine":
91 self.assertTrue(isArcLineSmooth(aConnectedFeatures[0], aConnectedFeatures[1], self.myTolerance))
92 elif aConnectedFeatures[0].getKind() == "SketchLine" and aConnectedFeatures[1].getKind() == "SketchArc":
93 self.assertTrue(isArcLineSmooth(aConnectedFeatures[1], aConnectedFeatures[0], self.myTolerance))
95 def getCoincidences(self):
97 for aSubObj in self.mySketch.features().list():
98 aSubFeature = ModelAPI.ModelAPI_Feature.feature(aSubObj)
99 if aSubFeature is not None and aSubFeature.getKind() == "SketchConstraintCoincidence":
100 anEntityA = aSubFeature.refattr("ConstraintEntityA")
101 anEntityB = aSubFeature.refattr("ConstraintEntityB")
102 if not anEntityA.isObject() and not anEntityB.isObject():
103 aCoincidences.append(aSubFeature)
106 def connectedFeatures(self, theCoincidence):
107 anEntityA = theCoincidence.refattr("ConstraintEntityA")
108 anEntityB = theCoincidence.refattr("ConstraintEntityB")
109 aFeatureA = ModelAPI.ModelAPI_Feature.feature(anEntityA.attr().owner())
110 aFeatureB = ModelAPI.ModelAPI_Feature.feature(anEntityB.attr().owner())
111 return [aFeatureA, aFeatureB]
114 def test_fillet_two_lines(self):
115 """ Test 1. Fillet on two connected lines
117 aSketchLineA = self.mySketch.addLine(10., 10., 20., 10.)
118 aSketchLineB = self.mySketch.addLine(10., 10., 10., 20.)
121 self.mySketch.setCoincident(aSketchLineA.startPoint(), aSketchLineB.startPoint())
125 self.mySketch.setFillet(aSketchLineA.startPoint())
131 self.collectFeatures()
132 self.checkNbFeatures("SketchLine", 2)
133 self.checkNbFeatures("SketchArc", 1)
134 self.checkNbFeatures("SketchConstraintCoincidence", 2)
135 self.checkNbFeatures("SketchConstraintTangent", 2)
136 self.checkNbFeatures("SketchFillet", 0)
138 model.testNbSubShapes(self.mySketch, GeomAPI_Shape.FACE, [0])
139 model.testNbSubShapes(self.mySketch, GeomAPI_Shape.EDGE, [3])
140 model.testNbSubShapes(self.mySketch, GeomAPI_Shape.VERTEX, [6])
142 def test_wrong_fillet_two_lines(self):
143 """ Test 2. Check the fillet is wrong on two connected lines when selecting incorrect point
145 aSketchLineA = self.mySketch.addLine(10., 10., 20., 10.)
146 aSketchLineB = self.mySketch.addLine(10., 10., 10., 20.)
149 self.mySketch.setCoincident(aSketchLineA.startPoint(), aSketchLineB.startPoint())
153 aFillet = self.mySketch.setFillet(aSketchLineA.endPoint())
157 self.collectFeatures()
158 self.checkNbFeatures("SketchLine", 2)
159 self.checkNbFeatures("SketchArc", 0) # no arcs should be created
160 self.checkNbFeatures("SketchConstraintCoincidence", 1) # number of coincidences should not change
161 self.checkNbFeatures("SketchConstraintTangent", 0) # no tangencies should not be created
162 self.checkNbFeatures("SketchFillet", 1) # fillet feature should still exist. it should be wrong
164 model.testNbSubShapes(self.mySketch, GeomAPI_Shape.FACE, [0])
165 model.testNbSubShapes(self.mySketch, GeomAPI_Shape.EDGE, [2])
166 model.testNbSubShapes(self.mySketch, GeomAPI_Shape.VERTEX, [4])
168 # remove fillet for correct python dump
169 self.myDocument.removeFeature(aFillet.feature())
171 def test_fillet_arc_line(self):
172 """ Test 3. Fillet on connected arc and line
174 aSketchLine = self.mySketch.addLine(10., 10., 20., 10.)
175 aSketchArc = self.mySketch.addArc(20., 10., 20., 20., 10., 10., False)
178 self.mySketch.setCoincident(aSketchLine.startPoint(), aSketchArc.endPoint())
182 self.mySketch.setFillet(aSketchLine.startPoint())
188 self.collectFeatures()
189 self.checkNbFeatures("SketchLine", 1)
190 self.checkNbFeatures("SketchArc", 2)
191 self.checkNbFeatures("SketchConstraintCoincidence", 2)
192 self.checkNbFeatures("SketchConstraintTangent", 2)
193 self.checkNbFeatures("SketchFillet", 0)
195 model.testNbSubShapes(self.mySketch, GeomAPI_Shape.FACE, [0])
196 model.testNbSubShapes(self.mySketch, GeomAPI_Shape.EDGE, [3])
197 model.testNbSubShapes(self.mySketch, GeomAPI_Shape.VERTEX, [6])
199 def test_fillet_two_arcs(self):
200 """ Test 4. Fillet on two connected arcs
202 aSketchArc1 = self.mySketch.addArc(20., 0., 20., 20., 10., 17.32050807568877293, False)
203 aSketchArc2 = self.mySketch.addArc(20., 34.64101615137754586, 20., 14.64101615137754586, 10., 17.32050807568877293, True)
206 self.mySketch.setCoincident(aSketchArc1.endPoint(), aSketchArc2.endPoint())
210 self.mySketch.setFillet(aSketchArc1.endPoint())
216 self.collectFeatures()
217 self.checkNbFeatures("SketchLine", 0)
218 self.checkNbFeatures("SketchArc", 3)
219 self.checkNbFeatures("SketchConstraintCoincidence", 2)
220 self.checkNbFeatures("SketchConstraintTangent", 2)
221 self.checkNbFeatures("SketchFillet", 0)
223 model.testNbSubShapes(self.mySketch, GeomAPI_Shape.FACE, [0])
224 model.testNbSubShapes(self.mySketch, GeomAPI_Shape.EDGE, [3])
225 model.testNbSubShapes(self.mySketch, GeomAPI_Shape.VERTEX, [6])
227 def test_fillet_with_horizontal_vertical(self):
228 """ Test 5. Fillet on two connected lines in case of Horizontal or Vertical constraints applied
230 aSketchLineA = self.mySketch.addLine(10., 10., 20., 10.)
231 aSketchLineB = self.mySketch.addLine(10., 10., 10., 20.)
234 self.mySketch.setCoincident(aSketchLineA.startPoint(), aSketchLineB.startPoint())
238 self.mySketch.setHorizontal(aSketchLineA.result())
239 self.mySketch.setVertical(aSketchLineB.result())
243 self.mySketch.setFillet(aSketchLineA.startPoint())
249 self.collectFeatures()
250 self.checkNbFeatures("SketchLine", 2)
251 self.checkNbFeatures("SketchArc", 1)
252 self.checkNbFeatures("SketchConstraintCoincidence", 2)
253 self.checkNbFeatures("SketchConstraintTangent", 2)
254 self.checkNbFeatures("SketchConstraintHorizontal", 1)
255 self.checkNbFeatures("SketchConstraintVertical", 1)
256 self.checkNbFeatures("SketchFillet", 0)
258 model.testNbSubShapes(self.mySketch, GeomAPI_Shape.FACE, [0])
259 model.testNbSubShapes(self.mySketch, GeomAPI_Shape.EDGE, [3])
260 model.testNbSubShapes(self.mySketch, GeomAPI_Shape.VERTEX, [6])
262 def test_fillet_with_orthogonal(self):
263 """ Test 6. Fillet on two connected lines in case of Perpendicular constraint applied
265 aSketchLineA = self.mySketch.addLine(10., 10., 20., 10.)
266 aSketchLineB = self.mySketch.addLine(10., 10., 10., 20.)
269 self.mySketch.setCoincident(aSketchLineA.startPoint(), aSketchLineB.startPoint())
273 self.mySketch.setPerpendicular(aSketchLineA.result(), aSketchLineB.result())
277 self.mySketch.setFillet(aSketchLineA.startPoint())
283 self.collectFeatures()
284 self.checkNbFeatures("SketchLine", 2)
285 self.checkNbFeatures("SketchArc", 1)
286 self.checkNbFeatures("SketchConstraintCoincidence", 2)
287 self.checkNbFeatures("SketchConstraintTangent", 2)
288 self.checkNbFeatures("SketchConstraintPerpendicular", 1)
289 self.checkNbFeatures("SketchFillet", 0)
291 model.testNbSubShapes(self.mySketch, GeomAPI_Shape.FACE, [0])
292 model.testNbSubShapes(self.mySketch, GeomAPI_Shape.EDGE, [3])
293 model.testNbSubShapes(self.mySketch, GeomAPI_Shape.VERTEX, [6])
295 def test_fillet_with_parallel(self):
296 """ Test 7. Fillet on two connected lines in case of Parallel constraint applied
298 aSketchLineA = self.mySketch.addLine(10., 10., 20., 10.)
299 aSketchLineB = self.mySketch.addLine(10., 10., 10., 20.)
302 self.mySketch.setCoincident(aSketchLineA.startPoint(), aSketchLineB.startPoint())
306 # third line to apply parallel constraint
307 aSketchLineC = self.mySketch.addLine(10., 0., 20., 5.)
309 self.mySketch.setParallel(aSketchLineB.result(), aSketchLineC.result())
313 self.mySketch.setFillet(aSketchLineA.startPoint())
319 self.collectFeatures()
320 self.checkNbFeatures("SketchLine", 3)
321 self.checkNbFeatures("SketchArc", 1)
322 self.checkNbFeatures("SketchConstraintCoincidence", 2)
323 self.checkNbFeatures("SketchConstraintTangent", 2)
324 self.checkNbFeatures("SketchConstraintParallel", 1)
325 self.checkNbFeatures("SketchFillet", 0)
327 model.testNbSubShapes(self.mySketch, GeomAPI_Shape.FACE, [0])
328 model.testNbSubShapes(self.mySketch, GeomAPI_Shape.EDGE, [4])
329 model.testNbSubShapes(self.mySketch, GeomAPI_Shape.VERTEX, [8])
331 def test_fillet_with_equal_lines(self):
332 """ Test 8. Fillet on two connected lines in case of Equal constraint applied
334 aSketchLineA = self.mySketch.addLine(10., 10., 20., 10.)
335 aSketchLineB = self.mySketch.addLine(10., 10., 10., 20.)
338 self.mySketch.setCoincident(aSketchLineA.startPoint(), aSketchLineB.startPoint())
342 self.mySketch.setEqual(aSketchLineA.result(), aSketchLineB.result())
346 self.mySketch.setFillet(aSketchLineA.startPoint())
347 self.myDOF += 2 # Equal has been removed
352 self.collectFeatures()
353 self.checkNbFeatures("SketchLine", 2)
354 self.checkNbFeatures("SketchArc", 1)
355 self.checkNbFeatures("SketchConstraintCoincidence", 2)
356 self.checkNbFeatures("SketchConstraintTangent", 2)
357 self.checkNbFeatures("SketchConstraintEqual", 0) # Equal constraint expected to be removed
358 self.checkNbFeatures("SketchFillet", 0)
360 model.testNbSubShapes(self.mySketch, GeomAPI_Shape.FACE, [0])
361 model.testNbSubShapes(self.mySketch, GeomAPI_Shape.EDGE, [3])
362 model.testNbSubShapes(self.mySketch, GeomAPI_Shape.VERTEX, [6])
364 def test_fillet_with_equal_arcs(self):
365 """ Test 9. Fillet on two connected arcs in case of Equal constraint applied
367 aSketchArc1 = self.mySketch.addArc(20., 0., 20., 20., 10., 17.32050807568877293, False)
368 aSketchArc2 = self.mySketch.addArc(20., 34.64101615137754586, 20., 14.64101615137754586, 10., 17.32050807568877293, True)
371 self.mySketch.setCoincident(aSketchArc1.endPoint(), aSketchArc2.endPoint())
375 self.mySketch.setEqual(aSketchArc1.results()[1], aSketchArc2.results()[1])
379 self.mySketch.setFillet(aSketchArc1.endPoint())
380 self.myDOF += 2 # Equal has been removed
385 self.collectFeatures()
386 self.checkNbFeatures("SketchLine", 0)
387 self.checkNbFeatures("SketchArc", 3)
388 self.checkNbFeatures("SketchConstraintCoincidence", 2)
389 self.checkNbFeatures("SketchConstraintTangent", 2)
390 self.checkNbFeatures("SketchConstraintEqual", 0) # Equal constraint expected to be removed
391 self.checkNbFeatures("SketchFillet", 0)
393 model.testNbSubShapes(self.mySketch, GeomAPI_Shape.FACE, [0])
394 model.testNbSubShapes(self.mySketch, GeomAPI_Shape.EDGE, [3])
395 model.testNbSubShapes(self.mySketch, GeomAPI_Shape.VERTEX, [6])
397 def test_fillet_with_length(self):
398 """ Test 10. Fillet on two connected lines in case of Length constraint applied
400 aSketchLineA = self.mySketch.addLine(10., 10., 20., 10.)
401 aSketchLineB = self.mySketch.addLine(10., 10., 10., 20.)
404 self.mySketch.setCoincident(aSketchLineA.startPoint(), aSketchLineB.startPoint())
408 self.mySketch.setLength(aSketchLineA.result(), 15.)
412 self.mySketch.setFillet(aSketchLineA.startPoint())
418 self.collectFeatures()
419 self.checkNbFeatures("SketchLine", 2)
420 self.checkNbFeatures("SketchArc", 1)
421 self.checkNbFeatures("SketchConstraintCoincidence", 2)
422 self.checkNbFeatures("SketchConstraintTangent", 2)
423 self.checkNbFeatures("SketchConstraintLength", 0) # Length constraint expected to be removed
424 self.checkNbFeatures("SketchFillet", 0)
426 model.testNbSubShapes(self.mySketch, GeomAPI_Shape.FACE, [0])
427 model.testNbSubShapes(self.mySketch, GeomAPI_Shape.EDGE, [3])
428 model.testNbSubShapes(self.mySketch, GeomAPI_Shape.VERTEX, [6])
430 def test_fillet_with_radius(self):
431 """ Test 11. Fillet on connected arc and line in case of Radius constraint is applied to arc
433 aSketchLine = self.mySketch.addLine(10., 10., 20., 10.)
434 aSketchArc = self.mySketch.addArc(0., 10., 0., 20., 10., 10., True)
437 self.mySketch.setCoincident(aSketchLine.startPoint(), aSketchArc.endPoint())
441 self.mySketch.setRadius(aSketchArc.results()[1], 12.)
445 self.mySketch.setFillet(aSketchLine.startPoint())
451 self.collectFeatures()
452 self.checkNbFeatures("SketchLine", 1)
453 self.checkNbFeatures("SketchArc", 2)
454 self.checkNbFeatures("SketchConstraintCoincidence", 2)
455 self.checkNbFeatures("SketchConstraintTangent", 2)
456 self.checkNbFeatures("SketchConstraintRadius", 1)
457 self.checkNbFeatures("SketchFillet", 0)
459 model.testNbSubShapes(self.mySketch, GeomAPI_Shape.FACE, [0])
460 model.testNbSubShapes(self.mySketch, GeomAPI_Shape.EDGE, [3])
461 model.testNbSubShapes(self.mySketch, GeomAPI_Shape.VERTEX, [6])
463 def test_fillet_with_distance(self):
464 """ Test 12. Fillet on two connected lines in case of Distance constraint applied
466 aSketchLineA = self.mySketch.addLine(10., 10., 20., 10.)
467 aSketchLineB = self.mySketch.addLine(10., 10., 10., 20.)
470 self.mySketch.setCoincident(aSketchLineA.startPoint(), aSketchLineB.startPoint())
474 # third line to apply Distance constraints
475 aSketchLineC = self.mySketch.addLine(10., 0., 20., 5.)
477 self.mySketch.setDistance(aSketchLineB.startPoint(), aSketchLineC.result(), 10.)
478 self.mySketch.setDistance(aSketchLineB.endPoint(), aSketchLineC.result(), 5.)
482 self.mySketch.setFillet(aSketchLineA.startPoint())
483 self.myDOF += 2 # Distance has been removed
488 self.collectFeatures()
489 self.checkNbFeatures("SketchLine", 3)
490 self.checkNbFeatures("SketchArc", 1)
491 self.checkNbFeatures("SketchConstraintCoincidence", 2)
492 self.checkNbFeatures("SketchConstraintTangent", 2)
493 self.checkNbFeatures("SketchConstraintDistance", 1) # only one Distance should be left
494 self.checkNbFeatures("SketchFillet", 0)
496 model.testNbSubShapes(self.mySketch, GeomAPI_Shape.FACE, [0])
497 model.testNbSubShapes(self.mySketch, GeomAPI_Shape.EDGE, [4])
498 model.testNbSubShapes(self.mySketch, GeomAPI_Shape.VERTEX, [8])
500 def test_fillet_with_fixed_point(self):
501 """ Test 13. Fillet on two connected lines in case of Fixed constraint applied to the fillet point
503 aSketchLineA = self.mySketch.addLine(10., 10., 20., 10.)
504 aSketchLineB = self.mySketch.addLine(10., 10., 10., 20.)
507 self.mySketch.setCoincident(aSketchLineA.startPoint(), aSketchLineB.startPoint())
511 self.mySketch.setFixed(aSketchLineA.startPoint())
515 self.mySketch.setFillet(aSketchLineA.startPoint())
516 self.myDOF += 3 # Fixed constraint has been removed
521 self.collectFeatures()
522 self.checkNbFeatures("SketchLine", 2)
523 self.checkNbFeatures("SketchArc", 1)
524 self.checkNbFeatures("SketchConstraintCoincidence", 2)
525 self.checkNbFeatures("SketchConstraintTangent", 2)
526 self.checkNbFeatures("SketchConstraintFixed", 0) # Fixed constraint expected to be removed
527 self.checkNbFeatures("SketchFillet", 0)
529 model.testNbSubShapes(self.mySketch, GeomAPI_Shape.FACE, [0])
530 model.testNbSubShapes(self.mySketch, GeomAPI_Shape.EDGE, [3])
531 model.testNbSubShapes(self.mySketch, GeomAPI_Shape.VERTEX, [6])
533 def test_fillet_with_fixed_line(self):
534 """ Test 14. Fillet on two connected lines in case of Fixed constraint applied to one of lines
536 aSketchLineA = self.mySketch.addLine(10., 10., 20., 10.)
537 aSketchLineB = self.mySketch.addLine(10., 10., 10., 20.)
540 self.mySketch.setCoincident(aSketchLineA.startPoint(), aSketchLineB.startPoint())
544 self.mySketch.setFixed(aSketchLineA.result())
548 self.mySketch.setFillet(aSketchLineA.startPoint())
554 self.collectFeatures()
555 self.checkNbFeatures("SketchLine", 2)
556 self.checkNbFeatures("SketchArc", 1)
557 self.checkNbFeatures("SketchConstraintCoincidence", 2)
558 self.checkNbFeatures("SketchConstraintTangent", 2)
559 self.checkNbFeatures("SketchConstraintLength", 0) # Fixed constraint expected to be kept
560 self.checkNbFeatures("SketchFillet", 0)
562 model.testNbSubShapes(self.mySketch, GeomAPI_Shape.FACE, [0])
563 model.testNbSubShapes(self.mySketch, GeomAPI_Shape.EDGE, [3])
564 model.testNbSubShapes(self.mySketch, GeomAPI_Shape.VERTEX, [6])
566 def test_fillet_with_angle(self):
567 """ Test 15. Fillet on two connected lines in case of Perpendicular constraint applied
569 aSketchLineA = self.mySketch.addLine(10., 10., 20., 10.)
570 aSketchLineB = self.mySketch.addLine(10., 10., 10., 20.)
573 self.mySketch.setCoincident(aSketchLineA.startPoint(), aSketchLineB.startPoint())
577 self.mySketch.setAngle(aSketchLineA.result(), aSketchLineB.result(), 60.)
581 self.mySketch.setFillet(aSketchLineA.startPoint())
587 self.collectFeatures()
588 self.checkNbFeatures("SketchLine", 2)
589 self.checkNbFeatures("SketchArc", 1)
590 self.checkNbFeatures("SketchConstraintCoincidence", 2)
591 self.checkNbFeatures("SketchConstraintTangent", 2)
592 self.checkNbFeatures("SketchConstraintAngle", 1)
593 self.checkNbFeatures("SketchFillet", 0)
595 model.testNbSubShapes(self.mySketch, GeomAPI_Shape.FACE, [0])
596 model.testNbSubShapes(self.mySketch, GeomAPI_Shape.EDGE, [3])
597 model.testNbSubShapes(self.mySketch, GeomAPI_Shape.VERTEX, [6])
600 if __name__ == '__main__':