]> SALOME platform Git repositories - modules/shaper.git/blob - src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Solver.cpp
Salome HOME
Correct DoF calculation
[modules/shaper.git] / src / SketchSolver / PlaneGCSSolver / PlaneGCSSolver_Solver.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
2
3 // File:    PlaneGCSSolver_Solver.cpp
4 // Created: 14 Dec 2014
5 // Author:  Artem ZHIDKOV
6
7 #include <PlaneGCSSolver_Solver.h>
8 #include <Events_LongOp.h>
9
10
11 PlaneGCSSolver_Solver::PlaneGCSSolver_Solver()
12   : myEquationSystem(new GCS::System),
13     myDiagnoseBeforeSolve(false),
14     myConfCollected(false),
15     myDOF(0)
16 {
17 }
18
19 PlaneGCSSolver_Solver::~PlaneGCSSolver_Solver()
20 {
21   clear();
22 }
23
24 void PlaneGCSSolver_Solver::clear()
25 {
26   myEquationSystem->clear();
27   myParameters.clear();
28   myConstraints.clear();
29   myConflictingIDs.clear();
30   myDOF = 0;
31 }
32
33 void PlaneGCSSolver_Solver::addConstraint(GCSConstraintPtr theConstraint)
34 {
35   myEquationSystem->addConstraint(theConstraint.get());
36   myConstraints[theConstraint->getTag()].insert(theConstraint);
37   myDOF = -1;
38 }
39
40 void PlaneGCSSolver_Solver::removeConstraint(ConstraintID theID)
41 {
42   myConstraints.erase(theID);
43   if (myConstraints.empty()) {
44     myEquationSystem->clear();
45     myDOF = (int)myParameters.size();
46   } else {
47     myEquationSystem->clearByTag(theID);
48     myDOF = -1;
49   }
50 }
51
52 double* PlaneGCSSolver_Solver::createParameter()
53 {
54   double* aResult = new double(0);
55   myParameters.push_back(aResult);
56   if (myConstraints.empty() && myDOF >= 0)
57     ++myDOF; // calculate DoF by hand if and only if there is no constraints yet
58   else
59     myDiagnoseBeforeSolve = true;
60   return aResult;
61 }
62
63 void PlaneGCSSolver_Solver::removeParameters(const GCS::SET_pD& theParams)
64 {
65   for (int i = (int)myParameters.size() - 1; i >= 0; --i)
66     if (theParams.find(myParameters[i]) != theParams.end()) {
67       myParameters.erase(myParameters.begin() + i);
68       --myDOF;
69     }
70 }
71
72 PlaneGCSSolver_Solver::SolveStatus PlaneGCSSolver_Solver::solve()
73 {
74   // clear list of conflicting constraints
75   if (myConfCollected) {
76     myConflictingIDs.clear();
77     myConfCollected = false;
78   }
79
80   if (myParameters.empty())
81     return STATUS_INCONSISTENT;
82
83   Events_LongOp::start(this);
84   if (myDiagnoseBeforeSolve)
85     diagnose();
86   // solve equations
87   GCS::SolveStatus aResult = (GCS::SolveStatus)myEquationSystem->solve(myParameters);
88   Events_LongOp::end(this);
89
90   GCS::VEC_I aRedundant;
91   myEquationSystem->getRedundant(aRedundant);
92   if (!aRedundant.empty()) {
93     collectConflicting();
94     if (!myConflictingIDs.empty())
95       aResult = GCS::Failed;
96   }
97
98   SolveStatus aStatus;
99   if (aResult == GCS::Failed)
100     aStatus = STATUS_FAILED;
101   else {
102     myEquationSystem->applySolution();
103     if (myDOF < 0)
104       myDOF = myEquationSystem->dofsNumber();
105     aStatus = STATUS_OK;
106   }
107
108   return aStatus;
109 }
110
111 void PlaneGCSSolver_Solver::undo()
112 {
113   myEquationSystem->undoSolution();
114 }
115
116 bool PlaneGCSSolver_Solver::isConflicting(const ConstraintID& theConstraint) const
117 {
118   if (!myConfCollected)
119     const_cast<PlaneGCSSolver_Solver*>(this)->collectConflicting();
120   return myConflictingIDs.find((int)theConstraint) != myConflictingIDs.end();
121 }
122
123 void PlaneGCSSolver_Solver::collectConflicting()
124 {
125   GCS::VEC_I aConflict;
126   myEquationSystem->getConflicting(aConflict);
127   myConflictingIDs.insert(aConflict.begin(), aConflict.end());
128
129   myEquationSystem->getRedundant(aConflict);
130   myConflictingIDs.insert(aConflict.begin(), aConflict.end());
131
132   myConfCollected = true;
133 }
134
135 int PlaneGCSSolver_Solver::dof()
136 {
137   if (myDOF < 0 && !myConstraints.empty())
138     diagnose();
139   return myDOF;
140 }
141
142 void PlaneGCSSolver_Solver::diagnose()
143 {
144   myEquationSystem->declareUnknowns(myParameters);
145   myDOF = myEquationSystem->diagnose();
146   myDiagnoseBeforeSolve = false;
147 }