root/MOAB/branches/ref_counting/WriteTemplate.cpp

Revision 1255, 23.8 kB (checked in by kraftche, 1 year ago)

o Change behavior of FileOptions?: don't remove options from the list once

they've been processed. Doesn't work so good for reader-specific options
when trying all the registered readers.

o Pass FileOptions? instance to all readers and writers
o Combine ReadASCIISTL and ReadBinarySTL into ReadSTL
o Combine WriteASCIISTL and WriteBinarySTL into WriteSTL.
o Get rid of made-up "stlb" file extension to request binary STL files.

Reader can auto-detect file type. Use option "BINARY" to file to
control write type (or to force read type.)

o Replace tag convention with option to control byte order for binary

STL files. Options are "LITTLE_ENDIAN" and "BIG_ENDIAN". Default
for write is LITTLE_ENDIAN. Default for read is auto-detect, with
fallback to LITTLE_ENDIAN if ambiguous.

o Get rid if tag convention to control SAT file dumped by Tqdcfr. Make

Tqdcfr dump no SAT files by default. Add option "SAT_FILE=<filename>"
to request dump of SAT file.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 /**
2  * MOAB, a Mesh-Oriented datABase, is a software component for creating,
3  * storing and accessing finite element mesh data.
4  *
5  * Copyright 2004 Sandia Corporation.  Under the terms of Contract
6  * DE-AC04-94AL85000 with Sandia Coroporation, the U.S. Government
7  * retains certain rights in this software.
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  */
15
16
17 #ifdef WIN32
18 #ifdef _DEBUG
19 // turn off warnings that say they debugging identifier has been truncated
20 // this warning comes up when using some STL containers
21 #pragma warning(disable : 4786)
22 #endif
23 #endif
24
25
26 #include "WriteTemplate.hpp"
27
28 #include <utility>
29 #include <algorithm>
30 #include <time.h>
31 #include <string>
32 #include <vector>
33 #include <stdio.h>
34 #include <iostream>
35
36 #include "MBInterface.hpp"
37 #include "MBRange.hpp"
38 #include "MBCN.hpp"
39 #include "assert.h"
40 #include "MBInternals.hpp"
41 #include "ExoIIUtil.hpp"
42 #include "MBTagConventions.hpp"
43 #include "MBWriteUtilIface.hpp"
44
45 #define INS_ID(stringvar, prefix, id) \
46           sprintf(stringvar, prefix, id)
47
48 MBWriterIface* WriteTEMPLATE::factory( MBInterface* iface )
49   { return new WriteTEMPLATE( iface ); }
50
51 WriteTEMPLATE::WriteTEMPLATE(MBInterface *impl)
52     : mbImpl(impl), mCurrentMeshHandle(0)
53 {
54   assert(impl != NULL);
55
56   std::string iface_name = "MBWriteUtilIface";
57   impl->query_interface(iface_name, reinterpret_cast<void**>(&mWriteIface));
58
59   // initialize in case tag_get_handle fails below
60   //! get and cache predefined tag handles
61   int dum_val = 0;
62   MBErrorCode result = impl->tag_get_handle(MATERIAL_SET_TAG_NAME,  mMaterialSetTag);
63   if (MB_TAG_NOT_FOUND == result)
64     result = impl->tag_create(MATERIAL_SET_TAG_NAME, sizeof(int), MB_TAG_SPARSE, mMaterialSetTag,
65                               &dum_val);
66  
67   result = impl->tag_get_handle(DIRICHLET_SET_TAG_NAME, mDirichletSetTag);
68   if (MB_TAG_NOT_FOUND == result)
69     result = impl->tag_create(DIRICHLET_SET_TAG_NAME, sizeof(int), MB_TAG_SPARSE, mDirichletSetTag,
70                               &dum_val);
71  
72   result = impl->tag_get_handle(NEUMANN_SET_TAG_NAME,   mNeumannSetTag);
73   if (MB_TAG_NOT_FOUND == result)
74     result = impl->tag_create(NEUMANN_SET_TAG_NAME, sizeof(int), MB_TAG_SPARSE, mNeumannSetTag,
75                               &dum_val);
76  
77   result = impl->tag_get_handle(HAS_MID_NODES_TAG_NAME, mHasMidNodesTag);
78   if (MB_TAG_NOT_FOUND == result) {
79     int dum_val_array[] = {0, 0, 0, 0};
80     result = impl->tag_create(HAS_MID_NODES_TAG_NAME, 4*sizeof(int), MB_TAG_SPARSE, mHasMidNodesTag,
81                               dum_val_array);
82   }
83  
84   result = impl->tag_get_handle(GLOBAL_ID_TAG_NAME, mGlobalIdTag);
85   if (MB_TAG_NOT_FOUND == result)
86     result = impl->tag_create(GLOBAL_ID_TAG_NAME, sizeof(int), MB_TAG_SPARSE, mGlobalIdTag,
87                               &dum_val);
88  
89   dum_val = -1;
90   result = impl->tag_get_handle("__matSetIdTag", mMatSetIdTag);
91   if (MB_TAG_NOT_FOUND == result)
92     result = impl->tag_create("__matSetIdTag", sizeof(int), MB_TAG_DENSE, mMatSetIdTag,
93                               &dum_val);
94  
95
96   impl->tag_create("WriteTEMPLATE element mark", 1, MB_TAG_BIT, mEntityMark, NULL);
97
98 }
99
100 WriteTEMPLATE::~WriteTEMPLATE() 
101 {
102   std::string iface_name = "MBWriteUtilIface";
103   mbImpl->release_interface(iface_name, mWriteIface);
104
105   mbImpl->tag_delete(mEntityMark);
106
107 }
108
109 void WriteTEMPLATE::reset_matset(std::vector<WriteTEMPLATE::MaterialSetData> &matset_info)
110 {
111   std::vector<WriteTEMPLATE::MaterialSetData>::iterator iter;
112  
113   for (iter = matset_info.begin(); iter != matset_info.end(); iter++)
114   {
115     delete (*iter).elements;
116   }
117 }
118
119 MBErrorCode WriteTEMPLATE::write_file(const char *file_name,
120                                       const bool /* overwrite (commented out to remove warning) */,
121                                       const FileOptions& opts,
122                                       const MBEntityHandle *ent_handles,
123                                       const int num_sets,
124                                       std::vector<std::string>&, int )
125 {
126   assert(0 != mMaterialSetTag &&
127          0 != mNeumannSetTag &&
128          0 != mDirichletSetTag);
129
130     // check the file name
131   if (NULL == strstr(file_name, ".template"))
132     return MB_FAILURE;
133
134   std::vector<MBEntityHandle> matsets, dirsets, neusets, entities;
135
136   fileName = file_name;
137  
138     // separate into material sets, dirichlet sets, neumann sets
139
140   if (num_sets == 0) {
141       // default to all defined sets
142     MBRange this_range;
143     mbImpl->get_entities_by_type_and_tag(0, MBENTITYSET, &mMaterialSetTag, NULL, 1, this_range);
144     std::copy(this_range.begin(), this_range.end(), std::back_inserter(matsets));
145     this_range.clear();
146     mbImpl->get_entities_by_type_and_tag(0, MBENTITYSET, &mDirichletSetTag, NULL, 1, this_range);
147     std::copy(this_range.begin(), this_range.end(), std::back_inserter(dirsets));
148     this_range.clear();
149     mbImpl->get_entities_by_type_and_tag(0, MBENTITYSET, &mNeumannSetTag, NULL, 1, this_range);
150     std::copy(this_range.begin(), this_range.end(), std::back_inserter(neusets));
151   }
152   else {
153     int dummy;
154     for (const MBEntityHandle *iter = ent_handles; iter < ent_handles+num_sets; iter++)
155     {
156       if (MB_SUCCESS == mbImpl->tag_get_data(mMaterialSetTag, &(*iter), 1, &dummy))
157         matsets.push_back(*iter);
158       else if (MB_SUCCESS == mbImpl->tag_get_data(mDirichletSetTag, &(*iter), 1, &dummy))
159         dirsets.push_back(*iter);
160       else if (MB_SUCCESS == mbImpl->tag_get_data(mNeumannSetTag, &(*iter), 1, &dummy))
161         neusets.push_back(*iter);
162     }
163   }
164  
165     // if there is nothing to write just return.
166   if (matsets.empty() && dirsets.empty() && neusets.empty())
167     return MB_FILE_WRITE_ERROR;
168
169   std::vector<WriteTEMPLATE::MaterialSetData> matset_info;
170   std::vector<WriteTEMPLATE::DirichletSetData> dirset_info;
171   std::vector<WriteTEMPLATE::NeumannSetData> neuset_info;
172
173   MeshInfo mesh_info;
174  
175   matset_info.clear();
176   if(gather_mesh_information(mesh_info, matset_info, neuset_info, dirset_info,
177                              matsets, neusets, dirsets) != MB_SUCCESS)
178   {
179     reset_matset(matset_info);
180     return MB_FAILURE;
181   }
182
183
184   // try to open the file after gather mesh info succeeds
185   if (/* test for file open failure */ true) {
186     reset_matset(matset_info);
187     return MB_FAILURE;
188   }
189
190   if( initialize_file(mesh_info) != MB_SUCCESS)
191   {
192     reset_matset(matset_info);
193     return MB_FAILURE;
194   }
195
196   if( write_nodes(mesh_info.num_nodes, mesh_info.nodes, mesh_info.num_dim) != MB_SUCCESS )
197   {
198     reset_matset(matset_info);
199     return MB_FAILURE;
200   }
201
202   if( write_matsets(mesh_info, matset_info, neuset_info) )
203   {
204     reset_matset(matset_info);
205     return MB_FAILURE;
206   }
207
208   return MB_SUCCESS;
209 }
210
211 MBErrorCode WriteTEMPLATE::gather_mesh_information(MeshInfo &mesh_info,
212                                                    std::vector<WriteTEMPLATE::MaterialSetData> &matset_info,
213                                                    std::vector<WriteTEMPLATE::NeumannSetData> &neuset_info,
214                                                    std::vector<WriteTEMPLATE::DirichletSetData> &dirset_info,
215                                                    std::vector<MBEntityHandle> &matsets,
216                                                    std::vector<MBEntityHandle> &neusets,
217                                                    std::vector<MBEntityHandle> &dirsets)
218 {
219
220   std::vector<MBEntityHandle>::iterator vector_iter, end_vector_iter;
221
222   mesh_info.num_nodes = 0;
223   mesh_info.num_elements = 0;
224   mesh_info.num_matsets = 0;
225  
226   int id = 0;
227
228   vector_iter= matsets.begin();
229   end_vector_iter = matsets.end();
230
231   mesh_info.num_matsets = matsets.size();
232
233   std::vector<MBEntityHandle> parent_meshsets;
234
235   // clean out the bits for the element mark
236   mbImpl->tag_delete(mEntityMark);
237   mbImpl->tag_create("WriteTEMPLATE element mark", 1, MB_TAG_BIT, mEntityMark, NULL);
238
239   int highest_dimension_of_element_matsets = 0;
240
241   for(vector_iter = matsets.begin(); vector_iter != matsets.end(); vector_iter++)
242   {
243        
244     WriteTEMPLATE::MaterialSetData matset_data;
245     matset_data.elements = new MBRange;
246
247     //for the purpose of qa records, get the parents of these matsets
248     if( mbImpl->get_parent_meshsets( *vector_iter, parent_meshsets ) != MB_SUCCESS )
249       return MB_FAILURE;
250
251     // get all Entity Handles in the mesh set
252     MBRange dummy_range;
253     mbImpl->get_entities_by_handle(*vector_iter, dummy_range, true );
254
255       // find the dimension of the last entity in this range
256     MBRange::iterator entity_iter = dummy_range.end();
257     entity_iter = dummy_range.end();
258     entity_iter--;
259     int this_dim = MBCN::Dimension(TYPE_FROM_HANDLE(*entity_iter));
260     entity_iter = dummy_range.begin();
261     while (entity_iter != dummy_range.end() &&
262            MBCN::Dimension(TYPE_FROM_HANDLE(*entity_iter)) != this_dim)
263       entity_iter++;
264    
265     if (entity_iter != dummy_range.end())
266       std::copy(entity_iter, dummy_range.end(), mb_range_inserter(*(matset_data.elements)));
267
268     assert(matset_data.elements->begin() == matset_data.elements->end() ||
269            MBCN::Dimension(TYPE_FROM_HANDLE(*(matset_data.elements->begin()))) == this_dim);
270    
271     // get the matset's id
272     if(mbImpl->tag_get_data(mMaterialSetTag, &(*vector_iter), 1, &id) != MB_SUCCESS ) {
273       mWriteIface->report_error("Couldn't get matset id from a tag for an element matset.");
274       return MB_FAILURE;
275     }
276    
277     matset_data.id = id;
278     matset_data.number_attributes = 0;
279  
280      // iterate through all the elements in the meshset
281     MBRange::iterator elem_range_iter, end_elem_range_iter;
282     elem_range_iter = matset_data.elements->begin();
283     end_elem_range_iter = matset_data.elements->end();
284
285       // get the entity type for this matset, verifying that it's the same for all elements
286       // THIS ASSUMES HANDLES SORT BY TYPE!!!
287     MBEntityType entity_type = TYPE_FROM_HANDLE(*elem_range_iter);
288     end_elem_range_iter--;
289     if (entity_type != TYPE_FROM_HANDLE(*(end_elem_range_iter++))) {
290       mWriteIface->report_error("Entities in matset %i not of common type", id);
291       return MB_FAILURE;
292     }
293
294     int dimension = MBCN::Dimension(entity_type);
295
296     if( dimension > highest_dimension_of_element_matsets )
297       highest_dimension_of_element_matsets = dimension;
298
299     matset_data.moab_type = mbImpl->type_from_handle(*(matset_data.elements->begin()));
300     if (MBMAXTYPE == matset_data.moab_type) return MB_FAILURE;
301    
302     std::vector<MBEntityHandle> tmp_conn;
303     mbImpl->get_connectivity(&(*(matset_data.elements->begin())), 1, tmp_conn);
304     matset_data.element_type =
305       ExoIIUtil::get_element_type_from_num_verts(tmp_conn.size(), entity_type, dimension);
306    
307     if (matset_data.element_type == EXOII_MAX_ELEM_TYPE) {
308       mWriteIface->report_error("Element type in matset %i didn't get set correctly", id);
309       return MB_FAILURE;
310     }
311    
312     matset_data.number_nodes_per_element = ExoIIUtil::VerticesPerElement[matset_data.element_type];
313
314     // number of nodes for this matset
315     matset_data.number_elements = matset_data.elements->size();
316
317     // total number of elements
318     mesh_info.num_elements += matset_data.number_elements;
319
320     // get the nodes for the elements
321     mWriteIface->gather_nodes_from_elements(*matset_data.elements, mEntityMark, mesh_info.nodes);
322
323     if(!neusets.empty())
324     {
325       // if there are neusets, keep track of which elements are being written out
326       for(MBRange::iterator iter = matset_data.elements->begin();
327           iter != matset_data.elements->end(); ++iter)
328       {
329         unsigned char bit = 0x1;
330         mbImpl->tag_set_data(mEntityMark, &(*iter), 1, &bit);
331       }
332     }
333
334     matset_info.push_back( matset_data );
335  
336   }
337  
338
339   //if user hasn't entered dimension, we figure it out
340   if( mesh_info.num_dim == 0 )
341   {
342     //never want 1 or zero dimensions
343     if( highest_dimension_of_element_matsets < 2 )
344       mesh_info.num_dim = 3;
345     else
346       mesh_info.num_dim = highest_dimension_of_element_matsets;
347   }
348
349   MBRange::iterator range_iter, end_range_iter;
350   range_iter = mesh_info.nodes.begin();
351   end_range_iter = mesh_info.nodes.end();
352
353   mesh_info.num_nodes = mesh_info.nodes.size();
354
355   //------dirsets--------
356  
357   vector_iter= dirsets.begin();
358   end_vector_iter = dirsets.end();
359
360   for(; vector_iter != end_vector_iter; vector_iter++)
361   {
362    
363     WriteTEMPLATE::DirichletSetData dirset_data;
364     dirset_data.id = 0;
365     dirset_data.number_nodes = 0;
366
367     // get the dirset's id
368     if(mbImpl->tag_get_data(mDirichletSetTag,&(*vector_iter), 1,&id) != MB_SUCCESS) {
369       mWriteIface->report_error("Couldn't get id tag for dirset %i", id);
370       return MB_FAILURE;
371     }
372    
373     dirset_data.id = id;
374
375     std::vector<MBEntityHandle> node_vector;
376     //get the nodes of the dirset that are in mesh_info.nodes
377     if( mbImpl->get_entities_by_handle(*vector_iter, node_vector, true) != MB_SUCCESS ) {
378       mWriteIface->report_error("Couldn't get nodes in dirset %i", id);
379       return MB_FAILURE;
380     }
381
382     std::vector<MBEntityHandle>::iterator iter, end_iter;
383     iter = node_vector.begin();
384     end_iter= node_vector.end();
385  
386     int j=0;
387     unsigned char node_marked = 0;
388     MBErrorCode result;
389     for(; iter != end_iter; iter++)
390     {
391       if (TYPE_FROM_HANDLE(*iter) != MBVERTEX) continue;
392       result = mbImpl->tag_get_data(mEntityMark, &(*iter), 1, &node_marked);
393       if (MB_SUCCESS != result) {
394         mWriteIface->report_error("Couldn't get mark data.");
395         return result;
396       }
397      
398       if(node_marked == 0x1) dirset_data.nodes.push_back( *iter );   
399       j++;
400     }
401    
402     dirset_data.number_nodes = dirset_data.nodes.size();
403     dirset_info.push_back( dirset_data );
404   }
405
406   //------neusets--------
407   vector_iter= neusets.begin();
408   end_vector_iter = neusets.end();
409
410   for(; vector_iter != end_vector_iter; vector_iter++)
411   {
412     WriteTEMPLATE::NeumannSetData neuset_data;
413
414     // get the neuset's id
415     if(mbImpl->tag_get_data(mNeumannSetTag,&(*vector_iter), 1,&id) != MB_SUCCESS)
416       return MB_FAILURE;
417
418     neuset_data.id = id;
419     neuset_data.mesh_set_handle = *vector_iter;
420  
421     //get the sides in two lists, one forward the other reverse; starts with forward sense
422       // by convention
423     MBRange forward_elems, reverse_elems;
424     if(get_neuset_elems(*vector_iter, 0, forward_elems, reverse_elems) == MB_FAILURE)
425       return MB_FAILURE;
426
427     MBErrorCode result = get_valid_sides(forward_elems, 1, neuset_data);
428     if (MB_SUCCESS != result) {
429       mWriteIface->report_error("Couldn't get valid sides data.");
430       return result;
431     }
432     result = get_valid_sides(reverse_elems, -1, neuset_data);
433     if (MB_SUCCESS != result) {
434       mWriteIface->report_error("Couldn't get valid sides data.");
435       return result;
436     }
437    
438     neuset_data.number_elements = neuset_data.elements.size();
439     neuset_info.push_back( neuset_data );
440   }
441
442   return MB_SUCCESS;
443 }
444
445 MBErrorCode WriteTEMPLATE::get_valid_sides(MBRange &elems, const int sense,
446                                            WriteTEMPLATE::NeumannSetData &neuset_data)
447 {
448     // this is where we see if underlying element of side set element is included in output
449
450   unsigned char element_marked = 0;
451   MBErrorCode result;
452   for(MBRange::iterator iter = elems.begin(); iter != elems.end(); iter++)
453   {
454       // should insert here if "side" is a quad/tri on a quad/tri mesh
455     result = mbImpl->tag_get_data(mEntityMark, &(*iter), 1, &element_marked);
456     if (MB_SUCCESS != result) {
457       mWriteIface->report_error("Couldn't get mark data.");
458       return result;
459     }
460    
461     if(element_marked == 0x1)
462     {
463       neuset_data.elements.push_back( *iter );
464
465         // TJT TODO: the sense should really be # edges + 1or2
466       neuset_data.side_numbers.push_back((sense == 1 ? 1 : 2));
467     }
468     else //then "side" is probably a quad/tri on a hex/tet mesh
469     {
470       std::vector<MBEntityHandle> parents;
471       int dimension = MBCN::Dimension( TYPE_FROM_HANDLE(*iter));
472
473         //get the adjacent parent element of "side"
474       if( mbImpl->get_adjacencies( &(*iter), 1, dimension+1, false, parents) != MB_SUCCESS ) {
475         mWriteIface->report_error("Couldn't get adjacencies for neuset.");
476         return MB_FAILURE;
477       }
478        
479       if(!parents.empty())     
480       {
481           //make sure the adjacent parent element will be output
482         for(unsigned int k=0; k<parents.size(); k++)
483         {
484           result = mbImpl->tag_get_data(mEntityMark, &(parents[k]), 1, &element_marked);
485           if (MB_SUCCESS != result) {
486             mWriteIface->report_error("Couldn't get mark data.");
487             return result;
488           }
489        
490           int side_no, this_sense, this_offset;
491           if(element_marked == 0x1 &&
492              mbImpl->side_number(parents[k], *iter, side_no,
493                                   this_sense, this_offset) == MB_SUCCESS &&
494              this_sense == sense) {
495             neuset_data.elements.push_back(parents[k]);
496             neuset_data.side_numbers.push_back(side_no+1);
497             break;
498           }
499         }
500       }
501       else
502       {
503         mWriteIface->report_error("No parent element exists for element in neuset %i", neuset_data.id);
504         return MB_FAILURE;
505       }
506     }
507   }
508
509   return MB_SUCCESS;
510 }
511
512 MBErrorCode WriteTEMPLATE::write_nodes(const int num_nodes, const MBRange& nodes, const int dimension)
513 {
514   //see if should transform coordinates
515   MBErrorCode result;
516   MBTag trans_tag;
517   result = mbImpl->tag_get_handle( MESH_TRANSFORM_TAG_NAME, trans_tag);
518   bool transform_needed = true;
519   if( result == MB_TAG_NOT_FOUND )
520     transform_needed = false;
521
522   int num_coords_to_fill = transform_needed ? 3 : dimension;
523
524   std::vector<double*> coord_arrays(3);
525   coord_arrays[0] = new double[num_nodes];
526   coord_arrays[1] = new double[num_nodes];
527   coord_arrays[2] = NULL;
528
529   if( num_coords_to_fill == 3 )
530     coord_arrays[2] = new double[num_nodes];
531  
532   result = mWriteIface->get_node_arrays(dimension, num_nodes, nodes,
533                                         mGlobalIdTag, 0, coord_arrays);
534   if(result != MB_SUCCESS)
535   {
536     delete [] coord_arrays[0];
537     delete [] coord_arrays[1];
538     if(coord_arrays[2]) delete [] coord_arrays[2];
539     return result;
540   }
541
542   if( transform_needed )
543   {
544     double trans_matrix[16];
545     result = mbImpl->tag_get_data( trans_tag, NULL, 0, trans_matrix );
546     if (MB_SUCCESS != result) {
547       mWriteIface->report_error("Couldn't get transform data.");
548       return result;
549     }
550      
551     for( int i=0; i<num_nodes; i++)
552     {
553
554       double vec1[3];
555       double vec2[3];
556
557       vec2[0] =  coord_arrays[0][i];
558       vec2[1] =  coord_arrays[1][i];
559       vec2[2] =  coord_arrays[2][i];
560
561       for( int row=0; row<3; row++ )
562       {
563         vec1[row] = 0.0;
564         for( int col = 0; col<3; col++ )
565         {
566           vec1[row] += ( trans_matrix[ (row*4)+col ] * vec2[col] );
567         }
568       }
569
570       coord_arrays[0][i] = vec1[0];
571       coord_arrays[1][i] = vec1[1];
572       coord_arrays[2][i] = vec1[2];
573
574     }
575   }
576
577
578   // write the nodes
579
580   /* template - write nodes to file here in some way */
581
582   // clean up
583   delete [] coord_arrays[0];
584   delete [] coord_arrays[1];
585   if(coord_arrays[2])
586     delete [] coord_arrays[2];
587
588   return MB_SUCCESS;
589
590 }
591
592 MBErrorCode WriteTEMPLATE::write_matsets(MeshInfo & /* mesh_info (commented out to remove warning) */,
593                                          std::vector<WriteTEMPLATE::MaterialSetData> &matset_data,
594                                          std::vector<WriteTEMPLATE::NeumannSetData> &/* neuset_data (commented out to remove warning) */)
595 {
596
597   unsigned int i;
598   std::vector<int> connect;
599   const MBEntityHandle *connecth;
600   int num_connecth;
601   MBErrorCode result;
602  
603     // don't usually have anywhere near 31 nodes per element
604   connect.reserve(31);
605   MBRange::iterator rit;
606
607   WriteTEMPLATE::MaterialSetData matset;
608   for (i = 0; i < matset_data.size(); i++) {
609     matset = matset_data[i];
610    
611     int id = matset.id;
612       // bogus line to get rid of warning
613     if (0 == id) ;
614
615     for (rit = matset.elements->begin(); rit != matset.elements->end(); rit++) {
616      
617         // get the connectivity of this element
618       result = mbImpl->get_connectivity(*rit, connecth, num_connecth);
619       if (MB_SUCCESS != result) return result;
620      
621         // get the vertex ids
622       result = mbImpl->tag_get_data(mGlobalIdTag, connecth, num_connecth, &connect[0]);
623       if (MB_SUCCESS != result) return result;
624      
625         // write the data
626         /* template - write element connectivity here */
627
628       if(/* template - check for error condition! */ false)
629         return MB_FAILURE;
630     }
631   }
632
633   return MB_SUCCESS;
634 }
635
636 MBErrorCode WriteTEMPLATE::initialize_file(MeshInfo &mesh_info)
637 {
638     // perform the initializations
639
640   int coord_size, ncoords;
641  
642   coord_size = mesh_info.num_dim;
643     /* template - write coord size */
644
645   ncoords = mesh_info.num_nodes;
646     /* template - write num nodes*/
647  
648     /* template - write information on the element types & numbers (depends
649        on material and other sets) */
650
651 /* node coordinate arrays: */
652     /* template - initialize variable to hold coordinate arrays */
653
654    return MB_SUCCESS;
655 }
656
657
658 MBErrorCode WriteTEMPLATE::open_file(const char* filename)
659 {
660    // not a valid filname
661    if(strlen((const char*)filename) == 0)
662    {
663      mWriteIface->report_error("Output filename not specified");
664       return MB_FAILURE;
665    }
666
667      /* template - open file & store somewhere */
668
669    // file couldn't be opened
670    if(/* template - check for file open error here! */ false)
671    {
672      mWriteIface->report_error("Cannot open %s", filename);
673      return MB_FAILURE;
674    }
675    return MB_SUCCESS;
676 }
677
678 MBErrorCode WriteTEMPLATE::get_neuset_elems(MBEntityHandle neuset, int current_sense,
679                                         MBRange &forward_elems, MBRange &reverse_elems)
680 {
681   MBRange neuset_elems, neuset_meshsets;
682
683     // get the sense tag; don't need to check return, might be an error if the tag
684     // hasn't been created yet
685   MBTag sense_tag = 0;
686   mbImpl->tag_get_handle("SENSE", sense_tag);
687
688     // get the entities in this set
689   MBErrorCode result = mbImpl->get_entities_by_handle(neuset, neuset_elems, true);
690   if (MB_FAILURE == result) return result;
691  
692     // now remove the meshsets into the neuset_meshsets; first find the first meshset,
693   MBRange::iterator range_iter = neuset_elems.begin();
694   while (TYPE_FROM_HANDLE(*range_iter) != MBENTITYSET && range_iter != neuset_elems.end())
695     range_iter++;
696  
697     // then, if there are some, copy them into neuset_meshsets and erase from neuset_elems
698   if (range_iter != neuset_elems.end()) {
699     std::copy(range_iter, neuset_elems.end(), mb_range_inserter(neuset_meshsets));
700     neuset_elems.erase(range_iter, neuset_elems.end());
701   }
702  
703
704     // ok, for the elements, check the sense of this set and copy into the right range
705     // (if the sense is 0, copy into both ranges)
706
707     // need to step forward on list until we reach the right dimension
708   MBRange::iterator dum_it = neuset_elems.end();
709   dum_it--;
710   int target_dim = MBCN::Dimension(TYPE_FROM_HANDLE(*dum_it));
711   dum_it = neuset_elems.begin();
712   while (target_dim != MBCN::Dimension(TYPE_FROM_HANDLE(*dum_it)) &&
713          dum_it != neuset_elems.end())
714     dum_it++;
715
716   if (current_sense == 1 || current_sense == 0)
717     std::copy(dum_it, neuset_elems.end(), mb_range_inserter(forward_elems));
718   if (current_sense == -1 || current_sense == 0)
719     std::copy(dum_it, neuset_elems.end(), mb_range_inserter(reverse_elems));
720  
721     // now loop over the contained meshsets, getting the sense of those and calling this
722     // function recursively
723   for (range_iter = neuset_meshsets.begin(); range_iter != neuset_meshsets.end(); range_iter++) {
724
725       // first get the sense; if it's not there, by convention it's forward
726     int this_sense;
727     if (0 == sense_tag ||
728         MB_FAILURE == mbImpl->tag_get_data(sense_tag, &(*range_iter), 1, &this_sense))
729       this_sense = 1;
730      
731       // now get all the entities on this meshset, with the proper (possibly reversed) sense
732     get_neuset_elems(*range_iter, this_sense*current_sense,
733                       forward_elems, reverse_elems);
734   }
735  
736   return result;
737 }
738
739
740  
Note: See TracBrowser for help on using the browser.