Salome HOME
Attach second point of the Coincidence constraint to the first one.
[modules/shaper.git] / src / SketchSolver / SketchSolver_ConstraintMovement.cpp
1 #include <SketchSolver_ConstraintMovement.h>
2 #include <SketchSolver_Error.h>
3 #include <SketchSolver_Group.h>
4
5 SketchSolver_ConstraintMovement::SketchSolver_ConstraintMovement(FeaturePtr theFeature)
6   : SketchSolver_ConstraintRigid(theFeature)
7 {
8   process();
9 }
10
11 void SketchSolver_ConstraintMovement::process()
12 {
13   cleanErrorMsg();
14   if (!myBaseFeature || !myStorage || myGroup == 0) {
15     /// TODO: Put error message here
16     return;
17   }
18   if (!mySlvsConstraints.empty()) // some data is changed, update constraint
19     update(myBaseConstraint);
20
21   double aValue;
22   std::vector<Slvs_hEntity> anEntities;
23   bool isFullyMoved;
24   getAttributes(aValue, anEntities, isFullyMoved);
25   if (!myErrorMsg.empty() || (myFeatureMap.empty() && myAttributeMap.empty()))
26     return;
27
28   if (isFullyMoved)
29     fixFeature();
30   else {
31     std::vector<Slvs_hEntity>::iterator anEntIt = anEntities.begin();
32     for (; anEntIt != anEntities.end(); ++anEntIt)
33       fixPoint(*anEntIt);
34   }
35 }
36
37
38 void SketchSolver_ConstraintMovement::getAttributes(
39     double& theValue,
40     std::vector<Slvs_hEntity>& theAttributes,
41     bool& theIsFullyMoved)
42 {
43   bool isComplexFeature = false;
44   theValue = 0.0;
45   theIsFullyMoved = true;
46   int aType = SLVS_E_UNKNOWN; // type of created entity
47   Slvs_hEntity anEntityID = SLVS_E_UNKNOWN;
48   anEntityID = myGroup->getFeatureId(myBaseFeature);
49   if (anEntityID == SLVS_E_UNKNOWN) {
50     anEntityID = changeEntity(myBaseFeature, aType);
51     if (anEntityID == SLVS_E_UNKNOWN) {
52       myErrorMsg = SketchSolver_Error::NOT_INITIALIZED();
53       return;
54     }
55
56     // Check the entity is complex
57     Slvs_Entity anEntity = myStorage->getEntity(anEntityID);
58     if (anEntity.point[0] != SLVS_E_UNKNOWN)
59       isComplexFeature = true;
60     else // simple entity
61       theAttributes.push_back(anEntityID);
62   }
63   else {
64      myFeatureMap[myBaseFeature] = anEntityID;
65      isComplexFeature = true;
66   }
67
68   if (isComplexFeature) {
69      std::list<AttributePtr> aPoints =
70         myBaseFeature->data()->attributes(GeomDataAPI_Point2D::typeId());
71      std::list<AttributePtr>::iterator anIt = aPoints.begin();
72      for (; anIt != aPoints.end(); ++anIt) {
73        Slvs_hEntity anAttr = myGroup->getAttributeId(*anIt);
74
75        // Check the attribute changes coordinates
76        std::shared_ptr<GeomDataAPI_Point2D> aPt =
77           std::dynamic_pointer_cast<GeomDataAPI_Point2D>(*anIt);
78        if (isMoved(aPt, anAttr)) {
79          theAttributes.push_back(anAttr);
80          // update point coordinates
81          Slvs_Entity anAttrEnt = myStorage->getEntity(anAttr);
82          double aNewPos[2] = {aPt->x(), aPt->y()};
83          for (int i = 0; i < 2; i++) {
84            Slvs_Param aParam = myStorage->getParameter(anAttrEnt.param[i]);
85            aParam.val = aNewPos[i];
86            myStorage->updateParameter(aParam);
87          }
88        }
89        else
90          theIsFullyMoved = false;
91      }
92   }
93
94   // Leave only points which are used in constraints
95   if (myStorage->isUsedByConstraints(anEntityID))
96     return;
97   std::vector<Slvs_hEntity>::iterator anIt = theAttributes.begin();
98   while (anIt != theAttributes.end()) {
99     if (myStorage->isUsedByConstraints(*anIt))
100       ++anIt;
101     else {
102       int aShift = anIt - theAttributes.begin();
103       theAttributes.erase(anIt);
104       anIt = theAttributes.begin() + aShift;
105     }
106   }
107 }
108
109 bool SketchSolver_ConstraintMovement::isMoved(
110     std::shared_ptr<GeomDataAPI_Point2D> thePoint, Slvs_hEntity theEntity)
111 {
112   Slvs_Entity anAttrEnt = myStorage->getEntity(theEntity);
113   double aDeltaX = myStorage->getParameter(anAttrEnt.param[0]).val;
114   double aDeltaY = myStorage->getParameter(anAttrEnt.param[1]).val;
115   aDeltaX -= thePoint->x();
116   aDeltaY -= thePoint->y();
117   return aDeltaX * aDeltaX + aDeltaY * aDeltaY >= tolerance * tolerance;
118 }