X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2FSketchSolver%2FSketchSolver_ConstraintMovement.cpp;h=5d9f56c2be5a499bfc0be10caf645d1d5acacad7;hb=fc72d43b677baa05ae7fd317346fd8b723b799ed;hp=fdc4b0e78ff85afa6e34be69fb70fc3341219d67;hpb=6e421e939851e0de46554ae45a3ca0e1f67cd91d;p=modules%2Fshaper.git diff --git a/src/SketchSolver/SketchSolver_ConstraintMovement.cpp b/src/SketchSolver/SketchSolver_ConstraintMovement.cpp index fdc4b0e78..5d9f56c2b 100644 --- a/src/SketchSolver/SketchSolver_ConstraintMovement.cpp +++ b/src/SketchSolver/SketchSolver_ConstraintMovement.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2017-2019 CEA/DEN, EDF R&D +// Copyright (C) 2017-2023 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -22,10 +22,13 @@ #include #include +#include #include #include #include +#include +#include #include #include @@ -33,6 +36,16 @@ #include +#include + +static GCS::Point createGCSPoint(double* x, double* y) +{ + GCS::Point aPoint; + aPoint.x = x; + aPoint.y = y; + return aPoint; +} + SketchSolver_ConstraintMovement::SketchSolver_ConstraintMovement(FeaturePtr theFeature) : SketchSolver_ConstraintFixed(ConstraintPtr()), @@ -41,12 +54,14 @@ SketchSolver_ConstraintMovement::SketchSolver_ConstraintMovement(FeaturePtr theF { } -SketchSolver_ConstraintMovement::SketchSolver_ConstraintMovement(AttributePtr thePoint) +SketchSolver_ConstraintMovement::SketchSolver_ConstraintMovement(AttributePtr theAttribute, + const int thePointIndex) : SketchSolver_ConstraintFixed(ConstraintPtr()), - myDraggedPoint(thePoint), + myDraggedAttribute(theAttribute), + myDraggedPointIndex(thePointIndex), mySimpleMove(true) { - myMovedFeature = ModelAPI_Feature::feature(thePoint->owner()); + myMovedFeature = ModelAPI_Feature::feature(theAttribute->owner()); } void SketchSolver_ConstraintMovement::blockEvents(bool isBlocked) @@ -78,11 +93,14 @@ static bool isSimpleMove(FeaturePtr theMovedFeature, AttributePtr theDraggedPoin { bool isSimple = true; #ifdef CHANGE_RADIUS_WHILE_MOVE - if (theMovedFeature->getKind() == SketchPlugin_Circle::ID()) + if (theMovedFeature->getKind() == SketchPlugin_Circle::ID() || + theMovedFeature->getKind() == SketchPlugin_Ellipse::ID()) isSimple = (theDraggedPoint.get() != 0); - else if (theMovedFeature->getKind() == SketchPlugin_Arc::ID()) { + else if (theMovedFeature->getKind() == SketchPlugin_Arc::ID() || + theMovedFeature->getKind() == SketchPlugin_EllipticArc::ID()) { isSimple = (theDraggedPoint.get() != 0 && - theDraggedPoint->id() == SketchPlugin_Arc::CENTER_ID()); + (theDraggedPoint->id() == SketchPlugin_Arc::CENTER_ID() || + theDraggedPoint->id() == SketchPlugin_EllipticArc::CENTER_ID())); } #endif return isSimple; @@ -100,25 +118,36 @@ ConstraintWrapperPtr SketchSolver_ConstraintMovement::initMovement() return aConstraint; } - EntityWrapperPtr anEntity = - myDraggedPoint ? myStorage->entity(myDraggedPoint) : myStorage->entity(myMovedFeature); + EntityWrapperPtr anEntity = myDraggedAttribute ? myStorage->entity(myDraggedAttribute) + : myStorage->entity(myMovedFeature); if (!anEntity) { myStorage->update(myMovedFeature, true); - anEntity = - myDraggedPoint ? myStorage->entity(myDraggedPoint) : myStorage->entity(myMovedFeature); + anEntity = myDraggedAttribute ? myStorage->entity(myDraggedAttribute) + : myStorage->entity(myMovedFeature); if (!anEntity) return aConstraint; } - mySimpleMove = isSimpleMove(myMovedFeature, myDraggedPoint); + mySimpleMove = isSimpleMove(myMovedFeature, myDraggedAttribute); - if (mySimpleMove) + if (mySimpleMove) { + if (anEntity->type() == ENTITY_POINT_ARRAY) { + anEntity = std::dynamic_pointer_cast(anEntity) + ->value(myDraggedPointIndex); + } aConstraint = fixFeature(anEntity); + } else { - if (myDraggedPoint) // start or end point of arc has been moved + if (myDraggedAttribute) // start or end point of arc has been moved aConstraint = fixArcExtremity(anEntity); - else // arc or circle has been moved + else if (anEntity->type() == ENTITY_CIRCLE || anEntity->type() == ENTITY_ARC) { + // arc or circle has been moved aConstraint = fixPointOnCircle(anEntity); + } + else if (anEntity->type() == ENTITY_ELLIPSE || anEntity->type() == ENTITY_ELLIPTIC_ARC) { + // ellipse or elliptic arc has been moved + aConstraint = fixPointOnEllipse(anEntity); + } } return aConstraint; @@ -134,12 +163,21 @@ ConstraintWrapperPtr SketchSolver_ConstraintMovement::fixArcExtremity( myStorage->entity(myMovedFeature)); std::shared_ptr anArc = std::dynamic_pointer_cast(aCircularEntity->entity()); + std::shared_ptr anEllArc = + std::dynamic_pointer_cast(aCircularEntity->entity()); PointWrapperPtr aPoint = std::dynamic_pointer_cast(theArcExtremity); - double* aParams[nbParams] = { aPoint->point()->x, aPoint->point()->y, - anArc->center.x, anArc->center.y }; + double* aParams[nbParams] = { aPoint->point()->x, aPoint->point()->y, 0, 0 }; + if (anArc) { + aParams[2] = anArc->center.x; + aParams[3] = anArc->center.y; + } + else if (anEllArc) { + aParams[2] = anEllArc->center.x; + aParams[3] = anEllArc->center.y; + } std::list aConstraints; for (int i = 0; i < nbParams; ++i) { @@ -172,9 +210,7 @@ ConstraintWrapperPtr SketchSolver_ConstraintMovement::fixPointOnCircle( myFixedValues.push_back(*aCircular->center.y); // create a moved point - GCS::Point aPointOnCircle; - aPointOnCircle.x = &myFixedValues[0]; - aPointOnCircle.y = &myFixedValues[1]; + GCS::Point aPointOnCircle = createGCSPoint(&myFixedValues[0], &myFixedValues[1]); std::list aConstraints; // point-on-circle @@ -197,6 +233,69 @@ ConstraintWrapperPtr SketchSolver_ConstraintMovement::fixPointOnCircle( new PlaneGCSSolver_ConstraintWrapper(aConstraints, getType())); } +ConstraintWrapperPtr SketchSolver_ConstraintMovement::fixPointOnEllipse( + const EntityWrapperPtr& theConic) +{ + static const double scale = 0.01; + static const int nbParams = 6; + myFixedValues.reserve(nbParams); // moved point; center and focus of ellipse + + EdgeWrapperPtr anEdge = std::dynamic_pointer_cast(theConic); + std::shared_ptr aConic = std::dynamic_pointer_cast(anEdge->entity()); + + // major axis direction + double dx = *aConic->focus1.x - *aConic->center.x; + double dy = *aConic->focus1.y - *aConic->center.y; + double norm = sqrt(dx * dx + dy* dy); + if (norm < tolerance) { + dx = 1.0; + dy = 0.0; + } + else { + dx /= norm; + dy /= norm; + } + + double aMajorRad = aConic->getRadMaj(); + + // initialize fixed values + myFixedValues.push_back(*aConic->center.x + dx * aMajorRad); + myFixedValues.push_back(*aConic->center.y + dy * aMajorRad); + myFixedValues.push_back(*aConic->center.x); + myFixedValues.push_back(*aConic->center.y); + myFixedValues.push_back(*aConic->focus1.x); + myFixedValues.push_back(*aConic->focus1.y); + + // create a moved point + GCS::Point aPointOnEllipse = createGCSPoint(&myFixedValues[0], &myFixedValues[1]); + + std::list aConstraints; + // point-on-circle + GCSConstraintPtr aNewConstraint( + new GCS::ConstraintPointOnEllipse(aPointOnEllipse, *aConic)); + aNewConstraint->rescale(scale); + aConstraints.push_back(aNewConstraint); + // fixed center (x) + aNewConstraint = GCSConstraintPtr( + new GCS::ConstraintEqual(&myFixedValues[2], aConic->center.x)); + aNewConstraint->rescale(scale); + aConstraints.push_back(aNewConstraint); + // fixed center (y) + aNewConstraint = GCSConstraintPtr( + new GCS::ConstraintEqual(&myFixedValues[3], aConic->center.y)); + aNewConstraint->rescale(scale); + aConstraints.push_back(aNewConstraint); + // focus on the major axis + GCS::Point aStartPoint = createGCSPoint(&myFixedValues[2], &myFixedValues[3]); + GCS::Point aEndPoint = createGCSPoint(&myFixedValues[4], &myFixedValues[5]); + aNewConstraint = GCSConstraintPtr( + new GCS::ConstraintPointOnLine(aConic->focus1, aStartPoint, aEndPoint)); + aNewConstraint->rescale(scale); + aConstraints.push_back(aNewConstraint); + + return ConstraintWrapperPtr( + new PlaneGCSSolver_ConstraintWrapper(aConstraints, getType())); +} void SketchSolver_ConstraintMovement::startPoint( const std::shared_ptr& theStartPoint) @@ -220,7 +319,8 @@ void SketchSolver_ConstraintMovement::moveTo( #ifdef CHANGE_RADIUS_WHILE_MOVE int aMaxSize = mySimpleMove ? (int)myFixedValues.size() : 2; #else - int aMaxSize = myMovedFeature->getKind() == SketchPlugin_Line::ID() && !myDraggedPoint ? 4 : 2; + int aMaxSize = + myMovedFeature->getKind() == SketchPlugin_Line::ID() && !myDraggedAttribute ? 4 : 2; #endif for (int i = 0; i < aMaxSize; ++i) myFixedValues[i] += aDelta[i % 2];