From: azv Date: Tue, 22 Dec 2015 13:10:48 +0000 (+0300) Subject: "Conflicting constraints" should appear when a center of fillet is coincident with... X-Git-Tag: V_2.1.0~109 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=45d7a2bd3a8c6f9de2927a53bea219ade14a733c;p=modules%2Fshaper.git "Conflicting constraints" should appear when a center of fillet is coincident with fillet base point (issue #1138) --- diff --git a/src/Model/Model_Data.cpp b/src/Model/Model_Data.cpp index 47f27eaad..1072d921b 100644 --- a/src/Model/Model_Data.cpp +++ b/src/Model/Model_Data.cpp @@ -565,7 +565,9 @@ void Model_Data::copyTo(std::shared_ptr theTarget) std::map >::iterator aMyIter = myAttrs.begin(); for(; aMyIter != myAttrs.end(); aMyIter++) { if (aMyIter->second->isInitialized()) { - theTarget->attribute(aMyIter->first)->setInitialized(); + AttributePtr aTargetAttr = theTarget->attribute(aMyIter->first); + if (aTargetAttr) + aTargetAttr->setInitialized(); } } } diff --git a/src/SketchSolver/SketchSolver_Group.cpp b/src/SketchSolver/SketchSolver_Group.cpp index b4856ba88..d62f995e1 100644 --- a/src/SketchSolver/SketchSolver_Group.cpp +++ b/src/SketchSolver/SketchSolver_Group.cpp @@ -297,6 +297,7 @@ bool SketchSolver_Group::resolveConstraints() mySketchSolver->setGroup(myID); mySketchSolver->calculateFailedConstraints(false); myStorage->initializeSolver(mySketchSolver); + mySketchSolver->prepare(); SketchSolver_SolveStatus aResult = STATUS_OK; try { @@ -329,6 +330,7 @@ bool SketchSolver_Group::resolveConstraints() sendMessage(EVENT_SOLVER_FAILED); myPrevSolved = false; } + mySketchSolver->undo(); return false; } if (aResult == STATUS_OK || aResult == STATUS_EMPTYSET) { // solution succeeded, store results into correspondent attributes @@ -339,13 +341,16 @@ bool SketchSolver_Group::resolveConstraints() sendMessage(EVENT_SOLVER_REPAIRED); myPrevSolved = true; } - } else if (!myConstraints.empty()) { + } else { + mySketchSolver->undo(); + if (!myConstraints.empty()) { // Events_Error::send(SketchSolver_Error::CONSTRAINTS(), this); - getWorkplane()->string(SketchPlugin_Sketch::SOLVER_ERROR())->setValue(SketchSolver_Error::CONSTRAINTS()); - if (myPrevSolved) { - // the error message should be changed before sending the message - sendMessage(EVENT_SOLVER_FAILED); - myPrevSolved = false; + getWorkplane()->string(SketchPlugin_Sketch::SOLVER_ERROR())->setValue(SketchSolver_Error::CONSTRAINTS()); + if (myPrevSolved) { + // the error message should be changed before sending the message + sendMessage(EVENT_SOLVER_FAILED); + myPrevSolved = false; + } } } diff --git a/src/SketchSolver/SketchSolver_ISolver.h b/src/SketchSolver/SketchSolver_ISolver.h index 75ddbfdf4..19c2c5e22 100644 --- a/src/SketchSolver/SketchSolver_ISolver.h +++ b/src/SketchSolver/SketchSolver_ISolver.h @@ -36,10 +36,16 @@ public: void calculateFailedConstraints(bool theSic) { myFindFaileds = theSic; } + /// \brief Prepare for solving. Store initial values of parameters for undo + virtual void prepare() = 0; + /// \brief Solve the set of equations /// \return identifier whether solution succeeded virtual SketchSolver_SolveStatus solve() = 0; + /// \brief Revert solution to initial values + virtual void undo() = 0; + protected: GroupID myGroup; ///< ID of the group to be solved bool myFindFaileds; ///< flag to find conflicting or inappropriate constraints diff --git a/src/SketchSolver/SketchSolver_Storage.cpp b/src/SketchSolver/SketchSolver_Storage.cpp index 742ef54bd..f5617bbea 100644 --- a/src/SketchSolver/SketchSolver_Storage.cpp +++ b/src/SketchSolver/SketchSolver_Storage.cpp @@ -85,6 +85,15 @@ void SketchSolver_Storage::addEntity(FeaturePtr theFeature, (theSolverEntity && !aFound->second->isEqual(theSolverEntity))) setNeedToResolve(true); // the entity is new or modified + if (!theSolverEntity) { + // feature links to the empty entity, add its attributes + std::list aPntAttrs = + theFeature->data()->attributes(GeomDataAPI_Point2D::typeId()); + std::list::const_iterator anAttrIt = aPntAttrs.begin(); + for (; anAttrIt != aPntAttrs.end(); ++anAttrIt) + addEntity(*anAttrIt, EntityWrapperPtr()); + } + myFeatureMap[theFeature] = theSolverEntity; // block events if necessary if (myEventsBlocked && theFeature->data() && theFeature->data()->isValid()) diff --git a/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Solver.cpp b/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Solver.cpp index a46a7c0b3..a7a83a13d 100644 --- a/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Solver.cpp +++ b/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Solver.cpp @@ -27,6 +27,8 @@ SolveSpaceSolver_Solver::SolveSpaceSolver_Solver() // If the set of constraints is inconsistent, // the failed field will contain wrong constraints myEquationsSystem.calculateFaileds = 0; + + myParamsCopy = 0; } SolveSpaceSolver_Solver::~SolveSpaceSolver_Solver() @@ -37,6 +39,9 @@ SolveSpaceSolver_Solver::~SolveSpaceSolver_Solver() if (myEquationsSystem.failed) delete[] myEquationsSystem.failed; myEquationsSystem.failed = 0; + if (myParamsCopy) + delete [] myParamsCopy; + myParamsCopy = 0; } void SolveSpaceSolver_Solver::setParameters(Slvs_Param* theParameters, int theSize) @@ -104,5 +109,83 @@ SketchSolver_SolveStatus SolveSpaceSolver_Solver::solve() default: aStatus = STATUS_FAILED; } + + if (aStatus == STATUS_OK) { + // additional verification of arcs to be non-degenerated + if (hasDegeneratedArcs()) { + undo(); + aStatus = STATUS_INCONSISTENT; + } + } + return aStatus; } + +void SolveSpaceSolver_Solver::prepare() +{ + // make a copy of parameters to be able to make undo + if (myParamsCopy) + delete [] myParamsCopy; + myParamsCopy = new Slvs_Param[myEquationsSystem.params]; + memcpy(myParamsCopy, myEquationsSystem.param, myEquationsSystem.params * sizeof(Slvs_Param)); +} + +void SolveSpaceSolver_Solver::undo() +{ + if (myParamsCopy) { + memcpy(myEquationsSystem.param, myParamsCopy, myEquationsSystem.params * sizeof(Slvs_Param)); + delete [] myParamsCopy; + } + myParamsCopy = 0; +} + + +bool SolveSpaceSolver_Solver::hasDegeneratedArcs() const +{ + const double aTol2 = tolerance * tolerance; + double anArcPoints[3][2]; + + for (int anEnt = 0; anEnt < myEquationsSystem.entities; ++anEnt) { + const Slvs_Entity& anEntity = myEquationsSystem.entity[anEnt]; + if (anEntity.type != SLVS_E_ARC_OF_CIRCLE) + continue; + + for (int aPnt = 0; aPnt < 3; ++aPnt) { + // search point of arc + const int aShift = anEntity.point[aPnt] - anEntity.h; + int aPntInd = anEnt + aShift; + int aStep = 1; + if (myEquationsSystem.entity[aPntInd].h > anEntity.point[aPnt]) + aStep = -1; + for (; aPntInd >=0 && aPntInd < myEquationsSystem.entities; aPntInd += aStep) + if (myEquationsSystem.entity[aPntInd].h == anEntity.point[aPnt]) + break; + + // search coordinates of the point + int aParamInd = myEquationsSystem.entity[aPntInd].param[0]; + if (aParamInd >= myEquationsSystem.params) { + aParamInd = myEquationsSystem.params - 1; + aStep = -1; + } + else if ((int)myEquationsSystem.param[aParamInd].h > aParamInd) + aStep = -1; + else aStep = 1; + + for (; aParamInd >=0 && aParamInd < myEquationsSystem.params; aParamInd += aStep) + if (myEquationsSystem.param[aParamInd].h == myEquationsSystem.entity[aPntInd].param[0]) + break; + anArcPoints[aPnt][0] = myEquationsSystem.param[aParamInd].val; + anArcPoints[aPnt][1] = myEquationsSystem.param[aParamInd+1].val; + } + + // check radius of arc + anArcPoints[1][0] -= anArcPoints[0][0]; + anArcPoints[1][1] -= anArcPoints[0][1]; + anArcPoints[2][0] -= anArcPoints[0][0]; + anArcPoints[2][1] -= anArcPoints[0][1]; + if (anArcPoints[1][0] * anArcPoints[1][0] + anArcPoints[1][1] * anArcPoints[1][1] < aTol2 || + anArcPoints[2][0] * anArcPoints[2][0] + anArcPoints[2][1] * anArcPoints[2][1] < aTol2) + return true; + } + return false; +} diff --git a/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Solver.h b/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Solver.h index aa7729551..3ddadc8e6 100644 --- a/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Solver.h +++ b/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Solver.h @@ -74,8 +74,19 @@ public: */ virtual SketchSolver_SolveStatus solve(); - private: + /// \brief Prepare for solving. Store initial values of parameters for undo + virtual void prepare(); + + /// \brief Revert solution to initial values + virtual void undo(); + +private: + /// \brief Check whether degenerated arcs exist + bool hasDegeneratedArcs() const; + +private: Slvs_System myEquationsSystem; ///< set of equations for solving in SolveSpace + Slvs_Param* myParamsCopy; ///< copy of parameters }; #endif diff --git a/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Storage.cpp b/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Storage.cpp index 35b4cf0cc..169302581 100644 --- a/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Storage.cpp +++ b/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Storage.cpp @@ -161,6 +161,8 @@ bool SolveSpaceSolver_Storage::update(EntityWrapperPtr theEntity) aSlvsEnt.distance = anID; else if (aSlvsEnt.point[anInd] != anID) { aSlvsEnt.point[anInd] = anID; + if ((*aSIt)->baseAttribute()) + SketchSolver_Storage::addEntity((*aSIt)->baseAttribute(), *aSIt); isUpdated = true; } }