Salome HOME
[bos #38360] [CEA] improve performances of exportXAO and PublishToStudy jfa/38360_performance 45/head
authorjfa <jfa@opencascade.com>
Mon, 12 Feb 2024 14:01:23 +0000 (14:01 +0000)
committerjfa <jfa@opencascade.com>
Mon, 12 Feb 2024 14:01:23 +0000 (14:01 +0000)
src/ConnectorPlugin/ConnectorPlugin_PublishToStudyFeature.py
src/ExchangePlugin/ExchangePlugin_ExportFeature.cpp
src/GeomAPI/CMakeLists.txt
src/GeomAPI/GeomAPI.i
src/GeomAPI/GeomAPI_IndexedMapOfShape.cpp [new file with mode: 0644]
src/GeomAPI/GeomAPI_IndexedMapOfShape.h [new file with mode: 0644]
src/GeomAPI/GeomAPI_swig.h
src/GeomAlgoAPI/GeomAlgoAPI_CompoundBuilder.cpp
src/GeomAlgoAPI/GeomAlgoAPI_CompoundBuilder.h
src/XGUI/XGUI_Tools.cpp

index 4933bd05dac0dfe33cfb9405dfae86902838dc80..c1dc8749e1be24b7d281eae1670f9348452d0811 100644 (file)
@@ -169,11 +169,12 @@ class PublishToStudyFeature(ModelAPI.ModelAPI_Feature):
       else:
         allRefGroups.append(ModelAPI.referencedFeatures(theRes, "Group", True))
         allRefGroups.append(ModelAPI.referencedFeatures(theRes, "Shared_faces", True))
+      aResShape = theRes.shape()
+      aMapOfShape = GeomAPI_IndexedMapOfShape(aResShape)
       for aRefGroups in allRefGroups:
         for aRef in aRefGroups:
           aGroupIndices = []
           aGroupHasIndex = {}
-          aResShape = theRes.shape()
           if theFields:
             aSelList = aRef.selectionList("selected")
           else:
@@ -183,7 +184,7 @@ class PublishToStudyFeature(ModelAPI.ModelAPI_Feature):
             aShape = aGroupRes.shape()
             anExplorer = GeomAPI_ShapeExplorer(aShape, aSelType)
             while anExplorer.more():
-              anId = GeomAlgoAPI.GeomAlgoAPI_CompoundBuilder.id(aResShape, anExplorer.current())
+              anId = aMapOfShape.FindIndexEqualLocations(anExplorer.current())
               if anId > 0 and not anId in aGroupHasIndex:
                 aGroupIndices.append(anId)
                 aGroupHasIndex[anId] = 0
index 33bba9b1c4e669347391cc7464f837dd4d35fb67..3924fb73376db6af1bb9c53a4f193fc5a8c5b807 100644 (file)
@@ -38,6 +38,7 @@
 #include <GeomAlgoAPI_Tools.h>
 #include <GeomAlgoAPI_XAOExport.h>
 
+#include <GeomAPI_IndexedMapOfShape.h>
 #include <GeomAPI_Shape.h>
 #include <GeomAPI_ShapeExplorer.h>
 #include <GeomAPI_Trsf.h>
@@ -426,6 +427,10 @@ void ExchangePlugin_ExportFeature::exportXAO(const std::string& theFileName,
 
   std::set<ResultPtr> allResultsCashed; // cash to speed up searching in all results selected
 
+  // [bos #38360] [CEA] improve performances of exportXAO and PublishToStudy
+  GeomAPI_IndexedMapOfShape aSubShapesMap;
+  bool isSubShapesMap = false; // we will init it only if required (for performance reason)
+
   // iterate all documents used
   if (aDocuments.empty())
     aDocuments.push_back(document());
@@ -464,7 +469,12 @@ void ExchangePlugin_ExportFeature::exportXAO(const std::string& theFileName,
           GeomShapePtr aGroupShape = aGroupResExplorer.current();
           if (aDocTrsf.find(*aDoc) != aDocTrsf.end())
             aGroupShape->move(aDocTrsf[*aDoc]);
-          int aReferenceID = GeomAlgoAPI_CompoundBuilder::id(aShape, aGroupShape);
+
+          if (!isSubShapesMap) {
+            aSubShapesMap.MapShapes(aShape);
+            isSubShapesMap = true;
+          }
+          int aReferenceID = aSubShapesMap.FindIndexEqualLocations(aGroupShape);
           if (aReferenceID == 0) // selected value does not found in the exported shape
             continue;
           std::string aReferenceString = XAO::XaoUtils::intToString(aReferenceID);
@@ -540,7 +550,11 @@ void ExchangePlugin_ExportFeature::exportXAO(const std::string& theFileName,
               if (!isWholePart) {
                 // element index actually is the ID of the selection
                 AttributeSelectionPtr aSel = aSelectionList->value(aRow - 1);
-                int aReferenceID = GeomAlgoAPI_CompoundBuilder::id(aShape, aSel->value());
+                if (!isSubShapesMap) {
+                  aSubShapesMap.MapShapes(aShape);
+                  isSubShapesMap = true;
+                }
+                int aReferenceID = aSubShapesMap.FindIndexEqualLocations(aSel->value());
                 if (aReferenceID == 0) // selected value does not found in the exported shape
                   continue;
 
index ec892a755cf6563ec8765d4a54ad63d85a26dd34..20168aab632035aa96a53c5bccaee13af446b345 100644 (file)
@@ -50,6 +50,7 @@ SET(PROJECT_HEADERS
     GeomAPI_Curve.h
     GeomAPI_DataMapOfShapeMapOfShapes.h
     GeomAPI_DataMapOfShapeShape.h
+    GeomAPI_IndexedMapOfShape.h
     GeomAPI_ICustomPrs.h
     GeomAPI_Vertex.h
     GeomAPI_Ax1.h
@@ -98,6 +99,7 @@ SET(PROJECT_SOURCES
     GeomAPI_Curve.cpp
     GeomAPI_DataMapOfShapeMapOfShapes.cpp
     GeomAPI_DataMapOfShapeShape.cpp
+    GeomAPI_IndexedMapOfShape.cpp
     GeomAPI_Vertex.cpp
     GeomAPI_ICustomPrs.cpp
     GeomAPI_Ax1.cpp
index b01c33325a050510eb0fc0badf10ed95da26a77a..1ee5c3faabdc86a066a25a6a9a5f32bf39a0c0a6 100644 (file)
@@ -51,6 +51,7 @@
 %shared_ptr(GeomAPI_Cylinder)
 %shared_ptr(GeomAPI_DataMapOfShapeMapOfShapes)
 %shared_ptr(GeomAPI_DataMapOfShapeShape)
+%shared_ptr(GeomAPI_IndexedMapOfShape)
 %shared_ptr(GeomAPI_Dir)
 %shared_ptr(GeomAPI_Dir2d)
 %shared_ptr(GeomAPI_Edge)
@@ -138,6 +139,7 @@ template<class T1, class T2> std::shared_ptr<T1> shared_ptr_cast(std::shared_ptr
 %include "GeomAPI_Cylinder.h"
 %include "GeomAPI_DataMapOfShapeMapOfShapes.h"
 %include "GeomAPI_DataMapOfShapeShape.h"
+%include "GeomAPI_IndexedMapOfShape.h"
 %include "GeomAPI_Dir.h"
 %include "GeomAPI_Dir2d.h"
 %include "GeomAPI_Edge.h"
diff --git a/src/GeomAPI/GeomAPI_IndexedMapOfShape.cpp b/src/GeomAPI/GeomAPI_IndexedMapOfShape.cpp
new file mode 100644 (file)
index 0000000..5ea5293
--- /dev/null
@@ -0,0 +1,96 @@
+// Copyright (C) 2014-2024  CEA, EDF
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include <GeomAPI_IndexedMapOfShape.h>
+
+#include <gp_Trsf.hxx>
+#include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopLoc_Location.hxx>
+#include <TopoDS_Shape.hxx>
+#include <TopTools_IndexedMapOfShape.hxx>
+
+GeomAPI_IndexedMapOfShape::GeomAPI_IndexedMapOfShape(const std::shared_ptr<GeomAPI_Shape> theMainShape)
+{
+  MapShapes(theMainShape);
+}
+
+void GeomAPI_IndexedMapOfShape::MapShapes(const std::shared_ptr<GeomAPI_Shape> theMainShape)
+{
+  if (!empty()) {
+    implPtr<TopTools_IndexedMapOfShape>()->Clear();
+  }
+
+  TopoDS_Shape aMainShape = theMainShape->impl<TopoDS_Shape>();
+  if (!aMainShape.IsNull()) {
+    TopTools_IndexedMapOfShape aSubShapesMap;
+    TopExp::MapShapes(aMainShape, aSubShapesMap);
+
+    setImpl(new TopTools_IndexedMapOfShape(aSubShapesMap));
+  }
+}
+
+int GeomAPI_IndexedMapOfShape::FindIndex(std::shared_ptr<GeomAPI_Shape> theKey)
+{
+  return impl<TopTools_IndexedMapOfShape>().FindIndex(theKey->impl<TopoDS_Shape>());
+}
+
+// Returns true if transformations are equal with the given precision
+static bool isEqual(const gp_Trsf& theT1, const gp_Trsf& theT2, const double thePrecision)
+{
+  for(int aRow = 1; aRow < 4; aRow++) {
+    for(int aCol = 1; aCol < 5; aCol++) {
+      double aDiff = theT1.Value(aRow, aCol) - theT2.Value(aRow, aCol);
+      if (aDiff < 0) aDiff = -aDiff;
+      if (aDiff > thePrecision)
+        return false;
+    }
+  }
+  return true;
+}
+
+int GeomAPI_IndexedMapOfShape::FindIndexEqualLocations(std::shared_ptr<GeomAPI_Shape> theKey)
+{
+  int anID = impl<TopTools_IndexedMapOfShape>().FindIndex(theKey->impl<TopoDS_Shape>());
+  if (anID == 0) {
+    // Try to search shape with the same location if TopLoc_Location is different.
+    // It's a special fix for the problem related to the Placement of parts
+    // feature - it adds additional transformation to all results and groups.
+    const TopoDS_Shape& aMainShape = impl<TopTools_IndexedMapOfShape>().FindKey(1);
+    const TopoDS_Shape& aSubShape = theKey->impl<TopoDS_Shape>();
+    TopExp_Explorer anExp (aMainShape, aSubShape.ShapeType());
+    for (; anExp.More(); anExp.Next()) {
+      if (anExp.Current().TShape() == aSubShape.TShape()) {
+        const TopLoc_Location aLoc1 = anExp.Current().Location();
+        if (isEqual(aLoc1.Transformation(), aSubShape.Location().Transformation(), 1.e-7)) {
+          anID = impl<TopTools_IndexedMapOfShape>().FindIndex(anExp.Current());
+          break;
+        }
+      }
+    }
+  }
+  return anID;
+}
+
+GeomAPI_IndexedMapOfShape::~GeomAPI_IndexedMapOfShape()
+{
+  if (!empty()) {
+    implPtr<TopTools_IndexedMapOfShape>()->Clear();
+  }
+}
diff --git a/src/GeomAPI/GeomAPI_IndexedMapOfShape.h b/src/GeomAPI/GeomAPI_IndexedMapOfShape.h
new file mode 100644 (file)
index 0000000..b9f9e57
--- /dev/null
@@ -0,0 +1,60 @@
+// Copyright (C) 2014-2024  CEA, EDF
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef GeomAPI_IndexedMapOfShape_H_
+#define GeomAPI_IndexedMapOfShape_H_
+
+#include <GeomAPI_Interface.h>
+#include <GeomAPI_Shape.h>
+
+/**\class GeomAPI_IndexedMapOfShape
+ * \ingroup DataModel
+ * \brief IndexedMap of Shape defined by TopoDS_Shape
+ */
+class GeomAPI_IndexedMapOfShape : public GeomAPI_Interface
+{
+ public:
+  /// Constructor.
+  GEOMAPI_EXPORT
+  GeomAPI_IndexedMapOfShape() {};
+
+  /// Constructor.
+  GEOMAPI_EXPORT
+  GeomAPI_IndexedMapOfShape(const std::shared_ptr<GeomAPI_Shape> theMainShape);
+
+  /// Initialize the Map.
+  GEOMAPI_EXPORT
+  void MapShapes(const std::shared_ptr<GeomAPI_Shape> theMainShape);
+
+  /// \return index of the Key in the Map.
+  GEOMAPI_EXPORT
+  int FindIndex(const std::shared_ptr<GeomAPI_Shape> theKey);
+
+  /// \return index of the Key in the Map.
+  /// It works also for the case of equal locations
+  GEOMAPI_EXPORT
+  int FindIndexEqualLocations(const std::shared_ptr<GeomAPI_Shape> theKey);
+
+  /// Destructor
+  GEOMAPI_EXPORT
+  ~GeomAPI_IndexedMapOfShape();
+};
+
+#endif
+
index 1d0de85c341866ac470ae013c72f62e3460b032a..d0b06f300c6f0bca8dbea5313071c9f8f5764cc3 100644 (file)
@@ -37,6 +37,7 @@
   #include "GeomAPI_Cylinder.h"
   #include "GeomAPI_DataMapOfShapeMapOfShapes.h"
   #include "GeomAPI_DataMapOfShapeShape.h"
+  #include "GeomAPI_IndexedMapOfShape.h"
   #include "GeomAPI_Dir.h"
   #include "GeomAPI_Dir2d.h"
   #include "GeomAPI_Edge.h"
index aa654d8882eb783a3bd8129a36ee734056955cea..2eaf19f1906bbeeb6b189b6411fd187abb0587ed 100644 (file)
@@ -41,44 +41,3 @@ std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_CompoundBuilder::compound(
   aRes->setImpl(new TopoDS_Shape(aComp));
   return aRes;
 }
-
-// Returns true if transformations are equal with the given precision
-static bool isEqual(const gp_Trsf& theT1, const gp_Trsf& theT2, const double thePrecision)
-{
-  for(int aRow = 1; aRow < 4; aRow++) {
-    for(int aCol = 1; aCol < 5; aCol++) {
-      double aDiff = theT1.Value(aRow, aCol) - theT2.Value(aRow, aCol);
-      if (aDiff < 0) aDiff = -aDiff;
-      if (aDiff > thePrecision)
-        return false;
-    }
-  }
-  return true;
-}
-
-int GeomAlgoAPI_CompoundBuilder::id(
-      std::shared_ptr<GeomAPI_Shape> theContext, std::shared_ptr<GeomAPI_Shape> theSub)
-{
-  int anID = 0;
-  TopoDS_Shape aMainShape = theContext->impl<TopoDS_Shape>();
-  const TopoDS_Shape& aSubShape = theSub->impl<TopoDS_Shape>();
-  if (!aMainShape.IsNull() && !aSubShape.IsNull()) {
-    TopTools_IndexedMapOfShape aSubShapesMap;
-    TopExp::MapShapes(aMainShape, aSubShapesMap);
-    anID = aSubShapesMap.FindIndex(aSubShape);
-    if (anID == 0) { // try to search shape with the same location if TopLoc_Location is different
-      TopExp_Explorer anExp(aMainShape, aSubShape.ShapeType());
-      for(; anExp.More(); anExp.Next()) {
-        if (anExp.Current().TShape() == aSubShape.TShape()) {
-          const TopLoc_Location aLoc1 = anExp.Current().Location();
-          if (isEqual(aLoc1.Transformation(), aSubShape.Location().Transformation(), 1.e-7)) {
-            anID = aSubShapesMap.FindIndex(anExp.Current());
-            break;
-          }
-        }
-      }
-    }
-  }
-
-  return anID;
-}
index 66081ef389fb6631f5e147ade38ef1c9f60330e3..013efb74cb03b88cb5dbadd69e2cd2434aac7106 100644 (file)
@@ -40,12 +40,6 @@ class GEOMALGOAPI_EXPORT GeomAlgoAPI_CompoundBuilder
   /// \param theShapes a list of shapes
   static std::shared_ptr<GeomAPI_Shape> compound(
       std::list<std::shared_ptr<GeomAPI_Shape> > theShapes);
-
-  /// Produces the integerr identifier of the shape theSub in theContext (needed for
-  /// groups export to old GEOM)
-  /// \returns zero if theSub not found in theContext
-  static int id(
-      std::shared_ptr<GeomAPI_Shape> theContext, std::shared_ptr<GeomAPI_Shape> theSub);
 };
 
 #endif
index 5976ae4c3998ba3d5407c115d821a5dc07d3951c..0b1d37a6433ca1c706d03c550628a4b3d0dd4ca4 100644 (file)
@@ -40,7 +40,7 @@
 #include <Events_InfoMessage.h>
 
 #include <GeomAPI_Shape.h>
-#include <GeomAlgoAPI_CompoundBuilder.h>
+#include <GeomAPI_IndexedMapOfShape.h>
 
 #include <TopoDS_Shape.hxx>
 
@@ -300,7 +300,8 @@ QString generateName(const ModuleBase_ViewerPrsPtr& thePrs)
           aTypeName = "shape";
           break;
         }
-        int aId = GeomAlgoAPI_CompoundBuilder::id(aContext, aSubShape);
+        GeomAPI_IndexedMapOfShape aSubShapesMap (aContext);
+        int aId = aSubShapesMap.FindIndexEqualLocations(aSubShape);
         aName += QString("/%1_%2").arg(aTypeName).arg(aId);
       }
     }