1
15
16 #ifdef WIN32
17 #ifdef _DEBUG
18
19
20 #pragma warning( disable : 4786 )
21 #endif
22 #endif
23
24 #include "WriteGMV.hpp"
25
26 #include "moab/Interface.hpp"
27 #include "Internals.hpp"
28 #include "moab/Range.hpp"
29 #include "moab/CN.hpp"
30 #include "MBTagConventions.hpp"
31 #include "moab/WriteUtilIface.hpp"
32 #include <fstream>
33 #include <cassert>
34
35 namespace moab
36 {
37
38 const char* WriteGMV::gmvTypeNames[] = { "", "line", "tri", "quad", "", "tet", "pyramid", "prism", "", "hex", "", "" };
39
40 WriterIface* WriteGMV::factory( Interface* iface )
41 {
42 return new WriteGMV( iface );
43 }
44
45 WriteGMV::WriteGMV( Interface* impl ) : mbImpl( impl )
46 {
47 assert( impl != NULL );
48
49 impl->query_interface( mWriteIface );
50
51
52 mMaterialSetTag = 0;
53 mDirichletSetTag = 0;
54 mNeumannSetTag = 0;
55 mHasMidNodesTag = 0;
56 mGeomDimensionTag = 0;
57 mGlobalIdTag = 0;
58
59
60
61
62 int negone = -1;
63 impl->tag_get_handle( MATERIAL_SET_TAG_NAME, 1, MB_TYPE_INTEGER, mMaterialSetTag, MB_TAG_SPARSE | MB_TAG_CREAT,
64 &negone );
65
66 impl->tag_get_handle( DIRICHLET_SET_TAG_NAME, 1, MB_TYPE_INTEGER, mDirichletSetTag, MB_TAG_SPARSE | MB_TAG_CREAT,
67 &negone );
68
69 impl->tag_get_handle( NEUMANN_SET_TAG_NAME, 1, MB_TYPE_INTEGER, mNeumannSetTag, MB_TAG_SPARSE | MB_TAG_CREAT,
70 &negone );
71
72 mGlobalIdTag = impl->globalId_tag();
73
74 int dum_val_array[] = { -1, -1, -1, -1 };
75 impl->tag_get_handle( HAS_MID_NODES_TAG_NAME, 4, MB_TYPE_INTEGER, mHasMidNodesTag, MB_TAG_SPARSE | MB_TAG_CREAT,
76 dum_val_array );
77 }
78
79 WriteGMV::~WriteGMV()
80 {
81 mbImpl->release_interface( mWriteIface );
82 }
83
84 ErrorCode WriteGMV::write_file( const char* file_name,
85 const EntityHandle output_set,
86 const int user_dimension,
87 const bool mesh,
88 const bool poly_mesh )
89 {
90
91
92 ErrorCode result = MB_SUCCESS;
93
94
95
96 if( mesh )
97 {
98 result = local_write_mesh( file_name, output_set, user_dimension, true, false );
99 if( MB_SUCCESS != result ) return result;
100 }
101
102 if( poly_mesh )
103 {
104 result = local_write_mesh( file_name, output_set, user_dimension, false, true );
105 if( MB_SUCCESS != result ) return result;
106 }
107
108 return result;
109 }
110
111 ErrorCode WriteGMV::write_file( const char* filename,
112 const bool,
113 const FileOptions& ,
114 const EntityHandle* output_sets,
115 const int num_output_sets,
116 const std::vector< std::string >&,
117 const Tag*,
118 int,
119 int dimension )
120 {
121 EntityHandle output_set = 0;
122 if( output_sets && num_output_sets > 0 )
123 {
124 if( num_output_sets > 1 ) return MB_FAILURE;
125 output_set = output_sets[0];
126 }
127
128 if( dimension == 0 )
129 {
130 mbImpl->get_dimension( dimension );
131 }
132
133 return write_file( filename, output_set, dimension, true, true );
134 }
135
136 ErrorCode WriteGMV::local_write_mesh( const char* file_name,
137 const EntityHandle output_set,
138 const int user_dimension,
139 const bool mesh,
140 const bool poly_mesh )
141 {
142 std::ofstream ofile;
143 ErrorCode result;
144
145 if( mesh )
146 {
147
148 std::string tmp_name( file_name );
149 tmp_name += ".gmv";
150 ofile.open( tmp_name.c_str() );
151 }
152 else if( poly_mesh )
153 {
154
155 std::string tmp_name( file_name );
156 tmp_name += ".poly.gmv";
157 ofile.open( tmp_name.c_str() );
158 }
159
160 ofile << "gmvinput ascii" << std::endl;
161
162
163 Range dum_range, elements, all_verts;
164 EntityType otype;
165 if( poly_mesh )
166 {
167 result = mbImpl->get_entities_by_type( output_set, MBPOLYGON, elements, true );
168 if( MB_SUCCESS != result ) return result;
169 }
170 else
171 {
172 for( otype = CN::TypeDimensionMap[user_dimension].first; otype <= CN::TypeDimensionMap[user_dimension].second;
173 otype++ )
174 {
175 if( otype == MBPOLYGON || otype == MBPOLYHEDRON ) continue;
176 dum_range.clear();
177 result = mbImpl->get_entities_by_type( output_set, otype, dum_range, true );
178 if( MB_SUCCESS != result ) return result;
179
180 std::copy( dum_range.begin(), dum_range.end(), range_inserter( elements ) );
181 }
182 }
183
184
185 result = mbImpl->get_adjacencies( elements, 0, false, all_verts, Interface::UNION );
186 if( MB_SUCCESS != result ) return result;
187
188 int num_verts = all_verts.size();
189
190
191 double* xcoord = new double[num_verts];
192 double* ycoord = new double[num_verts];
193 double* zcoord = new double[num_verts];
194 std::vector< double* > coord_arrays;
195 coord_arrays.push_back( xcoord );
196 coord_arrays.push_back( ycoord );
197 coord_arrays.push_back( zcoord );
198
199
200 result = mWriteIface->get_node_coords( 3, num_verts, all_verts, mGlobalIdTag, 1, coord_arrays );
201 if( MB_SUCCESS != result ) return result;
202
203 int i, j;
204
205
206
207
208 ofile << "nodev " << num_verts << std::endl;
209 for( i = 0; i < num_verts; i++ )
210 ofile << xcoord[i] << " " << ycoord[i] << " " << zcoord[i] << std::endl;
211
212
213
214 delete[] xcoord;
215 delete[] ycoord;
216 delete[] zcoord;
217
218
219
220 std::vector< int > connect;
221 std::vector< EntityHandle > connecth;
222
223 if( mesh )
224 {
225 Range sub_range;
226
227 ofile << "cells " << elements.size() << std::endl;
228
229 for( otype = CN::TypeDimensionMap[user_dimension].first; otype <= CN::TypeDimensionMap[user_dimension].second;
230 otype++ )
231 {
232
233 if( otype == MBPOLYGON || otype == MBPOLYHEDRON ) continue;
234
235
236 Range::iterator lower =
237 Range::lower_bound( elements.begin(), elements.end(), CREATE_HANDLE( otype, MB_START_ID, i ) );
238 Range::iterator upper =
239 Range::lower_bound( elements.begin(), elements.end(), CREATE_HANDLE( otype + 1, MB_START_ID, i ) );
240
241 if( lower == upper ) continue;
242
243
244 sub_range.clear();
245 std::copy( lower, upper, range_inserter( sub_range ) );
246
247
248 int verts_per = CN::VerticesPerEntity( otype );
249 if( connect.size() < verts_per * sub_range.size() ) connect.resize( verts_per * sub_range.size() );
250
251
252 result = mWriteIface->get_element_connect( sub_range.size(), verts_per, mGlobalIdTag, sub_range,
253 mGlobalIdTag, 1, &connect[0] );
254 if( MB_SUCCESS != result ) return result;
255
256
257
258
259 for( i = 0; i < (int)sub_range.size(); i++ )
260 {
261 ofile << gmvTypeNames[otype] << " " << verts_per << std::endl;
262 for( j = i * verts_per; j < (int)( i + 1 ) * verts_per; j++ )
263 ofile << connect[j] << " ";
264 ofile << std::endl;
265 }
266
267
268 }
269 }
270
271 else if( poly_mesh )
272 {
273
274
275 Range polygons, polyhedra;
276 result = mbImpl->get_entities_by_type( output_set, MBPOLYGON, polygons, true );
277 if( MB_SUCCESS != result ) return result;
278
279 result = mbImpl->get_entities_by_type( output_set, MBPOLYHEDRON, polyhedra, true );
280 if( MB_SUCCESS != result ) return result;
281
282 if( polygons.size() == 0 ) return result;
283
284
285 result = mWriteIface->assign_ids( polyhedra, mGlobalIdTag, 1 );
286 if( MB_SUCCESS != result ) return result;
287
288 ofile << "faces " << polygons.size() << " " << polyhedra.size() << std::endl;
289
290 for( Range::iterator rit = polygons.begin(); rit != polygons.end(); ++rit )
291 {
292
293 connecth.clear();
294 result = mbImpl->get_connectivity( &( *rit ), 1, connecth, true );
295 if( MB_SUCCESS != result ) return result;
296
297 if( 0 == connecth.size() ) continue;
298
299
300 if( user_dimension == 3 )
301 {
302 polyhedra.clear();
303 result = mbImpl->get_adjacencies( Range( *rit, *rit ), 3, false, polyhedra );
304 if( MB_SUCCESS != result ) return result;
305
306
307 connecth.push_back( ( polyhedra.size() > 0 ? *polyhedra.begin() : 0 ) );
308 connecth.push_back( ( polyhedra.size() > 1 ? *polyhedra.rbegin() : 0 ) );
309 }
310
311
312 connect.resize( connecth.size() + 2 );
313
314
315 connect[connecth.size()] = 0;
316 connect[connecth.size() + 1] = 0;
317 result =
318 mbImpl->tag_get_data( mGlobalIdTag, &connecth[0], connecth.size() - 2 + polyhedra.size(), &connect[0] );
319 if( MB_SUCCESS != result ) return result;
320
321
322 ofile << connecth.size() - 2;
323
324 for( i = 0; i < (int)connecth.size(); i++ )
325 ofile << " " << connect[i];
326
327 ofile << std::endl;
328 }
329 }
330
331 ofile << std::endl << "endgmv" << std::endl;
332
333 ofile.close();
334
335 return MB_SUCCESS;
336 }
337
338 }