X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSketchPlugin%2FSketchPlugin_Arc.cpp;h=9de0fc49b97dc5851cf50f116c523120b22ac3af;hb=22b8f7fe2eccd1eeee183f52834b191b1e904dc3;hp=0cb74987a0e63c5a060f709a26142415cdce9834;hpb=241b57ba3887bc2d239df98405c4fc4d6979119b;p=modules%2Fshaper.git diff --git a/src/SketchPlugin/SketchPlugin_Arc.cpp b/src/SketchPlugin/SketchPlugin_Arc.cpp index 0cb74987a..9de0fc49b 100644 --- a/src/SketchPlugin/SketchPlugin_Arc.cpp +++ b/src/SketchPlugin/SketchPlugin_Arc.cpp @@ -12,32 +12,51 @@ #include #include +#include #include +#include #include #include #include #include #include #include +// for sqrt on Linux +#include const double tolerance = 1e-7; +const double paramTolerance = 1.e-4; +const double PI =3.141592653589793238463; SketchPlugin_Arc::SketchPlugin_Arc() : SketchPlugin_SketchEntity() { myStartUpdate = false; myEndUpdate = false; + // default values + myXEndBefore = 0; + myYEndBefore = 0; + + myForwardDirection = true; + myParamBefore = 0; } void SketchPlugin_Arc::initAttributes() { SketchPlugin_SketchEntity::initAttributes(); - data()->addAttribute(CENTER_ID(), GeomDataAPI_Point2D::type()); - data()->addAttribute(START_ID(), GeomDataAPI_Point2D::type()); - data()->addAttribute(END_ID(), GeomDataAPI_Point2D::type()); - data()->addAttribute(EXTERNAL_ID(), ModelAPI_AttributeSelection::type()); + data()->addAttribute(CENTER_ID(), GeomDataAPI_Point2D::typeId()); + data()->addAttribute(START_ID(), GeomDataAPI_Point2D::typeId()); + std::shared_ptr 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() @@ -80,8 +99,28 @@ void SketchPlugin_Arc::execute() */ std::shared_ptr aEndPoint(aSketch->to3D(anEndAttr->x(), anEndAttr->y())); - std::shared_ptr aCircleShape = GeomAlgoAPI_EdgeBuilder::lineCircleArc( - aCenter, aStartPoint, aEndPoint, aNormal); + std::shared_ptr anXDir(new GeomAPI_Dir(aStartPoint->xyz()->decreased(aCenter->xyz()))); + std::shared_ptr anAx2(new GeomAPI_Ax2(aCenter, aNormal, anXDir)); + std::shared_ptr 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 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 aConstr2 = document()->createConstruction( data(), 1); @@ -148,10 +187,6 @@ void SketchPlugin_Arc::move(double theDeltaX, double theDeltaY) if (!aData->isValid()) return; - std::shared_ptr aPoint1 = std::dynamic_pointer_cast( - aData->attribute(SketchPlugin_Arc::CENTER_ID())); - aPoint1->move(theDeltaX, theDeltaY); - myStartUpdate = true; myEndUpdate = true; std::shared_ptr aPoint2 = std::dynamic_pointer_cast( @@ -163,30 +198,10 @@ void SketchPlugin_Arc::move(double theDeltaX, double theDeltaY) aPoint3->move(theDeltaX, theDeltaY); myStartUpdate = false; myEndUpdate = false; -} - -double SketchPlugin_Arc::distanceToPoint(const std::shared_ptr& thePoint) -{ - double aDelta = 0; - std::shared_ptr aData = data(); std::shared_ptr aPoint1 = std::dynamic_pointer_cast( aData->attribute(SketchPlugin_Arc::CENTER_ID())); - aDelta = aPoint1->pnt()->distance(thePoint); - - std::shared_ptr aPoint2 = std::dynamic_pointer_cast( - aData->attribute(SketchPlugin_Arc::START_ID())); - double aDistance = aPoint2->pnt()->distance(thePoint); - if (aDelta < aDistance) - aDelta = aDistance; - - std::shared_ptr aPoint3 = std::dynamic_pointer_cast( - aData->attribute(SketchPlugin_Arc::END_ID())); - aDistance = aPoint3->pnt()->distance(thePoint); - if (aDelta < aDistance) - aDelta = aDistance; - - return aDelta; + aPoint1->move(theDeltaX, theDeltaY); } bool SketchPlugin_Arc::isFixed() { @@ -209,14 +224,29 @@ void SketchPlugin_Arc::attributeChanged(const std::string& theID) { std::shared_ptr aCenterAttr = std::dynamic_pointer_cast< GeomDataAPI_Point2D>(data()->attribute(CENTER_ID())); - if (!aCenterAttr->isInitialized()) - return; std::shared_ptr aStartAttr = std::dynamic_pointer_cast< GeomDataAPI_Point2D>(data()->attribute(START_ID())); - if (!aStartAttr->isInitialized()) - return; std::shared_ptr anEndAttr = std::dynamic_pointer_cast< GeomDataAPI_Point2D>(data()->attribute(END_ID())); + // the second condition for unability to move external segments anywhere + if (theID == EXTERNAL_ID() || isFixed()) { + std::shared_ptr aSelection = data()->selection(EXTERNAL_ID())->value(); + // update arguments due to the selection value + if (aSelection && !aSelection->isNull() && aSelection->isEdge()) { + std::shared_ptr anEdge( new GeomAPI_Edge(aSelection)); + std::shared_ptr aCirc = anEdge->circle(); + if (aCirc.get()) { + aStartAttr->setValue(sketch()->to2D(anEdge->firstPoint())); + anEndAttr->setValue(sketch()->to2D(anEdge->lastPoint())); + aCenterAttr->setValue(sketch()->to2D(aCirc->center())); + } + } + return; + } + if (!aCenterAttr->isInitialized()) + return; + if (!aStartAttr->isInitialized()) + return; if (!anEndAttr->isInitialized()) return; @@ -227,12 +257,42 @@ void SketchPlugin_Arc::attributeChanged(const std::string& theID) std::shared_ptr aCircleForArc( new GeomAPI_Circ2d(aCenterAttr->pnt(), aStartAttr->pnt())); std::shared_ptr aProjection = aCircleForArc->project(anEndAttr->pnt()); - if (aProjection && anEndAttr->pnt()->distance(aProjection) > tolerance) + if (aProjection && anEndAttr->pnt()->distance(aProjection) > tolerance) { + // issue #855: trying to update only not-updated coordinate if it is possible + if (abs(myXEndBefore - anEndAttr->x()) < 1.e-10) { // keep Y unchanged + double aVy = aCenterAttr->y() - anEndAttr->y(); + double aVy2 = aVy * aVy; + double aR2 = aCircleForArc->radius() * aCircleForArc->radius(); + if (aVy2 <= aR2) { + double aDX = sqrt(aR2 - aVy * aVy); + if (anEndAttr->x() > aCenterAttr->x()) + aProjection->setX(aCenterAttr->x() + aDX); + else + aProjection->setX(aCenterAttr->x() - aDX); + aProjection->setY(anEndAttr->y()); + } + } else if (abs(myYEndBefore - anEndAttr->y()) < 1.e-10) { // keep X unchanged + double aVx = aCenterAttr->x() - anEndAttr->x(); + double aVx2 = aVx * aVx; + double aR2 = aCircleForArc->radius() * aCircleForArc->radius(); + if (aVx2 <= aR2) { + double aDY = sqrt(aR2 - aVx * aVx); + if (anEndAttr->y() > aCenterAttr->y()) + aProjection->setY(aCenterAttr->y() + aDY); + else + aProjection->setY(aCenterAttr->y() - aDY); + aProjection->setX(anEndAttr->x()); + } + } + anEndAttr->setValue(aProjection); + } + myXEndBefore = anEndAttr->x(); + myYEndBefore = anEndAttr->y(); myEndUpdate = false; } else if (theID == START_ID() && !myStartUpdate) { myStartUpdate = true; - // compute and change the arc end point + // compute and change the arc start point std::shared_ptr aCircleForArc( new GeomAPI_Circ2d(aCenterAttr->pnt(), anEndAttr->pnt())); std::shared_ptr aProjection = aCircleForArc->project(aStartAttr->pnt());