moab
WriteUtil.cpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines