From e097b3a9684dda6a50cc099fab4f522d5b05f9ce Mon Sep 17 00:00:00 2001 From: azv Date: Mon, 30 May 2016 17:09:47 +0300 Subject: [PATCH] Incorrect processing of middle point on line (issue #1511) --- .../SketchSolver_ConstraintMiddle.cpp | 33 +++++++++++++++++++ .../SketchSolver_ConstraintMiddle.h | 4 +++ .../SolveSpaceSolver_Builder.cpp | 27 +++++++++++++++ .../SolveSpaceSolver_Storage.cpp | 8 +++-- 4 files changed, 70 insertions(+), 2 deletions(-) diff --git a/src/SketchSolver/SketchSolver_ConstraintMiddle.cpp b/src/SketchSolver/SketchSolver_ConstraintMiddle.cpp index 826a429af..5c1a98604 100644 --- a/src/SketchSolver/SketchSolver_ConstraintMiddle.cpp +++ b/src/SketchSolver/SketchSolver_ConstraintMiddle.cpp @@ -1,5 +1,10 @@ #include +#include +#include + +#include + SketchSolver_ConstraintMiddle::SketchSolver_ConstraintMiddle(ConstraintPtr theConstraint) : SketchSolver_Constraint(theConstraint) { @@ -39,3 +44,31 @@ void SketchSolver_ConstraintMiddle::notifyCoincidenceChanged( process(); } } + +void SketchSolver_ConstraintMiddle::adjustConstraint() +{ + BuilderPtr aBuilder = SketchSolver_Manager::instance()->builder(); + + ConstraintWrapperPtr aConstraint = myStorage->constraint(myBaseConstraint).front(); + const std::list& aSubs = aConstraint->entities(); + std::shared_ptr aMidPoint, aStart, aEnd; + std::list::const_iterator aSIt = aSubs.begin(); + for (; aSIt != aSubs.end(); ++aSIt) { + if ((*aSIt)->type() == ENTITY_POINT) + aMidPoint = aBuilder->point(*aSIt); + else if ((*aSIt)->type() == ENTITY_LINE) { + const std::list& aLinePoints = (*aSIt)->subEntities(); + aStart = aBuilder->point(aLinePoints.front()); + aEnd = aBuilder->point(aLinePoints.back()); + } + } + + if (aMidPoint && aStart && aEnd) { + std::shared_ptr aMP = aMidPoint->xy(); + double aDot = aMP->decreased(aStart->xy())->dot(aMP->decreased(aEnd->xy())); + if (aDot > 0.0) { + aBuilder->adjustConstraint(aConstraint); + myStorage->addConstraint(myBaseConstraint, aConstraint); + } + } +} diff --git a/src/SketchSolver/SketchSolver_ConstraintMiddle.h b/src/SketchSolver/SketchSolver_ConstraintMiddle.h index b86e714f5..fadcadab2 100644 --- a/src/SketchSolver/SketchSolver_ConstraintMiddle.h +++ b/src/SketchSolver/SketchSolver_ConstraintMiddle.h @@ -23,6 +23,10 @@ public: /// \brief Notify constraint, that coincidence appears or removed virtual void notifyCoincidenceChanged(EntityWrapperPtr theCoincAttr1, EntityWrapperPtr theCoincAttr2); + +protected: + /// \brief This method is used in derived objects to check consistence of constraint. + virtual void adjustConstraint(); }; #endif diff --git a/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Builder.cpp b/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Builder.cpp index 9792467c1..d5d039040 100644 --- a/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Builder.cpp +++ b/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Builder.cpp @@ -56,6 +56,8 @@ static void adjustAngle(ConstraintWrapperPtr theConstraint); static void adjustMirror(ConstraintWrapperPtr theConstraint); /// \brief Update a sign of the point-line distance constraint static void adjustPtLineDistance(ConstraintWrapperPtr theConstraint); +/// \brief Update point to be a middle of a line +static void adjustMiddlePoint(ConstraintWrapperPtr theConstraint); /// \brief Transform points to be symmetric regarding to the mirror line static void makeMirrorPoints(EntityWrapperPtr theOriginal, @@ -297,6 +299,8 @@ void SolveSpaceSolver_Builder::adjustConstraint(ConstraintWrapperPtr theConstrai adjustMirror(theConstraint); else if (aType == CONSTRAINT_PT_LINE_DISTANCE) adjustPtLineDistance(theConstraint); + else if (aType == CONSTRAINT_MIDDLE_POINT) + adjustMiddlePoint(theConstraint); } EntityWrapperPtr SolveSpaceSolver_Builder::createFeature( @@ -827,3 +831,26 @@ void adjustPtLineDistance(ConstraintWrapperPtr theConstraint) if (aPtLineVec->cross(aLineVec) * theConstraint->value() < 0.0) theConstraint->setValue(theConstraint->value() * (-1.0)); } + +void adjustMiddlePoint(ConstraintWrapperPtr theConstraint) +{ + BuilderPtr aBuilder = SolveSpaceSolver_Builder::getInstance(); + + const std::list& aSubs = theConstraint->entities(); + std::shared_ptr aStart, aEnd; + std::shared_ptr aMidPoint; + std::list::const_iterator aSIt = aSubs.begin(); + for (; aSIt != aSubs.end(); ++aSIt) { + if ((*aSIt)->type() == ENTITY_POINT) + aMidPoint = std::dynamic_pointer_cast((*aSIt)->baseAttribute()); + else if ((*aSIt)->type() == ENTITY_LINE) { + const std::list& aLinePoints = (*aSIt)->subEntities(); + aStart = aBuilder->point(aLinePoints.front()); + aEnd = aBuilder->point(aLinePoints.back()); + } + } + if (aMidPoint && aStart && aEnd) { + std::shared_ptr aMid = aStart->xy()->added(aEnd->xy())->multiplied(0.5); + aMidPoint->setValue(aMid->x(), aMid->y()); + } +} diff --git a/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Storage.cpp b/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Storage.cpp index bcec0c314..202779e19 100644 --- a/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Storage.cpp +++ b/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Storage.cpp @@ -21,6 +21,7 @@ #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 @@ -75,8 +76,11 @@ bool SolveSpaceSolver_Storage::update(ConstraintWrapperPtr theConstraint) std::list::iterator anIt = anEntities.begin(); for (; anIt != anEntities.end(); ++anIt) { isUpdated = update(*anIt) || isUpdated; - // do not update constrained entities for Multi constraints - if (aSlvsConstr.type == SLVS_C_MULTI_ROTATION || aSlvsConstr.type == SLVS_C_MULTI_TRANSLATION) + // do not update constrained entities for Multi constraints, + // and for middle point constraint translated to equal lines + if (aSlvsConstr.type == SLVS_C_MULTI_ROTATION || aSlvsConstr.type == SLVS_C_MULTI_TRANSLATION || + (theConstraint->baseConstraint()->getKind() == SketchPlugin_ConstraintMiddle::ID() && + aSlvsConstr.type != SLVS_C_AT_MIDPOINT)) continue; Slvs_hEntity anID = (Slvs_hEntity)(*anIt)->id(); -- 2.39.2