]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Merge remote-tracking branch 'origin/Dev_0.6' V_0.6.0
authormpv <mikhail.ponikarov@opencascade.com>
Mon, 8 Dec 2014 16:43:02 +0000 (19:43 +0300)
committermpv <mikhail.ponikarov@opencascade.com>
Mon, 8 Dec 2014 16:43:02 +0000 (19:43 +0300)
src/FeaturesPlugin/CMakeLists.txt
src/FeaturesPlugin/FeaturesPlugin_Boolean.h
src/FeaturesPlugin/Test/TestBoolean.py [new file with mode: 0644]
src/FeaturesPlugin/Test/TestExtrusion.py [new file with mode: 0644]
src/SketchPlugin/CMakeLists.txt
src/SketchPlugin/Test/TestConstraintConcidence.py
src/SketchPlugin/Test/TestConstraintParallel.py
src/SketchPlugin/Test/TestConstraintPerpendicular.py
src/SketchPlugin/Test/TestConstraintRigid.py [new file with mode: 0644]
src/SketchPlugin/Test/TestHighload.py [new file with mode: 0644]
src/SketchPlugin/Test/TestSnowflake.py [new file with mode: 0644]

index 3fd916de3f8f3dbb10378e52376fc6c66b58bba8..9de0da779701c8dc95d086b7cae44deed770b895 100644 (file)
@@ -1,4 +1,5 @@
 INCLUDE(Common)
