+bool SolveSpaceSolver_Storage::removeCoincidence(ConstraintWrapperPtr theConstraint)
+{
+ std::list<EntityWrapperPtr> aPoints = theConstraint->entities();
+ std::list<EntityWrapperPtr>::const_iterator aPIt;
+
+ CoincidentPointsMap::iterator aPtPtIt = myCoincidentPoints.begin();
+ for (; aPtPtIt != myCoincidentPoints.end(); ++aPtPtIt) {
+ for (aPIt = aPoints.begin(); aPIt != aPoints.end(); ++aPIt)
+ if (aPtPtIt->first == *aPIt ||
+ aPtPtIt->second.find(*aPIt) != aPtPtIt->second.end())
+ break;
+ if (aPIt != aPoints.end())
+ break;
+ }
+
+ if (aPtPtIt == myCoincidentPoints.end())
+ return true; // already removed
+
+ // Create new copies of coincident points
+ BuilderPtr aBuilder = SolveSpaceSolver_Builder::getInstance();
+ std::list<EntityWrapperPtr> aNewPoints;
+ for (aPIt = aPoints.begin(); aPIt != aPoints.end(); ++aPIt)
+ aNewPoints.push_back(aBuilder->createAttribute(
+ (*aPIt)->baseAttribute(), myGroupID, myWorkplaneID));
+
+ // Find all points fallen out of group of coincident points
+ std::map<EntityWrapperPtr, EntityWrapperPtr> aNotCoinc;
+ aNotCoinc[aPtPtIt->first] = EntityWrapperPtr();
+ std::set<EntityWrapperPtr>::const_iterator aTempIt = aPtPtIt->second.begin();
+ for (; aTempIt != aPtPtIt->second.end(); ++aTempIt)
+ aNotCoinc[*aTempIt] = EntityWrapperPtr();
+ std::map<ConstraintPtr, std::list<ConstraintWrapperPtr> >::iterator
+ aConstrIt = myConstraintMap.begin();
+ for (; aConstrIt != myConstraintMap.end(); ++aConstrIt)
+ if (aConstrIt->first->getKind() == SketchPlugin_ConstraintCoincidence::ID()) {
+ AttributeRefAttrPtr aRefAttrA = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+ aConstrIt->first->attribute(SketchPlugin_Constraint::ENTITY_A()));
+ AttributeRefAttrPtr aRefAttrB = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+ aConstrIt->first->attribute(SketchPlugin_Constraint::ENTITY_B()));
+ if (!aRefAttrA || !aRefAttrB || aRefAttrA->isObject() || aRefAttrB->isObject())
+ continue;
+ std::map<AttributePtr, EntityWrapperPtr>::iterator
+ aFound = myAttributeMap.find(aRefAttrA->attr());
+ if (aFound != myAttributeMap.end())
+ aNotCoinc.erase(aFound->second);
+ aFound = myAttributeMap.find(aRefAttrB->attr());
+ if (aFound != myAttributeMap.end())
+ aNotCoinc.erase(aFound->second);
+ }
+ if (aNotCoinc.empty())
+ return false;
+ std::list<EntityWrapperPtr>::const_iterator aNewPIt;
+ for (aPIt = aPoints.begin(), aNewPIt = aNewPoints.begin();
+ aPIt != aPoints.end(); ++aPIt, ++aNewPIt) {
+ if (aNotCoinc.find(*aPIt) != aNotCoinc.end())
+ aNotCoinc[*aPIt] = *aNewPIt;
+ }
+
+ // Find all features and constraints uses coincident points
+ std::map<EntityWrapperPtr, EntityWrapperPtr>::iterator aNotCIt;
+ std::set<EntityWrapperPtr> anUpdFeatures;
+ std::map<FeaturePtr, EntityWrapperPtr>::iterator aFIt = myFeatureMap.begin();
+ for (; aFIt != myFeatureMap.end(); ++aFIt) {
+ for (aNotCIt = aNotCoinc.begin(); aNotCIt != aNotCoinc.end(); ++aNotCIt) {
+ if (!aFIt->second->isUsed(aNotCIt->first->baseAttribute()))
+ continue;
+ std::list<EntityWrapperPtr> aSubs = aFIt->second->subEntities();
+ std::list<EntityWrapperPtr>::iterator aSIt = aSubs.begin();
+ for (; aSIt != aSubs.end(); ++aSIt)
+ if (*aSIt == aNotCIt->first)
+ *aSIt = aNotCIt->second;
+ aFIt->second->setSubEntities(aSubs);
+ anUpdFeatures.insert(aFIt->second);
+ }
+ }
+ // update features
+ std::set<EntityWrapperPtr>::iterator anUpdIt = anUpdFeatures.begin();
+ for (; anUpdIt != anUpdFeatures.end(); ++anUpdIt)
+ update(EntityWrapperPtr(*anUpdIt));
+
+ // remove not coincident points
+ for (aNotCIt = aNotCoinc.begin(); aNotCIt != aNotCoinc.end(); ++aNotCIt) {
+ if (aPtPtIt->second.size() <= 1) {
+ myCoincidentPoints.erase(aPtPtIt);
+ break;
+ }
+ if (aPtPtIt->first == aNotCIt->first) {
+ std::set<EntityWrapperPtr> aSlaves = aPtPtIt->second;
+ EntityWrapperPtr aNewMaster = *aSlaves.begin();
+ aSlaves.erase(aSlaves.begin());
+ myCoincidentPoints[aNewMaster] = aSlaves;
+ myCoincidentPoints.erase(aPtPtIt);
+ aPtPtIt = myCoincidentPoints.find(aNewMaster);
+ } else
+ aPtPtIt->second.erase(aNotCIt->first);
+ }
+ return true;
+}
+