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>
11 #include <SketchPlugin_Feature.h>
15 // Find parameters of the feature that have been updated during the movement
16 static EntityWrapperPtr getChangedEntity(const FeaturePtr& theFeature,
17 const StoragePtr& theStorage);
20 SketchSolver_ConstraintFixed::SketchSolver_ConstraintFixed(ConstraintPtr theConstraint)
21 : SketchSolver_Constraint(theConstraint)
23 myType = CONSTRAINT_FIXED;
26 SketchSolver_ConstraintFixed::SketchSolver_ConstraintFixed(FeaturePtr theFeature)
27 : SketchSolver_Constraint(),
28 myBaseFeature(theFeature)
30 myType = CONSTRAINT_FIXED;
33 void SketchSolver_ConstraintFixed::blockEvents(bool isBlocked)
36 myBaseFeature->data()->blockSendAttributeUpdated(isBlocked);
38 SketchSolver_Constraint::blockEvents(isBlocked);
41 void SketchSolver_ConstraintFixed::process()
44 if ((!myBaseConstraint && !myBaseFeature) || !myStorage) {
45 // Not enough parameters are assigned
49 EntityWrapperPtr aValue;
50 std::vector<EntityWrapperPtr> anEntities;
51 getAttributes(aValue, anEntities);
52 if (anEntities.empty())
53 myErrorMsg = SketchSolver_Error::ALREADY_FIXED();
54 if (!myErrorMsg.empty())
56 fixFeature(anEntities.front());
59 void SketchSolver_ConstraintFixed::fixFeature(EntityWrapperPtr theFeature)
61 std::shared_ptr<PlaneGCSSolver_EdgeWrapper> anEntity =
62 std::dynamic_pointer_cast<PlaneGCSSolver_EdgeWrapper>(theFeature);
64 GCS::VEC_pD aParameters; // parameters of entity to be fixed
66 // Collect parameters for each type of entity
67 switch (theFeature->type()) {
69 std::shared_ptr<PlaneGCSSolver_PointWrapper> aPoint =
70 std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(theFeature);
71 aParameters.push_back(aPoint->point()->x);
72 aParameters.push_back(aPoint->point()->y);
76 std::shared_ptr<GCS::Line> aLine = std::dynamic_pointer_cast<GCS::Line>(anEntity->entity());
77 aParameters.push_back(aLine->p1.x);
78 aParameters.push_back(aLine->p1.y);
79 aParameters.push_back(aLine->p2.x);
80 aParameters.push_back(aLine->p2.y);
84 std::shared_ptr<GCS::Circle> aCircle =
85 std::dynamic_pointer_cast<GCS::Circle>(anEntity->entity());
86 aParameters.push_back(aCircle->center.x);
87 aParameters.push_back(aCircle->center.y);
88 aParameters.push_back(aCircle->rad);
92 myFixedValues.reserve(4);
93 std::shared_ptr<GCS::Arc> anArc = std::dynamic_pointer_cast<GCS::Arc>(anEntity->entity());
94 aParameters.push_back(anArc->center.x);
95 aParameters.push_back(anArc->center.y);
96 aParameters.push_back(anArc->rad);
97 aParameters.push_back(anArc->startAngle);
98 aParameters.push_back(anArc->endAngle);
105 // Fix given list of parameters
106 std::list<GCSConstraintPtr> aConstraints;
107 myFixedValues.reserve(aParameters.size());
108 GCS::VEC_pD::const_iterator anIt = aParameters.begin();
109 for (int i = 0; anIt != aParameters.end(); ++anIt, ++i) {
110 myFixedValues.push_back(**anIt);
111 aConstraints.push_back(
112 GCSConstraintPtr(new GCS::ConstraintEqual(*anIt, &myFixedValues[i])));
115 myConstraint = ConstraintWrapperPtr(
116 new PlaneGCSSolver_ConstraintWrapper(aConstraints, getType()));
118 if (myBaseConstraint)
119 myStorage->addConstraint(myBaseConstraint, myConstraint);
121 myStorage->addTemporaryConstraint(myConstraint);
124 void SketchSolver_ConstraintFixed::getAttributes(
125 EntityWrapperPtr& theValue,
126 std::vector<EntityWrapperPtr>& theAttributes)
129 // if the feature is copy, do not move it
130 std::shared_ptr<SketchPlugin_Feature> aSketchFeature =
131 std::dynamic_pointer_cast<SketchPlugin_Feature>(myBaseFeature);
132 if (aSketchFeature && aSketchFeature->isCopy()) {
133 myStorage->setNeedToResolve(true);
137 // The feature is fixed.
138 EntityWrapperPtr aSolverEntity = getChangedEntity(myBaseFeature, myStorage);
139 myStorage->update(myBaseFeature);
141 theAttributes.push_back(aSolverEntity);
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 std::vector<EntityWrapperPtr> anAttributes;
146 SketchSolver_Constraint::getAttributes(theValue, anAttributes);
147 std::vector<EntityWrapperPtr>::const_iterator anIt = anAttributes.begin();
148 for (; anIt != anAttributes.end(); ++anIt)
150 theAttributes.push_back(*anIt);
152 myErrorMsg = SketchSolver_Error::NOT_INITIALIZED();
158 // ==================== Auxiliary functions ===============================
159 static bool isSameCoordinates(const AttributePoint2DPtr& thePointAttr,
160 const PointWrapperPtr& thePointWrapper)
162 GCSPointPtr aGCSPoint = thePointWrapper->point();
163 return fabs(*aGCSPoint->x - thePointAttr->x()) < tolerance &&
164 fabs(*aGCSPoint->y - thePointAttr->y()) < tolerance;
167 EntityWrapperPtr getChangedEntity(const FeaturePtr& theFeature,
168 const StoragePtr& theStorage)
170 std::list<AttributePtr> aPoints = theFeature->data()->attributes(GeomDataAPI_Point2D::typeId());
171 std::list<EntityWrapperPtr> aChangedPoints;
173 std::list<AttributePtr>::const_iterator aPIt = aPoints.begin();
174 for (; aPIt != aPoints.end(); ++aPIt) {
175 AttributePoint2DPtr aPnt = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(*aPIt);
176 EntityWrapperPtr anEnt = theStorage->entity(*aPIt);
178 PointWrapperPtr aPW = std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(anEnt);
179 if (!isSameCoordinates(aPnt, aPW))
180 aChangedPoints.push_back(anEnt);
182 theStorage->update(*aPIt);
183 aChangedPoints.push_back(theStorage->entity(*aPIt));
187 EntityWrapperPtr aChanged;
188 if (aChangedPoints.size() == 1)
189 aChanged = aChangedPoints.front();
190 else if (!aChangedPoints.empty()) // update whole feature
191 aChanged = theStorage->entity(theFeature);