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 myConfCollected(false),
18 PlaneGCSSolver_Solver::~PlaneGCSSolver_Solver()
23 void PlaneGCSSolver_Solver::clear()
25 myEquationSystem->clear();
27 myConstraints.clear();
28 myConflictingIDs.clear();
32 void PlaneGCSSolver_Solver::addConstraint(GCSConstraintPtr theConstraint,
33 const SketchSolver_ConstraintType theType)
35 myEquationSystem->addConstraint(theConstraint.get());
36 myConstraints[theConstraint->getTag()].insert(theConstraint);
39 // Workaround: avoid tangent constraint in the list of redundant
40 if (theType == CONSTRAINT_TANGENT_CIRCLE_LINE ||
41 theType == CONSTRAINT_TANGENT_CIRCLE_CIRCLE ||
42 theType == CONSTRAINT_PT_PT_COINCIDENT ||
43 theType == CONSTRAINT_PT_ON_CIRCLE ||
44 theType == CONSTRAINT_PT_ON_LINE)
45 myConstraintIDsNotRedundant.insert(theConstraint->getTag());
48 void PlaneGCSSolver_Solver::removeConstraint(ConstraintID theID)
50 myConstraints.erase(theID);
51 myConstraintIDsNotRedundant.erase(theID);
52 if (myConstraints.empty()) {
53 myEquationSystem->clear();
54 myDOF = (int)myParameters.size();
56 myEquationSystem->clearByTag(theID);
61 double* PlaneGCSSolver_Solver::createParameter()
63 double* aResult = new double(0);
64 myParameters.push_back(aResult);
70 void PlaneGCSSolver_Solver::removeParameters(const GCS::SET_pD& theParams)
72 for (int i = (int)myParameters.size() - 1; i >= 0; --i)
73 if (theParams.find(myParameters[i]) != theParams.end()) {
74 myParameters.erase(myParameters.begin() + i);
79 PlaneGCSSolver_Solver::SolveStatus PlaneGCSSolver_Solver::solve()
81 // clear list of conflicting constraints
82 if (myConfCollected) {
83 myConflictingIDs.clear();
84 myConfCollected = false;
87 if (myParameters.empty())
88 return STATUS_INCONSISTENT;
90 Events_LongOp::start(this);
92 GCS::SolveStatus aResult = (GCS::SolveStatus)myEquationSystem->solve(myParameters);
93 Events_LongOp::end(this);
95 GCS::VEC_I aRedundant;
96 myEquationSystem->getRedundant(aRedundant);
97 if (!aRedundant.empty()) {
99 if (!myConflictingIDs.empty())
100 aResult = GCS::Failed;
104 if (aResult == GCS::Success) {
105 myEquationSystem->applySolution();
107 myDOF = myEquationSystem->dofsNumber();
110 aStatus = STATUS_FAILED;
115 void PlaneGCSSolver_Solver::undo()
117 myEquationSystem->undoSolution();
120 bool PlaneGCSSolver_Solver::isConflicting(const ConstraintID& theConstraint) const
122 if (!myConfCollected)
123 const_cast<PlaneGCSSolver_Solver*>(this)->collectConflicting();
124 return myConflictingIDs.find((int)theConstraint) != myConflictingIDs.end();
127 void PlaneGCSSolver_Solver::collectConflicting()
129 GCS::VEC_I aConflict;
130 myEquationSystem->getConflicting(aConflict);
131 myConflictingIDs.insert(aConflict.begin(), aConflict.end());
133 myEquationSystem->getRedundant(aConflict);
134 // Workaround: avoid conflicting tangent constraints
135 GCS::VEC_I aTemp = aConflict;
137 for (GCS::VEC_I::iterator anIt = aTemp.begin(); anIt != aTemp.end(); ++anIt)
138 if (myConstraintIDsNotRedundant.find(*anIt) == myConstraintIDsNotRedundant.end())
139 aConflict.push_back(*anIt);
140 myConflictingIDs.insert(aConflict.begin(), aConflict.end());
142 myConfCollected = true;
145 int PlaneGCSSolver_Solver::dof()
147 if (myDOF < 0 && !myConstraints.empty())