Salome HOME
Issue #2024: Redesign of circle and arc of circle
authorazv <azv@opencascade.com>
Sat, 25 Mar 2017 09:35:35 +0000 (12:35 +0300)
committerdbv <dbv@opencascade.com>
Mon, 27 Mar 2017 06:56:57 +0000 (09:56 +0300)
* Prepare shape for MacroCircle according to already selected points.
* Remove waste fields (myCenter and myRadius) from MacroCircle class.
* Adjust test cases for creating circle.

src/GeomAPI/GeomAPI_Circ2d.cpp
src/ModelAPI/ModelAPI_Attribute.cpp
src/SketchPlugin/SketchPlugin_MacroCircle.cpp
src/SketchPlugin/SketchPlugin_MacroCircle.h
src/SketchPlugin/Test/TestCreateCircleByCenterAndPassed.py
src/SketchPlugin/Test/TestCreateCircleByThreePoints.py
src/SketchPlugin/Test/TestCreateCircleChangeType.py

index f4533c1440eed7bc4cc68b501b6e4716a30280f5..743b44db29134a3b7c972ac2060500a4266028fa 100644 (file)
@@ -231,7 +231,7 @@ private:
                                   GccEnt::Unqualified(aCurve1->Line()),
                                   aPoint, Precision::Confusion()));
       }
