]> SALOME platform Git repositories - modules/shaper.git/blob - src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Solver.cpp
Salome HOME
Update test cases according to new Fillet API.
[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     myConfCollected(false),
14     myDOF(0)
15 {
16 }
17
18 PlaneGCSSolver_Solver::~PlaneGCSSolver_Solver()
19 {
20   clear();
21 }
22
23 void PlaneGCSSolver_Solver::clear()
24 {
25   myEquationSystem->clear();
26   myParameters.clear();
27   myConstraints.clear();
28   myConflictingIDs.clear();
29   myDOF = 0;
30 }
31
32 void PlaneGCSSolver_Solver::addConstraint(GCSConstraintPtr theConstraint,
33                                           const SketchSolver_ConstraintType theType)
34 {
35   myEquationSystem->addConstraint(theConstraint.get());
36   myConstraints[theConstraint->getTag()].insert(theConstraint);
37   myDOF = -1;
38
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());
46 }
47
48 void PlaneGCSSolver_Solver::removeConstraint(ConstraintID theID)
49 {
50   myConstraints.erase(theID);
51   myConstraintIDsNotRedundant.erase(theID);
52   if (myConstraints.empty()) {
53     myEquationSystem->clear();
54     myDOF = (int)myParameters.size();
55   } else {
56     myEquationSystem->clearByTag(theID);
57     myDOF = -1;
58   }
59 }
60
61 double* PlaneGCSSolver_Solver::createParameter()
62 {
63   double* aResult = new double(0);
64   myParameters.push_back(aResult);
65   if (myDOF >= 0)
66     ++myDOF;
67   return aResult;
68 }
69
70 void PlaneGCSSolver_Solver::removeParameters(const GCS::SET_pD& theParams)
71 {
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);
75       --myDOF;
76     }
77 }
78
79 PlaneGCSSolver_Solver::SolveStatus PlaneGCSSolver_Solver::solve()
80 {
81   // clear list of conflicting constraints
82   if (myConfCollected) {
83     myConflictingIDs.clear();
84     myConfCollected = false;
85   }
86
87   if (myParameters.empty())
88     return STATUS_INCONSISTENT;
89
90   Events_LongOp::start(this);
91   // solve equations
92   GCS::SolveStatus aResult = (GCS::SolveStatus)myEquationSystem->solve(myParameters);
93   Events_LongOp::end(this);
94
95   GCS::VEC_I aRedundant;
96   myEquationSystem->getRedundant(aRedundant);
97   if (!aRedundant.empty()) {
98     collectConflicting();
99     if (!myConflictingIDs.empty())
100       aResult = GCS::Failed;
101   }
102
103   SolveStatus aStatus;
104   if (aResult == GCS::Failed)
105     aStatus = STATUS_FAILED;
106   else {
107     myEquationSystem->applySolution();
108     if (myDOF < 0)
109       myDOF = myEquationSystem->dofsNumber();
110     aStatus = STATUS_OK;
111   }
112
113   return aStatus;
114 }
115
116 void PlaneGCSSolver_Solver::undo()
117 {
118   myEquationSystem->undoSolution();
119 }
120
121 bool PlaneGCSSolver_Solver::isConflicting(const ConstraintID& theConstraint) const
122 {
123   if (!myConfCollected)
124     const_cast<PlaneGCSSolver_Solver*>(this)->collectConflicting();
125   return myConflictingIDs.find((int)theConstraint) != myConflictingIDs.end();
126 }
127
128 void PlaneGCSSolver_Solver::collectConflicting()
129 {
130   GCS::VEC_I aConflict;
131   myEquationSystem->getConflicting(aConflict);
132   myConflictingIDs.insert(aConflict.begin(), aConflict.end());
133
134   myEquationSystem->getRedundant(aConflict);
135   // Workaround: avoid conflicting tangent constraints
136   GCS::VEC_I aTemp = aConflict;
137   aConflict.clear();
138   for (GCS::VEC_I::iterator anIt = aTemp.begin(); anIt != aTemp.end(); ++anIt)
139     if (myConstraintIDsNotRedundant.find(*anIt) == myConstraintIDsNotRedundant.end())
140       aConflict.push_back(*anIt);
141   myConflictingIDs.insert(aConflict.begin(), aConflict.end());
142
143   myConfCollected = true;
144 }
145
146 int PlaneGCSSolver_Solver::dof()
147 {
148   if (myDOF < 0 && !myConstraints.empty())
149     solve();
150   return myDOF;
151 }