Salome HOME
Fix compilation error on Linux
[modules/shaper.git] / src / SketchSolver / SketchSolver_ConstraintMultiRotation.cpp
1 #include <SketchSolver_ConstraintMultiRotation.h>
2 #include <SketchSolver_Error.h>
3 #include <SketchSolver_Manager.h>
4
5 #include <SketchPlugin_MultiRotation.h>
6
7 #include <ModelAPI_AttributeString.h>
8
9 #include <math.h>
10
11 void SketchSolver_ConstraintMultiRotation::getAttributes(
12     EntityWrapperPtr& theCenter, double& theAngle,
13     bool& theFullValue, std::list<EntityWrapperPtr>& theEntities)
14 {
15   DataPtr aData = myBaseConstraint->data();
16   theAngle = std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(
17       aData->attribute(SketchPlugin_MultiRotation::ANGLE_ID()))->value();
18
19   AttributePtr aCenterAttr = aData->attribute(SketchPlugin_MultiRotation::CENTER_ID());
20   if (!aCenterAttr || !aCenterAttr->isInitialized()) {
21     myErrorMsg = SketchSolver_Error::NOT_INITIALIZED();
22     return;
23   }
24
25   myType = CONSTRAINT_MULTI_ROTATION;
26
27   myStorage->update(aCenterAttr);
28   theCenter = myStorage->entity(aCenterAttr);
29
30   AttributeStringPtr aMethodTypeAttr = aData->string(SketchPlugin_MultiRotation::ANGLE_TYPE());
31   theFullValue = aMethodTypeAttr->value() != "SingleAngle";
32
33   getEntities(theEntities);
34 }
35
36 void SketchSolver_ConstraintMultiRotation::process()
37 {
38   cleanErrorMsg();
39   if (!myBaseConstraint || !myStorage || myGroupID == GID_UNKNOWN) {
40     /// TODO: Put error message here
41     return;
42   }
43
44   EntityWrapperPtr aRotationCenter;
45   bool isFullValue;
46   std::list<EntityWrapperPtr> aBaseEntities;
47   getAttributes(aRotationCenter, myAngle, isFullValue, aBaseEntities);
48   if (!myErrorMsg.empty())
49     return;
50
51   BuilderPtr aBuilder = SketchSolver_Manager::instance()->builder();
52   std::list<ConstraintWrapperPtr> aRotConstraints;
53
54   std::list<EntityWrapperPtr>::iterator anEntIt = aBaseEntities.begin();
55   for (; anEntIt != aBaseEntities.end(); ++anEntIt) {
56     std::list<ConstraintWrapperPtr> aNewConstraints =
57         aBuilder->createConstraint(myBaseConstraint, myGroupID, mySketchID, myType,
58         myAngle, isFullValue, aRotationCenter, EntityWrapperPtr(), std::list<EntityWrapperPtr>(1, *anEntIt));
59     aRotConstraints.insert(aRotConstraints.end(), aNewConstraints.begin(), aNewConstraints.end());
60   }
61   myStorage->addConstraint(myBaseConstraint, aRotConstraints);
62
63   myAdjusted = false;
64   adjustConstraint();
65 }
66
67 void SketchSolver_ConstraintMultiRotation::updateLocal()
68 {
69   double aValue = std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(
70       myBaseConstraint->attribute(SketchPlugin_MultiRotation::ANGLE_ID()))->value();
71   if (fabs(myAngle - aValue) > tolerance)
72     myAdjusted = false;
73   // update angle value
74   myAngle = aValue;
75
76   // update center
77   DataPtr aData = myBaseConstraint->data();
78   AttributePoint2DPtr aCenterPointAttribute = GeomDataAPI_Point2D::getPoint2D(aData,
79                                            SketchPlugin_MultiRotation::CENTER_ID());
80   bool aCenterPointChanged = aCenterPointAttribute != myCenterPointAttribute;
81   if (aCenterPointChanged)
82     myCenterPointAttribute = aCenterPointAttribute;
83
84   AttributeStringPtr aMethodTypeAttr = aData->string(SketchPlugin_MultiRotation::ANGLE_TYPE());
85   bool aFullValue = aMethodTypeAttr->value() != "SingleAngle";
86   bool isMethodChanged = aFullValue != myIsFullValue;
87   if (isMethodChanged)
88     myIsFullValue = aFullValue;
89
90   if (aCenterPointChanged || isMethodChanged) {
91     DataPtr aData = myBaseConstraint->data();
92     std::list<ConstraintWrapperPtr> aConstraints = myStorage->constraint(myBaseConstraint);
93     std::list<ConstraintWrapperPtr>::const_iterator anIt = aConstraints.begin(),
94       aLast = aConstraints.end();
95     std::list<EntityWrapperPtr> anEntities;
96     for (; anIt != aLast; anIt++) {
97       ConstraintWrapperPtr aConstraint = *anIt;
98       aConstraint->setIsFullValue(myIsFullValue);
99       if (aCenterPointChanged) {
100         anEntities.clear();
101         const std::list<EntityWrapperPtr>& aConstraintEntities = aConstraint->entities();
102         std::list<EntityWrapperPtr>::const_iterator aSIt = aConstraintEntities.begin(),
103           aSLast = aConstraintEntities.end();
104         EntityWrapperPtr aCenterPointEntity = *aSIt++;
105         if (aCenterPointChanged) {
106           AttributePtr aCenterPointAttr = aData->attribute(SketchPlugin_MultiRotation::CENTER_ID());
107           myStorage->update(aCenterPointAttr);
108           aCenterPointEntity = myStorage->entity(aCenterPointAttr);
109         }
110         anEntities.push_back(aCenterPointEntity);
111
112         for (; aSIt != aSLast; ++aSIt)
113           anEntities.push_back(*aSIt);
114
115         aConstraint->setEntities(anEntities);
116       }
117     }
118     myStorage->addConstraint(myBaseConstraint, aConstraints);
119
120     myAdjusted = false;
121   }
122 }
123
124 void SketchSolver_ConstraintMultiRotation::adjustConstraint()
125 {
126   if (myAdjusted)
127     return;
128
129   if (fabs(myAngle) < tolerance) {
130     myStorage->setNeedToResolve(false);
131     return;
132   }
133
134   const std::list<ConstraintWrapperPtr>& aConstraints = myStorage->constraint(myBaseConstraint);
135   std::list<ConstraintWrapperPtr>::const_iterator aCIt = aConstraints.begin();
136   for (; aCIt != aConstraints.end(); ++aCIt)
137     (*aCIt)->setValue(myAngle);
138
139   // Obtain coordinates of rotation center
140   EntityWrapperPtr aRotCenter = myStorage->entity(
141       myBaseConstraint->attribute(SketchPlugin_MultiRotation::CENTER_ID()));
142   std::list<ParameterWrapperPtr> aParams = aRotCenter->parameters();
143   myCenterCoord[0] = aParams.front()->value();
144   myCenterCoord[1] = aParams.back()->value();
145
146   double anAngleValue = myAngle;
147   if (myIsFullValue && myNumberOfCopies > 0)
148     anAngleValue /= myNumberOfCopies;
149
150   myRotationVal[0] = sin(anAngleValue * PI / 180.0);
151   myRotationVal[1] = cos(anAngleValue * PI / 180.0);
152
153   SketchSolver_ConstraintMulti::adjustConstraint();
154 }
155
156 void SketchSolver_ConstraintMultiRotation::getRelative(
157     double theAbsX, double theAbsY, double& theRelX, double& theRelY)
158 {
159   theRelX = theAbsX - myCenterCoord[0];
160   theRelY = theAbsY - myCenterCoord[1];
161 }
162
163 void SketchSolver_ConstraintMultiRotation::getAbsolute(
164     double theRelX, double theRelY, double& theAbsX, double& theAbsY)
165 {
166   theAbsX = theRelX + myCenterCoord[0];
167   theAbsY = theRelY + myCenterCoord[1];
168 }
169
170 void SketchSolver_ConstraintMultiRotation::transformRelative(double& theX, double& theY)
171 {
172   // rotate direction
173   // myRotationVal[0] = sinA, myRotationVal[1] = cosA
174   double aTemp = theX * myRotationVal[1] - theY * myRotationVal[0];
175   theY = theX * myRotationVal[0] + theY * myRotationVal[1];
176   theX = aTemp;
177 }
178
179 const std::string& SketchSolver_ConstraintMultiRotation::nameNbObjects()
180 {
181   return SketchPlugin_MultiRotation::NUMBER_OF_OBJECTS_ID();
182 }