-    } else if (aCurve2->GetType() == GeomAbs_Circle) {
+    } else if (aCurve1->GetType() == GeomAbs_Circle) {
       if (aCurve2->GetType() == GeomAbs_Line) {
         aCircleBuilder = std::shared_ptr<GccAna_Circ2d3Tan>(
             new GccAna_Circ2d3Tan(GccEnt::Unqualified(aCurve1->Circle()),
index 69465bf6160e38e08780489ddde7d6249274c2cf..bdf4a4df9e4ffcbaae2ca074479efe9115a77818 100644 (file)
@@ -86,4 +86,7 @@ void ModelAPI_Attribute::setID(const std::string theID)
 
 void ModelAPI_Attribute::reinit() {}
 
-void ModelAPI_Attribute::reset() {}
+void ModelAPI_Attribute::reset()
+{
+  myIsInitialized = false;
+}
index 2e67b322a3fa1c285206c6d38c86c9d13c50c16d..d1bbbd65acf8f8db22b176518eb565b851b3f4e7 100644 (file)
@@ -21,9 +21,7 @@
 
 #include <GeomAPI_Circ2d.h>
 #include <GeomAPI_Pnt2d.h>
-#include <GeomAPI_Circ.h>
 #include <GeomAPI_Vertex.h>
-#include <GeomAPI_XY.h>
 
 #include <GeomAlgoAPI_CompoundBuilder.h>
 #include <GeomAlgoAPI_EdgeBuilder.h>
@@ -48,8 +46,7 @@ namespace {
 
 
 SketchPlugin_MacroCircle::SketchPlugin_MacroCircle()
-: SketchPlugin_SketchEntity(),
-myRadius(0)
+: SketchPlugin_SketchEntity()
 {
 }
 
@@ -86,9 +83,6 @@ void SketchPlugin_MacroCircle::execute()
     createCircleByCenterAndPassed();
   else if (aType == CIRCLE_TYPE_BY_THREE_POINTS())
     createCircleByThreePoints();
-
-  myCenter.reset();
-  myRadius = 0;
 }
 
 static void convertToPointOrTangent(const AttributeRefAttrPtr&      theRefAttr,
@@ -114,24 +108,8 @@ static void convertToPointOrTangent(const AttributeRefAttrPtr&      theRefAttr,
 
 void SketchPlugin_MacroCircle::createCircleByCenterAndPassed()
 {
-  AttributePtr aPassedAttr = attribute(PASSED_POINT_ID());
-  AttributeRefAttrPtr aPassedRef = refattr(PASSED_POINT_REF_ID());
-  // Calculate circle parameters
-  std::shared_ptr<GeomAPI_Pnt2d> aCenter =
-      std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(CENTER_POINT_ID()))->pnt();
-  std::shared_ptr<GeomAPI_Pnt2d> aPassedPoint;
-  std::shared_ptr<GeomAPI_Shape> aTangentCurve;
-  convertToPointOrTangent(aPassedRef, aPassedAttr, aPassedPoint, aTangentCurve);
-
-  // Build a circle
-  std::shared_ptr<GeomAPI_Circ2d> aCircle;
-  if (aTangentCurve) {
-    std::shared_ptr<GeomAPI_Ax3> anAxis = SketchPlugin_Sketch::plane(sketch());
-    aCircle = std::shared_ptr<GeomAPI_Circ2d>(new GeomAPI_Circ2d(aCenter, aTangentCurve, anAxis));
-  } else
-    aCircle = std::shared_ptr<GeomAPI_Circ2d>(new GeomAPI_Circ2d(aCenter, aPassedPoint));
-
   // Create circle feature.
+  std::shared_ptr<GeomAPI_Circ2d> aCircle = shapeByCenterAndPassed();
   FeaturePtr aCircleFeature = createCircleFeature(aCircle);
 
   // Create constraints.
@@ -149,32 +127,12 @@ void SketchPlugin_MacroCircle::createCircleByCenterAndPassed()
 
 void SketchPlugin_MacroCircle::createCircleByThreePoints()
 {
-  std::string aPointAttr[3] = { FIRST_POINT_ID(),
-                                SECOND_POINT_ID(),
-                                THIRD_POINT_ID() };
   std::string aPointRef[3] = { FIRST_POINT_REF_ID(),
                                SECOND_POINT_REF_ID(),
                                THIRD_POINT_REF_ID() };
-  std::shared_ptr<GeomAPI_Interface> aPassedEntities[3];
-  for (int i = 0; i < 3; ++i) {
-    AttributePtr aPassedAttr = attribute(aPointAttr[i]);
-    AttributeRefAttrPtr aPassedRef = refattr(aPointRef[i]);
-    // calculate circle parameters
-    std::shared_ptr<GeomAPI_Pnt2d> aPassedPoint;
-    std::shared_ptr<GeomAPI_Shape> aTangentCurve;
-    convertToPointOrTangent(aPassedRef, aPassedAttr, aPassedPoint, aTangentCurve);
-
-    if (aPassedPoint)
-      aPassedEntities[i] = aPassedPoint;
-    else
-      aPassedEntities[i] = aTangentCurve;
-  }
-
-  std::shared_ptr<GeomAPI_Ax3> anAxis = SketchPlugin_Sketch::plane(sketch());
-  std::shared_ptr<GeomAPI_Circ2d> aCircle = std::shared_ptr<GeomAPI_Circ2d>(
-      new GeomAPI_Circ2d(aPassedEntities[0], aPassedEntities[1], aPassedEntities[2], anAxis));
 
   // Create circle feature.
+  std::shared_ptr<GeomAPI_Circ2d> aCircle = shapeByThreePoints();
   FeaturePtr aCircleFeature = createCircleFeature(aCircle);
   ResultPtr aCircleResult = aCircleFeature->lastResult();
 
@@ -198,24 +156,147 @@ FeaturePtr SketchPlugin_MacroCircle::createCircleFeature(
   return aCircleFeature;
 }
 
-AISObjectPtr SketchPlugin_MacroCircle::getAISObject(AISObjectPtr thePrevious)
+std::shared_ptr<GeomAPI_Circ2d> SketchPlugin_MacroCircle::shapeByCenterAndPassed()
 {
-  if(!myCenter.get() || myRadius < tolerance) {
-    return AISObjectPtr();
+  AttributePtr aCenterAttr = attribute(CENTER_POINT_ID());
+  AttributePtr aPassedAttr = attribute(PASSED_POINT_ID());
+  if (!aCenterAttr->isInitialized() || !aPassedAttr->isInitialized())
+    return std::shared_ptr<GeomAPI_Circ2d>();
+
+  AttributeRefAttrPtr aPassedRef = refattr(PASSED_POINT_REF_ID());
+  // Calculate circle parameters
+  std::shared_ptr<GeomAPI_Pnt2d> aCenter =
+      std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aCenterAttr)->pnt();
+  std::shared_ptr<GeomAPI_Pnt2d> aPassedPoint;
+  std::shared_ptr<GeomAPI_Shape> aTangentCurve;
+  convertToPointOrTangent(aPassedRef, aPassedAttr, aPassedPoint, aTangentCurve);
+
+  // Build a circle
+  std::shared_ptr<GeomAPI_Circ2d> aCircle;
+  if (aTangentCurve) {
+    std::shared_ptr<GeomAPI_Ax3> anAxis = SketchPlugin_Sketch::plane(sketch());
+    aCircle = std::shared_ptr<GeomAPI_Circ2d>(new GeomAPI_Circ2d(aCenter, aTangentCurve, anAxis));
+  } else
+    aCircle = std::shared_ptr<GeomAPI_Circ2d>(new GeomAPI_Circ2d(aCenter, aPassedPoint));
+  return aCircle;
+}
+
+std::shared_ptr<GeomAPI_Circ2d> SketchPlugin_MacroCircle::shapeByThreePoints()
+{
+  std::string aPointAttr[3] = { FIRST_POINT_ID(),
+                                SECOND_POINT_ID(),
+                                THIRD_POINT_ID() };
+  std::string aPointRef[3] = { FIRST_POINT_REF_ID(),
+                               SECOND_POINT_REF_ID(),
+                               THIRD_POINT_REF_ID() };
+  std::shared_ptr<GeomAPI_Interface> aPassedEntities[3];
+  for (int aPntIndex = 0; aPntIndex < 3; ++aPntIndex) {
+    AttributePtr aPassedAttr = attribute(aPointAttr[aPntIndex]);
+    if (!aPassedAttr->isInitialized())
+      break;
+
+    AttributeRefAttrPtr aPassedRef = refattr(aPointRef[aPntIndex]);
+    // calculate circle parameters
+    std::shared_ptr<GeomAPI_Pnt2d> aPassedPoint;
+    std::shared_ptr<GeomAPI_Shape> aTangentCurve;
+    convertToPointOrTangent(aPassedRef, aPassedAttr, aPassedPoint, aTangentCurve);
+
+    if (aPassedPoint)
+      aPassedEntities[aPntIndex] = aPassedPoint;
+    else
+      aPassedEntities[aPntIndex] = aTangentCurve;
   }
 
+  std::shared_ptr<GeomAPI_Ax3> anAxis = SketchPlugin_Sketch::plane(sketch());
+  std::shared_ptr<GeomAPI_Circ2d> aCircle = std::shared_ptr<GeomAPI_Circ2d>(
+      new GeomAPI_Circ2d(aPassedEntities[0], aPassedEntities[1], aPassedEntities[2], anAxis));
+  if (!aCircle->implPtr<char>())
+    return std::shared_ptr<GeomAPI_Circ2d>();
+  return aCircle;
+}
+
+std::shared_ptr<GeomAPI_Circ2d> SketchPlugin_MacroCircle::shapeByTwoPassedPoints()
+{
+  std::string aPointAttr[2] = { FIRST_POINT_ID(),
+                                SECOND_POINT_ID() };
+  std::string aPointRef[2] = { FIRST_POINT_REF_ID(),
+                               SECOND_POINT_REF_ID() };
+  std::shared_ptr<GeomAPI_Pnt2d> aPassedPoints[2]; // there is possible only two passed points
+  std::shared_ptr<GeomAPI_Interface> aPassedEntities[3];
+  int aPntIndex = 0;
+  for (; aPntIndex < 2; ++aPntIndex) {
+    AttributePtr aPassedAttr = attribute(aPointAttr[aPntIndex]);
+    if (!aPassedAttr->isInitialized())
+      break;
+
+    AttributeRefAttrPtr aPassedRef = refattr(aPointRef[aPntIndex]);
+    // calculate circle parameters
+    std::shared_ptr<GeomAPI_Pnt2d> aPassedPoint;
+    std::shared_ptr<GeomAPI_Shape> aTangentCurve;
+    convertToPointOrTangent(aPassedRef, aPassedAttr, aPassedPoint, aTangentCurve);
+
+    if (aPassedPoint) {
+      aPassedEntities[aPntIndex] = aPassedPoint;
+      aPassedPoints[aPntIndex] = aPassedPoint;
+    } else {
+      aPassedEntities[aPntIndex] = aTangentCurve;
+      // if the circle is tangent to any curve,
+      // the third point will be initialized by the tangent point
+      aPassedEntities[2] = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aPassedAttr)->pnt();
+    }
+  }
+  if (aPntIndex <= 1)
+    return std::shared_ptr<GeomAPI_Circ2d>();
+
+  std::shared_ptr<GeomAPI_Circ2d> aCircle;
+  if (aPassedEntities[2]) {
+    std::shared_ptr<GeomAPI_Ax3> anAxis = SketchPlugin_Sketch::plane(sketch());
+    aCircle = std::shared_ptr<GeomAPI_Circ2d>(
+        new GeomAPI_Circ2d(aPassedEntities[0], aPassedEntities[1], aPassedEntities[2], anAxis));
+  } else {
+    // the circle is defined by two points, calculate its parameters manually
+    std::shared_ptr<GeomAPI_Pnt2d> aCenter(new GeomAPI_Pnt2d(
+        (aPassedPoints[0]->x() + aPassedPoints[1]->x()) * 0.5,
+        (aPassedPoints[0]->y() + aPassedPoints[1]->y()) * 0.5));
+    aCircle = std::shared_ptr<GeomAPI_Circ2d>(new GeomAPI_Circ2d(aCenter, aPassedPoints[0]));
+  }
+  if (!aCircle->implPtr<char>())
+    return std::shared_ptr<GeomAPI_Circ2d>();
+  return aCircle;
+}
+
+AISObjectPtr SketchPlugin_MacroCircle::getAISObject(AISObjectPtr thePrevious)
+{
   SketchPlugin_Sketch* aSketch = sketch();
   if(!aSketch) {
     return AISObjectPtr();
   }
 
+  // Create circle on the sketch plane
+  std::shared_ptr<GeomAPI_Circ2d> aCircleOnSketch;
+  std::string aType = string(CIRCLE_TYPE())->value();
+  if (aType == CIRCLE_TYPE_BY_CENTER_AND_PASSED_POINTS())
+    aCircleOnSketch = shapeByCenterAndPassed();
+  else if (aType == CIRCLE_TYPE_BY_THREE_POINTS()) {
+    if (attribute(THIRD_POINT_ID())->isInitialized())
+      aCircleOnSketch = shapeByThreePoints();
+    else
+      aCircleOnSketch = shapeByTwoPassedPoints();
+  }
+
+  if (!aCircleOnSketch)
+    return AISObjectPtr();
+
+  std::shared_ptr<GeomAPI_Pnt2d> aCenter2D = aCircleOnSketch->center();
+  double aRadius = aCircleOnSketch->radius();
+
   // Compute a circle in 3D view.
-  std::shared_ptr<GeomAPI_Pnt> aCenter(aSketch->to3D(myCenter->x(), myCenter->y()));
+  std::shared_ptr<GeomAPI_Pnt> aCenter(aSketch->to3D(aCenter2D->x(), aCenter2D->y()));
   std::shared_ptr<GeomDataAPI_Dir> aNDir =
       std::dynamic_pointer_cast<GeomDataAPI_Dir>(
           aSketch->data()->attribute(SketchPlugin_Sketch::NORM_ID()));
   std::shared_ptr<GeomAPI_Dir> aNormal = aNDir->dir();
-  GeomShapePtr aCircleShape = GeomAlgoAPI_EdgeBuilder::lineCircle(aCenter, aNormal, myRadius);
+  GeomShapePtr aCircleShape = GeomAlgoAPI_EdgeBuilder::lineCircle(aCenter, aNormal, aRadius);
   GeomShapePtr aCenterPointShape = GeomAlgoAPI_PointBuilder::vertex(aCenter);
   if(!aCircleShape.get() || !aCenterPointShape.get()) {
     return AISObjectPtr();
@@ -235,24 +316,19 @@ AISObjectPtr SketchPlugin_MacroCircle::getAISObject(AISObjectPtr thePrevious)
 }
 
 void SketchPlugin_MacroCircle::attributeChanged(const std::string& theID) {
-  // If circle type switched reset according attributes.
+  double aRadius = 0.0;
+  // If circle type switched reset all attributes.
   if(theID == CIRCLE_TYPE()) {
-    std::string aType = string(CIRCLE_TYPE())->value();
-    if(aType == CIRCLE_TYPE_BY_CENTER_AND_PASSED_POINTS()) {
-      SketchPlugin_Tools::resetAttribute(this, CENTER_POINT_ID());
-      SketchPlugin_Tools::resetAttribute(this, CENTER_POINT_REF_ID());
-      SketchPlugin_Tools::resetAttribute(this, PASSED_POINT_ID());
-      SketchPlugin_Tools::resetAttribute(this, PASSED_POINT_REF_ID());
-    } else if(aType == CIRCLE_TYPE_BY_THREE_POINTS()) {
-      SketchPlugin_Tools::resetAttribute(this, FIRST_POINT_ID());
-      SketchPlugin_Tools::resetAttribute(this, FIRST_POINT_REF_ID());
-      SketchPlugin_Tools::resetAttribute(this, SECOND_POINT_ID());
-      SketchPlugin_Tools::resetAttribute(this, SECOND_POINT_REF_ID());
-      SketchPlugin_Tools::resetAttribute(this, THIRD_POINT_ID());
-      SketchPlugin_Tools::resetAttribute(this, THIRD_POINT_REF_ID());
-    }
-    myCenter.reset();
-    myRadius = 0;
+    SketchPlugin_Tools::resetAttribute(this, CENTER_POINT_ID());
+    SketchPlugin_Tools::resetAttribute(this, CENTER_POINT_REF_ID());
+    SketchPlugin_Tools::resetAttribute(this, PASSED_POINT_ID());
+    SketchPlugin_Tools::resetAttribute(this, PASSED_POINT_REF_ID());
+    SketchPlugin_Tools::resetAttribute(this, FIRST_POINT_ID());
+    SketchPlugin_Tools::resetAttribute(this, FIRST_POINT_REF_ID());
+    SketchPlugin_Tools::resetAttribute(this, SECOND_POINT_ID());
+    SketchPlugin_Tools::resetAttribute(this, SECOND_POINT_REF_ID());
+    SketchPlugin_Tools::resetAttribute(this, THIRD_POINT_ID());
+    SketchPlugin_Tools::resetAttribute(this, THIRD_POINT_REF_ID());
   } else if(theID == CENTER_POINT_ID() || theID == PASSED_POINT_ID()) {
     std::shared_ptr<GeomDataAPI_Point2D> aCenterPointAttr =
         std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(CENTER_POINT_ID()));
@@ -265,8 +341,7 @@ void SketchPlugin_MacroCircle::attributeChanged(const std::string& theID) {
       return;
     }
 
-    myCenter = aCenterPointAttr->pnt();
-    myRadius = myCenter->distance(aPassedPointAttr->pnt());
+    aRadius = aCenterPointAttr->pnt()->distance(aPassedPointAttr->pnt());
   } else if(theID == FIRST_POINT_ID() || theID == SECOND_POINT_ID() || theID == THIRD_POINT_ID()) {
     std::shared_ptr<GeomAPI_Pnt2d> aPoints[3];
     int aNbInitialized = 0;
@@ -277,25 +352,19 @@ void SketchPlugin_MacroCircle::attributeChanged(const std::string& theID) {
         aPoints[aNbInitialized++] = aCurPnt->pnt();
     }
 
-    if(aNbInitialized == 1) {
+    std::shared_ptr<GeomAPI_Circ2d> aCircle;
+    if(aNbInitialized == 1)
       return;
-    } else if(aNbInitialized == 2) {
-      std::shared_ptr<GeomAPI_XY> aCenterXY =
-          aPoints[0]->xy()->added(aPoints[1]->xy())->multiplied(0.5);
-      myCenter.reset(new GeomAPI_Pnt2d(aCenterXY->x(), aCenterXY->y()));
-      myRadius = aPoints[0]->distance(aPoints[1]) * 0.5;
-    } else {
-      std::shared_ptr<GeomAPI_Circ2d> aCircle(
-          new GeomAPI_Circ2d(aPoints[0], aPoints[1], aPoints[2]));
-      myCenter = aCircle->center();
-      if(myCenter.get()) {
-        myRadius = aCircle->radius();
-      }
-    }
+    else if(aNbInitialized == 2)
+      aCircle = shapeByTwoPassedPoints();
+    else
+      aCircle = shapeByThreePoints();
+    if (aCircle)
+      aRadius = aCircle->radius();
   }
 
   AttributeDoublePtr aRadiusAttr = real(CIRCLE_RADIUS_ID());
   bool aWasBlocked = data()->blockSendAttributeUpdated(true);
-  aRadiusAttr->setValue(myRadius);
+  aRadiusAttr->setValue(aRadius);
   data()->blockSendAttributeUpdated(aWasBlocked, false);
 }
index 974a0eeb6c529dde433e03d7e9ef50901f76c964..27130a4e7bc63f6e7b26a00731c7be3384197209 100644 (file)
@@ -163,14 +163,15 @@ class SketchPlugin_MacroCircle: public SketchPlugin_SketchEntity,
   SketchPlugin_MacroCircle();
 
 private:
+  std::shared_ptr<GeomAPI_Circ2d> shapeByCenterAndPassed();
+  std::shared_ptr<GeomAPI_Circ2d> shapeByThreePoints();
+  /// Creates shape if only two of three points is initialized
+  std::shared_ptr<GeomAPI_Circ2d> shapeByTwoPassedPoints();
+
   void createCircleByCenterAndPassed();
   void createCircleByThreePoints();
 
   FeaturePtr createCircleFeature(const std::shared_ptr<GeomAPI_Circ2d>& theCircle);
-
-private:
-  std::shared_ptr<GeomAPI_Pnt2d> myCenter;
-  double myRadius;
 };
 
 #endif
index e6695c8526d4c257db8bef3a76fdd003fc531afb..272399734498cbdd49028efbd215d291af79bed4 100644 (file)
@@ -248,7 +248,7 @@ 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"
+assert aLastFeature.getKind() == "SketchMacroCircle", "ERROR: SketchMacroCircle has NOT expected to be valid"
 aDocument.removeFeature(aCircle)
 assert (aSketchFeature.numberOfSubs() == 10)
 
index 22f70e6eda05af163fafff64ad9d4b72c4c46106..060127a349bc5bee8766e27a70013de1d3425388 100644 (file)
@@ -61,8 +61,8 @@ def verifyTangentCircles(theCircle1, theCircle2):
 
 def verifyTangentCircleArc(theCircle, theArc):
     aCircleCenter = geomDataAPI_Point2D(theCircle.attribute("circle_center"))
-    anArcCenter = geomDataAPI_Point2D(theArc.attribute("ArcCenter"))
-    anArcStart = geomDataAPI_Point2D(theArc.attribute("ArcStartPoint"))
+    anArcCenter = geomDataAPI_Point2D(theArc.attribute("center_point"))
+    anArcStart = geomDataAPI_Point2D(theArc.attribute("start_point"))
     aDistCC = distancePointPoint(aCircleCenter, anArcCenter)
     aCircleRadius = theCircle.real("circle_radius").value()
     anArcRadius = distancePointPoint(anArcCenter, anArcStart)
@@ -200,11 +200,11 @@ 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 = geomDataAPI_Point2D(anArc.attribute("center_point"))
 anArcCenterPnt.setValue(anArcCenter[0], anArcCenter[1])
-anArcStartPnt = geomDataAPI_Point2D(anArc.attribute("ArcStartPoint"))
+anArcStartPnt = geomDataAPI_Point2D(anArc.attribute("start_point"))
 anArcStartPnt.setValue(anArcStart[0], anArcStart[1])
-anArcEndPnt = geomDataAPI_Point2D(anArc.attribute("ArcEndPoint"))
+anArcEndPnt = geomDataAPI_Point2D(anArc.attribute("end_point"))
 anArcEndPnt.setValue(anArcEnd[0], anArcEnd[1])
 aSession.finishOperation()
 # create new circle
@@ -267,7 +267,7 @@ 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"
+assert aLastFeature.getKind() == "SketchMacroCircle", "ERROR: SketchMacroCircle has NOT expected to be valid"
 aDocument.removeFeature(aCircle)
 assert (aSketchFeature.numberOfSubs() == 12)
 
@@ -294,7 +294,7 @@ 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"
+assert aLastFeature.getKind() == "SketchMacroCircle", "ERROR: SketchMacroCircle has NOT expected to be valid"
 aDocument.removeFeature(aCircle)
 assert (aSketchFeature.numberOfSubs() == 12)
 
index 92998894a1c3bd1c9bc40be92742c7cb58121492..52daff262dbdae4ee654dd088d7db8b6156885c3 100644 (file)
@@ -49,6 +49,29 @@ def assertNotInitializedByThreePoints(theMacroCircle):
     assert (not aSecondPointRef.isInitialized())
     assert (not aThirdPointRef.isInitialized())
 
+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 distancePointPoint(thePoint1, thePoint2):
     return thePoint1.pnt().distance(thePoint2.pnt())
 
@@ -160,7 +183,8 @@ aPassedPoint.setValue(aLineEnd.pnt())
 aSession.finishOperation()
 
 aRadius = distancePointPoint(aLineStart, aLineEnd)
-assert (aSketchFeature.numberOfSubs() == 2)
+NB_FEATURES_EXPECTED = 4 # line, circle and two coincidences
+assert (aSketchFeature.numberOfSubs() == NB_FEATURES_EXPECTED), "Number of features in sketch {}, expected {}".format(aSketchFeature.numberOfSubs(), NB_FEATURES_EXPECTED)
 verifyLastCircle(aSketchFeature, aLineStart.x(), aLineStart.y(), aRadius)
 
 #=========================================================================