MOAB: Mesh Oriented datABase  (version 5.2.1)
MsqIMesh.cpp
Go to the documentation of this file.
00001 /* *****************************************************************
00002     MESQUITE -- The Mesh Quality Improvement Toolkit
00003 
00004     Copyright 2007 Sandia National Laboratories.  Developed at the
00005     University of Wisconsin--Madison under SNL contract number
00006     624796.  The U.S. Government and the University of Wisconsin
00007     retain certain rights to this software.
00008 
00009     This library is free software; you can redistribute it and/or
00010     modify it under the terms of the GNU Lesser General Public
00011     License as published by the Free Software Foundation; either
00012     version 2.1 of the License, or (at your option) any later version.
00013 
00014     This library is distributed in the hope that it will be useful,
00015     but WITHOUT ANY WARRANTY; without even the implied warranty of
00016     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017     Lesser General Public License for more details.
00018 
00019     You should have received a copy of the GNU Lesser General Public License
00020     (lgpl.txt) along with this library; if not, write to the Free Software
00021     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00022 
00023     (2007) kraftche@cae.wisc.edu
00024 
00025   ***************************************************************** */
00026 
00027 /** \file MsqIMesh.cpp
00028  *  \brief
00029  *  \author Jason Kraftcheck
00030  */
00031 
00032 #include "MsqIMesh.hpp"
00033 #include "MsqError.hpp"
00034 #include "MeshInterface.hpp"
00035 #include "MsqDebug.hpp"
00036 #include "MsqVertex.hpp"
00037 #include <assert.h>
00038 #include "MsqIBase.hpp"
00039 #include <algorithm>
00040 
00041 #ifdef IMESH_MAJOR_VERSION
00042 #define IMESH_VERSION_ATLEAST( MAJOR, MINOR ) 1000 * IMESH_MAJOR_VERSION + IMESH_MINOR_VERSION <= 1000 * MAJOR + MINOR
00043 #else
00044 #define IMESH_VERSION_ATLEAST( MAJOR, MINOR ) 0
00045 #endif
00046 
00047 namespace MBMesquite
00048 {
00049 
00050 /*************************************************************************
00051  *                          Mesh Definition
00052  ************************************************************************/
00053 
00054 MsqIMesh::MsqIMesh( iMesh_Instance mesh, iBase_EntitySetHandle meshset, iBase_EntityType type, MsqError& err,
00055                     const iBase_TagHandle* fixed_tag, const iBase_TagHandle* slaved_tag )
00056     : meshInstance( mesh ), inputSetType( iBase_ALL_TYPES ), inputSet( 0 ), byteTag( 0 ), createdByteTag( false ),
00057       geometricDimension( 0 )
00058 {
00059     init_active_mesh( mesh, err, fixed_tag, slaved_tag );MSQ_ERRRTN( err );
00060     set_active_set( meshset, type, err );MSQ_ERRRTN( err );
00061 }
00062 
00063 MsqIMesh::MsqIMesh( iMesh_Instance mesh, iBase_EntityType type, MsqError& err, const iBase_TagHandle* fixed_tag,
00064                     const iBase_TagHandle* slaved_tag )
00065     : meshInstance( mesh ), inputSetType( iBase_ALL_TYPES ), inputSet( 0 ), byteTag( 0 ), createdByteTag( false ),
00066       geometricDimension( 0 )
00067 {
00068     init_active_mesh( mesh, err, fixed_tag, slaved_tag );MSQ_ERRRTN( err );
00069 
00070     int ierr;
00071     iBase_EntitySetHandle root_set;
00072     iMesh_getRootSet( mesh, &root_set, &ierr );
00073     if( ierr != iBase_SUCCESS )
00074     {
00075         MSQ_SETERR( err )( "Invalid iMesh instance.", MsqError::INVALID_STATE );
00076         return;
00077     }
00078     set_active_set( root_set, type, err );MSQ_ERRRTN( err );
00079 }
00080 
00081 MsqIMesh::~MsqIMesh()
00082 {
00083     int ierr;
00084     if( createdByteTag ) iMesh_destroyTag( meshInstance, byteTag, true, &ierr );
00085 }
00086 
00087 iMesh_Instance MsqIMesh::get_imesh_instance() const
00088 {
00089     return meshInstance;
00090 }
00091 
00092 iBase_EntitySetHandle MsqIMesh::get_entity_set() const
00093 {
00094     return inputSet;
00095 }
00096 
00097 iBase_TagValueType MsqIMesh::check_valid_flag_tag( iBase_TagHandle tag, const char* which_flag, MsqError& err )
00098 {
00099     int ierr, size, type;
00100     const int MAX_NAME_LEN = 127;
00101     char name[MAX_NAME_LEN + 1];
00102 
00103     std::fill( name, name + sizeof( name ), '\0' );
00104     iMesh_getTagName( meshInstance, tag, name, &ierr, MAX_NAME_LEN );
00105     name[MAX_NAME_LEN - 1] = '\0';  // make sure strings are null-terminated
00106     if( iBase_SUCCESS != ierr )
00107     {
00108         MSQ_SETERR( err )
00109         ( MsqError::INVALID_ARG, "Invalid tag handle for vertex %s flag", which_flag );
00110         return iBase_ENTITY_HANDLE;
00111     }
00112     iMesh_getTagSizeBytes( meshInstance, tag, &size, &ierr );
00113     if( iBase_SUCCESS != ierr || size != sizeof( int ) )
00114     {
00115         MSQ_SETERR( err )( MsqError::INVALID_STATE, "Tag \"%s\" exists with invalid size", name );
00116         return iBase_ENTITY_HANDLE;
00117     }
00118 
00119     iMesh_getTagType( meshInstance, tag, &type, &ierr );
00120     if( iBase_SUCCESS != ierr || ( type != iBase_INTEGER && type != iBase_BYTES ) )
00121     {
00122         MSQ_SETERR( err )( MsqError::INVALID_STATE, "Tag \"%s\" exists with invalid type", name );
00123         return iBase_ENTITY_HANDLE;
00124     }
00125     return static_cast< iBase_TagValueType >( type );
00126 }
00127 
00128 void MsqIMesh::init_active_mesh( iMesh_Instance /*mesh*/, MsqError& err, const iBase_TagHandle* fixed_tag,
00129                                  const iBase_TagHandle* slaved_tag )
00130 {
00131     int ierr;
00132 
00133     // Initialize topology map
00134 
00135     const size_t mapsize = sizeof( topologyMap ) / sizeof( MBMesquite::EntityTopology );
00136     if( mapsize < iMesh_ALL_TOPOLOGIES )
00137     {
00138         MSQ_SETERR( err )
00139         ( "MsqIMesh needs to be updated for new iMesh element topologies.", MsqError::INTERNAL_ERROR );
00140     }
00141 
00142     for( size_t i = 0; i <= iMesh_ALL_TOPOLOGIES; ++i )
00143         topologyMap[i] = MBMesquite::MIXED;
00144 
00145     topologyMap[iMesh_TRIANGLE]      = MBMesquite::TRIANGLE;
00146     topologyMap[iMesh_QUADRILATERAL] = MBMesquite::QUADRILATERAL;
00147     topologyMap[iMesh_TETRAHEDRON]   = MBMesquite::TETRAHEDRON;
00148     topologyMap[iMesh_HEXAHEDRON]    = MBMesquite::HEXAHEDRON;
00149     topologyMap[iMesh_PRISM]         = MBMesquite::PRISM;
00150     topologyMap[iMesh_PYRAMID]       = MBMesquite::PYRAMID;
00151 
00152     // Check that fixed tag is valid
00153     haveFixedTag = false;
00154     if( fixed_tag )
00155     {
00156         fixedTagType = check_valid_flag_tag( *fixed_tag, "fixed", err );MSQ_ERRRTN( err );
00157         haveFixedTag = true;
00158         fixedTag     = *fixed_tag;
00159     }
00160 
00161     // Check that slaved tag is valid
00162     haveSlavedTag = false;
00163     if( slaved_tag )
00164     {
00165         slavedTagType = check_valid_flag_tag( *slaved_tag, "slaved", err );MSQ_ERRRTN( err );
00166         haveSlavedTag = true;
00167         slavedTag     = *slaved_tag;
00168     }
00169 
00170     // Get/create tag for vertex byte
00171     iMesh_getTagHandle( meshInstance, VERTEX_BYTE_TAG_NAME, &byteTag, &ierr, strlen( VERTEX_BYTE_TAG_NAME ) );
00172     if( iBase_SUCCESS != ierr )
00173     {
00174         iMesh_createTag( meshInstance, VERTEX_BYTE_TAG_NAME, 1, iBase_INTEGER, &byteTag, &ierr,
00175                          strlen( VERTEX_BYTE_TAG_NAME ) );
00176         if( iBase_SUCCESS != ierr )
00177         {
00178             MSQ_SETERR( err )
00179             ( MsqError::INVALID_STATE, "Tag \"%s\" could not be created", VERTEX_BYTE_TAG_NAME );
00180             return;
00181         }
00182         createdByteTag = true;
00183     }
00184     else
00185     {
00186         int size, type;
00187         iMesh_getTagSizeBytes( meshInstance, byteTag, &size, &ierr );
00188         if( iBase_SUCCESS != ierr || size != sizeof( int ) )
00189         {
00190             MSQ_SETERR( err )
00191             ( MsqError::INVALID_STATE, "Tag \"%s\" exists with invalid size", VERTEX_BYTE_TAG_NAME );
00192             return;
00193         }
00194         iMesh_getTagType( meshInstance, byteTag, &type, &ierr );
00195         if( iBase_SUCCESS != ierr || type != iBase_INTEGER )
00196         {
00197             MSQ_SETERR( err )
00198             ( MsqError::INVALID_STATE, "Tag \"%s\" exists with invalid type", VERTEX_BYTE_TAG_NAME );
00199             return;
00200         }
00201     }
00202     iMesh_getGeometricDimension( meshInstance, &geometricDimension, &ierr );
00203     if( iBase_SUCCESS != ierr )
00204     {
00205         MSQ_SETERR( err )( process_itaps_error( ierr ), MsqError::INTERNAL_ERROR );
00206         return;
00207     }
00208 }
00209 
00210 void MsqIMesh::set_fixed_tag( iBase_TagHandle tag, MsqError& err )
00211 {
00212     iBase_TagValueType t = check_valid_flag_tag( tag, "fixed", err );MSQ_ERRRTN( err );
00213     fixedTag     = tag;
00214     fixedTagType = t;
00215     haveFixedTag = true;
00216 }
00217 
00218 void MsqIMesh::clear_fixed_tag()
00219 {
00220     haveFixedTag = false;
00221 }
00222 
00223 const iBase_TagHandle* MsqIMesh::get_fixed_tag() const
00224 {
00225     return haveFixedTag ? &fixedTag : 0;
00226 }
00227 
00228 void MsqIMesh::set_slaved_tag( iBase_TagHandle tag, MsqError& err )
00229 {
00230     iBase_TagValueType t = check_valid_flag_tag( tag, "slaved", err );MSQ_ERRRTN( err );
00231     slavedTag     = tag;
00232     slavedTagType = t;
00233     haveSlavedTag = true;
00234 }
00235 
00236 void MsqIMesh::clear_slaved_tag()
00237 {
00238     haveSlavedTag = false;
00239 }
00240 
00241 const iBase_TagHandle* MsqIMesh::get_slaved_tag() const
00242 {
00243     return haveSlavedTag ? &slavedTag : 0;
00244 }
00245 
00246 void MsqIMesh::set_active_set( iBase_EntitySetHandle elem_set, iBase_EntityType type_in, MsqError& err )
00247 {
00248     inputSetType = type_in;
00249     inputSet     = elem_set;
00250 
00251     // clear vertex byte
00252     std::vector< VertexHandle > verts;
00253     get_all_vertices( verts, err );MSQ_ERRRTN( err );
00254     if( !verts.empty() )
00255     {
00256         std::vector< unsigned char > zeros( verts.size(), 0 );
00257         vertices_set_byte( arrptr( verts ), arrptr( zeros ), verts.size(), err );MSQ_CHKERR( err );
00258     }
00259 }
00260 
00261 // Returns whether this mesh lies in a 2D or 3D coordinate system.
00262 int MsqIMesh::get_geometric_dimension( MBMesquite::MsqError& /*err*/ )
00263 {
00264     return geometricDimension;
00265 }
00266 
00267 //************ Vertex Properties ********************
00268 
00269 void MsqIMesh::get_flag_data( iBase_TagHandle tag, bool have_tag, iBase_TagValueType type,
00270                               const VertexHandle vert_array[], std::vector< bool >& flag_array, size_t num_vtx,
00271                               MsqError& err )
00272 {
00273     if( !num_vtx ) return;
00274 
00275     if( !have_tag )
00276     {
00277         flag_array.clear();
00278         flag_array.resize( num_vtx, false );
00279         return;
00280     }
00281 
00282     flag_array.resize( num_vtx );
00283 
00284     assert( sizeof( VertexHandle ) == sizeof( iBase_EntityHandle ) );
00285     const iBase_EntityHandle* arr = reinterpret_cast< const iBase_EntityHandle* >( vert_array );
00286 
00287     int ierr, alloc = num_vtx, size = 0;
00288     assert( (size_t)alloc == num_vtx );  // size_t can hold larger values than int if 64-bit
00289 
00290     if( type == iBase_INTEGER )
00291     {
00292         std::vector< int > values( num_vtx );
00293         int* ptr = arrptr( values );
00294         iMesh_getIntArrData( meshInstance, arr, num_vtx, tag, &ptr, &alloc, &size, &ierr );
00295         for( int i = 0; i < size; ++i )
00296             flag_array[i] = !!values[i];
00297     }
00298     else if( type == iBase_BYTES )
00299     {
00300         std::vector< char > values( num_vtx );
00301         void* ptr = arrptr( values );
00302         iMesh_getArrData( meshInstance, arr, num_vtx, tag, &ptr, &alloc, &size, &ierr );
00303         for( int i = 0; i < size; ++i )
00304             flag_array[i] = !!values[i];
00305     }
00306     else
00307     {
00308         MSQ_SETERR( err )( "Invalid tag type for vertex flag data", MsqError::INVALID_STATE );
00309         return;
00310     }
00311 
00312     // check if query for tag data failed
00313     if( iBase_SUCCESS != ierr )
00314     {
00315         MSQ_SETERR( err )( process_itaps_error( ierr ), MsqError::INTERNAL_ERROR );
00316         return;
00317     }
00318 
00319     // make sure we got back the requested number of values
00320     assert( static_cast< size_t >( size ) == num_vtx );
00321 }
00322 
00323 // Returns true or false, indicating whether the vertex
00324 // is allowed to be repositioned.  True indicates that the vertex
00325 // is fixed and cannot be moved.  Note that this is a read-only
00326 // property; this flag can't be modified by users of the
00327 // MBMesquite::Mesh interface.
00328 void MsqIMesh::vertices_get_fixed_flag( const VertexHandle vert_array[], std::vector< bool >& bool_array,
00329                                         size_t num_vtx, MsqError& err )
00330 {
00331     get_flag_data( fixedTag, haveFixedTag, fixedTagType, vert_array, bool_array, num_vtx, err );
00332 }
00333 
00334 void MsqIMesh::vertices_get_slaved_flag( const VertexHandle vert_array[], std::vector< bool >& bool_array,
00335                                          size_t num_vtx, MsqError& err )
00336 {
00337     get_flag_data( slavedTag, haveSlavedTag, slavedTagType, vert_array, bool_array, num_vtx, err );
00338 }
00339 
00340 // Get vertex coordinates
00341 void MsqIMesh::vertices_get_coordinates( const MBMesquite::Mesh::VertexHandle vert_array[], MsqVertex* coordinates,
00342                                          size_t num_vtx, MsqError& err )
00343 {
00344     if( !num_vtx ) return;
00345 
00346     std::vector< double > dbl_store( 3 * num_vtx );
00347     double* dbl_array = arrptr( dbl_store );
00348 
00349     int ierr, junk = 3 * num_vtx, junk2;
00350     assert( sizeof( VertexHandle ) == sizeof( iBase_EntityHandle ) );
00351     const iBase_EntityHandle* arr = reinterpret_cast< const iBase_EntityHandle* >( vert_array );
00352     iMesh_getVtxArrCoords( meshInstance, arr, num_vtx, iBase_INTERLEAVED, &dbl_array, &junk, &junk2, &ierr );
00353     if( iBase_SUCCESS != ierr )
00354     {
00355         MSQ_SETERR( err )( process_itaps_error( ierr ), MsqError::INTERNAL_ERROR );
00356         return;
00357     }
00358 
00359     if( geometricDimension == 2 )
00360     {
00361         double* iter = dbl_array;
00362         for( size_t i = 0; i < num_vtx; ++i )
00363         {
00364             coordinates[i].x( *iter );
00365             ++iter;
00366             coordinates[i].y( *iter );
00367             ++iter;
00368             coordinates[i].z( 0 );
00369         }
00370     }
00371     else
00372     {
00373         double* iter = dbl_array;
00374         for( size_t i = 0; i < num_vtx; ++i )
00375         {
00376             coordinates[i].set( iter );
00377             iter += 3;
00378         }
00379     }
00380 }
00381 
00382 void MsqIMesh::vertex_set_coordinates( MBMesquite::Mesh::VertexHandle vertex, const Vector3D& coords, MsqError& err )
00383 {
00384     int ierr;
00385     iBase_EntityHandle bh = static_cast< iBase_EntityHandle >( vertex );
00386     iMesh_setVtxCoord( meshInstance, bh, coords[0], coords[1], coords[2], &ierr );
00387     if( iBase_SUCCESS != ierr ) MSQ_SETERR( err )( process_itaps_error( ierr ), MsqError::INTERNAL_ERROR );
00388 }
00389 
00390 // Each vertex has a byte-sized flag that can be used to store
00391 // flags.  This byte's value is neither set nor used by the mesh
00392 // implementation.  It is intended to be used by Mesquite algorithms.
00393 // Until a vertex's byte has been explicitly set, its value is 0.
00394 void MsqIMesh::vertex_set_byte( MBMesquite::Mesh::VertexHandle vertex, unsigned char byte, MsqError& err )
00395 {
00396     int ierr, value = byte;
00397     iBase_EntityHandle bh = static_cast< iBase_EntityHandle >( vertex );
00398     iMesh_setIntData( meshInstance, bh, byteTag, value, &ierr );
00399     if( iBase_SUCCESS != ierr ) MSQ_SETERR( err )( process_itaps_error( ierr ), MsqError::INTERNAL_ERROR );
00400 }
00401 
00402 void MsqIMesh::vertices_set_byte( const VertexHandle* vert_array, const unsigned char* byte_array, size_t array_size,
00403                                   MsqError& err )
00404 {
00405     if( !array_size ) return;
00406 
00407     std::vector< int > data( array_size );
00408     std::copy( byte_array, byte_array + array_size, data.begin() );
00409     int ierr;
00410     assert( sizeof( VertexHandle ) == sizeof( iBase_EntityHandle ) );
00411     const iBase_EntityHandle* arr = reinterpret_cast< const iBase_EntityHandle* >( vert_array );
00412     iMesh_setIntArrData( meshInstance, arr, array_size, byteTag, arrptr( data ), array_size, &ierr );
00413     if( iBase_SUCCESS != ierr ) MSQ_SETERR( err )( process_itaps_error( ierr ), MsqError::INTERNAL_ERROR );
00414 }
00415 
00416 // Retrieve the byte value for the specified vertex or vertices.
00417 // The byte value is 0 if it has not yet been set via one of the
00418 // *_set_byte() functions.
00419 void MsqIMesh::vertex_get_byte( MBMesquite::Mesh::VertexHandle vertex, unsigned char* byte, MsqError& err )
00420 {
00421     int ierr, value;
00422     iBase_EntityHandle bh = static_cast< iBase_EntityHandle >( vertex );
00423     iMesh_getIntData( meshInstance, bh, byteTag, &value, &ierr );
00424     if( iBase_SUCCESS != ierr ) MSQ_SETERR( err )( process_itaps_error( ierr ), MsqError::INTERNAL_ERROR );
00425     *byte = value;
00426 }
00427 
00428 void MsqIMesh::vertices_get_byte( const VertexHandle* vert_array, unsigned char* byte_array, size_t array_size,
00429                                   MsqError& err )
00430 {
00431     if( !array_size ) return;
00432 
00433     std::vector< int > data( array_size );
00434     int ierr;
00435     int* ptr  = arrptr( data );
00436     int junk1 = data.size(), junk2;
00437     assert( sizeof( VertexHandle ) == sizeof( iBase_EntityHandle ) );
00438     const iBase_EntityHandle* arr = reinterpret_cast< const iBase_EntityHandle* >( vert_array );
00439     iMesh_getIntArrData( meshInstance, arr, array_size, byteTag, &ptr, &junk1, &junk2, &ierr );
00440     if( iBase_SUCCESS != ierr ) MSQ_SETERR( err )( process_itaps_error( ierr ), MsqError::INTERNAL_ERROR );
00441     std::copy( data.begin(), data.end(), byte_array );
00442 }
00443 
00444 //**************** Topology *****************
00445 
00446 void MsqIMesh::get_adjacent_entities( const iBase_EntityHandle* source, size_t num_source, iBase_EntityType target_type,
00447                                       std::vector< EntityHandle >& target, std::vector< size_t >& offsets,
00448                                       MsqError& err )
00449 {
00450     if( num_source == 0 )
00451     {
00452         target.clear();
00453         offsets.clear();
00454         offsets.reserve( 1 );
00455         offsets.push_back( 0 );
00456         return;
00457     }
00458 
00459     int ierr, num_adj = 0, num_offset;
00460 
00461     assert( sizeof( size_t ) >= sizeof( int ) );
00462     offsets.resize( num_source + 1 );
00463     int* ptr2;
00464     bool expand = false;
00465     if( sizeof( size_t ) > sizeof( int ) )
00466     {
00467         ptr2   = (int*)malloc( sizeof( int ) * ( num_source + 1 ) );
00468         expand = true;
00469     }
00470     else
00471     {
00472         // sizeof(int) == sizeof(size_t)
00473         ptr2 = (int*)arrptr( offsets );
00474     }
00475 
00476     assert( sizeof( iBase_EntityHandle ) == sizeof( EntityHandle ) );
00477     bool have_adj = false;
00478     // If passed vector has allocated storage, try to use existing space
00479     if( target.capacity() >= num_source )
00480     {
00481         target.resize( target.capacity() );
00482         int junk1 = target.capacity(), junk3 = offsets.size();
00483         iBase_EntityHandle* ptr = reinterpret_cast< iBase_EntityHandle* >( arrptr( target ) );
00484         iMesh_getEntArrAdj( meshInstance, source, num_source, target_type, &ptr, &junk1, &num_adj, &ptr2, &junk3,
00485                             &num_offset, &ierr );
00486         if( iBase_SUCCESS == ierr )
00487         {
00488             have_adj = true;
00489             target.resize( num_adj );
00490         }
00491     }
00492 
00493     // If implementation passed back a size, try that
00494     if( !have_adj && num_adj && (unsigned)num_adj > target.capacity() )
00495     {
00496         target.resize( num_adj );
00497         int junk1 = target.capacity(), junk3 = offsets.size();
00498         iBase_EntityHandle* ptr = reinterpret_cast< iBase_EntityHandle* >( arrptr( target ) );
00499         iMesh_getEntArrAdj( meshInstance, source, num_source, target_type, &ptr, &junk1, &num_adj, &ptr2, &junk3,
00500                             &num_offset, &ierr );
00501         if( iBase_SUCCESS == ierr ) have_adj = true;
00502     }
00503 
00504     // Try with empty sidl array, and copy into elements vector
00505     if( !have_adj )
00506     {
00507         iBase_EntityHandle* mArray = 0;
00508         int junk1 = 0, junk3 = offsets.size();
00509         iMesh_getEntArrAdj( meshInstance, source, num_source, target_type, &mArray, &junk1, &num_adj, &ptr2, &junk3,
00510                             &num_offset, &ierr );
00511         if( iBase_SUCCESS != ierr )
00512         {
00513             MSQ_SETERR( err )( process_itaps_error( ierr ), MsqError::INTERNAL_ERROR );
00514             return;
00515         }
00516 
00517         target.resize( num_adj );
00518         std::copy( mArray, mArray + num_adj, reinterpret_cast< iBase_EntityHandle* >( arrptr( target ) ) );
00519         free( mArray );
00520     }
00521 
00522     if( expand )
00523     {
00524         for( size_t i = num_offset; i > 0; --i )
00525             offsets[i - 1] = static_cast< size_t >( ptr2[i - 1] );
00526         free( ptr2 );
00527     }
00528 
00529     // iMesh implementations seem to be inconsistent with regard to
00530     // placing the last value on this list.
00531     if( offsets.size() - num_offset == 1 ) offsets[num_offset++] = num_adj;
00532     assert( (unsigned)num_offset == offsets.size() );
00533 }
00534 
00535 void MsqIMesh::vertices_get_attached_elements( const VertexHandle* vertices, size_t num_vertex,
00536                                                std::vector< ElementHandle >& elements, std::vector< size_t >& offsets,
00537                                                MsqError& err )
00538 {
00539     int ierr, cont;
00540     assert( sizeof( EntityHandle ) == sizeof( iBase_EntityHandle ) );
00541     const iBase_EntityHandle* verts = reinterpret_cast< const iBase_EntityHandle* >( vertices );
00542     get_adjacent_entities( verts, num_vertex, inputSetType, elements, offsets, err );MSQ_ERRRTN( err );
00543 
00544     iBase_EntitySetHandle root_set;
00545     iMesh_getRootSet( meshInstance, &root_set, &ierr );
00546     if( iBase_SUCCESS != ierr )
00547     {
00548         MSQ_SETERR( err )( process_itaps_error( ierr ), MsqError::INTERNAL_ERROR );
00549         return;
00550     }
00551 
00552     // Remove all elements not in inputSet
00553     if( root_set != inputSet )
00554     {
00555         std::vector< size_t >::iterator offset_iter = offsets.begin();
00556         size_t read_idx, write_idx;
00557         for( read_idx = write_idx = 0; read_idx < elements.size(); ++read_idx )
00558         {
00559             if( *offset_iter == read_idx )
00560             {
00561                 *offset_iter = write_idx;
00562                 ++offset_iter;
00563             }
00564 
00565             iBase_EntityHandle bh = static_cast< iBase_EntityHandle >( elements[read_idx] );
00566             iMesh_isEntContained( meshInstance, inputSet, bh, &cont, &ierr );
00567             if( iBase_SUCCESS != ierr )
00568             {
00569                 MSQ_SETERR( err )( process_itaps_error( ierr ), MsqError::INTERNAL_ERROR );
00570                 return;
00571             }
00572 
00573             if( cont ) elements[write_idx++] = elements[read_idx];
00574         }
00575         *offset_iter = write_idx;
00576         elements.resize( write_idx );
00577     }
00578 }
00579 
00580 //**************** Element Topology *****************
00581 
00582 /** Get connectivity
00583  *\param elements - Array of length num_elems containing elements
00584  *                  handles of elements for which connectivity is to
00585  *                  be queried.
00586  *\param vertices - Array of vertex handles in connectivity list.
00587  *\param offsets  - Indices into \ref vertex_handles, one per element
00588  */
00589 void MsqIMesh::elements_get_attached_vertices( const ElementHandle* elements, size_t num_elems,
00590                                                std::vector< VertexHandle >& vertices, std::vector< size_t >& offsets,
00591                                                MBMesquite::MsqError& err )
00592 {
00593     assert( sizeof( iBase_EntityHandle ) == sizeof( EntityHandle ) );
00594     const iBase_EntityHandle* elems = reinterpret_cast< const iBase_EntityHandle* >( elements );
00595     get_adjacent_entities( elems, num_elems, iBase_VERTEX, vertices, offsets, err );MSQ_CHKERR( err );
00596 }
00597 
00598 void MsqIMesh::get_all_elements( std::vector< ElementHandle >& elements, MsqError& err )
00599 {
00600     int ierr, count_in, count_out;
00601 
00602     if( inputSetType == iBase_ALL_TYPES )
00603     {
00604         int num_vol, num_face;
00605 
00606         iMesh_getNumOfType( meshInstance, inputSet, iBase_FACE, &num_face, &ierr );
00607         if( iBase_SUCCESS != ierr )
00608         {
00609             MSQ_SETERR( err )( process_itaps_error( ierr ), MsqError::INTERNAL_ERROR );
00610             return;
00611         }
00612         iMesh_getNumOfType( meshInstance, inputSet, iBase_REGION, &num_vol, &ierr );
00613         if( iBase_SUCCESS != ierr )
00614         {
00615             MSQ_SETERR( err )( process_itaps_error( ierr ), MsqError::INTERNAL_ERROR );
00616             return;
00617         }
00618         elements.resize( num_face + num_vol );
00619         if( elements.empty() ) return;
00620 
00621         iBase_EntityHandle* ptr = reinterpret_cast< iBase_EntityHandle* >( arrptr( elements ) );
00622         if( num_face )
00623         {
00624             count_in = num_face + num_vol;
00625             iMesh_getEntities( meshInstance, inputSet, iBase_FACE, iMesh_ALL_TOPOLOGIES, &ptr, &count_in, &count_out,
00626                                &ierr );
00627             if( iBase_SUCCESS != ierr )
00628             {
00629                 MSQ_SETERR( err )( process_itaps_error( ierr ), MsqError::INTERNAL_ERROR );
00630                 return;
00631             }
00632             assert( count_out == num_face );
00633         }
00634 
00635         if( num_vol )
00636         {
00637             ptr += num_face;
00638             count_in = num_vol;
00639             iMesh_getEntities( meshInstance, inputSet, iBase_REGION, iMesh_ALL_TOPOLOGIES, &ptr, &count_in, &count_out,
00640                                &ierr );
00641             if( iBase_SUCCESS != ierr )
00642             {
00643                 MSQ_SETERR( err )( process_itaps_error( ierr ), MsqError::INTERNAL_ERROR );
00644                 return;
00645             }
00646             assert( count_out == num_vol );
00647         }
00648     }
00649     else
00650     {
00651         int count;
00652         iMesh_getNumOfType( meshInstance, inputSet, inputSetType, &count, &ierr );
00653         if( iBase_SUCCESS != ierr )
00654         {
00655             MSQ_SETERR( err )( process_itaps_error( ierr ), MsqError::INTERNAL_ERROR );
00656             return;
00657         }
00658 
00659         if( !count ) return;
00660         elements.resize( count );
00661 
00662         iBase_EntityHandle* ptr = reinterpret_cast< iBase_EntityHandle* >( arrptr( elements ) );
00663         count_in                = count;
00664         iMesh_getEntities( meshInstance, inputSet, inputSetType, iMesh_ALL_TOPOLOGIES, &ptr, &count_in, &count_out,
00665                            &ierr );
00666         if( iBase_SUCCESS != ierr )
00667         {
00668             MSQ_SETERR( err )( process_itaps_error( ierr ), MsqError::INTERNAL_ERROR );
00669             return;
00670         }
00671         assert( count_out == count );
00672     }
00673 }
00674 
00675 void MsqIMesh::get_all_vertices( std::vector< VertexHandle >& vertices, MsqError& err )
00676 {
00677     std::vector< ElementHandle > elems;
00678     get_all_elements( elems, err );MSQ_CHKERR( err );
00679     if( elems.empty() ) return;
00680 
00681     std::vector< size_t > offsets;
00682     elements_get_attached_vertices( arrptr( elems ), elems.size(), vertices, offsets, err );MSQ_CHKERR( err );
00683 
00684     std::sort( vertices.begin(), vertices.end() );
00685     vertices.erase( std::unique( vertices.begin(), vertices.end() ), vertices.end() );
00686 }
00687 
00688 // Returns the topologies of the given entities.  The "entity_topologies"
00689 // array must be at least "num_elements" in size.
00690 void MsqIMesh::elements_get_topologies( const ElementHandle* element_handle_array, EntityTopology* element_topologies,
00691                                         size_t num_elements, MsqError& err )
00692 {
00693     if( !num_elements ) return;
00694 
00695     // don't copy unless we have to
00696     std::vector< int > topo_store;
00697     int* topo_array;
00698     if( sizeof( EntityTopology ) == sizeof( int ) )
00699         topo_array = (int*)element_topologies;
00700     else
00701     {
00702         topo_store.resize( num_elements );
00703         topo_array = arrptr( topo_store );
00704     }
00705 
00706     int ierr, junk1 = num_elements, junk2;
00707     assert( sizeof( ElementHandle ) == sizeof( iBase_EntityHandle ) );
00708     const iBase_EntityHandle* arr = reinterpret_cast< const iBase_EntityHandle* >( element_handle_array );
00709     iMesh_getEntArrTopo( meshInstance, arr, num_elements, &topo_array, &junk1, &junk2, &ierr );
00710     if( iBase_SUCCESS != ierr )
00711     {
00712         MSQ_SETERR( err )( process_itaps_error( ierr ), MsqError::INTERNAL_ERROR );
00713         return;
00714     }
00715 
00716     for( size_t i = 0; i < num_elements; ++i )
00717         element_topologies[i] = topologyMap[topo_array[i]];
00718 }
00719 
00720 //**************** Memory Management ****************
00721 // Tells the mesh that the client is finished with a given
00722 // entity handle.
00723 void MsqIMesh::release_entity_handles( const MBMesquite::Mesh::EntityHandle* /*handle_array*/, size_t /*num_handles*/,
00724                                        MsqError& /*err*/ )
00725 {
00726     // Do nothing
00727 }
00728 
00729 // Instead of deleting a Mesh when you think you are done,
00730 // call release().  In simple cases, the implementation could
00731 // just call the destructor.  More sophisticated implementations
00732 // may want to keep the Mesh object to live longer than Mesquite
00733 // is using it.
00734 void MsqIMesh::release() {}
00735 
00736 //**************** Tags ****************
00737 TagHandle MsqIMesh::tag_create( const std::string& name, TagType type, unsigned length, const void*, MsqError& err )
00738 {
00739     int itaps_type;
00740     switch( type )
00741     {
00742         case MBMesquite::Mesh::BYTE:
00743             itaps_type = iBase_BYTES;
00744             break;
00745         case MBMesquite::Mesh::INT:
00746             itaps_type = iBase_INTEGER;
00747             break;
00748         case MBMesquite::Mesh::DOUBLE:
00749             itaps_type = iBase_DOUBLE;
00750             break;
00751         case MBMesquite::Mesh::HANDLE:
00752             itaps_type = iBase_ENTITY_HANDLE;
00753             break;
00754         default:
00755             MSQ_SETERR( err )( "Invalid tag type", MsqError::INVALID_ARG );
00756             return 0;
00757     }
00758 
00759     int ierr;
00760     iBase_TagHandle result;
00761     iMesh_createTag( meshInstance, name.c_str(), length, itaps_type, &result, &ierr, name.size() );
00762     if( iBase_SUCCESS != ierr )
00763     {
00764         MSQ_SETERR( err )( process_itaps_error( ierr ), MsqError::INTERNAL_ERROR );
00765         return 0;
00766     }
00767 
00768     return static_cast< TagHandle >( result );
00769 }
00770 
00771 void MsqIMesh::tag_delete( TagHandle handle, MsqError& err )
00772 {
00773     int ierr;
00774     iMesh_destroyTag( meshInstance, static_cast< iBase_TagHandle >( handle ), true, &ierr );
00775     if( iBase_SUCCESS != ierr )
00776     {
00777         MSQ_SETERR( err )( process_itaps_error( ierr ), MsqError::INTERNAL_ERROR );
00778         return;
00779     }
00780 }
00781 
00782 TagHandle MsqIMesh::tag_get( const std::string& name, MsqError& err )
00783 {
00784     iBase_TagHandle handle = 0;
00785     int ierr;
00786     iMesh_getTagHandle( meshInstance, name.c_str(), &handle, &ierr, name.length() );
00787     if( iBase_TAG_NOT_FOUND == ierr )
00788     {
00789         MSQ_SETERR( err )( process_itaps_error( ierr ), MsqError::TAG_NOT_FOUND );
00790         return 0;
00791     }
00792     else if( iBase_SUCCESS != ierr )
00793     {
00794         MSQ_SETERR( err )( process_itaps_error( ierr ), MsqError::INTERNAL_ERROR );
00795         return 0;
00796     }
00797     return static_cast< TagHandle >( handle );
00798 }
00799 
00800 void MsqIMesh::tag_properties( TagHandle handle, std::string& name_out, TagType& type_out, unsigned& length_out,
00801                                MsqError& err )
00802 {
00803     char buffer[256];
00804     int ierr1, ierr2, ierr3, itype;
00805 
00806     iBase_TagHandle th = static_cast< iBase_TagHandle >( handle );
00807     iMesh_getTagName( meshInstance, th, buffer, &ierr1, sizeof( buffer ) );
00808     iMesh_getTagSizeValues( meshInstance, th, (int*)&length_out, &ierr2 );
00809     iMesh_getTagType( meshInstance, th, &itype, &ierr3 );
00810 
00811     int ierr = iBase_SUCCESS;
00812     if( ierr1 != iBase_SUCCESS )
00813         ierr = ierr1;
00814     else if( ierr2 != iBase_SUCCESS )
00815         ierr = ierr2;
00816     else if( ierr3 != iBase_SUCCESS )
00817         ierr = ierr3;
00818     if( iBase_SUCCESS != ierr )
00819     {
00820         MSQ_SETERR( err )( process_itaps_error( ierr ), MsqError::INTERNAL_ERROR );
00821         return;
00822     }
00823 
00824     buffer[255] = '\0';
00825     name_out    = buffer;
00826     switch( itype )
00827     {
00828         case iBase_BYTES:
00829             type_out = MBMesquite::Mesh::BYTE;
00830             break;
00831         case iBase_INTEGER:
00832             type_out = MBMesquite::Mesh::INT;
00833             break;
00834         case iBase_DOUBLE:
00835             type_out = MBMesquite::Mesh::DOUBLE;
00836             break;
00837         case iBase_ENTITY_HANDLE:
00838             type_out = MBMesquite::Mesh::HANDLE;
00839             break;
00840         default:
00841             MSQ_SETERR( err )( "Unsupported iMesh tag type", MsqError::NOT_IMPLEMENTED );
00842             return;
00843     }
00844 }
00845 
00846 void MsqIMesh::tag_set_element_data( TagHandle tag, size_t num_elems, const ElementHandle* array, const void* data,
00847                                      MsqError& err )
00848 {
00849     tag_set_data( tag, num_elems, array, data, err );
00850 }
00851 
00852 void MsqIMesh::tag_set_vertex_data( TagHandle tag, size_t num_elems, const VertexHandle* array, const void* data,
00853                                     MsqError& err )
00854 {
00855     tag_set_data( tag, num_elems, array, data, err );
00856 }
00857 
00858 void MsqIMesh::tag_set_data( TagHandle tag, size_t num_elems, const EntityHandle* array, const void* data,
00859                              MsqError& err )
00860 {
00861     int ierr, size;
00862     iMesh_getTagSizeBytes( meshInstance, static_cast< iBase_TagHandle >( tag ), &size, &ierr );
00863     if( iBase_SUCCESS != ierr )
00864     {
00865         MSQ_SETERR( err )( process_itaps_error( ierr ), MsqError::INTERNAL_ERROR );
00866         return;
00867     }
00868     assert( sizeof( EntityHandle ) == sizeof( iBase_EntityHandle ) );
00869     const iBase_EntityHandle* arr = reinterpret_cast< const iBase_EntityHandle* >( array );
00870     iMesh_setArrData( meshInstance, arr, num_elems, static_cast< iBase_TagHandle >( tag ),
00871                       static_cast< const char* >( data ), size * num_elems, &ierr );
00872     if( iBase_SUCCESS != ierr )
00873     {
00874         MSQ_SETERR( err )( process_itaps_error( ierr ), MsqError::INTERNAL_ERROR );
00875         return;
00876     }
00877 }
00878 
00879 void MsqIMesh::tag_get_element_data( TagHandle tag, size_t num_elems, const ElementHandle* array, void* data,
00880                                      MsqError& err )
00881 {
00882     tag_get_data( tag, num_elems, array, data, err );
00883 }
00884 
00885 void MsqIMesh::tag_get_vertex_data( TagHandle tag, size_t num_elems, const VertexHandle* array, void* data,
00886                                     MsqError& err )
00887 {
00888     tag_get_data( tag, num_elems, array, data, err );
00889 }
00890 
00891 void MsqIMesh::tag_get_data( TagHandle tag, size_t num_elems, const EntityHandle* array, void* data, MsqError& err )
00892 {
00893     int ierr, size;
00894     iMesh_getTagSizeBytes( meshInstance, static_cast< iBase_TagHandle >( tag ), &size, &ierr );
00895     if( iBase_SUCCESS != ierr )
00896     {
00897         MSQ_SETERR( err )( process_itaps_error( ierr ), MsqError::INTERNAL_ERROR );
00898         return;
00899     }
00900 #if IMESH_VERSION_ATLEAST( 1, 1 )
00901     void* ptr = data;
00902 #else
00903     char* ptr = static_cast< char* >( data );
00904 #endif
00905     int junk1 = size * num_elems, junk2;
00906     assert( sizeof( EntityHandle ) == sizeof( iBase_EntityHandle ) );
00907     const iBase_EntityHandle* arr = reinterpret_cast< const iBase_EntityHandle* >( array );
00908     iMesh_getArrData( meshInstance, arr, num_elems, static_cast< iBase_TagHandle >( tag ), &ptr, &junk1, &junk2,
00909                       &ierr );
00910     if( iBase_SUCCESS != ierr )
00911     {
00912         MSQ_SETERR( err )( process_itaps_error( ierr ), MsqError::INTERNAL_ERROR );
00913         return;
00914     }
00915 }
00916 
00917 }  // namespace MBMesquite
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines