]> SALOME platform Git repositories - modules/shaper.git/blob - src/SketchSolver/SketchSolver_Constraint.cpp
Salome HOME
SketchSolver library refactoring
[modules/shaper.git] / src / SketchSolver / SketchSolver_Constraint.cpp
1 #include <SketchSolver_Constraint.h>
2 #include <SketchSolver_Group.h>
3 #include <SketchSolver_Error.h>
4
5 #include <SketchPlugin_Arc.h>
6 #include <SketchPlugin_Circle.h>
7 #include <SketchPlugin_Line.h>
8 #include <SketchPlugin_Point.h>
9
10 #include <GeomDataAPI_Point.h>
11 #include <GeomDataAPI_Point2D.h>
12 #include <ModelAPI_AttributeDouble.h>
13 #include <ModelAPI_ResultConstruction.h>
14
15
16 SketchSolver_Constraint::SketchSolver_Constraint(
17     ConstraintPtr  theConstraint)
18   : myBaseConstraint(theConstraint),
19     myGroup(0)
20 {
21 }
22
23 SketchSolver_Constraint::~SketchSolver_Constraint()
24 {
25   std::map<AttributePtr, Slvs_hParam>::const_iterator anIt1 = myValueMap.begin();
26   for (; anIt1 != myValueMap.end(); anIt1++)
27     myStorage->removeParameter(anIt1->second);
28   myValueMap.clear();
29
30   std::map<AttributePtr, Slvs_hEntity>::const_iterator anIt2 = myAttributeMap.begin();
31   for (; anIt2 != myAttributeMap.end(); anIt2++)
32     myStorage->removeEntity(anIt2->second);
33   myAttributeMap.clear();
34
35   std::map<FeaturePtr, Slvs_hEntity>::const_iterator anIt3 =  myFeatureMap.begin();
36   for (; anIt3 != myFeatureMap.end(); anIt3++)
37     myStorage->removeEntity(anIt3->second);
38   myFeatureMap.clear();
39
40   std::vector<Slvs_hConstraint>::const_iterator anIt4 = mySlvsConstraints.begin();
41   for (; anIt4 != mySlvsConstraints.end(); anIt4++)
42     myStorage->removeConstraint(*anIt4);
43   mySlvsConstraints.clear();
44 }
45
46 void SketchSolver_Constraint::setStorage(StoragePtr theStorage)
47 {
48   myStorage = theStorage;
49   process();
50 }
51
52 void SketchSolver_Constraint::setGroup(SketchSolver_Group* theGroup)
53 {
54   myGroup = theGroup;
55   process();
56 }
57
58
59 void SketchSolver_Constraint::process()
60 {
61   cleanErrorMsg();
62   if (!myBaseConstraint || !myStorage || myGroup == 0) {
63     /// TODO: Put error message here
64     return;
65   }
66   if (!mySlvsConstraints.empty()) // some data is changed, update constraint
67     update(myBaseConstraint);
68
69   int aConstrType = getType();
70   double aValue = 0.0;
71   std::vector<Slvs_hEntity> anAttributes;
72   getAttributes(aValue, anAttributes);
73   if (!myErrorMsg.empty())
74     return;
75
76   Slvs_hGroup aGroupID = myGroup->getId();
77   Slvs_hEntity aWorkplaneID = myGroup->getWorkplaneId();
78   Slvs_Constraint aConstraint;
79   if (mySlvsConstraints.empty())
80     aConstraint = Slvs_MakeConstraint(SLVS_C_UNKNOWN, aGroupID, aConstrType, aWorkplaneID,
81         aValue, anAttributes[0], anAttributes[1], anAttributes[2], anAttributes[3]);
82   else {
83     aConstraint = myStorage->getConstraint(mySlvsConstraints[0]);
84     aConstraint.valA = aValue;
85     static const int aNbAttrs = 6;
86     Slvs_hEntity* aConstrAttrs[aNbAttrs] = {
87         &aConstraint.ptA, &aConstraint.ptB,
88         &aConstraint.entityA, &aConstraint.entityB,
89         &aConstraint.entityC, &aConstraint.entityD};
90     std::vector<Slvs_hEntity>::const_iterator anIter = anAttributes.begin();
91     for (int i = 0; i < aNbAttrs && anIter != anAttributes.end(); i++, anIter++)
92       *(aConstrAttrs[i]) = *anIter;
93   }
94
95   Slvs_hConstraint anID = myStorage->addConstraint(aConstraint);
96   if (mySlvsConstraints.empty())
97     mySlvsConstraints.push_back(anID);
98   else
99     mySlvsConstraints[0] = anID;
100   adjustConstraint();
101 }
102
103 void SketchSolver_Constraint::update(ConstraintPtr theConstraint)
104 {
105   cleanErrorMsg();
106   if (theConstraint && theConstraint != myBaseConstraint) {
107     if (theConstraint->getKind() != myBaseConstraint->getKind())
108       return;
109     remove(myBaseConstraint);
110     myBaseConstraint = theConstraint;
111     process();
112   }
113
114   // Update all attributes
115   int aType;
116   std::map<Slvs_hEntity, Slvs_hEntity> aRelocationMap;
117   std::map<FeaturePtr, Slvs_hEntity>::iterator aFeatIter = myFeatureMap.begin();
118   for (; aFeatIter != myFeatureMap.end(); aFeatIter++) {
119     Slvs_hEntity aPrevID = aFeatIter->second;
120     aFeatIter->second = changeEntity(aFeatIter->first, aType);
121     if (aFeatIter->second != aPrevID)
122       aRelocationMap[aPrevID] = aFeatIter->second;
123   }
124   std::map<AttributePtr, Slvs_hEntity>::iterator anAttrIter = myAttributeMap.begin();
125   for (; anAttrIter != myAttributeMap.end(); anAttrIter++) {
126     Slvs_hEntity aPrevID = anAttrIter->second;
127     anAttrIter->second = changeEntity(anAttrIter->first, aType);
128     if (anAttrIter->second != aPrevID)
129       aRelocationMap[aPrevID] = anAttrIter->second;
130   }
131
132   // Value if exists
133   AttributeDoublePtr aValueAttr = std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(
134     myBaseConstraint->data()->attribute(SketchPlugin_Constraint::VALUE()));
135   double aValue = aValueAttr ? aValueAttr->value() : 0.0;
136
137   // Update constraint
138   std::vector<Slvs_hConstraint>::iterator aCIter = mySlvsConstraints.begin();
139   for (; aCIter != mySlvsConstraints.end(); aCIter++) {
140     Slvs_Constraint aConstraint = myStorage->getConstraint(*aCIter);
141     aConstraint.valA = aValue;
142     Slvs_hEntity* aCoeffs[6] = {
143         &aConstraint.ptA, &aConstraint.ptB,
144         &aConstraint.entityA, &aConstraint.entityB,
145         &aConstraint.entityC, &aConstraint.entityD};
146     for (int i = 0; i < 6; i++) {
147       if (*(aCoeffs[i]) == SLVS_E_UNKNOWN)
148         continue;
149       std::map<Slvs_hEntity, Slvs_hEntity>::iterator aFound = aRelocationMap.find(*(aCoeffs[i]));
150       if (aFound != aRelocationMap.end())
151         *(aCoeffs[i]) = aFound->second;
152     }
153     *aCIter = myStorage->addConstraint(aConstraint);
154   }
155   adjustConstraint();
156 }
157
158 bool SketchSolver_Constraint::remove(ConstraintPtr theConstraint)
159 {
160   cleanErrorMsg();
161   if (theConstraint && theConstraint != myBaseConstraint)
162     return false;
163   bool isFullyRemoved = myStorage->removeConstraint(mySlvsConstraints.front());
164   if (isFullyRemoved) {
165     myFeatureMap.clear();
166     myAttributeMap.clear();
167     myValueMap.clear();
168   } else
169     cleanRemovedEntities();
170   return true;
171 }
172
173 void SketchSolver_Constraint::cleanRemovedEntities()
174 {
175   std::set<Slvs_hParam> aRemovedParams;
176   std::set<Slvs_hEntity> aRemovedEntities;
177   std::set<Slvs_hConstraint> aRemovedConstraints;
178   myStorage->getRemoved(aRemovedParams, aRemovedEntities, aRemovedConstraints);
179   std::map<FeaturePtr, Slvs_hEntity>::iterator aFeatIt = myFeatureMap.begin();
180   while (aFeatIt != myFeatureMap.end()) {
181     if (aRemovedEntities.find(aFeatIt->second) == aRemovedEntities.end()) {
182       aFeatIt++;
183       continue;
184     }
185     std::map<FeaturePtr, Slvs_hEntity>::iterator aTmpIter = aFeatIt++;
186     myFeatureMap.erase(aTmpIter);
187   }
188   std::map<AttributePtr, Slvs_hEntity>::iterator anAttrIt = myAttributeMap.begin();
189   while (anAttrIt != myAttributeMap.end()) {
190     if (aRemovedEntities.find(anAttrIt->second) == aRemovedEntities.end()) {
191       anAttrIt++;
192       continue;
193     }
194     std::map<AttributePtr, Slvs_hEntity>::iterator aTmpIter = anAttrIt++;
195     myAttributeMap.erase(aTmpIter);
196   }
197   std::map<AttributePtr, Slvs_hParam>::iterator aValIt = myValueMap.begin();
198   while (aValIt != myValueMap.end()) {
199     if (aRemovedParams.find(aValIt->second) == aRemovedParams.end()) {
200       aValIt++;
201       continue;
202     }
203     std::map<AttributePtr, Slvs_hParam>::iterator aTmpIter = aValIt++;
204     myValueMap.erase(aTmpIter);
205   }
206 }
207
208 void SketchSolver_Constraint::getAttributes(
209     double& theValue,
210     std::vector<Slvs_hEntity>& theAttributes)
211 {
212   static const int anInitNbOfAttr = 4;
213   theAttributes.assign(anInitNbOfAttr, SLVS_E_UNKNOWN);
214
215   DataPtr aData = myBaseConstraint->data();
216
217   AttributeDoublePtr aValueAttr = std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(
218     aData->attribute(SketchPlugin_Constraint::VALUE()));
219   theValue = aValueAttr ? aValueAttr->value() : 0.0;
220
221   int aPtInd = 0; // index of first point in the list of attributes
222   int aEntInd = 2; // index of first antity in the list of attributes
223   std::list<AttributePtr> aConstrAttrs = aData->attributes(ModelAPI_AttributeRefAttr::typeId());
224   std::list<AttributePtr>::iterator anIter = aConstrAttrs.begin();
225   for (; anIter != aConstrAttrs.end(); anIter++) {
226     AttributeRefAttrPtr aRefAttr =
227         std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anIter);
228     if (!aRefAttr || !aRefAttr->isInitialized()) {
229       myErrorMsg = SketchSolver_Error::NOT_INITIALIZED();
230       return;
231     }
232
233     int aType = SLVS_E_UNKNOWN; // type of created entity
234     Slvs_hEntity anEntity = myGroup->getAttributeId(aRefAttr);
235     if (anEntity == SLVS_E_UNKNOWN)
236       anEntity = changeEntity(aRefAttr, aType);
237     else {
238       Slvs_Entity anEnt = myStorage->getEntity(anEntity);
239       aType = anEnt.type;
240     }
241
242     if (aType == SLVS_E_UNKNOWN)
243       continue;
244     else if (aType == SLVS_E_POINT_IN_2D || aType == SLVS_E_POINT_IN_3D)
245       theAttributes[aPtInd++] = anEntity; // the point is created
246     else { // another entity (not a point) is created
247       if (aEntInd < anInitNbOfAttr)
248         theAttributes[aEntInd] = anEntity;
249       else
250         theAttributes.push_back(anEntity);
251       aEntInd++;
252     }
253   }
254 }
255
256 Slvs_hEntity SketchSolver_Constraint::changeEntity(AttributeRefAttrPtr theAttribute, int& theType)
257 {
258   // Convert the object of the attribute to the feature
259   FeaturePtr aFeature;
260   if (theAttribute->isObject() && theAttribute->object()) {
261     ResultConstructionPtr aRC = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(
262         theAttribute->object());
263     if (!aRC) {
264       myErrorMsg = SketchSolver_Error::NOT_INITIALIZED();
265       return SLVS_E_UNKNOWN;
266     }
267     std::shared_ptr<ModelAPI_Document> aDoc = aRC->document();
268     aFeature = aDoc->feature(aRC);
269
270     return changeEntity(aFeature, theType);
271   }
272
273   return changeEntity(theAttribute->attr(), theType);
274 }
275
276 Slvs_hEntity SketchSolver_Constraint::changeEntity(AttributePtr theEntity, int& theType)
277 {
278   Slvs_hEntity aResult = SLVS_E_UNKNOWN;
279   if (!theEntity->isInitialized())
280     return SLVS_E_UNKNOWN;
281
282   // If the entity is already in the group, try to find it
283   std::map<std::shared_ptr<ModelAPI_Attribute>, Slvs_hEntity>::const_iterator anEntIter =
284       myAttributeMap.find(theEntity);
285   Slvs_Entity aCurrentEntity;
286   aCurrentEntity.h = SLVS_E_UNKNOWN;
287   if (anEntIter != myAttributeMap.end())
288     aCurrentEntity = myStorage->getEntity(anEntIter->second);
289   else {
290     aResult = myGroup->getAttributeId(theEntity);
291     if (aResult != SLVS_E_UNKNOWN) {
292       Slvs_Entity anEnt = myStorage->getEntity(aResult);
293       theType = anEnt.type;
294       return aResult;
295     }
296   }
297
298   Slvs_hGroup aGroupID = myGroup->getId();
299   // Point in 3D
300   std::shared_ptr<GeomDataAPI_Point> aPoint =
301       std::dynamic_pointer_cast<GeomDataAPI_Point>(theEntity);
302   if (aPoint) {
303     double aXYZ[3] = {aPoint->x(), aPoint->y(), aPoint->z()};
304     Slvs_hParam aParams[3];
305     for (int i = 0; i < 3; i++) {
306       Slvs_Param aPar = aCurrentEntity.h != SLVS_E_UNKNOWN ?
307           myStorage->getParameter(aCurrentEntity.param[i]) :
308           Slvs_MakeParam(SLVS_E_UNKNOWN, aGroupID, 0.0);
309       aPar.val = aXYZ[i];
310       aParams[i] = myStorage->addParameter(aPar);
311     }
312
313     if (aCurrentEntity.h == SLVS_E_UNKNOWN) // New entity
314       aCurrentEntity = Slvs_MakePoint3d(SLVS_E_UNKNOWN, aGroupID, aParams[0], aParams[1], aParams[2]);
315     else { // update entity data
316       for (int i = 0; i < 3; i++)
317         aCurrentEntity.param[i] = aParams[i];
318     }
319     aResult = myStorage->addEntity(aCurrentEntity);
320   } else {
321     // All entities except 3D points are created on workplane. So, if there is no workplane yet, then error
322     Slvs_hEntity aWorkplaneID = myGroup->getWorkplaneId();
323     if (aWorkplaneID == SLVS_E_UNKNOWN)
324       return SLVS_E_UNKNOWN;
325
326     // Point in 2D
327     std::shared_ptr<GeomDataAPI_Point2D> aPoint2D =
328         std::dynamic_pointer_cast<GeomDataAPI_Point2D>(theEntity);
329     if (aPoint2D) {
330       double aXY[2] = {aPoint2D->x(), aPoint2D->y()};
331       Slvs_hParam aParams[2];
332       for (int i = 0; i < 2; i++) {
333         Slvs_Param aPar = aCurrentEntity.h != SLVS_E_UNKNOWN ?
334             myStorage->getParameter(aCurrentEntity.param[i]) :
335             Slvs_MakeParam(SLVS_E_UNKNOWN, aGroupID, 0.0);
336         aPar.val = aXY[i];
337         aParams[i] = myStorage->addParameter(aPar);
338       }
339
340       if (aCurrentEntity.h == SLVS_E_UNKNOWN) // New entity
341         aCurrentEntity = Slvs_MakePoint2d(SLVS_E_UNKNOWN, aGroupID, aWorkplaneID, aParams[0], aParams[1]);
342       else { // update entity data
343         for (int i = 0; i < 2; i++)
344           aCurrentEntity.param[i] = aParams[i];
345       }
346       aResult = myStorage->addEntity(aCurrentEntity);
347     } else {
348       // Scalar value (used for the distance entities)
349       AttributeDoublePtr aScalar = std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(theEntity);
350       if (aScalar) {
351         Slvs_Param aParam = aCurrentEntity.h != SLVS_E_UNKNOWN ?
352             myStorage->getParameter(aCurrentEntity.param[0]) :
353             Slvs_MakeParam(SLVS_E_UNKNOWN, aGroupID, 0.0);
354         aParam.val = aScalar->value();
355         Slvs_hParam aValue = myStorage->addParameter(aParam);
356
357         if (aCurrentEntity.h == SLVS_E_UNKNOWN) // New entity
358           aCurrentEntity = Slvs_MakeDistance(SLVS_E_UNKNOWN, aGroupID, aWorkplaneID, aValue);
359         else
360           aCurrentEntity.param[0] = aValue;
361         aResult = myStorage->addEntity(aCurrentEntity);
362       }
363     }
364   }
365
366   myAttributeMap[theEntity] = aResult;
367   theType = aCurrentEntity.type;
368   return aResult;
369 }
370
371 Slvs_hEntity SketchSolver_Constraint::changeEntity(FeaturePtr theEntity, int& theType)
372 {
373   Slvs_hEntity aResult = SLVS_E_UNKNOWN;
374   if (!theEntity->data()->isValid())
375     return SLVS_E_UNKNOWN;
376   // If the entity is already in the group, try to find it
377   std::map<FeaturePtr, Slvs_hEntity>::const_iterator anEntIter = myFeatureMap.find(theEntity);
378   Slvs_Entity aCurrentEntity;
379   aCurrentEntity.h = SLVS_E_UNKNOWN;
380   if (anEntIter != myFeatureMap.end())
381     aCurrentEntity = myStorage->getEntity(anEntIter->second);
382   else {
383     aResult = myGroup->getFeatureId(theEntity);
384     if (aResult != SLVS_E_UNKNOWN) {
385       Slvs_Entity anEnt = myStorage->getEntity(aResult);
386       theType = anEnt.type;
387       return aResult;
388     }
389   }
390
391   Slvs_hGroup aGroupID = myGroup->getId();
392   Slvs_hEntity aWorkplaneID = myGroup->getWorkplaneId();
393   // SketchPlugin features
394   std::shared_ptr<SketchPlugin_Feature> aFeature = std::dynamic_pointer_cast<
395       SketchPlugin_Feature>(theEntity);
396   if (aFeature) {  // Verify the feature by its kind
397     const std::string& aFeatureKind = aFeature->getKind();
398     AttributePtr anAttribute;
399     int anAttrType;
400
401     // Line
402     if (aFeatureKind == SketchPlugin_Line::ID()) {
403       anAttribute = aFeature->data()->attribute(SketchPlugin_Line::START_ID());
404       if (!anAttribute->isInitialized()) return SLVS_E_UNKNOWN;
405       Slvs_hEntity aStart = changeEntity(anAttribute, anAttrType);
406
407       anAttribute = aFeature->data()->attribute(SketchPlugin_Line::END_ID());
408       if (!anAttribute->isInitialized()) return SLVS_E_UNKNOWN;
409       Slvs_hEntity aEnd = changeEntity(anAttribute, anAttrType);
410
411       if (aCurrentEntity.h == SLVS_E_UNKNOWN) // New entity
412         aCurrentEntity = Slvs_MakeLineSegment(SLVS_E_UNKNOWN, aGroupID, aWorkplaneID, aStart, aEnd);
413       else {
414         aCurrentEntity.point[0] = aStart;
415         aCurrentEntity.point[1] = aEnd;
416       }
417       aResult = myStorage->addEntity(aCurrentEntity);
418     }
419     // Circle
420     else if (aFeatureKind == SketchPlugin_Circle::ID()) {
421       anAttribute = aFeature->data()->attribute(SketchPlugin_Circle::CENTER_ID());
422       if (!anAttribute->isInitialized()) return SLVS_E_UNKNOWN;
423       Slvs_hEntity aCenter = changeEntity(anAttribute, anAttrType);
424
425       anAttribute = aFeature->data()->attribute(SketchPlugin_Circle::RADIUS_ID());
426       if (!anAttribute->isInitialized()) return SLVS_E_UNKNOWN;
427       Slvs_hEntity aRadius = changeEntity(anAttribute, anAttrType);
428
429       if (aCurrentEntity.h == SLVS_E_UNKNOWN) { // New entity
430         Slvs_Entity aWorkplane = myStorage->getEntity(aWorkplaneID);
431         aCurrentEntity = Slvs_MakeCircle(SLVS_E_UNKNOWN, aGroupID, aWorkplaneID,
432                                          aCenter, aWorkplane.normal, aRadius);
433       } else {
434         aCurrentEntity.point[0] = aCenter;
435         aCurrentEntity.distance = aRadius;
436       }
437       aResult = myStorage->addEntity(aCurrentEntity);
438     }
439     // Arc
440     else if (aFeatureKind == SketchPlugin_Arc::ID()) {
441       anAttribute = aFeature->data()->attribute(SketchPlugin_Arc::CENTER_ID());
442       if (!anAttribute->isInitialized()) return SLVS_E_UNKNOWN;
443       Slvs_hEntity aCenter = changeEntity(anAttribute, anAttrType);
444
445       anAttribute = aFeature->data()->attribute(SketchPlugin_Arc::START_ID());
446       if (!anAttribute->isInitialized()) return SLVS_E_UNKNOWN;
447       Slvs_hEntity aStart = changeEntity(anAttribute, anAttrType);
448
449       anAttribute = aFeature->data()->attribute(SketchPlugin_Arc::END_ID());
450       if (!anAttribute->isInitialized()) return SLVS_E_UNKNOWN;
451       Slvs_hEntity aEnd = changeEntity(anAttribute, anAttrType);
452
453       if (aCurrentEntity.h == SLVS_E_UNKNOWN) { // New entity
454         Slvs_Entity aWorkplane = myStorage->getEntity(aWorkplaneID);
455         aCurrentEntity = Slvs_MakeArcOfCircle(SLVS_E_UNKNOWN, aGroupID, aWorkplaneID,
456                                               aWorkplane.normal, aCenter, aStart, aEnd);
457       } else {
458         aCurrentEntity.point[0] = aCenter;
459         aCurrentEntity.point[1] = aStart;
460         aCurrentEntity.point[2] = aEnd;
461       }
462       aResult = myStorage->addEntity(aCurrentEntity);
463     }
464     // Point (it has low probability to be an attribute of constraint, so it is checked at the end)
465     else if (aFeatureKind == SketchPlugin_Point::ID()) {
466       anAttribute = aFeature->data()->attribute(SketchPlugin_Point::COORD_ID());
467       if (!anAttribute->isInitialized()) return SLVS_E_UNKNOWN;
468       // Both the sketch point and its attribute (coordinates) link to the same SolveSpace point identifier
469       aResult = changeEntity(anAttribute, anAttrType);
470       aCurrentEntity.type = SLVS_E_POINT_IN_3D;
471     }
472   }
473
474   if (aResult != SLVS_E_UNKNOWN) {
475     myFeatureMap[theEntity] = aResult;
476     theType = aCurrentEntity.type;
477   }
478   return aResult;
479 }
480
481 std::list<ConstraintPtr> SketchSolver_Constraint::constraints() const
482 {
483   std::list<ConstraintPtr> aConstraints;
484   aConstraints.push_back(myBaseConstraint);
485   return aConstraints;
486 }
487
488 void SketchSolver_Constraint::refresh()
489 {
490   cleanErrorMsg();
491   std::map<AttributePtr, Slvs_hEntity>::iterator anAttrIter = myAttributeMap.begin();
492   for (; anAttrIter != myAttributeMap.end(); anAttrIter++) {
493     std::shared_ptr<GeomDataAPI_Point> aPoint =
494         std::dynamic_pointer_cast<GeomDataAPI_Point>(anAttrIter->first);
495     if (aPoint) {
496       Slvs_Entity anEntity = myStorage->getEntity(anAttrIter->second);
497       double aXYZ[3];
498       for (int i = 0; i < 3; i++) {
499         Slvs_Param aPar = myStorage->getParameter(anEntity.param[i]);
500         aXYZ[i] = aPar.val;
501       }
502       aPoint->setValue(aXYZ[0], aXYZ[1], aXYZ[2]);
503     } else {
504       // Point in 2D
505       std::shared_ptr<GeomDataAPI_Point2D> aPoint2D =
506           std::dynamic_pointer_cast<GeomDataAPI_Point2D>(anAttrIter->first);
507       if (aPoint2D) {
508         Slvs_Entity anEntity = myStorage->getEntity(anAttrIter->second);
509         double aXYZ[2];
510         for (int i = 0; i < 2; i++) {
511           Slvs_Param aPar = myStorage->getParameter(anEntity.param[i]);
512           aXYZ[i] = aPar.val;
513         }
514         aPoint2D->setValue(aXYZ[0], aXYZ[1]);
515       } else {
516         // Scalar value (used for the distance entities)
517         AttributeDoublePtr aScalar =
518             std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(anAttrIter->first);
519         if (aScalar) {
520           Slvs_Entity anEntity = myStorage->getEntity(anAttrIter->second);
521           Slvs_Param aPar = myStorage->getParameter(anEntity.param[0]);
522           aScalar->setValue(aPar.val);
523         }
524       }
525     }
526   }
527
528   std::map<AttributePtr, Slvs_hParam>::iterator aValIter = myValueMap.begin();
529   for (; aValIter != myValueMap.end(); aValIter++) {
530     AttributeDoublePtr aScalar =
531         std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(anAttrIter->first);
532     if (aScalar) {
533       Slvs_Param aPar = myStorage->getParameter(anAttrIter->second);
534       aScalar->setValue(aPar.val);
535     }
536   }
537 }
538
539 Slvs_hEntity SketchSolver_Constraint::getId(FeaturePtr theFeature) const
540 {
541   std::map<FeaturePtr, Slvs_hEntity>::const_iterator aFIter = myFeatureMap.find(theFeature);
542   if (aFIter == myFeatureMap.end())
543     return SLVS_E_UNKNOWN;
544   return aFIter->second;
545 }
546
547 Slvs_hEntity SketchSolver_Constraint::getId(AttributePtr theAttribute) const
548 {
549   std::map<AttributePtr, Slvs_hEntity>::const_iterator anAttrIter = myAttributeMap.find(theAttribute);
550   if (anAttrIter == myAttributeMap.end())
551     return SLVS_E_UNKNOWN;
552   return anAttrIter->second;
553 }
554