moab
WriteSmf.cpp
Go to the documentation of this file.
00001 
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 #include "moab/Version.h"
00043 
00044 namespace moab {
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)
00055   : mbImpl(impl), writeTool(0)
00056 {
00057   assert(impl != NULL);
00058   impl->query_interface(writeTool);
00059 }
00060 
00061 WriteSmf::~WriteSmf() 
00062 {
00063   mbImpl->release_interface(writeTool);
00064 }
00065 
00066 ErrorCode WriteSmf::write_file(const char *file_name, 
00067                                  const bool overwrite,
00068                                  const FileOptions& opts,
00069                                  const EntityHandle *output_list,
00070                                  const int num_sets,
00071                                  const std::vector<std::string>& ,
00072                                  const Tag* /*tag_list*/,
00073                                  int /*num_tags*/,
00074                                  int /*export_dimension*/)
00075 {
00076   ErrorCode rval;
00077 
00078   // Get precision for node coordinates
00079   int precision;
00080   if (MB_SUCCESS != opts.get_int_option("PRECISION", precision))
00081     precision = DEFAULT_PRECISION;
00082 
00083   // Honor overwrite flag
00084   if (!overwrite) {
00085     rval = writeTool->check_doesnt_exist(file_name);
00086     if (MB_SUCCESS != rval)
00087       return rval;
00088   }
00089 
00090   // Create file
00091   std::ofstream file(file_name);
00092   if (!file) {
00093     writeTool->report_error("Could not open file: %s\n", file_name);
00094     return MB_FILE_WRITE_ERROR;
00095   }
00096   file.precision(precision);
00097 
00098   // Get entities to write
00099   Range triangles;
00100   if (!output_list || !num_sets) {
00101     rval = mbImpl->get_entities_by_type(0, MBTRI, triangles, false);
00102     if (MB_SUCCESS != rval)
00103       return rval;
00104 
00105   // Somehow get all the nodes from this range, order them, uniquify, then use binary search
00106   }
00107   else {
00108     // get all triangles from output sets
00109     for (int i = 0; i < num_sets; i++)
00110       rval = mbImpl->get_entities_by_type(output_list[i], MBTRI, triangles, false);
00111   }
00112   // Use an array with all the connectivities in the triangles; it will be converted later to ints
00113   int numTriangles = triangles.size();
00114   int array_alloc = 3 * numTriangles;       // allocated size of 'array'
00115   EntityHandle* array = new EntityHandle[array_alloc]; // ptr to working array of result handles
00116   // Fill up array with node handles; reorder and uniquify
00117   if (!array)
00118      return MB_MEMORY_ALLOCATION_FAILED;
00119   int fillA = 0;
00120   for (Range::const_iterator e = triangles.begin(); e != triangles.end(); ++e) {
00121       const EntityHandle* conn;
00122       int conn_len;
00123       rval = mbImpl->get_connectivity(*e, conn, conn_len);
00124       if (MB_SUCCESS != rval) {
00125         delete[] array;
00126         return rval;
00127       }
00128       if (3 != conn_len) {
00129         delete[] array;
00130         return MB_INVALID_SIZE;
00131       }
00132 
00133       for (int i = 0; i < conn_len; ++i)
00134         array[fillA++] = conn[i];
00135   }
00136   if (fillA != array_alloc) {
00137     delete[] array;
00138     return MB_INVALID_SIZE;
00139   }
00140 
00141   std::sort(array, array + array_alloc);
00142   int numNodes = std::unique(array, array + array_alloc) - array;
00143 
00144   file << "#$SMF 1.0\n";
00145   file << "#$vertices " << numNodes << std::endl;
00146   file << "#$faces " << numTriangles << std::endl;
00147   file << "# \n";
00148   file << "# output from MOAB \n";
00149   file << "# \n";
00150 
00151   // output first the nodes
00152   // num nodes??
00153   // write the nodes 
00154   double coord[3];
00155   for (int i = 0; i < numNodes; i++) {
00156     EntityHandle node_handle = array[i];
00157 
00158     rval = mbImpl->get_coords(&node_handle, 1, coord);
00159     if (rval != MB_SUCCESS) {
00160       delete[] array;
00161       return rval;
00162     }
00163 
00164     file << "v " << coord[0] << " " << coord[1] << " " << coord[2] << std::endl;
00165   }
00166   // Write faces now
00167   // Leave a blank line for cosmetics
00168   file << " \n";
00169   for (Range::const_iterator e = triangles.begin(); e != triangles.end(); ++e) {
00170     const EntityHandle* conn;
00171     int conn_len;
00172     rval = mbImpl->get_connectivity(*e, conn, conn_len);
00173     if (MB_SUCCESS != rval) {
00174       delete[] array;
00175       return rval;
00176     }
00177     if (3!= conn_len) {
00178       delete[] array;
00179       return MB_INVALID_SIZE;
00180     }
00181     file << "f ";
00182     for (int i = 0; i < conn_len; ++i) {
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