Salome HOME
Issue #2024: Redesign of circle and arc of circle: Unit tests for creation of a circl...
authorazv <azv@opencascade.com>
Wed, 22 Mar 2017 07:05:21 +0000 (10:05 +0300)
committerdbv <dbv@opencascade.com>
Mon, 27 Mar 2017 06:56:52 +0000 (09:56 +0300)
src/PythonAPI/model/tests/tests.py
src/SketchPlugin/CMakeLists.txt
src/SketchPlugin/Test/TestCreateArc.py [new file with mode: 0644]
src/SketchPlugin/Test/TestCreateCircleByCenterAndPassed.py [new file with mode: 0644]
src/SketchPlugin/Test/TestCreateCircleByThreePoints.py [new file with mode: 0644]
src/SketchPlugin/Test/TestCreateCircleChangeType.py [new file with mode: 0644]
src/SketchPlugin/Test/TestSketchArcCircle.py [deleted file]
src/SketchPlugin/plugin-Sketch.xml

index 88e0731d4cf2c86e3cc1e3c4257d9ad774c0b70d..68b766385ff109fcd75d92ad92790da2162e8011 100644 (file)
@@ -1,5 +1,6 @@
 from GeomAlgoAPI import *
 from GeomAPI import *
+from ModelAPI import ModelAPI_Feature
 import math
 
 
@@ -139,3 +140,16 @@ def testHaveNamingFaces(theFeature, theModel, thePartDoc) :
     name = attrSelection.namingName()
     assert(shape.isFace())
     assert(name != ""), "String empty"
