This commit is contained in:
eap 2013-07-24 12:43:59 +00:00
parent 45953e0114
commit 2e6e5e83cb

View File

@ -19,257 +19,257 @@
// //
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
// //
// SMESH SMESH_Tree : tree implementation // SMESH SMESH_Tree : tree implementation
// File : SMESH_Tree.hxx // File : SMESH_Tree.hxx
// Created : Tue Jan 16 16:00:00 2007 // Created : Tue Jan 16 16:00:00 2007
// Author : Nicolas Geimer & Aurélien Motteux (OCC) // Author : Nicolas Geimer & Aurélien Motteux (OCC)
// Module : SMESH // Module : SMESH
// //
#ifndef _SMESH_Tree_HXX_ #ifndef _SMESH_Tree_HXX_
#define _SMESH_Tree_HXX_ #define _SMESH_Tree_HXX_
#include "SMESH_Utils.hxx" #include "SMESH_Utils.hxx"
//================================================================================ //================================================================================
// Data limiting the tree height // Data limiting the tree height
struct SMESH_TreeLimit { struct SMESH_TreeLimit {
// MaxLevel of the Tree // MaxLevel of the Tree
int myMaxLevel; int myMaxLevel;
// Minimal size of the Box // Minimal size of the Box
double myMinBoxSize; double myMinBoxSize;
// Default: // Default:
// maxLevel-> 8^8 = 16777216 terminal trees at most // maxLevel-> 8^8 = 16777216 terminal trees at most
// minSize -> box size not checked // minSize -> box size not checked
SMESH_TreeLimit(int maxLevel=8, double minSize=0.):myMaxLevel(maxLevel),myMinBoxSize(minSize) {} SMESH_TreeLimit(int maxLevel=8, double minSize=0.):myMaxLevel(maxLevel),myMinBoxSize(minSize) {}
virtual ~SMESH_TreeLimit() {} // it can be inherited virtual ~SMESH_TreeLimit() {} // it can be inherited
}; };
//================================================================================ //================================================================================
/*! /*!
* \brief Base class for 2D and 3D trees * \brief Base class for 2D and 3D trees
*/ */
//================================================================================ //================================================================================
template< class BND_BOX, template< class BND_BOX,
int NB_CHILDREN> int NB_CHILDREN>
class SMESH_Tree class SMESH_Tree
{ {
public: public:
typedef BND_BOX box_type; typedef BND_BOX box_type;
// Constructor. limit must be provided at tree root construction. // Constructor. limit must be provided at tree root construction.
// limit will be deleted by SMESH_Tree // limit will be deleted by SMESH_Tree
SMESH_Tree (SMESH_TreeLimit* limit=0); SMESH_Tree (SMESH_TreeLimit* limit=0);
// Destructor // Destructor
virtual ~SMESH_Tree (); virtual ~SMESH_Tree ();
// Compute the Tree. Must be called by constructor of inheriting class // Compute the Tree. Must be called by constructor of inheriting class
void compute(); void compute();
// Tell if Tree is a leaf or not. // Tell if Tree is a leaf or not.
// An inheriting class can influence it via myIsLeaf protected field // An inheriting class can influence it via myIsLeaf protected field
bool isLeaf() const; bool isLeaf() const;
// Return its level // Return its level
int level() const { return myLevel; } int level() const { return myLevel; }
// Return Bounding Box of the Tree // Return Bounding Box of the Tree
const box_type* getBox() const { return myBox; } const box_type* getBox() const { return myBox; }
// Return height of the tree, full or from this level to topest leaf // Return height of the tree, full or from this level to topest leaf
int getHeight(const bool full=true) const; int getHeight(const bool full=true) const;
static int nbChildren() { return NB_CHILDREN; } static int nbChildren() { return NB_CHILDREN; }
// Compute the bigger dimension of my box // Compute the bigger dimension of my box
virtual double maxSize() const = 0; virtual double maxSize() const = 0;
protected: protected:
// Return box of the whole tree // Return box of the whole tree
virtual box_type* buildRootBox() = 0; virtual box_type* buildRootBox() = 0;
// Allocate a child // Allocate a child
virtual SMESH_Tree* newChild() const = 0; virtual SMESH_Tree* newChild() const = 0;
// Allocate a bndbox according to childIndex. childIndex is zero based // Allocate a bndbox according to childIndex. childIndex is zero based
virtual box_type* newChildBox(int childIndex) const = 0; virtual box_type* newChildBox(int childIndex) const = 0;
// Fill in data of the children // Fill in data of the children
virtual void buildChildrenData() = 0; virtual void buildChildrenData() = 0;
// members // members
// Array of children // Array of children
SMESH_Tree** myChildren; SMESH_Tree** myChildren;
// Point the father, NULL for the level 0 // Point the father, NULL for the level 0
SMESH_Tree* myFather; SMESH_Tree* myFather;
// Tell us if the Tree is a leaf or not // Tell us if the Tree is a leaf or not
bool myIsLeaf; bool myIsLeaf;
// Tree limit // Tree limit
const SMESH_TreeLimit* myLimit; const SMESH_TreeLimit* myLimit;
private: private:
// Build the children recursively // Build the children recursively
void buildChildren(); void buildChildren();
// Level of the Tree // Level of the Tree
int myLevel; int myLevel;
box_type* myBox; box_type* myBox;
}; };
//=========================================================================== //===========================================================================
/*! /*!
* Constructor. limit must be provided at tree root construction. * Constructor. limit must be provided at tree root construction.
* limit will be deleted by SMESH_Tree. * limit will be deleted by SMESH_Tree.
*/ */
//=========================================================================== //===========================================================================
template< class BND_BOX, int NB_CHILDREN> template< class BND_BOX, int NB_CHILDREN>
SMESH_Tree<BND_BOX,NB_CHILDREN>::SMESH_Tree (SMESH_TreeLimit* limit): SMESH_Tree<BND_BOX,NB_CHILDREN>::SMESH_Tree (SMESH_TreeLimit* limit):
myChildren(0), myChildren(0),
myFather(0), myFather(0),
myIsLeaf( false ), myIsLeaf( false ),
myLimit( limit ), myLimit( limit ),
myLevel(0), myLevel(0),
myBox(0) myBox(0)
{ {
if ( !myLimit ) myLimit = new SMESH_TreeLimit(); if ( !myLimit ) myLimit = new SMESH_TreeLimit();
} }
//================================================================================ //================================================================================
/*! /*!
* \brief Compute the Tree * \brief Compute the Tree
*/ */
//================================================================================ //================================================================================
template< class BND_BOX, int NB_CHILDREN> template< class BND_BOX, int NB_CHILDREN>
void SMESH_Tree<BND_BOX,NB_CHILDREN>::compute() void SMESH_Tree<BND_BOX,NB_CHILDREN>::compute()
{ {
if ( myLevel==0 ) if ( myLevel==0 )
{ {
myBox = buildRootBox(); myBox = buildRootBox();
if ( myLimit->myMinBoxSize > 0. && maxSize() <= myLimit->myMinBoxSize ) if ( myLimit->myMinBoxSize > 0. && maxSize() <= myLimit->myMinBoxSize )
myIsLeaf = true; myIsLeaf = true;
else else
buildChildren(); buildChildren();
} }
} }
//====================================== //======================================
/*! /*!
* \brief SMESH_Tree Destructor * \brief SMESH_Tree Destructor
*/ */
//====================================== //======================================
template< class BND_BOX, int NB_CHILDREN> template< class BND_BOX, int NB_CHILDREN>
SMESH_Tree<BND_BOX,NB_CHILDREN>::~SMESH_Tree () SMESH_Tree<BND_BOX,NB_CHILDREN>::~SMESH_Tree ()
{ {
if ( myChildren ) if ( myChildren )
{ {
if ( !isLeaf() ) if ( !isLeaf() )
{ {
for(int i = 0; i<NB_CHILDREN; i++) for(int i = 0; i<NB_CHILDREN; i++)
delete myChildren[i]; delete myChildren[i];
delete[] myChildren; delete[] myChildren;
myChildren = 0; myChildren = 0;
} }
} }
if ( myBox ) if ( myBox )
delete myBox; delete myBox;
myBox = 0; myBox = 0;
if ( level() == 0 ) if ( level() == 0 )
delete myLimit; delete myLimit;
myLimit = 0; myLimit = 0;
} }
//================================================================= //=================================================================
/*! /*!
* \brief Build the children boxes and call buildChildrenData() * \brief Build the children boxes and call buildChildrenData()
*/ */
//================================================================= //=================================================================
template< class BND_BOX, int NB_CHILDREN> template< class BND_BOX, int NB_CHILDREN>
void SMESH_Tree<BND_BOX,NB_CHILDREN>::buildChildren() void SMESH_Tree<BND_BOX,NB_CHILDREN>::buildChildren()
{ {
if ( isLeaf() ) return; if ( isLeaf() ) return;
myChildren = new SMESH_Tree*[NB_CHILDREN]; myChildren = new SMESH_Tree*[NB_CHILDREN];
// get the whole model size // get the whole model size
double rootSize = 0; double rootSize = 0;
{ {
SMESH_Tree* root = this; SMESH_Tree* root = this;
while ( root->myLevel > 0 ) while ( root->myLevel > 0 )
root = root->myFather; root = root->myFather;
rootSize = root->maxSize(); rootSize = root->maxSize();
} }
for (int i = 0; i < NB_CHILDREN; i++) for (int i = 0; i < NB_CHILDREN; i++)
{ {
// The child is of the same type than its father (For instance, a SMESH_OctreeNode) // The child is of the same type than its father (For instance, a SMESH_OctreeNode)
// We allocate the memory we need for the child // We allocate the memory we need for the child
myChildren[i] = newChild(); myChildren[i] = newChild();
// and we assign to him its box. // and we assign to him its box.
myChildren[i]->myFather = this; myChildren[i]->myFather = this;
myChildren[i]->myLimit = myLimit; myChildren[i]->myLimit = myLimit;
myChildren[i]->myLevel = myLevel + 1; myChildren[i]->myLevel = myLevel + 1;
myChildren[i]->myBox = newChildBox( i ); myChildren[i]->myBox = newChildBox( i );
myChildren[i]->myBox->Enlarge( rootSize * 1e-10 ); myChildren[i]->myBox->Enlarge( rootSize * 1e-10 );
if ( myLimit->myMinBoxSize > 0. && myChildren[i]->maxSize() <= myLimit->myMinBoxSize ) if ( myLimit->myMinBoxSize > 0. && myChildren[i]->maxSize() <= myLimit->myMinBoxSize )
myChildren[i]->myIsLeaf = true; myChildren[i]->myIsLeaf = true;
} }
// After building the NB_CHILDREN boxes, we put the data into the children. // After building the NB_CHILDREN boxes, we put the data into the children.
buildChildrenData(); buildChildrenData();
//After we pass to the next level of the Tree //After we pass to the next level of the Tree
for (int i = 0; i<NB_CHILDREN; i++) for (int i = 0; i<NB_CHILDREN; i++)
myChildren[i]->buildChildren(); myChildren[i]->buildChildren();
} }
//================================================================================ //================================================================================
/*! /*!
* \brief Tell if Tree is a leaf or not * \brief Tell if Tree is a leaf or not
* An inheriting class can influence it via myIsLeaf protected field * An inheriting class can influence it via myIsLeaf protected field
*/ */
//================================================================================ //================================================================================
template< class BND_BOX, int NB_CHILDREN> template< class BND_BOX, int NB_CHILDREN>
bool SMESH_Tree<BND_BOX,NB_CHILDREN>::isLeaf() const bool SMESH_Tree<BND_BOX,NB_CHILDREN>::isLeaf() const
{ {
return myIsLeaf || ((myLimit->myMaxLevel > 0) ? (level() >= myLimit->myMaxLevel) : false ); return myIsLeaf || ((myLimit->myMaxLevel > 0) ? (level() >= myLimit->myMaxLevel) : false );
} }
//================================================================================ //================================================================================
/*! /*!
* \brief Return height of the tree, full or from this level to topest leaf * \brief Return height of the tree, full or from this level to topest leaf
*/ */
//================================================================================ //================================================================================
template< class BND_BOX, int NB_CHILDREN> template< class BND_BOX, int NB_CHILDREN>
int SMESH_Tree<BND_BOX,NB_CHILDREN>::getHeight(const bool full) const int SMESH_Tree<BND_BOX,NB_CHILDREN>::getHeight(const bool full) const
{ {
if ( full && myFather ) if ( full && myFather )
return myFather->getHeight( true ); return myFather->getHeight( true );
if ( isLeaf() ) if ( isLeaf() )
return 1; return 1;
int heigth = 0; int heigth = 0;
for (int i = 0; i<NB_CHILDREN; i++) for (int i = 0; i<NB_CHILDREN; i++)
{ {
int h = myChildren[i]->getHeight( false ); int h = myChildren[i]->getHeight( false );
if ( h > heigth ) if ( h > heigth )
heigth = h; heigth = h;
} }
return heigth + 1; return heigth + 1;
} }
#endif #endif