#include "SMESH_MeshAlgos.hxx"
+#include "ObjectPool.hxx"
#include "SMDS_FaceOfNodes.hxx"
#include "SMDS_LinearEdge.hxx"
#include "SMDS_Mesh.hxx"
TIDSortedNodeSet nodes;
if ( theMesh ) {
- SMDS_NodeIteratorPtr nIt = theMesh->nodesIterator(/*idInceasingOrder=*/true);
+ SMDS_NodeIteratorPtr nIt = theMesh->nodesIterator();
while ( nIt->more() )
nodes.insert( nodes.end(), nIt->next() );
}
myOctreeNode->NodesAround( thePnt.Coord(), dist2Nodes, myHalfLeafSize );
if ( !dist2Nodes.empty() )
return dist2Nodes.begin()->second;
- std::list<const SMDS_MeshNode*> nodes;
+
+ std::vector<const SMDS_MeshNode*> nodes;
//myOctreeNode->NodesAround( &tgtNode, &nodes, myHalfLeafSize );
double minSqDist = DBL_MAX;
if ( nodes.empty() ) // get all nodes of OctreeNode's closest to thePnt
{
// sort leafs by their distance from thePnt
- typedef std::map< double, SMESH_OctreeNode* > TDistTreeMap;
+ typedef std::multimap< double, SMESH_OctreeNode* > TDistTreeMap;
TDistTreeMap treeMap;
std::list< SMESH_OctreeNode* > treeList;
std::list< SMESH_OctreeNode* >::iterator trIt;
{
const Bnd_B3d& box = *tree->getBox();
double sqDist = thePnt.SquareDistance( 0.5 * ( box.CornerMin() + box.CornerMax() ));
- std::pair<TDistTreeMap::iterator,bool> it_in =
- treeMap.insert( std::make_pair( sqDist, tree ));
- if ( !it_in.second ) // not unique distance to box center
- treeMap.insert( it_in.first, std::make_pair( sqDist + 1e-13*treeMap.size(), tree ));
+ treeMap.insert( std::make_pair( sqDist, tree ));
}
}
// find distance after which there is no sense to check tree's
if ( sqDist_tree->first > sqLimit )
break;
SMESH_OctreeNode* tree = sqDist_tree->second;
- tree->NodesAround( tree->GetNodeIterator()->next(), &nodes );
+ tree->AllNodesAround( tree->GetNodeIterator()->next(), &nodes );
}
}
// find closest among nodes
minSqDist = DBL_MAX;
const SMDS_MeshNode* closestNode = 0;
- std::list<const SMDS_MeshNode*>::iterator nIt = nodes.begin();
- for ( ; nIt != nodes.end(); ++nIt ) {
- double sqDist = thePnt.SquareDistance( SMESH_TNodeXYZ( *nIt ) );
+ for ( size_t i = 0; i < nodes.size(); ++i )
+ {
+ double sqDist = thePnt.SquareDistance( SMESH_NodeXYZ( nodes[ i ]));
if ( minSqDist > sqDist ) {
- closestNode = *nIt;
+ closestNode = nodes[ i ];
minSqDist = sqDist;
}
}
//---------------------------------------------------------------------
/*!
- * \brief Finds nodes located within a tolerance near a point
+ * \brief Finds nodes located within a tolerance near a point
*/
int FindNearPoint(const gp_Pnt& point,
const double tolerance,
{
public:
- typedef boost::container::flat_set< const SMDS_MeshElement* > TElemSeq;
+ typedef boost::container::flat_set< const SMDS_MeshElement*, TIDCompare > TElemSeq;
ElementBndBoxTree(const SMDS_Mesh& mesh,
SMDSAbs_ElementType elemType,
//!< allocator of ElementBox's and SMESH_TreeLimit
struct LimitAndPool : public SMESH_TreeLimit
{
- TElementBoxPool _elBoPool;
+ TElementBoxPool _elBoPool;
LimitAndPool():SMESH_TreeLimit( MaxLevel, /*minSize=*/0. ) {}
};
LimitAndPool* getLimitAndPool() const
ElementBndBoxTree*& ebbTree = _ebbTree[ _elementType ];
if ( !ebbTree )
- ebbTree = new ElementBndBoxTree( *_mesh, _elementType );
+ ebbTree = new ElementBndBoxTree( *_mesh, _elementType, _meshPartIt );
gp_XYZ p = point.XYZ();
ElementBndBoxTree* ebbLeaf = ebbTree->getLeafAtPoint( p );
- const Bnd_B3d* box = ebbLeaf->getBox();
+ const Bnd_B3d* box = ebbLeaf ? ebbLeaf->getBox() : ebbTree->getBox();
double radius = ( box->CornerMax() - box->CornerMin() ).Modulus();
ElementBndBoxTree::TElemSeq elems;
std::vector< SMESH_TNodeXYZ > xyz; xyz.reserve( element->NbNodes()+1 );
- SMDS_ElemIteratorPtr nodeIt = element->interlacedNodesElemIterator();
+ SMDS_NodeIteratorPtr nodeIt = element->interlacedNodesIterator();
for ( int i = 0; nodeIt->more(); ++i )
xyz.push_back( SMESH_TNodeXYZ( nodeIt->next() ));
//================================================================================
/*!
- * \brief Return of a point relative to a segment
+ * \brief Return position of a point relative to a segment
* \param point2D - the point to analyze position of
- * \param xyVec - end points of segments
+ * \param segEnds - end points of segments
* \param index0 - 0-based index of the first point of segment
* \param posToFindOut - flags of positions to detect
* \retval PointPos - point position
switch ( elem->GetType() )
{
case SMDSAbs_Volume:
- return GetDistance( dynamic_cast<const SMDS_MeshVolume*>( elem ), point, closestPnt );
+ return GetDistance( static_cast<const SMDS_MeshVolume*>( elem ), point, closestPnt );
case SMDSAbs_Face:
- return GetDistance( dynamic_cast<const SMDS_MeshFace*>( elem ), point, closestPnt );
+ return GetDistance( static_cast<const SMDS_MeshFace*>( elem ), point, closestPnt );
case SMDSAbs_Edge:
- return GetDistance( dynamic_cast<const SMDS_MeshEdge*>( elem ), point, closestPnt );
+ return GetDistance( static_cast<const SMDS_MeshEdge*>( elem ), point, closestPnt );
case SMDSAbs_Node:
if ( closestPnt ) *closestPnt = SMESH_TNodeXYZ( elem );
return point.Distance( SMESH_TNodeXYZ( elem ));
}
// compute distance
- PointPos pos = *pntPosSet.begin();
- switch ( pos._name )
- {
- case POS_LEFT:
- {
- // point is most close to an edge
- gp_Vec edge( xyz[ pos._index ], xyz[ pos._index+1 ]);
- gp_Vec n1p ( xyz[ pos._index ], point );
- double u = ( edge * n1p ) / edge.SquareMagnitude(); // param [0,1] on the edge
- // projection of the point on the edge
- gp_XYZ proj = xyz[ pos._index ] + u * edge.XYZ();
- if ( closestPnt ) *closestPnt = proj;
- return point.Distance( proj );
- }
- case POS_RIGHT:
+
+ double minDist2 = Precision::Infinite();
+ for ( std::set< PointPos >::iterator posIt = pntPosSet.begin(); posIt != pntPosSet.end(); ++posIt)
{
- // point is inside the face
- double distToFacePlane = Abs( tmpPnt.Y() );
- if ( closestPnt )
+ PointPos pos = *posIt;
+ if ( pos._name != pntPosSet.begin()->_name )
+ break;
+ switch ( pos._name )
{
- if ( distToFacePlane < std::numeric_limits<double>::min() ) {
- *closestPnt = point.XYZ();
+ case POS_LEFT: // point is most close to an edge
+ {
+ gp_Vec edge( xyz[ pos._index ], xyz[ pos._index+1 ]);
+ gp_Vec n1p ( xyz[ pos._index ], point );
+ double u = ( edge * n1p ) / edge.SquareMagnitude(); // param [0,1] on the edge
+ // projection of the point on the edge
+ gp_XYZ proj = xyz[ pos._index ] + u * edge.XYZ();
+ double dist2 = point.SquareDistance( proj );
+ if ( dist2 < minDist2 )
+ {
+ if ( closestPnt ) *closestPnt = proj;
+ minDist2 = dist2;
}
- else {
- tmpPnt.SetY( 0 );
- trsf.Inverted().Transforms( tmpPnt );
- *closestPnt = tmpPnt;
+ break;
+ }
+
+ case POS_RIGHT: // point is inside the face
+ {
+ double distToFacePlane = Abs( tmpPnt.Y() );
+ if ( closestPnt )
+ {
+ if ( distToFacePlane < std::numeric_limits<double>::min() ) {
+ *closestPnt = point.XYZ();
+ }
+ else {
+ tmpPnt.SetY( 0 );
+ trsf.Inverted().Transforms( tmpPnt );
+ *closestPnt = tmpPnt;
+ }
}
+ return distToFacePlane;
+ }
+
+ case POS_VERTEX: // point is most close to a node
+ {
+ double dist2 = point.SquareDistance( xyz[ pos._index ]);
+ if ( dist2 < minDist2 )
+ {
+ if ( closestPnt ) *closestPnt = xyz[ pos._index ];
+ minDist2 = dist2;
+ }
+ break;
+ }
+ default:;
+ return badDistance;
}
- return distToFacePlane;
- }
- case POS_VERTEX:
- {
- // point is most close to a node
- gp_Vec distVec( point, xyz[ pos._index ]);
- return distVec.Magnitude();
- }
- default:;
}
- return badDistance;
+ return Sqrt( minDist2 );
}
//=======================================================================
int i = 0, nbNodes = seg->NbNodes();
std::vector< SMESH_TNodeXYZ > xyz( nbNodes );
- SMDS_ElemIteratorPtr nodeIt = seg->interlacedNodesElemIterator();
- while ( nodeIt->more() )
- xyz[ i++ ].Set( nodeIt->next() );
+ for ( SMDS_NodeIteratorPtr nodeIt = seg->interlacedNodesIterator(); nodeIt->more(); i++ )
+ xyz[ i ].Set( nodeIt->next() );
for ( i = 1; i < nbNodes; ++i )
{
const double t11 = T22, t12 = -T12, t21 = -T21, t22 = T11;
// vector
const double r11 = p.X()-t2.X(), r12 = p.Y()-t2.Y();
- // barycentric coordinates: mutiply matrix by vector
+ // barycentric coordinates: multiply matrix by vector
bc0 = (t11 * r11 + t12 * r12)/Tdet;
bc1 = (t21 * r11 + t22 * r12)/Tdet;
}
if ( !face && elem->IsQuadratic())
{
// analysis for quadratic elements using all nodes
- SMDS_ElemIteratorPtr anIter = elem->interlacedNodesElemIterator();
+ SMDS_NodeIteratorPtr anIter = elem->interlacedNodesIterator();
const SMDS_MeshNode* prevN = static_cast<const SMDS_MeshNode*>( anIter->next() );
for ( i1 = -1, i2 = 0; anIter->more() && !face; i1++, i2++ )
{