From 43c9c7d63b45ab5ef506c2ff3a1d99ee6a034675 Mon Sep 17 00:00:00 2001 From: nds Date: Wed, 27 Apr 2016 19:22:35 +0300 Subject: [PATCH] Issue #1037 Time performance on a big model: cash in widget validated is corrected --- src/ModuleBase/ModuleBase_ViewerPrs.cpp | 44 ++++++++++ src/ModuleBase/ModuleBase_ViewerPrs.h | 4 + src/ModuleBase/ModuleBase_WidgetValidated.cpp | 81 ++++++++++++++++--- src/ModuleBase/ModuleBase_WidgetValidated.h | 11 +++ 4 files changed, 128 insertions(+), 12 deletions(-) diff --git a/src/ModuleBase/ModuleBase_ViewerPrs.cpp b/src/ModuleBase/ModuleBase_ViewerPrs.cpp index 43b584bdb..fa417072a 100644 --- a/src/ModuleBase/ModuleBase_ViewerPrs.cpp +++ b/src/ModuleBase/ModuleBase_ViewerPrs.cpp @@ -21,8 +21,52 @@ ModuleBase_ViewerPrs::~ModuleBase_ViewerPrs() { } +bool ModuleBase_ViewerPrs::isEqual(ModuleBase_ViewerPrs* thePrs) const +{ + if (!thePrs || thePrs->isEmpty()) + return false; + + bool isEqualResult = (myResult.get() == thePrs->object().get()); + bool isEqualShape = (!myShape.get() && !thePrs->shape().get()) || + (myShape.get() && myShape->isEqual(thePrs->shape())); + bool isEqualIO = (myInteractive == thePrs->interactive()) == Standard_True; + + bool isEqualOwner = (myOwner.Access() == thePrs->owner().Access()); + if (isEqualResult && isEqualShape && isEqualIO && + !isEqualOwner) { /// owners are different + // as we might loading object with the same shape in different modes like + // "objects" and "other", it is possible that two owners are created linked + // to one shape. We should accept such ViewerPrs as equal to current in order + // to do not use the same twice + Handle(StdSelect_BRepOwner) anOwner1 = Handle(StdSelect_BRepOwner)::DownCast(myOwner); + Handle(StdSelect_BRepOwner) anOwner2 = Handle(StdSelect_BRepOwner)::DownCast(thePrs->owner()); + if (!anOwner1.IsNull() && !anOwner2.IsNull()) + isEqualOwner = (anOwner1->Shape().IsNull() && anOwner2->Shape().IsNull()) || + anOwner1->Shape().IsEqual(anOwner2->Shape()); + } + + if (isEqualResult && isEqualShape && + !isEqualIO) { /// AIS are different + // check that the owner is a fictive owner for compsolid object, created in the + // ComputeSelection of ModuleBase_ResultPrs. A new owner is created there for each subsolid + // and set in the sub-solid AIS. ViewerPrs of these fictive owners are accepted as equal + // as they use the same shape and result(of compsolid) + Handle(ModuleBase_BRepOwner) aCSolidOwner1 = Handle(ModuleBase_BRepOwner)::DownCast(myOwner); + Handle(ModuleBase_BRepOwner) aCSolidOwner2 = Handle(ModuleBase_BRepOwner)::DownCast(thePrs->owner()); + isEqualIO = !aCSolidOwner1.IsNull() && !aCSolidOwner2.IsNull(); + if (!aCSolidOwner1.IsNull() && !aCSolidOwner1.IsNull()) + isEqualOwner = (aCSolidOwner1->Shape().IsNull() && aCSolidOwner2->Shape().IsNull()) || + aCSolidOwner1->Shape().IsEqual(aCSolidOwner2->Shape()); + } + + return isEqualResult && isEqualShape && isEqualOwner && isEqualIO; +} + bool ModuleBase_ViewerPrs::operator==(const ModuleBase_ViewerPrs& thePrs) { + if (thePrs.isEmpty()) + return false; + bool isEqualResult = (myResult.get() == thePrs.object().get()); bool isEqualShape = (!myShape.get() && !thePrs.shape().get()) || (myShape.get() && myShape->isEqual(thePrs.shape())); diff --git a/src/ModuleBase/ModuleBase_ViewerPrs.h b/src/ModuleBase/ModuleBase_ViewerPrs.h index 7a3112b42..4dcca83c2 100644 --- a/src/ModuleBase/ModuleBase_ViewerPrs.h +++ b/src/ModuleBase/ModuleBase_ViewerPrs.h @@ -97,6 +97,10 @@ class ModuleBase_ViewerPrs myOwner.IsNull() && !myResult.get(); } + /// Returns true if all presentation fields are empty + /// \return boolean value + MODULEBASE_EXPORT bool isEqual(ModuleBase_ViewerPrs* thePrs) const; + /// Returns True if the current object is equal to the given one /// \param thePrs an object to compare MODULEBASE_EXPORT bool operator==(const ModuleBase_ViewerPrs& thePrs); diff --git a/src/ModuleBase/ModuleBase_WidgetValidated.cpp b/src/ModuleBase/ModuleBase_WidgetValidated.cpp index 7e85bce2e..a5915e51f 100644 --- a/src/ModuleBase/ModuleBase_WidgetValidated.cpp +++ b/src/ModuleBase/ModuleBase_WidgetValidated.cpp @@ -50,8 +50,8 @@ void ModuleBase_WidgetValidated::clearValidatedCash() #ifdef DEBUG_VALID_STATE qDebug("clearValidatedCash"); #endif - myValidPrs.clear(); - myInvalidPrs.clear(); + myValidPrs.Clear(); + myInvalidPrs.Clear(); } //******************************************************************** @@ -244,22 +244,47 @@ void ModuleBase_WidgetValidated::blockAttribute(const AttributePtr& theAttribute //******************************************************************** void ModuleBase_WidgetValidated::storeValidState(const ModuleBase_ViewerPrsPtr& theValue, const bool theValid) { - bool aValidPrs = myInvalidPrs.contains(theValue); - bool anInvalidPrs = myInvalidPrs.contains(theValue); - if (theValid) { - if (!aValidPrs) + GeomShapePtr aShape = theValue.get() ? theValue->shape() : GeomShapePtr(); + const TopoDS_Shape& aTDShape = aShape->impl(); + bool aValidPrsContains = aShape.get() && myValidPrs.IsBound(aTDShape) && + theValue.get()->isEqual(myValidPrs.Find(aTDShape).get()); + if (!aValidPrsContains) { +#ifdef LIST_OF_VALID_PRS + myValidPrs.append(theValue); +#else + GeomShapePtr aShape = theValue->shape(); + if (aShape.get()) { + const TopoDS_Shape& aTDShape = aShape->impl(); + myValidPrs.Bind(aTDShape, theValue); + } +#endif // the commented code will be useful when the valid state of the presentation // will be changable between activate/deactivate. Currently it does not happen. //if (anInvalidPrs) // myInvalidPrs.removeOne(theValue); + } } else { // !theValid - if (!anInvalidPrs) + GeomShapePtr aShape = theValue.get() ? theValue->shape() : GeomShapePtr(); + const TopoDS_Shape& aTDShape = aShape->impl(); + bool anIValidPrsContains = aShape.get() && myInvalidPrs.IsBound(aTDShape) && + theValue.get()->isEqual(myInvalidPrs.Find(aTDShape).get()); + + if (!anIValidPrsContains) { +#ifdef LIST_OF_VALID_PRS myInvalidPrs.append(theValue); +#else + GeomShapePtr aShape = theValue->shape(); + if (aShape.get()) { + const TopoDS_Shape& aTDShape = aShape->impl(); + myInvalidPrs.Bind(aTDShape, theValue); + } +#endif //if (!aValidPrs) // myValidPrs.removeOne(theValue); + } } #ifdef DEBUG_VALID_STATE qDebug(QString("storeValidState: myValidPrs.size() = %1, myInvalidPrs.size() = %2").arg(myValidPrs.count()) @@ -270,15 +295,47 @@ void ModuleBase_WidgetValidated::storeValidState(const ModuleBase_ViewerPrsPtr& //******************************************************************** bool ModuleBase_WidgetValidated::getValidState(const ModuleBase_ViewerPrsPtr& theValue, bool& theValid) { - bool aValidPrs = myValidPrs.contains(theValue); - bool anInvalidPrs = myInvalidPrs.contains(theValue); + if (!theValue.get()) + return false; + +#ifdef LIST_OF_VALID_PRS + bool aValidPrsContains = myValidPrs.contains(theValue); + bool anInvalidPrsContains = myInvalidPrs.contains(theValue); +#else + GeomShapePtr aShape = theValue.get() ? theValue->shape() : GeomShapePtr(); + const TopoDS_Shape& aTDShape = aShape->impl(); + bool aValidPrsContains = aShape.get() && myValidPrs.IsBound(aTDShape) && + theValue.get()->isEqual(myValidPrs.Find(aTDShape).get()); + /*if (aShape.get() && myValidPrs.IsBound(aTDShape)) { + ModuleBase_ViewerPrs* aPrs1 = theValue.get(); + ModuleBase_ViewerPrs* aPrs2 = myValidPrs.Find(aTDShape).get(); + + bool isEqual2 = aPrs1->isEqual(aPrs2); + + bool aValue = 9; + }*/ + + bool anInvalidPrsContains = aShape.get() && myInvalidPrs.IsBound(aTDShape) && + theValue.get()->isEqual(myInvalidPrs.Find(aTDShape).get()); + /* + bool aValidPrsContains = false, anInvalidPrsContains = false; + GeomShapePtr aShape = theValue.get() ? theValue->shape() : GeomShapePtr(); + if (aShape.get()) { + aValidPrsContains = myValidPrs.contains(aShape); + anInvalidPrsContains = myInvalidPrs.contains(aShape); + + if (aValidPrsContains) + aValidPrsContains = theValue == myValidPrs[aShape]; + else + anInvalidPrsContains = theValue == myInvalidPrs[aShape];*/ +#endif - if (aValidPrs) + if (aValidPrsContains) theValid = true; - else if (anInvalidPrs) + else if (anInvalidPrsContains) theValid = false; - return aValidPrs || anInvalidPrs; + return aValidPrsContains || anInvalidPrsContains; } //******************************************************************** diff --git a/src/ModuleBase/ModuleBase_WidgetValidated.h b/src/ModuleBase/ModuleBase_WidgetValidated.h index 8b2ae15ba..87432cb72 100644 --- a/src/ModuleBase/ModuleBase_WidgetValidated.h +++ b/src/ModuleBase/ModuleBase_WidgetValidated.h @@ -17,8 +17,11 @@ #include #include +#include +#include #include +#include class QWidget; class ModuleBase_IWorkshop; @@ -28,6 +31,8 @@ class ModelAPI_Validator; class Config_WidgetAPI; class Handle_SelectMgr_EntityOwner; +//#define LIST_OF_VALID_PRS + /** * \ingroup GUI * Implementation of widget with validators and filters processing. @@ -159,8 +164,14 @@ protected: private: ObjectPtr myPresentedObject; /// back up of the filtered object +#ifdef LIST_OF_VALID_PRS QList> myValidPrs; /// cash of valid selection presentations QList> myInvalidPrs; /// cash of invalid selection presentations +#else + // assume that one presentation selection presentation corresponds only one shape + NCollection_DataMap > myValidPrs; + NCollection_DataMap > myInvalidPrs; +#endif /// store to backup parameters of the model ModuleBase_WidgetSelectorStore* myAttributeStore; -- 2.39.2