Branch data Line data Source code
1 : : /* *****************************************************************
2 : : MESQUITE -- The Mesh Quality Improvement Toolkit
3 : :
4 : : Copyright 2004 Lawrence Livermore National Laboratory. Under
5 : : the terms of Contract B545069 with the University of Wisconsin --
6 : : Madison, Lawrence Livermore National Laboratory retains certain
7 : : rights in this software.
8 : :
9 : : This library is free software; you can redistribute it and/or
10 : : modify it under the terms of the GNU Lesser General Public
11 : : License as published by the Free Software Foundation; either
12 : : version 2.1 of the License, or (at your option) any later version.
13 : :
14 : : This library is distributed in the hope that it will be useful,
15 : : but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 : : Lesser General Public License for more details.
18 : :
19 : : You should have received a copy of the GNU Lesser General Public License
20 : : (lgpl.txt) along with this library; if not, write to the Free Software
21 : : Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 : :
23 : : [email protected]
24 : :
25 : : ***************************************************************** */
26 : :
27 : : #include "MeshImplTags.hpp"
28 : : #include "MsqError.hpp"
29 : : #include <assert.h>
30 : : #include <stdlib.h>
31 : :
32 : : namespace MBMesquite
33 : : {
34 : :
35 : 368 : MeshImplTags::TagData::~TagData()
36 : : {
37 [ + + ]: 184 : if( elementData ) free( elementData );
38 [ + + ]: 184 : if( vertexData ) free( vertexData );
39 [ - + ]: 184 : if( defaultValue ) free( defaultValue );
40 : 184 : }
41 : :
42 : 311 : void MeshImplTags::clear()
43 : : {
44 [ + - ][ + - ]: 495 : for( std::vector< TagData* >::iterator iter = tagList.begin(); iter != tagList.end(); ++iter )
[ + + ]
45 [ + - ][ + + ]: 184 : if( *iter ) delete *iter;
[ + - ][ + - ]
46 : :
47 : 311 : tagList.clear();
48 : 311 : }
49 : :
50 : 256 : size_t MeshImplTags::size_from_tag_type( Mesh::TagType type )
51 : : {
52 [ - + + + : 256 : switch( type )
- - ]
53 : : {
54 : : case Mesh::BYTE:
55 : 0 : return 1;
56 : : case Mesh::BOOL:
57 : 75 : return sizeof( bool );
58 : : case Mesh::DOUBLE:
59 : 98 : return sizeof( double );
60 : : case Mesh::INT:
61 : 83 : return sizeof( int );
62 : : case Mesh::HANDLE:
63 : 0 : return sizeof( void* );
64 : : default:
65 : 0 : assert( 0 );
66 : : return 0;
67 : : }
68 : : }
69 : :
70 : 0 : size_t MeshImplTags::create( const std::string& name, Mesh::TagType type, unsigned length, const void* defval,
71 : : MsqError& err )
72 : : {
73 [ # # ]: 0 : size_t h = handle( name, err );
74 [ # # ]: 0 : if( h )
75 : : {
76 [ # # ][ # # ]: 0 : MSQ_SETERR( err )( name, MsqError::TAG_ALREADY_EXISTS );
77 : 0 : return 0;
78 : : }
79 : :
80 [ # # ][ # # ]: 0 : if( length == 0 || size_from_tag_type( type ) == 0 )
[ # # ][ # # ]
81 : : {
82 [ # # ][ # # ]: 0 : MSQ_SETERR( err )( MsqError::INVALID_ARG );
83 : 0 : return 0;
84 : : }
85 : :
86 [ # # ][ # # ]: 0 : TagData* tag = new TagData( name, type, length );
[ # # ]
87 : 0 : h = tagList.size();
88 [ # # ]: 0 : tagList.push_back( tag );
89 : :
90 [ # # ]: 0 : if( defval )
91 : : {
92 : 0 : tag->defaultValue = malloc( tag->desc.size );
93 : 0 : memcpy( tag->defaultValue, defval, tag->desc.size );
94 : : }
95 : :
96 : 0 : return h + 1;
97 : : }
98 : :
99 : 193 : size_t MeshImplTags::create( const TagDescription& desc, const void* defval, MsqError& err )
100 : : {
101 [ + - ][ + - ]: 193 : size_t h = handle( desc.name.c_str(), err );
102 [ + + ]: 193 : if( h )
103 : : {
104 [ + - ][ + - ]: 9 : MSQ_SETERR( err )( desc.name.c_str(), MsqError::TAG_ALREADY_EXISTS );
105 : 9 : return 0;
106 : : }
107 : :
108 [ + - ]: 184 : err.clear();
109 [ + - ][ + - ]: 184 : if( desc.size == 0 || ( desc.size % size_from_tag_type( desc.type ) ) != 0 )
[ - + ][ - + ]
110 : : {
111 [ # # ][ # # ]: 0 : MSQ_SETERR( err )( MsqError::INVALID_ARG );
112 : 0 : return 0;
113 : : }
114 : :
115 [ + - ][ + - ]: 184 : TagData* tag = new TagData( desc );
116 : 184 : h = tagList.size();
117 [ + - ]: 184 : tagList.push_back( tag );
118 : :
119 [ - + ]: 184 : if( defval )
120 : : {
121 : 0 : tag->defaultValue = malloc( tag->desc.size );
122 : 0 : memcpy( tag->defaultValue, defval, tag->desc.size );
123 : : }
124 : :
125 : 193 : return h + 1;
126 : : }
127 : :
128 : 152 : void MeshImplTags::destroy( size_t tag_index, MsqError& err )
129 : : {
130 : 152 : --tag_index;
131 [ + - ][ - + ]: 152 : if( tag_index >= tagList.size() || 0 == tagList[tag_index] )
[ - + ]
132 : : {
133 [ # # ]: 0 : MSQ_SETERR( err )( MsqError::TAG_NOT_FOUND );
134 : 152 : return;
135 : : }
136 : :
137 [ + - ]: 152 : delete tagList[tag_index];
138 : 152 : tagList[tag_index] = 0;
139 : : }
140 : :
141 : 715 : size_t MeshImplTags::handle( const std::string& name, MsqError& ) const
142 : : {
143 [ + + ]: 1058 : for( size_t i = 0; i < tagList.size(); ++i )
144 [ + + ][ + + ]: 540 : if( tagList[i] && tagList[i]->desc.name == name ) return i + 1;
[ + + ]
145 : :
146 : 518 : return 0;
147 : : }
148 : :
149 : 245 : const TagDescription& MeshImplTags::properties( size_t tag_index, MsqError& err ) const
150 : : {
151 [ + + ][ + - ]: 245 : static TagDescription dummy_desc;
[ + - ][ # # ]
152 : 245 : --tag_index;
153 : :
154 [ + - ][ - + ]: 245 : if( tag_index >= tagList.size() || !tagList[tag_index] )
[ - + ]
155 : : {
156 [ # # ]: 0 : MSQ_SETERR( err )( "Invalid tag handle", MsqError::INVALID_ARG );
157 : 0 : return dummy_desc;
158 : : }
159 : :
160 : 245 : return tagList[tag_index]->desc;
161 : : }
162 : :
163 : 471 : void MeshImplTags::set_element_data( size_t tag_index, size_t num_indices, const size_t* index_array,
164 : : const void* values, MsqError& err )
165 : : {
166 : : size_t i;
167 : : char* data;
168 : 471 : --tag_index;
169 [ + - ][ - + ]: 471 : if( tag_index >= tagList.size() || !tagList[tag_index] )
[ - + ]
170 : : {
171 [ # # ]: 0 : MSQ_SETERR( err )( "Invalid tag handle", MsqError::INVALID_ARG );
172 : 471 : return;
173 : : }
174 : :
175 : 471 : TagData* tag = tagList[tag_index];
176 : :
177 : : // Get highest element index
178 : 471 : size_t total = tag->elementCount;
179 [ + + ]: 27926 : for( i = 0; i < num_indices; ++i )
180 [ + - ]: 27455 : if( index_array[i] >= total ) total = index_array[i] + 1;
181 : :
182 : : // If need more space
183 [ + - ]: 471 : if( total > tag->elementCount )
184 : : {
185 : : // allocate more space
186 : 471 : tag->elementData = realloc( tag->elementData, tag->desc.size * total );
187 : : // if a default value, initialize new space with it
188 [ - + ]: 471 : if( tag->defaultValue )
189 : : {
190 : 0 : data = ( (char*)tag->elementData ) + tag->elementCount * tag->desc.size;
191 [ # # ]: 0 : for( i = tag->elementCount; i < total; ++i )
192 : : {
193 : 0 : memcpy( data, tag->defaultValue, tag->desc.size );
194 : 0 : data += tag->desc.size;
195 : : }
196 : : }
197 : : else
198 : : {
199 : 471 : memset( (char*)tag->elementData + tag->elementCount * tag->desc.size, 0,
200 : 471 : ( total - tag->elementCount ) * tag->desc.size );
201 : : }
202 : 471 : tag->elementCount = total;
203 : : }
204 : :
205 : : // Store passed tag values
206 : 471 : data = (char*)tag->elementData;
207 : 471 : const char* iter = (const char*)values;
208 [ + + ]: 27926 : for( i = 0; i < num_indices; ++i )
209 : : {
210 : 27455 : memcpy( data + index_array[i] * tag->desc.size, iter, tag->desc.size );
211 : 27455 : iter += tag->desc.size;
212 : : }
213 : : }
214 : :
215 : 152781 : void MeshImplTags::get_element_data( size_t tag_index, size_t num_indices, const size_t* index_array, void* values,
216 : : MsqError& err ) const
217 : : {
218 : 152781 : --tag_index;
219 [ + - ][ - + ]: 152781 : if( tag_index >= tagList.size() || !tagList[tag_index] )
[ - + ]
220 : : {
221 [ # # ]: 0 : MSQ_SETERR( err )( "Invalid tag handle", MsqError::INVALID_ARG );
222 : 0 : return;
223 : : }
224 : :
225 : 152781 : TagData* tag = tagList[tag_index];
226 : :
227 : 152781 : char* iter = (char*)values;
228 : 152781 : const char* data = (const char*)tag->elementData;
229 : :
230 [ + + ]: 305562 : for( size_t i = 0; i < num_indices; ++i )
231 : : {
232 : : const void* ptr;
233 : 152781 : size_t index = index_array[i];
234 [ + + ]: 152781 : if( index >= tag->elementCount )
235 : : {
236 : 10 : ptr = tag->defaultValue;
237 [ + - ]: 10 : if( !ptr )
238 : : {
239 [ + - ]: 10 : MSQ_SETERR( err )( MsqError::TAG_NOT_FOUND );
240 : 10 : return;
241 : : }
242 : : }
243 : : else
244 : : {
245 : 152771 : ptr = data + index * tag->desc.size;
246 : : }
247 : :
248 : 152771 : memcpy( iter, ptr, tag->desc.size );
249 : 152771 : iter += tag->desc.size;
250 : : }
251 : : }
252 : :
253 : 182 : void MeshImplTags::set_vertex_data( size_t tag_index, size_t num_indices, const size_t* index_array, const void* values,
254 : : MsqError& err )
255 : : {
256 : : size_t i;
257 : : char* data;
258 : 182 : --tag_index;
259 [ + - ][ - + ]: 182 : if( tag_index >= tagList.size() || !tagList[tag_index] )
[ - + ]
260 : : {
261 [ # # ]: 0 : MSQ_SETERR( err )( "Invalid tag handle", MsqError::INVALID_ARG );
262 : 182 : return;
263 : : }
264 : :
265 : 182 : TagData* tag = tagList[tag_index];
266 : :
267 : : // Get highest element index
268 : 182 : size_t total = tag->vertexCount;
269 [ + + ]: 73527 : for( i = 0; i < num_indices; ++i )
270 [ + + ]: 73345 : if( index_array[i] >= total ) total = index_array[i] + 1;
271 : :
272 : : // If need more space
273 [ + + ]: 182 : if( total > tag->vertexCount )
274 : : {
275 : : // allocate more space
276 : 179 : tag->vertexData = realloc( tag->vertexData, tag->desc.size * total );
277 : : // if a default value, initialize new space with it
278 [ - + ]: 179 : if( tag->defaultValue )
279 : : {
280 : 0 : data = ( (char*)tag->vertexData ) + tag->vertexCount * tag->desc.size;
281 [ # # ]: 0 : for( i = tag->vertexCount; i < total; ++i )
282 : : {
283 : 0 : memcpy( data, tag->defaultValue, tag->desc.size );
284 : 0 : data += tag->desc.size;
285 : : }
286 : : }
287 : : else
288 : : {
289 : 179 : memset( (char*)tag->vertexData + tag->vertexCount * tag->desc.size, 0,
290 : 179 : ( total - tag->vertexCount ) * tag->desc.size );
291 : : }
292 : 179 : tag->vertexCount = total;
293 : : }
294 : :
295 : : // Store passed tag values
296 : 182 : data = (char*)tag->vertexData;
297 : 182 : const char* iter = (const char*)values;
298 [ + + ]: 73527 : for( i = 0; i < num_indices; ++i )
299 : : {
300 : 73345 : memcpy( data + index_array[i] * tag->desc.size, iter, tag->desc.size );
301 : 73345 : iter += tag->desc.size;
302 : : }
303 : : }
304 : :
305 : 4867413 : void MeshImplTags::get_vertex_data( size_t tag_index, size_t num_indices, const size_t* index_array, void* values,
306 : : MsqError& err ) const
307 : : {
308 : 4867413 : --tag_index;
309 [ + - ][ - + ]: 4867413 : if( tag_index >= tagList.size() || !tagList[tag_index] )
[ - + ]
310 : : {
311 [ # # ]: 0 : MSQ_SETERR( err )( "Invalid tag handle", MsqError::INVALID_ARG );
312 : 0 : return;
313 : : }
314 : :
315 : 4867413 : TagData* tag = tagList[tag_index];
316 : :
317 : 4867413 : char* iter = (char*)values;
318 : 4867413 : const char* data = (const char*)tag->vertexData;
319 : :
320 [ + + ]: 24168282 : for( size_t i = 0; i < num_indices; ++i )
321 : : {
322 : : const void* ptr;
323 : 19300869 : size_t index = index_array[i];
324 [ - + ]: 19300869 : if( index >= tag->vertexCount )
325 : : {
326 : 0 : ptr = tag->defaultValue;
327 [ # # ]: 0 : if( !ptr )
328 : : {
329 [ # # ]: 0 : MSQ_SETERR( err )( MsqError::TAG_NOT_FOUND );
330 : 0 : return;
331 : : }
332 : : }
333 : : else
334 : : {
335 : 19300869 : ptr = data + index * tag->desc.size;
336 : : }
337 : :
338 : 19300869 : memcpy( iter, ptr, tag->desc.size );
339 : 19300869 : iter += tag->desc.size;
340 : : }
341 : : }
342 : :
343 : 177 : bool MeshImplTags::tag_has_vertex_data( size_t tag_index, MsqError& err )
344 : : {
345 : 177 : --tag_index;
346 [ + - ][ - + ]: 177 : if( tag_index >= tagList.size() || !tagList[tag_index] )
[ - + ]
347 : : {
348 [ # # ]: 0 : MSQ_SETERR( err )( "Invalid tag handle", MsqError::INVALID_ARG );
349 : 0 : return false;
350 : : }
351 : :
352 : 177 : TagData* tag = tagList[tag_index];
353 [ + + ][ - + ]: 177 : return 0 != tag->vertexData || tag->defaultValue;
354 : : }
355 : :
356 : 52 : bool MeshImplTags::tag_has_element_data( size_t tag_index, MsqError& err )
357 : : {
358 : 52 : --tag_index;
359 [ + - ][ - + ]: 52 : if( tag_index >= tagList.size() || !tagList[tag_index] )
[ - + ]
360 : : {
361 [ # # ]: 0 : MSQ_SETERR( err )( "Invalid tag handle", MsqError::INVALID_ARG );
362 : 0 : return false;
363 : : }
364 : :
365 : 52 : TagData* tag = tagList[tag_index];
366 [ - + ][ # # ]: 52 : return 0 != tag->elementData || tag->defaultValue;
367 : : }
368 : :
369 : 61 : MeshImplTags::TagIterator MeshImplTags::tag_begin()
370 : : {
371 : 61 : size_t index = 0;
372 [ + + ][ + + ]: 122 : while( index < tagList.size() && tagList[index] == NULL )
[ + + ]
373 : 61 : ++index;
374 : 61 : return TagIterator( this, index );
375 : : }
376 : :
377 : 13 : MeshImplTags::TagIterator MeshImplTags::TagIterator::operator++()
378 : : {
379 : 13 : ++index;
380 [ + + ][ - + ]: 13 : while( index < tags->tagList.size() && NULL == tags->tagList[index] )
[ - + ]
381 : 0 : ++index;
382 : 13 : return TagIterator( tags, index );
383 : : }
384 : :
385 : 0 : MeshImplTags::TagIterator MeshImplTags::TagIterator::operator--()
386 : : {
387 : 0 : --index;
388 [ # # ][ # # ]: 0 : while( index < tags->tagList.size() && NULL == tags->tagList[index] )
[ # # ]
389 : 0 : --index;
390 : 0 : return TagIterator( tags, index );
391 : : }
392 : :
393 : 0 : MeshImplTags::TagIterator MeshImplTags::TagIterator::operator++( int )
394 : : {
395 : 0 : size_t old = index;
396 : 0 : ++index;
397 [ # # ][ # # ]: 0 : while( index < tags->tagList.size() && NULL == tags->tagList[index] )
[ # # ]
398 : 0 : ++index;
399 : 0 : return TagIterator( tags, old );
400 : : }
401 : :
402 : 0 : MeshImplTags::TagIterator MeshImplTags::TagIterator::operator--( int )
403 : : {
404 : 0 : size_t old = index;
405 : 0 : --index;
406 [ # # ][ # # ]: 0 : while( index < tags->tagList.size() && NULL == tags->tagList[index] )
[ # # ]
407 : 0 : --index;
408 : 0 : return TagIterator( tags, old );
409 : : }
410 : :
411 [ + - ][ + - ]: 128 : } // namespace MBMesquite
|