moab
AdaptiveKDTree.hpp
Go to the documentation of this file.
00001 
00006 #ifndef MOAB_ADAPTIVE_KD_TREE_HPP
00007 #define MOAB_ADAPTIVE_KD_TREE_HPP
00008 
00009 #include "moab/Types.hpp"
00010 #include "moab/Tree.hpp"
00011 
00012 #include <string>
00013 #include <vector>
00014 #include <math.h>
00015 
00016 namespace moab {
00017 
00018     class AdaptiveKDTreeIter;
00019     class Interface;
00020     class Range;
00021 
00022     class AdaptiveKDTree : public Tree
00023     {
00024   public:
00025 
00026       AdaptiveKDTree( Interface* iface);
00027 
00036       AdaptiveKDTree(Interface* iface, const Range &entities, 
00037                      EntityHandle *tree_root_set = NULL, FileOptions *opts = NULL);
00038 
00039       ~AdaptiveKDTree();
00040 
00046       ErrorCode parse_options(FileOptions &options);
00047 
00061       virtual ErrorCode build_tree(const Range& entities,
00062                                    EntityHandle *tree_root_set = NULL,
00063                                    FileOptions *options = NULL);
00064 
00066       virtual ErrorCode reset_tree();
00067 
00086       virtual ErrorCode point_search(const double *point,
00087                                      EntityHandle& leaf_out,
00088                                      const double iter_tol = 1.0e-10,
00089                                      const double inside_tol = 1.0e-6,
00090                                      bool *multiple_leaves = NULL,
00091                                      EntityHandle *start_node = NULL,
00092                                      CartVect *params = NULL);
00093 
00112       ErrorCode point_search(const double *point,
00113                              AdaptiveKDTreeIter& leaf_it,
00114                              const double iter_tol = 1.0e-10,
00115                              const double inside_tol = 1.0e-6,
00116                              bool *multiple_leaves = NULL,
00117                              EntityHandle *start_node = NULL);
00118       
00134       virtual ErrorCode distance_search(const double *point,
00135                                         const double distance,
00136                                         std::vector<EntityHandle>& leaves_out,
00137                                         const double iter_tol = 1.0e-10,
00138                                         const double inside_tol = 1.0e-6,
00139                                         std::vector<double> *dists_out = NULL,
00140                                         std::vector<CartVect> *params_out = NULL,
00141                                         EntityHandle *start_node = NULL);
00142       
00143       ErrorCode get_info(EntityHandle root,
00144                          double min[3], double max[3], 
00145                          unsigned int &dep);
00146   
00148       enum Axis { X = 0, Y = 1, Z = 2 };
00149   
00151       struct Plane {
00152         double coord;  
00153         int norm; 
00154     
00156         bool left_side( const double point[3] ) {
00157           return point[norm] < coord;
00158         }
00160         bool right_side( const double point[3] ) {
00161           return point[norm] > coord;
00162         }
00164         double distance( const double point[3] ) const {
00165           return fabs(point[norm] - coord);
00166         }
00167       };
00168   
00170       ErrorCode get_split_plane( EntityHandle node, Plane& plane );
00171   
00173       ErrorCode set_split_plane( EntityHandle node, const Plane& plane );
00174   
00176       ErrorCode get_tree_iterator( EntityHandle tree_root,
00177                                    AdaptiveKDTreeIter& result );
00178   
00180       ErrorCode get_last_iterator( EntityHandle tree_root,
00181                                    AdaptiveKDTreeIter& result );
00182 
00184       ErrorCode get_sub_tree_iterator( EntityHandle tree_root,
00185                                        const double box_min[3], 
00186                                        const double box_max[3],
00187                                        AdaptiveKDTreeIter& result );
00188 
00191       ErrorCode split_leaf( AdaptiveKDTreeIter& leaf, Plane plane );
00192 
00195       ErrorCode split_leaf( AdaptiveKDTreeIter& leaf, 
00196                             Plane plane,
00197                             EntityHandle& left_child,
00198                             EntityHandle& right_child );
00201       ErrorCode split_leaf( AdaptiveKDTreeIter& leaf, 
00202                             Plane plane,
00203                             const Range& left_entities,
00204                             const Range& right_entities );
00205 
00208       ErrorCode split_leaf( AdaptiveKDTreeIter& leaf, 
00209                             Plane plane,
00210                             const std::vector<EntityHandle>& left_entities,
00211                             const std::vector<EntityHandle>& right_entities );
00212   
00216       ErrorCode merge_leaf( AdaptiveKDTreeIter& iter );
00217   
00222       ErrorCode closest_triangle( EntityHandle tree_root,
00223                                   const double from_coords[3],
00224                                   double closest_point_out[3],
00225                                   EntityHandle& triangle_out );
00226 
00227       ErrorCode sphere_intersect_triangles( EntityHandle tree_root,
00228                                             const double center[3],
00229                                             double radius,
00230                                             std::vector<EntityHandle>& triangles );
00231 
00232       ErrorCode ray_intersect_triangles( EntityHandle tree_root,
00233                                          const double tolerance,
00234                                          const double ray_unit_dir[3],
00235                                          const double ray_base_pt[3],
00236                                          std::vector<EntityHandle>& triangles_out,
00237                                          std::vector<double>& distance_out,
00238                                          int result_count_limit = 0,
00239                                          double distance_limit = -1.0);
00240 
00241       ErrorCode compute_depth( EntityHandle root, 
00242                                unsigned int& min_depth,
00243                                unsigned int& max_depth );
00244   
00246       enum CandidatePlaneSet {
00248           SUBDIVISION=0,
00250           SUBDIVISION_SNAP, // = 1
00252           VERTEX_MEDIAN, // = 2
00254           VERTEX_SAMPLE // = 3
00255       };
00256   
00258       virtual ErrorCode print();
00259       
00260   private:
00261       friend class AdaptiveKDTreeIter;
00262 
00263       ErrorCode init();
00264   
00266       ErrorCode find_close_triangle( EntityHandle root,
00267                                      const double from_point[3],
00268                                      double pt[3],
00269                                      EntityHandle& triangle );
00270 
00271       ErrorCode make_tag( Interface* iface, std::string name, TagType storage, 
00272                           DataType type, int count, void* default_val, Tag& tag_handle,
00273                           std::vector<Tag>& created_tags );
00274   
00275       ErrorCode intersect_children_with_elems(
00276           const Range& elems,
00277           AdaptiveKDTree::Plane plane,
00278           double eps,
00279           CartVect box_min,
00280           CartVect box_max,
00281           Range& left_tris,
00282           Range& right_tris,
00283           Range& both_tris,
00284           double& metric_value );
00285 
00286       ErrorCode best_subdivision_snap_plane( int num_planes,
00287                                                     const AdaptiveKDTreeIter& iter,
00288                                                     Range& best_left,
00289                                                     Range& best_right,
00290                                                     Range& best_both,
00291                                                     AdaptiveKDTree::Plane& best_plane,
00292                                                     std::vector<double>& tmp_data,
00293                                                     double eps );
00294   
00295       ErrorCode best_subdivision_plane( int num_planes,
00296                                                const AdaptiveKDTreeIter& iter,
00297                                                Range& best_left,
00298                                                Range& best_right,
00299                                                Range& best_both,
00300                                                AdaptiveKDTree::Plane& best_plane,
00301                                                double eps );
00302   
00303       ErrorCode best_vertex_median_plane( int num_planes,
00304                                                  const AdaptiveKDTreeIter& iter,
00305                                                  Range& best_left,
00306                                                  Range& best_right,
00307                                                  Range& best_both,
00308                                                  AdaptiveKDTree::Plane& best_plane,
00309                                                  std::vector<double>& coords,
00310                                                  double eps);
00311   
00312       ErrorCode best_vertex_sample_plane( int num_planes,
00313                                                  const AdaptiveKDTreeIter& iter,
00314                                                  Range& best_left,
00315                                                  Range& best_right,
00316                                                  Range& best_both,
00317                                                  AdaptiveKDTree::Plane& best_plane,
00318                                                  std::vector<double>& coords,
00319                                                  std::vector<EntityHandle>& indices,
00320                                                  double eps );
00321 
00322       static const char *treeName;
00323       
00324       Tag planeTag, axisTag;
00325 
00326       unsigned splitsPerDir;
00327   
00328       CandidatePlaneSet planeSet;
00329     };
00330                     
00331 
00333     class AdaptiveKDTreeIter
00334     {
00335   public:
00336 
00337       enum Direction { LEFT = 0, RIGHT = 1 };
00338 
00339   private:
00340   
00341       struct StackObj {
00342         StackObj( EntityHandle e, double c ) : entity(e), coord(c) {}
00343         StackObj() {}
00344         EntityHandle entity; 
00345         double coord;          
00346       };
00347   
00348       enum { BMIN = 0, BMAX = 1 };  
00349   
00350       CartVect mBox[2];                
00351       AdaptiveKDTree* treeTool;       
00352       std::vector<StackObj> mStack;     
00353       mutable std::vector<EntityHandle> childVect; 
00354   
00357       ErrorCode step_to_first_leaf( Direction direction );
00358 
00359       friend class AdaptiveKDTree;
00360   public:
00361 
00362       AdaptiveKDTreeIter() : treeTool(0), childVect(2) {}
00363   
00364       ErrorCode initialize( AdaptiveKDTree* tool,
00365                             EntityHandle root,
00366                             const double box_min[3],
00367                             const double box_max[3],
00368                             Direction direction );
00369 
00370       AdaptiveKDTree* tool() const
00371           { return treeTool; }
00372 
00374       EntityHandle handle() const
00375           { return mStack.back().entity; }
00376   
00378       const double* box_min() const 
00379           { return mBox[BMIN].array(); }
00380     
00382       const double* box_max() const 
00383           { return mBox[BMAX].array(); }
00384   
00385       double volume() const
00386           { return (mBox[BMAX][0] - mBox[BMIN][0]) * 
00387                 (mBox[BMAX][1] - mBox[BMIN][1]) * 
00388                 (mBox[BMAX][2] - mBox[BMIN][2]); }
00389   
00391       bool intersects( const AdaptiveKDTree::Plane& plane ) const
00392           { return mBox[BMIN][plane.norm] <= plane.coord &&
00393                 mBox[BMAX][plane.norm] >= plane.coord; }
00394   
00396       unsigned depth() const
00397           { return mStack.size(); }
00398   
00403       ErrorCode step( Direction direction );
00404 
00409       ErrorCode step() { return step(RIGHT); }
00410 
00415       ErrorCode back() { return step(LEFT); }
00416   
00417   
00430       ErrorCode sibling_side( AdaptiveKDTree::Axis& axis_out, bool& neg_out ) const;
00431 
00455       ErrorCode get_neighbors( AdaptiveKDTree::Axis norm, bool neg,
00456                                std::vector<AdaptiveKDTreeIter>& results,
00457                                double epsilon = 0.0 ) const;
00458   
00460       ErrorCode get_parent_split_plane( AdaptiveKDTree::Plane& plane ) const;
00461   
00464       bool is_sibling( const AdaptiveKDTreeIter& other_leaf ) const;
00465   
00468       bool is_sibling( EntityHandle other_leaf ) const;
00469   
00474       bool sibling_is_forward( ) const;
00475   
00491       bool intersect_ray( const double ray_point[3],
00492                           const double ray_vect[3],
00493                           double& t_enter, double& t_exit ) const;
00494     };
00495 
00496     inline ErrorCode AdaptiveKDTree::reset_tree()
00497     {
00498       return delete_tree_sets();
00499     }
00500 
00501 } // namespace moab 
00502 
00503 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines