Version: 6.3.1
Public Member Functions | Static Public Member Functions | Protected Member Functions | Protected Attributes

SMESH_OctreeNode Class Reference

#include <SMESH_OctreeNode.hxx>

Inheritance diagram for SMESH_OctreeNode:
Inheritance graph
[legend]

Public Member Functions

 SMESH_OctreeNode (const TIDSortedNodeSet &theNodes, const int maxLevel=8, const int maxNbNodes=5, const double minBoxSize=0.)
 Constructor : Build all the Octree using Compute()
virtual ~SMESH_OctreeNode ()
 Empty destructor.
virtual const bool isInside (const gp_XYZ &p, const double precision=0.)
 Tells us if Node is inside the current box with the precision "precision".
void NodesAround (const SMDS_MeshNode *Node, std::list< const SMDS_MeshNode * > *Result, const double precision=0.)
 Return in Result a list of Nodes potentials to be near Node.
bool NodesAround (const gp_XYZ &node, std::map< double, const SMDS_MeshNode * > &dist2Nodes, double precision)
 Return in dist2Nodes nodes mapped to their square distance from Node.
void FindCoincidentNodes (TIDSortedNodeSet *nodes, const double theTolerance, std::list< std::list< const SMDS_MeshNode * > > *theGroupsOfNodes)
 Return in theGroupsOfNodes a list of group of nodes close to each other within theTolerance Search for all the nodes in theSetOfNodes.
void UpdateByMoveNode (const SMDS_MeshNode *node, const gp_Pnt &toPnt)
 Update data according to node movement.
SMESH_OctreeNodeIteratorPtr GetChildrenIterator ()
 Return iterator over children.
SMDS_NodeIteratorPtr GetNodeIterator ()
 Return nodes iterator.
int NbNodes () const
 Return nb nodes in a tree.
void compute ()
 Compute the Octree.
bool isLeaf () const
 Tell if Octree is a leaf or not An inheriting class can influence it via myIsLeaf protected field.
int level () const
const Bnd_B3d & getBox () const
double maxSize () const
 Compute the bigger dimension of my box.
int getChildIndex (double x, double y, double z, const gp_XYZ &boxMiddle) const
 Return index of a child the given point is in.

Static Public Member Functions

static void FindCoincidentNodes (TIDSortedNodeSet &nodes, std::list< std::list< const SMDS_MeshNode * > > *theGroupsOfNodes, const double theTolerance=0.00001, const int maxLevel=-1, const int maxNbNodes=5)
 Return in theGroupsOfNodes a list of group of nodes close to each other within theTolerance Search for all the nodes in theSetOfNodes Static Method : no need to create an SMESH_OctreeNode.

Protected Member Functions

 SMESH_OctreeNode (int maxNbNodes)
 Constructor used to allocate a child.
virtual Bnd_B3d * buildRootBox ()
 Compute the first bounding box.
virtual void buildChildrenData ()
 Set the data of the children Shares the father's data with each of his child.
virtual SMESH_OctreeallocateOctreeChild () const
 Construct an empty SMESH_OctreeNode used by SMESH_Octree.buildChildren()
void FindCoincidentNodes (const SMDS_MeshNode *Node, TIDSortedNodeSet *SetOfNodes, std::list< const SMDS_MeshNode * > *Result, const double precision)
 Return a list of nodes closed to Node and remove it from SetOfNodes.

Protected Attributes

int myMaxNbNodes
TIDSortedNodeSet myNodes
SMESH_Octree ** myChildren
SMESH_OctreemyFather
bool myIsLeaf
const LimitmyLimit

Detailed Description

Definition at line 51 of file SMESH_OctreeNode.hxx.


Constructor & Destructor Documentation

SMESH_OctreeNode::SMESH_OctreeNode ( const TIDSortedNodeSet theNodes,
const int  maxLevel = 8,
const int  maxNbNodes = 5,
const double  minBoxSize = 0. 
)

Constructor : Build all the Octree using Compute()

