]> SALOME platform Git repositories - modules/shaper.git/blob - src/SketchSolver/SketchSolver_FeatureStorage.cpp
Salome HOME
Merge branch 'Dev_1.1.0' of newgeom:newgeom into Dev_1.1.0
[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   std::list<AttributePtr> anAttributes = theFeature->data()->attributes(std::string());
215   std::list<AttributePtr>::iterator anIter = anAttributes.begin();
216   for (; anIter != anAttributes.end(); anIter++) {
217     AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anIter);
218     if (aRefAttr) {
219       if (!aRefAttr->isObject())
220         removeAttribute(aRefAttr->attr(), theFeature);
221       continue;
222     }
223     removeAttribute(*anIter, theFeature);
224   }
225
226   aFeatIter->second.erase(theConstraint);
227   if (aFeatIter->second.empty())
228     myFeatures.erase(aFeatIter);
229 }
230
231 bool SketchSolver_FeatureStorage::isInteract(FeaturePtr theFeature) const
232 {
233   if (myFeatures.find(theFeature) != myFeatures.end())
234     return true;
235
236   std::list<AttributePtr> anAttributes = theFeature->data()->attributes(std::string());
237   std::list<AttributePtr>::iterator anIter = anAttributes.begin();
238   for (; anIter != anAttributes.end(); anIter++) {
239     AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anIter);
240     if (aRefAttr) {
241       if (!aRefAttr->isObject())
242         if (isInteract(aRefAttr->attr()))
243           return true;
244       continue;
245     }
246     if (isInteract(*anIter))
247       return true;
248   }
249   return false;
250 }
251
252
253 void SketchSolver_FeatureStorage::changeAttribute(AttributePtr theAttribute)
254 {
255   if (myAttributes.find(theAttribute) == myAttributes.end())
256     myAttributes[theAttribute] = std::set<FeaturePtr>();
257 }
258
259 void SketchSolver_FeatureStorage::changeAttribute(AttributePtr theAttribute, FeaturePtr theFeature)
260 {
261   MapAttributeFeature::iterator anAttrIter = myAttributes.find(theAttribute);
262   if (anAttrIter == myAttributes.end()) {
263     std::set<FeaturePtr> aFeatures;
264     aFeatures.insert(theFeature);
265     myAttributes[theAttribute] = aFeatures;
266     return;
267   }
268   anAttrIter->second.insert(theFeature);
269 }
270
271 void SketchSolver_FeatureStorage::removeAttribute(AttributePtr theAttribute)
272 {
273   MapAttributeFeature::iterator anAttrIter = myAttributes.find(theAttribute);
274   if (anAttrIter == myAttributes.end())
275     return;
276
277   std::set<FeaturePtr> aFeatures = anAttrIter->second;
278   std::set<FeaturePtr>::iterator aFeatIter = aFeatures.begin();
279   for (; aFeatIter != aFeatures.end(); aFeatIter++)
280     removeAttribute(theAttribute, *aFeatIter);
281 }
282
283 void SketchSolver_FeatureStorage::removeAttribute(AttributePtr theAttribute, FeaturePtr theFeature)
284 {
285   MapAttributeFeature::iterator anAttrIter = myAttributes.find(theAttribute);
286   if (anAttrIter == myAttributes.end())
287     return; // no such attribute
288
289   anAttrIter->second.erase(theFeature);
290   if (anAttrIter->second.empty())
291     myAttributes.erase(anAttrIter);
292 }
293
294 bool SketchSolver_FeatureStorage::isInteract(AttributePtr theAttribute) const
295 {
296   return myAttributes.find(theAttribute) != myAttributes.end();
297 }
298
299
300 bool SketchSolver_FeatureStorage::isConsistent() const
301 {
302   // Check the constraints are valid
303   std::set<ConstraintPtr>::const_iterator aCIter = myConstraints.begin();
304   for (; aCIter != myConstraints.end(); aCIter++)
305     if (!(*aCIter)->data() || !(*aCIter)->data()->isValid())
306       return false;
307   // Check the features are valid
308   MapFeatureConstraint::const_iterator aFIter = myFeatures.begin();
309   for (; aFIter != myFeatures.end(); aFIter++)
310     if (!aFIter->first->data() || !aFIter->first->data()->isValid())
311       return false;
312   return true;
313 }
314
315 std::set<ConstraintPtr> SketchSolver_FeatureStorage::getConstraints(FeaturePtr theFeature) const
316 {
317   std::set<ConstraintPtr> aResult;
318   MapFeatureConstraint::const_iterator aFeatIter = myFeatures.find(theFeature);
319   if (aFeatIter != myFeatures.end())
320     aResult.insert(aFeatIter->second.begin(), aFeatIter->second.end());
321
322   std::list<AttributePtr> anAttributes = theFeature->data()->attributes(std::string());
323   std::list<AttributePtr>::const_iterator anAttrIter = anAttributes.begin();
324   for (; anAttrIter != anAttributes.end(); anAttrIter++) {
325     MapAttributeFeature::const_iterator anIt = myAttributes.find(*anAttrIter);
326     if (anIt == myAttributes.end())
327       continue;
328     std::set<FeaturePtr>::const_iterator aFIter = anIt->second.begin();
329     for (; aFIter != anIt->second.end(); aFIter++) {
330       aFeatIter = myFeatures.find(*aFIter);
331       if (aFeatIter != myFeatures.end())
332         aResult.insert(aFeatIter->second.begin(), aFeatIter->second.end());
333       else {
334         ConstraintPtr aConstraint = std::dynamic_pointer_cast<SketchPlugin_Constraint>(*aFIter);
335         if (aConstraint)
336           aResult.insert(aConstraint);
337       }
338     }
339   }
340   return aResult;
341 }
342
343 std::set<ConstraintPtr> SketchSolver_FeatureStorage::getConstraints(AttributePtr theAttribute) const
344 {
345   std::set<ConstraintPtr> aResult;
346   MapAttributeFeature::const_iterator anIt = myAttributes.find(theAttribute);
347   if (anIt == myAttributes.end())
348     return aResult;
349   std::set<FeaturePtr>::const_iterator aFIter = anIt->second.begin();
350   MapFeatureConstraint::const_iterator aFeatIter;
351   for (; aFIter != anIt->second.end(); aFIter++) {
352     aFeatIter = myFeatures.find(*aFIter);
353     if (aFeatIter != myFeatures.end())
354       aResult.insert(aFeatIter->second.begin(), aFeatIter->second.end());
355     else {
356       ConstraintPtr aConstraint = std::dynamic_pointer_cast<SketchPlugin_Constraint>(*aFIter);
357       if (aConstraint)
358         aResult.insert(aConstraint);
359     }
360   }
361   return aResult;
362 }
363
364 void SketchSolver_FeatureStorage::blockEvents(bool isBlocked) const
365 {
366   std::set<ConstraintPtr>::iterator aCIter = myConstraints.begin();
367   for (; aCIter != myConstraints.end(); aCIter++)
368     if ((*aCIter)->data() && (*aCIter)->data()->isValid())
369       (*aCIter)->data()->blockSendAttributeUpdated(isBlocked);
370
371   MapFeatureConstraint::const_iterator aFIter = myFeatures.begin();
372   for (; aFIter != myFeatures.end(); aFIter++)
373     if (aFIter->first->data() && aFIter->first->data()->isValid())
374       aFIter->first->data()->blockSendAttributeUpdated(isBlocked);
375
376   MapAttributeFeature::const_iterator anAtIter = myAttributes.begin();
377   for (; anAtIter != myAttributes.end(); anAtIter++)
378     if (anAtIter->first->owner() && anAtIter->first->owner()->data() &&
379         anAtIter->first->owner()->data()->isValid())
380       anAtIter->first->owner()->data()->blockSendAttributeUpdated(isBlocked);
381 }