Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "SMESH_Octree.hxx"
00030
00031
00036
00037
00038 SMESH_Octree::SMESH_Octree (SMESH_Octree::Limit* limit):
00039 myChildren(NULL),
00040 myFather(NULL),
00041 myIsLeaf( false ),
00042 myLimit( limit ),
00043 myLevel(0),
00044 myBox(NULL)
00045 {
00046 }
00047
00048
00052
00053
00054 void SMESH_Octree::compute()
00055 {
00056 if ( myLevel==0 )
00057 {
00058 myBox = buildRootBox();
00059 if ( myLimit->myMinBoxSize > 0. && maxSize() <= myLimit->myMinBoxSize )
00060 myIsLeaf = true;
00061 else
00062 buildChildren();
00063 }
00064 }
00065
00066
00070
00071
00072 SMESH_Octree::~SMESH_Octree ()
00073 {
00074 if(myChildren != NULL)
00075 {
00076 if(!isLeaf())
00077 {
00078 for(int i = 0; i<8; i++)
00079 delete myChildren[i];
00080 delete[] myChildren;
00081 myChildren = 0;
00082 }
00083 }
00084 if ( myBox )
00085 delete myBox;
00086 myBox = 0;
00087 if ( level() == 0 )
00088 delete myLimit;
00089 myLimit = 0;
00090 }
00091
00092
00096
00097
00098 void SMESH_Octree::buildChildren()
00099 {
00100 if ( isLeaf() ) return;
00101
00102 myChildren = new SMESH_Octree*[8];
00103
00104 gp_XYZ min = myBox->CornerMin();
00105 gp_XYZ max = myBox->CornerMax();
00106 gp_XYZ HSize = (max - min)/2.;
00107 gp_XYZ mid = min + HSize;
00108 gp_XYZ childHsize = HSize/2.;
00109
00110
00111 double rootSize = 0;
00112 {
00113 SMESH_Octree* root = this;
00114 while ( root->myLevel > 0 )
00115 root = root->myFather;
00116 rootSize = root->maxSize();
00117 }
00118 Standard_Real XminChild, YminChild, ZminChild;
00119 gp_XYZ minChild;
00120 for (int i = 0; i < 8; i++)
00121 {
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132 XminChild = (i%2==0)?min.X():mid.X();
00133 YminChild = ((i%4)/2==0)?min.Y():mid.Y();
00134 ZminChild = (i<4)?min.Z():mid.Z();
00135 minChild.SetCoord(XminChild, YminChild, ZminChild);
00136
00137
00138
00139 myChildren[i] = allocateOctreeChild();
00140
00141 myChildren[i]->myFather = this;
00142 myChildren[i]->myLimit = myLimit;
00143 myChildren[i]->myLevel = myLevel + 1;
00144 myChildren[i]->myBox = new Bnd_B3d(minChild+childHsize,childHsize);
00145 myChildren[i]->myBox->Enlarge( rootSize * 1e-10 );
00146 if ( myLimit->myMinBoxSize > 0. && myChildren[i]->maxSize() <= myLimit->myMinBoxSize )
00147 myChildren[i]->myIsLeaf = true;
00148 }
00149
00150
00151 buildChildrenData();
00152
00153
00154 for (int i = 0; i<8; i++)
00155 myChildren[i]->buildChildren();
00156 }
00157
00158
00163
00164
00165 bool SMESH_Octree::isLeaf() const
00166 {
00167 return myIsLeaf || ((myLimit->myMaxLevel > 0) ? (level() >= myLimit->myMaxLevel) : false );
00168 }
00169
00170
00174
00175
00176 double SMESH_Octree::maxSize() const
00177 {
00178 if ( myBox )
00179 {
00180 gp_XYZ min = myBox->CornerMin();
00181 gp_XYZ max = myBox->CornerMax();
00182 gp_XYZ Size = (max - min);
00183 double returnVal = (Size.X()>Size.Y())?Size.X():Size.Y();
00184 return (returnVal>Size.Z())?returnVal:Size.Z();
00185 }
00186 return 0.;
00187 }