Parameters:
theNodes- Set of nodes, the Octree is built from this nodes
maxLevel- Maximum level for the leaves
maxNbNodes- Maximum number of nodes, a leaf can contain
minBoxSize- Minimal size of the Octree Box

Definition at line 46 of file SMESH_OctreeNode.cxx.

References SMESH_Octree.compute().

Referenced by allocateOctreeChild().

  :SMESH_Octree( new SMESH_Octree::Limit( maxLevel,minBoxSize)),
  myMaxNbNodes(maxNbNodes),
  myNodes(theNodes)
{
  compute();
}
virtual SMESH_OctreeNode.~SMESH_OctreeNode ( ) [virtual]

Empty destructor.

Definition at line 64 of file SMESH_OctreeNode.hxx.

{};
SMESH_OctreeNode::SMESH_OctreeNode ( int  maxNbNodes) [protected]

Constructor used to allocate a child.

Definition at line 61 of file SMESH_OctreeNode.cxx.

                                                 :
  SMESH_Octree(), myMaxNbNodes(maxNbNodes)
{
}

Member Function Documentation

SMESH_Octree * SMESH_OctreeNode::allocateOctreeChild ( ) const [protected, virtual]

Construct an empty SMESH_OctreeNode used by SMESH_Octree.buildChildren()

Implements SMESH_Octree.

Definition at line 72 of file SMESH_OctreeNode.cxx.

References myMaxNbNodes, and SMESH_OctreeNode().

{
  return new SMESH_OctreeNode(myMaxNbNodes);
}
void SMESH_OctreeNode::buildChildrenData ( ) [protected, virtual]

Set the data of the children Shares the father's data with each of his child.

Implements SMESH_Octree.

Definition at line 124 of file SMESH_OctreeNode.cxx.

References SMESH_Octree.getBox(), SMESH_Octree.getChildIndex(), SMESH_Octree.myChildren, SMESH_Octree.myIsLeaf, myMaxNbNodes, myNodes, SMESH_AdvancedEditor.n1, SMDS_MeshNode.X(), SMDS_MeshNode.Y(), and SMDS_MeshNode.Z().

{
  gp_XYZ min = getBox().CornerMin();
  gp_XYZ max = getBox().CornerMax();
  gp_XYZ mid = (min + max)/2.;

  TIDSortedNodeSet::iterator it = myNodes.begin();
  while (it != myNodes.end())
  {
    const SMDS_MeshNode* n1 = *it;
    int ChildBoxNum = getChildIndex( n1->X(), n1->Y(), n1->Z(), mid );
    SMESH_OctreeNode* myChild = dynamic_cast<SMESH_OctreeNode*> (myChildren[ChildBoxNum]);
    myChild->myNodes.insert(myChild->myNodes.end(),n1);
    myNodes.erase( it );
    it = myNodes.begin();
  }
  for (int i = 0; i < 8; i++)
  {
    SMESH_OctreeNode* myChild = dynamic_cast<SMESH_OctreeNode*> (myChildren[i]);
    if ( myChild->myNodes.size() <= myMaxNbNodes )
      myChild->myIsLeaf = true;
  }
}
Bnd_B3d * SMESH_OctreeNode::buildRootBox ( ) [protected, virtual]

Compute the first bounding box.

We take the max/min coord of the nodes

Implements SMESH_Octree.

Definition at line 85 of file SMESH_OctreeNode.cxx.

References ex13_hole1partial.box, SMESH_Octree.myIsLeaf, myMaxNbNodes, myNodes, SMESH_AdvancedEditor.n1, PAL_MESH_041_mesh.p1, SMDS_MeshNode.X(), SMDS_MeshNode.Y(), and SMDS_MeshNode.Z().

