]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Tests update
authordbv <dbv@opencascade.com>
Thu, 2 Jul 2015 19:25:14 +0000 (22:25 +0300)
committerdbv <dbv@opencascade.com>
Fri, 3 Jul 2015 08:29:06 +0000 (11:29 +0300)
src/FeaturesPlugin/CMakeLists.txt
src/FeaturesPlugin/Test/TestMovement.py [new file with mode: 0644]
src/FeaturesPlugin/Test/TestMultiBoolean.py
src/FeaturesPlugin/Test/TestRotation.py [new file with mode: 0644]
src/FeaturesPlugin/Test/TestSerialBoolean.py [new file with mode: 0644]

index a29526870e0e828d2315efb90fc1425ce2962178..a1e85685aadd133d6c05a96278fb689abce34245 100644 (file)
@@ -73,7 +73,10 @@ INSTALL(TARGETS FeaturesPlugin DESTINATION plugins)
 INSTALL(FILES ${XML_RESOURCES} DESTINATION plugins)
 
 ADD_UNIT_TESTS(TestExtrusion.py
-               TestBoolean.py
                TestRevolution.py
-               TestGroup.py
-               TestMultiBoolean.py)
+               TestMovement.py
+               TestRotation.py
+               TestBoolean.py
+               TestMultiBoolean.py
+                          TestSerialBoolean.py
+               TestGroup.py)
diff --git a/src/FeaturesPlugin/Test/TestMovement.py b/src/FeaturesPlugin/Test/TestMovement.py
new file mode 100644 (file)
index 0000000..058efe4
--- /dev/null
@@ -0,0 +1,134 @@
+"""
+      TestMovement.py
+      Unit test of FeaturesPlugin_Movement class
+
+      class FeaturesPlugin_Movement : public ModelAPI_Feature
+        static const std::string MY_MOVEMENT_ID("Movement");
+        static const std::string MY_OBJECTS_LIST_ID("main_objects");
+        static const std::string MY_AXIS_OBJECT_ID("axis_object");
+        static const std::string MY_DISTANCE_ID("distance");
+
+        data()->addAttribute(OBJECTS_LIST_ID(), ModelAPI_AttributeSelectionList::typeId());
+        data()->addAttribute(AXIS_OBJECT_ID(), ModelAPI_AttributeSelection::typeId());
+        data()->addAttribute(DISTANCE_ID(), ModelAPI_AttributeDouble::typeId());
+"""
+#=========================================================================
+# Initialization of the test
+#=========================================================================
+from ModelAPI import *
+from GeomDataAPI import *
+from GeomAlgoAPI import *
+from GeomAPI import *
+import math
+
+aSession = ModelAPI_Session.get()
+aDocument = aSession.moduleDocument()
+# Create a part for movement
+aSession.startOperation()
+aPartFeature = aDocument.addFeature("Part")
+aSession.finishOperation()
+assert (len(aPartFeature.results()) == 1)
+# Another way is:
+# aPart = aSession.activeDocument()
+aPartResult = modelAPI_ResultPart(aPartFeature.firstResult())
+aPart = aPartResult.partDoc()
+
+#=========================================================================
+# Create a sketch circle to extrude
+#=========================================================================
+aSession.startOperation()
+aCircleSketchFeature = featureToCompositeFeature(aPart.addFeature("Sketch"))
+origin = geomDataAPI_Point(aCircleSketchFeature.attribute("Origin"))
+origin.setValue(0, 0, 0)
+dirx = geomDataAPI_Dir(aCircleSketchFeature.attribute("DirX"))
+dirx.setValue(1, 0, 0)
+norm = geomDataAPI_Dir(aCircleSketchFeature.attribute("Norm"))
+norm.setValue(0, 0, 1)
+# Create circle
+aSketchCircle = aCircleSketchFeature.addFeature("SketchCircle")
+anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("CircleCenter"))
+aCircleRadius = aSketchCircle.real("CircleRadius")
+anCircleCentr.setValue(50, 50)
+aCircleRadius.setValue(20)
+aSession.finishOperation()
+#=========================================================================
+# Make extrusion on circle
+#=========================================================================
+# Build shape from sketcher results
+aCircleSketchResult = aCircleSketchFeature.firstResult()
+aCircleSketchEdges = modelAPI_ResultConstruction(aCircleSketchResult).shape()
+origin = geomDataAPI_Point(aCircleSketchFeature.attribute("Origin")).pnt()
+dirX = geomDataAPI_Dir(aCircleSketchFeature.attribute("DirX")).dir()
+norm = geomDataAPI_Dir(aCircleSketchFeature.attribute("Norm")).dir()
+aCircleSketchFaces = ShapeList()
+GeomAlgoAPI_SketchBuilder.createFaces(
+    origin, dirX, norm, aCircleSketchEdges, aCircleSketchFaces)
+assert (len(aCircleSketchFaces) > 0)
+assert (aCircleSketchFaces[0] is not None)
+# Create extrusion
+aSession.startOperation()
+anExtrusionFt = aPart.addFeature("Extrusion")
+assert (anExtrusionFt.getKind() == "Extrusion")
+# selection type FACE=4
+anExtrusionFt.selectionList("base").append(
+    aCircleSketchResult, aCircleSketchFaces[0])
+anExtrusionFt.string("CreationMethod").setValue("BySizes")
+anExtrusionFt.real("to_size").setValue(50)
+anExtrusionFt.real("from_size").setValue(0)
+anExtrusionFt.real("to_offset").setValue(0) #TODO: remove
+anExtrusionFt.real("from_offset").setValue(0) #TODO: remove
+anExtrusionFt.execute()
+aSession.finishOperation()
+assert (anExtrusionFt.real("to_size").value() == 50)
+
+# Check extrusion results
+assert (len(anExtrusionFt.results()) > 0)
+anExtrusionResult = modelAPI_ResultBody(anExtrusionFt.firstResult())
+assert (anExtrusionResult is not None)
+
+#=========================================================================
+# Create a sketch line to movement
+#=========================================================================
+aSession.startOperation()
+aLineSketchFeature = featureToCompositeFeature(aPart.addFeature("Sketch"))
+origin = geomDataAPI_Point(aLineSketchFeature.attribute("Origin"))
+origin.setValue(0, 0, 0)
+dirx = geomDataAPI_Dir(aLineSketchFeature.attribute("DirX"))
+dirx.setValue(1, 0, 0)
+norm = geomDataAPI_Dir(aLineSketchFeature.attribute("Norm"))
+norm.setValue(0, 0, 1)
+
+aSketchLine = aLineSketchFeature.addFeature("SketchLine")
+aLineStartPoint = geomDataAPI_Point2D(aSketchLine.attribute("StartPoint"))
+aLineEndPoint = geomDataAPI_Point2D(aSketchLine.attribute("EndPoint"))
+aLineStartPoint.setValue(-100, -100)
+aLineEndPoint.setValue(100, -100)
+aSession.finishOperation()
+
+# Build shape from sketcher results
+aLineSketchResult = aLineSketchFeature.firstResult()
+aLineSketchShape = modelAPI_ResultConstruction(aLineSketchResult).shape()
+aShapeExplorer = GeomAPI_ShapeExplorer(aLineSketchShape, GeomAPI_Shape.EDGE)
+aLineEdge = aShapeExplorer.current()
+
+#=========================================================================
+# Test movement
+#=========================================================================
+aSession.startOperation()
+aMoveFt = aPart.addFeature("Movement")
+assert (aMoveFt.getKind() == "Movement")
+aMoveFt.selectionList("main_objects").append(
+    anExtrusionResult, anExtrusionResult.shape())
+aMoveFt.selection("axis_object").setValue(aLineSketchResult, aLineEdge)
+aMoveFt.real("distance").setValue(100)
+aMoveFt.execute()
+aSession.finishOperation()
+assert (aMoveFt.real("distance").value() == 100)
+
+# Check movement results
+aFactory = ModelAPI_Session.get().validators()
+assert (aFactory.validate(aMoveFt))
+assert (len(aMoveFt.results()) > 0)
+aMoveResult = modelAPI_ResultBody(aMoveFt.firstResult())
+assert (aMoveResult is not None)
+
index ce9fa673474e020385339392a5cce9c49b08e99a..65ca076f16edf1b96f33262a8bd0fadb24cc9578 100644 (file)
@@ -170,23 +170,23 @@ aSession.finishOperation()
 
 #=========================================================================
 # Create a boolean cut of cylinders from the box:
