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 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);
219 if (!aRefAttr->isObject())
220 removeAttribute(aRefAttr->attr(), theFeature);
223 removeAttribute(*anIter, theFeature);
226 aFeatIter->second.erase(theConstraint);
227 if (aFeatIter->second.empty())
228 myFeatures.erase(aFeatIter);
231 bool SketchSolver_FeatureStorage::isInteract(FeaturePtr theFeature) const
233 if (myFeatures.find(theFeature) != myFeatures.end())
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);
241 if (!aRefAttr->isObject())
242 if (isInteract(aRefAttr->attr()))
246 if (isInteract(*anIter))
253 void SketchSolver_FeatureStorage::changeAttribute(AttributePtr theAttribute)
255 if (myAttributes.find(theAttribute) == myAttributes.end())
256 myAttributes[theAttribute] = std::set<FeaturePtr>();
259 void SketchSolver_FeatureStorage::changeAttribute(AttributePtr theAttribute, FeaturePtr theFeature)
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;
268 anAttrIter->second.insert(theFeature);
271 void SketchSolver_FeatureStorage::removeAttribute(AttributePtr theAttribute)
273 MapAttributeFeature::iterator anAttrIter = myAttributes.find(theAttribute);
274 if (anAttrIter == myAttributes.end())
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);
283 void SketchSolver_FeatureStorage::removeAttribute(AttributePtr theAttribute, FeaturePtr theFeature)
285 MapAttributeFeature::iterator anAttrIter = myAttributes.find(theAttribute);
286 if (anAttrIter == myAttributes.end())
287 return; // no such attribute
289 anAttrIter->second.erase(theFeature);
290 if (anAttrIter->second.empty())
291 myAttributes.erase(anAttrIter);
294 bool SketchSolver_FeatureStorage::isInteract(AttributePtr theAttribute) const
296 return myAttributes.find(theAttribute) != myAttributes.end();
300 bool SketchSolver_FeatureStorage::isConsistent() const
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())
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())
315 std::set<ConstraintPtr> SketchSolver_FeatureStorage::getConstraints(FeaturePtr theFeature) const
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());
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())
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());
334 ConstraintPtr aConstraint = std::dynamic_pointer_cast<SketchPlugin_Constraint>(*aFIter);
336 aResult.insert(aConstraint);
343 std::set<ConstraintPtr> SketchSolver_FeatureStorage::getConstraints(AttributePtr theAttribute) const
345 std::set<ConstraintPtr> aResult;
346 MapAttributeFeature::const_iterator anIt = myAttributes.find(theAttribute);
347 if (anIt == myAttributes.end())
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());
356 ConstraintPtr aConstraint = std::dynamic_pointer_cast<SketchPlugin_Constraint>(*aFIter);
358 aResult.insert(aConstraint);
364 void SketchSolver_FeatureStorage::blockEvents(bool isBlocked) const
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);
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);
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);