]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Optimization for the model from the issue #2659 :
authormpv <mpv@opencascade.com>
Tue, 2 Oct 2018 13:43:16 +0000 (16:43 +0300)
committermpv <mpv@opencascade.com>
Tue, 2 Oct 2018 13:43:40 +0000 (16:43 +0300)
- cash history information for big amount of sub-shapes
- use direct method of result parent checking instead of iteration of all results in hasObjects
- remove checking of self-intersection: too slow for big models

src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.cpp
src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.h
src/GeomValidators/GeomValidators_NotSelfIntersected.cpp
src/Model/Model_ResultBody.cpp
src/ModuleBase/ModuleBase_OperationFeature.cpp

index 916feb8142afc338f158f68bd5578f0daecab1c2..6ed3adf8e21d25821bbb702c697d84204216a1f6 100644 (file)
 #include <TopTools_ListOfShape.hxx>
 #include <TopTools_ListIteratorOfListOfShape.hxx>
 #include <GeomAPI_ShapeExplorer.h>
+#include <GeomAPI_ShapeIterator.h>
+#include <TopoDS_Builder.hxx>
+
+// new shape -> old shapes -> index in the old shape
+typedef NCollection_DataMap<TopoDS_Shape,
+  NCollection_DataMap<TopoDS_Shape, int, TopTools_ShapeMapHasher>, TopTools_ShapeMapHasher>
+  MapNewToOld;
+typedef
+  NCollection_DataMap<int, NCollection_DataMap<TopoDS_Shape, MapNewToOld, TopTools_ShapeMapHasher> >
+  HistoryMap;
 
 //=================================================================================================
 GeomAlgoAPI_MakeShape::GeomAlgoAPI_MakeShape()
 : myBuilderType(Unknown),
   myDone(false)
 {
+  myHist = 0;
+}
+
+GeomAlgoAPI_MakeShape::~GeomAlgoAPI_MakeShape() {
+  if (myHist) {
+    delete (HistoryMap*)myHist;
+  }
 }
 
 //=================================================================================================
@@ -220,6 +237,7 @@ void GeomAlgoAPI_MakeShape::initialize() {
     aCurrentShape->setImpl(new TopoDS_Shape(anExp.Current()));
     myMap->bind(aCurrentShape, aCurrentShape);
   }
+  myHist = 0;
 }
 
 
@@ -260,3 +278,93 @@ bool GeomAlgoAPI_MakeShape::checkValid(std::string theMessage){
   return true ;
 }
 
