Salome HOME
3288c9830480d228ef7b87c0e68cea055707cd3a
[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 <PlaneGCSSolver_AttributeBuilder.h>
8 #include <PlaneGCSSolver_PointWrapper.h>
9 #include <PlaneGCSSolver_ScalarWrapper.h>
10 #include <PlaneGCSSolver_UpdateFeature.h>
11
12 #include <SketchPlugin_MultiRotation.h>
13
14 #include <ModelAPI_AttributeString.h>
15
16 #include <cmath>
17
18 void SketchSolver_ConstraintMultiRotation::getAttributes(
19     EntityWrapperPtr& theCenter, EntityWrapperPtr& theAngle,
20     bool& theFullValue, std::list<EntityWrapperPtr>& theEntities)
21 {
22   AttributePtr anAngleAttr = myBaseConstraint->attribute(SketchPlugin_MultiRotation::ANGLE_ID());
23   PlaneGCSSolver_AttributeBuilder aValueBuilder;
24   theAngle = aValueBuilder.createAttribute(anAngleAttr);
25   myStorage->addEntity(anAngleAttr, theAngle);
26
27   AttributeRefAttrPtr aCenterAttr =
28       myBaseConstraint->refattr(SketchPlugin_MultiRotation::CENTER_ID());
29   if (!aCenterAttr || !aCenterAttr->isInitialized()) {
30     myErrorMsg = SketchSolver_Error::NOT_INITIALIZED();
31     return;
32   }
33
34   myType = CONSTRAINT_MULTI_ROTATION;
35
36   myStorage->update(AttributePtr(aCenterAttr));
37   theCenter = myStorage->entity(AttributePtr(aCenterAttr));
38
39   AttributeStringPtr aMethodTypeAttr =
40       myBaseConstraint->string(SketchPlugin_MultiRotation::ANGLE_TYPE());
41   theFullValue = aMethodTypeAttr->value() != "SingleAngle";
42
43   getEntities(theEntities);
44
45   // add owner of central point of Multi-Rotation to the list of monitored features
46   FeaturePtr anOwner = ModelAPI_Feature::feature(aCenterAttr->attr()->owner());
47   if (anOwner)
48     myFeatures.insert(anOwner);
49 }
50
51 void SketchSolver_ConstraintMultiRotation::process()
52 {
53   cleanErrorMsg();
54   if (!myBaseConstraint || !myStorage) {
55     // Not enough parameters are assigned
56     return;
57   }
58
59   EntityWrapperPtr anAngle;
60   EntityWrapperPtr aRotationCenter;
61   bool isFullValue;
62   std::list<EntityWrapperPtr> aBaseEntities;
63   getAttributes(aRotationCenter, anAngle, isFullValue, aBaseEntities);
64   if (!myErrorMsg.empty())
65     return;
66
67   ScalarWrapperPtr anAngleVal = std::dynamic_pointer_cast<PlaneGCSSolver_ScalarWrapper>(anAngle);
68   myAngle = anAngleVal->value();
69   myAdjusted = false;
70   adjustConstraint();
71
72   myStorage->subscribeUpdates(this, PlaneGCSSolver_UpdateFeature::GROUP());
73 }
74
75 void SketchSolver_ConstraintMultiRotation::updateLocal()
76 {
77   double aValue = myBaseConstraint->real(SketchPlugin_MultiRotation::ANGLE_ID())->value();
78   if (fabs(myAngle - aValue) > tolerance)
79     myAdjusted = false;
80   // update angle value
81   myAngle = aValue;
82
83   // update center
84   DataPtr aData = myBaseConstraint->data();
85   AttributePoint2DPtr aCenterPointAttribute = GeomDataAPI_Point2D::getPoint2D(aData,
86                                            SketchPlugin_MultiRotation::CENTER_ID());
87   bool aCenterPointChanged = aCenterPointAttribute != myCenterPointAttribute;
88   if (aCenterPointChanged)
89     myCenterPointAttribute = aCenterPointAttribute;
90
91   AttributeStringPtr aMethodTypeAttr = aData->string(SketchPlugin_MultiRotation::ANGLE_TYPE());
92   bool aFullValue = aMethodTypeAttr->value() != "SingleAngle";
93   bool isMethodChanged = aFullValue != myIsFullValue;
94   if (isMethodChanged)
95     myIsFullValue = aFullValue;
96
97   if (aCenterPointChanged || isMethodChanged)
98     myAdjusted = false;
99 }
100
101 void SketchSolver_ConstraintMultiRotation::adjustConstraint()
102 {
103   if (myAdjusted)
104     return;
105
106   if (fabs(myAngle) < tolerance) {
107     myStorage->setNeedToResolve(false);
108     return;
109   }
110
111   // Obtain coordinates of rotation center
112   std::shared_ptr<PlaneGCSSolver_PointWrapper> aRotCenter =
113       std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(myStorage->entity(
114       myBaseConstraint->attribute(SketchPlugin_MultiRotation::CENTER_ID())));
115   GCSPointPtr aCenterPoint = aRotCenter->point();
116   myCenterCoord[0] = *(aCenterPoint->x);
117   myCenterCoord[1] = *(aCenterPoint->y);
118
119   double anAngleValue = myAngle;
120   if (myIsFullValue && myNumberOfCopies > 0)
121     anAngleValue /= myNumberOfCopies;
122
123   myRotationVal[0] = sin(anAngleValue * PI / 180.0);
124   myRotationVal[1] = cos(anAngleValue * PI / 180.0);
125
126   SketchSolver_ConstraintMulti::adjustConstraint();
127 }
128
129 void SketchSolver_ConstraintMultiRotation::getRelative(
130     double theAbsX, double theAbsY, double& theRelX, double& theRelY)
131 {
132   theRelX = theAbsX - myCenterCoord[0];
133   theRelY = theAbsY - myCenterCoord[1];
134 }
135
136 void SketchSolver_ConstraintMultiRotation::getAbsolute(
137     double theRelX, double theRelY, double& theAbsX, double& theAbsY)
138 {
139   theAbsX = theRelX + myCenterCoord[0];
140   theAbsY = theRelY + myCenterCoord[1];
141 }
142
143 void SketchSolver_ConstraintMultiRotation::transformRelative(double& theX, double& theY)
144 {
145   // rotate direction
146   // myRotationVal[0] = sinA, myRotationVal[1] = cosA
147   double aTemp = theX * myRotationVal[1] - theY * myRotationVal[0];
148   theY = theX * myRotationVal[0] + theY * myRotationVal[1];
149   theX = aTemp;
150 }
151
152 const std::string& SketchSolver_ConstraintMultiRotation::nameNbObjects()
153 {
154   return SketchPlugin_MultiRotation::NUMBER_OF_OBJECTS_ID();
155 }