From fbb53b9e27cf3f739251f8a94b66748bedb0a47a Mon Sep 17 00:00:00 2001 From: azv Date: Tue, 30 Aug 2016 16:14:10 +0300 Subject: [PATCH] PlaneGCSSolver: correct processing of redundant constraints (relates to issue #1673) --- .../PlaneGCSSolver/PlaneGCSSolver_Solver.cpp | 37 ++++++++++--------- .../PlaneGCSSolver/PlaneGCSSolver_Solver.h | 18 +++++---- .../PlaneGCSSolver/PlaneGCSSolver_Storage.cpp | 4 +- 3 files changed, 32 insertions(+), 27 deletions(-) diff --git a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Solver.cpp b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Solver.cpp index 5dd83a86d..2399193cb 100644 --- a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Solver.cpp +++ b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Solver.cpp @@ -22,14 +22,15 @@ void PlaneGCSSolver_Solver::clear() myParameters.clear(); } -void PlaneGCSSolver_Solver::addConstraint(GCSConstraintPtr theConstraint) +void PlaneGCSSolver_Solver::addConstraint(GCSConstraintPtr theConstraint, + const SketchSolver_ConstraintType theType) { GCS::Constraint* aConstraint = theConstraint.get(); if (myConstraints.find(aConstraint) != myConstraints.end()) return; // constraint already exists, no need to add it again myEquationSystem.addConstraint(aConstraint); - myConstraints.insert(aConstraint); + myConstraints[aConstraint] = theType; } void PlaneGCSSolver_Solver::removeConstraint(GCSConstraintPtr theConstraint) @@ -65,15 +66,15 @@ SketchSolver_SolveStatus PlaneGCSSolver_Solver::solve() // if there is a constraint with all attributes constant, set fail status GCS::SET_pD aParameters; aParameters.insert(myParameters.begin(), myParameters.end()); - std::set::const_iterator aConstrIt = myConstraints.begin(); + ConstraintMap::const_iterator aConstrIt = myConstraints.begin(); for (; aConstrIt != myConstraints.end(); ++aConstrIt) { - GCS::VEC_pD aParams = (*aConstrIt)->params(); + GCS::VEC_pD aParams = aConstrIt->first->params(); GCS::VEC_pD::const_iterator aPIt = aParams.begin(); for (; aPIt != aParams.end(); ++aPIt) if (aParameters.find(*aPIt) != aParameters.end()) break; - if (aPIt == aParams.end() && (*aConstrIt)->getTag() > 0) { - myConflictingIDs.push_back((*aConstrIt)->getTag()); + if (aPIt == aParams.end() && aConstrIt->first->getTag() > 0) { + myConflictingIDs.push_back(aConstrIt->first->getTag()); myConfCollected = true; aResult = GCS::Failed; } @@ -106,15 +107,15 @@ SketchSolver_SolveStatus PlaneGCSSolver_Solver::solve() GCS::VEC_I aRedundantLocal; myEquationSystem.getRedundant(aRedundantLocal); aRedundantID.insert(aRedundantID.end(), aRedundantLocal.begin(), aRedundantLocal.end()); - // Workaround: remove all constraints "Equal" + // Workaround: remove all point-point coincidences from list of redundant if (!aRedundantID.empty()) { - std::set::const_iterator aCIt = myConstraints.begin(); + ConstraintMap::const_iterator aCIt = myConstraints.begin(); for (; aCIt != myConstraints.end(); ++aCIt) { - if ((*aCIt)->getTypeId() != GCS::Equal) + if (aCIt->second != CONSTRAINT_PT_PT_COINCIDENT) continue; GCS::VEC_I::iterator aRIt = aRedundantID.begin(); for (; aRIt != aRedundantID.end(); ++aRIt) - if ((*aCIt)->getTag() == *aRIt) { + if (aCIt->first->getTag() == *aRIt) { aRedundantID.erase(aRIt); break; } @@ -157,9 +158,9 @@ SketchSolver_SolveStatus PlaneGCSSolver_Solver::solveWithoutTangent() --aNbRemove; } - std::set::const_iterator aConstrIt = myConstraints.begin(); + ConstraintMap::const_iterator aConstrIt = myConstraints.begin(); while (aConstrIt != myConstraints.end()) { - GCS::Constraint* aConstraint = *aConstrIt; + GCS::Constraint* aConstraint = aConstrIt->first; int anID = aConstraint->getTag(); ++aConstrIt; if (aTangentToRemove.find(anID) != aTangentToRemove.end()) @@ -175,12 +176,12 @@ bool PlaneGCSSolver_Solver::isTangentTruth(int theTagID) const static const double aTol = 1e-7; static const double aTol2 = aTol *aTol; - std::set::const_iterator anIt = myConstraints.begin(); + ConstraintMap::const_iterator anIt = myConstraints.begin(); for (; anIt != myConstraints.end(); ++anIt) { - if ((*anIt)->getTag() != theTagID) + if (anIt->first->getTag() != theTagID) continue; - if ((*anIt)->getTypeId() == GCS::TangentCircumf) { - GCS::VEC_pD aParams = (*anIt)->params(); + if (anIt->first->getTypeId() == GCS::TangentCircumf) { + GCS::VEC_pD aParams = anIt->first->params(); double dx = *(aParams[2]) - *(aParams[0]); double dy = *(aParams[3]) - *(aParams[1]); double aDist2 = dx * dx + dy * dy; @@ -189,8 +190,8 @@ bool PlaneGCSSolver_Solver::isTangentTruth(int theTagID) const return fabs(aDist2 - aRadSum * aRadSum) <= aTol2 || fabs(aDist2 - aRadDiff * aRadDiff) <= aTol2; } - if ((*anIt)->getTypeId() == GCS::P2LDistance) { - GCS::VEC_pD aParams = (*anIt)->params(); + if (anIt->first->getTypeId() == GCS::P2LDistance) { + GCS::VEC_pD aParams = anIt->first->params(); double aDist2 = *(aParams[6]) * *(aParams[6]); // orthogonal line direction double aDirX = *(aParams[5]) - *(aParams[3]); diff --git a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Solver.h b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Solver.h index a9e89f07e..0ff96aff2 100644 --- a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Solver.h +++ b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Solver.h @@ -8,6 +8,7 @@ #define PlaneGCSSolver_Solver_H_ #include +#include #include #include @@ -25,7 +26,8 @@ public: void clear(); /// \brief Add constraint to the system of equations - void addConstraint(GCSConstraintPtr theConstraint); + void addConstraint(GCSConstraintPtr theConstraint, + const SketchSolver_ConstraintType theType); /// \brief Remove constraint from the system of equations void removeConstraint(GCSConstraintPtr theConstraint); @@ -72,14 +74,16 @@ private: bool isTangentTruth(int theTagID) const; private: - GCS::VEC_pD myParameters; ///< list of unknowns - std::set myConstraints; ///< list of constraints already processed by the system - GCS::System myEquationSystem; ///< set of equations for solving in FreeGCS + typedef std::map ConstraintMap; - GCS::VEC_I myConflictingIDs; ///< list of IDs of conflicting constraints - bool myConfCollected; ///< specifies the conflicting constraints are already collected + GCS::VEC_pD myParameters; ///< list of unknowns + ConstraintMap myConstraints; ///< list of constraints already processed by the system + GCS::System myEquationSystem; ///< set of equations for solving in FreeGCS - GCS::SET_I myTangent; ///< list of tangent IDs to check incorrect redundant constraints + GCS::VEC_I myConflictingIDs; ///< list of IDs of conflicting constraints + bool myConfCollected; ///< specifies the conflicting constraints are already collected + + GCS::SET_I myTangent; ///< list of tangent IDs to check incorrect redundant constraints }; #endif diff --git a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.cpp b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.cpp index b090c18d4..2b83759b8 100644 --- a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.cpp +++ b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.cpp @@ -628,7 +628,7 @@ void PlaneGCSSolver_Storage::initializeSolver(SolverPtr theSolver) std::list::const_iterator anIt = aGCS->constraints().begin(); for (; anIt != aGCS->constraints().end(); ++anIt) if (!isRedundant(*anIt, aGCS, aCoincidentPoints)) - aSolver->addConstraint(*anIt); + aSolver->addConstraint(*anIt, aGCS->type()); } // store IDs of tangent constraints to avoid incorrect report of redundant constraints if (aCIt->first && aCIt->first->getKind() == SketchPlugin_ConstraintTangent::ID()) @@ -641,7 +641,7 @@ void PlaneGCSSolver_Storage::initializeSolver(SolverPtr theSolver) for (; anArcIt != myArcConstraintMap.end(); ++anArcIt) { std::vector::const_iterator anIt = anArcIt->second.begin(); for (; anIt != anArcIt->second.end(); ++anIt) - aSolver->addConstraint(*anIt); + aSolver->addConstraint(*anIt, CONSTRAINT_UNKNOWN); } // removed waste constraints std::list::const_iterator aRemIt = myRemovedConstraints.begin(); -- 2.39.2