]> SALOME platform Git repositories - modules/shaper.git/blob - src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Solver.cpp
Salome HOME
PlaneGCSSolver: workaround for wrong redundant constraints available on arc-line...
[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 {
13   clear();
14 }
15
16 void PlaneGCSSolver_Solver::clear()
17 {
18   myEquationSystem.clear();
19   myConstraints.clear();
20   myParameters.clear();
21 }
22
23 void PlaneGCSSolver_Solver::addConstraint(GCSConstraintPtr theConstraint)
24 {
25   GCS::Constraint* aConstraint = theConstraint.get();
26   if (myConstraints.find(aConstraint) != myConstraints.end())
27     return; // constraint already exists, no need to add it again
28
29   myEquationSystem.addConstraint(aConstraint);
30   myConstraints.insert(aConstraint);
31 }
32
33 void PlaneGCSSolver_Solver::removeConstraint(GCSConstraintPtr theConstraint)
34 {
35   GCS::Constraint* aConstraint = theConstraint.get();
36   if (myConstraints.find(aConstraint) == myConstraints.end())
37     return; // no constraint, no need to remove it
38
39   myEquationSystem.removeConstraint(aConstraint);
40   myConstraints.erase(aConstraint);
41 }
42
43 static void removeTangent(GCS::VEC_I& theRedundant, const GCS::SET_I& theTangent)
44 {
45   int i = 0;
46   while (i < theRedundant.size()) {
47     if (theTangent.find(theRedundant[i]) == theTangent.end())
48       ++i;
49     else
50       theRedundant.erase(theRedundant.begin() + i);
51   }
52 }
53
54 SketchSolver_SolveStatus PlaneGCSSolver_Solver::solve()
55 {
56   // clear list of conflicting constraints
57   if (myConfCollected) {
58     myConflictingIDs.clear();
59     myConfCollected = false;
60   }
61
62   if (myConstraints.empty())
63     return STATUS_EMPTYSET;
64   if (myParameters.empty())
65     return STATUS_INCONSISTENT;
66
67   Events_LongOp::start(this);
68   GCS::SolveStatus aResult = GCS::Success;
69   // if there is a constraint with all attributes constant, set fail status
70   GCS::SET_pD aParameters;
71   aParameters.insert(myParameters.begin(), myParameters.end());
72   std::set<GCS::Constraint*>::const_iterator aConstrIt = myConstraints.begin();
73   for (; aConstrIt != myConstraints.end(); ++aConstrIt) {
74     GCS::VEC_pD aParams = (*aConstrIt)->params();
75     GCS::VEC_pD::const_iterator aPIt = aParams.begin();
76     for (; aPIt != aParams.end(); ++aPIt)
77       if (aParameters.find(*aPIt) != aParameters.end())
78         break;
79     if (aPIt == aParams.end()) {
80       aResult = GCS::Failed;
81     }
82   }
83   // solve equations
84   if (aResult == GCS::Success)
85     aResult = (GCS::SolveStatus)myEquationSystem.solve(myParameters);
86   if (aResult == GCS::Success) {
87     // additionally check redundant constraints
88     GCS::VEC_I aRedundantID;
89     myEquationSystem.getRedundant(aRedundantID);
90     // remove redundant constraints relative to tangency
91     removeTangent(aRedundantID, myTangent);
92     if (!aRedundantID.empty())
93       aResult = GCS::Failed;
94   }
95   Events_LongOp::end(this);
96
97   SketchSolver_SolveStatus aStatus;
98   if (aResult == GCS::Success) {
99     myEquationSystem.applySolution();
100     aStatus = STATUS_OK;
101   } else {
102     undo();
103     aStatus = STATUS_FAILED;
104   }
105
106   return aStatus;
107 }
108
109 void PlaneGCSSolver_Solver::undo()
110 {
111   myEquationSystem.undoSolution();
112 }
113
114 bool PlaneGCSSolver_Solver::isConflicting(const ConstraintID& theConstraint) const
115 {
116   if (!myConfCollected)
117     const_cast<PlaneGCSSolver_Solver*>(this)->collectConflicting();
118
119   GCS::VEC_I::const_iterator anIt = myConflictingIDs.begin();
120   for (; anIt != myConflictingIDs.end(); ++anIt)
121     if (*anIt == (int)theConstraint)
122       return true;
123   return false;
124 }
125
126 void PlaneGCSSolver_Solver::collectConflicting()
127 {
128   myEquationSystem.getConflicting(myConflictingIDs);
129
130   GCS::VEC_I aRedundantID;
131   myEquationSystem.getRedundant(aRedundantID);
132   myConflictingIDs.insert(myConflictingIDs.end(), aRedundantID.begin(), aRedundantID.end());
133
134   myConfCollected = true;
135 }
136
137 int PlaneGCSSolver_Solver::dof() const
138 {
139   return const_cast<PlaneGCSSolver_Solver*>(this)->myEquationSystem.dofsNumber();
140 }