-# result of Boolean is the first argument of the next Boolean
 #=========================================================================
 aCurrentResult = modelAPI_ResultBody(aBox.firstResult())
 aSession.startOperation()
-aFactory = ModelAPI_Session.get().validators()
+
+aBooleanFt = aPart.addFeature("Boolean")
+aBooleanFt.selectionList("main_objects").append(aCurrentResult, aCurrentResult.shape())
 for i in xrange(0, N * N):
     anExtrusionResult = modelAPI_ResultBody(anExtrusions[i].firstResult())
-    aBooleanFt = aPart.addFeature("Boolean")
-    aBooleanFt.selectionList("main_objects").append(aCurrentResult, aCurrentResult.shape())
     aBooleanFt.selectionList("tool_objects").append(anExtrusionResult, anExtrusionResult.shape())
-    kBooleanTypeCut = 0
-    aBooleanFt.integer("bool_type").setValue(kBooleanTypeCut)
-    aBooleanFt.execute()
-    assert (aFactory.validate(aBooleanFt))
-    assert (len(aBooleanFt.results()) > 0)
-    aCurrentResult = modelAPI_ResultBody(aBooleanFt.firstResult())
-    assert (aCurrentResult is not None)
+kBooleanTypeCut = 0
+aBooleanFt.integer("bool_type").setValue(kBooleanTypeCut)
+aBooleanFt.execute()
+aFactory = ModelAPI_Session.get().validators()
+assert (aFactory.validate(aBooleanFt))
+assert (len(aBooleanFt.results()) > 0)
+aCurrentResult = modelAPI_ResultBody(aBooleanFt.firstResult())
+assert (aCurrentResult is not None)
 aSession.finishOperation()
 
 #=========================================================================