+INCLUDE(UnitTest)
 
 SET(PROJECT_HEADERS
     FeaturesPlugin.h
@@ -45,3 +46,6 @@ TARGET_LINK_LIBRARIES(FeaturesPlugin ${PROJECT_LIBRARIES})
 
 INSTALL(TARGETS FeaturesPlugin DESTINATION plugins)
 INSTALL(FILES ${XML_RESOURCES} DESTINATION plugins)
+
+ADD_UNIT_TESTS(TestExtrusion.py
+               TestBoolean.py)
index 021b99da602c34a0904831825132345db713e93f..e9f28ae1dd60580b4844c2a7724dd663ba48cbcd 100644 (file)
@@ -16,8 +16,8 @@ class FeaturesPlugin_Boolean : public ModelAPI_Feature
   /// Extrusion kind
   inline static const std::string& ID()
   {
-    static const std::string MY_CUT_ID("Boolean");
-    return MY_CUT_ID;
+    static const std::string MY_ID("Boolean");
+    return MY_ID;
   }
   /// attribute name of referenced object
   inline static const std::string& OBJECT_ID()
@@ -34,8 +34,8 @@ class FeaturesPlugin_Boolean : public ModelAPI_Feature
   /// attribute name of operation type
   inline static const std::string& TYPE_ID()
   {
-    static const std::string MY_TOOL_ID("bool_type");
-    return MY_TOOL_ID;
+    static const std::string MY_TYPE_ID("bool_type");
+    return MY_TYPE_ID;
   }
 
   enum {
diff --git a/src/FeaturesPlugin/Test/TestBoolean.py b/src/FeaturesPlugin/Test/TestBoolean.py
new file mode 100644 (file)
index 0000000..63f1891
--- /dev/null
@@ -0,0 +1,121 @@
+"""
+      TestBoolean.py
+      Unit test of FeaturesPlugin_Boolean class
+      
+      class FeaturesPlugin_Boolean
+        static const std::string MY_ID("Boolean");
+        static const std::string MY_OBJECT_ID("main_object");
+        static const std::string MY_TOOL_ID("tool_object");
+        static const std::string MY_TYPE_ID("bool_type");
+        
+        data()->addAttribute(FeaturesPlugin_Boolean::OBJECT_ID(), ModelAPI_AttributeReference::type());
+        data()->addAttribute(FeaturesPlugin_Boolean::TOOL_ID(), ModelAPI_AttributeReference::type());
+        data()->addAttribute(FeaturesPlugin_Boolean::TYPE_ID(), ModelAPI_AttributeInteger::type());
+"""
+#=========================================================================
+# Initialization of the test
+#=========================================================================
+from ModelAPI import *
+from GeomDataAPI import *
+from GeomAlgoAPI import *
+
+__updated__ = "2014-11-21"
+
+aSession = ModelAPI_Session.get()
+# Create a part for extrusions & boolean
+aSession.startOperation()
+aPartFeature = aSession.moduleDocument().addFeature("Part")
+aPart = aSession.activeDocument()
+aSession.finishOperation()
+#=========================================================================
+# Create a sketch with circle to extrude
+#=========================================================================
+aSession.startOperation()
+aCircleSketchFeature = modelAPI_CompositeFeature(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)
+diry = geomDataAPI_Dir(aCircleSketchFeature.attribute("DirY"))
+diry.setValue(0, 1, 0)
+norm = geomDataAPI_Dir(aCircleSketchFeature.attribute("Norm"))
+norm.setValue(0, 0, 1)
+aSketchCircle = aCircleSketchFeature.addFeature("SketchCircle")
+anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("CircleCenter"))
+aCircleRadius = aSketchCircle.real("CircleRadius")
+anCircleCentr.setValue(10., 10.)
+aCircleRadius.setValue(50.)
+aSession.finishOperation()
+#=========================================================================
+# Create a sketch with triangle to extrude
+#=========================================================================
+aSession.startOperation()
+aTriangleSketchFeature = modelAPI_CompositeFeature(aPart.addFeature("Sketch"))
+origin = geomDataAPI_Point(aTriangleSketchFeature.attribute("Origin"))
+origin.setValue(0, 0, 0)
+dirx = geomDataAPI_Dir(aTriangleSketchFeature.attribute("DirX"))
+dirx.setValue(1, 0, 0)
+diry = geomDataAPI_Dir(aTriangleSketchFeature.attribute("DirY"))
+diry.setValue(0, 1, 0)
+norm = geomDataAPI_Dir(aTriangleSketchFeature.attribute("Norm"))
+norm.setValue(0, 0, 1)
+aSketchLineA = aTriangleSketchFeature.addFeature("SketchLine")
+aSketchLineB = aTriangleSketchFeature.addFeature("SketchLine")
+aSketchLineC = aTriangleSketchFeature.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"))
+aLineAStartPoint.setValue(25., 25.)
+aLineAEndPoint.setValue(100., 25.)
+aLineBStartPoint.setValue(100., 25.)
+aLineBEndPoint.setValue(60., 75.)
+aLineCStartPoint.setValue(60., 75.)
+aLineCEndPoint.setValue(25., 25.)
+aSession.finishOperation()
+#=========================================================================
+# Make extrusion on circle (cylinder) and triangle (prism)
+#=========================================================================
+# Build shape from sketcher results
+aSession.startOperation()
+extrudedObjects = []
+for eachSketchFeature in [aCircleSketchFeature, aTriangleSketchFeature]:
+    # Build sketch faces
+    aSketchResult = eachSketchFeature.firstResult()
+    aSketchEdges = modelAPI_ResultConstruction(aSketchResult).shape()
+    origin = geomDataAPI_Point(eachSketchFeature.attribute("Origin")).pnt()
+    dirX = geomDataAPI_Dir(eachSketchFeature.attribute("DirX")).dir()
+    dirY = geomDataAPI_Dir(eachSketchFeature.attribute("DirY")).dir()
+    norm = geomDataAPI_Dir(eachSketchFeature.attribute("Norm")).dir()
+    aSketchFaces = ShapeList()
+    GeomAlgoAPI_SketchBuilder.createFaces(
+        origin, dirX, dirY, norm, aSketchEdges, aSketchFaces)
+    # Create extrusion on them
+    anExtrusionFt = aPart.addFeature("Extrusion")
+    anExtrusionFt.selection("extrusion_face").setValue(
+        aSketchResult, aSketchFaces[0])
+    anExtrusionFt.real("extrusion_size").setValue(50)
+    anExtrusionFt.boolean("extrusion_reverse").setValue(False)
+    anExtrusionFt.execute()
+    extrudedObjects.append(modelAPI_ResultBody(anExtrusionFt.firstResult()))
+aSession.finishOperation()
+#=========================================================================
+# Create a pacman as boolean cut of the prism from the cylinder
+#=========================================================================
+aSession.startOperation()
+aBooleanFt = aPart.addFeature("Boolean")
+aBooleanFt.reference("main_object").setValue(extrudedObjects[0])
+aBooleanFt.reference("tool_object").setValue(extrudedObjects[1])
+kBooleanTypeCut = 0
+aBooleanFt.integer("bool_type").setValue(kBooleanTypeCut)
+aBooleanFt.execute()
+aSession.finishOperation()
+
+assert (len(aBooleanFt.results()) > 0)
+aBooleanResult = modelAPI_ResultBody(aBooleanFt.firstResult())
+assert (aBooleanResult is not None)
+#=========================================================================
+# End of test
+#=========================================================================
diff --git a/src/FeaturesPlugin/Test/TestExtrusion.py b/src/FeaturesPlugin/Test/TestExtrusion.py
new file mode 100644 (file)
index 0000000..1f60c4e
--- /dev/null
@@ -0,0 +1,89 @@
+"""
+      TestExtrusion.py
+      Unit test of FeaturesPlugin_Extrusion class
+      
+      class FeaturesPlugin_Extrusion : public ModelAPI_Feature
+        static const std::string MY_EXTRUSION_ID("Extrusion");
+        static const std::string MY_FACE_ID("extrusion_face");
+        static const std::string MY_SIZE_ID("extrusion_size");
+        static const std::string MY_REVERSE_ID("extrusion_reverse");
+          
+        data()->addAttribute(FeaturesPlugin_Extrusion::FACE_ID(), ModelAPI_AttributeSelection::type());
+        data()->addAttribute(FeaturesPlugin_Extrusion::SIZE_ID(), ModelAPI_AttributeDouble::type());
+        data()->addAttribute(FeaturesPlugin_Extrusion::REVERSE_ID(), ModelAPI_AttributeBoolean::type());
+"""
+#=========================================================================
+# Initialization of the test
+#=========================================================================
+from ModelAPI import *
+from GeomDataAPI import *
+from GeomAlgoAPI import *
+
+__updated__ = "2014-11-21"
+
+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 sketch circle to extrude
+#=========================================================================
+aSession.startOperation()
+aSketchFeature = modelAPI_CompositeFeature(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)
+diry = geomDataAPI_Dir(aSketchFeature.attribute("DirY"))
+diry.setValue(0, 1, 0)
+norm = geomDataAPI_Dir(aSketchFeature.attribute("Norm"))
+norm.setValue(0, 0, 1)
+# Create circle
+aSketchCircle = aSketchFeature.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
+aSketchResult = aSketchFeature.firstResult()
+aSketchEdges = modelAPI_ResultConstruction(aSketchResult).shape()
+origin = geomDataAPI_Point(aSketchFeature.attribute("Origin")).pnt()
+dirX = geomDataAPI_Dir(aSketchFeature.attribute("DirX")).dir()
+dirY = geomDataAPI_Dir(aSketchFeature.attribute("DirY")).dir()
+norm = geomDataAPI_Dir(aSketchFeature.attribute("Norm")).dir()
+aSketchFaces = ShapeList()
+GeomAlgoAPI_SketchBuilder.createFaces(
+    origin, dirX, dirY, norm, aSketchEdges, aSketchFaces)
+assert (len(aSketchFaces) > 0)
+assert (aSketchFaces[0] is not None)
+# Create extrusion
+aSession.startOperation()
+anExtrusionFt = aPart.addFeature("Extrusion")
+assert (anExtrusionFt.getKind() == "Extrusion")
+anExtrusionFt.selection("extrusion_face").setValue(
+    aSketchResult, aSketchFaces[0])
+anExtrusionFt.real("extrusion_size").setValue(50)
+anExtrusionFt.boolean("extrusion_reverse").setValue(False)
+anExtrusionFt.execute()
+aSession.finishOperation()
+assert (anExtrusionFt.real("extrusion_size").value() == 50.0)
+assert (anExtrusionFt.boolean("extrusion_reverse").value() == False)
+
+# Check extrusion results
+assert (len(anExtrusionFt.results()) > 0)
+anExtrusionResult = modelAPI_ResultBody(anExtrusionFt.firstResult())
+assert (anExtrusionResult is not None)
+#=========================================================================
+# End of test
+#=========================================================================
index 4d46a62719e876360eba8b1bdee3536ac91e8e07..d8506cf84f921a70ca7105202a1dba64e3111b9a 100644 (file)
@@ -78,4 +78,7 @@ ADD_UNIT_TESTS(TestSketchPointLine.py
                TestConstraintDistance.py
                TestConstraintParallel.py
                TestConstraintPerpendicular.py
-               TestConstraintRadius.py)
+               TestConstraintRadius.py
+               TestConstraintRigid.py
+               TestHighload.py
+               TestSnowflake.py)
index 35e9ac0c8e95da10d1a7776e6d02a34aa52b869c..772c94b96ea400fa9efdd87a0966b289d072ff9e 100644 (file)
@@ -30,7 +30,8 @@ aDocument = aSession.moduleDocument()
 # Creation of a sketch
 #=========================================================================
 aSession.startOperation()
