X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSketchPlugin%2FSketchPlugin_Arc.cpp;h=4de5125106cb02038952369b76739524bc415c71;hb=07889bdf129940bf25021b91aa58902e634a64ce;hp=9825ce9c2be65542bdee5ac4087b826d58b170e6;hpb=0852116f20f2e9a48124102209eafbde3df7d046;p=modules%2Fshaper.git diff --git a/src/SketchPlugin/SketchPlugin_Arc.cpp b/src/SketchPlugin/SketchPlugin_Arc.cpp index 9825ce9c2..4de512510 100644 --- a/src/SketchPlugin/SketchPlugin_Arc.cpp +++ b/src/SketchPlugin/SketchPlugin_Arc.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -40,7 +41,7 @@ const double tolerance = 1e-7; const double paramTolerance = 1.e-4; -const double PI =3.141592653589793238463; +const double PI = 3.141592653589793238463; namespace { static const std::string& POINT_ID(int theIndex) @@ -67,7 +68,7 @@ SketchPlugin_Arc::SketchPlugin_Arc() myXEndBefore = 0; myYEndBefore = 0; - myParamBefore = 0; + myParamBefore = PI * 2.0; } void SketchPlugin_Arc::initDerivedClassAttributes() @@ -119,7 +120,7 @@ void SketchPlugin_Arc::execute() std::shared_ptr aCenter(aSketch->to3D(aCenterAttr->x(), aCenterAttr->y())); // make a visible point - std::shared_ptr aCenterPointShape = GeomAlgoAPI_PointBuilder::point(aCenter); + std::shared_ptr aCenterPointShape = GeomAlgoAPI_PointBuilder::vertex(aCenter); std::shared_ptr aConstr1 = document()->createConstruction( data(), 0); aConstr1->setShape(aCenterPointShape); @@ -144,20 +145,8 @@ void SketchPlugin_Arc::execute() AttributeBooleanPtr isInversed = std::dynamic_pointer_cast(attribute(INVERSED_ID())); - 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) { - isInversed->setValue(true); - } else if(PI * 1.5 <= myParamBefore && myParamBefore <= PI * 2.0 - && 0 <= aParameterNew && aParameterNew <= PI / 2.0) { - isInversed->setValue(false); - } - } - myParamBefore = aParameterNew; + // compute end parameter + aCircleForArc->parameter(anEndAttr->pnt(), paramTolerance, myParamBefore); std::shared_ptr aCircleShape; if(!isInversed->value()) { @@ -207,31 +196,46 @@ AISObjectPtr SketchPlugin_Arc::getAISObject(AISObjectPtr thePrevious) std::shared_ptr aStartPoint(aSketch->to3D(aStartAttr->x(), aStartAttr->y())); std::shared_ptr aEndPoint = aStartPoint; if (aTypeAttr && aTypeAttr->isInitialized() && - aTypeAttr->value() == ARC_TYPE_THREE_POINTS() && aEndAttr->isInitialized() && - aEndAttr->pnt()->distance(aStartAttr->pnt()) > tolerance) { - aEndPoint = aSketch->to3D(aEndAttr->x(), aEndAttr->y()); - std::shared_ptr aPassedAttr = - std::dynamic_pointer_cast(data()->attribute(PASSED_POINT_ID())); - if (!aPassedAttr->isInitialized()) { // calculate the appropriate center for the presentation - std::shared_ptr aDir = - aEndAttr->pnt()->xy()->decreased(aStartAttr->pnt()->xy())->multiplied(0.5); - double x = aDir->x(); - double y = aDir->y(); - aDir->setX(x - y); - aDir->setY(y + x); - std::shared_ptr aCenterXY = aStartAttr->pnt()->xy()->added(aDir); - aCenter = aSketch->to3D(aCenterXY->x(), aCenterXY->y()); + aTypeAttr->value() == ARC_TYPE_THREE_POINTS()) { + if (aEndAttr->isInitialized() && // + aEndAttr->pnt()->distance(aStartAttr->pnt()) > tolerance) { + aEndPoint = aSketch->to3D(aEndAttr->x(), aEndAttr->y()); + std::shared_ptr aPassedAttr = + std::dynamic_pointer_cast(data()->attribute(PASSED_POINT_ID())); + if (!aPassedAttr->isInitialized()) { // calculate the appropriate center for the presentation + // check that center is bad for the current start and end and must be recomputed + std::shared_ptr aCircleForArc(new GeomAPI_Circ2d( + aCenterAttr->pnt(), aStartAttr->pnt())); + std::shared_ptr aProjection = aCircleForArc->project(aEndAttr->pnt()); + if (!aProjection.get() || aEndAttr->pnt()->distance(aProjection) > tolerance) { + std::shared_ptr aDir = + aEndAttr->pnt()->xy()->decreased(aStartAttr->pnt()->xy())->multiplied(0.5); + double x = aDir->x(); + double y = aDir->y(); + aDir->setX(x - y); + aDir->setY(y + x); + std::shared_ptr aCenterXY = aStartAttr->pnt()->xy()->added(aDir); + aCenter = aSketch->to3D(aCenterXY->x(), aCenterXY->y()); + } + } + } else { // issue #1695: don't display circle if initialized only start point + return AISObjectPtr(); } } + AttributeBooleanPtr isInversed = + std::dynamic_pointer_cast(attribute(INVERSED_ID())); + + std::shared_ptr aCircleShape = + (isInversed->isInitialized() && isInversed->value()) ? + GeomAlgoAPI_EdgeBuilder::lineCircleArc(aCenter, aEndPoint, aStartPoint, aNormal) : + GeomAlgoAPI_EdgeBuilder::lineCircleArc(aCenter, aStartPoint, aEndPoint, aNormal); - std::shared_ptr aCircleShape = GeomAlgoAPI_EdgeBuilder::lineCircleArc( - aCenter, aStartPoint, aEndPoint, aNormal); if (aCircleShape) aShapes.push_back(aCircleShape); } } // make a visible point - std::shared_ptr aCenterPointShape = GeomAlgoAPI_PointBuilder::point(aCenter); + std::shared_ptr aCenterPointShape = GeomAlgoAPI_PointBuilder::vertex(aCenter); aShapes.push_back(aCenterPointShape); } if (!aShapes.empty()) { @@ -240,6 +244,9 @@ AISObjectPtr SketchPlugin_Arc::getAISObject(AISObjectPtr thePrevious) if (!anAIS) anAIS = AISObjectPtr(new GeomAPI_AISObject); anAIS->createShape(aCompound); + double aDeflection = Config_PropManager::real("Visualization", "construction_deflection", + ModelAPI_ResultConstruction::DEFAULT_DEFLECTION()); + anAIS->setDeflection(aDeflection); anAIS->setWidth(3); return anAIS; } @@ -260,21 +267,25 @@ void SketchPlugin_Arc::move(double theDeltaX, double theDeltaY) myEndUpdate = true; std::shared_ptr aPoint2 = std::dynamic_pointer_cast( aData->attribute(SketchPlugin_Arc::START_ID())); - aPoint2->move(theDeltaX, theDeltaY); + if (aPoint2->isInitialized()) + aPoint2->move(theDeltaX, theDeltaY); std::shared_ptr aPoint3 = std::dynamic_pointer_cast( aData->attribute(SketchPlugin_Arc::END_ID())); - aPoint3->move(theDeltaX, theDeltaY); + if (aPoint3->isInitialized()) + aPoint3->move(theDeltaX, theDeltaY); myStartUpdate = false; myEndUpdate = false; std::shared_ptr aPoint1 = std::dynamic_pointer_cast( aData->attribute(SketchPlugin_Arc::CENTER_ID())); - aPoint1->move(theDeltaX, theDeltaY); + if (aPoint1->isInitialized()) + aPoint1->move(theDeltaX, theDeltaY); std::shared_ptr aPassedPoint = std::dynamic_pointer_cast(aData->attribute(PASSED_POINT_ID())); - aPassedPoint->move(theDeltaX, theDeltaY); + if (aPassedPoint->isInitialized()) + aPassedPoint->move(theDeltaX, theDeltaY); aData->blockSendAttributeUpdated(false); } @@ -326,6 +337,12 @@ void SketchPlugin_Arc::attributeChanged(const std::string& theID) // the second condition for unability to move external segments anywhere if (theID == EXTERNAL_ID() || isFixed()) { std::shared_ptr aSelection = data()->selection(EXTERNAL_ID())->value(); + if (!aSelection) { + // empty shape in selection shows that the shape is equal to context + ResultPtr anExtRes = selection(EXTERNAL_ID())->context(); + if (anExtRes) + aSelection = anExtRes->shape(); + } // update arguments due to the selection value if (aSelection && !aSelection->isNull() && aSelection->isEdge()) { std::shared_ptr anEdge( new GeomAPI_Edge(aSelection)); @@ -339,6 +356,8 @@ void SketchPlugin_Arc::attributeChanged(const std::string& theID) double aStartAngle, aEndAngle; anEdge->getRange(aStartAngle, aEndAngle); data()->real(ANGLE_ID())->setValue(aEndAngle - aStartAngle); + myParamBefore = aEndAngle; + adjustPeriod(myParamBefore); } } return; @@ -358,6 +377,8 @@ void SketchPlugin_Arc::attributeChanged(const std::string& theID) std::shared_ptr aTangentPoint = std::dynamic_pointer_cast(aTangPtAttr->attr()); std::shared_ptr aTangPnt2d = aTangentPoint->pnt(); + if (aTangPnt2d->isEqual(anEndAttr->pnt())) + return; FeaturePtr aTangFeature = ModelAPI_Feature::feature(aTangentPoint->owner()); std::shared_ptr aTangEdge = std::dynamic_pointer_cast( aTangFeature->lastResult()->shape()); @@ -472,13 +493,26 @@ void SketchPlugin_Arc::attributeChanged(const std::string& theID) double aNewAngle = aPassedParam >= aStartParam && aPassedParam <= aEndParam ? ((aEndParam - aStartParam) * 180.0 / PI) : ((aEndParam - aStartParam - 2.0 * PI) * 180.0 / PI); - if (fabs(aNewAngle - anAngleAttr->value()) > tolerance) + if (!anAngleAttr->isInitialized() || fabs(aNewAngle - anAngleAttr->value()) > tolerance) anAngleAttr->setValue(aNewAngle); } else { double aNewAngle = (aEndParam - aStartParam) * 180.0 / PI; - if (fabs(aNewAngle - anAngleAttr->value()) > tolerance) + if (!anAngleAttr->isInitialized() || fabs(aNewAngle - anAngleAttr->value()) > tolerance) anAngleAttr->setValue(aNewAngle); } + + // calculate arc aperture and change the Inversed flag if needed + AttributeBooleanPtr isInversed = + std::dynamic_pointer_cast(attribute(INVERSED_ID())); + double aParameterNew = aEndParam - aStartParam; + if (0 <= myParamBefore && myParamBefore <= PI / 2.0 && + PI * 1.5 <= aParameterNew && aParameterNew <= PI * 2.0) + isInversed->setValue(true); + else if (PI * 1.5 <= myParamBefore && myParamBefore <= PI * 2.0 && + 0 <= aParameterNew && aParameterNew <= PI / 2.0) + isInversed->setValue(false); + myParamBefore = aParameterNew; + // do not need to inform that other parameters were changed in this basis mode: these arguments // change is enough data()->blockSendAttributeUpdated(false, false);