37 #ifdef MB_VTK_MATERIAL_SETS
44 #ifdef MB_VTK_MATERIAL_SETS
56 Hash(
const unsigned char* bytes,
size_t len )
59 for( ; len; --len, ++bytes )
60 this->value = this->value * 33 + ( *bytes );
68 Hash(
const Hash& src )
70 this->value = src.value;
73 Hash& operator=(
const Hash& src )
75 this->value = src.value;
81 return this->value < other.value;
94 class Modulator :
public std::map< Hash, EntityHandle >
97 Modulator( Interface*
iface ) : mesh(
iface ) {}
101 std::vector< unsigned char > default_val;
102 default_val.resize( sz * per_elem );
103 ErrorCode rval = this->mesh->tag_get_handle( tag_name.c_str(), per_elem, mb_type, this->tag,
108 void add_entity(
EntityHandle ent,
const unsigned char* bytes,
size_t len )
110 Hash h( bytes, len );
113 rval = this->mesh->add_entities( mset, &ent, 1 );
MB_CHK_SET_ERR_RET( rval,
"Failed to add entities to mesh" );
116 void add_entities( Range& range,
const unsigned char* bytes,
size_t bytes_per_ent )
118 for(
Range::iterator it = range.begin(); it != range.end(); ++it, bytes += bytes_per_ent )
120 Hash h( bytes, bytes_per_ent );
123 rval = this->mesh->add_entities( mset, &*it, 1 );
MB_CHK_SET_ERR_RET( rval,
"Failed to add entities to mesh" );
127 EntityHandle congruence_class(
const Hash& h,
const void* tag_data )
129 std::map< Hash, EntityHandle >::iterator it = this->find( h );
130 if( it == this->end() )
136 if( preexist.size() )
138 mset = *preexist.begin();
176 "bit",
"char",
"unsigned_char",
"short",
"unsigned_short",
"int",
"unsigned_int",
177 "long",
"unsigned_long",
"float",
"double",
"vtkIdType", 0 };
182 std::vector< int >& ,
192 const Tag* file_id_tag )
197 char vendor_string[257];
198 std::vector< Range > element_list;
208 std::string partition_tag_name;
209 result = opts.
get_option(
"PARTITION", partition_tag_name );
212 FILE* file = fopen( filename,
"r" );
217 if( !fgets( vendor_string,
sizeof( vendor_string ), file ) )
223 if( !strchr( vendor_string,
'\n' ) || 2 != sscanf( vendor_string,
"# vtk DataFile Version %d.%d", &
major, &
minor ) )
229 if( !fgets( vendor_string,
sizeof( vendor_string ), file ) )
236 if( !strchr( vendor_string,
'\n' ) )
239 MB_SET_ERR( MB_FAILURE,
"Vendor string (line 2) exceeds 256 characters" );
245 const char*
const file_type_names[] = {
"ASCII",
"BINARY", 0 };
246 int filetype = tokens.
match_token( file_type_names );
250 MB_SET_ERR( MB_FAILURE,
"Cannot read BINARY VTK files" );
258 if( !tokens.
match_token(
"DATASET" ) )
return MB_FAILURE;
270 for( std::vector< Range >::iterator it = element_list.begin(); it != element_list.end(); ++it )
271 elem_count += it->size();
274 const char*
const block_type_names[] = {
"POINT_DATA",
"CELL_DATA", 0 };
275 std::vector< Range > vertex_list( 1 );
276 vertex_list[0] = vertices;
278 while( !tokens.
eof() )
281 int new_block_type = tokens.
match_token( block_type_names,
false );
282 if( tokens.
eof() )
break;
284 if( !new_block_type )
295 blocktype = new_block_type;
299 if( blocktype == 1 && (
unsigned long)count != vertices.
size() )
301 MB_SET_ERR( MB_FAILURE,
"Count inconsistent with number of vertices at line " << tokens.
line_number() );
303 else if( blocktype == 2 && count != elem_count )
305 MB_SET_ERR( MB_FAILURE,
"Count inconsistent with number of elements at line " << tokens.
line_number() );
322 double*& x_coord_array_out,
323 double*& y_coord_array_out,
324 double*& z_coord_array_out )
329 std::vector< double* > arrays;
330 start_handle_out = 0;
334 x_coord_array_out = arrays[0];
335 y_coord_array_out = arrays[1];
336 z_coord_array_out = arrays[2];
350 for(
long vtx = 0; vtx < num_verts; ++vtx )
360 int vert_per_element,
364 std::vector< Range >& append_to_this )
368 start_handle_out = 0;
373 Range range( start_handle_out, start_handle_out + num_elements - 1 );
374 append_to_this.push_back( range );
380 const char*
const data_type_names[] = {
381 "STRUCTURED_POINTS",
"STRUCTURED_GRID",
"UNSTRUCTURED_GRID",
"POLYDATA",
"RECTILINEAR_GRID",
"FIELD", 0 };
382 int datatype = tokens.
match_token( data_type_names );
404 std::vector< Range >& elem_list )
408 double origin[3], space[3];
414 if( dims[0] < 1 || dims[1] < 1 || dims[2] < 1 )
422 const char*
const spacing_names[] = {
"SPACING",
"ASPECT_RATIO", 0 };
429 long num_verts = dims[0] * dims[1] * dims[2];
432 vertex_list.
insert( start_handle, start_handle + num_verts - 1 );
434 for( k = 0; k < dims[2]; ++k )
435 for( j = 0; j < dims[1]; ++j )
436 for( i = 0; i < dims[0]; ++i )
438 *x = origin[0] + i * space[0];
440 *y = origin[1] + j * space[1];
442 *z = origin[2] + k * space[2];
451 std::vector< Range >& elem_list )
453 long num_verts, dims[3];
459 if( dims[0] < 1 || dims[1] < 1 || dims[2] < 1 )
468 if( num_verts != ( dims[0] * dims[1] * dims[2] ) )
470 MB_SET_ERR( MB_FAILURE,
"Point count not consistent with dimensions at line " << tokens.
line_number() );
477 vertex_list.
insert( start_handle, start_handle + num_verts - 1 );
484 std::vector< Range >& elem_list )
488 const char* labels[] = {
"X_COORDINATES",
"Y_COORDINATES",
"Z_COORDINATES" };
489 std::vector< double > coords[3];
495 if( dims[0] < 1 || dims[1] < 1 || dims[2] < 1 )
500 for( i = 0; i < 3; i++ )
507 if( count != dims[i] )
509 MB_SET_ERR( MB_FAILURE,
"Coordinate count inconsistent with dimensions at line " << tokens.
line_number() );
512 coords[i].resize( count );
513 if( !tokens.
get_doubles( count, &coords[i][0] ) )
return MB_FAILURE;
519 long num_verts = dims[0] * dims[1] * dims[2];
522 vertex_list.
insert( start_handle, start_handle + num_verts - 1 );
525 for( k = 0; k < dims[2]; ++k )
526 for( j = 0; j < dims[1]; ++j )
527 for( i = 0; i < dims[0]; ++i )
544 const char*
const poly_data_names[] = {
"VERTICES",
"LINES",
"POLYGONS",
"TRIANGLE_STRIPS", 0 };
559 vertex_list.
insert( start_handle, start_handle + num_verts - 1 );
561 int poly_type = tokens.
match_token( poly_data_names );
594 std::vector< EntityHandle > conn_hdl;
595 std::vector< long > conn_idx;
597 for(
int i = 0; i <
size[0]; ++i )
601 conn_idx.resize( count );
602 conn_hdl.resize( count );
603 if( !tokens.
get_long_ints( count, &conn_idx[0] ) )
return MB_FAILURE;
605 for(
long j = 0; j < count; ++j )
606 conn_hdl[j] = first_vtx + conn_idx[j];
611 if( prev + 1 != handle )
615 if( elem_list.empty() ||
first < elem_list.back().front() )
617 elem_list.push_back( empty );
618 elem_list.back().insert(
first, prev );
626 if( elem_list.empty() ||
first < elem_list.back().front() )
628 elem_list.push_back( empty );
629 elem_list.back().insert(
first, prev );
637 std::vector< Range >& elem_list )
640 long i, num_verts, num_elems[2];
649 const char* pts_str[] = {
"FIELD",
"POINTS", 0 };
650 while( 1 == ( i = tokens.
match_token( pts_str ) ) )
655 if( i != 2 )
return MB_FAILURE;
669 vertex_list.
insert( first_vertex, first_vertex + num_verts - 1 );
671 const char* cell_str[] = {
"FIELD",
"CELLS", 0 };
672 while( 1 == ( i = tokens.
match_token( cell_str ) ) )
677 if( i != 2 )
return MB_FAILURE;
682 std::vector< long > connectivity( num_elems[1] );
683 if( !tokens.
get_long_ints( num_elems[1], &connectivity[0] ) )
return MB_FAILURE;
689 std::vector< long > types( num_elems[0] );
690 if( !tokens.
get_long_ints( num_elems[0], &types[0] ) )
return MB_FAILURE;
697 std::vector< long >::iterator conn_iter = connectivity.begin();
698 while(
id < num_elems[0] )
700 unsigned vtk_type = types[id];
707 << vtk_type <<
")" );
710 int num_vtx = *conn_iter;
714 <<
"' but has " << num_vtx <<
" vertices" );
719 std::vector< long >::iterator conn_iter2 = conn_iter + num_vtx + 1;
720 long end_id =
id + 1;
723 while( end_id < num_elems[0] && (
unsigned)types[end_id] == vtk_type && *conn_iter2 == num_vtx )
726 conn_iter2 += num_vtx + 1;
732 int num_faces = conn_iter[1];
733 while( end_id < num_elems[0] && (
unsigned)types[end_id] == vtk_type && conn_iter2[1] == num_faces )
736 conn_iter2 += num_vtx + 1;
746 long num_elem = end_id - id;
754 conn_iter += 2 * num_elem;
758 result =
allocate_elements( num_elem, num_vtx, type, start_handle, conn_array, elem_list );
766 for( ;
id < end_id; ++id )
768 if( conn_iter == connectivity.end() )
770 MB_SET_ERR( MB_FAILURE,
"Connectivity data truncated at cell " <<
id );
773 if( *conn_iter != num_vtx )
776 <<
"' but has " << num_vtx <<
" vertices" );
780 for( i = 0; i < num_vtx; ++i, ++conn_iter )
782 if( conn_iter == connectivity.end() )
784 MB_SET_ERR( MB_FAILURE,
"Connectivity data truncated at cell " <<
id );
787 conn_array[i] = *conn_iter + first_vertex;
793 assert( num_vtx *
sizeof(
EntityHandle ) <=
sizeof( tmp_conn_list ) );
794 memcpy( tmp_conn_list, conn_array, num_vtx *
sizeof(
EntityHandle ) );
795 for(
int j = 0; j < num_vtx; ++j )
796 conn_array[order[j]] = tmp_conn_list[j];
799 conn_array += num_vtx;
807 for( ;
id < end_id; ++id )
809 if( conn_iter == connectivity.end() )
811 MB_SET_ERR( MB_FAILURE,
"Connectivity data truncated at polyhedra cell " <<
id );
816 int num_faces = *conn_iter;
817 if( num_faces != num_vtx )
MB_SET_ERR( MB_FAILURE,
"Connectivity data wrong at polyhedra cell " <<
id );
821 for(
int j = 0; j < num_faces; j++ )
824 int numverticesInFace = (int)*conn_iter;
825 if( numverticesInFace > 20 )
827 "too many vertices in face index " << j <<
" for polyhedra cell " <<
id );
829 for(
int k = 0; k < numverticesInFace; k++ )
831 connec[k] = first_vertex + *( ++conn_iter );
836 if( adjFaces.
size() >= 1 )
838 conn_array[j] = adjFaces[0];
843 EntityType etype =
MBTRI;
844 if( 4 == numverticesInFace ) etype =
MBQUAD;
845 if( 4 < numverticesInFace ) etype =
MBPOLYGON;
851 conn_array += num_vtx;
866 std::vector< Range >& elem_list )
873 long edims[3] = { 1, 1, 1 };
876 for(
int d = 0; d < 3; d++ )
882 edims[d] = dims[d] - 1;
883 num_elems *= edims[d];
886 vert_per_elem = 1 << elem_dim;
902 MB_SET_ERR( MB_FAILURE,
"Invalid dimension for structured elements: " << elem_dim );
908 result =
allocate_elements( num_elems, vert_per_elem, type, start_handle, conn_array, elem_list );
914 long k = dims[0] * dims[1];
915 const long corners[8] = { 0, 1, 1 + dims[0], dims[0], k, k + 1, k + 1 + dims[0], k + dims[0] };
918 for(
long z = 0; z < edims[2]; ++z )
919 for(
long y = 0; y < edims[1]; ++y )
920 for(
long x = 0; x < edims[0]; ++x )
922 const long index = x + y * dims[0] + z * ( dims[0] * dims[1] );
923 for(
long j = 0; j < vert_per_elem; ++j, ++conn_array )
924 *conn_array = index + corners[j] + first_vtx;
953 for(
long i = 0; i < num_arrays; ++i )
960 long num_vals = dims[0] * dims[1];
962 for(
long j = 0; j < num_vals; j++ )
965 if( !tokens.
get_doubles( 1, &junk ) )
return MB_FAILURE;
974 const char*
const type_names[] = {
"SCALARS",
"COLOR_SCALARS",
"VECTORS",
"NORMALS",
"TEXTURE_COORDINATES",
975 "TENSORS",
"FIELD", 0 };
979 if( !type || !tmp_name )
return MB_FAILURE;
981 std::string name_alloc( tmp_name );
982 const char* name = name_alloc.c_str();
1016 else if( type >= 2 && type <= 9 )
1020 else if( type == 10 || type == 11 )
1024 else if( type == 12 )
1031 #ifdef MB_VTK_MATERIAL_SETS
1035 size =
sizeof( bool );
1037 else if( type >= 2 && type <= 9 )
1039 size =
sizeof( int );
1041 else if( type == 10 || type == 11 )
1043 size =
sizeof( double );
1050 Modulator materialMap( this->
mdbImpl );
1052 bool isMaterial =
size * per_elem <= 4 &&
1061 std::vector< Range >::iterator iter;
1067 bool* data =
new bool[iter->size() * per_elem];
1068 if( !tokens.
get_booleans( per_elem * iter->size(), data ) )
1074 bool* data_iter = data;
1076 for( ; ent_iter != iter->end(); ++ent_iter )
1078 unsigned char bits = 0;
1079 for(
unsigned j = 0; j < per_elem; ++j, ++data_iter )
1080 bits |= (
unsigned char)( *data_iter << j );
1081 #ifdef MB_VTK_MATERIAL_SETS
1082 if( isMaterial ) materialMap.add_entity( *ent_iter, &bits, 1 );
1094 else if( ( type >= 2 && type <= 9 ) || type == 12 )
1096 std::vector< int > data;
1099 data.resize( iter->size() * per_elem );
1100 if( !tokens.
get_integers( iter->size() * per_elem, &data[0] ) )
return MB_FAILURE;
1101 #ifdef MB_VTK_MATERIAL_SETS
1102 if( isMaterial ) materialMap.add_entities( *iter, (
unsigned char*)&data[0], per_elem *
size );
1108 else if( type == 10 || type == 11 )
1110 std::vector< double > data;
1113 data.resize( iter->size() * per_elem );
1114 if( !tokens.
get_doubles( iter->size() * per_elem, &data[0] ) )
return MB_FAILURE;
1115 #ifdef MB_VTK_MATERIAL_SETS
1116 if( isMaterial ) materialMap.add_entities( *iter, (
unsigned char*)&data[0], per_elem *
size );
1129 if( !type )
return MB_FAILURE;
1133 if( !tok )
return MB_FAILURE;
1135 const char* end = 0;
1136 size = strtol( tok, (
char**)&end, 0 );
1165 if( !type )
return MB_FAILURE;
1175 if( dim < 1 || dim > 3 )
1186 if( !type )
return MB_FAILURE;
1194 if( !tokens.
get_long_ints( 1, &num_fields ) )
return MB_FAILURE;
1197 for( i = 0; i < num_fields; ++i )
1200 if( !tok )
return MB_FAILURE;
1202 std::string name_alloc( tok );
1205 if( !tokens.
get_long_ints( 1, &num_comp ) )
return MB_FAILURE;
1208 if( !tokens.
get_long_ints( 1, &num_tuples ) )
return MB_FAILURE;
1211 if( !type )
return MB_FAILURE;
1214 << num_tuples <<
" tuples, type " << type
1229 for(
size_t i = 0; i < elems.size(); ++i )
1232 id += elems[i].size();