1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
3 // File: SketchSolver_FeatureStorage.cpp
4 // Created: 23 Mar 2015
5 // Author: Artem ZHIDKOV
7 #include <SketchSolver_FeatureStorage.h>
9 #include <ModelAPI_AttributeRefAttr.h>
10 #include <ModelAPI_AttributeRefList.h>
11 #include <ModelAPI_ResultConstruction.h>
13 void SketchSolver_FeatureStorage::changeConstraint(ConstraintPtr theConstraint)
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);
20 if (!aRefAttr->isObject()) {
21 changeAttribute(aRefAttr->attr(), theConstraint);
24 ResultConstructionPtr aRC = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(
26 FeaturePtr aFeature = aRC ? aRC->document()->feature(aRC) :
27 std::dynamic_pointer_cast<ModelAPI_Feature>(aRefAttr->object());
29 changeFeature(aFeature, theConstraint);
32 AttributeRefListPtr aRefList = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(*anIter);
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>(
39 FeaturePtr aFeature = aRC ? aRC->document()->feature(aRC) :
40 std::dynamic_pointer_cast<ModelAPI_Feature>(*aListIter);
42 changeFeature(aFeature, theConstraint);
46 changeAttribute(*anIter, theConstraint);
48 myConstraints.insert(theConstraint);
51 void SketchSolver_FeatureStorage::removeConstraint(ConstraintPtr theConstraint)
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);
60 if (!aRefAttr->isObject()) {
61 removeAttribute(aRefAttr->attr(), theConstraint);
64 ResultConstructionPtr aRC = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(
66 FeaturePtr aFeature = aRC ? aRC->document()->feature(aRC) :
67 std::dynamic_pointer_cast<ModelAPI_Feature>(aRefAttr->object());
69 removeFeature(aFeature, theConstraint);
72 AttributeRefListPtr aRefList = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(*anIter);
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>(
79 FeaturePtr aFeature = aRC ? aRC->document()->feature(aRC) :
80 std::dynamic_pointer_cast<ModelAPI_Feature>(*aListIter);
82 removeFeature(aFeature, theConstraint);
86 removeAttribute(*anIter, theConstraint);
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
98 myFeatures.erase(aFeatIter);
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
114 myAttributes.erase(anAttrIter);
115 anAttrIter = aTmpIter;
122 myConstraints.erase(theConstraint);
125 bool SketchSolver_FeatureStorage::isInteract(ConstraintPtr theConstraint) const
127 if (myConstraints.empty() || myConstraints.find(theConstraint) != myConstraints.end())
130 DataPtr aData = theConstraint->data();
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);
139 if (!aRefAttr->isObject()) {
140 if (isInteract(aRefAttr->attr()))
144 ResultConstructionPtr aRC = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(
146 FeaturePtr aFeature = aRC ? aRC->document()->feature(aRC) :
147 std::dynamic_pointer_cast<ModelAPI_Feature>(aRefAttr->object());
149 if (isInteract(aFeature))
153 AttributeRefListPtr aRefList = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(*anIter);
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>(
160 FeaturePtr aFeature = aRC ? aRC->document()->feature(aRC) :
161 std::dynamic_pointer_cast<ModelAPI_Feature>(*aListIter);
163 if (isInteract(aFeature))
168 if (isInteract(*anIter))
175 void SketchSolver_FeatureStorage::changeFeature(FeaturePtr theFeature)
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);
182 if (!aRefAttr->isObject())
183 changeAttribute(aRefAttr->attr(), theFeature);
186 changeAttribute(*anIter, theFeature);
188 if (myFeatures.find(theFeature) == myFeatures.end())
189 myFeatures[theFeature] = std::set<ConstraintPtr>();
192 void SketchSolver_FeatureStorage::changeFeature(FeaturePtr theFeature, ConstraintPtr theConstraint)
194 // Change all attributes of the feature
195 changeFeature(theFeature);
196 // Add back reference feature to constraint
197 myFeatures[theFeature].insert(theConstraint);
200 void SketchSolver_FeatureStorage::removeFeature(FeaturePtr theFeature)
202 MapFeatureConstraint::iterator aFeatIter = myFeatures.find(theFeature);
203 if (aFeatIter != myFeatures.end())
204 return; // no such feature
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);
212 void SketchSolver_FeatureStorage::removeFeature(FeaturePtr theFeature, ConstraintPtr theConstraint)
214 MapFeatureConstraint::iterator aFeatIter = myFeatures.find(theFeature);
215 if (aFeatIter != myFeatures.end())
216 return; // no such feature
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);
223 if (!aRefAttr->isObject())
224 removeAttribute(aRefAttr->attr(), theFeature);
227 removeAttribute(*anIter, theFeature);
230 aFeatIter->second.erase(theConstraint);
231 if (aFeatIter->second.empty())
232 myFeatures.erase(aFeatIter);
235 bool SketchSolver_FeatureStorage::isInteract(FeaturePtr theFeature) const
237 if (myFeatures.find(theFeature) != myFeatures.end())
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);
245 if (!aRefAttr->isObject())
246 if (isInteract(aRefAttr->attr()))
250 if (isInteract(*anIter))
257 void SketchSolver_FeatureStorage::changeAttribute(AttributePtr theAttribute)
259 if (myAttributes.find(theAttribute) == myAttributes.end())
260 myAttributes[theAttribute] = std::set<FeaturePtr>();
263 void SketchSolver_FeatureStorage::changeAttribute(AttributePtr theAttribute, FeaturePtr theFeature)
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;
272 anAttrIter->second.insert(theFeature);
275 void SketchSolver_FeatureStorage::removeAttribute(AttributePtr theAttribute)
277 MapAttributeFeature::iterator anAttrIter = myAttributes.find(theAttribute);
278 if (anAttrIter == myAttributes.end())
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);
287 void SketchSolver_FeatureStorage::removeAttribute(AttributePtr theAttribute, FeaturePtr theFeature)
289 MapAttributeFeature::iterator anAttrIter = myAttributes.find(theAttribute);
290 if (anAttrIter != myAttributes.end())
291 return; // no such attribute
293 anAttrIter->second.erase(theFeature);
294 if (anAttrIter->second.empty())
295 myAttributes.erase(anAttrIter);
298 bool SketchSolver_FeatureStorage::isInteract(AttributePtr theAttribute) const
300 return myAttributes.find(theAttribute) != myAttributes.end();
304 bool SketchSolver_FeatureStorage::isConsistent() const
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())
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())
319 std::set<ConstraintPtr> SketchSolver_FeatureStorage::getConstraints(FeaturePtr theFeature) const
321 std::set<ConstraintPtr> aResult;
322 MapFeatureConstraint::const_iterator aFeatIter = myFeatures.find(theFeature);
323 if (aFeatIter != myFeatures.end())
324 aResult.insert(aFeatIter->second.begin(), aFeatIter->second.end());
326 std::list<AttributePtr> anAttributes = theFeature->data()->attributes(std::string());
327 std::list<AttributePtr>::const_iterator anAttrIter = anAttributes.begin();
328 for (; anAttrIter != anAttributes.end(); anAttrIter++) {
329 MapAttributeFeature::const_iterator anIt = myAttributes.find(*anAttrIter);
330 if (anIt == myAttributes.end())
332 std::set<FeaturePtr>::const_iterator aFIter = anIt->second.begin();
333 for (; aFIter != anIt->second.end(); aFIter++) {
334 aFeatIter = myFeatures.find(*aFIter);
335 if (aFeatIter != myFeatures.end())
336 aResult.insert(aFeatIter->second.begin(), aFeatIter->second.end());
338 ConstraintPtr aConstraint = std::dynamic_pointer_cast<SketchPlugin_Constraint>(*aFIter);
340 aResult.insert(aConstraint);
347 std::set<ConstraintPtr> SketchSolver_FeatureStorage::getConstraints(AttributePtr theAttribute) const
349 std::set<ConstraintPtr> aResult;
350 MapAttributeFeature::const_iterator anIt = myAttributes.find(theAttribute);
351 if (anIt == myAttributes.end())
353 std::set<FeaturePtr>::const_iterator aFIter = anIt->second.begin();
354 MapFeatureConstraint::const_iterator aFeatIter;
355 for (; aFIter != anIt->second.end(); aFIter++) {
356 aFeatIter = myFeatures.find(*aFIter);
357 if (aFeatIter != myFeatures.end())
358 aResult.insert(aFeatIter->second.begin(), aFeatIter->second.end());
360 ConstraintPtr aConstraint = std::dynamic_pointer_cast<SketchPlugin_Constraint>(*aFIter);
362 aResult.insert(aConstraint);
368 void SketchSolver_FeatureStorage::blockEvents(bool isBlocked) const
370 std::set<ConstraintPtr>::iterator aCIter = myConstraints.begin();
371 for (; aCIter != myConstraints.end(); aCIter++)
372 if ((*aCIter)->data() && (*aCIter)->data()->isValid())
373 (*aCIter)->data()->blockSendAttributeUpdated(isBlocked);
375 MapFeatureConstraint::const_iterator aFIter = myFeatures.begin();
376 for (; aFIter != myFeatures.end(); aFIter++)
377 if (aFIter->first->data() && aFIter->first->data()->isValid())
378 aFIter->first->data()->blockSendAttributeUpdated(isBlocked);
380 MapAttributeFeature::const_iterator anAtIter = myAttributes.begin();
381 for (; anAtIter != myAttributes.end(); anAtIter++)
382 if (anAtIter->first->owner() && anAtIter->first->owner()->data() &&
383 anAtIter->first->owner()->data()->isValid())
384 anAtIter->first->owner()->data()->blockSendAttributeUpdated(isBlocked);