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>
12 #include <GeomDataAPI_Point2D.h>
14 void SketchSolver_FeatureStorage::changeConstraint(ConstraintPtr theConstraint)
16 std::list<AttributePtr> anAttributes = theConstraint->data()->attributes(std::string());
17 std::list<AttributePtr>::iterator anIter = anAttributes.begin();
18 for (; anIter != anAttributes.end(); anIter++) {
19 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anIter);
21 if (!aRefAttr->isObject()) {
22 changeAttribute(aRefAttr->attr(), theConstraint);
25 ResultConstructionPtr aRC = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(
27 FeaturePtr aFeature = aRC ? aRC->document()->feature(aRC) :
28 std::dynamic_pointer_cast<ModelAPI_Feature>(aRefAttr->object());
30 changeFeature(aFeature, theConstraint);
33 AttributeRefListPtr aRefList = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(*anIter);
35 std::list<ObjectPtr> aList = aRefList->list();
36 std::list<ObjectPtr>::iterator aListIter = aList.begin();
37 for (; aListIter != aList.end(); aListIter++) {
38 ResultConstructionPtr aRC = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(
40 FeaturePtr aFeature = aRC ? aRC->document()->feature(aRC) :
41 std::dynamic_pointer_cast<ModelAPI_Feature>(*aListIter);
43 changeFeature(aFeature, theConstraint);
47 changeAttribute(*anIter, theConstraint);
49 myConstraints.insert(theConstraint);
52 void SketchSolver_FeatureStorage::removeConstraint(ConstraintPtr theConstraint)
54 DataPtr aData = theConstraint->data();
55 if (aData) { // Constraint has data. Iterate through its attributes and remove them
56 std::list<AttributePtr> anAttributes = aData->attributes(std::string());
57 std::list<AttributePtr>::iterator anIter = anAttributes.begin();
58 for (; anIter != anAttributes.end(); anIter++) {
59 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anIter);
61 if (!aRefAttr->isObject()) {
62 removeAttribute(aRefAttr->attr(), theConstraint);
65 ResultConstructionPtr aRC = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(
67 FeaturePtr aFeature = aRC ? aRC->document()->feature(aRC) :
68 std::dynamic_pointer_cast<ModelAPI_Feature>(aRefAttr->object());
70 removeFeature(aFeature, theConstraint);
73 AttributeRefListPtr aRefList = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(*anIter);
75 std::list<ObjectPtr> aList = aRefList->list();
76 std::list<ObjectPtr>::iterator aListIter = aList.begin();
77 for (; aListIter != aList.end(); aListIter++) {
78 ResultConstructionPtr aRC = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(
80 FeaturePtr aFeature = aRC ? aRC->document()->feature(aRC) :
81 std::dynamic_pointer_cast<ModelAPI_Feature>(*aListIter);
83 removeFeature(aFeature, theConstraint);
87 removeAttribute(*anIter, theConstraint);
89 } else { // Constraint has no data. Search the links on it in the lists of back references for features and attributes
90 std::set<ConstraintPtr>::iterator aCIter;
91 MapFeatureConstraint::iterator aFeatIter = myFeatures.begin();
92 while (aFeatIter != myFeatures.end()) {
93 aCIter = aFeatIter->second.find(theConstraint);
94 if (aCIter != aFeatIter->second.end()) {
95 FeaturePtr aFeature = aFeatIter->first;
97 removeFeature(aFeature, theConstraint);
102 std::set<FeaturePtr>::iterator aFIter;
103 MapAttributeFeature::iterator anAttrIter = myAttributes.begin();
104 while (anAttrIter != myAttributes.end()) {
105 aFIter = anAttrIter->second.find(theConstraint);
106 if (aFIter != anAttrIter->second.end()) {
107 anAttrIter->second.erase(aFIter);
108 if (anAttrIter->second.empty()) {
109 MapAttributeFeature::iterator aTmpIter = anAttrIter; // stores iterator for the next element, while the current is deleting
111 myAttributes.erase(anAttrIter);
112 anAttrIter = aTmpIter;
119 myConstraints.erase(theConstraint);
122 bool SketchSolver_FeatureStorage::isInteract(ConstraintPtr theConstraint) const
124 if (myConstraints.empty() || myConstraints.find(theConstraint) != myConstraints.end())
127 DataPtr aData = theConstraint->data();
131 std::list<AttributePtr> anAttributes = aData->attributes(std::string());
132 std::list<AttributePtr>::iterator anIter = anAttributes.begin();
133 for (; anIter != anAttributes.end(); anIter++) {
134 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anIter);
136 if (!aRefAttr->isObject()) {
137 if (isInteract(aRefAttr->attr()))
141 ResultConstructionPtr aRC = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(
143 FeaturePtr aFeature = aRC ? aRC->document()->feature(aRC) :
144 std::dynamic_pointer_cast<ModelAPI_Feature>(aRefAttr->object());
146 if (isInteract(aFeature))
150 AttributeRefListPtr aRefList = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(*anIter);
152 std::list<ObjectPtr> aList = aRefList->list();
153 std::list<ObjectPtr>::iterator aListIter = aList.begin();
154 for (; aListIter != aList.end(); aListIter++) {
155 ResultConstructionPtr aRC = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(
157 FeaturePtr aFeature = aRC ? aRC->document()->feature(aRC) :
158 std::dynamic_pointer_cast<ModelAPI_Feature>(*aListIter);
160 if (isInteract(aFeature))
165 if (isInteract(*anIter))
172 void SketchSolver_FeatureStorage::changeFeature(FeaturePtr theFeature)
174 std::list<AttributePtr> anAttributes = theFeature->data()->attributes(std::string());
175 std::list<AttributePtr>::iterator anIter = anAttributes.begin();
176 for (; anIter != anAttributes.end(); anIter++) {
177 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anIter);
179 if (!aRefAttr->isObject())
180 changeAttribute(aRefAttr->attr(), theFeature);
183 changeAttribute(*anIter, theFeature);
185 if (myFeatures.find(theFeature) == myFeatures.end())
186 myFeatures[theFeature] = std::set<ConstraintPtr>();
189 void SketchSolver_FeatureStorage::changeFeature(FeaturePtr theFeature, ConstraintPtr theConstraint)
191 // Change all attributes of the feature
192 changeFeature(theFeature);
193 // Add back reference feature to constraint
194 myFeatures[theFeature].insert(theConstraint);
197 void SketchSolver_FeatureStorage::removeFeature(FeaturePtr theFeature)
199 MapFeatureConstraint::iterator aFeatIter = myFeatures.find(theFeature);
200 if (aFeatIter == myFeatures.end())
201 return; // no such feature
203 std::set<ConstraintPtr> aConstraints = aFeatIter->second;
204 std::set<ConstraintPtr>::iterator aCIter = aConstraints.begin();
205 for (; aCIter != aConstraints.end(); aCIter++)
206 removeFeature(theFeature, *aCIter);
209 void SketchSolver_FeatureStorage::removeFeature(FeaturePtr theFeature, ConstraintPtr theConstraint)
211 MapFeatureConstraint::iterator aFeatIter = myFeatures.find(theFeature);
212 if (aFeatIter == myFeatures.end())
213 return; // no such feature
215 if (theFeature->data()) {
216 std::list<AttributePtr> anAttributes = theFeature->data()->attributes(std::string());
217 std::list<AttributePtr>::iterator anIter = anAttributes.begin();
218 for (; anIter != anAttributes.end(); anIter++) {
219 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anIter);
221 if (!aRefAttr->isObject())
222 removeAttribute(aRefAttr->attr(), theFeature);
225 removeAttribute(*anIter, theFeature);
228 // iterate on attributes to find items refered to theFeature
229 MapAttributeFeature::iterator anIter = myAttributes.begin();
230 while (anIter != myAttributes.end()) {
231 if (anIter->second.find(theFeature) != anIter->second.end()) {
232 anIter->second.erase(theFeature);
233 if (anIter->second.empty()) {
234 MapAttributeFeature::iterator aDeadIter = anIter++;
235 myAttributes.erase(aDeadIter);
243 aFeatIter->second.erase(theConstraint);
244 if (aFeatIter->second.empty())
245 myFeatures.erase(aFeatIter);
248 bool SketchSolver_FeatureStorage::isInteract(FeaturePtr theFeature) const
250 if (myFeatures.find(theFeature) != myFeatures.end())
252 if (!theFeature->data() || !theFeature->data()->isValid())
255 std::list<AttributePtr> anAttributes = theFeature->data()->attributes(std::string());
256 std::list<AttributePtr>::iterator anIter = anAttributes.begin();
257 for (; anIter != anAttributes.end(); anIter++) {
258 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anIter);
260 if (!aRefAttr->isObject())
261 if (isInteract(aRefAttr->attr()))
265 if (isInteract(*anIter))
272 void SketchSolver_FeatureStorage::changeAttribute(AttributePtr theAttribute)
274 if (myAttributes.find(theAttribute) == myAttributes.end())
275 myAttributes[theAttribute] = std::set<FeaturePtr>();
278 void SketchSolver_FeatureStorage::changeAttribute(AttributePtr theAttribute, FeaturePtr theFeature)
280 MapAttributeFeature::iterator anAttrIter = myAttributes.find(theAttribute);
281 if (anAttrIter == myAttributes.end()) {
282 std::set<FeaturePtr> aFeatures;
283 aFeatures.insert(theFeature);
284 myAttributes[theAttribute] = aFeatures;
287 anAttrIter->second.insert(theFeature);
290 void SketchSolver_FeatureStorage::removeAttribute(AttributePtr theAttribute)
292 MapAttributeFeature::iterator anAttrIter = myAttributes.find(theAttribute);
293 if (anAttrIter == myAttributes.end())
296 std::set<FeaturePtr> aFeatures = anAttrIter->second;
297 std::set<FeaturePtr>::iterator aFeatIter = aFeatures.begin();
298 for (; aFeatIter != aFeatures.end(); aFeatIter++)
299 removeAttribute(theAttribute, *aFeatIter);
302 void SketchSolver_FeatureStorage::removeAttribute(AttributePtr theAttribute, FeaturePtr theFeature)
304 MapAttributeFeature::iterator anAttrIter = myAttributes.find(theAttribute);
305 if (anAttrIter == myAttributes.end())
306 return; // no such attribute
308 anAttrIter->second.erase(theFeature);
309 if (!anAttrIter->second.empty())
312 // Check there is no features containing such attribute
313 MapFeatureConstraint::iterator aFeatIter = myFeatures.begin();
314 for (; aFeatIter != myFeatures.end(); aFeatIter++) {
315 DataPtr aData = aFeatIter->first->data();
316 if (!aData || !aData->isValid())
318 std::list<AttributePtr> anAttrList = aData->attributes(GeomDataAPI_Point2D::typeId());
319 std::list<AttributePtr>::iterator anAtIt = anAttrList.begin();
320 for (; anAtIt != anAttrList.end(); anAtIt++) {
321 std::shared_ptr<GeomDataAPI_Point2D> aPoint =
322 std::dynamic_pointer_cast<GeomDataAPI_Point2D>(*anAtIt);
323 if (aPoint == theAttribute)
324 anAttrIter->second.insert(aFeatIter->first);
327 if (anAttrIter->second.empty())
328 myAttributes.erase(anAttrIter);
331 bool SketchSolver_FeatureStorage::isInteract(AttributePtr theAttribute) const
333 return myAttributes.find(theAttribute) != myAttributes.end();
337 bool SketchSolver_FeatureStorage::isConsistent() const
339 // Check the constraints are valid
340 std::set<ConstraintPtr>::const_iterator aCIter = myConstraints.begin();
341 for (; aCIter != myConstraints.end(); aCIter++)
342 if (!(*aCIter)->data() || !(*aCIter)->data()->isValid())
344 // Check the features are valid
345 MapFeatureConstraint::const_iterator aFIter = myFeatures.begin();
346 for (; aFIter != myFeatures.end(); aFIter++)
347 if (!aFIter->first->data() || !aFIter->first->data()->isValid())
352 std::set<ConstraintPtr> SketchSolver_FeatureStorage::getConstraints(FeaturePtr theFeature) const
354 std::set<ConstraintPtr> aResult;
355 MapFeatureConstraint::const_iterator aFeatIter = myFeatures.find(theFeature);
356 if (aFeatIter != myFeatures.end())
357 aResult.insert(aFeatIter->second.begin(), aFeatIter->second.end());
359 std::list<AttributePtr> anAttributes = theFeature->data()->attributes(std::string());
360 std::list<AttributePtr>::const_iterator anAttrIter = anAttributes.begin();
361 for (; anAttrIter != anAttributes.end(); anAttrIter++) {
362 MapAttributeFeature::const_iterator anIt = myAttributes.find(*anAttrIter);
363 if (anIt == myAttributes.end())
365 std::set<FeaturePtr>::const_iterator aFIter = anIt->second.begin();
366 for (; aFIter != anIt->second.end(); aFIter++) {
367 aFeatIter = myFeatures.find(*aFIter);
368 if (aFeatIter != myFeatures.end())
369 aResult.insert(aFeatIter->second.begin(), aFeatIter->second.end());
371 ConstraintPtr aConstraint = std::dynamic_pointer_cast<SketchPlugin_Constraint>(*aFIter);
373 aResult.insert(aConstraint);
380 std::set<ConstraintPtr> SketchSolver_FeatureStorage::getConstraints(AttributePtr theAttribute) const
382 std::set<ConstraintPtr> aResult;
383 MapAttributeFeature::const_iterator anIt = myAttributes.find(theAttribute);
384 if (anIt == myAttributes.end())
386 std::set<FeaturePtr>::const_iterator aFIter = anIt->second.begin();
387 MapFeatureConstraint::const_iterator aFeatIter;
388 for (; aFIter != anIt->second.end(); aFIter++) {
389 aFeatIter = myFeatures.find(*aFIter);
390 if (aFeatIter != myFeatures.end())
391 aResult.insert(aFeatIter->second.begin(), aFeatIter->second.end());
393 ConstraintPtr aConstraint = std::dynamic_pointer_cast<SketchPlugin_Constraint>(*aFIter);
395 aResult.insert(aConstraint);
401 void SketchSolver_FeatureStorage::blockEvents(bool isBlocked) const
403 std::set<ConstraintPtr>::iterator aCIter = myConstraints.begin();
404 for (; aCIter != myConstraints.end(); aCIter++)
405 if ((*aCIter)->data() && (*aCIter)->data()->isValid())
406 (*aCIter)->data()->blockSendAttributeUpdated(isBlocked);
408 MapFeatureConstraint::const_iterator aFIter = myFeatures.begin();
409 for (; aFIter != myFeatures.end(); aFIter++)
410 if (aFIter->first->data() && aFIter->first->data()->isValid())
411 aFIter->first->data()->blockSendAttributeUpdated(isBlocked);
413 MapAttributeFeature::const_iterator anAtIter = myAttributes.begin();
414 for (; anAtIter != myAttributes.end(); anAtIter++)
415 if (anAtIter->first->owner() && anAtIter->first->owner()->data() &&
416 anAtIter->first->owner()->data()->isValid())
417 anAtIter->first->owner()->data()->blockSendAttributeUpdated(isBlocked);