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