[MOAB-dev] r3289 - MOAB/trunk
kraftche at cae.wisc.edu
kraftche at cae.wisc.edu
Thu Nov 5 17:44:53 CST 2009
Author: kraftche
Date: 2009-11-05 17:44:53 -0600 (Thu, 05 Nov 2009)
New Revision: 3289
Modified:
MOAB/trunk/TagServer.cpp
MOAB/trunk/TagTest.cpp
Log:
Fix for Trac ticket #15: if a tag has a default value and that value is
passed to get_entities_by_type_and_tag, the result should be all entities
except those with a value other than the default, not just the entities for
which the value was unnecessarily set to the same as the default.
Modified: MOAB/trunk/TagServer.cpp
===================================================================
--- MOAB/trunk/TagServer.cpp 2009-11-05 22:15:34 UTC (rev 3288)
+++ MOAB/trunk/TagServer.cpp 2009-11-05 23:44:53 UTC (rev 3289)
@@ -44,6 +44,7 @@
#include "MBBits.hpp"
#include "MBInterface.hpp"
#include "SequenceManager.hpp"
+#include "TagCompare.hpp"
using namespace std;
@@ -861,9 +862,26 @@
const TagInfo* info = get_tag_info( tag_handle );
if (!info)
return MB_TAG_NOT_FOUND;
- if (!value_size && info->get_size() != MB_VARIABLE_LENGTH)
+
+ if (!value_size) {
+ if (info->get_size() == MB_VARIABLE_LENGTH)
+ return MB_VARIABLE_DATA_LENGTH;
value_size = info->get_size();
-
+ }
+
+ // If tag value is default value, then we want every entity
+ // in 'range' of the correct type, except those with a different tag value.
+ bool equals_default;
+ if (info->default_value()) {
+ if (PROP_FROM_TAG_HANDLE(tag_handle) == MB_TAG_BIT)
+ equals_default = (*(char*)value == *(char*)info->default_value());
+ else
+ equals_default = !memcmp( value, info->default_value(), info->default_value_size() );
+ }
+ MBRange tmp_ents;
+ if (equals_default)
+ tmp_ents.swap( entities );
+
switch (PROP_FROM_TAG_HANDLE(tag_handle)) {
case MB_TAG_SPARSE:
result = mSparseData->get_entities_with_tag_value(range, id, *info, type, entities, value, value_size);
@@ -880,8 +898,30 @@
break;
}
- return result;
+ if (MB_SUCCESS != result || !equals_default)
+ return result;
+
+ // If tag value is default value, then we want every entity
+ // in 'range' of the correct type, except those with a different tag value.
+ MBRange all_tagged;
+ result = get_entities( range, tag_handle, type, all_tagged );
+ if (MB_SUCCESS != result)
+ return result;
+
+ // get entities with a different tag value
+ entities = subtract( all_tagged, entities );
+ // get everything that does not have a different value
+ entities = subtract( range, entities );
+ // remove entities of the incorrect type, if any
+ std::pair<MBRange::iterator,MBRange::iterator> p = entities.equal_range(type);
+ entities.erase( entities.begin(), p.first );
+ entities.erase( p.second, entities.end() );
+ // merge with entities initially in range
+ entities.merge( tmp_ents );
+
+ return MB_SUCCESS;
+
}
MBErrorCode TagServer::get_entities_with_tag_values( const MBRange &input_range,
Modified: MOAB/trunk/TagTest.cpp
===================================================================
--- MOAB/trunk/TagTest.cpp 2009-11-05 22:15:34 UTC (rev 3288)
+++ MOAB/trunk/TagTest.cpp 2009-11-05 23:44:53 UTC (rev 3289)
@@ -1,6 +1,6 @@
#include "MBCore.hpp"
+#include "MBRange.hpp"
#include "TestUtil.hpp"
-#include "MBRange.hpp"
#include <stdlib.h>
#include <algorithm>
@@ -28,6 +28,7 @@
void test_get_set_variable_length_sparse();
void test_get_set_variable_length_dense();
void test_get_set_variable_length_mesh();
+void test_get_ents_with_default_value();
void regression_one_entity_by_var_tag();
void regression_tag_on_nonexistent_entity();
@@ -60,6 +61,7 @@
failures += RUN_TEST( test_get_set_variable_length_sparse );
failures += RUN_TEST( test_get_set_variable_length_dense );
failures += RUN_TEST( test_get_set_variable_length_mesh );
+ failures += RUN_TEST( test_get_ents_with_default_value );
failures += RUN_TEST( regression_one_entity_by_var_tag );
failures += RUN_TEST( regression_tag_on_nonexistent_entity );
@@ -1585,7 +1587,94 @@
CHECK_EQUAL( values5[4], reinterpret_cast<const int*>(data[0])[4] );
}
+void test_get_ents_with_default_value()
+{
+ MBCore moab;
+ MBInterface &mb = moab;
+ MBErrorCode rval;
+ MBRange result;
+ // create a bunch of vertices
+ std::vector<double> coords(90,0.0);
+ MBRange verts;
+ rval = mb.create_vertices( &coords[0], coords.size()/3, verts );
+ CHECK_ERR( rval );
+ CHECK_EQUAL( coords.size()/3, verts.size() );
+ // create one edge, which we should never get back from
+ // our queries with type == MBVERTEX
+ MBEntityHandle edge, ends[] = { verts.front(), verts.back() };
+ rval = mb.create_element( MBEDGE, ends, 2, edge );
+ CHECK_ERR(rval);
+
+ // split vertices into four groups
+ MBRange sets[4];
+ size_t s = 0;
+ for (MBRange::iterator i = verts.begin(); i != verts.end(); ++i) {
+ sets[s].insert(*i);
+ s = (s+1)%4;
+ }
+
+
+ // create a sparse tag and set some verts to non-default value
+ int default_sparse = 5;
+ MBTag tag_sparse = test_create_tag( mb, "int", sizeof(int), MB_TAG_SPARSE, MB_TYPE_INTEGER, &default_sparse );
+ std::vector<int> sparse_vals(sets[0].size(), -1);
+ rval = mb.tag_set_data( tag_sparse, sets[0], &sparse_vals[0] );
+ CHECK_ERR(rval);
+
+ // get all entities with default value for sparse tag
+ result.clear();
+ const void* ptrs[] = { &default_sparse };
+ rval = mb.get_entities_by_type_and_tag( 0, MBVERTEX, &tag_sparse, ptrs, 1, result );
+ CHECK_ERR(rval);
+ CHECK_EQUAL( subtract(verts, sets[0]), result );
+
+
+ // create a dense tag and set some verts to non-default value
+ double default_dense = -1.0;
+ MBTag tag_dense = test_create_tag( mb, "double", sizeof(double), MB_TAG_DENSE, MB_TYPE_DOUBLE, &default_dense );
+ std::vector<double> dense_vals(sets[1].size(), 3.14159);
+ rval = mb.tag_set_data( tag_dense, sets[1], &dense_vals[0] );
+ CHECK_ERR(rval);
+
+ // get all entities with default value for dense tag
+ result.clear();
+ ptrs[0] = &default_dense;
+ rval = mb.get_entities_by_type_and_tag( 0, MBVERTEX, &tag_dense, ptrs, 1, result );
+ CHECK_ERR(rval);
+ CHECK_EQUAL( subtract(verts, sets[1]), result );
+
+
+ // create a variable-length tag and set some verts to non-default value
+ // SKIP THIS: NO API FOR QUERYING ENTITIES WITH VARIABLE-LENGTH VALUE
+ //int default_vlen[] = { 1, 2, 3 };
+ //MBTag tag_vlen = test_create_var_len_tag( mb, "vlen", MB_TAG_SPARSE, MB_TYPE_INTEGER, default_vlen, sizeof(default_vlen) );
+ //int other_vlen[] = { 4, 5, 6, 7 };
+ //std::vector<const void*> vlen_ptrs( sets[2].size(), other_vlen );
+ //std::vector<int> vlen_sizes( sets[2].size)(), sizeof(other_vlen) );
+ //rval = mb.tag_set_data( tag_vlen, sets[2], &vlen_ptrs[0], &vlen_sizes[0] );
+ //CHECK_ERR(rval);
+
+
+ // check that INTERSECT option works as expected
+ result.clear();
+ result.insert( sets[1].front() );
+ ptrs[0] = &default_sparse;
+ rval = mb.get_entities_by_type_and_tag( 0, MBVERTEX, &tag_sparse, ptrs, 1, result, MBInterface::INTERSECT );
+ CHECK_ERR(rval);
+ CHECK_EQUAL( (size_t)1, result.size() );
+ CHECK_EQUAL( sets[1].front(), result.front() );
+
+
+ // check that UNITE option works as expected
+ result.clear();
+ result.insert( edge );
+ ptrs[0] = &default_sparse;
+ rval = mb.get_entities_by_type_and_tag( 0, MBVERTEX, &tag_sparse, ptrs, 1, result, MBInterface::UNION );
+ CHECK_ERR(rval);
+ CHECK_EQUAL( edge, result.back() );
+}
+
void setup_mesh( MBInterface& mb )
{
MBRange vertex_handles;
More information about the moab-dev
mailing list