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);
19 // Convert entity to the list of parameters
20 static GCS::VEC_pD toParameters(const EntityWrapperPtr& theEntity);
23 SketchSolver_ConstraintFixed::SketchSolver_ConstraintFixed(ConstraintPtr theConstraint)
24 : SketchSolver_Constraint(theConstraint)
26 myType = CONSTRAINT_FIXED;
29 SketchSolver_ConstraintFixed::SketchSolver_ConstraintFixed(FeaturePtr theFeature)
30 : SketchSolver_Constraint(),
31 myBaseFeature(theFeature)
33 myType = CONSTRAINT_FIXED;
36 void SketchSolver_ConstraintFixed::blockEvents(bool isBlocked)
39 myBaseFeature->data()->blockSendAttributeUpdated(isBlocked);
41 SketchSolver_Constraint::blockEvents(isBlocked);
44 void SketchSolver_ConstraintFixed::process()
47 if ((!myBaseConstraint && !myBaseFeature) || !myStorage) {
48 // Not enough parameters are assigned
52 EntityWrapperPtr aBaseEntity;
53 getAttributes(aBaseEntity, myFixedEntity);
55 moveFeature(); // remove myFixed entity
56 myErrorMsg = SketchSolver_Error::ALREADY_FIXED();
58 if (!myErrorMsg.empty())
61 fixFeature(aBaseEntity);
64 void SketchSolver_ConstraintFixed::fixFeature(EntityWrapperPtr theFeature)
66 GCS::VEC_pD aParameters = toParameters(theFeature);
68 // Fix given list of parameters
69 std::list<GCSConstraintPtr> aConstraints;
70 myFixedValues.reserve(aParameters.size());
71 GCS::VEC_pD::const_iterator anIt = aParameters.begin();
72 for (int i = 0; anIt != aParameters.end(); ++anIt, ++i) {
73 myFixedValues.push_back(**anIt);
74 aConstraints.push_back(
75 GCSConstraintPtr(new GCS::ConstraintEqual(&myFixedValues[i], *anIt)));
78 myConstraint = ConstraintWrapperPtr(
79 new PlaneGCSSolver_ConstraintWrapper(aConstraints, getType()));
82 myStorage->addConstraint(myBaseConstraint, myConstraint);
84 myStorage->addTemporaryConstraint(myConstraint);
87 void SketchSolver_ConstraintFixed::getAttributes(EntityWrapperPtr& theBaseEntity,
88 EntityWrapperPtr& theFixedEntity)
91 // if the feature is copy, do not move it
92 std::shared_ptr<SketchPlugin_Feature> aSketchFeature =
93 std::dynamic_pointer_cast<SketchPlugin_Feature>(myBaseFeature);
94 if (aSketchFeature && aSketchFeature->isCopy()) {
95 myStorage->setNeedToResolve(true);
99 // The feature is fixed.
100 PlaneGCSSolver_FeatureBuilder aBuilder;
101 std::list<AttributePtr> aBaseAttr = myBaseFeature->data()->attributes(std::string());
102 std::list<AttributePtr>::const_iterator anIt = aBaseAttr.begin();
103 for (; anIt != aBaseAttr.end(); ++anIt)
104 aBuilder.createAttribute(*anIt);
105 theFixedEntity = aBuilder.createFeature(myBaseFeature);
107 theBaseEntity = myStorage->entity(myBaseFeature);
108 if (isEqual(theBaseEntity, theFixedEntity))
109 theBaseEntity = EntityWrapperPtr(); // do not want to fix already fixed entity
111 } else if (myBaseConstraint) {
112 // Constraint Fixed is added by user.
113 // Get the attribute of constraint (it should be alone in the list of constraints).
114 EntityWrapperPtr aValue;
115 std::vector<EntityWrapperPtr> anAttributes;
116 SketchSolver_Constraint::getAttributes(aValue, anAttributes);
117 std::vector<EntityWrapperPtr>::const_iterator anIt = anAttributes.begin();
118 for (; anIt != anAttributes.end(); ++anIt)
120 theBaseEntity = *anIt;
122 myErrorMsg = SketchSolver_Error::NOT_INITIALIZED();
125 void SketchSolver_ConstraintFixed::moveFeature()
130 GCS::VEC_pD aFixedParams = toParameters(myFixedEntity);
131 for (int i = 0; i < aFixedParams.size() && i < myFixedValues.size(); ++i)
132 myFixedValues[i] = *(aFixedParams[i]);
134 // Remove fixed entity due to its parameters already copied into the constraint
135 PlaneGCSSolver_EntityDestroyer aDestroyer;
136 aDestroyer.remove(myFixedEntity);
137 std::dynamic_pointer_cast<PlaneGCSSolver_Storage>(myStorage)->removeParameters(
138 aDestroyer.parametersToRemove());
140 myFixedEntity = EntityWrapperPtr();
146 // ==================== Auxiliary functions ===============================
147 GCS::VEC_pD toParameters(const EntityWrapperPtr& theEntity)
149 GCS::VEC_pD aParameters;
153 std::shared_ptr<PlaneGCSSolver_EdgeWrapper> anEntity =
154 std::dynamic_pointer_cast<PlaneGCSSolver_EdgeWrapper>(theEntity);
156 // Collect parameters for each type of entity
157 switch (theEntity->type()) {
159 std::shared_ptr<PlaneGCSSolver_PointWrapper> aPoint =
160 std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(theEntity);
161 aParameters.push_back(aPoint->point()->x);
162 aParameters.push_back(aPoint->point()->y);
166 std::shared_ptr<GCS::Line> aLine = std::dynamic_pointer_cast<GCS::Line>(anEntity->entity());
167 aParameters.push_back(aLine->p1.x);
168 aParameters.push_back(aLine->p1.y);
169 aParameters.push_back(aLine->p2.x);
170 aParameters.push_back(aLine->p2.y);
173 case ENTITY_CIRCLE: {
174 std::shared_ptr<GCS::Circle> aCircle =
175 std::dynamic_pointer_cast<GCS::Circle>(anEntity->entity());
176 aParameters.push_back(aCircle->center.x);
177 aParameters.push_back(aCircle->center.y);
178 aParameters.push_back(aCircle->rad);
182 std::shared_ptr<GCS::Arc> anArc = std::dynamic_pointer_cast<GCS::Arc>(anEntity->entity());
183 aParameters.push_back(anArc->center.x);
184 aParameters.push_back(anArc->center.y);
185 aParameters.push_back(anArc->rad);
186 aParameters.push_back(anArc->startAngle);
187 aParameters.push_back(anArc->endAngle);
197 bool isEqual(const EntityWrapperPtr& theEntity1, const EntityWrapperPtr& theEntity2)
199 GCS::VEC_pD aParamList1 = toParameters(theEntity1);
200 GCS::VEC_pD aParamList2 = toParameters(theEntity2);
202 GCS::VEC_pD::const_iterator anIt1 = aParamList1.begin();
203 GCS::VEC_pD::const_iterator anIt2 = aParamList2.begin();
204 for (; anIt1 != aParamList1.end() && anIt2 != aParamList2.end(); ++anIt1, ++anIt2)
205 if (fabs((**anIt1) - (**anIt2)) > tolerance)
208 return anIt1 == aParamList1.end() && anIt2 == aParamList2.end();