Mesh Oriented datABase  (version 5.6.0)
An array-based unstructured mesh library
KDTree.cpp
Go to the documentation of this file.
1 /** @example KDTree.cpp
2  * This example demonstrates adaptive kD-tree for point location in hexahedral meshes.
3  * It shows how to load a hexahedral mesh, build an adaptive kD-tree for efficient spatial queries,
4  * find hexahedra containing specified points, and use geometric utilities for point-in-hex tests.
5  * The adaptive kD-tree provides efficient spatial partitioning for point location queries in large meshes.
6  */
7 
8 #include "moab/Core.hpp"
10 #include "moab/Range.hpp"
11 #include "moab/GeomUtil.hpp"
12 
13 #include <iostream>
14 #include <string>
15 
16 const double EPSILON = 1e-6; // tolerance to use in intersection checks
17 
18 // Help with error handling. Given ErrorCode, print
19 // corresponding string and any available message.
21 {
22  std::string message;
23  std::string code;
24  if( moab::MB_SUCCESS != mb.get_last_error( message ) ) message.clear();
25  code = mb.get_error_string( err );
26  std::cerr << "Error: " << code << std::endl;
27  if( !message.empty() ) std::cerr << " " << message << std::endl;
28 }
29 
30 // Print diagnostic info for unexpected failures.
31 #define CHKERR( err ) \
32  do \
33  { \
34  if( moab::MB_SUCCESS != ( err ) ) \
35  { \
36  print_error( mb, ( err ) ); \
37  std::cerr << "Unexpected failure at: " << __FILE__ << ":" << __LINE__ << std::endl; \
38  return 2; \
39  } \
40  } while( false )
41 
42 // Given an entity set and a point, find the hex contained in the
43 // entity set which in turn contains the specified point. Returns
44 // 0 if point is not in any hexahedron.
46 
47 // Print hex containing point.
49 
50 int main()
51 {
52  // Ask user for file to read
53  std::string filename;
54  std::cout << "Hex mesh file name: ";
55  std::cin >> filename;
56 
57  // Read file into MOAB instance
58  moab::ErrorCode rval;
61  MB_CHK_SET_ERR( mb.load_file( filename.c_str() ), "File load failed" );
62 
63  // Get all hex elemeents
64  moab::Range elems;
65  MB_CHK_SET_ERR( mb.get_entities_by_type( 0, moab::MBHEX, elems ), "Failed to get hexahedra" );
66  if( elems.empty() )
67  {
68  std::cerr << filename << ": file containd no hexahedra" << std::endl;
69  return 1;
70  }
71 
72  // Build a kD-tree from hex elements
73  moab::EntityHandle tree_root;
74  moab::AdaptiveKDTree tool( &mb );
75  MB_CHK_SET_ERR( tool.build_tree( elems, tree_root ), "Failed to build kD-tree" );
76 
77  // Loop forever (or until EOF), asking user for a point
78  // to query and printing the hex element containing that
79  // point.
80  for( ;; )
81  {
82  double point[3];
83  std::cout << "Point coordinates: ";
84  if( !( std::cin >> point[0] >> point[1] >> point[2] ) ) break;
85 
86  moab::EntityHandle leaf;
87  MB_CHK_SET_ERR( tool.leaf_containing_point( tree_root, point, leaf ), "Failed to find leaf containing point" );
88  moab::EntityHandle hex = hex_containing_point( mb, leaf, point );
89  if( 0 == hex )
90  std::cout << "Point is not contained in any hexahedron." << std::endl;
91  else
92  print_hex( mb, hex );
93  }
94 
95  return 0;
96 }
97 
99 {
100  moab::ErrorCode rval;
101  moab::CartVect pt( point ); // input location
102  moab::CartVect coords[8]; // coordinates of corners of hexahedron
103  const moab::EntityHandle* conn; // hex connectivity
104  int conn_len;
105 
106  // Get hexes in leaf
107  std::vector< moab::EntityHandle > hexes;
108  MB_CHK_SET_ERR( mb.get_entities_by_type( set, moab::MBHEX, hexes ), "Failed to get hexahedra from set" );
109 
110  // Check which hex the point is in
111  std::vector< moab::EntityHandle >::const_iterator i;
112  for( i = hexes.begin(); i != hexes.end(); ++i )
113  {
114  MB_CHK_SET_ERR( mb.get_connectivity( *i, conn, conn_len ), "Failed to get connectivity" );
115  MB_CHK_SET_ERR( mb.get_coords( conn, 8, &coords[0][0] ), "Failed to get coordinates" );
116  if( moab::GeomUtil::point_in_trilinear_hex( coords, pt, EPSILON ) ) return *i;
117  }
118 
119  // Return 0 if no hex contains point.
120  return 0;
121 }
122 
124 {
125  // Get MOAB's internal ID for hex element
126  int id = mb.id_from_handle( hex );
127 
128  // Get vertex handles for hex corners
129  const moab::EntityHandle* conn; // hex connectivity
130  int conn_len;
131  mb.get_connectivity( hex, conn, conn_len );
132 
133  // Get coordinates of vertices
134  double coords[3 * 8];
135  mb.get_coords( conn, 8, coords );
136 
137  // Print
138  std::cout << " Point is in hex " << id << " with corners: " << std::endl;
139  for( int i = 0; i < 8; ++i )
140  {
141  std::cout << " (" << coords[3 * i] << ", " << coords[3 * i + 1] << ", " << coords[3 * i + 2] << ")"
142  << std::endl;
143  }
144 }