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