+// ============================================================================
+// Function: removeConstraint
+// Class: SketchSolver_ConstraintGroup
+// Purpose: remove constraint and all unused entities
+// ============================================================================
+void SketchSolver_ConstraintGroup::removeConstraint(boost::shared_ptr<SketchPlugin_Constraint> theConstraint)
+{
+ std::map<boost::shared_ptr<SketchPlugin_Constraint>, Slvs_hConstraint>::iterator
+ anIterToRemove = myConstraintMap.find(theConstraint);
+ if (anIterToRemove == myConstraintMap.end())
+ return ;
+
+ Slvs_hConstraint aCnstrToRemove = anIterToRemove->second;
+ // Remove constraint from the map
+ myConstraintMap.erase(anIterToRemove);
+
+ // Find unused entities
+ int aConstrPos = Search(aCnstrToRemove, myConstraints);
+ std::set<Slvs_hEntity> anEntToRemove;
+ Slvs_hEntity aCnstEnt[] = {myConstraints[aConstrPos].ptA, myConstraints[aConstrPos].ptB,
+ myConstraints[aConstrPos].entityA, myConstraints[aConstrPos].entityB};
+ for (int i = 0; i < 4; i++)
+ if (aCnstEnt[i] != 0)
+ anEntToRemove.insert(aCnstEnt[i]);
+ myConstraints.erase(myConstraints.begin() + aConstrPos);
+ if (aCnstrToRemove == myConstrMaxID)
+ myConstrMaxID--;
+ std::vector<Slvs_Constraint>::const_iterator aConstrIter = myConstraints.begin();
+ for ( ; aConstrIter != myConstraints.end(); aConstrIter++)
+ {
+ Slvs_hEntity aEnts[] = {aConstrIter->ptA, aConstrIter->ptB,
+ aConstrIter->entityA, aConstrIter->entityB};
+ for (int i = 0; i < 4; i++)
+ if (aEnts[i] != 0 && anEntToRemove.find(aEnts[i]) != anEntToRemove.end())
+ anEntToRemove.erase(aEnts[i]);
+ }
+
+ if (anEntToRemove.empty())
+ return ;
+
+ // Remove unused entities
+ std::map<boost::shared_ptr<ModelAPI_Attribute>, Slvs_hEntity>::iterator
+ anEntAttrIter = myEntityAttrMap.begin();
+ while (anEntAttrIter != myEntityAttrMap.end())
+ {
+ if (anEntToRemove.find(anEntAttrIter->second) != anEntToRemove.end())
+ {
+ std::map<boost::shared_ptr<ModelAPI_Attribute>, Slvs_hEntity>::iterator
+ aRemovedIter = anEntAttrIter;
+ anEntAttrIter++;
+ myEntityAttrMap.erase(aRemovedIter);
+ }
+ else anEntAttrIter++;
+ }
+ std::map<FeaturePtr, Slvs_hEntity>::iterator
+ anEntFeatIter = myEntityFeatMap.begin();
+ while (anEntFeatIter != myEntityFeatMap.end())
+ {
+ if (anEntToRemove.find(anEntFeatIter->second) != anEntToRemove.end())
+ {
+ std::map<FeaturePtr, Slvs_hEntity>::iterator
+ aRemovedIter = anEntFeatIter;
+ anEntFeatIter++;
+ myEntityFeatMap.erase(aRemovedIter);
+ }
+ else anEntFeatIter++;
+ }
+ std::set<Slvs_hEntity>::const_reverse_iterator aRemIter = anEntToRemove.rbegin();
+ for ( ; aRemIter != anEntToRemove.rend(); aRemIter++)
+ {
+ unsigned int anEntPos = Search(*aRemIter, myEntities);
+ if (anEntPos >= myEntities.size())
+ continue;
+ unsigned int aParamPos = Search(myEntities[anEntPos].param[0], myParams);
+ if (aParamPos >= myParams.size())
+ continue;
+ int aNbParams = 0;
+ while (myEntities[anEntPos].param[aNbParams] != 0)
+ aNbParams++;
+ if (myEntities[anEntPos].param[aNbParams-1] == myParamMaxID)
+ myParamMaxID -= aNbParams;
+ myParams.erase(myParams.begin() + aParamPos, myParams.begin() + aParamPos + aNbParams);
+ if (*aRemIter == myEntityMaxID)
+ myEntityMaxID--;
+ myEntities.erase(myEntities.begin() + anEntPos);
+
+ // Remove entity's ID from the lists of conincident points
+ std::vector< std::set<Slvs_hEntity> >::iterator aCoPtIter = myCoincidentPoints.begin();
+ for ( ; aCoPtIter != myCoincidentPoints.end(); aCoPtIter++)
+ aCoPtIter->erase(*aRemIter);
+ }
+ if (myCoincidentPoints.size() == 1 && myCoincidentPoints.front().empty())
+ myCoincidentPoints.clear();
+}
+
+
+// ============================================================================
+// Function: addCoincidentPoints
+// Class: SketchSolver_ConstraintGroup
+// Purpose: add coincident point the appropriate list of such points
+// ============================================================================
+bool SketchSolver_ConstraintGroup::addCoincidentPoints(
+ const Slvs_hEntity& thePoint1, const Slvs_hEntity& thePoint2)
+{
+ std::vector< std::set<Slvs_hEntity> >::iterator aCoPtIter = myCoincidentPoints.begin();
+ std::vector< std::set<Slvs_hEntity> >::iterator aFirstFound = myCoincidentPoints.end();
+ while (aCoPtIter != myCoincidentPoints.end())
+ {
+ bool isFound[2] = { // indicate which point ID was already in coincidence constraint
+ aCoPtIter->find(thePoint1) != aCoPtIter->end(),
+ aCoPtIter->find(thePoint2) != aCoPtIter->end(),
+ };
+ if (isFound[0] && isFound[1]) // points are already connected by coincidence constraints => no need additional one
+ return false;
+ if ((isFound[0] && !isFound[1]) || (!isFound[0] && isFound[1]))
+ {
+ if (aFirstFound != myCoincidentPoints.end())
+ { // there are two groups of coincident points connected by created constraint => merge them
+ int aFirstFoundShift = aFirstFound - myCoincidentPoints.begin();
+ int aCurrentShift = aCoPtIter - myCoincidentPoints.begin();
+ aFirstFound->insert(aCoPtIter->begin(), aCoPtIter->end());
+ myCoincidentPoints.erase(aCoPtIter);
+ aFirstFound = myCoincidentPoints.begin() + aFirstFoundShift;
+ aCoPtIter = myCoincidentPoints.begin() + aCurrentShift;
+ continue;
+ }
+ else
+ {
+ aCoPtIter->insert(isFound[0] ? thePoint2 : thePoint1);
+ aFirstFound = aCoPtIter;
+ }
+ }
+ aCoPtIter++;
+ }
+ // No points were found, need to create new set
+ if (aFirstFound == myCoincidentPoints.end())
+ {
+ std::set<Slvs_hEntity> aNewSet;
+ aNewSet.insert(thePoint1);
+ aNewSet.insert(thePoint2);
+ myCoincidentPoints.push_back(aNewSet);
+ }
+
+ return true;
+}
+
+