1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
3 // File: SketchSolver_Storage.cpp
4 // Created: 18 Mar 2015
5 // Author: Artem ZHIDKOV
7 #include <SketchSolver_Storage.h>
9 /** \brief Search the entity/parameter with specified ID in the list of elements
10 * \param[in] theEntityID unique ID of the element
11 * \param[in] theEntities list of elements
12 * \return position of the found element or -1 if the element is not found
15 static int Search(const uint32_t& theEntityID, const std::vector<T>& theEntities);
17 /// \brief Compare two parameters to be different
18 static bool IsNotEqual(const Slvs_Param& theParam1, const Slvs_Param& theParam2);
19 /// \brief Compare two entities to be different
20 static bool IsNotEqual(const Slvs_Entity& theEntity1, const Slvs_Entity& theEntity2);
21 /// \brief Compare two constriants to be different
22 static bool IsNotEqual(const Slvs_Constraint& theConstraint1, const Slvs_Constraint& theConstraint2);
25 SketchSolver_Storage::SketchSolver_Storage()
26 : myParamMaxID(SLVS_E_UNKNOWN),
27 myEntityMaxID(SLVS_E_UNKNOWN),
28 myConstrMaxID(SLVS_C_UNKNOWN),
29 myNeedToResolve(false)
33 Slvs_hParam SketchSolver_Storage::addParameter(const Slvs_Param& theParam)
35 if (theParam.h > 0 && theParam.h <= myParamMaxID) {
36 // parameter is already used, rewrite it
37 return updateParameter(theParam);
40 Slvs_Param aParam = theParam;
41 if (aParam.h > myParamMaxID)
42 myParamMaxID = aParam.h;
44 aParam.h = ++myParamMaxID;
45 myParameters.push_back(aParam);
46 myNeedToResolve = true;
50 Slvs_hParam SketchSolver_Storage::updateParameter(const Slvs_Param& theParam)
52 if (theParam.h > 0 && theParam.h <= myParamMaxID) {
53 // parameter already used, rewrite it
54 int aPos = Search(theParam.h, myParameters);
55 if (aPos >= 0 && aPos < (int)myParameters.size()) {
56 myNeedToResolve = myNeedToResolve || IsNotEqual(myParameters[aPos], theParam);
57 myParameters[aPos] = theParam;
62 // Parameter is not found, add new one
63 Slvs_Param aParam = theParam;
65 return addParameter(aParam);
68 bool SketchSolver_Storage::removeParameter(const Slvs_hParam& theParamID)
70 int aPos = Search(theParamID, myParameters);
71 if (aPos >= 0 && aPos < (int)myParameters.size()) {
72 // Firstly, search the parametes is not used elsewhere
73 std::vector<Slvs_Entity>::const_iterator anEntIter = myEntities.begin();
74 for (; anEntIter != myEntities.end(); anEntIter++) {
75 for (int i = 0; i < 4; i++)
76 if (anEntIter->param[i] == theParamID)
80 myParameters.erase(myParameters.begin() + aPos);
81 myNeedToResolve = true;
82 myRemovedParameters.insert(theParamID);
88 const Slvs_Param& SketchSolver_Storage::getParameter(const Slvs_hParam& theParamID) const
90 int aPos = Search(theParamID, myParameters);
91 if (aPos >= 0 && aPos < (int)myParameters.size())
92 return myParameters[aPos];
94 // Parameter is not found, return empty object
95 static Slvs_Param aDummy;
101 Slvs_hEntity SketchSolver_Storage::addEntity(const Slvs_Entity& theEntity)
103 if (theEntity.h > 0 && theEntity.h <= myEntityMaxID) {
104 // Entity is already used, rewrite it
105 return updateEntity(theEntity);
108 Slvs_Entity aEntity = theEntity;
109 if (aEntity.h > myEntityMaxID)
110 myEntityMaxID = aEntity.h;
112 aEntity.h = ++myEntityMaxID;
113 myEntities.push_back(aEntity);
114 myNeedToResolve = true;
118 Slvs_hEntity SketchSolver_Storage::updateEntity(const Slvs_Entity& theEntity)
120 if (theEntity.h > 0 && theEntity.h <= myEntityMaxID) {
121 // Entity already used, rewrite it
122 int aPos = Search(theEntity.h, myEntities);
123 if (aPos >= 0 && aPos < (int)myEntities.size()) {
124 myNeedToResolve = myNeedToResolve || IsNotEqual(myEntities[aPos], theEntity);
125 myEntities[aPos] = theEntity;
130 // Entity is not found, add new one
131 Slvs_Entity aEntity = theEntity;
133 return addEntity(aEntity);
136 bool SketchSolver_Storage::removeEntity(const Slvs_hEntity& theEntityID)
139 int aPos = Search(theEntityID, myEntities);
140 if (aPos >= 0 && aPos < (int)myEntities.size()) {
141 // Firstly, check the entity is not used elsewhere
142 std::vector<Slvs_Entity>::const_iterator anEntIter = myEntities.begin();
143 for (; anEntIter != myEntities.end(); anEntIter++) {
144 for (int i = 0; i < 4; i++)
145 if (anEntIter->point[i] == theEntityID)
147 if (anEntIter->distance == theEntityID)
150 std::vector<Slvs_Constraint>::const_iterator aConstrIter = myConstraints.begin();
151 for (; aConstrIter != myConstraints.end(); aConstrIter++) {
152 Slvs_hEntity anEntIDs[6] = {aConstrIter->ptA, aConstrIter->ptB,
153 aConstrIter->entityA, aConstrIter->entityB,
154 aConstrIter->entityC, aConstrIter->entityD};
155 for (int i = 0; i < 6; i++)
156 if (anEntIDs[i] == theEntityID)
159 // The entity is not used, remove it and its parameters
160 Slvs_Entity anEntity = myEntities[aPos];
161 myEntities.erase(myEntities.begin() + aPos);
162 if (anEntity.distance != SLVS_E_UNKNOWN)
163 aResult = aResult && removeParameter(anEntity.distance);
164 for (int i = 0; i < 4; i++)
165 if (anEntity.param[i] != SLVS_E_UNKNOWN)
166 aResult = removeParameter(anEntity.param[i]) && aResult;
167 for (int i = 0; i < 4; i++)
168 if (anEntity.point[i] != SLVS_E_UNKNOWN)
169 aResult = removeEntity(anEntity.point[i]) && aResult;
170 myNeedToResolve = true;
171 myRemovedEntities.insert(theEntityID);
176 const Slvs_Entity& SketchSolver_Storage::getEntity(const Slvs_hEntity& theEntityID) const
178 int aPos = Search(theEntityID, myEntities);
179 if (aPos >= 0 && aPos < (int)myEntities.size())
180 return myEntities[aPos];
182 // Entity is not found, return empty object
183 static Slvs_Entity aDummy;
189 Slvs_hConstraint SketchSolver_Storage::addConstraint(const Slvs_Constraint& theConstraint)
191 if (theConstraint.h > 0 && theConstraint.h <= myConstrMaxID) {
192 // Constraint is already used, rewrite it
193 return updateConstraint(theConstraint);
196 Slvs_Constraint aConstraint = theConstraint;
197 if (aConstraint.h > myConstrMaxID)
198 myConstrMaxID = aConstraint.h;
200 aConstraint.h = ++myConstrMaxID;
201 myConstraints.push_back(aConstraint);
202 myNeedToResolve = true;
203 return aConstraint.h;
206 Slvs_hConstraint SketchSolver_Storage::updateConstraint(const Slvs_Constraint& theConstraint)
208 if (theConstraint.h > 0 && theConstraint.h <= myConstrMaxID) {
209 // Constraint already used, rewrite it
210 int aPos = Search(theConstraint.h, myConstraints);
211 if (aPos >= 0 && aPos < (int)myConstraints.size()) {
212 myNeedToResolve = myNeedToResolve || IsNotEqual(myConstraints[aPos], theConstraint);
213 myConstraints[aPos] = theConstraint;
214 return theConstraint.h;
218 // Constraint is not found, add new one
219 Slvs_Constraint aConstraint = theConstraint;
221 return addConstraint(aConstraint);
224 bool SketchSolver_Storage::removeConstraint(const Slvs_hConstraint& theConstraintID)
227 int aPos = Search(theConstraintID, myConstraints);
228 if (aPos >= 0 && aPos < (int)myConstraints.size()) {
229 Slvs_Constraint aConstraint = myConstraints[aPos];
230 myConstraints.erase(myConstraints.begin() + aPos);
231 myNeedToResolve = true;
232 myRemovedConstraints.insert(theConstraintID);
233 // Remove all entities
234 Slvs_hEntity anEntities[6] = {aConstraint.ptA, aConstraint.ptB,
235 aConstraint.entityA, aConstraint.entityB,
236 aConstraint.entityC, aConstraint.entityD};
237 for (int i = 0; i < 6; i++)
238 if (anEntities[i] != SLVS_E_UNKNOWN) {
239 aResult = removeEntity(anEntities[i]) && aResult;
240 // remove temporary fixed points, if exists
241 std::vector<Slvs_hEntity>::iterator aFPIt = myFixedPoints.begin();
242 for (; aFPIt != myFixedPoints.end(); aFPIt++)
243 if (*aFPIt == anEntities[i]) {
244 myFixedPoints.erase(aFPIt);
252 const Slvs_Constraint& SketchSolver_Storage::getConstraint(const Slvs_hConstraint& theConstraintID) const
254 int aPos = Search(theConstraintID, myConstraints);
255 if (aPos >= 0 && aPos < (int)myConstraints.size())
256 return myConstraints[aPos];
258 // Constraint is not found, return empty object
259 static Slvs_Constraint aDummy;
264 void SketchSolver_Storage::addTemporaryConstraint(const Slvs_hConstraint& theConstraintID)
266 int aPos = Search(theConstraintID, myConstraints);
267 myFixedPoints.push_back(myConstraints[aPos].ptA);
270 void SketchSolver_Storage::getRemoved(
271 std::set<Slvs_hParam>& theParameters,
272 std::set<Slvs_hEntity>& theEntities,
273 std::set<Slvs_hConstraint>& theConstraints)
275 theParameters = myRemovedParameters;
276 theEntities = myRemovedEntities;
277 theConstraints = myRemovedConstraints;
279 myRemovedParameters.clear();
280 myRemovedEntities.clear();
281 myRemovedConstraints.clear();
284 void SketchSolver_Storage::initializeSolver(SketchSolver_Solver& theSolver)
286 theSolver.setParameters(myParameters.data(), (int)myParameters.size());
287 theSolver.setEntities(myEntities.data(), (int)myEntities.size());
288 theSolver.setConstraints(myConstraints.data(), (int)myConstraints.size());
290 // initialize fixed points
291 if (!myFixedPoints.empty()) {
292 int aPos = Search(myFixedPoints.front(), myEntities);
293 theSolver.setDraggedParameters(myEntities[aPos].param);
298 // ========================================================
299 // ========= Auxiliary functions ===============
300 // ========================================================
303 int Search(const uint32_t& theEntityID, const std::vector<T>& theEntities)
305 int aResIndex = theEntityID <= theEntities.size() ? theEntityID - 1 : 0;
306 int aVecSize = theEntities.size();
307 while (aResIndex >= 0 && theEntities[aResIndex].h > theEntityID)
309 while (aResIndex < aVecSize && aResIndex >= 0 && theEntities[aResIndex].h < theEntityID)
312 aResIndex = aVecSize;
316 bool IsNotEqual(const Slvs_Param& theParam1, const Slvs_Param& theParam2)
318 return fabs(theParam1.val - theParam2.val) > tolerance;
321 bool IsNotEqual(const Slvs_Entity& theEntity1, const Slvs_Entity& theEntity2)
324 for (; theEntity1.param[i] != 0 && i < 4; i++)
325 if (theEntity1.param[i] != theEntity2.param[i])
328 for (; theEntity1.point[i] != 0 && i < 4; i++)
329 if (theEntity1.point[i] != theEntity2.point[i])
334 bool IsNotEqual(const Slvs_Constraint& theConstraint1, const Slvs_Constraint& theConstraint2)
336 return theConstraint1.ptA != theConstraint2.ptA ||
337 theConstraint1.ptB != theConstraint2.ptB ||
338 theConstraint1.entityA != theConstraint2.entityA ||
339 theConstraint1.entityB != theConstraint2.entityB ||
340 theConstraint1.entityC != theConstraint2.entityC ||
341 theConstraint1.entityD != theConstraint2.entityD ||
342 fabs(theConstraint1.valA - theConstraint2.valA) > tolerance;