From f0f16150673228d3a7b1f2eec79802157eed79c7 Mon Sep 17 00:00:00 2001 From: azv Date: Mon, 6 Apr 2015 14:44:24 +0300 Subject: [PATCH] Fix for correct detaching of coincident points --- .../SketchSolver_ConstraintCoincidence.cpp | 105 ++++++++++++++---- .../SketchSolver_ConstraintCoincidence.h | 2 +- 2 files changed, 85 insertions(+), 22 deletions(-) diff --git a/src/SketchSolver/SketchSolver_ConstraintCoincidence.cpp b/src/SketchSolver/SketchSolver_ConstraintCoincidence.cpp index a5b6001e7..52dc868ba 100644 --- a/src/SketchSolver/SketchSolver_ConstraintCoincidence.cpp +++ b/src/SketchSolver/SketchSolver_ConstraintCoincidence.cpp @@ -8,9 +8,9 @@ bool SketchSolver_ConstraintCoincidence::hasConstraint(ConstraintPtr theConstrai { if (myBaseConstraint == theConstraint) return true; - std::map::const_iterator anIt = myExtraCoincidence.begin(); + std::map::const_iterator anIt = myExtraCoincidence.begin(); for (; anIt != myExtraCoincidence.end(); anIt++) - if (anIt->first == theConstraint) + if (anIt->second == theConstraint) return true; return false; } @@ -19,9 +19,9 @@ std::list SketchSolver_ConstraintCoincidence::constraints() const { std::list aConstraints; aConstraints.push_back(myBaseConstraint); - std::map::const_iterator anIt = myExtraCoincidence.begin(); + std::map::const_iterator anIt = myExtraCoincidence.begin(); for (; anIt != myExtraCoincidence.end(); anIt++) - aConstraints.push_back(anIt->first); + aConstraints.push_back(anIt->second); return aConstraints; } @@ -59,10 +59,10 @@ void SketchSolver_ConstraintCoincidence::attach( // Copy data. addConstraint(theConstraint->myBaseConstraint); - std::map::iterator aConstrIter = + std::map::iterator aConstrIter = theConstraint->myExtraCoincidence.begin(); for (; aConstrIter != theConstraint->myExtraCoincidence.end(); aConstrIter++) - addConstraint(aConstrIter->first); + addConstraint(aConstrIter->second); // Clear the lists to not remove the entities on destruction theConstraint->mySlvsConstraints.clear(); theConstraint->myFeatureMap.clear(); @@ -103,38 +103,101 @@ void SketchSolver_ConstraintCoincidence::addConstraint(ConstraintPtr theConstrai std::vector::iterator anEntIter = anEntities.begin(); for (; anEntIter != anEntities.end(); anEntIter++) aNewConstr = addConstraint(aBaseCoincidence.ptA, *anEntIter); - myExtraCoincidence[theConstraint] = aNewConstr; + myExtraCoincidence[aNewConstr] = theConstraint; } bool SketchSolver_ConstraintCoincidence::remove(ConstraintPtr theConstraint) { cleanErrorMsg(); + if (mySlvsConstraints.empty()) + return true; ConstraintPtr aConstraint = theConstraint ? theConstraint : myBaseConstraint; int aPos = -1; // position of constraint in the list (-1 for base constraint) + std::map::iterator anExtraIt; if (aConstraint != myBaseConstraint) { - std::map::const_iterator anIt = myExtraCoincidence.begin(); - for (aPos = 0; anIt != myExtraCoincidence.end(); anIt++, aPos++) - if (anIt->first == aConstraint) + anExtraIt = myExtraCoincidence.begin(); + for (aPos = 0; anExtraIt != myExtraCoincidence.end(); anExtraIt++, aPos++) + if (anExtraIt->second == aConstraint) break; if (aPos >= (int)myExtraCoincidence.size()) return false; // there is no constraint, which is specified to remove + else + myExtraCoincidence.erase(anExtraIt); } bool isFullyRemoved = myStorage->removeConstraint(mySlvsConstraints[aPos+1]); mySlvsConstraints.erase(mySlvsConstraints.begin() + (1+aPos)); - cleanRemovedEntities(); if (aPos < 0 && !myExtraCoincidence.empty()) { - // Need to specify another base coincidence constraint - myBaseConstraint = myExtraCoincidence.begin()->first; - myExtraCoincidence.erase(myExtraCoincidence.begin()); - std::vector::iterator aCIter = mySlvsConstraints.begin(); - Slvs_Constraint aBase = myStorage->getConstraint(*aCIter); - for (++aCIter; aCIter != mySlvsConstraints.end(); aCIter++) { - Slvs_Constraint aConstr = myStorage->getConstraint(*aCIter); - aConstr.ptA = aBase.ptA; - myStorage->updateConstraint(aConstr); + anExtraIt = myExtraCoincidence.begin(); + // Remove invalid constraints + while (anExtraIt != myExtraCoincidence.end()) { + if (!anExtraIt->second->data() || !anExtraIt->second->data()->isValid()) { + std::map::iterator aTempIt = anExtraIt++; + if (aTempIt->first != SLVS_E_UNKNOWN) { + myStorage->removeConstraint(aTempIt->first); + std::vector::iterator anIt = mySlvsConstraints.begin(); + for (; anIt != mySlvsConstraints.end(); anIt++) + if (*anIt == aTempIt->first) { + mySlvsConstraints.erase(anIt); + break; + } + } + myExtraCoincidence.erase(aTempIt); + continue; + } + anExtraIt++; + } + // Find first non-extra conststraint + while (anExtraIt != myExtraCoincidence.end() && anExtraIt->first == SLVS_E_UNKNOWN) + anExtraIt++; + if (anExtraIt != myExtraCoincidence.end()) { + // Need to specify another base coincidence constraint + myBaseConstraint = anExtraIt->second; + myExtraCoincidence.erase(anExtraIt); + std::vector::iterator aCIter = mySlvsConstraints.begin(); + Slvs_Constraint aBase = myStorage->getConstraint(*aCIter); + for (++aCIter; aCIter != mySlvsConstraints.end(); aCIter++) { + Slvs_Constraint aConstr = myStorage->getConstraint(*aCIter); + aConstr.ptA = aBase.ptA; + myStorage->updateConstraint(aConstr); + } + } + } + // Clear removed attributes + std::set aParamRemoved; + std::set anEntRemoved; + std::set aConstrRemoved; + myStorage->getRemoved(aParamRemoved, anEntRemoved, aConstrRemoved); + std::map::iterator anAttrIter = myAttributeMap.begin(); + while (anAttrIter != myAttributeMap.end()) { + if (anEntRemoved.find(anAttrIter->second) != anEntRemoved.end()) { + std::map::iterator aTempIt = anAttrIter++; + myAttributeMap.erase(aTempIt); + continue; + } + anAttrIter++; + } + + // Go through remaining extra coincidence and try to add or remove them + anExtraIt = myExtraCoincidence.begin(); + while (anExtraIt != myExtraCoincidence.end()) { + if (anExtraIt->first == SLVS_E_UNKNOWN) { + if (!anExtraIt->second->data() || !anExtraIt->second->data()->isValid()) { + std::map::iterator aTempIt = anExtraIt++; + myExtraCoincidence.erase(aTempIt); + continue; + } + if (mySlvsConstraints.empty()) { + myBaseConstraint = anExtraIt->second; + std::map::iterator aTempIt = anExtraIt++; + myExtraCoincidence.erase(aTempIt); + process(); + continue; + } else + addConstraint(anExtraIt->second); } + anExtraIt++; } - return true; + return isFullyRemoved; } diff --git a/src/SketchSolver/SketchSolver_ConstraintCoincidence.h b/src/SketchSolver/SketchSolver_ConstraintCoincidence.h index 97c1c1250..f726020c7 100644 --- a/src/SketchSolver/SketchSolver_ConstraintCoincidence.h +++ b/src/SketchSolver/SketchSolver_ConstraintCoincidence.h @@ -49,7 +49,7 @@ private: void addConstraint(ConstraintPtr theConstraint); private: - std::map myExtraCoincidence; ///< multiple coincidence of points + std::map myExtraCoincidence; ///< multiple coincidence of points }; #endif -- 2.39.2