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 AttributePtr anAttr = myBaseConstraint->attribute(SketchPlugin_ConstraintRigid::ENTITY_A());
123 AttributeRefAttrPtr aRefAttr =
124 std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(anAttr);
125 if (!aRefAttr || !aRefAttr->isInitialized()) {
126 myErrorMsg = SketchSolver_Error::NOT_INITIALIZED();
130 myStorage->update(anAttr, myGroupID);
131 aSolverEntity = myStorage->entity(anAttr);
133 myErrorMsg = SketchSolver_Error::NOT_INITIALIZED();
136 theAttributes.push_back(aSolverEntity);
140 bool SketchSolver_ConstraintFixed::remove()
143 // Move fixed entities back to the current group
144 FeaturePtr aFeature = myBaseFeature;
145 if (myBaseConstraint && myFixedAttribute && myFixedAttribute->isObject())
146 aFeature = ModelAPI_Feature::feature(myFixedAttribute->object());
148 myStorage->update(aFeature, myGroupID);
150 // Remove constraint or base feature
151 if (myBaseConstraint) {
152 bool isRemoved = false;
154 isRemoved = myStorage->removeEntity(aFeature);
155 return SketchSolver_Constraint::remove() || isRemoved;
156 } else if (myBaseFeature)
157 myStorage->removeEntity(myBaseFeature);
161 ////Slvs_hConstraint SketchSolver_ConstraintFixed::fixPoint(const Slvs_hEntity& thePointID)
163 //// if (thePointID == SLVS_E_UNKNOWN)
164 //// return SLVS_C_UNKNOWN;
166 //// Slvs_Constraint aConstraint;
167 //// Slvs_hConstraint aConstrID = SLVS_E_UNKNOWN;
168 //// bool isFixed = myStorage->isPointFixed(thePointID, aConstrID, true);
169 //// bool isForceUpdate = (isFixed && !myBaseConstraint &&
170 //// myStorage->isTemporary(aConstrID));
171 //// if (!isForceUpdate) { // create new constraint
172 //// if (isFixed) return aConstrID;
173 //// aConstraint = Slvs_MakeConstraint(SLVS_C_UNKNOWN, myGroup->getId(), getType(), myGroup->getWorkplaneId(),
174 //// 0.0, thePointID, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN);
175 //// aConstraint.h = myStorage->addConstraint(aConstraint);
176 //// mySlvsConstraints.push_back(aConstraint.h);
177 //// if (!myBaseConstraint)
178 //// myStorage->addConstraintWhereDragged(aConstraint.h);
179 //// } else { // update already existent constraint
180 //// if (!isFixed || aConstrID == SLVS_C_UNKNOWN || myBaseConstraint)
181 //// return SLVS_C_UNKNOWN;
182 //// aConstraint = myStorage->getConstraint(aConstrID);
183 //// aConstraint.ptA = thePointID;
184 //// myStorage->addConstraint(aConstraint);
185 //// if (!myBaseConstraint)
186 //// myStorage->addConstraintWhereDragged(aConstraint.h);
188 //// return aConstraint.h;
191 ////void SketchSolver_ConstraintFixed::fixLine(const Slvs_Entity& theLine)
193 //// Slvs_Constraint anEqual;
194 //// if (myStorage->isAxisParallel(theLine.h)) {
195 //// // Fix one point and a line length
196 //// Slvs_hConstraint aFixed;
197 //// if (!myStorage->isPointFixed(theLine.point[0], aFixed, true) &&
198 //// !myStorage->isPointFixed(theLine.point[1], aFixed, true))
199 //// fixPoint(theLine.point[0]);
200 //// if (!myStorage->isUsedInEqual(theLine.h, anEqual)) {
201 //// // Check the distance is not set yet
202 //// std::list<Slvs_Constraint> aDistConstr = myStorage->getConstraintsByType(SLVS_C_PT_PT_DISTANCE);
203 //// std::list<Slvs_Constraint>::const_iterator aDIt = aDistConstr.begin();
204 //// for (; aDIt != aDistConstr.end(); aDIt++)
205 //// if ((aDIt->ptA == theLine.point[0] && aDIt->ptB == theLine.point[1]) ||
206 //// (aDIt->ptA == theLine.point[1] && aDIt->ptB == theLine.point[0]))
208 //// // Calculate distance between points on the line
209 //// double aCoords[4];
210 //// for (int i = 0; i < 2; i++) {
211 //// Slvs_Entity aPnt = myStorage->getEntity(theLine.point[i]);
212 //// for (int j = 0; j < 2; j++) {
213 //// Slvs_Param aParam = myStorage->getParameter(aPnt.param[j]);
214 //// aCoords[2*i+j] = aParam.val;
217 //// double aLength = sqrt((aCoords[2] - aCoords[0]) * (aCoords[2] - aCoords[0]) +
218 //// (aCoords[3] - aCoords[1]) * (aCoords[3] - aCoords[1]));
219 //// // fix line length
220 //// Slvs_Constraint aDistance = Slvs_MakeConstraint(SLVS_E_UNKNOWN, myGroup->getId(),
221 //// SLVS_C_PT_PT_DISTANCE, myGroup->getWorkplaneId(), aLength,
222 //// theLine.point[0], theLine.point[1], SLVS_E_UNKNOWN, SLVS_E_UNKNOWN);
223 //// aDistance.h = myStorage->addConstraint(aDistance);
224 //// mySlvsConstraints.push_back(aDistance.h);
228 //// else if (myStorage->isUsedInEqual(theLine.h, anEqual)) {
229 //// // Check another entity of Equal is already fixed
230 //// Slvs_hEntity anOtherEntID = anEqual.entityA == theLine.h ? anEqual.entityB : anEqual.entityA;
231 //// if (myStorage->isEntityFixed(anOtherEntID, true)) {
232 //// // Fix start point of the line (if end point is not fixed yet) ...
233 //// Slvs_hConstraint anEndFixedID = SLVS_E_UNKNOWN;
234 //// bool isFixed = myStorage->isPointFixed(theLine.point[1], anEndFixedID, true);
235 //// if (isFixed == SLVS_E_UNKNOWN)
236 //// fixPoint(theLine.point[0]);
237 //// // ... and create fixed point lying on this line
238 //// Slvs_hEntity aPointToCopy = anEndFixedID == SLVS_E_UNKNOWN ? theLine.point[1] : theLine.point[0];
239 //// // Firstly, search already fixed point on line
240 //// bool isPonLineFixed = false;
241 //// Slvs_hEntity aFixedPoint;
242 //// std::list<Slvs_Constraint> aPonLineList = myStorage->getConstraintsByType(SLVS_C_PT_ON_LINE);
243 //// std::list<Slvs_Constraint>::const_iterator aPLIter = aPonLineList.begin();
244 //// for (; aPLIter != aPonLineList.end() && !isPonLineFixed; aPLIter++)
245 //// if (aPLIter->entityA == theLine.h) {
246 //// isPonLineFixed = myStorage->isPointFixed(aPLIter->ptA, anEndFixedID);
247 //// aFixedPoint = aPLIter->ptA;
250 //// if (isPonLineFixed) { // update existent constraint
251 //// myStorage->copyEntity(aPointToCopy, aFixedPoint);
252 //// } else { // create new constraint
253 //// Slvs_hEntity aCopied = myStorage->copyEntity(aPointToCopy);
254 //// Slvs_Constraint aPonLine = Slvs_MakeConstraint(SLVS_E_UNKNOWN, myGroup->getId(), SLVS_C_PT_ON_LINE,
255 //// myGroup->getWorkplaneId(), 0.0, aCopied, SLVS_E_UNKNOWN, theLine.h, SLVS_E_UNKNOWN);
256 //// aPonLine.h = myStorage->addConstraint(aPonLine);
257 //// mySlvsConstraints.push_back(aPonLine.h);
258 //// fixPoint(aCopied);
264 //// for (int i = 0; i < 2; i++)
265 //// fixPoint(theLine.point[i]);
268 ////void SketchSolver_ConstraintFixed::fixCircle(const Slvs_Entity& theCircle)
270 //// bool isFixRadius = true;
271 //// // Verify the arc is under Equal constraint
272 //// Slvs_Constraint anEqual;
273 //// if (myStorage->isUsedInEqual(theCircle.h, anEqual)) {
274 //// // Check another entity of Equal is already fixed
275 //// Slvs_hEntity anOtherEntID = anEqual.entityA == theCircle.h ? anEqual.entityB : anEqual.entityA;
276 //// if (myStorage->isEntityFixed(anOtherEntID, true))
277 //// isFixRadius = false;
280 //// fixPoint(theCircle.point[0]);
282 //// if (isFixRadius) {
283 //// // Search the radius is already fixed
284 //// std::list<Slvs_Constraint> aDiamConstr = myStorage->getConstraintsByType(SLVS_C_DIAMETER);
285 //// std::list<Slvs_Constraint>::const_iterator aDiamIter = aDiamConstr.begin();
286 //// for (; aDiamIter != aDiamConstr.end(); aDiamIter++)
287 //// if (aDiamIter->entityA == theCircle.h)
290 //// // Fix radius of a circle
291 //// AttributeDoublePtr aRadiusAttr = std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(
292 //// myFeatureMap.begin()->first->attribute(SketchPlugin_Circle::RADIUS_ID()));
293 //// Slvs_Constraint aFixedR = Slvs_MakeConstraint(SLVS_E_UNKNOWN, myGroup->getId(), SLVS_C_DIAMETER,
294 //// myGroup->getWorkplaneId(), aRadiusAttr->value() * 2.0, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN,
295 //// myFeatureMap.begin()->second, SLVS_E_UNKNOWN);
296 //// aFixedR.h = myStorage->addConstraint(aFixedR);
297 //// mySlvsConstraints.push_back(aFixedR.h);
301 ////void SketchSolver_ConstraintFixed::fixArc(const Slvs_Entity& theArc)
303 //// bool isFixRadius = true;
304 //// std::list<Slvs_hEntity> aPointsToFix;
305 //// aPointsToFix.push_back(theArc.point[1]);
306 //// aPointsToFix.push_back(theArc.point[2]);
308 //// // Verify the arc is under Equal constraint
309 //// Slvs_Constraint anEqual;
310 //// if (myStorage->isUsedInEqual(theArc.h, anEqual)) {
311 //// // Check another entity of Equal is already fixed
312 //// Slvs_hEntity anOtherEntID = anEqual.entityA == theArc.h ? anEqual.entityB : anEqual.entityA;
313 //// if (myStorage->isEntityFixed(anOtherEntID, true)) {
314 //// isFixRadius = false;
315 //// Slvs_Entity anOtherEntity = myStorage->getEntity(anOtherEntID);
316 //// if (anOtherEntity.type == SLVS_E_LINE_SEGMENT) {
317 //// aPointsToFix.pop_back();
318 //// aPointsToFix.push_back(theArc.point[0]);
323 //// Slvs_hConstraint aConstrID;
324 //// int aNbPointsToFix = 2; // number of fixed points for the arc
325 //// if (myStorage->isPointFixed(theArc.point[0], aConstrID, true))
326 //// aNbPointsToFix--;
328 //// // Radius of the arc
329 //// FeaturePtr aFeature = myFeatureMap.begin()->first;
330 //// std::shared_ptr<GeomAPI_Pnt2d> aCenter = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
331 //// aFeature->attribute(SketchPlugin_Arc::CENTER_ID()))->pnt();
332 //// std::shared_ptr<GeomAPI_Pnt2d> aStart = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
333 //// aFeature->attribute(SketchPlugin_Arc::START_ID()))->pnt();
334 //// double aRadius = aCenter->distance(aStart);
336 //// // Update end point of the arc to be on a curve
337 //// std::shared_ptr<GeomAPI_Pnt2d> anEnd = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
338 //// aFeature->attribute(SketchPlugin_Arc::END_ID()))->pnt();
339 //// double aDistance = anEnd->distance(aCenter);
340 //// std::shared_ptr<GeomAPI_XY> aDir = anEnd->xy()->decreased(aCenter->xy());
341 //// if (aDistance < tolerance)
342 //// aDir = aStart->xy()->decreased(aCenter->xy())->multiplied(-1.0);
344 //// aDir = aDir->multiplied(aRadius / aDistance);
345 //// double xy[2] = {aCenter->x() + aDir->x(), aCenter->y() + aDir->y()};
346 //// Slvs_Entity aEndPoint = myStorage->getEntity(theArc.point[2]);
347 //// for (int i = 0; i < 2; i++) {
348 //// Slvs_Param aParam = myStorage->getParameter(aEndPoint.param[i]);
349 //// aParam.val = xy[i];
350 //// myStorage->updateParameter(aParam);
353 //// std::list<Slvs_hEntity>::iterator aPtIt = aPointsToFix.begin();
354 //// for (; aNbPointsToFix > 0; aPtIt++, aNbPointsToFix--)
355 //// fixPoint(*aPtIt);
357 //// if (isFixRadius) {
358 //// // Fix radius of the arc
359 //// bool isExists = false;
360 //// std::list<Slvs_Constraint> aDiamConstraints = myStorage->getConstraintsByType(SLVS_C_DIAMETER);
361 //// std::list<Slvs_Constraint>::iterator anIt = aDiamConstraints.begin();
362 //// for (; anIt != aDiamConstraints.end() && !isExists; anIt++)
363 //// if (anIt->entityA == theArc.h)
364 //// isExists = true;
365 //// if (!isExists) {
366 //// Slvs_Constraint aFixedR = Slvs_MakeConstraint(SLVS_E_UNKNOWN, myGroup->getId(), SLVS_C_DIAMETER,
367 //// myGroup->getWorkplaneId(), aRadius * 2.0, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN,
368 //// myFeatureMap.begin()->second, SLVS_E_UNKNOWN);
369 //// aFixedR.h = myStorage->addConstraint(aFixedR);
370 //// mySlvsConstraints.push_back(aFixedR.h);
371 //// if (!myBaseConstraint)
372 //// myStorage->addConstraintWhereDragged(aFixedR.h);