]> SALOME platform Git repositories - modules/shaper.git/blob - src/SketchSolver/SketchSolver_FeatureStorage.cpp
Salome HOME
e274244fb3dba6eb56dfbf4f24a371e28021c09c
[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         FeaturePtr aFeature = aFeatIter->first;
95         aFeatIter++;
96         removeFeature(aFeature, theConstraint);
97         continue;
98       }
99       aFeatIter++;
100     }
101     std::set<FeaturePtr>::iterator aFIter;
102     MapAttributeFeature::iterator anAttrIter = myAttributes.begin();
103     while (anAttrIter != myAttributes.end()) {
104       aFIter = anAttrIter->second.find(theConstraint);
105       if (aFIter != anAttrIter->second.end()) {
106         anAttrIter->second.erase(aFIter);
107         if (anAttrIter->second.empty()) {
108           MapAttributeFeature::iterator aTmpIter = anAttrIter; // stores iterator for the next element, while the current is deleting
109           aTmpIter++;
110           myAttributes.erase(anAttrIter);
111           anAttrIter = aTmpIter;
112           continue;
113         }
114       }
115       anAttrIter++;
116     }
117   }
118   myConstraints.erase(theConstraint);
119 }
120
121 bool SketchSolver_FeatureStorage::isInteract(ConstraintPtr theConstraint) const
122 {
123   if (myConstraints.empty() || myConstraints.find(theConstraint) != myConstraints.end())
124     return true;
125
126   DataPtr aData = theConstraint->data();
127   if (!aData)
128     return false;
129
130   std::list<AttributePtr> anAttributes = aData->attributes(std::string());
131   std::list<AttributePtr>::iterator anIter = anAttributes.begin();
132   for (; anIter != anAttributes.end(); anIter++) {
133     AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anIter);
134     if (aRefAttr) {
135       if (!aRefAttr->isObject()) {
136         if (isInteract(aRefAttr->attr()))
137           return true;
138         continue;
139       }
140       ResultConstructionPtr aRC = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(
141           aRefAttr->object());
142       FeaturePtr aFeature = aRC ? aRC->document()->feature(aRC) :
143           std::dynamic_pointer_cast<ModelAPI_Feature>(aRefAttr->object());
144       if (aFeature)
145         if (isInteract(aFeature))
146           return true;
147       continue;
148     }
149     AttributeRefListPtr aRefList = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(*anIter);
150     if (aRefList) {
151       std::list<ObjectPtr> aList = aRefList->list();
152       std::list<ObjectPtr>::iterator aListIter = aList.begin();
153       for (; aListIter != aList.end(); aListIter++) {
154         ResultConstructionPtr aRC = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(
155             *aListIter);
156         FeaturePtr aFeature = aRC ? aRC->document()->feature(aRC) :
157             std::dynamic_pointer_cast<ModelAPI_Feature>(*aListIter);
158         if (aFeature)
159           if (isInteract(aFeature))
160             return true;
161       }
162       continue;
163     }
164     if (isInteract(*anIter))
165       return true;
166   }
167   return false;
168 }
169
170
171 void SketchSolver_FeatureStorage::changeFeature(FeaturePtr theFeature)
172 {
173   std::list<AttributePtr> anAttributes = theFeature->data()->attributes(std::string());
174   std::list<AttributePtr>::iterator anIter = anAttributes.begin();
175   for (; anIter != anAttributes.end(); anIter++) {
176     AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anIter);
177     if (aRefAttr) {
178       if (!aRefAttr->isObject())
179         changeAttribute(aRefAttr->attr(), theFeature);
180       continue;
181     }
182     changeAttribute(*anIter, theFeature);
183   }
184   if (myFeatures.find(theFeature) == myFeatures.end())
185     myFeatures[theFeature] = std::set<ConstraintPtr>();
186 }
187
188 void SketchSolver_FeatureStorage::changeFeature(FeaturePtr theFeature, ConstraintPtr theConstraint)
189 {
190   // Change all attributes of the feature
191   changeFeature(theFeature);
192   // Add back reference feature to constraint
193   myFeatures[theFeature].insert(theConstraint);
194 }
195
196 void SketchSolver_FeatureStorage::removeFeature(FeaturePtr theFeature)
197 {
198   MapFeatureConstraint::iterator aFeatIter = myFeatures.find(theFeature);
199   if (aFeatIter == myFeatures.end())
200     return; // no such feature
201
202   std::set<ConstraintPtr> aConstraints = aFeatIter->second;
203   std::set<ConstraintPtr>::iterator aCIter = aConstraints.begin();
204   for (; aCIter != aConstraints.end(); aCIter++)
205     removeFeature(theFeature, *aCIter);
206 }
207
208 void SketchSolver_FeatureStorage::removeFeature(FeaturePtr theFeature, ConstraintPtr theConstraint)
209 {
210   MapFeatureConstraint::iterator aFeatIter = myFeatures.find(theFeature);
211   if (aFeatIter == myFeatures.end())
212     return; // no such feature
213
214   if (theFeature->data()) {
215     std::list<AttributePtr> anAttributes = theFeature->data()->attributes(std::string());
216     std::list<AttributePtr>::iterator anIter = anAttributes.begin();
217     for (; anIter != anAttributes.end(); anIter++) {
218       AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anIter);
219       if (aRefAttr) {
220         if (!aRefAttr->isObject())
221           removeAttribute(aRefAttr->attr(), theFeature);
222         continue;
223       }
224       removeAttribute(*anIter, theFeature);
225     }
226   } else {
227     // iterate on attributes to find items refered to theFeature
228     MapAttributeFeature::iterator anIter = myAttributes.begin();
229     while (anIter != myAttributes.end()) {
230       if (anIter->second.find(theFeature) != anIter->second.end()) {
231         anIter->second.erase(theFeature);
232         if (anIter->second.empty()) {
233           MapAttributeFeature::iterator aDeadIter = anIter++;
234           myAttributes.erase(aDeadIter);
235           continue;
236         }
237       }
238       anIter++;
239     }
240   }
241
242   aFeatIter->second.erase(theConstraint);
243   if (aFeatIter->second.empty())
244     myFeatures.erase(aFeatIter);
245 }
246
247 bool SketchSolver_FeatureStorage::isInteract(FeaturePtr theFeature) const
248 {
249   if (myFeatures.find(theFeature) != myFeatures.end())
250     return true;
251   if (!theFeature->data() || !theFeature->data()->isValid())
252     return false;
253
254   std::list<AttributePtr> anAttributes = theFeature->data()->attributes(std::string());
255   std::list<AttributePtr>::iterator anIter = anAttributes.begin();
256   for (; anIter != anAttributes.end(); anIter++) {
257     AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anIter);
258     if (aRefAttr) {
259       if (!aRefAttr->isObject())
260         if (isInteract(aRefAttr->attr()))
261           return true;
262       continue;
263     }
264     if (isInteract(*anIter))
265       return true;
266   }
267   return false;
268 }
269
270
271 void SketchSolver_FeatureStorage::changeAttribute(AttributePtr theAttribute)
272 {
273   if (myAttributes.find(theAttribute) == myAttributes.end())
274     myAttributes[theAttribute] = std::set<FeaturePtr>();
275 }
276
277 void SketchSolver_FeatureStorage::changeAttribute(AttributePtr theAttribute, FeaturePtr theFeature)
278 {
279   MapAttributeFeature::iterator anAttrIter = myAttributes.find(theAttribute);
280   if (anAttrIter == myAttributes.end()) {
281     std::set<FeaturePtr> aFeatures;
282     aFeatures.insert(theFeature);
283     myAttributes[theAttribute] = aFeatures;
284     return;
285   }
286   anAttrIter->second.insert(theFeature);
287 }
288
289 void SketchSolver_FeatureStorage::removeAttribute(AttributePtr theAttribute)
290 {
291   MapAttributeFeature::iterator anAttrIter = myAttributes.find(theAttribute);
292   if (anAttrIter == myAttributes.end())
293     return;
294
295   std::set<FeaturePtr> aFeatures = anAttrIter->second;
296   std::set<FeaturePtr>::iterator aFeatIter = aFeatures.begin();
297   for (; aFeatIter != aFeatures.end(); aFeatIter++)
298     removeAttribute(theAttribute, *aFeatIter);
299 }
300
301 void SketchSolver_FeatureStorage::removeAttribute(AttributePtr theAttribute, FeaturePtr theFeature)
302 {
303   MapAttributeFeature::iterator anAttrIter = myAttributes.find(theAttribute);
304   if (anAttrIter == myAttributes.end())
305     return; // no such attribute
306
307   anAttrIter->second.erase(theFeature);
308   if (anAttrIter->second.empty())
309     myAttributes.erase(anAttrIter);
310 }
311
312 bool SketchSolver_FeatureStorage::isInteract(AttributePtr theAttribute) const
313 {
314   return myAttributes.find(theAttribute) != myAttributes.end();
315 }
316
317
318 bool SketchSolver_FeatureStorage::isConsistent() const
319 {
320   // Check the constraints are valid
321   std::set<ConstraintPtr>::const_iterator aCIter = myConstraints.begin();
322   for (; aCIter != myConstraints.end(); aCIter++)
323     if (!(*aCIter)->data() || !(*aCIter)->data()->isValid())
324       return false;
325   // Check the features are valid
326   MapFeatureConstraint::const_iterator aFIter = myFeatures.begin();
327   for (; aFIter != myFeatures.end(); aFIter++)
328     if (!aFIter->first->data() || !aFIter->first->data()->isValid())
329       return false;
330   return true;
331 }
332
333 std::set<ConstraintPtr> SketchSolver_FeatureStorage::getConstraints(FeaturePtr theFeature) const
334 {
335   std::set<ConstraintPtr> aResult;
336   MapFeatureConstraint::const_iterator aFeatIter = myFeatures.find(theFeature);
337   if (aFeatIter != myFeatures.end())
338     aResult.insert(aFeatIter->second.begin(), aFeatIter->second.end());
339
340   std::list<AttributePtr> anAttributes = theFeature->data()->attributes(std::string());
341   std::list<AttributePtr>::const_iterator anAttrIter = anAttributes.begin();
342   for (; anAttrIter != anAttributes.end(); anAttrIter++) {
343     MapAttributeFeature::const_iterator anIt = myAttributes.find(*anAttrIter);
344     if (anIt == myAttributes.end())
345       continue;
346     std::set<FeaturePtr>::const_iterator aFIter = anIt->second.begin();
347     for (; aFIter != anIt->second.end(); aFIter++) {
348       aFeatIter = myFeatures.find(*aFIter);
349       if (aFeatIter != myFeatures.end())
350         aResult.insert(aFeatIter->second.begin(), aFeatIter->second.end());
351       else {
352         ConstraintPtr aConstraint = std::dynamic_pointer_cast<SketchPlugin_Constraint>(*aFIter);
353         if (aConstraint)
354           aResult.insert(aConstraint);
355       }
356     }
357   }
358   return aResult;
359 }
360
361 std::set<ConstraintPtr> SketchSolver_FeatureStorage::getConstraints(AttributePtr theAttribute) const
362 {
363   std::set<ConstraintPtr> aResult;
364   MapAttributeFeature::const_iterator anIt = myAttributes.find(theAttribute);
365   if (anIt == myAttributes.end())
366     return aResult;
367   std::set<FeaturePtr>::const_iterator aFIter = anIt->second.begin();
368   MapFeatureConstraint::const_iterator aFeatIter;
369   for (; aFIter != anIt->second.end(); aFIter++) {
370     aFeatIter = myFeatures.find(*aFIter);
371     if (aFeatIter != myFeatures.end())
372       aResult.insert(aFeatIter->second.begin(), aFeatIter->second.end());
373     else {
374       ConstraintPtr aConstraint = std::dynamic_pointer_cast<SketchPlugin_Constraint>(*aFIter);
375       if (aConstraint)
376         aResult.insert(aConstraint);
377     }
378   }
379   return aResult;
380 }
381
382 void SketchSolver_FeatureStorage::blockEvents(bool isBlocked) const
383 {
384   std::set<ConstraintPtr>::iterator aCIter = myConstraints.begin();
385   for (; aCIter != myConstraints.end(); aCIter++)
386     if ((*aCIter)->data() && (*aCIter)->data()->isValid())
387       (*aCIter)->data()->blockSendAttributeUpdated(isBlocked);
388
389   MapFeatureConstraint::const_iterator aFIter = myFeatures.begin();
390   for (; aFIter != myFeatures.end(); aFIter++)
391     if (aFIter->first->data() && aFIter->first->data()->isValid())
392       aFIter->first->data()->blockSendAttributeUpdated(isBlocked);
393
394   MapAttributeFeature::const_iterator anAtIter = myAttributes.begin();
395   for (; anAtIter != myAttributes.end(); anAtIter++)
396     if (anAtIter->first->owner() && anAtIter->first->owner()->data() &&
397         anAtIter->first->owner()->data()->isValid())
398       anAtIter->first->owner()->data()->blockSendAttributeUpdated(isBlocked);
399 }