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_PointWrapper.h>
10 #include <GeomDataAPI_Point2D.h>
14 // Find parameters of the feature that have been updated during the movement
15 static EntityWrapperPtr getChangedEntity(const FeaturePtr& theFeature,
16 const StoragePtr& theStorage);
19 SketchSolver_ConstraintFixed::SketchSolver_ConstraintFixed(ConstraintPtr theConstraint)
20 : SketchSolver_Constraint(theConstraint)
22 myType = CONSTRAINT_FIXED;
25 SketchSolver_ConstraintFixed::SketchSolver_ConstraintFixed(FeaturePtr theFeature)
26 : SketchSolver_Constraint(),
27 myBaseFeature(theFeature)
29 myType = CONSTRAINT_FIXED;
32 void SketchSolver_ConstraintFixed::blockEvents(bool isBlocked)
35 myBaseFeature->data()->blockSendAttributeUpdated(isBlocked);
37 SketchSolver_Constraint::blockEvents(isBlocked);
40 void SketchSolver_ConstraintFixed::process()
43 if ((!myBaseConstraint && !myBaseFeature) || !myStorage) {
44 // Not enough parameters are assigned
48 EntityWrapperPtr aValue;
49 std::vector<EntityWrapperPtr> anEntities;
50 getAttributes(aValue, anEntities);
51 if (anEntities.empty())
52 myErrorMsg = SketchSolver_Error::ALREADY_FIXED();
53 if (!myErrorMsg.empty())
55 fixFeature(anEntities.front());
58 void SketchSolver_ConstraintFixed::fixFeature(EntityWrapperPtr theFeature)
60 std::shared_ptr<PlaneGCSSolver_EdgeWrapper> anEntity =
61 std::dynamic_pointer_cast<PlaneGCSSolver_EdgeWrapper>(theFeature);
63 GCS::VEC_pD aParameters; // parameters of entity to be fixed
65 // Collect parameters for each type of entity
66 switch (theFeature->type()) {
68 std::shared_ptr<PlaneGCSSolver_PointWrapper> aPoint =
69 std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(theFeature);
70 aParameters.push_back(aPoint->point()->x);
71 aParameters.push_back(aPoint->point()->y);
75 std::shared_ptr<GCS::Line> aLine = std::dynamic_pointer_cast<GCS::Line>(anEntity->entity());
76 aParameters.push_back(aLine->p1.x);
77 aParameters.push_back(aLine->p1.y);
78 aParameters.push_back(aLine->p2.x);
79 aParameters.push_back(aLine->p2.y);
83 std::shared_ptr<GCS::Circle> aCircle =
84 std::dynamic_pointer_cast<GCS::Circle>(anEntity->entity());
85 aParameters.push_back(aCircle->center.x);
86 aParameters.push_back(aCircle->center.y);
87 aParameters.push_back(aCircle->rad);
91 myFixedValues.reserve(4);
92 std::shared_ptr<GCS::Arc> anArc = std::dynamic_pointer_cast<GCS::Arc>(anEntity->entity());
93 aParameters.push_back(anArc->center.x);
94 aParameters.push_back(anArc->center.y);
95 aParameters.push_back(anArc->rad);
96 aParameters.push_back(anArc->startAngle);
97 aParameters.push_back(anArc->endAngle);
104 // Fix given list of parameters
105 std::list<GCSConstraintPtr> aConstraints;
106 myFixedValues.reserve(aParameters.size());
107 GCS::VEC_pD::const_iterator anIt = aParameters.begin();
108 for (int i = 0; anIt != aParameters.end(); ++anIt, ++i) {
109 myFixedValues.push_back(**anIt);
110 aConstraints.push_back(
111 GCSConstraintPtr(new GCS::ConstraintEqual(*anIt, &myFixedValues[i])));
114 myConstraint = ConstraintWrapperPtr(
115 new PlaneGCSSolver_ConstraintWrapper(aConstraints, getType()));
117 if (myBaseConstraint)
118 myStorage->addConstraint(myBaseConstraint, myConstraint);
120 myStorage->addTemporaryConstraint(myConstraint);
123 void SketchSolver_ConstraintFixed::getAttributes(
124 EntityWrapperPtr& theValue,
125 std::vector<EntityWrapperPtr>& theAttributes)
128 // The feature is fixed.
129 EntityWrapperPtr aSolverEntity = getChangedEntity(myBaseFeature, myStorage);
130 myStorage->update(myBaseFeature);
132 theAttributes.push_back(aSolverEntity);
133 } else if (myBaseConstraint) {
134 // Constraint Fixed is added by user.
135 // Get the attribute of constraint (it should be alone in the list of constraints).
136 std::vector<EntityWrapperPtr> anAttributes;
137 SketchSolver_Constraint::getAttributes(theValue, anAttributes);
138 std::vector<EntityWrapperPtr>::const_iterator anIt = anAttributes.begin();
139 for (; anIt != anAttributes.end(); ++anIt)
141 theAttributes.push_back(*anIt);
143 myErrorMsg = SketchSolver_Error::NOT_INITIALIZED();
149 // ==================== Auxiliary functions ===============================
150 static bool isSameCoordinates(const AttributePoint2DPtr& thePointAttr,
151 const PointWrapperPtr& thePointWrapper)
153 GCSPointPtr aGCSPoint = thePointWrapper->point();
154 return fabs(*aGCSPoint->x - thePointAttr->x()) < tolerance &&
155 fabs(*aGCSPoint->y - thePointAttr->y()) < tolerance;
158 EntityWrapperPtr getChangedEntity(const FeaturePtr& theFeature,
159 const StoragePtr& theStorage)
161 std::list<AttributePtr> aPoints = theFeature->data()->attributes(GeomDataAPI_Point2D::typeId());
162 std::list<EntityWrapperPtr> aChangedPoints;
164 std::list<AttributePtr>::const_iterator aPIt = aPoints.begin();
165 for (; aPIt != aPoints.end(); ++aPIt) {
166 AttributePoint2DPtr aPnt = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(*aPIt);
167 EntityWrapperPtr anEnt = theStorage->entity(*aPIt);
169 PointWrapperPtr aPW = std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(anEnt);
170 if (!isSameCoordinates(aPnt, aPW))
171 aChangedPoints.push_back(anEnt);
173 theStorage->update(*aPIt);
174 aChangedPoints.push_back(theStorage->entity(*aPIt));
178 EntityWrapperPtr aChanged;
179 if (aChangedPoints.size() == 1)
180 aChanged = aChangedPoints.front();
181 else if (!aChangedPoints.empty()) // update whole feature
182 aChanged = theStorage->entity(theFeature);