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