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())
251 if (!theFeature->data() || !theFeature->data()->isValid())
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);
259 if (!aRefAttr->isObject())
260 if (isInteract(aRefAttr->attr()))
264 if (isInteract(*anIter))
271 void SketchSolver_FeatureStorage::changeAttribute(AttributePtr theAttribute)
273 if (myAttributes.find(theAttribute) == myAttributes.end())
274 myAttributes[theAttribute] = std::set<FeaturePtr>();
277 void SketchSolver_FeatureStorage::changeAttribute(AttributePtr theAttribute, FeaturePtr theFeature)
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;
286 anAttrIter->second.insert(theFeature);
289 void SketchSolver_FeatureStorage::removeAttribute(AttributePtr theAttribute)
291 MapAttributeFeature::iterator anAttrIter = myAttributes.find(theAttribute);
292 if (anAttrIter == myAttributes.end())
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);
301 void SketchSolver_FeatureStorage::removeAttribute(AttributePtr theAttribute, FeaturePtr theFeature)
303 MapAttributeFeature::iterator anAttrIter = myAttributes.find(theAttribute);
304 if (anAttrIter == myAttributes.end())
305 return; // no such attribute
307 anAttrIter->second.erase(theFeature);
308 if (anAttrIter->second.empty())
309 myAttributes.erase(anAttrIter);
312 bool SketchSolver_FeatureStorage::isInteract(AttributePtr theAttribute) const
314 return myAttributes.find(theAttribute) != myAttributes.end();
318 bool SketchSolver_FeatureStorage::isConsistent() const
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())
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())
333 std::set<ConstraintPtr> SketchSolver_FeatureStorage::getConstraints(FeaturePtr theFeature) const
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());
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())
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());
352 ConstraintPtr aConstraint = std::dynamic_pointer_cast<SketchPlugin_Constraint>(*aFIter);
354 aResult.insert(aConstraint);
361 std::set<ConstraintPtr> SketchSolver_FeatureStorage::getConstraints(AttributePtr theAttribute) const
363 std::set<ConstraintPtr> aResult;
364 MapAttributeFeature::const_iterator anIt = myAttributes.find(theAttribute);
365 if (anIt == myAttributes.end())
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());
374 ConstraintPtr aConstraint = std::dynamic_pointer_cast<SketchPlugin_Constraint>(*aFIter);
376 aResult.insert(aConstraint);
382 void SketchSolver_FeatureStorage::blockEvents(bool isBlocked) const
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);
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);
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);