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 : : #ifdef WIN32
17 : : #pragma warning( disable : 4786 )
18 : : #endif
19 : :
20 : : #include "WriteUtil.hpp"
21 : : #include "moab/Core.hpp"
22 : : #include "moab/Error.hpp"
23 : : #include "SequenceManager.hpp"
24 : : #include "ElementSequence.hpp"
25 : : #include "VertexSequence.hpp"
26 : : #include "AEntityFactory.hpp"
27 : : #include "MBTagConventions.hpp"
28 : : #include "RangeSeqIntersectIter.hpp"
29 : : #include "MeshSetSequence.hpp"
30 : :
31 : : #include <sys/types.h>
32 : : #include <sys/stat.h>
33 : : #include <errno.h>
34 : : #include <assert.h>
35 : : #include <iostream>
36 : :
37 : : #ifdef WIN32
38 : : #define stat _stat
39 : : #else
40 : : #include <unistd.h>
41 : : #endif
42 : :
43 : : namespace moab
44 : : {
45 : :
46 : 94 : WriteUtil::WriteUtil( Core* mdb ) : WriteUtilIface(), mMB( mdb ) {}
47 : :
48 : : //! Check if the specified file already exists.
49 : : //! Returns MB_SUCCESS if file does not exist, MB_ALREADY_ALLOCATED
50 : : //! if file does exist, or MB_FAILURE for some other error condition.
51 : 0 : ErrorCode WriteUtil::check_doesnt_exist( const char* file_name )
52 : : {
53 : : struct stat s;
54 [ # # ][ # # ]: 0 : if( 0 == stat( file_name, &s ) ) { MB_SET_ERR( MB_ALREADY_ALLOCATED, file_name << ": file already exists" ); }
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
55 [ # # ]: 0 : else if( errno == ENOENT )
56 : 0 : return MB_SUCCESS;
57 : : else
58 : 0 : return MB_FAILURE;
59 : : }
60 : :
61 : : //! Gather all entities in the mesh, or in the sets specified
62 : 0 : ErrorCode WriteUtil::gather_entities( Range& all_ents,
63 : : /**< range in which entities are returned */
64 : : const EntityHandle* ent_sets,
65 : : /**< entity sets whose contents are to be gathered */
66 : : const int num_sets
67 : : /**< number of sets in list */
68 : : )
69 : : {
70 : 0 : ErrorCode rval = MB_SUCCESS;
71 [ # # ][ # # ]: 0 : if( !ent_sets || num_sets == 0 ) { rval = mMB->get_entities_by_handle( 0, all_ents ); }
72 : : else
73 : : {
74 [ # # ]: 0 : for( int i = 0; i < num_sets; i++ )
75 : : {
76 : 0 : ErrorCode tmp_rval = mMB->get_entities_by_handle( ent_sets[i], all_ents );
77 [ # # ]: 0 : if( MB_SUCCESS != tmp_rval ) rval = tmp_rval;
78 : : }
79 : : }
80 : :
81 : 0 : return rval;
82 : : }
83 : :
84 : 9 : ErrorCode WriteUtil::get_node_coords( const int num_arrays, const int num_nodes, const Range& entities, Tag node_id_tag,
85 : : const int start_node_id, std::vector< double* >& arrays )
86 : : {
87 : : // Check the data coming into the function
88 : : // Dimension should be proper
89 [ + - ][ - + ]: 9 : if( num_arrays < 1 || num_arrays > 3 ) return MB_FAILURE;
90 : :
91 : : // There should be some entities
92 : : // if (entities.empty())
93 : : // return MB_FAILURE;
94 : : // The above necessitates annoying special cases for files
95 : : // w/out vertices (e.g. a kD-tree). Return NULL array
96 : : // pointers instead. - kraftcheck, 3-14-08
97 [ + - ][ - + ]: 9 : if( entities.empty() )
98 : : {
99 : 0 : arrays.clear();
100 [ # # ]: 0 : arrays.resize( num_arrays, NULL );
101 : 0 : return MB_SUCCESS;
102 : : }
103 : :
104 : : // Memory should already be allocated for us
105 : 9 : int tmp_num_arrays = 0;
106 [ + + ]: 36 : for( unsigned int i = 0; i < 3; i++ )
107 [ + - ][ + - ]: 27 : if( i + 1 <= arrays.size() && NULL != arrays[i] ) tmp_num_arrays++;
[ + - ][ + - ]
108 [ - + ]: 9 : if( 0 == tmp_num_arrays ) return MB_FAILURE;
109 : :
110 : : // Get coordinate data
111 [ + - ][ + - ]: 9 : ErrorCode result = mMB->get_coords( entities, num_arrays < 1 || arrays.size() < 1 ? NULL : arrays[0],
112 [ + - ][ + - ]: 9 : num_arrays < 2 || arrays.size() < 2 ? NULL : arrays[1],
113 [ + - ][ + - ]: 27 : num_arrays < 3 || arrays.size() < 3 ? NULL : arrays[2] );
[ + - ][ + - ]
[ + - ][ + - ]
114 : :
115 [ + - ][ - + ]: 9 : if( 0 == node_id_tag || MB_SUCCESS != result ) return result;
116 : :
117 : : // Now assign tags
118 [ + - ]: 9 : std::vector< int > ids( num_nodes );
119 : 9 : int node_id = start_node_id;
120 [ + + ]: 2345551 : for( int i = 0; i < num_nodes; i++ )
121 [ + - ]: 2345542 : ids[i] = node_id++;
122 [ + - ][ + - ]: 9 : result = mMB->tag_set_data( node_id_tag, entities, &ids[0] );
123 : :
124 : 9 : return result;
125 : : }
126 : :
127 : 38 : ErrorCode WriteUtil::get_node_coords( const int which_array, /* 0->X, 1->Y, 2->Z, -1->all */
128 : : Range::const_iterator iter, const Range::const_iterator& end,
129 : : const size_t output_array_len, double* const output_array )
130 : : {
131 : : // Check the data coming into the function
132 : : // Dimension should be proper
133 [ + - ][ - + ]: 38 : if( which_array < -1 || which_array > 2 ) return MB_FAILURE;
134 : :
135 : : // There should be some entities
136 [ + - ][ - + ]: 38 : if( iter == end ) return MB_FAILURE;
137 : :
138 : : // Memory should already be allocated for us
139 [ + - ][ - + ]: 38 : if( NULL == output_array || 0 == output_array_len ) return MB_FAILURE;
140 : :
141 : : // Sequence iterators
142 [ + - ][ + - ]: 38 : TypeSequenceManager::iterator seq_iter, seq_end;
143 [ + - ][ + - ]: 38 : seq_iter = mMB->sequence_manager()->entity_map( MBVERTEX ).begin();
[ + - ]
144 [ + - ][ + - ]: 38 : seq_end = mMB->sequence_manager()->entity_map( MBVERTEX ).end();
[ + - ]
145 : :
146 : : // Loop over range, getting coordinate value
147 : 38 : double* output_iter = output_array;
148 : 38 : double* const output_end = output_array + output_array_len;
149 [ + - ][ + + ]: 458 : while( iter != end )
150 : : {
151 : : // Find the sequence containing the current handle
152 [ + - ][ + - ]: 437 : while( seq_iter != seq_end && ( *seq_iter )->end_handle() < *iter )
[ + - ][ + - ]
[ + - ][ + + ]
[ + + ]
153 [ + - ]: 17 : ++seq_iter;
154 [ + - ][ + - ]: 420 : if( seq_iter == seq_end || *iter < ( *seq_iter )->start_handle() ) return MB_FAILURE;
[ + - ][ + - ]
[ + - ][ - + ]
[ - + ]
155 : :
156 : : // Determine how much of the sequence we want.
157 [ + - ]: 420 : Range::pair_iterator pair( iter );
158 : 420 : Range::const_iterator prev( end );
159 [ + - ]: 420 : --prev;
160 [ + - ]: 420 : EntityHandle range_end = pair->second;
161 [ + - ][ + - ]: 420 : EntityHandle sequence_end = ( *seq_iter )->end_handle();
162 [ + + ]: 420 : EntityHandle end_handle = range_end > sequence_end ? sequence_end : range_end;
163 [ + - ][ - + ]: 420 : if( end_handle > *prev ) end_handle = *prev;
[ # # ]
164 [ + - ]: 420 : EntityHandle count = end_handle - *iter + 1;
165 : :
166 : : // Get offset in sequence to start at
167 [ + - ][ + - ]: 420 : assert( *iter >= ( *seq_iter )->start_handle() );
[ + - ][ - + ]
168 [ + - ][ + - ]: 420 : EntityHandle offset = *iter - ( *seq_iter )->start_handle();
[ + - ]
169 : :
170 : : // Get coordinate arrays from sequence
171 : : double* coord_array[3];
172 [ + - ]: 420 : static_cast< VertexSequence* >( *seq_iter )
173 [ + - ]: 420 : ->get_coordinate_arrays( coord_array[0], coord_array[1], coord_array[2] );
174 : :
175 : : // Copy data to output buffer
176 [ - + ]: 420 : if( -1 != which_array )
177 : : {
178 [ # # ]: 0 : if( output_iter + count > output_end ) return MB_FAILURE;
179 : 0 : memcpy( output_iter, coord_array[which_array] + offset, count * sizeof( double ) );
180 : 0 : output_iter += count;
181 : : }
182 : : else
183 : : {
184 [ - + ]: 420 : if( output_iter + 3 * count > output_end ) return MB_FAILURE;
185 [ + + ]: 15165 : for( unsigned int i = 0; i < count; i++ )
186 : : {
187 : 14745 : *output_iter = coord_array[0][i + offset];
188 : 14745 : output_iter++;
189 : 14745 : *output_iter = coord_array[1][i + offset];
190 : 14745 : output_iter++;
191 : 14745 : *output_iter = coord_array[2][i + offset];
192 : 14745 : output_iter++;
193 : : }
194 : : }
195 : :
196 : : // Iterate
197 [ + - ]: 420 : iter += count;
198 : : }
199 : :
200 : 38 : return MB_SUCCESS;
201 : : }
202 : :
203 : 25 : ErrorCode WriteUtil::get_element_connect( const int num_elements, const int verts_per_element, Tag node_id_tag,
204 : : const Range& elements, Tag element_id_tag, int start_element_id,
205 : : int* element_array, bool add_sizes )
206 : : {
207 : : // Check the data we got
208 [ - + ]: 25 : if( num_elements < 1 ) return MB_FAILURE;
209 [ - + ]: 25 : if( verts_per_element < 1 ) return MB_FAILURE;
210 [ + - ][ - + ]: 25 : if( elements.empty() ) return MB_FAILURE;
211 [ - + ]: 25 : if( !element_array ) return MB_FAILURE;
212 : :
213 [ + - ]: 25 : Range::const_iterator range_iter = elements.begin();
214 [ + - ]: 25 : Range::const_iterator range_iter_end = elements.end();
215 : :
216 [ + - ][ + - ]: 25 : TypeSequenceManager::iterator seq_iter, seq_iter_end;
217 [ + - ][ + - ]: 25 : EntityType current_type = TYPE_FROM_HANDLE( *range_iter );
218 : :
219 [ + - ][ + - ]: 25 : seq_iter = mMB->sequence_manager()->entity_map( current_type ).begin();
[ + - ]
220 [ + - ][ + - ]: 25 : seq_iter_end = mMB->sequence_manager()->entity_map( current_type ).end();
[ + - ]
221 : :
222 : : // Let's find the entity sequence which holds the first entity
223 : 25 : TypeSequenceManager::iterator seq_iter_lookahead = seq_iter;
224 [ + - ]: 25 : ++seq_iter_lookahead;
225 [ + - ][ + + ]: 25 : for( ; seq_iter_lookahead != seq_iter_end && ( *seq_iter_lookahead )->start_handle() < *range_iter; )
[ + - ][ + - ]
[ + - ][ - + ]
[ - + ]
226 : : {
227 [ # # ]: 0 : ++seq_iter;
228 [ # # ]: 0 : ++seq_iter_lookahead;
229 : : }
230 : :
231 : : // A look ahead iterator
232 : 25 : Range::const_iterator range_iter_lookahead = range_iter;
233 : :
234 : : // Our main loop
235 [ + - ][ + + ]: 88 : for( ; range_iter != range_iter_end && seq_iter != seq_iter_end; /* ++ is handled in loop*/ )
[ + - ][ + - ]
[ + + ]
236 : : {
237 : : // Find a range that fits in the current entity sequence
238 [ + - ][ + - ]: 512303 : for( ; range_iter_lookahead != range_iter_end && *range_iter_lookahead <= ( *seq_iter )->end_handle();
[ + + ][ + - ]
[ + - ][ + - ]
[ + + ][ + + ]
239 : : ++range_iter_lookahead )
240 : : {}
241 : :
242 [ + - ][ + - ]: 63 : if( current_type != TYPE_FROM_HANDLE( *range_iter ) )
[ - + ]
243 : : {
244 [ # # ][ # # ]: 0 : current_type = TYPE_FROM_HANDLE( *range_iter );
245 [ # # ][ # # ]: 0 : seq_iter = mMB->sequence_manager()->entity_map( current_type ).begin();
[ # # ]
246 [ # # ][ # # ]: 0 : seq_iter_end = mMB->sequence_manager()->entity_map( current_type ).end();
[ # # ]
247 : :
248 : : // Let's find the entity sequence which holds the first entity of this type
249 : 0 : TypeSequenceManager::const_iterator seq_iter_lookahead2 = seq_iter;
250 [ # # ]: 0 : ++seq_iter_lookahead2;
251 [ # # ][ # # ]: 0 : for( ; seq_iter_lookahead2 != seq_iter_end && ( *seq_iter_lookahead2 )->start_handle() < *range_iter; )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
252 : : {
253 [ # # ]: 0 : ++seq_iter;
254 [ # # ]: 0 : ++seq_iter_lookahead2;
255 : : }
256 : : }
257 : :
258 [ + - ][ + - ]: 63 : int i = static_cast< ElementSequence* >( *seq_iter )->nodes_per_element();
259 : :
260 : : // Get the connectivity array
261 [ + - ][ + - ]: 63 : EntityHandle* conn_array = static_cast< ElementSequence* >( *seq_iter )->get_connectivity_array();
262 : :
263 [ + - ][ + - ]: 63 : EntityHandle start_handle = ( *seq_iter )->start_handle();
264 : :
265 [ + - ][ + - ]: 512303 : for( Range::const_iterator tmp_iter = range_iter; tmp_iter != range_iter_lookahead; ++tmp_iter )
[ + + ]
266 : : {
267 : : // Set the element id tag
268 [ + - ][ + - ]: 512240 : mMB->tag_set_data( element_id_tag, &*tmp_iter, 1, &start_element_id );
269 : 512240 : ++start_element_id;
270 : :
271 [ - + ]: 512240 : if( add_sizes ) *element_array++ = i;
272 : :
273 : : // For each node
274 [ + + ]: 4610606 : for( int j = 0; j < i; j++ )
275 : : {
276 [ + - ]: 4098366 : EntityHandle node = *( conn_array + j + i * ( *tmp_iter - start_handle ) );
277 [ + - ]: 4098366 : mMB->tag_get_data( node_id_tag, &node, 1, element_array );
278 : 4098366 : element_array++;
279 : : }
280 : : }
281 : :
282 : : // Go to the next entity sequence
283 [ + - ]: 63 : ++seq_iter;
284 : : // Start with the next entities
285 : 63 : range_iter = range_iter_lookahead;
286 : : }
287 : :
288 : 25 : return MB_SUCCESS;
289 : : }
290 : :
291 : 0 : ErrorCode WriteUtil::get_element_connect( Range::const_iterator iter, const Range::const_iterator& end,
292 : : const int vertices_per_elem, Tag node_id_tag, const size_t elem_array_size,
293 : : int* const element_array, bool add_sizes )
294 : : {
295 : : // Check the data we got
296 [ # # ][ # # ]: 0 : if( iter == end ) return MB_FAILURE;
297 [ # # ]: 0 : if( vertices_per_elem < 1 ) return MB_FAILURE;
298 [ # # ][ # # ]: 0 : if( !element_array || elem_array_size < (unsigned)vertices_per_elem ) return MB_FAILURE;
299 : :
300 : : // Sequence iterators
301 [ # # ][ # # ]: 0 : TypeSequenceManager::const_iterator seq_iter, seq_end;
302 : :
303 : : // loop over range, getting coordinate value
304 : 0 : EntityType current_type = MBMAXTYPE;
305 : 0 : int* output_iter = element_array;
306 : 0 : int* const output_end = element_array + elem_array_size;
307 [ # # ][ # # ]: 0 : while( iter != end )
308 : : {
309 : : // Make sure we have the right sequence list (and get the sequence
310 : : // list for the first iteration.)
311 [ # # ][ # # ]: 0 : EntityType type = TYPE_FROM_HANDLE( *iter );
312 [ # # ]: 0 : if( type != current_type )
313 : : {
314 [ # # ][ # # ]: 0 : if( type >= MBENTITYSET || type < MBEDGE ) return MB_FAILURE;
315 [ # # ][ # # ]: 0 : seq_iter = mMB->sequence_manager()->entity_map( type ).begin();
[ # # ]
316 [ # # ][ # # ]: 0 : seq_end = mMB->sequence_manager()->entity_map( type ).end();
[ # # ]
317 : 0 : current_type = type;
318 : : }
319 : :
320 : : // Find the sequence containing the current handle
321 [ # # ][ # # ]: 0 : while( seq_iter != seq_end && ( *seq_iter )->end_handle() < *iter )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
322 [ # # ]: 0 : ++seq_iter;
323 [ # # ][ # # ]: 0 : if( seq_iter == seq_end || *iter < ( *seq_iter )->start_handle() ) return MB_FAILURE;
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
324 : :
325 : : // Get the connectivity array
326 : 0 : EntityHandle* conn_array = NULL;
327 [ # # ][ # # ]: 0 : int conn_size = static_cast< ElementSequence* >( *seq_iter )->nodes_per_element();
328 [ # # ][ # # ]: 0 : conn_array = static_cast< ElementSequence* >( *seq_iter )->get_connectivity_array();
329 : :
330 : : // Determine how much of the sequence we want.
331 [ # # ]: 0 : Range::pair_iterator pair( iter );
332 : 0 : Range::const_iterator prev( end );
333 [ # # ]: 0 : --prev;
334 [ # # ]: 0 : EntityHandle range_end = pair->second;
335 [ # # ][ # # ]: 0 : EntityHandle sequence_end = ( *seq_iter )->end_handle();
336 [ # # ]: 0 : EntityHandle end_handle = range_end > sequence_end ? sequence_end : range_end;
337 [ # # ][ # # ]: 0 : if( end_handle > *prev ) end_handle = *prev;
[ # # ]
338 [ # # ]: 0 : EntityHandle count = end_handle - *iter + 1;
339 : :
340 : : // Get offset in sequence to start at
341 [ # # ][ # # ]: 0 : assert( *iter >= ( *seq_iter )->start_handle() );
[ # # ][ # # ]
342 [ # # ][ # # ]: 0 : EntityHandle offset = *iter - ( *seq_iter )->start_handle();
[ # # ]
343 : :
344 : : // Make sure sufficient space in output array
345 [ # # ][ # # ]: 0 : if( ( !add_sizes && output_iter + ( count * conn_size ) > output_end ) ||
[ # # ]
346 [ # # ]: 0 : ( add_sizes && output_iter + ( count * ( conn_size + 1 ) ) > output_end ) )
347 : 0 : return MB_FAILURE;
348 : :
349 : : // If the nodes per element match, do in one call
350 : 0 : conn_array += ( conn_size * offset );
351 [ # # ][ # # ]: 0 : if( vertices_per_elem == conn_size && !add_sizes )
352 : : {
353 [ # # ]: 0 : ErrorCode rval = mMB->tag_get_data( node_id_tag, conn_array, count * conn_size, output_iter );
354 [ # # ]: 0 : if( MB_SUCCESS != rval ) return rval;
355 : :
356 : 0 : output_iter += count * conn_size;
357 : : }
358 : : // Otherwise need to do one at a time
359 : : else
360 : : {
361 [ # # ]: 0 : int min = vertices_per_elem > conn_size ? conn_size : vertices_per_elem;
362 [ # # ]: 0 : for( EntityHandle i = 0; i < count; ++i )
363 : : {
364 : 0 : *output_iter++ = min;
365 [ # # ]: 0 : ErrorCode rval = mMB->tag_get_data( node_id_tag, conn_array, min, output_iter );
366 [ # # ]: 0 : if( MB_SUCCESS != rval ) return rval;
367 : :
368 : 0 : output_iter += min;
369 : 0 : conn_array += conn_size;
370 : :
371 [ # # ]: 0 : if( vertices_per_elem > conn_size )
372 : : { // Need to pad
373 : 0 : memset( output_iter, 0, sizeof( int ) * ( vertices_per_elem - conn_size ) );
374 : 0 : output_iter += ( vertices_per_elem - conn_size );
375 : : }
376 : : }
377 : : }
378 : :
379 [ # # ]: 0 : iter += count;
380 : : }
381 : :
382 : 0 : return MB_SUCCESS;
383 : : }
384 : :
385 : 52 : ErrorCode WriteUtil::get_element_connect( Range::const_iterator iter, const Range::const_iterator& end,
386 : : const int vertices_per_elem, const size_t elem_array_size,
387 : : EntityHandle* const element_array )
388 : : {
389 : : // Check the data we got
390 [ + - ][ - + ]: 52 : if( iter == end ) return MB_FAILURE;
391 [ - + ]: 52 : if( vertices_per_elem < 1 ) return MB_FAILURE;
392 [ + - ][ - + ]: 52 : if( !element_array || elem_array_size < (unsigned)vertices_per_elem ) return MB_FAILURE;
393 : :
394 : : // Sequence iterators
395 [ + - ][ + - ]: 52 : TypeSequenceManager::const_iterator seq_iter, seq_end;
396 : :
397 : : // Loop over range, getting coordinate value
398 : 52 : EntityType current_type = MBMAXTYPE;
399 : 52 : EntityHandle* output_iter = element_array;
400 : 52 : EntityHandle* const output_end = element_array + elem_array_size;
401 [ + - ][ + + ]: 2473 : while( iter != end )
402 : : {
403 : : // Make sure we have the right sequence list (and get the sequence
404 : : // list for the first iteration.)
405 [ + - ][ + - ]: 2421 : EntityType type = TYPE_FROM_HANDLE( *iter );
406 [ + + ]: 2421 : if( type != current_type )
407 : : {
408 [ + - ][ - + ]: 52 : if( type >= MBENTITYSET || type < MBEDGE ) return MB_FAILURE;
409 [ + - ][ + - ]: 52 : seq_iter = mMB->sequence_manager()->entity_map( type ).begin();
[ + - ]
410 [ + - ][ + - ]: 52 : seq_end = mMB->sequence_manager()->entity_map( type ).end();
[ + - ]
411 : 52 : current_type = type;
412 : : }
413 : :
414 : : // Find the sequence containing the current handle
415 [ + - ][ + - ]: 3345 : while( seq_iter != seq_end && ( *seq_iter )->end_handle() < *iter )
[ + - ][ + - ]
[ + - ][ + + ]
[ + + ]
416 [ + - ]: 924 : ++seq_iter;
417 [ + - ][ + - ]: 2421 : if( seq_iter == seq_end || *iter < ( *seq_iter )->start_handle() ) return MB_FAILURE;
[ + - ][ + - ]
[ + - ][ - + ]
[ - + ]
418 : :
419 : : // Get the connectivity array
420 : 2421 : EntityHandle* conn_array = NULL;
421 [ + - ][ + - ]: 2421 : int conn_size = static_cast< ElementSequence* >( *seq_iter )->nodes_per_element();
422 [ - + ]: 2421 : if( conn_size != vertices_per_elem ) return MB_FAILURE;
423 [ + - ][ + - ]: 2421 : conn_array = static_cast< ElementSequence* >( *seq_iter )->get_connectivity_array();
424 : :
425 : : // Determine how much of the sequence we want.
426 [ + - ]: 2421 : Range::pair_iterator pair( iter );
427 : 2421 : Range::const_iterator prev( end );
428 [ + - ]: 2421 : --prev;
429 [ + - ]: 2421 : EntityHandle range_end = pair->second;
430 [ + - ][ + - ]: 2421 : EntityHandle sequence_end = ( *seq_iter )->end_handle();
431 [ + + ]: 2421 : EntityHandle end_handle = range_end > sequence_end ? sequence_end : range_end;
432 [ + - ][ - + ]: 2421 : if( end_handle > *prev ) end_handle = *prev;
[ # # ]
433 [ + - ]: 2421 : EntityHandle count = end_handle - *iter + 1;
434 : :
435 : : // Get offset in sequence to start at
436 [ + - ][ + - ]: 2421 : assert( *iter >= ( *seq_iter )->start_handle() );
[ + - ][ - + ]
437 [ + - ][ + - ]: 2421 : EntityHandle offset = *iter - ( *seq_iter )->start_handle();
[ + - ]
438 : :
439 : : // Make sure sufficient space in output array
440 [ - + ]: 2421 : if( output_iter + ( count * conn_size ) > output_end ) return MB_FAILURE;
441 : :
442 [ - + ]: 2421 : if( conn_array == NULL )
443 : : { // If it is structured mesh
444 : : ErrorCode rval;
445 : 0 : int temp_buff_size = conn_size * sizeof( EntityHandle );
446 [ # # ]: 0 : for( unsigned i = 0; i < count; i++ )
447 : : { // Copy connectivity element by element
448 [ # # ]: 0 : std::vector< EntityHandle > connect;
449 [ # # ][ # # ]: 0 : rval = static_cast< ElementSequence* >( *seq_iter )->get_connectivity( *iter, connect );
[ # # ]
450 [ # # ]: 0 : if( MB_SUCCESS != rval ) { return rval; }
451 [ # # ]: 0 : memcpy( output_iter, &connect[0], temp_buff_size );
452 : 0 : output_iter += conn_size;
453 [ # # ][ # # ]: 0 : ++iter;
454 : 0 : }
455 : : }
456 : : else
457 : : {
458 : : // Copy connectivity into output array
459 : 2421 : conn_array += ( conn_size * offset );
460 : 2421 : memcpy( output_iter, conn_array, count * conn_size * sizeof( EntityHandle ) );
461 : 2421 : output_iter += count * conn_size;
462 [ + - ]: 2421 : iter += count;
463 : : }
464 : : }
465 : :
466 : 52 : return MB_SUCCESS;
467 : : }
468 : :
469 : 0 : ErrorCode WriteUtil::get_poly_connect_size( Range::const_iterator /* begin */, const Range::const_iterator& /* end */,
470 : : int& /* connectivity_size */ )
471 : : {
472 : 0 : return MB_NOT_IMPLEMENTED;
473 : : }
474 : :
475 : 0 : ErrorCode WriteUtil::get_poly_connect( Range::const_iterator& /* iter */, const Range::const_iterator& /* end */,
476 : : const Tag /* node_id_tag */, size_t& /* handle_array_len */,
477 : : int* const /* handle_array */, size_t& /* index_array_len */,
478 : : int* const /* index_array */, int& /* index_offset */ )
479 : : {
480 : 0 : return MB_NOT_IMPLEMENTED;
481 : : }
482 : :
483 : 100 : ErrorCode WriteUtil::gather_nodes_from_elements( const Range& elements, const Tag node_bit_mark_tag, Range& nodes )
484 : : {
485 : 100 : bool printed_warning = false;
486 : :
487 [ + - ][ + + ]: 100 : if( elements.empty() ) return MB_SUCCESS;
488 : :
489 [ + - ][ + - ]: 55 : if( TYPE_FROM_HANDLE( elements.front() ) <= MBVERTEX || TYPE_FROM_HANDLE( elements.back() ) >= MBENTITYSET )
[ + - ][ + - ]
[ + - ][ - + ]
[ - + ]
490 : 0 : return MB_TYPE_OUT_OF_RANGE;
491 : :
492 : : // See if we need to use our own marking tag
493 : 55 : Tag exporting_nodes_tag = 0;
494 [ + + ]: 55 : if( node_bit_mark_tag )
495 : 25 : exporting_nodes_tag = node_bit_mark_tag;
496 : : else
497 : : {
498 [ + - ]: 30 : mMB->tag_get_handle( "__MBWriteUtil::exporting_nodes", 1, MB_TYPE_BIT, exporting_nodes_tag, MB_TAG_CREAT );
499 : : }
500 : :
501 : : // The x,y,z tag handles we need
502 : 55 : EntityHandle lower_bound = ~0, upper_bound = 0;
503 : :
504 [ + - ]: 55 : std::vector< EntityHandle > tmp_conn;
505 : :
506 [ + - ][ + - ]: 55 : RangeSeqIntersectIter iter( mMB->sequence_manager() );
507 [ + - ][ + - ]: 2355 : for( ErrorCode rval = iter.init( elements.begin(), elements.end() ); MB_FAILURE != rval; rval = iter.step() )
[ + - ][ + - ]
[ + + ]
508 : : {
509 [ - + ]: 2300 : if( MB_ENTITY_NOT_FOUND == rval )
510 : : {
511 [ # # ]: 0 : if( !printed_warning )
512 : : {
513 [ # # ][ # # ]: 0 : std::cerr << "Warning: ignoring invalid element handle(s) in gather_nodes_from_elements" << std::endl;
514 : 0 : printed_warning = true;
515 : : }
516 : 0 : continue;
517 : : }
518 : :
519 [ + - ]: 2300 : ElementSequence* seq = static_cast< ElementSequence* >( iter.get_sequence() );
520 : :
521 : : // Get the connectivity array
522 [ + - ]: 2300 : const EntityHandle* conn_array = seq->get_connectivity_array();
523 : :
524 : : // If unstructured mesh
525 [ + - ][ + - ]: 2300 : if( conn_array && mMB->type_from_handle( iter.get_start_handle() ) != MBPOLYHEDRON )
[ + - ][ + - ]
[ + - ]
526 : : {
527 [ + - ][ + - ]: 2300 : assert( iter.get_start_handle() >= seq->start_handle() );
[ - + ]
528 [ + - ][ + - ]: 2300 : assert( iter.get_end_handle() <= seq->end_handle() );
[ - + ]
529 [ + - ][ + - ]: 2300 : const EntityHandle offset = iter.get_start_handle() - seq->start_handle();
530 [ + - ][ + - ]: 2300 : const EntityHandle num_elem = iter.get_end_handle() - iter.get_start_handle() + 1;
531 : :
532 [ + - ]: 2300 : conn_array += offset * seq->nodes_per_element();
533 [ + - ]: 2300 : const EntityHandle num_node = num_elem * seq->nodes_per_element();
534 : :
535 : : // For each node
536 [ + + ]: 4170090 : for( EntityHandle j = 0; j < num_node; j++ )
537 : : {
538 : 4167790 : EntityHandle node = conn_array[j];
539 [ + + ]: 4167790 : if( node < lower_bound ) lower_bound = node;
540 [ + + ]: 4167790 : if( node > upper_bound ) upper_bound = node;
541 : 4167790 : unsigned char bit = 0x1;
542 [ + - ]: 4167790 : rval = mMB->tag_set_data( exporting_nodes_tag, &node, 1, &bit );
543 [ - + ]: 4167790 : assert( MB_SUCCESS == rval );
544 [ - + ]: 4167790 : if( MB_SUCCESS != rval ) return rval;
545 : : }
546 : : }
547 : : // Polyhedra
548 [ # # ][ # # ]: 0 : else if( conn_array && mMB->type_from_handle( iter.get_start_handle() ) == MBPOLYHEDRON )
[ # # ][ # # ]
[ # # ]
549 : : {
550 [ # # ][ # # ]: 0 : assert( iter.get_start_handle() >= seq->start_handle() );
[ # # ]
551 [ # # ][ # # ]: 0 : assert( iter.get_end_handle() <= seq->end_handle() );
[ # # ]
552 [ # # ][ # # ]: 0 : const EntityHandle offset = iter.get_start_handle() - seq->start_handle();
553 [ # # ][ # # ]: 0 : const EntityHandle num_elem = iter.get_end_handle() - iter.get_start_handle() + 1;
554 : :
555 [ # # ]: 0 : conn_array += offset * seq->nodes_per_element();
556 [ # # ]: 0 : int num_face = num_elem * seq->nodes_per_element();
557 : :
558 : : // For each node
559 [ # # ]: 0 : for( int j = 0; j < num_face; j++ )
560 : : {
561 : 0 : const EntityHandle* face_conn = NULL;
562 : 0 : int face_num_conn = 0;
563 [ # # ]: 0 : rval = mMB->get_connectivity( conn_array[j], face_conn, face_num_conn, false );
564 [ # # ]: 0 : if( MB_SUCCESS != rval ) return rval;
565 [ # # ]: 0 : for( int k = 0; k < face_num_conn; k++ )
566 : : {
567 : 0 : EntityHandle node = face_conn[k];
568 [ # # ]: 0 : if( node < lower_bound ) lower_bound = node;
569 [ # # ]: 0 : if( node > upper_bound ) upper_bound = node;
570 : 0 : unsigned char bit = 0x1;
571 [ # # ]: 0 : rval = mMB->tag_set_data( exporting_nodes_tag, &node, 1, &bit );
572 [ # # ]: 0 : assert( MB_SUCCESS == rval );
573 [ # # ]: 0 : if( MB_SUCCESS != rval ) return rval;
574 : : }
575 : : }
576 : : }
577 : : // Structured mesh
578 : : else
579 : : {
580 [ # # ]: 0 : EntityHandle end_h = iter.get_end_handle() + 1;
581 [ # # ][ # # ]: 0 : for( EntityHandle h = iter.get_start_handle(); h < end_h; ++h )
582 : : {
583 : 0 : tmp_conn.clear();
584 [ # # ]: 0 : rval = seq->get_connectivity( h, tmp_conn, false );
585 [ # # ]: 0 : if( MB_SUCCESS != rval )
586 : : {
587 [ # # ][ # # ]: 0 : if( node_bit_mark_tag == 0 ) mMB->tag_delete( exporting_nodes_tag );
588 : 0 : return rval;
589 : : }
590 : :
591 : : // For each node
592 [ # # ]: 0 : for( size_t j = 0; j < tmp_conn.size(); j++ )
593 : : {
594 [ # # ]: 0 : EntityHandle node = tmp_conn[j];
595 [ # # ]: 0 : if( node < lower_bound ) lower_bound = node;
596 [ # # ]: 0 : if( node > upper_bound ) upper_bound = node;
597 : 0 : unsigned char bit = 0x1;
598 [ # # ]: 0 : mMB->tag_set_data( exporting_nodes_tag, &node, 1, &bit );
599 : : }
600 : : }
601 : : }
602 : : }
603 : :
604 : : // We can get a REALLY long loop if lower_bound is zero
605 [ - + ]: 55 : assert( lower_bound != 0 );
606 : : // Gather up all the nodes
607 [ + + ]: 2373824 : for( ; upper_bound >= lower_bound; --upper_bound )
608 : : {
609 : 2373769 : unsigned char node_marked = 0;
610 [ + - ]: 2373769 : mMB->tag_get_data( exporting_nodes_tag, &upper_bound, 1, &node_marked );
611 [ + + ][ + - ]: 2373769 : if( node_marked == 0x1 ) nodes.insert( upper_bound );
612 : : }
613 : :
614 : : // Clean up our own marking tag
615 [ + + ][ + - ]: 55 : if( node_bit_mark_tag == 0 ) mMB->tag_delete( exporting_nodes_tag );
616 : :
617 : 100 : return MB_SUCCESS;
618 : : }
619 : :
620 : : //! Assign ids to input elements starting with start_id, written to id_tag
621 : : //! if zero, assigns to GLOBAL_ID_TAG_NAME
622 : 0 : ErrorCode WriteUtil::assign_ids( Range& elements, Tag id_tag, const int start_id )
623 : : {
624 : : ErrorCode result;
625 [ # # ]: 0 : if( 0 == id_tag )
626 : : {
627 : : // Get the global id tag
628 [ # # ]: 0 : id_tag = mMB->globalId_tag();
629 : : }
630 : :
631 : : // Now assign the ids
632 : : int i;
633 [ # # ]: 0 : Range::iterator rit;
634 : : ErrorCode tmp_result;
635 : 0 : result = MB_SUCCESS;
636 [ # # ][ # # ]: 0 : for( i = start_id, rit = elements.begin(); rit != elements.end(); ++rit, i++ )
[ # # ][ # # ]
[ # # ]
637 : : {
638 [ # # ][ # # ]: 0 : tmp_result = mMB->tag_set_data( id_tag, &( *rit ), 1, &i );
639 [ # # ]: 0 : if( MB_SUCCESS != tmp_result ) result = tmp_result;
640 : : }
641 : :
642 : 0 : return result;
643 : : }
644 : :
645 : 0 : ErrorCode WriteUtil::get_adjacencies( EntityHandle entity, Tag id_tag, std::vector< int >& adj )
646 : : {
647 : : ErrorCode rval;
648 : : const EntityHandle* adj_array;
649 : : int num_adj, id;
650 : :
651 : : // Get handles of adjacent entities
652 [ # # ][ # # ]: 0 : rval = mMB->a_entity_factory()->get_adjacencies( entity, adj_array, num_adj );
653 [ # # ]: 0 : if( MB_SUCCESS != rval )
654 : : {
655 : 0 : adj.clear();
656 : 0 : return rval;
657 : : }
658 : :
659 : : // Append IDs of adjacent entities -- skip meshsets
660 [ # # ]: 0 : adj.resize( num_adj ); // Pre-allocate space
661 : 0 : adj.clear(); // Clear used space
662 : :
663 : 0 : const EntityHandle* const end = adj_array + num_adj;
664 [ # # ]: 0 : for( const EntityHandle* iter = adj_array; iter != end; ++iter )
665 : : {
666 [ # # ][ # # ]: 0 : if( TYPE_FROM_HANDLE( *iter ) != MBENTITYSET )
667 : : {
668 [ # # ]: 0 : rval = mMB->tag_get_data( id_tag, iter, 1, &id );
669 [ # # ]: 0 : if( MB_SUCCESS != rval ) return rval;
670 [ # # ]: 0 : adj.push_back( id );
671 : : }
672 : : }
673 : :
674 : 0 : return MB_SUCCESS;
675 : : }
676 : :
677 : 37080 : ErrorCode WriteUtil::get_adjacencies( EntityHandle entity, const EntityHandle*& adj_array, int& num_adj )
678 : : {
679 : 37080 : return mMB->a_entity_factory()->get_adjacencies( entity, adj_array, num_adj );
680 : : }
681 : :
682 : 47 : ErrorCode WriteUtil::get_tag_list( std::vector< Tag >& result_list, const Tag* user_tag_list, int user_tag_list_length,
683 : : bool include_variable_length_tags )
684 : : {
685 : : ErrorCode rval;
686 : :
687 [ - + ]: 47 : if( user_tag_list )
688 : : {
689 : 0 : result_list.clear();
690 : 0 : result_list.reserve( user_tag_list_length );
691 [ # # ]: 0 : for( int i = 0; i < user_tag_list_length; ++i )
692 : : {
693 [ # # ]: 0 : std::string name;
694 [ # # ][ # # ]: 0 : rval = mMB->tag_get_name( user_tag_list[i], name );MB_CHK_SET_ERR( rval, "Error " << (int)rval << " getting name for tag (Invalid input tag handle?)" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
695 : :
696 [ # # ][ # # ]: 0 : if( name.empty() ) { MB_SET_ERR( MB_TAG_NOT_FOUND, "Explicit request to save anonymous tag" ); }
[ # # ][ # # ]
[ # # ][ # # ]
697 : :
698 : : int size;
699 [ # # ][ # # ]: 0 : if( !include_variable_length_tags &&
[ # # ]
700 [ # # ]: 0 : MB_VARIABLE_DATA_LENGTH == mMB->tag_get_length( user_tag_list[i], size ) )
701 : : {
702 [ # # ][ # # ]: 0 : MB_SET_ERR( MB_TYPE_OUT_OF_RANGE, "File format cannot store variable-length tag: \"" << name << "\"" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
703 : : }
704 : :
705 [ # # ][ # # ]: 0 : result_list.push_back( user_tag_list[i] );
706 : 0 : }
707 : : }
708 : : else
709 : : {
710 [ + - ]: 47 : std::vector< Tag > temp_list;
711 [ + - ][ - + ]: 47 : rval = mMB->tag_get_tags( temp_list );MB_CHK_SET_ERR( rval, "Interface::tag_get_tags failed" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
712 : :
713 : 47 : result_list.clear();
714 [ + - ]: 47 : result_list.reserve( temp_list.size() );
715 : :
716 : 47 : std::vector< Tag >::iterator i;
717 [ + - ][ + - ]: 559 : for( i = temp_list.begin(); i != temp_list.end(); ++i )
[ + + ][ + - ]
718 : : {
719 [ + - ]: 512 : std::string name;
720 [ + - ][ + - ]: 512 : rval = mMB->tag_get_name( *i, name );MB_CHK_SET_ERR( rval, "Error " << (int)rval << " getting name for tag (Stale tag handle?)" );
[ - + ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
721 : :
722 : : // Skip anonymous tags
723 [ + + ]: 512 : if( name.empty() ) continue;
724 : :
725 : : // Skip private/internal tags
726 [ + - ][ + - ]: 498 : if( name.size() >= 2 && name[0] == '_' && name[1] == '_' ) continue;
[ + + ][ + - ]
[ + - ][ + + ]
727 : :
728 : : // If requested, skip variable-length tags
729 : : int size;
730 [ + + ][ + - ]: 431 : if( !include_variable_length_tags && MB_VARIABLE_DATA_LENGTH == mMB->tag_get_length( *i, size ) ) continue;
[ + - ][ + + ]
[ + + ]
731 : :
732 [ + - ][ + - ]: 512 : result_list.push_back( *i );
[ + - + ]
733 : 559 : }
734 : : }
735 : :
736 : 47 : return MB_SUCCESS;
737 : : }
738 : :
739 : 1097 : ErrorCode WriteUtil::get_entity_list_pointers( Range::const_iterator begin, Range::const_iterator end,
740 : : EntityHandle const** pointers, EntityListType relation, int* lengths,
741 : : unsigned char* flags )
742 : : {
743 [ + - ][ + - ]: 1097 : RangeSeqIntersectIter iter( mMB->sequence_manager() );
744 [ + - ]: 1097 : ErrorCode rval = iter.init( begin, end );
745 [ + + ]: 2194 : while( MB_SUCCESS == rval )
746 : : {
747 [ + - ][ + - ]: 1097 : EntityType type = TYPE_FROM_HANDLE( iter.get_start_handle() );
748 : :
749 [ + - ]: 1097 : if( MBENTITYSET == type )
750 : : {
751 [ + - ]: 1097 : const MeshSetSequence* seq = reinterpret_cast< MeshSetSequence* >( iter.get_sequence() );
752 : : const MeshSet* set;
753 : 1097 : int len = 0;
754 : : size_t clen;
755 [ + - ][ + - ]: 2194 : for( EntityHandle h = iter.get_start_handle(); h <= iter.get_end_handle(); ++h )
[ + + ]
756 : : {
757 [ + - ]: 1097 : set = seq->get_set( h );
758 [ + + + - ]: 1097 : switch( relation )
759 : : {
760 : : case CONTENTS:
761 [ + - ]: 356 : *pointers = set->get_contents( clen );
762 : 356 : len = clen;
763 : 356 : break;
764 : : case CHILDREN:
765 [ + - ]: 434 : *pointers = set->get_children( len );
766 : 434 : break;
767 : : case PARENTS:
768 [ + - ]: 307 : *pointers = set->get_parents( len );
769 : 307 : break;
770 : : }
771 [ + - ]: 1097 : if( lengths )
772 : : {
773 : 1097 : *lengths = len;
774 : 1097 : ++lengths;
775 : : }
776 [ + - ]: 1097 : if( flags )
777 : : {
778 [ + - ]: 1097 : *flags = (unsigned char)set->flags();
779 : 1097 : ++flags;
780 : : }
781 : 1097 : ++pointers;
782 : : }
783 : : }
784 : :
785 [ # # ]: 0 : else if( MBVERTEX != type )
786 : : {
787 : 0 : const bool topological = ( relation == TOPOLOGICAL );
788 : : int len;
789 [ # # ]: 0 : const ElementSequence* seq = reinterpret_cast< ElementSequence* >( iter.get_sequence() );
790 [ # # ][ # # ]: 0 : for( EntityHandle h = iter.get_start_handle(); h <= iter.get_end_handle(); ++h )
[ # # ]
791 : : {
792 [ # # ]: 0 : rval = seq->get_connectivity( h, *pointers, len, topological );
793 [ # # ]: 0 : if( MB_SUCCESS != rval ) return rval;
794 [ # # ]: 0 : if( lengths )
795 : : {
796 : 0 : *lengths = len;
797 : 0 : ++lengths;
798 : : }
799 [ # # ]: 0 : if( flags )
800 : : {
801 : 0 : *flags = 0;
802 : 0 : ++flags;
803 : : }
804 : 0 : ++pointers;
805 : : }
806 : : }
807 : : else
808 : : {
809 : 0 : return MB_TYPE_OUT_OF_RANGE;
810 : : }
811 : :
812 [ + - ]: 1097 : rval = iter.step();
813 : : }
814 [ + - ]: 1097 : if( MB_FAILURE == rval )
815 : 1097 : return MB_SUCCESS; // At end of list
816 : : else
817 : 1097 : return rval;
818 : : }
819 : :
820 : 766 : ErrorCode WriteUtil::get_entity_list_pointers( EntityHandle const* entities, int num_entities,
821 : : EntityHandle const** pointers, EntityListType relation, int* lengths,
822 : : unsigned char* flags )
823 : : {
824 [ + - ]: 766 : SequenceManager* sm = mMB->sequence_manager();
825 : : const EntitySequence* tmp_seq;
826 : 766 : ErrorCode rval = MB_SUCCESS;
827 [ + + ]: 1532 : for( int i = 0; i < num_entities; i++ )
828 : : {
829 [ + - ]: 766 : rval = sm->find( entities[i], tmp_seq );
830 [ - + ]: 766 : if( MB_SUCCESS != rval ) return rval;
831 : :
832 [ + - ]: 766 : EntityType type = TYPE_FROM_HANDLE( entities[i] );
833 : :
834 [ + - ]: 766 : if( MBENTITYSET == type )
835 : : {
836 : 766 : const MeshSetSequence* seq = reinterpret_cast< const MeshSetSequence* >( tmp_seq );
837 : : const MeshSet* set;
838 : 766 : int len = 0;
839 : : size_t clen;
840 [ + - ]: 766 : set = seq->get_set( entities[i] );
841 [ + - - - ]: 766 : switch( relation )
842 : : {
843 : : case CONTENTS:
844 [ + - ]: 766 : *pointers = set->get_contents( clen );
845 : 766 : len = clen;
846 : 766 : break;
847 : : case CHILDREN:
848 [ # # ]: 0 : *pointers = set->get_children( len );
849 : 0 : break;
850 : : case PARENTS:
851 [ # # ]: 0 : *pointers = set->get_parents( len );
852 : 0 : break;
853 : : }
854 [ + - ]: 766 : if( lengths )
855 : : {
856 : 766 : *lengths = len;
857 : 766 : ++lengths;
858 : : }
859 [ + + ]: 766 : if( flags )
860 : : {
861 [ + - ]: 12 : *flags = (unsigned char)set->flags();
862 : 12 : ++flags;
863 : : }
864 : 766 : ++pointers;
865 : : }
866 [ # # ]: 0 : else if( MBVERTEX != type )
867 : : {
868 : 0 : const bool topological = ( relation == TOPOLOGICAL );
869 : : int len;
870 : 0 : const ElementSequence* seq = reinterpret_cast< const ElementSequence* >( tmp_seq );
871 [ # # ]: 0 : rval = seq->get_connectivity( entities[i], *pointers, len, topological );
872 [ # # ]: 0 : if( MB_SUCCESS != rval ) return rval;
873 [ # # ]: 0 : if( lengths )
874 : : {
875 : 0 : *lengths = len;
876 : 0 : ++lengths;
877 : : }
878 [ # # ]: 0 : if( flags )
879 : : {
880 : 0 : *flags = 0;
881 : 0 : ++flags;
882 : : }
883 : 0 : ++pointers;
884 : : }
885 : : else
886 : : {
887 : 0 : return MB_TYPE_OUT_OF_RANGE;
888 : : }
889 : : }
890 : :
891 : 766 : return MB_SUCCESS;
892 : : }
893 : :
894 [ + - ][ + - ]: 228 : } // namespace moab
|