MOAB: Mesh Oriented datABase  (version 5.2.1)
WriteSmf.cpp
Go to the documentation of this file.
00001 /**
00002  * MOAB, a Mesh-Oriented datABase, is a software component for creating,
00003  * storing and accessing finite element mesh data.
00004  *
00005  * Copyright 2004 Sandia Corporation.  Under the terms of Contract
00006  * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government
00007  * retains certain rights in this software.
00008  *
00009  * This library is free software; you can redistribute it and/or
00010  * modify it under the terms of the GNU Lesser General Public
00011  * License as published by the Free Software Foundation; either
00012  * version 2.1 of the License, or (at your option) any later version.
00013  *
00014  */
00015 
00016 #ifdef WIN32
00017 #ifdef _DEBUG
00018 // turn off warnings that say they debugging identifier has been truncated
00019 // this warning comes up when using some STL containers
00020 #pragma warning( disable : 4786 )
00021 #endif
00022 #endif
00023 
00024 #include "WriteSmf.hpp"
00025 
00026 #include <fstream>
00027 #include <iostream>
00028 #include <stdio.h>
00029 #include <assert.h>
00030 #include <vector>
00031 #include <set>
00032 #include <iterator>
00033 #include <algorithm>
00034 
00035 #include "moab/Interface.hpp"
00036 #include "moab/Range.hpp"
00037 #include "moab/CN.hpp"
00038 #include "MBTagConventions.hpp"
00039 #include "moab/WriteUtilIface.hpp"
00040 #include "Internals.hpp"
00041 #include "moab/FileOptions.hpp"
00042 
00043 namespace moab
00044 {
00045 
00046 const int DEFAULT_PRECISION = 10;
00047 // const bool DEFAULT_STRICT = true;
00048 
00049 WriterIface* WriteSmf::factory( Interface* iface )
00050 {
00051     return new WriteSmf( iface );
00052 }
00053 
00054 WriteSmf::WriteSmf( Interface* impl ) : mbImpl( impl ), writeTool( 0 )
00055 {
00056     assert( impl != NULL );
00057     impl->query_interface( writeTool );
00058 }
00059 
00060 WriteSmf::~WriteSmf()
00061 {
00062     mbImpl->release_interface( writeTool );
00063 }
00064 
00065 ErrorCode WriteSmf::write_file( const char* file_name, const bool overwrite, const FileOptions& opts,
00066                                 const EntityHandle* output_list, const int num_sets,
00067                                 const std::vector< std::string >& /* qa_list */, const Tag* /* tag_list */,
00068                                 int /* num_tags */, int /* export_dimension */ )
00069 {
00070     ErrorCode rval;
00071 
00072     // Get precision for node coordinates
00073     int precision;
00074     if( MB_SUCCESS != opts.get_int_option( "PRECISION", precision ) ) precision = DEFAULT_PRECISION;
00075 
00076     // Honor overwrite flag
00077     if( !overwrite )
00078     {
00079         rval = writeTool->check_doesnt_exist( file_name );
00080         if( MB_SUCCESS != rval ) return rval;
00081     }
00082 
00083     // Create file
00084     std::ofstream file( file_name );
00085     if( !file ) { MB_SET_ERR( MB_FILE_WRITE_ERROR, "Could not open file: " << file_name ); }
00086     file.precision( precision );
00087 
00088     // Get entities to write
00089     Range triangles;
00090     if( !output_list || !num_sets )
00091     {
00092         rval = mbImpl->get_entities_by_type( 0, MBTRI, triangles, false );
00093         if( MB_SUCCESS != rval ) return rval;
00094 
00095         // Somehow get all the nodes from this range, order them, uniquify, then use binary search
00096     }
00097     else
00098     {
00099         // Get all triangles from output sets
00100         for( int i = 0; i < num_sets; i++ )
00101             rval = mbImpl->get_entities_by_type( output_list[i], MBTRI, triangles, false );
00102     }
00103     // Use an array with all the connectivities in the triangles; it will be converted later to ints
00104     int numTriangles    = triangles.size();
00105     int array_alloc     = 3 * numTriangles;               // Allocated size of 'array'
00106     EntityHandle* array = new EntityHandle[array_alloc];  // ptr to working array of result handles
00107     // Fill up array with node handles; reorder and uniquify
00108     if( !array ) return MB_MEMORY_ALLOCATION_FAILED;
00109     int fillA = 0;
00110     for( Range::const_iterator e = triangles.begin(); e != triangles.end(); ++e )
00111     {
00112         const EntityHandle* conn;
00113         int conn_len;
00114         rval = mbImpl->get_connectivity( *e, conn, conn_len );
00115         if( MB_SUCCESS != rval )
00116         {
00117             delete[] array;
00118             return rval;
00119         }
00120         if( 3 != conn_len )
00121         {
00122             delete[] array;
00123             return MB_INVALID_SIZE;
00124         }
00125 
00126         for( int i = 0; i < conn_len; ++i )
00127             array[fillA++] = conn[i];
00128     }
00129     if( fillA != array_alloc )
00130     {
00131         delete[] array;
00132         return MB_INVALID_SIZE;
00133     }
00134 
00135     std::sort( array, array + array_alloc );
00136     int numNodes = std::unique( array, array + array_alloc ) - array;
00137 
00138     file << "#$SMF 1.0\n";
00139     file << "#$vertices " << numNodes << std::endl;
00140     file << "#$faces " << numTriangles << std::endl;
00141     file << "# \n";
00142     file << "# output from MOAB \n";
00143     file << "# \n";
00144 
00145     // Output first the nodes
00146     // num nodes??
00147     // Write the nodes
00148     double coord[3];
00149     for( int i = 0; i < numNodes; i++ )
00150     {
00151         EntityHandle node_handle = array[i];
00152 
00153         rval = mbImpl->get_coords( &node_handle, 1, coord );
00154         if( rval != MB_SUCCESS )
00155         {
00156             delete[] array;
00157             return rval;
00158         }
00159 
00160         file << "v " << coord[0] << " " << coord[1] << " " << coord[2] << std::endl;
00161     }
00162     // Write faces now
00163     // Leave a blank line for cosmetics
00164     file << " \n";
00165     for( Range::const_iterator e = triangles.begin(); e != triangles.end(); ++e )
00166     {
00167         const EntityHandle* conn;
00168         int conn_len;
00169         rval = mbImpl->get_connectivity( *e, conn, conn_len );
00170         if( MB_SUCCESS != rval )
00171         {
00172             delete[] array;
00173             return rval;
00174         }
00175         if( 3 != conn_len )
00176         {
00177             delete[] array;
00178             return MB_INVALID_SIZE;
00179         }
00180         file << "f ";
00181         for( int i = 0; i < conn_len; ++i )
00182         {
00183             int indexInArray = std::lower_bound( array, array + numNodes, conn[i] ) - array;
00184             file << indexInArray + 1 << " ";
00185         }
00186         file << std::endl;
00187     }
00188 
00189     file.close();
00190     delete[] array;
00191     return MB_SUCCESS;
00192 }
00193 
00194 }  // namespace moab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines