]> SALOME platform Git repositories - modules/shaper.git/blob - src/SketchSolver/SketchSolver_ConstraintFixed.cpp
Salome HOME
Task 2.4. Ability to modify the radius of circles and arcs of circle with the mouse
[modules/shaper.git] / src / SketchSolver / SketchSolver_ConstraintFixed.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
2
3 #include <SketchSolver_ConstraintFixed.h>
4 #include <SketchSolver_Error.h>
5
6 #include <PlaneGCSSolver_ConstraintWrapper.h>
7 #include <PlaneGCSSolver_EdgeWrapper.h>
8 #include <PlaneGCSSolver_EntityDestroyer.h>
9 #include <PlaneGCSSolver_FeatureBuilder.h>
10 #include <PlaneGCSSolver_PointWrapper.h>
11
12 #include <GeomDataAPI_Point2D.h>
13 #include <SketchPlugin_Feature.h>
14
15 #include <cmath>
16
17 // Verify the entities are equal
18 static bool isEqual(const EntityWrapperPtr& theEntity1, const EntityWrapperPtr& theEntity2);
19
20
21 SketchSolver_ConstraintFixed::SketchSolver_ConstraintFixed(ConstraintPtr theConstraint)
22   : SketchSolver_Constraint(theConstraint)
23 {
24   myType = CONSTRAINT_FIXED;
25 }
26
27 #ifndef SUPPORT_NEW_MOVE
28 SketchSolver_ConstraintFixed::SketchSolver_ConstraintFixed(FeaturePtr theFeature)
29   : SketchSolver_Constraint(),
30     myBaseFeature(theFeature)
31 {
32   myType = CONSTRAINT_FIXED;
33 }
34 #endif
35
36 void SketchSolver_ConstraintFixed::blockEvents(bool isBlocked)
37 {
38 #ifndef SUPPORT_NEW_MOVE
39   if (myBaseFeature)
40     myBaseFeature->data()->blockSendAttributeUpdated(isBlocked);
41   if (myBaseConstraint)
42 #endif
43   SketchSolver_Constraint::blockEvents(isBlocked);
44 }
45
46 void SketchSolver_ConstraintFixed::process()
47 {
48   cleanErrorMsg();
49 #ifdef SUPPORT_NEW_MOVE
50   if (!myBaseConstraint || !myStorage) {
51 #else
52   if ((!myBaseConstraint && !myBaseFeature) || !myStorage) {
53 #endif
54     // Not enough parameters are assigned
55     return;
56   }
57
58 #ifdef SUPPORT_NEW_MOVE
59   EntityWrapperPtr aBaseEntity = entityToFix();
60   if (!aBaseEntity)
61     myErrorMsg = SketchSolver_Error::ALREADY_FIXED();
62 #else
63   EntityWrapperPtr aBaseEntity;
64   getAttributes(aBaseEntity, myFixedEntity);
65   if (!aBaseEntity) {
66     moveFeature(); // remove myFixed entity
67     myErrorMsg = SketchSolver_Error::ALREADY_FIXED();
68   }
69 #endif
70   if (!myErrorMsg.empty())
71     return;
72
73 #ifdef SUPPORT_NEW_MOVE
74   ConstraintWrapperPtr aConstraint = fixFeature(aBaseEntity);
75   myStorage->addConstraint(myBaseConstraint, aConstraint);
76 #else
77   myConstraint = fixFeature(aBaseEntity);
78   if (myBaseConstraint)
79     myStorage->addConstraint(myBaseConstraint, myConstraint);
80   else
81     myStorage->addMovementConstraint(myConstraint);
82 #endif
83 }
84
85 ConstraintWrapperPtr SketchSolver_ConstraintFixed::fixFeature(EntityWrapperPtr theFeature)
86 {
87   GCS::VEC_pD aParameters = toParameters(theFeature);
88
89   // Fix given list of parameters
90   std::list<GCSConstraintPtr> aConstraints;
91   myFixedValues.reserve(aParameters.size());
92   GCS::VEC_pD::const_iterator anIt = aParameters.begin();
93   for (int i = 0; anIt != aParameters.end(); ++anIt, ++i) {
94     myFixedValues.push_back(**anIt);
95     aConstraints.push_back(
96         GCSConstraintPtr(new GCS::ConstraintEqual(&myFixedValues[i], *anIt)));
97   }
98
99   return ConstraintWrapperPtr(
100       new PlaneGCSSolver_ConstraintWrapper(aConstraints, getType()));
101 }
102
103 #ifdef SUPPORT_NEW_MOVE
104 EntityWrapperPtr SketchSolver_ConstraintFixed::entityToFix()
105 {
106   // Constraint Fixed is added by user.
107   // Get the attribute of constraint (it should be alone in the list of constraints).
108   EntityWrapperPtr aValue;
109   std::vector<EntityWrapperPtr> anAttributes;
110   SketchSolver_Constraint::getAttributes(aValue, anAttributes);
111   std::vector<EntityWrapperPtr>::const_iterator anIt = anAttributes.begin();
112   for (; anIt != anAttributes.end(); ++anIt)
113     if (*anIt)
114       return *anIt;
115   return EntityWrapperPtr();
116 }
117 #else
118 void SketchSolver_ConstraintFixed::getAttributes(EntityWrapperPtr& theBaseEntity,
119                                                  EntityWrapperPtr& theFixedEntity)
120 {
121   if (myBaseFeature) {
122     // if the feature is copy, do not move it
123     std::shared_ptr<SketchPlugin_Feature> aSketchFeature =
124         std::dynamic_pointer_cast<SketchPlugin_Feature>(myBaseFeature);
125     if (aSketchFeature && aSketchFeature->isCopy()) {
126       myStorage->setNeedToResolve(true);
127       return;
128     }
129
130     // The feature is fixed.
131     PlaneGCSSolver_FeatureBuilder aBuilder;
132     std::list<AttributePtr> aBaseAttr = myBaseFeature->data()->attributes(std::string());
133     std::list<AttributePtr>::const_iterator anIt = aBaseAttr.begin();
134     for (; anIt != aBaseAttr.end(); ++anIt)
135       aBuilder.createAttribute(*anIt);
136     theFixedEntity = aBuilder.createFeature(myBaseFeature);
137
138     theBaseEntity = myStorage->entity(myBaseFeature);
139     if (isEqual(theBaseEntity, theFixedEntity))
140       theBaseEntity = EntityWrapperPtr(); // do not want to fix already fixed entity
141
142   } else if (myBaseConstraint) {
143     // Constraint Fixed is added by user.
144     // Get the attribute of constraint (it should be alone in the list of constraints).
145     EntityWrapperPtr aValue;
146     std::vector<EntityWrapperPtr> anAttributes;
147     SketchSolver_Constraint::getAttributes(aValue, anAttributes);
148     std::vector<EntityWrapperPtr>::const_iterator anIt = anAttributes.begin();
149     for (; anIt != anAttributes.end(); ++anIt)
150       if (*anIt)
151         theBaseEntity = *anIt;
152   } else
153     myErrorMsg = SketchSolver_Error::NOT_INITIALIZED();
154 }
155
156 void SketchSolver_ConstraintFixed::moveFeature()
157 {
158   if (!myFixedEntity)
159     return;
160
161   GCS::VEC_pD aFixedParams = toParameters(myFixedEntity);
162   for (int i = 0; i < aFixedParams.size() && i < myFixedValues.size(); ++i)
163     myFixedValues[i] = *(aFixedParams[i]);
164
165   // Remove fixed entity due to its parameters already copied into the constraint
166   PlaneGCSSolver_EntityDestroyer aDestroyer;
167   aDestroyer.remove(myFixedEntity);
168   std::dynamic_pointer_cast<PlaneGCSSolver_Storage>(myStorage)->removeParameters(
169       aDestroyer.parametersToRemove());
170
171   myFixedEntity = EntityWrapperPtr();
172 }
173 #endif
174
175 GCS::VEC_pD SketchSolver_ConstraintFixed::toParameters(const EntityWrapperPtr& theEntity)
176 {
177   GCS::VEC_pD aParameters;
178   if (!theEntity)
179     return aParameters;
180
181   std::shared_ptr<PlaneGCSSolver_EdgeWrapper> anEntity =
182       std::dynamic_pointer_cast<PlaneGCSSolver_EdgeWrapper>(theEntity);
183
184   // Collect parameters for each type of entity
185   switch (theEntity->type()) {
186   case ENTITY_POINT: {
187     std::shared_ptr<PlaneGCSSolver_PointWrapper> aPoint =
188         std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(theEntity);
189     aParameters.push_back(aPoint->point()->x);
190     aParameters.push_back(aPoint->point()->y);
191     break;
192     }
193   case ENTITY_LINE: {
194     std::shared_ptr<GCS::Line> aLine = std::dynamic_pointer_cast<GCS::Line>(anEntity->entity());
195     aParameters.push_back(aLine->p1.x);
196     aParameters.push_back(aLine->p1.y);
197     aParameters.push_back(aLine->p2.x);
198     aParameters.push_back(aLine->p2.y);
199     break;
200     }
201   case ENTITY_CIRCLE: {
202     std::shared_ptr<GCS::Circle> aCircle =
203         std::dynamic_pointer_cast<GCS::Circle>(anEntity->entity());
204     aParameters.push_back(aCircle->center.x);
205     aParameters.push_back(aCircle->center.y);
206 #ifndef SUPPORT_NEW_MOVE
207     aParameters.push_back(aCircle->rad);
208 #endif
209     break;
210     }
211   case ENTITY_ARC: {
212     std::shared_ptr<GCS::Arc> anArc = std::dynamic_pointer_cast<GCS::Arc>(anEntity->entity());
213     aParameters.push_back(anArc->center.x);
214     aParameters.push_back(anArc->center.y);
215 #ifndef SUPPORT_NEW_MOVE
216     aParameters.push_back(anArc->rad);
217     aParameters.push_back(anArc->startAngle);
218     aParameters.push_back(anArc->endAngle);
219 #endif
220     break;
221     }
222   default:
223     break;
224   }
225
226   return aParameters;
227 }
228
229 #ifndef SUPPORT_NEW_MOVE
230 // ====================   Auxiliary functions   ===============================
231 bool isEqual(const EntityWrapperPtr& theEntity1, const EntityWrapperPtr& theEntity2)
232 {
233   GCS::VEC_pD aParamList1 = SketchSolver_ConstraintFixed::toParameters(theEntity1);
234   GCS::VEC_pD aParamList2 = SketchSolver_ConstraintFixed::toParameters(theEntity2);
235
236   GCS::VEC_pD::const_iterator anIt1 = aParamList1.begin();
237   GCS::VEC_pD::const_iterator anIt2 = aParamList2.begin();
238   for (; anIt1 != aParamList1.end() && anIt2 != aParamList2.end(); ++anIt1, ++anIt2)
239     if (fabs((**anIt1) - (**anIt2)) > tolerance)
240       return false;
241
242   return anIt1 == aParamList1.end() && anIt2 == aParamList2.end();
243 }
244 #endif