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 : : // turn off warnings that say they debugging identifier has been truncated
18 : : // this warning comes up when using some STL containers
19 : : #pragma warning( disable : 4786 )
20 : : #endif
21 : :
22 : : #define MOAB_MPE_LOG "moab.mpe"
23 : :
24 : : #include <iostream>
25 : : #include <sstream>
26 : : #include <vector>
27 : : #include <string>
28 : : #include <algorithm>
29 : : #include "moab/Core.hpp"
30 : : #include "MeshSetSequence.hpp"
31 : : #include "ElementSequence.hpp"
32 : : #include "VertexSequence.hpp"
33 : : #include <cassert>
34 : : #include "AEntityFactory.hpp"
35 : : #include "ReadUtil.hpp"
36 : : #include "WriteUtil.hpp"
37 : : #include "moab/CN.hpp"
38 : : #include "moab/HigherOrderFactory.hpp"
39 : : #include "SequenceManager.hpp"
40 : : #include "moab/Error.hpp"
41 : : #include "moab/ReaderWriterSet.hpp"
42 : : #include "moab/ReaderIface.hpp"
43 : : #include "moab/WriterIface.hpp"
44 : : #include "moab/ScdInterface.hpp"
45 : : #include "moab/SetIterator.hpp"
46 : :
47 : : #include "BitTag.hpp"
48 : : #include "DenseTag.hpp"
49 : : #include "MeshTag.hpp"
50 : : #include "SparseTag.hpp"
51 : : #include "VarLenDenseTag.hpp"
52 : : #include "VarLenSparseTag.hpp"
53 : :
54 : : #include <sys/stat.h>
55 : : #include <cerrno>
56 : : #include <cstring>
57 : :
58 : : #ifdef MOAB_HAVE_AHF
59 : : #include "moab/HalfFacetRep.hpp"
60 : : #endif
61 : :
62 : : #ifdef MOAB_HAVE_MPI
63 : : /* Leave ParallelComm.hpp before mpi.h or MPICH2 will fail
64 : : * because its C++ headers do not like SEEK_* macros.
65 : : */
66 : : #include "moab/ParallelComm.hpp"
67 : : #include "moab_mpi.h"
68 : : #include "ReadParallel.hpp"
69 : : #endif
70 : :
71 : : #ifdef MOAB_HAVE_HDF5
72 : : #ifdef MOAB_HAVE_HDF5_PARALLEL
73 : : #include "WriteHDF5Parallel.hpp"
74 : : typedef moab::WriteHDF5Parallel DefaultWriter;
75 : : #define DefaultWriterName "WriteHDF5Parallel"
76 : : #else
77 : : #include "WriteHDF5.hpp"
78 : : typedef moab::WriteHDF5 DefaultWriter;
79 : : #define DefaultWriterName "WriteHDF5"
80 : : #endif
81 : : #elif defined( MOAB_HAVE_NETCDF )
82 : : #include "WriteNCDF.hpp"
83 : : typedef moab::WriteNCDF DefaultWriter;
84 : : #define DefaultWriterName "WriteNCDF"
85 : : #else
86 : : #include "WriteVtk.hpp"
87 : : typedef moab::WriteVtk DefaultWriter;
88 : : #define DefaultWriterName "WriteVtk"
89 : : #endif
90 : : #include "MBTagConventions.hpp"
91 : : #include "ExoIIUtil.hpp"
92 : : #include "EntitySequence.hpp"
93 : : #include "moab/FileOptions.hpp"
94 : : #ifdef LINUX
95 : : #include <dlfcn.h>
96 : : #include <dirent.h>
97 : : #endif
98 : :
99 : : #ifdef MOAB_HAVE_MPI
100 : : #include "moab_mpe.h"
101 : : #endif
102 : :
103 : : // MOAB used to use a NULL handle list and a zero handle count
104 : : // to indicate that tag functions are to operate on the global/mesh
105 : : // value of the tag. For the 3.0 release MOAB also accepted a handle
106 : : // with a value of 0 to indicate the same. Now we want to drop the
107 : : // old NULL list method because a) it is one less special case that
108 : : // must be handled in the tag get/set paths and b) it aviods unexpected
109 : : // segfaults when applications requested tag data with an empty list
110 : : // of handles.
111 : : //
112 : : // Define this constant to revert to the old behavior, but also print
113 : : // a warning.
114 : : #define ALLOW_NULL_FOR_MESH_TAG
115 : : //
116 : : // Define this to print an error and abort() when a NULL handle list
117 : : // is passed. This is intended as an interim solution to help catch
118 : : // spots in code that haven't been updated for the change.
119 : : #undef DISALLOW_EMPTY_HANDLE_LIST_FOR_TAGS
120 : : //
121 : : // The eventual goal is to define neither of the above, eliminating the
122 : : // check and allowing applications to safely request tag data for no
123 : : // entities.
124 : :
125 : 0 : static void warn_null_array_mesh_tag()
126 : : {
127 : 0 : std::cerr << "WARNING: Accepting empty array to indicate mesh tag" << std::endl;
128 : 0 : }
129 : :
130 : : #ifdef ALLOW_NULL_FOR_MESH_TAG
131 : : #define CHECK_MESH_NULL \
132 : : EntityHandle root = 0; \
133 : : if( NULL == entity_handles && 0 == num_entities ) \
134 : : { \
135 : : entity_handles = &root; \
136 : : num_entities = 1; \
137 : : warn_null_array_mesh_tag(); \
138 : : }
139 : : #elif defined( DISALLOW_EMPTY_HANDLE_LIST_FOR_TAGS )
140 : : #define CHECK_MESH_NULL \
141 : : if( NULL == entity_handles ) \
142 : : { \
143 : : std::cerr << "ERROR: Deprecated NULL handle list at " __FILE__ ":" << __LINE__ << std::endl; \
144 : : abort(); \
145 : : }
146 : : #else
147 : : #define CHECK_MESH_NULL
148 : : #endif
149 : :
150 : : namespace moab
151 : : {
152 : :
153 : : using namespace std;
154 : :
155 : 1437 : static inline const MeshSet* get_mesh_set( const SequenceManager* sm, EntityHandle h )
156 : : {
157 : : const EntitySequence* seq;
158 [ + - ][ + - ]: 1437 : if( MBENTITYSET != TYPE_FROM_HANDLE( h ) || MB_SUCCESS != sm->find( h, seq ) ) return 0;
[ + - ][ - + ]
[ - + ]
159 [ + - ]: 1437 : return reinterpret_cast< const MeshSetSequence* >( seq )->get_set( h );
160 : : }
161 : :
162 : 213537 : static inline MeshSet* get_mesh_set( SequenceManager* sm, EntityHandle h )
163 : : {
164 : : EntitySequence* seq;
165 [ + - ][ + + ]: 213537 : if( MBENTITYSET != TYPE_FROM_HANDLE( h ) || MB_SUCCESS != sm->find( h, seq ) ) return 0;
[ + - ][ - + ]
[ + + ]
166 [ + - ]: 213537 : return reinterpret_cast< MeshSetSequence* >( seq )->get_set( h );
167 : : }
168 : :
169 : : //! Constructor
170 [ + - ][ + - ]: 744 : Core::Core()
171 : : {
172 [ + - ][ - + ]: 372 : if( initialize() != MB_SUCCESS )
173 : : {
174 [ # # ]: 0 : printf( "Error initializing moab::Core\n" );
175 : 0 : exit( 1 );
176 : : }
177 : 372 : }
178 : :
179 : : //! destructor
180 : 829 : Core::~Core()
181 : : {
182 [ + + ][ + - ]: 369 : if( mMBWriteUtil ) delete mMBWriteUtil;
183 [ + + ][ + - ]: 369 : if( mMBReadUtil ) delete mMBReadUtil;
184 [ + + ][ + - ]: 369 : if( scdInterface ) delete scdInterface;
185 : :
186 : 369 : mMBWriteUtil = NULL;
187 : 369 : mMBReadUtil = NULL;
188 : 369 : scdInterface = NULL;
189 : :
190 : 369 : deinitialize();
191 [ - + ]: 460 : }
192 : :
193 : 372 : ErrorCode Core::initialize()
194 : : {
195 : : #ifdef MOAB_HAVE_MPI
196 : : int flag;
197 [ + - ][ + - ]: 372 : if( MPI_SUCCESS == MPI_Initialized( &flag ) )
198 : : {
199 [ + + ]: 372 : if( flag )
200 : : {
201 : 174 : writeMPELog = !MPE_Initialized_logging();
202 : 174 : if( writeMPELog ) (void)MPE_Init_log();
203 : : }
204 : : }
205 : : #endif
206 : :
207 : 372 : initErrorHandlerInCore = false;
208 [ + - ][ + + ]: 372 : if( !MBErrorHandler_Initialized() )
209 : : {
210 [ + - ]: 335 : MBErrorHandler_Init();
211 : 335 : initErrorHandlerInCore = true;
212 : : }
213 : :
214 : 372 : geometricDimension = 3;
215 : 372 : materialTag = 0;
216 : 372 : neumannBCTag = 0;
217 : 372 : dirichletBCTag = 0;
218 : 372 : geomDimensionTag = 0;
219 : 372 : globalIdTag = 0;
220 : :
221 [ + - ][ + - ]: 372 : sequenceManager = new( std::nothrow ) SequenceManager;
222 [ - + ]: 372 : if( !sequenceManager ) return MB_MEMORY_ALLOCATION_FAILED;
223 : :
224 [ + - ][ + - ]: 372 : aEntityFactory = new( std::nothrow ) AEntityFactory( this );
225 [ - + ]: 372 : if( !aEntityFactory ) return MB_MEMORY_ALLOCATION_FAILED;
226 : :
227 [ + - ][ + - ]: 372 : mError = new( std::nothrow ) Error;
228 [ - + ]: 372 : if( !mError ) return MB_MEMORY_ALLOCATION_FAILED;
229 : :
230 : 372 : mMBWriteUtil = NULL;
231 : 372 : mMBReadUtil = NULL;
232 : 372 : scdInterface = NULL;
233 : :
234 : : // Readers and writers try to get pointers to above utils.
235 : : // Do this after pointers are initialized. (Pointers should
236 : : // really be initialized in constructor to avoid this kind
237 : : // of thing -- j.kraftcheck.)
238 [ + - ][ + - ]: 372 : readerWriterSet = new( std::nothrow ) ReaderWriterSet( this );
239 [ - + ]: 372 : if( !readerWriterSet ) return MB_MEMORY_ALLOCATION_FAILED;
240 : :
241 [ + - ]: 372 : material_tag();
242 [ + - ]: 372 : neumannBC_tag();
243 [ + - ]: 372 : dirichletBC_tag();
244 [ + - ]: 372 : geom_dimension_tag();
245 [ + - ]: 372 : globalId_tag();
246 : :
247 : : #ifdef MOAB_HAVE_AHF
248 : : ahfRep = new HalfFacetRep( this );
249 : : if( !ahfRep ) return MB_MEMORY_ALLOCATION_FAILED;
250 : : mesh_modified = false;
251 : : #endif
252 : :
253 : 372 : return MB_SUCCESS;
254 : : }
255 : :
256 : 1 : EntityHandle Core::get_root_set()
257 : : {
258 : 1 : return 0;
259 : : }
260 : :
261 : 369 : void Core::deinitialize()
262 : : {
263 : :
264 : : #ifdef MOAB_HAVE_MPI
265 [ + - ]: 369 : std::vector< ParallelComm* > pc_list;
266 [ + - ]: 369 : ParallelComm::get_all_pcomm( this, pc_list );
267 [ + - ][ + - ]: 411 : for( std::vector< ParallelComm* >::iterator vit = pc_list.begin(); vit != pc_list.end(); ++vit )
[ + + ]
268 [ + - ][ + - ]: 42 : delete *vit;
269 : : #endif
270 : :
271 : : #ifdef MOAB_HAVE_AHF
272 : : delete ahfRep;
273 : : ahfRep = 0;
274 : : #endif
275 : :
276 [ + - ][ + - ]: 369 : if( aEntityFactory ) delete aEntityFactory;
277 : :
278 : 369 : aEntityFactory = 0;
279 : :
280 [ + + ]: 3052 : while( !tagList.empty() )
281 [ + - ][ + - ]: 2683 : tag_delete( tagList.front() );
282 : :
283 [ + - ][ + - ]: 369 : if( sequenceManager ) delete sequenceManager;
284 : :
285 : 369 : sequenceManager = 0;
286 : :
287 [ + - ]: 369 : delete readerWriterSet;
288 : 369 : readerWriterSet = 0;
289 : :
290 [ + - ][ + - ]: 369 : if( mError ) delete mError;
291 : 369 : mError = 0;
292 : :
293 : : #ifdef MOAB_HAVE_MPI
294 [ + + ]: 369 : if( writeMPELog )
295 : : {
296 : 61 : const char* default_log = MOAB_MPE_LOG;
297 : 61 : const char* logfile = getenv( "MPE_LOG_FILE" );
298 [ + - ]: 61 : if( !logfile ) logfile = default_log;
299 : : MPE_Finish_log( logfile );
300 : : }
301 : : #endif
302 : :
303 [ + + ][ + - ]: 369 : if( initErrorHandlerInCore ) MBErrorHandler_Finalize();
304 : 369 : }
305 : :
306 : 1229 : ErrorCode Core::query_interface_type( const std::type_info& interface_type, void*& ptr )
307 : : {
308 [ + + ]: 1229 : if( interface_type == typeid( ReadUtilIface ) )
309 : : {
310 [ + + ][ + - ]: 314 : if( !mMBReadUtil ) mMBReadUtil = new ReadUtil( this, mError );
311 : 314 : ptr = static_cast< ReadUtilIface* >( mMBReadUtil );
312 : : }
313 [ + + ]: 915 : else if( interface_type == typeid( WriteUtilIface ) )
314 : : {
315 [ + + ][ + - ]: 818 : if( !mMBWriteUtil ) mMBWriteUtil = new WriteUtil( this );
316 : 818 : ptr = static_cast< WriteUtilIface* >( mMBWriteUtil );
317 : : }
318 [ - + ]: 97 : else if( interface_type == typeid( ReaderWriterSet ) )
319 : : {
320 : 0 : ptr = reader_writer_set();
321 : : }
322 [ + + ]: 97 : else if( interface_type == typeid( Error ) )
323 : : {
324 : 66 : ptr = mError;
325 : : }
326 [ - + ]: 31 : else if( interface_type == typeid( ExoIIInterface ) )
327 : : {
328 [ # # ]: 0 : ptr = static_cast< ExoIIInterface* >( new ExoIIUtil( this ) );
329 : : }
330 [ + - ]: 31 : else if( interface_type == typeid( ScdInterface ) )
331 : : {
332 [ + + ][ + - ]: 31 : if( !scdInterface ) scdInterface = new ScdInterface( this );
333 : 31 : ptr = scdInterface;
334 : : }
335 : : else
336 : : {
337 : 0 : ptr = 0;
338 : 0 : return MB_FAILURE;
339 : : }
340 : 1229 : return MB_SUCCESS;
341 : : }
342 : :
343 : 1020 : ErrorCode Core::release_interface_type( const std::type_info& interface_type, void* iface )
344 : : {
345 [ - + ]: 1020 : if( interface_type == typeid( ExoIIInterface ) )
346 [ # # ]: 0 : delete static_cast< ExoIIInterface* >( iface );
347 [ + + + - ]: 2862 : else if( interface_type != typeid( ReadUtilIface ) && interface_type != typeid( WriteUtilIface ) &&
[ - + ]
348 [ + + ]: 1844 : interface_type != typeid( ReaderWriterSet ) && interface_type != typeid( Error ) &&
[ + - - + ]
349 : 2 : interface_type != typeid( ScdInterface ) )
350 : 0 : return MB_FAILURE;
351 : :
352 : 1020 : return MB_SUCCESS;
353 : : }
354 : :
355 : 0 : int Core::QueryInterface( const MBuuid& uuid, UnknownInterface** iface )
356 : : {
357 : 0 : *iface = 0;
358 [ # # ]: 0 : if( uuid == IDD_MBUnknown ) *iface = this;
359 [ # # ]: 0 : if( uuid == IDD_MBCore )
360 : 0 : *iface = this;
361 : : else
362 : 0 : return 0;
363 : 0 : return 1;
364 : : }
365 : :
366 : 0 : float Core::impl_version( std::string* version_string )
367 : : {
368 [ # # ]: 0 : if( version_string ) *version_string = MOAB_VERSION_STRING;
369 : :
370 : 0 : return MOAB_VERSION_MAJOR + MOAB_VERSION_MINOR / 100.0f;
371 : : }
372 : :
373 : : //! get the type from a handle, returns type
374 : 18486481 : EntityType Core::type_from_handle( const EntityHandle handle ) const
375 : : {
376 [ + + ]: 18486481 : if( !handle ) // root set
377 : 1 : return MBENTITYSET;
378 : : else
379 : 18486480 : return TYPE_FROM_HANDLE( handle );
380 : : }
381 : :
382 : : //! get the id from a handle, returns id
383 : 906 : EntityID Core::id_from_handle( const EntityHandle handle ) const
384 : : {
385 : 906 : return ID_FROM_HANDLE( handle );
386 : : }
387 : :
388 : : //! get a handle from an id and type
389 : 19182558 : ErrorCode Core::handle_from_id( const EntityType entity_type, const EntityID id, EntityHandle& handle ) const
390 : : {
391 : : int err;
392 [ + - ]: 19182558 : handle = CREATE_HANDLE( entity_type, id, err );
393 : :
394 : : // check to see if handle exists
395 : 19182558 : const EntitySequence* dummy_seq = 0;
396 [ + - ][ + - ]: 19182558 : ErrorCode error_code = sequence_manager()->find( handle, dummy_seq );
397 : 19182558 : return error_code;
398 : : }
399 : :
400 : 1335594 : int Core::dimension_from_handle( const EntityHandle handle ) const
401 : : {
402 [ + + ]: 1335594 : if( !handle ) // root set
403 : 1 : return 4;
404 : : else
405 : 1335593 : return CN::Dimension( TYPE_FROM_HANDLE( handle ) );
406 : : }
407 : :
408 : : //! load mesh from data in file
409 : : //! NOTE: if there is mesh already present, the new mesh will be added
410 : 27 : ErrorCode Core::load_mesh( const char* file_name, const int* block_id_list, const int num_blocks )
411 : : {
412 [ - + ]: 27 : const char* name = block_id_list ? MATERIAL_SET_TAG_NAME : 0;
413 : 27 : return load_file( file_name, 0, 0, name, block_id_list, num_blocks );
414 : : }
415 : :
416 : 120 : ErrorCode Core::load_file( const char* file_name, const EntityHandle* file_set, const char* setoptions,
417 : : const char* set_tag_name, const int* set_tag_vals, int num_set_tag_vals )
418 : : {
419 [ + - ]: 120 : FileOptions opts( setoptions );
420 : : ErrorCode rval;
421 : 120 : ReaderIface::IDTag t = { set_tag_name, set_tag_vals, num_set_tag_vals };
422 : 120 : ReaderIface::SubsetList sl = { &t, 1, 0, 0 };
423 : :
424 [ + + ][ + - ]: 120 : assert( !file_set || ( *file_set && is_valid( *file_set ) ) );
[ + - ][ - + ]
425 [ + + ][ - + ]: 120 : if( file_set && !*file_set )
426 [ # # ][ # # ]: 0 : { MB_SET_GLB_ERR( MB_FAILURE, "Non-NULL file set pointer should point to non-NULL set" ); }
[ # # ][ # # ]
[ # # ]
427 : :
428 : : // if reading in parallel, call a different reader
429 [ + - ]: 240 : std::string parallel_opt;
430 [ + - ]: 120 : rval = opts.get_option( "PARALLEL", parallel_opt );
431 [ + + ]: 120 : if( MB_SUCCESS == rval )
432 : : {
433 : : #ifdef MOAB_HAVE_MPI
434 : 21 : ParallelComm* pcomm = 0;
435 : : int pcomm_id;
436 [ + - ]: 21 : rval = opts.get_int_option( "PARALLEL_COMM", pcomm_id );
437 [ + - ][ + - ]: 21 : if( MB_ENTITY_NOT_FOUND == rval ) rval = opts.get_int_option( "PCOMM", pcomm_id );
438 [ + + ]: 21 : if( rval == MB_SUCCESS )
439 : : {
440 [ + - ]: 19 : pcomm = ParallelComm::get_pcomm( this, pcomm_id );
441 [ - + ]: 21 : if( !pcomm ) return MB_ENTITY_NOT_FOUND;
442 : : }
443 [ - + ]: 2 : else if( rval != MB_ENTITY_NOT_FOUND )
444 : 0 : return rval;
445 [ - + ][ # # ]: 21 : if( set_tag_name && num_set_tag_vals )
446 : : {
447 [ # # ][ # # ]: 0 : rval = ReadParallel( this, pcomm ).load_file( file_name, file_set, opts, &sl );MB_CHK_ERR( rval );
[ # # ][ # # ]
[ # # ]
448 : : }
449 : : else
450 : : {
451 [ + - ][ + - ]: 21 : rval = ReadParallel( this, pcomm ).load_file( file_name, file_set, opts );MB_CHK_ERR( rval );
[ + + ][ - + ]
[ + - ]
452 : : }
453 : : #else
454 : : MB_SET_GLB_ERR( MB_FAILURE, "PARALLEL option not valid, this instance compiled for serial execution" );
455 : : #endif
456 : : }
457 : : else
458 : : {
459 [ - + ][ # # ]: 99 : if( set_tag_name && num_set_tag_vals )
460 : : {
461 [ # # ][ # # ]: 0 : rval = serial_load_file( file_name, file_set, opts, &sl );MB_CHK_ERR( rval );
[ # # ][ # # ]
462 : : }
463 : : else
464 : : {
465 [ + - ][ + + ]: 99 : rval = serial_load_file( file_name, file_set, opts );MB_CHK_ERR( rval );
[ - + ][ + - ]
466 : : }
467 : : }
468 : :
469 [ + - ][ + - ]: 116 : if( MB_SUCCESS == rval && !opts.all_seen() )
[ - + ][ - + ]
470 : : {
471 [ # # ]: 0 : std::string bad_opt;
472 [ # # ][ # # ]: 0 : if( MB_SUCCESS == opts.get_unseen_option( bad_opt ) )
473 [ # # ][ # # ]: 0 : { MB_SET_ERR( MB_UNHANDLED_OPTION, "Unrecognized option: \"" << bad_opt << "\"" ); }
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
474 : : else
475 : : {
476 [ # # ][ # # ]: 0 : MB_SET_ERR( MB_UNHANDLED_OPTION, "Unrecognized option" );
[ # # ][ # # ]
[ # # ]
477 : 0 : }
478 : : }
479 : :
480 : 236 : return MB_SUCCESS;
481 : : }
482 : :
483 : 25 : void Core::clean_up_failed_read( const Range& initial_ents, std::vector< Tag > initial_tags )
484 : : {
485 [ + - ]: 25 : Range new_ents;
486 [ + - ]: 25 : get_entities_by_handle( 0, new_ents );
487 [ + - ][ + - ]: 25 : new_ents = subtract( new_ents, initial_ents );
488 [ + - ]: 25 : delete_entities( new_ents );
489 : :
490 [ + - ][ + - ]: 50 : std::vector< Tag > all_tags, new_tags;
491 [ + - ]: 25 : tag_get_tags( all_tags );
492 [ + - ]: 25 : std::sort( initial_tags.begin(), initial_tags.end() );
493 [ + - ]: 25 : std::sort( all_tags.begin(), all_tags.end() );
494 : : std::set_difference( all_tags.begin(), all_tags.end(), initial_tags.begin(), initial_tags.end(),
495 [ + - ][ + - ]: 25 : std::back_inserter( new_tags ) );
496 [ + + ]: 84 : while( !new_tags.empty() )
497 : : {
498 [ + - ][ + - ]: 59 : tag_delete( new_tags.back() );
499 [ + - ]: 59 : new_tags.pop_back();
500 : 25 : }
501 : 25 : }
502 : :
503 : 120 : ErrorCode Core::serial_load_file( const char* file_name, const EntityHandle* file_set, const FileOptions& opts,
504 : : const ReaderIface::SubsetList* subsets, const Tag* id_tag )
505 : : {
506 : : int status;
507 : : #if defined( WIN32 ) || defined( WIN64 ) || defined( MSC_VER )
508 : : struct _stat stat_data;
509 : : status = _stat( file_name, &stat_data );
510 : : #else
511 : : struct stat stat_data;
512 : 120 : status = stat( file_name, &stat_data );
513 : : #endif
514 [ + + ][ + - ]: 120 : if( status ) { MB_SET_GLB_ERR( MB_FILE_DOES_NOT_EXIST, file_name << ": " << strerror( errno ) ); }
[ + - ][ + - ]
[ + - ][ + - ]
[ - + ][ + - ]
515 : : #if defined( WIN32 ) || defined( WIN64 ) || defined( MSC_VER )
516 : : else if( stat_data.st_mode & _S_IFDIR )
517 : : {
518 : : #else
519 [ - + ]: 119 : else if( S_ISDIR( stat_data.st_mode ) )
520 : : {
521 : : #endif
522 [ # # ][ # # ]: 0 : MB_SET_GLB_ERR( MB_FILE_DOES_NOT_EXIST, file_name << ": Cannot read directory/folder" );
[ # # ][ # # ]
[ # # ][ # # ]
523 : : }
524 : :
525 [ + - ]: 119 : const ReaderWriterSet* set = reader_writer_set();
526 : :
527 [ + - ]: 119 : Range initial_ents;
528 [ + - ][ - + ]: 119 : ErrorCode rval = get_entities_by_handle( 0, initial_ents );MB_CHK_ERR( rval );
[ # # ][ # # ]
529 : :
530 [ + - ]: 238 : std::vector< Tag > initial_tags;
531 [ + - ][ - + ]: 119 : rval = tag_get_tags( initial_tags );MB_CHK_ERR( rval );
[ # # ][ # # ]
532 : :
533 : : // otherwise try using the file extension to select a reader
534 [ + - ][ + - ]: 238 : std::string ext = set->extension_from_filename( file_name );
535 : :
536 : : // Try all the readers
537 [ + - ]: 119 : ReaderWriterSet::iterator iter;
538 : 119 : rval = MB_FAILURE;
539 : 119 : bool tried_one = false;
540 [ + - ][ + - ]: 900 : for( iter = set->begin(); iter != set->end(); ++iter )
[ + - ][ + - ]
[ + + ]
541 : : {
542 [ + - ][ + - ]: 876 : if( !iter->reads_extension( ext.c_str() ) ) continue;
[ + + ]
543 : :
544 [ + - ][ + - ]: 97 : ReaderIface* reader = iter->make_reader( this );
545 [ + - ]: 97 : if( NULL != reader )
546 : : {
547 : 97 : tried_one = true;
548 [ + - ]: 97 : rval = reader->load_file( file_name, file_set, opts, subsets, id_tag );
549 [ + - ]: 97 : delete reader;
550 [ + + ]: 97 : if( MB_SUCCESS == rval ) break;
551 [ + - ][ + - ]: 2 : clean_up_failed_read( initial_ents, initial_tags );
552 : : }
553 : : }
554 : :
555 [ + + ][ + + ]: 119 : if( MB_SUCCESS != rval && !tried_one )
556 : : {
557 : : // didn't recognize the extension; try all of them now
558 [ + - ][ + - ]: 66 : for( iter = set->begin(); iter != set->end(); ++iter )
[ + - ][ + - ]
[ + + ]
559 : : {
560 [ + - ][ + - ]: 44 : ReaderIface* reader = iter->make_reader( this );
561 [ + + ]: 44 : if( !reader ) continue;
562 [ + - ]: 41 : rval = reader->load_file( file_name, file_set, opts, subsets, id_tag );
563 [ + - ]: 41 : delete reader;
564 [ + + ]: 41 : if( MB_SUCCESS == rval )
565 : 21 : break;
566 : : else
567 [ + - ][ + - ]: 20 : clean_up_failed_read( initial_ents, initial_tags );
568 : : }
569 : : }
570 : :
571 [ + + ]: 119 : if( MB_SUCCESS != rval )
572 : : {
573 [ + - ][ + - ]: 3 : clean_up_failed_read( initial_ents, initial_tags );
574 [ + - ][ + - ]: 3 : MB_SET_ERR( rval, "Failed to load file after trying all possible readers" );
[ + - ][ - + ]
[ + - ]
575 : : }
576 [ + + ]: 116 : else if( file_set )
577 : : {
578 [ + - ]: 39 : Range new_ents;
579 [ + - ]: 39 : get_entities_by_handle( 0, new_ents );
580 [ + - ][ + - ]: 39 : new_ents = subtract( new_ents, initial_ents );
581 : :
582 : : // Check if gather set exists
583 : : EntityHandle gather_set;
584 [ + - ]: 39 : rval = mMBReadUtil->get_gather_set( gather_set );
585 [ - + ]: 39 : if( MB_SUCCESS == rval )
586 : : {
587 : : // Exclude gather set itself
588 [ # # ]: 0 : new_ents.erase( gather_set );
589 : :
590 : : // Exclude gather set entities
591 [ # # ]: 0 : Range gather_ents;
592 [ # # ]: 0 : rval = get_entities_by_handle( gather_set, gather_ents );
593 [ # # ][ # # ]: 0 : if( MB_SUCCESS == rval ) new_ents = subtract( new_ents, gather_ents );
[ # # ]
594 : : }
595 : :
596 [ + - ]: 39 : rval = add_entities( *file_set, new_ents );
597 : : }
598 : :
599 : 236 : return rval;
600 : : } // namespace moab
601 : :
602 : 0 : ErrorCode Core::serial_read_tag( const char* file_name, const char* tag_name, const FileOptions& opts,
603 : : std::vector< int >& vals, const ReaderIface::SubsetList* subsets )
604 : : {
605 : 0 : ErrorCode rval = MB_FAILURE;
606 : 0 : const ReaderWriterSet* set = reader_writer_set();
607 : :
608 : : // otherwise try using the file extension to select a reader
609 [ # # ][ # # ]: 0 : ReaderIface* reader = set->get_file_extension_reader( file_name );
610 [ # # ]: 0 : if( reader )
611 : : {
612 : 0 : rval = reader->read_tag_values( file_name, tag_name, opts, vals, subsets );
613 [ # # ]: 0 : delete reader;
614 : : }
615 : : else
616 : : {
617 : : // Try all the readers
618 [ # # ]: 0 : ReaderWriterSet::iterator iter;
619 [ # # ][ # # ]: 0 : for( iter = set->begin(); iter != set->end(); ++iter )
[ # # ][ # # ]
[ # # ]
620 : : {
621 [ # # ][ # # ]: 0 : reader = iter->make_reader( this );
622 [ # # ]: 0 : if( NULL != reader )
623 : : {
624 [ # # ]: 0 : rval = reader->read_tag_values( file_name, tag_name, opts, vals, subsets );
625 [ # # ]: 0 : delete reader;
626 [ # # ]: 0 : if( MB_SUCCESS == rval ) break;
627 : : }
628 : : }
629 : : }
630 : :
631 : 0 : return rval;
632 : : }
633 : :
634 : 17 : ErrorCode Core::write_mesh( const char* file_name, const EntityHandle* output_list, const int num_sets )
635 : : {
636 : 17 : return write_file( file_name, 0, 0, output_list, num_sets );
637 : : }
638 : :
639 : 52 : ErrorCode Core::write_file( const char* file_name, const char* file_type, const char* options_string,
640 : : const EntityHandle* output_sets, int num_output_sets, const Tag* tag_list, int num_tags )
641 : : {
642 [ + - ]: 52 : Range range;
643 [ + - ][ + - ]: 52 : std::copy( output_sets, output_sets + num_output_sets, range_inserter( range ) );
644 [ + - ]: 52 : return write_file( file_name, file_type, options_string, range, tag_list, num_tags );
645 : : }
646 : :
647 : 52 : ErrorCode Core::write_file( const char* file_name, const char* file_type, const char* options_string,
648 : : const Range& output_sets, const Tag* tag_list, int num_tags )
649 : : {
650 : : // convert range to vector
651 [ + - ][ + - ]: 52 : std::vector< EntityHandle > list( output_sets.size() );
652 [ + - ][ + - ]: 52 : std::copy( output_sets.begin(), output_sets.end(), list.begin() );
[ + - ]
653 : :
654 : : // parse some options
655 [ + - ]: 104 : FileOptions opts( options_string );
656 : : ErrorCode rval;
657 : :
658 [ + - ]: 52 : rval = opts.get_null_option( "CREATE" );
659 [ - + ][ # # ]: 52 : if( rval == MB_TYPE_OUT_OF_RANGE ) { MB_SET_GLB_ERR( MB_FAILURE, "Unexpected value for CREATE option" ); }
[ # # ][ # # ]
[ # # ][ # # ]
660 : 52 : bool overwrite = ( rval == MB_ENTITY_NOT_FOUND );
661 : :
662 : : // Get the file writer
663 [ + - ][ + - ]: 104 : std::string ext = ReaderWriterSet::extension_from_filename( file_name );
664 [ + - ]: 104 : std::vector< std::string > qa_records;
665 [ + + ][ + - ]: 52 : const EntityHandle* list_ptr = list.empty() ? (EntityHandle*)0 : &list[0];
666 : :
667 : 52 : rval = MB_TYPE_OUT_OF_RANGE;
668 : :
669 : : // Try all possible writers
670 [ + - ][ + - ]: 576 : for( ReaderWriterSet::iterator i = reader_writer_set()->begin(); i != reader_writer_set()->end(); ++i )
[ + - ][ + - ]
[ + - ][ + - ]
[ + + ]
671 : : {
672 : :
673 [ - + ][ # # ]: 555 : if( ( file_type && !i->name().compare( file_type ) ) || i->writes_extension( ext.c_str() ) )
[ # # ][ # # ]
[ # # ][ + - ]
[ + - ][ + + ]
[ + + ]
674 : : {
675 : :
676 [ + - ][ + - ]: 31 : WriterIface* writer = i->make_writer( this );
677 : :
678 : : // write the file
679 : : rval =
680 [ + - ]: 31 : writer->write_file( file_name, overwrite, opts, list_ptr, list.size(), qa_records, tag_list, num_tags );
681 [ + - ]: 31 : delete writer;
682 [ + - ]: 31 : if( MB_SUCCESS == rval ) break;
683 : : printf( "Writer with name %s for file %s using extension %s (file type \"%s\") was "
684 : : "unsuccessful\n",
685 [ # # ][ # # ]: 0 : i->name().c_str(), file_name, ext.c_str(), file_type );
[ # # ]
686 : : }
687 : : }
688 : :
689 [ - + ][ # # ]: 52 : if( file_type && rval == MB_TYPE_OUT_OF_RANGE )
690 [ # # ][ # # ]: 0 : { MB_SET_ERR( rval, "Unrecognized file type \"" << file_type << "\"" ); }
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
691 : : // Should we use default writer (e.g. HDF5)?
692 [ + + ]: 52 : else if( MB_SUCCESS != rval )
693 : : {
694 [ + - ]: 21 : DefaultWriter writer( this );
695 [ + - ]: 21 : printf( "Using default writer %s for file %s \n", DefaultWriterName, file_name );
696 [ + - ]: 21 : rval = writer.write_file( file_name, overwrite, opts, list_ptr, list.size(), qa_records, tag_list, num_tags );
697 : : }
698 : :
699 [ + - ][ + - ]: 52 : if( MB_SUCCESS == rval && !opts.all_seen() )
[ - + ][ - + ]
700 : : {
701 [ # # ]: 0 : std::string bad_opt;
702 [ # # ][ # # ]: 0 : if( MB_SUCCESS == opts.get_unseen_option( bad_opt ) )
703 [ # # ][ # # ]: 0 : { MB_SET_ERR( MB_UNHANDLED_OPTION, "Unrecognized option: \"" << bad_opt << "\"" ); }
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
704 : : else
705 : : {
706 [ # # ][ # # ]: 0 : MB_SET_ERR( MB_UNHANDLED_OPTION, "Unrecognized option" );
[ # # ][ # # ]
[ # # ]
707 : 0 : }
708 : : }
709 : :
710 : 104 : return MB_SUCCESS;
711 : : }
712 : :
713 : : //! deletes all mesh entities from this datastore
714 : 66 : ErrorCode Core::delete_mesh()
715 : : {
716 : :
717 : 66 : ErrorCode result = MB_SUCCESS;
718 : :
719 : : // perform all deinitialization procedures to clean up
720 [ + - ][ + - ]: 66 : if( aEntityFactory ) delete aEntityFactory;
721 [ + - ]: 66 : aEntityFactory = new AEntityFactory( this );
722 : :
723 [ + - ][ + - ]: 737 : for( std::list< TagInfo* >::iterator i = tagList.begin(); i != tagList.end(); ++i )
[ + + ]
724 : : {
725 [ + - ][ + - ]: 671 : result = ( *i )->release_all_data( sequenceManager, mError, false );MB_CHK_ERR( result );
[ - + ][ # # ]
[ # # ]
726 : : }
727 : :
728 : 66 : sequenceManager->clear();
729 : :
730 : 66 : return MB_SUCCESS;
731 : : }
732 : :
733 : : //! get overall geometric dimension
734 : 320 : ErrorCode Core::get_dimension( int& dim ) const
735 : : {
736 : 320 : dim = geometricDimension;
737 : 320 : return MB_SUCCESS;
738 : : }
739 : :
740 : : //! set overall geometric dimension
741 : : /** Returns error if setting to 3 dimensions, mesh has been created, and
742 : : * there are only 2 dimensions on that mesh
743 : : */
744 : 0 : ErrorCode Core::set_dimension( const int dim )
745 : : {
746 : : // check to see if current dimension is smaller
747 [ # # ]: 0 : if( geometricDimension < dim )
748 : : {
749 : : // need to check the number of entities
750 : : int num;
751 [ # # ]: 0 : /*ErrorCode result = */ get_number_entities_by_dimension( 0, geometricDimension, num );
752 : :
753 : : // test written to be more readable but possibly less efficient
754 : : // if (MB_SUCCESS != result) return MB_FAILURE;
755 : : // else if (0 != num && dim == 2 && ycoordTag == 0) return MB_FAILURE;
756 : : // else if (0 != num && dim == 3 && (ycoordTag == 0 || zcoordTag == 0)) return MB_FAILURE;
757 : : // TODO -- replace this with not using xcoordTag, etc...
758 : : }
759 : :
760 : : // if we got here, it's ok to set dimension
761 : 0 : geometricDimension = dim;
762 : 0 : return MB_SUCCESS;
763 : : }
764 : :
765 : : //! get blocked vertex coordinates for all vertices
766 : : /** Blocked = all x, then all y, etc.
767 : : */
768 : 0 : ErrorCode Core::get_vertex_coordinates( std::vector< double >& coords ) const
769 : : {
770 : : // INEFFICIENT implementation for now, until we get blocked tag access
771 [ # # ]: 0 : Range vertices;
772 [ # # ][ # # ]: 0 : ErrorCode result = get_entities_by_type( 0, MBVERTEX, vertices );MB_CHK_ERR( result );
[ # # ][ # # ]
773 : :
774 : : // the least we can do is resize the vector and only go through the
775 : : // vertex list once
776 [ # # ]: 0 : int num_verts = vertices.size();
777 : 0 : int vec_pos = 0;
778 : : double xyz[3];
779 [ # # ]: 0 : coords.resize( geometricDimension * num_verts );
780 [ # # ][ # # ]: 0 : for( Range::iterator it = vertices.begin(); it != vertices.end(); ++it )
[ # # ][ # # ]
[ # # ]
781 : : {
782 [ # # ][ # # ]: 0 : result = get_coords( &( *it ), 1, xyz );MB_CHK_ERR( result );
[ # # ][ # # ]
[ # # ]
783 : :
784 [ # # ]: 0 : coords[vec_pos] = xyz[0];
785 [ # # ]: 0 : coords[num_verts + vec_pos] = xyz[1];
786 [ # # ]: 0 : coords[2 * num_verts + vec_pos] = xyz[2];
787 : :
788 : 0 : vec_pos++;
789 : : }
790 : :
791 : 0 : return MB_SUCCESS;
792 : : }
793 : :
794 : 12 : ErrorCode Core::coords_iterate( Range::const_iterator iter, Range::const_iterator end, double*& xcoords_ptr,
795 : : double*& ycoords_ptr, double*& zcoords_ptr, int& count )
796 : : {
797 : : EntitySequence* seq;
798 [ + - ][ + - ]: 12 : ErrorCode rval = sequence_manager()->find( *iter, seq );
[ + - ]
799 [ - + ]: 12 : if( MB_SUCCESS != rval )
800 : : {
801 : 0 : xcoords_ptr = ycoords_ptr = zcoords_ptr = NULL;
802 [ # # ][ # # ]: 0 : MB_SET_ERR( rval, "Couldn't find sequence for start handle" );
[ # # ][ # # ]
[ # # ]
803 : : }
804 [ - + ]: 12 : VertexSequence* vseq = dynamic_cast< VertexSequence* >( seq );
805 [ - + ][ # # ]: 12 : if( !vseq ) { MB_SET_ERR( MB_ENTITY_NOT_FOUND, "Couldn't find sequence for start handle" ); }
[ # # ][ # # ]
[ # # ][ # # ]
806 : :
807 [ + - ][ + - ]: 12 : unsigned int offset = *iter - vseq->data()->start_handle();
[ + - ]
808 [ + - ][ + - ]: 12 : xcoords_ptr = reinterpret_cast< double* >( vseq->data()->get_sequence_data( 0 ) ) + offset;
809 [ + - ][ + - ]: 12 : ycoords_ptr = reinterpret_cast< double* >( vseq->data()->get_sequence_data( 1 ) ) + offset;
810 [ + - ][ + - ]: 12 : zcoords_ptr = reinterpret_cast< double* >( vseq->data()->get_sequence_data( 2 ) ) + offset;
811 : :
812 [ + - ][ + - ]: 12 : EntityHandle real_end = std::min( seq->end_handle(), *( iter.end_of_block() ) );
[ + - ][ + - ]
813 [ + - ][ - + ]: 12 : if( *end ) real_end = std::min( real_end, *end );
[ # # ][ # # ]
814 [ + - ]: 12 : count = real_end - *iter + 1;
815 : :
816 : 12 : return MB_SUCCESS;
817 : : }
818 : :
819 : 69879 : ErrorCode Core::get_coords( const Range& entities, double* coords ) const
820 : : {
821 [ + - ][ + - ]: 69879 : const TypeSequenceManager& vert_data = sequence_manager()->entity_map( MBVERTEX );
822 [ + - ]: 69879 : TypeSequenceManager::const_iterator seq_iter;
823 : :
824 [ + - ]: 69879 : Range::const_pair_iterator i = entities.const_pair_begin();
825 [ + - ]: 69879 : EntityHandle first = i->first;
826 [ + - ][ + - ]: 1293764 : while( i != entities.const_pair_end() && TYPE_FROM_HANDLE( i->first ) == MBVERTEX )
[ + + ][ + - ]
[ + - ][ + - ]
[ + - ]
[ + + # # ]
827 : : {
828 : :
829 [ + - ]: 1223885 : seq_iter = vert_data.lower_bound( first );
830 [ + - ][ + - ]: 1223885 : if( seq_iter == vert_data.end() || first < ( *seq_iter )->start_handle() ) return MB_ENTITY_NOT_FOUND;
[ + - ][ + - ]
[ + - ][ - + ]
[ + - ][ - + ]
[ # # ]
831 [ + - ]: 1223885 : const VertexSequence* vseq = reinterpret_cast< const VertexSequence* >( *seq_iter );
832 : :
833 [ + - ]: 1223885 : EntityID offset = first - vseq->start_handle();
834 : : EntityID count;
835 [ + - ][ + - ]: 1223885 : if( i->second <= vseq->end_handle() )
[ + - ]
836 : : {
837 [ + - ]: 1223885 : count = i->second - first + 1;
838 [ + - ]: 1223885 : ++i;
839 [ + - ][ + - ]: 1223885 : if( i != entities.const_pair_end() ) first = i->first;
[ + + ][ + - ]
840 : : }
841 : : else
842 : : {
843 [ # # ]: 0 : count = vseq->end_handle() - first + 1;
844 [ # # ]: 0 : first = vseq->end_handle() + 1;
845 : : }
846 : :
847 : : double const *x, *y, *z;
848 [ + - ][ - + ]: 1223885 : ErrorCode rval = vseq->get_coordinate_arrays( x, y, z );MB_CHK_ERR( rval );
[ # # ][ # # ]
849 : 1223885 : x += offset;
850 : 1223885 : y += offset;
851 : 1223885 : z += offset;
852 [ + + ]: 3297010 : for( EntityID j = 0; j < count; ++j )
853 : : {
854 : 2073125 : coords[3 * j] = x[j];
855 : 2073125 : coords[3 * j + 1] = y[j];
856 : 2073125 : coords[3 * j + 2] = z[j];
857 : : }
858 : 1223885 : coords = &coords[3 * count];
859 : : }
860 : :
861 : : // for non-vertices...
862 : 69879 : ErrorCode rval = MB_SUCCESS;
863 [ + - ][ + - ]: 69879 : for( Range::const_iterator rit( &( *i ), i->first ); rit != entities.end(); ++rit )
[ + - ][ # # ]
[ + - ][ + - ]
[ - + ]
864 : : {
865 [ # # ][ # # ]: 0 : rval = get_coords( &( *rit ), 1, coords );MB_CHK_ERR( rval );
[ # # ][ # # ]
[ # # ]
866 : 0 : coords += 3;
867 : : }
868 : :
869 : 69879 : return rval;
870 : : }
871 : :
872 : : /**\author Jason Kraftcheck <[email protected]> - 2007-5-15 */
873 : 2681 : ErrorCode Core::get_coords( const Range& entities, double* x_coords, double* y_coords, double* z_coords ) const
874 : : {
875 [ + - ][ + - ]: 2681 : const TypeSequenceManager& vert_data = sequence_manager()->entity_map( MBVERTEX );
876 [ + - ]: 2681 : TypeSequenceManager::const_iterator seq_iter;
877 : :
878 [ + - ]: 2681 : Range::const_pair_iterator i = entities.const_pair_begin();
879 [ + - ]: 2681 : EntityHandle first = i->first;
880 [ + - ][ + - ]: 20583 : while( i != entities.const_pair_end() && TYPE_FROM_HANDLE( i->first ) == MBVERTEX )
[ + + ][ + - ]
[ + - ][ + - ]
[ + - ]
[ + + # # ]
881 : : {
882 : :
883 [ + - ]: 17903 : seq_iter = vert_data.lower_bound( first );
884 [ + - ][ + - ]: 17903 : if( seq_iter == vert_data.end() || first < ( *seq_iter )->start_handle() ) return MB_ENTITY_NOT_FOUND;
[ + + ][ + - ]
[ + - ][ - + ]
[ + - ][ + + ]
[ # # ]
885 [ + - ]: 17902 : const VertexSequence* vseq = reinterpret_cast< const VertexSequence* >( *seq_iter );
886 : :
887 [ + - ]: 17902 : EntityID offset = first - vseq->start_handle();
888 : : EntityID count;
889 [ + - ][ + - ]: 17902 : if( i->second <= vseq->end_handle() )
[ + + ]
890 : : {
891 [ + - ]: 17876 : count = i->second - first + 1;
892 [ + - ]: 17876 : ++i;
893 [ + - ][ + - ]: 17876 : if( i != entities.const_pair_end() ) first = i->first;
[ + + ][ + - ]
894 : : }
895 : : else
896 : : {
897 [ + - ]: 26 : count = vseq->end_handle() - first + 1;
898 [ + - ]: 26 : first = vseq->end_handle() + 1;
899 : : }
900 : :
901 : : double const *x, *y, *z;
902 [ + - ][ - + ]: 17902 : ErrorCode rval = vseq->get_coordinate_arrays( x, y, z );MB_CHK_ERR( rval );
[ # # ][ # # ]
903 [ + - ]: 17902 : if( x_coords )
904 : : {
905 : 17902 : memcpy( x_coords, x + offset, count * sizeof( double ) );
906 : 17902 : x_coords += count;
907 : : }
908 [ + - ]: 17902 : if( y_coords )
909 : : {
910 : 17902 : memcpy( y_coords, y + offset, count * sizeof( double ) );
911 : 17902 : y_coords += count;
912 : : }
913 [ + - ]: 17902 : if( z_coords )
914 : : {
915 : 17902 : memcpy( z_coords, z + offset, count * sizeof( double ) );
916 : 17902 : z_coords += count;
917 : : }
918 : : }
919 : :
920 : : // for non-vertices...
921 : 2680 : ErrorCode rval = MB_SUCCESS;
922 : : double xyz[3];
923 [ + - ][ + - ]: 2680 : for( Range::const_iterator rit( &( *i ), i->first ); rit != entities.end(); ++rit )
[ + - ][ # # ]
[ + - ][ + - ]
[ - + ]
924 : : {
925 [ # # ][ # # ]: 0 : rval = get_coords( &( *rit ), 1, xyz );MB_CHK_ERR( rval );
[ # # ][ # # ]
[ # # ]
926 : 0 : *x_coords++ = xyz[0];
927 : 0 : *y_coords++ = xyz[1];
928 : 0 : *z_coords++ = xyz[2];
929 : : }
930 : :
931 : 2681 : return rval;
932 : : }
933 : :
934 : 5892573 : ErrorCode Core::get_coords( const EntityHandle* entities, const int num_entities, double* coords ) const
935 : : {
936 : 5892573 : const EntitySequence* seq = NULL;
937 : 5892573 : const VertexSequence* vseq = NULL;
938 : 5892573 : const EntityHandle* const end = entities + num_entities;
939 : 5892573 : const EntityHandle* iter = entities;
940 : 5892573 : ErrorCode status = MB_SUCCESS;
941 : :
942 [ + + ]: 18076916 : while( iter != end )
943 : : {
944 [ + - ][ + + ]: 12184343 : if( TYPE_FROM_HANDLE( *iter ) == MBVERTEX )
945 : : {
946 [ + + ]: 12184049 : if( !seq )
947 : : {
948 [ + - ][ + - ]: 5892279 : seq = sequence_manager()->get_last_accessed_sequence( MBVERTEX );
949 : 5892279 : vseq = static_cast< const VertexSequence* >( seq );
950 : : }
951 [ - + ]: 12184049 : if( !vseq )
952 : 0 : return MB_ENTITY_NOT_FOUND;
953 [ + - ][ + + ]: 12184049 : else if( vseq->start_handle() > *iter || vseq->end_handle() < *iter )
[ + - ][ + + ]
[ + + ]
954 : : {
955 [ + - ][ + - ]: 139419 : if( MB_SUCCESS != sequence_manager()->find( *iter, seq ) ) return MB_ENTITY_NOT_FOUND;
[ - + ]
956 : 139419 : vseq = static_cast< const VertexSequence* >( seq );
957 : : }
958 [ + - ]: 12184049 : vseq->get_coordinates( *iter, coords );
959 : : }
960 : : else
961 : : {
962 [ + + ][ + - ]: 294 : static std::vector< EntityHandle > dum_conn( CN::MAX_NODES_PER_ELEMENT );
[ + - ][ # # ]
963 [ + + ][ + - ]: 294 : static std::vector< double > dum_pos( 3 * CN::MAX_NODES_PER_ELEMENT );
[ + - ][ # # ]
964 : : static const EntityHandle* conn;
965 : : static int num_conn;
966 [ + - ][ - + ]: 294 : status = get_connectivity( *iter, conn, num_conn, false, &dum_conn );MB_CHK_ERR( status );
[ # # ][ # # ]
967 [ + - ][ + - ]: 294 : status = get_coords( conn, num_conn, &dum_pos[0] );MB_CHK_ERR( status );
[ - + ][ # # ]
[ # # ]
968 : 294 : coords[0] = coords[1] = coords[2] = 0.0;
969 [ + + ]: 1337 : for( int i = 0; i < num_conn; i++ )
970 : : {
971 [ + - ]: 1043 : coords[0] += dum_pos[3 * i];
972 [ + - ]: 1043 : coords[1] += dum_pos[3 * i + 1];
973 [ + - ]: 1043 : coords[2] += dum_pos[3 * i + 2];
974 : : }
975 : 294 : coords[0] /= num_conn;
976 : 294 : coords[1] /= num_conn;
977 : 294 : coords[2] /= num_conn;
978 : : }
979 : 12184343 : coords += 3;
980 : 12184343 : ++iter;
981 : : }
982 : :
983 : 5892573 : return status;
984 : : }
985 : :
986 : 0 : ErrorCode Core::get_coords( const EntityHandle entity_handle, const double*& x, const double*& y,
987 : : const double*& z ) const
988 : : {
989 : 0 : ErrorCode status = MB_TYPE_OUT_OF_RANGE;
990 : :
991 [ # # ]: 0 : if( TYPE_FROM_HANDLE( entity_handle ) == MBVERTEX )
992 : : {
993 : 0 : const EntitySequence* seq = 0;
994 [ # # ][ # # ]: 0 : status = sequence_manager()->find( entity_handle, seq );
995 : :
996 [ # # ][ # # ]: 0 : if( seq == 0 || status != MB_SUCCESS ) return MB_ENTITY_NOT_FOUND;
997 : :
998 [ # # ]: 0 : status = static_cast< const VertexSequence* >( seq )->get_coordinates_ref( entity_handle, x, y, z );
999 : : }
1000 : :
1001 : 0 : return status;
1002 : : }
1003 : :
1004 : : //! set the coordinate information for this handle if it is of type Vertex
1005 : : //! otherwise, return an error
1006 : 4937 : ErrorCode Core::set_coords( const EntityHandle* entity_handles, const int num_entities, const double* coords )
1007 : : {
1008 : :
1009 : 4937 : ErrorCode status = MB_SUCCESS;
1010 : :
1011 : 4937 : int i, j = 0;
1012 : :
1013 [ + + ]: 9922 : for( i = 0; i < num_entities; i++ )
1014 : : {
1015 [ + - ]: 4985 : if( TYPE_FROM_HANDLE( entity_handles[i] ) == MBVERTEX )
1016 : : {
1017 : 4985 : EntitySequence* seq = 0;
1018 [ + - ][ + - ]: 4985 : status = sequence_manager()->find( entity_handles[i], seq );
1019 : :
1020 [ + - ][ + - ]: 4985 : if( seq != 0 && status == MB_SUCCESS )
1021 : : {
1022 : 9970 : status = static_cast< VertexSequence* >( seq )->set_coordinates( entity_handles[i], coords[j],
1023 [ + - ]: 4985 : coords[j + 1], coords[j + 2] );
1024 : 4985 : j += 3;
1025 : : }
1026 : : }
1027 [ # # ]: 0 : else if( status == MB_SUCCESS )
1028 : 0 : status = MB_TYPE_OUT_OF_RANGE;
1029 : : }
1030 : :
1031 : 4937 : return status;
1032 : : }
1033 : :
1034 : : //! set the coordinate information for this handle if it is of type Vertex
1035 : : //! otherwise, return an error
1036 : 6 : ErrorCode Core::set_coords( Range entity_handles, const double* coords )
1037 : : {
1038 : :
1039 : 6 : ErrorCode status = MB_SUCCESS;
1040 : :
1041 : 6 : int j = 0;
1042 : :
1043 [ + - ][ + - ]: 2449 : for( Range::iterator rit = entity_handles.begin(); rit != entity_handles.end(); ++rit )
[ + - ][ + - ]
[ + + ]
1044 : : {
1045 [ + - ][ + - ]: 2443 : if( TYPE_FROM_HANDLE( *rit ) == MBVERTEX )
[ + - ]
1046 : : {
1047 : 2443 : EntitySequence* seq = 0;
1048 [ + - ][ + - ]: 2443 : status = sequence_manager()->find( *rit, seq );
[ + - ]
1049 : :
1050 [ + - ][ + - ]: 2443 : if( seq != 0 && status == MB_SUCCESS )
1051 : : {
1052 [ + - ]: 2443 : status = static_cast< VertexSequence* >( seq )->set_coordinates( *rit, coords[j], coords[j + 1],
1053 [ + - ]: 2443 : coords[j + 2] );
1054 : 2443 : j += 3;
1055 : : }
1056 : : }
1057 [ # # ]: 0 : else if( status == MB_SUCCESS )
1058 : 0 : status = MB_TYPE_OUT_OF_RANGE;
1059 : : }
1060 : :
1061 : 6 : return status;
1062 : : }
1063 : :
1064 : 0 : double Core::get_sequence_multiplier() const
1065 : : {
1066 : 0 : return sequenceManager->get_sequence_multiplier();
1067 : : }
1068 : :
1069 : 0 : void Core::set_sequence_multiplier( double factor )
1070 : : {
1071 [ # # ]: 0 : assert( factor >= 1.0 );
1072 : 0 : sequenceManager->set_sequence_multiplier( factor );
1073 : 0 : }
1074 : :
1075 : : //! get global connectivity array for specified entity type
1076 : : /** Assumes just vertices, no higher order nodes
1077 : : */
1078 : 0 : ErrorCode Core::get_connectivity_by_type( const EntityType entity_type, std::vector< EntityHandle >& connect ) const
1079 : : {
1080 : : // inefficient implementation until we get blocked tag access
1081 : :
1082 : : // get the range of entities of this type
1083 [ # # ]: 0 : Range this_range;
1084 [ # # ]: 0 : ErrorCode result = get_entities_by_type( 0, entity_type, this_range );
1085 : :
1086 [ # # ]: 0 : int num_ents = this_range.size();
1087 [ # # ][ # # ]: 0 : connect.reserve( num_ents * CN::VerticesPerEntity( entity_type ) );
1088 : :
1089 : : // now loop over these entities, getting connectivity for each
1090 [ # # ][ # # ]: 0 : for( Range::iterator this_it = this_range.begin(); this_it != this_range.end(); ++this_it )
[ # # ][ # # ]
[ # # ]
1091 : : {
1092 : 0 : const EntityHandle* connect_vec = NULL;
1093 [ # # ][ # # ]: 0 : result = get_connectivity( *this_it, connect_vec, num_ents, true );MB_CHK_ERR( result );
[ # # ][ # # ]
[ # # ]
1094 [ # # ]: 0 : connect.insert( connect.end(), &connect_vec[0], &connect_vec[num_ents] );
1095 : : }
1096 : :
1097 : 0 : return MB_SUCCESS;
1098 : : }
1099 : :
1100 : : //! get the connectivity for element /handles. For non-element handles, return an error
1101 : 206 : ErrorCode Core::get_connectivity( const EntityHandle* entity_handles, const int num_handles, Range& connectivity,
1102 : : bool corners_only ) const
1103 : : {
1104 [ + - ]: 206 : std::vector< EntityHandle > tmp_connect;
1105 [ + - ][ - + ]: 206 : ErrorCode result = get_connectivity( entity_handles, num_handles, tmp_connect, corners_only );MB_CHK_ERR( result );
[ # # ][ # # ]
1106 : :
1107 [ + - ]: 206 : std::sort( tmp_connect.begin(), tmp_connect.end() );
1108 [ + - ][ + - ]: 206 : std::copy( tmp_connect.rbegin(), tmp_connect.rend(), range_inserter( connectivity ) );
1109 : 206 : return result;
1110 : : }
1111 : :
1112 : : //! get the connectivity for element /handles. For non-element handles, return an error
1113 : 6139666 : ErrorCode Core::get_connectivity( const EntityHandle* entity_handles, const int num_handles,
1114 : : std::vector< EntityHandle >& connectivity, bool corners_only,
1115 : : std::vector< int >* offsets ) const
1116 : : {
1117 : 6139666 : connectivity.clear(); // this seems wrong as compared to other API functions,
1118 : : // but changing it breaks lost of code, so I'm leaving
1119 : : // it in. - j.kraftcheck 2009-11-06
1120 : :
1121 : : ErrorCode rval;
1122 [ + - ]: 6139666 : std::vector< EntityHandle > tmp_storage; // used only for structured mesh
1123 : : const EntityHandle* conn;
1124 : : int len;
1125 [ - + ][ # # ]: 6139666 : if( offsets ) offsets->push_back( 0 );
1126 [ + + ]: 12339111 : for( int i = 0; i < num_handles; ++i )
1127 : : {
1128 [ + - ][ - + ]: 6199445 : rval = get_connectivity( entity_handles[i], conn, len, corners_only, &tmp_storage );MB_CHK_ERR( rval );
[ # # ][ # # ]
1129 [ + - ]: 6199445 : connectivity.insert( connectivity.end(), conn, conn + len );
1130 [ - + ][ # # ]: 6199445 : if( offsets ) offsets->push_back( connectivity.size() );
1131 : : }
1132 : 6139666 : return MB_SUCCESS;
1133 : : }
1134 : :
1135 : : //! get the connectivity for element handles. For non-element handles, return an error
1136 : 23996752 : ErrorCode Core::get_connectivity( const EntityHandle entity_handle, const EntityHandle*& connectivity,
1137 : : int& number_nodes, bool corners_only, std::vector< EntityHandle >* storage ) const
1138 : : {
1139 : : ErrorCode status;
1140 : :
1141 : : // Make sure the entity should have a connectivity.
1142 [ + - ]: 23996752 : EntityType entity_type = TYPE_FROM_HANDLE( entity_handle );
1143 : :
1144 : : // WARNING: This is very dependent on the ordering of the EntityType enum
1145 [ + - ][ - + ]: 23996752 : if( entity_type < MBVERTEX || entity_type >= MBENTITYSET )
1146 : 0 : return MB_TYPE_OUT_OF_RANGE;
1147 : :
1148 [ - + ]: 23996752 : else if( entity_type == MBVERTEX )
1149 : : {
1150 : 0 : return MB_FAILURE;
1151 : : }
1152 : :
1153 : 23996752 : const EntitySequence* seq = 0;
1154 : :
1155 : : // We know that connectivity is stored in an EntitySequence so jump straight
1156 : : // to the entity sequence
1157 [ + - ][ + - ]: 23996752 : status = sequence_manager()->find( entity_handle, seq );
1158 [ + - ][ - + ]: 23996752 : if( seq == 0 || status != MB_SUCCESS ) return MB_ENTITY_NOT_FOUND;
1159 : :
1160 : : return static_cast< const ElementSequence* >( seq )->get_connectivity( entity_handle, connectivity, number_nodes,
1161 [ + - ]: 23996752 : corners_only, storage );
1162 : : }
1163 : :
1164 : : //! set the connectivity for element handles. For non-element handles, return an error
1165 : 3747 : ErrorCode Core::set_connectivity( const EntityHandle entity_handle, EntityHandle* connect, const int num_connect )
1166 : : {
1167 : 3747 : ErrorCode status = MB_FAILURE;
1168 : :
1169 : : // Make sure the entity should have a connectivity.
1170 : : // WARNING: This is very dependent on the ordering of the EntityType enum
1171 [ + - ]: 3747 : EntityType entity_type = TYPE_FROM_HANDLE( entity_handle );
1172 : :
1173 : 3747 : EntitySequence* seq = 0;
1174 : :
1175 [ + - ][ - + ]: 3747 : if( entity_type < MBVERTEX || entity_type > MBENTITYSET ) return MB_TYPE_OUT_OF_RANGE;
1176 : :
1177 [ + - ][ + - ]: 3747 : status = sequence_manager()->find( entity_handle, seq );
1178 [ + - ][ - + ]: 3747 : if( seq == 0 || status != MB_SUCCESS ) return ( status != MB_SUCCESS ? status : MB_ENTITY_NOT_FOUND );
[ # # ]
1179 : :
1180 : : const EntityHandle* old_conn;
1181 : : int len;
1182 [ + - ][ - + ]: 3747 : status = static_cast< ElementSequence* >( seq )->get_connectivity( entity_handle, old_conn, len );MB_CHK_ERR( status );
[ # # ][ # # ]
1183 : :
1184 [ + - ]: 3747 : aEntityFactory->notify_change_connectivity( entity_handle, old_conn, connect, num_connect );
1185 : :
1186 [ + - ]: 3747 : status = static_cast< ElementSequence* >( seq )->set_connectivity( entity_handle, connect, num_connect );
1187 [ - + ]: 3747 : if( status != MB_SUCCESS )
1188 [ # # ]: 0 : aEntityFactory->notify_change_connectivity( entity_handle, connect, old_conn, num_connect );
1189 : :
1190 : 3747 : return status;
1191 : : }
1192 : :
1193 : : template < typename ITER >
1194 : 192633 : static inline ErrorCode get_adjacencies_union( Core* gMB, ITER begin, ITER end, int to_dimension,
1195 : : bool create_if_missing, Range& adj_entities )
1196 : : {
1197 : 192633 : const size_t DEFAULT_MAX_BLOCKS_SIZE = 4000;
1198 : 192633 : const size_t MAX_OUTER_ITERATIONS = 100;
1199 : :
1200 [ + - ][ + - ]: 385266 : std::vector< EntityHandle > temp_vec, storage;
[ + - ][ + - ]
1201 : 192633 : std::vector< EntityHandle >::const_iterator ti;
1202 : 192633 : ErrorCode result = MB_SUCCESS, tmp_result;
1203 : 192633 : ITER i = begin;
1204 [ + - ][ + - ]: 192633 : Range::iterator ins;
1205 : : const EntityHandle* conn;
1206 : : int conn_len;
1207 : :
1208 : : // Just copy any vertices from the input range into the output
1209 [ + - ]: 117044 : size_t remaining = end - begin;
1210 [ + - ][ + - ]: 192633 : assert( begin + remaining == end );
[ - + ][ - + ]
1211 : :
1212 : : // How many entities to work with at once? 2000 or so shouldn't require
1213 : : // too much memory, but don't iterate in outer loop more than a
1214 : : // 1000 times (make it bigger if many input entiites.)
1215 [ + - ][ + - ]: 192633 : const size_t block_size = std::max( DEFAULT_MAX_BLOCKS_SIZE, remaining / MAX_OUTER_ITERATIONS );
1216 [ + + ][ + + ]: 328032 : while( remaining > 0 )
1217 : : {
1218 [ + + ][ - + ]: 135399 : const size_t count = remaining > block_size ? block_size : remaining;
1219 : 135399 : remaining -= count;
1220 : 135399 : temp_vec.clear();
1221 [ + - ][ + + ]: 329536 : for( size_t j = 0; j < count; ++i, ++j )
[ + + ]
1222 : : {
1223 [ + - ][ + - ]: 194137 : if( CN::Dimension( TYPE_FROM_HANDLE( *i ) ) == to_dimension ) { temp_vec.push_back( *i ); }
[ + - ][ + + ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + + ][ + - ]
1224 [ - + ][ # # ]: 194029 : else if( to_dimension == 0 && TYPE_FROM_HANDLE( *i ) != MBPOLYHEDRON )
[ # # ][ # # ]
[ - + ][ + + ]
[ + - ][ + + ]
[ + + ]
1225 : : {
1226 [ # # ][ # # ]: 8897 : tmp_result = gMB->get_connectivity( *i, conn, conn_len, false, &storage );
[ + - ]
1227 [ # # ][ - + ]: 8897 : if( MB_SUCCESS != tmp_result )
1228 : : {
1229 : 0 : result = tmp_result;
1230 : 0 : continue;
1231 : : }
1232 [ # # ][ + - ]: 8897 : temp_vec.insert( temp_vec.end(), conn, conn + conn_len );
1233 : : }
1234 : : else
1235 : : {
1236 [ + - ][ + - ]: 185132 : tmp_result = gMB->a_entity_factory()->get_adjacencies( *i, to_dimension, create_if_missing, temp_vec );
[ + - ][ + - ]
[ + - ]
1237 [ - + ][ - + ]: 185132 : if( MB_SUCCESS != tmp_result )
1238 : : {
1239 : 0 : result = tmp_result;
1240 : 0 : continue;
1241 : : }
1242 : : }
1243 : : }
1244 : :
1245 [ + - ][ + - ]: 135399 : std::sort( temp_vec.begin(), temp_vec.end() );
1246 [ + - ][ + - ]: 135399 : ins = adj_entities.begin();
1247 [ + - ][ + - ]: 135399 : ti = temp_vec.begin();
1248 [ + - ][ + + ]: 307012 : while( ti != temp_vec.end() )
[ + - ][ + + ]
1249 : : {
1250 [ + - ][ + - ]: 171613 : EntityHandle first = *ti;
1251 [ + - ][ + - ]: 171613 : EntityHandle second = *ti;
1252 [ + - ][ + - ]: 396331 : for( ++ti; ti != temp_vec.end() && ( *ti - second <= 1 ); ++ti )
[ + - ][ + + ]
[ + - ][ + + ]
[ + - ]
[ + + # # ]
[ + - ][ + - ]
[ + - ][ + + ]
[ + - ][ + + ]
[ + - ]
[ + + # # ]
1253 [ + - ][ + - ]: 224718 : second = *ti;
1254 [ + - ][ + - ]: 171613 : ins = adj_entities.insert( ins, first, second );
1255 : : }
1256 : : }
1257 : 192633 : return result;
1258 : : }
1259 : :
1260 : : template < typename ITER >
1261 : 580212 : static inline ErrorCode get_adjacencies_intersection( Core* mb, ITER begin, ITER end, const int to_dimension,
1262 : : const bool create_if_missing,
1263 : : std::vector< EntityHandle >& adj_entities )
1264 : : {
1265 : 580212 : const size_t SORT_THRESHOLD = 200;
1266 [ + - ][ + - ]: 580212 : std::vector< EntityHandle > temp_vec;
1267 : 580212 : std::vector< EntityHandle >::iterator adj_it, w_it;
1268 : 580212 : ErrorCode result = MB_SUCCESS;
1269 : :
1270 [ + - ][ + + ]: 580212 : if( begin == end )
[ - + ]
1271 : : {
1272 : 50 : adj_entities.clear(); // intersection
1273 : 50 : return MB_SUCCESS;
1274 : : }
1275 : :
1276 : : // First iteration is a special case if input list is empty.
1277 : : // Rather than returning nothing (intersecting with empty
1278 : : // input list), we begin with the adjacencies for the first entity.
1279 [ + - ][ + - ]: 580162 : if( adj_entities.empty() )
1280 : : {
1281 [ + - ][ + - ]: 580162 : EntityType entity_type = TYPE_FROM_HANDLE( *begin );
[ + - ]
1282 [ + - ][ - + ]: 580162 : if( to_dimension == CN::Dimension( entity_type ) )
[ + - ][ + + ]
1283 [ # # ][ # # ]: 4 : adj_entities.push_back( *begin );
[ + - ]
1284 [ - + ][ # # ]: 580833 : else if( to_dimension == 0 && entity_type != MBPOLYHEDRON )
[ + + ][ + + ]
1285 : : {
1286 [ # # ][ # # ]: 675 : result = mb->get_connectivity( &( *begin ), 1, adj_entities );MB_CHK_ERR( result );
[ # # ][ # # ]
[ # # ][ + - ]
[ - + ][ # # ]
[ # # ]
1287 : : }
1288 : : else
1289 : : {
1290 [ + - ][ + - ]: 579483 : result = mb->a_entity_factory()->get_adjacencies( *begin, to_dimension, create_if_missing, adj_entities );MB_CHK_ERR( result );
[ + - ][ - + ]
[ # # ][ # # ]
[ + - ][ + - ]
[ - + ][ # # ]
[ # # ]
1291 : : }
1292 [ + - ]: 580162 : ++begin;
1293 : : }
1294 : :
1295 [ + - ][ + - ]: 1313121 : for( ITER from_it = begin; from_it != end; ++from_it )
[ + + ][ + + ]
1296 : : {
1297 : : // running results kept in adj_entities; clear temp_vec, which is working space
1298 : 735848 : temp_vec.clear();
1299 : :
1300 : : // get the next set of adjacencies
1301 [ + - ]: 735848 : EntityType entity_type = TYPE_FROM_HANDLE( *from_it );
[ + - + - ]
1302 [ + - ][ - + ]: 735848 : if( to_dimension == CN::Dimension( entity_type ) )
[ + - ][ - + ]
1303 [ # # ][ # # ]: 0 : temp_vec.push_back( *from_it );
[ # # ]
1304 [ - + ][ # # ]: 735848 : else if( to_dimension == 0 && entity_type != MBPOLYHEDRON )
[ + + ][ - + ]
1305 : : {
1306 [ # # ][ # # ]: 0 : result = mb->get_connectivity( &( *from_it ), 1, temp_vec );MB_CHK_ERR( result );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1307 : : }
1308 : : else
1309 : : {
1310 [ + - ][ + - ]: 735848 : result = mb->a_entity_factory()->get_adjacencies( *from_it, to_dimension, create_if_missing, temp_vec );MB_CHK_ERR( result );
[ + - ][ - + ]
[ # # ][ # # ]
[ + - ][ + - ]
[ - + ][ # # ]
[ # # ]
1311 : : }
1312 : :
1313 : : // otherwise intersect with the current set of results
1314 : 735848 : w_it = adj_it = adj_entities.begin();
1315 [ + + + + ]: 735848 : if( temp_vec.size() * adj_entities.size() < SORT_THRESHOLD )
1316 : : {
1317 [ + - ][ + - ]: 3960249 : for( ; adj_it != adj_entities.end(); ++adj_it )
[ + + ][ + - ]
[ + - ][ + + ]
1318 [ + - ][ + - ]: 3292773 : if( std::find( temp_vec.begin(), temp_vec.end(), *adj_it ) != temp_vec.end() )
[ + - ][ + + ]
[ + - ][ + - ]
[ + - ][ + + ]
1319 : : {
1320 [ + - ][ + - ]: 1392153 : *w_it = *adj_it;
[ + - ][ + - ]
1321 [ + - ][ + - ]: 1392153 : ++w_it;
1322 : : }
1323 : : }
1324 : : else
1325 : : {
1326 [ + - ][ + - ]: 68372 : std::sort( temp_vec.begin(), temp_vec.end() );
1327 [ + - ][ + - ]: 1605290 : for( ; adj_it != adj_entities.end(); ++adj_it )
[ + + ][ + - ]
[ + - ][ + + ]
1328 [ + - ][ + - ]: 1536918 : if( std::binary_search( temp_vec.begin(), temp_vec.end(), *adj_it ) )
[ + + ][ + - ]
[ + - ][ + + ]
1329 : : {
1330 [ + - ][ + - ]: 360187 : *w_it = *adj_it;
[ + - ][ + - ]
1331 [ + - ][ + - ]: 360187 : ++w_it;
1332 : : }
1333 : : }
1334 [ + - ][ + - ]: 735848 : adj_entities.erase( w_it, adj_entities.end() );
1335 : :
1336 : : // we're intersecting, so if there are no more results, we're done
1337 [ + + ][ + + ]: 735848 : if( adj_entities.empty() ) break;
1338 : : }
1339 : :
1340 : 580212 : return MB_SUCCESS;
1341 : : }
1342 : :
1343 : : template < typename ITER >
1344 : 310543 : static inline ErrorCode get_adjacencies_intersection( Core* mb, ITER begin, ITER end, const int to_dimension,
1345 : : const bool create_if_missing, Range& adj_entities )
1346 : : {
1347 [ + - ][ + - ]: 310543 : std::vector< EntityHandle > results;
1348 [ + - ][ - + ]: 310543 : ErrorCode rval = moab::get_adjacencies_intersection( mb, begin, end, to_dimension, create_if_missing, results );MB_CHK_ERR( rval );
[ # # ][ # # ]
[ + - ][ - + ]
[ # # ][ # # ]
1349 : :
1350 [ + - ][ + - ]: 310543 : if( adj_entities.empty() )
[ + - ][ + + ]
1351 : : {
1352 [ + - ][ + - ]: 310538 : std::copy( results.begin(), results.end(), range_inserter( adj_entities ) );
[ + - ][ + - ]
1353 : 310538 : return MB_SUCCESS;
1354 : : }
1355 : :
1356 [ # # ][ + - ]: 5 : Range::iterator it = adj_entities.begin();
1357 [ # # ][ # # ]: 16 : while( it != adj_entities.end() )
[ # # ][ + - ]
[ + - ][ + + ]
1358 : : {
1359 [ # # ][ # # ]: 11 : if( std::find( results.begin(), results.end(), *it ) == results.end() )
[ # # ][ # # ]
[ + - ][ + - ]
[ + - ][ + + ]
1360 [ # # ][ + - ]: 5 : it = adj_entities.erase( it );
1361 : : else
1362 [ # # ][ + - ]: 6 : ++it;
1363 : : }
1364 : 310543 : return MB_SUCCESS;
1365 : : }
1366 : :
1367 : : ///////////////////////////////////////////////////////////////////
1368 : : //////////////////////////////////////////
1369 : : #ifdef MOAB_HAVE_AHF
1370 : :
1371 : : template < typename ITER >
1372 : : static inline ErrorCode get_adjacencies_intersection_ahf( Core* mb, ITER begin, ITER end, const int to_dimension,
1373 : : std::vector< EntityHandle >& adj_entities )
1374 : : {
1375 : : const size_t SORT_THRESHOLD = 200;
1376 : : std::vector< EntityHandle > temp_vec;
1377 : : std::vector< EntityHandle >::iterator adj_it, w_it;
1378 : : ErrorCode result = MB_SUCCESS;
1379 : :
1380 : : if( begin == end )
1381 : : {
1382 : : adj_entities.clear(); // intersection
1383 : : return MB_SUCCESS;
1384 : : }
1385 : :
1386 : : // First iteration is a special case if input list is empty.
1387 : : // Rather than returning nothing (intersecting with empty
1388 : : // input list), we begin with the adjacencies for the first entity.
1389 : : if( adj_entities.empty() )
1390 : : {
1391 : : EntityType entity_type = TYPE_FROM_HANDLE( *begin );
1392 : :
1393 : : if( to_dimension == 0 && entity_type != MBPOLYHEDRON )
1394 : : result = mb->get_connectivity( &( *begin ), 1, adj_entities );
1395 : : else
1396 : : result = mb->a_half_facet_rep()->get_adjacencies( *begin, to_dimension, adj_entities );
1397 : : if( MB_SUCCESS != result ) return result;
1398 : : ++begin;
1399 : : }
1400 : :
1401 : : for( ITER from_it = begin; from_it != end; ++from_it )
1402 : : {
1403 : : // running results kept in adj_entities; clear temp_vec, which is working space
1404 : : temp_vec.clear();
1405 : :
1406 : : // get the next set of adjacencies
1407 : : EntityType entity_type = TYPE_FROM_HANDLE( *from_it );
1408 : : if( to_dimension == 0 && entity_type != MBPOLYHEDRON )
1409 : : result = mb->get_connectivity( &( *from_it ), 1, temp_vec );
1410 : : else
1411 : : result = mb->a_half_facet_rep()->get_adjacencies( *from_it, to_dimension, temp_vec );
1412 : : if( MB_SUCCESS != result ) return result;
1413 : :
1414 : : // otherwise intersect with the current set of results
1415 : : w_it = adj_it = adj_entities.begin();
1416 : : if( temp_vec.size() * adj_entities.size() < SORT_THRESHOLD )
1417 : : {
1418 : : for( ; adj_it != adj_entities.end(); ++adj_it )
1419 : : if( std::find( temp_vec.begin(), temp_vec.end(), *adj_it ) != temp_vec.end() )
1420 : : {
1421 : : *w_it = *adj_it;
1422 : : ++w_it;
1423 : : }
1424 : : }
1425 : : else
1426 : : {
1427 : : std::sort( temp_vec.begin(), temp_vec.end() );
1428 : : for( ; adj_it != adj_entities.end(); ++adj_it )
1429 : : if( std::binary_search( temp_vec.begin(), temp_vec.end(), *adj_it ) )
1430 : : {
1431 : : *w_it = *adj_it;
1432 : : ++w_it;
1433 : : }
1434 : : }
1435 : : adj_entities.erase( w_it, adj_entities.end() );
1436 : :
1437 : : // we're intersecting, so if there are no more results, we're done
1438 : : if( adj_entities.empty() ) break;
1439 : : }
1440 : :
1441 : : return MB_SUCCESS;
1442 : : }
1443 : : #endif
1444 : :
1445 : : ///////////////////////////////////////////
1446 : :
1447 : 269720 : ErrorCode Core::get_adjacencies( const EntityHandle* from_entities, const int num_entities, const int to_dimension,
1448 : : const bool create_if_missing, std::vector< EntityHandle >& adj_entities,
1449 : : const int operation_type )
1450 : : {
1451 : :
1452 : : #ifdef MOAB_HAVE_AHF
1453 : : bool can_handle = true;
1454 : :
1455 : : if( to_dimension == 4 )
1456 : : can_handle = false; // NOT SUPPORTED: meshsets
1457 : : else if( create_if_missing )
1458 : : can_handle = false; // NOT SUPPORTED: create_if_missing
1459 : :
1460 : : bool mixed = ahfRep->check_mixed_entity_type(); // NOT SUPPORTED: mixed entity types or
1461 : : // polygonal/hedrals types
1462 : : if( mixed ) can_handle = false;
1463 : :
1464 : : if( mesh_modified ) // NOT SUPPORTED: modified mesh
1465 : : can_handle = false;
1466 : :
1467 : : if( can_handle )
1468 : : {
1469 : : ErrorCode result;
1470 : : if( operation_type == Interface::INTERSECT )
1471 : : return get_adjacencies_intersection_ahf( this, from_entities, from_entities + num_entities, to_dimension,
1472 : : adj_entities );
1473 : : else if( operation_type != Interface::UNION )
1474 : : return MB_FAILURE;
1475 : :
1476 : : // do union
1477 : :
1478 : : std::vector< EntityHandle > tmp_storage;
1479 : : const EntityHandle* conn;
1480 : : int len;
1481 : : for( int i = 0; i < num_entities; ++i )
1482 : : {
1483 : : if( to_dimension == 0 && TYPE_FROM_HANDLE( from_entities[0] ) != MBPOLYHEDRON )
1484 : : {
1485 : : result = get_connectivity( from_entities[i], conn, len, false, &tmp_storage );
1486 : : adj_entities.insert( adj_entities.end(), conn, conn + len );
1487 : : if( MB_SUCCESS != result ) return result;
1488 : : }
1489 : : else
1490 : : {
1491 : : result = ahfRep->get_adjacencies( from_entities[i], to_dimension, adj_entities );
1492 : : if( MB_SUCCESS != result ) return result;
1493 : : }
1494 : : }
1495 : : std::sort( adj_entities.begin(), adj_entities.end() );
1496 : : adj_entities.erase( std::unique( adj_entities.begin(), adj_entities.end() ), adj_entities.end() );
1497 : : }
1498 : : else
1499 : : {
1500 : :
1501 : : #endif
1502 : :
1503 [ + + ]: 269720 : if( operation_type == Interface::INTERSECT )
1504 : : return get_adjacencies_intersection( this, from_entities, from_entities + num_entities, to_dimension,
1505 [ + - ]: 269669 : create_if_missing, adj_entities );
1506 [ - + ]: 51 : else if( operation_type != Interface::UNION )
1507 : 0 : return MB_FAILURE;
1508 : :
1509 : : // do union
1510 : : ErrorCode result;
1511 [ + - ]: 51 : std::vector< EntityHandle > tmp_storage;
1512 : : const EntityHandle* conn;
1513 : : int len;
1514 [ + + ]: 229 : for( int i = 0; i < num_entities; ++i )
1515 : : {
1516 [ + + ][ + - ]: 178 : if( to_dimension == 0 && TYPE_FROM_HANDLE( from_entities[0] ) != MBPOLYHEDRON )
[ + - ][ + + ]
1517 : : {
1518 [ + - ][ - + ]: 119 : result = get_connectivity( from_entities[i], conn, len, false, &tmp_storage );MB_CHK_ERR( result );
[ # # ][ # # ]
1519 [ + - ]: 119 : adj_entities.insert( adj_entities.end(), conn, conn + len );
1520 : : }
1521 : : else
1522 : : {
1523 : : result =
1524 [ + - ][ - + ]: 59 : aEntityFactory->get_adjacencies( from_entities[i], to_dimension, create_if_missing, adj_entities );MB_CHK_ERR( result );
[ # # ][ # # ]
1525 : : }
1526 : : }
1527 [ + - ]: 51 : std::sort( adj_entities.begin(), adj_entities.end() );
1528 [ + - ][ + - ]: 51 : adj_entities.erase( std::unique( adj_entities.begin(), adj_entities.end() ), adj_entities.end() );
1529 : :
1530 : : // return MB_SUCCESS;
1531 : :
1532 : : #ifdef MOAB_HAVE_AHF
1533 : : }
1534 : : #endif
1535 : :
1536 : 269720 : return MB_SUCCESS;
1537 : : }
1538 : :
1539 : 384845 : ErrorCode Core::get_adjacencies( const EntityHandle* from_entities, const int num_entities, const int to_dimension,
1540 : : const bool create_if_missing, Range& adj_entities, const int operation_type )
1541 : : {
1542 [ + + ]: 384845 : if( operation_type == Interface::INTERSECT )
1543 : : return get_adjacencies_intersection( this, from_entities, from_entities + num_entities, to_dimension,
1544 : 309256 : create_if_missing, adj_entities );
1545 [ + - ]: 75589 : else if( operation_type == Interface::UNION )
1546 : : return get_adjacencies_union( this, from_entities, from_entities + num_entities, to_dimension,
1547 : 75589 : create_if_missing, adj_entities );
1548 : : else
1549 : 0 : return MB_FAILURE;
1550 : : }
1551 : :
1552 : 27684 : ErrorCode Core::get_connectivity( const Range& from_entities, Range& adj_entities, bool corners_only ) const
1553 : : {
1554 : 27684 : const size_t DEFAULT_MAX_BLOCKS_SIZE = 4000;
1555 : 27684 : const size_t MAX_OUTER_ITERATIONS = 100;
1556 : :
1557 [ + - ][ + - ]: 55368 : std::vector< EntityHandle > temp_vec, storage;
1558 : 27684 : std::vector< EntityHandle >::const_iterator ti;
1559 : 27684 : ErrorCode result = MB_SUCCESS, tmp_result;
1560 [ + - ]: 27684 : Range::const_iterator i = from_entities.begin();
1561 [ + - ]: 27684 : Range::iterator ins;
1562 : : const EntityHandle* conn;
1563 : : int conn_len;
1564 : :
1565 : : // Just copy any vertices from the input range into the output
1566 [ + - ]: 27684 : size_t remaining = from_entities.size();
1567 [ + - ][ + - ]: 43418 : for( ; i != from_entities.end() && TYPE_FROM_HANDLE( *i ) == MBVERTEX; ++i )
[ + - ][ + + ]
[ + - ][ + - ]
[ + + ][ + - ]
[ + + # # ]
1568 : 15734 : --remaining;
1569 [ + - ][ + - ]: 27684 : adj_entities.merge( from_entities.begin(), i );
1570 : :
1571 : : // How many entities to work with at once? 2000 or so shouldn't require
1572 : : // too much memory, but don't iterate in outer loop more than a
1573 : : // 1000 times (make it bigger if many input entiites.)
1574 [ + - ]: 27684 : const size_t block_size = std::max( DEFAULT_MAX_BLOCKS_SIZE, remaining / MAX_OUTER_ITERATIONS );
1575 [ + + ]: 54738 : while( remaining > 0 )
1576 : : {
1577 [ + + ]: 27054 : const size_t count = remaining > block_size ? block_size : remaining;
1578 : 27054 : remaining -= count;
1579 : 27054 : temp_vec.clear();
1580 [ + - ][ + + ]: 927286 : for( size_t j = 0; j < count; ++i, ++j )
1581 : : {
1582 [ + - ][ + - ]: 900232 : tmp_result = get_connectivity( *i, conn, conn_len, corners_only, &storage );
1583 [ - + ]: 900232 : if( MB_SUCCESS != tmp_result )
1584 : : {
1585 : 0 : result = tmp_result;
1586 : 0 : continue;
1587 : : }
1588 : :
1589 : 900232 : const size_t oldsize = temp_vec.size();
1590 [ + - ]: 900232 : temp_vec.resize( oldsize + conn_len );
1591 [ + - ]: 900232 : memcpy( &temp_vec[oldsize], conn, sizeof( EntityHandle ) * conn_len );
1592 : : }
1593 : :
1594 [ + - ]: 27054 : std::sort( temp_vec.begin(), temp_vec.end() );
1595 [ + - ]: 27054 : ins = adj_entities.begin();
1596 [ + - ]: 27054 : ti = temp_vec.begin();
1597 [ + - ][ + + ]: 252920 : while( ti != temp_vec.end() )
1598 : : {
1599 [ + - ]: 225866 : EntityHandle first = *ti;
1600 [ + - ]: 225866 : EntityHandle second = *ti;
1601 [ + - ][ + - ]: 2757050 : for( ++ti; ti != temp_vec.end() && ( *ti - second <= 1 ); ++ti )
[ + - ][ + + ]
[ + - ][ + + ]
[ + - ]
[ + + # # ]
1602 [ + - ]: 2531184 : second = *ti;
1603 [ + - ]: 225866 : ins = adj_entities.insert( ins, first, second );
1604 : : }
1605 : : }
1606 : 27684 : return result;
1607 : : }
1608 : :
1609 : 13 : ErrorCode Core::connect_iterate( Range::const_iterator iter, Range::const_iterator end, EntityHandle*& connect,
1610 : : int& verts_per_entity, int& count )
1611 : : {
1612 : : // Make sure the entity should have a connectivity.
1613 [ + - ][ + - ]: 13 : EntityType entity_type = TYPE_FROM_HANDLE( *iter );
1614 : :
1615 : : // WARNING: This is very dependent on the ordering of the EntityType enum
1616 [ + - ][ - + ]: 13 : if( entity_type <= MBVERTEX || entity_type >= MBENTITYSET ) return MB_TYPE_OUT_OF_RANGE;
1617 : :
1618 : 13 : EntitySequence* seq = NULL;
1619 : :
1620 : : // We know that connectivity is stored in an EntitySequence so jump straight
1621 : : // to the entity sequence
1622 [ + - ][ + - ]: 13 : ErrorCode rval = sequence_manager()->find( *iter, seq );
[ + - ]
1623 [ + - ][ - + ]: 13 : if( !seq || rval != MB_SUCCESS ) return MB_ENTITY_NOT_FOUND;
1624 : :
1625 [ - + ]: 13 : ElementSequence* eseq = dynamic_cast< ElementSequence* >( seq );
1626 [ - + ]: 13 : assert( eseq != NULL );
1627 : :
1628 [ + - ]: 13 : connect = eseq->get_connectivity_array();
1629 [ + + ][ + - ]: 13 : if( !connect ) { MB_SET_ERR( MB_FAILURE, "Couldn't find connectivity array for start handle" ); }
[ + - ][ + - ]
[ - + ][ + - ]
1630 : :
1631 [ + - ][ + - ]: 12 : connect += eseq->nodes_per_element() * ( *iter - eseq->start_handle() );
[ + - ]
1632 : :
1633 [ + - ][ + - ]: 12 : EntityHandle real_end = std::min( eseq->end_handle(), *( iter.end_of_block() ) );
[ + - ][ + - ]
1634 [ + - ][ - + ]: 12 : if( *end ) real_end = std::min( real_end, *end );
[ # # ][ # # ]
1635 [ + - ]: 12 : count = real_end - *iter + 1;
1636 : :
1637 [ + - ]: 12 : verts_per_entity = eseq->nodes_per_element();
1638 : :
1639 : 13 : return MB_SUCCESS;
1640 : : }
1641 : :
1642 : 27581 : ErrorCode Core::get_vertices( const Range& from_entities, Range& vertices )
1643 : : {
1644 [ + - ]: 27581 : Range range;
1645 [ + - ][ - + ]: 27581 : ErrorCode rval = get_connectivity( from_entities, range );MB_CHK_ERR( rval );
[ # # ][ # # ]
1646 : :
1647 : : // If input contained polyhedra, connectivity will contain faces.
1648 : : // Get vertices from faces.
1649 [ + - ][ - + ]: 27581 : if( !range.all_of_dimension( 0 ) )
1650 : : {
1651 [ # # ]: 0 : Range::iterator it = range.upper_bound( MBVERTEX );
1652 [ # # ]: 0 : Range polygons;
1653 [ # # ][ # # ]: 0 : polygons.merge( it, range.end() );
1654 [ # # ][ # # ]: 0 : range.erase( it, range.end() );
1655 [ # # ][ # # ]: 0 : rval = get_connectivity( polygons, range );MB_CHK_ERR( rval );
[ # # ][ # # ]
[ # # ]
1656 : : }
1657 : :
1658 [ + - ][ + + ]: 27581 : if( vertices.empty() )
1659 [ + - ]: 27578 : vertices.swap( range );
1660 : : else
1661 [ + - ]: 3 : vertices.merge( range );
1662 : 27581 : return MB_SUCCESS;
1663 : : }
1664 : :
1665 : 145912 : ErrorCode Core::get_adjacencies( const Range& from_entities, const int to_dimension, const bool create_if_missing,
1666 : : Range& adj_entities, const int operation_type )
1667 : : {
1668 [ + + ]: 145912 : if( operation_type == Interface::INTERSECT )
1669 : : return get_adjacencies_intersection( this, from_entities.begin(), from_entities.end(), to_dimension,
1670 : 1287 : create_if_missing, adj_entities );
1671 [ - + ]: 144625 : else if( operation_type != Interface::UNION )
1672 : 0 : return MB_FAILURE;
1673 [ + + ]: 144625 : else if( to_dimension == 0 )
1674 : 27581 : return get_vertices( from_entities, adj_entities );
1675 : : else
1676 : : return get_adjacencies_union( this, from_entities.begin(), from_entities.end(), to_dimension, create_if_missing,
1677 : 117044 : adj_entities );
1678 : : }
1679 : :
1680 : 91 : ErrorCode Core::add_adjacencies( const EntityHandle entity_handle, const EntityHandle* adjacencies,
1681 : : const int num_handles, bool both_ways )
1682 : : {
1683 : 91 : ErrorCode result = MB_SUCCESS;
1684 : :
1685 [ + + ]: 306 : for( const EntityHandle* it = adjacencies; it != adjacencies + num_handles; it++ )
1686 : : {
1687 [ - + ][ # # ]: 215 : result = aEntityFactory->add_adjacency( entity_handle, *it, both_ways );MB_CHK_ERR( result );
1688 : : }
1689 : :
1690 : 91 : return MB_SUCCESS;
1691 : : }
1692 : :
1693 : 0 : ErrorCode Core::add_adjacencies( const EntityHandle entity_handle, Range& adjacencies, bool both_ways )
1694 : : {
1695 : 0 : ErrorCode result = MB_SUCCESS;
1696 : :
1697 [ # # ][ # # ]: 0 : for( Range::iterator rit = adjacencies.begin(); rit != adjacencies.end(); ++rit )
[ # # ][ # # ]
[ # # ]
1698 : : {
1699 [ # # ][ # # ]: 0 : result = aEntityFactory->add_adjacency( entity_handle, *rit, both_ways );MB_CHK_ERR( result );
[ # # ][ # # ]
[ # # ]
1700 : : }
1701 : :
1702 : 0 : return MB_SUCCESS;
1703 : : }
1704 : :
1705 : 5 : ErrorCode Core::remove_adjacencies( const EntityHandle entity_handle, const EntityHandle* adjacencies,
1706 : : const int num_handles )
1707 : : {
1708 : 5 : ErrorCode result = MB_SUCCESS;
1709 : :
1710 [ + + ]: 10 : for( const EntityHandle* it = adjacencies; it != adjacencies + num_handles; it++ )
1711 : : {
1712 [ - + ][ # # ]: 5 : result = aEntityFactory->remove_adjacency( entity_handle, *it );MB_CHK_ERR( result );
1713 [ - + ][ # # ]: 5 : result = aEntityFactory->remove_adjacency( *it, entity_handle );MB_CHK_ERR( result );
1714 : : }
1715 : :
1716 : 5 : return MB_SUCCESS;
1717 : : }
1718 : :
1719 : 0 : ErrorCode Core::adjacencies_iterate( Range::const_iterator iter, Range::const_iterator end,
1720 : : const std::vector< EntityHandle >**& adjs_ptr, int& count )
1721 : : {
1722 : : // Make sure the entity should have a connectivity.
1723 [ # # ][ # # ]: 0 : EntityType entity_type = TYPE_FROM_HANDLE( *iter );
1724 : :
1725 : : // WARNING: This is very dependent on the ordering of the EntityType enum
1726 [ # # ][ # # ]: 0 : if( entity_type < MBVERTEX || entity_type > MBENTITYSET ) return MB_TYPE_OUT_OF_RANGE;
1727 : :
1728 : 0 : EntitySequence* seq = NULL;
1729 : :
1730 : : // We know that connectivity is stored in an EntitySequence so jump straight
1731 : : // to the entity sequence
1732 [ # # ][ # # ]: 0 : ErrorCode rval = sequence_manager()->find( *iter, seq );
[ # # ]
1733 [ # # ][ # # ]: 0 : if( !seq || rval != MB_SUCCESS ) return MB_ENTITY_NOT_FOUND;
1734 : :
1735 [ # # ][ # # ]: 0 : adjs_ptr = const_cast< const std::vector< EntityHandle >** >( seq->data()->get_adjacency_data() );
1736 [ # # ]: 0 : if( !adjs_ptr ) return rval;
1737 : :
1738 [ # # ][ # # ]: 0 : adjs_ptr += *iter - seq->data()->start_handle();
[ # # ]
1739 : :
1740 [ # # ][ # # ]: 0 : EntityHandle real_end = *( iter.end_of_block() );
1741 [ # # ][ # # ]: 0 : if( *end ) real_end = std::min( real_end, *end );
[ # # ][ # # ]
1742 [ # # ]: 0 : count = real_end - *iter + 1;
1743 : :
1744 : 0 : return MB_SUCCESS;
1745 : : }
1746 : :
1747 : 17911 : ErrorCode Core::get_entities_by_dimension( const EntityHandle meshset, const int dimension, Range& entities,
1748 : : const bool recursive ) const
1749 : : {
1750 : 17911 : ErrorCode result = MB_SUCCESS;
1751 [ + + ]: 17911 : if( meshset )
1752 : : {
1753 : : const EntitySequence* seq;
1754 [ + - ][ + - ]: 17568 : result = sequence_manager()->find( meshset, seq );MB_CHK_ERR( result );
[ - + ][ # # ]
[ # # ]
1755 : 17568 : const MeshSetSequence* mseq = reinterpret_cast< const MeshSetSequence* >( seq );
1756 [ + - ][ + - ]: 17568 : result = mseq->get_dimension( sequence_manager(), meshset, dimension, entities, recursive );MB_CHK_ERR( result );
[ - + ][ # # ]
[ # # ]
1757 : : }
1758 [ - + ]: 343 : else if( dimension > 3 )
1759 : : {
1760 : 0 : sequence_manager()->get_entities( MBENTITYSET, entities );
1761 : : }
1762 : : else
1763 : : {
1764 [ + - ][ + + ]: 1411 : for( EntityType this_type = CN::TypeDimensionMap[dimension].first;
1765 : 1411 : this_type <= CN::TypeDimensionMap[dimension].second; this_type++ )
1766 : : {
1767 [ + - ][ + - ]: 1068 : sequence_manager()->get_entities( this_type, entities );
1768 : : }
1769 : : }
1770 : :
1771 : 17911 : return MB_SUCCESS;
1772 : : }
1773 : :
1774 : 92 : ErrorCode Core::get_entities_by_dimension( const EntityHandle meshset, const int dimension,
1775 : : std::vector< EntityHandle >& entities, const bool recursive ) const
1776 : : {
1777 : 92 : ErrorCode result = MB_SUCCESS;
1778 [ + + ]: 92 : if( meshset )
1779 : : {
1780 : : const EntitySequence* seq;
1781 [ + - ][ + - ]: 66 : result = sequence_manager()->find( meshset, seq );MB_CHK_ERR( result );
[ - + ][ # # ]
[ # # ]
1782 : 66 : const MeshSetSequence* mseq = reinterpret_cast< const MeshSetSequence* >( seq );
1783 [ + - ][ + - ]: 66 : result = mseq->get_dimension( sequence_manager(), meshset, dimension, entities, recursive );MB_CHK_ERR( result );
[ - + ][ # # ]
[ # # ]
1784 : : }
1785 [ - + ]: 26 : else if( dimension > 3 )
1786 : : {
1787 : 0 : sequence_manager()->get_entities( MBENTITYSET, entities );
1788 : : }
1789 : : else
1790 : : {
1791 [ + - ][ + + ]: 103 : for( EntityType this_type = CN::TypeDimensionMap[dimension].first;
1792 : 103 : this_type <= CN::TypeDimensionMap[dimension].second; this_type++ )
1793 : : {
1794 [ + - ][ + - ]: 77 : sequence_manager()->get_entities( this_type, entities );
1795 : : }
1796 : : }
1797 : :
1798 : 92 : return MB_SUCCESS;
1799 : : }
1800 : :
1801 : 26746 : ErrorCode Core::get_entities_by_type( const EntityHandle meshset, const EntityType entity_type, Range& entities,
1802 : : const bool recursive ) const
1803 : : {
1804 : 26746 : ErrorCode result = MB_SUCCESS;
1805 [ + + ]: 26746 : if( meshset )
1806 : : {
1807 : : const EntitySequence* seq;
1808 [ + - ][ + - ]: 22177 : result = sequence_manager()->find( meshset, seq );MB_CHK_ERR( result );
[ - + ][ # # ]
[ # # ]
1809 : 22177 : const MeshSetSequence* mseq = reinterpret_cast< const MeshSetSequence* >( seq );
1810 [ + - ][ + - ]: 22177 : result = mseq->get_type( sequence_manager(), meshset, entity_type, entities, recursive );MB_CHK_ERR( result );
[ - + ][ # # ]
[ # # ]
1811 : : }
1812 : : else
1813 : : {
1814 : 4569 : sequence_manager()->get_entities( entity_type, entities );
1815 : : }
1816 : :
1817 : 26746 : return MB_SUCCESS;
1818 : : }
1819 : :
1820 : 389 : ErrorCode Core::get_entities_by_type( const EntityHandle meshset, const EntityType entity_type,
1821 : : std::vector< EntityHandle >& entities, const bool recursive ) const
1822 : : {
1823 : 389 : ErrorCode result = MB_SUCCESS;
1824 [ + + ]: 389 : if( meshset )
1825 : : {
1826 : : const EntitySequence* seq;
1827 [ + - ][ + - ]: 324 : result = sequence_manager()->find( meshset, seq );MB_CHK_ERR( result );
[ - + ][ # # ]
[ # # ]
1828 : 324 : const MeshSetSequence* mseq = reinterpret_cast< const MeshSetSequence* >( seq );
1829 [ + - ][ + - ]: 324 : result = mseq->get_type( sequence_manager(), meshset, entity_type, entities, recursive );MB_CHK_ERR( result );
[ - + ][ # # ]
[ # # ]
1830 : : }
1831 : : else
1832 : : {
1833 : 65 : sequence_manager()->get_entities( entity_type, entities );
1834 : : }
1835 : :
1836 : 389 : return MB_SUCCESS;
1837 : : }
1838 : :
1839 : 2738 : ErrorCode Core::get_entities_by_type_and_tag( const EntityHandle meshset, const EntityType entity_type, const Tag* tags,
1840 : : const void* const* values, const int num_tags, Range& entities,
1841 : : const int condition, const bool recursive ) const
1842 : : {
1843 : : ErrorCode result;
1844 [ + - ]: 2738 : Range range;
1845 : :
1846 [ + - ][ - + ]: 2738 : result = get_entities_by_type( meshset, entity_type, range, recursive );MB_CHK_ERR( result );
[ # # ][ # # ]
1847 [ + - ][ + + ]: 2738 : if( !entities.empty() && Interface::INTERSECT == condition ) range = intersect( entities, range );
[ + + ][ + + ]
[ + - ][ + - ]
1848 : :
1849 : : // For each tag:
1850 : : // if operation is INTERSECT remove from 'range' any non-tagged entities
1851 : : // if operation is UNION add to 'entities' any tagged entities
1852 [ + + ][ + - ]: 4948 : for( int it = 0; it < num_tags && !range.empty(); it++ )
[ + + ][ + + ]
1853 : : {
1854 [ + - ][ - + ]: 2210 : if( !valid_tag_handle( tags[it] ) ) return MB_TAG_NOT_FOUND;
1855 : :
1856 : : // Of the entities in 'range', put in 'tmp_range' the subset
1857 : : // that are tagged as requested for this tag.
1858 [ + - ]: 2210 : Range tmp_range;
1859 : :
1860 : : // get the entities with this tag/value combo
1861 [ + + ][ + + ]: 3093 : if( NULL == values || NULL == values[it] )
1862 : : {
1863 [ + - ][ - + ]: 883 : result = tags[it]->get_tagged_entities( sequenceManager, tmp_range, entity_type, &range );MB_CHK_ERR( result );
[ # # ][ # # ]
1864 : : }
1865 : : else
1866 : : {
1867 : 5308 : result = tags[it]->find_entities_with_value( sequenceManager, mError, tmp_range, values[it], 0, entity_type,
1868 [ + - ][ - + ]: 1327 : &range );MB_CHK_ERR( result );
[ # # ][ # # ]
1869 : : // if there is a default value, then we should return all entities
1870 : : // that are untagged
1871 [ + - ][ + + ]: 1327 : if( tags[it]->equals_default_value( values[it] ) )
1872 : : {
1873 [ + - ][ + - ]: 48 : Range all_tagged, untagged;
[ + - ]
1874 [ + - ][ - + ]: 24 : result = tags[it]->get_tagged_entities( sequenceManager, all_tagged, entity_type, &range );MB_CHK_ERR( result );
[ # # ][ # # ]
1875 : : // add to 'tmp_range' any untagged entities in 'range'
1876 [ + - ][ + - ]: 48 : tmp_range.merge( subtract( range, all_tagged ) );
[ + - ]
1877 : : }
1878 : : }
1879 : :
1880 : : // The above calls should have already done the intersect for us.
1881 [ + + ]: 2210 : if( Interface::INTERSECT == condition )
1882 [ + - ]: 2107 : range.swap( tmp_range );
1883 : : else
1884 [ + - ][ + - ]: 2210 : entities.merge( tmp_range );
1885 : 2210 : }
1886 : :
1887 [ + + ][ + - ]: 2738 : if( Interface::INTERSECT == condition ) entities.swap( range );
1888 : :
1889 : 2738 : return MB_SUCCESS;
1890 : : }
1891 : :
1892 : 16441 : ErrorCode Core::get_entities_by_handle( const EntityHandle meshset, Range& entities, const bool recursive ) const
1893 : : {
1894 : 16441 : ErrorCode result = MB_SUCCESS;
1895 [ + + ]: 16441 : if( meshset )
1896 : : {
1897 : : const EntitySequence* seq;
1898 [ + - ][ + - ]: 15451 : result = sequence_manager()->find( meshset, seq );MB_CHK_ERR( result );
[ - + ][ # # ]
[ # # ]
1899 : 15451 : const MeshSetSequence* mseq = reinterpret_cast< const MeshSetSequence* >( seq );
1900 [ + - ][ + - ]: 15451 : result = mseq->get_entities( sequence_manager(), meshset, entities, recursive );MB_CHK_ERR( result );
[ - + ][ # # ]
[ # # ]
1901 : : }
1902 : : else
1903 : : {
1904 : : // iterate backwards so range insertion is quicker
1905 [ + - ][ + + ]: 12870 : for( EntityType entity_type = MBENTITYSET; entity_type >= MBVERTEX; --entity_type )
1906 [ + - ][ + - ]: 11880 : sequence_manager()->get_entities( entity_type, entities );
1907 : : }
1908 : :
1909 : 16441 : return MB_SUCCESS;
1910 : : }
1911 : :
1912 : 3999 : ErrorCode Core::get_entities_by_handle( const EntityHandle meshset, std::vector< EntityHandle >& entities,
1913 : : const bool recursive ) const
1914 : : {
1915 : : ErrorCode result;
1916 [ + + ][ + + ]: 3999 : if( recursive || !meshset )
1917 : : {
1918 [ + - ]: 15 : Range tmp_range;
1919 [ + - ]: 15 : result = get_entities_by_handle( meshset, tmp_range, recursive );
1920 : 15 : size_t offset = entities.size();
1921 [ + - ][ + - ]: 15 : entities.resize( offset + tmp_range.size() );
1922 [ + - ][ + - ]: 15 : std::copy( tmp_range.begin(), tmp_range.end(), entities.begin() + offset );
[ + - ][ + - ]
1923 : : }
1924 : : else
1925 : : {
1926 : : const EntitySequence* seq;
1927 [ + - ][ + - ]: 3984 : result = sequence_manager()->find( meshset, seq );MB_CHK_ERR( result );
[ - + ][ # # ]
[ # # ]
1928 : 3984 : const MeshSetSequence* mseq = reinterpret_cast< const MeshSetSequence* >( seq );
1929 [ + - ][ - + ]: 3984 : result = mseq->get_entities( meshset, entities );MB_CHK_ERR( result );
[ # # ][ # # ]
1930 : : }
1931 : 3999 : return MB_SUCCESS;
1932 : : }
1933 : :
1934 : : //! get # entities of a given dimension
1935 : 183 : ErrorCode Core::get_number_entities_by_dimension( const EntityHandle meshset, const int dim, int& number,
1936 : : const bool recursive ) const
1937 : : {
1938 : 183 : ErrorCode result = MB_SUCCESS;
1939 : :
1940 [ + + ]: 183 : if( !meshset )
1941 : : {
1942 : 105 : number = 0;
1943 [ + - ][ + + ]: 463 : for( EntityType this_type = CN::TypeDimensionMap[dim].first; this_type <= CN::TypeDimensionMap[dim].second;
1944 : : this_type++ )
1945 : : {
1946 [ + - ][ + - ]: 358 : number += sequence_manager()->get_number_entities( this_type );
1947 : : }
1948 : : }
1949 : : else
1950 : : {
1951 : : const EntitySequence* seq;
1952 [ + - ][ + - ]: 78 : result = sequence_manager()->find( meshset, seq );MB_CHK_ERR( result );
[ - + ][ # # ]
[ # # ]
1953 : 78 : const MeshSetSequence* mseq = reinterpret_cast< const MeshSetSequence* >( seq );
1954 [ + - ][ + - ]: 78 : result = mseq->num_dimension( sequence_manager(), meshset, dim, number, recursive );MB_CHK_ERR( result );
[ - + ][ # # ]
[ # # ]
1955 : : }
1956 : :
1957 : 183 : return MB_SUCCESS;
1958 : : }
1959 : :
1960 : : //! returns the number of entities with a given type and tag
1961 : 2087 : ErrorCode Core::get_number_entities_by_type( const EntityHandle meshset, const EntityType entity_type, int& num_ent,
1962 : : const bool recursive ) const
1963 : : {
1964 : 2087 : ErrorCode result = MB_SUCCESS;
1965 : :
1966 [ + + ][ - + ]: 2087 : if( recursive && entity_type == MBENTITYSET ) // will never return anything
1967 : 0 : return MB_TYPE_OUT_OF_RANGE;
1968 : :
1969 [ + + ]: 2087 : if( meshset )
1970 : : {
1971 : : const EntitySequence* seq;
1972 [ + - ][ + - ]: 91 : result = sequence_manager()->find( meshset, seq );MB_CHK_ERR( result );
[ - + ][ # # ]
[ # # ]
1973 : 91 : const MeshSetSequence* mseq = reinterpret_cast< const MeshSetSequence* >( seq );
1974 [ + - ][ + - ]: 91 : result = mseq->num_type( sequence_manager(), meshset, entity_type, num_ent, recursive );MB_CHK_ERR( result );
[ - + ][ # # ]
[ # # ]
1975 : : }
1976 : : else
1977 : : {
1978 : 1996 : num_ent = sequence_manager()->get_number_entities( entity_type );
1979 : : }
1980 : :
1981 : 2087 : return MB_SUCCESS;
1982 : : }
1983 : :
1984 : 25 : ErrorCode Core::get_number_entities_by_type_and_tag( const EntityHandle meshset, const EntityType entity_type,
1985 : : const Tag* tag_handles, const void* const* values,
1986 : : const int num_tags, int& num_entities, int condition,
1987 : : const bool recursive ) const
1988 : : {
1989 [ + - ]: 25 : Range dum_ents;
1990 : : ErrorCode result = get_entities_by_type_and_tag( meshset, entity_type, tag_handles, values, num_tags, dum_ents,
1991 [ + - ]: 25 : condition, recursive );
1992 [ + - ]: 25 : num_entities = dum_ents.size();
1993 : 25 : return result;
1994 : : }
1995 : :
1996 : 8111 : ErrorCode Core::get_number_entities_by_handle( const EntityHandle meshset, int& num_ent, const bool recursive ) const
1997 : : {
1998 : : ErrorCode result;
1999 [ + + ]: 8111 : if( meshset )
2000 : : {
2001 : : const EntitySequence* seq;
2002 [ + - ][ + - ]: 7963 : result = sequence_manager()->find( meshset, seq );MB_CHK_ERR( result );
[ - + ][ # # ]
[ # # ]
2003 : 7963 : const MeshSetSequence* mseq = reinterpret_cast< const MeshSetSequence* >( seq );
2004 [ + - ][ + - ]: 7963 : return mseq->num_entities( sequence_manager(), meshset, num_ent, recursive );
2005 : : }
2006 : :
2007 : 148 : num_ent = 0;
2008 [ + - ][ + + ]: 1924 : for( EntityType this_type = MBVERTEX; this_type < MBMAXTYPE; this_type++ )
2009 : : {
2010 : 1776 : int dummy = 0;
2011 [ + - ]: 1776 : result = get_number_entities_by_type( 0, this_type, dummy );
2012 [ - + ]: 1776 : if( result != MB_SUCCESS )
2013 : : {
2014 : 0 : num_ent = 0;
2015 : 0 : return result;
2016 : : }
2017 : 1776 : num_ent += dummy;
2018 : : }
2019 : :
2020 : 8111 : return MB_SUCCESS;
2021 : : }
2022 : :
2023 : : //! return the tag data for a given EntityHandle and Tag
2024 : 7689817 : ErrorCode Core::tag_get_data( const Tag tag_handle, const EntityHandle* entity_handles, int num_entities,
2025 : : void* tag_data ) const
2026 : : {
2027 [ + - ][ - + ]: 7689817 : assert( valid_tag_handle( tag_handle ) );
2028 [ - + ][ # # ]: 7689817 : CHECK_MESH_NULL
[ # # ]
2029 [ + - ]: 7689817 : return tag_handle->get_data( sequenceManager, mError, entity_handles, num_entities, tag_data );
2030 : : }
2031 : :
2032 : : //! return the tag data for a given EntityHandle and Tag
2033 : 2689 : ErrorCode Core::tag_get_data( const Tag tag_handle, const Range& entity_handles, void* tag_data ) const
2034 : : {
2035 [ - + ]: 2689 : assert( valid_tag_handle( tag_handle ) );
2036 : 2689 : return tag_handle->get_data( sequenceManager, mError, entity_handles, tag_data );
2037 : : }
2038 : :
2039 : : //! set the data for given EntityHandles and Tag
2040 : 5172802 : ErrorCode Core::tag_set_data( Tag tag_handle, const EntityHandle* entity_handles, int num_entities,
2041 : : const void* tag_data )
2042 : : {
2043 [ + - ][ - + ]: 5172802 : assert( valid_tag_handle( tag_handle ) );
2044 [ - + ][ # # ]: 5172802 : CHECK_MESH_NULL
[ # # ]
2045 [ + - ]: 5172802 : return tag_handle->set_data( sequenceManager, mError, entity_handles, num_entities, tag_data );
2046 : : }
2047 : :
2048 : : //! set the data for given EntityHandles and Tag
2049 : 3427 : ErrorCode Core::tag_set_data( Tag tag_handle, const Range& entity_handles, const void* tag_data )
2050 : : {
2051 [ - + ]: 3427 : assert( valid_tag_handle( tag_handle ) );
2052 : 3427 : return tag_handle->set_data( sequenceManager, mError, entity_handles, tag_data );
2053 : : }
2054 : :
2055 : : //! return the tag data for a given EntityHandle and Tag
2056 : 22787 : ErrorCode Core::tag_get_by_ptr( const Tag tag_handle, const EntityHandle* entity_handles, int num_entities,
2057 : : const void** tag_data, int* tag_sizes ) const
2058 : : {
2059 [ + - ][ - + ]: 22787 : assert( valid_tag_handle( tag_handle ) );
2060 [ - + ][ # # ]: 22787 : CHECK_MESH_NULL
[ # # ]
2061 : : ErrorCode result =
2062 [ + - ]: 22787 : tag_handle->get_data( sequenceManager, mError, entity_handles, num_entities, tag_data, tag_sizes );
2063 [ + - ][ + - ]: 22787 : int typesize = TagInfo::size_from_data_type( tag_handle->get_data_type() );
2064 [ + + ][ + + ]: 22787 : if( tag_sizes && typesize != 1 )
2065 [ + + ]: 1870 : for( int i = 0; i < num_entities; ++i )
2066 : 935 : tag_sizes[i] /= typesize;
2067 : 22787 : return result;
2068 : : }
2069 : :
2070 : : //! return the tag data for a given EntityHandle and Tag
2071 : 105 : ErrorCode Core::tag_get_by_ptr( const Tag tag_handle, const Range& entity_handles, const void** tag_data,
2072 : : int* tag_sizes ) const
2073 : : {
2074 [ - + ]: 105 : assert( valid_tag_handle( tag_handle ) );
2075 : 105 : ErrorCode result = tag_handle->get_data( sequenceManager, mError, entity_handles, tag_data, tag_sizes );
2076 : 105 : int typesize = TagInfo::size_from_data_type( tag_handle->get_data_type() );
2077 [ + + ][ + + ]: 105 : if( tag_sizes && typesize != 1 )
2078 : : {
2079 : 74 : int num_entities = entity_handles.size();
2080 [ + + ]: 870 : for( int i = 0; i < num_entities; ++i )
2081 : 796 : tag_sizes[i] /= typesize;
2082 : : }
2083 : 105 : return result;
2084 : : }
2085 : :
2086 : : //! set the data for given EntityHandles and Tag
2087 : 997 : ErrorCode Core::tag_set_by_ptr( Tag tag_handle, const EntityHandle* entity_handles, int num_entities,
2088 : : void const* const* tag_data, const int* tag_sizes )
2089 : : {
2090 [ + - ][ - + ]: 997 : assert( valid_tag_handle( tag_handle ) );
2091 [ - + ][ # # ]: 997 : CHECK_MESH_NULL
[ # # ]
2092 [ + - ]: 997 : std::vector< int > tmp_sizes;
2093 [ + - ][ + - ]: 997 : int typesize = TagInfo::size_from_data_type( tag_handle->get_data_type() );
2094 [ + + ][ + + ]: 997 : if( typesize != 1 && tag_sizes )
2095 : : {
2096 [ + - ]: 983 : tmp_sizes.resize( num_entities );
2097 [ + + ]: 2014 : for( int i = 0; i < num_entities; ++i )
2098 [ + - ]: 1031 : tmp_sizes[i] = tag_sizes[i] * typesize;
2099 [ + - ]: 983 : tag_sizes = &tmp_sizes[0];
2100 : : }
2101 [ + - ]: 997 : return tag_handle->set_data( sequenceManager, mError, entity_handles, num_entities, tag_data, tag_sizes );
2102 : : }
2103 : :
2104 : : //! set the data for given EntityHandles and Tag
2105 : 14 : ErrorCode Core::tag_set_by_ptr( Tag tag_handle, const Range& entity_handles, void const* const* tag_data,
2106 : : const int* tag_sizes )
2107 : : {
2108 [ + - ][ - + ]: 14 : assert( valid_tag_handle( tag_handle ) );
2109 [ + - ]: 14 : std::vector< int > tmp_sizes;
2110 [ + - ][ + - ]: 14 : int typesize = TagInfo::size_from_data_type( tag_handle->get_data_type() );
2111 [ + + ][ + + ]: 14 : if( typesize != 1 && tag_sizes )
2112 : : {
2113 [ + - ]: 8 : int num_entities = entity_handles.size();
2114 [ + - ]: 8 : tmp_sizes.resize( num_entities );
2115 [ + + ]: 52 : for( int i = 0; i < num_entities; ++i )
2116 [ + - ]: 44 : tmp_sizes[i] = tag_sizes[i] * typesize;
2117 [ + - ]: 8 : tag_sizes = &tmp_sizes[0];
2118 : : }
2119 [ + - ]: 14 : return tag_handle->set_data( sequenceManager, mError, entity_handles, tag_data, tag_sizes );
2120 : : }
2121 : :
2122 : : //! set the data for given EntityHandles and Tag
2123 : 16 : ErrorCode Core::tag_clear_data( Tag tag_handle, const EntityHandle* entity_handles, int num_entities,
2124 : : const void* tag_data, int tag_size )
2125 : : {
2126 [ + - ][ - + ]: 16 : assert( valid_tag_handle( tag_handle ) );
2127 [ - + ][ # # ]: 16 : CHECK_MESH_NULL
[ # # ]
2128 : : return tag_handle->clear_data( sequenceManager, mError, entity_handles, num_entities, tag_data,
2129 [ + - ][ + - ]: 16 : tag_size * TagInfo::size_from_data_type( tag_handle->get_data_type() ) );
[ + - ]
2130 : : }
2131 : :
2132 : : //! set the data for given EntityHandles and Tag
2133 : 10 : ErrorCode Core::tag_clear_data( Tag tag_handle, const Range& entity_handles, const void* tag_data, int tag_size )
2134 : : {
2135 [ - + ]: 10 : assert( valid_tag_handle( tag_handle ) );
2136 : : return tag_handle->clear_data( sequenceManager, mError, entity_handles, tag_data,
2137 : 10 : tag_size * TagInfo::size_from_data_type( tag_handle->get_data_type() ) );
2138 : : }
2139 : :
2140 : 0 : static bool is_zero_bytes( const void* mem, size_t size )
2141 : : {
2142 : 0 : const char* iter = reinterpret_cast< const char* >( mem );
2143 : 0 : const char* const end = iter + size;
2144 [ # # ]: 0 : for( ; iter != end; ++iter )
2145 [ # # ]: 0 : if( *iter ) return false;
2146 : 0 : return true;
2147 : : }
2148 : :
2149 : 6435 : ErrorCode Core::tag_get_handle( const char* name, int size, DataType data_type, Tag& tag_handle, unsigned flags,
2150 : : const void* default_value, bool* created )
2151 : : {
2152 [ + + ]: 6435 : if( created ) *created = false;
2153 : :
2154 : : // we always work with sizes in bytes internally
2155 [ + + ][ + - ]: 6435 : if( !( ( flags & MB_TAG_VARLEN ) && size == MB_VARIABLE_LENGTH ) )
2156 : : {
2157 [ - + ]: 6435 : if( flags & MB_TAG_BYTES )
2158 : : {
2159 [ # # ]: 0 : if( size % TagInfo::size_from_data_type( data_type ) ) return MB_INVALID_SIZE;
2160 : : }
2161 : : else
2162 : : {
2163 : 6435 : size *= TagInfo::size_from_data_type( data_type );
2164 : : }
2165 : : }
2166 : :
2167 : 6435 : const TagType storage = static_cast< TagType >( flags & 3 );
2168 : :
2169 : : // search for an existing tag
2170 : 6435 : tag_handle = 0;
2171 [ + + ][ + + ]: 6435 : if( name && *name )
2172 : : { // not anonymous tag
2173 [ + - ][ + - ]: 43608 : for( std::list< Tag >::iterator i = tagList.begin(); i != tagList.end(); ++i )
[ + + ]
2174 : : {
2175 [ + - ][ + - ]: 37275 : if( ( *i )->get_name() == name )
[ + - ][ + + ]
2176 : : {
2177 [ + - ]: 2877 : tag_handle = *i;
2178 : 2877 : break;
2179 : : }
2180 : : }
2181 : : }
2182 : :
2183 [ + + ]: 6435 : if( tag_handle )
2184 : : {
2185 [ + + ]: 2877 : if( flags & MB_TAG_EXCL ) return MB_ALREADY_ALLOCATED;
2186 : : // user asked that we not check anything
2187 [ + + ]: 2794 : if( flags & MB_TAG_ANY ) return MB_SUCCESS;
2188 : : // user asked that we also match storage types
2189 [ - + ][ # # ]: 2512 : if( ( flags & MB_TAG_STORE ) && tag_handle->get_storage_type() != storage ) return MB_TYPE_OUT_OF_RANGE;
[ - + ]
2190 : : // check if data type matches
2191 : 2512 : const DataType extype = tag_handle->get_data_type();
2192 [ - + ]: 2512 : if( extype != data_type )
2193 : : {
2194 [ # # ]: 0 : if( flags & MB_TAG_NOOPQ )
2195 : 0 : return MB_TYPE_OUT_OF_RANGE;
2196 [ # # ][ # # ]: 0 : else if( extype != MB_TYPE_OPAQUE && data_type != MB_TYPE_OPAQUE )
2197 : 0 : return MB_TYPE_OUT_OF_RANGE;
2198 : : }
2199 : :
2200 : : // Require that the size value be zero or MB_VARIABLE_LENGTH
2201 : : // for variable length tags. The caller passing such a size
2202 : : // value is sufficient to indicate that the caller is aware
2203 : : // that it is requesting a variable-length tag, so no need
2204 : : // to also require/check the MB_TAG_VARLEN bit in the flags.
2205 [ + + ]: 2512 : if( tag_handle->variable_length() )
2206 : : {
2207 [ - + ][ # # ]: 110 : if( size != 0 && size != MB_VARIABLE_LENGTH && !( flags & MB_TAG_VARLEN ) ) return MB_INVALID_SIZE;
[ # # ]
2208 : : }
2209 : : // But /do/ fail if MB_TAG_VARLEN flag is set and tag is
2210 : : // not variable length.
2211 [ - + ]: 2402 : else if( flags & MB_TAG_VARLEN )
2212 : 0 : return MB_TYPE_OUT_OF_RANGE;
2213 : : // check size for fixed-length tag
2214 [ - + ]: 2402 : else if( tag_handle->get_size() != size )
2215 : 0 : return MB_INVALID_SIZE;
2216 : :
2217 : : // If user passed a default value, check that it matches.
2218 : : // If user did not pass a default value, assume they're OK
2219 : : // with the existing one.
2220 : : // If tag does not have a default value but the user passed
2221 : : // one, allow it only if the tag is dense and the passed value
2222 : : // is all zero bytes because dense tags have an implicit default
2223 : : // value of all zeros in some cases.
2224 [ + + ]: 2662 : if( default_value && !( flags & MB_TAG_DFTOK ) &&
[ + + - + ]
[ - + ]
2225 : 150 : !( tag_handle->equals_default_value( default_value, size ) ||
2226 [ # # # # ]: 0 : ( !tag_handle->get_default_value() && tag_handle->get_storage_type() == MB_TAG_DENSE &&
2227 [ # # ]: 0 : is_zero_bytes( default_value, size ) ) ) )
2228 : 0 : return MB_ALREADY_ALLOCATED;
2229 : :
2230 : 2512 : return MB_SUCCESS;
2231 : : }
2232 : :
2233 : : // MB_TAG_EXCL implies MB_TAG_CREAT
2234 [ + + ]: 3558 : if( !( flags & ( MB_TAG_CREAT | MB_TAG_EXCL ) ) ) return MB_TAG_NOT_FOUND;
2235 : :
2236 : : // if a non-opaque non-bit type was specified, then the size
2237 : : // must be multiple of the size of the type
2238 [ + + ][ + + ]: 5973 : if( ( !( flags & MB_TAG_VARLEN ) || default_value ) &&
[ + - ][ - + ]
2239 [ - + ]: 2936 : ( size <= 0 || ( size % TagInfo::size_from_data_type( data_type ) ) != 0 ) )
2240 : 0 : return MB_INVALID_SIZE;
2241 : :
2242 : : // if MB_TYPE_BIT may be used only with MB_TAG_BIT
2243 : : // if (storage != MB_TAG_BIT && data_type == MB_TYPE_BIT)
2244 : : // return MB_INVALID_ARG;
2245 [ + + ]: 3037 : if( data_type == MB_TYPE_BIT ) flags &= ~(unsigned)( MB_TAG_DENSE | MB_TAG_SPARSE );
2246 : :
2247 : : // create the tag
2248 [ + + + + : 3037 : switch( flags & ( MB_TAG_DENSE | MB_TAG_SPARSE | MB_TAG_MESH | MB_TAG_VARLEN ) )
+ + + - ]
2249 : : {
2250 : : case MB_TAG_DENSE | MB_TAG_VARLEN:
2251 : 12 : tag_handle = VarLenDenseTag::create_tag( sequenceManager, mError, name, data_type, default_value, size );
2252 : 12 : break;
2253 : : case MB_TAG_DENSE:
2254 : 643 : tag_handle = DenseTag::create_tag( sequenceManager, mError, name, size, data_type, default_value );
2255 : 643 : break;
2256 : : case MB_TAG_SPARSE | MB_TAG_VARLEN:
2257 [ + - ]: 98 : tag_handle = new VarLenSparseTag( name, data_type, default_value, size );
2258 : 98 : break;
2259 : : case MB_TAG_SPARSE:
2260 [ + - ]: 2119 : tag_handle = new SparseTag( name, size, data_type, default_value );
2261 : 2119 : break;
2262 : : case MB_TAG_MESH | MB_TAG_VARLEN:
2263 [ + - ]: 1 : tag_handle = new MeshTag( name, MB_VARIABLE_LENGTH, data_type, default_value, size );
2264 : 1 : break;
2265 : : case MB_TAG_MESH:
2266 [ + - ]: 4 : tag_handle = new MeshTag( name, size, data_type, default_value, size );
2267 : 4 : break;
2268 : : case MB_TAG_BIT:
2269 [ - + ][ # # ]: 160 : if( MB_TYPE_BIT != data_type && MB_TYPE_OPAQUE != data_type ) return MB_TYPE_OUT_OF_RANGE;
2270 : 160 : tag_handle = BitTag::create_tag( name, size, default_value );
2271 : 160 : break;
2272 : : default: // some illegal combination (multiple storage types, variable-length bit tag, etc.)
2273 : 0 : return MB_TYPE_OUT_OF_RANGE;
2274 : : }
2275 : :
2276 [ - + ]: 3037 : if( !tag_handle ) return MB_INVALID_SIZE;
2277 : :
2278 [ - + ]: 3037 : if( created ) *created = true;
2279 : 3037 : tagList.push_back( tag_handle );
2280 : 6435 : return MB_SUCCESS;
2281 : : }
2282 : :
2283 : 75 : ErrorCode Core::tag_get_handle( const char* name, int size, DataType data_type, Tag& tag_handle, unsigned flags,
2284 : : const void* default_value ) const
2285 : : {
2286 : : // If caller specified MB_TAG_EXCL, then we must fail because
2287 : : // this const function can never create a tag. We need to test
2288 : : // this here because the non-const version of this function
2289 : : // assumes MB_TAG_CREAT if MB_TAG_EXCL is specified.
2290 [ - + ]: 75 : if( flags & MB_TAG_EXCL )
2291 : : {
2292 : : // anonymous tag?
2293 [ # # ][ # # ]: 0 : if( !name || !*name ) return MB_TAG_NOT_FOUND;
2294 : :
2295 : : // search for an existing tag
2296 : 0 : tag_handle = 0;
2297 [ # # ][ # # ]: 0 : for( std::list< Tag >::const_iterator i = tagList.begin(); i != tagList.end(); ++i )
[ # # ]
2298 : : {
2299 [ # # ][ # # ]: 0 : if( ( *i )->get_name() == name )
[ # # ][ # # ]
2300 : : {
2301 [ # # ]: 0 : tag_handle = *i;
2302 : 0 : return MB_ALREADY_ALLOCATED;
2303 : : }
2304 : : }
2305 : :
2306 : 0 : return MB_TAG_NOT_FOUND;
2307 : : }
2308 : :
2309 : : return const_cast< Core* >( this )->tag_get_handle( name, size, data_type, tag_handle,
2310 : 75 : flags & ~(unsigned)MB_TAG_CREAT, default_value );
2311 : : }
2312 : :
2313 : : //! removes the tag from the entity
2314 : 118 : ErrorCode Core::tag_delete_data( Tag tag_handle, const EntityHandle* entity_handles, int num_entities )
2315 : : {
2316 [ + - ][ - + ]: 118 : assert( valid_tag_handle( tag_handle ) );
2317 [ - + ][ # # ]: 118 : CHECK_MESH_NULL
[ # # ]
2318 [ + - ]: 118 : return tag_handle->remove_data( sequenceManager, mError, entity_handles, num_entities );
2319 : : }
2320 : :
2321 : : //! removes the tag from the entity
2322 : 4 : ErrorCode Core::tag_delete_data( Tag tag_handle, const Range& entity_handles )
2323 : : {
2324 [ - + ]: 4 : assert( valid_tag_handle( tag_handle ) );
2325 : 4 : return tag_handle->remove_data( sequenceManager, mError, entity_handles );
2326 : : }
2327 : :
2328 : : //! removes the tag from MB
2329 : 3005 : ErrorCode Core::tag_delete( Tag tag_handle )
2330 : : {
2331 [ + - ]: 3005 : std::list< TagInfo* >::iterator i = std::find( tagList.begin(), tagList.end(), tag_handle );
2332 [ + - ][ + + ]: 3005 : if( i == tagList.end() ) return MB_TAG_NOT_FOUND;
2333 : :
2334 [ + - ][ - + ]: 3003 : ErrorCode rval = tag_handle->release_all_data( sequenceManager, mError, true );MB_CHK_ERR( rval );
[ # # ][ # # ]
2335 : :
2336 [ + - ]: 3003 : tagList.erase( i );
2337 [ + - ]: 3003 : delete tag_handle;
2338 : 3005 : return MB_SUCCESS;
2339 : : }
2340 : :
2341 : 5960 : ErrorCode Core::tag_iterate( Tag tag_handle, Range::const_iterator iter, Range::const_iterator end, int& count,
2342 : : void*& data_ptr, bool allocate )
2343 : : {
2344 : 5960 : Range::const_iterator init = iter;
2345 [ + - ][ - + ]: 5960 : assert( valid_tag_handle( tag_handle ) );
2346 [ + - ]: 5960 : ErrorCode result = tag_handle->tag_iterate( sequenceManager, mError, iter, end, data_ptr, allocate );
2347 [ + + ][ + - ]: 5960 : if( MB_SUCCESS == result ) count = iter - init;
2348 : 5960 : return result;
2349 : : }
2350 : :
2351 : : //! gets the tag name string for the tag_handle
2352 : 2333 : ErrorCode Core::tag_get_name( const Tag tag_handle, std::string& tag_name ) const
2353 : : {
2354 [ + + ]: 2333 : if( !valid_tag_handle( tag_handle ) ) return MB_TAG_NOT_FOUND;
2355 : 2330 : tag_name = tag_handle->get_name();
2356 : 2330 : return MB_SUCCESS;
2357 : : }
2358 : :
2359 : 75 : ErrorCode Core::tag_get_handle( const char* tag_name, Tag& tag_handle ) const
2360 : : {
2361 : 75 : return tag_get_handle( tag_name, 0, MB_TYPE_OPAQUE, tag_handle, MB_TAG_ANY );
2362 : : }
2363 : :
2364 : : //! get size of tag in bytes
2365 : 1898 : ErrorCode Core::tag_get_bytes( const Tag tag_handle, int& tag_size ) const
2366 : : {
2367 [ + + ]: 1898 : if( !valid_tag_handle( tag_handle ) ) return MB_TAG_NOT_FOUND;
2368 : :
2369 [ + + ]: 1895 : if( tag_handle->variable_length() )
2370 : : {
2371 : 150 : tag_size = MB_VARIABLE_LENGTH;
2372 : 150 : return MB_VARIABLE_DATA_LENGTH;
2373 : : }
2374 [ + + ]: 1745 : else if( tag_handle->get_storage_type() == MB_TAG_BIT )
2375 : : {
2376 : 12 : tag_size = 1;
2377 : 12 : return MB_SUCCESS;
2378 : : }
2379 : : else
2380 : : {
2381 : 1733 : tag_size = tag_handle->get_size();
2382 : 1733 : return MB_SUCCESS;
2383 : : }
2384 : : }
2385 : :
2386 : : //! get size of tag in $values
2387 : 1618 : ErrorCode Core::tag_get_length( const Tag tag_handle, int& tag_size ) const
2388 : : {
2389 [ + + ]: 1618 : if( !valid_tag_handle( tag_handle ) ) return MB_TAG_NOT_FOUND;
2390 : :
2391 [ + + ]: 1615 : if( tag_handle->variable_length() )
2392 : : {
2393 : 137 : tag_size = MB_VARIABLE_LENGTH;
2394 : 137 : return MB_VARIABLE_DATA_LENGTH;
2395 : : }
2396 : : else
2397 : : {
2398 : 1478 : tag_size = tag_handle->get_size() / TagInfo::size_from_data_type( tag_handle->get_data_type() );
2399 : 1478 : return MB_SUCCESS;
2400 : : }
2401 : : }
2402 : :
2403 : 1679 : ErrorCode Core::tag_get_data_type( const Tag handle, DataType& data_type ) const
2404 : : {
2405 [ + + ]: 1679 : if( !valid_tag_handle( handle ) ) return MB_TAG_NOT_FOUND;
2406 : :
2407 : 1676 : data_type = handle->get_data_type();
2408 : 1676 : return MB_SUCCESS;
2409 : : }
2410 : :
2411 : : //! get default value of the tag
2412 : 76 : ErrorCode Core::tag_get_default_value( const Tag tag_handle, void* def_value ) const
2413 : : {
2414 [ + + ]: 76 : if( !valid_tag_handle( tag_handle ) ) return MB_TAG_NOT_FOUND;
2415 : :
2416 [ - + ]: 73 : if( tag_handle->variable_length() ) return MB_VARIABLE_DATA_LENGTH;
2417 : :
2418 [ + + ]: 73 : if( !tag_handle->get_default_value() ) return MB_ENTITY_NOT_FOUND;
2419 : :
2420 : 41 : memcpy( def_value, tag_handle->get_default_value(), tag_handle->get_default_value_size() );
2421 : 41 : return MB_SUCCESS;
2422 : : }
2423 : :
2424 : 427 : ErrorCode Core::tag_get_default_value( Tag tag, const void*& ptr, int& size ) const
2425 : : {
2426 [ - + ]: 427 : if( !valid_tag_handle( tag ) ) return MB_ENTITY_NOT_FOUND;
2427 : :
2428 [ + + ]: 427 : if( !tag->get_default_value() ) return MB_ENTITY_NOT_FOUND;
2429 : :
2430 : 279 : ptr = tag->get_default_value();
2431 : 279 : size = tag->get_default_value_size() / TagInfo::size_from_data_type( tag->get_data_type() );
2432 : 279 : return MB_SUCCESS;
2433 : : }
2434 : :
2435 : : //! get type of tag (sparse, dense, etc.; 0 = dense, 1 = sparse, 2 = bit, 3 = static)
2436 : 818 : ErrorCode Core::tag_get_type( const Tag tag_handle, TagType& tag_type ) const
2437 : : {
2438 [ - + ]: 818 : assert( valid_tag_handle( tag_handle ) );
2439 : 818 : tag_type = tag_handle->get_storage_type();
2440 : 818 : return MB_SUCCESS;
2441 : : }
2442 : :
2443 : : //! get handles for all tags defined
2444 : 203 : ErrorCode Core::tag_get_tags( std::vector< Tag >& tag_handles ) const
2445 : : {
2446 : 203 : std::copy( tagList.begin(), tagList.end(), std::back_inserter( tag_handles ) );
2447 : 203 : return MB_SUCCESS;
2448 : : }
2449 : :
2450 : : //! Get handles for all tags defined on this entity
2451 : 131 : ErrorCode Core::tag_get_tags_on_entity( const EntityHandle entity, std::vector< Tag >& tag_handles ) const
2452 : : {
2453 [ + - ][ + - ]: 1349 : for( std::list< TagInfo* >::const_iterator i = tagList.begin(); i != tagList.end(); ++i )
[ + + ]
2454 [ + - ][ + - ]: 1218 : if( ( *i )->is_tagged( sequenceManager, entity ) ) tag_handles.push_back( *i );
[ + + ][ + - ]
[ + - ]
2455 : 131 : return MB_SUCCESS;
2456 : : }
2457 : :
2458 : 372 : Tag Core::material_tag()
2459 : : {
2460 : 372 : const int negone = -1;
2461 [ + - ]: 372 : if( 0 == materialTag )
2462 [ + - ]: 372 : tag_get_handle( MATERIAL_SET_TAG_NAME, 1, MB_TYPE_INTEGER, materialTag, MB_TAG_CREAT | MB_TAG_SPARSE, &negone );
2463 : 372 : return materialTag;
2464 : : }
2465 : :
2466 : 372 : Tag Core::neumannBC_tag()
2467 : : {
2468 : 372 : const int negone = -1;
2469 [ + - ]: 372 : if( 0 == neumannBCTag )
2470 [ + - ]: 372 : tag_get_handle( NEUMANN_SET_TAG_NAME, 1, MB_TYPE_INTEGER, neumannBCTag, MB_TAG_CREAT | MB_TAG_SPARSE, &negone );
2471 : 372 : return neumannBCTag;
2472 : : }
2473 : :
2474 : 372 : Tag Core::dirichletBC_tag()
2475 : : {
2476 : 372 : const int negone = -1;
2477 [ + - ]: 372 : if( 0 == dirichletBCTag )
2478 : : tag_get_handle( DIRICHLET_SET_TAG_NAME, 1, MB_TYPE_INTEGER, dirichletBCTag, MB_TAG_CREAT | MB_TAG_SPARSE,
2479 [ + - ]: 372 : &negone );
2480 : 372 : return dirichletBCTag;
2481 : : }
2482 : :
2483 : 653 : Tag Core::globalId_tag()
2484 : : {
2485 : 653 : const int negone = -1;
2486 [ + + ]: 653 : if( 0 == globalIdTag )
2487 [ + - ]: 372 : tag_get_handle( GLOBAL_ID_TAG_NAME, 1, MB_TYPE_INTEGER, globalIdTag, MB_TAG_CREAT | MB_TAG_DENSE, &negone );
2488 : 653 : return globalIdTag;
2489 : : }
2490 : :
2491 : 372 : Tag Core::geom_dimension_tag()
2492 : : {
2493 : 372 : const int negone = -1;
2494 [ + - ]: 372 : if( 0 == geomDimensionTag )
2495 : : tag_get_handle( GEOM_DIMENSION_TAG_NAME, 1, MB_TYPE_INTEGER, geomDimensionTag, MB_TAG_CREAT | MB_TAG_SPARSE,
2496 [ + - ]: 372 : &negone );
2497 : 372 : return geomDimensionTag;
2498 : : }
2499 : :
2500 : : //! creates an element based on the type and connectivity. returns a handle and error code
2501 : 417601 : ErrorCode Core::create_element( const EntityType entity_type, const EntityHandle* connectivity, const int num_nodes,
2502 : : EntityHandle& handle )
2503 : : {
2504 : : // make sure we have enough vertices for this entity type
2505 [ - + ]: 417601 : if( num_nodes < CN::VerticesPerEntity( entity_type ) ) return MB_FAILURE;
2506 : :
2507 : 417601 : ErrorCode status = sequence_manager()->create_element( entity_type, connectivity, num_nodes, handle );
2508 [ + - ]: 417601 : if( MB_SUCCESS == status ) status = aEntityFactory->notify_create_entity( handle, connectivity, num_nodes );
2509 : :
2510 : : #ifdef MOAB_HAVE_AHF
2511 : : mesh_modified = true;
2512 : : #endif
2513 : :
2514 : 417601 : return status;
2515 : : }
2516 : :
2517 : : //! creates a vertex based on coordinates, returns a handle and error code
2518 : 2114879 : ErrorCode Core::create_vertex( const double coords[3], EntityHandle& handle )
2519 : : {
2520 : : // get an available vertex handle
2521 : 2114879 : return sequence_manager()->create_vertex( coords, handle );
2522 : : }
2523 : :
2524 : 62 : ErrorCode Core::create_vertices( const double* coordinates, const int nverts, Range& entity_handles )
2525 : : {
2526 : : // Create vertices
2527 : : ReadUtilIface* read_iface;
2528 [ + - ][ - + ]: 62 : ErrorCode result = Interface::query_interface( read_iface );MB_CHK_ERR( result );
[ # # ][ # # ]
2529 : :
2530 [ + - ]: 62 : std::vector< double* > arrays;
2531 : 62 : EntityHandle start_handle_out = 0;
2532 [ + - ]: 62 : result = read_iface->get_node_coords( 3, nverts, MB_START_ID, start_handle_out, arrays );
2533 [ + - ][ - + ]: 62 : Interface::release_interface( read_iface );MB_CHK_ERR( result );
[ # # ][ # # ]
2534 : : // Cppcheck warning (false positive): variable arrays is assigned a value that is never used
2535 [ + + ]: 37729 : for( int i = 0; i < nverts; i++ )
2536 : : {
2537 [ + - ]: 37667 : arrays[0][i] = coordinates[3 * i];
2538 [ + - ]: 37667 : arrays[1][i] = coordinates[3 * i + 1];
2539 [ + - ]: 37667 : arrays[2][i] = coordinates[3 * i + 2];
2540 : : }
2541 : :
2542 [ + - ]: 62 : entity_handles.clear();
2543 [ + - ]: 62 : entity_handles.insert( start_handle_out, start_handle_out + nverts - 1 );
2544 : :
2545 : 62 : return MB_SUCCESS;
2546 : : }
2547 : :
2548 : : //! merges two entities
2549 : 442 : ErrorCode Core::merge_entities( EntityHandle entity_to_keep, EntityHandle entity_to_remove, bool auto_merge,
2550 : : bool delete_removed_entity )
2551 : : {
2552 [ - + ]: 442 : if( auto_merge ) return MB_FAILURE;
2553 : :
2554 : : // The two entities to merge must not be the same entity.
2555 [ - + ]: 442 : if( entity_to_keep == entity_to_remove ) return MB_FAILURE;
2556 : :
2557 : : // The two entities to merge must be of the same type
2558 [ + - ]: 442 : EntityType type_to_keep = TYPE_FROM_HANDLE( entity_to_keep );
2559 : :
2560 [ + - ][ - + ]: 442 : if( type_to_keep != TYPE_FROM_HANDLE( entity_to_remove ) ) return MB_TYPE_OUT_OF_RANGE;
2561 : :
2562 : : // Make sure both entities exist before trying to merge.
2563 : 442 : EntitySequence* seq = 0;
2564 : : ErrorCode result, status;
2565 [ + - ][ + - ]: 442 : status = sequence_manager()->find( entity_to_keep, seq );
2566 [ + - ][ - + ]: 442 : if( seq == 0 || status != MB_SUCCESS ) return MB_ENTITY_NOT_FOUND;
2567 [ + - ][ + - ]: 442 : status = sequence_manager()->find( entity_to_remove, seq );
2568 [ + - ][ - + ]: 442 : if( seq == 0 || status != MB_SUCCESS ) return MB_ENTITY_NOT_FOUND;
2569 : :
2570 : : // If auto_merge is not set, all sub-entities should
2571 : : // be merged if the entities are to be merged.
2572 [ + - ]: 442 : int ent_dim = CN::Dimension( type_to_keep );
2573 [ + + ]: 442 : if( ent_dim > 0 )
2574 : : {
2575 [ + - ][ + - ]: 62 : std::vector< EntityHandle > conn, conn2;
[ + - ]
2576 : :
2577 [ + - ][ - + ]: 31 : result = get_connectivity( &entity_to_keep, 1, conn );MB_CHK_ERR( result );
[ # # ][ # # ]
2578 [ + - ][ - + ]: 31 : result = get_connectivity( &entity_to_remove, 1, conn2 );MB_CHK_ERR( result );
[ # # ][ # # ]
2579 : :
2580 : : // Check to see if we can merge before pulling adjacencies.
2581 : : int dum1, dum2;
2582 [ + - + - ]: 93 : if( !auto_merge &&
[ - + ]
2583 [ + - ][ + - ]: 62 : ( conn.size() != conn2.size() || !CN::ConnectivityMatch( &conn[0], &conn2[0], conn.size(), dum1, dum2 ) ) )
[ + - ][ - + ]
2584 [ + - ]: 62 : return MB_FAILURE;
2585 : : }
2586 : :
2587 [ + - ]: 442 : result = aEntityFactory->merge_adjust_adjacencies( entity_to_keep, entity_to_remove );
2588 : :
2589 [ + - ][ + + ]: 442 : if( MB_SUCCESS == result && delete_removed_entity ) result = delete_entities( &entity_to_remove, 1 );
[ + - ]
2590 : :
2591 : 442 : return result;
2592 : : }
2593 : :
2594 : : //! deletes an entity range
2595 : 56 : ErrorCode Core::delete_entities( const Range& range )
2596 : : {
2597 : 56 : ErrorCode result = MB_SUCCESS, temp_result;
2598 [ + - ]: 56 : Range failed_ents;
2599 : :
2600 [ + - ][ + - ]: 617 : for( std::list< TagInfo* >::iterator i = tagList.begin(); i != tagList.end(); ++i )
[ + + ]
2601 : : {
2602 [ + - ][ + - ]: 561 : temp_result = ( *i )->remove_data( sequenceManager, mError, range );
2603 : : // ok if the error is tag_not_found, some ents may not have every tag on them
2604 [ + + ][ - + ]: 561 : if( MB_SUCCESS != temp_result && MB_TAG_NOT_FOUND != temp_result ) result = temp_result;
2605 : : }
2606 : :
2607 [ + - ][ + - ]: 23806 : for( Range::const_reverse_iterator rit = range.rbegin(); rit != range.rend(); ++rit )
[ + - ][ + - ]
[ + + ]
2608 : : {
2609 : :
2610 : : // tell AEntityFactory that this element is going away
2611 [ + - ][ + - ]: 23750 : temp_result = aEntityFactory->notify_delete_entity( *rit );
2612 [ - + ]: 23750 : if( MB_SUCCESS != temp_result )
2613 : : {
2614 : 0 : result = temp_result;
2615 [ # # ][ # # ]: 0 : failed_ents.insert( *rit );
2616 : 0 : continue;
2617 : : }
2618 : :
2619 [ + - ][ + - ]: 23750 : if( TYPE_FROM_HANDLE( *rit ) == MBENTITYSET )
[ + + ]
2620 : : {
2621 [ + - ][ + - ]: 30 : if( MeshSet* ptr = get_mesh_set( sequence_manager(), *rit ) )
[ + - ][ + - ]
2622 : : {
2623 : : int j, count;
2624 : : const EntityHandle* rel;
2625 [ + - ][ + - ]: 30 : ptr->clear( *rit, a_entity_factory() );
[ + - ]
2626 [ + - ]: 30 : rel = ptr->get_parents( count );
2627 [ - + ]: 30 : for( j = 0; j < count; ++j )
2628 [ # # ][ # # ]: 0 : remove_child_meshset( rel[j], *rit );
2629 [ + - ]: 30 : rel = ptr->get_children( count );
2630 [ + + ]: 60 : for( j = 0; j < count; ++j )
2631 [ + - ][ + - ]: 30 : remove_parent_meshset( rel[j], *rit );
2632 : : }
2633 : : }
2634 : : }
2635 : :
2636 [ + - ][ - + ]: 56 : if( !failed_ents.empty() )
2637 : : {
2638 [ # # ]: 0 : Range dum_range = subtract( range, failed_ents );
2639 : : // don't test for success, since we'll return failure in this case
2640 [ # # ][ # # ]: 0 : sequence_manager()->delete_entities( mError, dum_range );
2641 : : }
2642 : : else
2643 : : // now delete the entities
2644 [ + - ][ + - ]: 56 : result = sequence_manager()->delete_entities( mError, range );
2645 : :
2646 : 56 : return result;
2647 : : }
2648 : :
2649 : : //! deletes an entity vector
2650 : 837 : ErrorCode Core::delete_entities( const EntityHandle* entities, const int num_entities )
2651 : : {
2652 : 837 : ErrorCode result = MB_SUCCESS, temp_result;
2653 [ + - ]: 837 : Range failed_ents;
2654 : :
2655 [ + - ][ + - ]: 7910 : for( std::list< TagInfo* >::iterator i = tagList.begin(); i != tagList.end(); ++i )
[ + + ]
2656 : : {
2657 [ + - ][ + - ]: 7073 : temp_result = ( *i )->remove_data( sequenceManager, mError, entities, num_entities );
2658 : : // ok if the error is tag_not_found, some ents may not have every tag on them
2659 [ + + ][ - + ]: 7073 : if( MB_SUCCESS != temp_result && MB_TAG_NOT_FOUND != temp_result ) result = temp_result;
2660 : : }
2661 : :
2662 [ + + ]: 30944 : for( int i = 0; i < num_entities; i++ )
2663 : : {
2664 : :
2665 : : // tell AEntityFactory that this element is going away
2666 : 30107 : bool failed = false;
2667 [ + - ]: 30107 : temp_result = aEntityFactory->notify_delete_entity( entities[i] );
2668 [ - + ]: 30107 : if( MB_SUCCESS != temp_result )
2669 : : {
2670 : 0 : result = temp_result;
2671 : 0 : failed = true;
2672 : : }
2673 : :
2674 [ + - ][ + + ]: 30107 : if( TYPE_FROM_HANDLE( entities[i] ) == MBENTITYSET )
2675 : : {
2676 [ + - ][ + - ]: 29542 : if( MeshSet* ptr = get_mesh_set( sequence_manager(), entities[i] ) )
[ + - ]
2677 : : {
2678 : : int j, count;
2679 : : const EntityHandle* rel;
2680 [ + - ][ + - ]: 29542 : ptr->clear( entities[i], a_entity_factory() );
2681 [ + - ]: 29542 : rel = ptr->get_parents( count );
2682 [ + + ]: 29543 : for( j = 0; j < count; ++j )
2683 [ + - ]: 1 : remove_child_meshset( rel[j], entities[i] );
2684 [ + - ]: 29542 : rel = ptr->get_children( count );
2685 [ + + ]: 58711 : for( j = 0; j < count; ++j )
2686 [ + - ]: 29169 : remove_parent_meshset( rel[j], entities[i] );
2687 : : }
2688 : : }
2689 : :
2690 [ - + ]: 30107 : if( failed )
2691 : : // don't test for success, since we'll return failure in this case
2692 [ # # ][ # # ]: 0 : sequence_manager()->delete_entity( mError, entities[i] );
2693 : : else
2694 : : {
2695 : : // now delete the entity
2696 [ + - ][ + - ]: 30107 : temp_result = sequence_manager()->delete_entity( mError, entities[i] );
2697 [ - + ]: 30107 : if( MB_SUCCESS != temp_result ) result = temp_result;
2698 : : }
2699 : : }
2700 : :
2701 : 837 : return result;
2702 : : }
2703 : :
2704 : 0 : ErrorCode Core::list_entities( const EntityHandle* entities, const int num_entities ) const
2705 : : {
2706 [ # # ]: 0 : Range temp_range;
2707 : 0 : ErrorCode result = MB_SUCCESS;
2708 [ # # ][ # # ]: 0 : if( NULL == entities && num_entities == 0 )
2709 : : {
2710 : : // just list the numbers of each entity type
2711 : : int num_ents;
2712 [ # # ]: 0 : std::cout << std::endl;
2713 [ # # ][ # # ]: 0 : std::cout << "Number of entities per type: " << std::endl;
2714 [ # # ][ # # ]: 0 : for( EntityType this_type = MBVERTEX; this_type < MBMAXTYPE; this_type++ )
2715 : : {
2716 [ # # ]: 0 : result = get_number_entities_by_type( 0, this_type, num_ents );
2717 [ # # ][ # # ]: 0 : std::cout << CN::EntityTypeName( this_type ) << ": " << num_ents << std::endl;
[ # # ][ # # ]
[ # # ]
2718 : : }
2719 [ # # ]: 0 : std::cout << std::endl;
2720 : :
2721 : 0 : return MB_SUCCESS;
2722 : : }
2723 [ # # ][ # # ]: 0 : else if( NULL == entities && num_entities < 0 )
2724 : : {
2725 : :
2726 : : // list all entities of all types
2727 [ # # ]: 0 : std::cout << std::endl;
2728 [ # # ][ # # ]: 0 : for( EntityType this_type = MBVERTEX; this_type < MBMAXTYPE; this_type++ )
2729 : : {
2730 [ # # ]: 0 : result = get_entities_by_type( 0, this_type, temp_range );
2731 : : }
2732 : :
2733 [ # # ]: 0 : return list_entities( temp_range );
2734 : : }
2735 [ # # ][ # # ]: 0 : else if( NULL == entities && num_entities > 0 )
2736 : : {
2737 : :
2738 : : // list all entities of type == num_entities
2739 [ # # ]: 0 : std::cout << std::endl;
2740 [ # # ]: 0 : result = get_entities_by_type( 0, (EntityType)num_entities, temp_range );
2741 : :
2742 [ # # ]: 0 : return list_entities( temp_range );
2743 : : }
2744 : : else
2745 : : {
2746 : : ErrorCode tmp_result;
2747 [ # # ]: 0 : for( int i = 0; i < num_entities; i++ )
2748 : : {
2749 [ # # ]: 0 : EntityType this_type = TYPE_FROM_HANDLE( entities[i] );
2750 [ # # ][ # # ]: 0 : std::cout << CN::EntityTypeName( this_type ) << " " << ID_FROM_HANDLE( entities[i] ) << ":" << endl;
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
2751 : :
2752 [ # # ]: 0 : tmp_result = ( const_cast< Core* >( this ) )->list_entity( entities[i] );
2753 [ # # ]: 0 : if( MB_SUCCESS != tmp_result ) result = tmp_result;
2754 : : }
2755 : : }
2756 : :
2757 : 0 : return result;
2758 : : }
2759 : :
2760 : 0 : ErrorCode Core::list_entities( const Range& temp_range ) const
2761 : : {
2762 : 0 : ErrorCode result = MB_SUCCESS, tmp_result;
2763 : :
2764 [ # # ][ # # ]: 0 : for( Range::const_iterator rit = temp_range.begin(); rit != temp_range.end(); ++rit )
[ # # ][ # # ]
[ # # ]
2765 : : {
2766 [ # # ][ # # ]: 0 : EntityType this_type = TYPE_FROM_HANDLE( *rit );
2767 [ # # ][ # # ]: 0 : std::cout << CN::EntityTypeName( this_type ) << " " << ID_FROM_HANDLE( *rit ) << ":" << endl;
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
2768 : :
2769 [ # # ][ # # ]: 0 : tmp_result = ( const_cast< Core* >( this ) )->list_entity( *rit );
2770 [ # # ]: 0 : if( MB_SUCCESS != tmp_result ) result = tmp_result;
2771 : : }
2772 : :
2773 : 0 : return result;
2774 : : }
2775 : :
2776 : 68 : ErrorCode Core::list_entity( const EntityHandle entity ) const
2777 : : {
2778 : : ErrorCode result;
2779 [ + - ]: 68 : HandleVec adj_vec;
2780 : :
2781 [ + - ][ - + ]: 68 : if( !is_valid( entity ) )
2782 : : {
2783 [ # # ][ # # ]: 0 : std::cout << "(invalid)" << std::endl;
2784 : 0 : return MB_SUCCESS;
2785 : : }
2786 : :
2787 [ + - ]: 68 : if( 0 != globalIdTag )
2788 : : {
2789 : : int dum;
2790 [ + - ]: 68 : result = tag_get_data( globalIdTag, &entity, 1, &dum );
2791 [ + - ][ + - ]: 68 : if( MB_SUCCESS == result ) std::cout << "Global id = " << dum << std::endl;
[ + - ][ + - ]
2792 : : }
2793 : :
2794 : : // list entity
2795 [ + - ]: 68 : EntityType this_type = TYPE_FROM_HANDLE( entity );
2796 [ - + ]: 68 : if( this_type == MBVERTEX )
2797 : : {
2798 : : double coords[3];
2799 [ # # ][ # # ]: 0 : result = get_coords( &( entity ), 1, coords );MB_CHK_ERR( result );
[ # # ][ # # ]
2800 [ # # ][ # # ]: 0 : std::cout << "Coordinates: (" << coords[0] << ", " << coords[1] << ", " << coords[2] << ")" << std::endl;
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
2801 : : }
2802 [ - + ]: 68 : else if( this_type == MBENTITYSET )
2803 [ # # ]: 0 : this->print( entity, "" );
2804 : :
2805 [ + - ][ + - ]: 68 : std::cout << " Adjacencies:" << std::endl;
2806 : 68 : bool some = false;
2807 : 68 : int multiple = 0;
2808 [ + + ]: 340 : for( int dim = 0; dim <= 3; dim++ )
2809 : : {
2810 [ + - ][ + + ]: 272 : if( dim == CN::Dimension( this_type ) ) continue;
2811 : 204 : adj_vec.clear();
2812 : : // use const_cast here 'cuz we're in a const function and we're passing 'false' for
2813 : : // create_if_missing, so we know we won't change anything
2814 [ + - ]: 204 : result = ( const_cast< Core* >( this ) )->get_adjacencies( &( entity ), 1, dim, false, adj_vec );
2815 [ - + ]: 204 : if( MB_FAILURE == result ) continue;
2816 [ + - ][ + - ]: 566 : for( HandleVec::iterator adj_it = adj_vec.begin(); adj_it != adj_vec.end(); ++adj_it )
[ + + ]
2817 : : {
2818 [ + - ][ + + ]: 362 : if( adj_it != adj_vec.begin() )
2819 [ + - ]: 217 : std::cout << ", ";
2820 : : else
2821 [ + - ]: 145 : std::cout << " ";
2822 [ + - ][ + - ]: 362 : std::cout << CN::EntityTypeName( TYPE_FROM_HANDLE( *adj_it ) ) << " " << ID_FROM_HANDLE( *adj_it );
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
2823 : : }
2824 [ + + ]: 204 : if( !adj_vec.empty() )
2825 : : {
2826 [ + - ]: 145 : std::cout << std::endl;
2827 : 145 : some = true;
2828 : : }
2829 [ - + ]: 204 : if( MB_MULTIPLE_ENTITIES_FOUND == result ) multiple += dim;
2830 : : }
2831 [ - + ][ # # ]: 68 : if( !some ) std::cout << "(none)" << std::endl;
[ # # ]
2832 : : const EntityHandle* explicit_adjs;
2833 : : int num_exp;
2834 [ + - ]: 68 : aEntityFactory->get_adjacencies( entity, explicit_adjs, num_exp );
2835 [ - + ][ # # ]: 68 : if( NULL != explicit_adjs && 0 != num_exp )
2836 : : {
2837 [ # # ]: 0 : std::cout << " Explicit adjacencies: ";
2838 [ # # ]: 0 : for( int i = 0; i < num_exp; i++ )
2839 : : {
2840 [ # # ][ # # ]: 0 : if( i != 0 ) std::cout << ", ";
2841 [ # # ][ # # ]: 0 : std::cout << CN::EntityTypeName( TYPE_FROM_HANDLE( explicit_adjs[i] ) ) << " "
[ # # ][ # # ]
2842 [ # # ][ # # ]: 0 : << ID_FROM_HANDLE( explicit_adjs[i] );
2843 : : }
2844 [ # # ]: 0 : std::cout << std::endl;
2845 : : }
2846 [ - + ][ # # ]: 68 : if( multiple != 0 ) std::cout << " (MULTIPLE = " << multiple << ")" << std::endl;
[ # # ][ # # ]
[ # # ]
2847 : :
2848 [ + - ][ + - ]: 68 : result = print_entity_tags( std::string(), entity, MB_TAG_DENSE );
2849 : :
2850 [ + - ]: 68 : std::cout << std::endl;
2851 : :
2852 : 68 : return result;
2853 : : }
2854 : :
2855 : 8 : ErrorCode Core::convert_entities( const EntityHandle meshset, const bool mid_side, const bool mid_face,
2856 : : const bool mid_volume, Interface::HONodeAddedRemoved* function_object )
2857 : : {
2858 [ + - ]: 8 : HigherOrderFactory fact( this, function_object );
2859 [ + - ]: 8 : return fact.convert( meshset, mid_side, mid_face, mid_volume );
2860 : : }
2861 : :
2862 : : //! function to get the side number given two elements; returns
2863 : : //! MB_FAILURE if child not related to parent; does *not* create adjacencies
2864 : : //! between parent and child
2865 : 3604 : ErrorCode Core::side_number( const EntityHandle parent, const EntityHandle child, int& sd_number, int& sense,
2866 : : int& offset ) const
2867 : : {
2868 : : // get the connectivity of parent and child
2869 : 3604 : const EntityHandle *parent_conn = NULL, *child_conn = NULL;
2870 : 3604 : int num_parent_vertices = 0, num_child_vertices = 0;
2871 [ + - ]: 3604 : ErrorCode result = get_connectivity( parent, parent_conn, num_parent_vertices, true );
2872 [ - + ]: 3604 : if( MB_NOT_IMPLEMENTED == result )
2873 : : {
2874 [ # # ][ # # ]: 0 : static std::vector< EntityHandle > tmp_connect( CN::MAX_NODES_PER_ELEMENT );
[ # # ][ # # ]
2875 [ # # ]: 0 : result = get_connectivity( parent, parent_conn, num_parent_vertices, true, &tmp_connect );
2876 : : }
2877 [ - + ]: 3604 : if( MB_SUCCESS != result ) return result;
2878 : :
2879 [ + - ][ - + ]: 3604 : if( TYPE_FROM_HANDLE( child ) == MBVERTEX )
2880 : : {
2881 [ # # ]: 0 : int child_index = std::find( parent_conn, parent_conn + num_parent_vertices, child ) - parent_conn;
2882 [ # # ]: 0 : if( child_index == num_parent_vertices )
2883 : : {
2884 : 0 : sd_number = -1;
2885 : 0 : sense = 0;
2886 : 0 : return MB_FAILURE;
2887 : : }
2888 : : else
2889 : : {
2890 : 0 : sd_number = child_index;
2891 : 0 : sense = 1;
2892 : 0 : return MB_SUCCESS;
2893 : : }
2894 : : }
2895 : :
2896 [ + - ][ - + ]: 3604 : if( TYPE_FROM_HANDLE( parent ) == MBPOLYHEDRON )
2897 : : {
2898 : : // find the child in the parent_conn connectivity list, and call it a day ..
2899 : : // it should work only for faces within a conn list
2900 [ # # ]: 0 : for( int i = 0; i < num_parent_vertices; i++ )
2901 [ # # ]: 0 : if( child == parent_conn[i] )
2902 : : {
2903 : 0 : sd_number = i;
2904 : 0 : sense = 1; // always
2905 : 0 : offset = 0;
2906 : 0 : return MB_SUCCESS;
2907 : : }
2908 : 0 : return MB_FAILURE;
2909 : : }
2910 [ + - ][ - + ]: 3604 : result = get_connectivity( child, child_conn, num_child_vertices, true );MB_CHK_ERR( result );
[ # # ][ # # ]
2911 : :
2912 : : // call handle vector-based function
2913 [ + - ][ + - ]: 3604 : if( TYPE_FROM_HANDLE( parent ) != MBPOLYGON && TYPE_FROM_HANDLE( parent ) != MBPOLYHEDRON )
[ + - ][ + - ]
[ + - ]
2914 : : {
2915 : :
2916 : : // find indices into parent_conn for each entry in child_conn
2917 : : int child_conn_indices[10];
2918 [ - + ]: 3604 : assert( (unsigned)num_child_vertices <= sizeof( child_conn_indices ) / sizeof( child_conn_indices[0] ) );
2919 [ + + ]: 10933 : for( int i = 0; i < num_child_vertices; ++i )
2920 : : {
2921 : : child_conn_indices[i] =
2922 [ + - ]: 7330 : std::find( parent_conn, parent_conn + num_parent_vertices, child_conn[i] ) - parent_conn;
2923 [ + + ]: 7330 : if( child_conn_indices[i] >= num_parent_vertices )
2924 : : {
2925 : 1 : sd_number = -1;
2926 : 1 : return MB_FAILURE;
2927 : : }
2928 : : }
2929 : :
2930 : : int temp_result = CN::SideNumber( TYPE_FROM_HANDLE( parent ), child_conn_indices, num_child_vertices,
2931 [ + - ][ + - ]: 3603 : CN::Dimension( TYPE_FROM_HANDLE( child ) ), sd_number, sense, offset );
[ + - ][ + - ]
2932 [ + + ]: 3604 : return ( 0 == temp_result ? MB_SUCCESS : MB_FAILURE );
2933 : : }
2934 [ # # ][ # # ]: 0 : else if( TYPE_FROM_HANDLE( parent ) == MBPOLYGON )
2935 : : {
2936 : : // find location of 1st vertex; this works even for padded vertices
2937 [ # # ]: 0 : const EntityHandle* first_v = std::find( parent_conn, parent_conn + num_parent_vertices, child_conn[0] );
2938 [ # # ]: 0 : if( first_v == parent_conn + num_parent_vertices ) return MB_ENTITY_NOT_FOUND;
2939 : 0 : sd_number = first_v - parent_conn;
2940 : 0 : offset = sd_number;
2941 [ # # ][ # # ]: 0 : if( TYPE_FROM_HANDLE( child ) == MBVERTEX )
2942 : : {
2943 : 0 : sense = 0;
2944 : 0 : return MB_SUCCESS;
2945 : : }
2946 [ # # ][ # # ]: 0 : else if( TYPE_FROM_HANDLE( child ) == MBPOLYGON )
2947 : : {
2948 [ # # ]: 0 : bool match = CN::ConnectivityMatch( parent_conn, child_conn, num_parent_vertices, sense, offset );
2949 : 0 : sd_number = 0;
2950 [ # # ]: 0 : if( match )
2951 : 0 : return MB_SUCCESS;
2952 : : else
2953 : 0 : return MB_ENTITY_NOT_FOUND;
2954 : : }
2955 [ # # ][ # # ]: 0 : else if( TYPE_FROM_HANDLE( child ) == MBEDGE )
2956 : : {
2957 : : // determine the actual number of vertices, for the padded case
2958 : : // the padded case could be like ABCDEFFF; num_parent_vertices=8,
2959 : : // actual_num_parent_vertices=6
2960 : 0 : int actual_num_parent_vertices = num_parent_vertices;
2961 [ # # ][ # # ]: 0 : while( actual_num_parent_vertices >= 3 &&
2962 : 0 : ( parent_conn[actual_num_parent_vertices - 2] == parent_conn[actual_num_parent_vertices - 1] ) )
2963 : 0 : actual_num_parent_vertices--;
2964 : :
2965 [ # # ]: 0 : if( parent_conn[( sd_number + 1 ) % num_parent_vertices] == child_conn[1] )
2966 : 0 : sense = 1;
2967 [ # # ]: 0 : else if( parent_conn[( sd_number + num_parent_vertices - 1 ) % num_parent_vertices] ==
2968 : 0 : child_conn[1] ) // this will also cover edge AF for padded case, side will
2969 : : // be 0, sense -1
2970 : 0 : sense = -1;
2971 : : // if edge FA in above example, we should return sd_number = 5, sense 1
2972 [ # # ][ # # ]: 0 : else if( ( sd_number == actual_num_parent_vertices - 1 ) && ( child_conn[1] == parent_conn[0] ) )
2973 : 0 : sense = 1;
2974 : : else
2975 : 0 : return MB_ENTITY_NOT_FOUND;
2976 : 0 : return MB_SUCCESS;
2977 : : }
2978 : : }
2979 : :
2980 : 3604 : return MB_FAILURE;
2981 : : }
2982 : :
2983 : : //! given an entity and the connectivity and type of one of its subfacets, find the
2984 : : //! high order node on that subfacet, if any
2985 : 0 : ErrorCode Core::high_order_node( const EntityHandle parent_handle, const EntityHandle* subfacet_conn,
2986 : : const EntityType subfacet_type, EntityHandle& hon ) const
2987 : : {
2988 : 0 : hon = 0;
2989 : :
2990 [ # # ]: 0 : EntityType parent_type = TYPE_FROM_HANDLE( parent_handle );
2991 : :
2992 : : // get the parent's connectivity
2993 : 0 : const EntityHandle* parent_conn = NULL;
2994 : 0 : int num_parent_vertices = 0;
2995 [ # # ][ # # ]: 0 : ErrorCode result = get_connectivity( parent_handle, parent_conn, num_parent_vertices, false );MB_CHK_ERR( result );
[ # # ][ # # ]
2996 : :
2997 : : // find whether this entity has ho nodes
2998 : : int mid_nodes[4];
2999 [ # # ]: 0 : CN::HasMidNodes( parent_type, num_parent_vertices, mid_nodes );
3000 : :
3001 : : // check whether this entity has mid nodes on this dimension subfacet;
3002 : : // use dimension-1 because vertices don't have mid nodes
3003 [ # # ][ # # ]: 0 : if( !mid_nodes[CN::Dimension( subfacet_type )] ) return MB_SUCCESS;
3004 : :
3005 : : // ok, we have mid nodes; now must compute expected index in connectivity array;
3006 : : // ho nodes stored for edges, faces then entity
3007 : :
3008 : : // offset starts with # corner vertices
3009 [ # # ]: 0 : int offset = CN::VerticesPerEntity( parent_type );
3010 : : int i;
3011 : :
3012 [ # # ][ # # ]: 0 : for( i = 0; i < CN::Dimension( subfacet_type ) - 1; i++ )
3013 : : // for each dimension lower than that of the subfacet we're looking for,
3014 : : // if this entity has midnodes in that dimension, increment offset by #
3015 : : // of subfacets of that dimension; use dimension-1 in loop because
3016 : : // canon numbering table only has 2 positions, for edges and faces;
3017 [ # # ]: 0 : if( mid_nodes[i + 1] ) offset += CN::mConnectivityMap[parent_type][i].num_sub_elements;
3018 : :
3019 : : // now add the index of this subfacet; only need to if it's not the highest dimension
3020 [ # # ]: 0 : if( subfacet_type != parent_type )
3021 : : {
3022 : :
3023 : : // find indices into parent_conn for each entry in child_conn
3024 [ # # ]: 0 : unsigned subfacet_size = CN::VerticesPerEntity( subfacet_type );
3025 : : int subfacet_indices[10];
3026 [ # # ]: 0 : assert( subfacet_size <= sizeof( subfacet_indices ) / sizeof( subfacet_indices[0] ) );
3027 [ # # ]: 0 : for( unsigned j = 0; j < subfacet_size; ++j )
3028 : : {
3029 : : subfacet_indices[j] =
3030 [ # # ]: 0 : std::find( parent_conn, parent_conn + num_parent_vertices, subfacet_conn[j] ) - parent_conn;
3031 [ # # ]: 0 : if( subfacet_indices[j] >= num_parent_vertices ) { return MB_FAILURE; }
3032 : : }
3033 : :
3034 : : int dum, side_no, temp_offset;
3035 : : int temp_result =
3036 [ # # ]: 0 : CN::SideNumber( parent_type, subfacet_indices, subfacet_size, subfacet_type, side_no, dum, temp_offset );
3037 [ # # ]: 0 : if( temp_result != 0 ) return MB_FAILURE;
3038 : :
3039 : 0 : offset += side_no;
3040 : : }
3041 : :
3042 : : // offset shouldn't be off the end of the connectivity vector
3043 [ # # ]: 0 : if( offset >= num_parent_vertices ) return MB_INDEX_OUT_OF_RANGE;
3044 : :
3045 : 0 : hon = parent_conn[offset];
3046 : :
3047 : 0 : return MB_SUCCESS;
3048 : : }
3049 : :
3050 : : //! given an entity and a target dimension & side number, get that entity
3051 : 177 : ErrorCode Core::side_element( const EntityHandle source_entity, const int dim, const int sd_number,
3052 : : EntityHandle& target_entity ) const
3053 : : {
3054 : : // get a handle on the connectivity
3055 : : const EntityHandle* verts;
3056 : : int num_verts;
3057 [ + - ][ - + ]: 177 : ErrorCode result = get_connectivity( source_entity, verts, num_verts );MB_CHK_ERR( result );
[ # # ][ # # ]
3058 : :
3059 : : // special case for vertices
3060 [ - + ]: 177 : if( dim == 0 )
3061 : : {
3062 [ # # ]: 0 : if( sd_number < num_verts )
3063 : : {
3064 : 0 : target_entity = verts[sd_number];
3065 : 0 : return MB_SUCCESS;
3066 : : }
3067 : :
3068 : : else
3069 : 0 : return MB_INDEX_OUT_OF_RANGE;
3070 : : }
3071 : :
3072 : : // get the vertices comprising the target entity
3073 [ + - ][ + - ]: 354 : Range side_verts, target_ents;
3074 [ + - ]: 177 : const EntityType source_type = TYPE_FROM_HANDLE( source_entity );
3075 : : // first get the indices
3076 [ + - ]: 354 : std::vector< int > vertex_indices;
3077 : :
3078 [ + - ]: 177 : int temp_result = CN::AdjacentSubEntities( source_type, &sd_number, 1, dim, 0, vertex_indices );
3079 [ - + ]: 177 : if( 0 != temp_result ) return MB_FAILURE;
3080 : : // now get the actual vertices
3081 [ + + ]: 531 : for( unsigned int i = 0; i < vertex_indices.size(); i++ )
3082 [ + - ][ + - ]: 354 : side_verts.insert( verts[vertex_indices[i]] );
3083 : :
3084 : : // now look for an entity of the correct type
3085 : : // use const_cast here 'cuz we're in a const function and we're passing 'false' for
3086 : : // create_if_missing, so we know we won't change anything
3087 [ + - ]: 177 : result = ( const_cast< Core* >( this ) )->get_adjacencies( side_verts, dim, false, target_ents );
3088 [ - + ][ # # ]: 177 : if( MB_SUCCESS != result && MB_MULTIPLE_ENTITIES_FOUND != result ) return result;
3089 : :
3090 [ + - ][ - + ]: 354 : if( !target_ents.empty() && TYPE_FROM_HANDLE( *( target_ents.begin() ) ) != MBVERTEX &&
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ - + ]
[ - + # # ]
3091 [ # # ][ # # ]: 177 : TYPE_FROM_HANDLE( *( target_ents.begin() ) ) !=
[ # # ][ - + ]
[ # # ]
3092 : 0 : CN::mConnectivityMap[source_type][dim - 1].target_type[sd_number] )
3093 : 0 : return MB_ENTITY_NOT_FOUND;
3094 : :
3095 [ + - ][ - + ]: 177 : if( !target_ents.empty() ) target_entity = *( target_ents.begin() );
[ # # ][ # # ]
3096 : :
3097 : 354 : return result;
3098 : : }
3099 : :
3100 : : //-------------------------Set Functions---------------------//
3101 : :
3102 : 31176 : ErrorCode Core::create_meshset( const unsigned int setoptions, EntityHandle& ms_handle, int )
3103 : : {
3104 : 31176 : return sequence_manager()->create_mesh_set( setoptions, ms_handle );
3105 : : }
3106 : :
3107 : 1473 : ErrorCode Core::get_meshset_options( const EntityHandle ms_handle, unsigned int& setoptions ) const
3108 : : {
3109 [ + + ]: 1473 : if( !ms_handle )
3110 : : { // root set
3111 : 36 : setoptions = MESHSET_SET | MESHSET_TRACK_OWNER;
3112 : 36 : return MB_SUCCESS;
3113 : : }
3114 : :
3115 : 1437 : const MeshSet* set = get_mesh_set( sequence_manager(), ms_handle );
3116 [ - + ]: 1437 : if( !set ) return MB_ENTITY_NOT_FOUND;
3117 : :
3118 : 1437 : setoptions = set->flags();
3119 : 1437 : return MB_SUCCESS;
3120 : : }
3121 : :
3122 : 5 : ErrorCode Core::set_meshset_options( const EntityHandle ms_handle, const unsigned int setoptions )
3123 : : {
3124 : 5 : MeshSet* set = get_mesh_set( sequence_manager(), ms_handle );
3125 [ + + ]: 5 : if( !set ) return MB_ENTITY_NOT_FOUND;
3126 : :
3127 : 4 : return set->set_flags( setoptions, ms_handle, a_entity_factory() );
3128 : : }
3129 : :
3130 : 32932 : ErrorCode Core::clear_meshset( const EntityHandle* ms_handles, const int num_meshsets )
3131 : : {
3132 : 32932 : ErrorCode result = MB_SUCCESS;
3133 [ + + ]: 65864 : for( int i = 0; i < num_meshsets; ++i )
3134 : : {
3135 : 32932 : MeshSet* set = get_mesh_set( sequence_manager(), ms_handles[i] );
3136 [ + + ]: 32932 : if( set )
3137 : 32931 : set->clear( ms_handles[i], a_entity_factory() );
3138 : : else
3139 : 1 : result = MB_ENTITY_NOT_FOUND;
3140 : : }
3141 : :
3142 : 32932 : return result;
3143 : : }
3144 : :
3145 : 0 : ErrorCode Core::clear_meshset( const Range& ms_handles )
3146 : : {
3147 : 0 : ErrorCode result = MB_SUCCESS;
3148 [ # # ][ # # ]: 0 : for( Range::iterator i = ms_handles.begin(); i != ms_handles.end(); ++i )
[ # # ][ # # ]
[ # # ]
3149 : : {
3150 [ # # ][ # # ]: 0 : MeshSet* set = get_mesh_set( sequence_manager(), *i );
[ # # ]
3151 [ # # ]: 0 : if( set )
3152 [ # # ][ # # ]: 0 : set->clear( *i, a_entity_factory() );
[ # # ]
3153 : : else
3154 : 0 : result = MB_ENTITY_NOT_FOUND;
3155 : : }
3156 : :
3157 : 0 : return result;
3158 : : }
3159 : :
3160 : 37 : ErrorCode Core::subtract_meshset( EntityHandle meshset1, const EntityHandle meshset2 )
3161 : : {
3162 : 37 : MeshSet* set1 = get_mesh_set( sequence_manager(), meshset1 );
3163 : 37 : MeshSet* set2 = get_mesh_set( sequence_manager(), meshset2 );
3164 [ + + ][ - + ]: 37 : if( !set1 || !set2 ) return MB_ENTITY_NOT_FOUND;
3165 : :
3166 : 36 : return set1->subtract( set2, meshset1, a_entity_factory() );
3167 : : }
3168 : :
3169 : 38 : ErrorCode Core::intersect_meshset( EntityHandle meshset1, const EntityHandle meshset2 )
3170 : : {
3171 : 38 : MeshSet* set1 = get_mesh_set( sequence_manager(), meshset1 );
3172 : 38 : MeshSet* set2 = get_mesh_set( sequence_manager(), meshset2 );
3173 [ + + ][ - + ]: 38 : if( !set1 || !set2 ) return MB_ENTITY_NOT_FOUND;
3174 : :
3175 : 37 : return set1->intersect( set2, meshset1, a_entity_factory() );
3176 : : }
3177 : :
3178 : 40 : ErrorCode Core::unite_meshset( EntityHandle meshset1, const EntityHandle meshset2 )
3179 : : {
3180 : 40 : MeshSet* set1 = get_mesh_set( sequence_manager(), meshset1 );
3181 : 40 : MeshSet* set2 = get_mesh_set( sequence_manager(), meshset2 );
3182 [ + + ][ - + ]: 40 : if( !set1 || !set2 ) return MB_ENTITY_NOT_FOUND;
3183 : :
3184 : 39 : return set1->unite( set2, meshset1, a_entity_factory() );
3185 : : }
3186 : :
3187 : 19052 : ErrorCode Core::add_entities( EntityHandle meshset, const Range& entities )
3188 : : {
3189 : 19052 : MeshSet* set = get_mesh_set( sequence_manager(), meshset );
3190 [ + - ]: 19052 : if( set )
3191 : 19052 : return set->add_entities( entities, meshset, a_entity_factory() );
3192 : : else
3193 : 0 : return MB_ENTITY_NOT_FOUND;
3194 : : }
3195 : :
3196 : 11572 : ErrorCode Core::add_entities( EntityHandle meshset, const EntityHandle* entities, const int num_entities )
3197 : : {
3198 : 11572 : MeshSet* set = get_mesh_set( sequence_manager(), meshset );
3199 [ + + ]: 11572 : if( set )
3200 : 11571 : return set->add_entities( entities, num_entities, meshset, a_entity_factory() );
3201 : : else
3202 : 1 : return MB_ENTITY_NOT_FOUND;
3203 : : }
3204 : :
3205 : : //! remove a range of entities from a meshset
3206 : 172 : ErrorCode Core::remove_entities( EntityHandle meshset, const Range& entities )
3207 : : {
3208 : 172 : MeshSet* set = get_mesh_set( sequence_manager(), meshset );
3209 [ + - ]: 172 : if( set )
3210 : 172 : return set->remove_entities( entities, meshset, a_entity_factory() );
3211 : : else
3212 : 0 : return MB_ENTITY_NOT_FOUND;
3213 : : }
3214 : :
3215 : : //! remove a vector of entities from a meshset
3216 : 203 : ErrorCode Core::remove_entities( EntityHandle meshset, const EntityHandle* entities, const int num_entities )
3217 : : {
3218 : 203 : MeshSet* set = get_mesh_set( sequence_manager(), meshset );
3219 [ + + ]: 203 : if( set )
3220 : 202 : return set->remove_entities( entities, num_entities, meshset, a_entity_factory() );
3221 : : else
3222 : 1 : return MB_ENTITY_NOT_FOUND;
3223 : : }
3224 : :
3225 : : //! return true if all entities are contained in set
3226 : 23389 : bool Core::contains_entities( EntityHandle meshset, const EntityHandle* entities, int num_entities,
3227 : : const int operation_type )
3228 : : {
3229 [ + + ]: 23389 : if( !meshset ) // root
3230 : 142 : return true;
3231 [ + - ]: 23247 : else if( MeshSet* set = get_mesh_set( sequence_manager(), meshset ) )
3232 : 23247 : return set->contains_entities( entities, num_entities, operation_type );
3233 : : else
3234 : 0 : return false;
3235 : : }
3236 : :
3237 : : // replace entities in a meshset
3238 : 7 : ErrorCode Core::replace_entities( EntityHandle meshset, const EntityHandle* old_entities,
3239 : : const EntityHandle* new_entities, int num_entities )
3240 : : {
3241 : 7 : MeshSet* set = get_mesh_set( sequence_manager(), meshset );
3242 [ + + ]: 7 : if( set )
3243 : 6 : return set->replace_entities( meshset, old_entities, new_entities, num_entities, a_entity_factory() );
3244 : : else
3245 : 1 : return MB_ENTITY_NOT_FOUND;
3246 : : }
3247 : :
3248 : 462 : ErrorCode Core::get_parent_meshsets( const EntityHandle meshset, std::vector< EntityHandle >& parents,
3249 : : const int num_hops ) const
3250 : : {
3251 [ - + ]: 462 : if( 0 == meshset ) return MB_ENTITY_NOT_FOUND;
3252 : :
3253 : : const EntitySequence* seq;
3254 [ + - ][ + - ]: 462 : ErrorCode rval = sequence_manager()->find( meshset, seq );
3255 [ - + ]: 462 : if( MB_SUCCESS != rval ) return MB_ENTITY_NOT_FOUND;
3256 : 462 : const MeshSetSequence* mseq = reinterpret_cast< const MeshSetSequence* >( seq );
3257 : :
3258 [ + - ][ + - ]: 462 : return mseq->get_parents( sequence_manager(), meshset, parents, num_hops );
3259 : : }
3260 : :
3261 : 285 : ErrorCode Core::get_parent_meshsets( const EntityHandle meshset, Range& parents, const int num_hops ) const
3262 : : {
3263 [ + + ]: 285 : if( 0 == meshset ) return MB_ENTITY_NOT_FOUND;
3264 : :
3265 [ + - ]: 283 : std::vector< EntityHandle > parent_vec;
3266 [ + - ][ - + ]: 283 : ErrorCode result = get_parent_meshsets( meshset, parent_vec, num_hops );MB_CHK_ERR( result );
[ # # ][ # # ]
3267 [ + - ]: 283 : std::sort( parent_vec.begin(), parent_vec.end() );
3268 [ + - ][ + - ]: 283 : std::copy( parent_vec.rbegin(), parent_vec.rend(), range_inserter( parents ) );
3269 : 285 : return MB_SUCCESS;
3270 : : }
3271 : :
3272 : 195625 : ErrorCode Core::get_child_meshsets( const EntityHandle meshset, std::vector< EntityHandle >& children,
3273 : : const int num_hops ) const
3274 : : {
3275 [ - + ]: 195625 : if( 0 == meshset ) return MB_ENTITY_NOT_FOUND;
3276 : :
3277 : : const EntitySequence* seq;
3278 [ + - ][ + - ]: 195625 : ErrorCode rval = sequence_manager()->find( meshset, seq );
3279 [ - + ]: 195625 : if( MB_SUCCESS != rval ) return MB_ENTITY_NOT_FOUND;
3280 : 195625 : const MeshSetSequence* mseq = reinterpret_cast< const MeshSetSequence* >( seq );
3281 : :
3282 [ + - ][ + - ]: 195625 : return mseq->get_children( sequence_manager(), meshset, children, num_hops );
3283 : : }
3284 : :
3285 : 1158 : ErrorCode Core::get_child_meshsets( const EntityHandle meshset, Range& children, const int num_hops ) const
3286 : : {
3287 [ + + ]: 1158 : if( 0 == meshset ) return MB_ENTITY_NOT_FOUND;
3288 : :
3289 [ + - ]: 1156 : std::vector< EntityHandle > child_vec;
3290 [ + - ][ - + ]: 1156 : ErrorCode result = get_child_meshsets( meshset, child_vec, num_hops );MB_CHK_ERR( result );
[ # # ][ # # ]
3291 [ + - ]: 1156 : std::sort( child_vec.begin(), child_vec.end() );
3292 [ + - ][ + - ]: 1156 : std::copy( child_vec.rbegin(), child_vec.rend(), range_inserter( children ) );
3293 : 1158 : return MB_SUCCESS;
3294 : : }
3295 : :
3296 : 13 : ErrorCode Core::get_contained_meshsets( const EntityHandle meshset, std::vector< EntityHandle >& children,
3297 : : const int num_hops ) const
3298 : : {
3299 [ + + ][ + - ]: 13 : if( 0 == meshset ) { return get_entities_by_type( meshset, MBENTITYSET, children ); }
3300 : :
3301 : : const EntitySequence* seq;
3302 [ + - ][ + - ]: 2 : ErrorCode rval = sequence_manager()->find( meshset, seq );
3303 [ - + ]: 2 : if( MB_SUCCESS != rval ) return MB_ENTITY_NOT_FOUND;
3304 : 2 : const MeshSetSequence* mseq = reinterpret_cast< const MeshSetSequence* >( seq );
3305 : :
3306 [ + - ][ + - ]: 13 : return mseq->get_contained_sets( sequence_manager(), meshset, children, num_hops );
3307 : : }
3308 : :
3309 : 1 : ErrorCode Core::get_contained_meshsets( const EntityHandle meshset, Range& children, const int num_hops ) const
3310 : : {
3311 [ + - ][ + - ]: 1 : if( 0 == meshset ) { return get_entities_by_type( meshset, MBENTITYSET, children ); }
3312 : :
3313 [ # # ]: 0 : std::vector< EntityHandle > child_vec;
3314 [ # # ][ # # ]: 0 : ErrorCode result = get_contained_meshsets( meshset, child_vec, num_hops );MB_CHK_ERR( result );
[ # # ][ # # ]
3315 [ # # ]: 0 : std::sort( child_vec.begin(), child_vec.end() );
3316 [ # # ][ # # ]: 0 : std::copy( child_vec.rbegin(), child_vec.rend(), range_inserter( children ) );
3317 : 1 : return MB_SUCCESS;
3318 : : }
3319 : :
3320 : 978 : ErrorCode Core::num_parent_meshsets( const EntityHandle meshset, int* number, const int num_hops ) const
3321 : : {
3322 [ + + ]: 978 : if( 0 == meshset ) return MB_ENTITY_NOT_FOUND;
3323 : :
3324 : : const EntitySequence* seq;
3325 [ + - ][ + - ]: 976 : ErrorCode rval = sequence_manager()->find( meshset, seq );
3326 [ - + ]: 976 : if( MB_SUCCESS != rval ) return MB_ENTITY_NOT_FOUND;
3327 : 976 : const MeshSetSequence* mseq = reinterpret_cast< const MeshSetSequence* >( seq );
3328 : :
3329 [ + - ][ + - ]: 978 : return mseq->num_parents( sequence_manager(), meshset, *number, num_hops );
3330 : : }
3331 : :
3332 : 1066 : ErrorCode Core::num_child_meshsets( const EntityHandle meshset, int* number, const int num_hops ) const
3333 : : {
3334 [ + + ]: 1066 : if( 0 == meshset ) return MB_ENTITY_NOT_FOUND;
3335 : :
3336 : : const EntitySequence* seq;
3337 [ + - ][ + - ]: 1064 : ErrorCode rval = sequence_manager()->find( meshset, seq );
3338 [ - + ]: 1064 : if( MB_SUCCESS != rval ) return MB_ENTITY_NOT_FOUND;
3339 : 1064 : const MeshSetSequence* mseq = reinterpret_cast< const MeshSetSequence* >( seq );
3340 : :
3341 [ + - ][ + - ]: 1066 : return mseq->num_children( sequence_manager(), meshset, *number, num_hops );
3342 : : }
3343 : :
3344 : 22 : ErrorCode Core::num_contained_meshsets( const EntityHandle meshset, int* number, const int num_hops ) const
3345 : : {
3346 [ + + ][ + - ]: 22 : if( 0 == meshset ) { return get_number_entities_by_type( 0, MBENTITYSET, *number ); }
3347 : :
3348 : : const EntitySequence* seq;
3349 [ + - ][ + - ]: 3 : ErrorCode rval = sequence_manager()->find( meshset, seq );
3350 [ - + ]: 3 : if( MB_SUCCESS != rval ) return MB_ENTITY_NOT_FOUND;
3351 : 3 : const MeshSetSequence* mseq = reinterpret_cast< const MeshSetSequence* >( seq );
3352 : :
3353 [ + - ][ + - ]: 22 : return mseq->num_contained_sets( sequence_manager(), meshset, *number, num_hops );
3354 : : }
3355 : :
3356 : 18 : ErrorCode Core::add_parent_meshset( EntityHandle meshset, const EntityHandle parent_meshset )
3357 : : {
3358 : 18 : MeshSet* set_ptr = get_mesh_set( sequence_manager(), meshset );
3359 : 18 : MeshSet* parent_ptr = get_mesh_set( sequence_manager(), parent_meshset );
3360 [ + + ][ - + ]: 18 : if( !set_ptr || !parent_ptr ) return MB_ENTITY_NOT_FOUND;
3361 : :
3362 : 17 : set_ptr->add_parent( parent_meshset );
3363 : 17 : return MB_SUCCESS;
3364 : : }
3365 : :
3366 : 771 : ErrorCode Core::add_parent_meshsets( EntityHandle meshset, const EntityHandle* parents, int count )
3367 : : {
3368 : 771 : MeshSet* set_ptr = get_mesh_set( sequence_manager(), meshset );
3369 [ + + ]: 771 : if( !set_ptr ) return MB_ENTITY_NOT_FOUND;
3370 : :
3371 [ + + ]: 2191 : for( int i = 0; i < count; ++i )
3372 [ - + ]: 1421 : if( !get_mesh_set( sequence_manager(), parents[i] ) ) return MB_ENTITY_NOT_FOUND;
3373 : :
3374 [ + + ]: 2191 : for( int i = 0; i < count; ++i )
3375 : 1421 : set_ptr->add_parent( parents[i] );
3376 : 770 : return MB_SUCCESS;
3377 : : }
3378 : :
3379 : 30302 : ErrorCode Core::add_child_meshset( EntityHandle meshset, const EntityHandle child_meshset )
3380 : : {
3381 : 30302 : MeshSet* set_ptr = get_mesh_set( sequence_manager(), meshset );
3382 : 30302 : MeshSet* child_ptr = get_mesh_set( sequence_manager(), child_meshset );
3383 [ + + ][ - + ]: 30302 : if( !set_ptr || !child_ptr ) return MB_ENTITY_NOT_FOUND;
3384 : :
3385 : 30301 : set_ptr->add_child( child_meshset );
3386 : 30301 : return MB_SUCCESS;
3387 : : }
3388 : :
3389 : 940 : ErrorCode Core::add_child_meshsets( EntityHandle meshset, const EntityHandle* children, int count )
3390 : : {
3391 : 940 : MeshSet* set_ptr = get_mesh_set( sequence_manager(), meshset );
3392 [ + + ]: 940 : if( !set_ptr ) return MB_ENTITY_NOT_FOUND;
3393 : :
3394 [ + + ]: 2558 : for( int i = 0; i < count; ++i )
3395 [ - + ]: 1619 : if( !get_mesh_set( sequence_manager(), children[i] ) ) return MB_ENTITY_NOT_FOUND;
3396 : :
3397 [ + + ]: 2558 : for( int i = 0; i < count; ++i )
3398 : 1619 : set_ptr->add_child( children[i] );
3399 : 939 : return MB_SUCCESS;
3400 : : }
3401 : :
3402 : 770 : ErrorCode Core::add_parent_child( EntityHandle parent, EntityHandle child )
3403 : : {
3404 : 770 : MeshSet* parent_ptr = get_mesh_set( sequence_manager(), parent );
3405 : 770 : MeshSet* child_ptr = get_mesh_set( sequence_manager(), child );
3406 [ + + ][ - + ]: 770 : if( !parent_ptr || !child_ptr ) return MB_ENTITY_NOT_FOUND;
3407 : :
3408 : 769 : parent_ptr->add_child( child );
3409 : 769 : child_ptr->add_parent( parent );
3410 : 769 : return MB_SUCCESS;
3411 : : }
3412 : :
3413 : 153 : ErrorCode Core::remove_parent_child( EntityHandle parent, EntityHandle child )
3414 : : {
3415 : 153 : MeshSet* parent_ptr = get_mesh_set( sequence_manager(), parent );
3416 : 153 : MeshSet* child_ptr = get_mesh_set( sequence_manager(), child );
3417 [ + + ][ - + ]: 153 : if( !parent_ptr || !child_ptr ) return MB_ENTITY_NOT_FOUND;
3418 : :
3419 : 152 : parent_ptr->remove_child( child );
3420 : 152 : child_ptr->remove_parent( parent );
3421 : 152 : return MB_SUCCESS;
3422 : : }
3423 : :
3424 : 29216 : ErrorCode Core::remove_parent_meshset( EntityHandle meshset, const EntityHandle parent_meshset )
3425 : : {
3426 : 29216 : MeshSet* set_ptr = get_mesh_set( sequence_manager(), meshset );
3427 [ + + ]: 29216 : if( !set_ptr ) return MB_ENTITY_NOT_FOUND;
3428 : 29215 : set_ptr->remove_parent( parent_meshset );
3429 : 29215 : return MB_SUCCESS;
3430 : : }
3431 : :
3432 : 92 : ErrorCode Core::remove_child_meshset( EntityHandle meshset, const EntityHandle child_meshset )
3433 : : {
3434 : 92 : MeshSet* set_ptr = get_mesh_set( sequence_manager(), meshset );
3435 [ + + ]: 92 : if( !set_ptr ) return MB_ENTITY_NOT_FOUND;
3436 : 91 : set_ptr->remove_child( child_meshset );
3437 : 91 : return MB_SUCCESS;
3438 : : }
3439 : :
3440 : 0 : ErrorCode Core::get_last_error( std::string& info ) const
3441 : : {
3442 : 0 : MBErrorHandler_GetLastError( info );
3443 : 0 : return MB_SUCCESS;
3444 : : }
3445 : :
3446 : 35 : std::string Core::get_error_string( const ErrorCode code ) const
3447 : : {
3448 [ + - ][ + - ]: 35 : return (unsigned)code <= (unsigned)MB_FAILURE ? ErrorCodeStr[code] : "INVALID ERROR CODE";
3449 : : }
3450 : :
3451 : 0 : void Core::print( const EntityHandle ms_handle, const char* prefix, bool first_call ) const
3452 : : {
3453 : : // get the entities
3454 [ # # ]: 0 : Range entities;
3455 : :
3456 [ # # ]: 0 : if( 0 != ms_handle )
3457 : : {
3458 [ # # ]: 0 : get_entities_by_handle( ms_handle, entities );
3459 [ # # ][ # # ]: 0 : std::cout << prefix << "MBENTITYSET " << ID_FROM_HANDLE( ms_handle ) << std::endl;
[ # # ][ # # ]
[ # # ]
3460 : : }
3461 : : else
3462 : : {
3463 [ # # ]: 0 : get_entities_by_dimension( 0, 3, entities );
3464 [ # # ][ # # ]: 0 : if( entities.empty() ) get_entities_by_dimension( 0, 2, entities );
[ # # ]
3465 [ # # ][ # # ]: 0 : if( entities.empty() ) get_entities_by_dimension( 0, 1, entities );
[ # # ]
3466 [ # # ]: 0 : get_entities_by_dimension( 0, 0, entities );
3467 [ # # ]: 0 : get_entities_by_type( 0, MBENTITYSET, entities );
3468 [ # # ][ # # ]: 0 : std::cout << prefix << "--: " << std::endl;
[ # # ]
3469 : : }
3470 : :
3471 [ # # ][ # # ]: 0 : std::string indent_prefix = prefix;
3472 [ # # ]: 0 : indent_prefix += " ";
3473 [ # # ]: 0 : entities.print( indent_prefix.c_str() );
3474 : :
3475 [ # # ][ # # ]: 0 : if( !first_call || !ms_handle ) return;
3476 : :
3477 : : // print parent/children
3478 [ # # ][ # # ]: 0 : Range temp;
3479 [ # # ]: 0 : this->get_parent_meshsets( ms_handle, temp );
3480 [ # # ]: 0 : std::cout << " Parent sets: ";
3481 [ # # ][ # # ]: 0 : if( temp.empty() )
3482 [ # # ][ # # ]: 0 : std::cout << "(none)" << std::endl;
3483 : : else
3484 : : {
3485 [ # # ][ # # ]: 0 : for( Range::iterator rit = temp.begin(); rit != temp.end(); ++rit )
[ # # ][ # # ]
[ # # ]
3486 : : {
3487 [ # # ][ # # ]: 0 : if( rit != temp.begin() ) std::cout << ", ";
[ # # ][ # # ]
3488 [ # # ][ # # ]: 0 : std::cout << ID_FROM_HANDLE( *rit );
[ # # ]
3489 : : }
3490 [ # # ]: 0 : std::cout << std::endl;
3491 : : }
3492 : :
3493 [ # # ]: 0 : temp.clear();
3494 [ # # ]: 0 : this->get_child_meshsets( ms_handle, temp );
3495 [ # # ]: 0 : std::cout << " Child sets: ";
3496 [ # # ][ # # ]: 0 : if( temp.empty() )
3497 [ # # ][ # # ]: 0 : std::cout << "(none)" << std::endl;
3498 : : else
3499 : : {
3500 [ # # ][ # # ]: 0 : for( Range::iterator rit = temp.begin(); rit != temp.end(); ++rit )
[ # # ][ # # ]
[ # # ]
3501 : : {
3502 [ # # ][ # # ]: 0 : if( rit != temp.begin() ) std::cout << ", ";
[ # # ][ # # ]
3503 [ # # ][ # # ]: 0 : std::cout << ID_FROM_HANDLE( *rit );
[ # # ]
3504 : : }
3505 [ # # ]: 0 : std::cout << std::endl;
3506 : : }
3507 : :
3508 : : // print all sparse tags
3509 [ # # ][ # # ]: 0 : print_entity_tags( indent_prefix, ms_handle, MB_TAG_SPARSE );
3510 : : }
3511 : :
3512 : 68 : ErrorCode Core::print_entity_tags( std::string indent_prefix, const EntityHandle handle, TagType tp ) const
3513 : : {
3514 [ + - ]: 68 : std::vector< Tag > set_tags;
3515 [ + - ]: 68 : ErrorCode result = this->tag_get_tags_on_entity( handle, set_tags );
3516 [ - + ][ + - ]: 68 : std::cout << indent_prefix << ( tp == MB_TAG_SPARSE ? "Sparse tags:" : "Dense tags:" ) << std::endl;
[ + - ][ + - ]
3517 [ + - ]: 68 : indent_prefix += " ";
3518 : :
3519 [ + - ][ + - ]: 136 : for( std::vector< Tag >::iterator vit = set_tags.begin(); vit != set_tags.end(); ++vit )
[ + + ]
3520 : : {
3521 : : TagType this_type;
3522 [ + - ][ + - ]: 68 : result = this->tag_get_type( *vit, this_type );
3523 [ + - ][ - + ]: 68 : if( MB_SUCCESS != result || tp != this_type ) continue;
3524 : : DataType this_data_type;
3525 [ + - ][ + - ]: 68 : result = this->tag_get_data_type( *vit, this_data_type );
3526 [ - + ]: 68 : if( MB_SUCCESS != result ) continue;
3527 : : int this_size;
3528 [ + - ][ + - ]: 68 : result = this->tag_get_length( *vit, this_size );
3529 [ - + ]: 68 : if( MB_SUCCESS != result ) continue;
3530 : : // use double since this is largest single-valued tag
3531 [ + - ]: 68 : std::vector< double > dbl_vals( this_size );
3532 [ + - ][ + - ]: 136 : std::vector< int > int_vals( this_size );
3533 [ + - ][ + - ]: 136 : std::vector< EntityHandle > hdl_vals( this_size );
3534 [ + - ][ + - ]: 136 : std::string tag_name;
3535 [ + - ][ + - ]: 68 : result = this->tag_get_name( *vit, tag_name );
3536 [ - + ]: 68 : if( MB_SUCCESS != result ) continue;
3537 [ + - - - : 68 : switch( this_data_type )
- - ]
3538 : : {
3539 : : case MB_TYPE_INTEGER:
3540 [ + - ][ + - ]: 68 : result = this->tag_get_data( *vit, &handle, 1, &int_vals[0] );
[ + - ]
3541 [ - + ]: 68 : if( MB_SUCCESS != result ) continue;
3542 [ + - ][ + - ]: 68 : std::cout << indent_prefix << tag_name << " = ";
[ + - ]
3543 [ + - ]: 68 : if( this_size < 10 )
3544 [ + + ]: 136 : for( int i = 0; i < this_size; i++ )
3545 [ + - ][ + - ]: 68 : std::cout << int_vals[i] << " ";
[ + - ]
3546 : : else
3547 [ # # ][ # # ]: 0 : std::cout << int_vals[0] << "... (mult values)";
[ # # ]
3548 [ + - ]: 68 : std::cout << std::endl;
3549 : 68 : break;
3550 : : case MB_TYPE_DOUBLE:
3551 [ # # ][ # # ]: 0 : result = this->tag_get_data( *vit, &handle, 1, &dbl_vals[0] );
[ # # ]
3552 [ # # ]: 0 : if( MB_SUCCESS != result ) continue;
3553 [ # # ][ # # ]: 0 : std::cout << indent_prefix << tag_name << " = ";
[ # # ]
3554 [ # # ]: 0 : if( this_size < 10 )
3555 [ # # ]: 0 : for( int i = 0; i < this_size; i++ )
3556 [ # # ][ # # ]: 0 : std::cout << dbl_vals[i] << " ";
[ # # ]
3557 : : else
3558 [ # # ][ # # ]: 0 : std::cout << dbl_vals[0] << "... (mult values)";
[ # # ]
3559 [ # # ]: 0 : std::cout << std::endl;
3560 : 0 : break;
3561 : : case MB_TYPE_HANDLE:
3562 [ # # ][ # # ]: 0 : result = this->tag_get_data( *vit, &handle, 1, &hdl_vals[0] );
[ # # ]
3563 [ # # ]: 0 : if( MB_SUCCESS != result ) continue;
3564 [ # # ][ # # ]: 0 : std::cout << indent_prefix << tag_name << " = ";
[ # # ]
3565 [ # # ]: 0 : if( this_size < 10 )
3566 [ # # ]: 0 : for( int i = 0; i < this_size; i++ )
3567 [ # # ][ # # ]: 0 : std::cout << hdl_vals[i] << " ";
[ # # ]
3568 : : else
3569 [ # # ][ # # ]: 0 : std::cout << hdl_vals[0] << "... (mult values)";
[ # # ]
3570 [ # # ]: 0 : std::cout << std::endl;
3571 : 0 : break;
3572 : : case MB_TYPE_OPAQUE:
3573 [ # # ]: 0 : if( NAME_TAG_SIZE == this_size )
3574 : : {
3575 : : char dum_tag[NAME_TAG_SIZE];
3576 [ # # ][ # # ]: 0 : result = this->tag_get_data( *vit, &handle, 1, &dum_tag );
3577 [ # # ]: 0 : if( MB_SUCCESS != result ) continue;
3578 : : // insert NULL just in case there isn't one
3579 : 0 : dum_tag[NAME_TAG_SIZE - 1] = '\0';
3580 [ # # ][ # # ]: 0 : std::cout << indent_prefix << tag_name << " = " << dum_tag << std::endl;
[ # # ][ # # ]
[ # # ]
3581 : : }
3582 : 0 : break;
3583 : : case MB_TYPE_BIT:
3584 [ + - ]: 68 : break;
3585 : : }
3586 : 68 : }
3587 : :
3588 : 68 : return MB_SUCCESS;
3589 : : }
3590 : :
3591 : 2 : ErrorCode Core::check_adjacencies()
3592 : : {
3593 : : // run through all entities, checking adjacencies and reverse-evaluating them
3594 [ + - ]: 2 : Range all_ents;
3595 [ + - ][ - + ]: 2 : ErrorCode result = get_entities_by_handle( 0, all_ents );MB_CHK_ERR( result );
[ # # ][ # # ]
3596 : :
3597 [ + - ][ + - ]: 51 : for( Range::iterator rit = all_ents.begin(); rit != all_ents.end(); ++rit )
[ + - ][ + - ]
[ + + ]
3598 : : {
3599 [ + - ][ + - ]: 49 : result = check_adjacencies( &( *rit ), 1 );MB_CHK_ERR( result );
[ - + ][ # # ]
[ # # ]
3600 : : }
3601 : :
3602 : 2 : return MB_SUCCESS;
3603 : : }
3604 : :
3605 : 49 : ErrorCode Core::check_adjacencies( const EntityHandle* ents, int num_ents )
3606 : : {
3607 : :
3608 : 49 : ErrorCode result = MB_SUCCESS, tmp_result;
3609 [ + - ]: 49 : std::ostringstream oss;
3610 : :
3611 [ + + ]: 98 : for( int i = 0; i < num_ents; i++ )
3612 : : {
3613 : 49 : EntityHandle this_ent = ents[i];
3614 [ + - ]: 49 : std::ostringstream ent_str;
3615 [ + - ][ + - ]: 49 : ent_str << CN::EntityTypeName( TYPE_FROM_HANDLE( this_ent ) ) << " " << ID_FROM_HANDLE( this_ent ) << ": ";
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
3616 [ + - ]: 49 : int this_dim = dimension_from_handle( this_ent );
3617 : :
3618 [ + - ][ - + ]: 49 : if( !is_valid( this_ent ) )
3619 : : {
3620 [ # # ][ # # ]: 0 : std::cerr << ent_str.str() << "Not a valid entity." << std::endl;
[ # # ][ # # ]
3621 : 0 : result = MB_FAILURE;
3622 : : }
3623 : :
3624 : : else
3625 : : {
3626 [ + - ][ - + ]: 49 : if( TYPE_FROM_HANDLE( this_ent ) == MBENTITYSET ) continue;
3627 : :
3628 : : // get adjacencies for this entity
3629 [ + - ]: 49 : Range adjs;
3630 [ + + ]: 245 : for( int dim = 0; dim <= 3; dim++ )
3631 : : {
3632 [ + + ]: 196 : if( dim == this_dim ) continue;
3633 [ + - ]: 147 : tmp_result = get_adjacencies( &this_ent, 1, dim, false, adjs, Interface::UNION );
3634 [ - + ]: 147 : if( MB_SUCCESS != tmp_result )
3635 : : {
3636 [ # # ][ # # ]: 0 : oss << ent_str.str() << "Failed to get adjacencies for dimension " << dim << "." << std::endl;
[ # # ][ # # ]
[ # # ][ # # ]
3637 : 0 : result = tmp_result;
3638 : : }
3639 : : }
3640 [ + - ][ - + ]: 49 : if( !oss.str().empty() )
3641 : : {
3642 [ # # ][ # # ]: 0 : std::cerr << oss.str();
3643 [ # # ][ # # ]: 0 : oss.str( "" );
3644 : : }
3645 : :
3646 : : // now check and reverse-evaluate them
3647 [ + - ][ + - ]: 289 : for( Range::iterator rit = adjs.begin(); rit != adjs.end(); ++rit )
[ + - ][ + - ]
[ + + ]
3648 : : {
3649 : 240 : EntitySequence* seq = 0;
3650 [ + - ][ + - ]: 240 : tmp_result = sequence_manager()->find( *rit, seq );
[ + - ]
3651 [ + - ][ - + ]: 240 : if( seq == 0 || tmp_result != MB_SUCCESS )
3652 : : {
3653 [ # # ][ # # ]: 0 : oss << ent_str.str() << "Adjacent entity " << CN::EntityTypeName( TYPE_FROM_HANDLE( *rit ) ) << " "
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
3654 [ # # ][ # # ]: 0 : << ID_FROM_HANDLE( *rit ) << " is invalid." << std::endl;
[ # # ][ # # ]
[ # # ]
3655 : 0 : result = tmp_result;
3656 : : }
3657 : : else
3658 : : {
3659 [ + - ]: 240 : Range rev_adjs;
3660 [ + - ][ + - ]: 240 : tmp_result = get_adjacencies( &( *rit ), 1, this_dim, false, rev_adjs );
3661 [ - + ]: 240 : if( MB_SUCCESS != tmp_result )
3662 : : {
3663 [ # # ][ # # ]: 0 : oss << ent_str.str() << "Failed to get reverse adjacency from "
[ # # ]
3664 [ # # ][ # # ]: 0 : << CN::EntityTypeName( TYPE_FROM_HANDLE( *rit ) ) << " " << ID_FROM_HANDLE( *rit );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
3665 [ # # ]: 0 : if( MB_MULTIPLE_ENTITIES_FOUND == tmp_result )
3666 [ # # ][ # # ]: 0 : oss << " (MULTIPLE)" << std::endl;
3667 : : else
3668 [ # # ][ # # ]: 0 : oss << " (" << tmp_result << ")" << std::endl;
[ # # ][ # # ]
3669 : 0 : result = tmp_result;
3670 : : }
3671 [ + - ][ + - ]: 240 : else if( rev_adjs.find( this_ent ) == rev_adjs.end() )
[ + - ][ - + ]
3672 : : {
3673 [ # # ][ # # ]: 0 : oss << ent_str.str() << "Failed to find adjacency to this entity from "
[ # # ]
3674 [ # # ][ # # ]: 0 : << CN::EntityTypeName( TYPE_FROM_HANDLE( *rit ) ) << " " << ID_FROM_HANDLE( *rit ) << "."
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
3675 [ # # ]: 0 : << std::endl;
3676 : 0 : result = tmp_result;
3677 : 240 : }
3678 : : }
3679 [ + - ][ - + ]: 240 : if( !oss.str().empty() )
3680 : : {
3681 [ # # ][ # # ]: 0 : std::cerr << oss.str();
3682 [ # # ][ # # ]: 0 : oss.str( "" );
3683 : : }
3684 [ + - ]: 49 : }
3685 : : }
3686 : 49 : }
3687 : :
3688 : 49 : return result;
3689 : : }
3690 : :
3691 : 82809 : bool Core::is_valid( const EntityHandle this_ent ) const
3692 : : {
3693 : 82809 : const EntitySequence* seq = 0;
3694 [ + - ][ + - ]: 82809 : ErrorCode result = sequence_manager()->find( this_ent, seq );
3695 [ + - ][ + - ]: 82809 : return seq != 0 && result == MB_SUCCESS;
3696 : : }
3697 : :
3698 : 48 : ErrorCode Core::create_set_iterator( EntityHandle meshset, EntityType ent_type, int ent_dim, int chunk_size,
3699 : : bool check_valid, SetIterator*& set_iter )
3700 : : {
3701 : : // check the type of set
3702 : : unsigned int setoptions;
3703 : 48 : ErrorCode rval = MB_SUCCESS;
3704 [ + - ]: 48 : if( meshset )
3705 : : {
3706 [ + - ][ - + ]: 48 : rval = get_meshset_options( meshset, setoptions );MB_CHK_ERR( rval );
[ # # ][ # # ]
3707 : : }
3708 : :
3709 [ + - ][ + + ]: 48 : if( !meshset || ( setoptions & MESHSET_SET ) )
3710 [ + - ][ + - ]: 24 : set_iter = new( std::nothrow ) RangeSetIterator( this, meshset, chunk_size, ent_type, ent_dim, check_valid );
3711 : : else
3712 [ + - ][ + - ]: 24 : set_iter = new( std::nothrow ) VectorSetIterator( this, meshset, chunk_size, ent_type, ent_dim, check_valid );
3713 : :
3714 [ + - ]: 48 : setIterators.push_back( set_iter );
3715 : 48 : return MB_SUCCESS;
3716 : : }
3717 : :
3718 : : /** \brief Remove the set iterator from the instance's list
3719 : : * This function is called from the SetIterator destructor, and should not be called directly
3720 : : * from anywhere else.
3721 : : * \param set_iter Set iterator being removed
3722 : : */
3723 : 48 : ErrorCode Core::remove_set_iterator( SetIterator* set_iter )
3724 : : {
3725 [ + - ]: 48 : std::vector< SetIterator* >::iterator vit = std::find( setIterators.begin(), setIterators.end(), set_iter );
3726 [ + - ][ - + ]: 48 : if( vit == setIterators.end() ) { MB_SET_ERR( MB_FAILURE, "Didn't find that iterator" ); }
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
3727 : :
3728 [ + - ]: 48 : setIterators.erase( vit );
3729 : :
3730 : 48 : return MB_SUCCESS;
3731 : : }
3732 : :
3733 : : /** \brief Get all set iterators associated with the set passed in
3734 : : * \param meshset Meshset for which iterators are requested
3735 : : * \param set_iters Set iterators for the set
3736 : : */
3737 : 0 : ErrorCode Core::get_set_iterators( EntityHandle meshset, std::vector< SetIterator* >& set_iters )
3738 : : {
3739 [ # # ][ # # ]: 0 : for( std::vector< SetIterator* >::const_iterator vit = setIterators.begin(); vit != setIterators.end(); ++vit )
[ # # ][ # # ]
3740 [ # # ][ # # ]: 0 : if( ( *vit )->ent_set() == meshset ) set_iters.push_back( *vit );
[ # # ][ # # ]
[ # # ]
3741 : 0 : return MB_SUCCESS;
3742 : : }
3743 : :
3744 : 8 : void Core::estimated_memory_use_internal( const Range* ents, type_memstorage* total_storage,
3745 : : type_memstorage* total_amortized_storage, type_memstorage* entity_storage,
3746 : : type_memstorage* amortized_entity_storage, type_memstorage* adjacency_storage,
3747 : : type_memstorage* amortized_adjacency_storage, const Tag* tag_array,
3748 : : unsigned num_tags, type_memstorage* tag_storage,
3749 : : type_memstorage* amortized_tag_storage )
3750 : : {
3751 : : // Figure out which values we need to calculate
3752 : : type_memstorage i_entity_storage, ia_entity_storage, i_adjacency_storage, ia_adjacency_storage, i_tag_storage,
3753 : : ia_tag_storage;
3754 : 8 : type_memstorage *total_tag_storage = 0, *amortized_total_tag_storage = 0;
3755 [ + - ]: 8 : if( !tag_array )
3756 : : {
3757 : 8 : total_tag_storage = tag_storage;
3758 : 8 : amortized_total_tag_storage = amortized_tag_storage;
3759 : : }
3760 [ + + ][ + - ]: 8 : if( total_storage || total_amortized_storage )
3761 : : {
3762 [ + - ]: 8 : if( !entity_storage ) entity_storage = &i_entity_storage;
3763 [ + - ]: 8 : if( !amortized_entity_storage ) amortized_entity_storage = &ia_entity_storage;
3764 [ + - ]: 8 : if( !adjacency_storage ) adjacency_storage = &i_adjacency_storage;
3765 [ + - ]: 8 : if( !amortized_adjacency_storage ) amortized_adjacency_storage = &ia_adjacency_storage;
3766 : : }
3767 : : else
3768 : : {
3769 [ # # ][ # # ]: 0 : if( entity_storage || amortized_entity_storage )
3770 : : {
3771 [ # # ]: 0 : if( !amortized_entity_storage )
3772 : 0 : amortized_entity_storage = &ia_entity_storage;
3773 [ # # ]: 0 : else if( !entity_storage )
3774 : 0 : entity_storage = &i_entity_storage;
3775 : : }
3776 [ # # ][ # # ]: 0 : if( adjacency_storage || amortized_adjacency_storage )
3777 : : {
3778 [ # # ]: 0 : if( !amortized_adjacency_storage )
3779 : 0 : amortized_adjacency_storage = &ia_adjacency_storage;
3780 [ # # ]: 0 : else if( !adjacency_storage )
3781 : 0 : adjacency_storage = &i_adjacency_storage;
3782 : : }
3783 : : }
3784 [ + - ][ + + ]: 8 : if( !total_tag_storage && total_storage ) total_tag_storage = &i_tag_storage;
3785 [ + - ][ + - ]: 8 : if( !amortized_total_tag_storage && total_amortized_storage ) amortized_total_tag_storage = &ia_tag_storage;
3786 : :
3787 : : // get entity storage
3788 [ + - ]: 8 : if( amortized_entity_storage )
3789 : : {
3790 [ + + ]: 8 : if( ents )
3791 [ + - ]: 4 : sequenceManager->get_memory_use( *ents, *entity_storage, *amortized_entity_storage );
3792 : : else
3793 [ + - ]: 8 : sequenceManager->get_memory_use( *entity_storage, *amortized_entity_storage );
3794 : : }
3795 : :
3796 : : // get adjacency storage
3797 [ + - ]: 8 : if( amortized_adjacency_storage )
3798 : : {
3799 [ + + ]: 8 : if( ents )
3800 [ + - ]: 4 : aEntityFactory->get_memory_use( *ents, *adjacency_storage, *amortized_adjacency_storage );
3801 : : else
3802 : : #ifdef MOAB_HAVE_AHF
3803 : : ahfRep->get_memory_use( *adjacency_storage, *amortized_adjacency_storage );
3804 : : #else
3805 [ + - ]: 8 : aEntityFactory->get_memory_use( *adjacency_storage, *amortized_adjacency_storage );
3806 : : #endif
3807 : : }
3808 : :
3809 : : // get storage for requested list of tags
3810 [ - + ]: 8 : if( tag_array )
3811 : : {
3812 [ # # ]: 0 : for( unsigned i = 0; i < num_tags; ++i )
3813 : : {
3814 [ # # ][ # # ]: 0 : if( !valid_tag_handle( tag_array[i] ) ) continue;
3815 : :
3816 : 0 : unsigned long total = 0, per_ent = 0;
3817 [ # # ]: 0 : tag_array[i]->get_memory_use( sequenceManager, total, per_ent );
3818 : :
3819 [ # # ]: 0 : if( ents )
3820 : : {
3821 : 0 : size_t count = 0, count2 = 0;
3822 [ # # ]: 0 : tag_array[i]->num_tagged_entities( sequenceManager, count, MBMAXTYPE, ents );
3823 [ # # ]: 0 : if( tag_storage ) tag_storage[i] = count * per_ent;
3824 [ # # ]: 0 : if( amortized_tag_storage )
3825 : : {
3826 [ # # ]: 0 : tag_array[i]->num_tagged_entities( sequenceManager, count2 );
3827 [ # # ]: 0 : if( count2 )
3828 : 0 : amortized_tag_storage[i] = static_cast< type_memstorage >( total * count * 1.0 / count2 );
3829 : : }
3830 : : }
3831 : : else
3832 : : {
3833 : 0 : size_t count = 0;
3834 [ # # ]: 0 : if( tag_storage )
3835 : : {
3836 [ # # ]: 0 : tag_array[i]->num_tagged_entities( sequenceManager, count );
3837 : 0 : tag_storage[i] = count * per_ent;
3838 : : }
3839 [ # # ]: 0 : if( amortized_tag_storage ) amortized_tag_storage[i] = total;
3840 : : }
3841 : : }
3842 : : }
3843 : :
3844 : : // get storage for all tags
3845 [ + + ][ + - ]: 8 : if( total_tag_storage || amortized_total_tag_storage )
3846 : : {
3847 [ + - ]: 8 : if( amortized_total_tag_storage ) *amortized_total_tag_storage = 0;
3848 [ + + ]: 8 : if( total_tag_storage ) *total_tag_storage = 0;
3849 : :
3850 [ + - ]: 8 : std::vector< Tag > tags;
3851 [ + - ]: 8 : tag_get_tags( tags );
3852 [ + - ][ + - ]: 52 : for( std::list< TagInfo* >::const_iterator i = tagList.begin(); i != tagList.end(); ++i )
[ + - ][ + - ]
[ + + ]
3853 : : {
3854 : 44 : unsigned long total = 0, per_ent = 0;
3855 [ + - ][ + - ]: 44 : ( *i )->get_memory_use( sequenceManager, total, per_ent );
3856 : :
3857 [ + + ]: 44 : if( ents )
3858 : : {
3859 : 22 : size_t count = 0, count2 = 0;
3860 [ + - ][ + - ]: 22 : ( *i )->num_tagged_entities( sequenceManager, count, MBMAXTYPE, ents );
3861 [ + - ]: 22 : if( total_tag_storage ) *total_tag_storage += count * per_ent;
3862 [ + - ]: 22 : if( amortized_total_tag_storage )
3863 : : {
3864 [ + - ][ + - ]: 22 : ( *i )->num_tagged_entities( sequenceManager, count2 );
3865 [ + + ]: 22 : if( count2 )
3866 : 22 : *amortized_total_tag_storage += static_cast< type_memstorage >( total * count * 1.0 / count2 );
3867 : : }
3868 : : }
3869 : : else
3870 : : {
3871 : 22 : size_t count = 0;
3872 [ - + ]: 22 : if( total_tag_storage )
3873 : : {
3874 [ # # ][ # # ]: 0 : ( *i )->num_tagged_entities( sequenceManager, count );
3875 : 0 : *total_tag_storage += count * per_ent;
3876 : : }
3877 [ + - ]: 22 : if( amortized_total_tag_storage ) *amortized_total_tag_storage += total;
3878 : : }
3879 : 8 : }
3880 : : }
3881 : :
3882 : : // calculate totals
3883 [ + + ]: 8 : if( total_storage ) *total_storage = *entity_storage + *adjacency_storage + *total_tag_storage;
3884 : :
3885 [ + - ]: 8 : if( total_amortized_storage )
3886 : : *total_amortized_storage =
3887 : 8 : *amortized_entity_storage + *amortized_adjacency_storage + *amortized_total_tag_storage;
3888 : 8 : }
3889 : :
3890 : 4 : void Core::estimated_memory_use( const EntityHandle* ent_array, unsigned long num_ents, type_memstorage* total_storage,
3891 : : type_memstorage* total_amortized_storage, type_memstorage* entity_storage,
3892 : : type_memstorage* amortized_entity_storage, type_memstorage* adjacency_storage,
3893 : : type_memstorage* amortized_adjacency_storage, const Tag* tag_array, unsigned num_tags,
3894 : : type_memstorage* tag_storage, type_memstorage* amortized_tag_storage )
3895 : : {
3896 [ + - ]: 4 : Range range;
3897 : :
3898 : : // If non-empty entity list, call range version of function
3899 [ - + ]: 4 : if( ent_array )
3900 : : {
3901 [ # # ]: 0 : if( num_ents > 20 )
3902 : : {
3903 [ # # ]: 0 : std::vector< EntityHandle > list( num_ents );
3904 [ # # ]: 0 : std::copy( ent_array, ent_array + num_ents, list.begin() );
3905 [ # # ]: 0 : std::sort( list.begin(), list.end() );
3906 [ # # ]: 0 : Range::iterator j = range.begin();
3907 [ # # ][ # # ]: 0 : for( std::vector< EntityHandle >::reverse_iterator i = list.rbegin(); i != list.rend(); ++i )
[ # # ]
3908 [ # # ][ # # ]: 0 : j = range.insert( j, *i, *i );
[ # # ]
3909 : : }
3910 : : else
3911 : : {
3912 [ # # ][ # # ]: 0 : std::copy( ent_array, ent_array + num_ents, range_inserter( range ) );
3913 : : }
3914 : : }
3915 : :
3916 : : estimated_memory_use_internal( ent_array ? &range : 0, total_storage, total_amortized_storage, entity_storage,
3917 : : amortized_entity_storage, adjacency_storage, amortized_adjacency_storage, tag_array,
3918 [ - + ][ + - ]: 4 : num_tags, tag_storage, amortized_tag_storage );
3919 : 4 : }
3920 : :
3921 : 4 : void Core::estimated_memory_use( const Range& ents, type_memstorage* total_storage,
3922 : : type_memstorage* total_amortized_storage, type_memstorage* entity_storage,
3923 : : type_memstorage* amortized_entity_storage, type_memstorage* adjacency_storage,
3924 : : type_memstorage* amortized_adjacency_storage, const Tag* tag_array, unsigned num_tags,
3925 : : type_memstorage* tag_storage, type_memstorage* amortized_tag_storage )
3926 : : {
3927 : : estimated_memory_use_internal( &ents, total_storage, total_amortized_storage, entity_storage,
3928 : : amortized_entity_storage, adjacency_storage, amortized_adjacency_storage, tag_array,
3929 : 4 : num_tags, tag_storage, amortized_tag_storage );
3930 : 4 : }
3931 : :
3932 : 0 : void Core::print_database() const
3933 : : {
3934 : : ErrorCode rval;
3935 [ # # ]: 0 : TypeSequenceManager::const_iterator i;
3936 [ # # ][ # # ]: 0 : const TypeSequenceManager& verts = sequence_manager()->entity_map( MBVERTEX );
3937 [ # # ][ # # ]: 0 : if( !verts.empty() )
3938 : : printf( " Vertex ID X Y Z Adjacencies \n"
3939 [ # # ]: 0 : " ---------- -------- -------- -------- -----------...\n" );
3940 : : const EntityHandle* adj;
3941 : : int nadj;
3942 [ # # ][ # # ]: 0 : for( i = verts.begin(); i != verts.end(); ++i )
[ # # ][ # # ]
[ # # ]
3943 : : {
3944 [ # # ]: 0 : const VertexSequence* seq = static_cast< const VertexSequence* >( *i );
3945 [ # # ][ # # ]: 0 : printf( "(Sequence [%d,%d] in SequenceData [%d,%d])\n", (int)ID_FROM_HANDLE( seq->start_handle() ),
3946 [ # # ][ # # ]: 0 : (int)ID_FROM_HANDLE( seq->end_handle() ), (int)ID_FROM_HANDLE( seq->data()->start_handle() ),
[ # # ][ # # ]
[ # # ]
3947 [ # # ][ # # ]: 0 : (int)ID_FROM_HANDLE( seq->data()->end_handle() ) );
[ # # ][ # # ]
3948 : :
3949 : : double c[3];
3950 [ # # ][ # # ]: 0 : for( EntityHandle h = seq->start_handle(); h <= seq->end_handle(); ++h )
[ # # ]
3951 : : {
3952 [ # # ]: 0 : rval = seq->get_coordinates( h, c );
3953 [ # # ]: 0 : if( MB_SUCCESS == rval )
3954 [ # # ][ # # ]: 0 : printf( " %10d %8g %8g %8g", (int)ID_FROM_HANDLE( h ), c[0], c[1], c[2] );
3955 : : else
3956 [ # # ][ # # ]: 0 : printf( " %10d < ERROR %4d >", (int)ID_FROM_HANDLE( h ), (int)rval );
3957 : :
3958 [ # # ][ # # ]: 0 : rval = a_entity_factory()->get_adjacencies( h, adj, nadj );
3959 [ # # ]: 0 : if( MB_SUCCESS != rval )
3960 : : {
3961 [ # # ]: 0 : printf( " <ERROR %d>\n", (int)rval );
3962 : 0 : continue;
3963 : : }
3964 : 0 : EntityType pt = MBMAXTYPE;
3965 [ # # ]: 0 : for( int j = 0; j < nadj; ++j )
3966 : : {
3967 [ # # ][ # # ]: 0 : if( TYPE_FROM_HANDLE( adj[j] ) != pt )
3968 : : {
3969 [ # # ]: 0 : pt = TYPE_FROM_HANDLE( adj[j] );
3970 [ # # ][ # # ]: 0 : printf( " %s", pt >= MBMAXTYPE ? "INVALID TYPE" : CN::EntityTypeName( pt ) );
[ # # ]
3971 : : }
3972 [ # # ][ # # ]: 0 : printf( " %d", (int)ID_FROM_HANDLE( adj[j] ) );
3973 : : }
3974 [ # # ]: 0 : printf( "\n" );
3975 : : }
3976 : : }
3977 : :
3978 [ # # ][ # # ]: 0 : for( EntityType t = MBEDGE; t < MBENTITYSET; ++t )
3979 : : {
3980 [ # # ][ # # ]: 0 : const TypeSequenceManager& elems = sequence_manager()->entity_map( t );
3981 [ # # ][ # # ]: 0 : if( elems.empty() ) continue;
3982 : :
3983 : 0 : int clen = 0;
3984 [ # # ][ # # ]: 0 : for( i = elems.begin(); i != elems.end(); ++i )
[ # # ][ # # ]
[ # # ]
3985 : : {
3986 [ # # ][ # # ]: 0 : int n = static_cast< const ElementSequence* >( *i )->nodes_per_element();
3987 [ # # ]: 0 : if( n > clen ) clen = n;
3988 : : }
3989 : :
3990 : 0 : clen *= 5;
3991 [ # # ]: 0 : if( clen < (int)strlen( "Connectivity" ) ) clen = strlen( "Connectivity" );
3992 [ # # ]: 0 : std::vector< char > dashes( clen, '-' );
3993 [ # # ]: 0 : dashes.push_back( '\0' );
3994 [ # # ][ # # ]: 0 : printf( " %7s ID %-*s Adjacencies\n", CN::EntityTypeName( t ), clen, "Connectivity" );
3995 [ # # ][ # # ]: 0 : printf( " ---------- %s -----------...\n", &dashes[0] );
3996 : :
3997 [ # # ]: 0 : std::vector< EntityHandle > storage;
3998 : : const EntityHandle* conn;
3999 : : int nconn;
4000 [ # # ][ # # ]: 0 : for( i = elems.begin(); i != elems.end(); ++i )
[ # # ][ # # ]
[ # # ]
4001 : : {
4002 [ # # ]: 0 : const ElementSequence* seq = static_cast< const ElementSequence* >( *i );
4003 [ # # ][ # # ]: 0 : printf( "(Sequence [%d,%d] in SequenceData [%d,%d])\n", (int)ID_FROM_HANDLE( seq->start_handle() ),
4004 [ # # ][ # # ]: 0 : (int)ID_FROM_HANDLE( seq->end_handle() ), (int)ID_FROM_HANDLE( seq->data()->start_handle() ),
[ # # ][ # # ]
[ # # ]
4005 [ # # ][ # # ]: 0 : (int)ID_FROM_HANDLE( seq->data()->end_handle() ) );
[ # # ][ # # ]
4006 : :
4007 [ # # ][ # # ]: 0 : for( EntityHandle h = seq->start_handle(); h <= seq->end_handle(); ++h )
[ # # ]
4008 : : {
4009 [ # # ][ # # ]: 0 : printf( " %10d", (int)ID_FROM_HANDLE( h ) );
4010 [ # # ]: 0 : rval = get_connectivity( h, conn, nconn, false, &storage );
4011 [ # # ]: 0 : if( MB_SUCCESS != rval )
4012 [ # # ]: 0 : printf( " <ERROR %2d>%*s", (int)rval, clen - 10, "" );
4013 : : else
4014 : : {
4015 [ # # ]: 0 : for( int j = 0; j < nconn; ++j )
4016 [ # # ][ # # ]: 0 : printf( " %4d", (int)ID_FROM_HANDLE( conn[j] ) );
4017 [ # # ]: 0 : printf( "%*s", clen - 5 * nconn, "" );
4018 : : }
4019 : :
4020 [ # # ][ # # ]: 0 : rval = a_entity_factory()->get_adjacencies( h, adj, nadj );
4021 [ # # ]: 0 : if( MB_SUCCESS != rval )
4022 : : {
4023 [ # # ]: 0 : printf( " <ERROR %d>\n", (int)rval );
4024 : 0 : continue;
4025 : : }
4026 : 0 : EntityType pt = MBMAXTYPE;
4027 [ # # ]: 0 : for( int j = 0; j < nadj; ++j )
4028 : : {
4029 [ # # ][ # # ]: 0 : if( TYPE_FROM_HANDLE( adj[j] ) != pt )
4030 : : {
4031 [ # # ]: 0 : pt = TYPE_FROM_HANDLE( adj[j] );
4032 [ # # ][ # # ]: 0 : printf( " %s", pt >= MBMAXTYPE ? "INVALID TYPE" : CN::EntityTypeName( pt ) );
[ # # ]
4033 : : }
4034 [ # # ][ # # ]: 0 : printf( " %d", (int)ID_FROM_HANDLE( adj[j] ) );
4035 : : }
4036 [ # # ]: 0 : printf( "\n" );
4037 : : }
4038 : : }
4039 : 0 : }
4040 : 0 : }
4041 : :
4042 : 0 : ErrorCode Core::create_scd_sequence( const HomCoord& coord_min, const HomCoord& coord_max, EntityType entity_type,
4043 : : EntityID start_id_hint, EntityHandle& first_handle_out,
4044 : : EntitySequence*& sequence_out )
4045 : : {
4046 : : // NR: Previously, the structured element sequences were created via direct call to
4047 : : // the sequence manager instead of using the same from the ScdInterface which
4048 : : // creates the associated scd bounding box after element sequence creation.
4049 : :
4050 [ # # ][ # # ]: 0 : if( !scdInterface ) scdInterface = new ScdInterface( this );
[ # # ]
4051 : 0 : ScdBox* newBox = NULL;
4052 : : ErrorCode rval = scdInterface->create_scd_sequence( coord_min, coord_max, entity_type,
4053 [ # # ][ # # ]: 0 : /*starting_id*/ (int)start_id_hint, newBox );MB_CHK_ERR( rval );
[ # # ][ # # ]
4054 : :
4055 [ # # ]: 0 : if( MBVERTEX == entity_type )
4056 [ # # ]: 0 : first_handle_out = newBox->get_vertex( coord_min );
4057 : : else
4058 [ # # ]: 0 : first_handle_out = newBox->get_element( coord_min );
4059 [ # # ][ # # ]: 0 : return sequence_manager()->find( first_handle_out, sequence_out );
4060 : : }
4061 : :
4062 : 0 : ErrorCode Core::add_vsequence( EntitySequence* vert_seq, EntitySequence* elem_seq, const HomCoord& p1,
4063 : : const HomCoord& q1, const HomCoord& p2, const HomCoord& q2, const HomCoord& p3,
4064 : : const HomCoord& q3, bool bb_input, const HomCoord* bb_min, const HomCoord* bb_max )
4065 : : {
4066 : 0 : return sequence_manager()->add_vsequence( vert_seq, elem_seq, p1, q1, p2, q2, p3, q3, bb_input, bb_min, bb_max );
4067 : : }
4068 : :
4069 [ + - ][ + - ]: 228 : } // namespace moab
|