- theSolver.setConstraints(aConstraints.data(), (int)aConstraints.size());
-}
-
-void SketchSolver_Storage::addCoincidentPoints(
- const Slvs_hEntity& thePoint1, const Slvs_hEntity& thePoint2)
-{
- std::vector< std::set<Slvs_hEntity> >::iterator aCIter = myCoincidentPoints.begin();
- std::vector< std::set<Slvs_hEntity> >::iterator aFoundIter = myCoincidentPoints.end(); // already found coincidence
- bool isFound = false;
- for (; aCIter != myCoincidentPoints.end(); aCIter++) {
- bool isFirstFound = aCIter->find(thePoint1) != aCIter->end();
- bool isSecondFound = aCIter->find(thePoint2) != aCIter->end();
- isFound = isFound || isFirstFound || isSecondFound;
- if (isFirstFound && isSecondFound)
- break; // already coincident
- else if (isFirstFound || isSecondFound) {
- if (aFoundIter != myCoincidentPoints.end()) {
- // merge two sets
- aFoundIter->insert(aCIter->begin(), aCIter->end());
- myCoincidentPoints.erase(aCIter);
- break;
+
+ // Collect alone points and build them new instances
+ std::list<EntityWrapperPtr> aShutOffList;
+ BuilderPtr aBuilder = SketchSolver_Manager::instance()->builder();
+ std::map<EntityWrapperPtr, EntityWrapperPtr> aNotCoinc;
+ std::list<std::set<EntityWrapperPtr> >::iterator aGroupIt = aCoincGroups.begin();
+ while (aGroupIt != aCoincGroups.end()) {
+ if (aGroupIt->size() == 1) {
+ EntityWrapperPtr aPoint = *aGroupIt->begin();
+ aShutOffList.push_back(aPoint);
+ aNotCoinc[aPoint] =
+ aBuilder->createAttribute(aPoint->baseAttribute(), myGroupID, mySketchID);
+ std::list<std::set<EntityWrapperPtr> >::iterator aRemoveIt = aGroupIt++;
+ aCoincGroups.erase(aRemoveIt);
+ } else // point is not alone
+ ++aGroupIt;
+ }
+
+ if (aNotCoinc.empty() && aCoincGroups.size() == 1)
+ return false;
+
+ // Find all features and constraints uses non-coincident points
+ replaceEntities(aNotCoinc);
+
+ // Remove not coincident points and points in separated groups
+ if (!aCoincGroups.empty()) {
+ aGroupIt = aCoincGroups.begin();
+ for (++aGroupIt; aGroupIt != aCoincGroups.end(); ++aGroupIt)
+ aShutOffList.insert(aShutOffList.end(), aGroupIt->begin(), aGroupIt->end());
+ }
+ std::list<EntityWrapperPtr>::iterator aNotCIt = aShutOffList.begin();
+ for (; aNotCIt != aShutOffList.end(); ++aNotCIt) {
+ if (aPtPtIt->second.size() <= 1) {
+ myCoincidentPoints.erase(aPtPtIt);
+ break;
+ }
+ if (aPtPtIt->first == *aNotCIt) {
+ std::set<EntityWrapperPtr> aSlaves = aPtPtIt->second;
+ EntityWrapperPtr aNewMaster = *aSlaves.begin();
+ aSlaves.erase(aSlaves.begin());
+ myCoincidentPoints.erase(aPtPtIt);
+ myCoincidentPoints[aNewMaster] = aSlaves;
+ aPtPtIt = myCoincidentPoints.find(aNewMaster);
+ } else
+ aPtPtIt->second.erase(*aNotCIt);
+ }
+
+ // Create additional groups of coincident points
+ aGroupIt = aCoincGroups.begin();
+ if (!aCoincGroups.empty())
+ ++aGroupIt;
+ for (; aGroupIt != aCoincGroups.end(); ++aGroupIt) {
+ aNotCoinc.clear();
+ std::set<EntityWrapperPtr>::iterator anEntIt = aGroupIt->begin();
+ for (; anEntIt != aGroupIt->end(); ++anEntIt) {
+ aNotCoinc[*anEntIt] =
+ aBuilder->createAttribute((*anEntIt)->baseAttribute(), myGroupID, mySketchID);
+ }
+ // replace points by newly created
+ replaceEntities(aNotCoinc);
+ // set new group of coincident points
+ EntityWrapperPtr aMasterEnt = aNotCoinc.begin()->second;
+ std::map<EntityWrapperPtr, EntityWrapperPtr>::iterator aNCIt = aNotCoinc.begin();
+ for (++aNCIt; aNCIt != aNotCoinc.end(); ++aNCIt)
+ addCoincidentPoints(aMasterEnt, aNCIt->second);
+ }
+
+ return true;
+}
+
+void SketchSolver_Storage::replaceEntities(const std::map<EntityWrapperPtr,
+ EntityWrapperPtr>& theChange)
+{
+ std::set<EntityWrapperPtr> anUpdFeatures;
+ std::map<EntityWrapperPtr, EntityWrapperPtr>::const_iterator aSubIt;
+ std::map<FeaturePtr, EntityWrapperPtr>::iterator aFIt = myFeatureMap.begin();
+ for (; aFIt != myFeatureMap.end(); ++aFIt) {
+ if (!aFIt->second)
+ continue; // avoid not completed arcs
+ for (aSubIt = theChange.begin(); aSubIt != theChange.end(); ++aSubIt) {
+ if (!aSubIt->second || !::isUsed(aFIt->first, aSubIt->first->baseAttribute()))
+ continue;
+ std::list<EntityWrapperPtr> aSubs = aFIt->second->subEntities();
+ std::list<EntityWrapperPtr>::iterator aSIt = aSubs.begin();
+ bool isUpd = false;
+ for (; aSIt != aSubs.end(); ++aSIt)
+ if (*aSIt == aSubIt->first) {
+ (*aSIt)->update(aSubIt->second);
+ (*aSIt)->setGroup(aFIt->second->group());
+ isUpd = true;
+ }
+ if (isUpd) {
+ aFIt->second->setSubEntities(aSubs);
+ anUpdFeatures.insert(aFIt->second);