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