1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
3 // File: SketchSolver_Storage.cpp
4 // Created: 30 Nov 2015
5 // Author: Artem ZHIDKOV
7 #include <SketchSolver_Storage.h>
8 #include <SketchSolver_Manager.h>
10 #include <GeomDataAPI_Point2D.h>
11 #include <ModelAPI_AttributeRefAttr.h>
12 #include <ModelAPI_AttributeRefList.h>
13 #include <SketchPlugin_Arc.h>
14 #include <SketchPlugin_Circle.h>
15 #include <SketchPlugin_Line.h>
16 #include <SketchPlugin_Point.h>
17 #include <SketchPlugin_ConstraintRigid.h>
20 /// \brief Verify two vectors of constraints are equal.
21 /// Vectors differ by the order of elements are equal.
22 static bool isEqual(const std::list<ConstraintWrapperPtr>& theCVec1,
23 const std::list<ConstraintWrapperPtr>& theCVec2);
26 void SketchSolver_Storage::addConstraint(ConstraintPtr theConstraint,
27 ConstraintWrapperPtr theSolverConstraint)
29 if (theSolverConstraint) {
30 std::list<ConstraintWrapperPtr> aConstrList(1, theSolverConstraint);
31 addConstraint(theConstraint, aConstrList);
33 addConstraint(theConstraint, std::list<ConstraintWrapperPtr>());
36 void SketchSolver_Storage::addConstraint(
37 ConstraintPtr theConstraint,
38 std::list<ConstraintWrapperPtr> theSolverConstraints)
40 std::map<ConstraintPtr, std::list<ConstraintWrapperPtr> >::const_iterator
41 aFound = myConstraintMap.find(theConstraint);
42 if (aFound == myConstraintMap.end() || !isEqual(aFound->second, theSolverConstraints))
43 setNeedToResolve(true);
45 if (theSolverConstraints.empty()) {
46 // constraint links to the empty list, add its attributes linked to the empty entities
47 std::list<AttributePtr> aRefAttrs =
48 theConstraint->data()->attributes(ModelAPI_AttributeRefAttr::typeId());
49 std::list<AttributePtr>::const_iterator anAttrIt = aRefAttrs.begin();
50 for (; anAttrIt != aRefAttrs.end(); ++anAttrIt) {
51 AttributeRefAttrPtr aRef = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anAttrIt);
52 if (aRef->isObject()) {
53 FeaturePtr aFeature = ModelAPI_Feature::feature(aRef->object());
54 if (aFeature) addEntity(aFeature, EntityWrapperPtr());
56 addEntity(aRef->attr(), EntityWrapperPtr());
58 std::list<AttributePtr> aRefLists =
59 theConstraint->data()->attributes(ModelAPI_AttributeRefList::typeId());
60 for (anAttrIt = aRefLists.begin(); anAttrIt != aRefLists.end(); ++anAttrIt) {
61 AttributeRefListPtr aRef = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(*anAttrIt);
62 std::list<ObjectPtr> anObj = aRef->list();
63 std::list<ObjectPtr>::iterator anIt = anObj.begin();
64 for (; anIt != anObj.end(); ++anIt) {
65 FeaturePtr aFeature = ModelAPI_Feature::feature(*anIt);
66 if (aFeature) addEntity(aFeature, EntityWrapperPtr());
70 else if (theSolverConstraints.front()->type() != CONSTRAINT_PT_PT_COINCIDENT) {
71 // Do not add point-point coincidence, because it is already made by setting
72 // the same parameters for both points
73 std::list<ConstraintWrapperPtr>::iterator aCIt = theSolverConstraints.begin();
74 for (; aCIt != theSolverConstraints.end(); ++aCIt)
78 if (!theSolverConstraints.empty() || aFound == myConstraintMap.end())
79 myConstraintMap[theConstraint] = theSolverConstraints;
80 // block events if necessary
81 if (myEventsBlocked && theConstraint && theConstraint->data() && theConstraint->data()->isValid())
82 theConstraint->data()->blockSendAttributeUpdated(myEventsBlocked);
85 static std::list<AttributePtr> pointAttributes(FeaturePtr theFeature)
87 std::list<AttributePtr> aPoints;
88 if (theFeature->getKind() == SketchPlugin_Arc::ID()) {
89 aPoints.push_back(theFeature->attribute(SketchPlugin_Arc::CENTER_ID()));
90 aPoints.push_back(theFeature->attribute(SketchPlugin_Arc::START_ID()));
91 aPoints.push_back(theFeature->attribute(SketchPlugin_Arc::END_ID()));
93 else if (theFeature->getKind() == SketchPlugin_Circle::ID())
94 aPoints.push_back(theFeature->attribute(SketchPlugin_Circle::CENTER_ID()));
95 else if (theFeature->getKind() == SketchPlugin_Line::ID()) {
96 aPoints.push_back(theFeature->attribute(SketchPlugin_Line::START_ID()));
97 aPoints.push_back(theFeature->attribute(SketchPlugin_Line::END_ID()));
99 else if (theFeature->getKind() == SketchPlugin_Point::ID())
100 aPoints.push_back(theFeature->attribute(SketchPlugin_Point::COORD_ID()));
104 void SketchSolver_Storage::addEntity(FeaturePtr theFeature,
105 EntityWrapperPtr theSolverEntity)
107 std::map<FeaturePtr, EntityWrapperPtr>::const_iterator aFound = myFeatureMap.find(theFeature);
108 if (aFound == myFeatureMap.end() || !aFound->second ||
109 (theSolverEntity && !aFound->second->isEqual(theSolverEntity)))
110 setNeedToResolve(true); // the entity is new or modified
112 if (!theSolverEntity) {
113 // feature links to the empty entity, add its attributes
114 std::list<AttributePtr> aPntAttrs = pointAttributes(theFeature);
115 std::list<AttributePtr>::const_iterator anAttrIt = aPntAttrs.begin();
116 for (; anAttrIt != aPntAttrs.end(); ++anAttrIt)
117 addEntity(*anAttrIt, EntityWrapperPtr());
118 if (aFound == myFeatureMap.end())
119 myFeatureMap[theFeature] = theSolverEntity;
121 myFeatureMap[theFeature] = theSolverEntity;
123 // block events if necessary
124 if (myEventsBlocked && theFeature->data() && theFeature->data()->isValid())
125 theFeature->data()->blockSendAttributeUpdated(myEventsBlocked);
128 void SketchSolver_Storage::addEntity(AttributePtr theAttribute,
129 EntityWrapperPtr theSolverEntity)
131 std::map<AttributePtr, EntityWrapperPtr>::const_iterator aFound = myAttributeMap.find(theAttribute);
132 if (aFound == myAttributeMap.end() || !aFound->second ||
133 (theSolverEntity && !aFound->second->isEqual(theSolverEntity)))
134 setNeedToResolve(true); // the entity is new or modified
136 if (theSolverEntity || aFound == myAttributeMap.end())
137 myAttributeMap[theAttribute] = theSolverEntity;
138 // block events if necessary
139 if (myEventsBlocked && theAttribute->owner() &&
140 theAttribute->owner()->data() && theAttribute->owner()->data()->isValid())
141 theAttribute->owner()->data()->blockSendAttributeUpdated(myEventsBlocked);
145 bool SketchSolver_Storage::update(FeaturePtr theFeature, const GroupID& theGroup)
147 bool isUpdated = false;
148 EntityWrapperPtr aRelated = entity(theFeature);
149 if (!aRelated) { // Feature is not exist, create it
150 std::list<EntityWrapperPtr> aSubs;
151 // Reserve the feature in the map of features (do not want to add several copies of it)
152 myFeatureMap[theFeature] = aRelated;
153 // Firstly, create/update its attributes
154 std::list<AttributePtr> anAttrs = pointAttributes(theFeature);
155 std::list<AttributePtr>::const_iterator anIt = anAttrs.begin();
156 for (; anIt != anAttrs.end(); ++anIt) {
157 isUpdated = update(*anIt, theGroup) || isUpdated;
158 aSubs.push_back(entity(*anIt));
160 // If the feature is a circle, add its radius as a sub
161 if (theFeature->getKind() == SketchPlugin_Circle::ID()) {
162 AttributePtr aRadius = theFeature->attribute(SketchPlugin_Circle::RADIUS_ID());
163 isUpdated = update(aRadius, theGroup) || isUpdated;
164 aSubs.push_back(entity(aRadius));
166 // If the feature if circle or arc, we need to add normal of the sketch to the list of subs
167 if (theFeature->getKind() == SketchPlugin_Arc::ID() ||
168 theFeature->getKind() == SketchPlugin_Circle::ID()) {
169 EntityWrapperPtr aNormal = getNormal();
170 if (aNormal) aSubs.push_back(aNormal);
172 // Secondly, convert feature
173 BuilderPtr aBuilder = SketchSolver_Manager::instance()->builder();
174 GroupID aGroup = theGroup != GID_UNKNOWN ? theGroup : myGroupID;
175 // Check external feature
176 std::shared_ptr<SketchPlugin_Feature> aSketchFeature =
177 std::dynamic_pointer_cast<SketchPlugin_Feature>(theFeature);
178 if (aSketchFeature && aSketchFeature->isExternal())
179 aGroup = GID_OUTOFGROUP;
180 aRelated = aBuilder->createFeature(theFeature, aSubs, aGroup);
183 addEntity(theFeature, aRelated);
184 } else if (theGroup != GID_UNKNOWN)
185 changeGroup(aRelated, theGroup);
186 return update(aRelated) || isUpdated;
189 bool SketchSolver_Storage::update(AttributePtr theAttribute, const GroupID& theGroup)
191 AttributePtr anAttribute = theAttribute;
192 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(anAttribute);
194 if (aRefAttr->isObject()) {
195 FeaturePtr aFeature = ModelAPI_Feature::feature(aRefAttr->object());
196 return update(aFeature, theGroup);
198 anAttribute = aRefAttr->attr();
201 EntityWrapperPtr aRelated = entity(anAttribute);
202 if (!aRelated) { // Attribute is not exist, create it
203 // verify the attribute is a point of arc and add whole arc
204 if (anAttribute->owner()) {
205 FeaturePtr aFeature = ModelAPI_Feature::feature(anAttribute->owner());
206 if (aFeature->getKind() == SketchPlugin_Arc::ID() &&
207 myFeatureMap.find(aFeature) == myFeatureMap.end()) {
208 // Additional checking that all attributes are initialized
209 if (aFeature->attribute(SketchPlugin_Arc::CENTER_ID())->isInitialized() &&
210 aFeature->attribute(SketchPlugin_Arc::START_ID())->isInitialized() &&
211 aFeature->attribute(SketchPlugin_Arc::END_ID())->isInitialized()) {
212 return SketchSolver_Storage::update(aFeature);
214 myFeatureMap[aFeature] = EntityWrapperPtr();
219 BuilderPtr aBuilder = SketchSolver_Manager::instance()->builder();
220 GroupID aGroup = theGroup != GID_UNKNOWN ? theGroup : myGroupID;
221 // Check attribute of external features
222 std::shared_ptr<SketchPlugin_Feature> aSketchFeature =
223 std::dynamic_pointer_cast<SketchPlugin_Feature>(theAttribute->owner());
224 if (aSketchFeature && aSketchFeature->isExternal())
225 aGroup = GID_OUTOFGROUP;
226 aRelated = aBuilder->createAttribute(anAttribute, aGroup);
229 addEntity(anAttribute, aRelated);
230 } else if (theGroup != GID_UNKNOWN)
231 changeGroup(aRelated, theGroup);
232 return update(aRelated);
237 const std::list<ConstraintWrapperPtr>& SketchSolver_Storage::constraint(
238 const ConstraintPtr& theConstraint) const
240 static std::list<ConstraintWrapperPtr> aDummy;
242 std::map<ConstraintPtr, std::list<ConstraintWrapperPtr>>::const_iterator
243 aFound = myConstraintMap.find(theConstraint);
244 if (aFound != myConstraintMap.end())
245 return aFound->second;
249 const EntityWrapperPtr& SketchSolver_Storage::entity(const FeaturePtr& theFeature) const
251 static EntityWrapperPtr aDummy;
253 std::map<FeaturePtr, EntityWrapperPtr>::const_iterator aFound = myFeatureMap.find(theFeature);
254 if (aFound != myFeatureMap.end())
255 return aFound->second;
259 const EntityWrapperPtr& SketchSolver_Storage::entity(const AttributePtr& theAttribute) const
261 static EntityWrapperPtr aDummy;
263 std::map<AttributePtr, EntityWrapperPtr>::const_iterator
264 aFound = myAttributeMap.find(theAttribute);
265 if (aFound != myAttributeMap.end())
266 return aFound->second;
268 AttributeRefAttrPtr aRefAttr =
269 std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
271 if (aRefAttr->isObject()) {
272 FeaturePtr aFeature = ModelAPI_Feature::feature(aRefAttr->object());
273 return entity(aFeature);
275 return entity(aRefAttr->attr());
280 bool SketchSolver_Storage::removeConstraint(ConstraintPtr theConstraint)
282 std::map<ConstraintPtr, std::list<ConstraintWrapperPtr> >::iterator
283 aFound = myConstraintMap.find(theConstraint);
284 if (aFound == myConstraintMap.end())
285 return true; // no constraint, already deleted
288 std::list<ConstraintWrapperPtr> aConstrList = aFound->second;
289 myConstraintMap.erase(aFound);
290 // Remove SolveSpace constraints
291 bool isFullyRemoved = true;
292 std::list<ConstraintWrapperPtr>::iterator anIt = aConstrList.begin();
293 while (anIt != aConstrList.end()) {
295 std::list<ConstraintWrapperPtr>::iterator aRemoveIt = anIt++;
296 aConstrList.erase(aRemoveIt);
298 isFullyRemoved = false;
302 return isFullyRemoved;
305 template <class ENT_TYPE>
306 static bool isUsed(ConstraintWrapperPtr theConstraint, ENT_TYPE theEntity)
308 if (!theConstraint || !theEntity)
310 std::list<EntityWrapperPtr>::const_iterator anEntIt = theConstraint->entities().begin();
311 for (; anEntIt != theConstraint->entities().end(); ++anEntIt)
312 if ((*anEntIt)->isBase(theEntity))
317 static bool isUsed(EntityWrapperPtr theFeature, AttributePtr theSubEntity)
319 if (!theFeature || !theSubEntity)
321 std::list<EntityWrapperPtr>::const_iterator aSubIt = theFeature->subEntities().begin();
322 for (; aSubIt != theFeature->subEntities().end(); ++aSubIt)
323 if ((*aSubIt)->isBase(theSubEntity))
328 static bool isUsed(ConstraintPtr theConstraint, AttributePtr theAttribute)
330 if (!theConstraint || !theAttribute)
332 std::list<AttributePtr> anAttrList = theConstraint->data()->attributes(std::string());
333 std::list<AttributePtr>::const_iterator anIt = anAttrList.begin();
334 for (; anIt != anAttrList.end(); ++anIt) {
335 if (*anIt == theAttribute)
337 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anIt);
338 if (aRefAttr && !aRefAttr->isObject() && aRefAttr->attr() == theAttribute)
344 bool SketchSolver_Storage::isUsed(FeaturePtr theFeature) const
346 if (myFeatureMap.find(theFeature) != myFeatureMap.end())
349 std::map<ConstraintPtr, std::list<ConstraintWrapperPtr> >::const_iterator
350 aCIt = myConstraintMap.begin();
351 std::list<ConstraintWrapperPtr>::const_iterator aCWIt;
352 for (; aCIt != myConstraintMap.end(); ++aCIt)
353 for (aCWIt = aCIt->second.begin(); aCWIt != aCIt->second.end(); ++aCWIt)
354 if (::isUsed(*aCWIt, theFeature))
357 std::list<AttributePtr> anAttrList = pointAttributes(theFeature);
358 std::list<AttributePtr>::const_iterator anIt = anAttrList.begin();
359 for (; anIt != anAttrList.end(); ++anIt)
365 bool SketchSolver_Storage::isUsed(AttributePtr theAttribute) const
367 AttributePtr anAttribute = theAttribute;
368 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(anAttribute);
370 if (aRefAttr->isObject())
371 return isUsed(ModelAPI_Feature::feature(aRefAttr->object()));
373 anAttribute = aRefAttr->attr();
376 if (myAttributeMap.find(theAttribute) != myAttributeMap.end())
378 // check in constraints
379 std::map<ConstraintPtr, std::list<ConstraintWrapperPtr> >::const_iterator
380 aCIt = myConstraintMap.begin();
381 std::list<ConstraintWrapperPtr>::const_iterator aCWIt;
382 for (; aCIt != myConstraintMap.end(); ++aCIt) {
383 for (aCWIt = aCIt->second.begin(); aCWIt != aCIt->second.end(); ++aCWIt)
384 if (::isUsed(*aCWIt, anAttribute))
386 // Additional check for the Fixed constraints, which have no wrapper associated.
387 if (aCIt->first->getKind() == SketchPlugin_ConstraintRigid::ID() &&
388 ::isUsed(aCIt->first, anAttribute))
392 std::map<FeaturePtr, EntityWrapperPtr>::const_iterator aFIt = myFeatureMap.begin();
393 for (; aFIt != myFeatureMap.end(); ++aFIt)
394 if (::isUsed(aFIt->second, anAttribute))
400 bool SketchSolver_Storage::removeEntity(FeaturePtr theFeature)
402 std::map<FeaturePtr, EntityWrapperPtr>::iterator aFound = myFeatureMap.find(theFeature);
403 if (aFound == myFeatureMap.end())
404 return true; // feature not found, nothing to delete
406 EntityWrapperPtr anEntity = aFound->second;
407 myFeatureMap.erase(aFound);
409 // Check if the feature is not used by constraints, remove it
410 if (!anEntity || (!isUsed(theFeature) && remove(anEntity)))
413 // feature is not removed, revert operation
414 myFeatureMap[theFeature] = anEntity;
419 bool SketchSolver_Storage::removeEntity(AttributePtr theAttribute)
421 std::map<AttributePtr, EntityWrapperPtr>::iterator aFound = myAttributeMap.find(theAttribute);
422 if (aFound == myAttributeMap.end())
423 return true; // attribute not found, nothing to delete
425 EntityWrapperPtr anEntity = aFound->second;
426 myAttributeMap.erase(aFound);
428 // Check if the attribute is not used by constraints and features, remove it
429 if (!anEntity || (!isUsed(theAttribute) && remove(anEntity)))
432 // attribute is not removed, revert operation
433 myAttributeMap[theAttribute] = anEntity;
439 bool SketchSolver_Storage::remove(ConstraintWrapperPtr theConstraint)
441 bool isFullyRemoved = true;
442 std::list<EntityWrapperPtr>::const_iterator anIt = theConstraint->entities().begin();
443 for (; anIt != theConstraint->entities().end(); ++anIt) {
444 FeaturePtr aBaseFeature = (*anIt)->baseFeature();
446 isFullyRemoved = SketchSolver_Storage::removeEntity(aBaseFeature) && isFullyRemoved;
448 isFullyRemoved = SketchSolver_Storage::removeEntity((*anIt)->baseAttribute()) && isFullyRemoved;
450 return isFullyRemoved;
453 bool SketchSolver_Storage::remove(EntityWrapperPtr theEntity)
455 bool isFullyRemoved = true;
456 std::list<EntityWrapperPtr>::const_iterator anEntIt = theEntity->subEntities().begin();
457 for (; anEntIt != theEntity->subEntities().end(); ++anEntIt) {
458 FeaturePtr aBaseFeature = (*anEntIt)->baseFeature();
460 isFullyRemoved = SketchSolver_Storage::removeEntity(aBaseFeature) && isFullyRemoved;
462 isFullyRemoved = SketchSolver_Storage::removeEntity((*anEntIt)->baseAttribute()) && isFullyRemoved;
465 std::list<ParameterWrapperPtr>::const_iterator aParIt = theEntity->parameters().begin();
466 for (; aParIt != theEntity->parameters().end(); ++aParIt)
467 isFullyRemoved = remove(*aParIt) && isFullyRemoved;
468 return isFullyRemoved;
472 bool SketchSolver_Storage::isInteract(const FeaturePtr& theFeature) const
476 if (myConstraintMap.empty())
477 return true; // empty storage interacts with each feature
479 ConstraintPtr aConstraint = std::dynamic_pointer_cast<SketchPlugin_Constraint>(theFeature);
481 if (myConstraintMap.find(aConstraint) != myConstraintMap.end())
483 } else if (myFeatureMap.find(theFeature) != myFeatureMap.end())
486 std::list<AttributePtr> anAttrList = theFeature->data()->attributes(std::string());
487 std::list<AttributePtr>::const_iterator anIt = anAttrList.begin();
488 for (; anIt != anAttrList.end(); ++anIt)
489 if (isInteract(*anIt))
495 bool SketchSolver_Storage::isInteract(const AttributePtr& theAttribute) const
500 AttributeRefListPtr aRefList =
501 std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(theAttribute);
503 std::list<ObjectPtr> anObjects = aRefList->list();
504 std::list<ObjectPtr>::iterator anObjIt = anObjects.begin();
505 for (; anObjIt != anObjects.end(); ++anObjIt) {
506 FeaturePtr aFeature = ModelAPI_Feature::feature(*anObjIt);
507 if (isInteract(aFeature))
513 AttributeRefAttrPtr aRefAttr =
514 std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
516 return myAttributeMap.find(theAttribute) != myAttributeMap.end();
517 if (!aRefAttr->isObject())
518 return myAttributeMap.find(aRefAttr->attr()) != myAttributeMap.end();
520 FeaturePtr aFeature = ModelAPI_Feature::feature(aRefAttr->object());
521 return isInteract(aFeature);
524 bool SketchSolver_Storage::isConsistent() const
526 // Check the constraints are valid
527 std::map<ConstraintPtr, std::list<ConstraintWrapperPtr> >::const_iterator
528 aCIter = myConstraintMap.begin();
529 for (; aCIter != myConstraintMap.end(); ++aCIter)
530 if (!aCIter->first->data() || !aCIter->first->data()->isValid())
532 // Check the features are valid
533 std::map<FeaturePtr, EntityWrapperPtr>::const_iterator aFIter = myFeatureMap.begin();
534 for (; aFIter != myFeatureMap.end(); aFIter++)
535 if (!aFIter->first->data() || !aFIter->first->data()->isValid())
540 bool SketchSolver_Storage::isFixed(EntityWrapperPtr theEntity) const
542 if (theEntity->group() != myGroupID)
544 // no need additional checking for entities differ than point
545 if (theEntity->type() != ENTITY_POINT)
548 CoincidentPointsMap::const_iterator anIt = myCoincidentPoints.begin();
549 for (; anIt != myCoincidentPoints.end(); ++anIt)
550 if (anIt->first == theEntity || anIt->second.find(theEntity) != anIt->second.end()) {
551 if (anIt->first->group() != myGroupID)
553 std::set<EntityWrapperPtr>::const_iterator anEntIt = anIt->second.begin();
554 for (; anEntIt != anIt->second.end(); ++anEntIt)
555 if ((*anEntIt)->group() != myGroupID)
559 std::map<ConstraintPtr, std::list<ConstraintWrapperPtr> >::const_iterator aCIt = myConstraintMap.begin();
560 std::list<ConstraintWrapperPtr>::const_iterator aCWIt;
561 for (; aCIt != myConstraintMap.end(); ++aCIt) {
562 if (aCIt->second.empty())
564 aCWIt = aCIt->second.begin();
565 if ((*aCWIt)->type() != CONSTRAINT_FIXED)
567 for (; aCWIt != aCIt->second.end(); ++aCIt)
568 if ((theEntity->baseAttribute() && (*aCWIt)->isUsed(theEntity->baseAttribute())) ||
569 (theEntity->baseFeature() && (*aCWIt)->isUsed(theEntity->baseFeature())))
576 void SketchSolver_Storage::removeInvalidEntities()
578 // Remove invalid constraints
579 std::list<ConstraintPtr> anInvalidConstraints;
580 std::map<ConstraintPtr, std::list<ConstraintWrapperPtr> >::const_iterator
581 aCIter = myConstraintMap.begin();
582 for (; aCIter != myConstraintMap.end(); ++aCIter)
583 if (!aCIter->first->data() || !aCIter->first->data()->isValid())
584 anInvalidConstraints.push_back(aCIter->first);
585 std::list<ConstraintPtr>::const_iterator anInvCIt = anInvalidConstraints.begin();
586 for (; anInvCIt != anInvalidConstraints.end(); ++anInvCIt)
587 removeConstraint(*anInvCIt);
588 // Remove invalid features
589 std::list<FeaturePtr> anInvalidFeatures;
590 std::map<FeaturePtr, EntityWrapperPtr>::const_iterator aFIter = myFeatureMap.begin();
591 for (; aFIter != myFeatureMap.end(); aFIter++)
592 if (!aFIter->first->data() || !aFIter->first->data()->isValid())
593 anInvalidFeatures.push_back(aFIter->first);
594 std::list<FeaturePtr>::const_iterator anInvFIt = anInvalidFeatures.begin();
595 for (; anInvFIt != anInvalidFeatures.end(); ++anInvFIt)
596 removeEntity(*anInvFIt);
599 EntityWrapperPtr SketchSolver_Storage::getNormal() const
601 EntityWrapperPtr aSketch = sketch();
605 // Find normal entity
606 const std::list<EntityWrapperPtr>& aSketchSubs = aSketch->subEntities();
607 std::list<EntityWrapperPtr>::const_iterator aSIt = aSketchSubs.begin();
608 for (; aSIt != aSketchSubs.end(); ++aSIt)
609 if ((*aSIt)->type() == ENTITY_NORMAL)
611 return EntityWrapperPtr();
614 const EntityWrapperPtr& SketchSolver_Storage::sketch() const
616 static EntityWrapperPtr aDummySketch;
618 std::map<FeaturePtr, EntityWrapperPtr>::const_iterator aFIt = myFeatureMap.begin();
619 for (; aFIt != myFeatureMap.end(); ++aFIt)
620 if (aFIt->second && aFIt->second->type() == ENTITY_SKETCH)
622 if (aFIt == myFeatureMap.end())
627 void SketchSolver_Storage::setSketch(const EntityWrapperPtr& theSketch)
631 addEntity(FeaturePtr(), theSketch);
634 void SketchSolver_Storage::processArcs()
637 std::map<FeaturePtr, EntityWrapperPtr>::iterator aFIt = myFeatureMap.begin();
638 for (; aFIt != myFeatureMap.end(); ++aFIt)
639 if (!aFIt->second && aFIt->first->getKind() == SketchPlugin_Arc::ID()) {
640 // Additional checking the attributes are initialized
641 if (aFIt->first->attribute(SketchPlugin_Arc::CENTER_ID())->isInitialized() &&
642 aFIt->first->attribute(SketchPlugin_Arc::START_ID())->isInitialized() &&
643 aFIt->first->attribute(SketchPlugin_Arc::END_ID())->isInitialized())
650 void SketchSolver_Storage::blockEvents(bool isBlocked)
652 if (isBlocked == myEventsBlocked)
655 std::map<ConstraintPtr, std::list<ConstraintWrapperPtr> >::const_iterator
656 aCIter = myConstraintMap.begin();
657 for (; aCIter != myConstraintMap.end(); aCIter++)
658 if (aCIter->first->data() && aCIter->first->data()->isValid())
659 aCIter->first->data()->blockSendAttributeUpdated(isBlocked);
661 std::map<FeaturePtr, EntityWrapperPtr>::const_iterator aFIter = myFeatureMap.begin();
662 for (; aFIter != myFeatureMap.end(); aFIter++)
663 if (aFIter->first->data() && aFIter->first->data()->isValid())
664 aFIter->first->data()->blockSendAttributeUpdated(isBlocked);
666 std::map<AttributePtr, EntityWrapperPtr>::const_iterator anAtIter = myAttributeMap.begin();
667 for (; anAtIter != myAttributeMap.end(); anAtIter++)
668 if (anAtIter->first->owner() && anAtIter->first->owner()->data() &&
669 anAtIter->first->owner()->data()->isValid())
670 anAtIter->first->owner()->data()->blockSendAttributeUpdated(isBlocked);
671 myEventsBlocked = isBlocked;
674 std::set<ObjectPtr> SketchSolver_Storage::getConflictingConstraints(SolverPtr theSolver) const
676 std::set<ObjectPtr> aConflicting;
677 std::map<ConstraintPtr, std::list<ConstraintWrapperPtr> >::const_iterator
678 aConstrIt = myConstraintMap.begin();
679 for (; aConstrIt != myConstraintMap.end(); ++aConstrIt) {
680 std::list<ConstraintWrapperPtr>::const_iterator anIt = aConstrIt->second.begin();
681 for (; anIt != aConstrIt->second.end(); ++anIt)
682 if (theSolver->isConflicting((*anIt)->id())) {
683 aConflicting.insert(aConstrIt->first);
694 // ============== Auxiliary functions ====================================
695 bool isEqual(const std::list<ConstraintWrapperPtr>& theCVec1,
696 const std::list<ConstraintWrapperPtr>& theCVec2)
698 if (theCVec1.size() != theCVec2.size())
701 std::list<bool> aChecked(theCVec2.size(), false);
702 std::list<ConstraintWrapperPtr>::const_iterator anIt1 = theCVec1.begin();
703 for (; anIt1 != theCVec1.end(); ++anIt1) {
704 std::list<ConstraintWrapperPtr>::const_iterator anIt2 = theCVec2.begin();
705 std::list<bool>::iterator aCheckIt = aChecked.begin();
706 while (aCheckIt != aChecked.end() && *aCheckIt) {
710 for (; anIt2 != theCVec2.end(); ++anIt2, ++aCheckIt)
711 if (!(*aCheckIt) && (*anIt1)->isEqual(*anIt2)) {
715 // the same constraint is not found
716 if (anIt2 == theCVec2.end())