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