MOAB: Mesh Oriented datABase
(version 5.2.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 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