MOAB: Mesh Oriented datABase
(version 5.4.1)
|
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