{
  Bnd_B3d* box = new Bnd_B3d;
  TIDSortedNodeSet::iterator it = myNodes.begin();
  for (; it != myNodes.end(); it++) {
    const SMDS_MeshNode* n1 = *it;
    gp_XYZ p1( n1->X(), n1->Y(), n1->Z() );
    box->Add(p1);
  }
  if ( myNodes.size() <= myMaxNbNodes )
    myIsLeaf = true;

  return box;
}
void SMESH_Octree::compute ( ) [inherited]
void SMESH_OctreeNode::FindCoincidentNodes ( TIDSortedNodeSet theSetOfNodes,
const double  theTolerance,
std::list< std::list< const SMDS_MeshNode * > > *  theGroupsOfNodes 
)

Return in theGroupsOfNodes a list of group of nodes close to each other within theTolerance Search for all the nodes in theSetOfNodes.

Note:
The Octree itself is also modified by this method
Parameters:
theSetOfNodes- set of nodes we look at, modified during research
theTolerance- Precision used
theGroupsOfNodes- list of nodes closed to each other returned

Definition at line 266 of file SMESH_OctreeNode.cxx.

References SMESH_AdvancedEditor.n1, and SMESH_AdvancedEditor.n2.

Referenced by FindCoincidentNodes(), and SMESH_MeshEditor.FindCoincidentNodes().

{
  TIDSortedNodeSet::iterator it1 = theSetOfNodes->begin();
  list<const SMDS_MeshNode*>::iterator it2;

  while (it1 != theSetOfNodes->end())
  {
    const SMDS_MeshNode * n1 = *it1;

    list<const SMDS_MeshNode*> ListOfCoincidentNodes;// Initialize the lists via a declaration, it's enough

    list<const SMDS_MeshNode*> * groupPtr = 0;

    // Searching for Nodes around n1 and put them in ListofCoincidentNodes.
    // Found nodes are also erased from theSetOfNodes
    FindCoincidentNodes(n1, theSetOfNodes, &ListOfCoincidentNodes, theTolerance);

    // We build a list {n1 + his neigbours} and add this list in theGroupsOfNodes
    for (it2 = ListOfCoincidentNodes.begin(); it2 != ListOfCoincidentNodes.end(); it2++)
    {
      const SMDS_MeshNode* n2 = *it2;
      if ( !groupPtr )
      {
        theGroupsOfNodes->push_back( list<const SMDS_MeshNode*>() );
        groupPtr = & theGroupsOfNodes->back();
        groupPtr->push_back( n1 );
      }
      if (groupPtr->front() > n2)
        groupPtr->push_front( n2 );
      else
        groupPtr->push_back( n2 );
    }
    if (groupPtr != 0)
      groupPtr->sort();

    theSetOfNodes->erase(it1);
    it1 = theSetOfNodes->begin();
  }
}
void SMESH_OctreeNode::FindCoincidentNodes ( TIDSortedNodeSet theSetOfNodes,
std::list< std::list< const SMDS_MeshNode * > > *  theGroupsOfNodes,
const double  theTolerance = 0.00001,
const int  maxLevel = -1,
const int  maxNbNodes = 5 
) [static]

Return in theGroupsOfNodes a list of group of nodes close to each other within theTolerance Search for all the nodes in theSetOfNodes Static Method : no need to create an SMESH_OctreeNode.

Parameters:
theSetOfNodes- set of nodes we look at, modified during research
theGroupsOfNodes- list of nodes closed to each other returned
theTolerance- Precision used, default value is 0.00001
maxLevel- Maximum level for SMESH_OctreeNode constructed, default value is -1 (Infinite)
maxNbNodes- maximum Nodes in a Leaf of the SMESH_OctreeNode constructed, default value is 5

Definition at line 246 of file SMESH_OctreeNode.cxx.

References FindCoincidentNodes().

{
  SMESH_OctreeNode theOctreeNode(theSetOfNodes, maxLevel, maxNbNodes, theTolerance);
  theOctreeNode.FindCoincidentNodes (&theSetOfNodes, theTolerance, theGroupsOfNodes);
}
void SMESH_OctreeNode::FindCoincidentNodes ( const SMDS_MeshNode Node,
TIDSortedNodeSet SetOfNodes,
std::list< const SMDS_MeshNode * > *  Result,
const double  precision 
) [protected]

