From c8c7a421b7640fa35bcb024244a82a86fbb20f8d Mon Sep 17 00:00:00 2001 From: jfa Date: Wed, 6 Mar 2024 13:36:40 +0000 Subject: [PATCH] [bos #38090] [CEA] improve loadModifiedShapes deal with thousands of faces faster --- src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.cpp | 56 +++++++++++++++++++- src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.h | 23 +++++++- src/GeomAlgoAPI/GeomAlgoAPI_MakeShapeSet.cpp | 1 - src/Model/Model_BodyBuilder.cpp | 10 +++- src/Model/Model_ResultBody.cpp | 8 ++- 5 files changed, 91 insertions(+), 7 deletions(-) diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.cpp index 534afd0a9..1206dd3ee 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.cpp @@ -42,6 +42,9 @@ typedef NCollection_DataMap > HistoryMap; +typedef + NCollection_DataMap > + MapModified; //================================================================================================== GeomAlgoAPI_MakeShape::GeomAlgoAPI_MakeShape() @@ -49,6 +52,7 @@ GeomAlgoAPI_MakeShape::GeomAlgoAPI_MakeShape() myDone(false) { myHist = 0; + myModifHist = 0; } //================================================================================================== @@ -57,6 +61,9 @@ GeomAlgoAPI_MakeShape::~GeomAlgoAPI_MakeShape() if (myHist) { delete (HistoryMap*)myHist; } + if (myModifHist) { + delete (MapModified*)myModifHist; + } } //================================================================================================== @@ -114,7 +121,7 @@ void GeomAlgoAPI_MakeShape::modified(const GeomShapePtr theOldShape, BRepBuilderAPI_MakeShape* aMakeShape = implPtr(); try { aList = aMakeShape->Modified(theOldShape->impl()); - } catch(Standard_NoSuchObject) { + } catch(Standard_NoSuchObject const&) { } } else if(myBuilderType == OCCT_BOPAlgo_Builder) { BOPAlgo_Builder* aBOPBuilder = implPtr(); @@ -129,6 +136,23 @@ void GeomAlgoAPI_MakeShape::modified(const GeomShapePtr theOldShape, } } +//================================================================================================== +void GeomAlgoAPI_MakeShape::modifiedCached(const GeomShapePtr theOldShape, + ListOfShape& theNewShapes) +{ + if (myModifHist) { + MapModified* aModified = (MapModified*)myModifHist; + int aShapeType = (int)theOldShape->impl().ShapeType(); + if (aModified->IsBound(aShapeType)) { + const NCollection_DataMap& aM = + aModified->Find(aShapeType); + if (aM.IsBound(theOldShape->impl())) { + theNewShapes = aM.Find(theOldShape->impl()); + } + } + } +} + //================================================================================================== bool GeomAlgoAPI_MakeShape::isDeleted(const GeomShapePtr theOldShape) { @@ -250,6 +274,7 @@ void GeomAlgoAPI_MakeShape::initialize() myMap->bind(aCurrentShape, aCurrentShape); } myHist = 0; + myModifHist = 0; } @@ -304,6 +329,15 @@ bool GeomAlgoAPI_MakeShape::isNewShapesCollected(GeomShapePtr theWholeOld, void GeomAlgoAPI_MakeShape::collectNewShapes( GeomShapePtr theWholeOld, const int theShapeType) { + if (!myModifHist) + myModifHist = new MapModified; + MapModified* aModified = (MapModified*)myModifHist; + if (!aModified->IsBound(theShapeType)) + aModified->Bind(theShapeType, + NCollection_DataMap()); + NCollection_DataMap& aM = + aModified->ChangeFind(theShapeType); + if (!myHist) myHist = new HistoryMap; HistoryMap* aHist = (HistoryMap*)myHist; @@ -330,6 +364,26 @@ void GeomAlgoAPI_MakeShape::collectNewShapes( } aCurrent.ChangeFind(aNewShape).Bind(anExp.current()->impl(), anIndexInWholeOld); } + aM.Bind(anExp.current()->impl(), aNewList); + } +} + +void GeomAlgoAPI_MakeShape::cleanNewShapes( + GeomShapePtr theWholeOld, const int theShapeType) +{ + if (myModifHist) { + MapModified* aModified = (MapModified*)myModifHist; + if (aModified->IsBound(theShapeType)) { + aModified->UnBind(theShapeType); + } + } + if (myHist) { + HistoryMap* aHist = (HistoryMap*)myHist; + if (aHist->IsBound(theShapeType)) { + if (aHist->Find(theShapeType).IsBound(theWholeOld->impl())) { + aHist->ChangeFind(theShapeType).UnBind(theWholeOld->impl()); + } + } } } diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.h b/src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.h index cf844349a..7acd2291a 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.h +++ b/src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.h @@ -93,12 +93,21 @@ public: GEOMALGOAPI_EXPORT virtual void generated(const GeomShapePtr theOldShape, ListOfShape& theNewShapes); - /// \return the list of shapes modified from the shape \a theShape. + /// Get a list of new shapes, modified from the given old shape. + /// \return the list of shapes modified from the shape \a theOldShape. /// \param[in] theOldShape base shape. - /// \param[out] theNewShapes shapes modified from \a theShape. Does not cleared! + /// \param[out] theNewShapes shapes modified from \a theOldShape. Does not cleared! GEOMALGOAPI_EXPORT virtual void modified(const GeomShapePtr theOldShape, ListOfShape& theNewShapes); + /// Get a list of new shapes, modified from the given old shape. + /// Works correctly only in case if the modifications are cached. Check this with isNewShapesCollected(). + /// \return the list of shapes modified from the shape \a theOldShape. + /// \param[in] theOldShape base shape. + /// \param[out] theNewShapes shapes modified from \a theOldShape. Does not cleared! + GEOMALGOAPI_EXPORT void modifiedCached(const GeomShapePtr theOldShape, + ListOfShape& theNewShapes); + /// \return true if theShape was deleted. /// \param[in] theOldShape base shape. GEOMALGOAPI_EXPORT virtual bool isDeleted(const GeomShapePtr theOldShape); @@ -134,6 +143,12 @@ public: GEOMALGOAPI_EXPORT void collectNewShapes(GeomShapePtr theWholeOld, const int theShapeType); + /// Clean cached data, created by collectNewShapes() method, called with the same arguments. + /// \param theWholeOld the whole old shape + /// \param theShapeType type of the sub-shapes that is used for optimization + GEOMALGOAPI_EXPORT void cleanNewShapes(GeomShapePtr theWholeOld, + const int theShapeType); + /// Optimization of access the new shapes by old shapes for the limited set of needed new shapes. /// \param theWholeOld the whole old shape /// \param theNewShape the whole new shape @@ -182,6 +197,10 @@ private: /// map that is used to keep the optimization structure for access to the history /// kind of sub-shapes -> whole old shape -> new shape -> list of old shapes that create this new void* myHist; + + /// map that is used to keep the optimization structure for access to the history + /// kind of sub-shapes -> old shape -> list of new shapes modified from this old shape + void* myModifHist; }; typedef std::shared_ptr GeomMakeShapePtr; diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_MakeShapeSet.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_MakeShapeSet.cpp index d0a2f4555..cce4b1afb 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_MakeShapeSet.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_MakeShapeSet.cpp @@ -65,7 +65,6 @@ void GeomAlgoAPI_MakeShapeSet::modified(const GeomShapePtr theOldShape, ++aBuilderIt) { GeomMakeShapePtr aMakeShape = *aBuilderIt; - ListOfShape aModifiedShapes; aMakeShape->modified(theOldShape, theNewShapes); } } diff --git a/src/Model/Model_BodyBuilder.cpp b/src/Model/Model_BodyBuilder.cpp index d397d0a9b..9a9fc1454 100644 --- a/src/Model/Model_BodyBuilder.cpp +++ b/src/Model/Model_BodyBuilder.cpp @@ -626,7 +626,8 @@ void Model_BodyBuilder::loadModifiedShapes(const GeomMakeShapePtr& theAlgo, { GeomShapePtr aResultShape = shape(); GeomShapePtr aShapeToExplore = theOldShape; - if (theAlgo->isNewShapesCollected(theOldShape, theShapeTypeToExplore)) { + bool isAlgoHistoryCollected = theAlgo->isNewShapesCollected(theOldShape, theShapeTypeToExplore); + if (isAlgoHistoryCollected) { // use optimized set of old shapes for this GeomShapePtr aCompound = theAlgo->oldShapesForNew(theOldShape, aResultShape, @@ -664,7 +665,12 @@ void Model_BodyBuilder::loadModifiedShapes(const GeomMakeShapePtr& theAlgo, // Get new shapes. ListOfShape aNewShapes; - theAlgo->modified(anOldSubShape, aNewShapes); + if (isAlgoHistoryCollected) { + theAlgo->modifiedCached(anOldSubShape, aNewShapes); + } + else { + theAlgo->modified(anOldSubShape, aNewShapes); + } for (ListOfShape::const_iterator aNewShapesIt = aNewShapes.cbegin(); aNewShapesIt != aNewShapes.cend(); ++aNewShapesIt) diff --git a/src/Model/Model_ResultBody.cpp b/src/Model/Model_ResultBody.cpp index 5b2d769ee..f6bc7d31a 100644 --- a/src/Model/Model_ResultBody.cpp +++ b/src/Model/Model_ResultBody.cpp @@ -112,12 +112,18 @@ void Model_ResultBody::loadModifiedShapes(const std::shared_ptrisNewShapesCollected(theOldShape, theShapeTypeToExplore)) + bool isJustCollectedNS = false; + if (!theAlgo->isNewShapesCollected(theOldShape, theShapeTypeToExplore)) { theAlgo->collectNewShapes(theOldShape, theShapeTypeToExplore); + isJustCollectedNS = true; + } std::vector::const_iterator aSubIter = mySubs.cbegin(); for(; aSubIter != mySubs.cend(); aSubIter++) { (*aSubIter)->loadModifiedShapes(theAlgo, theOldShape, theShapeTypeToExplore, theName); } + if (isJustCollectedNS) { + theAlgo->cleanNewShapes(theOldShape, theShapeTypeToExplore); + } } else { // do for this directly myBuilder->loadModifiedShapes(theAlgo, theOldShape, theShapeTypeToExplore, theName); } -- 2.39.2