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