Return a list of nodes closed to Node and remove it from SetOfNodes.

Note:
The Octree itself is also modified by this method
Parameters:
Node- We're searching the nodes next to him.
SetOfNodes- set of nodes in which we erase the found nodes
Result- list of nodes closed to Node
precision- Precision used

Definition at line 318 of file SMESH_OctreeNode.cxx.

References FindCoincidentNodes(), SMDS_MeshElement.GetID(), isInside(), SMESH_Octree.isLeaf(), SMESH_Octree.myChildren, myNodes, SMESH_AdvancedEditor.n2, PAL_MESH_041_mesh.p1, PAL_MESH_041_mesh.p2, SMDS_MeshNode.X(), SMDS_MeshNode.Y(), and SMDS_MeshNode.Z().

{
  gp_XYZ p(Node->X(), Node->Y(), Node->Z());
  bool isInsideBool = isInside(p, precision);

  if (isInsideBool)
  {
    // I'm only looking in the leaves, since all the nodes are stored there.
    if (isLeaf())
    {
      gp_Pnt p1 (Node->X(), Node->Y(), Node->Z());

      TIDSortedNodeSet myNodesCopy = myNodes;
      TIDSortedNodeSet::iterator it = myNodesCopy.begin();
      double tol2 = precision * precision;
      bool squareBool;

      while (it != myNodesCopy.end())
      {
        const SMDS_MeshNode* n2 = *it;
        // We're only looking at nodes with a superior Id.
        // JFA: Why?
        //if (Node->GetID() < n2->GetID())
        if (Node->GetID() != n2->GetID()) // JFA: for bug 0020185
        {
          gp_Pnt p2 (n2->X(), n2->Y(), n2->Z());
          // Distance optimized computation
          squareBool = (p1.SquareDistance( p2 ) <= tol2);

          // If n2 inside the SquareDistance, we add it in Result and remove it from SetOfNodes and myNodes
          if (squareBool)
          {
            Result->insert(Result->begin(), n2);
            SetOfNodes->erase( n2 );
            myNodes.erase( n2 );
          }
        }
        //myNodesCopy.erase( it );
        //it = myNodesCopy.begin();
        it++;
      }
      if (Result->size() > 0)
        myNodes.erase(Node); // JFA: for bug 0020185
    }
    else
    {
      // If I'm not a leaf, I'm going to see my children !
      for (int i = 0; i < 8; i++)
      {
        SMESH_OctreeNode* myChild = dynamic_cast<SMESH_OctreeNode*> (myChildren[i]);
        myChild->FindCoincidentNodes(Node, SetOfNodes, Result, precision);
      }
    }
  }
}
const Bnd_B3d& SMESH_Octree.getBox ( ) const [inherited]
int SMESH_Octree::getChildIndex ( double  x,
double  y,
double  z,
const gp_XYZ &  boxMiddle 
) const [inherited]

Return index of a child the given point is in.

Definition at line 118 of file SMESH_Octree.hxx.

Referenced by buildChildrenData(), NodesAround(), and UpdateByMoveNode().

{
  return (x > mid.X()) + ( y > mid.Y())*2 + (z > mid.Z())*4;
}
SMESH_OctreeNodeIteratorPtr SMESH_OctreeNode::GetChildrenIterator ( )
SMDS_NodeIteratorPtr SMESH_OctreeNode::GetNodeIterator ( )

Return nodes iterator.

Definition at line 430 of file SMESH_OctreeNode.cxx.

References myNodes.

Referenced by SMESH_NodeSearcherImpl.FindClosestTo().

const bool SMESH_OctreeNode::isInside ( const gp_XYZ &  p,
const double  precision = 0. 
) [virtual]

Tells us if Node is inside the current box with the precision "precision".

Parameters:
Node- Node
precision- The box is enlarged with this precision
Return values:
bool- True if Node is in the box within precision

Definition at line 109 of file SMESH_OctreeNode.cxx.

References SMESH_Octree.getBox().

