Salome HOME
Fix compilation error on Linux. Part V.
[modules/shaper.git] / src / SketchSolver / SketchSolver_ConstraintFixed.cpp
1 #include <SketchSolver_ConstraintFixed.h>
2 #include <SketchSolver_Error.h>
3 #include <SketchSolver_Manager.h>
4
5 #include <SketchPlugin_Arc.h>
6 #include <SketchPlugin_Circle.h>
7 #include <SketchPlugin_ConstraintRigid.h>
8 #include <SketchPlugin_Line.h>
9 #include <SketchPlugin_Point.h>
10
11 #include <GeomAPI_Pnt2d.h>
12 #include <GeomAPI_XY.h>
13 #include <GeomDataAPI_Point2D.h>
14 #include <ModelAPI_AttributeDouble.h>
15
16 #include <math.h>
17
18 SketchSolver_ConstraintFixed::SketchSolver_ConstraintFixed(ConstraintPtr theConstraint)
19   : SketchSolver_Constraint()
20 {
21   myBaseConstraint = theConstraint;
22   myType = CONSTRAINT_FIXED;
23   myFixedAttribute = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
24       theConstraint->attribute(SketchPlugin_ConstraintRigid::ENTITY_A()));
25 }
26
27 SketchSolver_ConstraintFixed::SketchSolver_ConstraintFixed(FeaturePtr theFeature)
28   : SketchSolver_Constraint(),
29     myBaseFeature(theFeature)
30 {
31   myType = CONSTRAINT_FIXED;
32   process();
33 }
34
35 void SketchSolver_ConstraintFixed::process()
36 {
37   cleanErrorMsg();
38   if ((!myBaseConstraint && !myBaseFeature) || !myStorage || myGroupID == GID_UNKNOWN) {
39     // Not enough parameters are assigned
40     return;
41   }
42 ////  if (!mySlvsConstraints.empty()) // some data is changed, update constraint
43 ////    update(myBaseConstraint);
44
45   ParameterWrapperPtr aValue;
46   std::vector<EntityWrapperPtr> anEntities;
47   getAttributes(aValue, anEntities);
48   if (!myErrorMsg.empty() || anEntities.empty())
49     return;
50   fixFeature(anEntities.front());
51 }
52
53 ////static void fixEntity(StoragePtr theStorage, const Slvs_hEntity& theEntID)
54 ////{
55 ////  Slvs_Entity anEntity = theStorage->getEntity(theEntID);
56 ////  anEntity.group = SLVS_G_OUTOFGROUP;
57 ////  theStorage->updateEntity(anEntity);
58 ////  // move out of group all sub-entities
59 ////  for (int i = 0; i < 4; ++i)
60 ////    if (anEntity.point[i] != SLVS_E_UNKNOWN)
61 ////      fixEntity(theStorage, anEntity.point[i]);
62 ////  // move out of group the radius of circle
63 ////  if (anEntity.distance != SLVS_E_UNKNOWN)
64 ////    fixEntity(theStorage, anEntity.distance);
65 ////  // move out of group parameters
66 ////  for (int i = 0; i < 4; ++i)
67 ////    if (anEntity.param[i] != SLVS_E_UNKNOWN) {
68 ////      Slvs_Param aParam = theStorage->getParameter(anEntity.param[i]);
69 ////      aParam.group = SLVS_G_OUTOFGROUP;
70 ////      theStorage->updateParameter(aParam);
71 ////    }
72 ////}
73
74 void SketchSolver_ConstraintFixed::fixFeature(EntityWrapperPtr theFeature)
75 {
76   // extract feature from the group
77   if (theFeature->baseAttribute())
78     myStorage->update(theFeature->baseAttribute(), GID_OUTOFGROUP);
79   else
80     myStorage->update(theFeature->baseFeature(), GID_OUTOFGROUP);
81 }
82
83 ////Slvs_hEntity SketchSolver_ConstraintFixed::fixedEntity() const
84 ////{
85 ////  Slvs_hEntity anEntID = SLVS_E_UNKNOWN;
86 ////  if (myBaseConstraint) {
87 ////    AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
88 ////        myBaseConstraint->attribute(SketchPlugin_Constraint::ENTITY_A()));
89 ////    if (aRefAttr->isObject()) {
90 ////      FeaturePtr aFeature = ModelAPI_Feature::feature(aRefAttr->object());
91 ////      std::map<FeaturePtr, Slvs_hEntity>::const_iterator aFound = myFeatureMap.find(aFeature);
92 ////      if (aFound != myFeatureMap.end())
93 ////        anEntID = aFound->second;
94 ////    } else {
95 ////      std::map<AttributePtr, Slvs_hEntity>::const_iterator aFound = myAttributeMap.find(aRefAttr->attr());
96 ////      if (aFound != myAttributeMap.end())
97 ////        anEntID = aFound->second;
98 ////    }
99 ////  }
100 ////  else if (myBaseFeature) {
101 ////    std::map<FeaturePtr, Slvs_hEntity>::const_iterator aFound = myFeatureMap.find(myBaseFeature);
102 ////    if (aFound != myFeatureMap.end())
103 ////      anEntID = aFound->second;
104 ////  }
105 ////  return anEntID;
106 ////}
107
108 void SketchSolver_ConstraintFixed::getAttributes(
109     ParameterWrapperPtr& theValue,
110     std::vector<EntityWrapperPtr>& theAttributes)
111 {
112   BuilderPtr aBuilder = SketchSolver_Manager::instance()->builder();
113
114   EntityWrapperPtr aSolverEntity;
115   if (myBaseFeature) {
116     // The feature is fixed.
117     myStorage->update(myBaseFeature, myGroupID);
118     aSolverEntity = myStorage->entity(myBaseFeature);
119   } else if (myBaseConstraint) {
120     // Constraint Fixed is added by user.
121     // Get the attribute of constraint (it should be alone in the list of constraints).
122     AttributePtr anAttr = myBaseConstraint->attribute(SketchPlugin_ConstraintRigid::ENTITY_A());
123     AttributeRefAttrPtr aRefAttr =
124         std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(anAttr);
125     if (!aRefAttr || !aRefAttr->isInitialized()) {
126       myErrorMsg = SketchSolver_Error::NOT_INITIALIZED();
127       return;
128     }
129
130     myStorage->update(anAttr, myGroupID);
131     aSolverEntity = myStorage->entity(anAttr);
132   } else
133     myErrorMsg = SketchSolver_Error::NOT_INITIALIZED();
134
135   if (aSolverEntity)
136     theAttributes.push_back(aSolverEntity);
137 }
138
139
140 bool SketchSolver_ConstraintFixed::remove()
141 {
142   cleanErrorMsg();
143   // Move fixed entities back to the current group
144   FeaturePtr aFeature = myBaseFeature;
145   if (myBaseConstraint && myFixedAttribute && myFixedAttribute->isObject())
146     aFeature = ModelAPI_Feature::feature(myFixedAttribute->object());
147   if (aFeature)
148     myStorage->update(aFeature, myGroupID);
149
150   // Remove constraint or base feature
151   if (myBaseConstraint) {
152     bool isRemoved = false;
153     if (aFeature)
154       isRemoved = myStorage->removeEntity(aFeature);
155     return SketchSolver_Constraint::remove() || isRemoved;
156   } else if (myBaseFeature)
157     myStorage->removeEntity(myBaseFeature);
158   return true;
159 }
160
161 ////Slvs_hConstraint SketchSolver_ConstraintFixed::fixPoint(const Slvs_hEntity& thePointID)
162 ////{
163 ////  if (thePointID == SLVS_E_UNKNOWN)
164 ////    return SLVS_C_UNKNOWN;
165 ////
166 ////  Slvs_Constraint aConstraint;
167 ////  Slvs_hConstraint aConstrID = SLVS_E_UNKNOWN;
168 ////  bool isFixed = myStorage->isPointFixed(thePointID, aConstrID, true);
169 ////  bool isForceUpdate = (isFixed && !myBaseConstraint &&
170 ////                        myStorage->isTemporary(aConstrID));
171 ////  if (!isForceUpdate) { // create new constraint
172 ////    if (isFixed) return aConstrID;
173 ////    aConstraint = Slvs_MakeConstraint(SLVS_C_UNKNOWN, myGroup->getId(), getType(), myGroup->getWorkplaneId(),
174 ////        0.0, thePointID, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN);
175 ////    aConstraint.h = myStorage->addConstraint(aConstraint);
176 ////    mySlvsConstraints.push_back(aConstraint.h);
177 ////    if (!myBaseConstraint)
178 ////      myStorage->addConstraintWhereDragged(aConstraint.h);
179 ////  } else { // update already existent constraint
180 ////    if (!isFixed || aConstrID == SLVS_C_UNKNOWN || myBaseConstraint)
181 ////      return SLVS_C_UNKNOWN;
182 ////    aConstraint = myStorage->getConstraint(aConstrID);
183 ////    aConstraint.ptA = thePointID;
184 ////    myStorage->addConstraint(aConstraint);
185 ////    if (!myBaseConstraint)
186 ////      myStorage->addConstraintWhereDragged(aConstraint.h);
187 ////  }
188 ////  return aConstraint.h;
189 ////}
190 ////
191 ////void SketchSolver_ConstraintFixed::fixLine(const Slvs_Entity& theLine)
192 ////{
193 ////  Slvs_Constraint anEqual;
194 ////  if (myStorage->isAxisParallel(theLine.h)) {
195 ////    // Fix one point and a line length
196 ////    Slvs_hConstraint aFixed;
197 ////    if (!myStorage->isPointFixed(theLine.point[0], aFixed, true) &&
198 ////        !myStorage->isPointFixed(theLine.point[1], aFixed, true))
199 ////      fixPoint(theLine.point[0]);
200 ////    if (!myStorage->isUsedInEqual(theLine.h, anEqual)) {
201 ////      // Check the distance is not set yet
202 ////      std::list<Slvs_Constraint> aDistConstr = myStorage->getConstraintsByType(SLVS_C_PT_PT_DISTANCE);
203 ////      std::list<Slvs_Constraint>::const_iterator aDIt = aDistConstr.begin();
204 ////      for (; aDIt != aDistConstr.end(); aDIt++)
205 ////        if ((aDIt->ptA == theLine.point[0] && aDIt->ptB == theLine.point[1]) ||
206 ////            (aDIt->ptA == theLine.point[1] && aDIt->ptB == theLine.point[0]))
207 ////          return;
208 ////      // Calculate distance between points on the line
209 ////      double aCoords[4];
210 ////      for (int i = 0; i < 2; i++) {
211 ////        Slvs_Entity aPnt = myStorage->getEntity(theLine.point[i]);
212 ////        for (int j = 0; j < 2; j++) {
213 ////          Slvs_Param aParam = myStorage->getParameter(aPnt.param[j]);
214 ////          aCoords[2*i+j] = aParam.val;
215 ////        }
216 ////      }
217 ////      double aLength = sqrt((aCoords[2] - aCoords[0]) * (aCoords[2] - aCoords[0]) + 
218 ////                            (aCoords[3] - aCoords[1]) * (aCoords[3] - aCoords[1]));
219 ////      // fix line length
220 ////      Slvs_Constraint aDistance = Slvs_MakeConstraint(SLVS_E_UNKNOWN, myGroup->getId(),
221 ////          SLVS_C_PT_PT_DISTANCE, myGroup->getWorkplaneId(), aLength,
222 ////          theLine.point[0], theLine.point[1], SLVS_E_UNKNOWN, SLVS_E_UNKNOWN);
223 ////      aDistance.h = myStorage->addConstraint(aDistance);
224 ////      mySlvsConstraints.push_back(aDistance.h);
225 ////    }
226 ////    return;
227 ////  }
228 ////  else if (myStorage->isUsedInEqual(theLine.h, anEqual)) {
229 ////    // Check another entity of Equal is already fixed
230 ////    Slvs_hEntity anOtherEntID = anEqual.entityA == theLine.h ? anEqual.entityB : anEqual.entityA;
231 ////    if (myStorage->isEntityFixed(anOtherEntID, true)) {
232 ////      // Fix start point of the line (if end point is not fixed yet) ...
233 ////      Slvs_hConstraint anEndFixedID = SLVS_E_UNKNOWN;
234 ////      bool isFixed = myStorage->isPointFixed(theLine.point[1], anEndFixedID, true);
235 ////      if (isFixed == SLVS_E_UNKNOWN)
236 ////        fixPoint(theLine.point[0]);
237 ////      // ...  and create fixed point lying on this line
238 ////      Slvs_hEntity aPointToCopy = anEndFixedID == SLVS_E_UNKNOWN ? theLine.point[1] : theLine.point[0];
239 ////      // Firstly, search already fixed point on line
240 ////      bool isPonLineFixed = false;
241 ////      Slvs_hEntity aFixedPoint;
242 ////      std::list<Slvs_Constraint> aPonLineList = myStorage->getConstraintsByType(SLVS_C_PT_ON_LINE);
243 ////      std::list<Slvs_Constraint>::const_iterator aPLIter = aPonLineList.begin();
244 ////      for (; aPLIter != aPonLineList.end() && !isPonLineFixed; aPLIter++)
245 ////        if (aPLIter->entityA == theLine.h) {
246 ////          isPonLineFixed = myStorage->isPointFixed(aPLIter->ptA, anEndFixedID);
247 ////          aFixedPoint = aPLIter->ptA;
248 ////        }
249 ////
250 ////      if (isPonLineFixed) { // update existent constraint
251 ////        myStorage->copyEntity(aPointToCopy, aFixedPoint);
252 ////      } else { // create new constraint
253 ////        Slvs_hEntity aCopied = myStorage->copyEntity(aPointToCopy);
254 ////        Slvs_Constraint aPonLine = Slvs_MakeConstraint(SLVS_E_UNKNOWN, myGroup->getId(), SLVS_C_PT_ON_LINE,
255 ////            myGroup->getWorkplaneId(), 0.0, aCopied, SLVS_E_UNKNOWN, theLine.h, SLVS_E_UNKNOWN);
256 ////        aPonLine.h = myStorage->addConstraint(aPonLine);
257 ////        mySlvsConstraints.push_back(aPonLine.h);
258 ////        fixPoint(aCopied);
259 ////      }
260 ////      return;
261 ////    }
262 ////  }
263 ////
264 ////  for (int i = 0; i < 2; i++)
265 ////    fixPoint(theLine.point[i]);
266 ////}
267 ////
268 ////void SketchSolver_ConstraintFixed::fixCircle(const Slvs_Entity& theCircle)
269 ////{
270 ////  bool isFixRadius = true;
271 ////  // Verify the arc is under Equal constraint
272 ////  Slvs_Constraint anEqual;
273 ////  if (myStorage->isUsedInEqual(theCircle.h, anEqual)) {
274 ////    // Check another entity of Equal is already fixed
275 ////    Slvs_hEntity anOtherEntID = anEqual.entityA == theCircle.h ? anEqual.entityB : anEqual.entityA;
276 ////    if (myStorage->isEntityFixed(anOtherEntID, true))
277 ////      isFixRadius = false;
278 ////  }
279 ////
280 ////  fixPoint(theCircle.point[0]);
281 ////
282 ////  if (isFixRadius) {
283 ////    // Search the radius is already fixed
284 ////    std::list<Slvs_Constraint> aDiamConstr = myStorage->getConstraintsByType(SLVS_C_DIAMETER);
285 ////    std::list<Slvs_Constraint>::const_iterator aDiamIter = aDiamConstr.begin();
286 ////    for (; aDiamIter != aDiamConstr.end(); aDiamIter++)
287 ////      if (aDiamIter->entityA == theCircle.h)
288 ////        return;
289 ////
290 ////    // Fix radius of a circle
291 ////    AttributeDoublePtr aRadiusAttr = std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(
292 ////        myFeatureMap.begin()->first->attribute(SketchPlugin_Circle::RADIUS_ID()));
293 ////    Slvs_Constraint aFixedR = Slvs_MakeConstraint(SLVS_E_UNKNOWN, myGroup->getId(), SLVS_C_DIAMETER,
294 ////        myGroup->getWorkplaneId(), aRadiusAttr->value() * 2.0, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN,
295 ////        myFeatureMap.begin()->second, SLVS_E_UNKNOWN);
296 ////    aFixedR.h = myStorage->addConstraint(aFixedR);
297 ////    mySlvsConstraints.push_back(aFixedR.h);
298 ////  }
299 ////}
300 ////
301 ////void SketchSolver_ConstraintFixed::fixArc(const Slvs_Entity& theArc)
302 ////{
303 ////  bool isFixRadius = true;
304 ////  std::list<Slvs_hEntity> aPointsToFix;
305 ////  aPointsToFix.push_back(theArc.point[1]);
306 ////  aPointsToFix.push_back(theArc.point[2]);
307 ////
308 ////  // Verify the arc is under Equal constraint
309 ////  Slvs_Constraint anEqual;
310 ////  if (myStorage->isUsedInEqual(theArc.h, anEqual)) {
311 ////    // Check another entity of Equal is already fixed
312 ////    Slvs_hEntity anOtherEntID = anEqual.entityA == theArc.h ? anEqual.entityB : anEqual.entityA;
313 ////    if (myStorage->isEntityFixed(anOtherEntID, true)) {
314 ////      isFixRadius = false;
315 ////      Slvs_Entity anOtherEntity = myStorage->getEntity(anOtherEntID);
316 ////      if (anOtherEntity.type == SLVS_E_LINE_SEGMENT) {
317 ////        aPointsToFix.pop_back();
318 ////        aPointsToFix.push_back(theArc.point[0]);
319 ////      }
320 ////    }
321 ////  }
322 ////
323 ////  Slvs_hConstraint aConstrID;
324 ////  int aNbPointsToFix = 2; // number of fixed points for the arc
325 ////  if (myStorage->isPointFixed(theArc.point[0], aConstrID, true))
326 ////    aNbPointsToFix--;
327 ////
328 ////  // Radius of the arc
329 ////  FeaturePtr aFeature = myFeatureMap.begin()->first;
330 ////  std::shared_ptr<GeomAPI_Pnt2d> aCenter = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
331 ////    aFeature->attribute(SketchPlugin_Arc::CENTER_ID()))->pnt();
332 ////  std::shared_ptr<GeomAPI_Pnt2d> aStart = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
333 ////    aFeature->attribute(SketchPlugin_Arc::START_ID()))->pnt();
334 ////  double aRadius = aCenter->distance(aStart);
335 ////
336 ////  // Update end point of the arc to be on a curve
337 ////  std::shared_ptr<GeomAPI_Pnt2d> anEnd = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
338 ////    aFeature->attribute(SketchPlugin_Arc::END_ID()))->pnt();
339 ////  double aDistance = anEnd->distance(aCenter);
340 ////  std::shared_ptr<GeomAPI_XY> aDir = anEnd->xy()->decreased(aCenter->xy());
341 ////  if (aDistance < tolerance)
342 ////    aDir = aStart->xy()->decreased(aCenter->xy())->multiplied(-1.0);
343 ////  else
344 ////    aDir = aDir->multiplied(aRadius / aDistance);
345 ////  double xy[2] = {aCenter->x() + aDir->x(), aCenter->y() + aDir->y()};
346 ////  Slvs_Entity aEndPoint = myStorage->getEntity(theArc.point[2]);
347 ////  for (int i = 0; i < 2; i++) {
348 ////    Slvs_Param aParam = myStorage->getParameter(aEndPoint.param[i]);
349 ////    aParam.val = xy[i];
350 ////    myStorage->updateParameter(aParam);
351 ////  }
352 ////
353 ////  std::list<Slvs_hEntity>::iterator aPtIt = aPointsToFix.begin();
354 ////  for (; aNbPointsToFix > 0; aPtIt++, aNbPointsToFix--)
355 ////    fixPoint(*aPtIt);
356 ////
357 ////  if (isFixRadius) {
358 ////    // Fix radius of the arc
359 ////    bool isExists = false;
360 ////    std::list<Slvs_Constraint> aDiamConstraints = myStorage->getConstraintsByType(SLVS_C_DIAMETER);
361 ////    std::list<Slvs_Constraint>::iterator anIt = aDiamConstraints.begin();
362 ////    for (; anIt != aDiamConstraints.end() && !isExists; anIt++)
363 ////      if (anIt->entityA == theArc.h)
364 ////        isExists = true;
365 ////    if (!isExists) {
366 ////      Slvs_Constraint aFixedR = Slvs_MakeConstraint(SLVS_E_UNKNOWN, myGroup->getId(), SLVS_C_DIAMETER,
367 ////          myGroup->getWorkplaneId(), aRadius * 2.0, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN,
368 ////          myFeatureMap.begin()->second, SLVS_E_UNKNOWN);
369 ////      aFixedR.h = myStorage->addConstraint(aFixedR);
370 ////      mySlvsConstraints.push_back(aFixedR.h);
371 ////      if (!myBaseConstraint)
372 ////        myStorage->addConstraintWhereDragged(aFixedR.h);
373 ////    }
374 ////  }
375 ////}