+ElementsOnShape::
+OctreeClassifier::OctreeClassifier( const std::vector< ElementsOnShape::Classifier* >& classifiers )
+ :SMESH_Octree( new SMESH_TreeLimit )
+{
+ myClassifiers = classifiers;
+ compute();
+}
+
+ElementsOnShape::
+OctreeClassifier::OctreeClassifier( const OctreeClassifier* otherTree,
+ const std::vector< ElementsOnShape::Classifier >& clsOther,
+ std::vector< ElementsOnShape::Classifier >& cls )
+ :SMESH_Octree( new SMESH_TreeLimit )
+{
+ myBox = new Bnd_B3d( *otherTree->getBox() );
+
+ if (( myIsLeaf = otherTree->isLeaf() ))
+ {
+ myClassifiers.resize( otherTree->myClassifiers.size() );
+ for ( size_t i = 0; i < otherTree->myClassifiers.size(); ++i )
+ {
+ int ind = otherTree->myClassifiers[i] - & clsOther[0];
+ myClassifiers[ i ] = & cls[ ind ];
+ }
+ }
+ else if ( otherTree->myChildren )
+ {
+ myChildren = new SMESH_Tree< Bnd_B3d, 8 > * [ 8 ];
+ for ( int i = 0; i < nbChildren(); i++ )
+ myChildren[i] =
+ new OctreeClassifier( static_cast<const OctreeClassifier*>( otherTree->myChildren[i]),
+ clsOther, cls );
+ }
+}
+
+void ElementsOnShape::
+OctreeClassifier::GetClassifiersAtPoint( const gp_XYZ& point,
+ std::vector< ElementsOnShape::Classifier* >& result )
+{
+ if ( getBox()->IsOut( point ))
+ return;
+
+ if ( isLeaf() )
+ {
+ for ( size_t i = 0; i < myClassifiers.size(); ++i )
+ if ( !myClassifiers[i]->GetBndBox()->IsOut( point ))
+ result.push_back( myClassifiers[i] );
+ }
+ else
+ {
+ for (int i = 0; i < nbChildren(); i++)
+ ((OctreeClassifier*) myChildren[i])->GetClassifiersAtPoint( point, result );
+ }
+}
+
+void ElementsOnShape::OctreeClassifier::buildChildrenData()
+{
+ // distribute myClassifiers among myChildren
+
+ const int childFlag[8] = { 0x0000001,
+ 0x0000002,
+ 0x0000004,
+ 0x0000008,
+ 0x0000010,
+ 0x0000020,
+ 0x0000040,
+ 0x0000080 };
+ int nbInChild[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+
+ for ( size_t i = 0; i < myClassifiers.size(); ++i )
+ {
+ for ( int j = 0; j < nbChildren(); j++ )
+ {
+ if ( !myClassifiers[i]->GetBndBox()->IsOut( *myChildren[j]->getBox() ))
+ {
+ myClassifiers[i]->SetFlag( childFlag[ j ]);
+ ++nbInChild[ j ];
+ }
+ }
+ }
+
+ for ( int j = 0; j < nbChildren(); j++ )
+ {
+ OctreeClassifier* child = static_cast<OctreeClassifier*>( myChildren[ j ]);
+ child->myClassifiers.resize( nbInChild[ j ]);
+ for ( size_t i = 0; nbInChild[ j ] && i < myClassifiers.size(); ++i )
+ {
+ if ( myClassifiers[ i ]->IsSetFlag( childFlag[ j ]))
+ {
+ --nbInChild[ j ];
+ child->myClassifiers[ nbInChild[ j ]] = myClassifiers[ i ];
+ myClassifiers[ i ]->UnsetFlag( childFlag[ j ]);
+ }
+ }
+ }
+ SMESHUtils::FreeVector( myClassifiers );
+
+ // define if a child isLeaf()
+ for ( int i = 0; i < nbChildren(); i++ )
+ {
+ OctreeClassifier* child = static_cast<OctreeClassifier*>( myChildren[ i ]);
+ child->myIsLeaf = ( child->myClassifiers.size() <= 5 );
+ }
+}
+
+Bnd_B3d* ElementsOnShape::OctreeClassifier::buildRootBox()
+{
+ Bnd_B3d* box = new Bnd_B3d;
+ for ( size_t i = 0; i < myClassifiers.size(); ++i )
+ box->Add( *myClassifiers[i]->GetBndBox() );
+ return box;
+}