- std::shared_ptr<GCS::System> aSystemWithoutTangent(new GCS::System);
-
- // Remove tangency which leads to redundant or conflicting constraints
- GCS::VEC_I aConflicting, aRedundant;
- myEquationSystem->getRedundant(aRedundant);
- size_t aNbRemove = myTangent.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<GCS::Constraint*> aRemovedTangent;
- ConstraintMap::const_iterator aConstrIt = myConstraints.begin();
- while (aConstrIt != myConstraints.end()) {
- GCS::Constraint* aConstraint = aConstrIt->first;
- int anID = aConstraint->getTag();
- ++aConstrIt;
- if (aTangentToRemove.find(anID) == aTangentToRemove.end())
- aSystemWithoutTangent->addConstraint(aConstraint);
- else
- aRemovedTangent.insert(aConstraint);
- }
-
- myTangent.clear();
- GCS::SolveStatus aResult = (GCS::SolveStatus)aSystemWithoutTangent->solve(myParameters);
- if (aResult == GCS::Success) {
- GCS::VEC_I aRedundant;
- aSystemWithoutTangent->getRedundant(aRedundant);
- if (aRedundant.empty())
- myEquationSystem = aSystemWithoutTangent;
- else
- aResult = GCS::Failed;
- }
-
- // additional check that removed constraints are still correct
- if (aResult == GCS::Success) {
- std::set<GCS::Constraint*>::const_iterator aRemIt = aRemovedTangent.begin();
- for (; aRemIt != aRemovedTangent.end(); ++aRemIt)
- if (!isTangentTruth(*aRemIt))
- break;
- if (aRemIt != aRemovedTangent.end())
- aResult = GCS::Failed;
- }
-
- // Add IDs of removed tangent to the list of conflicting constraints
- if (aResult == GCS::Failed) {
- std::set<GCS::Constraint*>::const_iterator aRemIt = aRemovedTangent.begin();
- for (; aRemIt != aRemovedTangent.end(); ++aRemIt)
- myConflictingIDs.insert((*aRemIt)->getTag());
- }
-
- return aResult;