This example creates a 1d row of quad elements, such that all quad and vertex handles are contiguous in the handle space and in the database. Then it shows how to get access to pointers to MOAB-native data for vertex coordinates, quad connectivity, tag storage, and vertex to quad adjacency lists. This allows applications to access this data directly without going through MOAB's API. In cases where the mesh is not changing (or only mesh vertices are moving), this can save significant execution time in applications.
#include <map>
#include <iostream>
#include <cassert>
using namespace std;
int main(
int argc,
char** argv )
{
Interface* mbImpl = new( std::nothrow ) Core;
if( NULL == mbImpl ) return 1;
int nquads = 1000;
opts.
addOpt<
int >( string(
"nquads,n" ), string(
"Number of quads in the mesh (default = 1000" ), &nquads );
Range verts, quads;
rval = mbImpl->get_entities_by_handle( 0, quads );
MB_CHK_SET_ERR( rval,
"Trouble getting all entities" );
verts = quads.subset_by_dimension( 0 );
quads -= verts;
double def_val[3] = { 0.0, 0.0, 0.0 };
int def_val_int = 0;
int count, vpere;
rval = mbImpl->connect_iterate( quads.begin(), quads.end(), conn_ptr, vpere, count );
MB_CHK_SET_ERR( rval,
"Error in connect_iterate" );
assert( count == (int)quads.size() );
double *x_ptr, *y_ptr, *z_ptr;
rval = mbImpl->coords_iterate( verts.begin(), verts.end(), x_ptr, y_ptr, z_ptr, count );
MB_CHK_SET_ERR( rval,
"Error in coords_iterate" );
assert( count == (int)verts.size() );
double *tag1_ptr, *tag2_ptr;
int* tag3_ptr;
rval = mbImpl->tag_iterate( tag1, quads.begin(), quads.end(), count, (
void*&)tag1_ptr );
MB_CHK_SET_ERR( rval,
"Error in tag1_iterate" );
assert( count == (int)quads.size() );
rval = mbImpl->tag_iterate( tag2, quads.begin(), quads.end(), count, (
void*&)tag2_ptr );
MB_CHK_SET_ERR( rval,
"Error in tag2_iterate" );
assert( count == (int)quads.size() );
rval = mbImpl->tag_iterate( tag3, quads.begin(), quads.end(), count, (
void*&)tag3_ptr );
MB_CHK_SET_ERR( rval,
"Error in tag3_iterate" );
assert( count == (int)quads.size() );
const vector< EntityHandle >** adjs_ptr;
rval = mbImpl->adjacencies_iterate( verts.begin(), verts.end(), adjs_ptr, count );
MB_CHK_SET_ERR( rval,
"Error in adjacencies_iterate" );
assert( count == (int)verts.size() );
EntityHandle start_vert = *verts.begin(), start_quad = *quads.begin();
for( int i = 0; i < nquads; i++ )
{
tag1_ptr[3 * i + 0] = tag1_ptr[3 * i + 1] = tag1_ptr[3 * i + 2] = 0.0;
for( int j = 0; j < vpere; j++ )
{
int v_index = conn_ptr[vpere * i + j] - start_vert;
tag1_ptr[3 * i + 0] += x_ptr[v_index];
tag1_ptr[3 * i + 1] += y_ptr[v_index];
tag1_ptr[3 * i + 2] += z_ptr[v_index];
}
tag1_ptr[3 * i + 0] /= vpere;
tag1_ptr[3 * i + 1] /= vpere;
tag1_ptr[3 * i + 2] /= vpere;
}
for( int v = 0; v < count; v++ )
{
const vector< EntityHandle >* avec = *( adjs_ptr + v );
for( vector< EntityHandle >::const_iterator ait = avec->begin(); ait != avec->end(); ++ait )
{
int a_ind = *ait - start_quad;
tag2_ptr[3 * a_ind + 0] += x_ptr[v];
tag2_ptr[3 * a_ind + 1] += y_ptr[v];
tag2_ptr[3 * a_ind + 2] += z_ptr[v];
tag3_ptr[a_ind]++;
}
}
int n_dis = 0;
{
int i = *q_it - start_quad;
for( int j = 0; j < 3; j++ )
tag2_ptr[3 * i + j] /= (double)tag3_ptr[i];
if( tag1_ptr[3 * i] != tag2_ptr[3 * i] || tag1_ptr[3 * i + 1] != tag2_ptr[3 * i + 1] ||
tag1_ptr[3 * i + 2] != tag2_ptr[3 * i + 2] )
{
cout << "Tag1, tag2 disagree for element " << *q_it + i << endl;
n_dis++;
}
}
if( !n_dis ) cout << "All tags agree, success!" << endl;
delete mbImpl;
return 0;
}
{
ReadUtilIface* read_iface;
vector< double* > coords;
rval = read_iface->get_node_coords( 3, 2 * ( nquads + 1 ), 0, start_vert, coords );
MB_CHK_SET_ERR( rval,
"Error in get_node_arrays" );
rval = read_iface->get_element_connect( nquads, 4,
MBQUAD, 0, start_elem, connect );
MB_CHK_SET_ERR( rval,
"Error in get_element_connect" );
for( int i = 0; i < nquads; i++ )
{
coords[0][2 * i] = coords[0][2 * i + 1] = (double)i;
coords[1][2 * i] = 0.0;
coords[1][2 * i + 1] = 1.0;
coords[2][2 * i] = coords[2][2 * i + 1] = (double)0.0;
connect[4 * i + 0] = quad_v;
connect[4 * i + 1] = quad_v + 2;
connect[4 * i + 2] = quad_v + 3;
connect[4 * i + 3] = quad_v + 1;
}
coords[0][2 * nquads] = coords[0][2 * nquads + 1] = (double)nquads;
coords[1][2 * nquads] = 0.0;
coords[1][2 * nquads + 1] = 1.0;
coords[2][2 * nquads] = coords[2][2 * nquads + 1] = (double)0.0;
Range dum_range;
rval = mbImpl->get_adjacencies( &start_vert, 1, 2,
false, dum_range );
MB_CHK_SET_ERR( rval,
"Error in get_adjacencies" );
assert( !dum_range.empty() );
}