[MOAB-dev] r1731 - MOAB/trunk
kraftche at mcs.anl.gov
kraftche at mcs.anl.gov
Tue Apr 1 10:49:58 CDT 2008
Author: kraftche
Date: 2008-04-01 10:49:58 -0500 (Tue, 01 Apr 2008)
New Revision: 1731
Added:
MOAB/trunk/Test_MBMeshSet.cpp
Modified:
MOAB/trunk/MBInternals.hpp
MOAB/trunk/MBMeshSet.cpp
MOAB/trunk/MBMeshSet.hpp
MOAB/trunk/Makefile.am
MOAB/trunk/MeshSetSequence.hpp
Log:
o Rewrite storage of entity set contents:
- use array-based representation of ranged sets
- embed small contents arrays directly into MBMeshSet struct
- reduces memory for empty sets by 22%
- reduces memory for large kd-tree by 33%
o Add some more unit tests for entity sets
o Change set unite behavior when the destination set is list-based
to a simple append (do not skip duplicates.)
Modified: MOAB/trunk/MBInternals.hpp
===================================================================
--- MOAB/trunk/MBInternals.hpp 2008-03-31 20:29:26 UTC (rev 1730)
+++ MOAB/trunk/MBInternals.hpp 2008-04-01 15:49:58 UTC (rev 1731)
@@ -62,6 +62,12 @@
return (((MBEntityHandle)type) << MB_ID_WIDTH)|id;
}
+inline MBEntityHandle FIRST_HANDLE( unsigned type )
+ { return (((MBEntityHandle)type) << MB_ID_WIDTH)|MB_START_ID; }
+
+inline MBEntityHandle LAST_HANDLE( unsigned type )
+ { return ((MBEntityHandle)(type+1) << MB_ID_WIDTH) - 1; }
+
//! Get the entity id out of the handle.
inline MBEntityID ID_FROM_HANDLE (MBEntityHandle handle)
{
Modified: MOAB/trunk/MBMeshSet.cpp
===================================================================
--- MOAB/trunk/MBMeshSet.cpp 2008-03-31 20:29:26 UTC (rev 1730)
+++ MOAB/trunk/MBMeshSet.cpp 2008-04-01 15:49:58 UTC (rev 1731)
@@ -1,30 +1,3 @@
-/**
- * MOAB, a Mesh-Oriented datABase, is a software component for creating,
- * storing and accessing finite element mesh data.
- *
- * Copyright 2004 Sandia Corporation. Under the terms of Contract
- * DE-AC04-94AL85000 with Sandia Coroporation, the U.S. Government
- * retains certain rights in this software.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- */
-
-//
-//-------------------------------------------------------------------------
-// Filename : MBMeshSet.cpp
-// Creator : Tim Tautges
-//
-// Date : 02/01/02
-//
-// Owner : Tim Tautges
-//
-// Description : MBMeshSet is the MB implementation of MBSet
-//-------------------------------------------------------------------------
-
#ifdef WIN32
#ifdef _DEBUG
// turn off warnings that say they debugging identifier has been truncated
@@ -33,77 +6,104 @@
#endif
#endif
-
-
-#include <algorithm>
-#include <utility>
-#include <set>
-#include "assert.h"
-#include "MBInternals.hpp"
#include "MBMeshSet.hpp"
#include "AEntityFactory.hpp"
-#include "MBCN.hpp"
-using namespace std;
-#ifndef MB_MESH_SET_COMPACT_PARENT_CHILD_LISTS
+/*****************************************************************************************
+ * Helper Function Declarations *
+ *****************************************************************************************/
-MBMeshSet::MBMeshSet( unsigned flags )
- : mFlags(flags)
- {}
+/**\brief Insert into parent/child list */
+static inline
+MBMeshSet::Count insert_in_vector( const MBMeshSet::Count count,
+ MBMeshSet::CompactList& list,
+ const MBEntityHandle h,
+ int &result );
-MBMeshSet::~MBMeshSet()
-{
-}
+/**\brief Remvoe from parent/child list */
+static inline
+MBMeshSet::Count remove_from_vector( const MBMeshSet::Count count,
+ MBMeshSet::CompactList& list,
+ const MBEntityHandle h,
+ int &result );
-static inline int insert_in_vector( MBMeshSet::LinkSet& s, MBEntityHandle h )
-{
- MBMeshSet::LinkSet::iterator i = find( s.begin(), s.end(), h );
- if (i != s.end())
- return 0;
- s.push_back( h );
- return 1;
-}
-int MBMeshSet::add_parent( MBEntityHandle parent )
- { return insert_in_vector( parentMeshSets, parent ); }
-int MBMeshSet::add_child( MBEntityHandle child )
- { return insert_in_vector( childMeshSets, child ); }
-static inline int remove_from_vector( MBMeshSet::LinkSet& s, MBEntityHandle h )
+/**\brief Resize MBMeshSet::CompactList. Returns pointer to storage */
+static MBEntityHandle* resize_compact_list( MBMeshSet::Count& count,
+ MBMeshSet::CompactList& clist,
+ size_t new_list_size );
+/**\brief Methods to insert/remove range-based data from contents list.
+ * Templatized to operate on both MBRange and set-based MBMeshSets.
+ */
+template <typename pair_iter_t> class range_tool
{
- MBMeshSet::LinkSet::iterator i = find( s.begin(), s.end(), h );
- if (i == s.end())
- return 0;
- s.erase( i );
- return 1;
-}
-int MBMeshSet::remove_parent( MBEntityHandle parent )
- { return remove_from_vector( parentMeshSets, parent ); }
-int MBMeshSet::remove_child( MBEntityHandle child )
- { return remove_from_vector( childMeshSets, child ); }
+public:
+ /** Insert range-based data into range-based MBMeshSet */
+ inline static MBErrorCode ranged_insert_entities( MBMeshSet::Count& count,
+ MBMeshSet::CompactList& clist,
+ pair_iter_t begin,
+ pair_iter_t end,
+ MBEntityHandle my_handle,
+ AEntityFactory* adj );
+
+ /** Remove range-based data from range-based MBMeshSet */
+ inline static MBErrorCode ranged_remove_entities( MBMeshSet::Count& count,
+ MBMeshSet::CompactList& clist,
+ pair_iter_t begin,
+ pair_iter_t end,
+ MBEntityHandle my_handle,
+ AEntityFactory* adj );
-unsigned long MBMeshSet::parent_child_memory_use() const
-{
- return (parentMeshSets.capacity() + childMeshSets.capacity())
- * sizeof(MBEntityHandle);
-}
+ /** Insert range-based data into list-based MBMeshSet */
+ inline static MBErrorCode vector_insert_entities( MBMeshSet::Count& count,
+ MBMeshSet::CompactList& clist,
+ pair_iter_t begin,
+ pair_iter_t end,
+ MBEntityHandle my_handle,
+ AEntityFactory* adj );
+};
-#else
+/** Remove MBRange of handles fromr vector-based MBMeshSet */
+static MBErrorCode vector_remove_range( MBMeshSet::Count& count,
+ MBMeshSet::CompactList& clist,
+ const MBRange& range,
+ MBEntityHandle my_handle,
+ AEntityFactory* adj );
-MBMeshSet::MBMeshSet( unsigned flags )
- : mFlags(flags),
- mParentCount(ZERO),
- mChildCount(ZERO)
- {}
+/** Remove range-based MBMeshSet contents from vector-based MBMeshSet */
+static MBErrorCode vector_remove_ranges( MBMeshSet::Count& count,
+ MBMeshSet::CompactList& clist,
+ const MBEntityHandle* pair_list,
+ size_t num_pairs,
+ MBEntityHandle my_handle,
+ AEntityFactory* adj );
-MBMeshSet::~MBMeshSet()
-{
- if (mParentCount > 2)
- free( parentMeshSets.ptr[0] );
- if (mChildCount > 2)
- free( childMeshSets.ptr[0] );
-}
+/** Remove unsorted array of handles from vector-based MBMeshSet */
+static MBErrorCode vector_remove_vector( MBMeshSet::Count& count,
+ MBMeshSet::CompactList& clist,
+ const MBEntityHandle* vect,
+ size_t vect_size,
+ MBEntityHandle my_handle,
+ AEntityFactory* adj );
+/** Insert unsorted array of handles into vector-based MBMeshSet */
+static MBErrorCode vector_insert_vector( MBMeshSet::Count& count,
+ MBMeshSet::CompactList& clist,
+ const MBEntityHandle* vect,
+ size_t vect_size,
+ MBEntityHandle my_handle,
+ AEntityFactory* adj );
+
+/** Convert unsorted array of handles into array of ranged [begin,end] pairs */
+static void convert_to_ranges( const MBEntityHandle* vect_in, size_t vect_in_len,
+ std::vector<MBEntityHandle>& vect_out );
+
+
+/*****************************************************************************************
+ * Parent/Child Operations *
+ *****************************************************************************************/
+
static inline
MBMeshSet::Count insert_in_vector( const MBMeshSet::Count count,
MBMeshSet::CompactList& list,
@@ -141,7 +141,7 @@
return MBMeshSet::MANY;
}
case MBMeshSet::MANY:
- if (find( list.ptr[0], list.ptr[1], h ) != list.ptr[1]) {
+ if (std::find( list.ptr[0], list.ptr[1], h ) != list.ptr[1]) {
result = false;
}
else {
@@ -157,19 +157,6 @@
return MBMeshSet::ZERO;
}
-int MBMeshSet::add_parent( MBEntityHandle parent )
-{
- int result;
- mParentCount = insert_in_vector( (Count)mParentCount, parentMeshSets, parent, result );
- return result;
-}
-int MBMeshSet::add_child( MBEntityHandle child )
-{
- int result;
- mChildCount = insert_in_vector( (Count)mChildCount, childMeshSets, child, result );
- return result;
-}
-
static inline
MBMeshSet::Count remove_from_vector( const MBMeshSet::Count count,
MBMeshSet::CompactList& list,
@@ -237,6 +224,20 @@
return MBMeshSet::ZERO;
}
+
+int MBMeshSet::add_parent( MBEntityHandle parent )
+{
+ int result;
+ mParentCount = insert_in_vector( (Count)mParentCount, parentMeshSets, parent, result );
+ return result;
+}
+int MBMeshSet::add_child( MBEntityHandle child )
+{
+ int result;
+ mChildCount = insert_in_vector( (Count)mChildCount, childMeshSets, child, result );
+ return result;
+}
+
int MBMeshSet::remove_parent( MBEntityHandle parent )
{
int result;
@@ -250,390 +251,902 @@
return result;
}
-unsigned long MBMeshSet::parent_child_memory_use() const
-{
- unsigned long result = 0;
- if (num_children() > 2)
- result += sizeof(MBEntityHandle) * num_children();
- if (num_parents() > 2)
- result += sizeof(MBEntityHandle) * num_parents();
- return result;
-}
-#endif
-
+/*****************************************************************************************
+ * Flag Conversion Operations *
+ *****************************************************************************************/
-MBErrorCode MBMeshSet_MBRange::clear( MBEntityHandle mEntityHandle,
- AEntityFactory* mAdjFact )
+MBErrorCode MBMeshSet::convert( unsigned flags, MBEntityHandle my_handle, AEntityFactory* adj )
{
- if(tracking() && mAdjFact)
- {
- for(MBRange::iterator iter = mRange.begin();
- iter != mRange.end(); ++iter)
- {
- mAdjFact->remove_adjacency(*iter, mEntityHandle);
+ MBErrorCode rval = MB_SUCCESS;
+ if ((mFlags & MESHSET_TRACK_OWNER) && !(flags & MESHSET_TRACK_OWNER))
+ rval = remove_adjacencies( my_handle, adj );
+ else if (!(mFlags & MESHSET_TRACK_OWNER) && (flags & MESHSET_TRACK_OWNER))
+ rval = create_adjacencies( my_handle, adj );
+ if (MB_SUCCESS != rval)
+ return rval;
+
+ if ((mFlags & MESHSET_ORDERED) && !(flags & MESHSET_ORDERED)) {
+ size_t datalen;
+ MBEntityHandle* data = get_contents(datalen);
+ if (datalen) {
+ std::vector<MBEntityHandle> list( datalen );
+ memcpy( &list[0], data, datalen*sizeof(MBEntityHandle) );
+ int num_ents = num_entities();
+ Count count = (Count)mContentCount;
+ data = resize_compact_list( count, contentList, num_ents );
+ mContentCount = count;
+ assert( list.size() % 2 == 0 );
+ std::vector<MBEntityHandle>::iterator i = list.begin();
+ while (i != list.end()) {
+ MBEntityHandle h = *i; ++i;
+ MBEntityHandle e = *i; ++i;
+ for (; h <= e; ++h) {
+ *data = h;
+ ++data;
+ }
+ }
}
}
- mRange.clear();
+ else if (!(mFlags & MESHSET_ORDERED) && (flags & MESHSET_ORDERED)) {
+ size_t datalen;
+ MBEntityHandle* data = get_contents(datalen);
+ if (datalen) {
+ std::vector<MBEntityHandle> ranges;
+ convert_to_ranges( data, datalen, ranges );
+ Count count = (Count)mContentCount;
+ data = resize_compact_list( count, contentList, ranges.size() );
+ mContentCount = count;
+ memcpy( data, &ranges[0], ranges.size()*sizeof(MBEntityHandle) );
+ }
+ }
+
return MB_SUCCESS;
}
-
-bool MBMeshSet_MBRange::replace_entities(MBEntityHandle set_handle,
- MBEntityHandle *entities,
- int num_entities,
- AEntityFactory* mAdjFact)
+MBErrorCode MBMeshSet::create_adjacencies( MBEntityHandle my_handle, AEntityFactory* adj )
{
- bool was_contained = false;
- MBRange::iterator rit;
- for (int i = 0; i < num_entities; i += 2) {
- if ((rit = mRange.find(entities[i])) != mRange.end()) {
- mRange.erase(rit);
- mRange.insert(entities[i+1]);
- was_contained = true;
-
- if (tracking() && mAdjFact)
- mAdjFact->remove_adjacency(entities[i], set_handle),
- mAdjFact->add_adjacency(entities[i+1], set_handle);
+ MBErrorCode rval = MB_SUCCESS;;
+ size_t count;
+ const MBEntityHandle *const ptr = get_contents( count );
+ const MBEntityHandle *const end = ptr + count;
+ if (vector_based()) {
+ for (const MBEntityHandle* i = ptr; i != end; ++i) {
+ rval = adj->add_adjacency( *i, my_handle, false );
+ if (MB_SUCCESS != rval) {
+ for (const MBEntityHandle* j = ptr; j != i; ++j)
+ adj->remove_adjacency( *j, my_handle );
+ return rval;
+ }
}
-
- if (remove_parent(entities[i]))
- add_parent(entities[i+1]), was_contained = true;
-
- if (remove_child(entities[i]))
- add_child(entities[i+1]), was_contained = true;
}
-
- return was_contained;
+ else {
+ assert( 0 == count % 2 );
+ for (const MBEntityHandle* i = ptr; i != end; i += 2) {
+ for (MBEntityHandle h = i[0]; h <= i[1]; ++h) {
+ rval = adj->add_adjacency( h, my_handle, false );
+ if (MB_SUCCESS != rval) {
+ for (MBEntityHandle j = i[0]; j < h; ++j)
+ adj->remove_adjacency( j, my_handle );
+ for (const MBEntityHandle* j = ptr; j != i; j += 2)
+ for (MBEntityHandle k = j[0]; k <= j[1]; ++k)
+ adj->remove_adjacency( k, my_handle );
+ return rval;
+ }
+ }
+ }
+ }
+ return MB_SUCCESS;
}
-
-MBErrorCode MBMeshSet_MBRange::add_entities( const MBEntityHandle *entities,
- const int num_entities,
- MBEntityHandle mEntityHandle,
- AEntityFactory* mAdjFact )
+MBErrorCode MBMeshSet::remove_adjacencies( MBEntityHandle my_handle, AEntityFactory* adj )
{
- int i;
- for(i = 0; i < num_entities; i++)
- mRange.insert(entities[i]);
-
- if(tracking() && mAdjFact)
- {
- for(i = 0; i < num_entities; i++)
- mAdjFact->add_adjacency(entities[i], mEntityHandle);
+ size_t count;
+ const MBEntityHandle *const ptr = get_contents( count );
+ const MBEntityHandle *const end = ptr + count;
+ if (vector_based()) {
+ for (const MBEntityHandle* i = ptr; i != end; ++i)
+ adj->remove_adjacency( *i, my_handle );
}
+ else {
+ assert( 0 == count % 2 );
+ for (const MBEntityHandle* i = ptr; i != end; i += 2)
+ for (MBEntityHandle h = i[0]; h <= i[1]; ++h)
+ adj->remove_adjacency( h, my_handle );
+ }
return MB_SUCCESS;
}
-MBErrorCode MBMeshSet_MBRange::add_entities( const MBRange& entities,
- MBEntityHandle mEntityHandle,
- AEntityFactory* mAdjFact )
+/*****************************************************************************************
+ * Contents Modifiction Methods *
+ *****************************************************************************************/
+
+static MBEntityHandle* resize_compact_list( MBMeshSet::Count& count,
+ MBMeshSet::CompactList& clist,
+ size_t new_list_size )
{
-
- mRange.merge(entities);
-
- if(tracking() && mAdjFact)
- {
- for(MBRange::const_iterator iter = entities.begin();
- iter != entities.end(); ++iter)
- mAdjFact->add_adjacency(*iter, mEntityHandle);
+ if (count <= 2) {
+ if (new_list_size <= 2) {
+ count = (MBMeshSet::Count)new_list_size;
+ return clist.hnd;
+ }
+ else {
+ MBEntityHandle* list = (MBEntityHandle*)malloc( new_list_size*sizeof(MBEntityHandle) );
+ list[0] = clist.hnd[0];
+ list[1] = clist.hnd[1];
+ clist.ptr[0] = list;
+ clist.ptr[1] = list + new_list_size;
+ count = MBMeshSet::MANY;
+ return list;
+ }
}
-
- return MB_SUCCESS;
+ else if (new_list_size > 2) {
+ if (new_list_size > (size_t)(clist.ptr[1] - clist.ptr[0]))
+ clist.ptr[0] = (MBEntityHandle*)realloc( clist.ptr[0], new_list_size*sizeof(MBEntityHandle) );
+ clist.ptr[1] = clist.ptr[0] + new_list_size;
+ count = MBMeshSet::MANY;
+ return clist.ptr[0];
+ }
+ else {
+ MBEntityHandle* list = clist.ptr[0];
+ clist.hnd[0] = list[0];
+ clist.hnd[1] = list[1];
+ free(list);
+ count = (MBMeshSet::Count)new_list_size;
+ return clist.hnd;
+ }
}
-MBErrorCode MBMeshSet_MBRange::remove_entities( const MBRange& entities,
- MBEntityHandle mEntityHandle,
- AEntityFactory* mAdjFact )
+template <typename pair_iter_t> inline MBErrorCode
+range_tool<pair_iter_t>::ranged_insert_entities( MBMeshSet::Count& count,
+ MBMeshSet::CompactList& clist,
+ pair_iter_t begin,
+ pair_iter_t end,
+ MBEntityHandle my_handle,
+ AEntityFactory* adj )
{
- MBRange common_ents = mRange.intersect(entities);
- MBRange tmp_range = mRange.subtract(common_ents);
- mRange.swap(tmp_range);
+ //first pass:
+ // 1) merge existing ranges
+ // 2) count number of new ranges that must be inserted
+ ptrdiff_t insert_count = 0;
+ MBEntityHandle *list;
+ size_t list_size;
+ if (count < MBMeshSet::MANY) {
+ list = clist.hnd;
+ list_size = count;
+ }
+ else {
+ list = clist.ptr[0];
+ list_size = clist.ptr[1] - clist.ptr[0];
+ }
+
+ MBEntityHandle* list_write = list;
+ MBEntityHandle *const list_end = list + list_size, *list_read = list;
+ pair_iter_t i = begin;
- if(tracking() && mAdjFact) {
- for(MBRange::const_iterator iter = common_ents.begin();
- iter != common_ents.end(); iter++) {
- mAdjFact->remove_adjacency(*iter, mEntityHandle);
+ while(i != end) {
+
+ // if there are holes in the current array, shuffle blocks
+ // down until we find the next block to merge with or insert before
+ if (list_read != list_write) {
+ while (list_read != list_end && i->second + 1 < list_read[0]) {
+ list_write[0] = list_read[0];
+ list_write[1] = list_read[1];
+ list_write += 2;
+ list_read += 2;
+ }
}
+ // otherwise do a binary search
+ else {
+ list_write = std::lower_bound( list_write, list_end, i->first - 1 );
+ // if in middle of range block (odd index), back up to start of block
+ list_write -= (list_write - list)%2;
+ list_read = list_write;
+ }
+
+ // handle any straight insertions of range blocks
+ for ( ; i != end && (list_read == list_end || i->second+1 < list_read[0]); ++i) {
+ // If we haven't removed any range pairs, we don't have space to
+ // insert here. Defer the insertion until later.
+ if (list_read == list_write) {
+ ++insert_count;
+ }
+ else {
+ if (adj)
+ for (MBEntityHandle j = i->first; j <= i->second; ++j)
+ adj->add_adjacency( j, my_handle, false );
+
+ list_write[0] = i->first;
+ list_write[1] = i->second;
+ list_write += 2;
+ }
+ }
+ if (i == end)
+ break;
+
+ // check if we need to prepend to the current range block
+ if (i->first >= list_read[0])
+ list_write[0] = list_read[0];
+ else {
+ if (adj)
+ for (MBEntityHandle h = i->first; h < list_read[0]; ++h)
+ adj->add_adjacency( h, my_handle, false );
+ list_write[0] = i->first;
+ }
+ list_write[1] = list_read[1];
+ list_read += 2;
+
+ // discard any input blocks already in the set
+ for (; i != end && i->second <= list_write[1]; ++i);
+ if (i == end) {
+ list_write += 2;
+ break;
+ }
+
+ // merge subsequent blocks in meshset
+ for (;list_read != list_end && list_read[0]+1 <= i->second; list_read += 2) {
+ if (adj)
+ for (MBEntityHandle h = list_write[1]+1; h < list_read[0]; ++h)
+ adj->add_adjacency( h, my_handle, false );
+ list_write[1] = list_read[1];
+ }
+
+ // check if we need to append to current meshset block
+ if (i->second > list_write[1]) {
+ if (adj)
+ for (MBEntityHandle h = list_write[1]+1; h <= i->second; ++h)
+ adj->add_adjacency( h, my_handle, false );
+ list_write[1] = i->second;
+ }
+
+ ++i;
+ list_write += 2;
}
- return MB_SUCCESS;
-}
+ // shuffle down entries to fill holes
+ if (list_read == list_write)
+ list_read = list_write = list_end;
+ else while(list_read < list_end) {
+ list_write[0] = list_read[0];
+ list_write[1] = list_read[1];
+ list_read += 2;
+ list_write += 2;
+ }
-MBErrorCode MBMeshSet_MBRange::remove_entities( const MBEntityHandle *entities,
- const int num_entities,
- MBEntityHandle mEntityHandle,
- AEntityFactory* mAdjFact )
-{
- for(int i = 0; i < num_entities; i++)
- {
- MBRange::iterator found = mRange.find(entities[i]);
- if(found != mRange.end())
- {
- mRange.erase(found);
- if(tracking() && mAdjFact)
- mAdjFact->remove_adjacency(entities[i], mEntityHandle);
+ // adjust allocated array size
+ const size_t occupied_size = list_write - list;
+ const size_t new_list_size = occupied_size + 2*insert_count;
+ list = resize_compact_list( count, clist, new_list_size );
+ // done?
+ if (!insert_count)
+ return MB_SUCCESS;
+
+ // Second pass: insert non-mergable range pairs
+ // All range pairs in the input are either completely disjoint from
+ // the ones in the mesh set and must be inserted or are entirely contained
+ // within range pair in the mesh set.
+ assert( begin != end ); // can't have items to insert if given empty input list
+ pair_iter_t ri = end; --ri;
+ list_write = list + new_list_size - 2;
+ list_read = list + occupied_size - 2;
+ for ( ; list_write >= list; list_write -= 2 ) {
+ if (list_read >= list) {
+ while (ri->first >= list_read[0] && ri->second <= list_read[1]) {
+ assert(ri != begin);
+ --ri;
+ }
+
+ if (list_read[0] > ri->second) {
+ list_write[0] = list_read[0];
+ list_write[1] = list_read[1];
+ list_read -= 2;
+ continue;
+ }
}
+
+ assert( insert_count > 0 );
+ if (adj)
+ for (MBEntityHandle j = ri->first; j <= ri->second; ++j)
+ adj->add_adjacency( j, my_handle, false );
+ list_write[0] = ri->first;
+ list_write[1] = ri->second;
+
+ // don't have reverse iterator, so check before decrement
+ // if insert_count isn't zero, must be more in range
+ if (0 == --insert_count) {
+ assert( list_read == list_write-2 );
+ break;
+ }
+ else {
+ --ri;
+ }
}
+ assert(!insert_count);
return MB_SUCCESS;
-
}
-
-MBErrorCode MBMeshSet_MBRange::subtract( const MBMeshSet *meshset_2,
- MBEntityHandle handle,
- AEntityFactory* adj_fact )
+
+template <typename pair_iter_t> inline MBErrorCode
+range_tool<pair_iter_t>::ranged_remove_entities( MBMeshSet::Count& count,
+ MBMeshSet::CompactList& clist,
+ pair_iter_t begin,
+ pair_iter_t end,
+ MBEntityHandle my_handle,
+ AEntityFactory* adj )
{
- MBRange other_range;
- meshset_2->get_entities(other_range);
+ //first pass:
+ // 1) remove (from) existing ranges
+ // 2) count number of ranges that must be split
+ ptrdiff_t split_count = 0;
+ MBEntityHandle *list;
+ size_t list_size;
+ if (count < MBMeshSet::MANY) {
+ list = clist.hnd;
+ list_size = count;
+ }
+ else {
+ list = clist.ptr[0];
+ list_size = clist.ptr[1] - clist.ptr[0];
+ }
- return remove_entities( other_range, handle, adj_fact );
-}
+ MBEntityHandle* list_write = list;
+ MBEntityHandle *const list_end = list + list_size, *list_read = list;
+ pair_iter_t i = begin;
+
+ while(list_read != list_end && i != end) {
+
+ while (i != end && i->second < list_read[0])
+ ++i;
+ if (i == end)
+ break;
+
+ // if there are holes in the current array, shuffle blocks
+ // down until we find the next block to remove
+ if (list_read != list_write) {
+ while (list_read != list_end && i->second < list_read[0]) {
+ list_write[0] = list_read[0];
+ list_write[1] = list_read[1];
+ list_write += 2;
+ list_read += 2;
+ }
+ }
+ // otherwise do a binary search
+ else {
+ list_write = std::lower_bound( list_write, list_end, i->first );
+ // if in middle of range block (odd index), back up to start of block
+ list_write -= (list_write - list)%2;
+ list_read = list_write;
+ }
+
+ // if everything remaning is past end of set contents...
+ if (list_read == list_end)
+ break;
+
+ // skip any remove pairs that aren't in the list
+ if (i->second < list_read[0]) {
+ ++i;
+ continue;
+ }
+
+ // Begin by assuming that we will keep the entire block
+ list_write[0] = list_read[0];
+ list_write[1] = list_read[1];
+ list_read += 2;
+
+ for (; i != end && i->first <= list_write[1]; ++i) {
+ if (i->first <= list_write[0]) {
+ // remove whole block
+ if (i->second >= list_write[1]) {
+ if (adj)
+ for (MBEntityHandle h = list_write[0]; h <= list_write[1]; ++h)
+ adj->remove_adjacency( h, my_handle );
+ list_write -= 2;
+ break;
+ }
+ // remove from start of block
+ else if (i->second >= list_write[0]) {
+ if (adj)
+ for (MBEntityHandle h = list_write[0]; h <= i->second; ++h)
+ adj->remove_adjacency( h, my_handle );
+ list_write[0] = i->second + 1;
+ }
+ }
+ else if (i->first <= list_write[1]) {
+ // remove from end of block
+ if (i->second >= list_write[1]) {
+ if (adj)
+ for (MBEntityHandle h = i->first; h <= list_write[1]; ++h)
+ adj->remove_adjacency( h, my_handle );
+ list_write[1] = i->first - 1;
+ //list_write += 2;
+ break;
+ }
+ // split block
+ else {
+ if (adj)
+ for (MBEntityHandle h = i->first; h <= i->second; ++h)
+ adj->remove_adjacency( h, my_handle );
-MBErrorCode MBMeshSet_MBRange::intersect( const MBMeshSet *meshset_2,
- MBEntityHandle mEntityHandle,
- AEntityFactory* mAdjFact )
-{
- MBRange other_range;
- meshset_2->get_entities(other_range);
+ if (list_read - list_write <= 2) {
+ ++split_count;
+ continue;
+ }
+ else {
+ list_write[3] = list_write[1];
+ list_write[1] = i->first - 1;
+ list_write[2] = i->second + 1;
+ list_write += 2;
+ }
+ }
+ }
+ }
+ list_write += 2;
+ }
- std::set<MBEntityHandle> tmp;
+ // shuffle down entries to fill holes
+ if (list_read == list_write)
+ list_read = list_write = list_end;
+ else
+ while(list_read < list_end) {
+ list_write[0] = list_read[0];
+ list_write[1] = list_read[1];
+ list_read += 2;
+ list_write += 2;
+ }
- std::set_intersection(mRange.begin(), mRange.end(), other_range.begin(), other_range.end(),
- std::inserter< std::set<MBEntityHandle> >(tmp, tmp.end()));
+ // adjust allocated array size
+ const size_t occupied_size = list_write - list;
+ const size_t new_list_size = occupied_size + 2*split_count;
+ list = resize_compact_list( count, clist, new_list_size );
+ // done?
+ if (!split_count)
+ return MB_SUCCESS;
- mRange.clear();
+ // Second pass: split range pairs
+ // All range pairs in the input are either already removed or
+ // require one of the existing range pairs to be split
+ assert( begin != end ); // can't have ranges to split if given empty input list
+ pair_iter_t ri = end; --ri;
+ list_write = list + new_list_size - 2;
+ list_read = list + occupied_size - 2;
+ for ( ; list_write >= list; list_write -= 2 ) {
+ if (list_read >= list) {
+ while (ri->second > list_read[1]) {
+ assert(ri != begin);
+ --ri;
+ }
+
+ if (list_read[0] > ri->second) {
+ list_write[0] = list_read[0];
+ list_write[1] = list_read[1];
+ list_read -= 2;
+ continue;
+ }
+ }
+
+ assert( split_count > 0 );
+ list_write[0] = ri->second + 1;
+ list_write[1] = list_read[1];
+ list_read[1] = ri->first - 1;
- for(std::set<MBEntityHandle>::reverse_iterator iter = tmp.rbegin();
- iter != tmp.rend(); ++iter)
- {
- mRange.insert(*iter);
+ // don't have reverse iterator, so check before decrement
+ // if insert_count isn't zero, must be more in range
+ if (0 == --split_count) {
+ assert( list_read == list_write-2 );
+ break;
+ }
+ else {
+ --ri;
+ }
}
- //track owner
- if(tracking() && mAdjFact)
- {
- tmp.clear();
- std::set_difference(mRange.begin(), mRange.end(), other_range.begin(), other_range.end(),
- std::inserter< std::set<MBEntityHandle> >(tmp, tmp.end()));
-
- for(std::set<MBEntityHandle>::iterator iter = tmp.begin();
- iter != tmp.end(); ++iter)
- mAdjFact->remove_adjacency(*iter, mEntityHandle);
- }
-
+ assert(!split_count);
return MB_SUCCESS;
}
-MBErrorCode MBMeshSet_MBRange::unite( const MBMeshSet *meshset_2,
- MBEntityHandle handle,
- AEntityFactory* adj_fact )
-{
- MBRange other_range;
- meshset_2->get_entities(other_range);
- return add_entities( other_range, handle, adj_fact );
-}
-unsigned long MBMeshSet_MBRange::get_memory_use() const
+template <typename pair_iter_t> inline MBErrorCode
+range_tool<pair_iter_t>::vector_insert_entities( MBMeshSet::Count& count,
+ MBMeshSet::CompactList& clist,
+ pair_iter_t begin,
+ pair_iter_t end,
+ MBEntityHandle my_handle,
+ AEntityFactory* adj )
{
- return parent_child_memory_use() + mRange.get_memory_use();
-}
+ const size_t init_size = count < MBMeshSet::MANY ? count : clist.ptr[1] - clist.ptr[0];
+ size_t add_size = 0;
+ for (pair_iter_t i = begin; i != end; ++i)
+ add_size += i->second - i->first + 1;
+ MBEntityHandle* list = resize_compact_list( count, clist, init_size + add_size );
+ MBEntityHandle* li = list + init_size;
-
-MBErrorCode MBMeshSet_Vector::clear( MBEntityHandle mEntityHandle,
- AEntityFactory* mAdjFact)
-{
- if(tracking() && mAdjFact)
- {
- for(std::vector<MBEntityHandle>::iterator iter = mVector.begin();
- iter != mVector.end(); ++iter)
- {
- mAdjFact->remove_adjacency(*iter, mEntityHandle);
+ for (pair_iter_t i = begin; i != end; ++i) {
+ for (MBEntityHandle h = i->first; h <= i->second; ++h) {
+ if (adj)
+ adj->add_adjacency( h, my_handle, false );
+ *li = h;
+ ++li;
}
}
- mVector.clear();
- mVector.reserve(0);
+
return MB_SUCCESS;
}
-bool MBMeshSet_Vector::replace_entities(MBEntityHandle set_handle,
- MBEntityHandle *entities,
- int num_entities,
- AEntityFactory* mAdjFact)
+static MBErrorCode vector_remove_range( MBMeshSet::Count& count,
+ MBMeshSet::CompactList& clist,
+ const MBRange& range,
+ MBEntityHandle my_handle,
+ AEntityFactory* adj )
{
- bool was_contained = false;
- std::vector<MBEntityHandle>::iterator vit;
- for (int i = 0; i < num_entities; i += 2) {
- if ((vit = std::find(mVector.begin(), mVector.end(), entities[i]))
- != mVector.end()) {
- *vit = entities[i+1];
- was_contained = true;
+ MBEntityHandle *list;
+ size_t list_size;
+ if (count < MBMeshSet::MANY) {
+ list = clist.hnd;
+ list_size = count;
+ }
+ else {
+ list = clist.ptr[0];
+ list_size = clist.ptr[1] - clist.ptr[0];
+ }
- if(tracking() && mAdjFact)
- mAdjFact->remove_adjacency(entities[i], set_handle),
- mAdjFact->add_adjacency(entities[i+1], set_handle);
+ const MBEntityHandle * const list_end = list + list_size;
+ MBEntityHandle* list_write = list;
+ for (const MBEntityHandle* list_read = list; list_read != list_end; ++list_read) {
+ if (range.find(*list_read) == range.end()) { // keep
+ *list_write = *list_read;
+ ++list_write;
}
-
- if (remove_parent(entities[i]))
- add_parent(entities[i+1]), was_contained = true;
+ else if (adj) {
+ adj->remove_adjacency( *list_read, my_handle );
+ }
+ }
- if (remove_child(entities[i]))
- add_child(entities[i+1]), was_contained = true;
- }
-
- return was_contained;
+ resize_compact_list( count, clist, list_write - list );
+ return MB_SUCCESS;
}
-
-void MBMeshSet_Vector::vector_to_range( std::vector<MBEntityHandle>& vect, MBRange& range )
+static MBErrorCode vector_remove_ranges( MBMeshSet::Count& count,
+ MBMeshSet::CompactList& clist,
+ const MBEntityHandle* pair_list,
+ size_t num_pairs,
+ MBEntityHandle my_handle,
+ AEntityFactory* adj )
{
- std::sort( vect.begin(), vect.end() );
- MBRange::iterator insert_iter = range.begin();
- std::vector<MBEntityHandle>::iterator iter = vect.begin();
- while (iter != vect.end()) {
- MBEntityHandle beg, end;
- beg = end = *iter;
- for (++iter; iter != vect.end() && *iter - end < 2; ++iter)
- end = *iter;
- insert_iter = range.insert( insert_iter, beg, end );
+ MBEntityHandle *list;
+ size_t list_size;
+ if (count < MBMeshSet::MANY) {
+ list = clist.hnd;
+ list_size = count;
}
+ else {
+ list = clist.ptr[0];
+ list_size = clist.ptr[1] - clist.ptr[0];
+ }
+
+ const MBEntityHandle *const list_end = list + list_size,
+ *const input_end = pair_list + 2*num_pairs;
+ MBEntityHandle* list_write = list;
+ for (const MBEntityHandle* list_read = list; list_read != list_end; ++list_read) {
+ const MBEntityHandle* ptr = std::lower_bound( pair_list, input_end, *list_read );
+ if ((ptr != input_end && (*ptr == *list_read || (ptr - pair_list)%2)) && // if in delete list
+ std::find(list_read+1, list_end, *list_read) == list_end) { // and is last occurance in list
+ // only remove adj if no previous occurance
+ if (adj && std::find(list, list_write, *list_read) == list_write)
+ adj->remove_adjacency( *list_read, my_handle );
+ }
+ else {
+ *list_write = *list_read;
+ ++list_write;
+ }
+ }
+
+ resize_compact_list( count, clist, list_write - list );
+ return MB_SUCCESS;
}
-MBErrorCode MBMeshSet_Vector::add_entities( const MBEntityHandle *entities,
- const int num_entities,
- MBEntityHandle mEntityHandle,
- AEntityFactory* mAdjFact )
+static MBErrorCode vector_remove_vector( MBMeshSet::Count& count,
+ MBMeshSet::CompactList& clist,
+ const MBEntityHandle* vect,
+ size_t vect_size,
+ MBEntityHandle my_handle,
+ AEntityFactory* adj )
{
- unsigned int prev_size = mVector.size();
- mVector.resize(prev_size + num_entities);
- std::copy(entities, entities+num_entities, &mVector[prev_size]);
+ MBEntityHandle *list;
+ size_t list_size;
+ if (count < MBMeshSet::MANY) {
+ list = clist.hnd;
+ list_size = count;
+ }
+ else {
+ list = clist.ptr[0];
+ list_size = clist.ptr[1] - clist.ptr[0];
+ }
- if(tracking() && mAdjFact)
- {
- for(int i = 0; i < num_entities; i++)
- mAdjFact->add_adjacency(entities[i], mEntityHandle);
+ const MBEntityHandle *const list_end = list + list_size,
+ *const input_end = vect + vect_size;
+ MBEntityHandle* list_write = list;
+ for (const MBEntityHandle* list_read = list; list_read != list_end; ++list_read) {
+ if (std::find(vect, input_end, *list_read) != input_end && // if in delete list
+ std::find(list_read+1, list_end, *list_read) == list_end) { // and is last occurance in list
+ // only remove adj if no previous occurance?
+ if (adj ) // && std::find(list, list_write, *list_read) == list_write)
+ adj->remove_adjacency( *list_read, my_handle );
+ }
+ else {
+ *list_write = *list_read;
+ ++list_write;
+ }
}
+ resize_compact_list( count, clist, list_write - list );
return MB_SUCCESS;
}
+static MBErrorCode vector_insert_vector( MBMeshSet::Count& count,
+ MBMeshSet::CompactList& clist,
+ const MBEntityHandle* vect,
+ size_t vect_size,
+ MBEntityHandle my_handle,
+ AEntityFactory* adj )
+{
+ const size_t orig_size = count < MBMeshSet::MANY ? count : clist.ptr[1] - clist.ptr[0];
+ MBEntityHandle* list = resize_compact_list( count, clist, orig_size + vect_size );
+ if (adj)
+ for (size_t i = 0; i < vect_size; ++i)
+ adj->add_adjacency( vect[i], my_handle, false );
+ memcpy( list+orig_size, vect, sizeof(MBEntityHandle)*vect_size );
+ return MB_SUCCESS;
+}
-MBErrorCode MBMeshSet_Vector::add_entities( const MBRange& entities,
- MBEntityHandle mEntityHandle,
- AEntityFactory* mAdjFact )
+MBErrorCode MBMeshSet::insert_entity_ranges( const MBEntityHandle* range_vect, size_t len, MBEntityHandle my_h, AEntityFactory* adj )
{
+ typedef const std::pair<MBEntityHandle,MBEntityHandle>* pair_vect_t;
+ pair_vect_t pair_vect = reinterpret_cast<pair_vect_t>(range_vect);
+ MBMeshSet::Count count = static_cast<MBMeshSet::Count>(mContentCount);
+ MBErrorCode rval;
+ if (!vector_based())
+ rval = range_tool<pair_vect_t>::ranged_insert_entities( count, contentList, pair_vect,
+ pair_vect + len/2, my_h, tracking() ? adj : 0 );
+ else
+ rval = range_tool<pair_vect_t>::vector_insert_entities( count, contentList, pair_vect,
+ pair_vect + len/2, my_h, tracking() ? adj : 0 );
+ mContentCount = count;
+ return rval;
+}
- unsigned int prev_size = mVector.size();
- mVector.resize(prev_size + entities.size());
- std::copy(entities.begin(), entities.end(), &mVector[prev_size]);
-
- if(tracking() && mAdjFact)
- {
- for(MBRange::const_iterator iter = entities.begin();
- iter != entities.end(); ++iter)
- mAdjFact->add_adjacency(*iter, mEntityHandle);
+MBErrorCode MBMeshSet::insert_entity_ranges( const MBRange& range, MBEntityHandle my_h, AEntityFactory* adj )
+{
+ MBErrorCode rval;
+ MBMeshSet::Count count = static_cast<MBMeshSet::Count>(mContentCount);
+ if (!vector_based())
+ rval = range_tool<MBRange::const_pair_iterator>::ranged_insert_entities( count,
+ contentList, range.const_pair_begin(), range.const_pair_end(),
+ my_h, tracking() ? adj : 0 );
+ else
+ rval = range_tool<MBRange::const_pair_iterator>::vector_insert_entities( count,
+ contentList, range.const_pair_begin(), range.const_pair_end(),
+ my_h, tracking() ? adj : 0 );
+ mContentCount = count;
+ return rval;
+}
+
+MBErrorCode MBMeshSet::remove_entity_ranges( const MBEntityHandle* range_vect, size_t len, MBEntityHandle my_h, AEntityFactory* adj )
+{
+ MBErrorCode rval;
+ MBMeshSet::Count count = static_cast<MBMeshSet::Count>(mContentCount);
+ if (vector_based())
+ rval = vector_remove_ranges( count, contentList, range_vect, len/2, my_h,
+ tracking() ? adj : 0 );
+ else {
+ typedef const std::pair<MBEntityHandle,MBEntityHandle>* pair_vect_t;
+ pair_vect_t pair_vect = reinterpret_cast<pair_vect_t>(range_vect);
+ rval = range_tool<pair_vect_t>::ranged_remove_entities( count, contentList, pair_vect,
+ pair_vect + len/2, my_h, tracking() ? adj : 0 );
}
+ mContentCount = count;
+ return rval;
+}
- return MB_SUCCESS;
+MBErrorCode MBMeshSet::remove_entity_ranges( const MBRange& range, MBEntityHandle my_h, AEntityFactory* adj )
+{
+ MBErrorCode rval;
+ MBMeshSet::Count count = static_cast<MBMeshSet::Count>(mContentCount);
+ if (vector_based())
+ rval = vector_remove_range( count, contentList, range, my_h, tracking() ? adj : 0 );
+ else
+ rval = range_tool<MBRange::const_pair_iterator>::ranged_remove_entities( count,
+ contentList, range.const_pair_begin(), range.const_pair_end(),
+ my_h, tracking() ? adj : 0 );
+ mContentCount = count;
+ return rval;
}
-MBErrorCode MBMeshSet_Vector::remove_entities( const MBRange& entities,
- MBEntityHandle mEntityHandle,
- AEntityFactory* mAdjFact )
+MBErrorCode MBMeshSet::intersect( const MBMeshSet* other, MBEntityHandle my_handle, AEntityFactory* adj )
{
- std::vector<MBEntityHandle>::iterator iter = mVector.begin();
- for(; iter < mVector.end(); )
- {
- if(entities.find(*iter) != entities.end())
- {
- if(tracking() && mAdjFact)
- mAdjFact->remove_adjacency(*iter, mEntityHandle);
- iter = mVector.erase(iter);
+ MBErrorCode rval;
+ if (!vector_based() && !other->vector_based()) {
+ size_t other_count = 0;
+ const MBEntityHandle* other_vect = other->get_contents( other_count );
+ if (!other_count)
+ return clear( my_handle, adj );
+ assert(0 == other_count%2);
+
+ std::vector<MBEntityHandle> compliment;
+ compliment.reserve( other_count + 4 );
+ if (*other_vect > 0) {
+ compliment.push_back( 0 );
+ compliment.push_back( *other_vect - 1 );
}
- else
- ++iter;
+ ++other_vect;
+ const MBEntityHandle *const other_end = other_vect + other_count - 2;
+ for (; other_vect < other_end; other_vect += 2) {
+ compliment.push_back( other_vect[0] + 1 );
+ compliment.push_back( other_vect[1] - 1 );
+ }
+ if (*other_vect < ~(MBEntityHandle)0) {
+ compliment.push_back( *other_vect + 1 );
+ compliment.push_back( ~(MBEntityHandle)0 );
+ }
+
+ return remove_entity_ranges( &compliment[0], compliment.size(), my_handle, adj );
}
-
- return MB_SUCCESS;
-
+ else {
+ MBRange my_ents, other_ents;
+ rval = get_entities(my_ents);
+ if (MB_SUCCESS != rval)
+ return rval;
+ rval = other->get_entities(other_ents);
+ return remove_entities( my_ents.subtract(other_ents), my_handle, adj );
+ }
}
-MBErrorCode MBMeshSet_Vector::remove_entities( const MBEntityHandle *entities,
- const int num_entities,
- MBEntityHandle mEntityHandle,
- AEntityFactory* mAdjFact )
+static void convert_to_ranges( const MBEntityHandle* vect_in, size_t vect_in_len,
+ std::vector<MBEntityHandle>& vect_out )
{
- std::vector<MBEntityHandle>::iterator temp_iter;
- for(int i = 0; i != num_entities; i++ )
- {
- temp_iter = std::find( mVector.begin(), mVector.end(), entities[i]);
- if( temp_iter != mVector.end() )
- {
- if(tracking() && mAdjFact)
- mAdjFact->remove_adjacency(entities[i], mEntityHandle);
- mVector.erase(temp_iter);
+ vect_out.reserve( 2*vect_in_len );
+ vect_out.resize( vect_in_len );
+ std::copy( vect_in, vect_in+vect_in_len, vect_out.begin() );
+ std::sort( vect_out.begin(), vect_out.end() );
+
+ // duplicate all entries
+ vect_out.resize( vect_out.size() * 2 );
+ for (long i = vect_out.size() - 1; i >= 0; --i)
+ vect_out[i] = vect_out[i/2];
+
+ // compact adjacent ranges
+ std::vector<MBEntityHandle>::iterator r = vect_out.begin(), w = vect_out.begin();
+ while (r != vect_out.end()) {
+ *w = *r;
+ ++w;
+ ++r;
+ *w = *r;
+ ++r;
+
+ while (r != vect_out.end() && *w + 1 == *r) {
+ ++r;
+ *w = *r;
+ ++r;
}
+ ++w;
}
- return MB_SUCCESS;
+
+ // remove extra space
+ vect_out.erase( w, vect_out.end() );
}
-MBErrorCode MBMeshSet_Vector::subtract( const MBMeshSet *meshset_2,
- MBEntityHandle my_handle,
- AEntityFactory* adj_fact )
+MBErrorCode MBMeshSet::insert_entity_vector( const MBEntityHandle* vect, size_t len, MBEntityHandle my_h, AEntityFactory* adj )
{
- std::vector<MBEntityHandle> other_vector;
- meshset_2->get_entities(other_vector);
-
- return remove_entities(&other_vector[0], other_vector.size(), my_handle, adj_fact);
+ MBMeshSet::Count count = static_cast<MBMeshSet::Count>(mContentCount);
+ MBErrorCode rval;
+ if (vector_based())
+ rval = vector_insert_vector( count, contentList, vect, len, my_h, tracking() ? adj : 0 );
+ else {
+ std::vector<MBEntityHandle> rangevect;
+ convert_to_ranges( vect, len, rangevect );
+ typedef const std::pair<MBEntityHandle,MBEntityHandle>* pair_vect_t;
+ pair_vect_t pair_vect = reinterpret_cast<pair_vect_t>(&rangevect[0]);
+ rval = range_tool<pair_vect_t>::ranged_insert_entities( count, contentList, pair_vect,
+ pair_vect + rangevect.size()/2, my_h, tracking() ? adj : 0 );
+ }
+ mContentCount = count;
+ return rval;
}
-MBErrorCode MBMeshSet_Vector::intersect( const MBMeshSet *meshset_2,
- MBEntityHandle mEntityHandle,
- AEntityFactory* mAdjFact )
+MBErrorCode MBMeshSet::remove_entity_vector( const MBEntityHandle* vect, size_t len, MBEntityHandle my_h, AEntityFactory* adj )
{
- MBRange other_range;
- meshset_2->get_entities(other_range);
+ MBMeshSet::Count count = static_cast<MBMeshSet::Count>(mContentCount);
+ MBErrorCode rval;
+ if (vector_based())
+ rval = vector_remove_vector( count, contentList, vect, len, my_h, tracking() ? adj : 0 );
+ else {
+ std::vector<MBEntityHandle> rangevect;
+ convert_to_ranges( vect, len, rangevect );
+ typedef const std::pair<MBEntityHandle,MBEntityHandle>* pair_vect_t;
+ pair_vect_t pair_vect = reinterpret_cast<pair_vect_t>(&rangevect[0]);
+ rval = range_tool<pair_vect_t>::ranged_remove_entities( count, contentList, pair_vect,
+ pair_vect + rangevect.size()/2, my_h, tracking() ? adj : 0 );
+ }
+ mContentCount = count;
+ return rval;
+}
- std::sort(mVector.begin(), mVector.end());
- std::set<MBEntityHandle> tmp;
- std::set_intersection(mVector.begin(), mVector.end(), other_range.begin(), other_range.end(),
- std::inserter< std::set<MBEntityHandle> >(tmp, tmp.end()));
+bool MBMeshSet::replace_entities( MBEntityHandle my_handle,
+ const MBEntityHandle* entities,
+ size_t num_entities,
+ AEntityFactory* adjfact )
+{
+ assert(0 == num_entities%2);
+ if (vector_based()) {
+ bool was_contained = false;
+ size_t count;
+ MBEntityHandle* vect = get_contents( count );
+ MBEntityHandle* const vect_end = vect+count;
+ for (size_t i = 0; i < num_entities; i+=2) {
+ for (MBEntityHandle* p = vect; p != vect_end; ++p ) {
+ if (*p == entities[i]) {
+ if (tracking()) {
+ adjfact->remove_adjacency( *p, my_handle );
+ adjfact->add_adjacency( entities[i+1], my_handle, false );
+ }
+ *p = entities[i+1];
+ was_contained = true;
+ }
+ }
+ }
+ return was_contained;
+ }
+ else {
+ std::vector<MBEntityHandle> swap_list;
+ swap_list.reserve( num_entities / 2 );
- mVector.resize(tmp.size());
-
- std::copy(tmp.begin(), tmp.end(), mVector.begin());
-
- //track owner
- tmp.clear();
- std::set_difference(mVector.begin(), mVector.end(), other_range.begin(), other_range.end(),
- std::inserter< std::set<MBEntityHandle> >(tmp, tmp.end()));
-
- if(tracking() && mAdjFact)
- {
- for(std::set<MBEntityHandle>::iterator iter = tmp.begin();
- iter != tmp.end(); ++iter)
- mAdjFact->remove_adjacency(*iter, mEntityHandle);
+ // get list of handles to remove
+ size_t count;
+ MBEntityHandle* vect = get_contents( count );
+ MBEntityHandle* const vect_end = vect+count;
+ for (size_t i = 0; i < num_entities; i+=2) {
+ MBEntityHandle* p = std::lower_bound(vect, vect_end, entities[i]);
+ if (p != vect_end && (*p == entities[i] || (p-vect)%2 == 1))
+ swap_list.push_back(entities[i]);
+ }
+ if (swap_list.empty())
+ return false;
+
+ // remove entities
+ remove_entities( &swap_list[0], swap_list.size(), my_handle, adjfact );
+
+ // get list of handles to add
+ std::vector<MBEntityHandle>::iterator si = swap_list.begin();
+ for (size_t i = 0; i < num_entities; ++i) {
+ if (entities[i] == *si) {
+ *si = entities[i+1];
+ if (++si == swap_list.end())
+ break;
+ }
+ }
+
+ // add entities
+ add_entities( &swap_list[0], swap_list.size(), my_handle, adjfact );
+ return true;
}
-
- return MB_SUCCESS;
}
-MBErrorCode MBMeshSet_Vector::unite( const MBMeshSet *meshset_2,
- MBEntityHandle my_handle,
- AEntityFactory* adj_fact )
-{
- std::vector<MBEntityHandle> other_vector;
- meshset_2->get_entities(other_vector);
- return add_entities(&other_vector[0], other_vector.size(), my_handle, adj_fact);
-}
-unsigned long MBMeshSet_Vector::get_memory_use() const
+/*****************************************************************************************
+ * Misc. Methods *
+ *****************************************************************************************/
+
+unsigned long MBMeshSet::get_memory_use() const
{
- return parent_child_memory_use()
- + mVector.capacity()*sizeof(MBEntityHandle);
+ unsigned long result = 0;
+ if (mParentCount == MANY)
+ result += parentMeshSets.ptr[1] - parentMeshSets.ptr[0];
+ if (mChildCount == MANY)
+ result += childMeshSets.ptr[1] - childMeshSets.ptr[0];
+ if (mContentCount == MANY)
+ result += contentList.ptr[1] - contentList.ptr[0];
+ return sizeof(MBEntityHandle)*result;
}
-
Modified: MOAB/trunk/MBMeshSet.hpp
===================================================================
--- MOAB/trunk/MBMeshSet.hpp 2008-03-31 20:29:26 UTC (rev 1730)
+++ MOAB/trunk/MBMeshSet.hpp 2008-04-01 15:49:58 UTC (rev 1731)
@@ -1,30 +1,3 @@
-/**
- * MOAB, a Mesh-Oriented datABase, is a software component for creating,
- * storing and accessing finite element mesh data.
- *
- * Copyright 2004 Sandia Corporation. Under the terms of Contract
- * DE-AC04-94AL85000 with Sandia Coroporation, the U.S. Government
- * retains certain rights in this software.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- */
-
-//
-//-------------------------------------------------------------------------
-// Filename : MB_MeshSet.hpp
-// Creator : Tim Tautges
-//
-// Date : 02/01/02
-//
-// Owner : Tim Tautges
-//
-// Description : MB_MeshSet is the MB implementation of MeshSet
-//-------------------------------------------------------------------------
-
#ifndef MB_MESHSET_HPP
#define MB_MESHSET_HPP
@@ -32,88 +5,46 @@
#error "MB_MeshSet.hpp isn't supposed to be included into an application"
#endif
-#include "MBTypes.h"
+#include "MBInterface.hpp"
+#include "MBInternals.hpp"
#include "MBRange.hpp"
-#include "MBInterface.hpp"
#include "MBCN.hpp"
+#include <assert.h>
#include <vector>
#include <algorithm>
+#include <iterator>
-#define MB_MESH_SET_COMPACT_PARENT_CHILD_LISTS
-
-
class AEntityFactory;
+/** \brief Class to implement entity set functionality
+ * \author Jason Kraftcheck <kraftche at cae.wisc.edu>
+ */
class MBMeshSet
{
-protected:
+public:
//! create an empty meshset
- MBMeshSet( unsigned flags );
+ inline MBMeshSet();
+ inline MBMeshSet(unsigned flags);
//! destructor
- ~MBMeshSet();
-
-public:
-
-#ifndef MB_MESH_SET_COMPACT_PARENT_CHILD_LISTS
- //! get all children pointed to by this meshset
- const MBEntityHandle* get_children( int& count_out ) const
- { count_out = childMeshSets.size(); return &childMeshSets[0]; }
-
- //! get all parents pointed to by this meshset
- const MBEntityHandle* get_parents( int& count_out ) const
- { count_out = parentMeshSets.size(); return &parentMeshSets[0]; }
-
- //! return the number of children pointed to by this meshset
- int num_children() const { return childMeshSets.size(); }
+ inline ~MBMeshSet();
+
+ inline MBErrorCode set_flags( unsigned flags, MBEntityHandle my_handle, AEntityFactory* adjacencies );
- //! return the number of parents pointed to by this meshset
- int num_parents() const { return parentMeshSets.size(); }
-#else
//! get all children pointed to by this meshset
- const MBEntityHandle* get_children( int& count_out ) const
- {
- count_out = mChildCount;
- if (count_out < MANY)
- return childMeshSets.hnd;
-
- count_out = childMeshSets.ptr[1] - childMeshSets.ptr[0];
- return childMeshSets.ptr[0];
- }
+ inline const MBEntityHandle* get_children( int& count_out ) const ;
//! get all parents pointed to by this meshset
- const MBEntityHandle* get_parents( int& count_out ) const
- {
- count_out = mParentCount;
- if (count_out < MANY)
- return parentMeshSets.hnd;
-
- count_out = parentMeshSets.ptr[1] - parentMeshSets.ptr[0];
- return parentMeshSets.ptr[0];
- }
+ inline const MBEntityHandle* get_parents( int& count_out ) const;
//! return the number of children pointed to by this meshset
- int num_children() const
- {
- if (mChildCount < MANY)
- return mChildCount;
- else
- return childMeshSets.ptr[1] - childMeshSets.ptr[0];
- }
+ inline int num_children() const ;
//! return the number of parents pointed to by this meshset
- int num_parents() const
- {
- if (mParentCount < MANY)
- return mParentCount;
- else
- return parentMeshSets.ptr[1] - parentMeshSets.ptr[0];
- }
-#endif
-
+ inline int num_parents() const;
//! add a parent to this meshset; returns true if parent was added, 0 if it was
//! already a parent of this meshset
@@ -138,45 +69,63 @@
int ordered() const { return mFlags & MESHSET_ORDERED; }
int vector_based() const { return ordered(); }
- //! PURE VIRTUAL FUNCTIONS overwritten by derived classes *******************
-
//! replace one entity with another in the set (contents and parent/child
//! lists); returns whether it was replaced or not
- inline bool replace_entities(MBEntityHandle my_handle,
- MBEntityHandle *entities, int num_entities,
- AEntityFactory* mAdjFact);
+ bool replace_entities(MBEntityHandle my_handle,
+ const MBEntityHandle *entities,
+ size_t num_entities,
+ AEntityFactory* mAdjFact);
+ /** Clear *contents* of set (not parents or children) */
inline MBErrorCode clear( MBEntityHandle myhandle, AEntityFactory* adjacencies );
+
+ /** Clear all set lists (contents, parents, and children) */
+ inline MBErrorCode clear_all( MBEntityHandle myhandle, AEntityFactory* adjacencies );
+ /** Get contents data array. NOTE: this may not contain what you expect if not vector_based */
+ inline const MBEntityHandle* get_contents( size_t& count_out ) const;
+ /** Get contents data array. NOTE: this may not contain what you expect if not vector_based */
+ inline MBEntityHandle* get_contents( size_t& count_out );
+
+ /** Get entities contained in set */
inline MBErrorCode get_entities(std::vector<MBEntityHandle>& entities) const;
+
+ /** Get entities contained in set */
+ inline MBErrorCode get_entities( MBRange& entities ) const;
- inline MBErrorCode get_entities(MBRange& entities) const;
-
//! get all entities in this MeshSet with the specified type
- inline MBErrorCode get_entities_by_type(MBEntityType entity_type,
- std::vector<MBEntityHandle> &entity_list) const;
+ inline MBErrorCode get_entities_by_type(MBEntityType entity_type, std::vector<MBEntityHandle> &entity_list) const;
- inline MBErrorCode get_entities_by_type(MBEntityType type,
- MBRange& entity_list) const;
+ inline MBErrorCode get_entities_by_type( MBEntityType type, MBRange& entity_list) const;
+
+ //! return the number of entities with the given type contained in this meshset
+ inline unsigned int num_entities_by_type(MBEntityType type) const;
- inline MBErrorCode get_entities_by_dimension( int dimension,
- std::vector<MBEntityHandle> &entity_list) const;
+ inline MBErrorCode get_entities_by_dimension( int dimension, std::vector<MBEntityHandle> &entity_list) const;
- inline MBErrorCode get_entities_by_dimension( int dimension,
- MBRange& entity_list) const;
+ inline MBErrorCode get_entities_by_dimension( int dimension, MBRange& entity_list) const;
+
+ //! return the number of entities with the given type contained in this meshset
+ inline unsigned int num_entities_by_dimension(int dimension) const;
inline MBErrorCode get_non_set_entities( MBRange& range ) const;
- inline bool contains_entities(MBEntityHandle *entities,
- int num_entities,
- const int operation_type) const;
+ /** Test of meshset contains some or all of passed entities
+ *
+ *\param entities Array of entities
+ *\param num_entities Length of array of entities.
+ *\param op - MBInterface::UNION : Test if set contains any of the input entities
+ * - MBInterface::INTERSECT : Test if set contains all of the input entities
+ */
+ inline bool contains_entities(const MBEntityHandle *entities, int num_entities, const int op) const;
+
//! subtract/intersect/unite meshset_2 from/with/into meshset_1; modifies meshset_1
inline MBErrorCode subtract(const MBMeshSet *meshset_2,
MBEntityHandle my_handle,
AEntityFactory* adjacencies);
- inline MBErrorCode intersect(const MBMeshSet *meshset_2,
+ MBErrorCode intersect(const MBMeshSet *meshset_2,
MBEntityHandle my_handle,
AEntityFactory* adjacencies);
@@ -199,6 +148,7 @@
inline MBErrorCode remove_entities(const MBRange& entities,
MBEntityHandle my_handle,
AEntityFactory* adjacencies);
+
//! remove these entities from this meshset
inline MBErrorCode remove_entities(const MBEntityHandle *entities,
@@ -208,32 +158,40 @@
//! return the number of entities contained in this meshset
inline unsigned int num_entities() const;
-
- //! return the number of entities with the given type contained in this meshset
- inline unsigned int num_entities_by_type(MBEntityType entity_type) const;
-
- //! return the number of entities with the given type contained in this meshset
- inline unsigned int num_entities_by_dimension(int dimension) const;
-
- typedef std::vector<MBEntityHandle> LinkSet;
- inline unsigned long get_memory_use() const;
+ inline bool empty() const { return mContentCount == ZERO; }
+
+ unsigned long get_memory_use() const;
protected:
+
+ /** Convert for changing flag values */
+ MBErrorCode convert( unsigned flags, MBEntityHandle my_handle, AEntityFactory* adj );
- unsigned long parent_child_memory_use() const;
+ /** Add explicit adjacencies from all contained entities to this (i.e. convert to tracking) */
+ MBErrorCode create_adjacencies( MBEntityHandle myhandle, AEntityFactory* adjacencies );
-#ifndef MB_MESH_SET_COMPACT_PARENT_CHILD_LISTS
- //!Meshset propery flags
- unsigned char mFlags;
- //! links to parents/children
- LinkSet parentMeshSets, childMeshSets;
-
- //!flag to indicate whether 'tracking' is occuring on this meshset
- //ie. all entities of the meshset know they belong to this meshset
- bool mTracking;
-#else
+ /** Remvoe explicit adjacencies from all contained entities to this (i.e. convert from tracking) */
+ MBErrorCode remove_adjacencies( MBEntityHandle myhandle, AEntityFactory* adjacencies );
+ /** Insert vector of handles into MBMeshSet */
+ MBErrorCode insert_entity_vector( const MBEntityHandle* vect, size_t len, MBEntityHandle my_h, AEntityFactory* adj );
+
+ /** Insert vector of handle range pairs into MBMeshSet */
+ MBErrorCode insert_entity_ranges( const MBEntityHandle* range_vect, size_t len, MBEntityHandle my_h, AEntityFactory* adj );
+
+ /** Insert MBRange of handles into MBMeshSet */
+ MBErrorCode insert_entity_ranges( const MBRange& range, MBEntityHandle my_h, AEntityFactory* adj );
+
+ /** Remove vector of handles from MBMeshSet */
+ MBErrorCode remove_entity_vector( const MBEntityHandle* vect, size_t len, MBEntityHandle my_h, AEntityFactory* adj );
+
+ /** Remove vector of handle range pairs from MBMeshSet */
+ MBErrorCode remove_entity_ranges( const MBEntityHandle* range_vect, size_t len, MBEntityHandle my_h, AEntityFactory* adj );
+
+ /** Remove MBRange of handles from MBMeshSet */
+ MBErrorCode remove_entity_ranges( const MBRange& range, MBEntityHandle my_h, AEntityFactory* adj );
+
public:
//! Possible values of mParentCount and mChildCount
enum Count { ZERO=0, ONE=1, TWO=2, MANY=3 };
@@ -245,7 +203,8 @@
MBEntityHandle hnd[2]; //!< Two handles
MBEntityHandle* ptr[2]; //!< begin and end pointers for array
};
-protected:
+
+private:
//!Meshset propery flags
unsigned char mFlags;
//! If less than MANY, the number of parents stored inline in
@@ -258,110 +217,27 @@
//! array begin and end pointers for a dynamically allocated array
//! of child handles.
unsigned mChildCount : 2;
-private:
- //! Storage for parent and child lists
- CompactList parentMeshSets, childMeshSets;
-#endif
-};
+ //! If less than MANY, the number of children stored inline in
+ //! contentList.hnd. If MANY, then contentList.ptr contains
+ //! array begin and end pointers for a dynamically allocated array..
+ unsigned mContentCount : 2;
+ //! Storage for data lists
+ CompactList parentMeshSets, childMeshSets, contentList;
-#define MESH_SET_VIRTUAL_FUNCTIONS \
- MBErrorCode clear( MBEntityHandle my_handle, AEntityFactory* adjacencies); \
- \
- bool replace_entities(MBEntityHandle my_handle, MBEntityHandle *entities, \
- int num_entities, AEntityFactory* mAdjFact); \
- \
- inline MBErrorCode get_entities(std::vector<MBEntityHandle>& entities) const; \
- \
- inline MBErrorCode get_entities(MBRange& entities) const; \
- \
- inline MBErrorCode get_entities_by_type(MBEntityType type, \
- std::vector<MBEntityHandle>& entity_list) const; \
- \
- inline MBErrorCode get_entities_by_type(MBEntityType type, \
- MBRange& entity_list) const; \
- \
- inline MBErrorCode get_entities_by_dimension(int dimension, \
- std::vector<MBEntityHandle>& entity_list) const; \
- \
- inline MBErrorCode get_entities_by_dimension(int dimension, \
- MBRange& entity_list) const; \
- \
- inline bool contains_entities(MBEntityHandle *entities, \
- int num_entities, \
- const int operation_type) const; \
- \
- inline MBErrorCode get_non_set_entities( MBRange& range ) const; \
- \
- MBErrorCode subtract(const MBMeshSet*, \
- MBEntityHandle my_handle, \
- AEntityFactory* adjacencies); \
- \
- MBErrorCode intersect(const MBMeshSet *meshset_2, \
- MBEntityHandle my_handle, \
- AEntityFactory* adjacencies); \
- \
- MBErrorCode unite(const MBMeshSet *meshset_2, \
- MBEntityHandle my_handle, \
- AEntityFactory* adjacencies); \
- \
- MBErrorCode add_entities(const MBEntityHandle *entity_handles, \
- const int num_entities, \
- MBEntityHandle my_handle, \
- AEntityFactory* adjacencies); \
- \
- MBErrorCode add_entities(const MBRange &entities, \
- MBEntityHandle my_handle, \
- AEntityFactory* adjacencies); \
- \
- MBErrorCode remove_entities(const MBRange& entities, \
- MBEntityHandle my_handle, \
- AEntityFactory* adjacencies); \
- \
- MBErrorCode remove_entities(const MBEntityHandle *entities, \
- const int num_entities, \
- MBEntityHandle my_handle, \
- AEntityFactory* adjacencies); \
- \
- inline unsigned int num_entities() const; \
- \
- inline unsigned int num_entities_by_type(MBEntityType entity_type) const; \
- \
- inline unsigned int num_entities_by_dimension(int dimesion) const; \
- \
- unsigned long get_memory_use() const;
-
-
-
-class MBMeshSet_MBRange : public MBMeshSet
-{
public:
+ /** get dimension of enity */
+ static inline int DIM_FROM_HANDLE( MBEntityHandle h )
+ { return MBCN::Dimension( TYPE_FROM_HANDLE( h ) ); }
+
+ /** Get smallest possible handle with specified dimension (first handle for first type of dimension) */
+ static inline MBEntityHandle FIRST_OF_DIM( int dim )
+ { return FIRST_HANDLE( MBCN::TypeDimensionMap[dim].first ); }
+
+ /** Get largest possible handle with specified dimension (largest handle for last type of dimension) */
+ static inline MBEntityHandle LAST_OF_DIM( int dim )
+ { return LAST_HANDLE( MBCN::TypeDimensionMap[dim].second ); }
- MBMeshSet_MBRange(bool track_ownership)
- : MBMeshSet(track_ownership ?
- MESHSET_SET|MESHSET_TRACK_OWNER :
- MESHSET_SET) {}
-
- MESH_SET_VIRTUAL_FUNCTIONS
-
-private:
- MBRange mRange;
-
-};
-
-class MBMeshSet_Vector : public MBMeshSet
-{
-public:
-
- MBMeshSet_Vector(bool track_ownership)
- : MBMeshSet(track_ownership ?
- MESHSET_ORDERED|MESHSET_TRACK_OWNER :
- MESHSET_ORDERED) {}
-
- MESH_SET_VIRTUAL_FUNCTIONS
-
-private:
- static void vector_to_range( std::vector<MBEntityHandle>& vect, MBRange& range );
-
+ /** functor: test if handle is not of type */
struct not_type_test {
inline not_type_test( MBEntityType type ) : mType(type) {}
inline bool operator()( MBEntityHandle handle )
@@ -369,6 +245,7 @@
MBEntityType mType;
};
+ /** functor: test if handle is of type */
struct type_test {
inline type_test( MBEntityType type ) : mType(type) {}
inline bool operator()( MBEntityHandle handle )
@@ -376,409 +253,538 @@
MBEntityType mType;
};
+ /** functor: test if handle is not of dimension */
struct not_dim_test {
inline not_dim_test( int dimension ) : mDim(dimension) {}
inline bool operator()( MBEntityHandle handle ) const
- { return MBCN::Dimension(TYPE_FROM_HANDLE(handle)) != mDim; }
+ { return DIM_FROM_HANDLE(handle) != mDim; }
int mDim;
};
+ /** functor: test if handle is of dimension */
struct dim_test {
inline dim_test( int dimension ) : mDim(dimension) {}
inline bool operator()( MBEntityHandle handle ) const
- { return MBCN::Dimension(TYPE_FROM_HANDLE(handle)) == mDim; }
+ { return DIM_FROM_HANDLE(handle) == mDim; }
int mDim;
};
-
-
- std::vector<MBEntityHandle> mVector;
+
+ /** Iterate over range of handles. That is, given [first_handle,last_handle],
+ * step through all contained values.
+ */
+ struct hdl_iter {
+ MBEntityHandle h;
+ hdl_iter( MBEntityHandle val ) : h(val) {}
+ hdl_iter& operator++() { ++h; return *this; }
+ hdl_iter& operator--() { --h; return *this; }
+ hdl_iter operator++(int) { return hdl_iter(h++); }
+ hdl_iter operator--(int) { return hdl_iter(h--); }
+ hdl_iter& operator+=(size_t s) { h += s; return *this; }
+ hdl_iter& operator-=(size_t s) { h -= s; return *this; }
+ MBEntityHandle operator*() const { return h; }
+ bool operator==(hdl_iter other) const { return h == other.h; }
+ bool operator!=(hdl_iter other) const { return h != other.h; }
+ bool operator< (hdl_iter other) const { return h < other.h; }
+ bool operator> (hdl_iter other) const { return h > other.h; }
+ bool operator<=(hdl_iter other) const { return h <= other.h; }
+ bool operator>=(hdl_iter other) const { return h >= other.h; }
+
+ struct iterator_category : public std::random_access_iterator_tag { };
+ typedef MBEntityID difference_type;
+ typedef MBEntityHandle value_type;
+ typedef MBEntityHandle* pointer;
+ typedef MBEntityHandle& reference;
+ };
+
};
-inline bool
-MBMeshSet::replace_entities( MBEntityHandle my_handle,
- MBEntityHandle *entities, int num_entities,
- AEntityFactory* mAdjFact)
-{
- return vector_based() ?
- reinterpret_cast<MBMeshSet_Vector* >(this)->replace_entities(my_handle, entities, num_entities,
- mAdjFact) :
- reinterpret_cast<MBMeshSet_MBRange*>(this)->replace_entities(my_handle, entities, num_entities,
- mAdjFact);
-}
-inline MBErrorCode
-MBMeshSet::clear( MBEntityHandle myhandle, AEntityFactory* adjacencies )
-{
- return vector_based() ?
- reinterpret_cast<MBMeshSet_Vector* >(this)->clear( myhandle, adjacencies ) :
- reinterpret_cast<MBMeshSet_MBRange*>(this)->clear( myhandle, adjacencies ) ;
-}
+ //! create an empty meshset
+MBMeshSet::MBMeshSet()
+ : mFlags(0), mParentCount(ZERO), mChildCount(ZERO), mContentCount(ZERO)
+{ }
-inline MBErrorCode
-MBMeshSet::get_entities(std::vector<MBEntityHandle>& entities) const
-{
- return vector_based() ?
- reinterpret_cast<const MBMeshSet_Vector* >(this)->get_entities( entities ) :
- reinterpret_cast<const MBMeshSet_MBRange*>(this)->get_entities( entities ) ;
-}
+ //! create an empty meshset
+MBMeshSet::MBMeshSet(unsigned flags)
+ : mFlags(flags), mParentCount(ZERO), mChildCount(ZERO), mContentCount(ZERO)
+{ }
-inline MBErrorCode
-MBMeshSet::get_entities(MBRange& entities) const
-{
- return vector_based() ?
- reinterpret_cast<const MBMeshSet_Vector* >(this)->get_entities( entities ) :
- reinterpret_cast<const MBMeshSet_MBRange*>(this)->get_entities( entities ) ;
+ //! destructor
+MBMeshSet::~MBMeshSet()
+{
+ if (mChildCount == MANY)
+ free( childMeshSets.ptr[0] );
+ if (mParentCount == MANY)
+ free( parentMeshSets.ptr[0] );
+ if (mContentCount == MANY)
+ free( contentList.ptr[0] );
+ mChildCount = mParentCount = mContentCount = ZERO;
}
-
- //! get all entities in this MeshSet with the specified type
-inline MBErrorCode
-MBMeshSet::get_entities_by_type(MBEntityType type, std::vector<MBEntityHandle> &entities) const
-{
- return vector_based() ?
- reinterpret_cast<const MBMeshSet_Vector* >(this)->get_entities_by_type( type, entities ) :
- reinterpret_cast<const MBMeshSet_MBRange*>(this)->get_entities_by_type( type, entities ) ;
+
+MBErrorCode MBMeshSet::set_flags( unsigned flags, MBEntityHandle my_handle, AEntityFactory* adjacencies )
+{
+ if (mContentCount == 0) {
+ mFlags = flags;
+ return MB_SUCCESS;
+ }
+ else
+ return convert( flags, my_handle, adjacencies );
}
+
-inline MBErrorCode
-MBMeshSet::get_entities_by_type(MBEntityType type, MBRange& entities) const
+//! get all children pointed to by this meshset
+const MBEntityHandle* MBMeshSet::get_children( int& count_out ) const
{
- return vector_based() ?
- reinterpret_cast<const MBMeshSet_Vector* >(this)->get_entities_by_type( type, entities ) :
- reinterpret_cast<const MBMeshSet_MBRange*>(this)->get_entities_by_type( type, entities ) ;
-}
-
-inline MBErrorCode
-MBMeshSet::get_entities_by_dimension( int dim, std::vector<MBEntityHandle> &entities) const
-{
- return vector_based() ?
- reinterpret_cast<const MBMeshSet_Vector* >(this)->get_entities_by_dimension( dim, entities ) :
- reinterpret_cast<const MBMeshSet_MBRange*>(this)->get_entities_by_dimension( dim, entities ) ;
-}
+ count_out = mChildCount;
+ if (count_out < MANY)
+ return childMeshSets.hnd;
-inline MBErrorCode
-MBMeshSet::get_entities_by_dimension( int dim, MBRange& entities) const
-{
- return vector_based() ?
- reinterpret_cast<const MBMeshSet_Vector* >(this)->get_entities_by_dimension( dim, entities ) :
- reinterpret_cast<const MBMeshSet_MBRange*>(this)->get_entities_by_dimension( dim, entities ) ;
+ count_out = childMeshSets.ptr[1] - childMeshSets.ptr[0];
+ return childMeshSets.ptr[0];
}
-
-inline MBErrorCode
-MBMeshSet::get_non_set_entities( MBRange& entities ) const
-{
- return vector_based() ?
- reinterpret_cast<const MBMeshSet_Vector* >(this)->get_non_set_entities( entities ) :
- reinterpret_cast<const MBMeshSet_MBRange*>(this)->get_non_set_entities( entities ) ;
-}
-
-inline bool
-MBMeshSet::contains_entities(MBEntityHandle *entities, int num_entities,
- const int operation_type) const
-{
- return vector_based() ?
- reinterpret_cast<const MBMeshSet_Vector* >(this)->contains_entities(entities, num_entities, operation_type) :
- reinterpret_cast<const MBMeshSet_MBRange*>(this)->contains_entities(entities, num_entities, operation_type) ;
-}
-
-//! subtract/intersect/unite meshset_2 from/with/into meshset_1; modifies meshset_1
-inline MBErrorCode
-MBMeshSet::subtract( const MBMeshSet *meshset_2,
- MBEntityHandle my_handle,
- AEntityFactory* adjacencies)
-{
- return vector_based() ?
- reinterpret_cast<MBMeshSet_Vector* >(this)->subtract( meshset_2, my_handle, adjacencies ) :
- reinterpret_cast<MBMeshSet_MBRange*>(this)->subtract( meshset_2, my_handle, adjacencies ) ;
-}
-inline MBErrorCode
-MBMeshSet::intersect( const MBMeshSet *meshset_2,
- MBEntityHandle my_handle,
- AEntityFactory* adjacencies)
+//! get all parents pointed to by this meshset
+const MBEntityHandle* MBMeshSet::get_parents( int& count_out ) const
{
- return vector_based() ?
- reinterpret_cast<MBMeshSet_Vector* >(this)->intersect( meshset_2, my_handle, adjacencies ) :
- reinterpret_cast<MBMeshSet_MBRange*>(this)->intersect( meshset_2, my_handle, adjacencies ) ;
-}
+ count_out = mParentCount;
+ if (count_out < MANY)
+ return parentMeshSets.hnd;
-inline MBErrorCode
-MBMeshSet::unite( const MBMeshSet *meshset_2,
- MBEntityHandle my_handle,
- AEntityFactory* adjacencies)
-{
- return vector_based() ?
- reinterpret_cast<MBMeshSet_Vector* >(this)->unite( meshset_2, my_handle, adjacencies ) :
- reinterpret_cast<MBMeshSet_MBRange*>(this)->unite( meshset_2, my_handle, adjacencies ) ;
+ count_out = parentMeshSets.ptr[1] - parentMeshSets.ptr[0];
+ return parentMeshSets.ptr[0];
}
-//! add these entities to this meshset
-inline MBErrorCode
-MBMeshSet::add_entities( const MBEntityHandle *entities,
- const int num_entities,
- MBEntityHandle my_handle,
- AEntityFactory* adjacencies)
-{
- return vector_based() ?
- reinterpret_cast<MBMeshSet_Vector* >(this)->add_entities( entities, num_entities, my_handle, adjacencies ) :
- reinterpret_cast<MBMeshSet_MBRange*>(this)->add_entities( entities, num_entities, my_handle, adjacencies ) ;
+//! return the number of children pointed to by this meshset
+int MBMeshSet::num_children() const
+{
+ if (mChildCount < MANY)
+ return mChildCount;
+ else
+ return childMeshSets.ptr[1] - childMeshSets.ptr[0];
}
-
- //! add these entities to this meshset
-inline MBErrorCode
-MBMeshSet::add_entities( const MBRange &entities,
- MBEntityHandle my_handle,
- AEntityFactory* adjacencies)
-{
- return vector_based() ?
- reinterpret_cast<MBMeshSet_Vector* >(this)->add_entities( entities, my_handle, adjacencies ) :
- reinterpret_cast<MBMeshSet_MBRange*>(this)->add_entities( entities, my_handle, adjacencies ) ;
-}
-
- //! add these entities to this meshset
-inline MBErrorCode
-MBMeshSet::remove_entities( const MBRange& entities,
- MBEntityHandle my_handle,
- AEntityFactory* adjacencies)
-{
- return vector_based() ?
- reinterpret_cast<MBMeshSet_Vector* >(this)->remove_entities( entities, my_handle, adjacencies ) :
- reinterpret_cast<MBMeshSet_MBRange*>(this)->remove_entities( entities, my_handle, adjacencies ) ;
-}
-
- //! remove these entities from this meshset
-inline MBErrorCode
-MBMeshSet::remove_entities( const MBEntityHandle *entities,
- const int num_entities,
- MBEntityHandle my_handle,
- AEntityFactory* adjacencies)
-{
- return vector_based() ?
- reinterpret_cast<MBMeshSet_Vector* >(this)->remove_entities( entities, num_entities, my_handle, adjacencies ) :
- reinterpret_cast<MBMeshSet_MBRange*>(this)->remove_entities( entities, num_entities, my_handle, adjacencies ) ;
-}
- //! return the number of entities contained in this meshset
-inline unsigned int MBMeshSet::num_entities() const
-{
- return vector_based() ?
- reinterpret_cast<const MBMeshSet_Vector* >(this)->num_entities() :
- reinterpret_cast<const MBMeshSet_MBRange*>(this)->num_entities() ;
+//! return the number of parents pointed to by this meshset
+int MBMeshSet::num_parents() const
+{
+ if (mParentCount < MANY)
+ return mParentCount;
+ else
+ return parentMeshSets.ptr[1] - parentMeshSets.ptr[0];
}
- //! return the number of entities with the given type contained in this meshset
-inline unsigned int
-MBMeshSet::num_entities_by_type(MBEntityType type) const
+inline MBErrorCode MBMeshSet::clear( MBEntityHandle myhandle, AEntityFactory* adjacencies )
{
- return vector_based() ?
- reinterpret_cast<const MBMeshSet_Vector* >(this)->num_entities_by_type(type) :
- reinterpret_cast<const MBMeshSet_MBRange*>(this)->num_entities_by_type(type) ;
+ if (tracking())
+ remove_adjacencies( myhandle, adjacencies );
+ if (mContentCount == MANY)
+ free( contentList.ptr[0] );
+ mContentCount = ZERO;
+ return MB_SUCCESS;
}
- //! return the number of entities with the given type contained in this meshset
-inline unsigned int
-MBMeshSet::num_entities_by_dimension(int dim) const
+inline MBErrorCode MBMeshSet::clear_all( MBEntityHandle myhandle, AEntityFactory* adjacencies )
{
- return vector_based() ?
- reinterpret_cast<const MBMeshSet_Vector* >(this)->num_entities_by_dimension(dim) :
- reinterpret_cast<const MBMeshSet_MBRange*>(this)->num_entities_by_dimension(dim) ;
+ MBErrorCode rval = clear( myhandle, adjacencies );
+ if (mChildCount == MANY)
+ free( childMeshSets.ptr[0] );
+ mChildCount = ZERO;
+ if (mParentCount == MANY)
+ free( parentMeshSets.ptr[0] );
+ mParentCount = ZERO;
+ return rval;
}
-inline unsigned long MBMeshSet::get_memory_use() const
-{
- return vector_based() ?
- reinterpret_cast<const MBMeshSet_Vector* >(this)->get_memory_use() :
- reinterpret_cast<const MBMeshSet_MBRange*>(this)->get_memory_use() ;
+inline const MBEntityHandle* MBMeshSet::get_contents( size_t& count_out ) const
+{
+ if (mContentCount == MANY) {
+ count_out = contentList.ptr[1] - contentList.ptr[0];
+ return contentList.ptr[0];
+ }
+ else {
+ count_out = mContentCount;
+ return contentList.hnd;
+ }
}
-inline MBErrorCode MBMeshSet_MBRange::get_entities(std::vector<MBEntityHandle>& entity_list) const
+inline MBEntityHandle* MBMeshSet::get_contents( size_t& count_out )
{
- size_t old_size = entity_list.size();
- entity_list.resize(old_size + mRange.size());
- std::copy( mRange.begin(), mRange.end(), entity_list.begin()+old_size );
- return MB_SUCCESS;
+ if (mContentCount == MANY) {
+ count_out = contentList.ptr[1] - contentList.ptr[0];
+ return contentList.ptr[0];
+ }
+ else {
+ count_out = mContentCount;
+ return contentList.hnd;
+ }
}
-inline MBErrorCode MBMeshSet_MBRange::get_entities(MBRange& entity_list) const
+inline MBErrorCode MBMeshSet::get_entities(std::vector<MBEntityHandle>& entities) const
{
- entity_list.merge( mRange );
+ size_t count;
+ const MBEntityHandle* ptr = get_contents( count );
+ if (vector_based()) {
+ size_t old_size = entities.size();
+ entities.resize( count+old_size );
+ std::copy( ptr, ptr+count, entities.begin()+old_size );
+ }
+ else {
+ assert(count%2 == 0);
+ for (size_t i = 0; i < count; i += 2)
+ std::copy( hdl_iter(ptr[i]), hdl_iter(ptr[i+1]+1), std::back_inserter(entities) );
+ }
return MB_SUCCESS;
-}
+}
-inline MBErrorCode MBMeshSet_MBRange::get_entities_by_type(MBEntityType type,
- std::vector<MBEntityHandle>& entity_list) const
+inline MBErrorCode MBMeshSet::get_entities(MBRange& entities) const
{
- std::pair<MBRange::const_iterator,MBRange::const_iterator> its;
- its = mRange.equal_range( type );
- std::copy( its.first, its.second, std::back_inserter( entity_list ) );
+ size_t count;
+ const MBEntityHandle* ptr = get_contents( count );
+ if (vector_based()) {
+ std::copy( ptr, ptr+count, mb_range_inserter(entities) );
+ }
+ else {
+ assert(count%2 == 0);
+ entities.clear();
+ MBRange::iterator in = entities.begin();
+ for (size_t i = 0; i < count; i += 2)
+ in = entities.insert( in, ptr[i], ptr[i+1] );
+ }
return MB_SUCCESS;
-}
+}
-inline MBErrorCode MBMeshSet_MBRange::get_entities_by_type(MBEntityType type,
- MBRange& entity_list) const
+
+ //! get all entities in this MeshSet with the specified type
+inline MBErrorCode MBMeshSet::get_entities_by_type(MBEntityType type,
+ std::vector<MBEntityHandle> &entity_list
+ ) const
{
- std::pair<MBRange::const_iterator,MBRange::const_iterator> its;
- its = mRange.equal_range( type );
- entity_list.merge( its.first, its.second );
- return MB_SUCCESS;
-}
+ size_t count;
+ const MBEntityHandle* ptr = get_contents( count );
+ if (vector_based()) {
+ std::remove_copy_if( ptr, ptr+count,
+ std::back_inserter( entity_list ),
+ not_type_test(type) );
+ }
+ else {
+ size_t idx = std::lower_bound( ptr, ptr+count, FIRST_HANDLE(type) ) - ptr;
+ if (idx < count && TYPE_FROM_HANDLE(ptr[idx]) == type) {
+ if (idx % 2) { // only part of first block is of type
+ std::copy( hdl_iter(FIRST_HANDLE(type)), hdl_iter(ptr[idx]+1), std::back_inserter( entity_list ) );
+ ++idx;
+ }
+ for (; idx < count; idx += 2) {
+ if (TYPE_FROM_HANDLE(ptr[idx+1]) == type) // whole block is of type
+ std::copy( hdl_iter(ptr[idx]), hdl_iter(ptr[idx+1]+1), std::back_inserter( entity_list ) );
+ else {
+ if (TYPE_FROM_HANDLE(ptr[idx]) == type) // part of last block is of type
+ std::copy( hdl_iter(ptr[idx]), hdl_iter(LAST_HANDLE(type)), std::back_inserter( entity_list ) );
+ break;
+ }
+ }
+ }
+ }
-inline MBErrorCode MBMeshSet_MBRange::get_entities_by_dimension(int dim,
- std::vector<MBEntityHandle>& entity_list) const
-{
- MBRange::const_iterator beg = mRange.lower_bound(MBCN::TypeDimensionMap[dim].first);
- MBRange::const_iterator end = mRange.lower_bound(MBCN::TypeDimensionMap[dim+1].first);
- std::copy( beg, end, std::back_inserter( entity_list ) );
return MB_SUCCESS;
}
-inline MBErrorCode MBMeshSet_MBRange::get_entities_by_dimension(int dim,
- MBRange& entity_list) const
+
+inline MBErrorCode MBMeshSet::get_entities_by_type( MBEntityType type,
+ MBRange& entity_list) const
{
- MBRange::const_iterator beg = mRange.lower_bound(MBCN::TypeDimensionMap[dim].first);
- MBRange::const_iterator end = mRange.lower_bound(MBCN::TypeDimensionMap[dim+1].first);
- entity_list.merge( beg, end );
- return MB_SUCCESS;
-}
+ size_t count;
+ const MBEntityHandle* ptr = get_contents( count );
+ if (vector_based()) {
+ std::remove_copy_if( ptr, ptr+count,
+ mb_range_inserter( entity_list ),
+ not_type_test(type) );
+ }
+ else {
+ size_t idx = std::lower_bound( ptr, ptr+count, FIRST_HANDLE(type) ) - ptr;
+ MBRange::iterator in = entity_list.begin();
+ if (idx < count && TYPE_FROM_HANDLE(ptr[idx]) == type) {
+ if (idx % 2) { // only part of first block is of type
+ in = entity_list.insert( in, FIRST_HANDLE(type), ptr[idx] );
+ ++idx;
+ }
+ for (; idx < count; idx += 2) {
+ if (TYPE_FROM_HANDLE(ptr[idx+1]) == type) // whole block is of type
+ in = entity_list.insert( in, ptr[idx], ptr[idx+1] );
+ else {
+ if (TYPE_FROM_HANDLE(ptr[idx]) == type) // part of last block is of type
+ entity_list.insert( in, ptr[idx], LAST_HANDLE(type) );
+ break;
+ }
+ }
+ }
+ }
-inline MBErrorCode MBMeshSet_MBRange::get_non_set_entities( MBRange& range ) const
-{
- range.merge( mRange.begin(), mRange.lower_bound( MBENTITYSET ) );
return MB_SUCCESS;
}
-inline bool MBMeshSet_MBRange::contains_entities(MBEntityHandle *entities,
- int num_entities,
- const int op_type) const
+ //! return the number of entities with the given type contained in this meshset
+inline unsigned int MBMeshSet::num_entities_by_type(MBEntityType type) const
{
- unsigned int num_in = 0;
- for (int i = 0; i < num_entities; i++) {
- if (mRange.find(entities[i]) != mRange.end()) num_in++;
- else if (MBInterface::INTERSECT == op_type) break;
+ unsigned int result;
+ size_t count;
+ const MBEntityHandle* ptr = get_contents( count );
+ if (vector_based()) {
+ #ifndef __SUNPRO_CC
+ result = std::count_if( ptr, ptr+count, type_test(type) );
+ #else
+ std::count_if( ptr, ptr+count, type_test(type), result );
+ #endif
}
+ else {
+ result = 0;
+ size_t idx = std::lower_bound( ptr, ptr+count, FIRST_HANDLE(type) ) - ptr;
+ if (idx < count && TYPE_FROM_HANDLE(ptr[idx]) == type) {
+ if (idx % 2) { // only part of first block is of type
+ result += ptr[idx] - FIRST_HANDLE(type) + 1;
+ ++idx;
+ }
+ for (; idx < count; idx += 2) {
+ if (TYPE_FROM_HANDLE(ptr[idx+1]) == type) // whole block is of type
+ result += ptr[idx+1] - ptr[idx] + 1;
+ else {
+ if (TYPE_FROM_HANDLE(ptr[idx]) == type) // part of last block is of type
+ result += LAST_HANDLE(type) - ptr[idx] + 1;
+ break;
+ }
+ }
+ }
+ }
- return ((MBInterface::INTERSECT == op_type && num_in == (unsigned int) num_entities) ||
- MBInterface::UNION == op_type && 0 < num_in);
+ return result;
}
-inline unsigned int MBMeshSet_MBRange::num_entities() const
+inline MBErrorCode MBMeshSet::get_entities_by_dimension( int dimension,
+ std::vector<MBEntityHandle> &entity_list
+ ) const
{
- return mRange.size();
-}
+ size_t count;
+ const MBEntityHandle* ptr = get_contents( count );
+ if (vector_based()) {
+ std::remove_copy_if( ptr, ptr+count,
+ std::back_inserter( entity_list ),
+ not_dim_test(dimension) );
+ }
+ else {
+ size_t idx = std::lower_bound( ptr, ptr+count, FIRST_OF_DIM(dimension) ) - ptr;
+ if (idx < count && DIM_FROM_HANDLE(ptr[idx]) == dimension) {
+ if (idx % 2) { // only part of first block is of type
+ std::copy( hdl_iter(FIRST_OF_DIM(dimension)), hdl_iter(ptr[idx]+1), std::back_inserter( entity_list ) );
+ ++idx;
+ }
+ for (; idx < count; idx += 2) {
+ if (DIM_FROM_HANDLE(ptr[idx+1]) == dimension) // whole block is of type
+ std::copy( hdl_iter(ptr[idx]), hdl_iter(ptr[idx+1]+1), std::back_inserter( entity_list ) );
+ else {
+ if (DIM_FROM_HANDLE(ptr[idx]) == dimension) // part of last block is of type
+ std::copy( hdl_iter(ptr[idx]), hdl_iter(LAST_OF_DIM(dimension)), std::back_inserter( entity_list ) );
+ break;
+ }
+ }
+ }
+ }
-inline unsigned int MBMeshSet_MBRange::num_entities_by_type(MBEntityType type) const
-{
- return mRange.num_of_type( type );
+ return MB_SUCCESS;
}
-inline unsigned int MBMeshSet_MBRange::num_entities_by_dimension(int dimension) const
+
+inline MBErrorCode MBMeshSet::get_entities_by_dimension( int dimension,
+ MBRange& entity_list) const
{
- return mRange.num_of_dimension( dimension );
-}
+ size_t count;
+ const MBEntityHandle* ptr = get_contents( count );
+ if (vector_based()) {
+ std::remove_copy_if( ptr, ptr+count,
+ mb_range_inserter( entity_list ),
+ not_dim_test(dimension) );
+ }
+ else {
+ size_t idx = std::lower_bound( ptr, ptr+count, FIRST_OF_DIM(dimension) ) - ptr;
+ MBRange::iterator in = entity_list.begin();
+ if (idx < count && DIM_FROM_HANDLE(ptr[idx]) == dimension) {
+ if (idx % 2) { // only part of first block is of type
+ in = entity_list.insert( in, FIRST_OF_DIM(dimension), ptr[idx] );
+ ++idx;
+ }
+ for (; idx < count; idx += 2) {
+ if (DIM_FROM_HANDLE(ptr[idx+1]) == dimension) // whole block is of type
+ in = entity_list.insert( in, ptr[idx], ptr[idx+1] );
+ else {
+ if (DIM_FROM_HANDLE(ptr[idx]) == dimension) // part of last block is of type
+ entity_list.insert( in, ptr[idx], LAST_OF_DIM(dimension) );
+ break;
+ }
+ }
+ }
+ }
-inline MBErrorCode MBMeshSet_Vector::get_entities(std::vector<MBEntityHandle>& entity_list) const
-{
- size_t old_size = entity_list.size();
- entity_list.resize( mVector.size() + old_size );
- std::copy( mVector.begin(), mVector.end(), entity_list.begin()+old_size );
return MB_SUCCESS;
}
-inline MBErrorCode MBMeshSet_Vector::get_entities(MBRange& entity_list) const
+ //! return the number of entities with the given type contained in this meshset
+inline unsigned int MBMeshSet::num_entities_by_dimension(int dimension) const
{
- std::vector<MBEntityHandle> tmp_vect( mVector );
- vector_to_range( tmp_vect, entity_list );
- return MB_SUCCESS;
+ unsigned int result;
+ size_t count;
+ const MBEntityHandle* ptr = get_contents( count );
+ if (vector_based()) {
+ #ifndef __SUNPRO_CC
+ result = std::count_if( ptr, ptr+count, dim_test(dimension) );
+ #else
+ std::count_if( ptr, ptr+count, dim_test(dimension), result );
+ #endif
+ }
+ else {
+ result = 0;
+ size_t idx = std::lower_bound( ptr, ptr+count, FIRST_OF_DIM(dimension) ) - ptr;
+ if (idx < count && DIM_FROM_HANDLE(ptr[idx]) == dimension) {
+ if (idx % 2) { // only part of first block is of type
+ result += ptr[idx] - FIRST_OF_DIM(dimension) + 1;
+ ++idx;
+ }
+ for (; idx < count; idx += 2) {
+ if (DIM_FROM_HANDLE(ptr[idx+1]) == dimension) // whole block is of type
+ result += ptr[idx+1] - ptr[idx] + 1;
+ else {
+ if (DIM_FROM_HANDLE(ptr[idx]) == dimension) // part of last block is of type
+ result += LAST_OF_DIM(dimension) - ptr[idx] + 1;
+ break;
+ }
+ }
+ }
+ }
+
+ return result;
}
-inline MBErrorCode MBMeshSet_Vector::get_entities_by_type(MBEntityType type,
- std::vector<MBEntityHandle>& entity_list) const
+inline MBErrorCode MBMeshSet::get_non_set_entities( MBRange& range ) const
{
- std::remove_copy_if( mVector.begin(), mVector.end(),
- std::back_inserter( entity_list ),
- not_type_test(type) );
+ size_t count;
+ const MBEntityHandle* ptr = get_contents( count );
+ if (vector_based()) {
+ std::remove_copy_if( ptr, ptr+count,
+ mb_range_inserter( range ),
+ type_test(MBENTITYSET) );
+ }
+ else {
+ MBRange::iterator in = range.begin();
+ for (size_t idx = 0; idx < count; idx += 2) {
+ if (TYPE_FROM_HANDLE(ptr[idx+1]) != MBENTITYSET)
+ in = range.insert( ptr[idx], ptr[idx+1] );
+ else {
+ if (TYPE_FROM_HANDLE(ptr[idx]) != MBENTITYSET)
+ range.insert( ptr[idx], LAST_HANDLE( MBENTITYSET - 1 ) );
+ break;
+ }
+ }
+ }
+
return MB_SUCCESS;
}
-inline MBErrorCode MBMeshSet_Vector::get_entities_by_type(MBEntityType type,
- MBRange& entity_list) const
+inline bool MBMeshSet::contains_entities(const MBEntityHandle *entities,
+ int num_entities,
+ const int op) const
{
- std::vector<MBEntityHandle> tmp_vect;
- get_entities_by_type( type, tmp_vect );
- vector_to_range( tmp_vect, entity_list );
- return MB_SUCCESS;
+ size_t count;
+ const MBEntityHandle* const ptr = get_contents( count );
+ const MBEntityHandle* const end = ptr + count;
+ size_t found_count = 0;
+ if (vector_based()) {
+ for (int i = 0; i < num_entities; ++i)
+ if (std::find( ptr, end, entities[i] ) < end)
+ ++found_count;
+ }
+ else {
+ assert(0 == count % 2);
+ for (int i = 0; i < num_entities; ++i) {
+ const unsigned long idx = std::lower_bound( ptr, end, entities[i] ) - ptr;
+ if (idx < count && (idx%2 != 0 || ptr[idx] == entities[i]))
+ ++found_count;
+ }
+ }
+
+ return found_count >= ((MBInterface::INTERSECT == op) ? (unsigned)num_entities : 1u);
}
-inline MBErrorCode MBMeshSet_Vector::get_entities_by_dimension( int dimension,
- std::vector<MBEntityHandle>& entity_list) const
+
+
+//! subtract/intersect/unite meshset_2 from/with/into meshset_1; modifies meshset_1
+inline MBErrorCode MBMeshSet::subtract(const MBMeshSet *meshset_2,
+ MBEntityHandle my_handle,
+ AEntityFactory* adjacencies)
{
- std::remove_copy_if( mVector.begin(), mVector.end(),
- std::back_inserter( entity_list ),
- not_dim_test(dimension) );
- return MB_SUCCESS;
+ size_t count;
+ const MBEntityHandle* const ptr = meshset_2->get_contents( count );
+ if (meshset_2->vector_based())
+ return remove_entity_vector( ptr, count, my_handle, adjacencies );
+ else
+ return remove_entity_ranges( ptr, count, my_handle, adjacencies );
}
-inline MBErrorCode MBMeshSet_Vector::get_entities_by_dimension( int dimension,
- MBRange& entity_list) const
+inline MBErrorCode MBMeshSet::unite(const MBMeshSet *meshset_2,
+ MBEntityHandle my_handle,
+ AEntityFactory* adjacencies)
{
- std::vector<MBEntityHandle> tmp_vect;
- get_entities_by_dimension( dimension, tmp_vect );
- vector_to_range( tmp_vect, entity_list );
- return MB_SUCCESS;
+ size_t count;
+ const MBEntityHandle* const ptr = meshset_2->get_contents( count );
+ if (meshset_2->vector_based())
+ return insert_entity_vector( ptr, count, my_handle, adjacencies );
+ else
+ return insert_entity_ranges( ptr, count, my_handle, adjacencies );
}
-inline MBErrorCode MBMeshSet_Vector::get_non_set_entities( MBRange& entities ) const
+//! add these entities to this meshset
+inline MBErrorCode MBMeshSet::add_entities(const MBEntityHandle *entity_handles,
+ const int num_entities,
+ MBEntityHandle my_handle,
+ AEntityFactory* adjacencies)
{
- std::vector<MBEntityHandle> tmp_vect;
- std::remove_copy_if( mVector.begin(), mVector.end(),
- std::back_inserter( tmp_vect ),
- type_test(MBENTITYSET) );
- vector_to_range( tmp_vect, entities );
- return MB_SUCCESS;
+ return insert_entity_vector( entity_handles, num_entities, my_handle, adjacencies );
}
-inline bool MBMeshSet_Vector::contains_entities(MBEntityHandle *entities,
- int num_entities,
- const int op_type) const
+ //! add these entities to this meshset
+inline MBErrorCode MBMeshSet::add_entities(const MBRange &entities,
+ MBEntityHandle my_handle,
+ AEntityFactory* adjacencies)
{
- unsigned int num_in = 0;
- for (int i = 0; i < num_entities; i++) {
- if (std::find(mVector.begin(), mVector.end(), entities[i]) !=
- mVector.end()) num_in++;
- else if (MBInterface::INTERSECT == op_type) break;
- }
-
- return ((MBInterface::INTERSECT == op_type &&
- num_in == (unsigned int) num_entities) ||
- MBInterface::UNION == op_type && 0 < num_in);
+ return insert_entity_ranges( entities, my_handle, adjacencies );
}
-inline unsigned int MBMeshSet_Vector::num_entities() const
+ //! add these entities to this meshset
+inline MBErrorCode MBMeshSet::remove_entities(const MBRange& entities,
+ MBEntityHandle my_handle,
+ AEntityFactory* adjacencies)
{
- return mVector.size();
+ return remove_entity_ranges( entities, my_handle, adjacencies );
}
-inline unsigned int MBMeshSet_Vector::num_entities_by_type(MBEntityType type) const
+
+ //! remove these entities from this meshset
+inline MBErrorCode MBMeshSet::remove_entities(const MBEntityHandle *entities,
+ const int num_entities,
+ MBEntityHandle my_handle,
+ AEntityFactory* adjacencies)
{
-#ifndef __SUNPRO_CC
- return std::count_if( mVector.begin(), mVector.end(), type_test(type) );
-#else
- unsigned int result = 0;
- std::count_if( mVector.begin(), mVector.end(), type_test(type), result );
- return result;
-#endif
+ return remove_entity_vector( entities, num_entities, my_handle, adjacencies );
}
-inline unsigned int MBMeshSet_Vector::num_entities_by_dimension( int dim ) const
+ //! return the number of entities contained in this meshset
+unsigned int MBMeshSet::num_entities() const
{
-#ifndef __SUNPRO_CC
- return std::count_if( mVector.begin(), mVector.end(), dim_test(dim) );
-#else
- unsigned int result = 0;
- std::count_if( mVector.begin(), mVector.end(), dim_test(dim), result );
+ size_t count;
+ const MBEntityHandle* list = get_contents( count );
+ if (vector_based())
+ return count;
+
+ int result = 0;
+ const MBEntityHandle *const end = list + count;
+ for (; list < end; list += 2)
+ result += list[1] - list[0] + 1;
return result;
-#endif
}
-
-
#endif
Modified: MOAB/trunk/Makefile.am
===================================================================
--- MOAB/trunk/Makefile.am 2008-03-31 20:29:26 UTC (rev 1730)
+++ MOAB/trunk/Makefile.am 2008-04-01 15:49:58 UTC (rev 1731)
@@ -31,7 +31,8 @@
file_options_test \
kd_tree_test \
var_len_test var_len_test_no_template \
- tag_test
+ tag_test \
+ mesh_set_test
# merge_test \ # input files no longer exist?
# test_tag_server \ # fails
@@ -290,8 +291,10 @@
seq_man_test_SOURCES = TestUtil.hpp TestTypeSequenceManager.cpp
seq_man_test_LDADD = $(top_builddir)/libMOAB.la
-seq_man_test_CXXFLAGS = -DTEST $(CXXFLAGS)
+mesh_set_test_SOURCES = Test_MBMeshSet.cpp TestUtil.hpp
+mesh_set_test_LDADD = $(top_builddir)/libMOAB.la
+
geom_util_test_SOURCES = TestUtil.hpp GeomUtilTests.cpp
geom_util_test_LDADD = $(top_builddir)/libMOAB.la
geom_util_test_DEPENDENCIES = $(geom_util_test_LDADD)
Modified: MOAB/trunk/MeshSetSequence.hpp
===================================================================
--- MOAB/trunk/MeshSetSequence.hpp 2008-03-31 20:29:26 UTC (rev 1730)
+++ MOAB/trunk/MeshSetSequence.hpp 2008-04-01 15:49:58 UTC (rev 1731)
@@ -106,10 +106,7 @@
SequenceManager* set_sequences,
std::vector<MBMeshSet*>& sets_out );
- enum {
- SET_SIZE = (sizeof(MBMeshSet_MBRange) > sizeof(MBMeshSet_Vector)) ?
- sizeof(MBMeshSet_MBRange) : sizeof(MBMeshSet_Vector)
- };
+ enum { SET_SIZE = sizeof(MBMeshSet) };
inline const unsigned char* array() const
{ return reinterpret_cast<const unsigned char*>(data()->get_sequence_data(0)); }
@@ -119,21 +116,14 @@
inline void allocate_set( unsigned flags, MBEntityID index )
{
- const bool tracking = (0 != (flags&MESHSET_TRACK_OWNER));
unsigned char* const ptr = array() + index * SET_SIZE;
- if (flags & MESHSET_ORDERED)
- new (ptr) MBMeshSet_Vector(tracking);
- else
- new (ptr) MBMeshSet_MBRange(tracking);
+ new (ptr) MBMeshSet(flags);
}
inline void deallocate_set( MBEntityID index )
{
MBMeshSet* set = reinterpret_cast<MBMeshSet*>(array() + SET_SIZE * index );
- if (set->vector_based())
- reinterpret_cast<MBMeshSet_Vector*>(set)->~MBMeshSet_Vector();
- else
- reinterpret_cast<MBMeshSet_MBRange*>(set)->~MBMeshSet_MBRange();
+ set->~MBMeshSet();
}
};
Added: MOAB/trunk/Test_MBMeshSet.cpp
===================================================================
--- MOAB/trunk/Test_MBMeshSet.cpp (rev 0)
+++ MOAB/trunk/Test_MBMeshSet.cpp 2008-04-01 15:49:58 UTC (rev 1731)
@@ -0,0 +1,1099 @@
+#include "MBMeshSet.hpp"
+#include "AEntityFactory.hpp"
+#include "TestUtil.hpp"
+#include "MBCore.hpp"
+
+#include <iostream>
+
+//! test add_entities, get_entities, num_entities
+void test_add_entities( unsigned flags );
+//! test remove_entities, get_entities, num_entities
+void test_remove_entities( unsigned flags );
+//! test get_entities_by_type, num_entities_by_type
+void test_entities_by_type( unsigned flags );
+//! test get_entities_by_dimension, num_entities_by_dimension
+void test_entities_by_dimension( unsigned flags );
+//! test subtract_meshset
+void test_subtract( unsigned flags1, unsigned flags2 );
+//! test intersect_meshset
+void test_intersect( unsigned flags1, unsigned flags2 );
+//! test unite_meshset
+void test_unite( unsigned flags1, unsigned flags2 );
+//! test MBMeshSet::contains_entities
+void test_contains_entities( unsigned flags );
+//! test clear_meshset
+void test_clear( unsigned flags );
+
+//! Create 10x10x10 hex mesh
+void make_mesh( MBInterface& iface );
+//! Create 10x10x10 hex mesh, return ranges of handles
+void make_mesh( MBInterface& iface, MBEntityHandle& vstart, MBEntityHandle& vend, MBEntityHandle& hstart, MBEntityHandle& hend );
+//! Print std::vector<MBEntityHandle>
+void print_handle_vect( const char* prefix, const std::vector<MBEntityHandle>& vect );
+//! Print MBRange
+void print_mbrange( const char* prefix, const MBRange& range );
+//! Compare set contents against passed vector, and if MESHSET_TRACK_OWNER then check adjacencies
+bool check_set_contents( MBCore& mb, MBEntityHandle set, const std::vector<MBEntityHandle>& expected );
+//! Compare result of get_entities_by_type to result of get_entities_by_handle
+bool check_set_contents( MBCore& mb, MBEntityType type, MBEntityHandle set, unsigned flags );
+//! Compare result of get_entities_by_dimension to result of get_entities_by_handle
+bool check_set_contents( MBCore& mb, int dim, MBEntityHandle set, unsigned flags );
+//! For each entry in range, if one or more occurances in vect, remove last occurance from vect.
+void remove_from_back( std::vector<MBEntityHandle>& vect, const MBRange& range );
+enum BoolOp { UNITE, INTERSECT, SUBTRACT };
+//! Perform boolean op on two entity sets and verify result
+bool test_boolean( MBCore& mb, BoolOp op,
+ unsigned flags1, const MBRange& set1_ents,
+ unsigned flags2, const MBRange& set2_ents );
+
+void test_add_entities_ordered() { test_add_entities( MESHSET_ORDERED ); }
+void test_add_entities_set() { test_add_entities( MESHSET_SET ); }
+void test_add_entities_ordered_tracking() { test_add_entities( MESHSET_TRACK_OWNER|MESHSET_ORDERED ); }
+void test_add_entities_set_tracking() { test_add_entities( MESHSET_TRACK_OWNER|MESHSET_SET ); }
+
+void test_remove_entities_ordered() { test_remove_entities( MESHSET_ORDERED ); }
+void test_remove_entities_set() { test_remove_entities( MESHSET_SET ); }
+void test_remove_entities_ordered_tracking() { test_remove_entities( MESHSET_TRACK_OWNER|MESHSET_ORDERED ); }
+void test_remove_entities_set_tracking() { test_remove_entities( MESHSET_TRACK_OWNER|MESHSET_SET ); }
+
+void test_entities_by_type_ordered() { test_entities_by_type ( MESHSET_ORDERED ); }
+void test_entities_by_type_set() { test_entities_by_type ( MESHSET_SET ); }
+void test_entities_by_dim_ordered() { test_entities_by_dimension( MESHSET_ORDERED ); }
+void test_entities_by_dim_set() { test_entities_by_dimension( MESHSET_SET ); }
+
+void test_subtract_set_set() { test_subtract( MESHSET_SET , MESHSET_SET ); }
+void test_subtract_set_ordered() { test_subtract( MESHSET_SET , MESHSET_ORDERED ); }
+void test_subtract_ordered_set() { test_subtract( MESHSET_ORDERED, MESHSET_SET ); }
+void test_subtract_ordered_ordered() { test_subtract( MESHSET_ORDERED, MESHSET_ORDERED ); }
+void test_subtract_set_set_tracking() { test_subtract( MESHSET_TRACK_OWNER|MESHSET_SET , MESHSET_TRACK_OWNER|MESHSET_SET ); }
+void test_subtract_set_ordered_tracking() { test_subtract( MESHSET_TRACK_OWNER|MESHSET_SET , MESHSET_TRACK_OWNER|MESHSET_ORDERED ); }
+void test_subtract_ordered_set_tracking() { test_subtract( MESHSET_TRACK_OWNER|MESHSET_ORDERED, MESHSET_TRACK_OWNER|MESHSET_SET ); }
+void test_subtract_ordered_ordered_tracking() { test_subtract( MESHSET_TRACK_OWNER|MESHSET_ORDERED, MESHSET_TRACK_OWNER|MESHSET_ORDERED ); }
+
+void test_itersect_set_set() { test_intersect( MESHSET_SET , MESHSET_SET ); }
+void test_itersect_set_ordered() { test_intersect( MESHSET_SET , MESHSET_ORDERED ); }
+void test_itersect_ordered_set() { test_intersect( MESHSET_ORDERED, MESHSET_SET ); }
+void test_itersect_ordered_ordered() { test_intersect( MESHSET_ORDERED, MESHSET_ORDERED ); }
+void test_itersect_set_set_tracking() { test_intersect( MESHSET_TRACK_OWNER|MESHSET_SET , MESHSET_TRACK_OWNER|MESHSET_SET ); }
+void test_itersect_set_ordered_tracking() { test_intersect( MESHSET_TRACK_OWNER|MESHSET_SET , MESHSET_TRACK_OWNER|MESHSET_ORDERED ); }
+void test_itersect_ordered_set_tracking() { test_intersect( MESHSET_TRACK_OWNER|MESHSET_ORDERED, MESHSET_TRACK_OWNER|MESHSET_SET ); }
+void test_itersect_ordered_ordered_tracking() { test_intersect( MESHSET_TRACK_OWNER|MESHSET_ORDERED, MESHSET_TRACK_OWNER|MESHSET_ORDERED ); }
+
+void test_unite_set_set() { test_unite( MESHSET_SET , MESHSET_SET ); }
+void test_unite_set_ordered() { test_unite( MESHSET_SET , MESHSET_ORDERED ); }
+void test_unite_ordered_set() { test_unite( MESHSET_ORDERED, MESHSET_SET ); }
+void test_unite_ordered_ordered() { test_unite( MESHSET_ORDERED, MESHSET_ORDERED ); }
+void test_unite_set_set_tracking() { test_unite( MESHSET_TRACK_OWNER|MESHSET_SET , MESHSET_TRACK_OWNER|MESHSET_SET ); }
+void test_unite_set_ordered_tracking() { test_unite( MESHSET_TRACK_OWNER|MESHSET_SET , MESHSET_TRACK_OWNER|MESHSET_ORDERED ); }
+void test_unite_ordered_set_tracking() { test_unite( MESHSET_TRACK_OWNER|MESHSET_ORDERED, MESHSET_TRACK_OWNER|MESHSET_SET ); }
+void test_unite_ordered_ordered_tracking() { test_unite( MESHSET_TRACK_OWNER|MESHSET_ORDERED, MESHSET_TRACK_OWNER|MESHSET_ORDERED ); }
+
+void test_contains_entities_ordered() { test_contains_entities( MESHSET_ORDERED ); }
+void test_contains_entities_set() { test_contains_entities( MESHSET_SET ); }
+
+void test_clear_ordered() { test_clear( MESHSET_ORDERED ); }
+void test_clear_set() { test_clear( MESHSET_SET ); }
+void test_clear_ordered_tracking() { test_clear( MESHSET_TRACK_OWNER|MESHSET_ORDERED ); }
+void test_clear_set_tracking() { test_clear( MESHSET_TRACK_OWNER|MESHSET_SET ); }
+
+int main()
+{
+ int err = 0;
+
+ err += RUN_TEST(test_add_entities_ordered);
+ err += RUN_TEST(test_add_entities_set);
+ err += RUN_TEST(test_add_entities_ordered_tracking);
+ err += RUN_TEST(test_add_entities_set_tracking);
+
+ err += RUN_TEST(test_remove_entities_ordered);
+ err += RUN_TEST(test_remove_entities_set);
+ err += RUN_TEST(test_remove_entities_ordered_tracking);
+ err += RUN_TEST(test_remove_entities_set_tracking);
+
+ err += RUN_TEST(test_entities_by_type_ordered);
+ err += RUN_TEST(test_entities_by_type_set);
+ err += RUN_TEST(test_entities_by_dim_ordered);
+ err += RUN_TEST(test_entities_by_dim_set);
+
+ err += RUN_TEST(test_subtract_set_set);
+ err += RUN_TEST(test_subtract_set_ordered);
+ err += RUN_TEST(test_subtract_ordered_set);
+ err += RUN_TEST(test_subtract_ordered_ordered);
+ err += RUN_TEST(test_subtract_set_set_tracking);
+ err += RUN_TEST(test_subtract_set_ordered_tracking);
+ err += RUN_TEST(test_subtract_ordered_set_tracking);
+ err += RUN_TEST(test_subtract_ordered_ordered_tracking);
+
+ err += RUN_TEST(test_itersect_set_set);
+ err += RUN_TEST(test_itersect_set_ordered);
+ err += RUN_TEST(test_itersect_ordered_set);
+ err += RUN_TEST(test_itersect_ordered_ordered);
+ err += RUN_TEST(test_itersect_set_set_tracking);
+ err += RUN_TEST(test_itersect_set_ordered_tracking);
+ err += RUN_TEST(test_itersect_ordered_set_tracking);
+ err += RUN_TEST(test_itersect_ordered_ordered_tracking);
+
+ err += RUN_TEST(test_unite_set_set);
+ err += RUN_TEST(test_unite_set_ordered);
+ err += RUN_TEST(test_unite_ordered_set);
+ err += RUN_TEST(test_unite_ordered_ordered);
+ err += RUN_TEST(test_unite_set_set_tracking);
+ err += RUN_TEST(test_unite_set_ordered_tracking);
+ err += RUN_TEST(test_unite_ordered_set_tracking);
+ err += RUN_TEST(test_unite_ordered_ordered_tracking);
+
+ err += RUN_TEST(test_contains_entities_ordered);
+ err += RUN_TEST(test_contains_entities_set);
+
+ err += RUN_TEST(test_clear_ordered);
+ err += RUN_TEST(test_clear_set);
+ err += RUN_TEST(test_clear_ordered_tracking);
+ err += RUN_TEST(test_clear_set_tracking);
+
+ if (!err)
+ printf("ALL TESTS PASSED\n");
+ else
+ printf("%d TESTS FAILED\n",err);
+
+ return err;
+}
+
+// Create 100x100x100 hex mesh
+void make_mesh( MBInterface& iface )
+{
+ const int dim = 10;
+
+ // create vertices
+ MBEntityHandle prev_handle = 0;
+ for (int z = 0; z <= dim; ++z) {
+ for (int y = 0; y <= dim; ++y) {
+ for (int x = 0; x <= dim; ++x) {
+ const double coords[] = {x, y, z};
+ MBEntityHandle new_handle = 0;
+ MBErrorCode rval = iface.create_vertex( coords, new_handle );
+ CHECK_ERR(rval);
+ CHECK_EQUAL( ++prev_handle, new_handle );
+ }
+ }
+ }
+
+ // create hexes
+ const int dim1 = dim + 1;
+ const int dimq = dim1 * dim1;
+ prev_handle = FIRST_HANDLE(MBHEX);
+ for (int z = 0; z < dim; ++z) {
+ for (int y = 0; y < dim; ++y) {
+ for (int x = 0; x < dim; ++x) {
+ const MBEntityHandle off = 1 + x + dim1*y + dimq*z;
+ const MBEntityHandle conn[] = { off, off+1, off+1+dim1, off+dim1,
+ off+dimq, off+1+dimq, off+1+dim1+dimq, off+dim1+dimq };
+ MBEntityHandle new_handle = 0;
+ MBErrorCode rval = iface.create_element( MBHEX, conn, 8, new_handle );
+ CHECK_ERR(rval);
+ CHECK_EQUAL( prev_handle++, new_handle );
+ }
+ }
+ }
+
+}
+
+void make_mesh( MBInterface& mb, MBEntityHandle& first_vert, MBEntityHandle& last_vert, MBEntityHandle& first_hex, MBEntityHandle& last_hex )
+{
+ make_mesh( mb );
+
+ // Get handle ranges, and validate assumption that handles
+ // are contiguous.
+ MBRange range;
+ MBErrorCode rval = mb.get_entities_by_type( 0, MBVERTEX, range );
+ CHECK_ERR(rval);
+ first_vert = range.front();
+ last_vert = range.back();
+ CHECK_EQUAL( 1331ul, last_vert - first_vert + 1 );
+ range.clear();
+ rval = mb.get_entities_by_type( 0, MBHEX, range );
+ CHECK_ERR(rval);
+ first_hex = range.front();
+ last_hex = range.back();
+ CHECK_EQUAL( 1000ul, last_hex - first_hex + 1 );
+}
+
+
+template <typename iter_type>
+void print_handles( std::ostream& str, const char* prefix, iter_type begin, iter_type end )
+{
+ if (prefix)
+ str << prefix << ':';
+ if (begin == end) {
+ str << " (empty)" << std::endl;
+ return;
+ }
+
+ iter_type i = begin;
+ MBEntityType prev_type = TYPE_FROM_HANDLE(*i);
+ MBEntityHandle prev_ent = *i;
+ str << ' ' << MBCN::EntityTypeName(prev_type) << ' ' << ID_FROM_HANDLE(*i);
+ for (;;) {
+ iter_type j = i;
+ for (++j, ++prev_ent; j != end && *j == prev_ent; ++j, ++prev_ent);
+ --prev_ent;
+ if (prev_ent - *i > 1)
+ str << "-" << ID_FROM_HANDLE(prev_ent);
+ else if (prev_ent - *i == 1)
+ str << ", " << ID_FROM_HANDLE(prev_ent);
+
+ i = j;
+ if (i == end)
+ break;
+
+ str << ',';
+ if (TYPE_FROM_HANDLE(*i) != prev_type)
+ str << ' ' << MBCN::EntityTypeName(prev_type = TYPE_FROM_HANDLE(*i));
+ str << ' ' << ID_FROM_HANDLE(*i);
+ prev_ent = *i;
+ }
+ str << std::endl;
+}
+
+void print_handle_vect( const char* prefix, const std::vector<MBEntityHandle>& vect )
+{
+ print_handles(std::cout, prefix, vect.begin(), vect.end());
+}
+
+void print_mbrange( const char* prefix, const MBRange& range )
+{
+ print_handles(std::cout, prefix, range.begin(), range.end());
+}
+
+bool compare_set_contents( unsigned flags,
+ const std::vector<MBEntityHandle>& expected,
+ int set_count,
+ std::vector<MBEntityHandle>& vect,
+ const MBRange& range )
+{
+
+ std::vector<MBEntityHandle> sorted( expected );
+ std::sort( sorted.begin(), sorted.end() );
+ sorted.erase( std::unique( sorted.begin(), sorted.end() ), sorted.end() );
+
+ int expected_size = 0;
+ if (flags&MESHSET_ORDERED) {
+ if (expected != vect) {
+ std::cout << "Incorrect set contents from vector-based query" << std::endl;
+ print_handle_vect( "Expected", expected );
+ print_handle_vect( "Actual", vect );
+ return false;
+ }
+ expected_size = expected.size();
+ }
+ else {
+ if (sorted != vect) {
+ std::cout << "Incorrect set contents from vector-based query" << std::endl;
+ print_handle_vect( "Expected", sorted );
+ print_handle_vect( "Actual", vect );
+ return false;
+ }
+ expected_size = sorted.size();
+ }
+
+ if (expected_size != set_count) {
+ std::cout << "Incorrect size for entity set" << std::endl;
+ std::cout << "Expected: " << expected_size << std::endl;
+ std::cout << "Actual: " << set_count << std::endl;
+ return false;
+ }
+
+ vect.clear();
+ vect.resize( range.size() );
+ std::copy( range.begin(), range.end(), vect.begin() );
+ if (sorted != vect) {
+ std::cout << "Incorrect set contents from mbrange-based query" << std::endl;
+ print_handle_vect( "Expected", vect );
+ print_mbrange( "Actual", range );
+ return false;
+ }
+
+ return true;
+}
+
+bool check_set_contents( MBCore& mb, MBEntityHandle set, const std::vector<MBEntityHandle>& expected )
+{
+ unsigned flags;
+ MBErrorCode rval = mb.get_meshset_options( set, flags );
+ CHECK_ERR(rval);
+
+ int count;
+ std::vector<MBEntityHandle> vect;
+ MBRange range;
+ rval = mb.get_entities_by_handle( set, vect, false );
+ CHECK_ERR(rval);
+ rval = mb.get_entities_by_handle( set, range, false );
+ CHECK_ERR(rval);
+ rval = mb.get_number_entities_by_handle( set, count, false );
+ CHECK_ERR(rval);
+
+ if (!compare_set_contents( flags, expected, count, vect, range ))
+ return false;
+
+ if (!(flags&MESHSET_TRACK_OWNER))
+ return true;
+
+ // get all entitites with an adjacency to the set
+ std::vector<MBEntityHandle> adj;
+ MBRange all, adjacent;
+ MBRange::iterator in = adjacent.begin();
+ mb.get_entities_by_handle( 0, all );
+ for (MBRange::iterator i = all.begin(); i != all.end(); ++i) {
+ adj.clear();
+ rval = mb.a_entity_factory()->get_adjacencies( *i, adj );
+ CHECK_ERR(rval);
+ std::vector<MBEntityHandle>::iterator j = std::lower_bound( adj.begin(), adj.end(), set );
+ if (j != adj.end() && *j == set)
+ in = adjacent.insert( in, *i, *i );
+ }
+
+ if (range != adjacent) {
+ std::cout << "Incorrect adjacent entities for tracking set" << std::endl;
+ print_mbrange( "Expected", range );
+ print_mbrange( "Actual", adjacent );
+ return false;
+ }
+
+ return true;
+}
+
+bool check_set_contents( MBCore& mb, MBEntityType type, MBEntityHandle set, unsigned flags )
+{
+ MBErrorCode rval;
+ int count;
+ std::vector<MBEntityHandle> vect, expected;
+ MBRange range;
+
+ rval = mb.get_entities_by_handle( set, expected, false );
+ CHECK_ERR(rval);
+ std::vector<MBEntityHandle>::iterator i = expected.begin();
+ while (i != expected.end()) {
+ if (TYPE_FROM_HANDLE(*i) != type)
+ i = expected.erase( i );
+ else
+ ++i;
+ }
+
+ rval = mb.get_entities_by_type( set, type, range, false );
+ CHECK_ERR(rval);
+ rval = mb.get_number_entities_by_type( set, type, count, false );
+ CHECK_ERR(rval);
+
+ std::copy( range.begin(), range.end(), std::back_inserter(vect) );
+ return compare_set_contents( flags, expected, count, vect, range );
+}
+
+bool check_set_contents( MBCore& mb, int dim, MBEntityHandle set, unsigned flags )
+{
+ MBErrorCode rval;
+ int count;
+ std::vector<MBEntityHandle> vect, expected;
+ MBRange range;
+
+ rval = mb.get_entities_by_handle( set, expected, false );
+ CHECK_ERR(rval);
+ std::vector<MBEntityHandle>::iterator i = expected.begin();
+ while (i != expected.end()) {
+ if (MBCN::Dimension(TYPE_FROM_HANDLE(*i)) != dim)
+ i = expected.erase( i );
+ else
+ ++i;
+ }
+
+ rval = mb.get_entities_by_dimension( set, dim, range, false );
+ CHECK_ERR(rval);
+ rval = mb.get_number_entities_by_dimension( set, dim, count, false );
+ CHECK_ERR(rval);
+
+ std::copy( range.begin(), range.end(), std::back_inserter(vect) );
+ return compare_set_contents( flags, expected, count, vect, range );
+}
+
+void test_add_entities( unsigned flags )
+{
+ MBCore mb; make_mesh( mb );
+
+ MBEntityHandle set;
+ MBErrorCode rval = mb.create_meshset( flags, set );
+ CHECK_ERR(rval);
+
+ std::vector<MBEntityHandle> contents, vect;
+ MBRange range;
+
+ range.clear();
+ range.insert( 11, 20 );
+ std::copy( range.begin(), range.end(), std::back_inserter(contents) );
+ rval = mb.add_entities( set, range );
+ CHECK_ERR(rval);
+ // [11,20]
+ CHECK( check_set_contents( mb, set, contents ) );
+
+ range.clear();
+ range.insert( 31, 40 );
+ std::copy( range.begin(), range.end(), std::back_inserter(contents) );
+ rval = mb.add_entities( set, range );
+ CHECK_ERR(rval);
+ // [11,20],[31,40]
+ CHECK( check_set_contents( mb, set, contents ) );
+
+ range.clear();
+ range.insert( 51, 60 );
+ std::copy( range.begin(), range.end(), std::back_inserter(contents) );
+ rval = mb.add_entities( set, range );
+ CHECK_ERR(rval);
+ // [11,20],[31,40],[51,60]
+ CHECK( check_set_contents( mb, set, contents ) );
+
+ range.clear();
+ range.insert( 71, 80 );
+ std::copy( range.begin(), range.end(), std::back_inserter(contents) );
+ rval = mb.add_entities( set, range );
+ CHECK_ERR(rval);
+ // [11,20],[31,40],[51,60],[71,80]
+ CHECK( check_set_contents( mb, set, contents ) );
+
+ range.clear();
+ range.insert( 91, 100 );
+ std::copy( range.begin(), range.end(), std::back_inserter(contents) );
+ rval = mb.add_entities( set, range );
+ CHECK_ERR(rval);
+ // [11,20],[31,40],[51,60],[71,80],[91,100]
+ CHECK( check_set_contents( mb, set, contents ) );
+
+ range.clear();
+ range.insert( 111, 120 );
+ std::copy( range.begin(), range.end(), std::back_inserter(contents) );
+ rval = mb.add_entities( set, range );
+ CHECK_ERR(rval);
+ // [11,20],[31,40],[51,60],[71,80],[91,100],[111,120]
+ CHECK( check_set_contents( mb, set, contents ) );
+
+ range.clear();
+ range.insert( 6, 12 );
+ std::copy( range.begin(), range.end(), std::back_inserter(contents) );
+ rval = mb.add_entities( set, range );
+ CHECK_ERR(rval);
+ // [6,20],[31,40],[51,60],[71,80],[91,100],[111,120]
+ CHECK( check_set_contents( mb, set, contents ) );
+
+ range.clear();
+ range.insert( 1, 3 );
+ std::copy( range.begin(), range.end(), std::back_inserter(contents) );
+ rval = mb.add_entities( set, range );
+ CHECK_ERR(rval);
+ // [1,3],[6,20],[31,40],[51,60],[71,80],[91,100],[111,120]
+ CHECK( check_set_contents( mb, set, contents ) );
+
+ range.clear();
+ range.insert( 25, 25 );
+ std::copy( range.begin(), range.end(), std::back_inserter(contents) );
+ rval = mb.add_entities( set, range );
+ CHECK_ERR(rval);
+ // [1,3],[6,20],[25,25],[31,40],[51,60],[71,80],[91,100],[111,120]
+ CHECK( check_set_contents( mb, set, contents ) );
+
+ range.clear();
+ range.insert( 30, 30 );
+ std::copy( range.begin(), range.end(), std::back_inserter(contents) );
+ rval = mb.add_entities( set, range );
+ CHECK_ERR(rval);
+ // [1,3],[6,20],[25,25],[30,40],[51,60],[71,80],[91,100],[111,120]
+ CHECK( check_set_contents( mb, set, contents ) );
+
+ range.clear();
+ range.insert( 29, 31 );
+ std::copy( range.begin(), range.end(), std::back_inserter(contents) );
+ rval = mb.add_entities( set, range );
+ CHECK_ERR(rval);
+ // [1,3],[6,20],[25,25],[29,40],[51,60],[71,80],[91,100],[111,120]
+ CHECK( check_set_contents( mb, set, contents ) );
+
+ range.clear();
+ range.insert( 41, 41 );
+ std::copy( range.begin(), range.end(), std::back_inserter(contents) );
+ rval = mb.add_entities( set, range );
+ CHECK_ERR(rval);
+ // [1,3],[6,20],[25,25],[29,41],[51,60],[71,80],[91,100],[111,120]
+ CHECK( check_set_contents( mb, set, contents ) );
+
+ range.clear();
+ range.insert( 41, 45 );
+ std::copy( range.begin(), range.end(), std::back_inserter(contents) );
+ rval = mb.add_entities( set, range );
+ CHECK_ERR(rval);
+ // [1,3],[6,20],[25,25],[29,45],[51,60],[71,80],[91,100],[111,120]
+ CHECK( check_set_contents( mb, set, contents ) );
+
+ range.clear();
+ range.insert( 47, 47 );
+ std::copy( range.begin(), range.end(), std::back_inserter(contents) );
+ rval = mb.add_entities( set, range );
+ CHECK_ERR(rval);
+ // [1,3],[6,20],[25,25],[29,45],[47,47],[51,60],[71,80],[91,100],[111,120]
+ CHECK( check_set_contents( mb, set, contents ) );
+
+ range.clear();
+ range.insert( 51, 80 );
+ std::copy( range.begin(), range.end(), std::back_inserter(contents) );
+ rval = mb.add_entities( set, range );
+ CHECK_ERR(rval);
+ // [1,3],[6,20],[25,25],[29,45],[47,47],[51,80],[91,100],[111,120]
+ CHECK( check_set_contents( mb, set, contents ) );
+
+ range.clear();
+ range.insert( 49, 105 );
+ std::copy( range.begin(), range.end(), std::back_inserter(contents) );
+ rval = mb.add_entities( set, range );
+ CHECK_ERR(rval);
+ // [1,3],[6,20],[25,25],[29,45],[47,47],[49,105],[111,120]
+ CHECK( check_set_contents( mb, set, contents ) );
+
+ vect.clear();
+ for (MBEntityHandle h = 1; h < 100; ++h) {
+ vect.push_back(h);
+ contents.push_back(h);
+ }
+ rval = mb.add_entities( set, &vect[0], vect.size() );
+ CHECK_ERR(rval);
+ // [1,105],[111,120]
+ CHECK( check_set_contents( mb, set, contents ) );
+
+ vect.clear();
+ vect.push_back( 106 );
+ vect.push_back( 108 );
+ vect.push_back( 110 );
+ std::copy( vect.begin(), vect.end(), std::back_inserter(contents) );
+ rval = mb.add_entities( set, &vect[0], vect.size() );
+ CHECK_ERR(rval);
+ // [1,106],[108,108],[110,120]
+ CHECK( check_set_contents( mb, set, contents ) );
+
+ range.clear();
+ range.insert( 107, 200 );
+ std::copy( range.begin(), range.end(), std::back_inserter(contents) );
+ rval = mb.add_entities( set, range );
+ CHECK_ERR(rval);
+ // [1,200]
+ CHECK( check_set_contents( mb, set, contents ) );
+
+ range.clear();
+ range.insert( 1, 1 );
+ range.insert( 5, 6 );
+ range.insert( 199, 200 );
+ range.insert( 201, 202 );
+ std::copy( range.begin(), range.end(), std::back_inserter(contents) );
+ rval = mb.add_entities( set, range );
+ CHECK_ERR(rval);
+ // [1,202]
+ CHECK( check_set_contents( mb, set, contents ) );
+
+ range.clear();
+ range.insert( 300, 301 );
+ std::copy( range.begin(), range.end(), std::back_inserter(contents) );
+ rval = mb.add_entities( set, range );
+ CHECK_ERR(rval);
+ // [1,202],[300,301]
+ CHECK( check_set_contents( mb, set, contents ) );
+
+ range.clear();
+ range.insert( 203,203 );
+ range.insert( 205,205 );
+ range.insert( 207,207 );
+ range.insert( 299,299 );
+ std::copy( range.begin(), range.end(), std::back_inserter(contents) );
+ rval = mb.add_entities( set, range );
+ CHECK_ERR(rval);
+ // [1,203],[205,205],[207,207],[299,301]
+ CHECK( check_set_contents( mb, set, contents ) );
+}
+
+void remove_from_back( std::vector<MBEntityHandle>& vect, const MBRange& range )
+{
+ for (MBRange::const_iterator r = range.begin(); r != range.end(); ++r) {
+ std::vector<MBEntityHandle>::reverse_iterator i = find( vect.rbegin(), vect.rend(), *r );
+ if (i != vect.rend())
+ *i = 0;
+ }
+ std::vector<MBEntityHandle>::iterator j = vect.begin();
+ while (j != vect.end()) {
+ if (*j == 0)
+ j = vect.erase(j);
+ else
+ ++j;
+ }
+}
+
+void test_remove_entities( unsigned flags )
+{
+ MBCore mb; make_mesh( mb );
+
+ MBEntityHandle set;
+ MBErrorCode rval = mb.create_meshset( flags, set );
+ CHECK_ERR(rval);
+
+ std::vector<MBEntityHandle> contents;
+ MBRange range;
+
+ range.clear();
+ range.insert( 1, 1000 );
+ std::copy( range.begin(), range.end(), std::back_inserter(contents) );
+ rval = mb.add_entities( set, range );
+ CHECK_ERR(rval);
+ // [1,1000]
+ CHECK( check_set_contents( mb, set, contents ) );
+
+ range.clear();
+ range.insert( 1, 5 );
+ remove_from_back( contents, range );
+ rval = mb.remove_entities( set, range );
+ CHECK_ERR(rval);
+ // [6,1000]
+ CHECK( check_set_contents( mb, set, contents ) );
+
+ range.clear();
+ range.insert( 6, 6 );
+ remove_from_back( contents, range );
+ rval = mb.remove_entities( set, range );
+ CHECK_ERR(rval);
+ // [7,1000]
+ CHECK( check_set_contents( mb, set, contents ) );
+
+ range.clear();
+ range.insert( 7, 10 );
+ remove_from_back( contents, range );
+ rval = mb.remove_entities( set, range );
+ CHECK_ERR(rval);
+ // [11,1000]
+ CHECK( check_set_contents( mb, set, contents ) );
+
+ range.clear();
+ range.insert( 1, 20 );
+ remove_from_back( contents, range );
+ rval = mb.remove_entities( set, range );
+ CHECK_ERR(rval);
+ // [21,1000]
+ CHECK( check_set_contents( mb, set, contents ) );
+
+ range.clear();
+ range.insert( 1, 5 );
+ remove_from_back( contents, range );
+ rval = mb.remove_entities( set, range );
+ CHECK_ERR(rval);
+ // [21,1000]
+ CHECK( check_set_contents( mb, set, contents ) );
+
+ range.clear();
+ range.insert( 22, 30 );
+ remove_from_back( contents, range );
+ rval = mb.remove_entities( set, range );
+ CHECK_ERR(rval);
+ // [21,21],[31,1000]
+ CHECK( check_set_contents( mb, set, contents ) );
+
+ range.clear();
+ range.insert( 1000, 1000 );
+ remove_from_back( contents, range );
+ rval = mb.remove_entities( set, range );
+ CHECK_ERR(rval);
+ // [21,21],[31,999]
+ CHECK( check_set_contents( mb, set, contents ) );
+
+ range.clear();
+ range.insert( 901, 999 );
+ remove_from_back( contents, range );
+ rval = mb.remove_entities( set, range );
+ CHECK_ERR(rval);
+ // [21,21],[31,900]
+ CHECK( check_set_contents( mb, set, contents ) );
+
+ range.clear();
+ range.insert( 900, 999 );
+ remove_from_back( contents, range );
+ rval = mb.remove_entities( set, range );
+ CHECK_ERR(rval);
+ // [21,21],[31,899]
+ CHECK( check_set_contents( mb, set, contents ) );
+
+ range.clear();
+ range.insert( 1000, 1001 );
+ remove_from_back( contents, range );
+ rval = mb.remove_entities( set, range );
+ CHECK_ERR(rval);
+ // [21,21],[31,899]
+ CHECK( check_set_contents( mb, set, contents ) );
+
+ range.clear();
+ range.insert( 890, 898 );
+ remove_from_back( contents, range );
+ rval = mb.remove_entities( set, range );
+ CHECK_ERR(rval);
+ // [21,21],[31,889],[899,899]
+ CHECK( check_set_contents( mb, set, contents ) );
+
+ range.clear();
+ range.insert( 100, 149 );
+ remove_from_back( contents, range );
+ rval = mb.remove_entities( set, range );
+ CHECK_ERR(rval);
+ // [21,21],[31,99],[150,889],[899,899]
+ CHECK( check_set_contents( mb, set, contents ) );
+
+ range.clear();
+ range.insert( 31, 99 );
+ remove_from_back( contents, range );
+ rval = mb.remove_entities( set, range );
+ CHECK_ERR(rval);
+ // [21,21],[150,889],[899,899]
+ CHECK( check_set_contents( mb, set, contents ) );
+
+ range.clear();
+ range.insert( 200, 249 );
+ remove_from_back( contents, range );
+ rval = mb.remove_entities( set, range );
+ CHECK_ERR(rval);
+ // [21,21],[150,199],[250,889],[899,899]
+ CHECK( check_set_contents( mb, set, contents ) );
+
+ range.clear();
+ range.insert( 300, 349 );
+ remove_from_back( contents, range );
+ rval = mb.remove_entities( set, range );
+ CHECK_ERR(rval);
+ // [21,21],[150,199],[250,299],[350,889],[899,899]
+ CHECK( check_set_contents( mb, set, contents ) );
+
+ range.clear();
+ range.insert( 159, 399 );
+ remove_from_back( contents, range );
+ rval = mb.remove_entities( set, range );
+ CHECK_ERR(rval);
+ // [21,21],[150,158],[400,889],[899,899]
+ CHECK( check_set_contents( mb, set, contents ) );
+
+ range.clear();
+ range.insert( 450, 499 );
+ remove_from_back( contents, range );
+ rval = mb.remove_entities( set, range );
+ CHECK_ERR(rval);
+ // [21,21],[150,158],[400,449],[500,889],[899,899]
+ CHECK( check_set_contents( mb, set, contents ) );
+
+ range.clear();
+ range.insert( 550, 599 );
+ remove_from_back( contents, range );
+ rval = mb.remove_entities( set, range );
+ CHECK_ERR(rval);
+ // [21,21],[150,158],[400,449],[500,549],[600,889],[899,899]
+ CHECK( check_set_contents( mb, set, contents ) );
+
+ range.clear();
+ range.insert( 150, 549 );
+ remove_from_back( contents, range );
+ rval = mb.remove_entities( set, range );
+ CHECK_ERR(rval);
+ // [21,21],[600,889],[899,899]
+ CHECK( check_set_contents( mb, set, contents ) );
+
+ range.clear();
+ range.insert( 650, 699 );
+ remove_from_back( contents, range );
+ rval = mb.remove_entities( set, range );
+ CHECK_ERR(rval);
+ // [21,21],[600,649],[700,889],[899,899]
+ CHECK( check_set_contents( mb, set, contents ) );
+
+
+ // test vector-based remove
+ assert(contents.size() == 242);
+ std::vector<MBEntityHandle> remlist(5);
+ remlist[0] = contents[240]; contents.erase( contents.begin() + 240 );
+ remlist[1] = contents[200]; contents.erase( contents.begin() + 200 );
+ remlist[2] = contents[100]; contents.erase( contents.begin() + 100 );
+ remlist[3] = contents[ 25]; contents.erase( contents.begin() + 25 );
+ remlist[4] = contents[ 0]; contents.erase( contents.begin() + 0 );
+ rval = mb.remove_entities( set, &remlist[0], remlist.size() );
+ CHECK_ERR(rval);
+ // [600,623],[625,649],[700,748],[750,848],[850,888],[899,899]
+ CHECK( check_set_contents( mb, set, contents ) );
+
+ // remove everything
+ std::reverse( contents.begin(), contents.begin() + contents.size()/2 ); // mix up a bit
+ rval = mb.remove_entities( set, &contents[0], contents.size() );
+ CHECK_ERR(rval);
+ contents.clear();
+ CHECK( check_set_contents( mb, set, contents ) );
+
+ // try complicated range-based remove
+ range.clear();
+ contents.clear();
+ range.insert( 100, 200 );
+ std::copy( range.begin(), range.end(), std::back_inserter(contents) );
+ rval = mb.add_entities( set, range );
+ CHECK_ERR(rval);
+ // [1000,2000]
+ CHECK( check_set_contents( mb, set, contents ) );
+
+ MBRange remove;
+ remove.insert( 1, 3 );
+ remove.insert( 10, 100 );
+ remove.insert( 110, 120 );
+ remove.insert( 130, 140 );
+ remove.insert( 150, 160 );
+ remove.insert( 190, 200 );
+ remove.insert( 210, 220 );
+ remove.insert( 230, 240 );
+ range = range.subtract( remove );
+
+ contents.clear();
+ std::copy( range.begin(), range.end(), std::back_inserter(contents) );
+ rval = mb.remove_entities( set, remove );
+ CHECK_ERR(rval);
+ CHECK( check_set_contents( mb, set, contents ) );
+}
+
+void test_entities_by_type( unsigned flags )
+{
+ MBEntityHandle first_vert, last_vert, first_hex, last_hex;
+ MBCore mb; make_mesh( mb, first_vert, last_vert, first_hex, last_hex );
+
+ // Create an entity set
+ MBEntityHandle set;
+ MBErrorCode rval = mb.create_meshset( flags, set );
+ CHECK_ERR(rval);
+
+ // Test empty set
+ CHECK( check_set_contents( mb, MBVERTEX, set, flags ) );
+ CHECK( check_set_contents( mb, MBEDGE , set, flags ) );
+ CHECK( check_set_contents( mb, MBHEX , set, flags ) );
+
+ // Add stuff to set
+ MBRange range;
+ range.insert( first_vert , first_vert + 10 );
+ range.insert( first_vert + 100, first_vert + 110 );
+ range.insert( first_hex + 200, first_hex + 299 );
+ range.insert( last_hex , last_hex - 99 );
+ rval = mb.add_entities( set, range );
+ CHECK_ERR(rval);
+
+ // Test
+ CHECK( check_set_contents( mb, MBVERTEX, set, flags ) );
+ CHECK( check_set_contents( mb, MBEDGE , set, flags ) );
+ CHECK( check_set_contents( mb, MBHEX , set, flags ) );
+}
+
+void test_entities_by_dimension( unsigned flags )
+{
+ MBEntityHandle first_vert, last_vert, first_hex, last_hex;
+ MBCore mb; make_mesh( mb, first_vert, last_vert, first_hex, last_hex );
+
+ // Create an entity set
+ MBEntityHandle set;
+ MBErrorCode rval = mb.create_meshset( flags, set );
+ CHECK_ERR(rval);
+
+ // Test empty set
+ CHECK( check_set_contents( mb, 0, set, flags ) );
+ CHECK( check_set_contents( mb, 1, set, flags ) );
+ CHECK( check_set_contents( mb, 2, set, flags ) );
+ CHECK( check_set_contents( mb, 3, set, flags ) );
+
+ // Add stuff to set
+ MBRange range;
+ range.insert( first_vert , first_vert + 10 );
+ range.insert( first_vert + 100, first_vert + 110 );
+ range.insert( first_hex + 200, first_hex + 299 );
+ range.insert( last_hex , last_hex - 99 );
+ rval = mb.add_entities( set, range );
+ CHECK_ERR(rval);
+
+ // Test
+ CHECK( check_set_contents( mb, 0, set, flags ) );
+ CHECK( check_set_contents( mb, 1, set, flags ) );
+ CHECK( check_set_contents( mb, 2, set, flags ) );
+ CHECK( check_set_contents( mb, 3, set, flags ) );
+}
+
+bool test_boolean( MBCore& mb, BoolOp op,
+ unsigned flags1, const MBRange& set1_ents,
+ unsigned flags2, const MBRange& set2_ents )
+{
+ MBErrorCode rval;
+
+ // make sets
+ MBEntityHandle set1, set2;
+ rval = mb.create_meshset( flags1, set1 );
+ CHECK_ERR(rval);
+ rval = mb.create_meshset( flags2, set2 );
+ CHECK_ERR(rval);
+ rval = mb.add_entities( set1, set1_ents );
+ CHECK_ERR(rval);
+ rval = mb.add_entities( set2, set2_ents );
+ CHECK_ERR(rval);
+
+ MBRange tmp_range;
+ std::vector<MBEntityHandle> expected;
+ rval = MB_INDEX_OUT_OF_RANGE;
+ switch (op) {
+ case UNITE:
+ if (flags1 & MESHSET_SET) {
+ tmp_range = set1_ents;
+ tmp_range.merge( set2_ents );
+ expected.resize( tmp_range.size() );
+ std::copy( tmp_range.begin(), tmp_range.end(), expected.begin() );
+ }
+ else {
+ expected.clear();
+ std::copy( set1_ents.begin(), set1_ents.end(), std::back_inserter(expected) );
+ std::copy( set2_ents.begin(), set2_ents.end(), std::back_inserter(expected) );
+ }
+ rval = mb.unite_meshset( set1, set2 );
+ break;
+ case INTERSECT:
+ tmp_range = set1_ents.intersect( set2_ents );
+ expected.resize(tmp_range.size());
+ std::copy( tmp_range.begin(), tmp_range.end(), expected.begin() );
+ rval = mb.intersect_meshset( set1, set2 );
+ break;
+ case SUBTRACT:
+ tmp_range = set1_ents.subtract( set2_ents );
+ expected.resize(tmp_range.size());
+ std::copy( tmp_range.begin(), tmp_range.end(), expected.begin() );
+ rval = mb.subtract_meshset( set1, set2 );
+ break;
+ }
+ CHECK_ERR(rval);
+
+ return check_set_contents( mb, set1, expected );
+}
+
+
+void test_intersect( unsigned flags1, unsigned flags2 )
+{
+ MBRange empty, set1_ents, set2_ents;
+ MBEntityHandle first_vert, last_vert, first_hex, last_hex;
+ MBCore mb; make_mesh( mb, first_vert, last_vert, first_hex, last_hex );
+
+ // define contents of first set
+ set1_ents.insert( first_vert, first_vert + 10 );
+ set1_ents.insert( first_vert+100, first_vert+199 );
+ set1_ents.insert( first_hex+100, first_hex+200 );
+
+ // define contents of second set
+ set2_ents.insert( first_vert, first_vert );
+ set2_ents.insert( first_vert+10, first_vert+10 );
+ set2_ents.insert( first_vert+90, first_vert+209 );
+ set2_ents.insert( first_hex+50, first_hex+300 );
+
+ // check empty sets
+ CHECK( test_boolean( mb, INTERSECT, flags1, empty, flags2, empty ) );
+ // check intersection with 1 empty
+ CHECK( test_boolean( mb, INTERSECT, flags1, empty, flags2, set2_ents ) );
+ CHECK( test_boolean( mb, INTERSECT, flags1, set1_ents, flags2, empty ) );
+ // check intersection of non-empty sets
+ CHECK( test_boolean( mb, INTERSECT, flags1, set1_ents, flags2, set2_ents ) );
+}
+
+void test_unite( unsigned flags1, unsigned flags2 )
+{
+ MBRange empty, set1_ents, set2_ents;
+ MBEntityHandle first_vert, last_vert, first_hex, last_hex;
+ MBCore mb; make_mesh( mb, first_vert, last_vert, first_hex, last_hex );
+
+ // define contents of first set
+ set1_ents.insert( first_vert, first_vert + 10 );
+ set1_ents.insert( first_vert+100, first_vert+199 );
+ set1_ents.insert( first_hex+100, first_hex+200 );
+
+ // define contents of second set
+ set2_ents.insert( first_vert, first_vert );
+ set2_ents.insert( first_vert+11, first_vert+99 );
+ set2_ents.insert( first_vert+150, first_vert+209 );
+ set2_ents.insert( first_vert+211, first_vert+211 );
+ set2_ents.insert( first_hex+50, first_hex+99 );
+
+ // check empty sets
+ CHECK( test_boolean( mb, UNITE, flags1, empty, flags2, empty ) );
+ // check union with 1 empty
+ CHECK( test_boolean( mb, UNITE, flags1, empty, flags2, set2_ents ) );
+ CHECK( test_boolean( mb, UNITE, flags1, set1_ents, flags2, empty ) );
+ // check union of non-empty sets
+ CHECK( test_boolean( mb, UNITE, flags1, set1_ents, flags2, set2_ents ) );
+}
+
+void test_subtract( unsigned flags1, unsigned flags2 )
+{
+ MBRange empty, set1_ents, set2_ents;
+ MBEntityHandle first_vert, last_vert, first_hex, last_hex;
+ MBCore mb; make_mesh( mb, first_vert, last_vert, first_hex, last_hex );
+
+ // define contents of first set
+ set1_ents.insert( first_vert, first_vert + 10 );
+ set1_ents.insert( first_vert+100, first_vert+199 );
+ set1_ents.insert( first_hex+100, first_hex+200 );
+
+ // define contents of second set
+ set2_ents.insert( first_vert, first_vert );
+ set2_ents.insert( first_vert+9, first_vert+9 );
+ set2_ents.insert( first_vert+11, first_vert+99 );
+ set2_ents.insert( first_vert+150, first_vert+199 );
+ set2_ents.insert( first_hex+50, first_hex+60 );
+ set2_ents.insert( first_hex+90, first_hex+220 );
+
+ // check empty sets
+ CHECK( test_boolean( mb, SUBTRACT, flags1, empty, flags2, empty ) );
+ // check union with 1 empty
+ CHECK( test_boolean( mb, SUBTRACT, flags1, empty, flags2, set2_ents ) );
+ CHECK( test_boolean( mb, SUBTRACT, flags1, set1_ents, flags2, empty ) );
+ // check union of non-empty sets
+ CHECK( test_boolean( mb, SUBTRACT, flags1, set1_ents, flags2, set2_ents ) );
+}
+
+void test_contains_entities( unsigned flags )
+{
+ CHECK( !(flags&MESHSET_TRACK_OWNER) );
+ MBMeshSet set(flags);
+ bool result;
+
+ const MBEntityHandle entities[] = { 1,2,3,6,10,11,25,100 };
+ const int num_ents = sizeof(entities)/sizeof(MBEntityHandle);
+ MBErrorCode rval = set.add_entities( entities, num_ents, 0, 0 );
+ CHECK_ERR(rval);
+
+ result = set.contains_entities( entities, num_ents, MBInterface::UNION );
+ CHECK(result);
+ result = set.contains_entities( entities, num_ents, MBInterface::INTERSECT );
+ CHECK(result);
+
+ result = set.contains_entities( entities, 1, MBInterface::UNION );
+ CHECK(result);
+ result = set.contains_entities( entities, 1, MBInterface::INTERSECT );
+ CHECK(result);
+
+ const MBEntityHandle entities2[] = { 3,4,5 };
+ const int num_ents2 = sizeof(entities2)/sizeof(MBEntityHandle);
+ result = set.contains_entities( entities2, num_ents2, MBInterface::UNION );
+ CHECK(result);
+ result = set.contains_entities( entities2, num_ents2, MBInterface::INTERSECT );
+ CHECK(!result);
+}
+
+void test_clear( unsigned flags )
+{
+ std::vector<MBEntityHandle> contents(4);
+ MBCore mb; make_mesh( mb, contents[0], contents[1], contents[2], contents[3] );
+ MBEntityHandle set;
+ MBErrorCode rval = mb.create_meshset( flags, set );
+ CHECK_ERR(rval);
+ rval = mb.add_entities( set, &contents[0], contents.size() );
+ CHECK_ERR(rval);
+ CHECK( check_set_contents( mb, set, contents ) );
+ rval = mb.clear_meshset( &set, 1 );
+ CHECK_ERR(rval);
+ contents.clear();
+ CHECK( check_set_contents( mb, set, contents ) );
+}
+
More information about the moab-dev
mailing list