Branch data Line data Source code
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 : : /**
17 : : * \class ReadGmsh
18 : : * \brief Gmsh (http://www.geuz.org/gmsh) file reader
19 : : *
20 : : * See: http://geuz.org/gmsh/doc/texinfo/gmsh.html#MSH-ASCII-file-format
21 : : *
22 : : * \author Jason Kraftcheck
23 : : */
24 : :
25 : : #include "ReadGmsh.hpp"
26 : : #include "FileTokenizer.hpp" // for file tokenizer
27 : : #include "Internals.hpp"
28 : : #include "moab/Interface.hpp"
29 : : #include "moab/ReadUtilIface.hpp"
30 : : #include "moab/Range.hpp"
31 : : #include "MBTagConventions.hpp"
32 : : #include "MBParallelConventions.h"
33 : : #include "moab/CN.hpp"
34 : : #include "GmshUtil.hpp"
35 : :
36 : : #include <errno.h>
37 : : #include <string.h>
38 : : #include <map>
39 : : #include <set>
40 : :
41 : : namespace moab
42 : : {
43 : :
44 : 1 : ReaderIface* ReadGmsh::factory( Interface* iface )
45 : : {
46 [ + - ]: 1 : return new ReadGmsh( iface );
47 : : }
48 : :
49 [ + - ]: 2 : ReadGmsh::ReadGmsh( Interface* impl ) : mdbImpl( impl ), globalId( 0 )
50 : : {
51 [ + - ]: 1 : mdbImpl->query_interface( readMeshIface );
52 : 1 : }
53 : :
54 : 3 : ReadGmsh::~ReadGmsh()
55 : : {
56 [ + - ]: 1 : if( readMeshIface )
57 : : {
58 : 1 : mdbImpl->release_interface( readMeshIface );
59 : 1 : readMeshIface = 0;
60 : : }
61 [ - + ]: 2 : }
62 : :
63 : 0 : ErrorCode ReadGmsh::read_tag_values( const char* /* file_name */, const char* /* tag_name */,
64 : : const FileOptions& /* opts */, std::vector< int >& /* tag_values_out */,
65 : : const SubsetList* /* subset_list */ )
66 : : {
67 : 0 : return MB_NOT_IMPLEMENTED;
68 : : }
69 : :
70 : 1 : ErrorCode ReadGmsh::load_file( const char* filename, const EntityHandle*, const FileOptions&,
71 : : const ReaderIface::SubsetList* subset_list, const Tag* file_id_tag )
72 : : {
73 : 1 : int num_material_sets = 0;
74 : 1 : const int* material_set_list = 0;
75 : :
76 [ - + ]: 1 : if( subset_list )
77 : : {
78 [ # # ][ # # ]: 0 : if( subset_list->tag_list_length > 1 && !strcmp( subset_list->tag_list[0].tag_name, MATERIAL_SET_TAG_NAME ) )
79 [ # # ][ # # ]: 0 : { MB_SET_ERR( MB_UNSUPPORTED_OPERATION, "GMsh supports subset read only by material ID" ); }
[ # # ][ # # ]
[ # # ]
80 : 0 : material_set_list = subset_list->tag_list[0].tag_values;
81 : 0 : num_material_sets = subset_list->tag_list[0].num_tag_values;
82 : : }
83 : :
84 [ + - ]: 1 : geomSets.clear();
85 [ + - ]: 1 : globalId = mdbImpl->globalId_tag();
86 : :
87 : : // Create set for more convenient check for material set ids
88 [ + - ]: 1 : std::set< int > blocks;
89 [ - + ]: 1 : for( const int* mat_set_end = material_set_list + num_material_sets; material_set_list != mat_set_end;
90 : : ++material_set_list )
91 [ # # ]: 0 : blocks.insert( *material_set_list );
92 : :
93 : : // Map of ID->handle for nodes
94 [ + - ]: 2 : std::map< long, EntityHandle > node_id_map;
95 : 1 : int data_size = 8;
96 : :
97 : : // Open file and hand off pointer to tokenizer
98 [ + - ]: 1 : FILE* file_ptr = fopen( filename, "r" );
99 [ - + ][ # # ]: 1 : if( !file_ptr ) { MB_SET_ERR( MB_FILE_DOES_NOT_EXIST, filename << ": " << strerror( errno ) ); }
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
100 [ + - ]: 2 : FileTokenizer tokens( file_ptr, readMeshIface );
101 : :
102 : : // Determine file format version
103 : 1 : const char* const start_tokens[] = { "$NOD", "$MeshFormat", 0 };
104 [ + - ]: 1 : int format_version = tokens.match_token( start_tokens );
105 [ + - ]: 1 : if( !format_version ) return MB_FILE_DOES_NOT_EXIST;
106 : :
107 : : // If version 2.0, read additional header info
108 [ # # ]: 0 : if( 2 == format_version )
109 : : {
110 : : double version;
111 [ # # ][ # # ]: 0 : if( !tokens.get_doubles( 1, &version ) ) return MB_FILE_WRITE_ERROR;
112 : :
113 [ # # ][ # # ]: 0 : if( version != 2.0 && version != 2.1 && version != 2.2 )
[ # # ]
114 : : {
115 [ # # ][ # # ]: 0 : MB_SET_ERR( MB_FILE_DOES_NOT_EXIST, filename << ": unknown format version: " << version );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
116 : : return MB_FILE_DOES_NOT_EXIST;
117 : : }
118 : :
119 : : int file_format;
120 [ # # ][ # # ]: 0 : if( !tokens.get_integers( 1, &file_format ) || !tokens.get_integers( 1, &data_size ) ||
[ # # ][ # # ]
[ # # ][ # # ]
121 [ # # ]: 0 : !tokens.match_token( "$EndMeshFormat" ) )
122 : 0 : return MB_FILE_WRITE_ERROR;
123 : : // If physical entities in the gmsh file -> discard this
124 : 0 : const char* const phys_tokens[] = { "$Nodes", "$PhysicalNames", 0 };
125 [ # # ]: 0 : int hasPhys = tokens.match_token( phys_tokens );
126 : :
127 [ # # ]: 0 : if( hasPhys == 2 )
128 : : {
129 : : long num_phys;
130 [ # # ][ # # ]: 0 : if( !tokens.get_long_ints( 1, &num_phys ) ) return MB_FILE_WRITE_ERROR;
131 [ # # ]: 0 : for( long loop_phys = 0; loop_phys < num_phys; loop_phys++ )
132 : : {
133 : : long physDim;
134 : : long physGroupNum;
135 : : // char const * physName;
136 [ # # ][ # # ]: 0 : if( !tokens.get_long_ints( 1, &physDim ) ) return MB_FILE_WRITE_ERROR;
137 [ # # ][ # # ]: 0 : if( !tokens.get_long_ints( 1, &physGroupNum ) ) return MB_FILE_WRITE_ERROR;
138 [ # # ]: 0 : const char* ptc = tokens.get_string();
139 [ # # ]: 0 : if( !ptc ) return MB_FILE_WRITE_ERROR;
140 : : // try to get to the end of the line, without reporting errors
141 : : // really, we need to skip this
142 [ # # ][ # # ]: 0 : while( !tokens.get_newline( false ) )
143 [ # # ]: 0 : ptc = tokens.get_string();
144 : : }
145 [ # # ][ # # ]: 0 : if( !tokens.match_token( "$EndPhysicalNames" ) || !tokens.match_token( "$Nodes" ) )
[ # # ][ # # ]
[ # # ]
146 : 0 : return MB_FILE_WRITE_ERROR;
147 : : }
148 : : }
149 : :
150 : : // Read number of nodes
151 : : long num_nodes;
152 [ # # ][ # # ]: 0 : if( !tokens.get_long_ints( 1, &num_nodes ) ) return MB_FILE_WRITE_ERROR;
153 : :
154 : : // Allocate nodes
155 [ # # ]: 0 : std::vector< double* > coord_arrays;
156 : 0 : EntityHandle handle = 0;
157 [ # # ]: 0 : ErrorCode result = readMeshIface->get_node_coords( 3, num_nodes, MB_START_ID, handle, coord_arrays );
158 [ # # ]: 0 : if( MB_SUCCESS != result ) return result;
159 : :
160 : : // Read nodes
161 [ # # ][ # # ]: 0 : double *x = coord_arrays[0], *y = coord_arrays[1], *z = coord_arrays[2];
[ # # ]
162 [ # # ]: 0 : for( long i = 0; i < num_nodes; ++i, ++handle )
163 : : {
164 : : long id;
165 [ # # ][ # # ]: 0 : if( !tokens.get_long_ints( 1, &id ) || !tokens.get_doubles( 1, x++ ) || !tokens.get_doubles( 1, y++ ) ||
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
166 [ # # ]: 0 : !tokens.get_doubles( 1, z++ ) )
167 : 0 : return MB_FILE_WRITE_ERROR;
168 : :
169 [ # # ][ # # ]: 0 : if( !node_id_map.insert( std::pair< long, EntityHandle >( id, handle ) ).second )
[ # # ]
170 [ # # ][ # # ]: 0 : { MB_SET_ERR( MB_FILE_WRITE_ERROR, "Duplicate node ID at line " << tokens.line_number() ); }
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
171 : : }
172 : :
173 : : // Create reverse map from handle to id
174 [ # # ]: 0 : std::vector< int > ids( num_nodes );
175 : 0 : std::vector< int >::iterator id_iter = ids.begin();
176 [ # # ]: 0 : std::vector< EntityHandle > handles( num_nodes );
177 : 0 : std::vector< EntityHandle >::iterator h_iter = handles.begin();
178 [ # # ][ # # ]: 0 : for( std::map< long, EntityHandle >::iterator i = node_id_map.begin(); i != node_id_map.end();
[ # # ][ # # ]
[ # # ]
179 : : ++i, ++id_iter, ++h_iter )
180 : : {
181 [ # # ][ # # ]: 0 : *id_iter = i->first;
182 [ # # ][ # # ]: 0 : *h_iter = i->second;
183 : : }
184 : : // Store IDs in tags
185 [ # # ][ # # ]: 0 : result = mdbImpl->tag_set_data( globalId, &handles[0], num_nodes, &ids[0] );
[ # # ]
186 [ # # ]: 0 : if( MB_SUCCESS != result ) return result;
187 [ # # ]: 0 : if( file_id_tag )
188 : : {
189 [ # # ][ # # ]: 0 : result = mdbImpl->tag_set_data( *file_id_tag, &handles[0], num_nodes, &ids[0] );
[ # # ]
190 [ # # ]: 0 : if( MB_SUCCESS != result ) return result;
191 : : }
192 : 0 : ids.clear();
193 : 0 : handles.clear();
194 : :
195 : : // Get tokens signifying end of node data and start of elements
196 [ # # ][ # # ]: 0 : if( !tokens.match_token( format_version == 1 ? "$ENDNOD" : "$EndNodes" ) ||
[ # # ][ # # ]
[ # # ]
197 [ # # ][ # # ]: 0 : !tokens.match_token( format_version == 1 ? "$ELM" : "$Elements" ) )
198 : 0 : return MB_FILE_WRITE_ERROR;
199 : :
200 : : // Get element count
201 : : long num_elem;
202 [ # # ][ # # ]: 0 : if( !tokens.get_long_ints( 1, &num_elem ) ) return MB_FILE_WRITE_ERROR;
203 : :
204 : : // Lists of data accumulated for elements
205 [ # # ]: 0 : std::vector< EntityHandle > connectivity;
206 [ # # ][ # # ]: 0 : std::vector< int > mat_set_list, geom_set_list, part_set_list, id_list;
[ # # ][ # # ]
207 : : // Temporary, per-element data
208 [ # # ][ # # ]: 0 : std::vector< int > int_data( 5 ), tag_data( 2 );
209 [ # # ]: 0 : std::vector< long > tmp_conn;
210 : 0 : int curr_elem_type = -1;
211 [ # # ]: 0 : for( long i = 0; i < num_elem; ++i )
212 : : {
213 : : // Read element description
214 : : // File format 1.0
215 [ # # ]: 0 : if( 1 == format_version )
216 : : {
217 [ # # ][ # # ]: 0 : if( !tokens.get_integers( 5, &int_data[0] ) ) return MB_FILE_WRITE_ERROR;
[ # # ]
218 [ # # ][ # # ]: 0 : tag_data[0] = int_data[2];
219 [ # # ][ # # ]: 0 : tag_data[1] = int_data[3];
220 [ # # ][ # # ]: 0 : if( (unsigned)tag_data[1] < GmshUtil::numGmshElemType &&
[ # # ][ # # ]
221 [ # # ][ # # ]: 0 : GmshUtil::gmshElemTypes[tag_data[1]].num_nodes != (unsigned)int_data[4] )
222 : : {
223 [ # # ][ # # ]: 0 : MB_SET_ERR( MB_FILE_WRITE_ERROR,
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
224 : : "Invalid node count for element type at line " << tokens.line_number() );
225 : : }
226 : : }
227 : : // File format 2.0
228 : : else
229 : : {
230 [ # # ][ # # ]: 0 : if( !tokens.get_integers( 3, &int_data[0] ) ) return MB_FILE_WRITE_ERROR;
[ # # ]
231 [ # # ][ # # ]: 0 : tag_data.resize( int_data[2] );
232 [ # # ][ # # ]: 0 : if( !tokens.get_integers( tag_data.size(), &tag_data[0] ) ) return MB_FILE_WRITE_ERROR;
[ # # ]
233 : : }
234 : :
235 : : // If a list of material sets was specified in the
236 : : // argument list, skip any elements for which the
237 : : // material set is not specified or is not in the
238 : : // passed list.
239 [ # # ][ # # ]: 0 : if( !blocks.empty() && ( tag_data.empty() || blocks.find( tag_data[0] ) != blocks.end() ) ) continue;
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
[ # # # # ]
240 : :
241 : : // If the next element is not the same type as the last one,
242 : : // create a sequence for the block of elements we've read
243 : : // to this point (all of the same type), and clear accumulated
244 : : // data.
245 [ # # ][ # # ]: 0 : if( int_data[1] != curr_elem_type )
246 : : {
247 [ # # ]: 0 : if( !id_list.empty() )
248 : : { // First iteration
249 : : result = create_elements( GmshUtil::gmshElemTypes[curr_elem_type], id_list, mat_set_list, geom_set_list,
250 [ # # ]: 0 : part_set_list, connectivity, file_id_tag );
251 [ # # ]: 0 : if( MB_SUCCESS != result ) return result;
252 : : }
253 : :
254 : 0 : id_list.clear();
255 : 0 : mat_set_list.clear();
256 : 0 : geom_set_list.clear();
257 : 0 : part_set_list.clear();
258 : 0 : connectivity.clear();
259 [ # # ]: 0 : curr_elem_type = int_data[1];
260 [ # # ][ # # ]: 0 : if( (unsigned)curr_elem_type >= GmshUtil::numGmshElemType ||
261 : 0 : GmshUtil::gmshElemTypes[curr_elem_type].mb_type == MBMAXTYPE )
262 : : {
263 [ # # ][ # # ]: 0 : MB_SET_ERR( MB_FILE_WRITE_ERROR,
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
264 : : "Unsupported element type " << curr_elem_type << " at line " << tokens.line_number() );
265 : : }
266 [ # # ]: 0 : tmp_conn.resize( GmshUtil::gmshElemTypes[curr_elem_type].num_nodes );
267 : : }
268 : :
269 : : // Store data from element description
270 [ # # ][ # # ]: 0 : id_list.push_back( int_data[0] );
271 [ # # ]: 0 : if( tag_data.size() > 3 )
272 [ # # ][ # # ]: 0 : part_set_list.push_back( tag_data[3] ); // it must be new format for gmsh, >= 2.5
273 : : // it could have negative partition ids, for ghost elements
274 [ # # ]: 0 : else if( tag_data.size() > 2 )
275 [ # # ][ # # ]: 0 : part_set_list.push_back( tag_data[2] ); // old format, partition id saved in 3rd tag field
276 : : else
277 [ # # ]: 0 : part_set_list.push_back( 0 );
278 [ # # ][ # # ]: 0 : geom_set_list.push_back( tag_data.size() > 1 ? tag_data[1] : 0 );
[ # # ]
279 [ # # ][ # # ]: 0 : mat_set_list.push_back( tag_data.size() > 0 ? tag_data[0] : 0 );
[ # # ]
280 : :
281 : : // Get element connectivity
282 [ # # ][ # # ]: 0 : if( !tokens.get_long_ints( tmp_conn.size(), &tmp_conn[0] ) ) return MB_FILE_WRITE_ERROR;
[ # # ]
283 : :
284 : : // Convert connectivity from IDs to handles
285 [ # # ]: 0 : for( unsigned j = 0; j < tmp_conn.size(); ++j )
286 : : {
287 [ # # ][ # # ]: 0 : std::map< long, EntityHandle >::iterator k = node_id_map.find( tmp_conn[j] );
288 [ # # ][ # # ]: 0 : if( k == node_id_map.end() )
289 [ # # ][ # # ]: 0 : { MB_SET_ERR( MB_FILE_WRITE_ERROR, "Invalid node ID at line " << tokens.line_number() ); }
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
290 [ # # ][ # # ]: 0 : connectivity.push_back( k->second );
291 : : }
292 : : } // for (num_nodes)
293 : :
294 : : // Create entity sequence for last element(s).
295 [ # # ]: 0 : if( !id_list.empty() )
296 : : {
297 : : result = create_elements( GmshUtil::gmshElemTypes[curr_elem_type], id_list, mat_set_list, geom_set_list,
298 [ # # ]: 0 : part_set_list, connectivity, file_id_tag );
299 [ # # ]: 0 : if( MB_SUCCESS != result ) return result;
300 : : }
301 : :
302 : : // Construct parent-child relations for geometric sets.
303 : : // Note: At the time this comment was written, the following
304 : : // function was not implemented.
305 [ # # ]: 0 : result = create_geometric_topology();
306 [ # # ]: 0 : geomSets.clear();
307 : 1 : return result;
308 : : }
309 : :
310 : : //! Create an element sequence
311 : 0 : ErrorCode ReadGmsh::create_elements( const GmshElemType& type, const std::vector< int >& elem_ids,
312 : : const std::vector< int >& matl_ids, const std::vector< int >& geom_ids,
313 : : const std::vector< int >& prtn_ids,
314 : : const std::vector< EntityHandle >& connectivity, const Tag* file_id_tag )
315 : : {
316 : : ErrorCode result;
317 : :
318 : : // Make sure input is consistent
319 : 0 : const unsigned long num_elem = elem_ids.size();
320 : 0 : const int node_per_elem = type.num_nodes;
321 [ # # ][ # # ]: 0 : if( matl_ids.size() != num_elem || geom_ids.size() != num_elem || prtn_ids.size() != num_elem ||
[ # # # # ]
[ # # ]
322 : 0 : connectivity.size() != num_elem * node_per_elem )
323 : 0 : return MB_FAILURE;
324 : :
325 : : // Create the element sequence
326 : : // for points, simply gather the connectivities and create the materials
327 [ # # ]: 0 : if( type.mb_type == MBVERTEX )
328 : : {
329 [ # # ]: 0 : Range elements;
330 [ # # ]: 0 : elements.insert< std::vector< EntityHandle > >( connectivity.begin(), connectivity.end() );
331 [ # # ]: 0 : result = create_sets( type.mb_type, elements, matl_ids, 0 );
332 [ # # ]: 0 : if( MB_SUCCESS != result ) return result;
333 : :
334 : 0 : return MB_SUCCESS;
335 : : }
336 : 0 : EntityHandle handle = 0;
337 : : EntityHandle* conn_array;
338 : : result =
339 [ # # ]: 0 : readMeshIface->get_element_connect( num_elem, node_per_elem, type.mb_type, MB_START_ID, handle, conn_array );
340 [ # # ]: 0 : if( MB_SUCCESS != result ) return result;
341 : :
342 : : // Copy passed element connectivity into entity sequence data.
343 [ # # ]: 0 : if( type.node_order )
344 : : {
345 [ # # ]: 0 : for( unsigned long i = 0; i < num_elem; ++i )
346 [ # # ]: 0 : for( int j = 0; j < node_per_elem; ++j )
347 [ # # ]: 0 : conn_array[i * node_per_elem + type.node_order[j]] = connectivity[i * node_per_elem + j];
348 : : }
349 : : else
350 : : {
351 [ # # ]: 0 : memcpy( conn_array, &connectivity[0], connectivity.size() * sizeof( EntityHandle ) );
352 : : }
353 : :
354 : : // Notify MOAB of the new elements
355 [ # # ]: 0 : result = readMeshIface->update_adjacencies( handle, num_elem, node_per_elem, conn_array );
356 [ # # ]: 0 : if( MB_SUCCESS != result ) return result;
357 : :
358 : : // Store element IDs
359 [ # # ]: 0 : Range elements( handle, handle + num_elem - 1 );
360 [ # # ][ # # ]: 0 : result = mdbImpl->tag_set_data( globalId, elements, &elem_ids[0] );
361 [ # # ]: 0 : if( MB_SUCCESS != result ) return result;
362 [ # # ]: 0 : if( file_id_tag )
363 : : {
364 [ # # ][ # # ]: 0 : result = mdbImpl->tag_set_data( *file_id_tag, elements, &elem_ids[0] );
365 [ # # ]: 0 : if( MB_SUCCESS != result ) return result;
366 : : }
367 : :
368 : : // Add elements to material sets
369 [ # # ]: 0 : result = create_sets( type.mb_type, elements, matl_ids, 0 );
370 [ # # ]: 0 : if( MB_SUCCESS != result ) return result;
371 : : // Add elements to geometric sets
372 [ # # ]: 0 : result = create_sets( type.mb_type, elements, geom_ids, 1 );
373 [ # # ]: 0 : if( MB_SUCCESS != result ) return result;
374 : : // Add elements to parallel partitions
375 [ # # ]: 0 : result = create_sets( type.mb_type, elements, prtn_ids, 2 );
376 [ # # ]: 0 : if( MB_SUCCESS != result ) return result;
377 : :
378 : 0 : return MB_SUCCESS;
379 : : }
380 : :
381 : : //! Add elements to sets as dictated by grouping ID in file.
382 : 0 : ErrorCode ReadGmsh::create_sets( EntityType type, const Range& elements, const std::vector< int >& set_ids,
383 : : int set_type )
384 : : {
385 : : ErrorCode result;
386 : :
387 : : // Get a unique list of set IDs
388 [ # # ]: 0 : std::set< int > ids;
389 [ # # ][ # # ]: 0 : for( std::vector< int >::const_iterator i = set_ids.begin(); i != set_ids.end(); ++i )
[ # # ]
390 [ # # ][ # # ]: 0 : ids.insert( *i );
391 : :
392 : : // No Sets?
393 [ # # ][ # # ]: 0 : if( ids.empty() || ( ids.size() == 1 && *ids.begin() == 0 ) ) return MB_SUCCESS; // no sets (all ids are zero)
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
394 : :
395 : : // Get/create tag handles
396 : : int num_tags;
397 : : Tag tag_handles[2];
398 : : int tag_val;
399 : 0 : const void* tag_values[2] = { &tag_val, NULL };
400 : :
401 [ # # # ]: 0 : switch( set_type )
402 : : {
403 : : default:
404 : 0 : return MB_FAILURE;
405 : : case 0:
406 : : case 2: {
407 [ # # ]: 0 : const char* name = set_type ? PARALLEL_PARTITION_TAG_NAME : MATERIAL_SET_TAG_NAME;
408 [ # # ]: 0 : result = mdbImpl->tag_get_handle( name, 1, MB_TYPE_INTEGER, tag_handles[0], MB_TAG_SPARSE | MB_TAG_CREAT );
409 [ # # ]: 0 : if( MB_SUCCESS != result ) return result;
410 : 0 : num_tags = 1;
411 : 0 : break;
412 : : }
413 : : case 1: {
414 : : result = mdbImpl->tag_get_handle( GEOM_DIMENSION_TAG_NAME, 1, MB_TYPE_INTEGER, tag_handles[1],
415 [ # # ]: 0 : MB_TAG_SPARSE | MB_TAG_CREAT );
416 [ # # ]: 0 : if( MB_SUCCESS != result ) return result;
417 : 0 : tag_values[1] = NULL;
418 : 0 : tag_handles[0] = globalId;
419 : 0 : num_tags = 2;
420 : 0 : break;
421 : : }
422 : : } // switch
423 : :
424 : : // For each unique set ID...
425 [ # # ][ # # ]: 0 : for( std::set< int >::iterator i = ids.begin(); i != ids.end(); ++i )
[ # # ]
426 : : {
427 : : // Skip "null" set ID
428 [ # # ][ # # ]: 0 : if( *i == 0 ) continue;
429 : :
430 : : // Get all entities with the current set ID
431 [ # # ][ # # ]: 0 : Range entities, sets;
[ # # ]
432 : 0 : std::vector< int >::const_iterator j = set_ids.begin();
433 [ # # ][ # # ]: 0 : for( Range::iterator k = elements.begin(); k != elements.end(); ++j, ++k )
[ # # ][ # # ]
[ # # ][ # # ]
434 [ # # ][ # # ]: 0 : if( *i == *j ) entities.insert( *k );
[ # # ][ # # ]
[ # # ]
435 : :
436 : : // Get set by ID
437 : : // Cppcheck warning (false positive): variable tag_val is assigned a value that is never
438 : : // used
439 [ # # ]: 0 : tag_val = *i;
440 [ # # ]: 0 : result = mdbImpl->get_entities_by_type_and_tag( 0, MBENTITYSET, tag_handles, tag_values, num_tags, sets );
441 [ # # ][ # # ]: 0 : if( MB_SUCCESS != result && MB_ENTITY_NOT_FOUND != result ) return result;
442 : :
443 : : // Don't use existing geometry sets (from some other file)
444 [ # # ]: 0 : if( 1 == set_type ) // Geometry
445 [ # # ][ # # ]: 0 : sets = intersect( sets, geomSets );
446 : :
447 : : // Get set handle
448 : : EntityHandle set;
449 : : // If no sets with ID, create one
450 [ # # ][ # # ]: 0 : if( sets.empty() )
451 : : {
452 [ # # ]: 0 : result = mdbImpl->create_meshset( MESHSET_SET, set );
453 [ # # ]: 0 : if( MB_SUCCESS != result ) return result;
454 : :
455 [ # # ][ # # ]: 0 : result = mdbImpl->tag_set_data( tag_handles[0], &set, 1, &*i );
456 [ # # ]: 0 : if( MB_SUCCESS != result ) return result;
457 : :
458 [ # # ]: 0 : if( 1 == set_type )
459 : : { // Geometry
460 [ # # ]: 0 : int dim = CN::Dimension( type );
461 [ # # ]: 0 : result = mdbImpl->tag_set_data( tag_handles[1], &set, 1, &dim );
462 [ # # ]: 0 : if( MB_SUCCESS != result ) return result;
463 [ # # ]: 0 : geomSets.insert( set );
464 : : }
465 : : }
466 : : else
467 : : {
468 [ # # ][ # # ]: 0 : set = *sets.begin();
469 [ # # ]: 0 : if( 1 == set_type )
470 : : { // Geometry
471 [ # # ]: 0 : int dim = CN::Dimension( type );
472 : : // Get dimension of set
473 : : int dim2;
474 [ # # ]: 0 : result = mdbImpl->tag_get_data( tag_handles[1], &set, 1, &dim2 );
475 [ # # ]: 0 : if( MB_SUCCESS != result ) return result;
476 : : // If we're putting geometry of a higher dimension into the
477 : : // set, increase the dimension of the set.
478 [ # # ]: 0 : if( dim > dim2 )
479 : : {
480 [ # # ]: 0 : result = mdbImpl->tag_set_data( tag_handles[1], &set, 1, &dim );
481 [ # # ]: 0 : if( MB_SUCCESS != result ) return result;
482 : : }
483 : : }
484 : : }
485 : :
486 : : // Put the mesh entities into the set
487 [ # # ]: 0 : result = mdbImpl->add_entities( set, entities );
488 [ # # ][ # # ]: 0 : if( MB_SUCCESS != result ) return result;
489 : 0 : } // for (ids)
490 : :
491 : 0 : return MB_SUCCESS;
492 : : }
493 : :
494 : : //! NOT IMPLEMENTED
495 : : //! Reconstruct parent-child relations for geometry sets from
496 : : //! mesh connectivity.
497 : 0 : ErrorCode ReadGmsh::create_geometric_topology()
498 : : {
499 [ # # ]: 0 : if( geomSets.empty() ) return MB_SUCCESS;
500 : :
501 : : // Not implemented yet
502 : 0 : geomSets.clear();
503 : 0 : return MB_SUCCESS;
504 : : }
505 : :
506 [ + - ][ + - ]: 228 : } // namespace moab
|