Changeset 3289

Show
Ignore:
Timestamp:
11/05/09 17:44:53 (3 weeks ago)
Author:
kraftche
Message:

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.

Location:
MOAB/trunk
Files:
2 modified

Legend:

Unmodified
Added
Removed
  • MOAB/trunk/TagServer.cpp

    r3004 r3289  
    4545#include "MBInterface.hpp" 
    4646#include "SequenceManager.hpp" 
     47#include "TagCompare.hpp" 
    4748 
    4849using namespace std; 
     
    862863  if (!info) 
    863864    return MB_TAG_NOT_FOUND; 
    864   if (!value_size && info->get_size() != MB_VARIABLE_LENGTH) 
     865     
     866  if (!value_size) { 
     867    if (info->get_size() == MB_VARIABLE_LENGTH) 
     868      return MB_VARIABLE_DATA_LENGTH; 
    865869    value_size = info->get_size(); 
    866  
     870  } 
     871   
     872    // If tag value is default value, then we want every entity 
     873    // in 'range' of the correct type, except those with a different tag value. 
     874  bool equals_default; 
     875  if (info->default_value()) { 
     876    if (PROP_FROM_TAG_HANDLE(tag_handle) == MB_TAG_BIT) 
     877      equals_default = (*(char*)value == *(char*)info->default_value()); 
     878    else 
     879      equals_default = !memcmp( value, info->default_value(), info->default_value_size() ); 
     880  } 
     881  MBRange tmp_ents; 
     882  if (equals_default) 
     883    tmp_ents.swap( entities ); 
     884   
    867885  switch (PROP_FROM_TAG_HANDLE(tag_handle)) { 
    868886    case MB_TAG_SPARSE: 
     
    881899  } 
    882900 
    883   return result; 
     901  if (MB_SUCCESS != result || !equals_default) 
     902    return result; 
     903 
     904    // If tag value is default value, then we want every entity 
     905    // in 'range' of the correct type, except those with a different tag value. 
     906   
     907  MBRange all_tagged; 
     908  result = get_entities( range, tag_handle, type, all_tagged ); 
     909  if (MB_SUCCESS != result)  
     910    return result; 
     911   
     912    // get entities with a different tag value 
     913  entities = subtract( all_tagged, entities ); 
     914    // get everything that does not have a different value 
     915  entities = subtract( range, entities ); 
     916    // remove entities of the incorrect type, if any 
     917  std::pair<MBRange::iterator,MBRange::iterator> p = entities.equal_range(type); 
     918  entities.erase( entities.begin(), p.first ); 
     919  entities.erase( p.second, entities.end() ); 
     920    // merge with entities initially in range 
     921  entities.merge( tmp_ents ); 
     922     
     923  return MB_SUCCESS; 
    884924   
    885925} 
  • MOAB/trunk/TagTest.cpp

    r3004 r3289  
    11#include "MBCore.hpp" 
     2#include "MBRange.hpp" 
    23#include "TestUtil.hpp" 
    3 #include "MBRange.hpp" 
    44#include <stdlib.h> 
    55#include <algorithm> 
     
    2929void test_get_set_variable_length_dense(); 
    3030void test_get_set_variable_length_mesh(); 
     31void test_get_ents_with_default_value(); 
    3132 
    3233void regression_one_entity_by_var_tag(); 
     
    6162  failures += RUN_TEST( test_get_set_variable_length_dense ); 
    6263  failures += RUN_TEST( test_get_set_variable_length_mesh );   
     64  failures += RUN_TEST( test_get_ents_with_default_value );   
    6365  failures += RUN_TEST( regression_one_entity_by_var_tag ); 
    6466  failures += RUN_TEST( regression_tag_on_nonexistent_entity ); 
     
    15861588} 
    15871589 
     1590void test_get_ents_with_default_value() 
     1591{ 
     1592  MBCore moab; 
     1593  MBInterface &mb = moab; 
     1594  MBErrorCode rval; 
     1595  MBRange result; 
     1596 
     1597    // create a bunch of vertices 
     1598  std::vector<double> coords(90,0.0); 
     1599  MBRange verts; 
     1600  rval = mb.create_vertices( &coords[0], coords.size()/3, verts ); 
     1601  CHECK_ERR( rval ); 
     1602  CHECK_EQUAL( coords.size()/3, verts.size() ); 
     1603    // create one edge, which we should never get back from  
     1604    // our queries with type == MBVERTEX 
     1605  MBEntityHandle edge, ends[] = { verts.front(), verts.back() }; 
     1606  rval = mb.create_element( MBEDGE, ends, 2, edge ); 
     1607  CHECK_ERR(rval); 
     1608   
     1609    // split vertices into four groups 
     1610  MBRange sets[4]; 
     1611  size_t s = 0; 
     1612  for (MBRange::iterator i = verts.begin(); i != verts.end(); ++i) { 
     1613    sets[s].insert(*i); 
     1614    s = (s+1)%4; 
     1615  } 
     1616 
     1617 
     1618    // create a sparse tag and set some verts to non-default value 
     1619  int default_sparse = 5; 
     1620  MBTag tag_sparse = test_create_tag( mb, "int", sizeof(int), MB_TAG_SPARSE, MB_TYPE_INTEGER, &default_sparse ); 
     1621  std::vector<int> sparse_vals(sets[0].size(), -1); 
     1622  rval = mb.tag_set_data( tag_sparse, sets[0], &sparse_vals[0] ); 
     1623  CHECK_ERR(rval); 
     1624   
     1625    // get all entities with default value for sparse tag 
     1626  result.clear(); 
     1627  const void* ptrs[] = { &default_sparse }; 
     1628  rval = mb.get_entities_by_type_and_tag( 0, MBVERTEX, &tag_sparse, ptrs, 1, result ); 
     1629  CHECK_ERR(rval); 
     1630  CHECK_EQUAL( subtract(verts, sets[0]), result ); 
     1631 
     1632 
     1633    // create a dense tag and set some verts to non-default value 
     1634  double default_dense = -1.0; 
     1635  MBTag tag_dense = test_create_tag( mb, "double", sizeof(double), MB_TAG_DENSE, MB_TYPE_DOUBLE, &default_dense ); 
     1636  std::vector<double> dense_vals(sets[1].size(), 3.14159); 
     1637  rval = mb.tag_set_data( tag_dense, sets[1], &dense_vals[0] ); 
     1638  CHECK_ERR(rval); 
     1639   
     1640    // get all entities with default value for dense tag 
     1641  result.clear(); 
     1642  ptrs[0] = &default_dense; 
     1643  rval = mb.get_entities_by_type_and_tag( 0, MBVERTEX, &tag_dense, ptrs, 1, result ); 
     1644  CHECK_ERR(rval); 
     1645  CHECK_EQUAL( subtract(verts, sets[1]), result ); 
     1646   
     1647   
     1648    // create a variable-length tag and set some verts to non-default value 
     1649  // SKIP THIS: NO API FOR QUERYING ENTITIES WITH VARIABLE-LENGTH VALUE 
     1650  //int default_vlen[] = { 1, 2, 3 }; 
     1651  //MBTag tag_vlen = test_create_var_len_tag( mb, "vlen", MB_TAG_SPARSE, MB_TYPE_INTEGER, default_vlen, sizeof(default_vlen) ); 
     1652  //int other_vlen[] = { 4, 5, 6, 7 }; 
     1653  //std::vector<const void*> vlen_ptrs( sets[2].size(), other_vlen ); 
     1654  //std::vector<int> vlen_sizes( sets[2].size)(), sizeof(other_vlen) ); 
     1655  //rval = mb.tag_set_data( tag_vlen, sets[2], &vlen_ptrs[0], &vlen_sizes[0] ); 
     1656  //CHECK_ERR(rval); 
     1657   
     1658   
     1659    // check that INTERSECT option works as expected 
     1660  result.clear(); 
     1661  result.insert( sets[1].front() ); 
     1662  ptrs[0] = &default_sparse; 
     1663  rval = mb.get_entities_by_type_and_tag( 0, MBVERTEX, &tag_sparse, ptrs, 1, result, MBInterface::INTERSECT ); 
     1664  CHECK_ERR(rval); 
     1665  CHECK_EQUAL( (size_t)1, result.size() ); 
     1666  CHECK_EQUAL( sets[1].front(), result.front() ); 
     1667   
     1668   
     1669    // check that UNITE option works as expected 
     1670  result.clear(); 
     1671  result.insert( edge ); 
     1672  ptrs[0] = &default_sparse; 
     1673  rval = mb.get_entities_by_type_and_tag( 0, MBVERTEX, &tag_sparse, ptrs, 1, result, MBInterface::UNION ); 
     1674  CHECK_ERR(rval); 
     1675  CHECK_EQUAL( edge, result.back() ); 
     1676} 
    15881677 
    15891678void setup_mesh( MBInterface& mb )