MOAB: Mesh Oriented datABase
(version 5.2.1)
|
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 #ifdef WIN32 00017 #ifdef _DEBUG 00018 // turn off warnings that say they debugging identifier has been truncated 00019 // this warning comes up when using some STL containers 00020 #pragma warning( disable : 4786 ) 00021 #endif 00022 #endif 00023 00024 #include "WriteTemplate.hpp" 00025 00026 #include <utility> 00027 #include <algorithm> 00028 #include <time.h> 00029 #include <string> 00030 #include <vector> 00031 #include <stdio.h> 00032 #include <string.h> 00033 #include <iostream> 00034 00035 #include "moab/Interface.hpp" 00036 #include "moab/Range.hpp" 00037 #include "moab/CN.hpp" 00038 #include "assert.h" 00039 #include "Internals.hpp" 00040 #include "ExoIIUtil.hpp" 00041 #include "MBTagConventions.hpp" 00042 #include "moab/WriteUtilIface.hpp" 00043 00044 namespace moab 00045 { 00046 00047 #define INS_ID( stringvar, prefix, id ) sprintf( stringvar, prefix, id ) 00048 00049 WriterIface* WriteTemplate::factory( Interface* iface ) 00050 { 00051 return new WriteTemplate( iface ); 00052 } 00053 00054 WriteTemplate::WriteTemplate( Interface* impl ) : mbImpl( impl ) 00055 { 00056 assert( impl != NULL ); 00057 00058 impl->query_interface( mWriteIface ); 00059 00060 // Initialize in case tag_get_handle fails below 00061 //! Get and cache predefined tag handles 00062 int negone = -1; 00063 impl->tag_get_handle( MATERIAL_SET_TAG_NAME, 1, MB_TYPE_INTEGER, mMaterialSetTag, MB_TAG_SPARSE | MB_TAG_CREAT, 00064 &negone ); 00065 00066 impl->tag_get_handle( DIRICHLET_SET_TAG_NAME, 1, MB_TYPE_INTEGER, mDirichletSetTag, MB_TAG_SPARSE | MB_TAG_CREAT, 00067 &negone ); 00068 00069 impl->tag_get_handle( NEUMANN_SET_TAG_NAME, 1, MB_TYPE_INTEGER, mNeumannSetTag, MB_TAG_SPARSE | MB_TAG_CREAT, 00070 &negone ); 00071 00072 mGlobalIdTag = impl->globalId_tag(); 00073 00074 impl->tag_get_handle( "WriteTemplate element mark", 1, MB_TYPE_BIT, mEntityMark, MB_TAG_CREAT ); 00075 } 00076 00077 WriteTemplate::~WriteTemplate() 00078 { 00079 mbImpl->release_interface( mWriteIface ); 00080 mbImpl->tag_delete( mEntityMark ); 00081 } 00082 00083 void WriteTemplate::reset_matset( std::vector< WriteTemplate::MaterialSetData >& matset_info ) 00084 { 00085 std::vector< WriteTemplate::MaterialSetData >::iterator iter; 00086 00087 for( iter = matset_info.begin(); iter != matset_info.end(); ++iter ) 00088 delete( *iter ).elements; 00089 } 00090 00091 ErrorCode WriteTemplate::write_file( const char* file_name, 00092 const bool /* overwrite (commented out to remove warning) */, 00093 const FileOptions& /*opts*/, const EntityHandle* ent_handles, const int num_sets, 00094 const std::vector< std::string >& /* qa_list */, const Tag* /* tag_list */, 00095 int /* num_tags */, int /* export_dimension */ ) 00096 { 00097 assert( 0 != mMaterialSetTag && 0 != mNeumannSetTag && 0 != mDirichletSetTag ); 00098 00099 // Check the file name 00100 if( NULL == strstr( file_name, ".template" ) ) return MB_FAILURE; 00101 00102 std::vector< EntityHandle > matsets, dirsets, neusets; 00103 00104 fileName = file_name; 00105 00106 // Separate into material sets, dirichlet sets, neumann sets 00107 00108 if( num_sets == 0 ) 00109 { 00110 // Default to all defined sets 00111 Range this_range; 00112 mbImpl->get_entities_by_type_and_tag( 0, MBENTITYSET, &mMaterialSetTag, NULL, 1, this_range ); 00113 std::copy( this_range.begin(), this_range.end(), std::back_inserter( matsets ) ); 00114 this_range.clear(); 00115 mbImpl->get_entities_by_type_and_tag( 0, MBENTITYSET, &mDirichletSetTag, NULL, 1, this_range ); 00116 std::copy( this_range.begin(), this_range.end(), std::back_inserter( dirsets ) ); 00117 this_range.clear(); 00118 mbImpl->get_entities_by_type_and_tag( 0, MBENTITYSET, &mNeumannSetTag, NULL, 1, this_range ); 00119 std::copy( this_range.begin(), this_range.end(), std::back_inserter( neusets ) ); 00120 } 00121 else 00122 { 00123 int dummy; 00124 for( const EntityHandle* iter = ent_handles; iter < ent_handles + num_sets; ++iter ) 00125 { 00126 if( MB_SUCCESS == mbImpl->tag_get_data( mMaterialSetTag, &( *iter ), 1, &dummy ) ) 00127 matsets.push_back( *iter ); 00128 else if( MB_SUCCESS == mbImpl->tag_get_data( mDirichletSetTag, &( *iter ), 1, &dummy ) ) 00129 dirsets.push_back( *iter ); 00130 else if( MB_SUCCESS == mbImpl->tag_get_data( mNeumannSetTag, &( *iter ), 1, &dummy ) ) 00131 neusets.push_back( *iter ); 00132 } 00133 } 00134 00135 // If there is nothing to write just return. 00136 if( matsets.empty() && dirsets.empty() && neusets.empty() ) return MB_FILE_WRITE_ERROR; 00137 00138 std::vector< WriteTemplate::MaterialSetData > matset_info; 00139 std::vector< WriteTemplate::DirichletSetData > dirset_info; 00140 std::vector< WriteTemplate::NeumannSetData > neuset_info; 00141 00142 MeshInfo mesh_info; 00143 00144 matset_info.clear(); 00145 if( gather_mesh_information( mesh_info, matset_info, neuset_info, dirset_info, matsets, neusets, dirsets ) != 00146 MB_SUCCESS ) 00147 { 00148 reset_matset( matset_info ); 00149 return MB_FAILURE; 00150 } 00151 00152 // Try to open the file after gather mesh info succeeds 00153 if( /* Test for file open failure */ false ) 00154 { 00155 reset_matset( matset_info ); 00156 return MB_FAILURE; 00157 } 00158 00159 if( initialize_file( mesh_info ) != MB_SUCCESS ) 00160 { 00161 reset_matset( matset_info ); 00162 return MB_FAILURE; 00163 } 00164 00165 if( write_nodes( mesh_info.num_nodes, mesh_info.nodes, mesh_info.num_dim ) != MB_SUCCESS ) 00166 { 00167 reset_matset( matset_info ); 00168 return MB_FAILURE; 00169 } 00170 00171 if( write_matsets( mesh_info, matset_info, neuset_info ) ) 00172 { 00173 reset_matset( matset_info ); 00174 return MB_FAILURE; 00175 } 00176 00177 return MB_SUCCESS; 00178 } 00179 00180 ErrorCode WriteTemplate::gather_mesh_information( MeshInfo& mesh_info, 00181 std::vector< WriteTemplate::MaterialSetData >& matset_info, 00182 std::vector< WriteTemplate::NeumannSetData >& neuset_info, 00183 std::vector< WriteTemplate::DirichletSetData >& dirset_info, 00184 std::vector< EntityHandle >& matsets, 00185 std::vector< EntityHandle >& neusets, 00186 std::vector< EntityHandle >& dirsets ) 00187 { 00188 std::vector< EntityHandle >::iterator vector_iter, end_vector_iter; 00189 00190 mesh_info.num_nodes = 0; 00191 mesh_info.num_elements = 0; 00192 mesh_info.num_matsets = 0; 00193 00194 int id = 0; 00195 00196 vector_iter = matsets.begin(); 00197 end_vector_iter = matsets.end(); 00198 00199 mesh_info.num_matsets = matsets.size(); 00200 00201 std::vector< EntityHandle > parent_meshsets; 00202 00203 // Clean out the bits for the element mark 00204 mbImpl->tag_delete( mEntityMark ); 00205 mbImpl->tag_get_handle( "WriteTemplate element mark", 1, MB_TYPE_BIT, mEntityMark, MB_TAG_CREAT ); 00206 00207 int highest_dimension_of_element_matsets = 0; 00208 00209 for( vector_iter = matsets.begin(); vector_iter != matsets.end(); ++vector_iter ) 00210 { 00211 WriteTemplate::MaterialSetData matset_data; 00212 matset_data.elements = new Range; 00213 00214 // For the purpose of qa records, get the parents of these matsets 00215 if( mbImpl->get_parent_meshsets( *vector_iter, parent_meshsets ) != MB_SUCCESS ) return MB_FAILURE; 00216 00217 // Get all Entity Handles in the mesh set 00218 Range dummy_range; 00219 mbImpl->get_entities_by_handle( *vector_iter, dummy_range, true ); 00220 00221 // Find the dimension of the last entity in this range 00222 Range::iterator entity_iter = dummy_range.end(); 00223 --entity_iter; 00224 int this_dim = CN::Dimension( TYPE_FROM_HANDLE( *entity_iter ) ); 00225 entity_iter = dummy_range.begin(); 00226 while( entity_iter != dummy_range.end() && CN::Dimension( TYPE_FROM_HANDLE( *entity_iter ) ) != this_dim ) 00227 ++entity_iter; 00228 00229 if( entity_iter != dummy_range.end() ) 00230 std::copy( entity_iter, dummy_range.end(), range_inserter( *( matset_data.elements ) ) ); 00231 00232 assert( matset_data.elements->begin() == matset_data.elements->end() || 00233 CN::Dimension( TYPE_FROM_HANDLE( *( matset_data.elements->begin() ) ) ) == this_dim ); 00234 00235 // Get the matset's id 00236 if( mbImpl->tag_get_data( mMaterialSetTag, &( *vector_iter ), 1, &id ) != MB_SUCCESS ) 00237 { MB_SET_ERR( MB_FAILURE, "Couldn't get matset id from a tag for an element matset" ); } 00238 00239 matset_data.id = id; 00240 matset_data.number_attributes = 0; 00241 00242 // Iterate through all the elements in the meshset 00243 Range::iterator elem_range_iter, end_elem_range_iter; 00244 elem_range_iter = matset_data.elements->begin(); 00245 end_elem_range_iter = matset_data.elements->end(); 00246 00247 // Get the entity type for this matset, verifying that it's the same for all elements 00248 // THIS ASSUMES HANDLES SORT BY TYPE!!! 00249 EntityType entity_type = TYPE_FROM_HANDLE( *elem_range_iter ); 00250 --end_elem_range_iter; 00251 if( entity_type != TYPE_FROM_HANDLE( *( end_elem_range_iter++ ) ) ) 00252 { MB_SET_ERR( MB_FAILURE, "Entities in matset " << id << " not of common type" ); } 00253 00254 int dimension = CN::Dimension( entity_type ); 00255 00256 if( dimension > highest_dimension_of_element_matsets ) highest_dimension_of_element_matsets = dimension; 00257 00258 matset_data.moab_type = mbImpl->type_from_handle( *( matset_data.elements->begin() ) ); 00259 if( MBMAXTYPE == matset_data.moab_type ) return MB_FAILURE; 00260 00261 std::vector< EntityHandle > tmp_conn; 00262 mbImpl->get_connectivity( &( *( matset_data.elements->begin() ) ), 1, tmp_conn ); 00263 matset_data.element_type = 00264 ExoIIUtil::get_element_type_from_num_verts( tmp_conn.size(), entity_type, dimension ); 00265 00266 if( matset_data.element_type == EXOII_MAX_ELEM_TYPE ) 00267 { MB_SET_ERR( MB_FAILURE, "Element type in matset " << id << " didn't get set correctly" ); } 00268 00269 matset_data.number_nodes_per_element = ExoIIUtil::VerticesPerElement[matset_data.element_type]; 00270 00271 // Number of nodes for this matset 00272 matset_data.number_elements = matset_data.elements->size(); 00273 00274 // Total number of elements 00275 mesh_info.num_elements += matset_data.number_elements; 00276 00277 // Get the nodes for the elements 00278 mWriteIface->gather_nodes_from_elements( *matset_data.elements, mEntityMark, mesh_info.nodes ); 00279 00280 if( !neusets.empty() ) 00281 { 00282 // If there are neusets, keep track of which elements are being written out 00283 for( Range::iterator iter = matset_data.elements->begin(); iter != matset_data.elements->end(); ++iter ) 00284 { 00285 unsigned char bit = 0x1; 00286 mbImpl->tag_set_data( mEntityMark, &( *iter ), 1, &bit ); 00287 } 00288 } 00289 00290 matset_info.push_back( matset_data ); 00291 } 00292 00293 // If user hasn't entered dimension, we figure it out 00294 if( mesh_info.num_dim == 0 ) 00295 { 00296 // Never want 1 or zero dimensions 00297 if( highest_dimension_of_element_matsets < 2 ) 00298 mesh_info.num_dim = 3; 00299 else 00300 mesh_info.num_dim = highest_dimension_of_element_matsets; 00301 } 00302 00303 Range::iterator range_iter, end_range_iter; 00304 range_iter = mesh_info.nodes.begin(); 00305 end_range_iter = mesh_info.nodes.end(); 00306 00307 mesh_info.num_nodes = mesh_info.nodes.size(); 00308 00309 //------dirsets-------- 00310 00311 vector_iter = dirsets.begin(); 00312 end_vector_iter = dirsets.end(); 00313 00314 for( ; vector_iter != end_vector_iter; ++vector_iter ) 00315 { 00316 WriteTemplate::DirichletSetData dirset_data; 00317 dirset_data.id = 0; 00318 dirset_data.number_nodes = 0; 00319 00320 // Get the dirset's id 00321 if( mbImpl->tag_get_data( mDirichletSetTag, &( *vector_iter ), 1, &id ) != MB_SUCCESS ) 00322 { MB_SET_ERR( MB_FAILURE, "Couldn't get id tag for dirset " << id ); } 00323 00324 dirset_data.id = id; 00325 00326 std::vector< EntityHandle > node_vector; 00327 // Get the nodes of the dirset that are in mesh_info.nodes 00328 if( mbImpl->get_entities_by_handle( *vector_iter, node_vector, true ) != MB_SUCCESS ) 00329 { MB_SET_ERR( MB_FAILURE, "Couldn't get nodes in dirset " << id ); } 00330 00331 std::vector< EntityHandle >::iterator iter, end_iter; 00332 iter = node_vector.begin(); 00333 end_iter = node_vector.end(); 00334 00335 int j = 0; 00336 unsigned char node_marked = 0; 00337 ErrorCode result; 00338 for( ; iter != end_iter; ++iter ) 00339 { 00340 if( TYPE_FROM_HANDLE( *iter ) != MBVERTEX ) continue; 00341 result = mbImpl->tag_get_data( mEntityMark, &( *iter ), 1, &node_marked );MB_CHK_SET_ERR( result, "Couldn't get mark data" ); 00342 00343 if( 0x1 == node_marked ) dirset_data.nodes.push_back( *iter ); 00344 j++; 00345 } 00346 00347 dirset_data.number_nodes = dirset_data.nodes.size(); 00348 dirset_info.push_back( dirset_data ); 00349 } 00350 00351 //------neusets-------- 00352 vector_iter = neusets.begin(); 00353 end_vector_iter = neusets.end(); 00354 00355 for( ; vector_iter != end_vector_iter; ++vector_iter ) 00356 { 00357 WriteTemplate::NeumannSetData neuset_data; 00358 00359 // Get the neuset's id 00360 if( mbImpl->tag_get_data( mNeumannSetTag, &( *vector_iter ), 1, &id ) != MB_SUCCESS ) return MB_FAILURE; 00361 00362 neuset_data.id = id; 00363 neuset_data.mesh_set_handle = *vector_iter; 00364 00365 // Get the sides in two lists, one forward the other reverse; starts with forward sense 00366 // by convention 00367 Range forward_elems, reverse_elems; 00368 if( get_neuset_elems( *vector_iter, 0, forward_elems, reverse_elems ) == MB_FAILURE ) return MB_FAILURE; 00369 00370 ErrorCode result = get_valid_sides( forward_elems, 1, neuset_data );MB_CHK_SET_ERR( result, "Couldn't get valid sides data" ); 00371 result = get_valid_sides( reverse_elems, -1, neuset_data );MB_CHK_SET_ERR( result, "Couldn't get valid sides data" ); 00372 00373 neuset_data.number_elements = neuset_data.elements.size(); 00374 neuset_info.push_back( neuset_data ); 00375 } 00376 00377 return MB_SUCCESS; 00378 } 00379 00380 ErrorCode WriteTemplate::get_valid_sides( Range& elems, const int sense, WriteTemplate::NeumannSetData& neuset_data ) 00381 { 00382 // This is where we see if underlying element of side set element is included in output 00383 00384 unsigned char element_marked = 0; 00385 ErrorCode result; 00386 for( Range::iterator iter = elems.begin(); iter != elems.end(); ++iter ) 00387 { 00388 // Should insert here if "side" is a quad/tri on a quad/tri mesh 00389 result = mbImpl->tag_get_data( mEntityMark, &( *iter ), 1, &element_marked );MB_CHK_SET_ERR( result, "Couldn't get mark data" ); 00390 00391 if( 0x1 == element_marked ) 00392 { 00393 neuset_data.elements.push_back( *iter ); 00394 00395 // TJT TODO: the sense should really be # edges + 1or2 00396 neuset_data.side_numbers.push_back( ( sense == 1 ? 1 : 2 ) ); 00397 } 00398 else 00399 { // Then "side" is probably a quad/tri on a hex/tet mesh 00400 std::vector< EntityHandle > parents; 00401 int dimension = CN::Dimension( TYPE_FROM_HANDLE( *iter ) ); 00402 00403 // Get the adjacent parent element of "side" 00404 if( mbImpl->get_adjacencies( &( *iter ), 1, dimension + 1, false, parents ) != MB_SUCCESS ) 00405 { MB_SET_ERR( MB_FAILURE, "Couldn't get adjacencies for neuset" ); } 00406 00407 if( !parents.empty() ) 00408 { 00409 // Make sure the adjacent parent element will be output 00410 for( unsigned int k = 0; k < parents.size(); k++ ) 00411 { 00412 result = mbImpl->tag_get_data( mEntityMark, &( parents[k] ), 1, &element_marked );MB_CHK_SET_ERR( result, "Couldn't get mark data" ); 00413 00414 int side_no, this_sense, this_offset; 00415 if( 0x1 == element_marked && 00416 mbImpl->side_number( parents[k], *iter, side_no, this_sense, this_offset ) == MB_SUCCESS && 00417 this_sense == sense ) 00418 { 00419 neuset_data.elements.push_back( parents[k] ); 00420 neuset_data.side_numbers.push_back( side_no + 1 ); 00421 break; 00422 } 00423 } 00424 } 00425 else 00426 { 00427 MB_SET_ERR( MB_FAILURE, "No parent element exists for element in neuset " << neuset_data.id ); 00428 } 00429 } 00430 } 00431 00432 return MB_SUCCESS; 00433 } 00434 00435 ErrorCode WriteTemplate::write_nodes( const int num_nodes, const Range& nodes, const int dimension ) 00436 { 00437 // See if should transform coordinates 00438 ErrorCode result; 00439 Tag trans_tag; 00440 result = mbImpl->tag_get_handle( MESH_TRANSFORM_TAG_NAME, 16, MB_TYPE_DOUBLE, trans_tag ); 00441 bool transform_needed = true; 00442 if( result == MB_TAG_NOT_FOUND ) transform_needed = false; 00443 00444 int num_coords_to_fill = transform_needed ? 3 : dimension; 00445 00446 std::vector< double* > coord_arrays( 3 ); 00447 coord_arrays[0] = new double[num_nodes]; 00448 coord_arrays[1] = new double[num_nodes]; 00449 coord_arrays[2] = NULL; 00450 00451 if( num_coords_to_fill == 3 ) coord_arrays[2] = new double[num_nodes]; 00452 00453 result = mWriteIface->get_node_coords( dimension, num_nodes, nodes, mGlobalIdTag, 0, coord_arrays ); 00454 if( result != MB_SUCCESS ) 00455 { 00456 delete[] coord_arrays[0]; 00457 delete[] coord_arrays[1]; 00458 if( coord_arrays[2] ) delete[] coord_arrays[2]; 00459 return result; 00460 } 00461 00462 if( transform_needed ) 00463 { 00464 double trans_matrix[16]; 00465 const EntityHandle mesh = 0; 00466 result = mbImpl->tag_get_data( trans_tag, &mesh, 1, trans_matrix );MB_CHK_SET_ERR( result, "Couldn't get transform data" ); 00467 00468 for( int i = 0; i < num_nodes; i++ ) 00469 { 00470 double vec1[3]; 00471 double vec2[3]; 00472 00473 vec2[0] = coord_arrays[0][i]; 00474 vec2[1] = coord_arrays[1][i]; 00475 vec2[2] = coord_arrays[2][i]; 00476 00477 for( int row = 0; row < 3; row++ ) 00478 { 00479 vec1[row] = 0.0; 00480 for( int col = 0; col < 3; col++ ) 00481 vec1[row] += ( trans_matrix[( row * 4 ) + col] * vec2[col] ); 00482 } 00483 00484 coord_arrays[0][i] = vec1[0]; 00485 coord_arrays[1][i] = vec1[1]; 00486 coord_arrays[2][i] = vec1[2]; 00487 } 00488 } 00489 00490 // Write the nodes 00491 00492 /* Template - write nodes to file here in some way */ 00493 00494 // Clean up 00495 delete[] coord_arrays[0]; 00496 delete[] coord_arrays[1]; 00497 if( coord_arrays[2] ) delete[] coord_arrays[2]; 00498 00499 return MB_SUCCESS; 00500 } 00501 00502 ErrorCode WriteTemplate::write_matsets( 00503 MeshInfo& /* mesh_info (commented out to remove warning) */, 00504 std::vector< WriteTemplate::MaterialSetData >& matset_data, 00505 std::vector< WriteTemplate::NeumannSetData >& /* neuset_data (commented out to remove warning) */ ) 00506 { 00507 unsigned int i; 00508 std::vector< int > connect; 00509 const EntityHandle* connecth; 00510 int num_connecth; 00511 ErrorCode result; 00512 00513 // Don't usually have anywhere near 31 nodes per element 00514 connect.reserve( 31 ); 00515 Range::iterator rit; 00516 00517 WriteTemplate::MaterialSetData matset; 00518 for( i = 0; i < matset_data.size(); i++ ) 00519 { 00520 matset = matset_data[i]; 00521 00522 for( rit = matset.elements->begin(); rit != matset.elements->end(); ++rit ) 00523 { 00524 // Get the connectivity of this element 00525 result = mbImpl->get_connectivity( *rit, connecth, num_connecth ); 00526 if( MB_SUCCESS != result ) return result; 00527 00528 // Get the vertex ids 00529 result = mbImpl->tag_get_data( mGlobalIdTag, connecth, num_connecth, &connect[0] ); 00530 if( MB_SUCCESS != result ) return result; 00531 00532 // Write the data 00533 /* Template - write element connectivity here */ 00534 00535 if( /* Template - check for error condition! */ false ) return MB_FAILURE; 00536 } 00537 } 00538 00539 return MB_SUCCESS; 00540 } 00541 00542 ErrorCode WriteTemplate::initialize_file( MeshInfo& mesh_info ) 00543 { 00544 // Perform the initializations 00545 00546 int coord_size, ncoords; 00547 00548 coord_size = mesh_info.num_dim; 00549 std::cout << "Coord_size = " << coord_size << std::endl; 00550 /* Template - write coord size */ 00551 00552 ncoords = mesh_info.num_nodes; 00553 std::cout << "ncoords = " << ncoords << std::endl; 00554 /* Template - write num nodes*/ 00555 00556 /* Template - write information on the element types & numbers (depends 00557 on material and other sets) */ 00558 00559 /* Node coordinate arrays: */ 00560 /* Template - initialize variable to hold coordinate arrays */ 00561 00562 return MB_SUCCESS; 00563 } 00564 00565 ErrorCode WriteTemplate::open_file( const char* filename ) 00566 { 00567 // Not a valid filename 00568 if( strlen( (const char*)filename ) == 0 ) { MB_SET_ERR( MB_FAILURE, "Output filename not specified" ); } 00569 00570 /* Template - open file & store somewhere */ 00571 00572 // File couldn't be opened 00573 if( /* Template - check for file open error here! */ false ) 00574 { MB_SET_ERR( MB_FAILURE, "Cannot open " << filename ); } 00575 00576 return MB_SUCCESS; 00577 } 00578 00579 ErrorCode WriteTemplate::get_neuset_elems( EntityHandle neuset, int current_sense, Range& forward_elems, 00580 Range& reverse_elems ) 00581 { 00582 Range neuset_elems, neuset_meshsets; 00583 00584 // Get the sense tag; don't need to check return, might be an error if the tag 00585 // hasn't been created yet 00586 Tag sense_tag = 0; 00587 mbImpl->tag_get_handle( "SENSE", 1, MB_TYPE_INTEGER, sense_tag ); 00588 00589 // Get the entities in this set 00590 ErrorCode result = mbImpl->get_entities_by_handle( neuset, neuset_elems, true ); 00591 if( MB_FAILURE == result ) return result; 00592 00593 // Now remove the meshsets into the neuset_meshsets; first find the first meshset, 00594 Range::iterator range_iter = neuset_elems.begin(); 00595 while( TYPE_FROM_HANDLE( *range_iter ) != MBENTITYSET && range_iter != neuset_elems.end() ) 00596 ++range_iter; 00597 00598 // Then, if there are some, copy them into neuset_meshsets and erase from neuset_elems 00599 if( range_iter != neuset_elems.end() ) 00600 { 00601 std::copy( range_iter, neuset_elems.end(), range_inserter( neuset_meshsets ) ); 00602 neuset_elems.erase( range_iter, neuset_elems.end() ); 00603 } 00604 00605 // OK, for the elements, check the sense of this set and copy into the right range 00606 // (if the sense is 0, copy into both ranges) 00607 00608 // Need to step forward on list until we reach the right dimension 00609 Range::iterator dum_it = neuset_elems.end(); 00610 --dum_it; 00611 int target_dim = CN::Dimension( TYPE_FROM_HANDLE( *dum_it ) ); 00612 dum_it = neuset_elems.begin(); 00613 while( target_dim != CN::Dimension( TYPE_FROM_HANDLE( *dum_it ) ) && dum_it != neuset_elems.end() ) 00614 ++dum_it; 00615 00616 if( current_sense == 1 || current_sense == 0 ) 00617 std::copy( dum_it, neuset_elems.end(), range_inserter( forward_elems ) ); 00618 if( current_sense == -1 || current_sense == 0 ) 00619 std::copy( dum_it, neuset_elems.end(), range_inserter( reverse_elems ) ); 00620 00621 // Now loop over the contained meshsets, getting the sense of those and calling this 00622 // function recursively 00623 for( range_iter = neuset_meshsets.begin(); range_iter != neuset_meshsets.end(); ++range_iter ) 00624 { 00625 // First get the sense; if it's not there, by convention it's forward 00626 int this_sense; 00627 if( 0 == sense_tag || MB_FAILURE == mbImpl->tag_get_data( sense_tag, &( *range_iter ), 1, &this_sense ) ) 00628 this_sense = 1; 00629 00630 // Now get all the entities on this meshset, with the proper (possibly reversed) sense 00631 get_neuset_elems( *range_iter, this_sense * current_sense, forward_elems, reverse_elems ); 00632 } 00633 00634 return result; 00635 } 00636 00637 } // namespace moab