Referenced by SMESH_NodeSearcherImpl.FindClosestTo(), FindCoincidentNodes(), NodesAround(), and UpdateByMoveNode().

{
  if (precision <= 0.)
    return !(getBox().IsOut(p));
  Bnd_B3d BoxWithPrecision = getBox();
  BoxWithPrecision.Enlarge(precision);
  return ! BoxWithPrecision.IsOut(p);
}
bool SMESH_Octree::isLeaf ( ) const [inherited]
int SMESH_Octree.level ( ) const [inherited]

Definition at line 67 of file SMESH_Octree.hxx.

References SMESH_Octree.myLevel.

Referenced by SMESH_Octree.isLeaf(), and SMESH_Octree.~SMESH_Octree().

{ return myLevel; }
double SMESH_Octree::maxSize ( ) const [inherited]

Compute the bigger dimension of my box.

Definition at line 176 of file SMESH_Octree.cxx.

References SMESH_Octree.myBox.

Referenced by SMESH_Octree.buildChildren(), SMESH_Octree.compute(), SMESH_ElementSearcherImpl.getTolerance(), NodesAround(), and SMESH_NodeSearcherImpl.SMESH_NodeSearcherImpl().

{
  if ( myBox )
  {
    gp_XYZ min = myBox->CornerMin();
    gp_XYZ max = myBox->CornerMax();
    gp_XYZ Size = (max - min);
    double returnVal = (Size.X()>Size.Y())?Size.X():Size.Y();
    return (returnVal>Size.Z())?returnVal:Size.Z();
  }
  return 0.;
}
int SMESH_OctreeNode.NbNodes ( ) const

Return nb nodes in a tree.

Definition at line 107 of file SMESH_OctreeNode.hxx.

References myNodes.

Referenced by SMESH_NodeSearcherImpl.FindClosestTo(), and NodesAround().

{ return myNodes.size(); }
bool SMESH_OctreeNode::NodesAround ( const gp_XYZ &  node,
std::map< double, const SMDS_MeshNode * > &  dist2Nodes,
double  precision 
)

Return in dist2Nodes nodes mapped to their square distance from Node.

Parameters:
node- node to find nodes closest to
dist2Nodes- map of found nodes and their distances
precision- radius of a sphere to check nodes inside
Return values:
bool- true if an exact overlapping found

Definition at line 188 of file SMESH_OctreeNode.cxx.

References SMESH_Octree.getBox(), SMESH_Octree.getChildIndex(), isInside(), SMESH_Octree.isLeaf(), SMESH_Octree.maxSize(), SMESH_Octree.myChildren, myNodes, NbNodes(), PAL_MESH_041_mesh.p1, and PAL_MESH_041_mesh.p2.

{
  if ( !dist2Nodes.empty() )
    precision = min ( precision, sqrt( dist2Nodes.begin()->first ));
  else if ( precision == 0. )
    precision = maxSize() / 2;

  //gp_XYZ p(node->X(), node->Y(), node->Z());
  if (isInside(node, precision))
  {
    if (!isLeaf())
    {
      // first check a child containing node
      gp_XYZ mid = (getBox().CornerMin() + getBox().CornerMax()) / 2.;
      int nodeChild  = getChildIndex( node.X(), node.Y(), node.Z(), mid );
      if ( ((SMESH_OctreeNode*) myChildren[nodeChild])->NodesAround(node, dist2Nodes, precision))
        return true;
      
      for (int i = 0; i < 8; i++)
        if ( i != nodeChild )
          if (((SMESH_OctreeNode*) myChildren[i])->NodesAround(node, dist2Nodes, precision))
            return true;
    }
    else if ( NbNodes() > 0 )
    {
      double minDist = precision * precision;
      gp_Pnt p1 ( node.X(), node.Y(), node.Z() );
      set<const SMDS_MeshNode*>::iterator nIt = myNodes.begin();
      for ( ; nIt != myNodes.end(); ++nIt )
      {
        gp_Pnt p2 ( (*nIt)->X(), (*nIt)->Y(), (*nIt)->Z() );
        double dist2 = p1.SquareDistance( p2 );
        if ( dist2 < minDist )
          dist2Nodes.insert( make_pair( minDist = dist2, *nIt ));
      }
//       if ( dist2Nodes.size() > 1 ) // leave only closest node in dist2Nodes
//         dist2Nodes.erase( ++dist2Nodes.begin(), dist2Nodes.end());

      return ( sqrt( minDist) <= precision * 1e-12 );
    }
  }
  return false;
}
void SMESH_OctreeNode::NodesAround ( const SMDS_MeshNode Node,
std::list< const SMDS_MeshNode * > *  Result,
const double  precision = 0. 
)

