]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
[bos #38090] [CEA] improve loadModifiedShapes deal with thousands of faces faster jfa/38090_loadModifiedShapes_performance 50/head
authorjfa <jfa@opencascade.com>
Wed, 6 Mar 2024 13:36:40 +0000 (13:36 +0000)
committerjfa <jfa@opencascade.com>
Fri, 3 May 2024 10:51:33 +0000 (11:51 +0100)
src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.cpp
src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.h
src/GeomAlgoAPI/GeomAlgoAPI_MakeShapeSet.cpp
src/Model/Model_BodyBuilder.cpp
src/Model/Model_ResultBody.cpp

index 534afd0a95c900d0833c2efd66b443639873fd04..1206dd3ee5cb8ce5a4c177568a055b0545588638 100644 (file)
@@ -42,6 +42,9 @@ typedef NCollection_DataMap<TopoDS_Shape,
 typedef
   NCollection_DataMap<int, NCollection_DataMap<TopoDS_Shape, MapNewToOld, TopTools_ShapeMapHasher> >
   HistoryMap;
+typedef
+  NCollection_DataMap<int, NCollection_DataMap<TopoDS_Shape, ListOfShape, TopTools_ShapeMapHasher> >
+  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<BRepBuilderAPI_MakeShape>();
     try {
       aList = aMakeShape->Modified(theOldShape->impl<TopoDS_Shape>());
-    } catch(Standard_NoSuchObject) {
+    } catch(Standard_NoSuchObject const&) {
     }
   } else if(myBuilderType == OCCT_BOPAlgo_Builder) {
     BOPAlgo_Builder* aBOPBuilder = implPtr<BOPAlgo_Builder>();
@@ -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<TopoDS_Shape>().ShapeType();
+    if (aModified->IsBound(aShapeType)) {
+      const NCollection_DataMap<TopoDS_Shape, ListOfShape, TopTools_ShapeMapHasher>& aM =
+        aModified->Find(aShapeType);
+      if (aM.IsBound(theOldShape->impl<TopoDS_Shape>())) {
+        theNewShapes = aM.Find(theOldShape->impl<TopoDS_Shape>());
+      }
+    }
+  }
+}
+
 //==================================================================================================
 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<TopoDS_Shape, ListOfShape, TopTools_ShapeMapHasher>());
+  NCollection_DataMap<TopoDS_Shape, ListOfShape, TopTools_ShapeMapHasher>& 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<TopoDS_Shape>(), anIndexInWholeOld);
     }
+    aM.Bind(anExp.current()->impl<TopoDS_Shape>(), 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<TopoDS_Shape>())) {
+        aHist->ChangeFind(theShapeType).UnBind(theWholeOld->impl<TopoDS_Shape>());
+      }
+    }
   }
 }
 
index cf844349a18d151f14d3b38ce8c3f4a7b5a818f7..7acd2291a925dc869fd94a18fcf6b86688597d1b 100644 (file)
@@ -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<GeomAlgoAPI_MakeShape> GeomMakeShapePtr;
index d0a2f4555ce396b854f2786327bb36cfda3f8e64..cce4b1afbf6ee224cdfd804af9a0cc6f62a30b73 100644 (file)
@@ -65,7 +65,6 @@ void GeomAlgoAPI_MakeShapeSet::modified(const GeomShapePtr theOldShape,
       ++aBuilderIt)
   {
     GeomMakeShapePtr aMakeShape = *aBuilderIt;
-    ListOfShape aModifiedShapes;
     aMakeShape->modified(theOldShape, theNewShapes);
   }
 }
index d397d0a9b3f4176d8a862af9d6d89d1b81a4c46e..9a9fc1454bc590d2d3dafc32b93fd038a2a93fab 100644 (file)
@@ -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)
index 5b2d769ee48aceb7cd418a6ed1bab964f53b13cd..f6bc7d31a6154e3a4064b34baa34b5b867300c22 100644 (file)
@@ -112,12 +112,18 @@ void Model_ResultBody::loadModifiedShapes(const std::shared_ptr<GeomAlgoAPI_Make
 {
   if (mySubs.size()) { // consists of subs
     // optimization of getting of new shapes for specific sub-result
-    if (!theAlgo->isNewShapesCollected(theOldShape, theShapeTypeToExplore))
+    bool isJustCollectedNS = false;
+    if (!theAlgo->isNewShapesCollected(theOldShape, theShapeTypeToExplore)) {
       theAlgo->collectNewShapes(theOldShape, theShapeTypeToExplore);
+      isJustCollectedNS = true;
+    }
     std::vector<ResultBodyPtr>::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);
   }