1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
3 #include <SketchSolver_ConstraintFixed.h>
4 #include <SketchSolver_Error.h>
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>
12 #include <GeomDataAPI_Point2D.h>
13 #include <SketchPlugin_Feature.h>
17 // Verify the entities are equal
18 static bool isEqual(const EntityWrapperPtr& theEntity1, const EntityWrapperPtr& theEntity2);
21 SketchSolver_ConstraintFixed::SketchSolver_ConstraintFixed(ConstraintPtr theConstraint)
22 : SketchSolver_Constraint(theConstraint)
24 myType = CONSTRAINT_FIXED;
27 #ifndef SUPPORT_NEW_MOVE
28 SketchSolver_ConstraintFixed::SketchSolver_ConstraintFixed(FeaturePtr theFeature)
29 : SketchSolver_Constraint(),
30 myBaseFeature(theFeature)
32 myType = CONSTRAINT_FIXED;
36 void SketchSolver_ConstraintFixed::blockEvents(bool isBlocked)
38 #ifndef SUPPORT_NEW_MOVE
40 myBaseFeature->data()->blockSendAttributeUpdated(isBlocked);
43 SketchSolver_Constraint::blockEvents(isBlocked);
46 void SketchSolver_ConstraintFixed::process()
49 #ifdef SUPPORT_NEW_MOVE
50 if (!myBaseConstraint || !myStorage) {
52 if ((!myBaseConstraint && !myBaseFeature) || !myStorage) {
54 // Not enough parameters are assigned
58 #ifdef SUPPORT_NEW_MOVE
59 EntityWrapperPtr aBaseEntity = entityToFix();
61 myErrorMsg = SketchSolver_Error::ALREADY_FIXED();
63 EntityWrapperPtr aBaseEntity;
64 getAttributes(aBaseEntity, myFixedEntity);
66 moveFeature(); // remove myFixed entity
67 myErrorMsg = SketchSolver_Error::ALREADY_FIXED();
70 if (!myErrorMsg.empty())
73 #ifdef SUPPORT_NEW_MOVE
74 ConstraintWrapperPtr aConstraint = fixFeature(aBaseEntity);
75 myStorage->addConstraint(myBaseConstraint, aConstraint);
77 myConstraint = fixFeature(aBaseEntity);
79 myStorage->addConstraint(myBaseConstraint, myConstraint);
81 myStorage->addMovementConstraint(myConstraint);
85 ConstraintWrapperPtr SketchSolver_ConstraintFixed::fixFeature(EntityWrapperPtr theFeature)
87 GCS::VEC_pD aParameters = toParameters(theFeature);
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)));
99 return ConstraintWrapperPtr(
100 new PlaneGCSSolver_ConstraintWrapper(aConstraints, getType()));
103 #ifdef SUPPORT_NEW_MOVE
104 EntityWrapperPtr SketchSolver_ConstraintFixed::entityToFix()
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)
115 return EntityWrapperPtr();
118 void SketchSolver_ConstraintFixed::getAttributes(EntityWrapperPtr& theBaseEntity,
119 EntityWrapperPtr& theFixedEntity)
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);
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);
138 theBaseEntity = myStorage->entity(myBaseFeature);
139 if (isEqual(theBaseEntity, theFixedEntity))
140 theBaseEntity = EntityWrapperPtr(); // do not want to fix already fixed entity
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)
151 theBaseEntity = *anIt;
153 myErrorMsg = SketchSolver_Error::NOT_INITIALIZED();
156 void SketchSolver_ConstraintFixed::moveFeature()
161 GCS::VEC_pD aFixedParams = toParameters(myFixedEntity);
162 for (int i = 0; i < aFixedParams.size() && i < myFixedValues.size(); ++i)
163 myFixedValues[i] = *(aFixedParams[i]);
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());
171 myFixedEntity = EntityWrapperPtr();
175 GCS::VEC_pD SketchSolver_ConstraintFixed::toParameters(const EntityWrapperPtr& theEntity)
177 GCS::VEC_pD aParameters;
181 std::shared_ptr<PlaneGCSSolver_EdgeWrapper> anEntity =
182 std::dynamic_pointer_cast<PlaneGCSSolver_EdgeWrapper>(theEntity);
184 // Collect parameters for each type of entity
185 switch (theEntity->type()) {
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);
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);
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);
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);
229 #ifndef SUPPORT_NEW_MOVE
230 // ==================== Auxiliary functions ===============================
231 bool isEqual(const EntityWrapperPtr& theEntity1, const EntityWrapperPtr& theEntity2)
233 GCS::VEC_pD aParamList1 = SketchSolver_ConstraintFixed::toParameters(theEntity1);
234 GCS::VEC_pD aParamList2 = SketchSolver_ConstraintFixed::toParameters(theEntity2);
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)
242 return anIt1 == aParamList1.end() && anIt2 == aParamList2.end();