From 3692e4ddfe1d709b235b6f1a8b96218ead1a45c5 Mon Sep 17 00:00:00 2001 From: jfa Date: Mon, 12 Feb 2024 14:01:23 +0000 Subject: [PATCH] [bos #38360] [CEA] improve performances of exportXAO and PublishToStudy --- .../ConnectorPlugin_PublishToStudyFeature.py | 5 +- .../ExchangePlugin_ExportFeature.cpp | 18 +++- src/GeomAPI/CMakeLists.txt | 2 + src/GeomAPI/GeomAPI.i | 2 + src/GeomAPI/GeomAPI_IndexedMapOfShape.cpp | 96 +++++++++++++++++++ src/GeomAPI/GeomAPI_IndexedMapOfShape.h | 60 ++++++++++++ src/GeomAPI/GeomAPI_swig.h | 1 + .../GeomAlgoAPI_CompoundBuilder.cpp | 41 -------- src/GeomAlgoAPI/GeomAlgoAPI_CompoundBuilder.h | 6 -- src/XGUI/XGUI_Tools.cpp | 5 +- 10 files changed, 183 insertions(+), 53 deletions(-) create mode 100644 src/GeomAPI/GeomAPI_IndexedMapOfShape.cpp create mode 100644 src/GeomAPI/GeomAPI_IndexedMapOfShape.h diff --git a/src/ConnectorPlugin/ConnectorPlugin_PublishToStudyFeature.py b/src/ConnectorPlugin/ConnectorPlugin_PublishToStudyFeature.py index 4933bd05d..c1dc8749e 100644 --- a/src/ConnectorPlugin/ConnectorPlugin_PublishToStudyFeature.py +++ b/src/ConnectorPlugin/ConnectorPlugin_PublishToStudyFeature.py @@ -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 diff --git a/src/ExchangePlugin/ExchangePlugin_ExportFeature.cpp b/src/ExchangePlugin/ExchangePlugin_ExportFeature.cpp index 33bba9b1c..3924fb733 100644 --- a/src/ExchangePlugin/ExchangePlugin_ExportFeature.cpp +++ b/src/ExchangePlugin/ExchangePlugin_ExportFeature.cpp @@ -38,6 +38,7 @@ #include #include +#include #include #include #include @@ -426,6 +427,10 @@ void ExchangePlugin_ExportFeature::exportXAO(const std::string& theFileName, std::set 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; diff --git a/src/GeomAPI/CMakeLists.txt b/src/GeomAPI/CMakeLists.txt index ec892a755..20168aab6 100644 --- a/src/GeomAPI/CMakeLists.txt +++ b/src/GeomAPI/CMakeLists.txt @@ -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 diff --git a/src/GeomAPI/GeomAPI.i b/src/GeomAPI/GeomAPI.i index b01c33325..1ee5c3faa 100644 --- a/src/GeomAPI/GeomAPI.i +++ b/src/GeomAPI/GeomAPI.i @@ -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 std::shared_ptr 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 index 000000000..5ea5293dc --- /dev/null +++ b/src/GeomAPI/GeomAPI_IndexedMapOfShape.cpp @@ -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 + +#include +#include +#include +#include +#include +#include + +GeomAPI_IndexedMapOfShape::GeomAPI_IndexedMapOfShape(const std::shared_ptr theMainShape) +{ + MapShapes(theMainShape); +} + +void GeomAPI_IndexedMapOfShape::MapShapes(const std::shared_ptr theMainShape) +{ + if (!empty()) { + implPtr()->Clear(); + } + + TopoDS_Shape aMainShape = theMainShape->impl(); + if (!aMainShape.IsNull()) { + TopTools_IndexedMapOfShape aSubShapesMap; + TopExp::MapShapes(aMainShape, aSubShapesMap); + + setImpl(new TopTools_IndexedMapOfShape(aSubShapesMap)); + } +} + +int GeomAPI_IndexedMapOfShape::FindIndex(std::shared_ptr theKey) +{ + return impl().FindIndex(theKey->impl()); +} + +// 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 theKey) +{ + int anID = impl().FindIndex(theKey->impl()); + 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().FindKey(1); + const TopoDS_Shape& aSubShape = theKey->impl(); + 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().FindIndex(anExp.Current()); + break; + } + } + } + } + return anID; +} + +GeomAPI_IndexedMapOfShape::~GeomAPI_IndexedMapOfShape() +{ + if (!empty()) { + implPtr()->Clear(); + } +} diff --git a/src/GeomAPI/GeomAPI_IndexedMapOfShape.h b/src/GeomAPI/GeomAPI_IndexedMapOfShape.h new file mode 100644 index 000000000..b9f9e57e8 --- /dev/null +++ b/src/GeomAPI/GeomAPI_IndexedMapOfShape.h @@ -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 +#include + +/**\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 theMainShape); + + /// Initialize the Map. + GEOMAPI_EXPORT + void MapShapes(const std::shared_ptr theMainShape); + + /// \return index of the Key in the Map. + GEOMAPI_EXPORT + int FindIndex(const std::shared_ptr 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 theKey); + + /// Destructor + GEOMAPI_EXPORT + ~GeomAPI_IndexedMapOfShape(); +}; + +#endif + diff --git a/src/GeomAPI/GeomAPI_swig.h b/src/GeomAPI/GeomAPI_swig.h index 1d0de85c3..d0b06f300 100644 --- a/src/GeomAPI/GeomAPI_swig.h +++ b/src/GeomAPI/GeomAPI_swig.h @@ -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" diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_CompoundBuilder.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_CompoundBuilder.cpp index aa654d888..2eaf19f19 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_CompoundBuilder.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_CompoundBuilder.cpp @@ -41,44 +41,3 @@ std::shared_ptr 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 theContext, std::shared_ptr theSub) -{ - int anID = 0; - TopoDS_Shape aMainShape = theContext->impl(); - const TopoDS_Shape& aSubShape = theSub->impl(); - 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; -} diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_CompoundBuilder.h b/src/GeomAlgoAPI/GeomAlgoAPI_CompoundBuilder.h index 66081ef38..013efb74c 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_CompoundBuilder.h +++ b/src/GeomAlgoAPI/GeomAlgoAPI_CompoundBuilder.h @@ -40,12 +40,6 @@ class GEOMALGOAPI_EXPORT GeomAlgoAPI_CompoundBuilder /// \param theShapes a list of shapes static std::shared_ptr compound( std::list > 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 theContext, std::shared_ptr theSub); }; #endif diff --git a/src/XGUI/XGUI_Tools.cpp b/src/XGUI/XGUI_Tools.cpp index 5976ae4c3..0b1d37a64 100644 --- a/src/XGUI/XGUI_Tools.cpp +++ b/src/XGUI/XGUI_Tools.cpp @@ -40,7 +40,7 @@ #include #include -#include +#include #include @@ -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); } } -- 2.39.2