Salome HOME
There is implemented fixed constraint for the points which coordinates are given...
[modules/shaper.git] / src / SketchSolver / SketchSolver_ConstraintParametric.cpp
1 #include <SketchSolver_ConstraintParametric.h>
2 #include <SketchSolver_Error.h>
3 #include <SketchSolver_Group.h>
4
5 #include <GeomDataAPI_Point2D.h>
6
7 SketchSolver_ConstraintParametric::SketchSolver_ConstraintParametric(AttributePtr theAttribute)
8   : SketchSolver_ConstraintRigid(ConstraintPtr()),
9     myBaseAttribute(theAttribute)
10 {
11   process();
12 }
13
14 void SketchSolver_ConstraintParametric::process()
15 {
16   cleanErrorMsg();
17   if (!myBaseAttribute || !myStorage || myGroup == 0) {
18     /// TODO: Put error message here
19     return;
20   }
21   if (!mySlvsConstraints.empty()) // some data is changed, update constraint
22     update(myBaseConstraint);
23
24   Slvs_hEntity anAttrID;
25   getAttributes(anAttrID);
26   if (!myErrorMsg.empty() || (myFeatureMap.empty() && myAttributeMap.empty()))
27     return;
28
29   myHorizLineID = SLVS_E_UNKNOWN;
30   myVertLineID = SLVS_E_UNKNOWN;
31
32   std::shared_ptr<GeomDataAPI_Point2D> aPoint =
33       std::dynamic_pointer_cast<GeomDataAPI_Point2D>(myBaseAttribute);
34   if (!aPoint)
35     return;
36   if (!aPoint->textX().empty()) {
37     // Create vertical line with fixed boundary point
38     Slvs_Param aParX = Slvs_MakeParam(SLVS_E_UNKNOWN, myGroup->getId(), aPoint->x());
39     Slvs_Param aParY = Slvs_MakeParam(SLVS_E_UNKNOWN, myGroup->getId(), -10000.0);
40     aParX.h = myStorage->addParameter(aParX);
41     aParY.h = myStorage->addParameter(aParY);
42     Slvs_Entity aStartPoint = Slvs_MakePoint2d(SLVS_E_UNKNOWN, myGroup->getId(),
43         myGroup->getWorkplaneId(), aParX.h, aParY.h);
44     aStartPoint.h = myStorage->addEntity(aStartPoint);
45     Slvs_Entity aLine = Slvs_MakeLineSegment(SLVS_E_UNKNOWN, myGroup->getId(),
46         myGroup->getWorkplaneId(), aStartPoint.h, anAttrID);
47     aLine.h = myStorage->addEntity(aLine);
48
49     // Fix start point
50     fixPoint(aStartPoint.h);
51     // Add vertical constraint
52     Slvs_Constraint aConstraint = Slvs_MakeConstraint(SLVS_C_UNKNOWN, myGroup->getId(),
53         SLVS_C_VERTICAL, myGroup->getWorkplaneId(), 0.0, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN,
54         aLine.h, SLVS_E_UNKNOWN);
55     aConstraint.h = myStorage->addConstraint(aConstraint);
56     mySlvsConstraints.push_back(aConstraint.h);
57     myVertLineID = aLine.h;
58     myX = aPoint->x();
59   }
60   if (!aPoint->textY().empty()) {
61     // Create horizontal line with fixed boundary point
62     Slvs_Param aParX = Slvs_MakeParam(SLVS_E_UNKNOWN, myGroup->getId(), -10000.0);
63     Slvs_Param aParY = Slvs_MakeParam(SLVS_E_UNKNOWN, myGroup->getId(), aPoint->y());
64     aParX.h = myStorage->addParameter(aParX);
65     aParY.h = myStorage->addParameter(aParY);
66     Slvs_Entity aStartPoint = Slvs_MakePoint2d(SLVS_E_UNKNOWN, myGroup->getId(),
67         myGroup->getWorkplaneId(), aParX.h, aParY.h);
68     aStartPoint.h = myStorage->addEntity(aStartPoint);
69     Slvs_Entity aLine = Slvs_MakeLineSegment(SLVS_E_UNKNOWN, myGroup->getId(),
70         myGroup->getWorkplaneId(), aStartPoint.h, anAttrID);
71     aLine.h = myStorage->addEntity(aLine);
72
73     // Fix start point
74     fixPoint(aStartPoint.h);
75     // Add horizontal constraint
76     Slvs_Constraint aConstraint = Slvs_MakeConstraint(SLVS_C_UNKNOWN, myGroup->getId(),
77         SLVS_C_HORIZONTAL, myGroup->getWorkplaneId(), 0.0, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN,
78         aLine.h, SLVS_E_UNKNOWN);
79     aConstraint.h = myStorage->addConstraint(aConstraint);
80     mySlvsConstraints.push_back(aConstraint.h);
81     myHorizLineID = aLine.h;
82     myY = aPoint->y();
83   }
84 }
85
86
87 void SketchSolver_ConstraintParametric::getAttributes(Slvs_hEntity& theAttributeID)
88 {
89   int aType = SLVS_E_UNKNOWN; // type of created entity
90   theAttributeID = SLVS_E_UNKNOWN;
91   theAttributeID = myGroup->getAttributeId(myBaseAttribute);
92   if (theAttributeID == SLVS_E_UNKNOWN) {
93     theAttributeID = changeEntity(myBaseAttribute, aType);
94     if (theAttributeID == SLVS_E_UNKNOWN) {
95       myErrorMsg = SketchSolver_Error::NOT_INITIALIZED();
96       return;
97     }
98   }
99   else
100      myAttributeMap[myBaseAttribute] = theAttributeID;
101 }
102
103
104 void SketchSolver_ConstraintParametric::update(ConstraintPtr theConstraint)
105 {
106   cleanErrorMsg();
107   if (!theConstraint || theConstraint == myBaseConstraint) {
108     std::shared_ptr<GeomDataAPI_Point2D> aPoint =
109         std::dynamic_pointer_cast<GeomDataAPI_Point2D>(myBaseAttribute);
110     if (aPoint && ((!aPoint->textX().empty() && myVertLineID != SLVS_E_UNKNOWN) || 
111         (!aPoint->textY().empty() && myHorizLineID != SLVS_E_UNKNOWN))) {
112       remove();
113       process();
114       return;
115     }
116   }
117   adjustConstraint();
118 }
119
120 void SketchSolver_ConstraintParametric::refresh()
121 {
122   Slvs_hEntity aBasePointID = myAttributeMap[myBaseAttribute];
123   const Slvs_Entity& aBasePoint = myStorage->getEntity(aBasePointID);
124   double aXY[2];
125   aXY[0] = myVertLineID  != SLVS_E_UNKNOWN ? myX : myStorage->getParameter(aBasePoint.param[0]).val;
126   aXY[1] = myHorizLineID != SLVS_E_UNKNOWN ? myY : myStorage->getParameter(aBasePoint.param[1]).val;
127
128   std::list<Slvs_Constraint> aCoincidence = myStorage->getConstraintsByType(SLVS_C_POINTS_COINCIDENT);
129   std::list<Slvs_Constraint>::const_iterator aCIt = aCoincidence.begin();
130   for (; aCIt != aCoincidence.end(); ++aCIt) {
131     if (aCIt->ptA != aBasePointID && aCIt->ptB != aBasePointID)
132       continue;
133     Slvs_hEntity anOtherPointID = aCIt->ptA == aBasePointID ? aCIt->ptB : aCIt->ptA;
134     const Slvs_Entity& aPoint = myStorage->getEntity(anOtherPointID);
135     for (int i = 0; i < 2; i++) {
136       Slvs_Param aParam = myStorage->getParameter(aPoint.param[i]);
137       aParam.val = aXY[i];
138       myStorage->updateParameter(aParam);
139     }
140   }
141 }
142
143 void SketchSolver_ConstraintParametric::adjustConstraint()
144 {
145   std::shared_ptr<GeomDataAPI_Point2D> aPoint =
146       std::dynamic_pointer_cast<GeomDataAPI_Point2D>(myBaseAttribute);
147   if (!aPoint)
148     return;
149
150   if (!aPoint->textX().empty()) {
151     const Slvs_Entity& aLine = myStorage->getEntity(myVertLineID);
152     const Slvs_Entity& aStartPoint = myStorage->getEntity(aLine.point[0]);
153     Slvs_Param aParX = myStorage->getParameter(aStartPoint.param[0]);
154     aParX.val = aPoint->x();
155     myStorage->updateParameter(aParX);
156     myX = aParX.val;
157   }
158   if (!aPoint->textY().empty()) {
159     const Slvs_Entity& aLine = myStorage->getEntity(myHorizLineID);
160     const Slvs_Entity& aStartPoint = myStorage->getEntity(aLine.point[0]);
161     Slvs_Param aParY = myStorage->getParameter(aStartPoint.param[1]);
162     aParY.val = aPoint->y();
163     myStorage->updateParameter(aParY);
164     myY = aParY.val;
165   }
166 }