From c04e1f7fe00afb98173b828c6fe4c62e95aa8dbe Mon Sep 17 00:00:00 2001 From: azv Date: Tue, 9 Feb 2016 13:47:13 +0300 Subject: [PATCH] Avoid conflicting constraint while mirroring the arc in PlaneGCS (issue #1280) --- .../PlaneGCSSolver/PlaneGCSSolver_Builder.cpp | 19 +++++++++++++++++ .../PlaneGCSSolver/PlaneGCSSolver_Storage.cpp | 21 ++++++++++++++++++- .../PlaneGCSSolver/PlaneGCSSolver_Storage.h | 6 ++++++ src/SketchSolver/SketchSolver_Group.cpp | 8 ++++--- 4 files changed, 50 insertions(+), 4 deletions(-) diff --git a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Builder.cpp b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Builder.cpp index 23933b232..e5002f130 100644 --- a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Builder.cpp +++ b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Builder.cpp @@ -462,6 +462,8 @@ void PlaneGCSSolver_Builder::adjustConstraint(ConstraintWrapperPtr theConstraint adjustAngle(theConstraint); else if (aType == CONSTRAINT_PT_LINE_DISTANCE) adjustPtLineDistance(theConstraint); + else if (aType == CONSTRAINT_SYMMETRIC) + adjustMirror(theConstraint); } EntityWrapperPtr PlaneGCSSolver_Builder::createFeature( @@ -1239,3 +1241,20 @@ void adjustPtLineDistance(ConstraintWrapperPtr theConstraint) theConstraint->setValue(theConstraint->value() * (-1.0)); } +void adjustMirror(ConstraintWrapperPtr theConstraint) +{ + std::vector aPoints; + EntityWrapperPtr aMirrorLine; + + const std::list& aSubs = theConstraint->entities(); + std::list::const_iterator anIt = aSubs.begin(); + for (; anIt != aSubs.end(); ++anIt) { + if ((*anIt)->type() == ENTITY_POINT) + aPoints.push_back(*anIt); + else if ((*anIt)->type() == ENTITY_LINE) + aMirrorLine = *anIt; + } + + makeMirrorPoints(aPoints[0], aPoints[1], aMirrorLine); +} + diff --git a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.cpp b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.cpp index eb96bceff..b79fd0dc8 100644 --- a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.cpp +++ b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.cpp @@ -467,6 +467,24 @@ void PlaneGCSSolver_Storage::updateCoincident(const EntityWrapperPtr& thePoint) } +bool PlaneGCSSolver_Storage::isRedundant( + GCSConstraintPtr theCheckedConstraint, + ConstraintWrapperPtr theParentConstraint) const +{ + if (theParentConstraint->type() == CONSTRAINT_SYMMETRIC) { + if (theCheckedConstraint->getTypeId() == GCS::Perpendicular) { + BuilderPtr aBuilder = PlaneGCSSolver_Builder::getInstance(); + // check the initial point is placed on the mirror line + std::list aSubs = theParentConstraint->entities(); + std::shared_ptr aPoint = aBuilder->point(aSubs.front()); + std::shared_ptr aLine = aBuilder->line(aSubs.back()); + return aLine->distance(aPoint) < tolerance; + } + } + + return false; +} + void PlaneGCSSolver_Storage::initializeSolver(SolverPtr theSolver) { std::shared_ptr aSolver = @@ -487,7 +505,8 @@ void PlaneGCSSolver_Storage::initializeSolver(SolverPtr theSolver) std::dynamic_pointer_cast(*aCWIt); std::list::const_iterator anIt = aGCS->constraints().begin(); for (; anIt != aGCS->constraints().end(); ++anIt) - aSolver->addConstraint(*anIt); + if (!isRedundant(*anIt, aGCS)) + aSolver->addConstraint(*anIt); } } // additional constraints for arcs diff --git a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.h b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.h index 45d8d0c5b..de3fbe301 100644 --- a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.h +++ b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.h @@ -103,6 +103,12 @@ private: /// \brief Adjust parameters of points coincident with the given void updateCoincident(const EntityWrapperPtr& thePoint); + /// \brief Verifies the constraint should not be added into the solver + /// + /// This is a workaround method to avoid some kinds of conflicting constraints: + /// * symmetric of two points placed on the mirror line (do not add perpendicular constraint) + bool isRedundant(GCSConstraintPtr theCheckedConstraint, ConstraintWrapperPtr theParentConstraint) const; + private: GCS::VEC_pD myParameters; ///< list of parameters GCS::VEC_pD myConst; ///< list of constants diff --git a/src/SketchSolver/SketchSolver_Group.cpp b/src/SketchSolver/SketchSolver_Group.cpp index 1da845930..d6c8b0218 100644 --- a/src/SketchSolver/SketchSolver_Group.cpp +++ b/src/SketchSolver/SketchSolver_Group.cpp @@ -186,11 +186,13 @@ static void updateMultiConstraints(ConstraintConstraintMap& theConstraints, Feat { ConstraintConstraintMap::iterator aCIt = theConstraints.begin(); for (; aCIt != theConstraints.end(); ++aCIt) { - if ((aCIt->second->getType() == CONSTRAINT_MULTI_ROTATION || - aCIt->second->getType() == CONSTRAINT_MULTI_TRANSLATION) + SketchSolver_ConstraintType aType = aCIt->second->getType(); + if ((aType == CONSTRAINT_MULTI_ROTATION || + aType == CONSTRAINT_MULTI_TRANSLATION) && aCIt->second->isUsed(theFeature)) std::dynamic_pointer_cast(aCIt->second)->update(true); - else if (aCIt->second->getType() == CONSTRAINT_TANGENT_CIRCLE_LINE + else if ((aType == CONSTRAINT_TANGENT_CIRCLE_LINE || + aType == CONSTRAINT_SYMMETRIC) && aCIt->second->isUsed(theFeature)) aCIt->second->update(); } -- 2.39.2