MOAB: Mesh Oriented datABase  (version 5.4.1)
iMeshTest.cpp
Go to the documentation of this file.
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" );
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines