From 66b868e71cedc4b7c6132b9ec15dddd9ef372a9a Mon Sep 17 00:00:00 2001 From: nds Date: Thu, 28 Apr 2016 14:58:58 +0300 Subject: [PATCH] Issue #1037 Time performance on a big model: do not perform validating for objects which are already in list. Case: deselect with SHIFT one of selected objects in Partition main widget control. --- src/ModuleBase/ModuleBase_Tools.cpp | 81 +++++++++++++++++-- src/ModuleBase/ModuleBase_Tools.h | 17 +++- .../ModuleBase_WidgetMultiSelector.cpp | 15 +++- src/ModuleBase/ModuleBase_WidgetSelector.cpp | 3 +- .../ModuleBase_WidgetSelectorStore.cpp | 2 +- 5 files changed, 107 insertions(+), 11 deletions(-) diff --git a/src/ModuleBase/ModuleBase_Tools.cpp b/src/ModuleBase/ModuleBase_Tools.cpp index 412b5e109..3211a935a 100755 --- a/src/ModuleBase/ModuleBase_Tools.cpp +++ b/src/ModuleBase/ModuleBase_Tools.cpp @@ -436,9 +436,80 @@ std::string findGreedAttribute(ModuleBase_IWorkshop* theWorkshop, const FeatureP return anAttributeId; } +bool hasObject(const AttributePtr& theAttribute, const ObjectPtr& theObject, + const std::shared_ptr& theShape, + ModuleBase_IWorkshop* theWorkshop, + const bool theTemporarily) +{ + bool aHasObject = false; + if (!theAttribute.get()) + return aHasObject; + + std::string aType = theAttribute->attributeType(); + if (aType == ModelAPI_AttributeReference::typeId()) { + AttributeReferencePtr aRef = std::dynamic_pointer_cast(theAttribute); + ObjectPtr aObject = aRef->value(); + aHasObject = aObject && aObject->isSame(theObject); + //if (!(aObject && aObject->isSame(theObject))) { + // aRef->setValue(theObject); + //} + } else if (aType == ModelAPI_AttributeRefAttr::typeId()) { + AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast(theAttribute); + + AttributePtr anAttribute = theWorkshop->module()->findAttribute(theObject, theShape); + if (anAttribute.get()) { + //aRefAttr->setAttr(anAttribute); + } + else { + ObjectPtr aObject = aRefAttr->object(); + aHasObject = aObject && aObject->isSame(theObject); + //if (!(aObject && aObject->isSame(theObject))) { + // aRefAttr->setObject(theObject); + //} + } + } else if (aType == ModelAPI_AttributeSelection::typeId()) { + /*AttributeSelectionPtr aSelectAttr = + std::dynamic_pointer_cast(theAttribute); + ResultPtr aResult = std::dynamic_pointer_cast(theObject); + if (aSelectAttr.get() != NULL) { + aSelectAttr->setValue(aResult, theShape, theTemporarily); + }*/ + } + if (aType == ModelAPI_AttributeSelectionList::typeId()) { + AttributeSelectionListPtr aSelectionListAttr = + std::dynamic_pointer_cast(theAttribute); + ResultPtr aResult = std::dynamic_pointer_cast(theObject); + aHasObject = aSelectionListAttr->isInList(aResult, theShape, theTemporarily); + //if (!theCheckIfAttributeHasObject || !aSelectionListAttr->isInList(aResult, theShape, theTemporarily)) + // aSelectionListAttr->append(aResult, theShape, theTemporarily); + } + else if (aType == ModelAPI_AttributeRefList::typeId()) { + AttributeRefListPtr aRefListAttr = std::dynamic_pointer_cast(theAttribute); + aHasObject = aRefListAttr->isInList(theObject); + //if (!theCheckIfAttributeHasObject || !aRefListAttr->isInList(theObject)) + // aRefListAttr->append(theObject); + } + else if (aType == ModelAPI_AttributeRefAttrList::typeId()) { + AttributeRefAttrListPtr aRefAttrListAttr = std::dynamic_pointer_cast(theAttribute); + AttributePtr anAttribute = theWorkshop->module()->findAttribute(theObject, theShape); + + if (anAttribute.get()) { + aHasObject = aRefAttrListAttr->isInList(anAttribute); + //if (!theCheckIfAttributeHasObject || !aRefAttrListAttr->isInList(anAttribute)) + // aRefAttrListAttr->append(anAttribute); + } + else { + aHasObject = aRefAttrListAttr->isInList(theObject); + //if (!theCheckIfAttributeHasObject || !aRefAttrListAttr->isInList(theObject)) + // aRefAttrListAttr->append(theObject); + } + } + return aHasObject; +} + void setObject(const AttributePtr& theAttribute, const ObjectPtr& theObject, const GeomShapePtr& theShape, ModuleBase_IWorkshop* theWorkshop, - const bool theTemporarily) + const bool theTemporarily, const bool theCheckIfAttributeHasObject) { if (!theAttribute.get()) return; @@ -474,12 +545,12 @@ void setObject(const AttributePtr& theAttribute, const ObjectPtr& theObject, AttributeSelectionListPtr aSelectionListAttr = std::dynamic_pointer_cast(theAttribute); ResultPtr aResult = std::dynamic_pointer_cast(theObject); - if (!aSelectionListAttr->isInList(aResult, theShape, theTemporarily)) + if (!theCheckIfAttributeHasObject || !aSelectionListAttr->isInList(aResult, theShape, theTemporarily)) aSelectionListAttr->append(aResult, theShape, theTemporarily); } else if (aType == ModelAPI_AttributeRefList::typeId()) { AttributeRefListPtr aRefListAttr = std::dynamic_pointer_cast(theAttribute); - if (!aRefListAttr->isInList(theObject)) + if (!theCheckIfAttributeHasObject || !aRefListAttr->isInList(theObject)) aRefListAttr->append(theObject); } else if (aType == ModelAPI_AttributeRefAttrList::typeId()) { @@ -487,11 +558,11 @@ void setObject(const AttributePtr& theAttribute, const ObjectPtr& theObject, AttributePtr anAttribute = theWorkshop->module()->findAttribute(theObject, theShape); if (anAttribute.get()) { - if (!aRefAttrListAttr->isInList(anAttribute)) + if (!theCheckIfAttributeHasObject || !aRefAttrListAttr->isInList(anAttribute)) aRefAttrListAttr->append(anAttribute); } else { - if (!aRefAttrListAttr->isInList(theObject)) + if (!theCheckIfAttributeHasObject || !aRefAttrListAttr->isInList(theObject)) aRefAttrListAttr->append(theObject); } } diff --git a/src/ModuleBase/ModuleBase_Tools.h b/src/ModuleBase/ModuleBase_Tools.h index fd70f33fb..a9b38bd80 100755 --- a/src/ModuleBase/ModuleBase_Tools.h +++ b/src/ModuleBase/ModuleBase_Tools.h @@ -187,10 +187,25 @@ MODULEBASE_EXPORT std::string findGreedAttribute(ModuleBase_IWorkshop* theWorksh /// \param theWorkshop to find an attribute for the given shape for attribute reference /// \param theTemporarily if it is true, do not store and name the added in the data framework /// It is useful for attribute selection +MODULEBASE_EXPORT bool hasObject(const AttributePtr& theAttribute, const ObjectPtr& theObject, + const std::shared_ptr& theShape, + ModuleBase_IWorkshop* theWorkshop, + const bool theTemporarily); + +/// Set the object to the attribute depending on the attribute type. If it is a list, +/// the values are appended if they are not in the list yet. +/// \param theAttribute an attribute where the object and shape are set +/// \param theObject an object +/// \param theShape a shape +/// \param theWorkshop to find an attribute for the given shape for attribute reference +/// \param theTemporarily if it is true, do not store and name the added in the data framework +/// \param theCheckIfAttributeHasObject if it is true, the check isInList is called +/// It is useful for attribute selection MODULEBASE_EXPORT void setObject(const AttributePtr& theAttribute, const ObjectPtr& theObject, const std::shared_ptr& theShape, ModuleBase_IWorkshop* theWorkshop, - const bool theTemporarily = false); + const bool theTemporarily, + const bool theCheckIfAttributeHasObject); /// Returns the shape of the attribute. If the attribute is AttributeRefAttrPtr, the shape is found /// using current module of the given workshop. diff --git a/src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp b/src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp index ab940f015..7a187e57c 100755 --- a/src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp +++ b/src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp @@ -225,10 +225,18 @@ bool ModuleBase_WidgetMultiSelector::setSelection(QList removeUnusedAttributeObjects(theValues); QList anInvalidValues; + QList anAttributeValues; QList::const_iterator anIt = theValues.begin(), aLast = theValues.end(); for (; anIt != aLast; anIt++) { ModuleBase_ViewerPrsPtr aValue = *anIt; - bool aProcessed = false; + // do not validate and append to attribute selection presentation if it exists in the attribute + ObjectPtr anObject; + GeomShapePtr aShape; + getGeomSelection(aValue, anObject, aShape); + if (ModuleBase_Tools::hasObject(attribute(), anObject, aShape, myWorkshop, myIsInValidate)) { + anAttributeValues.append(aValue); + continue; + } if (theToValidate && !isValidInFilters(aValue)) anInvalidValues.append(aValue); } @@ -238,9 +246,10 @@ bool ModuleBase_WidgetMultiSelector::setSelection(QList for (anIt = theValues.begin(); anIt != aLast; anIt++) { ModuleBase_ViewerPrsPtr aValue = *anIt; bool aProcessed = false; - if (aHasInvalidValues && anInvalidValues.contains(aValue)) + if ((aHasInvalidValues && anInvalidValues.contains(aValue)) || + anAttributeValues.contains(aValue)) continue; - aProcessed = setSelectionCustom(aValue); + aProcessed = setSelectionCustom(aValue); /// it is not optimal as hasObject() is already checked // if there is at least one set, the result is true isDone = isDone || aProcessed; } diff --git a/src/ModuleBase/ModuleBase_WidgetSelector.cpp b/src/ModuleBase/ModuleBase_WidgetSelector.cpp index b9fe6ef9c..9b044c602 100755 --- a/src/ModuleBase/ModuleBase_WidgetSelector.cpp +++ b/src/ModuleBase/ModuleBase_WidgetSelector.cpp @@ -176,7 +176,8 @@ bool ModuleBase_WidgetSelector::setSelectionCustom(const ModuleBase_ViewerPrsPtr GeomShapePtr aShape; getGeomSelection(thePrs, anObject, aShape); - ModuleBase_Tools::setObject(attribute(), anObject, aShape, myWorkshop, myIsInValidate); + // the last flag is to be depending on hasObject is called before. To be corrected later + ModuleBase_Tools::setObject(attribute(), anObject, aShape, myWorkshop, myIsInValidate, true); return true; } diff --git a/src/ModuleBase/ModuleBase_WidgetSelectorStore.cpp b/src/ModuleBase/ModuleBase_WidgetSelectorStore.cpp index 2bf5195ca..08e689387 100755 --- a/src/ModuleBase/ModuleBase_WidgetSelectorStore.cpp +++ b/src/ModuleBase/ModuleBase_WidgetSelectorStore.cpp @@ -85,7 +85,7 @@ void ModuleBase_WidgetSelectorStore::restoreAttributeValue(const AttributePtr& t aRefAttrListAttr->removeLast(); } else { - ModuleBase_Tools::setObject(theAttribute, myObject, myShape, theWorkshop, true); + ModuleBase_Tools::setObject(theAttribute, myObject, myShape, theWorkshop, true, true); AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast(theAttribute); if (aRefAttr) { if (!myIsObject) -- 2.39.2