[MOAB-dev] r3379 - MOAB/trunk
kraftche at cae.wisc.edu
kraftche at cae.wisc.edu
Fri Nov 20 13:00:50 CST 2009
Author: kraftche
Date: 2009-11-20 13:00:50 -0600 (Fri, 20 Nov 2009)
New Revision: 3379
Modified:
MOAB/trunk/MBBits.cpp
MOAB/trunk/MBBits.hpp
MOAB/trunk/MBInterface.hpp
MOAB/trunk/MBSkinner.cpp
MOAB/trunk/MBTest.cpp
MOAB/trunk/ReadHDF5.cpp
MOAB/trunk/TagServer.cpp
MOAB/trunk/TagServer.hpp
MOAB/trunk/WriteHDF5.cpp
Log:
o Allow get/set of bit tags for multiple entities in one call. Bits are
unpacked such that a byte is returned for each entity, with the tag value
stored in the lower bits (the same as was done for single entities before.)
o Fix inconsistent handling of default value for bits tags. When querying
a bit tag with a default value for some entity for which it was not set,
the previous code could do any of the following: successfully return zero,
successfully return the default value, or return failure, depending on
details of the internal representation.
o Add more tests for bit tag functionality.
o Update a couple places in code that might benefit from querying many
bit tags at once.
o Document behavior of query functions in MBInterface for bit tags and
multiple entities.
Modified: MOAB/trunk/MBBits.cpp
===================================================================
--- MOAB/trunk/MBBits.cpp 2009-11-20 17:58:25 UTC (rev 3378)
+++ MOAB/trunk/MBBits.cpp 2009-11-20 19:00:50 UTC (rev 3379)
@@ -64,7 +64,222 @@
return MB_SUCCESS;
}
+
+MBErrorCode MBBitPage::get_entities_with_value( unsigned char value,
+ int offset,
+ int count,
+ int num_bits_per_flag,
+ MBEntityHandle first,
+ MBRange& results ) const
+{
+ if (mBitArray) {
+ MBRange::iterator hint = results.begin();
+ for (int i = 0; i < count; ++i)
+ if (value == MBBitManipulator::get_bits( (offset+i)*num_bits_per_flag,
+ num_bits_per_flag, mBitArray))
+ hint = results.insert( hint, first + i );
+ }
+ return MB_SUCCESS;
+}
+void MBBitPage::alloc_array( int num_bits_per_flag,
+ const unsigned char* default_value )
+{
+ assert(!mBitArray);
+
+ mBitArray = new unsigned char[mPageSize];
+ // Modifed by J.Kraftcheck : 31 Jan, 2008:
+ // Need to initialize to default value to ensure that we return
+ // the default value for unset entities.
+
+ // Zero memory if no default value. Also, if default value is
+ // zero, we can zero all the memory w/out worring about the
+ // number of bits per entity.
+ if (!default_value || !*default_value)
+ memset(mBitArray, 0, mPageSize);
+ // Otherwise initialize memory using default value
+ else {
+ // Mask unused bits of default value so that we can set
+ // individual bits using bitwise-OR w/out having to worry
+ // about masking unwanted stuff.
+ unsigned char defval = (*default_value) & ((1u << num_bits_per_flag) - 1);
+
+ switch (num_bits_per_flag) {
+ // If number of bits is a power of two (a byte contains a whole
+ // number of tag bit values) then use memset to initialize the memory.
+ // Note fall-through for switch cases: for 1-bit tags we first
+ // copy the lsb into the adjacent bit, then fall through to 2-bit
+ // case, copying last two bits into next two, and so on.
+ case 1: defval |= (defval << 1);
+ case 2: defval |= (defval << 2);
+ case 4: defval |= (defval << 4);
+ case 8: memset( mBitArray, defval, mPageSize );
+ break;
+ // If num_bits_per_flag is not a power of two, then values do
+ // not align with byte boundaries. Need to initialize values
+ // individually.
+ default:
+ memset(mBitArray, 0, mPageSize);
+ // Subtract 1 from mPageSize because last byte is unused, allowing
+ // questionable MBBitManipulator code to read/write 1 past end
+ // of array.
+ for (int i = 0; i < 8 * (mPageSize-1); i += num_bits_per_flag)
+ MBBitManipulator::set_bits( i, num_bits_per_flag, defval, mBitArray );
+ }
+ }
+}
+
+
+MBErrorCode MBBitPageGroup::get_bits( MBEntityHandle start,
+ MBEntityID count,
+ unsigned char* bits,
+ const unsigned char* def_val)
+{
+ MBErrorCode result = MB_SUCCESS, tmp_result;
+
+
+ MBEntityID id = ID_FROM_HANDLE(start);
+ MBEntityHandle page = id/mOffsetFactor;
+ MBEntityID offset = id%mOffsetFactor;
+ MBEntityID pcount = mOffsetFactor - offset;
+ while (count) {
+ if (pcount > count)
+ pcount = count;
+
+ if (page >= mBitPagesSize) {
+ memset( bits, def_val ? *def_val : 0, count );
+ break;
+ }
+
+ tmp_result = mBitPages[page]->get_bits( offset, pcount, mBitsPerFlag, bits, def_val);
+ if (MB_SUCCESS != tmp_result) {
+ memset( bits, 0, pcount );
+ result = tmp_result;
+ }
+
+ count -= pcount;
+ bits += pcount;
+ ++page;
+ offset = 0;
+ pcount = mOffsetFactor;
+ }
+
+ return result;
+}
+
+MBErrorCode MBBitPageGroup::set_bits( MBEntityHandle start,
+ MBEntityID count,
+ const unsigned char* bits,
+ const unsigned char* def_val)
+{
+ MBErrorCode result = MB_SUCCESS, tmp_result;
+ MBEntityID id = ID_FROM_HANDLE(start);
+ MBEntityHandle page = id/mOffsetFactor;
+ MBEntityID offset = id%mOffsetFactor;
+ MBEntityID pcount = mOffsetFactor - offset;
+ while (count) {
+ if (pcount > count)
+ pcount = count;
+
+ if (page >= mBitPagesSize) {
+ for(int j = page - mBitPagesSize +1; j--;)
+ mBitPages.push_back(new MBBitPage());
+ mBitPagesSize = mBitPages.size();
+ }
+
+ tmp_result = mBitPages[page]->set_bits( offset, pcount, mBitsPerFlag, bits, def_val);
+ if (MB_SUCCESS != tmp_result) {
+ result = tmp_result;
+ }
+
+ count -= pcount;
+ bits += pcount;
+ ++page;
+ offset = 0;
+ pcount = mOffsetFactor;
+ }
+
+ return result;
+}
+
+
+MBErrorCode MBBitPageGroup::get_entities_with_value( unsigned char value,
+ MBEntityHandle first,
+ MBEntityHandle last,
+ MBRange& results )
+{
+ MBErrorCode rval;
+ assert(last >= first);
+ MBEntityID count = last - first + 1;
+
+ MBEntityID id = ID_FROM_HANDLE(first);
+ MBEntityHandle page = id/mOffsetFactor;
+ MBEntityID offset = id%mOffsetFactor;
+ MBEntityID pcount = mOffsetFactor - offset;
+ while (count && page < mBitPagesSize) {
+ if (pcount > count)
+ pcount = count;
+
+ rval = mBitPages[page]->get_entities_with_value( value, offset, pcount, mBitsPerFlag, first, results );
+ if (MB_SUCCESS != rval)
+ return rval;
+
+ first += pcount;
+ count -= pcount;
+ ++page;
+ offset = 0;
+ pcount = mOffsetFactor;
+ }
+
+ return MB_SUCCESS;
+}
+
+MBErrorCode MBBitServer::set_bits( MBTagId tag_id,
+ const MBRange& handles,
+ const unsigned char* data,
+ const unsigned char* default_val)
+{
+ --tag_id; // First ID is 1.
+ if(tag_id >= mBitPageGroups[0].size() || mBitPageGroups[0][tag_id] == NULL)
+ return MB_TAG_NOT_FOUND;
+
+ MBErrorCode rval;
+ MBRange::const_pair_iterator i;
+ for (i = handles.const_pair_begin(); i != handles.const_pair_end(); ++i) {
+ MBEntityType type = TYPE_FROM_HANDLE(i->first);
+ assert(TYPE_FROM_HANDLE(i->second) == type); // should be true because id of zero is never used
+ MBEntityID count = i->second - i->first + 1;
+ rval = mBitPageGroups[type][tag_id]->set_bits(i->first, count, data, default_val);
+ if (MB_SUCCESS != rval)
+ return rval;
+ data += count;
+ }
+ return MB_SUCCESS;
+}
+
+MBErrorCode MBBitServer::get_bits( MBTagId tag_id,
+ const MBRange& handles,
+ unsigned char* data,
+ const unsigned char* default_val)
+{
+ --tag_id; // First ID is 1.
+ if(tag_id >= mBitPageGroups[0].size() || mBitPageGroups[0][tag_id] == NULL)
+ return MB_TAG_NOT_FOUND;
+
+ MBErrorCode rval;
+ MBRange::const_pair_iterator i;
+ for (i = handles.const_pair_begin(); i != handles.const_pair_end(); ++i) {
+ MBEntityType type = TYPE_FROM_HANDLE(i->first);
+ assert(TYPE_FROM_HANDLE(i->second) == type); // should be true because id of zero is never used
+ MBEntityID count = i->second - i->first + 1;
+ rval = mBitPageGroups[type][tag_id]->get_bits(i->first, count, data, default_val);
+ if (MB_SUCCESS != rval)
+ return rval;
+ data += count;
+ }
+ return MB_SUCCESS;
+}
+
/*! give back a tag id that was used to set and get bits */
MBErrorCode MBBitServer::release_tag_id(MBTagId tag_id)
{
@@ -192,51 +407,50 @@
return result;
}
-MBErrorCode MBBitServer::get_entities_with_tag_value(MBTagId tag_id,
- MBEntityType type,
- MBRange& entities,
- const unsigned char bits)
+MBErrorCode MBBitServer::get_entities_with_tag_value( MBTagId tag_id,
+ MBEntityType type,
+ MBRange& entities,
+ const unsigned char bits)
{
- MBRange possibles;
- MBErrorCode result = get_entities(tag_id, type, possibles);
- if (MB_SUCCESS != result || possibles.empty()) return result;
- MBErrorCode tmp_result;
- unsigned char dum = 0;
- for (MBRange::iterator it = possibles.begin(); it != possibles.end(); it++) {
- tmp_result = get_bits(tag_id, *it, dum);
- if (dum == bits) entities.insert(*it);
- if (tmp_result != MB_SUCCESS) result = tmp_result;
- }
-
- return result;
+ --tag_id; // First ID is 1.
+ if(tag_id >= mBitPageGroups[type].size() || mBitPageGroups[type][tag_id] == NULL)
+ return MB_TAG_NOT_FOUND;
+
+ return mBitPageGroups[type][tag_id]->
+ get_entities_with_value( bits, FIRST_HANDLE(type), LAST_HANDLE(type), entities );
}
-MBErrorCode MBBitServer::get_entities_with_tag_value(const MBRange &range,
- MBTagId tag_id, MBEntityType type,
- MBRange& entities,
- const unsigned char bits)
+MBErrorCode MBBitServer::get_entities_with_tag_value( const MBRange &range,
+ MBTagId tag_id,
+ MBEntityType type,
+ MBRange& entities,
+ const unsigned char bits)
{
- MBRange temp1, temp2;
- MBErrorCode result = get_entities(tag_id, type, temp1);
- if (MB_SUCCESS != result) return result;
- std::set_intersection(range.begin(), range.end(),
- temp1.begin(), temp1.end(), mb_range_inserter(temp2));
- if (temp2.empty()) return result;
-
- unsigned char dum = 0;
- MBErrorCode tmp_result;
- for (MBRange::iterator it = temp2.begin(); it != temp2.end(); it++) {
- tmp_result = get_bits(tag_id, *it, dum);
- if (dum == bits) entities.insert(*it);
- if (tmp_result != MB_SUCCESS) result = tmp_result;
+ --tag_id; // First ID is 1.
+ if(tag_id >= mBitPageGroups[0].size() || mBitPageGroups[0][tag_id] == NULL)
+ return MB_TAG_NOT_FOUND;
+
+ MBErrorCode rval;
+ MBRange::const_pair_iterator i;
+ for (i = range.const_pair_begin(); i != range.const_pair_end(); ++i) {
+ MBEntityType this_type = TYPE_FROM_HANDLE(i->first);
+ assert(TYPE_FROM_HANDLE(i->second) == this_type); // should be true because id of zero is never used
+ if (type < this_type)
+ continue;
+ if (type > this_type)
+ break;
+
+ rval = mBitPageGroups[type][tag_id]->
+ get_entities_with_value( bits, i->first, i->second, entities );
+ if (MB_SUCCESS != rval)
+ return rval;
}
-
- return result;
+ return MB_SUCCESS;
}
MBErrorCode MBBitServer::get_number_entities( const MBTagId tag_id,
- const MBEntityType type,
- int& num_entities)
+ const MBEntityType type,
+ int& num_entities)
{
MBRange dum_range;
MBErrorCode result = get_entities(tag_id, type, dum_range);
Modified: MOAB/trunk/MBBits.hpp
===================================================================
--- MOAB/trunk/MBBits.hpp 2009-11-20 17:58:25 UTC (rev 3378)
+++ MOAB/trunk/MBBits.hpp 2009-11-20 19:00:50 UTC (rev 3379)
@@ -179,12 +179,30 @@
}
//! get the bits from a bit page
- MBErrorCode get_bits(int offset, int num_bits_per_flag, unsigned char& bits);
+ MBErrorCode get_bits(int offset, int num_bits_per_flag, unsigned char& bits,
+ const unsigned char* default_value);
//! set the bits in a bit page
MBErrorCode set_bits(int offset, int num_bits_per_flag, unsigned char bits,
const unsigned char* default_value);
+ //! get the bits from a bit page
+ MBErrorCode get_bits(int offset, int count, int num_bits_per_flag,
+ unsigned char* bits,
+ const unsigned char* default_value);
+
+ //! set the bits in a bit page
+ MBErrorCode set_bits(int offset, int count, int num_bits_per_flag,
+ const unsigned char* bits,
+ const unsigned char* default_value);
+
+ MBErrorCode get_entities_with_value( unsigned char value,
+ int offset,
+ int count,
+ int num_bits_per_flag,
+ MBEntityHandle first,
+ MBRange& results ) const;
+
//! set the bits in a bit page only if space has been allocated
MBErrorCode weak_set_bits(int offset, int num_bits_per_flag, unsigned char bits);
@@ -193,6 +211,8 @@
private:
//! bit array uses lazy allocation
unsigned char* mBitArray;
+
+ void alloc_array( int num_bits_per_flag, const unsigned char* default_value );
//! don't allow copying of these bit pages
MBBitPage(const MBBitPage&)
@@ -217,13 +237,15 @@
takes how many bits to get
return bits
*/
-inline MBErrorCode MBBitPage::get_bits(int offset, int num_bits_per_flag, unsigned char& bits)
+inline MBErrorCode MBBitPage::get_bits(int offset, int num_bits_per_flag,
+ unsigned char& bits,
+ const unsigned char* def_val)
{
// because the default bits are 0x0,
// we'll return that if no memory has been allocated
if(!mBitArray)
{
- bits = 0;
+ bits = def_val ? *def_val : 0;
return MB_SUCCESS;
}
@@ -233,66 +255,64 @@
return MB_SUCCESS;
}
+inline MBErrorCode MBBitPage::get_bits(int offset, int count,
+ int num_bits_per_flag,
+ unsigned char* bits,
+ const unsigned char* def_val)
+{
+ // because the default bits are 0x0,
+ // we'll return that if no memory has been allocated
+ if(!mBitArray)
+ {
+ memset( bits, def_val ? *def_val : 0, count );
+ return MB_SUCCESS;
+ }
+ // get bits using bit manipulator
+ for (int i = 0; i < count; ++i)
+ bits[i] = MBBitManipulator::get_bits(
+ (offset+i)*num_bits_per_flag, num_bits_per_flag, mBitArray);
+
+ return MB_SUCCESS;
+}
+
+
/*! set the bits in a bit page
takes bit offset into the page
takes how many bits to set
takes the bits to set
*/
-inline MBErrorCode MBBitPage::set_bits(int offset,
- int num_bits_per_flag, unsigned char bits,
- const unsigned char* default_value)
+inline MBErrorCode MBBitPage::set_bits( int offset,
+ int num_bits_per_flag,
+ unsigned char bits,
+ const unsigned char* default_value)
{
// if memory hasn't been allocated, allocate it and zero the memory
if(!mBitArray)
- {
- mBitArray = new unsigned char[mPageSize];
- // Modifed by J.Kraftcheck : 31 Jan, 2008:
- // Need to initialize to default value to ensure that we return
- // the default value for unset entities.
-
- // Zero memory if no default value. Also, if default value is
- // zero, we can zero all the memory w/out worring about the
- // number of bits per entity.
- if (!default_value || !*default_value)
- memset(mBitArray, 0, mPageSize);
- // Otherwise initialize memory using default value
- else {
- // Mask unused bits of default value so that we can set
- // individual bits using bitwise-OR w/out having to worry
- // about masking unwanted stuff.
- unsigned char defval = (*default_value) & ((1u << num_bits_per_flag) - 1);
-
- switch (num_bits_per_flag) {
- // If number of bits is a power of two (a byte contains a whole
- // number of tag bit values) then use memset to initialize the memory.
- // Note fall-through for switch cases: for 1-bit tags we first
- // copy the lsb into the adjacent bit, then fall through to 2-bit
- // case, copying last two bits into next two, and so on.
- case 1: defval |= (defval << 1);
- case 2: defval |= (defval << 2);
- case 4: defval |= (defval << 4);
- case 8: memset( mBitArray, defval, mPageSize );
- break;
- // If num_bits_per_flag is not a power of two, then values do
- // not align with byte boundaries. Need to initialize values
- // individually.
- default:
- memset(mBitArray, 0, mPageSize);
- // Subtract 1 from mPageSize because last byte is unused, allowing
- // questionable MBBitManipulator code to read/write 1 past end
- // of array.
- for (int i = 0; i < 8 * (mPageSize-1); i += num_bits_per_flag)
- MBBitManipulator::set_bits( i, num_bits_per_flag, defval, mBitArray );
- }
- }
- }
+ alloc_array( num_bits_per_flag, default_value );
// set the bits using bit manipulator
return MBBitManipulator::set_bits(
offset*num_bits_per_flag, num_bits_per_flag, bits, mBitArray);
}
+inline MBErrorCode MBBitPage::set_bits( int offset, int count,
+ int num_bits_per_flag,
+ const unsigned char* bits,
+ const unsigned char* default_value)
+{
+ // if memory hasn't been allocated, allocate it and zero the memory
+ if(!mBitArray)
+ alloc_array( num_bits_per_flag, default_value );
+ // set the bits using bit manipulator
+ for (int i = 0; i < count; ++i)
+ MBBitManipulator::set_bits( (offset+i)*num_bits_per_flag,
+ num_bits_per_flag,
+ bits[i], mBitArray );
+ return MB_SUCCESS;
+}
+
+
/*! weak set bits only sets bits if memory has been allocated
takes bit offset
takes number of bits to set
@@ -331,16 +351,32 @@
}
//! get bits from bit pages
- MBErrorCode get_bits(MBEntityHandle handle, unsigned char& bits);
+ MBErrorCode get_bits(MBEntityHandle handle, unsigned char& bits,
+ const unsigned char* default_value);
//! set bits in bit pages
MBErrorCode set_bits(MBEntityHandle handle, unsigned char bits,
const unsigned char* default_value);
+ //! get bits from bit pages
+ MBErrorCode get_bits(MBEntityHandle start, MBEntityID count,
+ unsigned char* data,
+ const unsigned char* default_value);
+
+ //! set bits in bit pages
+ MBErrorCode set_bits(MBEntityHandle start, MBEntityID count,
+ const unsigned char* data,
+ const unsigned char* default_value);
+
//! set bits in bit pages only if the bit page allocated memory
MBErrorCode weak_set_bits(MBEntityHandle handle, unsigned char bits);
MBErrorCode get_entities(MBEntityType type, MBRange& entities);
+
+ MBErrorCode get_entities_with_value( unsigned char value,
+ MBEntityHandle first,
+ MBEntityHandle last,
+ MBRange& results );
//! if this page group contains this entity, return true, otherwise false
bool contains(const MBEntityHandle handle) const;
@@ -391,7 +427,9 @@
takes entity handle
return the bits
*/
-inline MBErrorCode MBBitPageGroup::get_bits(MBEntityHandle handle, unsigned char& bits)
+inline MBErrorCode MBBitPageGroup::get_bits(MBEntityHandle handle,
+ unsigned char& bits,
+ const unsigned char* def_val)
{
// strip off the entity type
handle = ID_FROM_HANDLE(handle);
@@ -399,14 +437,14 @@
unsigned int which_page = handle / mOffsetFactor;
// if the page isn't there, just return 0x0
- if(which_page >= mBitPagesSize)
- {
- bits = 0;
- return MB_TAG_NOT_FOUND;
+ if(which_page >= mBitPagesSize) {
+ bits = def_val ? *def_val : 0;
+ return MB_SUCCESS;
}
// return bits from bit page
- return mBitPages[which_page]->get_bits( (handle - ( which_page * mOffsetFactor )), mBitsPerFlag, bits);
+ return mBitPages[which_page]->get_bits( (handle - ( which_page * mOffsetFactor )),
+ mBitsPerFlag, bits, def_val);
}
/*! set the bits in bit pages
@@ -504,11 +542,26 @@
//! release a tag id for reuse
MBErrorCode release_tag_id(MBTagId tag_id);
- //! get the bits associated with an entity handle
- MBErrorCode get_bits(MBTagId tag_id, MBEntityHandle handle, unsigned char& bits);
+ //! get the bits associated with entity handles
+ MBErrorCode get_bits(MBTagId tag_id,
+ const MBEntityHandle* handles,
+ int num_handles,
+ unsigned char* data,
+ const unsigned char* default_value);
+ MBErrorCode get_bits(MBTagId tag_id,
+ const MBRange& handles,
+ unsigned char* data,
+ const unsigned char* default_value);
//! set the bits associated with an entity handle
- MBErrorCode set_bits(MBTagId tag_id, MBEntityHandle handle, unsigned char bits,
+ MBErrorCode set_bits(MBTagId tag_id,
+ const MBEntityHandle* handles,
+ int num_handles,
+ const unsigned char* data,
const unsigned char* default_value);
+ MBErrorCode set_bits(MBTagId tag_id,
+ const MBRange& handles,
+ const unsigned char* data,
+ const unsigned char* default_value);
//! set the bits associated with an entity handle, only if memory has been allocated
MBErrorCode weak_set_bits(MBTagId tag_id, MBEntityHandle handle, unsigned char bits);
@@ -559,28 +612,46 @@
};
/*! get some bits based on a tag id and handle */
-inline MBErrorCode MBBitServer::get_bits(MBTagId tag_id,
- MBEntityHandle handle, unsigned char& bits)
+inline
+MBErrorCode MBBitServer::get_bits( MBTagId tag_id,
+ const MBEntityHandle* handles,
+ int num_handles,
+ unsigned char* data,
+ const unsigned char* default_val)
{
--tag_id; // First ID is 1.
- if(tag_id >= (*mBitPageGroups).size() || (*mBitPageGroups)[tag_id] == NULL)
- return MB_FAILURE;
+ if(tag_id >= mBitPageGroups[0].size() || mBitPageGroups[0][tag_id] == NULL)
+ return MB_TAG_NOT_FOUND;
- return mBitPageGroups[TYPE_FROM_HANDLE(handle)][tag_id]->get_bits(handle, bits);
-
+ MBErrorCode rval;
+ for (int i = 0; i < num_handles; ++i) {
+ rval = mBitPageGroups[TYPE_FROM_HANDLE(handles[i])][tag_id]
+ ->get_bits(handles[i], data[i], default_val);
+ if (MB_SUCCESS != rval)
+ return rval;
+ }
+ return MB_SUCCESS;
}
-/*! set some bits based on a tag id and handle */
-inline MBErrorCode MBBitServer::set_bits( MBTagId tag_id,
- MBEntityHandle handle,
- unsigned char bits,
- const unsigned char* default_value )
+inline
+MBErrorCode MBBitServer::set_bits( MBTagId tag_id,
+ const MBEntityHandle* handles,
+ int num_handles,
+ const unsigned char* data,
+ const unsigned char* default_val)
{
--tag_id; // First ID is 1.
- if(tag_id >= mBitPageGroupsSize || (*mBitPageGroups)[tag_id] == NULL)
- return MB_FAILURE;
+ if(tag_id >= mBitPageGroups[0].size() || mBitPageGroups[0][tag_id] == NULL)
+ return MB_TAG_NOT_FOUND;
- return mBitPageGroups[TYPE_FROM_HANDLE(handle)][tag_id]->set_bits(handle, bits, default_value);
+ MBErrorCode rval;
+ for (int i = 0; i < num_handles; ++i) {
+ rval = mBitPageGroups[TYPE_FROM_HANDLE(handles[i])][tag_id]
+ ->set_bits(handles[i], data[i], default_val);
+ if (MB_SUCCESS != rval)
+ return rval;
+ }
+ return MB_SUCCESS;
}
/*! set some bits based on a tag id and handle only if memory has been allocated*/
Modified: MOAB/trunk/MBInterface.hpp
===================================================================
--- MOAB/trunk/MBInterface.hpp 2009-11-20 17:58:25 UTC (rev 3378)
+++ MOAB/trunk/MBInterface.hpp 2009-11-20 19:00:50 UTC (rev 3379)
@@ -1143,8 +1143,11 @@
//! Get the value of the indicated tag on the specified entities in the specified vector
/** Get the value of the indicated tag on the specified entities; <em>tag_data</em> must contain
- enough space (i.e. tag_size*num_entities bytes or bits) to hold all tag data. MB does <em>not</em>
+ enough space (i.e. tag_size*num_entities bytes) to hold all tag data. MOAB does <em>not</em>
check whether this space is available before writing to it.
+ \note For bit tags, tag_data must contain one byte per entity. For each
+ entity, the corresponding byte will contain the tag bits in the
+ lower bit positions and zero bits in the higher.
\param tag_handle Tag whose values are being queried.
\param entity_handles 1d vector of entity handles whose tag values are being queried
\param num_entities Number of entities in 1d vector of entity handles
@@ -1168,6 +1171,9 @@
//! Set the value of the indicated tag on the specified entities in the specified vector
/** Set the value of the indicated tag on the specified entities; <em>tag_data</em> contains the
values, <em>one value per entity in <em>entity_handles</em></em>.
+ \note For bit tags, tag_data must contain one byte per entity. For each
+ entity, the tag bits will be read from the lower bits of the
+ corresponding byte.
\param tag_handle Tag whose values are being set
\param entity_handles 1d vector of entity handles whose tag values are being set
\param num_entities Number of entities in 1d vector of entity handles
@@ -1192,6 +1198,7 @@
/**\brief Get pointers to tag data
*
* For a tag, get the values for a list of passed entity handles.
+ *\note This function may not be used for bit tags.
*\param tag_handle The tag
*\param entity_handles An array of entity handles for which to retreive tag values.
*\param num_entities The length of the 'entity_handles' array.
@@ -1211,6 +1218,7 @@
/**\brief Get pointers to tag data
*
* For a tag, get the values for a list of passed entity handles.
+ *\note This function may not be used for bit tags.
*\param tag_handle The tag
*\param entity_handles The entity handles for which to retreive tag values.
*\param tag_data An array of 'const void*'. Array is populated (output)
@@ -1227,6 +1235,7 @@
/**\brief Set tag data given an array of pointers to tag values.
*
* For a tag, set the values for a list of passed entity handles.
+ *\note This function may not be used for bit tags.
*\param tag_handle The tag
*\param entity_handles An array of entity handles for which to set tag values.
*\param num_entities The length of the 'entity_handles' array.
@@ -1246,6 +1255,7 @@
/**\brief Set tag data given an array of pointers to tag values.
*
* For a tag, set the values for a list of passed entity handles.
+ *\note This function may not be used for bit tags.
*\param tag_handle The tag
*\param entity_handles The entity handles for which to set tag values.
*\param tag_data An array of 'const void*'. Array is expected to
Modified: MOAB/trunk/MBSkinner.cpp
===================================================================
--- MOAB/trunk/MBSkinner.cpp 2009-11-20 17:58:25 UTC (rev 3378)
+++ MOAB/trunk/MBSkinner.cpp 2009-11-20 19:00:50 UTC (rev 3379)
@@ -1031,27 +1031,15 @@
return rval;
// tag all entities in input range
- if (use_bit_tag) {
- bit = '\001';
- for (MBRange::const_iterator it = entities.begin(); it != entities.end(); ++it) {
- rval = thisMB->tag_set_data( tag, &*it, 1, &bit );
- if (MB_SUCCESS != rval) {
- thisMB->tag_delete(tag);
- return rval;
- }
- }
+ size_t count = entities.size();
+ char* vect = new char[count];
+ memset( vect, 1, count );
+ rval = thisMB->tag_set_data( tag, entities, vect );
+ delete [] vect;
+ if (MB_SUCCESS != rval) {
+ thisMB->tag_delete(tag);
+ return rval;
}
- else {
- size_t count = entities.size();
- char* vect = new char[count];
- memset( vect, 1, count );
- rval = thisMB->tag_set_data( tag, entities, vect );
- delete [] vect;
- if (MB_SUCCESS != rval) {
- thisMB->tag_delete(tag);
- return rval;
- }
- }
switch (dim) {
case 1:
@@ -1101,7 +1089,6 @@
std::vector<char> tag_vals;
std::vector<MBEntityHandle> adj;
int count;
- char bit;
for (MBRange::const_iterator it = verts.begin(); it != verts.end(); ++it) {
adj.clear();
rval = thisMB->get_adjacencies( &*it, 1, 1, false, adj );
@@ -1110,21 +1097,10 @@
continue;
// remove those not in the input list
- if (use_bit_tag) {
- count = 0;
- for (i = adj.begin(); i != adj.end(); ++i) {
- rval = thisMB->tag_get_data( tag, &*i, 1, &bit );
- if (MB_SUCCESS != rval) return rval;
- if (bit)
- ++count;
- }
- }
- else {
- tag_vals.resize( adj.size() );
- rval = thisMB->tag_get_data( tag, &adj[0], adj.size(), &tag_vals[0] );
- if (MB_SUCCESS != rval) return rval;
- count = std::count( tag_vals.begin(), tag_vals.end(), '\001' );
- }
+ tag_vals.resize( adj.size() );
+ rval = thisMB->tag_get_data( tag, &adj[0], adj.size(), &tag_vals[0] );
+ if (MB_SUCCESS != rval) return rval;
+ count = std::count( tag_vals.begin(), tag_vals.end(), '\001' );
if (count == 1) {
hint = skin_verts.insert( hint, *it );
@@ -1352,7 +1328,6 @@
std::vector<MBEntityHandle> storage;
const MBEntityHandle *conn;
int len;
- char bit;
bool find_edges = skin_edges || create_edges;
MBEntityHandle face;
@@ -1380,26 +1355,15 @@
// remove those not in the input list
i = j = adj.begin();
- if (use_bit_tag) {
- for (; i != adj.end(); ++i) {
- rval = thisMB->tag_get_data( tag, &*i, 1, &bit );
- if (MB_SUCCESS != rval) return rval;
- if (bit)
- *(j++) = *i;
- }
- adj.erase( j, adj.end() );
- }
- else {
- tag_vals.resize( adj.size() );
- rval = thisMB->tag_get_data( tag, &adj[0], adj.size(), &tag_vals[0] );
- if (MB_SUCCESS != rval) return rval;
-
- i = j = adj.begin();
- for (; i != adj.end(); ++i)
- if (tag_vals[i - adj.begin()])
- *(j++) = *i;
- adj.erase( j, adj.end() );
- }
+ tag_vals.resize( adj.size() );
+ rval = thisMB->tag_get_data( tag, &adj[0], adj.size(), &tag_vals[0] );
+ if (MB_SUCCESS != rval) return rval;
+
+ i = j = adj.begin();
+ for (; i != adj.end(); ++i)
+ if (tag_vals[i - adj.begin()])
+ *(j++) = *i;
+ adj.erase( j, adj.end() );
// For each adjacent face, check the edges adjacent to the current vertex
adj_edges.clear(); // other vertex for adjacent edges
@@ -1521,7 +1485,6 @@
std::vector<MBEntityHandle> storage, storage2;
const MBEntityHandle *conn, *conn2;
int len, len2;
- char bit;
bool find_faces = skin_faces || create_faces;
int clen, side, sense, offset, indices[9];
MBEntityType face_type;
@@ -1552,24 +1515,13 @@
// remove those not in the input list
i = j = adj.begin();
- if (use_bit_tag) {
- for (; i != adj.end(); ++i) {
- rval = thisMB->tag_get_data( tag, &*i, 1, &bit );
- if (MB_SUCCESS != rval) return rval;
- if (bit)
- *(j++) = *i;
- }
- adj.erase( j, adj.end() );
- }
- else {
- tag_vals.resize( adj.size() );
- rval = thisMB->tag_get_data( tag, &adj[0], adj.size(), &tag_vals[0] );
- if (MB_SUCCESS != rval) return rval;
- for (; i != adj.end(); ++i)
- if (tag_vals[i - adj.begin()])
- *(j++) = *i;
- adj.erase( j, adj.end() );
- }
+ tag_vals.resize( adj.size() );
+ rval = thisMB->tag_get_data( tag, &adj[0], adj.size(), &tag_vals[0] );
+ if (MB_SUCCESS != rval) return rval;
+ for (; i != adj.end(); ++i)
+ if (tag_vals[i - adj.begin()])
+ *(j++) = *i;
+ adj.erase( j, adj.end() );
// Build lists of sides of 3D element adjacent to the current vertex
adj_quads.clear(); // store three other vertices for each adjacent quad face
Modified: MOAB/trunk/MBTest.cpp
===================================================================
--- MOAB/trunk/MBTest.cpp 2009-11-20 17:58:25 UTC (rev 3378)
+++ MOAB/trunk/MBTest.cpp 2009-11-20 19:00:50 UTC (rev 3379)
@@ -3420,7 +3420,56 @@
if(bits != ((*iter) & 0x7))
return MB_FAILURE;
}
+
+ // test range-based query for all vertices
+ std::vector<unsigned char> data(entities.size());
+ success = MB->tag_get_data( bit_tag, entities, &data[0] );
+ if (MB_SUCCESS != success) return success;
+ std::vector<unsigned char>::iterator i = data.begin();
+ for (iter = entities.begin(); iter != entities.end(); ++iter, ++i)
+ if (*i != ((*iter) & 0x7))
+ return MB_FAILURE;
+ // test vector-based query for all vertices
+ std::vector<MBEntityHandle> verts(entities.begin(), entities.end());
+ success = MB->tag_get_data( bit_tag, &verts[0], verts.size(), &data[0] );
+ if (MB_SUCCESS != success) return success;
+ i = data.begin();
+ for (iter = entities.begin(); iter != entities.end(); ++iter, ++i)
+ if (*i != ((*iter) & 0x7))
+ return MB_FAILURE;
+
+ // test default value
+ const unsigned char default_bits = '\005'; // 0000 0101
+ MBTag tag2;
+ success = MB->tag_create( "bit with default", 4, MB_TAG_BIT, tag2, &default_bits );
+ if (MB_SUCCESS != success) {
+ cout << "Failed to create bit tag with default value" << std::endl;
+ return success;
+ }
+
+ // set value to zero on a single vertex
+ bits = 0;
+ MBEntityHandle zh = verts[verts.size()/2];
+ success = MB->tag_set_data( tag2, &zh, 1, &bits );
+ if (MB_SUCCESS != success)
+ return success;
+
+ // get tag values for all entities
+ data.clear();
+ data.resize( verts.size(), 0x7A ); // initialize with 0111 1010
+ success = MB->tag_get_data( tag2, entities, &data[0] );
+ if (MB_SUCCESS != success)
+ return success;
+
+ // check values
+ i = data.begin();
+ for (iter = entities.begin(); iter != entities.end(); ++iter, ++i)
+ if (*iter == zh && *i) // the one we set to zero
+ return MB_FAILURE;
+ else if (*iter != zh && *i != default_bits)
+ return MB_FAILURE;
+
return MB_SUCCESS;
}
Modified: MOAB/trunk/ReadHDF5.cpp
===================================================================
--- MOAB/trunk/ReadHDF5.cpp 2009-11-20 17:58:25 UTC (rev 3378)
+++ MOAB/trunk/ReadHDF5.cpp 2009-11-20 19:00:50 UTC (rev 3379)
@@ -3038,18 +3038,8 @@
return error(rval);
}
-/*** FIX ME - need to do one at a time for BIT tags! This is stupid. ***/
- if (mbtype == MB_TYPE_BIT)
- {
- rval = MB_SUCCESS;
- for ( ; MB_SUCCESS == rval && i < j; ++i)
- rval = iFace->tag_set_data( tag_handle, idbuf + i, 1, databuf + i );
- }
- else
- {
- rval = iFace->tag_set_data( tag_handle, idbuf + i, j - i, databuf + i*read_size );
- i = j;
- }
+ rval = iFace->tag_set_data( tag_handle, idbuf + i, j - i, databuf + i*read_size );
+ i = j;
if (MB_SUCCESS != rval)
return error(rval);
} // for(ever)
Modified: MOAB/trunk/TagServer.cpp
===================================================================
--- MOAB/trunk/TagServer.cpp 2009-11-20 17:58:25 UTC (rev 3378)
+++ MOAB/trunk/TagServer.cpp 2009-11-20 19:00:50 UTC (rev 3379)
@@ -223,37 +223,6 @@
}
-//! set the value of a tag
-MBErrorCode TagServer::set_bits(const MBTag tag_handle, const MBEntityHandle entity_handle, unsigned char data )
-{
- if(TYPE_FROM_HANDLE(entity_handle) >= MBMAXTYPE)
- return MB_TYPE_OUT_OF_RANGE;
- const TagInfo* info = get_tag_info( tag_handle );
- if (!info)
- return MB_TAG_NOT_FOUND;
- return mBitServer->set_bits(ID_FROM_TAG_HANDLE(tag_handle), entity_handle, data,
- reinterpret_cast<const unsigned char*>(info->default_value()));
-}
-
-//! get the value of a tag
-MBErrorCode TagServer::get_bits(const MBTag tag_handle, const MBEntityHandle entity_handle, unsigned char& data )
-{
- if(TYPE_FROM_HANDLE(entity_handle) >= MBMAXTYPE)
- return MB_TYPE_OUT_OF_RANGE;
- MBErrorCode rval = mBitServer->get_bits(ID_FROM_TAG_HANDLE(tag_handle), entity_handle, data);
- if (MB_TAG_NOT_FOUND == rval) {
- const TagInfo* info = get_tag_info( tag_handle );
- if (!info)
- return MB_FAILURE;
- if (info->default_value())
- data = *reinterpret_cast<const unsigned char*>(info->default_value());
- else
- data = '\0';
- return MB_SUCCESS;
- }
- return rval;
-}
-
MBErrorCode TagServer::set_mesh_data( const MBTag tag_handle,
const void* data,
int size )
@@ -301,12 +270,14 @@
break;
case MB_TAG_BIT:
- if (num_entities == 1)
- rval = sequenceManager->check_valid_entities( entity_handles, num_entities );
+ if (!(tag_info = get_tag_info( tag_id, tag_type )))
+ rval = MB_TAG_NOT_FOUND;
else
- rval = MB_FAILURE;
+ rval = sequenceManager->check_valid_entities( entity_handles, num_entities );
if (MB_SUCCESS == rval)
- rval = set_bits( tag_handle, *entity_handles, *reinterpret_cast<const unsigned char*>(data) );
+ rval= mBitServer->set_bits( tag_id, entity_handles, num_entities,
+ reinterpret_cast<const unsigned char*>(data),
+ reinterpret_cast<const unsigned char*>(tag_info->default_value()));
break;
default:
@@ -340,12 +311,14 @@
break;
case MB_TAG_BIT:
- if (entity_handles.size() == 1)
- rval = sequenceManager->check_valid_entities( entity_handles );
+ if (!(tag_info = get_tag_info( tag_id, tag_type )))
+ rval = MB_TAG_NOT_FOUND;
else
- rval = MB_FAILURE;
+ rval = sequenceManager->check_valid_entities( entity_handles );
if (MB_SUCCESS == rval)
- rval = set_bits( tag_handle, entity_handles.front(), *reinterpret_cast<const unsigned char*>(data) );
+ rval= mBitServer->set_bits( tag_id, entity_handles,
+ reinterpret_cast<const unsigned char*>(data),
+ reinterpret_cast<const unsigned char*>(tag_info->default_value()));
break;
default:
@@ -386,12 +359,7 @@
break;
case MB_TAG_BIT:
- if (num_entities == 1)
- rval = sequenceManager->check_valid_entities( entity_handles, num_entities );
- else
- rval = MB_FAILURE;
- if (MB_SUCCESS == rval)
- rval = set_bits( tag_handle, *entity_handles, *reinterpret_cast<const unsigned char*>(*data) );
+ rval = MB_FAILURE;
break;
default:
@@ -431,12 +399,7 @@
break;
case MB_TAG_BIT:
- if (entity_handles.size() == 1)
- rval = sequenceManager->check_valid_entities( entity_handles );
- else
- rval = MB_FAILURE;
- if (MB_SUCCESS == rval)
- rval = set_bits( tag_handle, entity_handles.front(), *reinterpret_cast<const unsigned char*>(*data) );
+ rval = MB_FAILURE;
break;
default:
@@ -517,11 +480,9 @@
case MB_TAG_SPARSE:
return mSparseData->get_data( tag_id, entity_handles, num_entities, data, default_val );
case MB_TAG_BIT:
- if (num_entities == 1)
- return get_bits( tag_handle, *entity_handles, *reinterpret_cast<unsigned char*>(data) );
- else
- return MB_FAILURE;
-
+ return mBitServer->get_bits( tag_id, entity_handles, num_entities,
+ reinterpret_cast<unsigned char*>(data),
+ reinterpret_cast<const unsigned char*>(default_val));
default:
return MB_TAG_NOT_FOUND;
}
@@ -543,11 +504,9 @@
case MB_TAG_SPARSE:
return mSparseData->get_data( tag_id, entity_handles, data, default_val );
case MB_TAG_BIT:
- if (entity_handles.size() == 1)
- return get_bits( tag_handle, entity_handles.front(), *reinterpret_cast<unsigned char*>(data) );
- else
- return MB_FAILURE;
-
+ return mBitServer->get_bits( tag_id, entity_handles,
+ reinterpret_cast<unsigned char*>(data),
+ reinterpret_cast<const unsigned char*>(default_val));
default:
return MB_TAG_NOT_FOUND;
}
@@ -572,11 +531,7 @@
case MB_TAG_SPARSE:
return mSparseData->get_data( tag_id, entity_handles, num_entities, data, lengths, default_val, def_val_len );
case MB_TAG_BIT:
- if (num_entities == 1)
- return get_bits( tag_handle, *entity_handles, *reinterpret_cast<unsigned char*>(data) );
- else
- return MB_FAILURE;
-
+ return MB_FAILURE;
default:
return MB_TAG_NOT_FOUND;
}
@@ -600,11 +555,7 @@
case MB_TAG_SPARSE:
return mSparseData->get_data( tag_id, entity_handles, data, lengths, default_val, def_val_len );
case MB_TAG_BIT:
- if (entity_handles.size() == 1)
- return get_bits( tag_handle, entity_handles.front(), *reinterpret_cast<unsigned char*>(data) );
- else
- return MB_FAILURE;
-
+ return MB_FAILURE;
default:
return MB_TAG_NOT_FOUND;
}
Modified: MOAB/trunk/TagServer.hpp
===================================================================
--- MOAB/trunk/TagServer.hpp 2009-11-20 17:58:25 UTC (rev 3378)
+++ MOAB/trunk/TagServer.hpp 2009-11-20 19:00:50 UTC (rev 3379)
@@ -222,13 +222,7 @@
const MBRange& entity_handles,
const void** data,
int* lengths = 0 );
-
- //! set the value of a tag
- MBErrorCode set_bits(const MBTag tag_handle, const MBEntityHandle entity_handle, unsigned char data );
- //! get the value of a tag
- MBErrorCode get_bits(const MBTag tag_handle, const MBEntityHandle entity_handle, unsigned char& data );
-
//! remove global/mesh value of tag
MBErrorCode remove_mesh_data( const MBTag tag_handle );
Modified: MOAB/trunk/WriteHDF5.cpp
===================================================================
--- MOAB/trunk/WriteHDF5.cpp 2009-11-20 17:58:25 UTC (rev 3378)
+++ MOAB/trunk/WriteHDF5.cpp 2009-11-20 19:00:50 UTC (rev 3379)
@@ -1845,20 +1845,7 @@
iter = stop;
assert(range.size() == (unsigned)count);
- /** Fix me - stupid API requires we get these one at a time for BIT tags */
- if (mb_type == MB_TAG_BIT)
- {
- rval = MB_SUCCESS;
- char* buf_iter = tag_buffer;
- for (MBRange::const_iterator it = range.begin();
- MB_SUCCESS == rval && it != range.end();
- ++it, buf_iter += mb_size)
- rval = iFace->tag_get_data( tag_data.tag_id, &*it, 1, buf_iter );
- }
- else
- {
- rval = iFace->tag_get_data( tag_data.tag_id, range, tag_buffer );
- }
+ rval = iFace->tag_get_data( tag_data.tag_id, range, tag_buffer );
if (MB_SUCCESS != rval) {
mhdf_closeData( filePtr, tables[1], &status );
if (value_type && value_type != id_type)
More information about the moab-dev
mailing list