MOAB: Mesh Oriented datABase
(version 5.4.1)
|
00001 /* ***************************************************************** 00002 MESQUITE -- The Mesh Quality Improvement Toolkit 00003 00004 Copyright 2004 Lawrence Livermore National Laboratory. Under 00005 the terms of Contract B545069 with the University of Wisconsin -- 00006 Madison, Lawrence Livermore National Laboratory retains certain 00007 rights in this software. 00008 00009 This library is free software; you can redistribute it and/or 00010 modify it under the terms of the GNU Lesser General Public 00011 License as published by the Free Software Foundation; either 00012 version 2.1 of the License, or (at your option) any later version. 00013 00014 This library is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00017 Lesser General Public License for more details. 00018 00019 You should have received a copy of the GNU Lesser General Public License 00020 (lgpl.txt) along with this library; if not, write to the Free Software 00021 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00022 00023 [email protected] 00024 00025 ***************************************************************** */ 00026 00027 #include <iostream> 00028 using std::cout; 00029 using std::endl; 00030 #include <string> 00031 #include <map> 00032 #include <set> 00033 #include <vector> 00034 #include <algorithm> 00035 using std::map; 00036 using std::set; 00037 using std::string; 00038 using std::vector; 00039 00040 #include <cstdlib> 00041 00042 #include "Mesquite.hpp" 00043 #include "MsqError.hpp" 00044 #include "Vector3D.hpp" 00045 #include "MsqVertex.hpp" 00046 #include "MsqIMesh.hpp" 00047 #include "UnitUtil.hpp" 00048 00049 using namespace MBMesquite; 00050 00051 /* This is the mesh defined in the two arrays below. This test 00052 * should work with any mesh composed entirely of triangle 00053 * elements. The mesh used for the test can be changed by modifying 00054 * the two arrays below. 00055 * 00056 * 3-------------------2 00057 * / \ / \ 00058 * / \ / \ 00059 * / \ / \ 00060 * / \ (1) / \ 00061 * / \ / \ 00062 * / (2) \ / (0) \ 00063 * / \ / \ 00064 * / \ / \ 00065 * / \ / \ 00066 * 4-------------------0-------------------1 00067 * \ / \ / 00068 * \ / \ / 00069 * \ / \ / 00070 * \ (3) / \ (5) / 00071 * \ / \ / 00072 * \ / (4) \ / 00073 * \ / \ / 00074 * \ / \ / 00075 * \ / \ / 00076 * 5-------------------6 00077 * 00078 */ 00079 00080 extern const double vertexCoords[] = { 00081 0.00, 0.00, 0.00, // 0 00082 2.00, 0.00, 0.00, // 1 00083 1.00, 1.73, 0.00, // 2 00084 -1.00, 1.73, 0.00, // 3 00085 -2.00, 0.00, 0.00, // 4 00086 -1.00, -1.73, 0.00, // 5 00087 1.00, -1.73, 0.00 // 6 00088 }; 00089 00090 extern const int triangleConnectivity[] = { 00091 0, 1, 2, // 0 00092 0, 2, 3, // 1 00093 0, 3, 4, // 2 00094 0, 4, 5, // 3 00095 0, 5, 6, // 4 00096 0, 6, 1 // 5 00097 }; 00098 00099 class iMeshTest : public CppUnit::TestFixture 00100 { 00101 private: 00102 CPPUNIT_TEST_SUITE( iMeshTest ); 00103 // CPPUNIT_TEST( testVertexIterator ); 00104 CPPUNIT_TEST( testVertexByte ); 00105 CPPUNIT_TEST( testFixedFlag ); 00106 CPPUNIT_TEST( testSlavedFlag ); 00107 CPPUNIT_TEST( testVertexAdjacency ); 00108 CPPUNIT_TEST( testElementConnectivity ); 00109 CPPUNIT_TEST( testElementTopology ); 00110 CPPUNIT_TEST( testIntTag ); 00111 CPPUNIT_TEST( testDoubleTag ); 00112 CPPUNIT_TEST_SUITE_END(); 00113 00114 MsqIMesh* myMesh; 00115 iMesh_Instance myIMesh; 00116 00117 Mesh::VertexHandle vtxIndexToHandle[7]; 00118 Mesh::ElementHandle triIndexToHandle[7]; 00119 map< Mesh::VertexHandle, int > vtxHandleToIndex; 00120 map< Mesh::ElementHandle, int > triHandleToIndex; 00121 00122 bool match_triangles( const int* tri1, const Mesh::VertexHandle* tri2_handles ); 00123 bool writeVtkFile( const char* name ); 00124 00125 public: 00126 iMeshTest() : myMesh( 0 ) {} 00127 00128 void setUp(); 00129 void tearDown(); 00130 00131 void testVertexFlag( bool fixed, iBase_TagValueType type ); 00132 void testVertexFlagNone( bool fixed ); 00133 00134 void matchVertexCoordinates(); 00135 void matchElementConnectivity(); 00136 void testVertexIterator(); 00137 void testVertexByte(); 00138 void testFixedFlag() 00139 { 00140 testVertexFlag( true, iBase_INTEGER ); 00141 } 00142 void testSlavedFlag() 00143 { 00144 testVertexFlag( false, iBase_INTEGER ); 00145 } 00146 void testFixedFlagByte() 00147 { 00148 testVertexFlag( true, iBase_BYTES ); 00149 } 00150 void testSlavedFlagByte() 00151 { 00152 testVertexFlag( false, iBase_BYTES ); 00153 } 00154 void testFixedFlagNone() 00155 { 00156 testVertexFlagNone( true ); 00157 } 00158 void testSlavedFlagNone() 00159 { 00160 testVertexFlagNone( false ); 00161 } 00162 void testVertexAdjacency(); 00163 void testElementConnectivity(); 00164 void testElementTopology(); 00165 void testIntTag(); 00166 void testDoubleTag(); 00167 }; 00168 00169 bool iMeshTest::writeVtkFile( const char* filename ) 00170 { 00171 int i; 00172 00173 FILE* file = fopen( filename, "w" ); 00174 if( !file ) 00175 { 00176 perror( filename ); 00177 return false; 00178 } 00179 00180 fputs( "# vtk DataFile Version 2.0\n" 00181 "Mesquite Mesh\n" 00182 "ASCII\n" 00183 "DATASET UNSTRUCTURED_GRID\n", 00184 file ); 00185 00186 const int num_pts = sizeof( vertexCoords ) / ( 3 * sizeof( double ) ); 00187 fprintf( file, "POINTS %d float\n", num_pts ); 00188 for( i = 0; i < num_pts; ++i ) 00189 fprintf( file, "%f %f %f\n", vertexCoords[3 * i], vertexCoords[3 * i + 1], vertexCoords[3 * i + 2] ); 00190 00191 int num_tris = sizeof( triangleConnectivity ) / ( 3 * sizeof( int ) ); 00192 fprintf( file, "CELLS %d %d\n", num_tris, 4 * num_tris ); 00193 for( i = 0; i < num_tris; ++i ) 00194 fprintf( file, "3 %d %d %d\n", triangleConnectivity[3 * i], triangleConnectivity[3 * i + 1], 00195 triangleConnectivity[3 * i + 2] ); 00196 00197 fprintf( file, "CELL_TYPES %d\n", num_tris ); 00198 for( i = 0; i < num_tris; ++i ) 00199 fprintf( file, "5\n" ); 00200 00201 fclose( file ); 00202 return true; 00203 } 00204 00205 void iMeshTest::setUp() 00206 { 00207 const char* TMP_FILE_NAME = "hexagon.vtk"; 00208 MsqPrintError err( cout ); 00209 int ierr; 00210 00211 CPPUNIT_ASSERT( writeVtkFile( TMP_FILE_NAME ) ); 00212 00213 iMesh_newMesh( NULL, &myIMesh, &ierr, 0 ); 00214 CPPUNIT_ASSERT_EQUAL( (int)iBase_SUCCESS, ierr ); 00215 00216 iMesh_load( myIMesh, 0, TMP_FILE_NAME, NULL, &ierr, strlen( TMP_FILE_NAME ), 0 ); 00217 CPPUNIT_ASSERT_EQUAL( (int)iBase_SUCCESS, ierr ); 00218 00219 iBase_EntitySetHandle root_set; 00220 iMesh_getRootSet( myIMesh, &root_set, &ierr ); 00221 CPPUNIT_ASSERT_EQUAL( (int)iBase_SUCCESS, ierr ); 00222 00223 myMesh = new MsqIMesh( myIMesh, root_set, iBase_ALL_TYPES, err ); 00224 ASSERT_NO_ERROR( err ); 00225 CPPUNIT_ASSERT( myMesh != NULL ); 00226 00227 matchVertexCoordinates(); 00228 matchElementConnectivity(); 00229 } 00230 00231 void iMeshTest::tearDown() 00232 { 00233 int err; 00234 delete myMesh; 00235 myMesh = 0; 00236 if( myIMesh ) 00237 { 00238 iMesh_dtor( myIMesh, &err ); 00239 CPPUNIT_ASSERT_EQUAL( (int)iBase_SUCCESS, err ); 00240 } 00241 } 00242 00243 void iMeshTest::matchVertexCoordinates() 00244 { 00245 MsqPrintError err( cout ); 00246 const size_t num_pts = sizeof( vertexCoords ) / ( 3 * sizeof( double ) ); 00247 00248 // check if initialized properly 00249 CPPUNIT_ASSERT( myMesh ); 00250 // make sure this hasn't been called yet 00251 CPPUNIT_ASSERT( 0 == vtxHandleToIndex.size() ); 00252 // initialize data 00253 memset( vtxIndexToHandle, 0, sizeof( vtxIndexToHandle ) ); 00254 00255 // Get vertex handles 00256 vector< Mesh::VertexHandle > vertices; 00257 myMesh->get_all_vertices( vertices, err ); 00258 CPPUNIT_ASSERT( !err ); 00259 CPPUNIT_ASSERT_EQUAL( num_pts, vertices.size() ); 00260 00261 // get vertex coordinates 00262 vector< MsqVertex > coordinates( num_pts ); 00263 myMesh->vertices_get_coordinates( arrptr( vertices ), arrptr( coordinates ), num_pts, err ); 00264 CPPUNIT_ASSERT( !err ); 00265 00266 // match vertex coordiantes 00267 for( size_t i = 0; i < num_pts; ++i ) 00268 { 00269 MBMesquite::Vector3D coord( vertexCoords[3 * i], vertexCoords[3 * i + 1], vertexCoords[3 * i + 2] ); 00270 size_t j; 00271 for( j = 0; j < vertices.size(); ++j ) 00272 { 00273 if( ( ( coordinates[j] ) - coord ).length() < DBL_EPSILON ) 00274 { 00275 vtxIndexToHandle[i] = vertices[j]; 00276 CPPUNIT_ASSERT( vtxHandleToIndex.find( vertices[j] ) == vtxHandleToIndex.end() ); 00277 vtxHandleToIndex[vertices[j]] = i; 00278 break; 00279 } 00280 } 00281 00282 CPPUNIT_ASSERT( j < vertices.size() ); // found a match 00283 } 00284 } 00285 00286 bool iMeshTest::match_triangles( const int* tri1, const Mesh::VertexHandle* tri2_handles ) 00287 { 00288 int tri2[3] = { vtxHandleToIndex[tri2_handles[0]], vtxHandleToIndex[tri2_handles[1]], 00289 vtxHandleToIndex[tri2_handles[2]] }; 00290 00291 return ( tri1[0] == tri2[0] && tri1[1] == tri2[1] && tri1[2] == tri2[2] ) || 00292 ( tri1[0] == tri2[1] && tri1[1] == tri2[2] && tri1[2] == tri2[0] ) || 00293 ( tri1[0] == tri2[2] && tri1[1] == tri2[0] && tri1[2] == tri2[1] ); 00294 } 00295 00296 void iMeshTest::matchElementConnectivity() 00297 { 00298 MsqPrintError err( cout ); 00299 const size_t num_tri = sizeof( triangleConnectivity ) / ( 3 * sizeof( int ) ); 00300 00301 // check if initialized properly 00302 CPPUNIT_ASSERT( myMesh ); 00303 // make sure this hasn't been called yet 00304 CPPUNIT_ASSERT( 0 == triHandleToIndex.size() ); 00305 // initialize data 00306 memset( triIndexToHandle, 0, sizeof( triIndexToHandle ) ); 00307 00308 vector< Mesh::VertexHandle > vertices; 00309 vector< Mesh::ElementHandle > elements; 00310 vector< size_t > offsets; 00311 myMesh->get_all_elements( elements, err ); 00312 CPPUNIT_ASSERT( !err ); 00313 CPPUNIT_ASSERT_EQUAL( num_tri, elements.size() ); 00314 myMesh->elements_get_attached_vertices( arrptr( elements ), elements.size(), vertices, offsets, err ); 00315 CPPUNIT_ASSERT( !err ); 00316 00317 // Make sure all are triangles 00318 size_t i; 00319 for( i = 0; i < elements.size(); ++i ) 00320 CPPUNIT_ASSERT_EQUAL( offsets[i] + 3, offsets[i + 1] ); 00321 00322 // Match triangles 00323 for( size_t i = 0; i < num_tri; ++i ) 00324 { 00325 size_t j; 00326 for( j = 0; j < elements.size(); ++j ) 00327 { 00328 Mesh::VertexHandle verts[3] = { vertices[offsets[j]], vertices[offsets[j] + 1], vertices[offsets[j] + 2] }; 00329 00330 if( match_triangles( triangleConnectivity + 3 * i, verts ) ) 00331 { 00332 triIndexToHandle[i] = elements[j]; 00333 CPPUNIT_ASSERT( triHandleToIndex.find( elements[j] ) == triHandleToIndex.end() ); 00334 triHandleToIndex[elements[j]] = i; 00335 break; 00336 } 00337 } 00338 00339 CPPUNIT_ASSERT( j < elements.size() ); // found a match 00340 } 00341 } 00342 00343 /* 00344 void iMeshTest::testVertexIterator() 00345 { 00346 MsqPrintError err(cout); 00347 const size_t num_pts = sizeof(vertexCoords) / (3*sizeof(double)); 00348 00349 // check if initialized properly 00350 CPPUNIT_ASSERT( myMesh ); 00351 00352 // mark each vertex as it is encountered 00353 std::vector<int> marks(num_pts); 00354 memset( arrptr(marks), 0, num_pts * sizeof(int) ); 00355 00356 // iterate over vertices 00357 size_t count = 0; 00358 VertexIterator* iter = myMesh->vertex_iterator(err); 00359 CPPUNIT_ASSERT(!err && iter); 00360 while (!iter->is_at_end()) 00361 { 00362 Mesh::VertexHandle handle = iter->operator*(); 00363 iter->operator++(); 00364 00365 map<Mesh::VertexHandle,int>::iterator f = vtxHandleToIndex.find(handle); 00366 CPPUNIT_ASSERT( f != vtxHandleToIndex.end() ); 00367 00368 unsigned index = f->second; 00369 CPPUNIT_ASSERT(index < num_pts); 00370 CPPUNIT_ASSERT(marks[index] == 0); 00371 marks[index] = 1; 00372 ++count; 00373 } 00374 CPPUNIT_ASSERT_EQUAL(count , num_pts); 00375 } 00376 */ 00377 void iMeshTest::testVertexByte() 00378 { 00379 MsqPrintError err( cout ); 00380 const size_t num_pts = sizeof( vertexCoords ) / ( 3 * sizeof( double ) ); 00381 00382 // check if initialized properly 00383 CPPUNIT_ASSERT( myMesh ); 00384 00385 // set each one individually 00386 unsigned char bytes[num_pts]; 00387 size_t i; 00388 for( i = 0; i < num_pts; ++i ) 00389 { 00390 bytes[i] = (unsigned char)( rand() % 128 ); 00391 myMesh->vertex_set_byte( vtxIndexToHandle[i], bytes[i], err ); 00392 CPPUNIT_ASSERT( !err ); 00393 } 00394 for( i = 0; i < num_pts; ++i ) 00395 { 00396 unsigned char byte = 0; 00397 myMesh->vertex_get_byte( vtxIndexToHandle[i], &byte, err ); 00398 CPPUNIT_ASSERT( !err ); 00399 CPPUNIT_ASSERT_EQUAL( byte, bytes[i] ); 00400 } 00401 00402 // set all at once 00403 for( i = 0; i < num_pts; ++i ) 00404 bytes[i] = (unsigned char)( rand() % 128 ); 00405 myMesh->vertices_set_byte( vtxIndexToHandle, bytes, num_pts, err ); 00406 CPPUNIT_ASSERT( !err ); 00407 unsigned char bytes2[num_pts]; 00408 myMesh->vertices_get_byte( vtxIndexToHandle, bytes2, num_pts, err ); 00409 CPPUNIT_ASSERT( !err ); 00410 CPPUNIT_ASSERT( !memcmp( bytes, bytes2, num_pts ) ); 00411 } 00412 00413 void iMeshTest::testVertexFlagNone( bool fixed ) 00414 { 00415 if( fixed ) 00416 { 00417 myMesh->clear_fixed_tag(); 00418 CPPUNIT_ASSERT( NULL == myMesh->get_fixed_tag() ); 00419 } 00420 else 00421 { 00422 myMesh->clear_slaved_tag(); 00423 CPPUNIT_ASSERT( NULL == myMesh->get_slaved_tag() ); 00424 } 00425 00426 // get all vertices 00427 MsqPrintError err( cout ); 00428 std::vector< Mesh::VertexHandle > handles; 00429 myMesh->get_all_vertices( handles, err ); 00430 ASSERT_NO_ERROR( err ); 00431 CPPUNIT_ASSERT( !handles.empty() ); 00432 00433 std::vector< bool > b( handles.size(), true ); 00434 if( fixed ) 00435 myMesh->vertices_get_fixed_flag( arrptr( handles ), b, handles.size(), err ); 00436 else 00437 myMesh->vertices_get_slaved_flag( arrptr( handles ), b, handles.size(), err ); 00438 CPPUNIT_ASSERT_EQUAL( handles.size(), b.size() ); 00439 size_t first_true = std::find( b.begin(), b.end(), true ) - b.begin(); 00440 ASSERT_NO_ERROR( err ); 00441 CPPUNIT_ASSERT_EQUAL( handles.size(), first_true ); 00442 } 00443 00444 void iMeshTest::testVertexFlag( bool fixed, iBase_TagValueType type ) 00445 { 00446 int ierr; 00447 MsqPrintError err( cout ); 00448 iBase_TagHandle tag; 00449 00450 const char* name = fixed ? "fixed" : "slaved"; 00451 iMesh_createTag( myIMesh, name, 1, type, &tag, &ierr, strlen( name ) ); 00452 CPPUNIT_ASSERT_EQUAL( (int)iBase_SUCCESS, ierr ); 00453 00454 if( fixed ) 00455 { 00456 myMesh->set_fixed_tag( tag, err ); 00457 ASSERT_NO_ERROR( err ); 00458 CPPUNIT_ASSERT( NULL != myMesh->get_fixed_tag() ); 00459 CPPUNIT_ASSERT_EQUAL( tag, *( myMesh->get_fixed_tag() ) ); 00460 } 00461 else 00462 { 00463 myMesh->set_slaved_tag( tag, err ); 00464 ASSERT_NO_ERROR( err ); 00465 CPPUNIT_ASSERT( NULL != myMesh->get_slaved_tag() ); 00466 CPPUNIT_ASSERT_EQUAL( tag, *( myMesh->get_slaved_tag() ) ); 00467 } 00468 00469 // get all vertices 00470 std::vector< Mesh::VertexHandle > handles; 00471 myMesh->get_all_vertices( handles, err ); 00472 ASSERT_NO_ERROR( err ); 00473 CPPUNIT_ASSERT( !handles.empty() ); 00474 iBase_EntityHandle* ihandles = reinterpret_cast< iBase_EntityHandle* >( arrptr( handles ) ); 00475 00476 if( type == iBase_INTEGER ) 00477 { 00478 // define alternating values for flag 00479 std::vector< int > values( handles.size(), !fixed ); 00480 for( size_t i = 0; i < handles.size(); i += 2 ) 00481 values[i] = fixed; 00482 00483 // set flag on vertices 00484 iMesh_setIntArrData( myIMesh, ihandles, handles.size(), tag, arrptr( values ), values.size(), &ierr ); 00485 CPPUNIT_ASSERT_EQUAL( (int)iBase_SUCCESS, ierr ); 00486 } 00487 else if( type == iBase_BYTES ) 00488 { 00489 // define alternating values for flag 00490 std::vector< char > values( handles.size(), !fixed ); 00491 for( size_t i = 0; i < handles.size(); i += 2 ) 00492 values[i] = fixed; 00493 00494 // set flag on vertices 00495 iMesh_setArrData( myIMesh, ihandles, handles.size(), tag, arrptr( values ), values.size(), &ierr ); 00496 CPPUNIT_ASSERT_EQUAL( (int)iBase_SUCCESS, ierr ); 00497 } 00498 else 00499 { 00500 CPPUNIT_ASSERT( !"Unexpected tag data type in test code" ); 00501 } 00502 00503 // get flag through MsqIMesh 00504 std::vector< bool > flags; 00505 if( fixed ) 00506 myMesh->vertices_get_fixed_flag( arrptr( handles ), flags, handles.size(), err ); 00507 else 00508 myMesh->vertices_get_slaved_flag( arrptr( handles ), flags, handles.size(), err ); 00509 ASSERT_NO_ERROR( err ); 00510 CPPUNIT_ASSERT_EQUAL( handles.size(), flags.size() ); 00511 00512 // check flag values 00513 for( size_t i = 0; i < handles.size(); ++i ) 00514 CPPUNIT_ASSERT_EQUAL( ( ( !( i % 2 ) ) == fixed ), (bool)flags[i] ); 00515 } 00516 00517 void iMeshTest::testVertexAdjacency() 00518 { 00519 MsqPrintError err( cout ); 00520 const size_t num_pts = sizeof( vertexCoords ) / ( 3 * sizeof( double ) ); 00521 const size_t num_tri = sizeof( triangleConnectivity ) / ( 3 * sizeof( int ) ); 00522 00523 // check if initialized properly 00524 CPPUNIT_ASSERT( myMesh ); 00525 00526 // construct adjacency list from input data to compare against 00527 std::set< int > adjset[num_pts]; 00528 size_t i; 00529 for( i = 0; i < num_tri; ++i ) 00530 for( size_t j = 3 * i; j < 3 * i + 3; ++j ) 00531 adjset[triangleConnectivity[j]].insert( i ); 00532 00533 std::vector< Mesh::ElementHandle > elements; 00534 std::vector< size_t > offsets; 00535 myMesh->vertices_get_attached_elements( vtxIndexToHandle, num_pts, elements, offsets, err ); 00536 CPPUNIT_ASSERT( !err ); 00537 CPPUNIT_ASSERT_EQUAL( offsets.size(), num_pts + 1 ); 00538 00539 // compare connectivity for each vertex 00540 for( i = 0; i < num_pts; ++i ) 00541 { 00542 size_t count = offsets[i + 1] - offsets[i]; 00543 CPPUNIT_ASSERT_EQUAL( adjset[i].size(), count ); 00544 Mesh::ElementHandle* elems = &elements[offsets[i]]; 00545 00546 for( size_t j = 0; j < count; ++j ) 00547 { 00548 // Get element index from handle 00549 Mesh::ElementHandle handle = elems[j]; 00550 std::map< Mesh::ElementHandle, int >::iterator idx = triHandleToIndex.find( handle ); 00551 CPPUNIT_ASSERT( idx != triHandleToIndex.end() ); 00552 00553 // Find element index in vertex adjacency set 00554 std::set< int >::iterator iter = adjset[i].find( idx->second ); 00555 CPPUNIT_ASSERT( iter != adjset[i].end() ); 00556 adjset[i].erase( iter ); 00557 } 00558 // Make sure we got all the adjacent elements 00559 CPPUNIT_ASSERT_EQUAL( (size_t)0, adjset[i].size() ); 00560 } 00561 } 00562 00563 void iMeshTest::testElementConnectivity() 00564 { 00565 MsqPrintError err( cout ); 00566 // const size_t num_pts = sizeof(vertexCoords) / (3*sizeof(double)); 00567 const size_t num_tri = sizeof( triangleConnectivity ) / ( 3 * sizeof( int ) ); 00568 00569 // check if initialized properly 00570 CPPUNIT_ASSERT( myMesh ); 00571 00572 // get element connectivity list 00573 std::vector< Mesh::VertexHandle > vertices; 00574 std::vector< size_t > offsets; 00575 myMesh->elements_get_attached_vertices( triIndexToHandle, num_tri, vertices, offsets, err ); 00576 CPPUNIT_ASSERT( !err ); 00577 CPPUNIT_ASSERT_EQUAL( offsets.size(), num_tri + 1 ); 00578 CPPUNIT_ASSERT_EQUAL( vertices.size(), 3 * num_tri ); 00579 00580 // check each element's connectivity 00581 Mesh::VertexHandle elem_vertices[3]; 00582 for( size_t i = 0; i < num_tri; ++i ) 00583 { 00584 // check that connectivity list contains three vertices 00585 CPPUNIT_ASSERT_EQUAL( offsets[i] + 3, offsets[i + 1] ); 00586 00587 // get list of vertex indices from connectivity data 00588 for( size_t j = 0; j < 3; j++ ) 00589 { 00590 size_t offset = offsets[i] + j; 00591 CPPUNIT_ASSERT( offset < vertices.size() ); 00592 elem_vertices[j] = vertices[offset]; 00593 } 00594 00595 // compare connectivity 00596 CPPUNIT_ASSERT( match_triangles( triangleConnectivity + 3 * i, elem_vertices ) ); 00597 } 00598 } 00599 00600 void iMeshTest::testElementTopology() 00601 { 00602 MsqPrintError err( cout ); 00603 const size_t num_tri = sizeof( triangleConnectivity ) / ( 3 * sizeof( int ) ); 00604 00605 // check if initialized properly 00606 CPPUNIT_ASSERT( myMesh ); 00607 00608 EntityTopology topo[num_tri]; 00609 myMesh->elements_get_topologies( triIndexToHandle, topo, num_tri, err ); 00610 CPPUNIT_ASSERT( !err ); 00611 for( size_t i = 0; i < num_tri; ++i ) 00612 CPPUNIT_ASSERT_EQUAL( topo[i], MBMesquite::TRIANGLE ); 00613 } 00614 00615 void iMeshTest::testIntTag() 00616 { 00617 const char* tagname = "TEST_TEST_INT_TAG"; 00618 MsqPrintError err( cout ); 00619 const size_t num_tri = sizeof( triangleConnectivity ) / ( 3 * sizeof( int ) ); 00620 00621 // check if initialized properly 00622 CPPUNIT_ASSERT( myMesh ); 00623 00624 // create a tag 00625 TagHandle tag = myMesh->tag_create( tagname, Mesh::INT, 2, NULL, err ); 00626 CPPUNIT_ASSERT( !err ); 00627 00628 // get the tag 00629 TagHandle tag2 = myMesh->tag_get( tagname, err ); 00630 CPPUNIT_ASSERT( !err ); 00631 CPPUNIT_ASSERT_EQUAL( tag, tag2 ); 00632 00633 // check tag metadata 00634 string name; 00635 Mesh::TagType type; 00636 unsigned length; 00637 myMesh->tag_properties( tag, name, type, length, err ); 00638 CPPUNIT_ASSERT( !err ); 00639 CPPUNIT_ASSERT_EQUAL( name, std::string( tagname ) ); 00640 CPPUNIT_ASSERT_EQUAL( type, Mesh::INT ); 00641 CPPUNIT_ASSERT_EQUAL( length, 2u ); 00642 00643 // set the tag on all triangles 00644 std::vector< int > data1( 2 * num_tri ), data2( 2 * num_tri ); 00645 std::vector< int >::iterator iter1, iter2; 00646 for( iter1 = data1.begin(); iter1 != data1.end(); ++iter1 ) 00647 *iter1 = rand(); 00648 myMesh->tag_set_element_data( tag, num_tri, triIndexToHandle, arrptr( data1 ), err ); 00649 CPPUNIT_ASSERT( !err ); 00650 00651 // get tag data from all triangles and compare 00652 myMesh->tag_get_element_data( tag, num_tri, triIndexToHandle, arrptr( data2 ), err ); 00653 CPPUNIT_ASSERT( !err ); 00654 for( iter1 = data1.begin(), iter2 = data2.begin(); iter1 != data1.end(); ++iter1, ++iter2 ) 00655 CPPUNIT_ASSERT_EQUAL( *iter1, *iter2 ); 00656 00657 // destroy the tag 00658 myMesh->tag_delete( tag, err ); 00659 CPPUNIT_ASSERT( !err ); 00660 tag2 = myMesh->tag_get( tagname, err ); 00661 CPPUNIT_ASSERT_EQUAL( err.error_code(), MsqError::TAG_NOT_FOUND ); 00662 err.clear(); 00663 } 00664 00665 void iMeshTest::testDoubleTag() 00666 { 00667 const char* tagname = "TEST_TEST_DOUBLE_TAG"; 00668 MsqPrintError err( cout ); 00669 const size_t num_pts = sizeof( vertexCoords ) / ( 3 * sizeof( double ) ); 00670 00671 // check if initialized properly 00672 CPPUNIT_ASSERT( myMesh ); 00673 00674 // create a tag 00675 TagHandle tag = myMesh->tag_create( tagname, Mesh::DOUBLE, 1, NULL, err ); 00676 CPPUNIT_ASSERT( !err ); 00677 00678 // get the tag 00679 TagHandle tag2 = myMesh->tag_get( tagname, err ); 00680 CPPUNIT_ASSERT( !err ); 00681 CPPUNIT_ASSERT_EQUAL( tag, tag2 ); 00682 00683 // check tag metadata 00684 string name; 00685 Mesh::TagType type; 00686 unsigned length; 00687 myMesh->tag_properties( tag, name, type, length, err ); 00688 CPPUNIT_ASSERT( !err ); 00689 CPPUNIT_ASSERT_EQUAL( name, std::string( tagname ) ); 00690 CPPUNIT_ASSERT_EQUAL( type, Mesh::DOUBLE ); 00691 CPPUNIT_ASSERT_EQUAL( length, 1u ); 00692 00693 // set the tag on all vertices 00694 std::vector< double > data1( num_pts ), data2( num_pts ); 00695 std::vector< double >::iterator iter1, iter2; 00696 for( iter1 = data1.begin(); iter1 != data1.end(); ++iter1 ) 00697 *iter1 = sqrt( abs( rand() ) ); 00698 myMesh->tag_set_vertex_data( tag, num_pts, vtxIndexToHandle, arrptr( data1 ), err ); 00699 CPPUNIT_ASSERT( !err ); 00700 00701 // get tag data from all vertices and compare 00702 myMesh->tag_get_vertex_data( tag, num_pts, vtxIndexToHandle, arrptr( data2 ), err ); 00703 CPPUNIT_ASSERT( !err ); 00704 for( iter1 = data1.begin(), iter2 = data2.begin(); iter1 != data1.end(); ++iter1, ++iter2 ) 00705 CPPUNIT_ASSERT_EQUAL( *iter1, *iter2 ); 00706 00707 // destroy the tag 00708 myMesh->tag_delete( tag, err ); 00709 CPPUNIT_ASSERT( !err ); 00710 tag2 = myMesh->tag_get( tagname, err ); 00711 CPPUNIT_ASSERT_EQUAL( err.error_code(), MsqError::TAG_NOT_FOUND ); 00712 err.clear(); 00713 } 00714 00715 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( iMeshTest, "iMeshTest" ); 00716 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( iMeshTest, "Unit" );