1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
3 // File: PlaneGCSSolver_UpdateCoincidence.cpp
4 // Created: 17 Feb 2017
5 // Author: Artem ZHIDKOV
7 #include <PlaneGCSSolver_UpdateCoincidence.h>
8 #include <SketchSolver_Constraint.h>
10 #include <SketchPlugin_ConstraintCoincidence.h>
11 #include <SketchPlugin_ConstraintMiddle.h>
13 void PlaneGCSSolver_UpdateCoincidence::attach(SketchSolver_Constraint* theObserver,
14 const std::string& theType)
16 if (theType == GROUP()) {
17 std::list<SketchSolver_Constraint*>::iterator aPlaceToAdd = myObservers.end();
18 // point-point coincidence is placed first
19 if (theObserver->getType() == CONSTRAINT_PT_PT_COINCIDENT) {
20 for (aPlaceToAdd = myObservers.begin(); aPlaceToAdd != myObservers.end(); ++aPlaceToAdd)
21 if ((*aPlaceToAdd)->getType() != CONSTRAINT_PT_PT_COINCIDENT)
24 myObservers.insert(aPlaceToAdd, theObserver);
26 myNext->attach(theObserver, theType);
29 void PlaneGCSSolver_UpdateCoincidence::update(const FeaturePtr& theFeature)
31 if (theFeature->getKind() == SketchPlugin_ConstraintCoincidence::ID() ||
32 theFeature->getKind() == SketchPlugin_ConstraintMiddle::ID()) {
34 // notify listeners and stop procesing
35 std::list<SketchSolver_Constraint*>::iterator anIt = myObservers.begin();
36 for (; anIt != myObservers.end(); ++anIt)
37 (*anIt)->notify(theFeature, this);
39 myNext->update(theFeature);
42 static bool hasAnotherExternalPoint(const std::set<EntityWrapperPtr>& theCoincidences,
43 const EntityWrapperPtr& thePoint)
45 std::set<EntityWrapperPtr>::const_iterator anIt = theCoincidences.begin();
46 for (; anIt != theCoincidences.end(); ++anIt)
47 if ((*anIt)->type() == ENTITY_POINT && (*anIt)->isExternal() && *anIt != thePoint)
52 bool PlaneGCSSolver_UpdateCoincidence::checkCoincidence(
53 const EntityWrapperPtr& theEntity1,
54 const EntityWrapperPtr& theEntity2)
56 bool isAccepted = true;
58 std::list<CoincidentEntities>::iterator anIt = myCoincident.begin();
59 std::list<CoincidentEntities>::iterator
60 aFound[2] = {myCoincident.end(), myCoincident.end()};
62 for (; anIt != myCoincident.end(); ++anIt) {
63 if (anIt->isExist(theEntity1))
65 if (anIt->isExist(theEntity2))
67 if (aFound[0] != myCoincident.end() && aFound[1] != myCoincident.end())
71 if (aFound[0] == myCoincident.end() && aFound[1] == myCoincident.end()) {
72 // new group of coincidence
73 myCoincident.push_back(CoincidentEntities(theEntity1, theEntity2));
74 } else if (aFound[0] == aFound[1]) // same group => already coincident
77 if (aFound[0] == myCoincident.end())
78 isAccepted = aFound[1]->isNewCoincidence(theEntity2, theEntity1);
79 else if (aFound[1] == myCoincident.end())
80 isAccepted = aFound[0]->isNewCoincidence(theEntity1, theEntity2);
81 else { // merge two groups
82 isAccepted = aFound[0]->isNewCoincidence(theEntity1, *(aFound[1]), theEntity2);
83 myCoincident.erase(aFound[1]);
93 PlaneGCSSolver_UpdateCoincidence::CoincidentEntities::CoincidentEntities(
94 const EntityWrapperPtr& theEntity1,
95 const EntityWrapperPtr& theEntity2)
97 if (theEntity1->isExternal() && theEntity2->isExternal()) {
98 myExternalAndConnected[theEntity1] = std::set<EntityWrapperPtr>();
99 myExternalAndConnected[theEntity2] = std::set<EntityWrapperPtr>();
100 } else if (theEntity1->isExternal())
101 myExternalAndConnected[theEntity1].insert(theEntity2);
102 else if (theEntity2->isExternal())
103 myExternalAndConnected[theEntity2].insert(theEntity1);
105 std::set<EntityWrapperPtr> aGroup;
106 aGroup.insert(theEntity1);
107 aGroup.insert(theEntity2);
108 myExternalAndConnected[EntityWrapperPtr()] = aGroup;
112 bool PlaneGCSSolver_UpdateCoincidence::CoincidentEntities::hasExternal() const
114 return myExternalAndConnected.size() != 1 ||
115 myExternalAndConnected.find(EntityWrapperPtr()) == myExternalAndConnected.end();
118 bool PlaneGCSSolver_UpdateCoincidence::CoincidentEntities::isExist(
119 const EntityWrapperPtr& theEntity) const
121 std::map<EntityWrapperPtr, std::set<EntityWrapperPtr> >::const_iterator
122 anIt = myExternalAndConnected.begin();
123 for (; anIt != myExternalAndConnected.end(); ++anIt)
124 if (anIt->first == theEntity ||
125 anIt->second.find(theEntity) != anIt->second.end())
130 bool PlaneGCSSolver_UpdateCoincidence::CoincidentEntities::isNewCoincidence(
131 const EntityWrapperPtr& theEntityExist,
132 const EntityWrapperPtr& theOtherEntity)
134 if (theOtherEntity->isExternal()) {
136 if (myExternalAndConnected.find(theOtherEntity) == myExternalAndConnected.end())
137 myExternalAndConnected[theOtherEntity] = std::set<EntityWrapperPtr>();
140 myExternalAndConnected[theOtherEntity] = myExternalAndConnected[EntityWrapperPtr()];
141 myExternalAndConnected.erase(EntityWrapperPtr());
146 if (theEntityExist->isExternal()) {
147 myExternalAndConnected[theEntityExist].insert(theOtherEntity);
151 std::map<EntityWrapperPtr, std::set<EntityWrapperPtr> >::iterator
152 anIt = myExternalAndConnected.begin();
153 for (; anIt != myExternalAndConnected.end(); ++anIt)
154 if (anIt->second.find(theEntityExist) != anIt->second.end()) {
155 anIt->second.insert(theOtherEntity);
161 bool PlaneGCSSolver_UpdateCoincidence::CoincidentEntities::isNewCoincidence(
162 const EntityWrapperPtr& theEntityExist,
163 const CoincidentEntities& theOtherGroup,
164 const EntityWrapperPtr& theEntityInOtherGroup)
166 bool hasExt[2] = {hasExternal(), theOtherGroup.hasExternal()};
167 if (hasExt[0] && hasExt[1]) {
168 myExternalAndConnected.insert(theOtherGroup.myExternalAndConnected.begin(),
169 theOtherGroup.myExternalAndConnected.end());
171 } else if (!hasExt[0] && !hasExt[1]) {
172 std::map<EntityWrapperPtr, std::set<EntityWrapperPtr> >::const_iterator
173 aFound = theOtherGroup.myExternalAndConnected.find(EntityWrapperPtr());
175 myExternalAndConnected[EntityWrapperPtr()].insert(
176 aFound->second.begin(), aFound->second.end());
179 std::map<EntityWrapperPtr, std::set<EntityWrapperPtr> > aSource, aDest;
180 EntityWrapperPtr aTarget;
182 aDest = myExternalAndConnected;
183 aSource = theOtherGroup.myExternalAndConnected;
184 aTarget = theEntityExist;
186 aSource = myExternalAndConnected;
187 aDest = theOtherGroup.myExternalAndConnected;
188 aTarget = theEntityInOtherGroup;
191 std::map<EntityWrapperPtr, std::set<EntityWrapperPtr> >::const_iterator
192 aFound = aSource.find(EntityWrapperPtr());
194 std::map<EntityWrapperPtr, std::set<EntityWrapperPtr> >::iterator anIt = aDest.begin();
195 for (; anIt != aDest.end(); ++anIt)
196 if (anIt->first == aTarget ||
197 anIt->second.find(aTarget) != anIt->second.end()) {
198 anIt->second.insert(aFound->second.begin(), aFound->second.end());