Return in Result a list of Nodes potentials to be near Node.

Parameters:
Node- Node
precision- precision used
Result- list of Nodes potentials to be near Node

Definition at line 156 of file SMESH_OctreeNode.cxx.

References isInside(), SMESH_Octree.isLeaf(), SMESH_Octree.myChildren, myNodes, NodesAround(), SMDS_MeshNode.X(), SMDS_MeshNode.Y(), and SMDS_MeshNode.Z().

Referenced by SMESH_NodeSearcherImpl.FindClosestTo(), and NodesAround().

{
  gp_XYZ p(Node->X(), Node->Y(), Node->Z());
  if (isInside(p, precision))
  {
    if (isLeaf())
    {
      Result->insert(Result->end(), myNodes.begin(), myNodes.end());
    }
    else
    {
      for (int i = 0; i < 8; i++)
      {
        SMESH_OctreeNode* myChild = dynamic_cast<SMESH_OctreeNode*> (myChildren[i]);
        myChild->NodesAround(Node, Result, precision);
      }
    }
  }
}
void SMESH_OctreeNode::UpdateByMoveNode ( const SMDS_MeshNode node,
const gp_Pnt &  toPnt 
)

Update data according to node movement.

Definition at line 383 of file SMESH_OctreeNode.cxx.

References SMESH_Octree.getBox(), SMESH_Octree.getChildIndex(), isInside(), SMESH_Octree.isLeaf(), SMESH_Octree.myChildren, myNodes, SMDS_MeshNode.X(), SMDS_MeshNode.Y(), and SMDS_MeshNode.Z().

{
  if ( isLeaf() )
  {
    TIDSortedNodeSet::iterator pNode = myNodes.find( node );
    bool nodeInMe = ( pNode != myNodes.end() );

    bool pointInMe = isInside( toPnt.Coord(), 1e-10 );

    if ( pointInMe != nodeInMe )
    {
      if ( pointInMe )
        myNodes.insert( node );
      else
        myNodes.erase( node );
    }
  }
  else if ( myChildren )
  {
    gp_XYZ mid = (getBox().CornerMin() + getBox().CornerMax()) / 2.;
    int nodeChild  = getChildIndex( node->X(), node->Y(), node->Z(), mid );
    int pointChild = getChildIndex( toPnt.X(), toPnt.Y(), toPnt.Z(), mid );
    if ( nodeChild != pointChild )
    {
      ((SMESH_OctreeNode*) myChildren[ nodeChild  ])->UpdateByMoveNode( node, toPnt );
      ((SMESH_OctreeNode*) myChildren[ pointChild ])->UpdateByMoveNode( node, toPnt );
    }
  }
}

Field Documentation

SMESH_Octree** SMESH_Octree.myChildren [protected, inherited]
SMESH_Octree* SMESH_Octree.myFather [protected, inherited]

Definition at line 94 of file SMESH_Octree.hxx.

Referenced by SMESH_Octree.buildChildren().

bool SMESH_Octree.myIsLeaf [protected, inherited]
const Limit* SMESH_Octree.myLimit [protected, inherited]

Definition at line 129 of file SMESH_OctreeNode.hxx.

Referenced by allocateOctreeChild(), buildChildrenData(), and buildRootBox().

Copyright © 2007-2011 CEA/DEN, EDF R&D, OPEN CASCADE
Copyright © 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS