From b2774b5c75e664ace3e03875b2bf5a0f2c238e23 Mon Sep 17 00:00:00 2001 From: azv Date: Fri, 30 May 2014 16:42:02 +0400 Subject: [PATCH] Crash on coincidence constraints --- .../SketchSolver_ConstraintGroup.cpp | 96 +++++++++++-------- .../SketchSolver_ConstraintGroup.h | 8 ++ 2 files changed, 64 insertions(+), 40 deletions(-) diff --git a/src/SketchSolver/SketchSolver_ConstraintGroup.cpp b/src/SketchSolver/SketchSolver_ConstraintGroup.cpp index 944d4ce4b..6d053d8c2 100644 --- a/src/SketchSolver/SketchSolver_ConstraintGroup.cpp +++ b/src/SketchSolver/SketchSolver_ConstraintGroup.cpp @@ -203,47 +203,11 @@ bool SketchSolver_ConstraintGroup::changeConstraint( { // Several points may be coincident, it is not necessary to store all constraints between them. // Try to find sequence of coincident points which connects the points of new constraint - if (aConstrType == SLVS_C_POINTS_COINCIDENT) + if (aConstrType == SLVS_C_POINTS_COINCIDENT && + !addCoincidentPoints(aConstrEnt[0], aConstrEnt[1])) { - std::vector< std::set >::iterator aCoPtIter = myCoincidentPoints.begin(); - std::vector< std::set >::iterator aFirstFound = myCoincidentPoints.end(); - for ( ; aCoPtIter != myCoincidentPoints.end(); aCoPtIter++) - { - bool isFound[2] = { // indicate which point ID was already in coincidence constraint - aCoPtIter->find(aConstrEnt[0]) != aCoPtIter->end(), - aCoPtIter->find(aConstrEnt[1]) != aCoPtIter->end(), - }; - if (isFound[0] && isFound[1]) // points are already connected by coincidence constraints => no need additional one - { - myExtraCoincidence.insert(theConstraint); // the constraint is stored for further purposes - 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; - } - else - { - aCoPtIter->insert(aConstrEnt[isFound[0] ? 1 : 0]); - aFirstFound = aCoPtIter; - } - } - } - // No points were found, need to create new set - if (aFirstFound == myCoincidentPoints.end()) - { - std::set aNewSet; - aNewSet.insert(aConstrEnt[0]); - aNewSet.insert(aConstrEnt[1]); - myCoincidentPoints.push_back(aNewSet); - } + myExtraCoincidence.insert(theConstraint); // the constraint is stored for further purposes + return false; } // Create SolveSpace constraint structure @@ -1048,6 +1012,58 @@ void SketchSolver_ConstraintGroup::removeConstraint(boost::shared_ptr >::iterator aCoPtIter = myCoincidentPoints.begin(); + std::vector< std::set >::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 aNewSet; + aNewSet.insert(thePoint1); + aNewSet.insert(thePoint2); + myCoincidentPoints.push_back(aNewSet); + } + + return true; +} + + + // ======================================================== // ========= Auxiliary functions =============== diff --git a/src/SketchSolver/SketchSolver_ConstraintGroup.h b/src/SketchSolver/SketchSolver_ConstraintGroup.h index 3d0ef2245..7baeac158 100644 --- a/src/SketchSolver/SketchSolver_ConstraintGroup.h +++ b/src/SketchSolver/SketchSolver_ConstraintGroup.h @@ -159,6 +159,14 @@ private: */ bool addWorkplane(boost::shared_ptr theSketch); + /** \brief Add the entities of constraint for points coincidence into the appropriate list + * \param[in] thePoint1 identifier of the first point + * \param[in] thePoint2 identifier of the second point + * \return \c true if the points are added successfully, and + * \c false if the constraint is the extra one (should not be created in SolveSpace) + */ + bool addCoincidentPoints(const Slvs_hEntity& thePoint1, const Slvs_hEntity& thePoint2); + private: // SolveSpace entities Slvs_hGroup myID; ///< the index of the group -- 2.39.2