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