1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
3 // File: PlaneGCSSolver_Solver.cpp
4 // Created: 14 Dec 2014
5 // Author: Artem ZHIDKOV
7 #include "PlaneGCSSolver_Solver.h"
8 #include <Events_LongOp.h>
11 PlaneGCSSolver_Solver::~PlaneGCSSolver_Solver()
16 void PlaneGCSSolver_Solver::clear()
18 myEquationSystem.clear();
19 myConstraints.clear();
23 void PlaneGCSSolver_Solver::addConstraint(GCSConstraintPtr theConstraint)
25 GCS::Constraint* aConstraint = theConstraint.get();
26 if (myConstraints.find(aConstraint) != myConstraints.end())
27 return; // constraint already exists, no need to add it again
29 myEquationSystem.addConstraint(aConstraint);
30 myConstraints.insert(aConstraint);
33 void PlaneGCSSolver_Solver::removeConstraint(GCSConstraintPtr theConstraint)
35 GCS::Constraint* aConstraint = theConstraint.get();
36 removeConstraint(aConstraint);
39 void PlaneGCSSolver_Solver::removeConstraint(GCS::Constraint* theConstraint)
41 if (myConstraints.find(theConstraint) == myConstraints.end())
42 return; // no constraint, no need to remove it
44 myEquationSystem.removeConstraint(theConstraint);
45 myConstraints.erase(theConstraint);
48 SketchSolver_SolveStatus PlaneGCSSolver_Solver::solve()
50 // clear list of conflicting constraints
51 if (myConfCollected) {
52 myConflictingIDs.clear();
53 myConfCollected = false;
56 if (myConstraints.empty())
57 return STATUS_EMPTYSET;
58 if (myParameters.empty())
59 return STATUS_INCONSISTENT;
61 Events_LongOp::start(this);
62 GCS::SolveStatus aResult = GCS::Success;
63 // if there is a constraint with all attributes constant, set fail status
64 GCS::SET_pD aParameters;
65 aParameters.insert(myParameters.begin(), myParameters.end());
66 std::set<GCS::Constraint*>::const_iterator aConstrIt = myConstraints.begin();
67 for (; aConstrIt != myConstraints.end(); ++aConstrIt) {
68 GCS::VEC_pD aParams = (*aConstrIt)->params();
69 GCS::VEC_pD::const_iterator aPIt = aParams.begin();
70 for (; aPIt != aParams.end(); ++aPIt)
71 if (aParameters.find(*aPIt) != aParameters.end())
73 if (aPIt == aParams.end() && (*aConstrIt)->getTag() > 0) {
74 myConflictingIDs.push_back((*aConstrIt)->getTag());
75 myConfCollected = true;
76 aResult = GCS::Failed;
80 if (aResult == GCS::Success)
81 aResult = (GCS::SolveStatus)myEquationSystem.solve(myParameters);
82 if (aResult == GCS::Success || aResult == GCS::Converged) {
83 // additionally check redundant constraints
84 GCS::VEC_I aRedundantID;
85 myEquationSystem.getRedundant(aRedundantID);
86 // Workaround: remove all constraints "Equal"
87 if (!aRedundantID.empty()) {
88 std::set<GCS::Constraint*>::const_iterator aCIt = myConstraints.begin();
89 for (; aCIt != myConstraints.end(); ++aCIt) {
90 if ((*aCIt)->getTypeId() != GCS::Equal)
92 GCS::VEC_I::iterator aRIt = aRedundantID.begin();
93 for (; aRIt != aRedundantID.end(); ++aRIt)
94 if ((*aCIt)->getTag() == *aRIt) {
95 aRedundantID.erase(aRIt);
100 // The system with tangent constraints may show redundant constraints if the entities are coupled smoothly.
101 // Sometimes tangent constraints are fall to both conflicting and redundant constraints.
102 // Need to check if there are redundant constraints without these tangencies.
103 if (!aRedundantID.empty())
104 aResult = myTangent.empty() ? GCS::Failed : (GCS::SolveStatus)solveWithoutTangent();
106 aResult = GCS::Success;
108 Events_LongOp::end(this);
110 SketchSolver_SolveStatus aStatus;
111 if (aResult == GCS::Success) {
112 myEquationSystem.applySolution();
115 aStatus = STATUS_FAILED;
120 SketchSolver_SolveStatus PlaneGCSSolver_Solver::solveWithoutTangent()
122 // Remove tangency which leads to redundant or conflicting constraints
123 GCS::VEC_I aConflicting, aRedundant;
124 myEquationSystem.getRedundant(aRedundant);
125 size_t aNbRemove = myTangent.size(); // number of tangent constraints which can be removed
126 myEquationSystem.getConflicting(aConflicting);
127 aRedundant.insert(aRedundant.end(), aConflicting.begin(), aConflicting.end());
129 GCS::SET_I aTangentToRemove;
130 GCS::VEC_I::iterator aCIt = aRedundant.begin();
131 for (; aCIt != aRedundant.end() && aNbRemove > 0; ++aCIt)
132 if (myTangent.find(*aCIt) != myTangent.end()) {
133 aTangentToRemove.insert(*aCIt);
137 std::set<GCS::Constraint*>::const_iterator aConstrIt = myConstraints.begin();
138 while (aConstrIt != myConstraints.end()) {
139 GCS::Constraint* aConstraint = *aConstrIt;
140 int anID = aConstraint->getTag();
142 if (aTangentToRemove.find(anID) != aTangentToRemove.end())
143 removeConstraint(aConstraint);
150 void PlaneGCSSolver_Solver::undo()
152 myEquationSystem.undoSolution();
155 bool PlaneGCSSolver_Solver::isConflicting(const ConstraintID& theConstraint) const
157 if (!myConfCollected)
158 const_cast<PlaneGCSSolver_Solver*>(this)->collectConflicting();
160 GCS::VEC_I::const_iterator anIt = myConflictingIDs.begin();
161 for (; anIt != myConflictingIDs.end(); ++anIt)
162 if (*anIt == (int)theConstraint)
167 void PlaneGCSSolver_Solver::collectConflicting()
169 GCS::VEC_I aConflict;
170 myEquationSystem.getConflicting(myConflictingIDs);
171 myConflictingIDs.insert(myConflictingIDs.end(), aConflict.begin(), aConflict.end());
173 myEquationSystem.getRedundant(aConflict);
174 myConflictingIDs.insert(myConflictingIDs.end(), aConflict.begin(), aConflict.end());
176 myConfCollected = true;
179 int PlaneGCSSolver_Solver::dof() const
181 return const_cast<PlaneGCSSolver_Solver*>(this)->myEquationSystem.dofsNumber();