From 6fd3b8e870b7d3c2ff6f3e0557e253137d2cded3 Mon Sep 17 00:00:00 2001 From: nds Date: Tue, 17 Mar 2015 10:04:09 +0300 Subject: [PATCH] Multi-selection widget to be used in the extrusion feature. Validator and filters redesign to unite them and simplify the isValid() method parameters --- src/Model/Model_AttributeRefAttr.cpp | 4 + src/ModelAPI/ModelAPI_RefAttrValidator.h | 8 -- .../ModuleBase_WidgetShapeSelector.cpp | 52 ++++++- src/PartSet/PartSet_Validators.cpp | 127 +++++++++--------- src/PartSet/PartSet_Validators.h | 28 ++-- src/PartSet/PartSet_WidgetShapeSelector.cpp | 50 ------- src/PartSet/PartSet_WidgetShapeSelector.h | 3 - src/SketchPlugin/SketchPlugin_Validators.cpp | 60 ++++----- src/SketchPlugin/SketchPlugin_Validators.h | 7 - 9 files changed, 155 insertions(+), 184 deletions(-) diff --git a/src/Model/Model_AttributeRefAttr.cpp b/src/Model/Model_AttributeRefAttr.cpp index b6ac11663..b6f9e3e67 100644 --- a/src/Model/Model_AttributeRefAttr.cpp +++ b/src/Model/Model_AttributeRefAttr.cpp @@ -47,6 +47,10 @@ void Model_AttributeRefAttr::setObject(ObjectPtr theObject) myRef->Set(aData->label().Father()); myID->Set(""); // feature is identified by the empty ID owner()->data()->sendAttributeUpdated(this); + } else if (theObject.get() == NULL) { + myRef->Set(myRef->Label()); // reference to itself means that object is null + myID->Set(""); // feature is identified by the empty ID + owner()->data()->sendAttributeUpdated(this); } } diff --git a/src/ModelAPI/ModelAPI_RefAttrValidator.h b/src/ModelAPI/ModelAPI_RefAttrValidator.h index ab8ffc6cd..087cff483 100644 --- a/src/ModelAPI/ModelAPI_RefAttrValidator.h +++ b/src/ModelAPI/ModelAPI_RefAttrValidator.h @@ -19,14 +19,6 @@ class ModelAPI_RefAttrValidator : public ModelAPI_AttributeValidator { public: - //! Returns true if object is good for the feature attribute - virtual bool isValid(const FeaturePtr& theFeature, const std::list& theArguments, - const ObjectPtr& theObject) const = 0; - - //! Returns true if the attribute is good for the feature attribute - virtual bool isValid(const FeaturePtr& theFeature, const std::list& theArguments, - const AttributePtr& theAttribute) const = 0; - }; #endif diff --git a/src/ModuleBase/ModuleBase_WidgetShapeSelector.cpp b/src/ModuleBase/ModuleBase_WidgetShapeSelector.cpp index 3d376aace..9f9cd941d 100644 --- a/src/ModuleBase/ModuleBase_WidgetShapeSelector.cpp +++ b/src/ModuleBase/ModuleBase_WidgetShapeSelector.cpp @@ -437,6 +437,52 @@ bool ModuleBase_WidgetShapeSelector::isValid(ObjectPtr theObj, std::shared_ptr > anArguments; aFactory->validators(parentID(), attributeID(), aValidators, anArguments); + DataPtr aData = myFeature->data(); + //AttributePtr aAttr = aData->attribute(attributeID()); + AttributeRefAttrPtr aRefAttr = aData->refattr(attributeID()); + if (aRefAttr) { + // 1. saves the previous attribute values + bool isObject = aRefAttr->isObject(); + ObjectPtr aPrevObject = aRefAttr->object(); + AttributePtr aPrevAttr = aRefAttr->attr(); + + // 2. store the current values, disable the model's update + aData->blockSendAttributeUpdated(true); + ObjectPtr aPrevSelectedObject = mySelectedObject; + GeomShapePtr aPrevShape = myShape; + + mySelectedObject = theObj; + myShape = theShape; + storeValueCustom(); + + // 3. check the acceptability of the current values + std::list::iterator aValidator = aValidators.begin(); + std::list >::iterator aArgs = anArguments.begin(); + bool aValid = true; + for (; aValidator != aValidators.end() && aValid; aValidator++, aArgs++) { + const ModelAPI_RefAttrValidator* aAttrValidator = + dynamic_cast(*aValidator); + if (aAttrValidator) { + aValid = aAttrValidator->isValid(aRefAttr, *aArgs); + } + } + + // 4. if the values are not valid, restore the previous values to the attribute + //if (!aValid) { + mySelectedObject = aPrevSelectedObject; + myShape = aPrevShape; + if (isObject) + aRefAttr->setObject(aPrevObject); + else + aRefAttr->setAttr(aPrevAttr); + //} + // 5. enable the model's update + aData->blockSendAttributeUpdated(false); + //updateObject(myFeature); + + return aValid; + } + // Check the acceptability of the object as attribute std::list::iterator aValidator = aValidators.begin(); std::list >::iterator aArgs = anArguments.begin(); @@ -444,9 +490,9 @@ bool ModuleBase_WidgetShapeSelector::isValid(ObjectPtr theObj, std::shared_ptr(*aValidator); if (aAttrValidator) { - if (!aAttrValidator->isValid(myFeature, *aArgs, theObj)) { - return false; - } + //if (!aAttrValidator->isValid(myFeature, *aArgs, theObj)) { + // return false; + //} } else { const ModelAPI_ShapeValidator* aShapeValidator = diff --git a/src/PartSet/PartSet_Validators.cpp b/src/PartSet/PartSet_Validators.cpp index 92100792e..9bda4c9dc 100644 --- a/src/PartSet/PartSet_Validators.cpp +++ b/src/PartSet/PartSet_Validators.cpp @@ -110,80 +110,53 @@ bool PartSet_RigidValidator::isValid(const ModuleBase_ISelection* theSelection) return (aCount > 0) && (aCount < 2); } -bool PartSet_DifferentObjectsValidator::isValid(const FeaturePtr& theFeature, - const std::list& theArguments, - const ObjectPtr& theObject) const +bool PartSet_DifferentObjectsValidator::isValid(const AttributePtr& theAttribute, + const std::list& theArguments) const { - // Check RefAttr attributes - std::list > anAttrs = - theFeature->data()->attributes(ModelAPI_AttributeRefAttr::type()); - if (anAttrs.size() > 0) { - std::list >::iterator anAttr = anAttrs.begin(); - for(; anAttr != anAttrs.end(); anAttr++) { - if (*anAttr) { - std::shared_ptr aRef = - std::dynamic_pointer_cast(*anAttr); - // check the object is already presented - if (aRef->isObject() && aRef->object() == theObject) - return false; - } + FeaturePtr aFeature = std::dynamic_pointer_cast(theAttribute->owner()); + + // 1. check whether the object of the attribute is not among the feature attributes + // find the attribute's object + ObjectPtr anObject = getObject(theAttribute); + + // check whether the object is not among other feature attributes + if (anObject.get() != NULL) { + // Check RefAttr attributes + std::list > anAttrs = aFeature->data()->attributes(""); + //if (anAttrs.size() > 0) { + std::list >::iterator anIt = anAttrs.begin(); + for(; anIt != anAttrs.end(); anIt++) { + AttributePtr anAttr = *anIt; + // the function parameter attribute should be skipped + if (anAttr.get() == NULL || anAttr->id() == theAttribute->id()) + continue; + ObjectPtr aCurObject = getObject(anAttr); + if (aCurObject && aCurObject == anObject) + return false; } } - // Check selection attributes - anAttrs = theFeature->data()->attributes(ModelAPI_AttributeSelection::type()); - if (anAttrs.size() > 0) { - std::list >::iterator anAttr = anAttrs.begin(); - for(; anAttr != anAttrs.end(); anAttr++) { - if (*anAttr) { - std::shared_ptr aRef = - std::dynamic_pointer_cast(*anAttr); - // check the object is already presented - if (aRef->isInitialized() && aRef->context() == theObject) - return false; + else { + // 2. collect object referenced by theAttribute and ... + if (featureHasReferences(theAttribute)) { + // 3. check whether the attribute value is not among other feature attributes + std::list > anAttrs = + aFeature->data()->attributes(ModelAPI_AttributeRefAttr::type()); + std::list >::iterator anAttr = anAttrs.begin(); + for(; anAttr != anAttrs.end(); anAttr++) { + if (*anAttr) { + std::shared_ptr aRef = + std::dynamic_pointer_cast(*anAttr); + // check the object is already presented + if (!aRef->isObject() && aRef->attr() == theAttribute) + return false; + } } + return true; } } - // Check selection attributes - anAttrs = theFeature->data()->attributes(ModelAPI_AttributeReference::type()); - if (anAttrs.size() > 0) { - std::list >::iterator anAttr = anAttrs.begin(); - for(; anAttr != anAttrs.end(); anAttr++) { - if (*anAttr) { - std::shared_ptr aRef = - std::dynamic_pointer_cast(*anAttr); - // check the object is already presented - if (aRef->isInitialized() && aRef->value() == theObject) - return false; - } - } - } - return true; } -bool PartSet_DifferentObjectsValidator::isValid(const FeaturePtr& theFeature, - const std::list& theArguments, - const AttributePtr& theAttribute) const -{ - if (PartSet_DifferentObjectsValidator::isValid(theAttribute, theArguments)) { - std::list > anAttrs = - theFeature->data()->attributes(ModelAPI_AttributeRefAttr::type()); - std::list >::iterator anAttr = anAttrs.begin(); - for(; anAttr != anAttrs.end(); anAttr++) { - if (*anAttr) { - std::shared_ptr aRef = - std::dynamic_pointer_cast(*anAttr); - // check the object is already presented - if (!aRef->isObject() && aRef->attr() == theAttribute) - return false; - } - } - return true; - } - return false; -} - -bool PartSet_DifferentObjectsValidator::isValid(const AttributePtr& theAttribute, - const std::list& theArguments) const +bool PartSet_DifferentObjectsValidator::featureHasReferences(const AttributePtr& theAttribute) const { std::list > > allRefs; if (theAttribute->owner().get() && theAttribute->owner()->data().get()) @@ -213,6 +186,28 @@ bool PartSet_DifferentObjectsValidator::isValid(const AttributePtr& theAttribute return true; } +ObjectPtr PartSet_DifferentObjectsValidator::getObject(const AttributePtr& theAttribute) const +{ + ObjectPtr anObject; + std::string anAttrType = theAttribute->attributeType(); + if (anAttrType == ModelAPI_AttributeRefAttr::type()) { + AttributeRefAttrPtr anAttr = std::dynamic_pointer_cast(theAttribute); + if (anAttr != NULL && anAttr->isObject()) + anObject = anAttr->object(); + } + if (anAttrType == ModelAPI_AttributeSelection::type()) { + AttributeSelectionPtr anAttr = std::dynamic_pointer_cast(theAttribute); + if (anAttr != NULL && anAttr->isInitialized()) + anObject = anAttr->context(); + } + if (anAttrType == ModelAPI_AttributeReference::type()) { + AttributeReferencePtr anAttr = std::dynamic_pointer_cast(theAttribute); + if (anAttr.get() != NULL && anAttr->isInitialized()) + anObject = anAttr->value(); + } + return anObject; +} + bool PartSet_SketchValidator::isValid(const ObjectPtr theObject) const { FeaturePtr aFeature = ModelAPI_Feature::feature(theObject); diff --git a/src/PartSet/PartSet_Validators.h b/src/PartSet/PartSet_Validators.h index be1bb0ef5..0dc5f4619 100644 --- a/src/PartSet/PartSet_Validators.h +++ b/src/PartSet/PartSet_Validators.h @@ -73,25 +73,22 @@ class PartSet_RigidValidator : public ModuleBase_SelectionValidator class PartSet_DifferentObjectsValidator : public ModelAPI_RefAttrValidator { public: - /// Returns True if the feature is valid - /// \param theFeature a feature to check - /// \param theArguments a list of arguments (names of attributes to check) - /// \param theObject a selected object - virtual bool isValid(const FeaturePtr& theFeature, const std::list& theArguments, - const ObjectPtr& theObject) const; - - //! Returns true if the attribute is good for the feature attribute - //! \param theFeature a feature to check - //! \param theArguments a list of arguments (names of attributes to check) - //! \param theAttribute an attribute - virtual bool isValid(const FeaturePtr& theFeature, const std::list& theArguments, - const AttributePtr& theAttribute) const; - //! Returns true if the attribute is good for the feature attribute //! \param theAttribute an attribute //! \param theArguments a list of arguments (names of attributes to check) virtual bool isValid(const AttributePtr& theAttribute, const std::list& theArguments) const; + +protected: + //! Casts the attribute to an attribute kind and obtains an object value if it is possible + //! \param theAttribute a source attribute to find object + //! \return an attribute object or NULL + ObjectPtr getObject(const AttributePtr& theAttribute) const; + + //! Checks whethe other feature attributes has a reference to the given attribute + //! \param theAttribute a source attribute to find object + //! \return a boolean value + bool featureHasReferences(const AttributePtr& theAttribute) const; }; /** @@ -106,5 +103,4 @@ class PartSet_SketchValidator : public ModelAPI_ResultValidator virtual bool isValid(const ObjectPtr theObject) const; }; - -#endif +#endif \ No newline at end of file diff --git a/src/PartSet/PartSet_WidgetShapeSelector.cpp b/src/PartSet/PartSet_WidgetShapeSelector.cpp index d51be0d51..422be37e1 100644 --- a/src/PartSet/PartSet_WidgetShapeSelector.cpp +++ b/src/PartSet/PartSet_WidgetShapeSelector.cpp @@ -62,53 +62,3 @@ bool PartSet_WidgetShapeSelector::storeValueCustom() const return ModuleBase_WidgetShapeSelector::storeValueCustom(); } -//******************************************************************** -bool PartSet_WidgetShapeSelector::isValid(ObjectPtr theObj, std::shared_ptr theShape) -{ - bool isValid = ModuleBase_WidgetValidated::isValid(theObj, theShape); - if (!isValid) - return false; - - // the method is redefined to analize the selected shape in validators - SessionPtr aMgr = ModelAPI_Session::get(); - ModelAPI_ValidatorsFactory* aFactory = aMgr->validators(); - std::list aValidators; - std::list > anArguments; - aFactory->validators(parentID(), attributeID(), aValidators, anArguments); - - // Check the acceptability of the object and shape as validator attribute - AttributePtr aPntAttr; - DataPtr aData = myFeature->data(); - if (theShape.get() != NULL) { - AttributePtr aAttr = aData->attribute(attributeID()); - AttributeRefAttrPtr aRefAttr = - std::dynamic_pointer_cast(aAttr); - if (aRefAttr) { - TopoDS_Shape aShape = theShape->impl(); - aPntAttr = PartSet_Tools::findAttributeBy2dPoint(theObj, aShape, mySketch); - } - } - // Check the acceptability of the object as attribute - std::list::iterator aValidator = aValidators.begin(); - std::list >::iterator aArgs = anArguments.begin(); - for (; aValidator != aValidators.end(); aValidator++, aArgs++) { - const ModelAPI_RefAttrValidator* aAttrValidator = - dynamic_cast(*aValidator); - if (aAttrValidator) { - if (aPntAttr.get() != NULL) - { - if (!aAttrValidator->isValid(myFeature, *aArgs, aPntAttr)) { - return false; - } - } - else - { - if (!aAttrValidator->isValid(myFeature, *aArgs, theObj)) { - return false; - } - } - } - } - return true; -} - diff --git a/src/PartSet/PartSet_WidgetShapeSelector.h b/src/PartSet/PartSet_WidgetShapeSelector.h index b69c66648..503625684 100644 --- a/src/PartSet/PartSet_WidgetShapeSelector.h +++ b/src/PartSet/PartSet_WidgetShapeSelector.h @@ -47,9 +47,6 @@ protected: /// \return True in success virtual bool storeValueCustom() const; - /// Check the selected with validators if installed - virtual bool isValid(ObjectPtr theObj, std::shared_ptr theShape); - private: /// Pointer to a sketch CompositeFeaturePtr mySketch; diff --git a/src/SketchPlugin/SketchPlugin_Validators.cpp b/src/SketchPlugin/SketchPlugin_Validators.cpp index 1fcac300d..e69dce246 100644 --- a/src/SketchPlugin/SketchPlugin_Validators.cpp +++ b/src/SketchPlugin/SketchPlugin_Validators.cpp @@ -14,47 +14,45 @@ #include #include -bool SketchPlugin_DistanceAttrValidator::isValid(const FeaturePtr& theFeature, - const std::list& theArguments, - const ObjectPtr& theObject) const +bool SketchPlugin_DistanceAttrValidator::isValid( + const AttributePtr& theAttribute, const std::list& theArguments ) const { + // there is a check whether the feature contains a point and a linear edge or two point values std::string aParamA = theArguments.front(); SessionPtr aMgr = ModelAPI_Session::get(); ModelAPI_ValidatorsFactory* aFactory = aMgr->validators(); - const ModelAPI_ResultValidator* anArcValidator = - dynamic_cast(aFactory->validator("SketchPlugin_ResultArc")); - bool anArcValid = anArcValidator->isValid(theObject); - if (anArcValid) + AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast(theAttribute); + if (!aRefAttr) return false; - - // If the object is not a line then it is accepted - const ModelAPI_ResultValidator* aLineValidator = - dynamic_cast(aFactory->validator("SketchPlugin_ResultLine")); - bool aLineValid = aLineValidator->isValid(theObject); - if (!aLineValid) + bool isObject = aRefAttr->isObject(); + if (!isObject) { + // an attribute is a point. A point value is valid always for the distance return true; + } else { + // 1. check whether the references object is a linear + ObjectPtr anObject = aRefAttr->object(); + const ModelAPI_ResultValidator* anArcValidator = + dynamic_cast(aFactory->validator("SketchPlugin_ResultArc")); + bool anArcValid = anArcValidator->isValid(anObject); + if (anArcValid) + return false; - // If it is a line then we have to check that first attribute id not a line - std::shared_ptr aPoint = getFeaturePoint(theFeature->data(), aParamA); - if (aPoint) - return true; - return false; -} + // If the object is not a line then it is accepted. It can be a point feature selected + const ModelAPI_ResultValidator* aLineValidator = + dynamic_cast(aFactory->validator("SketchPlugin_ResultLine")); + bool aLineValid = aLineValidator->isValid(anObject); + if (!aLineValid) + return true; + FeaturePtr aFeature = std::dynamic_pointer_cast(theAttribute->owner()); -bool SketchPlugin_DistanceAttrValidator::isValid( - const AttributePtr& theAttribute, const std::list& theArguments ) const -{ - // any point attribute is acceptable for the distance operation - return true; -} - -bool SketchPlugin_DistanceAttrValidator::isValid(const FeaturePtr& theFeature, - const std::list& theArguments, - const AttributePtr& theAttribute) const -{ - return isValid(theAttribute, theArguments); + // If it is a line then we have to check that first attribute id not a line + std::shared_ptr aPoint = getFeaturePoint(aFeature->data(), aParamA); + if (aPoint) + return true; + } + return false; } //bool SketchPlugin_DifferentObjectsValidator::isValid(const FeaturePtr& theFeature, diff --git a/src/SketchPlugin/SketchPlugin_Validators.h b/src/SketchPlugin/SketchPlugin_Validators.h index 61553fea8..9b732adee 100644 --- a/src/SketchPlugin/SketchPlugin_Validators.h +++ b/src/SketchPlugin/SketchPlugin_Validators.h @@ -24,13 +24,6 @@ class SketchPlugin_DistanceAttrValidator : public ModelAPI_RefAttrValidator //! \param theArguments arguments of the attribute virtual bool isValid( const AttributePtr& theAttribute, const std::list& theArguments) const; - //! Returns true if object is good for the feature attribute - virtual bool isValid(const FeaturePtr& theFeature, const std::list& theArguments, - const ObjectPtr& theObject) const; - - //! Returns true if the attribute is good for the feature attribute - virtual bool isValid(const FeaturePtr& theFeature, const std::list& theArguments, - const AttributePtr& theAttribute) const; }; /**\class SketchPlugin_DifferentObjectsValidator -- 2.39.2