-aSketchFeature = aDocument.addFeature("Sketch")
+aSketchCommonFeature = aDocument.addFeature("Sketch")
+aSketchFeature = modelAPI_CompositeFeature(aSketchCommonFeature)
 origin = geomDataAPI_Point(aSketchFeature.attribute("Origin"))
 origin.setValue(0, 0, 0)
 dirx = geomDataAPI_Dir(aSketchFeature.attribute("DirX"))
@@ -44,19 +45,15 @@ aSession.finishOperation()
 # Create a line and an arc
 #=========================================================================
 aSession.startOperation()
-aSketchReflist = aSketchFeature.reflist("Features")
-aSketchArc = aDocument.addFeature("SketchArc")
-aSketchReflist.append(aSketchArc)
+aSketchArc = aSketchFeature.addFeature("SketchArc")
 anArcCentr = geomDataAPI_Point2D(aSketchArc.attribute("ArcCenter"))
 anArcStartPoint = geomDataAPI_Point2D(
     aSketchArc.attribute("ArcStartPoint"))
 anArcEndPoint = geomDataAPI_Point2D(aSketchArc.attribute("ArcEndPoint"))
-aSketchFeature = aDocument.addFeature("SketchConstraintCoincidence")
 anArcCentr.setValue(10., 10.)
 anArcStartPoint.setValue(0., 50.)
 anArcEndPoint.setValue(50., 0.)
-aSketchLine = aDocument.addFeature("SketchLine")
-aSketchReflist.append(aSketchLine)
+aSketchLine = aSketchFeature.addFeature("SketchLine")
 aLineStartPoint = geomDataAPI_Point2D(aSketchLine.attribute("StartPoint"))
 aLineEndPoint = geomDataAPI_Point2D(aSketchLine.attribute("EndPoint"))
 # Lets initialize line start at circle's end:
@@ -67,12 +64,12 @@ aSession.finishOperation()
 # Link arc's end and line's start points with concidence constraint
 #=========================================================================
 aSession.startOperation()
-aConstraint = aDocument.addFeature("SketchConstraintCoincidence")
-aSketchReflist.append(aConstraint)
+aConstraint = aSketchFeature.addFeature("SketchConstraintCoincidence")
 reflistA = aConstraint.refattr("ConstraintEntityA")
 reflistB = aConstraint.refattr("ConstraintEntityB")
 reflistA.setAttr(anArcEndPoint)
 reflistB.setAttr(aLineStartPoint)
+aConstraint.execute()
 aSession.finishOperation()
 #=========================================================================
 # Check values and move one constrainted object
index 18fbc6832dfbec36bc441442cdab8e6ff41163d4..052e9272af1961924b4391a28c50aa2d93cdd02d 100644 (file)
@@ -55,15 +55,15 @@ aSession.finishOperation()
 # Make a constraint to keep the length of the line constant
 # to parallel perpendicular constraint collapsing line to point
 #=========================================================================
+aSession.startOperation()
 for eachFeature in [aSketchLineA, aSketchLineB]:
-    aSession.startOperation()
     aLengthConstraint = aSketchFeature.addFeature("SketchConstraintLength")
     refattrA = aLengthConstraint.refattr("ConstraintEntityA")
     aResultA = modelAPI_ResultConstruction(eachFeature.firstResult())
     assert (aResultA is not None)
     refattrA.setObject(aResultA)
     aLengthConstraint.execute()
-    aSession.finishOperation()
+aSession.finishOperation()
 # Coordinates of lines should not be changed after this constraint
 assert (aLineAStartPoint.x() == 0)
 assert (aLineAStartPoint.y() == 25)
@@ -81,8 +81,9 @@ aParallelConstraint = aSketchFeature.addFeature("SketchConstraintParallel")
 refattrA = aParallelConstraint.refattr("ConstraintEntityA")
 refattrB = aParallelConstraint.refattr("ConstraintEntityB")
 # aResultA is already defined for the length constraint
-aResultA = modelAPI_ResultConstruction(eachFeature.firstResult())
+aResultA = modelAPI_ResultConstruction(aSketchLineA.firstResult())
 aResultB = modelAPI_ResultConstruction(aSketchLineB.firstResult())
+assert (aResultA is not None)
 assert (aResultB is not None)
 refattrA.setObject(aResultA)
 refattrB.setObject(aResultB)
@@ -93,34 +94,19 @@ aSession.finishOperation()
 #=========================================================================
 deltaX = deltaY = 10.
 # rotate line, check that reference's line points are moved also
-# print "Rotate line, check that reference's line points are moved also"
-# print "assert (aLineAStartPoint.x() == %d)" % aLineAStartPoint.x()
-# print "assert (aLineAStartPoint.y() == %d)" % aLineAStartPoint.y()
-# print "assert (aLineAEndPoint.x() == %d)" % aLineAEndPoint.x()
-# print "assert (aLineAEndPoint.y() == %d)" % aLineAEndPoint.y()
-# print "assert (aLineBStartPoint.x() == %d)" % aLineBStartPoint.x()
-# print "assert (aLineBStartPoint.y() == %d)" % aLineBStartPoint.y()
-# print "assert (aLineBEndPoint.x() == %d)" % aLineBEndPoint.x()
-# print "assert (aLineBEndPoint.y() == %d)" % aLineBEndPoint.y()
-aLineBStartPointXPrev = aLineBStartPoint.x()
-aLineBStartPointYPrev = aLineBStartPoint.y()
-aLineBEndPointXPrev = aLineBEndPoint.x()
-aLineBEndPointYPrev = aLineBEndPoint.y()
+aLineBStartPointPrev = (aLineBStartPoint.x(), aLineBStartPoint.y())
+aLineBEndPointPrev = (aLineBEndPoint.x(), aLineBEndPoint.y())
 aSession.startOperation()
 aLineAStartPoint.setValue(aLineAStartPoint.x() + deltaX,
                           aLineAStartPoint.y() + deltaY)
 aLineAEndPoint.setValue(aLineAEndPoint.x() - deltaX,
                         aLineAEndPoint.y() - deltaY)
 aSession.finishOperation()