diff --git a/src/FeaturesPlugin/Test/TestRotation.py b/src/FeaturesPlugin/Test/TestRotation.py
new file mode 100644 (file)
index 0000000..e86b7b8
--- /dev/null
@@ -0,0 +1,134 @@
+"""
+      TestRotation.py
+      Unit test of FeaturesPlugin_Rotation class
+
+      class FeaturesPlugin_Movement : public ModelAPI_Feature
+        static const std::string MY_ROTATION_ID("Rotation");
+        static const std::string MY_OBJECTS_LIST_ID("main_objects");
+        static const std::string MY_AXIS_OBJECT_ID("axis_object");
+        static const std::string MY_ANGLE_ID("angle");
+
+        data()->addAttribute(OBJECTS_LIST_ID(), ModelAPI_AttributeSelectionList::typeId());
+        data()->addAttribute(AXIS_OBJECT_ID(), ModelAPI_AttributeSelection::typeId());
+        data()->addAttribute(ANGLE_ID(), ModelAPI_AttributeDouble::typeId());
+"""
+#=========================================================================
+# Initialization of the test
+#=========================================================================
+from ModelAPI import *
+from GeomDataAPI import *
+from GeomAlgoAPI import *
+from GeomAPI import *
+import math
+
+aSession = ModelAPI_Session.get()
+aDocument = aSession.moduleDocument()
+# Create a part for movement
+aSession.startOperation()
+aPartFeature = aDocument.addFeature("Part")
+aSession.finishOperation()
+assert (len(aPartFeature.results()) == 1)
+# Another way is:
+# aPart = aSession.activeDocument()
+aPartResult = modelAPI_ResultPart(aPartFeature.firstResult())
+aPart = aPartResult.partDoc()
+
+#=========================================================================
+# Create a sketch circle to extrude
+#=========================================================================
+aSession.startOperation()
+aCircleSketchFeature = featureToCompositeFeature(aPart.addFeature("Sketch"))
+origin = geomDataAPI_Point(aCircleSketchFeature.attribute("Origin"))
+origin.setValue(0, 0, 0)
+dirx = geomDataAPI_Dir(aCircleSketchFeature.attribute("DirX"))
+dirx.setValue(1, 0, 0)
+norm = geomDataAPI_Dir(aCircleSketchFeature.attribute("Norm"))
+norm.setValue(0, 0, 1)
+# Create circle
+aSketchCircle = aCircleSketchFeature.addFeature("SketchCircle")
+anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("CircleCenter"))
+aCircleRadius = aSketchCircle.real("CircleRadius")
+anCircleCentr.setValue(50, 50)
+aCircleRadius.setValue(20)
+aSession.finishOperation()
+#=========================================================================
+# Make extrusion on circle
+#=========================================================================
+# Build shape from sketcher results
+aCircleSketchResult = aCircleSketchFeature.firstResult()
+aCircleSketchEdges = modelAPI_ResultConstruction(aCircleSketchResult).shape()
+origin = geomDataAPI_Point(aCircleSketchFeature.attribute("Origin")).pnt()
+dirX = geomDataAPI_Dir(aCircleSketchFeature.attribute("DirX")).dir()
+norm = geomDataAPI_Dir(aCircleSketchFeature.attribute("Norm")).dir()
+aCircleSketchFaces = ShapeList()
+GeomAlgoAPI_SketchBuilder.createFaces(
+    origin, dirX, norm, aCircleSketchEdges, aCircleSketchFaces)
+assert (len(aCircleSketchFaces) > 0)
+assert (aCircleSketchFaces[0] is not None)
+# Create extrusion
+aSession.startOperation()
+anExtrusionFt = aPart.addFeature("Extrusion")
+assert (anExtrusionFt.getKind() == "Extrusion")
+# selection type FACE=4
+anExtrusionFt.selectionList("base").append(
+    aCircleSketchResult, aCircleSketchFaces[0])
+anExtrusionFt.string("CreationMethod").setValue("BySizes")
+anExtrusionFt.real("to_size").setValue(50)
+anExtrusionFt.real("from_size").setValue(0)
+anExtrusionFt.real("to_offset").setValue(0) #TODO: remove
+anExtrusionFt.real("from_offset").setValue(0) #TODO: remove
+anExtrusionFt.execute()
+aSession.finishOperation()
+assert (anExtrusionFt.real("to_size").value() == 50)
+
+# Check extrusion results
+assert (len(anExtrusionFt.results()) > 0)
+anExtrusionResult = modelAPI_ResultBody(anExtrusionFt.firstResult())
+assert (anExtrusionResult is not None)
+
+#=========================================================================
+# Create a sketch line to rotation
+#=========================================================================
+aSession.startOperation()
+aLineSketchFeature = featureToCompositeFeature(aPart.addFeature("Sketch"))
+origin = geomDataAPI_Point(aLineSketchFeature.attribute("Origin"))
+origin.setValue(0, 0, 0)
+dirx = geomDataAPI_Dir(aLineSketchFeature.attribute("DirX"))
+dirx.setValue(1, 0, 0)
+norm = geomDataAPI_Dir(aLineSketchFeature.attribute("Norm"))
+norm.setValue(0, 0, 1)
+
+aSketchLine = aLineSketchFeature.addFeature("SketchLine")
+aLineStartPoint = geomDataAPI_Point2D(aSketchLine.attribute("StartPoint"))
+aLineEndPoint = geomDataAPI_Point2D(aSketchLine.attribute("EndPoint"))
+aLineStartPoint.setValue(-100, -100)
+aLineEndPoint.setValue(100, -100)
+aSession.finishOperation()
+
+# Build shape from sketcher results
+aLineSketchResult = aLineSketchFeature.firstResult()
+aLineSketchShape = modelAPI_ResultConstruction(aLineSketchResult).shape()
+aShapeExplorer = GeomAPI_ShapeExplorer(aLineSketchShape, GeomAPI_Shape.EDGE)
+aLineEdge = aShapeExplorer.current()
+
+#=========================================================================
+# Test rotation
+#=========================================================================
+aSession.startOperation()
+aRotateFt = aPart.addFeature("Rotation")
+assert (aRotateFt.getKind() == "Rotation")
+aRotateFt.selectionList("main_objects").append(
+    anExtrusionResult, anExtrusionResult.shape())
+aRotateFt.selection("axis_object").setValue(aLineSketchResult, aLineEdge)
+aRotateFt.real("angle").setValue(90)
+aRotateFt.execute()
+aSession.finishOperation()
+assert (aRotateFt.real("angle").value() == 90)
+
+# Check rotation results
+aFactory = ModelAPI_Session.get().validators()
+assert (aFactory.validate(aRotateFt))
+assert (len(aRotateFt.results()) > 0)
+aMoveResult = modelAPI_ResultBody(aRotateFt.firstResult())
+assert (aMoveResult is not None)
+
diff --git a/src/FeaturesPlugin/Test/TestSerialBoolean.py b/src/FeaturesPlugin/Test/TestSerialBoolean.py
new file mode 100644 (file)
index 0000000..ce9fa67
--- /dev/null
@@ -0,0 +1,194 @@
+"""
+      TestExtrusion.py
+      Unit test of FeaturesPlugin_Boolean class: many Boolean operations performance
+      
+      class FeaturesPlugin_Extrusion : public ModelAPI_Feature
+        static const std::string MY_EXTRUSION_ID("Extrusion");
+        static const std::string MY_FACE_ID("base");
+        static const std::string MY_SIZE_ID("size");
+        static const std::string MY_REVERSE_ID("reverse");
+          
+        data()->addAttribute(FeaturesPlugin_Extrusion::FACE_ID(), ModelAPI_AttributeSelection::typeId());
+        data()->addAttribute(FeaturesPlugin_Extrusion::SIZE_ID(), ModelAPI_AttributeDouble::typeId());
+        data()->addAttribute(FeaturesPlugin_Extrusion::REVERSE_ID(), ModelAPI_AttributeBoolean::typeId());
+"""
+
+# Number rows and columns of cylinders that cuts the big box. Number of Boolena operations is N*N
+N = 5
+
+#=========================================================================
+# Initialization of the test
+#=========================================================================
+from GeomAPI import *
+from GeomAlgoAPI import *
+from GeomDataAPI import *
+from ModelAPI import *
+
+
+__updated__ = "2015-03-26"
+
+aSession = ModelAPI_Session.get()
+aDocument = aSession.moduleDocument()
+# Create a part for extrusion
+aSession.startOperation()
+aPartFeature = aDocument.addFeature("Part")
+aSession.finishOperation()
+assert (len(aPartFeature.results()) == 1)
+# Another way is:
+# aPart = aSession.activeDocument()
+aPartResult = modelAPI_ResultPart(aPartFeature.firstResult())
+aPart = aPartResult.partDoc()
+
+#=========================================================================
+# Create a list of sketches with one circle inside of each to extrude
+#=========================================================================
+step = 99. / N
+radius = 95. / N / 2.
+
+aSession.startOperation()
+aSketchFeatures = []
+for i in xrange(0, N):
+    for j in xrange(0, N):
+        # Create circle
+        aSketchFeature = featureToCompositeFeature(aPart.addFeature("Sketch"))
+        origin = geomDataAPI_Point(aSketchFeature.attribute("Origin"))
+        origin.setValue(0, 0, 0)
+        dirx = geomDataAPI_Dir(aSketchFeature.attribute("DirX"))
+        dirx.setValue(1, 0, 0)
+        norm = geomDataAPI_Dir(aSketchFeature.attribute("Norm"))
+        norm.setValue(0, 0, 1)
+        aSketchCircle = aSketchFeature.addFeature("SketchCircle")
+        anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("CircleCenter"))
+        aCircleRadius = aSketchCircle.real("CircleRadius")
+        anCircleCentr.setValue(0.5 + step * (0.5 + i), 0.5 + step * (0.5 + j))
+        aCircleRadius.setValue(radius)
+        aSketchFeatures.append(aSketchFeature)
+
+aSession.finishOperation()
+
+#=========================================================================
+# Make extrusions on circles
+#=========================================================================
+# Build shape from sketcher results
+
+# Create extrusions
+aSession.startOperation()
+
+anExtrusions = []
+for i in xrange(0, N * N):
+    aSketchResult = aSketchFeatures[i].firstResult()
+    aSketchEdges = modelAPI_ResultConstruction(aSketchResult).shape()
+    origin = geomDataAPI_Point(aSketchFeatures[i].attribute("Origin")).pnt()
+    dirX = geomDataAPI_Dir(aSketchFeatures[i].attribute("DirX")).dir()
+    norm = geomDataAPI_Dir(aSketchFeatures[i].attribute("Norm")).dir()
+    aSketchFaces = ShapeList()
+    GeomAlgoAPI_SketchBuilder.createFaces(
+        origin, dirX, norm, aSketchEdges, aSketchFaces)
+
+    anExtrusionFt = aPart.addFeature("Extrusion")
+    assert (anExtrusionFt.getKind() == "Extrusion")
+
+    anExtrusionFt.selectionList("base").append(
+        aSketchResult, aSketchFaces[0])
+    anExtrusionFt.string("CreationMethod").setValue("BySizes")
+    anExtrusionFt.real("from_size").setValue(0)
+    anExtrusionFt.real("to_size").setValue(10)
+    anExtrusionFt.real("to_offset").setValue(0) #TODO: remove
+    anExtrusionFt.real("from_offset").setValue(0) #TODO: remove        
+    # v1.0.2 from master
+    # anExtrusionFt.selection("extrusion_face").setValue(
+    #    aSketchResult, aSketchFaces[0])
+    # anExtrusionFt.real("extrusion_size").setValue(10)
+    # anExtrusionFt.boolean("extrusion_reverse").setValue(False)
+    anExtrusions.append(anExtrusionFt)
+
+aSession.finishOperation()
+
+#=========================================================================
+# Make rectangle sketch: base for the box, size 100x100
+#=========================================================================
+aSession.startOperation()
+aQuadrangleSketchFeature = featureToCompositeFeature(aPart.addFeature("Sketch"))
+origin = geomDataAPI_Point(aQuadrangleSketchFeature.attribute("Origin"))
+origin.setValue(0, 0, 0)
+dirx = geomDataAPI_Dir(aQuadrangleSketchFeature.attribute("DirX"))
+dirx.setValue(1, 0, 0)
+norm = geomDataAPI_Dir(aQuadrangleSketchFeature.attribute("Norm"))
+norm.setValue(0, 0, 1)
+aSketchLineA = aQuadrangleSketchFeature.addFeature("SketchLine")
+aSketchLineB = aQuadrangleSketchFeature.addFeature("SketchLine")
+aSketchLineC = aQuadrangleSketchFeature.addFeature("SketchLine")
+aSketchLineD = aQuadrangleSketchFeature.addFeature("SketchLine")
+aLineAStartPoint = geomDataAPI_Point2D(aSketchLineA.attribute("StartPoint"))
+aLineAEndPoint = geomDataAPI_Point2D(aSketchLineA.attribute("EndPoint"))
+aLineBStartPoint = geomDataAPI_Point2D(aSketchLineB.attribute("StartPoint"))
+aLineBEndPoint = geomDataAPI_Point2D(aSketchLineB.attribute("EndPoint"))
+aLineCStartPoint = geomDataAPI_Point2D(aSketchLineC.attribute("StartPoint"))
+aLineCEndPoint = geomDataAPI_Point2D(aSketchLineC.attribute("EndPoint"))
+aLineDStartPoint = geomDataAPI_Point2D(aSketchLineD.attribute("StartPoint"))
+aLineDEndPoint = geomDataAPI_Point2D(aSketchLineD.attribute("EndPoint"))
+aLineAStartPoint.setValue(0., 0.)
+aLineAEndPoint.setValue(0., 100.)
+aLineBStartPoint.setValue(0., 100.)
+aLineBEndPoint.setValue(100., 100.)
+aLineCStartPoint.setValue(100., 100.)
+aLineCEndPoint.setValue(100., 0.)
+aLineDStartPoint.setValue(100., 0.)
+aLineDEndPoint.setValue(0., 0.)
+
+aSession.finishOperation()
+aSession.startOperation()
+
+#=========================================================================
+# Build a big box extrusion
+#=========================================================================
+aSketchResult = aQuadrangleSketchFeature.firstResult()
+aSketchEdges = modelAPI_ResultConstruction(aSketchResult).shape()
+origin = geomDataAPI_Point(aQuadrangleSketchFeature.attribute("Origin")).pnt()
+dirX = geomDataAPI_Dir(aQuadrangleSketchFeature.attribute("DirX")).dir()
+norm = geomDataAPI_Dir(aQuadrangleSketchFeature.attribute("Norm")).dir()
+aSketchFaces = ShapeList()
+GeomAlgoAPI_SketchBuilder.createFaces(
+    origin, dirX, norm, aSketchEdges, aSketchFaces)
+# Create extrusion on them
+aBox = aPart.addFeature("Extrusion")
+aBox.selectionList("base").append(
+    aSketchResult, aSketchFaces[0])
+aBox.string("CreationMethod").setValue("BySizes")
+aBox.real("from_size").setValue(0)
+aBox.real("to_size").setValue(10)
+aBox.real("to_offset").setValue(0) #TODO: remove
+aBox.real("from_offset").setValue(0) #TODO: remove
+# v 1.0.2 from master
+# aBox.selection("extrusion_face").setValue(
+#     aSketchResult, aSketchFaces[0])
+# aBox.real("extrusion_size").setValue(10)
+# aBox.boolean("extrusion_reverse").setValue(False)
+
+aSession.finishOperation()
+
+
+#=========================================================================
+# Create a boolean cut of cylinders from the box:
+# result of Boolean is the first argument of the next Boolean
+#=========================================================================
+aCurrentResult = modelAPI_ResultBody(aBox.firstResult())
+aSession.startOperation()
+aFactory = ModelAPI_Session.get().validators()
+for i in xrange(0, N * N):
+    anExtrusionResult = modelAPI_ResultBody(anExtrusions[i].firstResult())
+    aBooleanFt = aPart.addFeature("Boolean")
+    aBooleanFt.selectionList("main_objects").append(aCurrentResult, aCurrentResult.shape())
+    aBooleanFt.selectionList("tool_objects").append(anExtrusionResult, anExtrusionResult.shape())
+    kBooleanTypeCut = 0
+    aBooleanFt.integer("bool_type").setValue(kBooleanTypeCut)
+    aBooleanFt.execute()
+    assert (aFactory.validate(aBooleanFt))
+    assert (len(aBooleanFt.results()) > 0)
+    aCurrentResult = modelAPI_ResultBody(aBooleanFt.firstResult())
+    assert (aCurrentResult is not None)
+aSession.finishOperation()
+
+#=========================================================================
+# End of test
+#=========================================================================