]> SALOME platform Git repositories - modules/shaper.git/blob - src/SketchSolver/SketchSolver_ConstraintCoincidence.cpp
Salome HOME
Merge branch 'Dev_1.1.0' of newgeom:newgeom into Dev_1.1.0
[modules/shaper.git] / src / SketchSolver / SketchSolver_ConstraintCoincidence.cpp
1 #include <SketchSolver_ConstraintCoincidence.h>
2 #include <SketchSolver_Error.h>
3 #include <SketchSolver_Group.h>
4
5 #include <map>
6
7 bool SketchSolver_ConstraintCoincidence::hasConstraint(ConstraintPtr theConstraint) const
8 {
9   if (myBaseConstraint == theConstraint)
10     return true;
11   std::map<Slvs_hConstraint, ConstraintPtr>::const_iterator anIt = myExtraCoincidence.begin();
12   for (; anIt != myExtraCoincidence.end(); anIt++)
13     if (anIt->second == theConstraint)
14       return true;
15   return false;
16 }
17
18 std::list<ConstraintPtr> SketchSolver_ConstraintCoincidence::constraints() const
19 {
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);
25   return aConstraints;
26 }
27
28 bool SketchSolver_ConstraintCoincidence::isCoincide(
29     std::shared_ptr<SketchSolver_ConstraintCoincidence> theConstraint) const
30 {
31   std::set<AttributePtr>::const_iterator anAttrIter = theConstraint->myCoincidentPoints.begin();
32   for (; anAttrIter != theConstraint->myCoincidentPoints.end(); anAttrIter++)
33     if (myCoincidentPoints.find(*anAttrIter) != myCoincidentPoints.end())
34       return true;
35   return false;
36 }
37
38 void SketchSolver_ConstraintCoincidence::attach(
39     std::shared_ptr<SketchSolver_ConstraintCoincidence> theConstraint)
40 {
41   cleanErrorMsg();
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);
47
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);
54   }
55
56   // Copy data.
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();
66 }
67
68 Slvs_hConstraint SketchSolver_ConstraintCoincidence::addConstraint(
69     Slvs_hEntity thePoint1, Slvs_hEntity thePoint2)
70 {
71   Slvs_Constraint aNewConstraint = Slvs_MakeConstraint(SLVS_E_UNKNOWN, myGroup->getId(),
72       SLVS_C_POINTS_COINCIDENT, myGroup->getWorkplaneId(), 0.0, thePoint1, thePoint2, 
73       SLVS_E_UNKNOWN, SLVS_E_UNKNOWN);
74   Slvs_hConstraint aNewID = myStorage->addConstraint(aNewConstraint);
75   mySlvsConstraints.push_back(aNewID);
76   return aNewID;
77 }
78
79 void SketchSolver_ConstraintCoincidence::addConstraint(ConstraintPtr theConstraint)
80 {
81   std::list<AttributePtr> anAttrList =
82       theConstraint->data()->attributes(ModelAPI_AttributeRefAttr::typeId());
83   std::list<AttributePtr>::iterator anIter = anAttrList.begin();
84   std::vector<Slvs_hEntity> anEntities;
85   for (; anIter != anAttrList.end(); anIter++) {
86     AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anIter);
87     if (!aRefAttr || aRefAttr->isObject() ||
88         myAttributeMap.find(aRefAttr->attr()) != myAttributeMap.end())
89       continue;
90     int aType;
91     Slvs_hEntity anEntityID = myGroup->getAttributeId(aRefAttr->attr());
92     if (anEntityID == SLVS_E_UNKNOWN)
93       anEntityID = changeEntity(aRefAttr->attr(), aType);
94     anEntities.push_back(anEntityID);
95     myCoincidentPoints.insert(aRefAttr->attr());
96   }
97
98   Slvs_Constraint aBaseCoincidence = myStorage->getConstraint(mySlvsConstraints.front());
99   Slvs_hConstraint aNewConstr = SLVS_E_UNKNOWN;
100   std::vector<Slvs_hEntity>::iterator anEntIter = anEntities.begin();
101   for (; anEntIter != anEntities.end(); anEntIter++)
102     aNewConstr = addConstraint(aBaseCoincidence.ptA, *anEntIter);
103   myExtraCoincidence[aNewConstr] = theConstraint;
104 }
105
106 void SketchSolver_ConstraintCoincidence::process()
107 {
108   SketchSolver_Constraint::process();
109
110   // Fill the list of coincident points
111   std::list<AttributePtr> anAttrList =
112       myBaseConstraint->data()->attributes(ModelAPI_AttributeRefAttr::typeId());
113   std::list<AttributePtr>::iterator anIt = anAttrList.begin();
114   for (; anIt != anAttrList.end(); anIt++) {
115     AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anIt);
116     if (!aRefAttr || aRefAttr->isObject())
117       continue;
118     myCoincidentPoints.insert(aRefAttr->attr());
119   }
120 }
121
122 bool SketchSolver_ConstraintCoincidence::remove(ConstraintPtr theConstraint)
123 {
124   cleanErrorMsg();
125   if (mySlvsConstraints.empty())
126     return true;
127   ConstraintPtr aConstraint = theConstraint ? theConstraint : myBaseConstraint;
128   int aPos = -1; // position of constraint in the list (-1 for base constraint)
129   std::map<Slvs_hConstraint, ConstraintPtr>::iterator anExtraIt;
130   if (aConstraint != myBaseConstraint) {
131     anExtraIt = myExtraCoincidence.begin();
132     for (aPos = 0; anExtraIt != myExtraCoincidence.end(); anExtraIt++, aPos++)
133       if (anExtraIt->second == aConstraint)
134         break;
135     if (aPos >= (int)myExtraCoincidence.size())
136       return false; // there is no constraint, which is specified to remove
137     else {
138       bool isEmpty = anExtraIt->first == SLVS_E_UNKNOWN;
139       myExtraCoincidence.erase(anExtraIt);
140       if (isEmpty)
141         return false;
142     }
143   }
144
145   bool isFullyRemoved = myStorage->removeConstraint(mySlvsConstraints[aPos+1]);
146   mySlvsConstraints.erase(mySlvsConstraints.begin() + (1+aPos));
147   if (aPos < 0 && !myExtraCoincidence.empty()) {
148     anExtraIt = myExtraCoincidence.begin();
149     // Remove invalid constraints
150     while (anExtraIt != myExtraCoincidence.end()) {
151       if (!anExtraIt->second->data() || !anExtraIt->second->data()->isValid()) {
152         std::map<Slvs_hConstraint, ConstraintPtr>::iterator aTempIt = anExtraIt++;
153         if (aTempIt->first != SLVS_E_UNKNOWN) {
154           myStorage->removeConstraint(aTempIt->first);
155           std::vector<Slvs_hConstraint>::iterator anIt = mySlvsConstraints.begin();
156           for (; anIt != mySlvsConstraints.end(); anIt++)
157             if (*anIt == aTempIt->first) {
158               mySlvsConstraints.erase(anIt);
159               break;
160             }
161         }
162         myExtraCoincidence.erase(aTempIt);
163         continue;
164       }
165       anExtraIt++;
166     }
167     // Find first non-extra conststraint
168     while (anExtraIt != myExtraCoincidence.end() && anExtraIt->first == SLVS_E_UNKNOWN)
169       anExtraIt++;
170     if (anExtraIt != myExtraCoincidence.end()) {
171       // Need to specify another base coincidence constraint
172       myBaseConstraint = anExtraIt->second;
173       myExtraCoincidence.erase(anExtraIt);
174       std::vector<Slvs_hConstraint>::iterator aCIter = mySlvsConstraints.begin();
175       Slvs_Constraint aBase = myStorage->getConstraint(*aCIter);
176       for (++aCIter; aCIter != mySlvsConstraints.end(); aCIter++) {
177         Slvs_Constraint aConstr = myStorage->getConstraint(*aCIter);
178         aConstr.ptA = aBase.ptA;
179         myStorage->updateConstraint(aConstr);
180       }
181     }
182   }
183   // Clear removed attributes
184   std::set<Slvs_hParam> aParamRemoved;
185   std::set<Slvs_hEntity> anEntRemoved;
186   std::set<Slvs_hConstraint> aConstrRemoved;
187   myStorage->getRemoved(aParamRemoved, anEntRemoved, aConstrRemoved);
188   std::map<AttributePtr, Slvs_hEntity>::iterator anAttrIter = myAttributeMap.begin();
189   while (anAttrIter != myAttributeMap.end()) {
190     if (anEntRemoved.find(anAttrIter->second) != anEntRemoved.end()) {
191       std::map<AttributePtr, Slvs_hEntity>::iterator aTempIt = anAttrIter++;
192       myCoincidentPoints.erase(aTempIt->first);
193       myAttributeMap.erase(aTempIt);
194       continue;
195     }
196     anAttrIter++;
197   }
198
199   // Go through remaining extra coincidence and try to add or remove them
200   anExtraIt = myExtraCoincidence.begin();
201   while (anExtraIt != myExtraCoincidence.end()) {
202     if (anExtraIt->first == SLVS_E_UNKNOWN) {
203       if (!anExtraIt->second->data() || !anExtraIt->second->data()->isValid()) {
204         std::map<Slvs_hConstraint, ConstraintPtr>::iterator aTempIt = anExtraIt++;
205         myExtraCoincidence.erase(aTempIt);
206         continue;
207       }
208       if (mySlvsConstraints.empty()) {
209         myBaseConstraint = anExtraIt->second;
210         std::map<Slvs_hConstraint, ConstraintPtr>::iterator aTempIt = anExtraIt++;
211         myExtraCoincidence.erase(aTempIt);
212         process();
213         continue;
214       } else
215         addConstraint(anExtraIt->second);
216     }
217     anExtraIt++;
218   }
219   return mySlvsConstraints.empty();
220 }
221