-# print "After transformation:"
-# print "assert (aLineAStartPoint.x() == %d)" % aLineAStartPoint.x()
-# print "assert (aLineAStartPoint.y() == %d)" % aLineAStartPoint.y()
-# print "assert (aLineAEndPoint.x() == %d)" % aLineAEndPoint.x()
-# print "assert (aLineAEndPoint.y() == %d)" % aLineAEndPoint.y()
-# print "assert (aLineBStartPoint.x() == %d)" % aLineBStartPoint.x()
-# print "assert (aLineBStartPoint.y() == %d)" % aLineBStartPoint.y()
-# print "assert (aLineBEndPoint.x() == %d)" % aLineBEndPoint.x()
-# print "assert (aLineBEndPoint.y() == %d)" % aLineBEndPoint.y()
+aLineBStartPointNew = (aLineBStartPoint.x(), aLineBStartPoint.y())
+aLineBEndPointNew = (aLineBEndPoint.x(), aLineBEndPoint.y())
+
+assert (aLineBStartPointPrev != aLineBStartPointNew)
+assert (aLineBEndPointPrev != aLineBEndPointNew)
 #=========================================================================
 # End of test
 #=========================================================================
index 38b605f233f80cc82a0f393cd11cc87d36d26981..2f9c6bf069f7daaf11d36e93c2d9e68e38514965 100644 (file)
@@ -49,10 +49,10 @@ aSession.startOperation()
 aSketchLineA = aSketchFeature.addFeature("SketchLine")
 aLineAStartPoint = geomDataAPI_Point2D(aSketchLineA.attribute("StartPoint"))
 aLineAEndPoint = geomDataAPI_Point2D(aSketchLineA.attribute("EndPoint"))
-# line B
-aSketchLineB = aSketchFeature.addFeature("SketchLine")
 aLineAStartPoint.setValue(0., 25)
 aLineAEndPoint.setValue(85., 25)
+# line B
+aSketchLineB = aSketchFeature.addFeature("SketchLine")
 aLineBStartPoint = geomDataAPI_Point2D(aSketchLineB.attribute("StartPoint"))
 aLineBEndPoint = geomDataAPI_Point2D(aSketchLineB.attribute("EndPoint"))
 aLineBStartPoint.setValue(25., 40.)
@@ -62,16 +62,15 @@ aSession.finishOperation()
 # Make a constraint to keep the length of the line constant
 # to prevent perpendicular constraint collapsing line to point
 #=========================================================================
-
+aSession.startOperation()
 for eachFeature in [aSketchLineA, aSketchLineB]:
-    aSession.startOperation()
     aLengthConstraint = aSketchFeature.addFeature("SketchConstraintLength")
-    refattrA = aLengthConstraint.refattr("ConstraintEntityA")
-    aResultA = modelAPI_ResultConstruction(eachFeature.firstResult())
-    assert (aResultA is not None)
-    refattrA.setObject(aResultA)
+    eachRefattr = aLengthConstraint.refattr("ConstraintEntityA")
+    eachResult = modelAPI_ResultConstruction(eachFeature.firstResult())
+    assert (eachResult is not None)
+    eachRefattr.setObject(eachResult)
     aLengthConstraint.execute()
-    aSession.finishOperation()
+aSession.finishOperation()
 
 # Coordinates of lines should not be changed after this constraint
 assert (aLineAStartPoint.x() == 0)
@@ -86,12 +85,12 @@ assert (aLineBEndPoint.y() == 125)
 # Link lines with perpendicular constraint
 #=========================================================================
 aSession.startOperation()
-aPerpendicularConstraint = aSketchFeature.addFeature(
-    "SketchConstraintPerpendicular")
+aPerpendicularConstraint = aSketchFeature.addFeature("SketchConstraintPerpendicular")
 refattrA = aPerpendicularConstraint.refattr("ConstraintEntityA")
 refattrB = aPerpendicularConstraint.refattr("ConstraintEntityB")
-# aResultA is already defined for the length constraint
+aResultA = modelAPI_ResultConstruction(aSketchLineA.firstResult())
 aResultB = modelAPI_ResultConstruction(aSketchLineB.firstResult())
+assert (aResultA is not None)
 assert (aResultB is not None)
 refattrA.setObject(aResultA)
 refattrB.setObject(aResultB)
@@ -100,46 +99,27 @@ aSession.finishOperation()
 #=========================================================================
 # Check values and move one constrainted object
 #=========================================================================
-# print "Check values and move one constrainted object"
-# print "assert (aLineAStartPoint.x() == %d)" % aLineAStartPoint.x()
-# print "assert (aLineAStartPoint.y() == %d)" % aLineAStartPoint.y()
-# print "assert (aLineAEndPoint.x() == %d)" % aLineAEndPoint.x()
-# print "assert (aLineAEndPoint.y() == %d)" % aLineAEndPoint.y()
-# print "assert (aLineBStartPoint.x() == %d)" % aLineBStartPoint.x()
-# print "assert (aLineBStartPoint.y() == %d)" % aLineBStartPoint.y()
-# print "assert (aLineBEndPoint.x() == %d)" % aLineBEndPoint.x()
-# print "assert (aLineBEndPoint.y() == %d)" % aLineBEndPoint.y()
+aLineBStartPointPrev = (aLineBStartPoint.x(),aLineBStartPoint.y())
+aLineBEndPointPrev = (aLineBEndPoint.x(),aLineBEndPoint.y())
 deltaX = deltaY = 5.
 # move line without rotation,
 # check that reference's line points are not changed also
