From 4a9dc0d21027467f5b6331017afd45504b293207 Mon Sep 17 00:00:00 2001 From: eap Date: Thu, 24 Feb 2022 18:36:53 +0300 Subject: [PATCH 1/3] bos #29143 [CEA] Compute takes too much time in polyhedron per solid use case --- src/SMESH/SMESH_Gen.cxx | 57 ++++++++++++++++++++++++++++++++++++++--- src/SMESH/SMESH_Gen.hxx | 1 + 2 files changed, 54 insertions(+), 4 deletions(-) diff --git a/src/SMESH/SMESH_Gen.cxx b/src/SMESH/SMESH_Gen.cxx index db4fe2136..06c47d8c0 100644 --- a/src/SMESH/SMESH_Gen.cxx +++ b/src/SMESH/SMESH_Gen.cxx @@ -39,11 +39,12 @@ #include "SMESH_MesherHelper.hxx" #include "SMESH_subMesh.hxx" -#include "utilities.h" -#include "Utils_ExceptHandlers.hxx" +#include +#include -#include +#include #include +#include #include "memoire.h" @@ -331,6 +332,32 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, else smWithAlgoSupportingSubmeshes[0].push_front( shDim2smIt->second ); + // gather sub-shapes with local uni-dimensional algos (bos #29143) + // ---------------------------------------------------------------- + TopTools_MapOfShape uniDimAlgoShapes; + ShapeToHypothesis::Iterator s2hyps( aMesh.GetMeshDS()->GetHypotheses() ); + for ( ; s2hyps.More(); s2hyps.Next() ) + { + const TopoDS_Shape& s = s2hyps.Key(); + if ( s.IsSame( aMesh.GetShapeToMesh() )) + continue; + for ( auto & hyp : s2hyps.Value() ) + { + if ( const SMESH_Algo* algo = dynamic_cast< const SMESH_Algo*>( hyp )) + if ( algo->NeedDiscreteBoundary() ) + { + TopAbs_ShapeEnum sType; + switch ( algo->GetDim() ) { + case 3: sType = TopAbs_SOLID; break; + case 2: sType = TopAbs_FACE; break; + default: sType = TopAbs_EDGE; break; + } + for ( TopExp_Explorer ex( s2hyps.Key(), sType ); ex.More(); ex.Next() ) + uniDimAlgoShapes.Add( ex.Current() ); + } + } + } + // ====================================================== // Apply all-dimensional algorithms supporing sub-meshes // ====================================================== @@ -374,9 +401,11 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, SMESH_subMesh* smToCompute = smIt->next(); const TopoDS_Shape& aSubShape = smToCompute->GetSubShape(); - const int aShapeDim = GetShapeDim( aSubShape ); + const int aShapeDim = GetShapeDim( aSubShape ); if ( aShapeDim < 1 || aSubShape.ShapeType() <= shapeType ) continue; + if ( !uniDimAlgoShapes.Contains( aSubShape )) + continue; // [bos #29143] aMesh.GetHypothesis() is too long // check for preview dimension limitations if ( aShapesId && GetShapeDim( aSubShape.ShapeType() ) > (int)aDim ) @@ -1222,6 +1251,26 @@ int SMESH_Gen::GetShapeDim(const TopAbs_ShapeEnum & aShapeType) return dim[ aShapeType ]; } +//================================================================================ +/*! + * \brief Return shape dimension by exploding compounds + */ +//================================================================================ + +int SMESH_Gen::GetFlatShapeDim(const TopoDS_Shape &aShape) +{ + int aShapeDim; + if ( aShape.ShapeType() == TopAbs_COMPOUND || + aShape.ShapeType() == TopAbs_COMPSOLID ) + { + TopoDS_Iterator it( aShape ); + aShapeDim = GetFlatShapeDim( it.Value() ); + } + else + aShapeDim = GetShapeDim( aShape ); + return aShapeDim; +} + //============================================================================= /*! * Generate a new id unique within this Gen diff --git a/src/SMESH/SMESH_Gen.hxx b/src/SMESH/SMESH_Gen.hxx index d2dd8271c..5c05f3bfa 100644 --- a/src/SMESH/SMESH_Gen.hxx +++ b/src/SMESH/SMESH_Gen.hxx @@ -154,6 +154,7 @@ public: static int GetShapeDim(const TopAbs_ShapeEnum & aShapeType); static int GetShapeDim(const TopoDS_Shape & aShape) { return GetShapeDim( aShape.ShapeType() ); } + static int GetFlatShapeDim(const TopoDS_Shape &aShape); SMESH_Algo* GetAlgo(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape, TopoDS_Shape* assignedTo=0); SMESH_Algo* GetAlgo(SMESH_subMesh * aSubMesh, TopoDS_Shape* assignedTo=0); From f85bc0ab6f009a118105bdcc1b04364ef4dbc298 Mon Sep 17 00:00:00 2001 From: eap Date: Fri, 25 Feb 2022 14:44:14 +0300 Subject: [PATCH 2/3] bos #29143 [CEA] Compute takes too much time in polyhedron per solid use case more optimization: don't fill in uniDimAlgoShapes if no multi-dimensional algo assigned --- src/SMESH/SMESH_Gen.cxx | 56 ++++++++++++++++++++++------------------- 1 file changed, 30 insertions(+), 26 deletions(-) diff --git a/src/SMESH/SMESH_Gen.cxx b/src/SMESH/SMESH_Gen.cxx index 06c47d8c0..db0010287 100644 --- a/src/SMESH/SMESH_Gen.cxx +++ b/src/SMESH/SMESH_Gen.cxx @@ -332,32 +332,6 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, else smWithAlgoSupportingSubmeshes[0].push_front( shDim2smIt->second ); - // gather sub-shapes with local uni-dimensional algos (bos #29143) - // ---------------------------------------------------------------- - TopTools_MapOfShape uniDimAlgoShapes; - ShapeToHypothesis::Iterator s2hyps( aMesh.GetMeshDS()->GetHypotheses() ); - for ( ; s2hyps.More(); s2hyps.Next() ) - { - const TopoDS_Shape& s = s2hyps.Key(); - if ( s.IsSame( aMesh.GetShapeToMesh() )) - continue; - for ( auto & hyp : s2hyps.Value() ) - { - if ( const SMESH_Algo* algo = dynamic_cast< const SMESH_Algo*>( hyp )) - if ( algo->NeedDiscreteBoundary() ) - { - TopAbs_ShapeEnum sType; - switch ( algo->GetDim() ) { - case 3: sType = TopAbs_SOLID; break; - case 2: sType = TopAbs_FACE; break; - default: sType = TopAbs_EDGE; break; - } - for ( TopExp_Explorer ex( s2hyps.Key(), sType ); ex.More(); ex.Next() ) - uniDimAlgoShapes.Add( ex.Current() ); - } - } - } - // ====================================================== // Apply all-dimensional algorithms supporing sub-meshes // ====================================================== @@ -367,6 +341,36 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, smVec.insert( smVec.end(), smWithAlgoSupportingSubmeshes[aShapeDim].begin(), smWithAlgoSupportingSubmeshes[aShapeDim].end() ); + + // gather sub-shapes with local uni-dimensional algos (bos #29143) + // ---------------------------------------------------------------- + TopTools_MapOfShape uniDimAlgoShapes; + if ( !smVec.empty() ) + { + ShapeToHypothesis::Iterator s2hyps( aMesh.GetMeshDS()->GetHypotheses() ); + for ( ; s2hyps.More(); s2hyps.Next() ) + { + const TopoDS_Shape& s = s2hyps.Key(); + if ( s.IsSame( aMesh.GetShapeToMesh() )) + continue; + for ( auto & hyp : s2hyps.Value() ) + { + if ( const SMESH_Algo* algo = dynamic_cast< const SMESH_Algo*>( hyp )) + if ( algo->NeedDiscreteBoundary() ) + { + TopAbs_ShapeEnum sType; + switch ( algo->GetDim() ) { + case 3: sType = TopAbs_SOLID; break; + case 2: sType = TopAbs_FACE; break; + default: sType = TopAbs_EDGE; break; + } + for ( TopExp_Explorer ex( s2hyps.Key(), sType ); ex.More(); ex.Next() ) + uniDimAlgoShapes.Add( ex.Current() ); + } + } + } + } + { // ------------------------------------------------ // sort list of sub-meshes according to mesh order From a065ed143c667923c28ff710017519215e309a36 Mon Sep 17 00:00:00 2001 From: eap Date: Mon, 28 Feb 2022 14:38:20 +0300 Subject: [PATCH 3/3] bos #29143 [CEA] Compute takes too much time in polyhedron per solid use case more optimization: don't try to find more local algos if uniDimAlgoShapes is empty --- src/SMESH/SMESH_Gen.cxx | 79 ++++++++++++++++++++------------------ src/SMESH/SMESH_Homard.hxx | 2 +- 2 files changed, 42 insertions(+), 39 deletions(-) diff --git a/src/SMESH/SMESH_Gen.cxx b/src/SMESH/SMESH_Gen.cxx index db0010287..02d5a217e 100644 --- a/src/SMESH/SMESH_Gen.cxx +++ b/src/SMESH/SMESH_Gen.cxx @@ -248,7 +248,7 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, // ================================================================ // Apply algos that do NOT require discreteized boundaries // ("all-dimensional") and do NOT support sub-meshes, starting from - // the most complex shapes and collect sub-meshes with algos that + // the most complex shapes and collect sub-meshes with algos that // DO support sub-meshes // ================================================================ @@ -273,7 +273,7 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape& aSubShape = smToCompute->GetSubShape(); aShapeDim = GetShapeDim( aSubShape ); if ( aShapeDim < 1 ) break; - + // check for preview dimension limitations if ( aShapesId && aShapeDim > (int)aDim ) continue; @@ -390,47 +390,50 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, const TopAbs_ShapeEnum shapeType = sm->GetSubShape().ShapeType(); - // get a shape the algo is assigned to - if ( !GetAlgo( sm, & algoShape )) - continue; // strange... - - // look for more local algos - if ( SMESH_subMesh* algoSM = aMesh.GetSubMesh( algoShape )) - smIt = algoSM->getDependsOnIterator(!includeSelf, !complexShapeFirst); - else - smIt = sm->getDependsOnIterator(!includeSelf, !complexShapeFirst); - - while ( smIt->more() ) + if ( !uniDimAlgoShapes.IsEmpty() ) { - SMESH_subMesh* smToCompute = smIt->next(); + // get a shape the algo is assigned to + if ( !GetAlgo( sm, & algoShape )) + continue; // strange... - const TopoDS_Shape& aSubShape = smToCompute->GetSubShape(); - const int aShapeDim = GetShapeDim( aSubShape ); - if ( aShapeDim < 1 || aSubShape.ShapeType() <= shapeType ) - continue; - if ( !uniDimAlgoShapes.Contains( aSubShape )) - continue; // [bos #29143] aMesh.GetHypothesis() is too long + // look for more local algos + if ( SMESH_subMesh* algoSM = aMesh.GetSubMesh( algoShape )) + smIt = algoSM->getDependsOnIterator(!includeSelf, !complexShapeFirst); + else + smIt = sm->getDependsOnIterator(!includeSelf, !complexShapeFirst); - // check for preview dimension limitations - if ( aShapesId && GetShapeDim( aSubShape.ShapeType() ) > (int)aDim ) - continue; - - SMESH_HypoFilter filter( SMESH_HypoFilter::IsAlgo() ); - filter - .And( SMESH_HypoFilter::IsApplicableTo( aSubShape )) - .And( SMESH_HypoFilter::IsMoreLocalThan( algoShape, aMesh )); - - if ( SMESH_Algo* subAlgo = (SMESH_Algo*) aMesh.GetHypothesis( smToCompute, filter, true)) + while ( smIt->more() ) { - if ( ! subAlgo->NeedDiscreteBoundary() ) continue; - TopTools_IndexedMapOfShape* localAllowed = allowedSubShapes; - if ( localAllowed && localAllowed->IsEmpty() ) - localAllowed = 0; // prevent fillAllowed() with aSubShape + SMESH_subMesh* smToCompute = smIt->next(); - SMESH_Hypothesis::Hypothesis_Status status; - if ( subAlgo->CheckHypothesis( aMesh, aSubShape, status )) - // mesh a lower smToCompute starting from vertices - Compute( aMesh, aSubShape, aFlags | SHAPE_ONLY_UPWARD, aDim, aShapesId, localAllowed ); + const TopoDS_Shape& aSubShape = smToCompute->GetSubShape(); + const int aShapeDim = GetShapeDim( aSubShape ); + if ( aShapeDim < 1 || aSubShape.ShapeType() <= shapeType ) + continue; + if ( !uniDimAlgoShapes.Contains( aSubShape )) + continue; // [bos #29143] aMesh.GetHypothesis() is too long + + // check for preview dimension limitations + if ( aShapesId && GetShapeDim( aSubShape.ShapeType() ) > (int)aDim ) + continue; + + SMESH_HypoFilter filter( SMESH_HypoFilter::IsAlgo() ); + filter + .And( SMESH_HypoFilter::IsApplicableTo( aSubShape )) + .And( SMESH_HypoFilter::IsMoreLocalThan( algoShape, aMesh )); + + if ( SMESH_Algo* subAlgo = (SMESH_Algo*) aMesh.GetHypothesis( smToCompute, filter, true)) + { + if ( ! subAlgo->NeedDiscreteBoundary() ) continue; + TopTools_IndexedMapOfShape* localAllowed = allowedSubShapes; + if ( localAllowed && localAllowed->IsEmpty() ) + localAllowed = 0; // prevent fillAllowed() with aSubShape + + SMESH_Hypothesis::Hypothesis_Status status; + if ( subAlgo->CheckHypothesis( aMesh, aSubShape, status )) + // mesh a lower smToCompute starting from vertices + Compute( aMesh, aSubShape, aFlags | SHAPE_ONLY_UPWARD, aDim, aShapesId, localAllowed ); + } } } // -------------------------------- diff --git a/src/SMESH/SMESH_Homard.hxx b/src/SMESH/SMESH_Homard.hxx index 9d2b7dc07..5fce29bb8 100644 --- a/src/SMESH/SMESH_Homard.hxx +++ b/src/SMESH/SMESH_Homard.hxx @@ -237,6 +237,6 @@ private: int _MessInfo; }; -}; // namespace SMESHHOMARDImpl +} // namespace SMESHHOMARDImpl #endif