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_IntersectionPoint.h>
18 #include <SketchPlugin_ConstraintMirror.h>
19 #include <SketchPlugin_ConstraintRigid.h>
22 /// \brief Verify two vectors of constraints are equal.
23 /// Vectors differ by the order of elements are equal.
24 static bool isEqual(const std::list<ConstraintWrapperPtr>& theCVec1,
25 const std::list<ConstraintWrapperPtr>& theCVec2);
28 void SketchSolver_Storage::addConstraint(ConstraintPtr theConstraint,
29 ConstraintWrapperPtr theSolverConstraint)
31 if (theSolverConstraint) {
32 std::list<ConstraintWrapperPtr> aConstrList(1, theSolverConstraint);
33 addConstraint(theConstraint, aConstrList);
35 addConstraint(theConstraint, std::list<ConstraintWrapperPtr>());
38 void SketchSolver_Storage::addConstraint(
39 ConstraintPtr theConstraint,
40 std::list<ConstraintWrapperPtr> theSolverConstraints)
42 std::map<ConstraintPtr, std::list<ConstraintWrapperPtr> >::const_iterator
43 aFound = myConstraintMap.find(theConstraint);
44 if (aFound == myConstraintMap.end() || !isEqual(aFound->second, theSolverConstraints))
45 setNeedToResolve(true);
47 if (theSolverConstraints.empty()) {
48 // constraint links to the empty list, add its attributes linked to the empty entities
49 std::list<AttributePtr> aRefAttrs =
50 theConstraint->data()->attributes(ModelAPI_AttributeRefAttr::typeId());
51 std::list<AttributePtr>::const_iterator anAttrIt = aRefAttrs.begin();
52 for (; anAttrIt != aRefAttrs.end(); ++anAttrIt) {
53 AttributeRefAttrPtr aRef = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anAttrIt);
54 if (aRef->isObject()) {
55 FeaturePtr aFeature = ModelAPI_Feature::feature(aRef->object());
56 if (aFeature) addEntity(aFeature, EntityWrapperPtr());
58 addEntity(aRef->attr(), EntityWrapperPtr());
60 std::list<AttributePtr> aRefLists =
61 theConstraint->data()->attributes(ModelAPI_AttributeRefList::typeId());
62 for (anAttrIt = aRefLists.begin(); anAttrIt != aRefLists.end(); ++anAttrIt) {
63 AttributeRefListPtr aRef = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(*anAttrIt);
64 std::list<ObjectPtr> anObj = aRef->list();
65 std::list<ObjectPtr>::iterator anIt = anObj.begin();
66 for (; anIt != anObj.end(); ++anIt) {
67 FeaturePtr aFeature = ModelAPI_Feature::feature(*anIt);
68 if (aFeature) addEntity(aFeature, EntityWrapperPtr());
72 else if (theSolverConstraints.front()->type() != CONSTRAINT_PT_PT_COINCIDENT) {
73 // Do not add point-point coincidence, because it is already made by setting
74 // the same parameters for both points
75 std::list<ConstraintWrapperPtr>::iterator aCIt = theSolverConstraints.begin();
76 for (; aCIt != theSolverConstraints.end(); ++aCIt)
80 if (!theSolverConstraints.empty() || aFound == myConstraintMap.end())
81 myConstraintMap[theConstraint] = theSolverConstraints;
82 // block events if necessary
83 if (myEventsBlocked && theConstraint && theConstraint->data() && theConstraint->data()->isValid())
84 theConstraint->data()->blockSendAttributeUpdated(myEventsBlocked);
87 static std::list<AttributePtr> pointAttributes(FeaturePtr theFeature)
89 std::list<AttributePtr> aPoints;
90 if (theFeature->getKind() == SketchPlugin_Arc::ID()) {
91 aPoints.push_back(theFeature->attribute(SketchPlugin_Arc::CENTER_ID()));
92 aPoints.push_back(theFeature->attribute(SketchPlugin_Arc::START_ID()));
93 aPoints.push_back(theFeature->attribute(SketchPlugin_Arc::END_ID()));
95 else if (theFeature->getKind() == SketchPlugin_Circle::ID())
96 aPoints.push_back(theFeature->attribute(SketchPlugin_Circle::CENTER_ID()));
97 else if (theFeature->getKind() == SketchPlugin_Line::ID()) {
98 aPoints.push_back(theFeature->attribute(SketchPlugin_Line::START_ID()));
99 aPoints.push_back(theFeature->attribute(SketchPlugin_Line::END_ID()));
101 else if (theFeature->getKind() == SketchPlugin_Point::ID() ||
102 theFeature->getKind() == SketchPlugin_IntersectionPoint::ID())
103 aPoints.push_back(theFeature->attribute(SketchPlugin_Point::COORD_ID()));
107 void SketchSolver_Storage::addEntity(FeaturePtr theFeature,
108 EntityWrapperPtr theSolverEntity)
110 std::map<FeaturePtr, EntityWrapperPtr>::const_iterator aFound = myFeatureMap.find(theFeature);
111 if (aFound == myFeatureMap.end() || !aFound->second ||
112 (theSolverEntity && !aFound->second->isEqual(theSolverEntity)))
113 setNeedToResolve(true); // the entity is new or modified
115 if (!theSolverEntity) {
116 // feature links to the empty entity, add its attributes
117 std::list<AttributePtr> aPntAttrs = pointAttributes(theFeature);
118 std::list<AttributePtr>::const_iterator anAttrIt = aPntAttrs.begin();
119 for (; anAttrIt != aPntAttrs.end(); ++anAttrIt)
120 addEntity(*anAttrIt, EntityWrapperPtr());
121 if (aFound == myFeatureMap.end())
122 myFeatureMap[theFeature] = theSolverEntity;
124 myFeatureMap[theFeature] = theSolverEntity;
126 // block events if necessary
127 if (myEventsBlocked && theFeature->data() && theFeature->data()->isValid())
128 theFeature->data()->blockSendAttributeUpdated(myEventsBlocked);
131 void SketchSolver_Storage::addEntity(AttributePtr theAttribute,
132 EntityWrapperPtr theSolverEntity)
134 std::map<AttributePtr, EntityWrapperPtr>::const_iterator aFound = myAttributeMap.find(theAttribute);
135 if (aFound == myAttributeMap.end() || !aFound->second ||
136 (theSolverEntity && !aFound->second->isEqual(theSolverEntity)))
137 setNeedToResolve(true); // the entity is new or modified
139 if (theSolverEntity || aFound == myAttributeMap.end())
140 myAttributeMap[theAttribute] = theSolverEntity;
141 // block events if necessary
142 if (myEventsBlocked && theAttribute->owner() &&
143 theAttribute->owner()->data() && theAttribute->owner()->data()->isValid())
144 theAttribute->owner()->data()->blockSendAttributeUpdated(myEventsBlocked);
148 static bool isCopyInMulti(std::shared_ptr<SketchPlugin_Feature> theFeature,
149 const std::map<ConstraintPtr, std::list<ConstraintWrapperPtr> >& theConstraints)
151 bool aResult = theFeature->isCopy();
153 std::map<ConstraintPtr, std::list<ConstraintWrapperPtr> >::const_iterator
154 anIt = theConstraints.begin();
155 for (; anIt != theConstraints.end() && aResult; ++anIt) {
156 if (anIt->first->getKind() != SketchPlugin_ConstraintMirror::ID())
158 AttributeRefListPtr aRefList = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
159 anIt->first->attribute(SketchPlugin_Constraint::ENTITY_C()));
160 std::list<ObjectPtr> aMirroredList = aRefList->list();
161 std::list<ObjectPtr>::const_iterator aMIt = aMirroredList.begin();
162 for (; aMIt != aMirroredList.end() && aResult; ++aMIt) {
163 FeaturePtr aFeat = ModelAPI_Feature::feature(*aMIt);
164 if (aFeat == theFeature)
172 bool SketchSolver_Storage::update(FeaturePtr theFeature, const GroupID& theGroup)
174 bool isUpdated = false;
175 EntityWrapperPtr aRelated = entity(theFeature);
176 if (!aRelated) { // Feature is not exist, create it
177 std::list<EntityWrapperPtr> aSubs;
178 // Reserve the feature in the map of features (do not want to add several copies of it)
179 myFeatureMap[theFeature] = aRelated;
180 // Firstly, create/update its attributes
181 std::list<AttributePtr> anAttrs = pointAttributes(theFeature);
182 std::list<AttributePtr>::const_iterator anIt = anAttrs.begin();
183 for (; anIt != anAttrs.end(); ++anIt) {
184 isUpdated = update(*anIt, theGroup) || isUpdated;
185 aSubs.push_back(entity(*anIt));
187 // If the feature is a circle, add its radius as a sub
188 if (theFeature->getKind() == SketchPlugin_Circle::ID()) {
189 AttributePtr aRadius = theFeature->attribute(SketchPlugin_Circle::RADIUS_ID());
190 isUpdated = update(aRadius, theGroup) || isUpdated;
191 aSubs.push_back(entity(aRadius));
193 // If the feature if circle or arc, we need to add normal of the sketch to the list of subs
194 if (theFeature->getKind() == SketchPlugin_Arc::ID() ||
195 theFeature->getKind() == SketchPlugin_Circle::ID()) {
196 EntityWrapperPtr aNormal = getNormal();
197 if (aNormal) aSubs.push_back(aNormal);
199 // Secondly, convert feature
200 BuilderPtr aBuilder = SketchSolver_Manager::instance()->builder();
201 GroupID aGroup = theGroup != GID_UNKNOWN ? theGroup : myGroupID;
202 // Check external feature
203 std::shared_ptr<SketchPlugin_Feature> aSketchFeature =
204 std::dynamic_pointer_cast<SketchPlugin_Feature>(theFeature);
205 if (aSketchFeature && (aSketchFeature->isExternal() || isCopyInMulti(aSketchFeature, myConstraintMap)))
206 aGroup = GID_OUTOFGROUP;
207 aRelated = aBuilder->createFeature(theFeature, aSubs, aGroup);
210 addEntity(theFeature, aRelated);
211 } else if (theGroup != GID_UNKNOWN)
212 changeGroup(aRelated, theGroup);
213 return update(aRelated) || isUpdated;
216 bool SketchSolver_Storage::update(AttributePtr theAttribute, const GroupID& theGroup)
218 AttributePtr anAttribute = theAttribute;
219 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(anAttribute);
221 if (aRefAttr->isObject()) {
222 FeaturePtr aFeature = ModelAPI_Feature::feature(aRefAttr->object());
223 return update(aFeature, theGroup);
225 anAttribute = aRefAttr->attr();
228 EntityWrapperPtr aRelated = entity(anAttribute);
229 if (!aRelated) { // Attribute is not exist, create it
230 // verify the attribute is a point of arc and add whole arc
231 if (anAttribute->owner()) {
232 FeaturePtr aFeature = ModelAPI_Feature::feature(anAttribute->owner());
233 if (aFeature->getKind() == SketchPlugin_Arc::ID() &&
234 myFeatureMap.find(aFeature) == myFeatureMap.end()) {
235 // Additional checking that all attributes are initialized
236 if (aFeature->attribute(SketchPlugin_Arc::CENTER_ID())->isInitialized() &&
237 aFeature->attribute(SketchPlugin_Arc::START_ID())->isInitialized() &&
238 aFeature->attribute(SketchPlugin_Arc::END_ID())->isInitialized()) {
239 return SketchSolver_Storage::update(aFeature);
241 myFeatureMap[aFeature] = EntityWrapperPtr();
246 BuilderPtr aBuilder = SketchSolver_Manager::instance()->builder();
247 GroupID aGroup = theGroup != GID_UNKNOWN ? theGroup : myGroupID;
248 // Check attribute of external features
249 std::shared_ptr<SketchPlugin_Feature> aSketchFeature =
250 std::dynamic_pointer_cast<SketchPlugin_Feature>(theAttribute->owner());
251 if (aSketchFeature && (aSketchFeature->isExternal() || isCopyInMulti(aSketchFeature, myConstraintMap)))
252 aGroup = GID_OUTOFGROUP;
253 aRelated = aBuilder->createAttribute(anAttribute, aGroup);
256 addEntity(anAttribute, aRelated);
257 } else if (theGroup != GID_UNKNOWN)
258 changeGroup(aRelated, theGroup);
259 return update(aRelated);
264 const std::list<ConstraintWrapperPtr>& SketchSolver_Storage::constraint(
265 const ConstraintPtr& theConstraint) const
267 static std::list<ConstraintWrapperPtr> aDummy;
269 std::map<ConstraintPtr, std::list<ConstraintWrapperPtr>>::const_iterator
270 aFound = myConstraintMap.find(theConstraint);
271 if (aFound != myConstraintMap.end())
272 return aFound->second;
276 const EntityWrapperPtr& SketchSolver_Storage::entity(const FeaturePtr& theFeature) const
278 static EntityWrapperPtr aDummy;
280 std::map<FeaturePtr, EntityWrapperPtr>::const_iterator aFound = myFeatureMap.find(theFeature);
281 if (aFound != myFeatureMap.end())
282 return aFound->second;
286 const EntityWrapperPtr& SketchSolver_Storage::entity(const AttributePtr& theAttribute) const
288 static EntityWrapperPtr aDummy;
290 std::map<AttributePtr, EntityWrapperPtr>::const_iterator
291 aFound = myAttributeMap.find(theAttribute);
292 if (aFound != myAttributeMap.end())
293 return aFound->second;
295 AttributeRefAttrPtr aRefAttr =
296 std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
298 if (aRefAttr->isObject()) {
299 FeaturePtr aFeature = ModelAPI_Feature::feature(aRefAttr->object());
300 return entity(aFeature);
302 return entity(aRefAttr->attr());
307 bool SketchSolver_Storage::removeConstraint(ConstraintPtr theConstraint)
309 std::map<ConstraintPtr, std::list<ConstraintWrapperPtr> >::iterator
310 aFound = myConstraintMap.find(theConstraint);
311 if (aFound == myConstraintMap.end())
312 return true; // no constraint, already deleted
315 std::list<ConstraintWrapperPtr> aConstrList = aFound->second;
316 myConstraintMap.erase(aFound);
317 // Remove SolveSpace constraints
318 bool isFullyRemoved = true;
319 std::list<ConstraintWrapperPtr>::iterator anIt = aConstrList.begin();
320 while (anIt != aConstrList.end()) {
322 std::list<ConstraintWrapperPtr>::iterator aRemoveIt = anIt++;
323 aConstrList.erase(aRemoveIt);
325 isFullyRemoved = false;
329 return isFullyRemoved;
332 template <class ENT_TYPE>
333 static bool isUsed(ConstraintWrapperPtr theConstraint, ENT_TYPE theEntity)
335 if (!theConstraint || !theEntity)
337 std::list<EntityWrapperPtr>::const_iterator anEntIt = theConstraint->entities().begin();
338 for (; anEntIt != theConstraint->entities().end(); ++anEntIt)
339 if ((*anEntIt)->isBase(theEntity))
344 static bool isUsed(EntityWrapperPtr theFeature, AttributePtr theSubEntity)
346 if (!theFeature || !theSubEntity)
348 std::list<EntityWrapperPtr>::const_iterator aSubIt = theFeature->subEntities().begin();
349 for (; aSubIt != theFeature->subEntities().end(); ++aSubIt)
350 if ((*aSubIt)->isBase(theSubEntity))
355 static bool isUsed(ConstraintPtr theConstraint, AttributePtr theAttribute)
357 if (!theConstraint || !theAttribute)
359 std::list<AttributePtr> anAttrList = theConstraint->data()->attributes(std::string());
360 std::list<AttributePtr>::const_iterator anIt = anAttrList.begin();
361 for (; anIt != anAttrList.end(); ++anIt) {
362 if (*anIt == theAttribute)
364 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anIt);
365 if (aRefAttr && !aRefAttr->isObject() && aRefAttr->attr() == theAttribute)
371 bool SketchSolver_Storage::isUsed(FeaturePtr theFeature) const
373 if (myFeatureMap.find(theFeature) != myFeatureMap.end())
376 std::map<ConstraintPtr, std::list<ConstraintWrapperPtr> >::const_iterator
377 aCIt = myConstraintMap.begin();
378 std::list<ConstraintWrapperPtr>::const_iterator aCWIt;
379 for (; aCIt != myConstraintMap.end(); ++aCIt)
380 for (aCWIt = aCIt->second.begin(); aCWIt != aCIt->second.end(); ++aCWIt)
381 if (::isUsed(*aCWIt, theFeature))
384 std::list<AttributePtr> anAttrList = pointAttributes(theFeature);
385 std::list<AttributePtr>::const_iterator anIt = anAttrList.begin();
386 for (; anIt != anAttrList.end(); ++anIt)
392 bool SketchSolver_Storage::isUsed(AttributePtr theAttribute) const
394 AttributePtr anAttribute = theAttribute;
395 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(anAttribute);
397 if (aRefAttr->isObject())
398 return isUsed(ModelAPI_Feature::feature(aRefAttr->object()));
400 anAttribute = aRefAttr->attr();
403 if (myAttributeMap.find(theAttribute) != myAttributeMap.end())
405 // check in constraints
406 std::map<ConstraintPtr, std::list<ConstraintWrapperPtr> >::const_iterator
407 aCIt = myConstraintMap.begin();
408 std::list<ConstraintWrapperPtr>::const_iterator aCWIt;
409 for (; aCIt != myConstraintMap.end(); ++aCIt) {
410 for (aCWIt = aCIt->second.begin(); aCWIt != aCIt->second.end(); ++aCWIt)
411 if (::isUsed(*aCWIt, anAttribute))
413 // Additional check for the Fixed constraints, which have no wrapper associated.
414 if (aCIt->first->getKind() == SketchPlugin_ConstraintRigid::ID() &&
415 ::isUsed(aCIt->first, anAttribute))
419 std::map<FeaturePtr, EntityWrapperPtr>::const_iterator aFIt = myFeatureMap.begin();
420 for (; aFIt != myFeatureMap.end(); ++aFIt)
421 if (::isUsed(aFIt->second, anAttribute))
427 bool SketchSolver_Storage::removeEntity(FeaturePtr theFeature)
429 std::map<FeaturePtr, EntityWrapperPtr>::iterator aFound = myFeatureMap.find(theFeature);
430 if (aFound == myFeatureMap.end())
431 return true; // feature not found, nothing to delete
433 EntityWrapperPtr anEntity = aFound->second;
434 myFeatureMap.erase(aFound);
436 // Check if the feature is not used by constraints, remove it
437 if (!anEntity || (!isUsed(theFeature) && remove(anEntity)))
440 // feature is not removed, revert operation
441 myFeatureMap[theFeature] = anEntity;
446 bool SketchSolver_Storage::removeEntity(AttributePtr theAttribute)
448 std::map<AttributePtr, EntityWrapperPtr>::iterator aFound = myAttributeMap.find(theAttribute);
449 if (aFound == myAttributeMap.end())
450 return true; // attribute not found, nothing to delete
452 EntityWrapperPtr anEntity = aFound->second;
453 myAttributeMap.erase(aFound);
455 // Check if the attribute is not used by constraints and features, remove it
456 if (!anEntity || (!isUsed(theAttribute) && remove(anEntity)))
459 // attribute is not removed, revert operation
460 myAttributeMap[theAttribute] = anEntity;
466 bool SketchSolver_Storage::remove(ConstraintWrapperPtr theConstraint)
468 bool isFullyRemoved = true;
469 std::list<EntityWrapperPtr>::const_iterator anIt = theConstraint->entities().begin();
470 for (; anIt != theConstraint->entities().end(); ++anIt) {
471 FeaturePtr aBaseFeature = (*anIt)->baseFeature();
473 isFullyRemoved = SketchSolver_Storage::removeEntity(aBaseFeature) && isFullyRemoved;
475 isFullyRemoved = SketchSolver_Storage::removeEntity((*anIt)->baseAttribute()) && isFullyRemoved;
477 return isFullyRemoved;
480 bool SketchSolver_Storage::remove(EntityWrapperPtr theEntity)
482 bool isFullyRemoved = true;
483 std::list<EntityWrapperPtr>::const_iterator anEntIt = theEntity->subEntities().begin();
484 for (; anEntIt != theEntity->subEntities().end(); ++anEntIt) {
485 FeaturePtr aBaseFeature = (*anEntIt)->baseFeature();
487 isFullyRemoved = SketchSolver_Storage::removeEntity(aBaseFeature) && isFullyRemoved;
489 isFullyRemoved = SketchSolver_Storage::removeEntity((*anEntIt)->baseAttribute()) && isFullyRemoved;
492 std::list<ParameterWrapperPtr>::const_iterator aParIt = theEntity->parameters().begin();
493 for (; aParIt != theEntity->parameters().end(); ++aParIt)
494 isFullyRemoved = remove(*aParIt) && isFullyRemoved;
495 return isFullyRemoved;
499 bool SketchSolver_Storage::isInteract(const FeaturePtr& theFeature) const
503 if (myConstraintMap.empty())
504 return true; // empty storage interacts with each feature
506 ConstraintPtr aConstraint = std::dynamic_pointer_cast<SketchPlugin_Constraint>(theFeature);
508 if (myConstraintMap.find(aConstraint) != myConstraintMap.end())
510 } else if (myFeatureMap.find(theFeature) != myFeatureMap.end())
513 std::list<AttributePtr> anAttrList = theFeature->data()->attributes(std::string());
514 std::list<AttributePtr>::const_iterator anIt = anAttrList.begin();
515 for (; anIt != anAttrList.end(); ++anIt)
516 if (isInteract(*anIt))
522 bool SketchSolver_Storage::isInteract(const AttributePtr& theAttribute) const
527 AttributeRefListPtr aRefList =
528 std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(theAttribute);
530 std::list<ObjectPtr> anObjects = aRefList->list();
531 std::list<ObjectPtr>::iterator anObjIt = anObjects.begin();
532 for (; anObjIt != anObjects.end(); ++anObjIt) {
533 FeaturePtr aFeature = ModelAPI_Feature::feature(*anObjIt);
534 if (isInteract(aFeature))
540 AttributeRefAttrPtr aRefAttr =
541 std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
543 return myAttributeMap.find(theAttribute) != myAttributeMap.end();
544 if (!aRefAttr->isObject())
545 return myAttributeMap.find(aRefAttr->attr()) != myAttributeMap.end();
547 FeaturePtr aFeature = ModelAPI_Feature::feature(aRefAttr->object());
548 return isInteract(aFeature);
551 bool SketchSolver_Storage::isConsistent() const
553 // Check the constraints are valid
554 std::map<ConstraintPtr, std::list<ConstraintWrapperPtr> >::const_iterator
555 aCIter = myConstraintMap.begin();
556 for (; aCIter != myConstraintMap.end(); ++aCIter)
557 if (!aCIter->first->data() || !aCIter->first->data()->isValid())
559 // Check the features are valid
560 std::map<FeaturePtr, EntityWrapperPtr>::const_iterator aFIter = myFeatureMap.begin();
561 for (; aFIter != myFeatureMap.end(); aFIter++)
562 if (!aFIter->first->data() || !aFIter->first->data()->isValid())
567 bool SketchSolver_Storage::isFixed(EntityWrapperPtr theEntity) const
569 if (theEntity->group() != myGroupID)
571 // no need additional checking for entities differ than point
572 if (theEntity->type() != ENTITY_POINT)
575 CoincidentPointsMap::const_iterator anIt = myCoincidentPoints.begin();
576 for (; anIt != myCoincidentPoints.end(); ++anIt)
577 if (anIt->first == theEntity || anIt->second.find(theEntity) != anIt->second.end()) {
578 if (anIt->first->group() != myGroupID)
580 std::set<EntityWrapperPtr>::const_iterator anEntIt = anIt->second.begin();
581 for (; anEntIt != anIt->second.end(); ++anEntIt)
582 if ((*anEntIt)->group() != myGroupID)
586 std::map<ConstraintPtr, std::list<ConstraintWrapperPtr> >::const_iterator aCIt = myConstraintMap.begin();
587 std::list<ConstraintWrapperPtr>::const_iterator aCWIt;
588 for (; aCIt != myConstraintMap.end(); ++aCIt) {
589 if (aCIt->second.empty())
591 aCWIt = aCIt->second.begin();
592 if ((*aCWIt)->type() != CONSTRAINT_FIXED)
594 for (; aCWIt != aCIt->second.end(); ++aCIt)
595 if ((theEntity->baseAttribute() && (*aCWIt)->isUsed(theEntity->baseAttribute())) ||
596 (theEntity->baseFeature() && (*aCWIt)->isUsed(theEntity->baseFeature())))
603 void SketchSolver_Storage::removeInvalidEntities()
605 // Remove invalid constraints
606 std::list<ConstraintPtr> anInvalidConstraints;
607 std::map<ConstraintPtr, std::list<ConstraintWrapperPtr> >::const_iterator
608 aCIter = myConstraintMap.begin();
609 for (; aCIter != myConstraintMap.end(); ++aCIter)
610 if (!aCIter->first->data() || !aCIter->first->data()->isValid())
611 anInvalidConstraints.push_back(aCIter->first);
612 std::list<ConstraintPtr>::const_iterator anInvCIt = anInvalidConstraints.begin();
613 for (; anInvCIt != anInvalidConstraints.end(); ++anInvCIt)
614 removeConstraint(*anInvCIt);
615 // Remove invalid features
616 std::list<FeaturePtr> anInvalidFeatures;
617 std::map<FeaturePtr, EntityWrapperPtr>::const_iterator aFIter = myFeatureMap.begin();
618 for (; aFIter != myFeatureMap.end(); aFIter++)
619 if (!aFIter->first->data() || !aFIter->first->data()->isValid())
620 anInvalidFeatures.push_back(aFIter->first);
621 std::list<FeaturePtr>::const_iterator anInvFIt = anInvalidFeatures.begin();
622 for (; anInvFIt != anInvalidFeatures.end(); ++anInvFIt)
623 removeEntity(*anInvFIt);
626 EntityWrapperPtr SketchSolver_Storage::getNormal() const
628 EntityWrapperPtr aSketch = sketch();
632 // Find normal entity
633 const std::list<EntityWrapperPtr>& aSketchSubs = aSketch->subEntities();
634 std::list<EntityWrapperPtr>::const_iterator aSIt = aSketchSubs.begin();
635 for (; aSIt != aSketchSubs.end(); ++aSIt)
636 if ((*aSIt)->type() == ENTITY_NORMAL)
638 return EntityWrapperPtr();
641 const EntityWrapperPtr& SketchSolver_Storage::sketch() const
643 static EntityWrapperPtr aDummySketch;
645 std::map<FeaturePtr, EntityWrapperPtr>::const_iterator aFIt = myFeatureMap.begin();
646 for (; aFIt != myFeatureMap.end(); ++aFIt)
647 if (aFIt->second && aFIt->second->type() == ENTITY_SKETCH)
649 if (aFIt == myFeatureMap.end())
654 void SketchSolver_Storage::setSketch(const EntityWrapperPtr& theSketch)
658 addEntity(FeaturePtr(), theSketch);
661 void SketchSolver_Storage::processArcs()
664 std::map<FeaturePtr, EntityWrapperPtr>::iterator aFIt = myFeatureMap.begin();
665 for (; aFIt != myFeatureMap.end(); ++aFIt)
666 if (!aFIt->second && aFIt->first->getKind() == SketchPlugin_Arc::ID()) {
667 // Additional checking the attributes are initialized
668 if (aFIt->first->attribute(SketchPlugin_Arc::CENTER_ID())->isInitialized() &&
669 aFIt->first->attribute(SketchPlugin_Arc::START_ID())->isInitialized() &&
670 aFIt->first->attribute(SketchPlugin_Arc::END_ID())->isInitialized())
677 void SketchSolver_Storage::blockEvents(bool isBlocked)
679 if (isBlocked == myEventsBlocked)
682 std::map<ConstraintPtr, std::list<ConstraintWrapperPtr> >::const_iterator
683 aCIter = myConstraintMap.begin();
684 for (; aCIter != myConstraintMap.end(); aCIter++)
685 if (aCIter->first->data() && aCIter->first->data()->isValid())
686 aCIter->first->data()->blockSendAttributeUpdated(isBlocked);
688 std::map<FeaturePtr, EntityWrapperPtr>::const_iterator aFIter = myFeatureMap.begin();
689 for (; aFIter != myFeatureMap.end(); aFIter++)
690 if (aFIter->first->data() && aFIter->first->data()->isValid())
691 aFIter->first->data()->blockSendAttributeUpdated(isBlocked);
693 std::map<AttributePtr, EntityWrapperPtr>::const_iterator anAtIter = myAttributeMap.begin();
694 for (; anAtIter != myAttributeMap.end(); anAtIter++)
695 if (anAtIter->first->owner() && anAtIter->first->owner()->data() &&
696 anAtIter->first->owner()->data()->isValid())
697 anAtIter->first->owner()->data()->blockSendAttributeUpdated(isBlocked);
698 myEventsBlocked = isBlocked;
701 std::set<ObjectPtr> SketchSolver_Storage::getConflictingConstraints(SolverPtr theSolver) const
703 std::set<ObjectPtr> aConflicting;
704 std::map<ConstraintPtr, std::list<ConstraintWrapperPtr> >::const_iterator
705 aConstrIt = myConstraintMap.begin();
706 for (; aConstrIt != myConstraintMap.end(); ++aConstrIt) {
707 std::list<ConstraintWrapperPtr>::const_iterator anIt = aConstrIt->second.begin();
708 for (; anIt != aConstrIt->second.end(); ++anIt)
709 if (theSolver->isConflicting((*anIt)->id())) {
710 aConflicting.insert(aConstrIt->first);
721 // ============== Auxiliary functions ====================================
722 bool isEqual(const std::list<ConstraintWrapperPtr>& theCVec1,
723 const std::list<ConstraintWrapperPtr>& theCVec2)
725 if (theCVec1.size() != theCVec2.size())
728 std::list<bool> aChecked(theCVec2.size(), false);
729 std::list<ConstraintWrapperPtr>::const_iterator anIt1 = theCVec1.begin();
730 for (; anIt1 != theCVec1.end(); ++anIt1) {
731 std::list<ConstraintWrapperPtr>::const_iterator anIt2 = theCVec2.begin();
732 std::list<bool>::iterator aCheckIt = aChecked.begin();
733 while (aCheckIt != aChecked.end() && *aCheckIt) {
737 for (; anIt2 != theCVec2.end(); ++anIt2, ++aCheckIt)
738 if (!(*aCheckIt) && (*anIt1)->isEqual(*anIt2)) {
742 // the same constraint is not found
743 if (anIt2 == theCVec2.end())