]> SALOME platform Git repositories - modules/shaper.git/blob - src/SketchSolver/SketchSolver_ConstraintFixed.cpp
Salome HOME
First phase of SketchSolver refactoring
[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     AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
123         myBaseConstraint->attribute(SketchPlugin_ConstraintRigid::ENTITY_A()));
124     if (!aRefAttr || !aRefAttr->isInitialized()) {
125       myErrorMsg = SketchSolver_Error::NOT_INITIALIZED();
126       return;
127     }
128
129     myStorage->update(aRefAttr, myGroupID);
130     aSolverEntity = myStorage->entity(aRefAttr);
131   } else
132     myErrorMsg = SketchSolver_Error::NOT_INITIALIZED();
133
134   if (aSolverEntity)
135     theAttributes.push_back(aSolverEntity);
136 }
137
138
139 bool SketchSolver_ConstraintFixed::remove()
140 {
141   cleanErrorMsg();
142   // Move fixed entities back to the current group
143   FeaturePtr aFeature = myBaseFeature;
144   if (myBaseConstraint && myFixedAttribute && myFixedAttribute->isObject())
145     aFeature = ModelAPI_Feature::feature(myFixedAttribute->object());
146   if (aFeature)
147     myStorage->update(aFeature, myGroupID);
148
149   // Remove constraint or base feature
150   if (myBaseConstraint) {
151     bool isRemoved = false;
152     if (aFeature)
153       isRemoved = myStorage->removeEntity(aFeature);
154     return SketchSolver_Constraint::remove() || isRemoved;
155   } else if (myBaseFeature)
156     myStorage->removeEntity(myBaseFeature);
157   return true;
158 }
159
160 ////Slvs_hConstraint SketchSolver_ConstraintFixed::fixPoint(const Slvs_hEntity& thePointID)
161 ////{
162 ////  if (thePointID == SLVS_E_UNKNOWN)
163 ////    return SLVS_C_UNKNOWN;
164 ////
165 ////  Slvs_Constraint aConstraint;
166 ////  Slvs_hConstraint aConstrID = SLVS_E_UNKNOWN;
167 ////  bool isFixed = myStorage->isPointFixed(thePointID, aConstrID, true);
168 ////  bool isForceUpdate = (isFixed && !myBaseConstraint &&
169 ////                        myStorage->isTemporary(aConstrID));
170 ////  if (!isForceUpdate) { // create new constraint
171 ////    if (isFixed) return aConstrID;
172 ////    aConstraint = Slvs_MakeConstraint(SLVS_C_UNKNOWN, myGroup->getId(), getType(), myGroup->getWorkplaneId(),
173 ////        0.0, thePointID, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN);
174 ////    aConstraint.h = myStorage->addConstraint(aConstraint);
175 ////    mySlvsConstraints.push_back(aConstraint.h);
176 ////    if (!myBaseConstraint)
177 ////      myStorage->addConstraintWhereDragged(aConstraint.h);
178 ////  } else { // update already existent constraint
179 ////    if (!isFixed || aConstrID == SLVS_C_UNKNOWN || myBaseConstraint)
180 ////      return SLVS_C_UNKNOWN;
181 ////    aConstraint = myStorage->getConstraint(aConstrID);
182 ////    aConstraint.ptA = thePointID;
183 ////    myStorage->addConstraint(aConstraint);
184 ////    if (!myBaseConstraint)
185 ////      myStorage->addConstraintWhereDragged(aConstraint.h);
186 ////  }
187 ////  return aConstraint.h;
188 ////}
189 ////
190 ////void SketchSolver_ConstraintFixed::fixLine(const Slvs_Entity& theLine)
191 ////{
192 ////  Slvs_Constraint anEqual;
193 ////  if (myStorage->isAxisParallel(theLine.h)) {
194 ////    // Fix one point and a line length
195 ////    Slvs_hConstraint aFixed;
196 ////    if (!myStorage->isPointFixed(theLine.point[0], aFixed, true) &&
197 ////        !myStorage->isPointFixed(theLine.point[1], aFixed, true))
198 ////      fixPoint(theLine.point[0]);
199 ////    if (!myStorage->isUsedInEqual(theLine.h, anEqual)) {
200 ////      // Check the distance is not set yet
201 ////      std::list<Slvs_Constraint> aDistConstr = myStorage->getConstraintsByType(SLVS_C_PT_PT_DISTANCE);
202 ////      std::list<Slvs_Constraint>::const_iterator aDIt = aDistConstr.begin();
203 ////      for (; aDIt != aDistConstr.end(); aDIt++)
204 ////        if ((aDIt->ptA == theLine.point[0] && aDIt->ptB == theLine.point[1]) ||
205 ////            (aDIt->ptA == theLine.point[1] && aDIt->ptB == theLine.point[0]))
206 ////          return;
207 ////      // Calculate distance between points on the line
208 ////      double aCoords[4];
209 ////      for (int i = 0; i < 2; i++) {
210 ////        Slvs_Entity aPnt = myStorage->getEntity(theLine.point[i]);
211 ////        for (int j = 0; j < 2; j++) {
212 ////          Slvs_Param aParam = myStorage->getParameter(aPnt.param[j]);
213 ////          aCoords[2*i+j] = aParam.val;
214 ////        }
215 ////      }
216 ////      double aLength = sqrt((aCoords[2] - aCoords[0]) * (aCoords[2] - aCoords[0]) + 
217 ////                            (aCoords[3] - aCoords[1]) * (aCoords[3] - aCoords[1]));
218 ////      // fix line length
219 ////      Slvs_Constraint aDistance = Slvs_MakeConstraint(SLVS_E_UNKNOWN, myGroup->getId(),
220 ////          SLVS_C_PT_PT_DISTANCE, myGroup->getWorkplaneId(), aLength,
221 ////          theLine.point[0], theLine.point[1], SLVS_E_UNKNOWN, SLVS_E_UNKNOWN);
222 ////      aDistance.h = myStorage->addConstraint(aDistance);
223 ////      mySlvsConstraints.push_back(aDistance.h);
224 ////    }
225 ////    return;
226 ////  }
227 ////  else if (myStorage->isUsedInEqual(theLine.h, anEqual)) {
228 ////    // Check another entity of Equal is already fixed
229 ////    Slvs_hEntity anOtherEntID = anEqual.entityA == theLine.h ? anEqual.entityB : anEqual.entityA;
230 ////    if (myStorage->isEntityFixed(anOtherEntID, true)) {
231 ////      // Fix start point of the line (if end point is not fixed yet) ...
232 ////      Slvs_hConstraint anEndFixedID = SLVS_E_UNKNOWN;
233 ////      bool isFixed = myStorage->isPointFixed(theLine.point[1], anEndFixedID, true);
234 ////      if (isFixed == SLVS_E_UNKNOWN)
235 ////        fixPoint(theLine.point[0]);
236 ////      // ...  and create fixed point lying on this line
237 ////      Slvs_hEntity aPointToCopy = anEndFixedID == SLVS_E_UNKNOWN ? theLine.point[1] : theLine.point[0];
238 ////      // Firstly, search already fixed point on line
239 ////      bool isPonLineFixed = false;
240 ////      Slvs_hEntity aFixedPoint;
241 ////      std::list<Slvs_Constraint> aPonLineList = myStorage->getConstraintsByType(SLVS_C_PT_ON_LINE);
242 ////      std::list<Slvs_Constraint>::const_iterator aPLIter = aPonLineList.begin();
243 ////      for (; aPLIter != aPonLineList.end() && !isPonLineFixed; aPLIter++)
244 ////        if (aPLIter->entityA == theLine.h) {
245 ////          isPonLineFixed = myStorage->isPointFixed(aPLIter->ptA, anEndFixedID);
246 ////          aFixedPoint = aPLIter->ptA;
247 ////        }
248 ////
249 ////      if (isPonLineFixed) { // update existent constraint
250 ////        myStorage->copyEntity(aPointToCopy, aFixedPoint);
251 ////      } else { // create new constraint
252 ////        Slvs_hEntity aCopied = myStorage->copyEntity(aPointToCopy);
253 ////        Slvs_Constraint aPonLine = Slvs_MakeConstraint(SLVS_E_UNKNOWN, myGroup->getId(), SLVS_C_PT_ON_LINE,
254 ////            myGroup->getWorkplaneId(), 0.0, aCopied, SLVS_E_UNKNOWN, theLine.h, SLVS_E_UNKNOWN);
255 ////        aPonLine.h = myStorage->addConstraint(aPonLine);
256 ////        mySlvsConstraints.push_back(aPonLine.h);
257 ////        fixPoint(aCopied);
258 ////      }
259 ////      return;
260 ////    }
261 ////  }
262 ////
263 ////  for (int i = 0; i < 2; i++)
264 ////    fixPoint(theLine.point[i]);
265 ////}
266 ////
267 ////void SketchSolver_ConstraintFixed::fixCircle(const Slvs_Entity& theCircle)
268 ////{
269 ////  bool isFixRadius = true;
270 ////  // Verify the arc is under Equal constraint
271 ////  Slvs_Constraint anEqual;
272 ////  if (myStorage->isUsedInEqual(theCircle.h, anEqual)) {
273 ////    // Check another entity of Equal is already fixed
274 ////    Slvs_hEntity anOtherEntID = anEqual.entityA == theCircle.h ? anEqual.entityB : anEqual.entityA;
275 ////    if (myStorage->isEntityFixed(anOtherEntID, true))
276 ////      isFixRadius = false;
277 ////  }
278 ////
279 ////  fixPoint(theCircle.point[0]);
280 ////
281 ////  if (isFixRadius) {
282 ////    // Search the radius is already fixed
283 ////    std::list<Slvs_Constraint> aDiamConstr = myStorage->getConstraintsByType(SLVS_C_DIAMETER);
284 ////    std::list<Slvs_Constraint>::const_iterator aDiamIter = aDiamConstr.begin();
285 ////    for (; aDiamIter != aDiamConstr.end(); aDiamIter++)
286 ////      if (aDiamIter->entityA == theCircle.h)
287 ////        return;
288 ////
289 ////    // Fix radius of a circle
290 ////    AttributeDoublePtr aRadiusAttr = std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(
291 ////        myFeatureMap.begin()->first->attribute(SketchPlugin_Circle::RADIUS_ID()));
292 ////    Slvs_Constraint aFixedR = Slvs_MakeConstraint(SLVS_E_UNKNOWN, myGroup->getId(), SLVS_C_DIAMETER,
293 ////        myGroup->getWorkplaneId(), aRadiusAttr->value() * 2.0, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN,
294 ////        myFeatureMap.begin()->second, SLVS_E_UNKNOWN);
295 ////    aFixedR.h = myStorage->addConstraint(aFixedR);
296 ////    mySlvsConstraints.push_back(aFixedR.h);
297 ////  }
298 ////}
299 ////
300 ////void SketchSolver_ConstraintFixed::fixArc(const Slvs_Entity& theArc)
301 ////{
302 ////  bool isFixRadius = true;
303 ////  std::list<Slvs_hEntity> aPointsToFix;
304 ////  aPointsToFix.push_back(theArc.point[1]);
305 ////  aPointsToFix.push_back(theArc.point[2]);
306 ////
307 ////  // Verify the arc is under Equal constraint
308 ////  Slvs_Constraint anEqual;
309 ////  if (myStorage->isUsedInEqual(theArc.h, anEqual)) {
310 ////    // Check another entity of Equal is already fixed
311 ////    Slvs_hEntity anOtherEntID = anEqual.entityA == theArc.h ? anEqual.entityB : anEqual.entityA;
312 ////    if (myStorage->isEntityFixed(anOtherEntID, true)) {
313 ////      isFixRadius = false;
314 ////      Slvs_Entity anOtherEntity = myStorage->getEntity(anOtherEntID);
315 ////      if (anOtherEntity.type == SLVS_E_LINE_SEGMENT) {
316 ////        aPointsToFix.pop_back();
317 ////        aPointsToFix.push_back(theArc.point[0]);
318 ////      }
319 ////    }
320 ////  }
321 ////
322 ////  Slvs_hConstraint aConstrID;
323 ////  int aNbPointsToFix = 2; // number of fixed points for the arc
324 ////  if (myStorage->isPointFixed(theArc.point[0], aConstrID, true))
325 ////    aNbPointsToFix--;
326 ////
327 ////  // Radius of the arc
328 ////  FeaturePtr aFeature = myFeatureMap.begin()->first;
329 ////  std::shared_ptr<GeomAPI_Pnt2d> aCenter = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
330 ////    aFeature->attribute(SketchPlugin_Arc::CENTER_ID()))->pnt();
331 ////  std::shared_ptr<GeomAPI_Pnt2d> aStart = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
332 ////    aFeature->attribute(SketchPlugin_Arc::START_ID()))->pnt();
333 ////  double aRadius = aCenter->distance(aStart);
334 ////
335 ////  // Update end point of the arc to be on a curve
336 ////  std::shared_ptr<GeomAPI_Pnt2d> anEnd = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
337 ////    aFeature->attribute(SketchPlugin_Arc::END_ID()))->pnt();
338 ////  double aDistance = anEnd->distance(aCenter);
339 ////  std::shared_ptr<GeomAPI_XY> aDir = anEnd->xy()->decreased(aCenter->xy());
340 ////  if (aDistance < tolerance)
341 ////    aDir = aStart->xy()->decreased(aCenter->xy())->multiplied(-1.0);
342 ////  else
343 ////    aDir = aDir->multiplied(aRadius / aDistance);
344 ////  double xy[2] = {aCenter->x() + aDir->x(), aCenter->y() + aDir->y()};
345 ////  Slvs_Entity aEndPoint = myStorage->getEntity(theArc.point[2]);
346 ////  for (int i = 0; i < 2; i++) {
347 ////    Slvs_Param aParam = myStorage->getParameter(aEndPoint.param[i]);
348 ////    aParam.val = xy[i];
349 ////    myStorage->updateParameter(aParam);
350 ////  }
351 ////
352 ////  std::list<Slvs_hEntity>::iterator aPtIt = aPointsToFix.begin();
353 ////  for (; aNbPointsToFix > 0; aPtIt++, aNbPointsToFix--)
354 ////    fixPoint(*aPtIt);
355 ////
356 ////  if (isFixRadius) {
357 ////    // Fix radius of the arc
358 ////    bool isExists = false;
359 ////    std::list<Slvs_Constraint> aDiamConstraints = myStorage->getConstraintsByType(SLVS_C_DIAMETER);
360 ////    std::list<Slvs_Constraint>::iterator anIt = aDiamConstraints.begin();
361 ////    for (; anIt != aDiamConstraints.end() && !isExists; anIt++)
362 ////      if (anIt->entityA == theArc.h)
363 ////        isExists = true;
364 ////    if (!isExists) {
365 ////      Slvs_Constraint aFixedR = Slvs_MakeConstraint(SLVS_E_UNKNOWN, myGroup->getId(), SLVS_C_DIAMETER,
366 ////          myGroup->getWorkplaneId(), aRadius * 2.0, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN,
367 ////          myFeatureMap.begin()->second, SLVS_E_UNKNOWN);
368 ////      aFixedR.h = myStorage->addConstraint(aFixedR);
369 ////      mySlvsConstraints.push_back(aFixedR.h);
370 ////      if (!myBaseConstraint)
371 ////        myStorage->addConstraintWhereDragged(aFixedR.h);
372 ////    }
373 ////  }
374 ////}