MOAB: Mesh Oriented datABase
(version 5.4.1)
|
00001 #include "moab/BSPTreePoly.hpp" 00002 #include "TestUtil.hpp" 00003 #include "moab/CartVect.hpp" 00004 00005 using namespace moab; 00006 00007 void test_construct_from_hex(); 00008 void test_cut_with_plane(); 00009 void test_volume(); 00010 00011 int main() 00012 { 00013 int error_count = 0; 00014 error_count += RUN_TEST( test_construct_from_hex ); 00015 error_count += RUN_TEST( test_cut_with_plane ); 00016 error_count += RUN_TEST( test_volume ); 00017 return error_count; 00018 } 00019 00020 const int hex_faces[6][4] = { { 0, 1, 5, 4 }, { 1, 2, 6, 5 }, { 2, 3, 7, 6 }, 00021 { 3, 0, 4, 7 }, { 3, 2, 1, 0 }, { 4, 5, 6, 7 } }; 00022 00023 static void get_corners( CartVect corners[8] ) 00024 { 00025 corners[0] = CartVect( 1, 1, 0 ); 00026 corners[1] = CartVect( 6, 1, 0 ); 00027 corners[2] = CartVect( 6, 3, 0 ); 00028 corners[3] = CartVect( 1, 3, 0 ); 00029 corners[4] = CartVect( 1, 1, 2 ); 00030 corners[5] = CartVect( 4, 1, 2 ); 00031 corners[6] = CartVect( 4, 3, 2 ); 00032 corners[7] = CartVect( 1, 3, 2 ); 00033 } 00034 00035 const BSPTreePoly::Face* find_face( const BSPTreePoly& poly, 00036 const CartVect* coords, 00037 int num_corners, 00038 const int* face_indices = 0 ) 00039 { 00040 std::vector< const BSPTreePoly::Face* >::iterator i; 00041 std::vector< const BSPTreePoly::Face* > faces; 00042 std::vector< CartVect > corners; 00043 poly.get_faces( faces ); 00044 for( i = faces.begin(); i != faces.end(); ++i ) 00045 { 00046 corners.clear(); 00047 poly.get_vertices( *i, corners ); 00048 if( corners.size() != (unsigned)num_corners ) continue; 00049 00050 int j; 00051 for( j = 0; j < num_corners; ++j ) 00052 { 00053 int corner = face_indices ? face_indices[j] : j; 00054 if( ( coords[corner] - corners.front() ).length_squared() < 1e-12 ) break; 00055 } 00056 if( j == num_corners ) continue; 00057 00058 int k; 00059 for( k = 1; k < num_corners; ++k ) 00060 { 00061 int corner = face_indices ? face_indices[( j + k ) % num_corners] : ( j + k ) % num_corners; 00062 if( ( coords[corner] - corners[k] ).length_squared() > 1e-12 ) break; 00063 } 00064 00065 if( k == num_corners ) return *i; 00066 } 00067 return 0; 00068 } 00069 00070 void test_construct_from_hex() 00071 { 00072 BSPTreePoly::reset_debug_ids(); 00073 00074 CartVect corners[8]; 00075 get_corners( corners ); 00076 BSPTreePoly poly( corners ); 00077 CHECK( poly.is_valid() ); 00078 00079 std::vector< const BSPTreePoly::Face* > faces; 00080 poly.get_faces( faces ); 00081 CHECK_EQUAL( (size_t)6, faces.size() ); 00082 00083 CHECK( 0 != find_face( poly, corners, 4, hex_faces[0] ) ); 00084 CHECK( 0 != find_face( poly, corners, 4, hex_faces[1] ) ); 00085 CHECK( 0 != find_face( poly, corners, 4, hex_faces[2] ) ); 00086 CHECK( 0 != find_face( poly, corners, 4, hex_faces[3] ) ); 00087 CHECK( 0 != find_face( poly, corners, 4, hex_faces[4] ) ); 00088 CHECK( 0 != find_face( poly, corners, 4, hex_faces[5] ) ); 00089 } 00090 00091 void test_cut_with_plane() 00092 { 00093 // create a hexahedron 00094 BSPTreePoly::reset_debug_ids(); 00095 CartVect corners[8]; 00096 get_corners( corners ); 00097 BSPTreePoly poly( corners ); 00098 CHECK( poly.is_valid() ); 00099 00100 // check that a plane entirely above the 00101 // polyhedron (coincident with one face) 00102 // doesn't modify the polyhedron 00103 bool r = poly.cut_polyhedron( CartVect( 0, 0, 1 ), -2 ); 00104 CHECK( !r ); 00105 CHECK( poly.is_valid() ); 00106 00107 // cut in half with Z=1 plane 00108 r = poly.cut_polyhedron( CartVect( 0, 0, 1 ), -1 ); 00109 CHECK( r ); 00110 CHECK( poly.is_valid() ); 00111 for( int i = 0; i < 8; ++i ) 00112 { 00113 if( fabs( corners[i][2] - 2 ) < 1e-6 ) corners[i][2] = 1; 00114 if( fabs( corners[i][0] - 4 ) < 1e-6 ) corners[i][0] = 5; 00115 } 00116 00117 std::vector< const BSPTreePoly::Face* > faces; 00118 poly.get_faces( faces ); 00119 CHECK_EQUAL( (size_t)6, faces.size() ); 00120 00121 CHECK( 0 != find_face( poly, corners, 4, hex_faces[0] ) ); 00122 CHECK( 0 != find_face( poly, corners, 4, hex_faces[1] ) ); 00123 CHECK( 0 != find_face( poly, corners, 4, hex_faces[2] ) ); 00124 CHECK( 0 != find_face( poly, corners, 4, hex_faces[3] ) ); 00125 CHECK( 0 != find_face( poly, corners, 4, hex_faces[4] ) ); 00126 CHECK( 0 != find_face( poly, corners, 4, hex_faces[5] ) ); 00127 00128 // create a hexahedron 00129 BSPTreePoly::reset_debug_ids(); 00130 get_corners( corners ); 00131 poly.set( corners ); 00132 CHECK( poly.is_valid() ); 00133 00134 // cut off two corners using X=5 plane 00135 r = poly.cut_polyhedron( CartVect( 1, 0, 0 ), -5 ); 00136 CHECK( r ); 00137 CHECK( poly.is_valid() ); 00138 00139 faces.clear(); 00140 poly.get_faces( faces ); 00141 CHECK_EQUAL( (size_t)7, faces.size() ); 00142 00143 CartVect new_vtx1( 5, 1, 1 ); 00144 CartVect new_vtx2( 5, 1, 0 ); 00145 CartVect new_vtx3( 5, 3, 0 ); 00146 CartVect new_vtx4( 5, 3, 1 ); 00147 00148 CartVect face1[5] = { corners[0], new_vtx2, new_vtx1, corners[5], corners[4] }; 00149 CartVect face2[4] = { new_vtx1, new_vtx4, corners[6], corners[5] }; 00150 CartVect face3[5] = { new_vtx4, new_vtx3, corners[3], corners[7], corners[6] }; 00151 CartVect face5[4] = { corners[3], new_vtx3, new_vtx2, corners[0] }; 00152 CartVect face7[4] = { new_vtx1, new_vtx2, new_vtx3, new_vtx4 }; 00153 00154 CHECK( 0 != find_face( poly, face1, 5 ) ); 00155 CHECK( 0 != find_face( poly, face2, 4 ) ); 00156 CHECK( 0 != find_face( poly, face3, 5 ) ); 00157 CHECK( 0 != find_face( poly, corners, 4, hex_faces[3] ) ); 00158 CHECK( 0 != find_face( poly, face5, 4 ) ); 00159 CHECK( 0 != find_face( poly, corners, 4, hex_faces[5] ) ); 00160 CHECK( 0 != find_face( poly, face7, 4 ) ); 00161 } 00162 00163 void test_volume() 00164 { 00165 CartVect corners[8]; 00166 get_corners( corners ); 00167 BSPTreePoly poly( corners ); 00168 CHECK( poly.is_valid() ); 00169 00170 CHECK_REAL_EQUAL( 16.0, poly.volume(), 1e-6 ); 00171 }