1 #include <SketchSolver_ConstraintMovement.h>
2 #include <SketchSolver_Error.h>
3 #include <SketchSolver_Group.h>
5 #include <SketchPlugin_Arc.h>
6 #include <SketchPlugin_Circle.h>
7 #include <SketchPlugin_Line.h>
8 #include <SketchPlugin_Point.h>
10 SketchSolver_ConstraintMovement::SketchSolver_ConstraintMovement(FeaturePtr theFeature)
11 : SketchSolver_ConstraintRigid(theFeature)
16 void SketchSolver_ConstraintMovement::process()
19 if (!myBaseFeature || !myStorage || myGroup == 0) {
20 /// TODO: Put error message here
23 if (!mySlvsConstraints.empty()) // some data is changed, update constraint
24 update(myBaseConstraint);
27 std::vector<Slvs_hEntity> anEntities;
29 getAttributes(aValue, anEntities, isFullyMoved);
30 if (!myErrorMsg.empty() || (myFeatureMap.empty() && myAttributeMap.empty()))
36 std::vector<Slvs_hEntity>::iterator anEntIt = anEntities.begin();
37 for (; anEntIt != anEntities.end(); ++anEntIt)
43 void SketchSolver_ConstraintMovement::getAttributes(
45 std::vector<Slvs_hEntity>& theAttributes,
46 bool& theIsFullyMoved)
48 bool isComplexFeature = false;
50 theIsFullyMoved = true;
51 int aType = SLVS_E_UNKNOWN; // type of created entity
52 Slvs_hEntity anEntityID = SLVS_E_UNKNOWN;
53 Slvs_hEntity anEntMaxID = myStorage->entityMaxID();
54 anEntityID = myGroup->getFeatureId(myBaseFeature);
55 if (anEntityID == SLVS_E_UNKNOWN) {
56 anEntityID = changeEntity(myBaseFeature, aType);
57 if (anEntityID == SLVS_E_UNKNOWN) {
58 myErrorMsg = SketchSolver_Error::NOT_INITIALIZED();
62 // Check the entity is complex
63 Slvs_Entity anEntity = myStorage->getEntity(anEntityID);
64 if (anEntity.point[0] != SLVS_E_UNKNOWN)
65 isComplexFeature = true;
67 theAttributes.push_back(anEntityID);
70 myFeatureMap[myBaseFeature] = anEntityID;
71 isComplexFeature = true;
74 int aNbOutOfGroup = 0;
75 if (isComplexFeature) {
76 std::list<AttributePtr> aPoints =
77 myBaseFeature->data()->attributes(GeomDataAPI_Point2D::typeId());
78 std::list<AttributePtr>::iterator anIt = aPoints.begin();
79 for (; anIt != aPoints.end(); ++anIt) {
80 std::map<AttributePtr, Slvs_hEntity>::const_iterator aFound = myAttributeMap.find(*anIt);
81 Slvs_hEntity anAttr = aFound != myAttributeMap.end() ?
82 aFound->second : myGroup->getAttributeId(*anIt);
83 Slvs_Entity anAttrEnt = myStorage->getEntity(anAttr);
85 // Check the attribute changes coordinates
86 std::shared_ptr<GeomDataAPI_Point2D> aPt =
87 std::dynamic_pointer_cast<GeomDataAPI_Point2D>(*anIt);
88 // Check the entity is not lying in the current group or it is not moved
89 if (anAttr == SLVS_E_UNKNOWN || anAttrEnt.group != myGroup->getId() ||
90 (anAttr <= anEntMaxID && !isMoved(aPt, anAttrEnt))) {
91 if (anAttrEnt.group == SLVS_G_OUTOFGROUP)
93 theIsFullyMoved = false;
96 theAttributes.push_back(anAttr);
97 // update point coordinates
98 Slvs_Entity anAttrEnt = myStorage->getEntity(anAttr);
99 double aNewPos[2] = {aPt->x(), aPt->y()};
100 for (int i = 0; i < 2; i++) {
101 Slvs_Param aParam = myStorage->getParameter(anAttrEnt.param[i]);
102 aParam.val = aNewPos[i];
103 myStorage->updateParameter(aParam);
109 // Additional checking, which leads to fix whole feature, if it has fixed points
110 if (!theIsFullyMoved) {
111 Slvs_Entity aFeature = myStorage->getEntity(anEntityID);
113 while (aNbPoints > 0 && aFeature.point[aNbPoints-1] == SLVS_E_UNKNOWN)
115 if (aNbPoints == aNbOutOfGroup + (int)theAttributes.size()) {
116 theIsFullyMoved = true;
121 // Leave only points which are used in constraints
122 if (myStorage->isUsedByConstraints(anEntityID))
124 std::vector<Slvs_hEntity>::iterator anIt = theAttributes.begin();
125 while (anIt != theAttributes.end()) {
126 if (myStorage->isUsedByConstraints(*anIt))
129 int aShift = anIt - theAttributes.begin();
130 theAttributes.erase(anIt);
131 anIt = theAttributes.begin() + aShift;
136 bool SketchSolver_ConstraintMovement::isMoved(
137 std::shared_ptr<GeomDataAPI_Point2D> thePoint, const Slvs_Entity& theEntity)
139 double aDeltaX = myStorage->getParameter(theEntity.param[0]).val;
140 double aDeltaY = myStorage->getParameter(theEntity.param[1]).val;
141 aDeltaX -= thePoint->x();
142 aDeltaY -= thePoint->y();
143 return aDeltaX * aDeltaX + aDeltaY * aDeltaY >= tolerance * tolerance;
146 void SketchSolver_ConstraintMovement::fixFeature()
148 Slvs_hEntity anEntID = fixedEntity();
151 std::map<FeaturePtr, Slvs_hEntity>::const_iterator aFIt = myFeatureMap.begin();
152 for (; aFIt != myFeatureMap.end() && aKind.empty(); ++aFIt)
153 if (aFIt->second == anEntID)
154 aKind = aFIt->first->getKind();
155 std::map<AttributePtr, Slvs_hEntity>::const_iterator anAtIt = myAttributeMap.begin();
156 for (; anAtIt != myAttributeMap.end() && aKind.empty(); ++anAtIt)
157 if (anAtIt->second == anEntID)
158 aKind = anAtIt->first->attributeType();
160 if (aKind == SketchPlugin_Line::ID()) {
161 Slvs_Entity aLine = myStorage->getEntity(anEntID);
164 else if (aKind == SketchPlugin_Arc::ID()) {
165 Slvs_Entity anArc = myStorage->getEntity(anEntID);
168 else if (aKind == SketchPlugin_Circle::ID()) {
169 Slvs_Entity aCirc = myStorage->getEntity(anEntID);
172 else if (aKind == SketchPlugin_Point::ID() || aKind == GeomDataAPI_Point2D::typeId()) {