[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