From c8425aa48535e2d3b94f2a7d008875565a3b10f9 Mon Sep 17 00:00:00 2001 From: azv Date: Mon, 30 May 2016 10:09:54 +0300 Subject: [PATCH] PlaneGCS: Fix the problem regarding update of a distance during moving of a line (issue #1513) --- .../PlaneGCSSolver/PlaneGCSSolver_Solver.cpp | 19 ++- .../PlaneGCSSolver/PlaneGCSSolver_Storage.cpp | 8 +- src/SketchSolver/SketchSolver_Storage.cpp | 117 +++++++++++++++++ src/SketchSolver/SketchSolver_Storage.h | 5 + .../SolveSpaceSolver_Storage.cpp | 120 +----------------- .../SolveSpaceSolver_Storage.h | 3 - 6 files changed, 146 insertions(+), 126 deletions(-) diff --git a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Solver.cpp b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Solver.cpp index be98e05d9..efd48c361 100644 --- a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Solver.cpp +++ b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Solver.cpp @@ -56,7 +56,24 @@ SketchSolver_SolveStatus PlaneGCSSolver_Solver::solve() return STATUS_INCONSISTENT; Events_LongOp::start(this); - GCS::SolveStatus aResult = (GCS::SolveStatus)myEquationSystem.solve(myParameters); + GCS::SolveStatus aResult = GCS::Success; + // if there is a constraint with all attributes constant, set fail status + GCS::SET_pD aParameters; + aParameters.insert(myParameters.begin(), myParameters.end()); + std::set::const_iterator aConstrIt = myConstraints.begin(); + for (; aConstrIt != myConstraints.end(); ++aConstrIt) { + GCS::VEC_pD aParams = (*aConstrIt)->params(); + GCS::VEC_pD::const_iterator aPIt = aParams.begin(); + for (; aPIt != aParams.end(); ++aPIt) + if (aParameters.find(*aPIt) != aParameters.end()) + break; + if (aPIt == aParams.end()) { + aResult = GCS::Failed; + } + } + // solve equations + if (aResult == GCS::Success) + aResult = (GCS::SolveStatus)myEquationSystem.solve(myParameters); Events_LongOp::end(this); SketchSolver_SolveStatus aStatus; diff --git a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.cpp b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.cpp index 91c4d3381..36e8bfc9c 100644 --- a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.cpp +++ b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.cpp @@ -212,6 +212,10 @@ bool PlaneGCSSolver_Storage::remove(ConstraintWrapperPtr theConstraint) std::dynamic_pointer_cast(theConstraint); bool isFullyRemoved = true; + // remove point-point coincidence + if (aConstraint->type() == CONSTRAINT_PT_PT_COINCIDENT) + isFullyRemoved = removeCoincidence(theConstraint) && isFullyRemoved; + // remove sub-entities const std::list& aSubs = aConstraint->entities(); std::list::const_iterator aSIt = aSubs.begin(); for (; aSIt != aSubs.end(); ++ aSIt) @@ -234,10 +238,6 @@ bool PlaneGCSSolver_Storage::remove(ConstraintWrapperPtr theConstraint) bool PlaneGCSSolver_Storage::remove(EntityWrapperPtr theEntity) { - if ((theEntity->baseAttribute() && isUsed(theEntity->baseAttribute())) || - (theEntity->baseFeature() && isUsed(theEntity->baseFeature()))) - return false; - bool isFullyRemoved = SketchSolver_Storage::remove(theEntity); if (isFullyRemoved && theEntity->id() == myEntityLastID) --myEntityLastID; diff --git a/src/SketchSolver/SketchSolver_Storage.cpp b/src/SketchSolver/SketchSolver_Storage.cpp index 8ef9d9c0e..688f6b35a 100644 --- a/src/SketchSolver/SketchSolver_Storage.cpp +++ b/src/SketchSolver/SketchSolver_Storage.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -463,6 +464,122 @@ bool SketchSolver_Storage::removeEntity(AttributePtr theAttribute) } +bool SketchSolver_Storage::removeCoincidence(ConstraintWrapperPtr theConstraint) +{ + std::list aPoints = theConstraint->entities(); + std::list::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 = SketchSolver_Manager::instance()->builder(); + std::list aNewPoints; + for (aPIt = aPoints.begin(); aPIt != aPoints.end(); ++aPIt) + aNewPoints.push_back(aBuilder->createAttribute( + (*aPIt)->baseAttribute(), myGroupID, mySketchID)); + + // Find all points fallen out of group of coincident points + std::map aNotCoinc; + aNotCoinc[aPtPtIt->first] = EntityWrapperPtr(); + std::set::const_iterator aTempIt = aPtPtIt->second.begin(); + for (; aTempIt != aPtPtIt->second.end(); ++aTempIt) + aNotCoinc[*aTempIt] = EntityWrapperPtr(); + std::map >::iterator + aConstrIt = myConstraintMap.begin(); + for (; aConstrIt != myConstraintMap.end(); ++aConstrIt) + if (aConstrIt->first->getKind() == SketchPlugin_ConstraintCoincidence::ID()) { + AttributeRefAttrPtr aRefAttrA = std::dynamic_pointer_cast( + aConstrIt->first->attribute(SketchPlugin_Constraint::ENTITY_A())); + AttributeRefAttrPtr aRefAttrB = std::dynamic_pointer_cast( + aConstrIt->first->attribute(SketchPlugin_Constraint::ENTITY_B())); + AttributePtr anAttrA, anAttrB; + if (aConstrIt->first->data()->isValid()) { + if (!aRefAttrA || !aRefAttrB || aRefAttrA->isObject() || aRefAttrB->isObject()) + continue; + anAttrA = aRefAttrA->attr(); + anAttrB = aRefAttrB->attr(); + } else { + // obtain attributes from the constraint wrapper + ConstraintWrapperPtr aWrapper = aConstrIt->second.front(); + anAttrA = aWrapper->entities().front()->baseAttribute(); + anAttrB = aWrapper->entities().back()->baseAttribute(); + } + std::map::iterator + aFound = myAttributeMap.find(anAttrA); + if (aFound != myAttributeMap.end()) + aNotCoinc.erase(aFound->second); + aFound = myAttributeMap.find(anAttrB); + if (aFound != myAttributeMap.end()) + aNotCoinc.erase(aFound->second); + } + if (aNotCoinc.empty()) + return false; + std::list::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::iterator aNotCIt; + std::set anUpdFeatures; + std::map::iterator aFIt = myFeatureMap.begin(); + for (; aFIt != myFeatureMap.end(); ++aFIt) { + if (!aFIt->second) + continue; // avoid not completed arcs + for (aNotCIt = aNotCoinc.begin(); aNotCIt != aNotCoinc.end(); ++aNotCIt) { + if (!aNotCIt->second || !aFIt->second->isUsed(aNotCIt->first->baseAttribute())) + continue; + std::list aSubs = aFIt->second->subEntities(); + std::list::iterator aSIt = aSubs.begin(); + bool isUpd = false; + for (; aSIt != aSubs.end(); ++aSIt) + if (*aSIt == aNotCIt->first) { + *aSIt = aNotCIt->second; + isUpd = true; + } + if (isUpd) { + aFIt->second->setSubEntities(aSubs); + anUpdFeatures.insert(aFIt->second); + } + } + } + // update features + std::set::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 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->first); + } + return true; +} + bool SketchSolver_Storage::remove(ConstraintWrapperPtr theConstraint) { bool isFullyRemoved = true; diff --git a/src/SketchSolver/SketchSolver_Storage.h b/src/SketchSolver/SketchSolver_Storage.h index 454044c88..9e2eae02f 100644 --- a/src/SketchSolver/SketchSolver_Storage.h +++ b/src/SketchSolver/SketchSolver_Storage.h @@ -37,6 +37,7 @@ private: public: SketchSolver_Storage(const GroupID& theGroup) : myGroupID(theGroup), + mySketchID(EID_UNKNOWN), myNeedToResolve(false), myEventsBlocked(false), myExistArc(false) @@ -189,6 +190,9 @@ protected: /// \return \c true if the parameter has been removed virtual bool remove(ParameterWrapperPtr theParameter) = 0; + /// \brief Remove point-point coincidence + SKETCHSOLVER_EXPORT bool removeCoincidence(ConstraintWrapperPtr theConstraint); + /// \brief Update the group for the given entity, its sub-entities and parameters virtual void changeGroup(EntityWrapperPtr theEntity, const GroupID& theGroup) = 0; /// \brief Update the group for the given parameter @@ -207,6 +211,7 @@ private: EntityWrapperPtr getNormal() const; protected: + EntityID mySketchID; ///< identifier of the sketch GroupID myGroupID; ///< identifier of the group, this storage belongs to bool myNeedToResolve; ///< parameters are changed and group needs to be resolved bool myEventsBlocked; ///< indicates that features do not send events diff --git a/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Storage.cpp b/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Storage.cpp index 5a27467d9..bcec0c314 100644 --- a/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Storage.cpp +++ b/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Storage.cpp @@ -21,7 +21,6 @@ #include #include #include -#include /** \brief Search the entity/parameter with specified ID in the list of elements * \param[in] theEntityID unique ID of the element @@ -215,7 +214,8 @@ bool SolveSpaceSolver_Storage::update(ParameterWrapperPtr theParameter) void SolveSpaceSolver_Storage::storeWorkplane(EntityWrapperPtr theSketch) { - myWorkplaneID = (Slvs_hEntity)theSketch->id(); + mySketchID = theSketch->id(); + myWorkplaneID = (Slvs_hEntity)mySketchID; // Update sub-entities of the sketch std::list aSubEntities = theSketch->subEntities(); @@ -889,122 +889,6 @@ void SolveSpaceSolver_Storage::initializeSolver(SolverPtr theSolver) } -bool SolveSpaceSolver_Storage::removeCoincidence(ConstraintWrapperPtr theConstraint) -{ - std::list aPoints = theConstraint->entities(); - std::list::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 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 aNotCoinc; - aNotCoinc[aPtPtIt->first] = EntityWrapperPtr(); - std::set::const_iterator aTempIt = aPtPtIt->second.begin(); - for (; aTempIt != aPtPtIt->second.end(); ++aTempIt) - aNotCoinc[*aTempIt] = EntityWrapperPtr(); - std::map >::iterator - aConstrIt = myConstraintMap.begin(); - for (; aConstrIt != myConstraintMap.end(); ++aConstrIt) - if (aConstrIt->first->getKind() == SketchPlugin_ConstraintCoincidence::ID()) { - AttributeRefAttrPtr aRefAttrA = std::dynamic_pointer_cast( - aConstrIt->first->attribute(SketchPlugin_Constraint::ENTITY_A())); - AttributeRefAttrPtr aRefAttrB = std::dynamic_pointer_cast( - aConstrIt->first->attribute(SketchPlugin_Constraint::ENTITY_B())); - AttributePtr anAttrA, anAttrB; - if (aConstrIt->first->data()->isValid()) { - if (!aRefAttrA || !aRefAttrB || aRefAttrA->isObject() || aRefAttrB->isObject()) - continue; - anAttrA = aRefAttrA->attr(); - anAttrB = aRefAttrB->attr(); - } else { - // obtain attributes from the constraint wrapper - ConstraintWrapperPtr aWrapper = aConstrIt->second.front(); - anAttrA = aWrapper->entities().front()->baseAttribute(); - anAttrB = aWrapper->entities().back()->baseAttribute(); - } - std::map::iterator - aFound = myAttributeMap.find(anAttrA); - if (aFound != myAttributeMap.end()) - aNotCoinc.erase(aFound->second); - aFound = myAttributeMap.find(anAttrB); - if (aFound != myAttributeMap.end()) - aNotCoinc.erase(aFound->second); - } - if (aNotCoinc.empty()) - return false; - std::list::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::iterator aNotCIt; - std::set anUpdFeatures; - std::map::iterator aFIt = myFeatureMap.begin(); - for (; aFIt != myFeatureMap.end(); ++aFIt) { - if (!aFIt->second) - continue; // avoid not completed arcs - for (aNotCIt = aNotCoinc.begin(); aNotCIt != aNotCoinc.end(); ++aNotCIt) { - if (!aNotCIt->second || !aFIt->second->isUsed(aNotCIt->first->baseAttribute())) - continue; - std::list aSubs = aFIt->second->subEntities(); - std::list::iterator aSIt = aSubs.begin(); - bool isUpd = false; - for (; aSIt != aSubs.end(); ++aSIt) - if (*aSIt == aNotCIt->first) { - *aSIt = aNotCIt->second; - isUpd = true; - } - if (isUpd) { - aFIt->second->setSubEntities(aSubs); - anUpdFeatures.insert(aFIt->second); - } - } - } - // update features - std::set::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 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->first); - } - return true; -} - bool SolveSpaceSolver_Storage::remove(ConstraintWrapperPtr theConstraint) { std::shared_ptr aConstraint = diff --git a/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Storage.h b/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Storage.h index 4de890e9f..24cb9f323 100644 --- a/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Storage.h +++ b/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Storage.h @@ -64,9 +64,6 @@ protected: /// \return \c true if the parameter has been removed virtual bool remove(ParameterWrapperPtr theParameter); - /// \brief Remove point-point coincidence - bool removeCoincidence(ConstraintWrapperPtr theConstraint); - /// \brief Update the group for the given entity, its sub-entities and parameters virtual void changeGroup(EntityWrapperPtr theEntity, const GroupID& theGroup); /// \brief Update the group for the given parameter -- 2.39.2