1 #include "moab/BSPTreePoly.hpp"
2 #include "TestUtil.hpp"
3 #include "moab/CartVect.hpp"
4 
5 using namespace moab;
6 
7 void test_construct_from_hex();
8 void test_cut_with_plane();
9 void test_volume();
10 
main()11 int main( )
12 {
13   int error_count = 0;
14   error_count += RUN_TEST( test_construct_from_hex );
15   error_count += RUN_TEST( test_cut_with_plane );
16   error_count += RUN_TEST( test_volume );
17   return error_count;
18 }
19 
20 
21 const int hex_faces[6][4] = { { 0, 1, 5, 4 },
22                               { 1, 2, 6, 5 },
23                               { 2, 3, 7, 6 },
24                               { 3, 0, 4, 7 },
25                               { 3, 2, 1, 0 },
26                               { 4, 5, 6, 7 } };
27 
get_corners(CartVect corners[8])28 static void get_corners( CartVect corners[8] )
29 {
30   corners[0] = CartVect( 1, 1, 0 );
31   corners[1] = CartVect( 6, 1, 0 );
32   corners[2] = CartVect( 6, 3, 0 );
33   corners[3] = CartVect( 1, 3, 0 );
34   corners[4] = CartVect( 1, 1, 2 );
35   corners[5] = CartVect( 4, 1, 2 );
36   corners[6] = CartVect( 4, 3, 2 );
37   corners[7] = CartVect( 1, 3, 2 );
38 }
39 
find_face(const BSPTreePoly & poly,const CartVect * coords,int num_corners,const int * face_indices=0)40 const BSPTreePoly::Face* find_face( const BSPTreePoly& poly,
41                                      const CartVect* coords,
42                                      int num_corners,
43                                      const int* face_indices = 0 )
44 {
45   std::vector<const BSPTreePoly::Face*>::iterator i;
46   std::vector<const BSPTreePoly::Face*> faces;
47   std::vector<CartVect> corners;
48   poly.get_faces( faces );
49   for (i = faces.begin(); i != faces.end(); ++i) {
50     corners.clear();
51     poly.get_vertices( *i, corners );
52     if (corners.size() != (unsigned)num_corners)
53       continue;
54 
55     int j;
56     for (j = 0; j < num_corners; ++j) {
57       int corner = face_indices ? face_indices[j] : j;
58       if ((coords[corner] - corners.front()).length_squared() < 1e-12)
59         break;
60     }
61     if (j == num_corners)
62       continue;
63 
64     int k;
65     for (k = 1; k < num_corners; ++k) {
66       int corner = face_indices ? face_indices[(j+k)%num_corners] : (j+k)%num_corners;
67       if ((coords[corner] - corners[k]).length_squared() > 1e-12)
68         break;
69     }
70 
71     if (k == num_corners)
72       return *i;
73   }
74   return 0;
75 }
76 
77 
test_construct_from_hex()78 void test_construct_from_hex()
79 {
80   BSPTreePoly::reset_debug_ids();
81 
82   CartVect corners[8];
83   get_corners( corners );
84   BSPTreePoly poly( corners );
85   CHECK( poly.is_valid() );
86 
87   std::vector<const BSPTreePoly::Face*> faces;
88   poly.get_faces( faces );
89   CHECK_EQUAL( (size_t)6, faces.size() );
90 
91   CHECK( 0 != find_face( poly, corners, 4, hex_faces[0] ) );
92   CHECK( 0 != find_face( poly, corners, 4, hex_faces[1] ) );
93   CHECK( 0 != find_face( poly, corners, 4, hex_faces[2] ) );
94   CHECK( 0 != find_face( poly, corners, 4, hex_faces[3] ) );
95   CHECK( 0 != find_face( poly, corners, 4, hex_faces[4] ) );
96   CHECK( 0 != find_face( poly, corners, 4, hex_faces[5] ) );
97 }
98 
test_cut_with_plane()99 void test_cut_with_plane()
100 {
101     // create a hexahedron
102   BSPTreePoly::reset_debug_ids();
103   CartVect corners[8];
104   get_corners( corners );
105   BSPTreePoly poly( corners );
106   CHECK( poly.is_valid() );
107 
108     // check that a plane entirely above the
109     // polyhedron (coincident with one face)
110     // doesn't modify the polyhedron
111   bool r = poly.cut_polyhedron( CartVect(0,0,1), -2 );
112   CHECK(!r);
113   CHECK( poly.is_valid() );
114 
115     // cut in half with Z=1 plane
116   r = poly.cut_polyhedron( CartVect(0,0,1), -1 );
117   CHECK(r);
118   CHECK( poly.is_valid() );
119   for (int i = 0; i < 8; ++i) {
120     if (fabs(corners[i][2] - 2) < 1e-6)
121       corners[i][2] = 1;
122     if (fabs(corners[i][0] - 4) < 1e-6)
123       corners[i][0] = 5;
124   }
125 
126   std::vector<const BSPTreePoly::Face*> faces;
127   poly.get_faces( faces );
128   CHECK_EQUAL( (size_t)6, faces.size() );
129 
130   CHECK( 0 != find_face( poly, corners, 4, hex_faces[0] ) );
131   CHECK( 0 != find_face( poly, corners, 4, hex_faces[1] ) );
132   CHECK( 0 != find_face( poly, corners, 4, hex_faces[2] ) );
133   CHECK( 0 != find_face( poly, corners, 4, hex_faces[3] ) );
134   CHECK( 0 != find_face( poly, corners, 4, hex_faces[4] ) );
135   CHECK( 0 != find_face( poly, corners, 4, hex_faces[5] ) );
136 
137     // create a hexahedron
138   BSPTreePoly::reset_debug_ids();
139   get_corners( corners );
140   poly.set( corners );
141   CHECK( poly.is_valid() );
142 
143     // cut off two corners using X=5 plane
144   r = poly.cut_polyhedron( CartVect(1,0,0), -5 );
145   CHECK(r);
146   CHECK( poly.is_valid() );
147 
148   faces.clear();
149   poly.get_faces( faces );
150   CHECK_EQUAL( (size_t)7, faces.size() );
151 
152   CartVect new_vtx1( 5, 1, 1 );
153   CartVect new_vtx2( 5, 1, 0 );
154   CartVect new_vtx3( 5, 3, 0 );
155   CartVect new_vtx4( 5, 3, 1 );
156 
157   CartVect face1[5] = { corners[0], new_vtx2, new_vtx1, corners[5], corners[4] };
158   CartVect face2[4] = { new_vtx1, new_vtx4, corners[6], corners[5] };
159   CartVect face3[5] = { new_vtx4, new_vtx3, corners[3], corners[7], corners[6] };
160   CartVect face5[4] = { corners[3], new_vtx3, new_vtx2, corners[0] };
161   CartVect face7[4] = { new_vtx1, new_vtx2, new_vtx3, new_vtx4 };
162 
163   CHECK( 0 != find_face( poly, face1, 5 ) );
164   CHECK( 0 != find_face( poly, face2, 4 ) );
165   CHECK( 0 != find_face( poly, face3, 5 ) );
166   CHECK( 0 != find_face( poly, corners, 4, hex_faces[3] ) );
167   CHECK( 0 != find_face( poly, face5, 4 ) );
168   CHECK( 0 != find_face( poly, corners, 4, hex_faces[5] ) );
169   CHECK( 0 != find_face( poly, face7, 4 ) );
170 }
171 
test_volume()172 void test_volume()
173 {
174   CartVect corners[8];
175   get_corners( corners );
176   BSPTreePoly poly( corners );
177   CHECK( poly.is_valid() );
178 
179   CHECK_REAL_EQUAL( 16.0, poly.volume(), 1e-6 );
180 }
181 
182