-// Copyright (C) 2007-2020 CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2022 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
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;
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;
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(); )
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