1 // Copyright (C) 2014-2017 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or
18 // email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
21 #include <PlaneGCSSolver_Solver.h>
22 #include <Events_LongOp.h>
25 PlaneGCSSolver_Solver::PlaneGCSSolver_Solver()
26 : myEquationSystem(new GCS::System),
27 myDiagnoseBeforeSolve(false),
29 myConfCollected(false),
34 PlaneGCSSolver_Solver::~PlaneGCSSolver_Solver()
39 void PlaneGCSSolver_Solver::clear()
41 myEquationSystem->clear();
43 myConstraints.clear();
44 myConflictingIDs.clear();
48 void PlaneGCSSolver_Solver::addConstraint(GCSConstraintPtr theConstraint)
50 myEquationSystem->addConstraint(theConstraint.get());
51 myConstraints[theConstraint->getTag()].insert(theConstraint);
52 if (theConstraint->getTag() >= 0)
57 void PlaneGCSSolver_Solver::removeConstraint(ConstraintID theID)
59 myConstraints.erase(theID);
60 if (myConstraints.empty()) {
61 myEquationSystem->clear();
62 myDOF = (int)myParameters.size();
64 myEquationSystem->clearByTag(theID);
71 double* PlaneGCSSolver_Solver::createParameter()
73 double* aResult = new double(0);
74 myParameters.push_back(aResult);
75 if (myConstraints.empty() && myDOF >= 0)
76 ++myDOF; // calculate DoF by hand if and only if there is no constraints yet
78 myDiagnoseBeforeSolve = true;
82 void PlaneGCSSolver_Solver::addParameters(const GCS::SET_pD& theParams)
84 GCS::SET_pD aParams(theParams);
85 // leave new parameters only
86 GCS::VEC_pD::iterator anIt = myParameters.begin();
87 for (; anIt != myParameters.end(); ++anIt)
88 if (aParams.find(*anIt) != aParams.end())
91 myParameters.insert(myParameters.end(), aParams.begin(), aParams.end());
92 if (myConstraints.empty() && myDOF >=0)
93 myDOF += (int)aParams.size(); // calculate DoF by hand only if there is no constraints yet
95 myDiagnoseBeforeSolve = true;
98 void PlaneGCSSolver_Solver::removeParameters(const GCS::SET_pD& theParams)
100 for (int i = (int)myParameters.size() - 1; i >= 0; --i)
101 if (theParams.find(myParameters[i]) != theParams.end()) {
102 myParameters.erase(myParameters.begin() + i);
105 if (!myConstraints.empty())
106 myDiagnoseBeforeSolve = true;
109 void PlaneGCSSolver_Solver::initialize()
111 Events_LongOp::start(this);
112 if (myDiagnoseBeforeSolve)
114 myEquationSystem->declareUnknowns(myParameters);
115 myEquationSystem->initSolution();
116 Events_LongOp::end(this);
121 PlaneGCSSolver_Solver::SolveStatus PlaneGCSSolver_Solver::solve()
123 // clear list of conflicting constraints
124 if (myConfCollected) {
125 myConflictingIDs.clear();
126 myConfCollected = false;
129 if (myParameters.empty())
130 return STATUS_INCONSISTENT;
132 GCS::SolveStatus aResult = GCS::Success;
133 Events_LongOp::start(this);
135 aResult = (GCS::SolveStatus)myEquationSystem->solve();
137 if (myDiagnoseBeforeSolve)
139 aResult = (GCS::SolveStatus)myEquationSystem->solve(myParameters);
141 Events_LongOp::end(this);
143 // collect information about conflicting constraints every time,
144 // sometimes solver reports about succeeded recalculation but has conflicting constraints
145 // (for example, apply horizontal constraint for a copied feature)
146 collectConflicting();
147 if (!myConflictingIDs.empty())
148 aResult = GCS::Failed;
151 if (aResult == GCS::Failed)
152 aStatus = STATUS_FAILED;
154 myEquationSystem->applySolution();
156 myDOF = myEquationSystem->dofsNumber();
160 myInitilized = false;
164 void PlaneGCSSolver_Solver::undo()
166 myEquationSystem->undoSolution();
169 bool PlaneGCSSolver_Solver::isConflicting(const ConstraintID& theConstraint) const
171 if (!myConfCollected)
172 const_cast<PlaneGCSSolver_Solver*>(this)->collectConflicting();
173 return myConflictingIDs.find((int)theConstraint) != myConflictingIDs.end();
176 void PlaneGCSSolver_Solver::collectConflicting()
178 GCS::VEC_I aConflict;
179 myEquationSystem->getConflicting(aConflict);
180 myConflictingIDs.insert(aConflict.begin(), aConflict.end());
182 myEquationSystem->getRedundant(aConflict);
183 myConflictingIDs.insert(aConflict.begin(), aConflict.end());
185 myConfCollected = true;
188 int PlaneGCSSolver_Solver::dof()
190 if (myDOF < 0 && !myConstraints.empty())
195 void PlaneGCSSolver_Solver::diagnose()
197 myEquationSystem->declareUnknowns(myParameters);
198 myDOF = myEquationSystem->diagnose();
199 myDiagnoseBeforeSolve = false;