Salome HOME
Issue #2063 crash during trim: it was corrected with #2065 issue, TestTrimLine02...
[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   AttributePtr aCenterAttr = myBaseConstraint->attribute(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
45 void SketchSolver_ConstraintMultiRotation::process()
46 {
47   cleanErrorMsg();
48   if (!myBaseConstraint || !myStorage) {
49     // Not enough parameters are assigned
50     return;
51   }
52
53   EntityWrapperPtr anAngle;
54   EntityWrapperPtr aRotationCenter;
55   bool isFullValue;
56   std::list<EntityWrapperPtr> aBaseEntities;
57   getAttributes(aRotationCenter, anAngle, isFullValue, aBaseEntities);
58   if (!myErrorMsg.empty())
59     return;
60
61   ScalarWrapperPtr anAngleVal = std::dynamic_pointer_cast<PlaneGCSSolver_ScalarWrapper>(anAngle);
62   myAngle = anAngleVal->value();
63   myAdjusted = false;
64   adjustConstraint();
65
66   myStorage->subscribeUpdates(this, PlaneGCSSolver_UpdateFeature::GROUP());
67 }
68
69 void SketchSolver_ConstraintMultiRotation::updateLocal()
70 {
71   double aValue = myBaseConstraint->real(SketchPlugin_MultiRotation::ANGLE_ID())->value();
72   if (fabs(myAngle - aValue) > tolerance)
73     myAdjusted = false;
74   // update angle value
75   myAngle = aValue;
76
77   // update center
78   DataPtr aData = myBaseConstraint->data();
79   AttributePoint2DPtr aCenterPointAttribute = GeomDataAPI_Point2D::getPoint2D(aData,
80                                            SketchPlugin_MultiRotation::CENTER_ID());
81   bool aCenterPointChanged = aCenterPointAttribute != myCenterPointAttribute;
82   if (aCenterPointChanged)
83     myCenterPointAttribute = aCenterPointAttribute;
84
85   AttributeStringPtr aMethodTypeAttr = aData->string(SketchPlugin_MultiRotation::ANGLE_TYPE());
86   bool aFullValue = aMethodTypeAttr->value() != "SingleAngle";
87   bool isMethodChanged = aFullValue != myIsFullValue;
88   if (isMethodChanged)
89     myIsFullValue = aFullValue;
90
91   if (aCenterPointChanged || isMethodChanged)
92     myAdjusted = false;
93 }
94
95 void SketchSolver_ConstraintMultiRotation::adjustConstraint()
96 {
97   if (myAdjusted)
98     return;
99
100   if (fabs(myAngle) < tolerance) {
101     myStorage->setNeedToResolve(false);
102     return;
103   }
104
105   // Obtain coordinates of rotation center
106   std::shared_ptr<PlaneGCSSolver_PointWrapper> aRotCenter =
107       std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(myStorage->entity(
108       myBaseConstraint->attribute(SketchPlugin_MultiRotation::CENTER_ID())));
109   GCSPointPtr aCenterPoint = aRotCenter->point();
110   myCenterCoord[0] = *(aCenterPoint->x);
111   myCenterCoord[1] = *(aCenterPoint->y);
112
113   double anAngleValue = myAngle;
114   if (myIsFullValue && myNumberOfCopies > 0)
115     anAngleValue /= myNumberOfCopies;
116
117   myRotationVal[0] = sin(anAngleValue * PI / 180.0);
118   myRotationVal[1] = cos(anAngleValue * PI / 180.0);
119
120   SketchSolver_ConstraintMulti::adjustConstraint();
121 }
122
123 void SketchSolver_ConstraintMultiRotation::getRelative(
124     double theAbsX, double theAbsY, double& theRelX, double& theRelY)
125 {
126   theRelX = theAbsX - myCenterCoord[0];
127   theRelY = theAbsY - myCenterCoord[1];
128 }
129
130 void SketchSolver_ConstraintMultiRotation::getAbsolute(
131     double theRelX, double theRelY, double& theAbsX, double& theAbsY)
132 {
133   theAbsX = theRelX + myCenterCoord[0];
134   theAbsY = theRelY + myCenterCoord[1];
135 }
136
137 void SketchSolver_ConstraintMultiRotation::transformRelative(double& theX, double& theY)
138 {
139   // rotate direction
140   // myRotationVal[0] = sinA, myRotationVal[1] = cosA
141   double aTemp = theX * myRotationVal[1] - theY * myRotationVal[0];
142   theY = theX * myRotationVal[0] + theY * myRotationVal[1];
143   theX = aTemp;
144 }
145
146 const std::string& SketchSolver_ConstraintMultiRotation::nameNbObjects()
147 {
148   return SketchPlugin_MultiRotation::NUMBER_OF_OBJECTS_ID();
149 }