From: azv Date: Wed, 8 Jun 2016 07:28:29 +0000 (+0300) Subject: PlaneGCS: Some incorrect conflicts fixed: X-Git-Tag: V_2.4.0~129 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=6ea1bd3c759d8726063a1af11075374f1205ade9;p=modules%2Fshaper.git PlaneGCS: Some incorrect conflicts fixed: * Resolve system one again if there are redundant tangent constraints. * Do not add redundant point-point coincidence constraint if multiple points are coincident. --- diff --git a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Solver.cpp b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Solver.cpp index 4480b1026..97edb3194 100644 --- a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Solver.cpp +++ b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Solver.cpp @@ -33,22 +33,16 @@ void PlaneGCSSolver_Solver::addConstraint(GCSConstraintPtr theConstraint) void PlaneGCSSolver_Solver::removeConstraint(GCSConstraintPtr theConstraint) { GCS::Constraint* aConstraint = theConstraint.get(); - if (myConstraints.find(aConstraint) == myConstraints.end()) - return; // no constraint, no need to remove it - - myEquationSystem.removeConstraint(aConstraint); - myConstraints.erase(aConstraint); + removeConstraint(aConstraint); } -static void removeTangent(GCS::VEC_I& theRedundant, const GCS::SET_I& theTangent) +void PlaneGCSSolver_Solver::removeConstraint(GCS::Constraint* theConstraint) { - int i = 0; - while (i < theRedundant.size()) { - if (theTangent.find(theRedundant[i]) == theTangent.end()) - ++i; - else - theRedundant.erase(theRedundant.begin() + i); - } + if (myConstraints.find(theConstraint) == myConstraints.end()) + return; // no constraint, no need to remove it + + myEquationSystem.removeConstraint(theConstraint); + myConstraints.erase(theConstraint); } SketchSolver_SolveStatus PlaneGCSSolver_Solver::solve() @@ -87,10 +81,11 @@ SketchSolver_SolveStatus PlaneGCSSolver_Solver::solve() // additionally check redundant constraints GCS::VEC_I aRedundantID; myEquationSystem.getRedundant(aRedundantID); - // remove redundant constraints relative to tangency - removeTangent(aRedundantID, myTangent); + // The system with tangent constraints may show redundant constraints if the entities are coupled smoothly. + // Sometimes tangent constraints are fall to both conflicting and redundant constraints. + // Need to check if there are redundant constraints without these tangencies. if (!aRedundantID.empty()) - aResult = GCS::Failed; + aResult = myTangent.empty() ? GCS::Failed : (GCS::SolveStatus)solveWithoutTangent(); } Events_LongOp::end(this); @@ -104,6 +99,36 @@ SketchSolver_SolveStatus PlaneGCSSolver_Solver::solve() return aStatus; } +SketchSolver_SolveStatus PlaneGCSSolver_Solver::solveWithoutTangent() +{ + // Remove tangency which leads to redundant or conflicting constraints + GCS::VEC_I aConflicting, aRedundant; + myEquationSystem.getRedundant(aRedundant); + size_t aNbRemove = aRedundant.size(); // number of tangent constraints which can be removed + myEquationSystem.getConflicting(aConflicting); + aRedundant.insert(aRedundant.end(), aConflicting.begin(), aConflicting.end()); + + GCS::SET_I aTangentToRemove; + GCS::VEC_I::iterator aCIt = aRedundant.begin(); + for (; aCIt != aRedundant.end() && aNbRemove > 0; ++aCIt) + if (myTangent.find(*aCIt) != myTangent.end()) { + aTangentToRemove.insert(*aCIt); + --aNbRemove; + } + + std::set::const_iterator aConstrIt = myConstraints.begin(); + while (aConstrIt != myConstraints.end()) { + GCS::Constraint* aConstraint = *aConstrIt; + int anID = aConstraint->getTag(); + ++aConstrIt; + if (aTangentToRemove.find(anID) != aTangentToRemove.end()) + removeConstraint(aConstraint); + } + + myTangent.clear(); + return solve(); +} + void PlaneGCSSolver_Solver::undo() { myEquationSystem.undoSolution(); diff --git a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Solver.h b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Solver.h index a3c266346..b1dcd50f9 100644 --- a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Solver.h +++ b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Solver.h @@ -62,6 +62,12 @@ public: private: void collectConflicting(); + /// \brief Remove constraint from the system of equations + void removeConstraint(GCS::Constraint* theConstraint); + + /// \brief Remove redundant tangent constraints and try to solve the system again + SketchSolver_SolveStatus solveWithoutTangent(); + private: GCS::VEC_pD myParameters; ///< list of unknowns std::set myConstraints; ///< list of constraints already processed by the system diff --git a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.cpp b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.cpp index 35973564d..a21c6848b 100644 --- a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.cpp +++ b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.cpp @@ -539,6 +539,16 @@ bool PlaneGCSSolver_Storage::isRedundant( return aLine->distance(aPoint) < tolerance; } } + else if (theParentConstraint->type() == CONSTRAINT_PT_PT_COINCIDENT) { + // Mark constraint redundant if the coincident points both are slaves in the list of stored coincidences + const std::list& aPoints = theParentConstraint->entities(); + CoincidentPointsMap::const_iterator aCoincIt = myCoincidentPoints.begin(); + for (; aCoincIt != myCoincidentPoints.end(); ++aCoincIt) { + if (aCoincIt->second.find(aPoints.front()) != aCoincIt->second.end() && + aCoincIt->second.find(aPoints.back()) != aCoincIt->second.end()) + return true; + } + } return false; } @@ -570,12 +580,8 @@ void PlaneGCSSolver_Storage::initializeSolver(SolverPtr theSolver) } // store IDs of tangent constraints to avoid incorrect report of redundant constraints if (aCIt->first && aCIt->first->getKind() == SketchPlugin_ConstraintTangent::ID()) - for (aCWIt = aCIt->second.begin(); aCWIt != aCIt->second.end(); ++ aCWIt) { - std::shared_ptr aGCS = - std::dynamic_pointer_cast(*aCWIt); - if (aGCS->constraints().front()->getTypeId() == GCS::P2LDistance) - aTangentIDs.insert((int)(*aCWIt)->id()); - } + for (aCWIt = aCIt->second.begin(); aCWIt != aCIt->second.end(); ++ aCWIt) + aTangentIDs.insert((int)(*aCWIt)->id()); } // additional constraints for arcs std::map >::const_iterator