+
+def testNbSubFeatures(theComposite, theKindOfSub, theExpectedCount):
+  """ Tests number of sub-features of the given type
+  :param theComposite     composite feature to check its subs
+  :param theKindOfSub     kind of sub-feature to calculate count
+  :param theExpectedCount expected number of sub-features
+  """
+  count = 0
+  for aSub in theComposite.features().list():
+    aFeature = ModelAPI_Feature.feature(aSub)
+    if aFeature is not None and aFeature.getKind() == theKindOfSub:
+       count += 1
+  assert (count == theExpectedCount), "Number of sub-features of type {}: {}, expected {}".format(theKindOfSub, count, theExpectedCount)
index 5cc31d85b5e58bd6db561d93fcf8db1265b7736c..614dd0d299401bda5ddd0d84e89d3af0566e41ee 100644 (file)
@@ -123,7 +123,10 @@ INSTALL(DIRECTORY icons/ DESTINATION ${SHAPER_INSTALL_XML_RESOURCES}/icons/Sketc
 INSTALL(FILES ${TEXT_RESOURCES} DESTINATION ${SHAPER_INSTALL_XML_RESOURCES})
 
 ADD_UNIT_TESTS(TestSketchPointLine.py
-               TestSketchArcCircle.py
+               TestCreateArc.py
+               TestCreateCircleByCenterAndPassed.py
+               TestCreateCircleByThreePoints.py
+               TestCreateCircleChangeType.py
                TestConstraintCoincidence.py
                TestConstraintCollinear.py
                TestConstraintLength.py
diff --git a/src/SketchPlugin/Test/TestCreateArc.py b/src/SketchPlugin/Test/TestCreateArc.py
new file mode 100644 (file)
index 0000000..936981d
--- /dev/null
@@ -0,0 +1,201 @@
+"""
+    TestCreateArc.py
+
+    static const std::string MY_SKETCH_ARC_ID("SketchArc");
+    static const std::string MY_CENTER_ID = "ArcCenter";
+    static const std::string MY_START_ID = "ArcStartPoint";
+    static const std::string MY_END_ID = "ArcEndPoint";
+    data()->addAttribute(SketchPlugin_Arc::CENTER_ID(), GeomDataAPI_Point2D::typeId());
+    data()->addAttribute(SketchPlugin_Arc::START_ID(),  GeomDataAPI_Point2D::typeId());
+    data()->addAttribute(SketchPlugin_Arc::END_ID(),    GeomDataAPI_Point2D::typeId());
+"""
+
+#=========================================================================
+# Initialization of the test
+#=========================================================================
+from GeomDataAPI import *
+from ModelAPI import *
+import math
+
+__updated__ = "2014-10-28"
+
+
+#=========================================================================
+# Auxiliary functions
+#=========================================================================
+
+def angle(theCenter, theFirst, theLast):
+    """
+    subroutine to calculate angle given by 3 points
+    """
+    aDirX1 = theFirst.x() - theCenter.x()
+    aDirY1 = theFirst.y() - theCenter.y()
+    aLen1 = math.hypot(aDirX1, aDirY1)
+    aDirX2 = theLast.x() - theCenter.x()
+    aDirY2 = theLast.y() - theCenter.y()
+    aLen2 = math.hypot(aDirX2, aDirY2)
+    aDot = aDirX1 * aDirX2 + aDirY1 * aDirY2
+    anAngle = math.acos(aDot / aLen1 / aLen2)
+    return round(anAngle * 180. / math.pi, 6)
+
+def distancePointPoint(thePointA, thePointB):
+    """
+    subroutine to calculate distance between two points
+    result of calculated distance is has 10**-5 precision
+    """
+    xdiff = math.pow((thePointA.x() - thePointB.x()), 2)
+    ydiff = math.pow((thePointA.y() - thePointB.y()), 2)
+    return round(math.sqrt(xdiff + ydiff), 5)
+
+def dot(thePoint11, thePoint12, thePoint21, thePoint22):
+    """
+    subroutine to calculate dit product between lines given by their points
+    """
+    aDirX1 = thePoint12.x() - thePoint11.x()
+    aDirY1 = thePoint12.y() - thePoint11.y()
+    aLen1 = math.hypot(aDirX1, aDirY1)
+    aDirX2 = thePoint22.x() - thePoint21.x()
+    aDirY2 = thePoint22.y() - thePoint21.y()
+    aLen2 = math.hypot(aDirX2, aDirY2)
+    aDot = aDirX1 * aDirX2 + aDirY1 * aDirY2
+    return aDot / aLen1 / aLen2
+
+
+aSession = ModelAPI_Session.get()
+aDocument = aSession.moduleDocument()
+#=========================================================================
+# Creation of a sketch
+#=========================================================================
+aSession.startOperation()
+#aSketchFeature = aDocument.addFeature("Sketch")
+aSketchCommonFeature = aDocument.addFeature("Sketch")
+aSketchFeature = featureToCompositeFeature(aSketchCommonFeature)
+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)
+aSession.finishOperation()
+#=========================================================================
+# Creation of an arc
+# 1. Test SketchPlugin_Arc attributes
+# 2.
+#=========================================================================
+aSession.startOperation()
+aSketchReflist = aSketchFeature.reflist("Features")
+assert (not aSketchReflist.isInitialized())
+assert (aSketchReflist.size() == 0)
+assert (len(aSketchReflist.list()) == 0)
+aSketchArc = aSketchFeature.addFeature("SketchArc")
+assert (aSketchArc.getKind() == "SketchArc")
+anArcCentr = geomDataAPI_Point2D(aSketchArc.attribute("ArcCenter"))
+assert (not anArcCentr.isInitialized())
+anArcCentr.setValue(10., 10.)
+anArcStartPoint = geomDataAPI_Point2D(
+    aSketchArc.attribute("ArcStartPoint"))
+assert (not anArcStartPoint.isInitialized())
+anArcStartPoint.setValue(0., 50.)
+anArcEndPoint = geomDataAPI_Point2D(aSketchArc.attribute("ArcEndPoint"))
+assert (not anArcEndPoint.isInitialized())
+anArcEndPoint.setValue(50., 0.)
+aSession.finishOperation()
+# check that values have been changed
+aSketchReflist = aSketchFeature.reflist("Features")
+assert (aSketchReflist.size() == 1)
+assert (len(aSketchReflist.list()) == 1)
+assert (anArcCentr.x() == 10.0)
+assert (anArcCentr.y() == 10.0)
+assert (anArcStartPoint.x() == 0.0)
+assert (anArcStartPoint.y() == 50.0)
+assert (anArcEndPoint.x() == 50.0)
+assert (anArcEndPoint.y() == 0.0)
+#=========================================================================
+# Edit the arc:
+# 1. Move whole arc
+# 2. Change the start point
+# 3. Change the radius of arc
+# 4. Change arc's angle
+#=========================================================================
+aSession.startOperation()
+deltaX, deltaY = 5., 10.
+anArcCentr.setValue(anArcCentr.x() + deltaX, anArcCentr.y() + deltaY)
+aSession.finishOperation()
+assert (anArcCentr.x() == 15)
+assert (anArcCentr.y() == 20)
+assert (math.fabs(distancePointPoint(anArcCentr, anArcStartPoint) - distancePointPoint(anArcCentr, anArcEndPoint)) < 1.e-10)
+# Change the start point
+aSession.startOperation()
+anArcStartPoint.setValue(anArcStartPoint.x() + deltaX, anArcStartPoint.y())
+aSession.finishOperation()
+assert (math.fabs(distancePointPoint(anArcCentr, anArcStartPoint) - distancePointPoint(anArcCentr, anArcEndPoint)) < 1.e-10)
+# Change radius
+RADIUS = 50
+aSession.startOperation()
+anArcRadius = aSketchArc.real("ArcRadius")
+anArcRadius.setValue(RADIUS)
+aSession.finishOperation()
+assert (math.fabs(distancePointPoint(anArcCentr, anArcStartPoint) - RADIUS) < 1.e-10)
+assert (math.fabs(distancePointPoint(anArcCentr, anArcEndPoint) - RADIUS) < 1.e-10)
+# Change angle
+ANGLE = 120
+aSession.startOperation()
+anArcAngle = aSketchArc.real("ArcAngle")
+anArcAngle.setValue(ANGLE)
+aSession.finishOperation()
+assert (math.fabs(angle(anArcCentr, anArcStartPoint, anArcEndPoint) - ANGLE) < 1.e-7)
+#=========================================================================
+# Check results of the Arc
+#=========================================================================
+aResult = aSketchArc.firstResult()
+aResultConstruction = modelAPI_ResultConstruction(aResult)
+aShape = aResultConstruction.shape()
+assert (aShape is not None)
+assert (not aShape.isNull())
+#=========================================================================
+# Create an arc, tangent to the line
+#=========================================================================
+aSession.startOperation()
+aSketchLine = aSketchFeature.addFeature("SketchLine")
+aLineStart = geomDataAPI_Point2D(aSketchLine.attribute("StartPoint"))
+aLineEnd = geomDataAPI_Point2D(aSketchLine.attribute("EndPoint"))
+aLineStart.setValue(0., 0.)
+aLineEnd.setValue(50., 0.)
+aSession.finishOperation()
+aSession.startOperation()
+aFixed = aSketchFeature.addFeature("SketchConstraintRigid")
+aRefObjectA = aFixed.refattr("ConstraintEntityA")
+aRefObjectA.setObject(modelAPI_ResultConstruction(aSketchLine.lastResult()))
+aFixed.execute()
+aSession.finishOperation()
+aSession.startOperation()
+aSketchArcTangent = aSketchFeature.addFeature("SketchArc")
+aSketchArcTangent.string("ArcType").setValue("Tangent")
+anArcEndPoint = geomDataAPI_Point2D(aSketchArcTangent.attribute("ArcEndPoint"))
+aTangent = aSketchArcTangent.refattr("ArcTangentPoint")
+aTangent.setAttr(aLineEnd)
+anArcEndPoint.setValue(51., 1.)
+aSession.finishOperation()
+aSession.startOperation()
+anArcEndPoint.setValue(100., 25.)
+aSession.finishOperation()
+anArcCenter = geomDataAPI_Point2D(aSketchArcTangent.attribute("ArcCenter"))
+aDot = dot(anArcCenter, aLineEnd, aLineStart, aLineEnd)
+assert math.fabs(aDot) <= 2.e-4, "Observed dot product: {0}".format(aDot)
+#=========================================================================
+# Create an arc, tangent to the previous arc
+#=========================================================================
+aSession.startOperation()
+aSketchArcTangent2 = aSketchFeature.addFeature("SketchArc")
+aSketchArcTangent2.string("ArcType").setValue("Tangent")
+anArcEndPoint2 = geomDataAPI_Point2D(aSketchArcTangent2.attribute("ArcEndPoint"))
+aTangent = aSketchArcTangent2.refattr("ArcTangentPoint")
+aTangent.setAttr(anArcEndPoint)
+anArcEndPoint2.setValue(50., 150.)
+aSession.finishOperation()
+#=========================================================================
+# End of test
+#=========================================================================
+
+from salome.shaper import model
+assert(model.checkPythonDump())
diff --git a/src/SketchPlugin/Test/TestCreateCircleByCenterAndPassed.py b/src/SketchPlugin/Test/TestCreateCircleByCenterAndPassed.py
new file mode 100644 (file)
index 0000000..e6695c8
--- /dev/null
@@ -0,0 +1,260 @@
+"""
+    TestCreateCircleByCenterAndPassed.py
+
+    Test creation methods of a circle built by a center and a passed point
+"""
+
+#=========================================================================
+# Initialization of the test
+#=========================================================================
+from GeomDataAPI import *
+from GeomAPI import *
+from ModelAPI import *
+from SketchAPI import SketchAPI_Sketch
+from salome.shaper import model
+import math
+
+__updated__ = "2017-03-22"
+
+
+#=========================================================================
+# Auxiliary functions
+#=========================================================================
+TOLERANCE = 1.e-7
+
+def getLastCircle(theSketch):
+    """
+    obtains last feature from the sketch and generates error if the feature is not a circle
+    """
+    expectedKind = "SketchCircle"
+    for anIndex in range(theSketch.numberOfSubs() - 1, -1, -1):
+        aSub = theSketch.subFeature(anIndex)
+        if (aSub.getKind() == expectedKind):
+            return aSub
+
+def verifyLastCircle(theSketch, theX, theY, theR):
+    """
+    subroutine to verify position of last circle in the sketch
+    """
+    aLastCircle = getLastCircle(theSketch)
+    aCenter = geomDataAPI_Point2D(aLastCircle.attribute("circle_center"))
+    verifyPointCoordinates(aCenter, theX, theY)
+    aRadius = aLastCircle.real("circle_radius")
+    assert aRadius.value() == theR, "Wrong radius {0}, expected {1}".format(aRadius.value(), theR)
+
+def verifyPointCoordinates(thePoint, theX, theY):
+    assert thePoint.x() == theX and thePoint.y() == theY, "Wrong '{0}' point ({1}, {2}), expected ({3}, {4})".format(thePoint.attributeType(), thePoint.x(), thePoint.y(), theX, theY)
+
+def verifyPointOnLine(thePoint, theLine):
+    aDistance = distancePointLine(thePoint, theLine)
+    assert aDistance < TOLERANCE, "Point is not on Line, distance: {0}".format(aDistance)
+
+def verifyTangentCircles(theCircle1, theCircle2):
+    aCenter1 = geomDataAPI_Point2D(theCircle1.attribute("circle_center"))
+    aCenter2 = geomDataAPI_Point2D(theCircle2.attribute("circle_center"))
+    aDistCC = distancePointPoint(aCenter1, aCenter2)
+    aRadius1 = theCircle1.real("circle_radius").value()
+    aRadius2 = theCircle2.real("circle_radius").value()
+    aRSum = aRadius1 + aRadius2
+    aRDiff = math.fabs(aRadius1 - aRadius2)
+    assert math.fabs(aRSum - aDistCC) < TOLERANCE or math.fabs(aRDiff - aDistCC) < TOLERANCE, "Circles do not tangent"
+
+def distancePointPoint(thePoint1, thePoint2):
+    return thePoint1.pnt().distance(thePoint2.pnt())
+
+def distancePointLine(thePoint, theLine):
+    aLineStart = geomDataAPI_Point2D(theLine.attribute("StartPoint")).pnt().xy()
+    aLineEnd = geomDataAPI_Point2D(theLine.attribute("EndPoint")).pnt().xy()
+    aLineDir = aLineEnd.decreased(aLineStart)
+    aLineLen = aLineEnd.distance(aLineStart)
+    aPntDir = thePoint.pnt().xy().decreased(aLineStart)
+    return math.fabs(aPntDir.cross(aLineDir) / aLineLen)
+
+
+#=========================================================================
+# Start of test
+#=========================================================================
+
+aSession = ModelAPI_Session.get()
+aDocument = aSession.moduleDocument()
+#=========================================================================
+# Creation of a sketch
+#=========================================================================
+aSession.startOperation()
+aSketchCommonFeature = aDocument.addFeature("Sketch")
+aSketchFeature = featureToCompositeFeature(aSketchCommonFeature)
+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)
+aSession.finishOperation()
+aSketch = SketchAPI_Sketch(aSketchFeature)
+
+#=========================================================================
+# Test 1. Create a circle by center and radius
+#=========================================================================
+aSession.startOperation()
+aCircle = aSketchFeature.addFeature("SketchCircle")
+assert (aCircle.getKind() == "SketchCircle")
+aCircleCenter = geomDataAPI_Point2D(aCircle.attribute("circle_center"))
+assert (not aCircleCenter.isInitialized())
+aCircleRadius = aCircle.real("circle_radius")
+assert (type(aCircleRadius) == ModelAPI_AttributeDouble)
+# ModelAPI_AttributeDouble.typeId() is checked in ModelAPI_TestConstants
+assert (aCircleRadius.attributeType() == ModelAPI_AttributeDouble.typeId())
+aCircleCenter.setValue(-25., -25)
+aCircleRadius.setValue(25.)
+aSession.finishOperation()
+verifyLastCircle(aSketchFeature, -25., -25., 25.)
+#=========================================================================
+# Edit the Circle
+# 1. check that changing the center of a circle does not affect radius and vise versa
+# 2. also check that int is acceptable as well as a real
+#=========================================================================
+aSession.startOperation()
+aCircleCenter.setValue(10, 60)
+aSession.finishOperation()
+verifyLastCircle(aSketchFeature, 10., 60., 25.)
+aSession.startOperation()
+aCircleRadius.setValue(int(20))
+aSession.finishOperation()
+verifyLastCircle(aSketchFeature, 10., 60., 20.)
+
+#=========================================================================
+# Test 2. Create a circle as a macro-feature by center and passed point
+#=========================================================================
+aSession.startOperation()
+aCircle = aSketchFeature.addFeature("SketchMacroCircle")
+assert (aCircle.getKind() == "SketchMacroCircle")
+aCircleCenter = geomDataAPI_Point2D(aCircle.attribute("center_point"))
+assert (not aCircleCenter.isInitialized())
+aCirclePassed = geomDataAPI_Point2D(aCircle.attribute("passed_point"))
+assert (not aCirclePassed.isInitialized())
+aCircleType = aCircle.string("circle_type")
+assert (not aCircleType.isInitialized())
+aCircleType.setValue("circle_type_by_center_and_passed_points")
+aCircleCenter.setValue(-25., -25)
+aCirclePassed.setValue(0., -25.)
+aRadius = distancePointPoint(aCircleCenter, aCirclePassed)
+aSession.finishOperation()
+assert (aSketchFeature.numberOfSubs() == 2)
+verifyLastCircle(aSketchFeature, -25., -25., aRadius)
+
+#=========================================================================
+# Test 3. Create a circle as a macro-feature by center and passed point coincident to other points
+#=========================================================================
+# get previous circle
+aPrevCircle = getLastCircle(aSketchFeature)
+aPrevCenter = geomDataAPI_Point2D(aPrevCircle.attribute("circle_center"))
+# create additional point
+aPointCoodinates = [0., 0.]
+aSession.startOperation()
+aPoint = aSketchFeature.addFeature("SketchPoint")
+aPointCoord = geomDataAPI_Point2D(aPoint.attribute("PointCoordindates"))
+aPointCoord.setValue(aPointCoodinates[0], aPointCoodinates[1])
+aSession.finishOperation()
+# create new circle
+aSession.startOperation()
+aCircle = aSketchFeature.addFeature("SketchMacroCircle")
+aCenter = geomDataAPI_Point2D(aCircle.attribute("center_point"))
+aCenterRef = aCircle.refattr("center_point_ref")
+assert (not aCenterRef.isInitialized())
+aPassed = geomDataAPI_Point2D(aCircle.attribute("passed_point"))
+aPassedRef = aCircle.refattr("passed_point_ref")
+assert (not aPassedRef.isInitialized())
+aCircleType = aCircle.string("circle_type")
+assert (not aCircleType.isInitialized())
+# initialize attributes
+aCircleType.setValue("circle_type_by_center_and_passed_points")
+aCenterRef.setObject(aPoint.lastResult())
+aCenter.setValue(aPointCoord.pnt())
+aPassedRef.setAttr(aPrevCenter)
+aPassed.setValue(aPrevCenter.pnt())
+aRadius = distancePointPoint(aPrevCenter, aPointCoord)
+aSession.finishOperation()
+assert (aSketchFeature.numberOfSubs() == 6)
+verifyPointCoordinates(aPointCoord, aPointCoodinates[0], aPointCoodinates[1])
+verifyLastCircle(aSketchFeature, aPointCoord.x(), aPointCoord.y(), aRadius)
+model.testNbSubFeatures(aSketch, "SketchConstraintCoincidence", 2)
+
+#=========================================================================
+# Test 4. Create a circle as a macro-feature by center on a line and passed point on another circle
+#=========================================================================
+# get previous circle
+aPrevCircle = getLastCircle(aSketchFeature)
+aPrevCenter = geomDataAPI_Point2D(aPrevCircle.attribute("circle_center"))
+aPrevCenterXY = [aPrevCenter.x(), aPrevCenter.y()]
+aPrevRadius = aPrevCircle.real("circle_radius").value()
+# create additional line
+aLineStart = [10., 0.]
+aLineEnd = [10., 50.]
+aSession.startOperation()
+aLine = aSketchFeature.addFeature("SketchLine")
+aStartPnt = geomDataAPI_Point2D(aLine.attribute("StartPoint"))
+aStartPnt.setValue(aLineStart[0], aLineStart[1])
+aEndPnt = geomDataAPI_Point2D(aLine.attribute("EndPoint"))
+aEndPnt.setValue(aLineEnd[0], aLineEnd[1])
+aSession.finishOperation()
+# create new circle
+aSession.startOperation()
+aCircle = aSketchFeature.addFeature("SketchMacroCircle")
+aCenter = geomDataAPI_Point2D(aCircle.attribute("center_point"))
+aCenterRef = aCircle.refattr("center_point_ref")
+aPassed = geomDataAPI_Point2D(aCircle.attribute("passed_point"))
+aPassedRef = aCircle.refattr("passed_point_ref")
+aCircleType = aCircle.string("circle_type")
+# initialize attributes
+aCircleType.setValue("circle_type_by_center_and_passed_points")
+aCenterRef.setObject(aLine.lastResult())
+anExpectedCenter = [(aLineStart[0] + aLineEnd[0]) * 0.5, (aLineStart[1] + aLineEnd[1]) * 0.5]
+aCenter.setValue(anExpectedCenter[0], anExpectedCenter[1])
+aPassedRef.setObject(aPrevCircle.lastResult())
+aPassed.setValue(aPrevCenter.x() + aPrevRadius, aPrevCenter.y())
+aRadius = distancePointPoint(aCenter, aPassed)
+aSession.finishOperation()
+assert (aSketchFeature.numberOfSubs() == 10)
+# check connected features do not change their positions
+verifyPointCoordinates(aPrevCenter, aPrevCenterXY[0], aPrevCenterXY[1])
+assert(aPrevCircle.real("circle_radius").value() == aPrevRadius)
+verifyPointCoordinates(aStartPnt, aLineStart[0], aLineStart[1])
+verifyPointCoordinates(aEndPnt, aLineEnd[0], aLineEnd[1])
+# verify newly created circle
+aCircle = getLastCircle(aSketchFeature)
+aCenter = geomDataAPI_Point2D(aCircle.attribute("circle_center"))
+verifyPointCoordinates(aCenter, anExpectedCenter[0], anExpectedCenter[1])
+verifyPointOnLine(aCenter, aLine)
+verifyTangentCircles(aCircle, aPrevCircle)
+model.testNbSubFeatures(aSketch, "SketchConstraintCoincidence", 3)
+model.testNbSubFeatures(aSketch, "SketchConstraintTangent", 1)
+
+#=========================================================================
+# Test 5. Create a circle as a macro-feature by center and passed point placed on the same line
+#         Check the circle is not created
+#=========================================================================
+aSession.startOperation()
+aCircle = aSketchFeature.addFeature("SketchMacroCircle")
+aCenter = geomDataAPI_Point2D(aCircle.attribute("center_point"))
+aCenterRef = aCircle.refattr("center_point_ref")
+aPassed = geomDataAPI_Point2D(aCircle.attribute("passed_point"))
+aPassedRef = aCircle.refattr("passed_point_ref")
+aCircleType = aCircle.string("circle_type")
+# initialize attributes
+aCircleType.setValue("circle_type_by_center_and_passed_points")
+aCenterRef.setObject(aLine.lastResult())
+aCenter.setValue(anExpectedCenter[0], anExpectedCenter[1])
+aPassedRef.setObject(aLine.lastResult())
+aPassed.setValue(aLineStart[0], aLineStart[1])
+aSession.finishOperation()
+aLastFeature = aSketchFeature.subFeature(aSketchFeature.numberOfSubs() - 1)
+assert aLastFeature == aCircle, "ERROR: SketchMacroCircle has NOT expected to be valid"
+aDocument.removeFeature(aCircle)
+assert (aSketchFeature.numberOfSubs() == 10)
+
+#=========================================================================
+# End of test
+#=========================================================================
+
+from salome.shaper import model
+assert(model.checkPythonDump())
diff --git a/src/SketchPlugin/Test/TestCreateCircleByThreePoints.py b/src/SketchPlugin/Test/TestCreateCircleByThreePoints.py
new file mode 100644 (file)
index 0000000..22f70e6
--- /dev/null
@@ -0,0 +1,306 @@
+"""
+    TestCreateCircleByThreePoints.py
+
+    Test creation methods of a circle built by three points
+"""
+
+#=========================================================================
+# Initialization of the test
+#=========================================================================
+from GeomDataAPI import *
+from GeomAPI import *
+from ModelAPI import *
+from SketchAPI import SketchAPI_Sketch
+from salome.shaper import model
+import math
+
+__updated__ = "2017-03-22"
+
+
+#=========================================================================
+# Auxiliary functions
+#=========================================================================
+TOLERANCE = 1.e-7
+
+def getLastCircle(theSketch):
+    """
+    obtains last feature from the sketch and generates error if the feature is not a circle
+    """
+    expectedKind = "SketchCircle"
+    for anIndex in range(theSketch.numberOfSubs() - 1, -1, -1):
+        aSub = theSketch.subFeature(anIndex)
+        if (aSub.getKind() == expectedKind):
+            return aSub
+
+def verifyLastCircle(theSketch, theX, theY, theR):
+    """
+    subroutine to verify position of last circle in the sketch
+    """
+    aLastCircle = getLastCircle(theSketch)
+    aCenter = geomDataAPI_Point2D(aLastCircle.attribute("circle_center"))
+    verifyPointCoordinates(aCenter, theX, theY)
+    aRadius = aLastCircle.real("circle_radius")
+    assert aRadius.value() == theR, "Wrong radius {0}, expected {1}".format(aRadius.value(), theR)
+
+def verifyPointCoordinates(thePoint, theX, theY):
+    assert thePoint.x() == theX and thePoint.y() == theY, "Wrong '{0}' point ({1}, {2}), expected ({3}, {4})".format(thePoint.attributeType(), thePoint.x(), thePoint.y(), theX, theY)
+
+def verifyPointOnCircle(thePoint, theCircle):
+    aCircleCenter = geomDataAPI_Point2D(theCircle.attribute("circle_center"))
+    aDistCP = distancePointPoint(aCircleCenter, thePoint)
+    aCircleRadius = theCircle.real("circle_radius").value()
+    assert math.fabs(aDistCP - aCircleRadius) < TOLERANCE, "Point is not on circle, distance: {0}, radius of circle: {1}".format(aDistCP, aCircleRadius)
+
+def verifyTangentCircles(theCircle1, theCircle2):
+    aCenter1 = geomDataAPI_Point2D(theCircle1.attribute("circle_center"))
+    aCenter2 = geomDataAPI_Point2D(theCircle2.attribute("circle_center"))
+    aDistCC = distancePointPoint(aCenter1, aCenter2)
+    aRadius1 = theCircle1.real("circle_radius").value()
+    aRadius2 = theCircle2.real("circle_radius").value()
+    verifyTangentCircular(aDistCC, aRadius1, aRadius2)
+
+def verifyTangentCircleArc(theCircle, theArc):
+    aCircleCenter = geomDataAPI_Point2D(theCircle.attribute("circle_center"))
+    anArcCenter = geomDataAPI_Point2D(theArc.attribute("ArcCenter"))
+    anArcStart = geomDataAPI_Point2D(theArc.attribute("ArcStartPoint"))
+    aDistCC = distancePointPoint(aCircleCenter, anArcCenter)
+    aCircleRadius = theCircle.real("circle_radius").value()
+    anArcRadius = distancePointPoint(anArcCenter, anArcStart)
+    verifyTangentCircular(aDistCC, aCircleRadius, anArcRadius)
+
+def verifyTangentCircular(theDistBetweenCenters, theRadius1, theRadius2):
+    aRSum = theRadius1 + theRadius2
+    aRDiff = math.fabs(theRadius1 - theRadius2)
+    assert math.fabs(aRSum - theDistBetweenCenters) < TOLERANCE or math.fabs(aRDiff - theDistBetweenCenters) < TOLERANCE, "Two circulars are not tangent"
+
+def verifyTangentCircleLine(theCircle, theLine):
+    aCenter = geomDataAPI_Point2D(theCircle.attribute("circle_center"))
+    aRadius = theCircle.real("circle_radius").value()
+    aDistCL = distancePointLine(aCenter, theLine)
+    assert math.fabs(aDistCL - aRadius) < TOLERANCE, "Circle and line are not tangent"
+
+def distancePointPoint(thePoint1, thePoint2):
+    return thePoint1.pnt().distance(thePoint2.pnt())
+
+def distancePointLine(thePoint, theLine):
+    aLineStart = geomDataAPI_Point2D(theLine.attribute("StartPoint")).pnt().xy()
+    aLineEnd = geomDataAPI_Point2D(theLine.attribute("EndPoint")).pnt().xy()
+    aLineDir = aLineEnd.decreased(aLineStart)
+    aLineLen = aLineEnd.distance(aLineStart)
+    aPntDir = thePoint.pnt().xy().decreased(aLineStart)
+    return math.fabs(aPntDir.cross(aLineDir) / aLineLen)
+
+
+#=========================================================================
+# Start of test
+#=========================================================================
+
+aSession = ModelAPI_Session.get()
+aDocument = aSession.moduleDocument()
+#=========================================================================
+# Creation of a sketch
+#=========================================================================
+aSession.startOperation()
+aSketchCommonFeature = aDocument.addFeature("Sketch")
+aSketchFeature = featureToCompositeFeature(aSketchCommonFeature)
+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)
+aSession.finishOperation()
+aSketch = SketchAPI_Sketch(aSketchFeature)
+
+#=========================================================================
+# Test 1. Create a circle by three points
+#=========================================================================
+expectedCenter = [0., 0.]
+expectedRadius = 10.
+aSession.startOperation()
+aCircle = aSketchFeature.addFeature("SketchMacroCircle")
+assert (aCircle.getKind() == "SketchMacroCircle")
+aCirclePnt1 = geomDataAPI_Point2D(aCircle.attribute("first_point"))
+aCirclePnt2 = geomDataAPI_Point2D(aCircle.attribute("second_point"))
+aCirclePnt3 = geomDataAPI_Point2D(aCircle.attribute("third_point"))
+assert (not aCirclePnt1.isInitialized())
+assert (not aCirclePnt2.isInitialized())
+assert (not aCirclePnt3.isInitialized())
+aCircleType = aCircle.string("circle_type")
+assert (not aCircleType.isInitialized())
+aCircleType.setValue("circle_type_by_three_points")
+aCirclePnt1.setValue(expectedCenter[0] - expectedRadius, expectedCenter[1])
+aCirclePnt2.setValue(expectedCenter[0] + expectedRadius, expectedCenter[1])
+aCirclePnt3.setValue(expectedCenter[0], expectedCenter[1] + expectedRadius)
+aSession.finishOperation()
+assert (aSketchFeature.numberOfSubs() == 1)
+verifyLastCircle(aSketchFeature, expectedCenter[0], expectedCenter[1], expectedRadius)
+
+#=========================================================================
+# Test 2. Create a circle by three points coincident to other points
+#=========================================================================
+# get previous circle
+aPrevCircle = getLastCircle(aSketchFeature)
+aPrevCenter = geomDataAPI_Point2D(aPrevCircle.attribute("circle_center"))
+aPrevCenterXY = [aPrevCenter.x(), aPrevCenter.y()]
+aPrevCircleRadius = aPrevCircle.real("circle_radius").value()
+# create additional point and line
+aPointCoodinates = [5., 20.]
+aLineStart = [10., 0.]
+aLineEnd = [10., 50.]
+aSession.startOperation()
+aPoint = aSketchFeature.addFeature("SketchPoint")
+aPointCoord = geomDataAPI_Point2D(aPoint.attribute("PointCoordindates"))
+aPointCoord.setValue(aPointCoodinates[0], aPointCoodinates[1])
+aLine = aSketchFeature.addFeature("SketchLine")
+aStartPnt = geomDataAPI_Point2D(aLine.attribute("StartPoint"))
+aStartPnt.setValue(aLineStart[0], aLineStart[1])
+aEndPnt = geomDataAPI_Point2D(aLine.attribute("EndPoint"))
+aEndPnt.setValue(aLineEnd[0], aLineEnd[1])
+aSession.finishOperation()
+# create new circle
+aSession.startOperation()
+aCircle = aSketchFeature.addFeature("SketchMacroCircle")
+aCirclePnt1 = geomDataAPI_Point2D(aCircle.attribute("first_point"))
+aCirclePnt2 = geomDataAPI_Point2D(aCircle.attribute("second_point"))
+aCirclePnt3 = geomDataAPI_Point2D(aCircle.attribute("third_point"))
+aCirclePnt1Ref = aCircle.refattr("first_point_ref")
+aCirclePnt2Ref = aCircle.refattr("second_point_ref")
+aCirclePnt3Ref = aCircle.refattr("third_point_ref")
+aCircleType = aCircle.string("circle_type")
+# initialize attributes
+aCircleType.setValue("circle_type_by_three_points")
+aCirclePnt1Ref.setAttr(aPrevCenter)
+aCirclePnt1.setValue(aPrevCenter.pnt())
+aCirclePnt2Ref.setObject(aPoint.lastResult())
+aCirclePnt2.setValue(aPointCoord.pnt())
+aCirclePnt3Ref.setAttr(aStartPnt)
+aCirclePnt3.setValue(aLineStart[0], aLineStart[1])
+aSession.finishOperation()
+assert (aSketchFeature.numberOfSubs() == 7)
+# check the points do not change their positions
+verifyPointCoordinates(aPrevCenter, aPrevCenterXY[0], aPrevCenterXY[1])
+verifyPointCoordinates(aPointCoord, aPointCoodinates[0], aPointCoodinates[1])
+verifyPointCoordinates(aStartPnt, aLineStart[0], aLineStart[1])
+# check newly created circle passes through the points
+aCircle = getLastCircle(aSketchFeature)
+verifyPointOnCircle(aPrevCenter, aCircle)
+verifyPointOnCircle(aPointCoord, aCircle)
+verifyPointOnCircle(aStartPnt, aCircle)
+model.testNbSubFeatures(aSketch, "SketchConstraintCoincidence", 3)
+model.testNbSubFeatures(aSketch, "SketchConstraintTangent", 0)
+
+#=========================================================================
+# Test 3. Create a circle by three points and tangent to line, circle and arc
+#=========================================================================
+# create additional arc
+anArcRadius = 5.
+anArcCenter = [-10., 10.]
+anArcStart = [anArcCenter[0], anArcCenter[1] - anArcRadius]
+anArcEnd = [anArcCenter[0], anArcCenter[1] + anArcRadius]
+aSession.startOperation()
+anArc = aSketchFeature.addFeature("SketchArc")
+anArcCenterPnt = geomDataAPI_Point2D(anArc.attribute("ArcCenter"))
+anArcCenterPnt.setValue(anArcCenter[0], anArcCenter[1])
+anArcStartPnt = geomDataAPI_Point2D(anArc.attribute("ArcStartPoint"))
+anArcStartPnt.setValue(anArcStart[0], anArcStart[1])
+anArcEndPnt = geomDataAPI_Point2D(anArc.attribute("ArcEndPoint"))
+anArcEndPnt.setValue(anArcEnd[0], anArcEnd[1])
+aSession.finishOperation()
+# create new circle
+aSession.startOperation()
+aCircle = aSketchFeature.addFeature("SketchMacroCircle")
+aCirclePnt1 = geomDataAPI_Point2D(aCircle.attribute("first_point"))
+aCirclePnt2 = geomDataAPI_Point2D(aCircle.attribute("second_point"))
+aCirclePnt3 = geomDataAPI_Point2D(aCircle.attribute("third_point"))
+aCirclePnt1Ref = aCircle.refattr("first_point_ref")
+aCirclePnt2Ref = aCircle.refattr("second_point_ref")
+aCirclePnt3Ref = aCircle.refattr("third_point_ref")
+aCircleType = aCircle.string("circle_type")
+# initialize attributes
+aCircleType.setValue("circle_type_by_three_points")
+aCirclePnt1Ref.setObject(aPrevCircle.lastResult())
+aCirclePnt1.setValue(aPrevCenter.x(), aPrevCenter.y() + aPrevCircleRadius)
+aCirclePnt2Ref.setObject(aLine.lastResult())
+aCirclePnt2.setValue(aLineEnd[0], aLineEnd[1])
+aCirclePnt3Ref.setObject(anArc.lastResult())
+aCirclePnt3.setValue(anArcCenter[0] + anArcRadius, anArcCenter[1])
+aSession.finishOperation()
+assert (aSketchFeature.numberOfSubs() == 12)
+# check the tangent entities do not change their positions
+verifyPointCoordinates(aPrevCenter, aPrevCenterXY[0], aPrevCenterXY[1])
+assert (aPrevCircle.real("circle_radius").value() == aPrevCircleRadius)
+verifyPointCoordinates(aStartPnt, aLineStart[0], aLineStart[1])
+verifyPointCoordinates(aEndPnt, aLineEnd[0], aLineEnd[1])
+verifyPointCoordinates(anArcCenterPnt, anArcCenter[0], anArcCenter[1])
+verifyPointCoordinates(anArcStartPnt, anArcStart[0], anArcStart[1])
+verifyPointCoordinates(anArcEndPnt, anArcEnd[0], anArcEnd[1])
+# check newly created circle passes through the points
+aCircle = getLastCircle(aSketchFeature)
+verifyTangentCircles(aCircle, aPrevCircle)
+verifyTangentCircleArc(aCircle, anArc)
+verifyTangentCircleLine(aCircle, aLine)
+model.testNbSubFeatures(aSketch, "SketchConstraintCoincidence", 3)
+model.testNbSubFeatures(aSketch, "SketchConstraintTangent", 3)
+
+#=========================================================================
+# Test 4. Create a circle by three points:
+#         a. first two points are coincident to extremities of the line
+#         b. check that this line is not selectable by third point
+#=========================================================================
+aSession.startOperation()
+aCircle = aSketchFeature.addFeature("SketchMacroCircle")
+aCirclePnt1 = geomDataAPI_Point2D(aCircle.attribute("first_point"))
+aCirclePnt2 = geomDataAPI_Point2D(aCircle.attribute("second_point"))
+aCirclePnt3 = geomDataAPI_Point2D(aCircle.attribute("third_point"))
+aCirclePnt1Ref = aCircle.refattr("first_point_ref")
+aCirclePnt2Ref = aCircle.refattr("second_point_ref")
+aCirclePnt3Ref = aCircle.refattr("third_point_ref")
+aCircleType = aCircle.string("circle_type")
+# initialize attributes
+aCircleType.setValue("circle_type_by_three_points")
+aCirclePnt1Ref.setAttr(aStartPnt)
+aCirclePnt1.setValue(aStartPnt.pnt())
+aCirclePnt2Ref.setAttr(aEndPnt)
+aCirclePnt2.setValue(aEndPnt.pnt())
+aCirclePnt3Ref.setObject(aLine.lastResult())
+aCirclePnt3.setValue(aLineEnd[0], aLineEnd[1])
+aSession.finishOperation()
+aLastFeature = aSketchFeature.subFeature(aSketchFeature.numberOfSubs() - 1)
+assert aLastFeature == aCircle, "ERROR: SketchMacroCircle has NOT expected to be valid"
+aDocument.removeFeature(aCircle)
+assert (aSketchFeature.numberOfSubs() == 12)
+
+#=========================================================================
+# Test 5. Create a circle by three points:
+#         a. first two points are placed on both sides from line
+#         b. check that this line is not selectable by third point
+#=========================================================================
+aDistanceFromLine = 20.
+aSession.startOperation()
+aCircle = aSketchFeature.addFeature("SketchMacroCircle")
+aCirclePnt1 = geomDataAPI_Point2D(aCircle.attribute("first_point"))
+aCirclePnt2 = geomDataAPI_Point2D(aCircle.attribute("second_point"))
+aCirclePnt3 = geomDataAPI_Point2D(aCircle.attribute("third_point"))
+aCirclePnt1Ref = aCircle.refattr("first_point_ref")
+aCirclePnt2Ref = aCircle.refattr("second_point_ref")
+aCirclePnt3Ref = aCircle.refattr("third_point_ref")
+aCircleType = aCircle.string("circle_type")
+# initialize attributes
+aCircleType.setValue("circle_type_by_three_points")
+aCirclePnt1.setValue(aLineStart[0] + aDistanceFromLine, aLineStart[1])
+aCirclePnt2.setValue(aLineStart[0] - aDistanceFromLine, aLineStart[1])
+aCirclePnt3Ref.setObject(aLine.lastResult())
+aCirclePnt3.setValue(aLineEnd[0], aLineEnd[1])
+aSession.finishOperation()
+aLastFeature = aSketchFeature.subFeature(aSketchFeature.numberOfSubs() - 1)
+assert aLastFeature == aCircle, "ERROR: SketchMacroCircle has NOT expected to be valid"
+aDocument.removeFeature(aCircle)
+assert (aSketchFeature.numberOfSubs() == 12)
+
+#=========================================================================
+# End of test
+#=========================================================================
+
+from salome.shaper import model
+assert(model.checkPythonDump())
diff --git a/src/SketchPlugin/Test/TestCreateCircleChangeType.py b/src/SketchPlugin/Test/TestCreateCircleChangeType.py
new file mode 100644 (file)
index 0000000..9299889
--- /dev/null
@@ -0,0 +1,171 @@
+"""
+    TestCreateCircleChangeType.py
+
+    Test attributes reset when changing creation method of a circle on-the-fly
+"""
+
+#=========================================================================
+# Initialization of the test
+#=========================================================================
+from GeomDataAPI import *
+from GeomAPI import *
+from ModelAPI import *
+from SketchAPI import SketchAPI_Sketch
+from salome.shaper import model
+import math
+
+__updated__ = "2017-03-22"
+
+
+##=========================================================================
+## Auxiliary functions
+##=========================================================================
+
+def assertNotInitializedByCenterAndPassed(theMacroCircle):
+    # check points
+    aCenterPoint = geomDataAPI_Point2D(theMacroCircle.attribute("center_point"))
+    aPassedPoint = geomDataAPI_Point2D(theMacroCircle.attribute("passed_point"))
+    assert (not aCenterPoint.isInitialized())
+    assert (not aPassedPoint.isInitialized())
+    # check references
+    aCenterPointRef = theMacroCircle.refattr("center_point_ref")
+    aPassedPointRef = theMacroCircle.refattr("passed_point_ref")
+    assert (not aCenterPointRef.isInitialized())
+    assert (not aPassedPointRef.isInitialized())
+
+def assertNotInitializedByThreePoints(theMacroCircle):
+    # check points
+    aFirstPoint = geomDataAPI_Point2D(theMacroCircle.attribute("first_point"))
+    aSecondPoint = geomDataAPI_Point2D(theMacroCircle.attribute("second_point"))
+    aThirdPoint = geomDataAPI_Point2D(theMacroCircle.attribute("third_point"))
+    assert (not aFirstPoint.isInitialized())
+    assert (not aSecondPoint.isInitialized())
+    assert (not aThirdPoint.isInitialized())
+    # check references
+    aFirstPointRef = theMacroCircle.refattr("first_point_ref")
+    aSecondPointRef = theMacroCircle.refattr("second_point_ref")
+    aThirdPointRef = theMacroCircle.refattr("third_point_ref")
+    assert (not aFirstPointRef.isInitialized())
+    assert (not aSecondPointRef.isInitialized())
+    assert (not aThirdPointRef.isInitialized())
+
+def distancePointPoint(thePoint1, thePoint2):
+    return thePoint1.pnt().distance(thePoint2.pnt())
+
+
+#=========================================================================
+# Start of test
+#=========================================================================
+
+aSession = ModelAPI_Session.get()
+aDocument = aSession.moduleDocument()
+#=========================================================================
+# Creation of a sketch
+#=========================================================================
+aSession.startOperation()
+aSketchCommonFeature = aDocument.addFeature("Sketch")
+aSketchFeature = featureToCompositeFeature(aSketchCommonFeature)
+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)
+aSession.finishOperation()
+aSketch = SketchAPI_Sketch(aSketchFeature)
+
+#=========================================================================
+# Creation of auxiliary features
+#=========================================================================
+aSession.startOperation()
+aSession.startOperation()
+aLine = aSketchFeature.addFeature("SketchLine")
+aLineStart = geomDataAPI_Point2D(aLine.attribute("StartPoint"))
+aLineStart.setValue(10., 0.)
+aLineEnd = geomDataAPI_Point2D(aLine.attribute("EndPoint"))
+aLineEnd.setValue(10., 50.)
+aSession.finishOperation()
+
+aSession.startOperation()
+#=========================================================================
+# Test 1. Create a circle as a macro-feature and check all attributes are not initialized
+#=========================================================================
+aCircle = aSketchFeature.addFeature("SketchMacroCircle")
+assert (aCircle.getKind() == "SketchMacroCircle")
+aCenterPoint = geomDataAPI_Point2D(aCircle.attribute("center_point"))
+aPassedPoint = geomDataAPI_Point2D(aCircle.attribute("passed_point"))
+aFirstPoint = geomDataAPI_Point2D(aCircle.attribute("first_point"))
+aSecondPoint = geomDataAPI_Point2D(aCircle.attribute("second_point"))
+aThirdPoint = geomDataAPI_Point2D(aCircle.attribute("third_point"))
+aCenterPointRef = aCircle.refattr("center_point_ref")
+aPassedPointRef = aCircle.refattr("passed_point_ref")
+aFirstPointRef = aCircle.refattr("first_point_ref")
+aSecondPointRef = aCircle.refattr("second_point_ref")
+aThirdPointRef = aCircle.refattr("third_point_ref")
+assertNotInitializedByCenterAndPassed(aCircle)
+assertNotInitializedByThreePoints(aCircle)
+aCircleType = aCircle.string("circle_type")
+assert (not aCircleType.isInitialized())
+#=========================================================================
+# Test 2. Initialize center of circle, check the three points are not initialized
+#=========================================================================
+aCircleType.setValue("circle_type_by_center_and_passed_points")
+aCenterPoint.setValue(-25., -25.)
+assertNotInitializedByThreePoints(aCircle)
+#=========================================================================
+# Test 3. Change type of circle and check the attributes related to center and passed point became uninitilized
+#=========================================================================
+aCircleType.setValue("circle_type_by_three_points")
+assertNotInitializedByCenterAndPassed(aCircle)
+#=========================================================================
+# Test 4. Initialize two points and change type, they should became uninitialized
+#=========================================================================
+aFirstPoint.setValue(-10., 10.)
+aSecondPoint.setValue(10., 10.)
+aCircleType.setValue("circle_type_by_center_and_passed_points")
+assertNotInitializedByThreePoints(aCircle)
+#=========================================================================
+# Test 5. Initialize center and passed point then change the type
+#=========================================================================
+aCenterPoint.setValue(-25., -25.)
+aPassedPoint.setValue(0., 0.)
+aCircleType.setValue("circle_type_by_three_points")
+assertNotInitializedByCenterAndPassed(aCircle)
+#=========================================================================
+# Test 6. Initialize all three points then change the type twice
+#=========================================================================
+aFirstPoint.setValue(-10., 10.)
+aSecondPoint.setValue(10., 10.)
+aThirdPoint.setValue(0., 0.)
+aCircleType.setValue("circle_type_by_center_and_passed_points")
+assertNotInitializedByThreePoints(aCircle)
+aCircleType.setValue("circle_type_by_three_points")
+assertNotInitializedByCenterAndPassed(aCircle)
+#=========================================================================
+# Test 7. Initialize first and third points then change the type
+#=========================================================================
+aFirstPointRef.setAttr(aLineStart)
+aFirstPoint.setValue(aLineStart.pnt())
+aThirdPointRef.setObject(aLine.lastResult())
+aThirdPoint.setValue(aLineEnd.pnt())
+aCircleType.setValue("circle_type_by_center_and_passed_points")
+assertNotInitializedByThreePoints(aCircle)
+#=========================================================================
+# Test 8. Initialize center and passed points and finish operation
+#=========================================================================
+aCenterPointRef.setAttr(aLineStart)
+aCenterPoint.setValue(aLineStart.pnt())
+aPassedPointRef.setAttr(aLineEnd)
+aPassedPoint.setValue(aLineEnd.pnt())
+aSession.finishOperation()
+
+aRadius = distancePointPoint(aLineStart, aLineEnd)
+assert (aSketchFeature.numberOfSubs() == 2)
+verifyLastCircle(aSketchFeature, aLineStart.x(), aLineStart.y(), aRadius)
+
+#=========================================================================
+# End of test
+#=========================================================================
+
+from salome.shaper import model
+assert(model.checkPythonDump())
diff --git a/src/SketchPlugin/Test/TestSketchArcCircle.py b/src/SketchPlugin/Test/TestSketchArcCircle.py
deleted file mode 100644 (file)
index 677de24..0000000
+++ /dev/null
@@ -1,248 +0,0 @@
-"""
-    TestSketchArcCircle.py
-    
-    static const std::string MY_SKETCH_ARC_ID("SketchArc");
-    static const std::string MY_CENTER_ID = "ArcCenter";
-    static const std::string MY_START_ID = "ArcStartPoint";
-    static const std::string MY_END_ID = "ArcEndPoint";
-    data()->addAttribute(SketchPlugin_Arc::CENTER_ID(), GeomDataAPI_Point2D::typeId());
-    data()->addAttribute(SketchPlugin_Arc::START_ID(),  GeomDataAPI_Point2D::typeId());
-    data()->addAttribute(SketchPlugin_Arc::END_ID(),    GeomDataAPI_Point2D::typeId());
-    
-    static const std::string MY_CIRCLE_ID("SketchCircle");
-    static const std::string MY_CIRCLE_CENTER_ID("CircleCenter");
-    static const std::string MY_CIRCLE_RADIUS_ID("CircleRadius");
-    data()->addAttribute(SketchPlugin_Circle::CENTER_ID(), GeomDataAPI_Point2D::typeId());
-    data()->addAttribute(SketchPlugin_Circle::RADIUS_ID(), ModelAPI_AttributeDouble::typeId());
-"""
-
-#=========================================================================
-# Initialization of the test
-#=========================================================================
-from GeomDataAPI import *
-from ModelAPI import *
-import math
-
-__updated__ = "2014-10-28"
-
-
-#=========================================================================
-# Auxiliary functions
-#=========================================================================
-
-def angle(theCenter, theFirst, theLast):
-    """
-    subroutine to calculate angle given by 3 points
-    """
-    aDirX1 = theFirst.x() - theCenter.x()
-    aDirY1 = theFirst.y() - theCenter.y()
-    aLen1 = math.hypot(aDirX1, aDirY1)
-    aDirX2 = theLast.x() - theCenter.x()
-    aDirY2 = theLast.y() - theCenter.y()
-    aLen2 = math.hypot(aDirX2, aDirY2)
-    aDot = aDirX1 * aDirX2 + aDirY1 * aDirY2
-    anAngle = math.acos(aDot / aLen1 / aLen2)
-    return round(anAngle * 180. / math.pi, 6)
-
-def distancePointPoint(thePointA, thePointB):
-    """
-    subroutine to calculate distance between two points
-    result of calculated distance is has 10**-5 precision
-    """
-    xdiff = math.pow((thePointA.x() - thePointB.x()), 2)
-    ydiff = math.pow((thePointA.y() - thePointB.y()), 2)
-    return round(math.sqrt(xdiff + ydiff), 5)
-
-def dot(thePoint11, thePoint12, thePoint21, thePoint22):
-    """
-    subroutine to calculate dit product between lines given by their points
-    """
-    aDirX1 = thePoint12.x() - thePoint11.x()
-    aDirY1 = thePoint12.y() - thePoint11.y()
-    aLen1 = math.hypot(aDirX1, aDirY1)
-    aDirX2 = thePoint22.x() - thePoint21.x()
-    aDirY2 = thePoint22.y() - thePoint21.y()
-    aLen2 = math.hypot(aDirX2, aDirY2)
-    aDot = aDirX1 * aDirX2 + aDirY1 * aDirY2
-    return aDot / aLen1 / aLen2
-
-
-aSession = ModelAPI_Session.get()
-aDocument = aSession.moduleDocument()
-#=========================================================================
-# Creation of a sketch
-#=========================================================================
-aSession.startOperation()
-#aSketchFeature = aDocument.addFeature("Sketch")
-aSketchCommonFeature = aDocument.addFeature("Sketch")
-aSketchFeature = featureToCompositeFeature(aSketchCommonFeature)
-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)
-aSession.finishOperation()
-#=========================================================================
-# Creation of an arc
-# 1. Test SketchPlugin_Arc attributes
-# 2.
-#=========================================================================
-aSession.startOperation()
-aSketchReflist = aSketchFeature.reflist("Features")
-assert (not aSketchReflist.isInitialized())
-assert (aSketchReflist.size() == 0)
-assert (len(aSketchReflist.list()) == 0)
-aSketchArc = aSketchFeature.addFeature("SketchArc")
-assert (aSketchArc.getKind() == "SketchArc")
-anArcCentr = geomDataAPI_Point2D(aSketchArc.attribute("ArcCenter"))
-assert (not anArcCentr.isInitialized())
-anArcCentr.setValue(10., 10.)
-anArcStartPoint = geomDataAPI_Point2D(
-    aSketchArc.attribute("ArcStartPoint"))
-assert (not anArcStartPoint.isInitialized())
-anArcStartPoint.setValue(0., 50.)
-anArcEndPoint = geomDataAPI_Point2D(aSketchArc.attribute("ArcEndPoint"))
-assert (not anArcEndPoint.isInitialized())
-anArcEndPoint.setValue(50., 0.)
-aSession.finishOperation()
-# check that values have been changed
-aSketchReflist = aSketchFeature.reflist("Features")
-assert (aSketchReflist.size() == 1)
-assert (len(aSketchReflist.list()) == 1)
-assert (anArcCentr.x() == 10.0)
-assert (anArcCentr.y() == 10.0)
-assert (anArcStartPoint.x() == 0.0)
-assert (anArcStartPoint.y() == 50.0)
-assert (anArcEndPoint.x() == 50.0)
-assert (anArcEndPoint.y() == 0.0)
-#=========================================================================
-# Edit the arc:
-# 1. Move whole arc
-# 2. Change the start point
-# 3. Change the radius of arc
-# 4. Change arc's angle
-#=========================================================================
-aSession.startOperation()
-deltaX, deltaY = 5., 10.
-anArcCentr.setValue(anArcCentr.x() + deltaX, anArcCentr.y() + deltaY)
-aSession.finishOperation()
-assert (anArcCentr.x() == 15)
-assert (anArcCentr.y() == 20)
-assert (math.fabs(distancePointPoint(anArcCentr, anArcStartPoint) - distancePointPoint(anArcCentr, anArcEndPoint)) < 1.e-10)
-# Change the start point
-aSession.startOperation()
-anArcStartPoint.setValue(anArcStartPoint.x() + deltaX, anArcStartPoint.y())
-aSession.finishOperation()
-assert (math.fabs(distancePointPoint(anArcCentr, anArcStartPoint) - distancePointPoint(anArcCentr, anArcEndPoint)) < 1.e-10)
-# Change radius
-RADIUS = 50
-aSession.startOperation()
-anArcRadius = aSketchArc.real("ArcRadius")
-anArcRadius.setValue(RADIUS)
-aSession.finishOperation()
-assert (math.fabs(distancePointPoint(anArcCentr, anArcStartPoint) - RADIUS) < 1.e-10)
-assert (math.fabs(distancePointPoint(anArcCentr, anArcEndPoint) - RADIUS) < 1.e-10)
-# Change angle
-ANGLE = 120
-aSession.startOperation()
-anArcAngle = aSketchArc.real("ArcAngle")
-anArcAngle.setValue(ANGLE)
-aSession.finishOperation()
-assert (math.fabs(angle(anArcCentr, anArcStartPoint, anArcEndPoint) - ANGLE) < 1.e-7)
-#=========================================================================
-# Check results of the Arc
-#=========================================================================
-aResult = aSketchArc.firstResult()
-aResultConstruction = modelAPI_ResultConstruction(aResult)
-aShape = aResultConstruction.shape()
-assert (aShape is not None)
-assert (not aShape.isNull())
-#=========================================================================
-# Create a circle
-# 1. Test SketchPlugin_Circle.h attributes
-# 2. ModelAPI_AttributeDouble attribute
-#=========================================================================
-aSession.startOperation()
-aSketchReflist = aSketchFeature.reflist("Features")
-# Arc is already added
-assert (aSketchReflist.size() == 1)
-assert (len(aSketchReflist.list()) == 1)
-aSketchCircle = aSketchFeature.addFeature("SketchCircle")
-assert (aSketchCircle.getKind() == "SketchCircle")
-anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("CircleCenter"))
-assert (not anCircleCentr.isInitialized())
-aCircleRadius = aSketchCircle.real("CircleRadius")
-assert (type(aCircleRadius) == ModelAPI_AttributeDouble)
-# ModelAPI_AttributeDouble.typeId() is checked in ModelAPI_TestConstants
-assert (aCircleRadius.attributeType() == ModelAPI_AttributeDouble.typeId())
-anCircleCentr.setValue(-25., -25)
-aCircleRadius.setValue(25.)
-assert (anCircleCentr.x() == -25)
-assert (anCircleCentr.y() == -25)
-assert (aCircleRadius.value() == 25)
-aSession.finishOperation()
-#=========================================================================
-# Edit the Cricle
-# 1. Check that changing the centr of a circle does not affects radius
-# 2. and vise versa; also check that int is acceptable as well as a real
-#=========================================================================
-aSession.startOperation()
-anCircleCentr.setValue(10, 60)
-aSession.finishOperation()
-assert (anCircleCentr.x() == 10)
-assert (anCircleCentr.y() == 60)
-assert (aCircleRadius.value() == 25)
-aSession.startOperation()
-aCircleRadius.setValue(int(20))
-aSession.finishOperation()
-assert (anCircleCentr.x() == 10)
-assert (anCircleCentr.y() == 60)
-assert (aCircleRadius.value() == 20)
-#=========================================================================
-# Create an arc, tangent to the line
-#=========================================================================
-aSession.startOperation()
-aSketchLine = aSketchFeature.addFeature("SketchLine")
-aLineStart = geomDataAPI_Point2D(aSketchLine.attribute("StartPoint"))
-aLineEnd = geomDataAPI_Point2D(aSketchLine.attribute("EndPoint"))
-aLineStart.setValue(0., 0.)
-aLineEnd.setValue(50., 0.)
-aSession.finishOperation()
-aSession.startOperation()
-aFixed = aSketchFeature.addFeature("SketchConstraintRigid")
-aRefObjectA = aFixed.refattr("ConstraintEntityA")
-aRefObjectA.setObject(modelAPI_ResultConstruction(aSketchLine.lastResult()))
-aFixed.execute()
-aSession.finishOperation()
-aSession.startOperation()
-aSketchArcTangent = aSketchFeature.addFeature("SketchArc")
-aSketchArcTangent.string("ArcType").setValue("Tangent")
-anArcEndPoint = geomDataAPI_Point2D(aSketchArcTangent.attribute("ArcEndPoint"))
-aTangent = aSketchArcTangent.refattr("ArcTangentPoint")
-aTangent.setAttr(aLineEnd)
-anArcEndPoint.setValue(51., 1.)
-aSession.finishOperation()
-aSession.startOperation()
-anArcEndPoint.setValue(100., 25.)
-aSession.finishOperation()
-anArcCenter = geomDataAPI_Point2D(aSketchArcTangent.attribute("ArcCenter"))
-aDot = dot(anArcCenter, aLineEnd, aLineStart, aLineEnd)
-assert math.fabs(aDot) <= 2.e-4, "Observed dot product: {0}".format(aDot)
-#=========================================================================
-# Create an arc, tangent to the previous arc
-#=========================================================================
-aSession.startOperation()
-aSketchArcTangent2 = aSketchFeature.addFeature("SketchArc")
-aSketchArcTangent2.string("ArcType").setValue("Tangent")
-anArcEndPoint2 = geomDataAPI_Point2D(aSketchArcTangent2.attribute("ArcEndPoint"))
-aTangent = aSketchArcTangent2.refattr("ArcTangentPoint")
-aTangent.setAttr(anArcEndPoint)
-anArcEndPoint2.setValue(50., 150.)
-aSession.finishOperation()
-#=========================================================================
-# End of test
-#=========================================================================
-
-from salome.shaper import model
-assert(model.checkPythonDump())
index 57c00874adc192814b7e39373ce3f847ff91e619..fa03e34aee9e0f7d259238b1d77f2c8f89a59546 100644 (file)
                icon="icons/Sketch/circle_3pt_32x32.png"
                title="Three points">
             <sketch-2dpoint_selector id="first_point"
+                                     reference_attribute="first_point_ref"
                                      title="First point"
                                      tooltip="First point"
                                      accept_expressions="0"
                                      enable_value="enable_by_preferences"/>
             <sketch-2dpoint_selector id="second_point"
+                                     reference_attribute="second_point_ref"
                                      title="Second point"
                                      tooltip="Second point"
                                      accept_expressions="0"
                                      enable_value="enable_by_preferences"/>
             <sketch-2dpoint_selector id="third_point"
+                                     reference_attribute="third_point_ref"
                                      title="Third point"
                                      tooltip="Third point"
                                      accept_expressions="0"