+ SketchPlugin_SketchEntity::initAttributes();
+
+ data()->addAttribute(CENTER_ID(), GeomDataAPI_Point2D::typeId());
+ data()->addAttribute(START_ID(), GeomDataAPI_Point2D::typeId());
+ std::shared_ptr<GeomDataAPI_Point2D> anEndAttr = std::dynamic_pointer_cast<
+ GeomDataAPI_Point2D>(data()->addAttribute(END_ID(), GeomDataAPI_Point2D::typeId()));
+ data()->addAttribute(EXTERNAL_ID(), ModelAPI_AttributeSelection::typeId());
+ ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), EXTERNAL_ID());
+
+ // get the initial values
+ if (anEndAttr->isInitialized()) {
+ myXEndBefore = anEndAttr->x();
+ myYEndBefore = anEndAttr->y();
+ }
+}
+
+void SketchPlugin_Arc::execute()
+{
+ SketchPlugin_Sketch* aSketch = sketch();
+ // result for the arc is set only when all obligatory attributes are initialized,
+ // otherwise AIS object is used to visualize the arc's preview
+ if (aSketch && isFeatureValid()) {
+ // compute a circle point in 3D view
+ std::shared_ptr<GeomDataAPI_Point2D> aCenterAttr = std::dynamic_pointer_cast<
+ GeomDataAPI_Point2D>(data()->attribute(CENTER_ID()));
+ // compute the arc start point
+ std::shared_ptr<GeomDataAPI_Point2D> aStartAttr = std::dynamic_pointer_cast<
+ GeomDataAPI_Point2D>(data()->attribute(START_ID()));
+
+ std::shared_ptr<GeomAPI_Pnt> aCenter(aSketch->to3D(aCenterAttr->x(), aCenterAttr->y()));
+ // make a visible point
+ std::shared_ptr<GeomAPI_Shape> aCenterPointShape = GeomAlgoAPI_PointBuilder::point(aCenter);
+ std::shared_ptr<ModelAPI_ResultConstruction> aConstr1 = document()->createConstruction(
+ data(), 0);
+ aConstr1->setShape(aCenterPointShape);
+ aConstr1->setIsInHistory(false);
+ setResult(aConstr1, 0);
+
+ // make a visible circle
+ 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();
+ std::shared_ptr<GeomAPI_Pnt> aStartPoint(aSketch->to3D(aStartAttr->x(), aStartAttr->y()));
+
+ // compute and change the arc end point
+ std::shared_ptr<GeomDataAPI_Point2D> anEndAttr = std::dynamic_pointer_cast<
+ GeomDataAPI_Point2D>(data()->attribute(END_ID()));
+ /* must be automatically done in attributeChanged
+ std::shared_ptr<GeomAPI_Circ2d> aCircleForArc(
+ new GeomAPI_Circ2d(aCenterAttr->pnt(), aStartAttr->pnt()));
+ std::shared_ptr<GeomAPI_Pnt2d> aProjection = aCircleForArc->project(anEndAttr->pnt());
+ if (aProjection && anEndAttr->pnt()->distance(aProjection) > tolerance)
+ anEndAttr->setValue(aProjection);
+ */
+ std::shared_ptr<GeomAPI_Pnt> aEndPoint(aSketch->to3D(anEndAttr->x(), anEndAttr->y()));
+
+ std::shared_ptr<GeomAPI_Dir> anXDir(new GeomAPI_Dir(aStartPoint->xyz()->decreased(aCenter->xyz())));
+ std::shared_ptr<GeomAPI_Ax2> anAx2(new GeomAPI_Ax2(aCenter, aNormal, anXDir));
+ std::shared_ptr<GeomAPI_Circ> aCirc(new GeomAPI_Circ(anAx2, aCenter->distance(aStartPoint)));
+ double aParameterNew = 0.0;
+ if(aCirc->parameter(aEndPoint, paramTolerance, aParameterNew)) {
+ if(0 < myParamBefore && myParamBefore <= PI / 2.0
+ && PI * 1.5 < aParameterNew && aParameterNew <= PI * 2.0) {
+ myForwardDirection = false;
+ } else if(PI * 1.5 < myParamBefore && myParamBefore <= PI * 2.0
+ && 0 < aParameterNew && aParameterNew <= PI / 2.0) {
+ myForwardDirection = true;
+ }
+ }
+ myParamBefore = aParameterNew;
+
+ std::shared_ptr<GeomAPI_Shape> aCircleShape;
+ if(myForwardDirection) {
+ aCircleShape = GeomAlgoAPI_EdgeBuilder::lineCircleArc(aCenter, aStartPoint, aEndPoint, aNormal);
+ } else {
+ aCircleShape = GeomAlgoAPI_EdgeBuilder::lineCircleArc(aCenter, aEndPoint, aStartPoint, aNormal);
+ }
+
+ if (aCircleShape) {
+ std::shared_ptr<ModelAPI_ResultConstruction> aConstr2 = document()->createConstruction(
+ data(), 1);
+ aConstr2->setShape(aCircleShape);
+ aConstr2->setIsInHistory(false);
+ setResult(aConstr2, 1);
+ }
+ }