From 66fd2a834f8c9bf1fdfd253addd143862325f1f0 Mon Sep 17 00:00:00 2001 From: azv Date: Tue, 15 Sep 2015 13:31:37 +0300 Subject: [PATCH] Update constraints defined by parameters (issue #976) --- .../SketchSolver_ConstraintParametric.cpp | 77 +++++++++++-------- .../SketchSolver_ConstraintParametric.h | 5 ++ src/SketchSolver/SketchSolver_Group.cpp | 34 ++++++-- src/SketchSolver/SketchSolver_Storage.cpp | 2 +- 4 files changed, 78 insertions(+), 40 deletions(-) diff --git a/src/SketchSolver/SketchSolver_ConstraintParametric.cpp b/src/SketchSolver/SketchSolver_ConstraintParametric.cpp index 29147d76f..d73042966 100644 --- a/src/SketchSolver/SketchSolver_ConstraintParametric.cpp +++ b/src/SketchSolver/SketchSolver_ConstraintParametric.cpp @@ -35,47 +35,33 @@ void SketchSolver_ConstraintParametric::process() return; if (!aPoint->textX().empty()) { // Create vertical line with fixed boundary point - Slvs_Param aParX = Slvs_MakeParam(SLVS_E_UNKNOWN, myGroup->getId(), aPoint->x()); - Slvs_Param aParY = Slvs_MakeParam(SLVS_E_UNKNOWN, myGroup->getId(), -10000.0); - aParX.h = myStorage->addParameter(aParX); - aParY.h = myStorage->addParameter(aParY); - Slvs_Entity aStartPoint = Slvs_MakePoint2d(SLVS_E_UNKNOWN, myGroup->getId(), - myGroup->getWorkplaneId(), aParX.h, aParY.h); - aStartPoint.h = myStorage->addEntity(aStartPoint); - Slvs_Entity aLine = Slvs_MakeLineSegment(SLVS_E_UNKNOWN, myGroup->getId(), - myGroup->getWorkplaneId(), aStartPoint.h, anAttrID); - aLine.h = myStorage->addEntity(aLine); - - // Fix start point - fixPoint(aStartPoint.h); - // Add vertical constraint - Slvs_Constraint aConstraint = Slvs_MakeConstraint(SLVS_C_UNKNOWN, myGroup->getId(), + Slvs_Entity aLine = createLine(aPoint->x(), -100.0, aPoint->x(), 100.0); + fixPoint(aLine.point[0]); + Slvs_Constraint aVertConstr = Slvs_MakeConstraint(SLVS_C_UNKNOWN, myGroup->getId(), SLVS_C_VERTICAL, myGroup->getWorkplaneId(), 0.0, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN, aLine.h, SLVS_E_UNKNOWN); + myStorage->addConstraint(aVertConstr); + // Place point on line + Slvs_Constraint aConstraint = Slvs_MakeConstraint(SLVS_C_UNKNOWN, myGroup->getId(), + SLVS_C_PT_ON_LINE, myGroup->getWorkplaneId(), 0.0, anAttrID, SLVS_E_UNKNOWN, + aLine.h, SLVS_E_UNKNOWN); aConstraint.h = myStorage->addConstraint(aConstraint); mySlvsConstraints.push_back(aConstraint.h); myVertLineID = aLine.h; myX = aPoint->x(); } if (!aPoint->textY().empty()) { - // Create horizontal line with fixed boundary point - Slvs_Param aParX = Slvs_MakeParam(SLVS_E_UNKNOWN, myGroup->getId(), -10000.0); - Slvs_Param aParY = Slvs_MakeParam(SLVS_E_UNKNOWN, myGroup->getId(), aPoint->y()); - aParX.h = myStorage->addParameter(aParX); - aParY.h = myStorage->addParameter(aParY); - Slvs_Entity aStartPoint = Slvs_MakePoint2d(SLVS_E_UNKNOWN, myGroup->getId(), - myGroup->getWorkplaneId(), aParX.h, aParY.h); - aStartPoint.h = myStorage->addEntity(aStartPoint); - Slvs_Entity aLine = Slvs_MakeLineSegment(SLVS_E_UNKNOWN, myGroup->getId(), - myGroup->getWorkplaneId(), aStartPoint.h, anAttrID); - aLine.h = myStorage->addEntity(aLine); - - // Fix start point - fixPoint(aStartPoint.h); - // Add horizontal constraint - Slvs_Constraint aConstraint = Slvs_MakeConstraint(SLVS_C_UNKNOWN, myGroup->getId(), + // Create horizontal line with fixed boundary points + Slvs_Entity aLine = createLine(-100.0, aPoint->y(), 100.0, aPoint->y()); + fixPoint(aLine.point[0]); + Slvs_Constraint aHorizConstr = Slvs_MakeConstraint(SLVS_C_UNKNOWN, myGroup->getId(), SLVS_C_HORIZONTAL, myGroup->getWorkplaneId(), 0.0, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN, aLine.h, SLVS_E_UNKNOWN); + myStorage->addConstraint(aHorizConstr); + // Place point on line + Slvs_Constraint aConstraint = Slvs_MakeConstraint(SLVS_C_UNKNOWN, myGroup->getId(), + SLVS_C_PT_ON_LINE, myGroup->getWorkplaneId(), 0.0, anAttrID, SLVS_E_UNKNOWN, + aLine.h, SLVS_E_UNKNOWN); aConstraint.h = myStorage->addConstraint(aConstraint); mySlvsConstraints.push_back(aConstraint.h); myHorizLineID = aLine.h; @@ -164,3 +150,32 @@ void SketchSolver_ConstraintParametric::adjustConstraint() myY = aParY.val; } } + + +Slvs_Entity SketchSolver_ConstraintParametric::createLine( + double theStartX, double theStartY, double theEndX, double theEndY) +{ + // Start point + Slvs_Param aParX = Slvs_MakeParam(SLVS_E_UNKNOWN, myGroup->getId(), theStartX); + Slvs_Param aParY = Slvs_MakeParam(SLVS_E_UNKNOWN, myGroup->getId(), theStartY); + aParX.h = myStorage->addParameter(aParX); + aParY.h = myStorage->addParameter(aParY); + Slvs_Entity aStartPoint = Slvs_MakePoint2d(SLVS_E_UNKNOWN, myGroup->getId(), + myGroup->getWorkplaneId(), aParX.h, aParY.h); + aStartPoint.h = myStorage->addEntity(aStartPoint); + + // End point + aParX = Slvs_MakeParam(SLVS_E_UNKNOWN, myGroup->getId(), theEndX); + aParY = Slvs_MakeParam(SLVS_E_UNKNOWN, myGroup->getId(), theEndY); + aParX.h = myStorage->addParameter(aParX); + aParY.h = myStorage->addParameter(aParY); + Slvs_Entity aEndPoint = Slvs_MakePoint2d(SLVS_E_UNKNOWN, myGroup->getId(), + myGroup->getWorkplaneId(), aParX.h, aParY.h); + aEndPoint.h = myStorage->addEntity(aEndPoint); + + // Line + Slvs_Entity aLine = Slvs_MakeLineSegment(SLVS_E_UNKNOWN, myGroup->getId(), + myGroup->getWorkplaneId(), aStartPoint.h, aEndPoint.h); + aLine.h = myStorage->addEntity(aLine); + return aLine; +} diff --git a/src/SketchSolver/SketchSolver_ConstraintParametric.h b/src/SketchSolver/SketchSolver_ConstraintParametric.h index 61eb3e72e..3a25d96ff 100644 --- a/src/SketchSolver/SketchSolver_ConstraintParametric.h +++ b/src/SketchSolver/SketchSolver_ConstraintParametric.h @@ -44,6 +44,11 @@ protected: /// \brief This method is used in derived objects to check consistence of constraint. virtual void adjustConstraint(); +private: + /// \brief Create SolveSpace line with given coordinates + /// \return created line + Slvs_Entity createLine(double theStartX, double theStartY, double theEndX, double theEndY); + private: AttributePtr myBaseAttribute; ///< attribute given by expression Slvs_hEntity myHorizLineID; ///< identifier of horizontal line, containing the point diff --git a/src/SketchSolver/SketchSolver_Group.cpp b/src/SketchSolver/SketchSolver_Group.cpp index 0e636f7df..35f90dc74 100644 --- a/src/SketchSolver/SketchSolver_Group.cpp +++ b/src/SketchSolver/SketchSolver_Group.cpp @@ -179,8 +179,6 @@ Slvs_hEntity SketchSolver_Group::getAttributeId(AttributePtr theAttribute) const return aResult; // Obtain regular constraints interacting with the attribute and find its ID std::set aConstraints = myFeatureStorage->getConstraints(theAttribute); - if (aConstraints.empty()) - return aResult; std::set::iterator aConstrIter = aConstraints.begin(); for (; aConstrIter != aConstraints.end(); aConstrIter++) { ConstraintConstraintMap::const_iterator aCIter = myConstraints.find(*aConstrIter); @@ -191,9 +189,14 @@ Slvs_hEntity SketchSolver_Group::getAttributeId(AttributePtr theAttribute) const return aResult; } // The attribute is not found, check it in the temporary constraints - std::set::iterator aTmpCIter = myTempConstraints.begin(); + std::set::const_iterator aTmpCIter = myTempConstraints.begin(); for (; aTmpCIter != myTempConstraints.end() && aResult == SLVS_E_UNKNOWN; ++aTmpCIter) aResult = (*aTmpCIter)->getId(theAttribute); + // Last chance to find attribute in parametric constraints + std::map::const_iterator aParIter = + myParametricConstraints.find(theAttribute); + if (aParIter != myParametricConstraints.end()) + aResult = aParIter->second->getId(theAttribute); return aResult; } @@ -376,16 +379,27 @@ bool SketchSolver_Group::updateFeature(std::shared_ptr the // Search attributes of the feature in the set of parametric constraints and update them std::list anAttrList = - theFeature->data()->attributes(ModelAPI_AttributeRefAttr::typeId()); + theFeature->data()->attributes(GeomDataAPI_Point2D::typeId()); std::list::iterator anAttrIt = anAttrList.begin(); for (; anAttrIt != anAttrList.end(); ++anAttrIt) { - AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast(*anAttrIt); - if (!aRefAttr || aRefAttr->isObject()) - continue; std::map::iterator aFound = - myParametricConstraints.find(aRefAttr->attr()); + myParametricConstraints.find(*anAttrIt); if (aFound != myParametricConstraints.end()) aFound->second->update(); + else { + std::shared_ptr aPoint = + std::dynamic_pointer_cast(*anAttrIt); + if (aPoint && (!aPoint->textX().empty() || !aPoint->textY().empty())) { + // Create new parametric constraint + SolverConstraintPtr aConstraint = + SketchSolver_Builder::getInstance()->createParametricConstraint(*anAttrIt); + if (!aConstraint) + continue; + aConstraint->setGroup(this); + aConstraint->setStorage(myStorage); + myParametricConstraints[*anAttrIt] = aConstraint; + } + } } return true; } @@ -714,7 +728,11 @@ bool SketchSolver_Group::isConsistent() // ============================================================================ void SketchSolver_Group::removeTemporaryConstraints() { + std::set::iterator aTmpIt = myTempConstraints.begin(); + for (; aTmpIt != myTempConstraints.end(); ++aTmpIt) + (*aTmpIt)->remove(); myTempConstraints.clear(); + while (myStorage->numberTemporary()) myStorage->deleteTemporaryConstraint(); // Clean lists of removed entities in the storage diff --git a/src/SketchSolver/SketchSolver_Storage.cpp b/src/SketchSolver/SketchSolver_Storage.cpp index c599c3fbb..485b81565 100644 --- a/src/SketchSolver/SketchSolver_Storage.cpp +++ b/src/SketchSolver/SketchSolver_Storage.cpp @@ -718,7 +718,7 @@ void SketchSolver_Storage::initializeSolver(SketchSolver_Solver& theSolver) for (; anIt != aConstraints.end(); anIt++) if (anIt->h == myFixed) { aFixedPoint = anIt->ptA; - aConstraints.erase(anIt); +// aConstraints.erase(anIt); break; } // set dragged parameters -- 2.39.2