Salome HOME
Revert "First phase of SketchSolver refactoring"
[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_Entity aLine = createLine(aPoint->x(), -100.0, aPoint->x(), 100.0);
39     // Place point on line
40     Slvs_Constraint aConstraint = Slvs_MakeConstraint(SLVS_C_UNKNOWN, myGroup->getId(),
41         SLVS_C_PT_ON_LINE, myGroup->getWorkplaneId(), 0.0, anAttrID, SLVS_E_UNKNOWN,
42         aLine.h, SLVS_E_UNKNOWN);
43     aConstraint.h = myStorage->addConstraint(aConstraint);
44     mySlvsConstraints.push_back(aConstraint.h);
45     myVertLineID = aLine.h;
46     myX = aPoint->x();
47   }
48   if (!aPoint->textY().empty()) {
49     // Create horizontal line with fixed boundary points
50     Slvs_Entity aLine = createLine(-100.0, aPoint->y(), 100.0, aPoint->y());
51     // Place point on line
52     Slvs_Constraint aConstraint = Slvs_MakeConstraint(SLVS_C_UNKNOWN, myGroup->getId(),
53         SLVS_C_PT_ON_LINE, myGroup->getWorkplaneId(), 0.0, anAttrID, SLVS_E_UNKNOWN,
54         aLine.h, SLVS_E_UNKNOWN);
55     aConstraint.h = myStorage->addConstraint(aConstraint);
56     mySlvsConstraints.push_back(aConstraint.h);
57     myHorizLineID = aLine.h;
58     myY = aPoint->y();
59   }
60 }
61
62
63 void SketchSolver_ConstraintParametric::getAttributes(Slvs_hEntity& theAttributeID)
64 {
65   int aType = SLVS_E_UNKNOWN; // type of created entity
66   theAttributeID = SLVS_E_UNKNOWN;
67   theAttributeID = myGroup->getAttributeId(myBaseAttribute);
68   if (theAttributeID == SLVS_E_UNKNOWN) {
69     theAttributeID = changeEntity(myBaseAttribute, aType);
70     if (theAttributeID == SLVS_E_UNKNOWN) {
71       myErrorMsg = SketchSolver_Error::NOT_INITIALIZED();
72       return;
73     }
74   }
75   else
76      myAttributeMap[myBaseAttribute] = theAttributeID;
77 }
78
79
80 void SketchSolver_ConstraintParametric::update(ConstraintPtr theConstraint)
81 {
82   cleanErrorMsg();
83   if (!theConstraint || theConstraint == myBaseConstraint) {
84     std::shared_ptr<GeomDataAPI_Point2D> aPoint =
85         std::dynamic_pointer_cast<GeomDataAPI_Point2D>(myBaseAttribute);
86     if (aPoint && ((!aPoint->textX().empty() && myVertLineID == SLVS_E_UNKNOWN) || 
87         (!aPoint->textY().empty() && myHorizLineID == SLVS_E_UNKNOWN))) {
88       remove();
89       process();
90       return;
91     }
92   }
93   adjustConstraint();
94 }
95
96 void SketchSolver_ConstraintParametric::refresh()
97 {
98   Slvs_hEntity aBasePointID = myAttributeMap[myBaseAttribute];
99   const Slvs_Entity& aBasePoint = myStorage->getEntity(aBasePointID);
100   double aXY[2];
101   aXY[0] = myVertLineID  != SLVS_E_UNKNOWN ? myX : myStorage->getParameter(aBasePoint.param[0]).val;
102   aXY[1] = myHorizLineID != SLVS_E_UNKNOWN ? myY : myStorage->getParameter(aBasePoint.param[1]).val;
103
104   std::list<Slvs_Constraint> aCoincidence = myStorage->getConstraintsByType(SLVS_C_POINTS_COINCIDENT);
105   std::list<Slvs_Constraint>::const_iterator aCIt = aCoincidence.begin();
106   for (; aCIt != aCoincidence.end(); ++aCIt) {
107     if (aCIt->ptA != aBasePointID && aCIt->ptB != aBasePointID)
108       continue;
109     Slvs_hEntity anOtherPointID = aCIt->ptA == aBasePointID ? aCIt->ptB : aCIt->ptA;
110     const Slvs_Entity& aPoint = myStorage->getEntity(anOtherPointID);
111     for (int i = 0; i < 2; i++) {
112       Slvs_Param aParam = myStorage->getParameter(aPoint.param[i]);
113       aParam.val = aXY[i];
114       myStorage->updateParameter(aParam);
115     }
116   }
117 }
118
119 void SketchSolver_ConstraintParametric::adjustConstraint()
120 {
121   std::shared_ptr<GeomDataAPI_Point2D> aPoint =
122       std::dynamic_pointer_cast<GeomDataAPI_Point2D>(myBaseAttribute);
123   if (!aPoint)
124     return;
125
126   if (!aPoint->textX().empty()) {
127     const Slvs_Entity& aLine = myStorage->getEntity(myVertLineID);
128     const Slvs_Entity& aStartPoint = myStorage->getEntity(aLine.point[0]);
129     Slvs_Param aParX = myStorage->getParameter(aStartPoint.param[0]);
130     aParX.val = aPoint->x();
131     myStorage->updateParameter(aParX);
132     myX = aParX.val;
133   }
134   if (!aPoint->textY().empty()) {
135     const Slvs_Entity& aLine = myStorage->getEntity(myHorizLineID);
136     const Slvs_Entity& aStartPoint = myStorage->getEntity(aLine.point[0]);
137     Slvs_Param aParY = myStorage->getParameter(aStartPoint.param[1]);
138     aParY.val = aPoint->y();
139     myStorage->updateParameter(aParY);
140     myY = aParY.val;
141   }
142 }
143
144
145 Slvs_Entity SketchSolver_ConstraintParametric::createLine(
146     double theStartX, double theStartY, double theEndX, double theEndY)
147 {
148   // Start point
149   Slvs_Param aParX = Slvs_MakeParam(SLVS_E_UNKNOWN, SLVS_G_OUTOFGROUP, theStartX);
150   Slvs_Param aParY = Slvs_MakeParam(SLVS_E_UNKNOWN, SLVS_G_OUTOFGROUP, theStartY);
151   aParX.h = myStorage->addParameter(aParX);
152   aParY.h = myStorage->addParameter(aParY);
153   Slvs_Entity aStartPoint = Slvs_MakePoint2d(SLVS_E_UNKNOWN, SLVS_G_OUTOFGROUP,
154     myGroup->getWorkplaneId(), aParX.h, aParY.h);
155   aStartPoint.h = myStorage->addEntity(aStartPoint);
156
157   // End point
158   aParX = Slvs_MakeParam(SLVS_E_UNKNOWN, SLVS_G_OUTOFGROUP, theEndX);
159   aParY = Slvs_MakeParam(SLVS_E_UNKNOWN, SLVS_G_OUTOFGROUP, theEndY);
160   aParX.h = myStorage->addParameter(aParX);
161   aParY.h = myStorage->addParameter(aParY);
162   Slvs_Entity aEndPoint = Slvs_MakePoint2d(SLVS_E_UNKNOWN, SLVS_G_OUTOFGROUP,
163     myGroup->getWorkplaneId(), aParX.h, aParY.h);
164   aEndPoint.h = myStorage->addEntity(aEndPoint);
165
166   // Line
167   Slvs_Entity aLine = Slvs_MakeLineSegment(SLVS_E_UNKNOWN, SLVS_G_OUTOFGROUP,
168     myGroup->getWorkplaneId(), aStartPoint.h, aEndPoint.h);
169   aLine.h = myStorage->addEntity(aLine);
170   return aLine;
171 }