X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2FSketchSolver%2FPlaneGCSSolver%2FPlaneGCSSolver_Storage.cpp;h=878f232ff2e707366d1ddffac947fa325b5a2f32;hb=745c72679f6346375d5e886b25cc3865f3c4daae;hp=4a9ae8a5af537c4208e7d1b1afc7f0bc731ea401;hpb=f1d9eaf541b43d0569e6fa00edb1ab2ee74aca0d;p=modules%2Fshaper.git diff --git a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.cpp b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.cpp index 4a9ae8a5a..878f232ff 100644 --- a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.cpp +++ b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2019 CEA/DEN, EDF R&D +// Copyright (C) 2014-2021 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 @@ -23,6 +23,8 @@ #include #include #include +#include +#include #include #include @@ -33,7 +35,10 @@ #include #include #include +#include +#include #include +#include #include #include @@ -102,55 +107,6 @@ EntityWrapperPtr PlaneGCSSolver_Storage::createAttribute( return aResult; } -/// \brief Update value -static bool updateValue(const double& theSource, double& theDest) -{ - static const double aTol = 1000. * tolerance; - bool isUpdated = fabs(theSource - theDest) > aTol; - if (isUpdated) - theDest = theSource; - return isUpdated; -} - -/// \brief Update coordinates of the point or scalar using its base attribute -static bool updateValues(AttributePtr& theAttribute, EntityWrapperPtr& theEntity) -{ - bool isUpdated = false; - - std::shared_ptr aPoint2D = - std::dynamic_pointer_cast(theAttribute); - if (aPoint2D) { - const GCSPointPtr& aGCSPoint = - std::dynamic_pointer_cast(theEntity)->point(); - isUpdated = updateValue(aPoint2D->x(), *(aGCSPoint->x)) || isUpdated; - isUpdated = updateValue(aPoint2D->y(), *(aGCSPoint->y)) || isUpdated; - } else { - AttributeDoublePtr aScalar = - std::dynamic_pointer_cast(theAttribute); - if (aScalar) { - ScalarWrapperPtr aWrapper = - std::dynamic_pointer_cast(theEntity); - // There is possible angular value, which is converted between degrees and radians. - // So, we use its value instead of using direct pointer to value. - double aValue = aWrapper->value(); - isUpdated = updateValue(aScalar->value(), aValue); - if (isUpdated) - aWrapper->setValue(aValue); - } else { - AttributeBooleanPtr aBoolean = - std::dynamic_pointer_cast(theAttribute); - if (aBoolean) { - BooleanWrapperPtr aWrapper = - std::dynamic_pointer_cast(theEntity); - isUpdated = aWrapper->value() != aBoolean->value(); - aWrapper->setValue(aBoolean->value()); - } - } - } - - return isUpdated; -} - static bool hasReference(std::shared_ptr theFeature, const std::string& theFeatureKind) { @@ -158,7 +114,7 @@ static bool hasReference(std::shared_ptr theFeature, for (std::set::const_iterator aRefIt = aRefs.begin(); aRefIt != aRefs.end(); ++aRefIt) { FeaturePtr anOwner = ModelAPI_Feature::feature((*aRefIt)->owner()); - if (anOwner && anOwner->getKind() == theFeatureKind) + if (anOwner && !anOwner->isMacro() && anOwner->getKind() == theFeatureKind) return true; } return false; @@ -203,9 +159,7 @@ bool PlaneGCSSolver_Storage::update(FeaturePtr theFeature, bool theForce) std::list anAttributes = theFeature->data()->attributes(std::string()); std::list::iterator anAttrIt = anAttributes.begin(); for (; anAttrIt != anAttributes.end(); ++anAttrIt) - if ((*anAttrIt)->attributeType() == GeomDataAPI_Point2D::typeId() || - (*anAttrIt)->attributeType() == ModelAPI_AttributeDouble::typeId() || - (*anAttrIt)->attributeType() == ModelAPI_AttributeBoolean::typeId()) + if (PlaneGCSSolver_Tools::isAttributeApplicable((*anAttrIt)->id(), theFeature->getKind())) isUpdated = update(*anAttrIt) || isUpdated; // check external attribute is changed @@ -257,7 +211,8 @@ bool PlaneGCSSolver_Storage::update(AttributePtr theAttribute, bool theForce) return aRelated.get() != 0; } - bool isUpdated = updateValues(anAttribute, aRelated); + PlaneGCSSolver_AttributeBuilder aBuilder(aRelated->isExternal() ? 0 : this); + bool isUpdated = aBuilder.updateAttribute(anAttribute, aRelated); if (isUpdated) { setNeedToResolve(true); notify(aFeature); @@ -413,6 +368,47 @@ static void createEllipticArcConstraints( constraintsToSolver(aConstraint, theSolver); } +static void createBSplineConstraints( + const EntityWrapperPtr& theCurve, + const SolverPtr& theSolver, + const ConstraintID theConstraintID, + std::map& theConstraints) +{ + // set start and end point of B-spline equal to first and last pole correspondingly + EdgeWrapperPtr anEdge = std::dynamic_pointer_cast(theCurve); + std::shared_ptr aBSpline = + std::dynamic_pointer_cast(anEdge->entity()); + if (aBSpline->periodic) + return; // additional constraints are not necessary + + std::list aBSplineConstraints; + + const std::map& anAdditional = anEdge->additionalAttributes(); + PointWrapperPtr aStartPoint = std::dynamic_pointer_cast( + anAdditional.at(SketchPlugin_BSpline::START_ID())); + + const GCS::Point& sp = *aStartPoint->point(); + const GCS::Point& p0 = aBSpline->poles.front(); + aBSplineConstraints.push_back(GCSConstraintPtr(new GCS::ConstraintEqual(p0.x, sp.x))); + aBSplineConstraints.push_back(GCSConstraintPtr(new GCS::ConstraintEqual(p0.y, sp.y))); + + PointWrapperPtr aEndPoint = std::dynamic_pointer_cast( + anAdditional.at(SketchPlugin_BSpline::END_ID())); + + const GCS::Point& ep = *aEndPoint->point(); + const GCS::Point& pN = aBSpline->poles.back(); + aBSplineConstraints.push_back(GCSConstraintPtr(new GCS::ConstraintEqual(pN.x, ep.x))); + aBSplineConstraints.push_back(GCSConstraintPtr(new GCS::ConstraintEqual(pN.y, ep.y))); + + ConstraintWrapperPtr aWrapper( + new PlaneGCSSolver_ConstraintWrapper(aBSplineConstraints, CONSTRAINT_UNKNOWN)); + aWrapper->setId(theConstraintID); + if (theSolver) + constraintsToSolver(aWrapper, theSolver); + + theConstraints[theCurve] = aWrapper; +} + void PlaneGCSSolver_Storage::createAuxiliaryConstraints(const EntityWrapperPtr& theEntity) { if (!theEntity || theEntity->isExternal()) @@ -426,6 +422,8 @@ void PlaneGCSSolver_Storage::createAuxiliaryConstraints(const EntityWrapperPtr& createEllipticArcConstraints(theEntity, mySketchSolver, ++myConstraintLastID, myAuxConstraintMap); } + else if (theEntity->type() == ENTITY_BSPLINE) + createBSplineConstraints(theEntity, mySketchSolver, ++myConstraintLastID, myAuxConstraintMap); } void PlaneGCSSolver_Storage::removeAuxiliaryConstraints(const EntityWrapperPtr& theEntity) @@ -470,10 +468,10 @@ void PlaneGCSSolver_Storage::adjustParametrizationOfArcs() if (anArc) adjustArcParametrization(*anArc, anEdge->isReversed()); else { -//// std::shared_ptr aEllArc = -//// std::dynamic_pointer_cast(anEdge->entity()); -//// if (aEllArc) -//// adjustArcParametrization(*aEllArc, anEdge->isReversed()); + std::shared_ptr aEllArc = + std::dynamic_pointer_cast(anEdge->entity()); + if (aEllArc) + adjustArcParametrization(*aEllArc, anEdge->isReversed()); } } @@ -578,6 +576,8 @@ double* PlaneGCSSolver_Storage::createParameter() void PlaneGCSSolver_Storage::removeParameters(const GCS::SET_pD& theParams) { mySketchSolver->removeParameters(theParams); + //for (GCS::SET_pD::iterator it = theParams.begin(); it != theParams.end(); ++it) + // delete *it; } // indicates attribute containing in the external feature @@ -626,6 +626,23 @@ void PlaneGCSSolver_Storage::refresh() const } continue; } + std::shared_ptr aPointArray = + std::dynamic_pointer_cast(anIt->first); + if (aPointArray) { + std::shared_ptr anArrayWrapper = + std::dynamic_pointer_cast(anIt->second); + int aSize = aPointArray->size(); + for (int anIndex = 0; anIndex < aSize; ++anIndex) { + GeomPnt2dPtr anOriginal = aPointArray->pnt(anIndex); + GCSPointPtr aGCSPoint = anArrayWrapper->value(anIndex)->point(); + if (fabs(anOriginal->x() - (*aGCSPoint->x)) > aTol || + fabs(anOriginal->y() - (*aGCSPoint->y)) > aTol) { + aPointArray->setPnt(anIndex, *aGCSPoint->x, *aGCSPoint->y); + addOwnerToSet(anIt->first, anUpdatedFeatures); + } + } + continue; + } AttributeDoublePtr aScalar = std::dynamic_pointer_cast(anIt->first); if (aScalar) { ScalarWrapperPtr aScalarWrapper = @@ -636,6 +653,20 @@ void PlaneGCSSolver_Storage::refresh() const } continue; } + AttributeDoubleArrayPtr aRealArray = + std::dynamic_pointer_cast(anIt->first); + if (aRealArray) { + std::shared_ptr anArrayWrapper = + std::dynamic_pointer_cast(anIt->second); + int aSize = aRealArray->size(); + for (int anIndex = 0; anIndex < aSize; ++anIndex) { + if (fabs(aRealArray->value(anIndex) - *anArrayWrapper->array()[anIndex]) > aTol) { + aRealArray->setValue(anIndex, *anArrayWrapper->array()[anIndex]); + addOwnerToSet(anIt->first, anUpdatedFeatures); + } + } + continue; + } } // notify listeners about features update @@ -654,3 +685,24 @@ PlaneGCSSolver_Solver::SolveStatus PlaneGCSSolver_Storage::checkDegeneratedGeome } return PlaneGCSSolver_Solver::STATUS_OK; } + + +void PlaneGCSSolver_Storage::getUnderconstrainedGeometry(std::set& theFeatures) const +{ + std::set aFreeParams; + mySketchSolver->getFreeParameters(aFreeParams); + if (aFreeParams.empty()) + return; + + for (std::map::const_iterator aFIt = myFeatureMap.begin(); + aFIt != myFeatureMap.end(); ++aFIt) { + if (!aFIt->second) + continue; + GCS::SET_pD aParams = PlaneGCSSolver_Tools::parameters(aFIt->second); + for (GCS::SET_pD::iterator aPIt = aParams.begin(); aPIt != aParams.end(); ++aPIt) + if (aFreeParams.find(*aPIt) != aFreeParams.end()) { + theFeatures.insert(aFIt->first); + break; + } + } +}