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<std::set<EntityWrapperPtr> >::iterator anIt = myCoincident.begin();
59 std::list<std::set<EntityWrapperPtr> >::iterator
60 aFound[2] = {myCoincident.end(), myCoincident.end()};
62 for (; anIt != myCoincident.end(); ++anIt) {
63 if (aFound[0] == myCoincident.end() && anIt->find(theEntity1) != anIt->end())
65 if (aFound[1] == myCoincident.end() && anIt->find(theEntity2) != anIt->end())
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 std::set<EntityWrapperPtr> aNewCoinc;
74 aNewCoinc.insert(theEntity1);
75 aNewCoinc.insert(theEntity2);
76 myCoincident.push_back(aNewCoinc);
77 } else if (aFound[0] == aFound[1]) // same group => already coincident
80 if (theEntity1->type() == ENTITY_POINT && theEntity2->type() == ENTITY_POINT &&
81 (theEntity1->isExternal() || theEntity2->isExternal())) {
82 bool hasExternal = false;
83 for (int i = 0; i < 2 && !hasExternal; ++i) {
84 if (aFound[i] != myCoincident.end()) {
85 if (theEntity1->isExternal())
86 hasExternal = hasAnotherExternalPoint(*aFound[i], theEntity1);
87 if (!hasExternal && theEntity2->isExternal())
88 hasExternal = hasAnotherExternalPoint(*aFound[i], theEntity2);
95 if (aFound[0] == myCoincident.end())
96 aFound[1]->insert(theEntity1);
97 else if (aFound[1] == myCoincident.end())
98 aFound[0]->insert(theEntity2);
99 else { // merge two groups
100 aFound[0]->insert(aFound[1]->begin(), aFound[1]->end());
101 myCoincident.erase(aFound[1]);