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