moab
|
00001 00016 #ifdef WIN32 00017 #pragma warning(disable : 4786) 00018 #endif 00019 00020 #include "WriteUtil.hpp" 00021 #include "moab/Core.hpp" 00022 #include "moab/Error.hpp" 00023 #include "SequenceManager.hpp" 00024 #include "ElementSequence.hpp" 00025 #include "VertexSequence.hpp" 00026 #include "AEntityFactory.hpp" 00027 #include "MBTagConventions.hpp" 00028 #include "RangeSeqIntersectIter.hpp" 00029 #include "MeshSetSequence.hpp" 00030 00031 #include <sys/types.h> 00032 #include <sys/stat.h> 00033 #include <errno.h> 00034 #include <assert.h> 00035 #include <iostream> 00036 00037 #ifdef WIN32 00038 # define stat _stat 00039 #else 00040 # include <unistd.h> 00041 #endif 00042 00043 namespace moab { 00044 00045 WriteUtil::WriteUtil(Core* mdb, Error* error_handler) 00046 : WriteUtilIface(), mMB(mdb), mError(error_handler) 00047 { 00048 } 00049 00053 ErrorCode WriteUtil::check_doesnt_exist( const char* file_name ) 00054 { 00055 struct stat s; 00056 if (0 == stat( file_name, &s )) 00057 { 00058 report_error( "%s: file already exists.\n", file_name ); 00059 return MB_ALREADY_ALLOCATED; 00060 } 00061 else if (errno == ENOENT) 00062 { 00063 return MB_SUCCESS; 00064 } 00065 else 00066 { 00067 return MB_FAILURE; 00068 } 00069 } 00070 00072 ErrorCode WriteUtil::gather_entities(Range &all_ents, 00074 const EntityHandle *ent_sets, 00076 const int num_sets 00078 ) 00079 { 00080 ErrorCode rval = MB_SUCCESS; 00081 if (!ent_sets || num_sets == 0) { 00082 rval = mMB->get_entities_by_handle(0, all_ents); 00083 } 00084 else { 00085 for (int i = 0; i < num_sets; i++) { 00086 ErrorCode tmp_rval = mMB->get_entities_by_handle(ent_sets[i], all_ents); 00087 if (MB_SUCCESS != tmp_rval) rval = tmp_rval; 00088 } 00089 } 00090 00091 return rval; 00092 } 00093 00094 ErrorCode WriteUtil::get_node_coords( 00095 const int num_arrays, 00096 const int num_nodes, 00097 const Range& entities, 00098 Tag node_id_tag, 00099 const int start_node_id, 00100 std::vector<double*>& arrays) 00101 { 00102 // check the data coming into the function 00103 // dimension should be proper 00104 if(num_arrays < 1 || num_arrays > 3) 00105 return MB_FAILURE; 00106 00107 // there should be some entities 00108 //if(entities.empty()) 00109 // return MB_FAILURE; 00110 // The above necessitates annoying special cases for files 00111 // w/out vertices (e.g. a kD-tree). Return NULL array 00112 // pointers instead. - kraftcheck, 3-14-08 00113 if (entities.empty()) { 00114 arrays.clear(); 00115 arrays.resize( num_arrays, NULL ); 00116 return MB_SUCCESS; 00117 } 00118 00119 // memory should already be allocated for us 00120 int tmp_num_arrays = 0; 00121 for (unsigned int i = 0; i < 3; i++) 00122 if (i+1 <= arrays.size() && NULL != arrays[i]) tmp_num_arrays++; 00123 if (0 == tmp_num_arrays) 00124 return MB_FAILURE; 00125 00126 // get coordinate data 00127 ErrorCode result = mMB->get_coords( entities, 00128 num_arrays < 1 || arrays.size() < 1 ? NULL : arrays[0], 00129 num_arrays < 2 || arrays.size() < 2 ? NULL : arrays[1], 00130 num_arrays < 3 || arrays.size() < 3 ? NULL : arrays[2] ); 00131 00132 00133 if (0 == node_id_tag || MB_SUCCESS != result) 00134 return result; 00135 00136 // now assign tags 00137 std::vector<int> ids(num_nodes); 00138 int node_id = start_node_id; 00139 for (int i = 0; i < num_nodes; i++) ids[i] = node_id++; 00140 result = mMB->tag_set_data(node_id_tag, entities, &ids[0]); 00141 00142 return result; 00143 } 00144 00145 ErrorCode WriteUtil::get_node_coords( 00146 const int which_array, /* 0->X, 1->Y, 2->Z, -1->all */ 00147 Range::const_iterator iter, 00148 const Range::const_iterator end, 00149 const size_t output_array_len, 00150 double* const output_array) 00151 { 00152 // check the data coming into the function 00153 // dimension should be proper 00154 if(which_array < -1 || which_array > 2) 00155 return MB_FAILURE; 00156 00157 // there should be some entities 00158 if(iter == end) 00159 return MB_FAILURE; 00160 00161 // memory should already be allocated for us 00162 if (NULL == output_array || 0 == output_array_len) 00163 return MB_FAILURE; 00164 00165 // Sequence iterators 00166 TypeSequenceManager::iterator seq_iter, seq_end; 00167 seq_iter = mMB->sequence_manager()->entity_map(MBVERTEX).begin(); 00168 seq_end = mMB->sequence_manager()->entity_map(MBVERTEX).end(); 00169 00170 // loop over range, getting coordinate value 00171 double* output_iter = output_array; 00172 double* const output_end = output_array + output_array_len; 00173 while (iter != end) 00174 { 00175 // Find the sqeuence containing the current handle 00176 while (seq_iter != seq_end && (*seq_iter)->end_handle() < *iter) 00177 ++seq_iter; 00178 if (seq_iter == seq_end || *iter < (*seq_iter)->start_handle()) 00179 return MB_FAILURE; 00180 00181 // Determine how much of the sequence we want. 00182 Range::pair_iterator pair(iter); 00183 Range::const_iterator prev(end); 00184 --prev; 00185 EntityHandle range_end = pair->second; 00186 EntityHandle sequence_end = (*seq_iter)->end_handle(); 00187 EntityHandle end_handle = range_end > sequence_end ? sequence_end : range_end; 00188 if (end_handle > *prev) 00189 end_handle = *prev; 00190 EntityHandle count = end_handle - *iter + 1; 00191 00192 // Get offset in sequence to start at 00193 assert( *iter >= (*seq_iter)->start_handle() ); 00194 EntityHandle offset = *iter - (*seq_iter)->start_handle(); 00195 00196 // Get coordinate arrays from sequence 00197 double* coord_array[3]; 00198 static_cast<VertexSequence*>(*seq_iter) 00199 ->get_coordinate_arrays( coord_array[0], coord_array[1], coord_array[2]); 00200 00201 // Copy data to ouput buffer 00202 if (-1 != which_array) { 00203 if (output_iter + count > output_end) 00204 return MB_FAILURE; 00205 memcpy( output_iter, coord_array[which_array] + offset, count * sizeof(double) ); 00206 output_iter += count; 00207 } 00208 else { 00209 if (output_iter + 3*count > output_end) 00210 return MB_FAILURE; 00211 for (unsigned int i = 0; i < count; i++) { 00212 *output_iter = coord_array[0][i+offset]; output_iter++; 00213 *output_iter = coord_array[1][i+offset]; output_iter++; 00214 *output_iter = coord_array[2][i+offset]; output_iter++; 00215 } 00216 } 00217 00218 // Iterate 00219 iter += count; 00220 } 00221 00222 return MB_SUCCESS; 00223 } 00224 00225 ErrorCode WriteUtil::get_element_connect( 00226 const int num_elements, 00227 const int verts_per_element, 00228 Tag node_id_tag, 00229 const Range& elements, 00230 Tag element_id_tag, 00231 int start_element_id, 00232 int* element_array, 00233 bool add_sizes) 00234 { 00235 00236 // check the data we got 00237 if(num_elements < 1) 00238 return MB_FAILURE; 00239 if(verts_per_element < 1) 00240 return MB_FAILURE; 00241 if(elements.empty()) 00242 return MB_FAILURE; 00243 if(!element_array) 00244 return MB_FAILURE; 00245 00246 Range::const_iterator range_iter = elements.begin(); 00247 Range::const_iterator range_iter_end = elements.end(); 00248 00249 TypeSequenceManager::iterator seq_iter, seq_iter_end; 00250 EntityType current_type = TYPE_FROM_HANDLE(*range_iter); 00251 00252 seq_iter = mMB->sequence_manager()->entity_map(current_type).begin(); 00253 seq_iter_end = mMB->sequence_manager()->entity_map(current_type).end(); 00254 00255 // lets find the entity sequence which holds the first entity 00256 TypeSequenceManager::iterator seq_iter_lookahead = seq_iter; 00257 seq_iter_lookahead++; 00258 for( ; seq_iter_lookahead != seq_iter_end && 00259 (*seq_iter_lookahead)->start_handle() < *range_iter; ) 00260 { 00261 ++seq_iter; 00262 ++seq_iter_lookahead; 00263 } 00264 00265 // a look ahead iterator 00266 Range::const_iterator range_iter_lookahead = range_iter; 00267 00268 // our main loop 00269 for(; range_iter != range_iter_end && seq_iter != seq_iter_end; /* ++ is handled in loop*/ ) 00270 { 00271 // find a range that fits in the current entity sequence 00272 for(; range_iter_lookahead != range_iter_end && 00273 *range_iter_lookahead <= (*seq_iter)->end_handle(); 00274 ++range_iter_lookahead) 00275 {} 00276 00277 if(current_type != TYPE_FROM_HANDLE(*range_iter)) 00278 { 00279 current_type = TYPE_FROM_HANDLE(*range_iter); 00280 seq_iter = mMB->sequence_manager()->entity_map(current_type).begin(); 00281 seq_iter_end = mMB->sequence_manager()->entity_map(current_type).end(); 00282 00283 // lets find the entity sequence which holds the first entity of this type 00284 TypeSequenceManager::const_iterator seq_iter_lookahead2 = seq_iter; 00285 seq_iter_lookahead2++; 00286 for( ; seq_iter_lookahead2 != seq_iter_end && 00287 (*seq_iter_lookahead2)->start_handle() < *range_iter; ) 00288 { 00289 ++seq_iter; 00290 ++seq_iter_lookahead2; 00291 } 00292 } 00293 00294 int i = static_cast<ElementSequence*>(*seq_iter)->nodes_per_element(); 00295 00296 // get the connectivity array 00297 EntityHandle* conn_array = 00298 static_cast<ElementSequence*>(*seq_iter)->get_connectivity_array(); 00299 00300 EntityHandle start_handle = (*seq_iter)->start_handle(); 00301 00302 for(Range::const_iterator tmp_iter = range_iter; 00303 tmp_iter != range_iter_lookahead; 00304 ++tmp_iter) 00305 { 00306 // set the element id tag 00307 mMB->tag_set_data(element_id_tag, &*tmp_iter, 1, &start_element_id); 00308 ++start_element_id; 00309 00310 if (add_sizes) *element_array++ = i; 00311 00312 // for each node 00313 for(int j=0; j<i; j++) 00314 { 00315 EntityHandle node = *(conn_array + j + i*(*tmp_iter - start_handle)); 00316 mMB->tag_get_data(node_id_tag, &node, 1, element_array); 00317 element_array++; 00318 } 00319 } 00320 00321 // go to the next entity sequence 00322 ++seq_iter; 00323 // start with the next entities 00324 range_iter = range_iter_lookahead; 00325 } 00326 00327 return MB_SUCCESS; 00328 } 00329 00330 ErrorCode WriteUtil::get_element_connect( 00331 Range::const_iterator iter, 00332 const Range::const_iterator end, 00333 const int vertices_per_elem, 00334 Tag node_id_tag, 00335 const size_t elem_array_size, 00336 int *const element_array, 00337 bool add_sizes) 00338 { 00339 00340 // check the data we got 00341 if(iter == end) 00342 return MB_FAILURE; 00343 if(vertices_per_elem < 1) 00344 return MB_FAILURE; 00345 if(!element_array || elem_array_size < (unsigned)vertices_per_elem) 00346 return MB_FAILURE; 00347 00348 00349 // Sequence iterators 00350 TypeSequenceManager::const_iterator seq_iter, seq_end; 00351 00352 // loop over range, getting coordinate value 00353 EntityType current_type = MBMAXTYPE; 00354 int* output_iter = element_array; 00355 int*const output_end = element_array + elem_array_size; 00356 while (iter != end) 00357 { 00358 // Make sure we have the right sequence list (and get the sequence 00359 // list for the first iteration.) 00360 EntityType type = TYPE_FROM_HANDLE(*iter); 00361 if (type != current_type) 00362 { 00363 if (type >= MBENTITYSET || type < MBEDGE) 00364 return MB_FAILURE; 00365 seq_iter = mMB->sequence_manager()->entity_map(type).begin(); 00366 seq_end = mMB->sequence_manager()->entity_map(type).end(); 00367 current_type = type; 00368 } 00369 00370 // Find the sqeuence containing the current handle 00371 while (seq_iter != seq_end && (*seq_iter)->end_handle() < *iter) 00372 ++seq_iter; 00373 if (seq_iter == seq_end || *iter < (*seq_iter)->start_handle()) 00374 return MB_FAILURE; 00375 00376 // get the connectivity array 00377 EntityHandle* conn_array = NULL; 00378 int conn_size = static_cast<ElementSequence*>(*seq_iter)->nodes_per_element(); 00379 conn_array = static_cast<ElementSequence*>(*seq_iter)->get_connectivity_array(); 00380 00381 // Determine how much of the sequence we want. 00382 Range::pair_iterator pair(iter); 00383 Range::const_iterator prev(end); 00384 --prev; 00385 EntityHandle range_end = pair->second; 00386 EntityHandle sequence_end = (*seq_iter)->end_handle(); 00387 EntityHandle end_handle = range_end > sequence_end ? sequence_end : range_end; 00388 if (end_handle > *prev) 00389 end_handle = *prev; 00390 EntityHandle count = end_handle - *iter + 1; 00391 00392 // Get offset in sequence to start at 00393 assert( *iter >= (*seq_iter)->start_handle() ); 00394 EntityHandle offset = *iter - (*seq_iter)->start_handle(); 00395 00396 // Make sure sufficient space in output array 00397 if ((!add_sizes && output_iter + (count * conn_size) > output_end) || 00398 (add_sizes && output_iter + (count * (conn_size+1)) > output_end)) 00399 return MB_FAILURE; 00400 00401 // If the nodes per element match, do in one call 00402 conn_array += (conn_size * offset); 00403 if (vertices_per_elem == conn_size && !add_sizes) 00404 { 00405 ErrorCode rval = mMB->tag_get_data( node_id_tag, 00406 conn_array, 00407 count * conn_size, 00408 output_iter ); 00409 if (MB_SUCCESS != rval) 00410 return rval; 00411 00412 output_iter += count * conn_size; 00413 } 00414 // Otherwise need to do one at a time 00415 else 00416 { 00417 int min = vertices_per_elem > conn_size ? conn_size : vertices_per_elem; 00418 for (EntityHandle i = 0; i < count; ++i) 00419 { 00420 *output_iter++ = min; 00421 ErrorCode rval = mMB->tag_get_data( node_id_tag, 00422 conn_array, 00423 min, 00424 output_iter ); 00425 if (MB_SUCCESS != rval) 00426 return rval; 00427 00428 output_iter += min; 00429 conn_array += conn_size; 00430 00431 if (vertices_per_elem > conn_size) // need to pad 00432 { 00433 memset( output_iter, 0, sizeof(int) * (vertices_per_elem - conn_size) ); 00434 output_iter += (vertices_per_elem - conn_size); 00435 } 00436 } 00437 } 00438 00439 iter += count; 00440 } 00441 00442 return MB_SUCCESS; 00443 } 00444 00445 ErrorCode WriteUtil::get_element_connect( 00446 Range::const_iterator iter, 00447 const Range::const_iterator end, 00448 const int vertices_per_elem, 00449 const size_t elem_array_size, 00450 EntityHandle *const element_array ) 00451 { 00452 // check the data we got 00453 if(iter == end) 00454 return MB_FAILURE; 00455 if(vertices_per_elem < 1) 00456 return MB_FAILURE; 00457 if(!element_array || elem_array_size < (unsigned)vertices_per_elem) 00458 return MB_FAILURE; 00459 00460 // Sequence iterators 00461 TypeSequenceManager::const_iterator seq_iter, seq_end; 00462 00463 // loop over range, getting coordinate value 00464 EntityType current_type = MBMAXTYPE; 00465 EntityHandle* output_iter = element_array; 00466 EntityHandle*const output_end = element_array + elem_array_size; 00467 while (iter != end) 00468 { 00469 // Make sure we have the right sequence list (and get the sequence 00470 // list for the first iteration.) 00471 EntityType type = TYPE_FROM_HANDLE(*iter); 00472 if (type != current_type) 00473 { 00474 if (type >= MBENTITYSET || type < MBEDGE) 00475 return MB_FAILURE; 00476 seq_iter = mMB->sequence_manager()->entity_map(type).begin(); 00477 seq_end = mMB->sequence_manager()->entity_map(type).end(); 00478 current_type = type; 00479 } 00480 00481 // Find the sqeuence containing the current handle 00482 while (seq_iter != seq_end && (*seq_iter)->end_handle() < *iter) 00483 ++seq_iter; 00484 if (seq_iter == seq_end || *iter < (*seq_iter)->start_handle()) 00485 return MB_FAILURE; 00486 00487 // get the connectivity array 00488 EntityHandle* conn_array = NULL; 00489 int conn_size = static_cast<ElementSequence*>(*seq_iter)->nodes_per_element(); 00490 if (conn_size != vertices_per_elem) 00491 return MB_FAILURE; 00492 conn_array = static_cast<ElementSequence*>(*seq_iter)->get_connectivity_array(); 00493 00494 // Determine how much of the sequence we want. 00495 Range::pair_iterator pair(iter); 00496 Range::const_iterator prev(end); 00497 --prev; 00498 EntityHandle range_end = pair->second; 00499 EntityHandle sequence_end = (*seq_iter)->end_handle(); 00500 EntityHandle end_handle = range_end > sequence_end ? sequence_end : range_end; 00501 if (end_handle > *prev) 00502 end_handle = *prev; 00503 EntityHandle count = end_handle - *iter + 1; 00504 00505 // Get offset in sequence to start at 00506 assert( *iter >= (*seq_iter)->start_handle() ); 00507 EntityHandle offset = *iter - (*seq_iter)->start_handle(); 00508 00509 // Make sure sufficient space in output array 00510 if (output_iter + (count * conn_size) > output_end) 00511 return MB_FAILURE; 00512 00513 if (conn_array == NULL) { // if it is structured mesh 00514 ErrorCode rval; 00515 int temp_buff_size = conn_size* sizeof(EntityHandle); 00516 for (unsigned i = 0; i < count; i++) { // copy connectivity element by element 00517 std::vector<EntityHandle> connect; 00518 rval = static_cast<ElementSequence*>(*seq_iter)->get_connectivity(*iter, 00519 connect); 00520 if (MB_SUCCESS != rval) { 00521 return rval; 00522 } 00523 memcpy(output_iter, &connect[0], temp_buff_size); 00524 output_iter += conn_size; 00525 iter++; 00526 } 00527 } 00528 else { 00529 // Copy connectivity into output array 00530 conn_array += (conn_size * offset); 00531 memcpy( output_iter, conn_array, count * conn_size * sizeof(EntityHandle)); 00532 output_iter += count * conn_size; 00533 iter += count; 00534 } 00535 } 00536 00537 return MB_SUCCESS; 00538 } 00539 00540 ErrorCode WriteUtil::get_poly_connect_size( 00541 Range::const_iterator , 00542 const Range::const_iterator , 00543 int& ) 00544 { 00545 return MB_NOT_IMPLEMENTED; 00546 } 00547 00548 ErrorCode WriteUtil::get_poly_connect( 00549 Range::const_iterator& , 00550 const Range::const_iterator , 00551 const Tag , 00552 size_t& , 00553 int *const , 00554 size_t& , 00555 int*const , 00556 int& ) 00557 { 00558 return MB_NOT_IMPLEMENTED; 00559 } 00560 00561 00562 ErrorCode WriteUtil::gather_nodes_from_elements( 00563 const Range& elements, 00564 const Tag node_bit_mark_tag, 00565 Range& nodes 00566 ) 00567 { 00568 bool printed_warning = false; 00569 00570 if(elements.empty()) 00571 return MB_SUCCESS; 00572 00573 if (TYPE_FROM_HANDLE(elements.front()) <= MBVERTEX || 00574 TYPE_FROM_HANDLE(elements.back()) >= MBENTITYSET) 00575 return MB_TYPE_OUT_OF_RANGE; 00576 00577 // see if we need to use our own marking tag 00578 Tag exporting_nodes_tag = 0; 00579 if(node_bit_mark_tag) 00580 exporting_nodes_tag = node_bit_mark_tag; 00581 else 00582 { 00583 mMB->tag_get_handle("__MBWriteUtil::exporting_nodes", 1, MB_TYPE_BIT, 00584 exporting_nodes_tag, MB_TAG_CREAT); 00585 } 00586 00587 // the x,y,z tag handles we need 00588 EntityHandle lower_bound = ~0, upper_bound = 0; 00589 00590 std::vector<EntityHandle> tmp_conn; 00591 00592 RangeSeqIntersectIter iter( mMB->sequence_manager() ); 00593 for (ErrorCode rval = iter.init( elements.begin(), elements.end() ); 00594 MB_FAILURE != rval; rval = iter.step()) { 00595 if (MB_ENTITY_NOT_FOUND == rval) { 00596 if (!printed_warning) { 00597 std::cerr << "Warning: ignoring invalid element handle(s) in gather_nodes_from_elements" << std::endl; 00598 printed_warning = true; 00599 } 00600 continue; 00601 } 00602 00603 ElementSequence* seq = static_cast<ElementSequence*>(iter.get_sequence()); 00604 00605 // get the connectivity array 00606 const EntityHandle* conn_array = seq->get_connectivity_array(); 00607 00608 // if unstructed mesh 00609 if (conn_array && mMB->type_from_handle(iter.get_start_handle()) != MBPOLYHEDRON) { 00610 assert(iter.get_start_handle() >= seq->start_handle()); 00611 assert(iter.get_end_handle() <= seq->end_handle()); 00612 const EntityHandle offset = iter.get_start_handle() - seq->start_handle(); 00613 const EntityHandle num_elem = iter.get_end_handle() - iter.get_start_handle() + 1; 00614 00615 conn_array += offset * seq->nodes_per_element(); 00616 const EntityHandle num_node = num_elem * seq->nodes_per_element(); 00617 00618 // for each node 00619 for (EntityHandle j = 0; j < num_node; j++) 00620 { 00621 EntityHandle node = conn_array[j]; 00622 if(node < lower_bound) 00623 lower_bound = node; 00624 if(node > upper_bound) 00625 upper_bound = node; 00626 unsigned char bit = 0x1; 00627 rval = mMB->tag_set_data(exporting_nodes_tag, &node, 1, &bit); 00628 assert(MB_SUCCESS == rval); 00629 if (MB_SUCCESS != rval) 00630 return rval; 00631 } 00632 } 00633 // polyhedra 00634 else if (conn_array && mMB->type_from_handle(iter.get_start_handle()) == MBPOLYHEDRON) { 00635 assert(iter.get_start_handle() >= seq->start_handle()); 00636 assert(iter.get_end_handle() <= seq->end_handle()); 00637 const EntityHandle offset = iter.get_start_handle() - seq->start_handle(); 00638 const EntityHandle num_elem = iter.get_end_handle() - iter.get_start_handle() + 1; 00639 00640 conn_array += offset * seq->nodes_per_element(); 00641 int num_face = num_elem * seq->nodes_per_element(); 00642 00643 // for each node 00644 for (int j = 0; j < num_face; j++) 00645 { 00646 const EntityHandle *face_conn; 00647 int face_num_conn; 00648 rval = mMB->get_connectivity(conn_array[j], face_conn, face_num_conn, false); 00649 if (MB_SUCCESS != rval) 00650 return rval; 00651 for (int k = 0; k < face_num_conn; k++) { 00652 EntityHandle node = face_conn[k]; 00653 if(node < lower_bound) 00654 lower_bound = node; 00655 if(node > upper_bound) 00656 upper_bound = node; 00657 unsigned char bit = 0x1; 00658 rval = mMB->tag_set_data(exporting_nodes_tag, &node, 1, &bit); 00659 assert(MB_SUCCESS == rval); 00660 if (MB_SUCCESS != rval) 00661 return rval; 00662 } 00663 } 00664 } 00665 // structured mesh 00666 else { 00667 EntityHandle end_h = iter.get_end_handle() + 1; 00668 for (EntityHandle h = iter.get_start_handle(); 00669 h < end_h; ++h) { 00670 tmp_conn.clear(); 00671 rval = seq->get_connectivity( h, tmp_conn, false ); 00672 if (MB_SUCCESS != rval) { 00673 if(node_bit_mark_tag == 0) 00674 mMB->tag_delete(exporting_nodes_tag); 00675 return rval; 00676 } 00677 00678 // for each node 00679 for(size_t j=0; j<tmp_conn.size(); j++) 00680 { 00681 EntityHandle node = tmp_conn[j]; 00682 if(node < lower_bound) 00683 lower_bound = node; 00684 if(node > upper_bound) 00685 upper_bound = node; 00686 unsigned char bit = 0x1; 00687 mMB->tag_set_data(exporting_nodes_tag, &node, 1, &bit); 00688 } 00689 } 00690 } 00691 } 00692 00693 // we can get a REALLY long loop if lower_bound is zero 00694 assert(lower_bound != 0); 00695 // gather up all the nodes 00696 for(; upper_bound >= lower_bound; --upper_bound) 00697 { 00698 unsigned char node_marked=0; 00699 mMB->tag_get_data(exporting_nodes_tag, &upper_bound, 1, &node_marked); 00700 if(node_marked == 0x1) 00701 nodes.insert(upper_bound); 00702 } 00703 00704 // clean up our own marking tag 00705 if(node_bit_mark_tag == 0) 00706 mMB->tag_delete(exporting_nodes_tag); 00707 00708 return MB_SUCCESS; 00709 } 00710 00713 ErrorCode WriteUtil::assign_ids(Range &elements, 00714 Tag id_tag, 00715 const int start_id) 00716 { 00717 ErrorCode result; 00718 if (0 == id_tag) { 00719 // get the global id tag 00720 int def_val = 0; 00721 result = mMB->tag_get_handle(GLOBAL_ID_TAG_NAME, 1, MB_TYPE_INTEGER, id_tag, MB_TAG_DENSE|MB_TAG_CREAT, &def_val); 00722 if (MB_SUCCESS != result) return result; 00723 } 00724 00725 // now assign the ids 00726 int i; 00727 Range::iterator rit; 00728 ErrorCode tmp_result; 00729 result = MB_SUCCESS; 00730 for (i = start_id, rit = elements.begin(); rit != elements.end(); rit++, i++) { 00731 tmp_result = mMB->tag_set_data(id_tag, &(*rit), 1, &i); 00732 if (MB_SUCCESS != tmp_result) result = tmp_result; 00733 } 00734 00735 return result; 00736 } 00737 00738 ErrorCode WriteUtil::report_error( const std::string& error ) 00739 { 00740 if(mError) 00741 return mError->set_last_error(error); 00742 else 00743 return MB_FAILURE; 00744 } 00745 00746 00747 ErrorCode WriteUtil::report_error( const char* error, ... ) 00748 { 00749 va_list args; 00750 va_start(args, error); 00751 ErrorCode result = mError->set_last_error(error, args); 00752 va_end(args); 00753 return result; 00754 } 00755 00756 00757 ErrorCode WriteUtil::get_adjacencies( EntityHandle entity, 00758 Tag id_tag, 00759 std::vector<int>& adj ) 00760 { 00761 ErrorCode rval; 00762 const EntityHandle* adj_array; 00763 int num_adj, id; 00764 00765 // Get handles of adjacent entities 00766 rval = mMB->a_entity_factory()->get_adjacencies( entity, adj_array, num_adj ); 00767 if (MB_SUCCESS != rval) 00768 { 00769 adj.clear(); 00770 return rval; 00771 } 00772 00773 // Append IDs of adjacent entities -- skip meshsets 00774 adj.resize( num_adj ); // pre-allocate space 00775 adj.clear(); // clear used space 00776 00777 const EntityHandle* const end = adj_array + num_adj; 00778 for (const EntityHandle* iter = adj_array; iter != end; ++iter) 00779 { 00780 if (TYPE_FROM_HANDLE( *iter ) != MBENTITYSET) 00781 { 00782 rval = mMB->tag_get_data( id_tag, iter, 1, &id ); 00783 if (MB_SUCCESS != rval) 00784 return rval; 00785 adj.push_back( id ); 00786 } 00787 } 00788 00789 return MB_SUCCESS; 00790 } 00791 00792 ErrorCode WriteUtil::get_adjacencies( EntityHandle entity, 00793 const EntityHandle*& adj_array, 00794 int& num_adj ) 00795 { 00796 return mMB->a_entity_factory()->get_adjacencies( entity, adj_array, num_adj ); 00797 } 00798 00799 ErrorCode WriteUtil::get_tag_list( std::vector<Tag>& result_list, 00800 const Tag* user_tag_list, 00801 int user_tag_list_length, 00802 bool include_variable_length_tags ) 00803 { 00804 ErrorCode rval; 00805 00806 if (user_tag_list) { 00807 result_list.clear(); 00808 result_list.reserve( user_tag_list_length ); 00809 for (int i = 0; i < user_tag_list_length; ++i) { 00810 std::string name; 00811 rval = mMB->tag_get_name( user_tag_list[i], name ); 00812 if (MB_SUCCESS != rval) { 00813 report_error( "Error %d getting name for tag. Invalid input tag handle?", (int)rval ); 00814 return rval; 00815 } 00816 00817 if (name.empty()) { 00818 report_error( "Explicit request to save anonymous tag." ); 00819 return MB_TAG_NOT_FOUND; 00820 } 00821 00822 int size; 00823 if (!include_variable_length_tags && 00824 MB_VARIABLE_DATA_LENGTH == mMB->tag_get_length( user_tag_list[i], size )) { 00825 report_error( "File format cannot store variable-length tag: \"%s\".", name.c_str() ); 00826 return MB_TYPE_OUT_OF_RANGE; 00827 } 00828 00829 result_list.push_back( user_tag_list[i] ); 00830 } 00831 } 00832 else { 00833 std::vector<Tag> temp_list; 00834 rval = mMB->tag_get_tags( temp_list ); 00835 if (MB_SUCCESS != rval) { 00836 report_error( "Interface::tag_get_tags failed!" ); 00837 return rval; 00838 } 00839 00840 result_list.clear(); 00841 result_list.reserve( temp_list.size() ); 00842 00843 std::vector<Tag>::iterator i; 00844 for (i = temp_list.begin(); i != temp_list.end(); ++i) { 00845 std::string name; 00846 rval = mMB->tag_get_name( *i, name ); 00847 if (MB_SUCCESS != rval) { 00848 report_error( "Error %d getting name for tag. Stale tag handle?", (int)rval ); 00849 return rval; 00850 } 00851 00852 // skip anonymous tags 00853 if (name.empty()) 00854 continue; 00855 00856 // skip private/internal tags 00857 if (name.size() >= 2 && name[0] == '_' && name[1] == '_') 00858 continue; 00859 00860 // if reqested, skip variable-length tags 00861 int size; 00862 if (!include_variable_length_tags && 00863 MB_VARIABLE_DATA_LENGTH == mMB->tag_get_length( *i, size )) 00864 continue; 00865 00866 result_list.push_back( *i ); 00867 } 00868 } 00869 00870 return MB_SUCCESS; 00871 } 00872 00873 ErrorCode WriteUtil::get_entity_list_pointers( Range::const_iterator begin, 00874 Range::const_iterator end, 00875 EntityHandle const* * pointers, 00876 EntityListType relation, 00877 int* lengths, 00878 unsigned char* flags ) 00879 { 00880 RangeSeqIntersectIter iter(mMB->sequence_manager()); 00881 ErrorCode rval = iter.init( begin, end ); 00882 while (MB_SUCCESS == rval) { 00883 00884 EntityType type = TYPE_FROM_HANDLE( iter.get_start_handle() ); 00885 00886 if (MBENTITYSET == type) { 00887 const MeshSetSequence* seq = reinterpret_cast<MeshSetSequence*>(iter.get_sequence()); 00888 const MeshSet* set; 00889 int len = 0; size_t clen; 00890 for (EntityHandle h = iter.get_start_handle(); h <= iter.get_end_handle(); ++h) { 00891 set = seq->get_set(h); 00892 switch (relation) { 00893 case CONTENTS: *pointers = set->get_contents( clen ); len = clen; break; 00894 case CHILDREN: *pointers = set->get_children( len ); break; 00895 case PARENTS: *pointers = set->get_parents( len ); break; 00896 } 00897 if (lengths) { 00898 *lengths = len; 00899 ++lengths; 00900 } 00901 if (flags) { 00902 *flags = (unsigned char)set->flags(); 00903 ++flags; 00904 } 00905 ++pointers; 00906 } 00907 } 00908 00909 else if (MBVERTEX != type) { 00910 const bool topological = (relation == TOPOLOGICAL); 00911 int len; 00912 const ElementSequence* seq = reinterpret_cast<ElementSequence*>(iter.get_sequence()); 00913 for (EntityHandle h = iter.get_start_handle(); h <= iter.get_end_handle(); ++h) { 00914 rval = seq->get_connectivity( h, *pointers, len, topological ); 00915 if (MB_SUCCESS != rval) return rval; 00916 if (lengths) { 00917 *lengths = len; 00918 ++lengths; 00919 } 00920 if (flags) { 00921 *flags = 0; 00922 ++flags; 00923 } 00924 ++pointers; 00925 } 00926 } 00927 else { 00928 return MB_TYPE_OUT_OF_RANGE; 00929 } 00930 00931 rval = iter.step(); 00932 } 00933 if (MB_FAILURE == rval) return MB_SUCCESS; // at end of list 00934 else return rval; 00935 } 00936 00937 ErrorCode WriteUtil::get_entity_list_pointers( EntityHandle const* entities, 00938 int num_entities, 00939 EntityHandle const* * pointers, 00940 EntityListType relation, 00941 int* lengths, 00942 unsigned char* flags ) 00943 { 00944 SequenceManager *sm = mMB->sequence_manager(); 00945 const EntitySequence *tmp_seq; 00946 ErrorCode rval = MB_SUCCESS; 00947 for (int i = 0; i < num_entities; i++) { 00948 rval = sm->find(entities[i], tmp_seq); 00949 if (MB_SUCCESS != rval) return rval; 00950 00951 EntityType type = TYPE_FROM_HANDLE(entities[i]); 00952 00953 if (MBENTITYSET == type) { 00954 const MeshSetSequence* seq = reinterpret_cast<const MeshSetSequence*>(tmp_seq); 00955 const MeshSet* set; 00956 int len = 0; size_t clen; 00957 set = seq->get_set(entities[i]); 00958 switch (relation) { 00959 case CONTENTS: *pointers = set->get_contents( clen ); len = clen; break; 00960 case CHILDREN: *pointers = set->get_children( len ); break; 00961 case PARENTS: *pointers = set->get_parents( len ); break; 00962 } 00963 if (lengths) { 00964 *lengths = len; 00965 ++lengths; 00966 } 00967 if (flags) { 00968 *flags = (unsigned char)set->flags(); 00969 ++flags; 00970 } 00971 ++pointers; 00972 } 00973 00974 else if (MBVERTEX != type) { 00975 const bool topological = (relation == TOPOLOGICAL); 00976 int len; 00977 const ElementSequence* seq = reinterpret_cast<const ElementSequence*>(tmp_seq); 00978 rval = seq->get_connectivity( entities[i], *pointers, len, topological ); 00979 if (MB_SUCCESS != rval) return rval; 00980 if (lengths) { 00981 *lengths = len; 00982 ++lengths; 00983 } 00984 if (flags) { 00985 *flags = 0; 00986 ++flags; 00987 } 00988 ++pointers; 00989 } 00990 else { 00991 return MB_TYPE_OUT_OF_RANGE; 00992 } 00993 } 00994 if (MB_FAILURE == rval) return MB_SUCCESS; // at end of list 00995 else return rval; 00996 } 00997 00998 } // namespace moab