-// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2020 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
void getElementsInBox ( const Bnd_B3d& box, TElemSeq& foundElems );
void getElementsInSphere ( const gp_XYZ& center, const double radius, TElemSeq& foundElems );
ElementBndBoxTree* getLeafAtPoint( const gp_XYZ& point );
+ int getNbElements();
protected:
ElementBndBoxTree() {}
return 0;
}
+ //================================================================================
+ /*!
+ * \brief Return number of elements
+ */
+ //================================================================================
+
+ int ElementBndBoxTree::getNbElements()
+ {
+ int nb = 0;
+ if ( isLeaf() )
+ {
+ nb = _elements.size();
+ }
+ else
+ {
+ for (int i = 0; i < 8; i++)
+ nb += ((ElementBndBoxTree*) myChildren[i])->getNbElements();
+ }
+ return nb;
+ }
+
//================================================================================
/*!
* \brief Construct the element box
/*!
* \brief Find an element of given type most close to the given point
*
- * WARNING: Only face search is implemeneted so far
+ * WARNING: Only edge, face and volume search is implemented so far
*/
//=======================================================================
const SMDS_MeshElement* prevFace = u_int1->second._face;
while ( ok && u_int2->second._coincides )
{
- if ( SMESH_MeshAlgos::GetCommonNodes(prevFace , u_int2->second._face).empty() )
+ if ( SMESH_MeshAlgos::NbCommonNodes(prevFace , u_int2->second._face) == 0 )
ok = false;
else
{
gp_XYZ p = point.XYZ();
ElementBndBoxTree* ebbLeaf = ebbTree->getLeafAtPoint( p );
const Bnd_B3d* box = ebbLeaf ? ebbLeaf->getBox() : ebbTree->getBox();
- double radius = ( box->CornerMax() - box->CornerMin() ).Modulus();
+ gp_XYZ pMin = box->CornerMin(), pMax = box->CornerMax();
+ double radius = Precision::Infinite();
+ if ( ebbLeaf || !box->IsOut( p ))
+ {
+ for ( int i = 1; i <= 3; ++i )
+ {
+ double d = 0.5 * ( pMax.Coord(i) - pMin.Coord(i) );
+ if ( d > Precision::Confusion() )
+ radius = Min( d, radius );
+ }
+ if ( !ebbLeaf )
+ radius /= ebbTree->getHeight( /*full=*/true );
+ }
+ else // p outside of box
+ {
+ for ( int i = 1; i <= 3; ++i )
+ {
+ double d = 0;
+ if ( point.Coord(i) < pMin.Coord(i) )
+ d = pMin.Coord(i) - point.Coord(i);
+ else if ( point.Coord(i) > pMax.Coord(i) )
+ d = point.Coord(i) - pMax.Coord(i);
+ if ( d > Precision::Confusion() )
+ radius = Min( d, radius );
+ }
+ }
ElementBndBoxTree::TElemSeq elems;
ebbTree->getElementsInSphere( p, radius, elems );
while ( elems.empty() && radius < 1e100 )
{
- radius *= 1.5;
+ radius *= 1.1;
ebbTree->getElementsInSphere( p, radius, elems );
}
gp_XYZ proj, bestProj;
const SMDS_MeshElement* elem = 0;
- double minDist = 2 * radius;
+ double minDist = Precision::Infinite();
ElementBndBoxTree::TElemSeq::iterator e = elems.begin();
for ( ; e != elems.end(); ++e )
{
minDist = d;
}
}
+ if ( minDist > radius )
+ {
+ ElementBndBoxTree::TElemSeq elems2;
+ ebbTree->getElementsInSphere( p, minDist, elems2 );
+ for ( e = elems2.begin(); e != elems2.end(); ++e )
+ {
+ if ( elems.count( *e ))
+ continue;
+ double d = SMESH_MeshAlgos::GetDistance( *e, point, &proj );
+ if ( d < minDist )
+ {
+ bestProj = proj;
+ elem = *e;
+ minDist = d;
+ }
+ }
+ }
if ( closestElem ) *closestElem = elem;
return bestProj;
return ok;
}
-//=======================================================================
-//function : GetCommonNodes
-//purpose : Return nodes common to two elements
-//=======================================================================
+//================================================================================
+/*!
+ * \brief Return nodes common to two elements
+ */
+//================================================================================
+
+int SMESH_MeshAlgos::NbCommonNodes(const SMDS_MeshElement* e1,
+ const SMDS_MeshElement* e2)
+{
+ int nb = 0;
+ for ( int i = 0 ; i < e1->NbNodes(); ++i )
+ nb += ( e2->GetNodeIndex( e1->GetNode( i )) >= 0 );
+ return nb;
+}
+
+//================================================================================
+/*!
+ * \brief Return nodes common to two elements
+ */
+//================================================================================
std::vector< const SMDS_MeshNode*> SMESH_MeshAlgos::GetCommonNodes(const SMDS_MeshElement* e1,
const SMDS_MeshElement* e2)
common.push_back( e1->GetNode( i ));
return common;
}
+
//================================================================================
/*!
* \brief Return true if node1 encounters first in the face and node2, after
if ( nbBranches == 2 && !startIsBranchEnd ) // join two branches starting at the same node
{
- if ( nodeBranches[0].back() == nodeBranches[1].back() )
- {
- // it is a closed branch, keep theStartNode first
- nodeBranches[0].pop_back();
- nodeBranches[0].reserve( nodeBranches[0].size() + nodeBranches[1].size() );
- nodeBranches[0].insert( nodeBranches[0].end(),
- nodeBranches[1].rbegin(), nodeBranches[1].rend() );
- branches[0].reserve( branches[0].size() + branches[1].size() );
- branches[0].insert( branches[0].end(), branches[1].rbegin(), branches[1].rend() );
- }
- else
- {
- std::reverse( nodeBranches[0].begin(), nodeBranches[0].end() );
- nodeBranches[0].pop_back();
- nodeBranches[0].reserve( nodeBranches[0].size() + nodeBranches[1].size() );
- nodeBranches[0].insert( nodeBranches[0].end(),
- nodeBranches[1].begin(), nodeBranches[1].end() );
-
- std::reverse( branches[0].begin(), branches[0].end() );
- branches[0].reserve( branches[0].size() + branches[1].size() );
- branches[0].insert( branches[0].end(), branches[1].begin(), branches[1].end() );
- }
+ std::reverse( nodeBranches[0].begin(), nodeBranches[0].end() );
+ nodeBranches[0].pop_back();
+ nodeBranches[0].reserve( nodeBranches[0].size() + nodeBranches[1].size() );
+ nodeBranches[0].insert( nodeBranches[0].end(),
+ nodeBranches[1].begin(), nodeBranches[1].end() );
+
+ std::reverse( branches[0].begin(), branches[0].end() );
+ branches[0].reserve( branches[0].size() + branches[1].size() );
+ branches[0].insert( branches[0].end(), branches[1].begin(), branches[1].end() );
+
nodeBranches[1].clear();
branches[1].clear();
}