Salome HOME
bos #29764 EDF - SMESH_blocfissure* fail
[modules/smesh.git] / src / SMESHUtils / SMESH_MeshAlgos.cxx
index 7a4a0a48127f78e2fe3be0498599b810d9e7a8b3..9bc76d69d4da63c1da3ed8857a3c0a7b9a2688cd 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2020  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2021  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -281,7 +281,7 @@ namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint()
                                        double               tolerance)
     :SMESH_Octree( new LimitAndPool() )
   {
-    int nbElems = mesh.GetMeshInfo().NbElements( elemType );
+    smIdType nbElems = mesh.GetMeshInfo().NbElements( elemType );
     _elements.reserve( nbElems );
 
     TElementBoxPool& elBoPool = getLimitAndPool()->_elBoPool;
@@ -1984,7 +1984,11 @@ SMESH_MeshAlgos::FindSharpEdges( SMDS_Mesh* theMesh,
   typedef std::pair< bool, const SMDS_MeshNode* >                            TIsSharpAndMedium;
   typedef NCollection_DataMap< SMESH_TLink, TIsSharpAndMedium, SMESH_TLink > TLinkSharpMap;
 
-  TLinkSharpMap linkIsSharp( theMesh->NbFaces() );
+  TLinkSharpMap linkIsSharp;
+  Standard_Integer nbBuckets = FromSmIdType<Standard_Integer>( theMesh->NbFaces() );
+  if ( nbBuckets > 0 )
+    linkIsSharp.ReSize( nbBuckets );
+
   TIsSharpAndMedium sharpMedium( true, 0 );
   bool                 & isSharp = sharpMedium.first;
   const SMDS_MeshNode* & nMedium = sharpMedium.second;
@@ -2091,7 +2095,10 @@ SMESH_MeshAlgos::SeparateFacesByEdges( SMDS_Mesh* theMesh, const std::vector< Ed
 
   typedef std::vector< const SMDS_MeshElement* >                    TFaceVec;
   typedef NCollection_DataMap< SMESH_TLink, TFaceVec, SMESH_TLink > TFacesByLinks;
-  TFacesByLinks facesByLink( theMesh->NbFaces() );
+  TFacesByLinks facesByLink;
+  Standard_Integer nbBuckets = FromSmIdType<Standard_Integer>( theMesh->NbFaces() );
+  if ( nbBuckets > 0 )
+    facesByLink.ReSize( nbBuckets );
 
   std::vector< const SMDS_MeshNode* > faceNodes;
   for ( SMDS_FaceIteratorPtr faceIt = theMesh->facesIterator(); faceIt->more(); )
@@ -2245,6 +2252,56 @@ std::vector< const SMDS_MeshNode*> SMESH_MeshAlgos::GetCommonNodes(const SMDS_Me
   return common;
 }
 
+//================================================================================
+/*!
+ * \brief Return true if a node is on a boundary of 2D mesh.
+ *        Optionally returns two neighboring boundary nodes (or more in non-manifold mesh)
+ */
+//================================================================================
+
+bool SMESH_MeshAlgos::IsOn2DBoundary( const SMDS_MeshNode*                 theNode,
+                                      std::vector< const SMDS_MeshNode*> * theNeibors )
+{
+  typedef NCollection_DataMap< SMESH_TLink, int, SMESH_TLink > TLinkCountMap;
+  TLinkCountMap linkCountMap( 10 );
+
+  int nbFreeLinks = 0;
+  for ( SMDS_ElemIteratorPtr fIt = theNode->GetInverseElementIterator(SMDSAbs_Face); fIt->more(); )
+  {
+    const SMDS_MeshElement* face = fIt->next();
+    const int          nbCorners = face->NbCornerNodes();
+
+    int    iN = face->GetNodeIndex( theNode );
+    int iPrev = ( iN - 1 + nbCorners ) % nbCorners;
+    int iNext = ( iN + 1 ) % nbCorners;
+
+    for ( int i : { iPrev, iNext } )
+    {
+      SMESH_TLink link( theNode, face->GetNode( i ));
+      int* count = linkCountMap.ChangeSeek( link );
+      if ( count )  ++( *count );
+      else          linkCountMap.Bind( link, 1 );
+
+      if ( !count ) ++nbFreeLinks;
+      else          --nbFreeLinks;
+    }
+  }
+
+  if ( theNeibors )
+  {
+    theNeibors->clear();
+    theNeibors->reserve( nbFreeLinks );
+    for ( TLinkCountMap::Iterator linkIt( linkCountMap ); linkIt.More(); linkIt.Next() )
+      if ( linkIt.Value() == 1 )
+      {
+        theNeibors->push_back( linkIt.Key().node1() );
+        if ( theNeibors->back() == theNode )
+          theNeibors->back() = linkIt.Key().node2();
+      }
+  }
+  return nbFreeLinks > 0;
+}
+
 //================================================================================
 /*!
  * \brief Return true if node1 encounters first in the face and node2, after