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 );
117 void add_entities( Range& range,
const unsigned char* bytes,
size_t bytes_per_ent )
119 for(
Range::iterator it = range.begin(); it != range.end(); ++it, bytes += bytes_per_ent )
121 Hash h( bytes, bytes_per_ent );
124 rval = this->mesh->add_entities( mset, &*it, 1 );
129 EntityHandle congruence_class(
const Hash& h,
const void* tag_data )
131 std::map< Hash, EntityHandle >::iterator it = this->find( h );
132 if( it == this->end() )
137 rval = this->mesh->get_entities_by_type_and_tag( 0,
MBENTITYSET, &this->tag, &tag_data, 1, preexist );
139 if( preexist.size() )
141 mset = *preexist.begin();
145 rval = this->mesh->create_meshset(
MESHSET_SET, mset );
147 rval = this->mesh->tag_set_data( this->tag, &mset, 1, tag_data );
181 "bit",
"char",
"unsigned_char",
"short",
"unsigned_short",
"int",
"unsigned_int",
182 "long",
"unsigned_long",
"float",
"double",
"vtkIdType", 0 };
187 std::vector< int >& ,
197 const Tag* file_id_tag )
202 char vendor_string[257];
203 std::vector< Range > element_list;
213 std::string partition_tag_name;
214 result = opts.
get_option(
"PARTITION", partition_tag_name );
217 FILE* file = fopen( filename,
"r" );
222 if( !fgets( vendor_string,
sizeof( vendor_string ), file ) )
228 if( !strchr( vendor_string,
'\n' ) || 2 != sscanf( vendor_string,
"# vtk DataFile Version %d.%d", &
major, &
minor ) )
234 if( !fgets( vendor_string,
sizeof( vendor_string ), file ) )
241 if( !strchr( vendor_string,
'\n' ) )
244 MB_SET_ERR( MB_FAILURE,
"Vendor string (line 2) exceeds 256 characters" );
250 const char*
const file_type_names[] = {
"ASCII",
"BINARY", 0 };
251 int filetype = tokens.
match_token( file_type_names );
255 MB_SET_ERR( MB_FAILURE,
"Cannot read BINARY VTK files" );
263 if( !tokens.
match_token(
"DATASET" ) )
return MB_FAILURE;
275 for( std::vector< Range >::iterator it = element_list.begin(); it != element_list.end(); ++it )
276 elem_count += it->size();
279 const char*
const block_type_names[] = {
"POINT_DATA",
"CELL_DATA", 0 };
280 std::vector< Range > vertex_list( 1 );
281 vertex_list[0] = vertices;
283 while( !tokens.
eof() )
286 int new_block_type = tokens.
match_token( block_type_names,
false );
287 if( tokens.
eof() )
break;
289 if( !new_block_type )
300 blocktype = new_block_type;
304 if( blocktype == 1 && (
unsigned long)count != vertices.
size() )
306 MB_SET_ERR( MB_FAILURE,
"Count inconsistent with number of vertices at line " << tokens.
line_number() );
308 else if( blocktype == 2 && count != elem_count )
310 MB_SET_ERR( MB_FAILURE,
"Count inconsistent with number of elements at line " << tokens.
line_number() );
327 double*& x_coord_array_out,
328 double*& y_coord_array_out,
329 double*& z_coord_array_out )
334 std::vector< double* > arrays;
335 start_handle_out = 0;
339 x_coord_array_out = arrays[0];
340 y_coord_array_out = arrays[1];
341 z_coord_array_out = arrays[2];
355 for(
long vtx = 0; vtx < num_verts; ++vtx )
365 int vert_per_element,
369 std::vector< Range >& append_to_this )
373 start_handle_out = 0;
378 Range range( start_handle_out, start_handle_out + num_elements - 1 );
379 append_to_this.push_back( range );
385 const char*
const data_type_names[] = {
386 "STRUCTURED_POINTS",
"STRUCTURED_GRID",
"UNSTRUCTURED_GRID",
"POLYDATA",
"RECTILINEAR_GRID",
"FIELD", 0 };
387 int datatype = tokens.
match_token( data_type_names );
409 std::vector< Range >& elem_list )
413 double origin[3], space[3];
419 if( dims[0] < 1 || dims[1] < 1 || dims[2] < 1 )
427 const char*
const spacing_names[] = {
"SPACING",
"ASPECT_RATIO", 0 };
434 long num_verts = dims[0] * dims[1] * dims[2];
437 vertex_list.
insert( start_handle, start_handle + num_verts - 1 );
439 for( k = 0; k < dims[2]; ++k )
440 for( j = 0; j < dims[1]; ++j )
441 for( i = 0; i < dims[0]; ++i )
443 *x = origin[0] + i * space[0];
445 *y = origin[1] + j * space[1];
447 *z = origin[2] + k * space[2];
456 std::vector< Range >& elem_list )
458 long num_verts, dims[3];
464 if( dims[0] < 1 || dims[1] < 1 || dims[2] < 1 )
473 if( num_verts != ( dims[0] * dims[1] * dims[2] ) )
475 MB_SET_ERR( MB_FAILURE,
"Point count not consistent with dimensions at line " << tokens.
line_number() );
482 vertex_list.
insert( start_handle, start_handle + num_verts - 1 );
489 std::vector< Range >& elem_list )
493 const char* labels[] = {
"X_COORDINATES",
"Y_COORDINATES",
"Z_COORDINATES" };
494 std::vector< double > coords[3];
500 if( dims[0] < 1 || dims[1] < 1 || dims[2] < 1 )
505 for( i = 0; i < 3; i++ )
512 if( count != dims[i] )
514 MB_SET_ERR( MB_FAILURE,
"Coordinate count inconsistent with dimensions at line " << tokens.
line_number() );
517 coords[i].resize( count );
518 if( !tokens.
get_doubles( count, &coords[i][0] ) )
return MB_FAILURE;
524 long num_verts = dims[0] * dims[1] * dims[2];
527 vertex_list.
insert( start_handle, start_handle + num_verts - 1 );
530 for( k = 0; k < dims[2]; ++k )
531 for( j = 0; j < dims[1]; ++j )
532 for( i = 0; i < dims[0]; ++i )
549 const char*
const poly_data_names[] = {
"VERTICES",
"LINES",
"POLYGONS",
"TRIANGLE_STRIPS", 0 };
564 vertex_list.
insert( start_handle, start_handle + num_verts - 1 );
566 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 );
837 if( adjFaces.
size() >= 1 )
839 conn_array[j] = adjFaces[0];
844 EntityType etype =
MBTRI;
845 if( 4 == numverticesInFace ) etype =
MBQUAD;
846 if( 4 < numverticesInFace ) etype =
MBPOLYGON;
853 conn_array += num_vtx;
868 std::vector< Range >& elem_list )
875 long edims[3] = { 1, 1, 1 };
878 for(
int d = 0; d < 3; d++ )
884 edims[d] = dims[d] - 1;
885 num_elems *= edims[d];
888 vert_per_elem = 1 << elem_dim;
904 MB_SET_ERR( MB_FAILURE,
"Invalid dimension for structured elements: " << elem_dim );
910 result =
allocate_elements( num_elems, vert_per_elem, type, start_handle, conn_array, elem_list );
916 long k = dims[0] * dims[1];
917 const long corners[8] = { 0, 1, 1 + dims[0], dims[0], k, k + 1, k + 1 + dims[0], k + dims[0] };
920 for(
long z = 0; z < edims[2]; ++z )
921 for(
long y = 0; y < edims[1]; ++y )
922 for(
long x = 0; x < edims[0]; ++x )
924 const long index = x + y * dims[0] + z * ( dims[0] * dims[1] );
925 for(
long j = 0; j < vert_per_elem; ++j, ++conn_array )
926 *conn_array =
index + corners[j] + first_vtx;
955 for(
long i = 0; i < num_arrays; ++i )
962 long num_vals = dims[0] * dims[1];
964 for(
long j = 0; j < num_vals; j++ )
967 if( !tokens.
get_doubles( 1, &junk ) )
return MB_FAILURE;
976 const char*
const type_names[] = {
"SCALARS",
"COLOR_SCALARS",
"VECTORS",
"NORMALS",
"TEXTURE_COORDINATES",
977 "TENSORS",
"FIELD", 0 };
981 if( !type || !tmp_name )
return MB_FAILURE;
983 std::string name_alloc( tmp_name );
984 const char* name = name_alloc.c_str();
1009 std::vector< Range >& entities,
1018 else if( type >= 2 && type <= 9 )
1022 else if( type == 10 || type == 11 )
1026 else if( type == 12 )
1033 #ifdef MB_VTK_MATERIAL_SETS
1037 size =
sizeof( bool );
1039 else if( type >= 2 && type <= 9 )
1041 size =
sizeof( int );
1043 else if( type == 10 || type == 11 )
1045 size =
sizeof( double );
1052 Modulator materialMap( this->
mdbImpl );
1053 result = materialMap.initialize( this->
mPartitionTagName, mb_type, size, per_elem );
1055 bool isMaterial = size * per_elem <= 4 &&
1065 std::vector< Range >::iterator iter;
1069 for( iter = entities.begin(); iter != entities.end(); ++iter )
1071 bool* data =
new bool[iter->size() * per_elem];
1072 if( !tokens.
get_booleans( per_elem * iter->size(), data ) )
1078 bool* data_iter = data;
1080 for( ; ent_iter != iter->end(); ++ent_iter )
1082 unsigned char bits = 0;
1083 for(
unsigned j = 0; j < per_elem; ++j, ++data_iter )
1084 bits |= (
unsigned char)( *data_iter << j );
1085 #ifdef MB_VTK_MATERIAL_SETS
1086 if( isMaterial ) materialMap.add_entity( *ent_iter, &bits, 1 );
1098 else if( ( type >= 2 && type <= 9 ) || type == 12 )
1100 std::vector< int > data;
1101 for( iter = entities.begin(); iter != entities.end(); ++iter )
1103 data.resize( iter->size() * per_elem );
1104 if( !tokens.
get_integers( iter->size() * per_elem, &data[0] ) )
return MB_FAILURE;
1105 #ifdef MB_VTK_MATERIAL_SETS
1106 if( isMaterial ) materialMap.add_entities( *iter, (
unsigned char*)&data[0], per_elem * size );
1112 else if( type == 10 || type == 11 )
1114 std::vector< double > data;
1115 for( iter = entities.begin(); iter != entities.end(); ++iter )
1117 data.resize( iter->size() * per_elem );
1118 if( !tokens.
get_doubles( iter->size() * per_elem, &data[0] ) )
return MB_FAILURE;
1119 #ifdef MB_VTK_MATERIAL_SETS
1120 if( isMaterial ) materialMap.add_entities( *iter, (
unsigned char*)&data[0], per_elem * size );
1133 if( !type )
return MB_FAILURE;
1137 if( !tok )
return MB_FAILURE;
1139 const char* end = 0;
1140 size = strtol( tok, (
char**)&end, 0 );
1161 if( !tokens.
get_long_ints( 1, &size ) || size < 1 )
return MB_FAILURE;
1169 if( !type )
return MB_FAILURE;
1179 if( dim < 1 || dim > 3 )
1190 if( !type )
return MB_FAILURE;
1198 if( !tokens.
get_long_ints( 1, &num_fields ) )
return MB_FAILURE;
1201 for( i = 0; i < num_fields; ++i )
1204 if( !tok )
return MB_FAILURE;
1206 std::string name_alloc( tok );
1209 if( !tokens.
get_long_ints( 1, &num_comp ) )
return MB_FAILURE;
1212 if( !tokens.
get_long_ints( 1, &num_tuples ) )
return MB_FAILURE;
1215 if( !type )
return MB_FAILURE;
1218 MB_CHK_SET_ERR( result,
"Error reading data for field \"" << name_alloc <<
"\" (" << num_comp <<
" components, "
1219 << num_tuples <<
" tuples, type " << type
1234 for(
size_t i = 0; i < elems.size(); ++i )
1237 id += elems[i].size();