MOAB: Mesh Oriented datABase  (version 5.4.1)
MeshImplTags.cpp
Go to the documentation of this file.
00001 /* *****************************************************************
00002     MESQUITE -- The Mesh Quality Improvement Toolkit
00003 
00004     Copyright 2004 Lawrence Livermore National Laboratory.  Under
00005     the terms of Contract B545069 with the University of Wisconsin --
00006     Madison, Lawrence Livermore National Laboratory retains certain
00007     rights in 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     [email protected]
00024 
00025   ***************************************************************** */
00026 
00027 #include "MeshImplTags.hpp"
00028 #include "MsqError.hpp"
00029 #include <cassert>
00030 #include <cstdlib>
00031 
00032 namespace MBMesquite
00033 {
00034 
00035 MeshImplTags::TagData::~TagData()
00036 {
00037     if( elementData ) free( elementData );
00038     if( vertexData ) free( vertexData );
00039     if( defaultValue ) free( defaultValue );
00040 }
00041 
00042 void MeshImplTags::clear()
00043 {
00044     for( std::vector< TagData* >::iterator iter = tagList.begin(); iter != tagList.end(); ++iter )
00045         if( *iter ) delete *iter;
00046 
00047     tagList.clear();
00048 }
00049 
00050 size_t MeshImplTags::size_from_tag_type( Mesh::TagType type )
00051 {
00052     switch( type )
00053     {
00054         case Mesh::BYTE:
00055             return 1;
00056         case Mesh::BOOL:
00057             return sizeof( bool );
00058         case Mesh::DOUBLE:
00059             return sizeof( double );
00060         case Mesh::INT:
00061             return sizeof( int );
00062         case Mesh::HANDLE:
00063             return sizeof( void* );
00064         default:
00065             assert( 0 );
00066             return 0;
00067     }
00068 }
00069 
00070 size_t MeshImplTags::create( const std::string& name,
00071                              Mesh::TagType type,
00072                              unsigned length,
00073                              const void* defval,
00074                              MsqError& err )
00075 {
00076     size_t h = handle( name, err );
00077     if( h )
00078     {
00079         MSQ_SETERR( err )( name, MsqError::TAG_ALREADY_EXISTS );
00080         return 0;
00081     }
00082 
00083     if( length == 0 || size_from_tag_type( type ) == 0 )
00084     {
00085         MSQ_SETERR( err )( MsqError::INVALID_ARG );
00086         return 0;
00087     }
00088 
00089     TagData* tag = new TagData( name, type, length );
00090     h            = tagList.size();
00091     tagList.push_back( tag );
00092 
00093     if( defval )
00094     {
00095         tag->defaultValue = malloc( tag->desc.size );
00096         memcpy( tag->defaultValue, defval, tag->desc.size );
00097     }
00098 
00099     return h + 1;
00100 }
00101 
00102 size_t MeshImplTags::create( const TagDescription& desc, const void* defval, MsqError& err )
00103 {
00104     size_t h = handle( desc.name.c_str(), err );
00105     if( h )
00106     {
00107         MSQ_SETERR( err )( desc.name.c_str(), MsqError::TAG_ALREADY_EXISTS );
00108         return 0;
00109     }
00110 
00111     err.clear();
00112     if( desc.size == 0 || ( desc.size % size_from_tag_type( desc.type ) ) != 0 )
00113     {
00114         MSQ_SETERR( err )( MsqError::INVALID_ARG );
00115         return 0;
00116     }
00117 
00118     TagData* tag = new TagData( desc );
00119     h            = tagList.size();
00120     tagList.push_back( tag );
00121 
00122     if( defval )
00123     {
00124         tag->defaultValue = malloc( tag->desc.size );
00125         memcpy( tag->defaultValue, defval, tag->desc.size );
00126     }
00127 
00128     return h + 1;
00129 }
00130 
00131 void MeshImplTags::destroy( size_t tag_index, MsqError& err )
00132 {
00133     --tag_index;
00134     if( tag_index >= tagList.size() || 0 == tagList[tag_index] )
00135     {
00136         MSQ_SETERR( err )( MsqError::TAG_NOT_FOUND );
00137         return;
00138     }
00139 
00140     delete tagList[tag_index];
00141     tagList[tag_index] = 0;
00142 }
00143 
00144 size_t MeshImplTags::handle( const std::string& name, MsqError& ) const
00145 {
00146     for( size_t i = 0; i < tagList.size(); ++i )
00147         if( tagList[i] && tagList[i]->desc.name == name ) return i + 1;
00148 
00149     return 0;
00150 }
00151 
00152 const TagDescription& MeshImplTags::properties( size_t tag_index, MsqError& err ) const
00153 {
00154     static TagDescription dummy_desc;
00155     --tag_index;
00156 
00157     if( tag_index >= tagList.size() || !tagList[tag_index] )
00158     {
00159         MSQ_SETERR( err )( "Invalid tag handle", MsqError::INVALID_ARG );
00160         return dummy_desc;
00161     }
00162 
00163     return tagList[tag_index]->desc;
00164 }
00165 
00166 void MeshImplTags::set_element_data( size_t tag_index,
00167                                      size_t num_indices,
00168                                      const size_t* index_array,
00169                                      const void* values,
00170                                      MsqError& err )
00171 {
00172     size_t i;
00173     char* data;
00174     --tag_index;
00175     if( tag_index >= tagList.size() || !tagList[tag_index] )
00176     {
00177         MSQ_SETERR( err )( "Invalid tag handle", MsqError::INVALID_ARG );
00178         return;
00179     }
00180 
00181     TagData* tag = tagList[tag_index];
00182 
00183     // Get highest element index
00184     size_t total = tag->elementCount;
00185     for( i = 0; i < num_indices; ++i )
00186         if( index_array[i] >= total ) total = index_array[i] + 1;
00187 
00188     // If need more space
00189     if( total > tag->elementCount )
00190     {
00191         // allocate more space
00192         tag->elementData = realloc( tag->elementData, tag->desc.size * total );
00193         // if a default value, initialize new space with it
00194         if( tag->defaultValue )
00195         {
00196             data = ( (char*)tag->elementData ) + tag->elementCount * tag->desc.size;
00197             for( i = tag->elementCount; i < total; ++i )
00198             {
00199                 memcpy( data, tag->defaultValue, tag->desc.size );
00200                 data += tag->desc.size;
00201             }
00202         }
00203         else
00204         {
00205             memset( (char*)tag->elementData + tag->elementCount * tag->desc.size, 0,
00206                     ( total - tag->elementCount ) * tag->desc.size );
00207         }
00208         tag->elementCount = total;
00209     }
00210 
00211     // Store passed tag values
00212     data             = (char*)tag->elementData;
00213     const char* iter = (const char*)values;
00214     for( i = 0; i < num_indices; ++i )
00215     {
00216         memcpy( data + index_array[i] * tag->desc.size, iter, tag->desc.size );
00217         iter += tag->desc.size;
00218     }
00219 }
00220 
00221 void MeshImplTags::get_element_data( size_t tag_index,
00222                                      size_t num_indices,
00223                                      const size_t* index_array,
00224                                      void* values,
00225                                      MsqError& err ) const
00226 {
00227     --tag_index;
00228     if( tag_index >= tagList.size() || !tagList[tag_index] )
00229     {
00230         MSQ_SETERR( err )( "Invalid tag handle", MsqError::INVALID_ARG );
00231         return;
00232     }
00233 
00234     TagData* tag = tagList[tag_index];
00235 
00236     char* iter       = (char*)values;
00237     const char* data = (const char*)tag->elementData;
00238 
00239     for( size_t i = 0; i < num_indices; ++i )
00240     {
00241         const void* ptr;
00242         size_t index = index_array[i];
00243         if( index >= tag->elementCount )
00244         {
00245             ptr = tag->defaultValue;
00246             if( !ptr )
00247             {
00248                 MSQ_SETERR( err )( MsqError::TAG_NOT_FOUND );
00249                 return;
00250             }
00251         }
00252         else
00253         {
00254             ptr = data + index * tag->desc.size;
00255         }
00256 
00257         memcpy( iter, ptr, tag->desc.size );
00258         iter += tag->desc.size;
00259     }
00260 }
00261 
00262 void MeshImplTags::set_vertex_data( size_t tag_index,
00263                                     size_t num_indices,
00264                                     const size_t* index_array,
00265                                     const void* values,
00266                                     MsqError& err )
00267 {
00268     size_t i;
00269     char* data;
00270     --tag_index;
00271     if( tag_index >= tagList.size() || !tagList[tag_index] )
00272     {
00273         MSQ_SETERR( err )( "Invalid tag handle", MsqError::INVALID_ARG );
00274         return;
00275     }
00276 
00277     TagData* tag = tagList[tag_index];
00278 
00279     // Get highest element index
00280     size_t total = tag->vertexCount;
00281     for( i = 0; i < num_indices; ++i )
00282         if( index_array[i] >= total ) total = index_array[i] + 1;
00283 
00284     // If need more space
00285     if( total > tag->vertexCount )
00286     {
00287         // allocate more space
00288         tag->vertexData = realloc( tag->vertexData, tag->desc.size * total );
00289         // if a default value, initialize new space with it
00290         if( tag->defaultValue )
00291         {
00292             data = ( (char*)tag->vertexData ) + tag->vertexCount * tag->desc.size;
00293             for( i = tag->vertexCount; i < total; ++i )
00294             {
00295                 memcpy( data, tag->defaultValue, tag->desc.size );
00296                 data += tag->desc.size;
00297             }
00298         }
00299         else
00300         {
00301             memset( (char*)tag->vertexData + tag->vertexCount * tag->desc.size, 0,
00302                     ( total - tag->vertexCount ) * tag->desc.size );
00303         }
00304         tag->vertexCount = total;
00305     }
00306 
00307     // Store passed tag values
00308     data             = (char*)tag->vertexData;
00309     const char* iter = (const char*)values;
00310     for( i = 0; i < num_indices; ++i )
00311     {
00312         memcpy( data + index_array[i] * tag->desc.size, iter, tag->desc.size );
00313         iter += tag->desc.size;
00314     }
00315 }
00316 
00317 void MeshImplTags::get_vertex_data( size_t tag_index,
00318                                     size_t num_indices,
00319                                     const size_t* index_array,
00320                                     void* values,
00321                                     MsqError& err ) const
00322 {
00323     --tag_index;
00324     if( tag_index >= tagList.size() || !tagList[tag_index] )
00325     {
00326         MSQ_SETERR( err )( "Invalid tag handle", MsqError::INVALID_ARG );
00327         return;
00328     }
00329 
00330     TagData* tag = tagList[tag_index];
00331 
00332     char* iter       = (char*)values;
00333     const char* data = (const char*)tag->vertexData;
00334 
00335     for( size_t i = 0; i < num_indices; ++i )
00336     {
00337         const void* ptr;
00338         size_t index = index_array[i];
00339         if( index >= tag->vertexCount )
00340         {
00341             ptr = tag->defaultValue;
00342             if( !ptr )
00343             {
00344                 MSQ_SETERR( err )( MsqError::TAG_NOT_FOUND );
00345                 return;
00346             }
00347         }
00348         else
00349         {
00350             ptr = data + index * tag->desc.size;
00351         }
00352 
00353         memcpy( iter, ptr, tag->desc.size );
00354         iter += tag->desc.size;
00355     }
00356 }
00357 
00358 bool MeshImplTags::tag_has_vertex_data( size_t tag_index, MsqError& err )
00359 {
00360     --tag_index;
00361     if( tag_index >= tagList.size() || !tagList[tag_index] )
00362     {
00363         MSQ_SETERR( err )( "Invalid tag handle", MsqError::INVALID_ARG );
00364         return false;
00365     }
00366 
00367     TagData* tag = tagList[tag_index];
00368     return 0 != tag->vertexData || tag->defaultValue;
00369 }
00370 
00371 bool MeshImplTags::tag_has_element_data( size_t tag_index, MsqError& err )
00372 {
00373     --tag_index;
00374     if( tag_index >= tagList.size() || !tagList[tag_index] )
00375     {
00376         MSQ_SETERR( err )( "Invalid tag handle", MsqError::INVALID_ARG );
00377         return false;
00378     }
00379 
00380     TagData* tag = tagList[tag_index];
00381     return 0 != tag->elementData || tag->defaultValue;
00382 }
00383 
00384 MeshImplTags::TagIterator MeshImplTags::tag_begin()
00385 {
00386     size_t index = 0;
00387     while( index < tagList.size() && tagList[index] == NULL )
00388         ++index;
00389     return TagIterator( this, index );
00390 }
00391 
00392 MeshImplTags::TagIterator MeshImplTags::TagIterator::operator++()
00393 {
00394     ++index;
00395     while( index < tags->tagList.size() && NULL == tags->tagList[index] )
00396         ++index;
00397     return TagIterator( tags, index );
00398 }
00399 
00400 MeshImplTags::TagIterator MeshImplTags::TagIterator::operator--()
00401 {
00402     --index;
00403     while( index < tags->tagList.size() && NULL == tags->tagList[index] )
00404         --index;
00405     return TagIterator( tags, index );
00406 }
00407 
00408 MeshImplTags::TagIterator MeshImplTags::TagIterator::operator++( int )
00409 {
00410     size_t old = index;
00411     ++index;
00412     while( index < tags->tagList.size() && NULL == tags->tagList[index] )
00413         ++index;
00414     return TagIterator( tags, old );
00415 }
00416 
00417 MeshImplTags::TagIterator MeshImplTags::TagIterator::operator--( int )
00418 {
00419     size_t old = index;
00420     --index;
00421     while( index < tags->tagList.size() && NULL == tags->tagList[index] )
00422         --index;
00423     return TagIterator( tags, old );
00424 }
00425 
00426 }  // namespace MBMesquite
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines