From 06864226f436bef182992679b7181d7038e36dd6 Mon Sep 17 00:00:00 2001 From: azv Date: Fri, 17 Apr 2015 08:06:29 +0300 Subject: [PATCH] Correct change of mirror line in the Mirror operation --- src/SketchSolver/SketchSolver_Constraint.cpp | 73 +++++++++---------- src/SketchSolver/SketchSolver_Constraint.h | 5 ++ .../SketchSolver_ConstraintMirror.cpp | 33 +++++++++ .../SketchSolver_ConstraintMirror.h | 5 ++ 4 files changed, 78 insertions(+), 38 deletions(-) diff --git a/src/SketchSolver/SketchSolver_Constraint.cpp b/src/SketchSolver/SketchSolver_Constraint.cpp index 4db4c4636..4e815d649 100644 --- a/src/SketchSolver/SketchSolver_Constraint.cpp +++ b/src/SketchSolver/SketchSolver_Constraint.cpp @@ -113,48 +113,45 @@ void SketchSolver_Constraint::process() adjustConstraint(); } -void SketchSolver_Constraint::update(ConstraintPtr theConstraint) +bool SketchSolver_Constraint::checkAttributesChanged(ConstraintPtr theConstraint) { - cleanErrorMsg(); - bool needToRebuild = (theConstraint && theConstraint != myBaseConstraint); - if (!needToRebuild) { - // Check the attrbutes of constraint are changed - ConstraintPtr aConstraint = theConstraint ? theConstraint : myBaseConstraint; - std::list anAttrList = aConstraint->data()->attributes(std::string()); - std::list::iterator anAttrIter = anAttrList.begin(); - for (; anAttrIter != anAttrList.end(); anAttrIter++) { - AttributeRefAttrPtr aRefAttr = - std::dynamic_pointer_cast(*anAttrIter); - if (aRefAttr) { - if (aRefAttr->isObject()) { - FeaturePtr aFeature = ModelAPI_Feature::feature(aRefAttr->object()); - if (aFeature && myFeatureMap.find(aFeature) == myFeatureMap.end()) { - needToRebuild = true; - break; - } - } else if (aRefAttr->attr() && - myAttributeMap.find(aRefAttr->attr()) == myAttributeMap.end()) { - needToRebuild = true; - break; - } - } - AttributeRefListPtr aRefList = - std::dynamic_pointer_cast(*anAttrIter); - if (aRefList) { - std::list anItems = aRefList->list(); - std::list::iterator anIt = anItems.begin(); - for (; anIt != anItems.end(); anIt++) { - FeaturePtr aFeature = ModelAPI_Feature::feature(*anIt); - if (aFeature && myFeatureMap.find(aFeature) == myFeatureMap.end()) { - needToRebuild = true; - break; - } - } - if (needToRebuild) - break; + // Check the attrbutes of constraint are changed + ConstraintPtr aConstraint = theConstraint ? theConstraint : myBaseConstraint; + std::list anAttrList = aConstraint->data()->attributes(std::string()); + std::list::iterator anAttrIter = anAttrList.begin(); + for (; anAttrIter != anAttrList.end(); anAttrIter++) { + AttributeRefAttrPtr aRefAttr = + std::dynamic_pointer_cast(*anAttrIter); + if (aRefAttr) { + if (aRefAttr->isObject()) { + FeaturePtr aFeature = ModelAPI_Feature::feature(aRefAttr->object()); + if (aFeature && myFeatureMap.find(aFeature) == myFeatureMap.end()) + return true; + } else if (aRefAttr->attr() && + myAttributeMap.find(aRefAttr->attr()) == myAttributeMap.end()) + return true; + } + AttributeRefListPtr aRefList = + std::dynamic_pointer_cast(*anAttrIter); + if (aRefList) { + std::list anItems = aRefList->list(); + std::list::iterator anIt = anItems.begin(); + for (; anIt != anItems.end(); anIt++) { + FeaturePtr aFeature = ModelAPI_Feature::feature(*anIt); + if (aFeature && myFeatureMap.find(aFeature) == myFeatureMap.end()) + return true; } } } + return false; +} + +void SketchSolver_Constraint::update(ConstraintPtr theConstraint) +{ + cleanErrorMsg(); + bool needToRebuild = (theConstraint && theConstraint != myBaseConstraint); + if (!needToRebuild) + needToRebuild = checkAttributesChanged(theConstraint); if (needToRebuild) { if (theConstraint && theConstraint->getKind() != myBaseConstraint->getKind()) return; diff --git a/src/SketchSolver/SketchSolver_Constraint.h b/src/SketchSolver/SketchSolver_Constraint.h index b6ff8f55b..0ceac2812 100644 --- a/src/SketchSolver/SketchSolver_Constraint.h +++ b/src/SketchSolver/SketchSolver_Constraint.h @@ -82,6 +82,11 @@ protected: /// \param[out] theAttributes list of attributes to be filled virtual void getAttributes(double& theValue, std::vector& theAttributes); + /// \brief Verify the attributes of constraint are changed (and constraint need to rebuild) + /// \param[in] theConstraint constraint, which attributes should be checked (if NULL, the myBaseConstraint is used) + /// \return \c true if some attributes are changed + virtual bool checkAttributesChanged(ConstraintPtr theConstraint); + /// \brief This method is used in derived objects to check consistence of constraint. /// E.g. the distance between line and point may be signed. virtual void adjustConstraint() diff --git a/src/SketchSolver/SketchSolver_ConstraintMirror.cpp b/src/SketchSolver/SketchSolver_ConstraintMirror.cpp index 8ed85ff49..c27000bd1 100644 --- a/src/SketchSolver/SketchSolver_ConstraintMirror.cpp +++ b/src/SketchSolver/SketchSolver_ConstraintMirror.cpp @@ -233,6 +233,39 @@ bool SketchSolver_ConstraintMirror::remove(ConstraintPtr theConstraint) return true; } +bool SketchSolver_ConstraintMirror::checkAttributesChanged(ConstraintPtr theConstraint) +{ + // First of all, check the mirror line is changed. + // It may be changed to one of mirrored lines, which is already in this constraint + // (this case is not marked as attribute changing) + ConstraintPtr aConstraint = theConstraint ? theConstraint : myBaseConstraint; + AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast( + aConstraint->attribute(SketchPlugin_Constraint::ENTITY_A())); + if (!aRefAttr || !aRefAttr->isObject() || !aRefAttr->object()) + return true; + FeaturePtr aMirrorLine = ModelAPI_Feature::feature(aRefAttr->object()); + if (!aMirrorLine) + return true; + + std::map::iterator aMirrorIter = myFeatureMap.find(aMirrorLine); + if (aMirrorIter == myFeatureMap.end()) + return true; + + // Check the entity is not used as mirror line + std::vector::iterator aCIter = mySlvsConstraints.begin(); + for (; aCIter != mySlvsConstraints.end(); aCIter++) { + Slvs_Constraint aMirrorConstr = myStorage->getConstraint(*aCIter); + if (aMirrorConstr.type != SLVS_C_SYMMETRIC_LINE) + continue; + if (aMirrorConstr.entityA != aMirrorIter->second) + return true; + else break; // check just one symmetric constraint + } + + // Base verification + return SketchSolver_Constraint::checkAttributesChanged(theConstraint); +} + void SketchSolver_ConstraintMirror::makeMirrorEntity( const Slvs_Entity& theBase, const Slvs_Entity& theMirror, diff --git a/src/SketchSolver/SketchSolver_ConstraintMirror.h b/src/SketchSolver/SketchSolver_ConstraintMirror.h index eb3af1fb3..e65dcb90b 100644 --- a/src/SketchSolver/SketchSolver_ConstraintMirror.h +++ b/src/SketchSolver/SketchSolver_ConstraintMirror.h @@ -42,6 +42,11 @@ protected: virtual void getAttributes(double& theValue, std::vector& theAttributes) { /* do nothing here */ } + /// \brief Verify the attributes of constraint are changed (and constraint need to rebuild) + /// \param[in] theConstraint constraint, which attributes should be checked (if NULL, the myBaseConstraint is used) + /// \return \c true if some attributes are changed + virtual bool checkAttributesChanged(ConstraintPtr theConstraint); + /// \brief Generate list of entities of mirror constraint /// \param[out] theMirrorLine entity corresponding to mirror line /// \param[out] theBaseEntities list of entities to mirror -- 2.39.2