+bool GeomAlgoAPI_MakeShape::newShapesCollected(
+  std::shared_ptr<GeomAPI_Shape> theWholeOld, const int theShapeType)
+{
+  if (!myHist)
+    return false;
+  HistoryMap* aHist = (HistoryMap*)myHist;
+  if (!aHist->IsBound(theShapeType))
+    return false;
+  return aHist->Find(theShapeType).IsBound(theWholeOld->impl<TopoDS_Shape>());
+}
+
+void GeomAlgoAPI_MakeShape::collectNewShapes(
+  std::shared_ptr<GeomAPI_Shape> theWholeOld, const int theShapeType)
+{
+  if (!myHist)
+    myHist = new HistoryMap;
+  HistoryMap* aHist = (HistoryMap*)myHist;
+  if (!aHist->IsBound(theShapeType))
+    aHist->Bind(
+      theShapeType, NCollection_DataMap<TopoDS_Shape, MapNewToOld, TopTools_ShapeMapHasher>());
+  aHist->ChangeFind(theShapeType). // add a new in anyway
+    Bind(theWholeOld->impl<TopoDS_Shape>(), MapNewToOld());
+  MapNewToOld& aCurrent =
+    aHist->ChangeFind(theShapeType).ChangeFind(theWholeOld->impl<TopoDS_Shape>());
+  ListOfShape aNewList;
+  TopTools_MapOfShape aViewed; //avoid same shapes
+  GeomAPI_ShapeExplorer anExp(theWholeOld, GeomAPI_Shape::ShapeType(theShapeType));
+  for(int anIndexInWholeOld = 0; anExp.more(); anExp.next(), anIndexInWholeOld++) {
+    if (!aViewed.Add(anExp.current()->impl<TopoDS_Shape>()))
+      continue;
+    aNewList.clear();
+    modified(anExp.current(), aNewList);
+    for(ListOfShape::iterator aNew = aNewList.begin(); aNew != aNewList.end(); aNew++) {
+      const TopoDS_Shape& aNewShape = (*aNew)->impl<TopoDS_Shape>();
+      if (!aCurrent.IsBound(aNewShape)) {
+        aCurrent.Bind(
+          aNewShape, NCollection_DataMap<TopoDS_Shape, int, TopTools_ShapeMapHasher>());
+      }
+      aCurrent.ChangeFind(aNewShape).Bind(anExp.current()->impl<TopoDS_Shape>(), anIndexInWholeOld);
+    }
+  }
+}
+
+static void addAllSubs(const TopoDS_Shape& theNewShape,
+  MapNewToOld& theCurrent, std::map<int, TopoDS_Shape>& theResMap)
+{
+  if (theCurrent.IsBound(theNewShape)) {
+    NCollection_DataMap<TopoDS_Shape, int, TopTools_ShapeMapHasher>::Iterator
+      anOldIter(theCurrent.Find(theNewShape));
+    for(; anOldIter.More(); anOldIter.Next()) {
+      theResMap[anOldIter.Value()] = anOldIter.Key();
+    }
+  }
+
+  TopoDS_Iterator anIter(theNewShape);
+  for(; anIter.More(); anIter.Next()) {
+    //if (anIter.Value().ShapeType() != TopAbs_VERTEX)
+    addAllSubs(anIter.Value(), theCurrent, theResMap); // add recursively
+  }
+}
+
+std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_MakeShape::oldShapesForNew(
+  std::shared_ptr<GeomAPI_Shape> theWholeOld,
+  std::shared_ptr<GeomAPI_Shape> theNewShape, const int theShapeType)
+{
+  GeomShapePtr aResult(new GeomAPI_Shape);
+  TopoDS_Compound aResComp;
+  TopoDS_Builder aBuilder;
+  aBuilder.MakeCompound(aResComp);
+  aResult->setImpl<TopoDS_Shape>(new TopoDS_Shape(aResComp));
+
+  HistoryMap* aHist = (HistoryMap*)myHist;
+  if (!aHist->IsBound(theShapeType))
+    return aResult; // not found, empty compound
+  const TopoDS_Shape& aWholeOld = theWholeOld->impl<TopoDS_Shape>();
+  if (!aHist->Find(theShapeType).IsBound(aWholeOld))
+    return aResult; // not found, empty compound
+  std::map<int, TopoDS_Shape> aResMap; // map with all results, ordered by index in whole old
+  MapNewToOld& aCurrent = aHist->ChangeFind(theShapeType).ChangeFind(aWholeOld);
+  // we don't know what type of new shapes were produced by the old theShapeType, so, iterate all
+  addAllSubs(theNewShape->impl<TopoDS_Shape>(), aCurrent, aResMap);
+
+  std::map<int, TopoDS_Shape>::iterator anOldIter = aResMap.begin();
+  for(; anOldIter != aResMap.end(); anOldIter++) {
+    if (anOldIter->second.ShapeType() == (TopAbs_ShapeEnum)theShapeType)
+      aBuilder.Add(aResComp, anOldIter->second);
+  }
+  aResult->setImpl<TopoDS_Shape>(new TopoDS_Shape(aResComp));
+  return aResult;
+}
index 6ed4f1d859425116d4bee21990fe318df4188ed1..eb2396c96736daaa37e0b95fa6fa5f49085228b2 100644 (file)
@@ -46,6 +46,9 @@ public:
   /// \brief Empty constructor.
   GEOMALGOAPI_EXPORT GeomAlgoAPI_MakeShape();
 
+  /// Destructor for remove myHist
+  GEOMALGOAPI_EXPORT ~GeomAlgoAPI_MakeShape();
+
   /// \brief Constructor by builder and builder type.
   /// \param[in] theBuilder pointer to the builder.
   /// \param[in] theBuilderType builder type.
@@ -115,6 +118,29 @@ public:
   /// \brief Check the validity of the produced shape.
   GEOMALGOAPI_EXPORT bool checkValid(std::string theMessage);
 