-aLineAStartPoint.setValue(aLineAStartPoint.x() + deltaX,
-                          aLineAStartPoint.y() + deltaY)
-aLineAEndPoint.setValue(aLineAEndPoint.x() + deltaX,
-                        aLineAEndPoint.y() + deltaY)
-# print "move line without rotation"
-# print "assert (aLineAStartPoint.x() == %d)" % aLineAStartPoint.x()
-# print "assert (aLineAStartPoint.y() == %d)" % aLineAStartPoint.y()
-# print "assert (aLineAEndPoint.x() == %d)" % aLineAEndPoint.x()
-# print "assert (aLineAEndPoint.y() == %d)" % aLineAEndPoint.y()
-# print "assert (aLineBStartPoint.x() == %d)" % aLineBStartPoint.x()
-# print "assert (aLineBStartPoint.y() == %d)" % aLineBStartPoint.y()
-# print "assert (aLineBEndPoint.x() == %d)" % aLineBEndPoint.x()
-# print "assert (aLineBEndPoint.y() == %d)" % aLineBEndPoint.y()
-
-# rotate line, check that reference's line points are moved also
-aLineAStartPoint.setValue(aLineAStartPoint.x() + deltaX,
-                          aLineAStartPoint.y() + deltaY)
-aLineAEndPoint.setValue(aLineAEndPoint.x() - deltaX,
-                        aLineAEndPoint.y() - deltaY)
-# print "Rotate line, check that reference's line points are moved also"
-# print "assert (aLineAStartPoint.x() == %d)" % aLineAStartPoint.x()
-# print "assert (aLineAStartPoint.y() == %d)" % aLineAStartPoint.y()
-# print "assert (aLineAEndPoint.x() == %d)" % aLineAEndPoint.x()
-# print "assert (aLineAEndPoint.y() == %d)" % aLineAEndPoint.y()
-# print "assert (aLineBStartPoint.x() == %d)" % aLineBStartPoint.x()
-# print "assert (aLineBStartPoint.y() == %d)" % aLineBStartPoint.y()
-# print "assert (aLineBEndPoint.x() == %d)" % aLineBEndPoint.x()
-# print "assert (aLineBEndPoint.y() == %d)" % aLineBEndPoint.y()
+aSession.startOperation()
+aLineAStartPoint.setValue(aLineAStartPoint.x() + deltaX, aLineAStartPoint.y() + deltaY)
+aLineAEndPoint.setValue(aLineAEndPoint.x() + deltaX, aLineAEndPoint.y() + deltaY)
+aSession.finishOperation()
+assert (aLineBStartPointPrev == (aLineBStartPoint.x(), aLineBStartPoint.y()))
+assert (aLineBEndPointPrev   == (aLineBEndPoint.x(),   aLineBEndPoint.y()))
+aLineBStartPointPrev = (aLineBStartPoint.x(),aLineBStartPoint.y())
+aLineBEndPointPrev = (aLineBEndPoint.x(),aLineBEndPoint.y())
+# rotate line, 
+# check that reference's line points are moved also
+aSession.startOperation()
+aLineAStartPoint.setValue(aLineAStartPoint.x() + deltaX, aLineAStartPoint.y() + deltaY)
+aLineAEndPoint.setValue(aLineAEndPoint.x() - deltaX, aLineAEndPoint.y() - deltaY)
+aSession.finishOperation()
+assert (aLineBStartPointPrev != (aLineBStartPoint.x(), aLineBStartPoint.y()))
+assert (aLineBEndPointPrev   != (aLineBEndPoint.x(),   aLineBEndPoint.y()))
 #=========================================================================
 # End of test
 #=========================================================================
