Salome HOME
SketchSolver library refactoring
[modules/shaper.git] / src / SketchSolver / SketchSolver_FeatureStorage.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
2
3 // File:    SketchSolver_FeatureStorage.cpp
4 // Created: 23 Mar 2015
5 // Author:  Artem ZHIDKOV
6
7 #include <SketchSolver_FeatureStorage.h>
8
9 #include <ModelAPI_AttributeRefAttr.h>
10 #include <ModelAPI_AttributeRefList.h>
11 #include <ModelAPI_ResultConstruction.h>
12
13 void SketchSolver_FeatureStorage::changeConstraint(ConstraintPtr theConstraint)
14 {
15   std::list<AttributePtr> anAttributes = theConstraint->data()->attributes(std::string());
16   std::list<AttributePtr>::iterator anIter = anAttributes.begin();
17   for (; anIter != anAttributes.end(); anIter++) {
18     AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anIter);
19     if (aRefAttr) {
20       if (!aRefAttr->isObject()) {
21         changeAttribute(aRefAttr->attr(), theConstraint);
22         continue;
23       }
24       ResultConstructionPtr aRC = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(
25           aRefAttr->object());
26       FeaturePtr aFeature = aRC ? aRC->document()->feature(aRC) :
27           std::dynamic_pointer_cast<ModelAPI_Feature>(aRefAttr->object());
28       if (aFeature)
29         changeFeature(aFeature, theConstraint);
30       continue;
31     }
32     AttributeRefListPtr aRefList = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(*anIter);
33     if (aRefList) {
34       std::list<ObjectPtr> aList = aRefList->list();
35       std::list<ObjectPtr>::iterator aListIter = aList.begin();
36       for (; aListIter != aList.end(); aListIter++) {
37         ResultConstructionPtr aRC = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(
38             *aListIter);
39         FeaturePtr aFeature = aRC ? aRC->document()->feature(aRC) :
40             std::dynamic_pointer_cast<ModelAPI_Feature>(*aListIter);
41         if (aFeature)
42           changeFeature(aFeature, theConstraint);
43       }
44       continue;
45     }
46     changeAttribute(*anIter, theConstraint);
47   }
48   myConstraints.insert(theConstraint);
49 }
50
51 void SketchSolver_FeatureStorage::removeConstraint(ConstraintPtr theConstraint)
52 {
53   DataPtr aData = theConstraint->data();
54   if (aData) { // Constraint has data. Iterate through its attributes and remove them
55     std::list<AttributePtr> anAttributes = aData->attributes(std::string());
56     std::list<AttributePtr>::iterator anIter = anAttributes.begin();
57     for (; anIter != anAttributes.end(); anIter++) {
58       AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anIter);
59       if (aRefAttr) {
60         if (!aRefAttr->isObject()) {
61           removeAttribute(aRefAttr->attr(), theConstraint);
62           continue;
63         }
64         ResultConstructionPtr aRC = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(
65             aRefAttr->object());
66         FeaturePtr aFeature = aRC ? aRC->document()->feature(aRC) :
67             std::dynamic_pointer_cast<ModelAPI_Feature>(aRefAttr->object());
68         if (aFeature)
69           removeFeature(aFeature, theConstraint);
70         continue;
71       }
72       AttributeRefListPtr aRefList = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(*anIter);
73       if (aRefList) {
74         std::list<ObjectPtr> aList = aRefList->list();
75         std::list<ObjectPtr>::iterator aListIter = aList.begin();
76         for (; aListIter != aList.end(); aListIter++) {
77           ResultConstructionPtr aRC = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(
78               *aListIter);
79           FeaturePtr aFeature = aRC ? aRC->document()->feature(aRC) :
80               std::dynamic_pointer_cast<ModelAPI_Feature>(*aListIter);
81           if (aFeature)
82             removeFeature(aFeature, theConstraint);
83         }
84         continue;
85       }
86       removeAttribute(*anIter, theConstraint);
87     }
88   } else { // Constraint has no data. Search the links on it in the lists of back references for features and attributes
89     std::set<ConstraintPtr>::iterator aCIter;
90     MapFeatureConstraint::iterator aFeatIter = myFeatures.begin();
91     while (aFeatIter != myFeatures.end()) {
92       aCIter = aFeatIter->second.find(theConstraint);
93       if (aCIter != aFeatIter->second.end()) {
94         aFeatIter->second.erase(aCIter);
95         if (aFeatIter->second.empty()) {
96           MapFeatureConstraint::iterator aTmpIter = aFeatIter; // stores iterator for the next element, while the current is deleting
97           aTmpIter++;
98           myFeatures.erase(aFeatIter);
99           aFeatIter = aTmpIter;
100           continue;
101         }
102       }
103       aFeatIter++;
104     }
105     std::set<FeaturePtr>::iterator aFIter;
106     MapAttributeFeature::iterator anAttrIter = myAttributes.begin();
107     while (anAttrIter != myAttributes.end()) {
108       aFIter = anAttrIter->second.find(theConstraint);
109       if (aFIter != anAttrIter->second.end()) {
110         anAttrIter->second.erase(aFIter);
111         if (anAttrIter->second.empty()) {
112           MapAttributeFeature::iterator aTmpIter = anAttrIter; // stores iterator for the next element, while the current is deleting
113           aTmpIter++;
114           myAttributes.erase(anAttrIter);
115           anAttrIter = aTmpIter;
116           continue;
117         }
118       }
119       anAttrIter++;
120     }
121   }
122   myConstraints.erase(theConstraint);
123 }
124
125 bool SketchSolver_FeatureStorage::isInteract(ConstraintPtr theConstraint) const
126 {
127   if (myConstraints.empty() || myConstraints.find(theConstraint) != myConstraints.end())
128     return true;
129
130   DataPtr aData = theConstraint->data();
131   if (!aData)
132     return false;
133
134   std::list<AttributePtr> anAttributes = aData->attributes(std::string());
135   std::list<AttributePtr>::iterator anIter = anAttributes.begin();
136   for (; anIter != anAttributes.end(); anIter++) {
137     AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anIter);
138     if (aRefAttr) {
139       if (!aRefAttr->isObject()) {
140         if (isInteract(aRefAttr->attr()))
141           return true;
142         continue;
143       }
144       ResultConstructionPtr aRC = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(
145           aRefAttr->object());
146       FeaturePtr aFeature = aRC ? aRC->document()->feature(aRC) :
147           std::dynamic_pointer_cast<ModelAPI_Feature>(aRefAttr->object());
148       if (aFeature)
149         if (isInteract(aFeature))
150           return true;
151       continue;
152     }
153     AttributeRefListPtr aRefList = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(*anIter);
154     if (aRefList) {
155       std::list<ObjectPtr> aList = aRefList->list();
156       std::list<ObjectPtr>::iterator aListIter = aList.begin();
157       for (; aListIter != aList.end(); aListIter++) {
158         ResultConstructionPtr aRC = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(
159             *aListIter);
160         FeaturePtr aFeature = aRC ? aRC->document()->feature(aRC) :
161             std::dynamic_pointer_cast<ModelAPI_Feature>(*aListIter);
162         if (aFeature)
163           if (isInteract(aFeature))
164             return true;
165       }
166       continue;
167     }
168     if (isInteract(*anIter))
169       return true;
170   }
171   return false;
172 }
173
174
175 void SketchSolver_FeatureStorage::changeFeature(FeaturePtr theFeature)
176 {
177   std::list<AttributePtr> anAttributes = theFeature->data()->attributes(std::string());
178   std::list<AttributePtr>::iterator anIter = anAttributes.begin();
179   for (; anIter != anAttributes.end(); anIter++) {
180     AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anIter);
181     if (aRefAttr) {
182       if (!aRefAttr->isObject())
183         changeAttribute(aRefAttr->attr(), theFeature);
184       continue;
185     }
186     changeAttribute(*anIter, theFeature);
187   }
188   if (myFeatures.find(theFeature) == myFeatures.end())
189     myFeatures[theFeature] = std::set<ConstraintPtr>();
190 }
191
192 void SketchSolver_FeatureStorage::changeFeature(FeaturePtr theFeature, ConstraintPtr theConstraint)
193 {
194   // Change all attributes of the feature
195   changeFeature(theFeature);
196   // Add back reference feature to constraint
197   myFeatures[theFeature].insert(theConstraint);
198 }
199
200 void SketchSolver_FeatureStorage::removeFeature(FeaturePtr theFeature)
201 {
202   MapFeatureConstraint::iterator aFeatIter = myFeatures.find(theFeature);
203   if (aFeatIter != myFeatures.end())
204     return; // no such feature
205
206   std::set<ConstraintPtr> aConstraints = aFeatIter->second;
207   std::set<ConstraintPtr>::iterator aCIter = aConstraints.begin();
208   for (; aCIter != aConstraints.end(); aCIter++)
209     removeFeature(theFeature, *aCIter);
210 }
211
212 void SketchSolver_FeatureStorage::removeFeature(FeaturePtr theFeature, ConstraintPtr theConstraint)
213 {
214   MapFeatureConstraint::iterator aFeatIter = myFeatures.find(theFeature);
215   if (aFeatIter != myFeatures.end())
216     return; // no such feature
217
218   std::list<AttributePtr> anAttributes = theFeature->data()->attributes(std::string());
219   std::list<AttributePtr>::iterator anIter = anAttributes.begin();
220   for (; anIter != anAttributes.end(); anIter++) {
221     AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anIter);
222     if (aRefAttr) {
223       if (!aRefAttr->isObject())
224         removeAttribute(aRefAttr->attr(), theFeature);
225       continue;
226     }
227     removeAttribute(*anIter, theFeature);
228   }
229
230   aFeatIter->second.erase(theConstraint);
231   if (aFeatIter->second.empty())
232     myFeatures.erase(aFeatIter);
233 }
234
235 bool SketchSolver_FeatureStorage::isInteract(FeaturePtr theFeature) const
236 {
237   if (myFeatures.find(theFeature) != myFeatures.end())
238     return true;
239
240   std::list<AttributePtr> anAttributes = theFeature->data()->attributes(std::string());
241   std::list<AttributePtr>::iterator anIter = anAttributes.begin();
242   for (; anIter != anAttributes.end(); anIter++) {
243     AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anIter);
244     if (aRefAttr) {
245       if (!aRefAttr->isObject())
246         if (isInteract(aRefAttr->attr()))
247           return true;
248       continue;
249     }
250     if (isInteract(*anIter))
251       return true;
252   }
253   return false;
254 }
255
256
257 void SketchSolver_FeatureStorage::changeAttribute(AttributePtr theAttribute)
258 {
259   if (myAttributes.find(theAttribute) == myAttributes.end())
260     myAttributes[theAttribute] = std::set<FeaturePtr>();
261 }
262
263 void SketchSolver_FeatureStorage::changeAttribute(AttributePtr theAttribute, FeaturePtr theFeature)
264 {
265   MapAttributeFeature::iterator anAttrIter = myAttributes.find(theAttribute);
266   if (anAttrIter == myAttributes.end()) {
267     std::set<FeaturePtr> aFeatures;
268     aFeatures.insert(theFeature);
269     myAttributes[theAttribute] = aFeatures;
270     return;
271   }
272   anAttrIter->second.insert(theFeature);
273 }
274
275 void SketchSolver_FeatureStorage::removeAttribute(AttributePtr theAttribute)
276 {
277   MapAttributeFeature::iterator anAttrIter = myAttributes.find(theAttribute);
278   if (anAttrIter == myAttributes.end())
279     return;
280
281   std::set<FeaturePtr> aFeatures = anAttrIter->second;
282   std::set<FeaturePtr>::iterator aFeatIter = aFeatures.begin();
283   for (; aFeatIter != aFeatures.end(); aFeatIter++)
284     removeAttribute(theAttribute, *aFeatIter);
285 }
286
287 void SketchSolver_FeatureStorage::removeAttribute(AttributePtr theAttribute, FeaturePtr theFeature)
288 {
289   MapAttributeFeature::iterator anAttrIter = myAttributes.find(theAttribute);
290   if (anAttrIter != myAttributes.end())
291     return; // no such attribute
292
293   anAttrIter->second.erase(theFeature);
294   if (anAttrIter->second.empty())
295     myAttributes.erase(anAttrIter);
296 }
297
298 bool SketchSolver_FeatureStorage::isInteract(AttributePtr theAttribute) const
299 {
300   return myAttributes.find(theAttribute) != myAttributes.end();
301 }
302
303
304 bool SketchSolver_FeatureStorage::isConsistent() const
305 {
306   // Check the constraints are valid
307   std::set<ConstraintPtr>::const_iterator aCIter = myConstraints.begin();
308   for (; aCIter != myConstraints.end(); aCIter++)
309     if (!(*aCIter)->data() || !(*aCIter)->data()->isValid())
310       return false;
311   // Check the features are valid
312   MapFeatureConstraint::const_iterator aFIter = myFeatures.begin();
313   for (; aFIter != myFeatures.end(); aFIter++)
314     if (!aFIter->first->data() || !aFIter->first->data()->isValid())
315       return false;
316   // Check the attributes are valid
317   MapAttributeFeature::const_iterator aTIter = myAttributes.begin();
318   for (; aTIter != myAttributes.end(); aTIter++)
319     if (!aTIter->first->isInitialized())
320       return false;
321   return true;
322 }
323
324 std::set<ConstraintPtr> SketchSolver_FeatureStorage::getConstraints(FeaturePtr theFeature) const
325 {
326   std::set<ConstraintPtr> aResult;
327   MapFeatureConstraint::const_iterator aFeatIter = myFeatures.find(theFeature);
328   if (aFeatIter != myFeatures.end())
329     aResult.insert(aFeatIter->second.begin(), aFeatIter->second.end());
330
331   std::list<AttributePtr> anAttributes = theFeature->data()->attributes(std::string());
332   std::list<AttributePtr>::const_iterator anAttrIter = anAttributes.begin();
333   for (; anAttrIter != anAttributes.end(); anAttrIter++) {
334     MapAttributeFeature::const_iterator anIt = myAttributes.find(*anAttrIter);
335     if (anIt == myAttributes.end())
336       continue;
337     std::set<FeaturePtr>::const_iterator aFIter = anIt->second.begin();
338     for (; aFIter != anIt->second.end(); aFIter++) {
339       aFeatIter = myFeatures.find(*aFIter);
340       if (aFeatIter != myFeatures.end())
341         aResult.insert(aFeatIter->second.begin(), aFeatIter->second.end());
342       else {
343         ConstraintPtr aConstraint = std::dynamic_pointer_cast<SketchPlugin_Constraint>(*aFIter);
344         if (aConstraint)
345           aResult.insert(aConstraint);
346       }
347     }
348   }
349   return aResult;
350 }
351
352 std::set<ConstraintPtr> SketchSolver_FeatureStorage::getConstraints(AttributePtr theAttribute) const
353 {
354   std::set<ConstraintPtr> aResult;
355   MapAttributeFeature::const_iterator anIt = myAttributes.find(theAttribute);
356   if (anIt == myAttributes.end())
357     return aResult;
358   std::set<FeaturePtr>::const_iterator aFIter = anIt->second.begin();
359   MapFeatureConstraint::const_iterator aFeatIter;
360   for (; aFIter != anIt->second.end(); aFIter++) {
361     aFeatIter = myFeatures.find(*aFIter);
362     if (aFeatIter != myFeatures.end())
363       aResult.insert(aFeatIter->second.begin(), aFeatIter->second.end());
364     else {
365       ConstraintPtr aConstraint = std::dynamic_pointer_cast<SketchPlugin_Constraint>(*aFIter);
366       if (aConstraint)
367         aResult.insert(aConstraint);
368     }
369   }
370   return aResult;
371 }
372