//===========================================================================
/*!
- * \brief SMESH_Octree Constructor
- * \param maxLevel - The level max the octree can reach (If <0 unlimited)
+ * Constructor. limit must be provided at tree root construction.
+ * limit will be deleted by SMESH_Octree.
*/
//===========================================================================
-SMESH_Octree::SMESH_Octree (const int maxLevel, const double minBoxSize):
- myChildren(NULL),
- myFather(NULL),
- myLevel(0),
- myMaxLevel(maxLevel),
- myMinBoxSize(minBoxSize),
- myIsLeaf(-1)
+
+SMESH_Octree::SMESH_Octree (SMESH_Octree::Limit* limit):
+ myChildren(NULL),
+ myFather(NULL),
+ myIsLeaf( false ),
+ myLimit( limit ),
+ myLevel(0),
+ myBox(NULL)
+{
+}
+
+//================================================================================
+/*!
+ * \brief Compute the Octree
+ */
+//================================================================================
+
+void SMESH_Octree::compute()
{
- myBox = new Bnd_B3d();
+ if ( myLevel==0 )
+ {
+ myBox = buildRootBox();
+ if ( myLimit->myMinBoxSize > 0. && maxSize() <= myLimit->myMinBoxSize )
+ myIsLeaf = true;
+ else
+ buildChildren();
+ }
}
//======================================
* \brief SMESH_Octree Destructor
*/
//======================================
+
SMESH_Octree::~SMESH_Octree ()
{
if(myChildren != NULL)
{
- if(!myIsLeaf)
+ if(!isLeaf())
{
for(int i = 0; i<8; i++)
delete myChildren[i];
delete[] myChildren;
+ myChildren = 0;
}
}
- delete myBox;
-}
-
-//===========================================================================
-/*!
- * \brief Set the bounding box of the Octree
- * \param box - 3d Bounding Box of the Octree
- */
-//===========================================================================
-void SMESH_Octree::setBox(const Bnd_B3d* box)
-{
-// delete myBox;
-// myBox=new Bnd_B3d(*box);
- *myBox = *box;
-}
-
-//===========================================================================
-/*!
- * \brief Set box to the 3d Bounding Box of the Octree
- * \param box - Set box to the 3d Bounding Box of the Octree
- */
-//===========================================================================
-void SMESH_Octree::getBox(Bnd_B3d& box)
-{
-// if(box != NULL)
-// delete box;
-// box = new Bnd_B3d (*myBox);
- box = *myBox;
-}
-
-//===========================================================================
-/*!
- * \brief Set the max level of the Octree
- * \param maxLevel - The level max the octree can reach (If <0 unlimited)
- */
-//===========================================================================
-void SMESH_Octree::setMaxLevel(const int maxLevel)
-{myMaxLevel = maxLevel;}
-
-
-//===========================================================================
-/*!
- * \brief Compute the bigger dimension of the box
- * \param box - 3d Box
- * \retval double - bigger dimension of the box
- */
-//===========================================================================
-double SMESH_Octree::maxSize(const Bnd_B3d* box)
-{
- if(box ==NULL)
- return 0;
- gp_XYZ min = box->CornerMin();
- gp_XYZ max = box->CornerMax();
- gp_XYZ Size = (max - min);
- double returnVal = (Size.X()>Size.Y())?Size.X():Size.Y();
- return (returnVal>Size.Z())?returnVal:Size.Z();
-}
-
-//=============================
-/*!
- * \brief Compute the Octree
- */
-//=============================
-void SMESH_Octree::Compute()
-{
- // As soon as the Octree is a Leaf, I stop building his children
- if(!isLeaf())
- buildChildren();
+ if ( myBox )
+ delete myBox;
+ myBox = 0;
+ if ( level() == 0 )
+ delete myLimit;
+ myLimit = 0;
}
//=================================================================
* \brief Build the 8 children boxes and call buildChildrenData()
*/
//=================================================================
+
void SMESH_Octree::buildChildren()
{
+ if ( isLeaf() ) return;
+
myChildren = new SMESH_Octree*[8];
gp_XYZ min = myBox->CornerMin();
gp_XYZ childHsize = HSize/2.;
Standard_Real XminChild, YminChild, ZminChild;
- Bnd_B3d* box;
gp_XYZ minChild;
for (int i = 0; i < 8; i++)
{
ZminChild = (i<4)?min.Z():mid.Z();
minChild.SetCoord(XminChild, YminChild, ZminChild);
- box = new Bnd_B3d(minChild+childHsize,childHsize);
// 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] = allocateOctreeChild();
// and we assign to him its box.
- myChildren[i]->setBox(box);
- delete box;
+ myChildren[i]->myFather = this;
+ myChildren[i]->myLimit = myLimit;
+ myChildren[i]->myLevel = myLevel + 1;
+ myChildren[i]->myBox = new Bnd_B3d(minChild+childHsize,childHsize);
+ if ( myLimit->myMinBoxSize > 0. && myChildren[i]->maxSize() <= myLimit->myMinBoxSize )
+ myChildren[i]->myIsLeaf = true;
}
- // After building the 8 boxes, we put the data into the children..
+ // After building the 8 boxes, we put the data into the children.
buildChildrenData();
//After we pass to the next level of the Octree
- for (int i = 0; i < 8; i++)
- myChildren[i]->Compute();
+ for (int i = 0; i<8; i++)
+ myChildren[i]->buildChildren();
+}
+
+//================================================================================
+/*!
+ * \brief Tell if Octree is a leaf or not
+ * An inheriting class can influence it via myIsLeaf protected field
+ */
+//================================================================================
+
+bool SMESH_Octree::isLeaf() const
+{
+ return myIsLeaf || ((myLimit->myMaxLevel > 0) ? (level() >= myLimit->myMaxLevel) : false );
+}
+
+//===========================================================================
+/*!
+ * \brief Compute the bigger dimension of my box
+ */
+//===========================================================================
+
+double SMESH_Octree::maxSize() const
+{
+ 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.;
}