moab
|
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