moab
|
00001 #include "TestRunner.hpp" 00002 #include "iMesh.h" 00003 #include "MBiMesh.hpp" 00004 #include "moab/Core.hpp" 00005 #include <algorithm> 00006 00007 void test_getEntArrAdj_conn(); 00008 void test_getEntArrAdj_vertex(); 00009 void test_getEntArrAdj_up(); 00010 void test_getEntArrAdj_down(); 00011 void test_getEntArrAdj_invalid_size(); 00012 void test_getEntArrAdj_none(); 00013 void test_existinterface(); 00014 void test_tags_retrieval(); 00015 00016 int main( int argc, char* argv[] ) 00017 { 00018 REGISTER_TEST( test_getEntArrAdj_conn ); 00019 REGISTER_TEST( test_getEntArrAdj_vertex ); 00020 REGISTER_TEST( test_getEntArrAdj_up ); 00021 REGISTER_TEST( test_getEntArrAdj_down ); 00022 REGISTER_TEST( test_getEntArrAdj_invalid_size ); 00023 REGISTER_TEST( test_getEntArrAdj_none ); 00024 REGISTER_TEST( test_existinterface ); 00025 #ifdef HDF5_FILE 00026 REGISTER_TEST( test_tags_retrieval ); 00027 #endif 00028 return RUN_TESTS( argc, argv ); 00029 } 00030 00031 // INTERVAL x INTERVAL x INTERVAL regular hex mesh with skin faces. 00032 // Vertices are located at even coordinate 00033 // values and adjacent vertices are separated by one unit. The entire 00034 // grid is in the first octant with the first vertex at the origin. 00035 // Faces are grouped by the side of the grid that they occur in. 00036 // The faces are { -Y, X, Y, -X, -Z, Z }. 00037 const int INTERVALS = 2; 00038 iBase_EntityHandle VERTS[INTERVALS+1][INTERVALS+1][INTERVALS+1]; 00039 iBase_EntityHandle HEXES[INTERVALS][INTERVALS][INTERVALS]; 00040 iBase_EntityHandle FACES[6][INTERVALS][INTERVALS]; 00041 00042 static void HEX_VERTS( int i, int j, int k, iBase_EntityHandle conn[8] ) { 00043 conn[0] = VERTS[i ][j ][k ]; 00044 conn[1] = VERTS[i+1][j ][k ]; 00045 conn[2] = VERTS[i+1][j+1][k ]; 00046 conn[3] = VERTS[i ][j+1][k ]; 00047 conn[4] = VERTS[i ][j ][k+1]; 00048 conn[5] = VERTS[i+1][j ][k+1]; 00049 conn[6] = VERTS[i+1][j+1][k+1]; 00050 conn[7] = VERTS[i ][j+1][k+1]; 00051 } 00052 00053 static void QUAD_VERTS( int f, int i, int j, iBase_EntityHandle conn[4] ) { 00054 switch (f) { 00055 case 0: case 2: 00056 conn[0] = VERTS[i ][INTERVALS*(f/2)][j ]; 00057 conn[1] = VERTS[i+1][INTERVALS*(f/2)][j ]; 00058 conn[2] = VERTS[i+1][INTERVALS*(f/2)][j+1]; 00059 conn[3] = VERTS[i ][INTERVALS*(f/2)][j+1]; 00060 break; 00061 case 1: case 3: 00062 conn[0] = VERTS[INTERVALS*(1/f)][i ][j ]; 00063 conn[1] = VERTS[INTERVALS*(1/f)][i+1][j ]; 00064 conn[2] = VERTS[INTERVALS*(1/f)][i+1][j+1]; 00065 conn[3] = VERTS[INTERVALS*(1/f)][i ][j+1]; 00066 break; 00067 case 4: case 5: 00068 conn[0] = VERTS[i ][j ][INTERVALS*(f-4)]; 00069 conn[1] = VERTS[i+1][j ][INTERVALS*(f-4)]; 00070 conn[2] = VERTS[i+1][j+1][INTERVALS*(f-4)]; 00071 conn[3] = VERTS[i ][j+1][INTERVALS*(f-4)]; 00072 break; 00073 default: 00074 CHECK(false); 00075 } 00076 } 00077 00078 00079 iMesh_Instance create_mesh() 00080 { 00081 static iMesh_Instance instance = 0; 00082 if (instance) 00083 return instance; 00084 00085 int err; 00086 iMesh_Instance tmp; 00087 iMesh_newMesh( 0, &tmp, &err, 0 ); 00088 CHECK_EQUAL( iBase_SUCCESS, err ); 00089 00090 for (int i = 0; i < INTERVALS+1; ++i) 00091 for (int j = 0; j < INTERVALS+1; ++j) 00092 for (int k = 0; k < INTERVALS+1; ++k) { 00093 iMesh_createVtx( tmp, i, j, k, &VERTS[i][j][k], &err ); 00094 CHECK_EQUAL( iBase_SUCCESS, err ); 00095 } 00096 00097 int status; 00098 iBase_EntityHandle conn[8]; 00099 for (int i = 0; i < INTERVALS; ++i) 00100 for (int j = 0; j < INTERVALS; ++j) 00101 for (int k = 0; k < INTERVALS; ++k) { 00102 HEX_VERTS(i,j,k,conn); 00103 iMesh_createEnt( tmp, iMesh_HEXAHEDRON, conn, 8, &HEXES[i][j][k], &status, &err ); 00104 CHECK_EQUAL( iBase_SUCCESS, err ); 00105 CHECK_EQUAL( iBase_NEW, status ); 00106 } 00107 00108 00109 for (int f = 0; f < 6; ++f) 00110 for (int i = 0; i < INTERVALS; ++i) 00111 for (int j = 0; j < INTERVALS; ++j) { 00112 QUAD_VERTS(f,i,j,conn); 00113 iMesh_createEnt( tmp, iMesh_QUADRILATERAL, conn, 4, &FACES[f][i][j], &status, &err ); 00114 CHECK_EQUAL( iBase_SUCCESS, err ); 00115 } 00116 00117 return (instance = tmp); 00118 } 00119 00120 void test_getEntArrAdj_conn() 00121 { 00122 iMesh_Instance mesh = create_mesh(); 00123 int err; 00124 00125 // test hex vertices 00126 for (int i = 0; i < INTERVALS; ++i) { 00127 for (int j = 0; j < INTERVALS; ++j) { 00128 iBase_EntityHandle adj[8*INTERVALS]; 00129 int off[INTERVALS+1]; 00130 int adj_alloc = sizeof(adj)/sizeof(adj[0]); 00131 int off_alloc = sizeof(off)/sizeof(off[0]); 00132 int adj_size = -1, off_size = -1; 00133 iBase_EntityHandle* adj_ptr = adj; 00134 int* off_ptr = off; 00135 iMesh_getEntArrAdj( mesh, HEXES[i][j], INTERVALS, iBase_VERTEX, 00136 &adj_ptr, &adj_alloc, &adj_size, 00137 &off_ptr, &off_alloc, &off_size, 00138 &err ); 00139 CHECK_EQUAL( &adj[0], adj_ptr ); 00140 CHECK_EQUAL( &off[0], off_ptr ); 00141 CHECK_EQUAL( iBase_SUCCESS, err ); 00142 CHECK_EQUAL( 8*INTERVALS, adj_size ); 00143 CHECK_EQUAL( 8*INTERVALS, adj_alloc ); 00144 CHECK_EQUAL( INTERVALS+1, off_size ); 00145 CHECK_EQUAL( INTERVALS+1, off_alloc ); 00146 for (int k = 0; k < INTERVALS; ++k) { 00147 CHECK_EQUAL( 8*k, off[k] ); 00148 iBase_EntityHandle conn[8]; 00149 HEX_VERTS( i, j, k, conn ); 00150 CHECK_ARRAYS_EQUAL( conn, 8, adj + off[k], off[k+1]-off[k] ); 00151 } 00152 } 00153 } 00154 00155 // test quad vertices for one side of mesh 00156 const int f = 0; 00157 for (int i = 0; i < INTERVALS; ++i) { 00158 iBase_EntityHandle adj[4*INTERVALS]; 00159 int off[INTERVALS+1]; 00160 int adj_alloc = sizeof(adj)/sizeof(adj[0]); 00161 int off_alloc = sizeof(off)/sizeof(off[0]); 00162 int adj_size = -1, off_size = -1; 00163 iBase_EntityHandle* adj_ptr = adj; 00164 int* off_ptr = off; 00165 iMesh_getEntArrAdj( mesh, FACES[f][i], INTERVALS, iBase_VERTEX, 00166 &adj_ptr, &adj_alloc, &adj_size, 00167 &off_ptr, &off_alloc, &off_size, 00168 &err ); 00169 CHECK_EQUAL( &adj[0], adj_ptr ); 00170 CHECK_EQUAL( &off[0], off_ptr ); 00171 CHECK_EQUAL( iBase_SUCCESS, err ); 00172 CHECK_EQUAL( 4*INTERVALS, adj_size ); 00173 CHECK_EQUAL( 4*INTERVALS, adj_alloc ); 00174 CHECK_EQUAL( INTERVALS+1, off_size ); 00175 CHECK_EQUAL( INTERVALS+1, off_alloc ); 00176 for (int k = 0; k < INTERVALS; ++k) { 00177 CHECK_EQUAL( 4*k, off[k] ); 00178 iBase_EntityHandle conn[4]; 00179 QUAD_VERTS( f, i, k, conn ); 00180 CHECK_ARRAYS_EQUAL( conn, 4, adj + off[k], off[k+1]-off[k] ); 00181 } 00182 } 00183 } 00184 00185 void test_getEntArrAdj_vertex() 00186 { 00187 iMesh_Instance mesh = create_mesh(); 00188 int err; 00189 00190 // get hexes adjacent to row of vertices at x=0,y=0; 00191 iBase_EntityHandle *adj = 0; 00192 int *off = 0; 00193 int adj_alloc = 0, off_alloc = 0; 00194 int adj_size = -1, off_size = -1; 00195 iMesh_getEntArrAdj( mesh, VERTS[0][0], INTERVALS+1, iBase_REGION, 00196 &adj, &adj_alloc, &adj_size, 00197 &off, &off_alloc, &off_size, 00198 &err ); 00199 CHECK_EQUAL( iBase_SUCCESS, err ); 00200 CHECK( 0 != adj ); 00201 CHECK( 0 != off ); 00202 CHECK_EQUAL( 2*INTERVALS, adj_size ); // INTERVALS+1 verts, end ones with one hex, others with two 00203 CHECK_EQUAL( INTERVALS+2, off_size ); // one more than number of input handles 00204 CHECK( adj_alloc >= adj_size ); 00205 CHECK( off_alloc >= off_size ); 00206 00207 // first and last vertices should have one adjacent hex 00208 CHECK_EQUAL( 1, off[1] - off[0] ); 00209 CHECK_EQUAL( HEXES[0][0][0], adj[off[0]] ); 00210 CHECK_EQUAL( 1, off[INTERVALS+1] - off[INTERVALS] ); 00211 CHECK_EQUAL( HEXES[0][0][INTERVALS-1], adj[off[INTERVALS]] ); 00212 // middle ones should have two adjacent hexes 00213 for (int i = 1; i < INTERVALS; ++i) { 00214 CHECK_EQUAL( 2, off[i+1] - off[i] ); 00215 CHECK_EQUAL( HEXES[0][0][i-1], adj[off[i] ] ); 00216 CHECK_EQUAL( HEXES[0][0][i ], adj[off[i]+1] ); 00217 } 00218 00219 free(adj); 00220 free(off); 00221 } 00222 00223 void test_getEntArrAdj_up() 00224 { 00225 iMesh_Instance mesh = create_mesh(); 00226 int err; 00227 00228 // get hexes adjacent to a row of faces in the z=0 plane 00229 iBase_EntityHandle *adj = 0; 00230 int *off = 0; 00231 int adj_alloc = 0, off_alloc = 0; 00232 int adj_size = -1, off_size = -1; 00233 iMesh_getEntArrAdj( mesh, FACES[4][0], INTERVALS, iBase_REGION, 00234 &adj, &adj_alloc, &adj_size, 00235 &off, &off_alloc, &off_size, 00236 &err ); 00237 CHECK_EQUAL( iBase_SUCCESS, err ); 00238 CHECK( 0 != adj ); 00239 CHECK( 0 != off ); 00240 CHECK_EQUAL( INTERVALS, adj_size ); // one hex adjacent to each skin face 00241 CHECK_EQUAL( INTERVALS+1, off_size ); // one more than number of input handles 00242 CHECK( adj_alloc >= adj_size ); 00243 CHECK( off_alloc >= off_size ); 00244 00245 for (int i = 0; i < INTERVALS; ++i) { 00246 CHECK_EQUAL( 1, off[i+1] - off[i] ); 00247 CHECK_EQUAL( HEXES[0][i][0], adj[off[i]] ); 00248 } 00249 00250 free(adj); 00251 free(off); 00252 } 00253 00254 void test_getEntArrAdj_down() 00255 { 00256 iMesh_Instance mesh = create_mesh(); 00257 int err; 00258 00259 // get quads adjacent to a edge-row of hexes 00260 iBase_EntityHandle *adj = 0; 00261 int *off = 0; 00262 int adj_alloc = 0, off_alloc = 0; 00263 int adj_size = -1, off_size = -1; 00264 iMesh_getEntArrAdj( mesh, HEXES[0][0], INTERVALS, iBase_FACE, 00265 &adj, &adj_alloc, &adj_size, 00266 &off, &off_alloc, &off_size, 00267 &err ); 00268 CHECK_EQUAL( iBase_SUCCESS, err ); 00269 CHECK( 0 != adj ); 00270 CHECK( 0 != off ); 00271 CHECK_EQUAL( 2*INTERVALS+2, adj_size ); // corner hexes adj to 3 faces, others adj to 2 00272 CHECK_EQUAL( INTERVALS+1, off_size ); // one more than number of input handles 00273 CHECK( adj_alloc >= adj_size ); 00274 CHECK( off_alloc >= off_size ); 00275 00276 // first (corner) hex should have three adjacent faces 00277 CHECK_EQUAL( 3, off[1] - off[0] ); 00278 iBase_EntityHandle exp[3] = { FACES[0][0][0], 00279 FACES[3][0][0], 00280 FACES[4][0][0] }; 00281 iBase_EntityHandle act[3]; 00282 std::copy( adj + off[0], adj+off[1], act ); 00283 std::sort( exp, exp+3 ); 00284 std::sort( act, act+3 ); 00285 CHECK_ARRAYS_EQUAL( exp, 3, act, 3 ); 00286 00287 // last (corner) hex should have three adjacent faces 00288 CHECK_EQUAL( 3, off[INTERVALS] - off[INTERVALS-1] ); 00289 iBase_EntityHandle exp2[3] = { FACES[0][0][INTERVALS-1], 00290 FACES[3][0][INTERVALS-1], 00291 FACES[5][0][0] }; 00292 std::copy( adj + off[INTERVALS-1], adj+off[INTERVALS], act ); 00293 std::sort( exp2, exp2+3 ); 00294 std::sort( act, act+3 ); 00295 CHECK_ARRAYS_EQUAL( exp2, 3, act, 3 ); 00296 00297 // all middle hexes should have two adjacent faces 00298 for (int i = 1; i < INTERVALS-1; ++i) { 00299 iBase_EntityHandle e1, e2, a1, a2; 00300 e1 = FACES[0][0][i]; 00301 e2 = FACES[3][0][i]; 00302 if (e1 > e2) std::swap(e1,e2); 00303 00304 CHECK_EQUAL( 2, off[i+1] - off[i] ); 00305 a1 = adj[off[i] ]; 00306 a2 = adj[off[i]+1]; 00307 if (a1 > a2) std::swap(a1,a2); 00308 00309 CHECK_EQUAL( e1, a1 ); 00310 CHECK_EQUAL( e2, a2 ); 00311 } 00312 00313 free(adj); 00314 free(off); 00315 } 00316 00317 void test_getEntArrAdj_invalid_size() 00318 { 00319 iMesh_Instance mesh = create_mesh(); 00320 int err = -1; 00321 00322 const int SPECIAL1 = 0xDeadBeef; 00323 const int SPECIAL2 = 0xCafe5; 00324 const int SPECIAL3 = 0xbabb1e; 00325 00326 // test a downward query 00327 volatile int marker1 = SPECIAL1; 00328 iBase_EntityHandle adj1[8*INTERVALS-1]; // one too small 00329 volatile int marker2 = SPECIAL2; 00330 int off1[INTERVALS+1]; 00331 int adj1_alloc = sizeof(adj1)/sizeof(adj1[0]); 00332 int off1_alloc = sizeof(off1)/sizeof(off1[0]); 00333 int adj_size, off_size; 00334 iBase_EntityHandle* adj_ptr = adj1; 00335 int* off_ptr = off1; 00336 iMesh_getEntArrAdj( mesh, HEXES[0][0], INTERVALS, iBase_VERTEX, 00337 &adj_ptr, &adj1_alloc, &adj_size, 00338 &off_ptr, &off1_alloc, &off_size, 00339 &err ); 00340 CHECK_EQUAL( &adj1[0], adj_ptr ); 00341 CHECK_EQUAL( &off1[0], off_ptr ); 00342 // first ensure no stack corruption from writing off end of array 00343 CHECK_EQUAL( SPECIAL1, marker1 ); 00344 CHECK_EQUAL( SPECIAL2, marker2 ); 00345 // now verify that it correctly failed 00346 CHECK_EQUAL( iBase_BAD_ARRAY_SIZE, err ); 00347 00348 // now test an upwards query 00349 volatile int marker3 = SPECIAL3; 00350 int off2[INTERVALS]; 00351 volatile int marker4 = SPECIAL1; 00352 int off2_alloc = sizeof(off2)/sizeof(off2[0]); 00353 err = iBase_SUCCESS; 00354 adj_ptr = adj1; 00355 off_ptr = off2; 00356 iMesh_getEntArrAdj( mesh, VERTS[0][0], INTERVALS+1, iBase_REGION, 00357 &adj_ptr, &adj1_alloc, &adj_size, 00358 &off_ptr, &off2_alloc, &off_size, 00359 &err ); 00360 // first ensure no stack corruption from writing off end of array 00361 CHECK_EQUAL( &adj1[0], adj_ptr ); 00362 CHECK_EQUAL( &off2[0], off_ptr ); 00363 CHECK_EQUAL( SPECIAL3, marker3 ); 00364 CHECK_EQUAL( SPECIAL1, marker4 ); 00365 // now verify that it correctly failed 00366 CHECK_EQUAL( iBase_BAD_ARRAY_SIZE, err ); 00367 } 00368 00369 void test_getEntArrAdj_none() 00370 { 00371 iMesh_Instance mesh = create_mesh(); 00372 int err = -1; 00373 00374 iBase_EntityHandle* adj = 0; 00375 int* off = 0; 00376 int adj_alloc = 0, off_alloc = 0; 00377 int adj_size = -1, off_size = -1; 00378 iMesh_getEntArrAdj( mesh, NULL, 0, iBase_REGION, 00379 &adj, &adj_alloc, &adj_size, 00380 &off, &off_alloc, &off_size, 00381 &err ); 00382 CHECK_EQUAL( iBase_SUCCESS, err ); 00383 CHECK_EQUAL( 0, adj_alloc ); 00384 CHECK_EQUAL( 0, adj_size ); 00385 CHECK_EQUAL( 1, off_size ); 00386 CHECK( off_alloc >= 1 ); 00387 CHECK_EQUAL( 0, off[0] ); 00388 00389 free(off); 00390 } 00391 00392 void test_existinterface() 00393 { 00394 // test construction of an imesh instance from a core instance 00395 moab::Core *core = new moab::Core(); 00396 MBiMesh *mesh = new MBiMesh(core); 00397 iMesh_Instance imesh = reinterpret_cast<iMesh_Instance>(mesh); 00398 00399 // make sure we can call imesh functions 00400 int dim, err; 00401 iMesh_getGeometricDimension(imesh, &dim, &err); 00402 CHECK_EQUAL( iBase_SUCCESS, err ); 00403 00404 // now make sure we can delete the instance without it deleting the MOAB instance 00405 iMesh_dtor(imesh, &err); 00406 CHECK_EQUAL(err, iBase_SUCCESS); 00407 00408 ErrorCode rval = core->get_number_entities_by_dimension(0, 0, dim); 00409 CHECK_EQUAL(moab::MB_SUCCESS, rval); 00410 00411 // finally, delete the MOAB instance 00412 delete core; 00413 } 00414 00415 void test_tags_retrieval() 00416 { 00417 iMesh_Instance mesh; 00418 int err; 00419 iMesh_newMesh("", &mesh, &err, 0); 00420 CHECK_EQUAL( iBase_SUCCESS, err ); 00421 00422 iBase_EntitySetHandle root_set; 00423 iMesh_getRootSet(mesh, &root_set, &err); 00424 CHECK_EQUAL( iBase_SUCCESS, err ); 00425 00426 // open a file with var len tags (sense tags) 00427 // they should be filtered out 00428 std::string filename = STRINGIFY(MESHDIR) "/PB.h5m"; 00429 00430 iMesh_load(mesh, root_set, filename.c_str(), NULL, &err, filename.length(), 0); 00431 CHECK_EQUAL( iBase_SUCCESS, err ); 00432 00433 iBase_EntitySetHandle* contained_set_handles = NULL; 00434 int contained_set_handles_allocated = 0; 00435 int contained_set_handles_size; 00436 // get all entity sets 00437 iMesh_getEntSets(mesh, root_set, 1, 00438 &contained_set_handles, 00439 &contained_set_handles_allocated, 00440 &contained_set_handles_size, 00441 &err ); 00442 CHECK_EQUAL( iBase_SUCCESS, err ); 00443 // get tags for all sets 00444 for (int i=0; i< contained_set_handles_size; i++) 00445 { 00446 iBase_TagHandle* tag_handles = NULL; 00447 int tag_handles_allocated=0; 00448 int tag_handles_size; 00449 iMesh_getAllEntSetTags (mesh, 00450 contained_set_handles[i], 00451 &tag_handles, 00452 &tag_handles_allocated, 00453 &tag_handles_size, &err); 00454 CHECK_EQUAL( iBase_SUCCESS, err ); 00455 00456 for (int j=0; j<tag_handles_size; j++) 00457 { 00458 int tagSize; 00459 iMesh_getTagSizeValues(mesh, tag_handles[j], &tagSize, &err); 00460 CHECK_EQUAL( iBase_SUCCESS, err ); 00461 00462 } 00463 free(tag_handles); 00464 } 00465 free (contained_set_handles); 00466 00467 return; 00468 } 00469