MOAB: Mesh Oriented datABase  (version 5.2.1)
ReadVtk.cpp
Go to the documentation of this file.
00001 /**
00002  * MOAB, a Mesh-Oriented datABase, is a software component for creating,
00003  * storing and accessing finite element mesh data.
00004  *
00005  * Copyright 2004 Sandia Corporation.  Under the terms of Contract
00006  * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government
00007  * retains certain 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  */
00015 
00016 /**
00017  * \class ReadVtk
00018  * \brief VTK reader from Mesquite
00019  * \author Jason Kraftcheck
00020  */
00021 
00022 #include <assert.h>
00023 #include <stdlib.h>
00024 #include <string.h>
00025 
00026 #include "ReadVtk.hpp"
00027 #include "moab/Range.hpp"
00028 #include "Internals.hpp"
00029 #include "moab/Interface.hpp"
00030 #include "moab/ReadUtilIface.hpp"
00031 #include "moab/FileOptions.hpp"
00032 #include "FileTokenizer.hpp"
00033 #include "moab/VtkUtil.hpp"
00034 #include "MBTagConventions.hpp"
00035 
00036 // #define MB_VTK_MATERIAL_SETS
00037 #ifdef MB_VTK_MATERIAL_SETS
00038 #include <map>
00039 #endif
00040 
00041 namespace moab
00042 {
00043 
00044 #ifdef MB_VTK_MATERIAL_SETS
00045 
00046 class Hash
00047 {
00048   public:
00049     unsigned long value;
00050 
00051     Hash()
00052     {
00053         this->value = 5381L;
00054     }
00055 
00056     Hash( const unsigned char* bytes, size_t len )
00057     {  // djb2, a hash by dan bernstein presented on comp.lang.c for hashing strings.
00058         this->value = 5381L;
00059         for( ; len; --len, ++bytes )
00060             this->value = this->value * 33 + ( *bytes );
00061     }
00062 
00063     Hash( bool duh )
00064     {
00065         this->value = duh;  // Hashing a single bit with a long is stupid but easy.
00066     }
00067 
00068     Hash( const Hash& src )
00069     {
00070         this->value = src.value;
00071     }
00072 
00073     Hash& operator=( const Hash& src )
00074     {
00075         this->value = src.value;
00076         return *this;
00077     }
00078 
00079     bool operator<( const Hash& other ) const
00080     {
00081         return this->value < other.value;
00082     }
00083 };
00084 
00085 // Pass this class opaque data + a handle and it adds the handle to a set
00086 // whose opaque data has the same hash. If no set exists for the hash,
00087 // it creates one. Each set is tagged with the opaque data.
00088 // When entities with different opaque data have the same hash, they
00089 // will be placed into the same set.
00090 // There will be no collisions when the opaque data is shorter than an
00091 // unsigned long, and this is really the only case we need to support.
00092 // The rest is bonus. Hash does quite well with strings, even those
00093 // with identical prefixes.
00094 class Modulator : public std::map< Hash, EntityHandle >
00095 {
00096   public:
00097     Modulator( Interface* iface ) : mesh( iface ) {}
00098 
00099     ErrorCode initialize( std::string tag_name, DataType mb_type, size_t sz, size_t per_elem )
00100     {
00101         std::vector< unsigned char > default_val;
00102         default_val.resize( sz * per_elem );
00103         ErrorCode rval = this->mesh->tag_get_handle( tag_name.c_str(), per_elem, mb_type, this->tag,
00104                                                      MB_TAG_SPARSE | MB_TAG_BYTES | MB_TAG_CREAT, &default_val[0] );
00105         return rval;
00106     }
00107 
00108     void add_entity( EntityHandle ent, const unsigned char* bytes, size_t len )
00109     {
00110         Hash h( bytes, len );
00111         EntityHandle mset = this->congruence_class( h, bytes );
00112         ErrorCode rval;
00113         rval = this->mesh->add_entities( mset, &ent, 1 );MB_CHK_SET_ERR_RET( rval, "Failed to add entities to mesh" );
00114     }
00115 
00116     void add_entities( Range& range, const unsigned char* bytes, size_t bytes_per_ent )
00117     {
00118         for( Range::iterator it = range.begin(); it != range.end(); ++it, bytes += bytes_per_ent )
00119         {
00120             Hash h( bytes, bytes_per_ent );
00121             EntityHandle mset = this->congruence_class( h, bytes );
00122             ErrorCode rval;
00123             rval = this->mesh->add_entities( mset, &*it, 1 );MB_CHK_SET_ERR_RET( rval, "Failed to add entities to mesh" );
00124         }
00125     }
00126 
00127     EntityHandle congruence_class( const Hash& h, const void* tag_data )
00128     {
00129         std::map< Hash, EntityHandle >::iterator it = this->find( h );
00130         if( it == this->end() )
00131         {
00132             EntityHandle mset;
00133             Range preexist;
00134             ErrorCode rval;
00135             rval = this->mesh->get_entities_by_type_and_tag( 0, MBENTITYSET, &this->tag, &tag_data, 1, preexist );MB_CHK_SET_ERR_RET_VAL( rval, "Failed to get entities by type and tag", (EntityHandle)0 );
00136             if( preexist.size() ) { mset = *preexist.begin(); }
00137             else
00138             {
00139                 rval = this->mesh->create_meshset( MESHSET_SET, mset );MB_CHK_SET_ERR_RET_VAL( rval, "Failed to create mesh set", (EntityHandle)0 );
00140                 rval = this->mesh->tag_set_data( this->tag, &mset, 1, tag_data );MB_CHK_SET_ERR_RET_VAL( rval, "Failed to set tag data", (EntityHandle)0 );
00141             }
00142             ( *this )[h] = mset;
00143             return mset;
00144         }
00145         return it->second;
00146     }
00147 
00148     Interface* mesh;
00149     Tag tag;
00150 };
00151 #endif  // MB_VTK_MATERIAL_SETS
00152 
00153 ReaderIface* ReadVtk::factory( Interface* iface )
00154 {
00155     return new ReadVtk( iface );
00156 }
00157 
00158 ReadVtk::ReadVtk( Interface* impl ) : mdbImpl( impl ), mPartitionTagName( MATERIAL_SET_TAG_NAME )
00159 {
00160     mdbImpl->query_interface( readMeshIface );
00161 }
00162 
00163 ReadVtk::~ReadVtk()
00164 {
00165     if( readMeshIface )
00166     {
00167         mdbImpl->release_interface( readMeshIface );
00168         readMeshIface = 0;
00169     }
00170 }
00171 
00172 const char* const vtk_type_names[] = {
00173     "bit",  "char",          "unsigned_char", "short",  "unsigned_short", "int", "unsigned_int",
00174     "long", "unsigned_long", "float",         "double", "vtkIdType",      0
00175 };
00176 
00177 ErrorCode ReadVtk::read_tag_values( const char* /* file_name */, const char* /* tag_name */,
00178                                     const FileOptions& /* opts */, std::vector< int >& /* tag_values_out */,
00179                                     const SubsetList* /* subset_list */ )
00180 {
00181     return MB_NOT_IMPLEMENTED;
00182 }
00183 
00184 ErrorCode ReadVtk::load_file( const char* filename, const EntityHandle* /* file_set */, const FileOptions& opts,
00185                               const ReaderIface::SubsetList* subset_list, const Tag* file_id_tag )
00186 {
00187     ErrorCode result;
00188 
00189     int major, minor;
00190     char vendor_string[257];
00191     std::vector< Range > element_list;
00192     Range vertices;
00193 
00194     if( subset_list ) { MB_SET_ERR( MB_UNSUPPORTED_OPERATION, "Reading subset of files not supported for VTK" ); }
00195 
00196     // Does the caller want a field to be used for partitioning the entities?
00197     // If not, we'll assume any scalar integer field named MATERIAL_SET specifies partitions.
00198     std::string partition_tag_name;
00199     result = opts.get_option( "PARTITION", partition_tag_name );
00200     if( result == MB_SUCCESS ) mPartitionTagName = partition_tag_name;
00201 
00202     FILE* file = fopen( filename, "r" );
00203     if( !file ) return MB_FILE_DOES_NOT_EXIST;
00204 
00205     // Read file header
00206 
00207     if( !fgets( vendor_string, sizeof( vendor_string ), file ) )
00208     {
00209         fclose( file );
00210         return MB_FAILURE;
00211     }
00212 
00213     if( !strchr( vendor_string, '\n' ) || 2 != sscanf( vendor_string, "# vtk DataFile Version %d.%d", &major, &minor ) )
00214     {
00215         fclose( file );
00216         return MB_FAILURE;
00217     }
00218 
00219     if( !fgets( vendor_string, sizeof( vendor_string ), file ) )
00220     {
00221         fclose( file );
00222         return MB_FAILURE;
00223     }
00224 
00225     // VTK spec says this should not exceed 256 chars.
00226     if( !strchr( vendor_string, '\n' ) )
00227     {
00228         fclose( file );
00229         MB_SET_ERR( MB_FAILURE, "Vendor string (line 2) exceeds 256 characters" );
00230     }
00231 
00232     // Check file type
00233 
00234     FileTokenizer tokens( file, readMeshIface );
00235     const char* const file_type_names[] = { "ASCII", "BINARY", 0 };
00236     int filetype                        = tokens.match_token( file_type_names );
00237     switch( filetype )
00238     {
00239         case 2:  // BINARY
00240             MB_SET_ERR( MB_FAILURE, "Cannot read BINARY VTK files" );
00241         default:  // ERROR
00242             return MB_FAILURE;
00243         case 1:  // ASCII
00244             break;
00245     }
00246 
00247     // Read the mesh
00248     if( !tokens.match_token( "DATASET" ) ) return MB_FAILURE;
00249     result = vtk_read_dataset( tokens, vertices, element_list );
00250     if( MB_SUCCESS != result ) return result;
00251 
00252     if( file_id_tag )
00253     {
00254         result = store_file_ids( *file_id_tag, vertices, element_list );
00255         if( MB_SUCCESS != result ) return result;
00256     }
00257 
00258     // Count the number of elements read
00259     long elem_count = 0;
00260     for( std::vector< Range >::iterator it = element_list.begin(); it != element_list.end(); ++it )
00261         elem_count += it->size();
00262 
00263     // Read attribute data until end of file.
00264     const char* const block_type_names[] = { "POINT_DATA", "CELL_DATA", 0 };
00265     std::vector< Range > vertex_list( 1 );
00266     vertex_list[0] = vertices;
00267     int blocktype  = 0;
00268     while( !tokens.eof() )
00269     {
00270         // Get POINT_DATA or CELL_DATA
00271         int new_block_type = tokens.match_token( block_type_names, false );
00272         if( tokens.eof() ) break;
00273 
00274         if( !new_block_type )
00275         {
00276             // If next token was neither POINT_DATA nor CELL_DATA,
00277             // then there's another attribute under the current one.
00278             if( blocktype )
00279                 tokens.unget_token();
00280             else
00281                 break;
00282         }
00283         else
00284         {
00285             blocktype = new_block_type;
00286             long count;
00287             if( !tokens.get_long_ints( 1, &count ) ) return MB_FAILURE;
00288 
00289             if( blocktype == 1 && (unsigned long)count != vertices.size() )
00290             {
00291                 MB_SET_ERR( MB_FAILURE, "Count inconsistent with number of vertices at line " << tokens.line_number() );
00292             }
00293             else if( blocktype == 2 && count != elem_count )
00294             {
00295                 MB_SET_ERR( MB_FAILURE, "Count inconsistent with number of elements at line " << tokens.line_number() );
00296             }
00297         }
00298 
00299         if( blocktype == 1 )
00300             result = vtk_read_attrib_data( tokens, vertex_list );
00301         else
00302             result = vtk_read_attrib_data( tokens, element_list );
00303 
00304         if( MB_SUCCESS != result ) return result;
00305     }
00306 
00307     return MB_SUCCESS;
00308 }
00309 
00310 ErrorCode ReadVtk::allocate_vertices( long num_verts, EntityHandle& start_handle_out, double*& x_coord_array_out,
00311                                       double*& y_coord_array_out, double*& z_coord_array_out )
00312 {
00313     ErrorCode result;
00314 
00315     // Create vertices
00316     std::vector< double* > arrays;
00317     start_handle_out = 0;
00318     result           = readMeshIface->get_node_coords( 3, num_verts, MB_START_ID, start_handle_out, arrays );
00319     if( MB_SUCCESS != result ) return result;
00320 
00321     x_coord_array_out = arrays[0];
00322     y_coord_array_out = arrays[1];
00323     z_coord_array_out = arrays[2];
00324 
00325     return MB_SUCCESS;
00326 }
00327 
00328 ErrorCode ReadVtk::read_vertices( FileTokenizer& tokens, long num_verts, EntityHandle& start_handle_out )
00329 {
00330     ErrorCode result;
00331     double *x, *y, *z;
00332 
00333     result = allocate_vertices( num_verts, start_handle_out, x, y, z );
00334     if( MB_SUCCESS != result ) return result;
00335 
00336     // Read vertex coordinates
00337     for( long vtx = 0; vtx < num_verts; ++vtx )
00338     {
00339         if( !tokens.get_doubles( 1, x++ ) || !tokens.get_doubles( 1, y++ ) || !tokens.get_doubles( 1, z++ ) )
00340             return MB_FAILURE;
00341     }
00342 
00343     return MB_SUCCESS;
00344 }
00345 
00346 ErrorCode ReadVtk::allocate_elements( long num_elements, int vert_per_element, EntityType type,
00347                                       EntityHandle& start_handle_out, EntityHandle*& conn_array_out,
00348                                       std::vector< Range >& append_to_this )
00349 {
00350     ErrorCode result;
00351 
00352     start_handle_out = 0;
00353     result = readMeshIface->get_element_connect( num_elements, vert_per_element, type, MB_START_ID, start_handle_out,
00354                                                  conn_array_out );
00355     if( MB_SUCCESS != result ) return result;
00356 
00357     Range range( start_handle_out, start_handle_out + num_elements - 1 );
00358     append_to_this.push_back( range );
00359     return MB_SUCCESS;
00360 }
00361 
00362 ErrorCode ReadVtk::vtk_read_dataset( FileTokenizer& tokens, Range& vertex_list, std::vector< Range >& element_list )
00363 {
00364     const char* const data_type_names[] = {
00365         "STRUCTURED_POINTS", "STRUCTURED_GRID", "UNSTRUCTURED_GRID", "POLYDATA", "RECTILINEAR_GRID", "FIELD", 0
00366     };
00367     int datatype = tokens.match_token( data_type_names );
00368     switch( datatype )
00369     {
00370         case 1:
00371             return vtk_read_structured_points( tokens, vertex_list, element_list );
00372         case 2:
00373             return vtk_read_structured_grid( tokens, vertex_list, element_list );
00374         case 3:
00375             return vtk_read_unstructured_grid( tokens, vertex_list, element_list );
00376         case 4:
00377             return vtk_read_polydata( tokens, vertex_list, element_list );
00378         case 5:
00379             return vtk_read_rectilinear_grid( tokens, vertex_list, element_list );
00380         case 6:
00381             return vtk_read_field( tokens );
00382         default:
00383             return MB_FAILURE;
00384     }
00385 }
00386 
00387 ErrorCode ReadVtk::vtk_read_structured_points( FileTokenizer& tokens, Range& vertex_list,
00388                                                std::vector< Range >& elem_list )
00389 {
00390     long i, j, k;
00391     long dims[3];
00392     double origin[3], space[3];
00393     ErrorCode result;
00394 
00395     if( !tokens.match_token( "DIMENSIONS" ) || !tokens.get_long_ints( 3, dims ) || !tokens.get_newline() )
00396         return MB_FAILURE;
00397 
00398     if( dims[0] < 1 || dims[1] < 1 || dims[2] < 1 )
00399     { MB_SET_ERR( MB_FAILURE, "Invalid dimension at line " << tokens.line_number() ); }
00400 
00401     if( !tokens.match_token( "ORIGIN" ) || !tokens.get_doubles( 3, origin ) || !tokens.get_newline() )
00402         return MB_FAILURE;
00403 
00404     const char* const spacing_names[] = { "SPACING", "ASPECT_RATIO", 0 };
00405     if( !tokens.match_token( spacing_names ) || !tokens.get_doubles( 3, space ) || !tokens.get_newline() )
00406         return MB_FAILURE;
00407 
00408     // Create vertices
00409     double *x, *y, *z;
00410     EntityHandle start_handle = 0;
00411     long num_verts            = dims[0] * dims[1] * dims[2];
00412     result                    = allocate_vertices( num_verts, start_handle, x, y, z );
00413     if( MB_SUCCESS != result ) return result;
00414     vertex_list.insert( start_handle, start_handle + num_verts - 1 );
00415 
00416     for( k = 0; k < dims[2]; ++k )
00417         for( j = 0; j < dims[1]; ++j )
00418             for( i = 0; i < dims[0]; ++i )
00419             {
00420                 *x = origin[0] + i * space[0];
00421                 ++x;
00422                 *y = origin[1] + j * space[1];
00423                 ++y;
00424                 *z = origin[2] + k * space[2];
00425                 ++z;
00426             }
00427 
00428     return vtk_create_structured_elems( dims, start_handle, elem_list );
00429 }
00430 
00431 ErrorCode ReadVtk::vtk_read_structured_grid( FileTokenizer& tokens, Range& vertex_list,
00432                                              std::vector< Range >& elem_list )
00433 {
00434     long num_verts, dims[3];
00435     ErrorCode result;
00436 
00437     if( !tokens.match_token( "DIMENSIONS" ) || !tokens.get_long_ints( 3, dims ) || !tokens.get_newline() )
00438         return MB_FAILURE;
00439 
00440     if( dims[0] < 1 || dims[1] < 1 || dims[2] < 1 )
00441     { MB_SET_ERR( MB_FAILURE, "Invalid dimension at line " << tokens.line_number() ); }
00442 
00443     if( !tokens.match_token( "POINTS" ) || !tokens.get_long_ints( 1, &num_verts ) ||
00444         !tokens.match_token( vtk_type_names ) || !tokens.get_newline() )
00445         return MB_FAILURE;
00446 
00447     if( num_verts != ( dims[0] * dims[1] * dims[2] ) )
00448     { MB_SET_ERR( MB_FAILURE, "Point count not consistent with dimensions at line " << tokens.line_number() ); }
00449 
00450     // Create and read vertices
00451     EntityHandle start_handle = 0;
00452     result                    = read_vertices( tokens, num_verts, start_handle );
00453     if( MB_SUCCESS != result ) return result;
00454     vertex_list.insert( start_handle, start_handle + num_verts - 1 );
00455 
00456     return vtk_create_structured_elems( dims, start_handle, elem_list );
00457 }
00458 
00459 ErrorCode ReadVtk::vtk_read_rectilinear_grid( FileTokenizer& tokens, Range& vertex_list,
00460                                               std::vector< Range >& elem_list )
00461 {
00462     int i, j, k;
00463     long dims[3];
00464     const char* labels[] = { "X_COORDINATES", "Y_COORDINATES", "Z_COORDINATES" };
00465     std::vector< double > coords[3];
00466     ErrorCode result;
00467 
00468     if( !tokens.match_token( "DIMENSIONS" ) || !tokens.get_long_ints( 3, dims ) || !tokens.get_newline() )
00469         return MB_FAILURE;
00470 
00471     if( dims[0] < 1 || dims[1] < 1 || dims[2] < 1 )
00472     { MB_SET_ERR( MB_FAILURE, "Invalid dimension at line " << tokens.line_number() ); }
00473 
00474     for( i = 0; i < 3; i++ )
00475     {
00476         long count;
00477         if( !tokens.match_token( labels[i] ) || !tokens.get_long_ints( 1, &count ) ||
00478             !tokens.match_token( vtk_type_names ) )
00479             return MB_FAILURE;
00480 
00481         if( count != dims[i] )
00482         {
00483             MB_SET_ERR( MB_FAILURE, "Coordinate count inconsistent with dimensions at line " << tokens.line_number() );
00484         }
00485 
00486         coords[i].resize( count );
00487         if( !tokens.get_doubles( count, &coords[i][0] ) ) return MB_FAILURE;
00488     }
00489 
00490     // Create vertices
00491     double *x, *y, *z;
00492     EntityHandle start_handle = 0;
00493     long num_verts            = dims[0] * dims[1] * dims[2];
00494     result                    = allocate_vertices( num_verts, start_handle, x, y, z );
00495     if( MB_SUCCESS != result ) return result;
00496     vertex_list.insert( start_handle, start_handle + num_verts - 1 );
00497 
00498     // Calculate vertex coordinates
00499     for( k = 0; k < dims[2]; ++k )
00500         for( j = 0; j < dims[1]; ++j )
00501             for( i = 0; i < dims[0]; ++i )
00502             {
00503                 *x = coords[0][i];
00504                 ++x;
00505                 *y = coords[1][j];
00506                 ++y;
00507                 *z = coords[2][k];
00508                 ++z;
00509             }
00510 
00511     return vtk_create_structured_elems( dims, start_handle, elem_list );
00512 }
00513 
00514 ErrorCode ReadVtk::vtk_read_polydata( FileTokenizer& tokens, Range& vertex_list, std::vector< Range >& elem_list )
00515 {
00516     ErrorCode result;
00517     long num_verts;
00518     const char* const poly_data_names[] = { "VERTICES", "LINES", "POLYGONS", "TRIANGLE_STRIPS", 0 };
00519 
00520     if( !tokens.match_token( "POINTS" ) || !tokens.get_long_ints( 1, &num_verts ) ||
00521         !tokens.match_token( vtk_type_names ) || !tokens.get_newline() )
00522         return MB_FAILURE;
00523 
00524     if( num_verts < 1 ) { MB_SET_ERR( MB_FAILURE, "Invalid point count at line " << tokens.line_number() ); }
00525 
00526     // Create vertices and read coordinates
00527     EntityHandle start_handle = 0;
00528     result                    = read_vertices( tokens, num_verts, start_handle );
00529     if( MB_SUCCESS != result ) return result;
00530     vertex_list.insert( start_handle, start_handle + num_verts - 1 );
00531 
00532     int poly_type = tokens.match_token( poly_data_names );
00533     switch( poly_type )
00534     {
00535         case 0:
00536             result = MB_FAILURE;
00537             break;
00538         case 1:
00539             MB_SET_ERR( MB_FAILURE, "Vertex element type at line " << tokens.line_number() );
00540             break;
00541         case 2:
00542             MB_SET_ERR( MB_FAILURE, "Unsupported type: polylines at line " << tokens.line_number() );
00543             result = MB_FAILURE;
00544             break;
00545         case 3:
00546             result = vtk_read_polygons( tokens, start_handle, elem_list );
00547             break;
00548         case 4:
00549             MB_SET_ERR( MB_FAILURE, "Unsupported type: triangle strips at line " << tokens.line_number() );
00550             result = MB_FAILURE;
00551             break;
00552     }
00553 
00554     return result;
00555 }
00556 
00557 ErrorCode ReadVtk::vtk_read_polygons( FileTokenizer& tokens, EntityHandle first_vtx, std::vector< Range >& elem_list )
00558 {
00559     ErrorCode result;
00560     long size[2];
00561 
00562     if( !tokens.get_long_ints( 2, size ) || !tokens.get_newline() ) return MB_FAILURE;
00563 
00564     const Range empty;
00565     std::vector< EntityHandle > conn_hdl;
00566     std::vector< long > conn_idx;
00567     EntityHandle first = 0, prev = 0, handle;
00568     for( int i = 0; i < size[0]; ++i )
00569     {
00570         long count;
00571         if( !tokens.get_long_ints( 1, &count ) ) return MB_FAILURE;
00572         conn_idx.resize( count );
00573         conn_hdl.resize( count );
00574         if( !tokens.get_long_ints( count, &conn_idx[0] ) ) return MB_FAILURE;
00575 
00576         for( long j = 0; j < count; ++j )
00577             conn_hdl[j] = first_vtx + conn_idx[j];
00578 
00579         result = mdbImpl->create_element( MBPOLYGON, &conn_hdl[0], count, handle );
00580         if( MB_SUCCESS != result ) return result;
00581 
00582         if( prev + 1 != handle )
00583         {
00584             if( first )
00585             {  // True except for first iteration (first == 0)
00586                 if( elem_list.empty() || first < elem_list.back().front() )  // Only need new range if order would get
00587                                                                              // mixed up, or we just began inserting
00588                     elem_list.push_back( empty );
00589                 elem_list.back().insert( first, prev );
00590             }
00591             first = handle;
00592         }
00593         prev = handle;
00594     }
00595     if( first )
00596     {                                                                // True unless no elements (size[0] == 0)
00597         if( elem_list.empty() || first < elem_list.back().front() )  // Only need new range if order would get mixed
00598                                                                      // up, or we just began inserting
00599             elem_list.push_back( empty );
00600         elem_list.back().insert( first, prev );
00601     }
00602 
00603     return MB_SUCCESS;
00604 }
00605 
00606 ErrorCode ReadVtk::vtk_read_unstructured_grid( FileTokenizer& tokens, Range& vertex_list,
00607                                                std::vector< Range >& elem_list )
00608 {
00609     ErrorCode result;
00610     long i, num_verts, num_elems[2];
00611     EntityHandle tmp_conn_list[27];
00612 
00613     // Poorly formatted VTK legacy format document seems to
00614     // lead many to think that a FIELD block can occur within
00615     // an UNSTRUCTURED_GRID dataset rather than as its own data
00616     // set. So allow for field data between other blocks of
00617     // data.
00618 
00619     const char* pts_str[] = { "FIELD", "POINTS", 0 };
00620     while( 1 == ( i = tokens.match_token( pts_str ) ) )
00621     {
00622         result = vtk_read_field( tokens );
00623         if( MB_SUCCESS != result ) return result;
00624     }
00625     if( i != 2 ) return MB_FAILURE;
00626 
00627     if( !tokens.get_long_ints( 1, &num_verts ) || !tokens.match_token( vtk_type_names ) || !tokens.get_newline() )
00628         return MB_FAILURE;
00629 
00630     if( num_verts < 1 ) { MB_SET_ERR( MB_FAILURE, "Invalid point count at line " << tokens.line_number() ); }
00631 
00632     // Create vertices and read coordinates
00633     EntityHandle first_vertex = 0;
00634     result                    = read_vertices( tokens, num_verts, first_vertex );
00635     if( MB_SUCCESS != result ) return result;
00636     vertex_list.insert( first_vertex, first_vertex + num_verts - 1 );
00637 
00638     const char* cell_str[] = { "FIELD", "CELLS", 0 };
00639     while( 1 == ( i = tokens.match_token( cell_str ) ) )
00640     {
00641         result = vtk_read_field( tokens );
00642         if( MB_SUCCESS != result ) return result;
00643     }
00644     if( i != 2 ) return MB_FAILURE;
00645 
00646     if( !tokens.get_long_ints( 2, num_elems ) || !tokens.get_newline() ) return MB_FAILURE;
00647 
00648     // Read element connectivity for all elements
00649     std::vector< long > connectivity( num_elems[1] );
00650     if( !tokens.get_long_ints( num_elems[1], &connectivity[0] ) ) return MB_FAILURE;
00651 
00652     if( !tokens.match_token( "CELL_TYPES" ) || !tokens.get_long_ints( 1, &num_elems[1] ) || !tokens.get_newline() )
00653         return MB_FAILURE;
00654 
00655     // Read element types
00656     std::vector< long > types( num_elems[0] );
00657     if( !tokens.get_long_ints( num_elems[0], &types[0] ) ) return MB_FAILURE;
00658 
00659     // Create elements in blocks of the same type
00660     // It is important to preserve the order in
00661     // which the elements were read for later reading
00662     // attribute data.
00663     long id                                 = 0;
00664     std::vector< long >::iterator conn_iter = connectivity.begin();
00665     while( id < num_elems[0] )
00666     {
00667         unsigned vtk_type = types[id];
00668         if( vtk_type >= VtkUtil::numVtkElemType ) return MB_FAILURE;
00669 
00670         EntityType type = VtkUtil::vtkElemTypes[vtk_type].mb_type;
00671         if( type == MBMAXTYPE )
00672         {
00673             MB_SET_ERR( MB_FAILURE, "Unsupported VTK element type: " << VtkUtil::vtkElemTypes[vtk_type].name << " ("
00674                                                                      << vtk_type << ")" );
00675         }
00676 
00677         int num_vtx = *conn_iter;
00678         if( type != MBPOLYGON && type != MBPOLYHEDRON && num_vtx != (int)VtkUtil::vtkElemTypes[vtk_type].num_nodes )
00679         {
00680             MB_SET_ERR( MB_FAILURE, "Cell " << id << " is of type '" << VtkUtil::vtkElemTypes[vtk_type].name
00681                                             << "' but has " << num_vtx << " vertices" );
00682         }
00683 
00684         // Find any subsequent elements of the same type
00685         // if polyhedra, need to look at the number of faces to put in the same range
00686         std::vector< long >::iterator conn_iter2 = conn_iter + num_vtx + 1;
00687         long end_id                              = id + 1;
00688         if( MBPOLYHEDRON != type )
00689         {
00690             while( end_id < num_elems[0] && (unsigned)types[end_id] == vtk_type && *conn_iter2 == num_vtx )
00691             {
00692                 ++end_id;
00693                 conn_iter2 += num_vtx + 1;
00694             }
00695         }
00696         else
00697         {
00698             // advance only if next is polyhedron too, and if number of faces is the same
00699             int num_faces = conn_iter[1];
00700             while( end_id < num_elems[0] && (unsigned)types[end_id] == vtk_type && conn_iter2[1] == num_faces )
00701             {
00702                 ++end_id;
00703                 conn_iter2 += num_vtx + 1;
00704             }
00705             // num_vtx becomes in this case num_faces
00706             num_vtx = num_faces;  // for polyhedra, this is what we want
00707             // trigger vertex adjacency call
00708             Range firstFaces;
00709             mdbImpl->get_adjacencies( &first_vertex, 1, 2, false, firstFaces );
00710         }
00711 
00712         // Allocate element block
00713         long num_elem             = end_id - id;
00714         EntityHandle start_handle = 0;
00715         EntityHandle* conn_array;
00716 
00717         // if type is MBVERTEX, skip, we will not create elements with one vertex
00718         if( MBVERTEX == type )
00719         {
00720             id += num_elem;
00721             conn_iter += 2 * num_elem;  // skip 2 * number of 1-vertex elements
00722             continue;
00723         }
00724 
00725         result = allocate_elements( num_elem, num_vtx, type, start_handle, conn_array, elem_list );
00726         if( MB_SUCCESS != result ) return result;
00727 
00728         EntityHandle* conn_sav = conn_array;
00729 
00730         // Store element connectivity
00731         if( type != MBPOLYHEDRON )
00732         {
00733             for( ; id < end_id; ++id )
00734             {
00735                 if( conn_iter == connectivity.end() )
00736                 { MB_SET_ERR( MB_FAILURE, "Connectivity data truncated at cell " << id ); }
00737                 // Make sure connectivity length is correct.
00738                 if( *conn_iter != num_vtx )
00739                 {
00740                     MB_SET_ERR( MB_FAILURE, "Cell " << id << " is of type '" << VtkUtil::vtkElemTypes[vtk_type].name
00741                                                     << "' but has " << num_vtx << " vertices" );
00742                 }
00743                 ++conn_iter;
00744 
00745                 for( i = 0; i < num_vtx; ++i, ++conn_iter )
00746                 {
00747                     if( conn_iter == connectivity.end() )
00748                     { MB_SET_ERR( MB_FAILURE, "Connectivity data truncated at cell " << id ); }
00749 
00750                     conn_array[i] = *conn_iter + first_vertex;
00751                 }
00752 
00753                 const unsigned* order = VtkUtil::vtkElemTypes[vtk_type].node_order;
00754                 if( order )
00755                 {
00756                     assert( num_vtx * sizeof( EntityHandle ) <= sizeof( tmp_conn_list ) );
00757                     memcpy( tmp_conn_list, conn_array, num_vtx * sizeof( EntityHandle ) );
00758                     for( int j = 0; j < num_vtx; ++j )
00759                         conn_array[order[j]] = tmp_conn_list[j];
00760                 }
00761 
00762                 conn_array += num_vtx;
00763             }
00764         }
00765         else  // type == MBPOLYHEDRON
00766         {
00767             // in some cases, we may need to create new elements; will it screw the tags?
00768             // not if the file was not from moab
00769             ErrorCode rv = MB_SUCCESS;
00770             for( ; id < end_id; ++id )
00771             {
00772                 if( conn_iter == connectivity.end() )
00773                 { MB_SET_ERR( MB_FAILURE, "Connectivity data truncated at polyhedra cell " << id ); }
00774                 ++conn_iter;
00775                 // iterator is now at number of faces
00776                 // we should check it is indeed num_vtx
00777                 int num_faces = *conn_iter;
00778                 if( num_faces != num_vtx ) MB_SET_ERR( MB_FAILURE, "Connectivity data wrong at polyhedra cell " << id );
00779 
00780                 EntityHandle connec[20];  // we bet we will have only 20 vertices at most, in a
00781                                           // face in a polyhedra
00782                 for( int j = 0; j < num_faces; j++ )
00783                 {
00784                     conn_iter++;
00785                     int numverticesInFace = (int)*conn_iter;
00786                     if( numverticesInFace > 20 )
00787                         MB_SET_ERR( MB_FAILURE,
00788                                     "too many vertices in face index " << j << " for polyhedra cell " << id );
00789                     // need to find the face, but first fill with vertices
00790                     for( int k = 0; k < numverticesInFace; k++ )
00791                     {
00792                         connec[k] = first_vertex + *( ++conn_iter );  //
00793                     }
00794                     Range adjFaces;
00795                     // find a face with these vertices; if not, we need to create one, on the fly :(
00796                     rv = mdbImpl->get_adjacencies( connec, numverticesInFace, 2, false, adjFaces );MB_CHK_ERR( rv );
00797                     if( adjFaces.size() >= 1 )
00798                     {
00799                         conn_array[j] = adjFaces[0];  // get the first face found
00800                     }
00801                     else
00802                     {
00803                         // create the face; tri, quad or polygon
00804                         EntityType etype = MBTRI;
00805                         if( 4 == numverticesInFace ) etype = MBQUAD;
00806                         if( 4 < numverticesInFace ) etype = MBPOLYGON;
00807 
00808                         rv = mdbImpl->create_element( etype, connec, numverticesInFace, conn_array[j] );MB_CHK_ERR( rv );
00809                     }
00810                 }
00811 
00812                 conn_array += num_vtx;  // advance for next polyhedra
00813                 conn_iter++;            // advance to the next field
00814             }
00815         }
00816 
00817         // Notify MOAB of the new elements
00818         result = readMeshIface->update_adjacencies( start_handle, num_elem, num_vtx, conn_sav );
00819         if( MB_SUCCESS != result ) return result;
00820     }
00821 
00822     return MB_SUCCESS;
00823 }
00824 
00825 ErrorCode ReadVtk::vtk_create_structured_elems( const long* dims, EntityHandle first_vtx,
00826                                                 std::vector< Range >& elem_list )
00827 {
00828     ErrorCode result;
00829     // int non_zero[3] = {0, 0, 0}; // True if dim > 0 for x, y, z respectively
00830     long elem_dim  = 0;           // Element dimension (2->quad, 3->hex)
00831     long num_elems = 1;           // Total number of elements
00832     long vert_per_elem;           // Element connectivity length
00833     long edims[3] = { 1, 1, 1 };  // Number of elements in each grid direction
00834 
00835     // Populate above data
00836     for( int d = 0; d < 3; d++ )
00837     {
00838         if( dims[d] > 1 )
00839         {
00840             // non_zero[elem_dim] = d;
00841             ++elem_dim;
00842             edims[d] = dims[d] - 1;
00843             num_elems *= edims[d];
00844         }
00845     }
00846     vert_per_elem = 1 << elem_dim;
00847 
00848     // Get element type from element dimension
00849     EntityType type;
00850     switch( elem_dim )
00851     {
00852         case 1:
00853             type = MBEDGE;
00854             break;
00855         case 2:
00856             type = MBQUAD;
00857             break;
00858         case 3:
00859             type = MBHEX;
00860             break;
00861         default:
00862             MB_SET_ERR( MB_FAILURE, "Invalid dimension for structured elements: " << elem_dim );
00863     }
00864 
00865     // Allocate storage for elements
00866     EntityHandle start_handle = 0;
00867     EntityHandle* conn_array;
00868     result = allocate_elements( num_elems, vert_per_elem, type, start_handle, conn_array, elem_list );
00869     if( MB_SUCCESS != result ) return MB_FAILURE;
00870 
00871     EntityHandle* conn_sav = conn_array;
00872 
00873     // Offsets of element vertices in grid relative to corner closest to origin
00874     long k                = dims[0] * dims[1];
00875     const long corners[8] = { 0, 1, 1 + dims[0], dims[0], k, k + 1, k + 1 + dims[0], k + dims[0] };
00876 
00877     // Populate element list
00878     for( long z = 0; z < edims[2]; ++z )
00879         for( long y = 0; y < edims[1]; ++y )
00880             for( long x = 0; x < edims[0]; ++x )
00881             {
00882                 const long index = x + y * dims[0] + z * ( dims[0] * dims[1] );
00883                 for( long j = 0; j < vert_per_elem; ++j, ++conn_array )
00884                     *conn_array = index + corners[j] + first_vtx;
00885             }
00886 
00887     // Notify MOAB of the new elements
00888     result = readMeshIface->update_adjacencies( start_handle, num_elems, vert_per_elem, conn_sav );
00889     if( MB_SUCCESS != result ) return result;
00890 
00891     return MB_SUCCESS;
00892 }
00893 
00894 ErrorCode ReadVtk::vtk_read_field( FileTokenizer& tokens )
00895 {
00896     // This is not supported yet.
00897     // Parse the data but throw it away because
00898     // Mesquite has no internal representation for it.
00899 
00900     // Could save this in tags, but the only useful thing that
00901     // could be done with the data is to write it back out
00902     // with the modified mesh. As there's no way to save the
00903     // type of a tag in Mesquite, it cannot be written back
00904     // out correctly either.
00905     // FIXME: Don't know what to do with this data.
00906     // For now, read it and throw it out.
00907 
00908     long num_arrays;
00909     if( !tokens.get_string() ||  // Name
00910         !tokens.get_long_ints( 1, &num_arrays ) )
00911         return MB_FAILURE;
00912 
00913     for( long i = 0; i < num_arrays; ++i )
00914     {
00915         /*const char* name =*/tokens.get_string();
00916 
00917         long dims[2];
00918         if( !tokens.get_long_ints( 2, dims ) || !tokens.match_token( vtk_type_names ) ) return MB_FAILURE;
00919 
00920         long num_vals = dims[0] * dims[1];
00921 
00922         for( long j = 0; j < num_vals; j++ )
00923         {
00924             double junk;
00925             if( !tokens.get_doubles( 1, &junk ) ) return MB_FAILURE;
00926         }
00927     }
00928 
00929     return MB_SUCCESS;
00930 }
00931 
00932 ErrorCode ReadVtk::vtk_read_attrib_data( FileTokenizer& tokens, std::vector< Range >& entities )
00933 {
00934     const char* const type_names[] = { "SCALARS", "COLOR_SCALARS", "VECTORS", "NORMALS", "TEXTURE_COORDINATES",
00935                                        "TENSORS", "FIELD",         0 };
00936 
00937     int type             = tokens.match_token( type_names );
00938     const char* tmp_name = tokens.get_string();
00939     if( !type || !tmp_name ) return MB_FAILURE;
00940 
00941     std::string name_alloc( tmp_name );
00942     const char* name = name_alloc.c_str();
00943     switch( type )
00944     {
00945         case 1:
00946             return vtk_read_scalar_attrib( tokens, entities, name );
00947         case 2:
00948             return vtk_read_color_attrib( tokens, entities, name );
00949         case 3:
00950             return vtk_read_vector_attrib( tokens, entities, name );
00951         case 4:
00952             return vtk_read_vector_attrib( tokens, entities, name );
00953         case 5:
00954             return vtk_read_texture_attrib( tokens, entities, name );
00955         case 6:
00956             return vtk_read_tensor_attrib( tokens, entities, name );
00957         case 7:
00958             return vtk_read_field_attrib( tokens, entities, name );
00959     }
00960 
00961     return MB_FAILURE;
00962 }
00963 
00964 ErrorCode ReadVtk::vtk_read_tag_data( FileTokenizer& tokens, int type, size_t per_elem, std::vector< Range >& entities,
00965                                       const char* name )
00966 {
00967     ErrorCode result;
00968     DataType mb_type;
00969     if( type == 1 ) { mb_type = MB_TYPE_BIT; }
00970     else if( type >= 2 && type <= 9 )
00971     {
00972         mb_type = MB_TYPE_INTEGER;
00973     }
00974     else if( type == 10 || type == 11 )
00975     {
00976         mb_type = MB_TYPE_DOUBLE;
00977     }
00978     else if( type == 12 )
00979     {
00980         mb_type = MB_TYPE_INTEGER;
00981     }
00982     else
00983         return MB_FAILURE;
00984 
00985 #ifdef MB_VTK_MATERIAL_SETS
00986     size_t size;
00987     if( type == 1 ) { size = sizeof( bool ); }
00988     else if( type >= 2 && type <= 9 )
00989     {
00990         size = sizeof( int );
00991     }
00992     else if( type == 10 || type == 11 )
00993     {
00994         size = sizeof( double );
00995     }
00996     else /* (type == 12) */
00997     {
00998         size = 4;  // Could be 4 or 8, but we don't know. Hope it's 4 because MOAB doesn't support
00999                    // 64-bit ints.
01000     }
01001     Modulator materialMap( this->mdbImpl );
01002     result = materialMap.initialize( this->mPartitionTagName, mb_type, size, per_elem );MB_CHK_SET_ERR( result, "MaterialMap tag (" << this->mPartitionTagName << ") creation failed." );
01003     bool isMaterial = size * per_elem <= 4 &&              // Must have int-sized values (ParallelComm requires it)
01004                       !this->mPartitionTagName.empty() &&  // Must have a non-empty field name...
01005                       !strcmp( name, this->mPartitionTagName.c_str() );  // ... that matches our spec.
01006 #endif                                                                   // MB_VTK_MATERIAL_SETS
01007 
01008     // Get/create tag
01009     Tag handle;
01010     result = mdbImpl->tag_get_handle( name, per_elem, mb_type, handle, MB_TAG_DENSE | MB_TAG_CREAT );MB_CHK_SET_ERR( result, "Tag name conflict for attribute \"" << name << "\" at line " << tokens.line_number() );
01011 
01012     std::vector< Range >::iterator iter;
01013 
01014     if( type == 1 )
01015     {
01016         for( iter = entities.begin(); iter != entities.end(); ++iter )
01017         {
01018             bool* data = new bool[iter->size() * per_elem];
01019             if( !tokens.get_booleans( per_elem * iter->size(), data ) )
01020             {
01021                 delete[] data;
01022                 return MB_FAILURE;
01023             }
01024 
01025             bool* data_iter          = data;
01026             Range::iterator ent_iter = iter->begin();
01027             for( ; ent_iter != iter->end(); ++ent_iter )
01028             {
01029                 unsigned char bits = 0;
01030                 for( unsigned j = 0; j < per_elem; ++j, ++data_iter )
01031                     bits |= (unsigned char)( *data_iter << j );
01032 #ifdef MB_VTK_MATERIAL_SETS
01033                 if( isMaterial ) materialMap.add_entity( *ent_iter, &bits, 1 );
01034 #endif  // MB_VTK_MATERIAL_SETS
01035                 result = mdbImpl->tag_set_data( handle, &*ent_iter, 1, &bits );
01036                 if( MB_SUCCESS != result )
01037                 {
01038                     delete[] data;
01039                     return result;
01040                 }
01041             }
01042             delete[] data;
01043         }
01044     }
01045     else if( ( type >= 2 && type <= 9 ) || type == 12 )
01046     {
01047         std::vector< int > data;
01048         for( iter = entities.begin(); iter != entities.end(); ++iter )
01049         {
01050             data.resize( iter->size() * per_elem );
01051             if( !tokens.get_integers( iter->size() * per_elem, &data[0] ) ) return MB_FAILURE;
01052 #ifdef MB_VTK_MATERIAL_SETS
01053             if( isMaterial ) materialMap.add_entities( *iter, (unsigned char*)&data[0], per_elem * size );
01054 #endif  // MB_VTK_MATERIAL_SETS
01055             result = mdbImpl->tag_set_data( handle, *iter, &data[0] );
01056             if( MB_SUCCESS != result ) return result;
01057         }
01058     }
01059     else if( type == 10 || type == 11 )
01060     {
01061         std::vector< double > data;
01062         for( iter = entities.begin(); iter != entities.end(); ++iter )
01063         {
01064             data.resize( iter->size() * per_elem );
01065             if( !tokens.get_doubles( iter->size() * per_elem, &data[0] ) ) return MB_FAILURE;
01066 #ifdef MB_VTK_MATERIAL_SETS
01067             if( isMaterial ) materialMap.add_entities( *iter, (unsigned char*)&data[0], per_elem * size );
01068 #endif  // MB_VTK_MATERIAL_SETS
01069             result = mdbImpl->tag_set_data( handle, *iter, &data[0] );
01070             if( MB_SUCCESS != result ) return result;
01071         }
01072     }
01073 
01074     return MB_SUCCESS;
01075 }
01076 
01077 ErrorCode ReadVtk::vtk_read_scalar_attrib( FileTokenizer& tokens, std::vector< Range >& entities, const char* name )
01078 {
01079     int type = tokens.match_token( vtk_type_names );
01080     if( !type ) return MB_FAILURE;
01081 
01082     long size;
01083     const char* tok = tokens.get_string();
01084     if( !tok ) return MB_FAILURE;
01085 
01086     const char* end = 0;
01087     size            = strtol( tok, (char**)&end, 0 );
01088     if( *end )
01089     {
01090         size = 1;
01091         tokens.unget_token();
01092     }
01093 
01094     // VTK spec says cannot be greater than 4--do we care?
01095     if( size < 1 )
01096     {  //|| size > 4)
01097         MB_SET_ERR( MB_FAILURE, "Scalar count out of range [1,4] at line " << tokens.line_number() );
01098     }
01099 
01100     if( !tokens.match_token( "LOOKUP_TABLE" ) || !tokens.match_token( "default" ) ) return MB_FAILURE;
01101 
01102     return vtk_read_tag_data( tokens, type, size, entities, name );
01103 }
01104 
01105 ErrorCode ReadVtk::vtk_read_color_attrib( FileTokenizer& tokens, std::vector< Range >& entities, const char* name )
01106 {
01107     long size;
01108     if( !tokens.get_long_ints( 1, &size ) || size < 1 ) return MB_FAILURE;
01109 
01110     return vtk_read_tag_data( tokens, 10, size, entities, name );
01111 }
01112 
01113 ErrorCode ReadVtk::vtk_read_vector_attrib( FileTokenizer& tokens, std::vector< Range >& entities, const char* name )
01114 {
01115     int type = tokens.match_token( vtk_type_names );
01116     if( !type ) return MB_FAILURE;
01117 
01118     return vtk_read_tag_data( tokens, type, 3, entities, name );
01119 }
01120 
01121 ErrorCode ReadVtk::vtk_read_texture_attrib( FileTokenizer& tokens, std::vector< Range >& entities, const char* name )
01122 {
01123     int type, dim;
01124     if( !tokens.get_integers( 1, &dim ) || !( type = tokens.match_token( vtk_type_names ) ) ) return MB_FAILURE;
01125 
01126     if( dim < 1 || dim > 3 )
01127     { MB_SET_ERR( MB_FAILURE, "Invalid dimension (" << dim << ") at line " << tokens.line_number() ); }
01128 
01129     return vtk_read_tag_data( tokens, type, dim, entities, name );
01130 }
01131 
01132 ErrorCode ReadVtk::vtk_read_tensor_attrib( FileTokenizer& tokens, std::vector< Range >& entities, const char* name )
01133 {
01134     int type = tokens.match_token( vtk_type_names );
01135     if( !type ) return MB_FAILURE;
01136 
01137     return vtk_read_tag_data( tokens, type, 9, entities, name );
01138 }
01139 
01140 ErrorCode ReadVtk::vtk_read_field_attrib( FileTokenizer& tokens, std::vector< Range >& entities, const char* )
01141 {
01142     long num_fields;
01143     if( !tokens.get_long_ints( 1, &num_fields ) ) return MB_FAILURE;
01144 
01145     long i;
01146     for( i = 0; i < num_fields; ++i )
01147     {
01148         const char* tok = tokens.get_string();
01149         if( !tok ) return MB_FAILURE;
01150 
01151         std::string name_alloc( tok );
01152 
01153         long num_comp;
01154         if( !tokens.get_long_ints( 1, &num_comp ) ) return MB_FAILURE;
01155 
01156         long num_tuples;
01157         if( !tokens.get_long_ints( 1, &num_tuples ) ) return MB_FAILURE;
01158 
01159         int type = tokens.match_token( vtk_type_names );
01160         if( !type ) return MB_FAILURE;
01161 
01162         ErrorCode result = vtk_read_tag_data( tokens, type, num_comp, entities, name_alloc.c_str() );MB_CHK_SET_ERR( result, "Error reading data for field \"" << name_alloc << "\" (" << num_comp << " components, "
01163                                                                   << num_tuples << " tuples, type " << type
01164                                                                   << ") at line " << tokens.line_number() );
01165     }
01166 
01167     return MB_SUCCESS;
01168 }
01169 
01170 ErrorCode ReadVtk::store_file_ids( Tag tag, const Range& verts, const std::vector< Range >& elems )
01171 {
01172     ErrorCode rval;
01173 
01174     rval = readMeshIface->assign_ids( tag, verts );
01175     if( MB_SUCCESS != rval ) return rval;
01176 
01177     int id = 0;
01178     for( size_t i = 0; i < elems.size(); ++i )
01179     {
01180         rval = readMeshIface->assign_ids( tag, elems[i], id );
01181         id += elems[i].size();
01182     }
01183 
01184     return MB_SUCCESS;
01185 }
01186 
01187 }  // namespace moab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines