Loading [MathJax]/extensions/tex2jax.js
Mesh Oriented datABase  (version 5.5.1)
An array-based unstructured mesh library
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
WriteSmf.cpp
Go to the documentation of this file.
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 Corporation, 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 #ifdef WIN32 17 #ifdef _DEBUG 18 // turn off warnings that say they debugging identifier has been truncated 19 // this warning comes up when using some STL containers 20 #pragma warning( disable : 4786 ) 21 #endif 22 #endif 23  24 #include "WriteSmf.hpp" 25  26 #include <fstream> 27 #include <iostream> 28 #include <cstdio> 29 #include <cassert> 30 #include <vector> 31 #include <set> 32 #include <iterator> 33 #include <algorithm> 34  35 #include "moab/Interface.hpp" 36 #include "moab/Range.hpp" 37 #include "moab/CN.hpp" 38 #include "MBTagConventions.hpp" 39 #include "moab/WriteUtilIface.hpp" 40 #include "Internals.hpp" 41 #include "moab/FileOptions.hpp" 42  43 namespace moab 44 { 45  46 const int DEFAULT_PRECISION = 10; 47 // const bool DEFAULT_STRICT = true; 48  49 WriterIface* WriteSmf::factory( Interface* iface ) 50 { 51  return new WriteSmf( iface ); 52 } 53  54 WriteSmf::WriteSmf( Interface* impl ) : mbImpl( impl ), writeTool( 0 ) 55 { 56  assert( impl != NULL ); 57  impl->query_interface( writeTool ); 58 } 59  60 WriteSmf::~WriteSmf() 61 { 62  mbImpl->release_interface( writeTool ); 63 } 64  65 ErrorCode WriteSmf::write_file( const char* file_name, 66  const bool overwrite, 67  const FileOptions& opts, 68  const EntityHandle* output_list, 69  const int num_sets, 70  const std::vector< std::string >& /* qa_list */, 71  const Tag* /* tag_list */, 72  int /* num_tags */, 73  int /* export_dimension */ ) 74 { 75  ErrorCode rval; 76  77  // Get precision for node coordinates 78  int precision; 79  if( MB_SUCCESS != opts.get_int_option( "PRECISION", precision ) ) precision = DEFAULT_PRECISION; 80  81  // Honor overwrite flag 82  if( !overwrite ) 83  { 84  rval = writeTool->check_doesnt_exist( file_name ); 85  if( MB_SUCCESS != rval ) return rval; 86  } 87  88  // Create file 89  std::ofstream file( file_name ); 90  if( !file ) 91  { 92  MB_SET_ERR( MB_FILE_WRITE_ERROR, "Could not open file: " << file_name ); 93  } 94  file.precision( precision ); 95  96  // Get entities to write 97  Range triangles; 98  if( !output_list || !num_sets ) 99  { 100  rval = mbImpl->get_entities_by_type( 0, MBTRI, triangles, false ); 101  if( MB_SUCCESS != rval ) return rval; 102  103  // Somehow get all the nodes from this range, order them, uniquify, then use binary search 104  } 105  else 106  { 107  // Get all triangles from output sets 108  for( int i = 0; i < num_sets; i++ ) 109  rval = mbImpl->get_entities_by_type( output_list[i], MBTRI, triangles, false ); 110  } 111  // Use an array with all the connectivities in the triangles; it will be converted later to ints 112  int numTriangles = triangles.size(); 113  int array_alloc = 3 * numTriangles; // Allocated size of 'array' 114  EntityHandle* array = new EntityHandle[array_alloc]; // ptr to working array of result handles 115  // Fill up array with node handles; reorder and uniquify 116  if( !array ) return MB_MEMORY_ALLOCATION_FAILED; 117  int fillA = 0; 118  for( Range::const_iterator e = triangles.begin(); e != triangles.end(); ++e ) 119  { 120  const EntityHandle* conn; 121  int conn_len; 122  rval = mbImpl->get_connectivity( *e, conn, conn_len ); 123  if( MB_SUCCESS != rval ) 124  { 125  delete[] array; 126  return rval; 127  } 128  if( 3 != conn_len ) 129  { 130  delete[] array; 131  return MB_INVALID_SIZE; 132  } 133  134  for( int i = 0; i < conn_len; ++i ) 135  array[fillA++] = conn[i]; 136  } 137  if( fillA != array_alloc ) 138  { 139  delete[] array; 140  return MB_INVALID_SIZE; 141  } 142  143  std::sort( array, array + array_alloc ); 144  int numNodes = std::unique( array, array + array_alloc ) - array; 145  146  file << "#$SMF 1.0\n"; 147  file << "#$vertices " << numNodes << std::endl; 148  file << "#$faces " << numTriangles << std::endl; 149  file << "# \n"; 150  file << "# output from MOAB \n"; 151  file << "# \n"; 152  153  // Output first the nodes 154  // num nodes?? 155  // Write the nodes 156  double coord[3]; 157  for( int i = 0; i < numNodes; i++ ) 158  { 159  EntityHandle node_handle = array[i]; 160  161  rval = mbImpl->get_coords( &node_handle, 1, coord ); 162  if( rval != MB_SUCCESS ) 163  { 164  delete[] array; 165  return rval; 166  } 167  168  file << "v " << coord[0] << " " << coord[1] << " " << coord[2] << std::endl; 169  } 170  // Write faces now 171  // Leave a blank line for cosmetics 172  file << " \n"; 173  for( Range::const_iterator e = triangles.begin(); e != triangles.end(); ++e ) 174  { 175  const EntityHandle* conn; 176  int conn_len; 177  rval = mbImpl->get_connectivity( *e, conn, conn_len ); 178  if( MB_SUCCESS != rval ) 179  { 180  delete[] array; 181  return rval; 182  } 183  if( 3 != conn_len ) 184  { 185  delete[] array; 186  return MB_INVALID_SIZE; 187  } 188  file << "f "; 189  for( int i = 0; i < conn_len; ++i ) 190  { 191  int indexInArray = std::lower_bound( array, array + numNodes, conn[i] ) - array; 192  file << indexInArray + 1 << " "; 193  } 194  file << std::endl; 195  } 196  197  file.close(); 198  delete[] array; 199  return MB_SUCCESS; 200 } 201  202 } // namespace moab