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()
12 : myEquationSystem(new GCS::System),
13 myDiagnoseBeforeSolve(false),
15 myConfCollected(false),
20 PlaneGCSSolver_Solver::~PlaneGCSSolver_Solver()
25 void PlaneGCSSolver_Solver::clear()
27 myEquationSystem->clear();
29 myConstraints.clear();
30 myConflictingIDs.clear();
34 void PlaneGCSSolver_Solver::addConstraint(GCSConstraintPtr theConstraint)
36 myEquationSystem->addConstraint(theConstraint.get());
37 myConstraints[theConstraint->getTag()].insert(theConstraint);
41 void PlaneGCSSolver_Solver::removeConstraint(ConstraintID theID)
43 myConstraints.erase(theID);
44 if (myConstraints.empty()) {
45 myEquationSystem->clear();
46 myDOF = (int)myParameters.size();
48 myEquationSystem->clearByTag(theID);
53 double* PlaneGCSSolver_Solver::createParameter()
55 double* aResult = new double(0);
56 myParameters.push_back(aResult);
57 if (myConstraints.empty() && myDOF >= 0)
58 ++myDOF; // calculate DoF by hand if and only if there is no constraints yet
60 myDiagnoseBeforeSolve = true;
64 void PlaneGCSSolver_Solver::removeParameters(const GCS::SET_pD& theParams)
66 for (int i = (int)myParameters.size() - 1; i >= 0; --i)
67 if (theParams.find(myParameters[i]) != theParams.end()) {
68 myParameters.erase(myParameters.begin() + i);
73 void PlaneGCSSolver_Solver::initialize()
75 Events_LongOp::start(this);
76 if (myDiagnoseBeforeSolve)
78 myEquationSystem->declareUnknowns(myParameters);
79 myEquationSystem->initSolution();
80 Events_LongOp::end(this);
85 PlaneGCSSolver_Solver::SolveStatus PlaneGCSSolver_Solver::solve()
87 // clear list of conflicting constraints
88 if (myConfCollected) {
89 myConflictingIDs.clear();
90 myConfCollected = false;
93 if (myParameters.empty())
94 return STATUS_INCONSISTENT;
96 GCS::SolveStatus aResult = GCS::Success;
97 Events_LongOp::start(this);
99 aResult = (GCS::SolveStatus)myEquationSystem->solve();
101 if (myDiagnoseBeforeSolve)
103 aResult = (GCS::SolveStatus)myEquationSystem->solve(myParameters);
105 Events_LongOp::end(this);
107 // collect information about conflicting constraints every time,
108 // sometimes solver reports about succeeded recalculation but has conflicting constraints
109 // (for example, apply horizontal constraint for a copied feature)
110 collectConflicting();
111 if (!myConflictingIDs.empty())
112 aResult = GCS::Failed;
115 if (aResult == GCS::Failed)
116 aStatus = STATUS_FAILED;
118 myEquationSystem->applySolution();
120 myDOF = myEquationSystem->dofsNumber();
124 myInitilized = false;
128 void PlaneGCSSolver_Solver::undo()
130 myEquationSystem->undoSolution();
133 bool PlaneGCSSolver_Solver::isConflicting(const ConstraintID& theConstraint) const
135 if (!myConfCollected)
136 const_cast<PlaneGCSSolver_Solver*>(this)->collectConflicting();
137 return myConflictingIDs.find((int)theConstraint) != myConflictingIDs.end();
140 void PlaneGCSSolver_Solver::collectConflicting()
142 GCS::VEC_I aConflict;
143 myEquationSystem->getConflicting(aConflict);
144 myConflictingIDs.insert(aConflict.begin(), aConflict.end());
146 myEquationSystem->getRedundant(aConflict);
147 myConflictingIDs.insert(aConflict.begin(), aConflict.end());
149 myConfCollected = true;
152 int PlaneGCSSolver_Solver::dof()
154 if (myDOF < 0 && !myConstraints.empty())
159 void PlaneGCSSolver_Solver::diagnose()
161 myEquationSystem->declareUnknowns(myParameters);
162 myDOF = myEquationSystem->diagnose();
163 myDiagnoseBeforeSolve = false;