diff --git a/src/SketchPlugin/Test/TestConstraintRigid.py b/src/SketchPlugin/Test/TestConstraintRigid.py
new file mode 100644 (file)
index 0000000..9f6eaf3
--- /dev/null
@@ -0,0 +1,135 @@
+"""
+    TestConstraintRigid.py
+    Unit test of SketchPlugin_ConstraintRigid class
+    
+    SketchPlugin_Constraint
+        static const std::string MY_CONSTRAINT_VALUE("ConstraintValue");
+        static const std::string MY_FLYOUT_VALUE_PNT("ConstraintFlyoutValuePnt");
+        static const std::string MY_ENTITY_A("ConstraintEntityA");
+        static const std::string MY_ENTITY_B("ConstraintEntityB");
+        static const std::string MY_ENTITY_C("ConstraintEntityC");
+        static const std::string MY_ENTITY_D("ConstraintEntityD");
+        
+    SketchPlugin_ConstraintRigid
+        static const std::string MY_CONSTRAINT_RIGID_ID("SketchConstraintRigid");
+        data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::type());
+
+"""
+from GeomDataAPI import *
+from ModelAPI import *
+from GeomAPI import *
+#=========================================================================
+# Initialization of the test
+#=========================================================================
+
+__updated__ = "2014-11-21"
+
+aSession = ModelAPI_Session.get()
+aDocument = aSession.moduleDocument()
+#=========================================================================
+# Creation of a sketch
+#=========================================================================
+aSession.startOperation()
+aSketchCommonFeature = aDocument.addFeature("Sketch")
+aSketchFeature = modelAPI_CompositeFeature(aSketchCommonFeature)
+origin = geomDataAPI_Point(aSketchFeature.attribute("Origin"))
+origin.setValue(0, 0, 0)
+dirx = geomDataAPI_Dir(aSketchFeature.attribute("DirX"))
+dirx.setValue(1, 0, 0)
+diry = geomDataAPI_Dir(aSketchFeature.attribute("DirY"))
+diry.setValue(0, 1, 0)
+norm = geomDataAPI_Dir(aSketchFeature.attribute("Norm"))
+norm.setValue(0, 0, 1)
+aSession.finishOperation()
+#=========================================================================
+# Create a triangle ABC
+#=========================================================================
+aSession.startOperation()
+aSketchLineA = aSketchFeature.addFeature("SketchLine")
+aSketchLineB = aSketchFeature.addFeature("SketchLine")
+aSketchLineC = aSketchFeature.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"))
+aLineAStartPoint.setValue(25., 25.)
+aLineAEndPoint.setValue(100., 25.)
+aLineBStartPoint.setValue(100., 25.)
+aLineBEndPoint.setValue(60., 75.)
+aLineCStartPoint.setValue(60., 75.)
+aLineCEndPoint.setValue(25., 25.)
+aSession.finishOperation()
+# Store initial values of lines
+kLineAStart = (aLineAStartPoint.x(), aLineAStartPoint.y())
+kLineAEnd = (aLineAEndPoint.x(),   aLineAEndPoint.y())
+kLineBStart = (aLineBStartPoint.x(), aLineBStartPoint.y())
+kLineBEnd = (aLineBEndPoint.x(),   aLineBEndPoint.y())
+kLineCStart = (aLineCStartPoint.x(), aLineCStartPoint.y())
+kLineCEnd = (aLineCEndPoint.x(),   aLineCEndPoint.y())
+#=========================================================================
+# Link triange lines with concidence
+#=========================================================================
+concidenceLinks = zip([aLineBStartPoint, aLineCStartPoint, aLineAStartPoint],
+                      [aLineAEndPoint, aLineBEndPoint, aLineCEndPoint])
+aSession.startOperation()
+for eachLink in concidenceLinks:
+    aConstraint = aSketchFeature.addFeature("SketchConstraintCoincidence")
+    reflistA = aConstraint.refattr("ConstraintEntityA")
+    reflistB = aConstraint.refattr("ConstraintEntityB")
+    reflistA.setAttr(eachLink[0])
+    reflistB.setAttr(eachLink[1])
+    aConstraint.execute()
+aSession.finishOperation()
+
+# Check that constarints doesn't affected lines' values
+assert (kLineAStart == (aLineAStartPoint.x(), aLineAStartPoint.y()))
+assert (kLineAEnd == (aLineAEndPoint.x(),   aLineAEndPoint.y()))
+assert (kLineBStart == (aLineBStartPoint.x(), aLineBStartPoint.y()))
+assert (kLineBEnd == (aLineBEndPoint.x(),   aLineBEndPoint.y()))
+assert (kLineCStart == (aLineCStartPoint.x(), aLineCStartPoint.y()))
+assert (kLineCEnd == (aLineCEndPoint.x(),   aLineCEndPoint.y()))
+#=========================================================================
+# Make line A rigid
+#=========================================================================
+aSession.startOperation()
+aRigidConstraint = aSketchFeature.addFeature("SketchConstraintRigid")
+eachRefattr = aRigidConstraint.refattr("ConstraintEntityA")
+lineResults = aSketchLineA.results()
+for eachResult in lineResults:
+    if eachResult.shape().isEdge():
+        break
+aResult = modelAPI_ResultConstruction(eachResult)
+assert (aResult is not None)
+eachRefattr.setObject(aResult)
+# aRigidConstraint.execute()
+aSession.finishOperation()
+
+# Check that constarints doesn't affected lines' values
+assert (kLineAStart == (aLineAStartPoint.x(), aLineAStartPoint.y()))
+assert (kLineAEnd == (aLineAEndPoint.x(),   aLineAEndPoint.y()))
+assert (kLineBStart == (aLineBStartPoint.x(), aLineBStartPoint.y()))
+assert (kLineBEnd == (aLineBEndPoint.x(),   aLineBEndPoint.y()))
+assert (kLineCStart == (aLineCStartPoint.x(), aLineCStartPoint.y()))
+assert (kLineCEnd == (aLineCEndPoint.x(),   aLineCEndPoint.y()))
+#=========================================================================
+# Check that
+#=========================================================================
+aSession.startOperation()
+aLineBEndPoint.setValue(90., 150.)
+aSession.finishOperation()
+# Check that constarint keep features' values
+assert (kLineAStart == (aLineAStartPoint.x(), aLineAStartPoint.y()))
+assert (kLineAEnd == (aLineAEndPoint.x(),   aLineAEndPoint.y()))
+assert (kLineBStart == (aLineBStartPoint.x(), aLineBStartPoint.y()))
+assert (kLineBEnd != (aLineBEndPoint.x(),   aLineBEndPoint.y()))
+assert (kLineCStart != (aLineCStartPoint.x(), aLineCStartPoint.y()))
+assert (kLineCEnd == (aLineCEndPoint.x(),   aLineCEndPoint.y()))
+#=========================================================================
+# TODO: improve test
+# 1. remove constraint, move line to check that constraint are not applied
+#=========================================================================
+#=========================================================================
+# End of test
+#=========================================================================
diff --git a/src/SketchPlugin/Test/TestHighload.py b/src/SketchPlugin/Test/TestHighload.py
new file mode 100644 (file)
index 0000000..f8fed60
--- /dev/null
@@ -0,0 +1,123 @@
+"""
+    TestHighload.py
+"""
+from GeomAPI import *
+from GeomDataAPI import *
+from ModelAPI import *
+import math
+
+
+#=========================================================================
+# Useful subroutines
+#=========================================================================
+def distance(pointA, pointB):
+    """
+    subroutine to calculate distance between two points
+    result of calculated distance is has 10**-5 precision
+    """
+    xdiff = math.pow((pointA.x() - pointB.x()), 2)
+    ydiff = math.pow((pointA.y() - pointB.y()), 2)
+    return round(math.sqrt(xdiff + ydiff), 5)
+
+
+def createNAngle(theSketch, theN, theRadius, theEdgeLength=0):
+    # Create an N-Angle at (0,0)
+    rad = 2. * math.pi / theN
+    points = []
+    for a in xrange(theN):
+        x = round(math.cos(rad * a), 10) * theRadius
+        y = round(math.sin(rad * a), 10) * theRadius
+        points.append((x, y))
+    # Close the contour
+    points.append(points[0])
+
+    # Create lines iterating over (A,B), (B,C), ... (N,A)
+    allStartPoints = []
+    allEndPoints = []
+    allLines = []
+    for begin, end in zip(points[:-1], points[1:]):
+        aSketchLine = theSketch.addFeature("SketchLine")
+        aStartPoint = geomDataAPI_Point2D(aSketchLine.attribute("StartPoint"))
+        anEndPoint = geomDataAPI_Point2D(aSketchLine.attribute("EndPoint"))
+        aStartPoint.setValue(begin[0], begin[1])
+        anEndPoint.setValue(end[0], end[1])
+        allStartPoints.append(aStartPoint)
+        allEndPoints.append(anEndPoint)
+        allLines.append(aSketchLine)
+    theSketch.execute()
+    # Shift a start point to the end of list:
+    # (Bb, Cb, Ab) zip (Ae, Be, Ce) --> ((Ae, Bb), (Cb, Be), (Ab, Ce))
+    allStartPoints.append(allStartPoints.pop(0))
+    # Make lines coincident:
+    for pointA, pointB in zip(allStartPoints, allEndPoints):
+        aCoincidence = theSketch.addFeature("SketchConstraintCoincidence")
+        aCoincidence.refattr("ConstraintEntityA").setAttr(pointA)
+        aCoincidence.refattr("ConstraintEntityB").setAttr(pointB)
+    return allLines
+
+
+def fixLineLength(theSketch, theLines, theEdgeLength=0):
+    aFirstLineLength = theEdgeLength
+    # Make give lines fixed length:
+    for aLine in theLines:
+        aLengthConstraint = aSketchFeature.addFeature("SketchConstraintLength")
+        refattrA = aLengthConstraint.refattr("ConstraintEntityA")
+        refattrA.setObject(modelAPI_ResultConstruction(aLine.firstResult()))
+        if aFirstLineLength == 0:
+            pointA = geomDataAPI_Point2D(aLine.attribute("StartPoint"))
+            pointB = geomDataAPI_Point2D(aLine.attribute("EndPoint"))
+            aFirstLineLength = distance(pointA, pointB)
+        aLengthConstraint.real("ConstraintValue").setValue(aFirstLineLength)
+
+
+def moveTo(theLines, theDeltaX, theDeltaY):
+    for aLine in theLines:
+        aStart = geomDataAPI_Point2D(aLine.attribute("StartPoint"))
+        anEnd = geomDataAPI_Point2D(aLine.attribute("EndPoint"))
+        aStart.setValue(aStart.x() + theDeltaX, aStart.y() + theDeltaY)
+        anEnd.setValue(anEnd.x() + theDeltaX, anEnd.y() + theDeltaY)
+
+#=========================================================================
+# Initialization of the test
+#=========================================================================
+
+__updated__ = "2014-11-27"
+
+aSession = ModelAPI_Session.get()
+aDocument = aSession.moduleDocument()
+#=========================================================================
+# Creation of a sketch
+#=========================================================================
+aSession.startOperation()
+aSketchCommonFeature = aDocument.addFeature("Sketch")
+aSketchFeature = modelAPI_CompositeFeature(aSketchCommonFeature)
+origin = geomDataAPI_Point(aSketchFeature.attribute("Origin"))
+origin.setValue(0, 0, 0)
+dirx = geomDataAPI_Dir(aSketchFeature.attribute("DirX"))
+dirx.setValue(1, 0, 0)
+diry = geomDataAPI_Dir(aSketchFeature.attribute("DirY"))
+diry.setValue(0, 1, 0)
+norm = geomDataAPI_Dir(aSketchFeature.attribute("Norm"))
+norm.setValue(0, 0, 1)
+aSession.finishOperation()
+#=========================================================================
+# Create 4x4 polygons N = {5, 21}
+#=========================================================================
+deltaX = deltaY = 50.
+n = 5
+aSession.startOperation()
+for i in xrange(4):
+    for j in xrange(4):
+        allNangleLines = createNAngle(aSketchFeature, n, 50)
+        fixLineLength(aSketchFeature, allNangleLines)
+        moveTo(allNangleLines, deltaX, deltaY)
+        n += 1
+        deltaX += 110.
+    deltaY += 110.
+    deltaX = 50.
+aSession.finishOperation()
+
+
+#=========================================================================
+# End of test
+#=========================================================================
diff --git a/src/SketchPlugin/Test/TestSnowflake.py b/src/SketchPlugin/Test/TestSnowflake.py
new file mode 100644 (file)
index 0000000..65b4213
--- /dev/null
@@ -0,0 +1,159 @@
+"""
+    TestSnowflake.py
+"""
+from GeomAPI import *
+from GeomDataAPI import *
+from ModelAPI import *
+import collections
+import math
+import random
+
+
+#=========================================================================
+# Useful subroutines
+#=========================================================================
+def mirrorDiagonal(theSketch, allLines):
+    result = []
+    for aLine in allLines:
+        aStartPoint = geomDataAPI_Point2D(aLine.attribute("StartPoint"))
+        anEndPoint = geomDataAPI_Point2D(aLine.attribute("EndPoint"))
+
+        aNewLine = aSketchFeature.addFeature("SketchLine")
+        aNewStartPoint = geomDataAPI_Point2D(aNewLine.attribute("StartPoint"))
+        aNewEndPoint = geomDataAPI_Point2D(aNewLine.attribute("EndPoint"))
+        aNewStartPoint.setValue(aStartPoint.y(), aStartPoint.x())
+        aNewEndPoint.setValue(anEndPoint.y(), anEndPoint.x())
+        result.append(aNewLine)
+    allLines.extend(result)
+
+
+def mirrorX(theSketch, allLines):
+    result = []
+    for aLine in allLines:
+        aStartPoint = geomDataAPI_Point2D(aLine.attribute("StartPoint"))
+        anEndPoint = geomDataAPI_Point2D(aLine.attribute("EndPoint"))
+
+        aNewLine = aSketchFeature.addFeature("SketchLine")
+        aNewStartPoint = geomDataAPI_Point2D(aNewLine.attribute("StartPoint"))
+        aNewEndPoint = geomDataAPI_Point2D(aNewLine.attribute("EndPoint"))
+        aNewStartPoint.setValue(aStartPoint.x() * -1., aStartPoint.y())
+        aNewEndPoint.setValue(anEndPoint.x() * -1., anEndPoint.y())
+        result.append(aNewLine)
+    allLines.extend(result)
+
+
+def mirrorY(theSketch, allLines):
+    result = []
+    for aLine in allLines:
+        aStartPoint = geomDataAPI_Point2D(aLine.attribute("StartPoint"))
+        anEndPoint = geomDataAPI_Point2D(aLine.attribute("EndPoint"))
+
+        aNewLine = aSketchFeature.addFeature("SketchLine")
+        aNewStartPoint = geomDataAPI_Point2D(aNewLine.attribute("StartPoint"))
+        aNewEndPoint = geomDataAPI_Point2D(aNewLine.attribute("EndPoint"))
+        aNewStartPoint.setValue(aStartPoint.x(), aStartPoint.y() * -1.)
+        aNewEndPoint.setValue(anEndPoint.x(), anEndPoint.y() * -1.)
+        result.append(aNewLine)
+    allLines.extend(result)
+
+
+def initContour(theNumLines):
+    prevPoint = (35, 0)
+    result = []
+    deltaY = random.uniform(20, 25)
+    for i in xrange(1, theNumLines):
+        rangeXMax = (prevPoint[1] + deltaY) * (30. / i if i % 2 != 0 else 2)
+        newX = random.uniform(prevPoint[1] + deltaY,
+                              max(rangeXMax, prevPoint[1] + deltaY + 25.))
+        newPoint = (round(newX, 4), round(prevPoint[1] + deltaY, 4))
+        result.append((prevPoint, newPoint))
+        prevPoint = newPoint
+    # Close the contour
+    result.append((prevPoint, (prevPoint[1], prevPoint[1])))
+    return result
+
+
+def makeLinesCoincident(theSketch, allLines):
+    allPoints = collections.defaultdict(list)
+    for aLine in allLines:
+        aStartPoint = geomDataAPI_Point2D(aLine.attribute("StartPoint"))
+        anEndPoint = geomDataAPI_Point2D(aLine.attribute("EndPoint"))
+        aStartPointValue = (aStartPoint.x(), aStartPoint.y())
+        anEndPointValue = (anEndPoint.x(), anEndPoint.y())
+        allPoints[aStartPointValue].append(aStartPoint)
+        allPoints[anEndPointValue].append(anEndPoint)
+    for keyPoint, valuePoints in allPoints.iteritems():
+        if len(valuePoints) != 2:
+            print "Strange point: ", keyPoint, "has in coincidence: ", len(valuePoints)
+            continue
+        aConstraint = theSketch.addFeature("SketchConstraintCoincidence")
+        aConstraint.refattr("ConstraintEntityA").setAttr(valuePoints[0])
+        aConstraint.refattr("ConstraintEntityB").setAttr(valuePoints[1])
+
+
+#=========================================================================
+# Initialization of the test
+#=========================================================================
+
+__updated__ = "2014-11-27"
+
+aSession = ModelAPI_Session.get()
+aDocument = aSession.moduleDocument()
+#=========================================================================
+# Creation of a sketch
+#=========================================================================
+aSession.startOperation()
+aSketchCommonFeature = aDocument.addFeature("Sketch")
+aSketchFeature = modelAPI_CompositeFeature(aSketchCommonFeature)
+origin = geomDataAPI_Point(aSketchFeature.attribute("Origin"))
+origin.setValue(0, 0, 0)
+dirx = geomDataAPI_Dir(aSketchFeature.attribute("DirX"))
+dirx.setValue(1, 0, 0)
+diry = geomDataAPI_Dir(aSketchFeature.attribute("DirY"))
+diry.setValue(0, 1, 0)
+norm = geomDataAPI_Dir(aSketchFeature.attribute("Norm"))
+norm.setValue(0, 0, 1)
+#=========================================================================
+# 1 With the predefined contour or a new random generated in X0Y
+# 2 Make complete contour using the diagonal, X and Y mirror symmetry
+# 3 Link all lines in contour with coincidence
+#=========================================================================
+initialContour = [((35, 0), (134.8224, 22.0494)), ((134.8224, 22.0494), (71.987, 44.0988)),
+                  ((71.987, 44.0988), (205.1448, 66.1482)), ((205.1448, 66.1482), (127.862, 88.1976)),
+                  ((127.862, 88.1976), (416.861, 110.247)), ((416.861, 110.247), (233.0475, 132.2964)),
+                  ((233.0475, 132.2964), (251.1518, 154.3458)), ((251.1518, 154.3458), (351.0993, 176.3952)),
+                  ((351.0993, 176.3952), (432.3397, 198.4446)), ((432.3397, 198.4446), (223.3246, 220.494)),
+                  ((223.3246, 220.494), (617.4069, 242.5434)), ((617.4069, 242.5434), (479.6524, 264.5928)),
+                  ((479.6524, 264.5928), (453.5778, 286.6422)), ((453.5778, 286.6422), (541.3463, 308.6916)),
+                  ((541.3463, 308.6916), (564.5509, 330.741)), ((564.5509, 330.741), (636.9284, 352.7904)),
+                  ((636.9284, 352.7904), (383.5946, 374.8398)), ((383.5946, 374.8398), (403.3764, 396.8892)),
+                  ((403.3764, 396.8892), (463.9447, 418.9386)), ((463.9447, 418.9386), (669.1751, 440.988)),
+                  ((669.1751, 440.988), (602.2044, 463.0374)), ((602.2044, 463.0374), (942.0456, 485.0868)),
+                  ((942.0456, 485.0868), (526.574, 507.1362)), ((526.574, 507.1362), (826.3619, 529.1856)),
+                  ((826.3619, 529.1856), (576.9488, 551.235)), ((576.9488, 551.235), (624.5595, 573.2844)),
+                  ((624.5595, 573.2844), (648.7146, 595.3338)), ((648.7146, 595.3338), (1194.6944, 617.3832)),
+                  ((1194.6944, 617.3832), (646.6597, 639.4326)), ((646.6597, 639.4326), (839.8201, 661.482)),
+                  ((839.8201, 661.482), (690.7487, 683.5314)), ((690.7487, 683.5314), (1350.2538, 705.5808)),
+                  ((1350.2538, 705.5808), (731.0722, 727.6302)), ((731.0722, 727.6302), (1324.0992, 749.6796)),
+                  ((1324.0992, 749.6796), (790.4873, 771.729)), ((790.4873, 771.729), (813.9883, 793.7784)),
+                  ((813.9883, 793.7784), (828.9997, 815.8278)), ((828.9997, 815.8278), (1321.9798, 837.8772)),
+                  ((1321.9798, 837.8772), (872.1503, 859.9266)), ((872.1503, 859.9266), (859.9266, 859.9266))]
+
+# Regenerate contour
+# initialContour = initContour(40)
+allLines = []
+for begin, end in initialContour:
+    aNewLine = aSketchFeature.addFeature("SketchLine")
+    aStartPoint = geomDataAPI_Point2D(aNewLine.attribute("StartPoint"))
+    anEndPoint = geomDataAPI_Point2D(aNewLine.attribute("EndPoint"))
+    aStartPoint.setValue(begin[0], begin[1])
+    anEndPoint.setValue(end[0], end[1])
+    allLines.append(aNewLine)
+mirrorDiagonal(aSketchFeature, allLines)
+mirrorX(aSketchFeature, allLines)
+mirrorY(aSketchFeature, allLines)
+makeLinesCoincident(aSketchFeature, allLines)
+aSession.finishOperation()
+#=========================================================================
+# End of test
+#=========================================================================