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 FeaturePtr aFeature = aFeatIter->first;
96 removeFeature(aFeature, theConstraint);
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
110 myAttributes.erase(anAttrIter);
111 anAttrIter = aTmpIter;
118 myConstraints.erase(theConstraint);
121 bool SketchSolver_FeatureStorage::isInteract(ConstraintPtr theConstraint) const
123 if (myConstraints.empty() || myConstraints.find(theConstraint) != myConstraints.end())
126 DataPtr aData = theConstraint->data();
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);
135 if (!aRefAttr->isObject()) {
136 if (isInteract(aRefAttr->attr()))
140 ResultConstructionPtr aRC = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(
142 FeaturePtr aFeature = aRC ? aRC->document()->feature(aRC) :
143 std::dynamic_pointer_cast<ModelAPI_Feature>(aRefAttr->object());
145 if (isInteract(aFeature))
149 AttributeRefListPtr aRefList = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(*anIter);
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>(
156 FeaturePtr aFeature = aRC ? aRC->document()->feature(aRC) :
157 std::dynamic_pointer_cast<ModelAPI_Feature>(*aListIter);
159 if (isInteract(aFeature))
164 if (isInteract(*anIter))
171 void SketchSolver_FeatureStorage::changeFeature(FeaturePtr theFeature)
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);
178 if (!aRefAttr->isObject())
179 changeAttribute(aRefAttr->attr(), theFeature);
182 changeAttribute(*anIter, theFeature);
184 if (myFeatures.find(theFeature) == myFeatures.end())
185 myFeatures[theFeature] = std::set<ConstraintPtr>();
188 void SketchSolver_FeatureStorage::changeFeature(FeaturePtr theFeature, ConstraintPtr theConstraint)
190 // Change all attributes of the feature
191 changeFeature(theFeature);
192 // Add back reference feature to constraint
193 myFeatures[theFeature].insert(theConstraint);
196 void SketchSolver_FeatureStorage::removeFeature(FeaturePtr theFeature)
198 MapFeatureConstraint::iterator aFeatIter = myFeatures.find(theFeature);
199 if (aFeatIter == myFeatures.end())
200 return; // no such feature
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);
208 void SketchSolver_FeatureStorage::removeFeature(FeaturePtr theFeature, ConstraintPtr theConstraint)
210 MapFeatureConstraint::iterator aFeatIter = myFeatures.find(theFeature);
211 if (aFeatIter == myFeatures.end())
212 return; // no such feature
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);
220 if (!aRefAttr->isObject())
221 removeAttribute(aRefAttr->attr(), theFeature);
224 removeAttribute(*anIter, theFeature);
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);
242 aFeatIter->second.erase(theConstraint);
243 if (aFeatIter->second.empty())
244 myFeatures.erase(aFeatIter);
247 bool SketchSolver_FeatureStorage::isInteract(FeaturePtr theFeature) const
249 if (myFeatures.find(theFeature) != myFeatures.end())
252 std::list<AttributePtr> anAttributes = theFeature->data()->attributes(std::string());
253 std::list<AttributePtr>::iterator anIter = anAttributes.begin();
254 for (; anIter != anAttributes.end(); anIter++) {
255 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anIter);
257 if (!aRefAttr->isObject())
258 if (isInteract(aRefAttr->attr()))
262 if (isInteract(*anIter))
269 void SketchSolver_FeatureStorage::changeAttribute(AttributePtr theAttribute)
271 if (myAttributes.find(theAttribute) == myAttributes.end())
272 myAttributes[theAttribute] = std::set<FeaturePtr>();
275 void SketchSolver_FeatureStorage::changeAttribute(AttributePtr theAttribute, FeaturePtr theFeature)
277 MapAttributeFeature::iterator anAttrIter = myAttributes.find(theAttribute);
278 if (anAttrIter == myAttributes.end()) {
279 std::set<FeaturePtr> aFeatures;
280 aFeatures.insert(theFeature);
281 myAttributes[theAttribute] = aFeatures;
284 anAttrIter->second.insert(theFeature);
287 void SketchSolver_FeatureStorage::removeAttribute(AttributePtr theAttribute)
289 MapAttributeFeature::iterator anAttrIter = myAttributes.find(theAttribute);
290 if (anAttrIter == myAttributes.end())
293 std::set<FeaturePtr> aFeatures = anAttrIter->second;
294 std::set<FeaturePtr>::iterator aFeatIter = aFeatures.begin();
295 for (; aFeatIter != aFeatures.end(); aFeatIter++)
296 removeAttribute(theAttribute, *aFeatIter);
299 void SketchSolver_FeatureStorage::removeAttribute(AttributePtr theAttribute, FeaturePtr theFeature)
301 MapAttributeFeature::iterator anAttrIter = myAttributes.find(theAttribute);
302 if (anAttrIter == myAttributes.end())
303 return; // no such attribute
305 anAttrIter->second.erase(theFeature);
306 if (anAttrIter->second.empty())
307 myAttributes.erase(anAttrIter);
310 bool SketchSolver_FeatureStorage::isInteract(AttributePtr theAttribute) const
312 return myAttributes.find(theAttribute) != myAttributes.end();
316 bool SketchSolver_FeatureStorage::isConsistent() const
318 // Check the constraints are valid
319 std::set<ConstraintPtr>::const_iterator aCIter = myConstraints.begin();
320 for (; aCIter != myConstraints.end(); aCIter++)
321 if (!(*aCIter)->data() || !(*aCIter)->data()->isValid())
323 // Check the features are valid
324 MapFeatureConstraint::const_iterator aFIter = myFeatures.begin();
325 for (; aFIter != myFeatures.end(); aFIter++)
326 if (!aFIter->first->data() || !aFIter->first->data()->isValid())
331 std::set<ConstraintPtr> SketchSolver_FeatureStorage::getConstraints(FeaturePtr theFeature) const
333 std::set<ConstraintPtr> aResult;
334 MapFeatureConstraint::const_iterator aFeatIter = myFeatures.find(theFeature);
335 if (aFeatIter != myFeatures.end())
336 aResult.insert(aFeatIter->second.begin(), aFeatIter->second.end());
338 std::list<AttributePtr> anAttributes = theFeature->data()->attributes(std::string());
339 std::list<AttributePtr>::const_iterator anAttrIter = anAttributes.begin();
340 for (; anAttrIter != anAttributes.end(); anAttrIter++) {
341 MapAttributeFeature::const_iterator anIt = myAttributes.find(*anAttrIter);
342 if (anIt == myAttributes.end())
344 std::set<FeaturePtr>::const_iterator aFIter = anIt->second.begin();
345 for (; aFIter != anIt->second.end(); aFIter++) {
346 aFeatIter = myFeatures.find(*aFIter);
347 if (aFeatIter != myFeatures.end())
348 aResult.insert(aFeatIter->second.begin(), aFeatIter->second.end());
350 ConstraintPtr aConstraint = std::dynamic_pointer_cast<SketchPlugin_Constraint>(*aFIter);
352 aResult.insert(aConstraint);
359 std::set<ConstraintPtr> SketchSolver_FeatureStorage::getConstraints(AttributePtr theAttribute) const
361 std::set<ConstraintPtr> aResult;
362 MapAttributeFeature::const_iterator anIt = myAttributes.find(theAttribute);
363 if (anIt == myAttributes.end())
365 std::set<FeaturePtr>::const_iterator aFIter = anIt->second.begin();
366 MapFeatureConstraint::const_iterator aFeatIter;
367 for (; aFIter != anIt->second.end(); aFIter++) {
368 aFeatIter = myFeatures.find(*aFIter);
369 if (aFeatIter != myFeatures.end())
370 aResult.insert(aFeatIter->second.begin(), aFeatIter->second.end());
372 ConstraintPtr aConstraint = std::dynamic_pointer_cast<SketchPlugin_Constraint>(*aFIter);
374 aResult.insert(aConstraint);
380 void SketchSolver_FeatureStorage::blockEvents(bool isBlocked) const
382 std::set<ConstraintPtr>::iterator aCIter = myConstraints.begin();
383 for (; aCIter != myConstraints.end(); aCIter++)
384 if ((*aCIter)->data() && (*aCIter)->data()->isValid())
385 (*aCIter)->data()->blockSendAttributeUpdated(isBlocked);
387 MapFeatureConstraint::const_iterator aFIter = myFeatures.begin();
388 for (; aFIter != myFeatures.end(); aFIter++)
389 if (aFIter->first->data() && aFIter->first->data()->isValid())
390 aFIter->first->data()->blockSendAttributeUpdated(isBlocked);
392 MapAttributeFeature::const_iterator anAtIter = myAttributes.begin();
393 for (; anAtIter != myAttributes.end(); anAtIter++)
394 if (anAtIter->first->owner() && anAtIter->first->owner()->data() &&
395 anAtIter->first->owner()->data()->isValid())
396 anAtIter->first->owner()->data()->blockSendAttributeUpdated(isBlocked);