1 #include <SketchSolver_ConstraintFixed.h>
2 #include <SketchSolver_Error.h>
3 #include <SketchSolver_Manager.h>
5 #include <SketchPlugin_Arc.h>
6 #include <SketchPlugin_Circle.h>
7 #include <SketchPlugin_ConstraintRigid.h>
8 #include <SketchPlugin_Line.h>
9 #include <SketchPlugin_Point.h>
11 #include <GeomAPI_Pnt2d.h>
12 #include <GeomAPI_XY.h>
13 #include <GeomDataAPI_Point2D.h>
14 #include <ModelAPI_AttributeDouble.h>
18 SketchSolver_ConstraintFixed::SketchSolver_ConstraintFixed(ConstraintPtr theConstraint)
19 : SketchSolver_Constraint()
21 myBaseConstraint = theConstraint;
22 myType = CONSTRAINT_FIXED;
23 myFixedAttribute = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
24 theConstraint->attribute(SketchPlugin_ConstraintRigid::ENTITY_A()));
27 SketchSolver_ConstraintFixed::SketchSolver_ConstraintFixed(FeaturePtr theFeature)
28 : SketchSolver_Constraint(),
29 myBaseFeature(theFeature)
31 myType = CONSTRAINT_FIXED;
35 void SketchSolver_ConstraintFixed::process()
38 if ((!myBaseConstraint && !myBaseFeature) || !myStorage || myGroupID == GID_UNKNOWN) {
39 // Not enough parameters are assigned
42 //// if (!mySlvsConstraints.empty()) // some data is changed, update constraint
43 //// update(myBaseConstraint);
45 ParameterWrapperPtr aValue;
46 std::vector<EntityWrapperPtr> anEntities;
47 getAttributes(aValue, anEntities);
48 if (!myErrorMsg.empty() || anEntities.empty())
50 fixFeature(anEntities.front());
53 ////static void fixEntity(StoragePtr theStorage, const Slvs_hEntity& theEntID)
55 //// Slvs_Entity anEntity = theStorage->getEntity(theEntID);
56 //// anEntity.group = SLVS_G_OUTOFGROUP;
57 //// theStorage->updateEntity(anEntity);
58 //// // move out of group all sub-entities
59 //// for (int i = 0; i < 4; ++i)
60 //// if (anEntity.point[i] != SLVS_E_UNKNOWN)
61 //// fixEntity(theStorage, anEntity.point[i]);
62 //// // move out of group the radius of circle
63 //// if (anEntity.distance != SLVS_E_UNKNOWN)
64 //// fixEntity(theStorage, anEntity.distance);
65 //// // move out of group parameters
66 //// for (int i = 0; i < 4; ++i)
67 //// if (anEntity.param[i] != SLVS_E_UNKNOWN) {
68 //// Slvs_Param aParam = theStorage->getParameter(anEntity.param[i]);
69 //// aParam.group = SLVS_G_OUTOFGROUP;
70 //// theStorage->updateParameter(aParam);
74 void SketchSolver_ConstraintFixed::fixFeature(EntityWrapperPtr theFeature)
76 // extract feature from the group
77 if (theFeature->baseAttribute())
78 myStorage->update(theFeature->baseAttribute(), GID_OUTOFGROUP);
80 myStorage->update(theFeature->baseFeature(), GID_OUTOFGROUP);
83 ////Slvs_hEntity SketchSolver_ConstraintFixed::fixedEntity() const
85 //// Slvs_hEntity anEntID = SLVS_E_UNKNOWN;
86 //// if (myBaseConstraint) {
87 //// AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
88 //// myBaseConstraint->attribute(SketchPlugin_Constraint::ENTITY_A()));
89 //// if (aRefAttr->isObject()) {
90 //// FeaturePtr aFeature = ModelAPI_Feature::feature(aRefAttr->object());
91 //// std::map<FeaturePtr, Slvs_hEntity>::const_iterator aFound = myFeatureMap.find(aFeature);
92 //// if (aFound != myFeatureMap.end())
93 //// anEntID = aFound->second;
95 //// std::map<AttributePtr, Slvs_hEntity>::const_iterator aFound = myAttributeMap.find(aRefAttr->attr());
96 //// if (aFound != myAttributeMap.end())
97 //// anEntID = aFound->second;
100 //// else if (myBaseFeature) {
101 //// std::map<FeaturePtr, Slvs_hEntity>::const_iterator aFound = myFeatureMap.find(myBaseFeature);
102 //// if (aFound != myFeatureMap.end())
103 //// anEntID = aFound->second;
108 void SketchSolver_ConstraintFixed::getAttributes(
109 ParameterWrapperPtr& theValue,
110 std::vector<EntityWrapperPtr>& theAttributes)
112 BuilderPtr aBuilder = SketchSolver_Manager::instance()->builder();
114 EntityWrapperPtr aSolverEntity;
116 // The feature is fixed.
117 myStorage->update(myBaseFeature, myGroupID);
118 aSolverEntity = myStorage->entity(myBaseFeature);
119 } else if (myBaseConstraint) {
120 // Constraint Fixed is added by user.
121 // Get the attribute of constraint (it should be alone in the list of constraints).
122 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
123 myBaseConstraint->attribute(SketchPlugin_ConstraintRigid::ENTITY_A()));
124 if (!aRefAttr || !aRefAttr->isInitialized()) {
125 myErrorMsg = SketchSolver_Error::NOT_INITIALIZED();
129 myStorage->update(aRefAttr, myGroupID);
130 aSolverEntity = myStorage->entity(aRefAttr);
132 myErrorMsg = SketchSolver_Error::NOT_INITIALIZED();
135 theAttributes.push_back(aSolverEntity);
139 bool SketchSolver_ConstraintFixed::remove()
142 // Move fixed entities back to the current group
143 FeaturePtr aFeature = myBaseFeature;
144 if (myBaseConstraint && myFixedAttribute && myFixedAttribute->isObject())
145 aFeature = ModelAPI_Feature::feature(myFixedAttribute->object());
147 myStorage->update(aFeature, myGroupID);
149 // Remove constraint or base feature
150 if (myBaseConstraint) {
151 bool isRemoved = false;
153 isRemoved = myStorage->removeEntity(aFeature);
154 return SketchSolver_Constraint::remove() || isRemoved;
155 } else if (myBaseFeature)
156 myStorage->removeEntity(myBaseFeature);
160 ////Slvs_hConstraint SketchSolver_ConstraintFixed::fixPoint(const Slvs_hEntity& thePointID)
162 //// if (thePointID == SLVS_E_UNKNOWN)
163 //// return SLVS_C_UNKNOWN;
165 //// Slvs_Constraint aConstraint;
166 //// Slvs_hConstraint aConstrID = SLVS_E_UNKNOWN;
167 //// bool isFixed = myStorage->isPointFixed(thePointID, aConstrID, true);
168 //// bool isForceUpdate = (isFixed && !myBaseConstraint &&
169 //// myStorage->isTemporary(aConstrID));
170 //// if (!isForceUpdate) { // create new constraint
171 //// if (isFixed) return aConstrID;
172 //// aConstraint = Slvs_MakeConstraint(SLVS_C_UNKNOWN, myGroup->getId(), getType(), myGroup->getWorkplaneId(),
173 //// 0.0, thePointID, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN);
174 //// aConstraint.h = myStorage->addConstraint(aConstraint);
175 //// mySlvsConstraints.push_back(aConstraint.h);
176 //// if (!myBaseConstraint)
177 //// myStorage->addConstraintWhereDragged(aConstraint.h);
178 //// } else { // update already existent constraint
179 //// if (!isFixed || aConstrID == SLVS_C_UNKNOWN || myBaseConstraint)
180 //// return SLVS_C_UNKNOWN;
181 //// aConstraint = myStorage->getConstraint(aConstrID);
182 //// aConstraint.ptA = thePointID;
183 //// myStorage->addConstraint(aConstraint);
184 //// if (!myBaseConstraint)
185 //// myStorage->addConstraintWhereDragged(aConstraint.h);
187 //// return aConstraint.h;
190 ////void SketchSolver_ConstraintFixed::fixLine(const Slvs_Entity& theLine)
192 //// Slvs_Constraint anEqual;
193 //// if (myStorage->isAxisParallel(theLine.h)) {
194 //// // Fix one point and a line length
195 //// Slvs_hConstraint aFixed;
196 //// if (!myStorage->isPointFixed(theLine.point[0], aFixed, true) &&
197 //// !myStorage->isPointFixed(theLine.point[1], aFixed, true))
198 //// fixPoint(theLine.point[0]);
199 //// if (!myStorage->isUsedInEqual(theLine.h, anEqual)) {
200 //// // Check the distance is not set yet
201 //// std::list<Slvs_Constraint> aDistConstr = myStorage->getConstraintsByType(SLVS_C_PT_PT_DISTANCE);
202 //// std::list<Slvs_Constraint>::const_iterator aDIt = aDistConstr.begin();
203 //// for (; aDIt != aDistConstr.end(); aDIt++)
204 //// if ((aDIt->ptA == theLine.point[0] && aDIt->ptB == theLine.point[1]) ||
205 //// (aDIt->ptA == theLine.point[1] && aDIt->ptB == theLine.point[0]))
207 //// // Calculate distance between points on the line
208 //// double aCoords[4];
209 //// for (int i = 0; i < 2; i++) {
210 //// Slvs_Entity aPnt = myStorage->getEntity(theLine.point[i]);
211 //// for (int j = 0; j < 2; j++) {
212 //// Slvs_Param aParam = myStorage->getParameter(aPnt.param[j]);
213 //// aCoords[2*i+j] = aParam.val;
216 //// double aLength = sqrt((aCoords[2] - aCoords[0]) * (aCoords[2] - aCoords[0]) +
217 //// (aCoords[3] - aCoords[1]) * (aCoords[3] - aCoords[1]));
218 //// // fix line length
219 //// Slvs_Constraint aDistance = Slvs_MakeConstraint(SLVS_E_UNKNOWN, myGroup->getId(),
220 //// SLVS_C_PT_PT_DISTANCE, myGroup->getWorkplaneId(), aLength,
221 //// theLine.point[0], theLine.point[1], SLVS_E_UNKNOWN, SLVS_E_UNKNOWN);
222 //// aDistance.h = myStorage->addConstraint(aDistance);
223 //// mySlvsConstraints.push_back(aDistance.h);
227 //// else if (myStorage->isUsedInEqual(theLine.h, anEqual)) {
228 //// // Check another entity of Equal is already fixed
229 //// Slvs_hEntity anOtherEntID = anEqual.entityA == theLine.h ? anEqual.entityB : anEqual.entityA;
230 //// if (myStorage->isEntityFixed(anOtherEntID, true)) {
231 //// // Fix start point of the line (if end point is not fixed yet) ...
232 //// Slvs_hConstraint anEndFixedID = SLVS_E_UNKNOWN;
233 //// bool isFixed = myStorage->isPointFixed(theLine.point[1], anEndFixedID, true);
234 //// if (isFixed == SLVS_E_UNKNOWN)
235 //// fixPoint(theLine.point[0]);
236 //// // ... and create fixed point lying on this line
237 //// Slvs_hEntity aPointToCopy = anEndFixedID == SLVS_E_UNKNOWN ? theLine.point[1] : theLine.point[0];
238 //// // Firstly, search already fixed point on line
239 //// bool isPonLineFixed = false;
240 //// Slvs_hEntity aFixedPoint;
241 //// std::list<Slvs_Constraint> aPonLineList = myStorage->getConstraintsByType(SLVS_C_PT_ON_LINE);
242 //// std::list<Slvs_Constraint>::const_iterator aPLIter = aPonLineList.begin();
243 //// for (; aPLIter != aPonLineList.end() && !isPonLineFixed; aPLIter++)
244 //// if (aPLIter->entityA == theLine.h) {
245 //// isPonLineFixed = myStorage->isPointFixed(aPLIter->ptA, anEndFixedID);
246 //// aFixedPoint = aPLIter->ptA;
249 //// if (isPonLineFixed) { // update existent constraint
250 //// myStorage->copyEntity(aPointToCopy, aFixedPoint);
251 //// } else { // create new constraint
252 //// Slvs_hEntity aCopied = myStorage->copyEntity(aPointToCopy);
253 //// Slvs_Constraint aPonLine = Slvs_MakeConstraint(SLVS_E_UNKNOWN, myGroup->getId(), SLVS_C_PT_ON_LINE,
254 //// myGroup->getWorkplaneId(), 0.0, aCopied, SLVS_E_UNKNOWN, theLine.h, SLVS_E_UNKNOWN);
255 //// aPonLine.h = myStorage->addConstraint(aPonLine);
256 //// mySlvsConstraints.push_back(aPonLine.h);
257 //// fixPoint(aCopied);
263 //// for (int i = 0; i < 2; i++)
264 //// fixPoint(theLine.point[i]);
267 ////void SketchSolver_ConstraintFixed::fixCircle(const Slvs_Entity& theCircle)
269 //// bool isFixRadius = true;
270 //// // Verify the arc is under Equal constraint
271 //// Slvs_Constraint anEqual;
272 //// if (myStorage->isUsedInEqual(theCircle.h, anEqual)) {
273 //// // Check another entity of Equal is already fixed
274 //// Slvs_hEntity anOtherEntID = anEqual.entityA == theCircle.h ? anEqual.entityB : anEqual.entityA;
275 //// if (myStorage->isEntityFixed(anOtherEntID, true))
276 //// isFixRadius = false;
279 //// fixPoint(theCircle.point[0]);
281 //// if (isFixRadius) {
282 //// // Search the radius is already fixed
283 //// std::list<Slvs_Constraint> aDiamConstr = myStorage->getConstraintsByType(SLVS_C_DIAMETER);
284 //// std::list<Slvs_Constraint>::const_iterator aDiamIter = aDiamConstr.begin();
285 //// for (; aDiamIter != aDiamConstr.end(); aDiamIter++)
286 //// if (aDiamIter->entityA == theCircle.h)
289 //// // Fix radius of a circle
290 //// AttributeDoublePtr aRadiusAttr = std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(
291 //// myFeatureMap.begin()->first->attribute(SketchPlugin_Circle::RADIUS_ID()));
292 //// Slvs_Constraint aFixedR = Slvs_MakeConstraint(SLVS_E_UNKNOWN, myGroup->getId(), SLVS_C_DIAMETER,
293 //// myGroup->getWorkplaneId(), aRadiusAttr->value() * 2.0, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN,
294 //// myFeatureMap.begin()->second, SLVS_E_UNKNOWN);
295 //// aFixedR.h = myStorage->addConstraint(aFixedR);
296 //// mySlvsConstraints.push_back(aFixedR.h);
300 ////void SketchSolver_ConstraintFixed::fixArc(const Slvs_Entity& theArc)
302 //// bool isFixRadius = true;
303 //// std::list<Slvs_hEntity> aPointsToFix;
304 //// aPointsToFix.push_back(theArc.point[1]);
305 //// aPointsToFix.push_back(theArc.point[2]);
307 //// // Verify the arc is under Equal constraint
308 //// Slvs_Constraint anEqual;
309 //// if (myStorage->isUsedInEqual(theArc.h, anEqual)) {
310 //// // Check another entity of Equal is already fixed
311 //// Slvs_hEntity anOtherEntID = anEqual.entityA == theArc.h ? anEqual.entityB : anEqual.entityA;
312 //// if (myStorage->isEntityFixed(anOtherEntID, true)) {
313 //// isFixRadius = false;
314 //// Slvs_Entity anOtherEntity = myStorage->getEntity(anOtherEntID);
315 //// if (anOtherEntity.type == SLVS_E_LINE_SEGMENT) {
316 //// aPointsToFix.pop_back();
317 //// aPointsToFix.push_back(theArc.point[0]);
322 //// Slvs_hConstraint aConstrID;
323 //// int aNbPointsToFix = 2; // number of fixed points for the arc
324 //// if (myStorage->isPointFixed(theArc.point[0], aConstrID, true))
325 //// aNbPointsToFix--;
327 //// // Radius of the arc
328 //// FeaturePtr aFeature = myFeatureMap.begin()->first;
329 //// std::shared_ptr<GeomAPI_Pnt2d> aCenter = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
330 //// aFeature->attribute(SketchPlugin_Arc::CENTER_ID()))->pnt();
331 //// std::shared_ptr<GeomAPI_Pnt2d> aStart = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
332 //// aFeature->attribute(SketchPlugin_Arc::START_ID()))->pnt();
333 //// double aRadius = aCenter->distance(aStart);
335 //// // Update end point of the arc to be on a curve
336 //// std::shared_ptr<GeomAPI_Pnt2d> anEnd = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
337 //// aFeature->attribute(SketchPlugin_Arc::END_ID()))->pnt();
338 //// double aDistance = anEnd->distance(aCenter);
339 //// std::shared_ptr<GeomAPI_XY> aDir = anEnd->xy()->decreased(aCenter->xy());
340 //// if (aDistance < tolerance)
341 //// aDir = aStart->xy()->decreased(aCenter->xy())->multiplied(-1.0);
343 //// aDir = aDir->multiplied(aRadius / aDistance);
344 //// double xy[2] = {aCenter->x() + aDir->x(), aCenter->y() + aDir->y()};
345 //// Slvs_Entity aEndPoint = myStorage->getEntity(theArc.point[2]);
346 //// for (int i = 0; i < 2; i++) {
347 //// Slvs_Param aParam = myStorage->getParameter(aEndPoint.param[i]);
348 //// aParam.val = xy[i];
349 //// myStorage->updateParameter(aParam);
352 //// std::list<Slvs_hEntity>::iterator aPtIt = aPointsToFix.begin();
353 //// for (; aNbPointsToFix > 0; aPtIt++, aNbPointsToFix--)
354 //// fixPoint(*aPtIt);
356 //// if (isFixRadius) {
357 //// // Fix radius of the arc
358 //// bool isExists = false;
359 //// std::list<Slvs_Constraint> aDiamConstraints = myStorage->getConstraintsByType(SLVS_C_DIAMETER);
360 //// std::list<Slvs_Constraint>::iterator anIt = aDiamConstraints.begin();
361 //// for (; anIt != aDiamConstraints.end() && !isExists; anIt++)
362 //// if (anIt->entityA == theArc.h)
363 //// isExists = true;
364 //// if (!isExists) {
365 //// Slvs_Constraint aFixedR = Slvs_MakeConstraint(SLVS_E_UNKNOWN, myGroup->getId(), SLVS_C_DIAMETER,
366 //// myGroup->getWorkplaneId(), aRadius * 2.0, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN,
367 //// myFeatureMap.begin()->second, SLVS_E_UNKNOWN);
368 //// aFixedR.h = myStorage->addConstraint(aFixedR);
369 //// mySlvsConstraints.push_back(aFixedR.h);
370 //// if (!myBaseConstraint)
371 //// myStorage->addConstraintWhereDragged(aFixedR.h);