+static void intersectShapeAndCircle(const GeomShapePtr& theShape,
+ const GeomAPI_Circ2d& theCircle,
+ const SketchPlugin_Sketch* theSketch,
+ AttributePoint2DPtr& theIntersection)
+{
+ if (!theShape->isEdge())
+ return projectPointOnCircle(theIntersection, theCircle);
+
+ // convert shape to unbounded
+ std::shared_ptr<GeomAPI_Edge> anEdge(new GeomAPI_Edge(theShape));
+ if (anEdge->isLine()) {
+ static const double HALF_SIZE = 1.e6;
+ std::shared_ptr<GeomAPI_XYZ> aLoc = anEdge->line()->location()->xyz();
+ std::shared_ptr<GeomAPI_XYZ> aDir = anEdge->line()->direction()->xyz();
+
+ std::shared_ptr<GeomAPI_Pnt> aStart(
+ new GeomAPI_Pnt(aLoc->added(aDir->multiplied(-HALF_SIZE))));
+ std::shared_ptr<GeomAPI_Pnt> aEnd(
+ new GeomAPI_Pnt(aLoc->added(aDir->multiplied(HALF_SIZE))));
+ anEdge = GeomAlgoAPI_EdgeBuilder::line(aStart, aEnd);
+ } else if (anEdge->isArc()) {
+ std::shared_ptr<GeomAPI_Circ> aCircle = anEdge->circle();
+ anEdge = GeomAlgoAPI_EdgeBuilder::lineCircle(
+ aCircle->center(), aCircle->normal(), aCircle->radius());
+ }
+
+ // convert 2D circle to 3D object
+ std::shared_ptr<GeomAPI_Pnt2d> aCenter2d = theCircle.center();
+ std::shared_ptr<GeomAPI_Pnt> aCenter(theSketch->to3D(aCenter2d->x(), aCenter2d->y()));
+ std::shared_ptr<GeomDataAPI_Dir> aNDir = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
+ const_cast<SketchPlugin_Sketch*>(theSketch)->attribute(SketchPlugin_Sketch::NORM_ID()));
+ std::shared_ptr<GeomAPI_Dir> aNormal(new GeomAPI_Dir(aNDir->x(), aNDir->y(), aNDir->z()));
+
+ GeomShapePtr aCircleShape =
+ GeomAlgoAPI_EdgeBuilder::lineCircle(aCenter, aNormal, theCircle.radius());
+
+ GeomShapePtr anInter = anEdge->intersect(aCircleShape);
+ std::shared_ptr<GeomAPI_Pnt2d> anInterPnt;
+ if (!anInter)
+ return projectPointOnCircle(theIntersection, theCircle);
+ if (anInter->isVertex()) {
+ std::shared_ptr<GeomAPI_Vertex> aVertex(new GeomAPI_Vertex(anInter));
+ anInterPnt = theSketch->to2D(aVertex->point());
+ } else if (anInter->isCompound()) {
+ double aMinDist = 1.e300;
+
+ GeomAPI_ShapeIterator anIt(anInter);
+ for (; anIt.more(); anIt.next()) {
+ GeomShapePtr aCurrent = anIt.current();
+ if (!aCurrent->isVertex())
+ continue;
+ std::shared_ptr<GeomAPI_Vertex> aVertex(new GeomAPI_Vertex(aCurrent));
+ std::shared_ptr<GeomAPI_Pnt2d> aPnt = theSketch->to2D(aVertex->point());
+ double aDist = aPnt->distance(theIntersection->pnt());
+ if (aDist < aMinDist) {
+ aMinDist = aDist;
+ anInterPnt = aPnt;
+ }
+ }
+ }
+ if(anInterPnt.get()) {
+ theIntersection->setValue(anInterPnt);
+ }
+}
+