+  /// Optimization of access the new shapes by old shapes for the limited set of needed new shapes.
+  /// \param theWholeOld the whole old shape
+  /// \param theShapeType type of the sub-shapes that is used for optimization
+  /// \returns true if optimization containers are already filled
+  GEOMALGOAPI_EXPORT bool newShapesCollected(
+    std::shared_ptr<GeomAPI_Shape> 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 theShapeType type of the sub-shapes that is used for optimization
+  /// \returns true if optimization containers are already filled
+  GEOMALGOAPI_EXPORT void collectNewShapes(
+    std::shared_ptr<GeomAPI_Shape> 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
+  /// \param theShapeType type of the old sub-shapes
+  /// \returns compound of all old shapes that were used for creation of the given new
+  GEOMALGOAPI_EXPORT std::shared_ptr<GeomAPI_Shape> oldShapesForNew(
+    std::shared_ptr<GeomAPI_Shape> theWholeOld,
+    std::shared_ptr<GeomAPI_Shape> theNewShape, const int theShapeType);
+
 protected:
   /// \brief Sets builder type.
   /// \param[in] theBuilderType new builder type.
@@ -144,6 +170,10 @@ private:
   GeomAlgoAPI_MakeShape::BuilderType myBuilderType; ///< Type of make shape builder.
   bool myDone; ///< Builder status.
   std::shared_ptr<GeomAPI_Shape> myShape; ///< Resulting shape.
+
+  /// 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;
 };
 
 typedef std::list<std::shared_ptr<GeomAlgoAPI_MakeShape> > ListOfMakeShape;
index 7ab81f26c0cfa6f5526a731d4f683a48390e505f..aa017935d63ced7532dd32c0521f85cc9e0dde35 100644 (file)
@@ -74,10 +74,10 @@ bool GeomValidators_NotSelfIntersected::isValid(const std::shared_ptr<ModelAPI_F
           return false;
         }
 
-        if (aShape->isSelfIntersected(4)) {
+        /* optimization if (aShape->isSelfIntersected(4)) {
           theError = "Error: One of selected shapes are self-intersected.";
           return false;
-        }
+        }*/
       }
     } else {
       theError = std::string("Error: validator does not support attribute with type: ")
index 9b3401290035a5711ffe328a4c91bb532f270801..eaee3ac1e01df37a144fb4e18d3fde829dd745fa 100644 (file)
@@ -53,13 +53,16 @@ Model_ResultBody::~Model_ResultBody()
 }
 
 void Model_ResultBody::loadAndOrientModifiedShapes(GeomAlgoAPI_MakeShape* theMS,
-    std::shared_ptr<GeomAPI_Shape>  theShapeIn, const int  theKindOfShape, const int  theTag,
+    std::shared_ptr<GeomAPI_Shape> theShapeIn, const int  theKindOfShape, const int  theTag,
     const std::string& theName, GeomAPI_DataMapOfShapeShape& theSubShapes,
     const bool theIsStoreSeparate,
     const bool theIsStoreAsGenerated,
     const bool theSplitInSubs)
 {
   if (theSplitInSubs && mySubs.size()) { // consists of subs
+    // optimization of getting of new shapes for specific sub-result
+    if (!theMS->newShapesCollected(theShapeIn, theKindOfShape))
+      theMS->collectNewShapes(theShapeIn, theKindOfShape);
     std::vector<ResultBodyPtr>::const_iterator aSubIter = mySubs.cbegin();
     for(; aSubIter != mySubs.cend(); aSubIter++) {
       // check that sub-shape was also created as modification of ShapeIn
index b7b72a47b2c91ad85888612732fff36771c0dc44..04edf79576b5a8e6df3fc796d0b954c6b096f3a9 100755 (executable)
@@ -206,13 +206,9 @@ bool ModuleBase_OperationFeature::hasObject(ObjectPtr theObj) const
   if (aFeature) {
     if (aFeature == theObj)
       return true;
-    std::list<ResultPtr> aResults;
-    ModelAPI_Tools::allResults(aFeature, aResults);
-    std::list<ResultPtr>::const_iterator aIt;
-    for (aIt = aResults.cbegin(); aIt != aResults.cend(); ++aIt) {
-      ResultPtr aResult = *aIt;
-      if (theObj == aResult)
-         return true;
+    ResultPtr anObjRes = std::dynamic_pointer_cast<ModelAPI_Result>(theObj);
+    if (anObjRes.get() && aFeature == aFeature->document()->feature(anObjRes)) {
+      return true;
     }
 #ifdef DEBUG_DO_NOT_ACTIVATE_SUB_FEATURE
     if (aFeature->isMacro()) {