1 #include <SketchSolver_ConstraintCoincidence.h>
2 #include <SketchSolver_Error.h>
3 #include <SketchSolver_Group.h>
7 bool SketchSolver_ConstraintCoincidence::hasConstraint(ConstraintPtr theConstraint) const
9 if (myBaseConstraint == theConstraint)
11 std::map<Slvs_hConstraint, ConstraintPtr>::const_iterator anIt = myExtraCoincidence.begin();
12 for (; anIt != myExtraCoincidence.end(); anIt++)
13 if (anIt->second == theConstraint)
18 std::list<ConstraintPtr> SketchSolver_ConstraintCoincidence::constraints() const
20 std::list<ConstraintPtr> aConstraints;
21 aConstraints.push_back(myBaseConstraint);
22 std::map<Slvs_hConstraint, ConstraintPtr>::const_iterator anIt = myExtraCoincidence.begin();
23 for (; anIt != myExtraCoincidence.end(); anIt++)
24 aConstraints.push_back(anIt->second);
28 bool SketchSolver_ConstraintCoincidence::isCoincide(
29 std::shared_ptr<SketchSolver_ConstraintCoincidence> theConstraint) const
31 std::set<AttributePtr>::const_iterator anAttrIter = theConstraint->myCoincidentPoints.begin();
32 for (; anAttrIter != theConstraint->myCoincidentPoints.end(); anAttrIter++)
33 if (myCoincidentPoints.find(*anAttrIter) != myCoincidentPoints.end())
38 void SketchSolver_ConstraintCoincidence::attach(
39 std::shared_ptr<SketchSolver_ConstraintCoincidence> theConstraint)
42 Slvs_Constraint aBaseCoincidence = myStorage->getConstraint(mySlvsConstraints.front());
43 // Remove constraints from theConstraint
44 std::vector<Slvs_hConstraint>::iterator aCIter = theConstraint->mySlvsConstraints.begin();
45 for (; aCIter != theConstraint->mySlvsConstraints.end(); aCIter++)
46 theConstraint->myStorage->removeConstraint(*aCIter);
48 if (myStorage == theConstraint->myStorage) {
49 // Clean removed items
50 std::set<Slvs_hParam> aRemParams;
51 std::set<Slvs_hEntity> aRemEnts;
52 std::set<Slvs_hConstraint> aRemConstr;
53 theConstraint->myStorage->getRemoved(aRemParams, aRemEnts, aRemConstr);
57 addConstraint(theConstraint->myBaseConstraint);
58 std::map<Slvs_hConstraint, ConstraintPtr>::iterator aConstrIter =
59 theConstraint->myExtraCoincidence.begin();
60 for (; aConstrIter != theConstraint->myExtraCoincidence.end(); aConstrIter++)
61 addConstraint(aConstrIter->second);
62 // Clear the lists to not remove the entities on destruction
63 theConstraint->mySlvsConstraints.clear();
64 theConstraint->myFeatureMap.clear();
65 theConstraint->myAttributeMap.clear();
68 Slvs_hConstraint SketchSolver_ConstraintCoincidence::addConstraint(
69 Slvs_hEntity thePoint1, Slvs_hEntity thePoint2)
71 bool hasDuplicated = myStorage->hasDuplicatedConstraint();
72 Slvs_Constraint aNewConstraint = Slvs_MakeConstraint(SLVS_E_UNKNOWN, myGroup->getId(),
73 SLVS_C_POINTS_COINCIDENT, myGroup->getWorkplaneId(), 0.0, thePoint1, thePoint2,
74 SLVS_E_UNKNOWN, SLVS_E_UNKNOWN);
75 Slvs_hConstraint aNewID = myStorage->addConstraint(aNewConstraint);
76 if (!hasDuplicated && myStorage->hasDuplicatedConstraint()) {
77 // the duplicated constraint appears
78 myStorage->removeConstraint(aNewID);
79 return SLVS_E_UNKNOWN;
81 mySlvsConstraints.push_back(aNewID);
85 void SketchSolver_ConstraintCoincidence::addConstraint(ConstraintPtr theConstraint)
87 std::list<AttributePtr> anAttrList =
88 theConstraint->data()->attributes(ModelAPI_AttributeRefAttr::typeId());
89 std::list<AttributePtr>::iterator anIter = anAttrList.begin();
90 std::vector<Slvs_hEntity> anEntities;
91 for (; anIter != anAttrList.end(); anIter++) {
92 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anIter);
93 if (!aRefAttr || aRefAttr->isObject() ||
94 myAttributeMap.find(aRefAttr->attr()) != myAttributeMap.end())
97 Slvs_hEntity anEntityID = myGroup->getAttributeId(aRefAttr->attr());
98 if (anEntityID == SLVS_E_UNKNOWN)
99 anEntityID = changeEntity(aRefAttr->attr(), aType);
100 anEntities.push_back(anEntityID);
101 myCoincidentPoints.insert(aRefAttr->attr());
104 Slvs_Constraint aBaseCoincidence = myStorage->getConstraint(mySlvsConstraints.front());
105 Slvs_hConstraint aNewConstr = SLVS_E_UNKNOWN;
106 std::vector<Slvs_hEntity>::iterator anEntIter = anEntities.begin();
107 for (; anEntIter != anEntities.end(); anEntIter++)
108 aNewConstr = addConstraint(aBaseCoincidence.ptA, *anEntIter);
109 myExtraCoincidence[aNewConstr] = theConstraint;
112 void SketchSolver_ConstraintCoincidence::process()
114 SketchSolver_Constraint::process();
116 // Fill the list of coincident points
117 std::list<AttributePtr> anAttrList =
118 myBaseConstraint->data()->attributes(ModelAPI_AttributeRefAttr::typeId());
119 std::list<AttributePtr>::iterator anIt = anAttrList.begin();
120 for (; anIt != anAttrList.end(); anIt++) {
121 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anIt);
122 if (!aRefAttr || aRefAttr->isObject())
124 myCoincidentPoints.insert(aRefAttr->attr());
128 bool SketchSolver_ConstraintCoincidence::remove(ConstraintPtr theConstraint)
131 if (mySlvsConstraints.empty())
133 ConstraintPtr aConstraint = theConstraint ? theConstraint : myBaseConstraint;
134 int aPos = -1; // position of constraint in the list (-1 for base constraint)
135 std::map<Slvs_hConstraint, ConstraintPtr>::iterator anExtraIt;
136 if (aConstraint != myBaseConstraint) {
137 anExtraIt = myExtraCoincidence.begin();
138 for (aPos = 0; anExtraIt != myExtraCoincidence.end(); anExtraIt++, aPos++)
139 if (anExtraIt->second == aConstraint)
141 if (aPos >= (int)myExtraCoincidence.size())
142 return false; // there is no constraint, which is specified to remove
144 bool isEmpty = anExtraIt->first == SLVS_E_UNKNOWN;
145 myExtraCoincidence.erase(anExtraIt);
151 bool isFullyRemoved = myStorage->removeConstraint(mySlvsConstraints[aPos+1]);
152 mySlvsConstraints.erase(mySlvsConstraints.begin() + (1+aPos));
153 if (aPos < 0 && !myExtraCoincidence.empty()) {
154 anExtraIt = myExtraCoincidence.begin();
155 // Remove invalid constraints
156 while (anExtraIt != myExtraCoincidence.end()) {
157 if (!anExtraIt->second->data() || !anExtraIt->second->data()->isValid()) {
158 std::map<Slvs_hConstraint, ConstraintPtr>::iterator aTempIt = anExtraIt++;
159 if (aTempIt->first != SLVS_E_UNKNOWN) {
160 myStorage->removeConstraint(aTempIt->first);
161 std::vector<Slvs_hConstraint>::iterator anIt = mySlvsConstraints.begin();
162 for (; anIt != mySlvsConstraints.end(); anIt++)
163 if (*anIt == aTempIt->first) {
164 mySlvsConstraints.erase(anIt);
168 myExtraCoincidence.erase(aTempIt);
173 // Find first non-extra conststraint
174 anExtraIt = myExtraCoincidence.begin();
175 while (anExtraIt != myExtraCoincidence.end() && anExtraIt->first == SLVS_E_UNKNOWN)
177 if (anExtraIt != myExtraCoincidence.end()) {
178 // Need to specify another base coincidence constraint
179 myBaseConstraint = anExtraIt->second;
180 myExtraCoincidence.erase(anExtraIt);
181 std::vector<Slvs_hConstraint>::iterator aCIter = mySlvsConstraints.begin();
182 Slvs_Constraint aBase = myStorage->getConstraint(*aCIter);
183 for (++aCIter; aCIter != mySlvsConstraints.end(); aCIter++) {
184 Slvs_Constraint aConstr = myStorage->getConstraint(*aCIter);
185 aConstr.ptA = aBase.ptA;
186 myStorage->updateConstraint(aConstr);
190 // Clear removed attributes
191 std::set<Slvs_hParam> aParamRemoved;
192 std::set<Slvs_hEntity> anEntRemoved;
193 std::set<Slvs_hConstraint> aConstrRemoved;
194 myStorage->getRemoved(aParamRemoved, anEntRemoved, aConstrRemoved);
195 std::map<AttributePtr, Slvs_hEntity>::iterator anAttrIter = myAttributeMap.begin();
196 while (anAttrIter != myAttributeMap.end()) {
197 if (anEntRemoved.find(anAttrIter->second) != anEntRemoved.end()) {
198 std::map<AttributePtr, Slvs_hEntity>::iterator aTempIt = anAttrIter++;
199 myCoincidentPoints.erase(aTempIt->first);
200 myAttributeMap.erase(aTempIt);
206 // Go through remaining extra coincidence and try to add or remove them
207 anExtraIt = myExtraCoincidence.begin();
208 while (anExtraIt != myExtraCoincidence.end()) {
209 if (anExtraIt->first == SLVS_E_UNKNOWN) {
210 if (!anExtraIt->second->data() || !anExtraIt->second->data()->isValid()) {
211 std::map<Slvs_hConstraint, ConstraintPtr>::iterator aTempIt = anExtraIt++;
212 myExtraCoincidence.erase(aTempIt);
215 if (mySlvsConstraints.empty()) {
216 myBaseConstraint = anExtraIt->second;
217 std::map<Slvs_hConstraint, ConstraintPtr>::iterator aTempIt = anExtraIt++;
218 myExtraCoincidence.erase(aTempIt);
222 addConstraint(anExtraIt->second);
226 return mySlvsConstraints.empty();