1 // Copyright (C) 2014-2017 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or
18 // email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
21 #include "SolveSpaceSolver_Solver.h"
22 #include <Events_LongOp.h>
24 SolveSpaceSolver_Solver::SolveSpaceSolver_Solver()
26 // Nullify all elements of the set of equations
27 myEquationsSystem.param = 0;
28 myEquationsSystem.params = 0;
29 myEquationsSystem.entity = 0;
30 myEquationsSystem.entities = 0;
31 myEquationsSystem.constraint = 0;
32 myEquationsSystem.constraints = 0;
33 myEquationsSystem.failed = 0;
34 myEquationsSystem.faileds = 0;
36 myEquationsSystem.dragged[0] = 0;
37 myEquationsSystem.dragged[1] = 0;
38 myEquationsSystem.dragged[2] = 0;
39 myEquationsSystem.dragged[3] = 0;
41 // If the set of constraints is inconsistent,
42 // the failed field will contain wrong constraints
43 myEquationsSystem.calculateFaileds = 0;
48 SolveSpaceSolver_Solver::~SolveSpaceSolver_Solver()
50 if (myEquationsSystem.constraint)
51 delete[] myEquationsSystem.constraint;
52 myEquationsSystem.constraint = 0;
53 if (myEquationsSystem.failed)
54 delete[] myEquationsSystem.failed;
55 myEquationsSystem.failed = 0;
57 delete [] myParamsCopy;
61 void SolveSpaceSolver_Solver::setParameters(Slvs_Param* theParameters, int theSize)
63 myEquationsSystem.param = theParameters;
64 myEquationsSystem.params = theSize;
68 void SolveSpaceSolver_Solver::setDraggedParameters(const Slvs_hParam* theDragged)
70 for (unsigned int i = 0; i < 4; i++)
71 myEquationsSystem.dragged[i] = theDragged[i];
74 void SolveSpaceSolver_Solver::setEntities(Slvs_Entity* theEntities, int theSize)
76 myEquationsSystem.entity = theEntities;
77 myEquationsSystem.entities = theSize;
80 void SolveSpaceSolver_Solver::setConstraints(Slvs_Constraint* theConstraints, int theSize)
82 if (!myEquationsSystem.constraint) {
83 myEquationsSystem.constraint = new Slvs_Constraint[theSize];
84 myEquationsSystem.constraints = theSize;
85 myEquationsSystem.failed = new Slvs_hConstraint[theSize];
87 else if (myEquationsSystem.constraints != theSize) {
88 if (theSize > myEquationsSystem.constraints) {
89 delete[] myEquationsSystem.constraint;
90 myEquationsSystem.constraint = new Slvs_Constraint[theSize];
91 if (myEquationsSystem.failed)
92 delete[] myEquationsSystem.failed;
93 myEquationsSystem.failed = new Slvs_hConstraint[theSize];
95 myEquationsSystem.constraints = theSize;
97 memcpy(myEquationsSystem.constraint, theConstraints, theSize * sizeof(Slvs_Constraint));
98 memset(myEquationsSystem.failed, SLVS_C_UNKNOWN, theSize * sizeof(Slvs_hConstraint));
102 SketchSolver_SolveStatus SolveSpaceSolver_Solver::solve()
104 //if (myEquationsSystem.constraints <= 0)
105 // return STATUS_EMPTYSET;
107 myEquationsSystem.calculateFaileds = 0;
109 myEquationsSystem.calculateFaileds = 1;
110 myEquationsSystem.faileds = myEquationsSystem.constraints;
113 Events_LongOp::start(this);
114 Slvs_Solve(&myEquationsSystem, (Slvs_hGroup)myGroup);
115 Events_LongOp::end(this);
117 SketchSolver_SolveStatus aStatus;
118 switch (myEquationsSystem.result) {
119 case SLVS_RESULT_OKAY:
122 case SLVS_RESULT_INCONSISTENT:
123 case SLVS_RESULT_DIDNT_CONVERGE:
124 case SLVS_RESULT_TOO_MANY_UNKNOWNS:
125 aStatus = STATUS_INCONSISTENT;
128 aStatus = STATUS_FAILED;
131 if (aStatus == STATUS_OK) {
132 // additional verification of arcs to be non-degenerated
133 if (hasDegeneratedArcs()) {
135 aStatus = STATUS_INCONSISTENT;
142 void SolveSpaceSolver_Solver::prepare()
144 // make a copy of parameters to be able to make undo
146 delete [] myParamsCopy;
147 myParamsCopy = new Slvs_Param[myEquationsSystem.params];
148 memcpy(myParamsCopy, myEquationsSystem.param, myEquationsSystem.params * sizeof(Slvs_Param));
151 void SolveSpaceSolver_Solver::undo()
154 memcpy(myEquationsSystem.param, myParamsCopy, myEquationsSystem.params * sizeof(Slvs_Param));
155 delete [] myParamsCopy;
161 bool SolveSpaceSolver_Solver::hasDegeneratedArcs() const
163 const double aTol2 = tolerance * tolerance;
164 double anArcPoints[3][2];
166 for (int anEnt = 0; anEnt < myEquationsSystem.entities; ++anEnt) {
167 const Slvs_Entity& anEntity = myEquationsSystem.entity[anEnt];
168 if (anEntity.type != SLVS_E_ARC_OF_CIRCLE)
171 for (int aPnt = 0; aPnt < 3; ++aPnt) {
172 // search point of arc
173 const int aShift = anEntity.point[aPnt] - anEntity.h;
174 int aPntInd = anEnt + aShift;
178 else if (aPntInd >= myEquationsSystem.entities)
179 aPntInd = myEquationsSystem.entities - 1;
180 if (myEquationsSystem.entity[aPntInd].h > anEntity.point[aPnt])
182 for (; aPntInd >=0 && aPntInd < myEquationsSystem.entities; aPntInd += aStep)
183 if (myEquationsSystem.entity[aPntInd].h == anEntity.point[aPnt])
186 // search coordinates of the point
187 int aParamInd = myEquationsSystem.entity[aPntInd].param[0];
188 if (aParamInd >= myEquationsSystem.params) {
189 aParamInd = myEquationsSystem.params - 1;
192 else if ((int)myEquationsSystem.param[aParamInd].h > aParamInd)
196 for (; aParamInd >=0 && aParamInd < myEquationsSystem.params; aParamInd += aStep)
197 if (myEquationsSystem.param[aParamInd].h == myEquationsSystem.entity[aPntInd].param[0])
199 anArcPoints[aPnt][0] = myEquationsSystem.param[aParamInd].val;
200 anArcPoints[aPnt][1] = myEquationsSystem.param[aParamInd+1].val;
203 // check radius of arc
204 anArcPoints[1][0] -= anArcPoints[0][0];
205 anArcPoints[1][1] -= anArcPoints[0][1];
206 anArcPoints[2][0] -= anArcPoints[0][0];
207 anArcPoints[2][1] -= anArcPoints[0][1];
208 if (anArcPoints[1][0] * anArcPoints[1][0] + anArcPoints[1][1] * anArcPoints[1][1] < aTol2 ||
209 anArcPoints[2][0] * anArcPoints[2][0] + anArcPoints[2][1] * anArcPoints[2][1] < aTol2)
215 bool SolveSpaceSolver_Solver::isConflicting(const ConstraintID& theConstraint) const
217 for (int i = 0; i < myEquationsSystem.faileds; ++i)
218 if (myEquationsSystem.failed[i] == (Slvs_hConstraint)theConstraint)
223 int SolveSpaceSolver_Solver::dof() const
225 return myEquationsSystem.dof;