Rocstar  1.0
Rocstar multiphysics simulation application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Mesh/MeshImplTags.cpp
Go to the documentation of this file.
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  kraftche@cae.wisc.edu
24 
25  ***************************************************************** */
26 
27 #include "MeshImplTags.hpp"
28 #include "MsqError.hpp"
29 #include <cassert>
30 #include <cstdlib>
31 #include <cstring>
32 
33 
34 namespace Mesquite {
35 
36 
38 {
39  if (elementData)
40  free(elementData);
41  if (vertexData)
42  free(vertexData);
43  if (defaultValue)
44  free(defaultValue);
45 }
46 
47 
49 {
50  for (msq_std::vector<TagData*>::iterator iter = tagList.begin();
51  iter != tagList.end(); ++iter)
52  if (*iter)
53  delete *iter;
54 
55  tagList.clear();
56 }
57 
59 {
60  switch( type ) {
61  case Mesh::BYTE: return 1;
62  case Mesh::BOOL: return sizeof(bool);
63  case Mesh::DOUBLE: return sizeof(double);
64  case Mesh::INT: return sizeof(int);
65  case Mesh::HANDLE: return sizeof(void*);
66  default: assert(0); return 0;
67  }
68 }
69 
70 size_t MeshImplTags::create( const msq_std::string& name,
71  Mesh::TagType type,
72  unsigned length,
73  const void* defval,
74  MsqError& err )
75 {
76  size_t h = handle( name, err );
77  if (h)
78  {
80  return 0;
81  }
82 
83  if (length == 0 || size_from_tag_type(type) == 0)
84  {
86  return 0;
87  }
88 
89  TagData* tag = new TagData( name, type, length );
90  h = tagList.size();
91  tagList.push_back(tag);
92 
93  if (defval)
94  {
95  tag->defaultValue = malloc( tag->desc.size );
96  memcpy( tag->defaultValue, defval, tag->desc.size );
97  }
98 
99  return h+1;
100 }
101 
103  MsqError& err )
104 {
105  size_t h = handle( desc.name.c_str(), err );
106  if (h)
107  {
108  MSQ_SETERR(err)(desc.name.c_str(), MsqError::TAG_ALREADY_EXISTS);
109  return 0;
110  }
111 
112  if (desc.size == 0 || (desc.size % size_from_tag_type(desc.type)) != 0)
113  {
115  return 0;
116  }
117 
118  TagData* tag = new TagData( desc );
119  h = tagList.size();
120  tagList.push_back(tag);
121 
122  return h+1;
123 }
124 
125 void MeshImplTags::destroy( size_t tag_index, MsqError& err )
126 {
127  --tag_index;
128  if (tag_index >= tagList.size() || 0 == tagList[tag_index])
129  {
131  return ;
132  }
133 
134  delete tagList[tag_index];
135  tagList[tag_index] = 0;
136 }
137 
138 size_t MeshImplTags::handle( const msq_std::string& name, MsqError& err ) const
139 {
140  for (size_t i = 0; i < tagList.size(); ++i)
141  if (tagList[i] && tagList[i]->desc.name == name)
142  return i+1;
143 
144  return 0;
145 }
146 
147 const TagDescription& MeshImplTags::properties( size_t tag_index, MsqError& err ) const
148 {
149  static TagDescription dummy_desc;
150  --tag_index;
151 
152  if (tag_index >= tagList.size() || !tagList[tag_index])
153  {
154  MSQ_SETERR(err)("Invalid tag handle", MsqError::INVALID_ARG);
155  return dummy_desc;
156  }
157 
158  return tagList[tag_index]->desc;
159 }
160 
161 
162 void MeshImplTags::set_element_data( size_t tag_index,
163  size_t num_indices,
164  const size_t* index_array,
165  const void* values,
166  MsqError& err )
167 {
168  size_t i;
169  char* data;
170  --tag_index;
171  if (tag_index >= tagList.size() || !tagList[tag_index])
172  {
173  MSQ_SETERR(err)("Invalid tag handle", MsqError::INVALID_ARG);
174  return;
175  }
176 
177  TagData* tag = tagList[tag_index];
178 
179  // Get highest element index
180  size_t total = tag->elementCount;
181  for (i = 0; i < num_indices; ++i)
182  if (index_array[i] >= total)
183  total = index_array[i] + 1;
184 
185  // If need more space
186  if (total > tag->elementCount)
187  {
188  // allocate more space
189  tag->elementData = realloc( tag->elementData, tag->desc.size * total );
190  // if a default value, initialize new space with it
191  if (tag->defaultValue)
192  {
193  data = ((char*)tag->elementData) + tag->elementCount * tag->desc.size;
194  for (i = tag->elementCount; i < total; ++i)
195  {
196  memcpy( data, tag->defaultValue, tag->desc.size );
197  data += tag->desc.size;
198  }
199  }
200  tag->elementCount = total;
201  }
202 
203  // Store passed tag values
204  data = (char*)tag->elementData;
205  const char* iter = (const char*)values;
206  for (i = 0; i < num_indices; ++i)
207  {
208  memcpy( data + index_array[i]*tag->desc.size, iter, tag->desc.size );
209  iter += tag->desc.size;
210  }
211 }
212 
213 void MeshImplTags::get_element_data( size_t tag_index,
214  size_t num_indices,
215  const size_t* index_array,
216  void* values,
217  MsqError& err ) const
218 {
219  --tag_index;
220  if (tag_index >= tagList.size() || !tagList[tag_index])
221  {
222  MSQ_SETERR(err)("Invalid tag handle", MsqError::INVALID_ARG);
223  return;
224  }
225 
226  TagData* tag = tagList[tag_index];
227 
228  char* iter = (char*)values;
229  const char* data = (const char*)tag->elementData;
230 
231  for (size_t i = 0; i < num_indices; ++i)
232  {
233  const void* ptr;
234  size_t index = index_array[i];
235  if (index >= tag->elementCount)
236  {
237  ptr = tag->defaultValue;
238  if (!ptr)
239  {
241  return;
242  }
243  }
244  else
245  {
246  ptr = data + index * tag->desc.size;
247  }
248 
249  memcpy( iter, ptr, tag->desc.size );
250  iter += tag->desc.size;
251  }
252 }
253 
254 void MeshImplTags::set_vertex_data( size_t tag_index,
255  size_t num_indices,
256  const size_t* index_array,
257  const void* values,
258  MsqError& err )
259 {
260  size_t i;
261  char* data;
262  --tag_index;
263  if (tag_index >= tagList.size() || !tagList[tag_index])
264  {
265  MSQ_SETERR(err)("Invalid tag handle", MsqError::INVALID_ARG);
266  return;
267  }
268 
269  TagData* tag = tagList[tag_index];
270 
271  // Get highest element index
272  size_t total = tag->vertexCount;
273  for (i = 0; i < num_indices; ++i)
274  if (index_array[i] >= total)
275  total = index_array[i] + 1;
276 
277  // If need more space
278  if (total > tag->vertexCount)
279  {
280  // allocate more space
281  tag->vertexData = realloc( tag->vertexData, tag->desc.size * total );
282  // if a default value, initialize new space with it
283  if (tag->defaultValue)
284  {
285  data = ((char*)tag->vertexData) + tag->vertexCount * tag->desc.size;
286  for (i = tag->vertexCount; i < total; ++i)
287  {
288  memcpy( data, tag->defaultValue, tag->desc.size );
289  data += tag->desc.size;
290  }
291  }
292  tag->vertexCount = total;
293  }
294 
295  // Store passed tag values
296  data = (char*)tag->vertexData;
297  const char* iter = (const char*)values;
298  for (i = 0; i < num_indices; ++i)
299  {
300  memcpy( data + index_array[i]*tag->desc.size, iter, tag->desc.size );
301  iter += tag->desc.size;
302  }
303 }
304 
305 void MeshImplTags::get_vertex_data( size_t tag_index,
306  size_t num_indices,
307  const size_t* index_array,
308  void* values,
309  MsqError& err ) const
310 {
311  --tag_index;
312  if (tag_index >= tagList.size() || !tagList[tag_index])
313  {
314  MSQ_SETERR(err)("Invalid tag handle", MsqError::INVALID_ARG);
315  return;
316  }
317 
318  TagData* tag = tagList[tag_index];
319 
320  char* iter = (char*)values;
321  const char* data = (const char*)tag->vertexData;
322 
323  for (size_t i = 0; i < num_indices; ++i)
324  {
325  const void* ptr;
326  size_t index = index_array[i];
327  if (index >= tag->vertexCount)
328  {
329  ptr = tag->defaultValue;
330  if (!ptr)
331  {
333  return;
334  }
335  }
336  else
337  {
338  ptr = data + index * tag->desc.size;
339  }
340 
341  memcpy( iter, ptr, tag->desc.size );
342  iter += tag->desc.size;
343  }
344 }
345 
346 bool MeshImplTags::tag_has_vertex_data( size_t tag_index, MsqError& err )
347 {
348  --tag_index;
349  if (tag_index >= tagList.size() || !tagList[tag_index])
350  {
351  MSQ_SETERR(err)("Invalid tag handle", MsqError::INVALID_ARG);
352  return false;
353  }
354 
355  TagData* tag = tagList[tag_index];
356  return 0 != tag->vertexData || tag->defaultValue;
357 }
358 
359 bool MeshImplTags::tag_has_element_data( size_t tag_index, MsqError& err )
360 {
361  --tag_index;
362  if (tag_index >= tagList.size() || !tagList[tag_index])
363  {
364  MSQ_SETERR(err)("Invalid tag handle", MsqError::INVALID_ARG);
365  return false;
366  }
367 
368  TagData* tag = tagList[tag_index];
369  return 0 != tag->elementData || tag->defaultValue;
370 }
371 
373 {
374  size_t index = 0;
375  while (index < tagList.size() && tagList[index] == NULL)
376  ++index;
377  return TagIterator( this, index );
378 }
379 
381 {
382  ++index;
383  while (index < tags->tagList.size() || NULL == tags->tagList[index])
384  ++index;
385  return TagIterator( tags, index );
386 }
387 
389 {
390  --index;
391  while (index < tags->tagList.size() || NULL == tags->tagList[index])
392  --index;
393  return TagIterator( tags, index );
394 }
395 
397 {
398  size_t old = index;
399  ++index;
400  while (index < tags->tagList.size() || NULL == tags->tagList[index])
401  ++index;
402  return TagIterator( tags, old );
403 }
404 
406 {
407  size_t old = index;
408  --index;
409  while (index < tags->tagList.size() || NULL == tags->tagList[index])
410  --index;
411  return TagIterator( tags, old );
412 }
413 
414 
415 } //namespace Mesquite
size_t handle(const msq_std::string &name, MsqError &err) const
Get tag index from name.
void destroy(size_t tag_index, MsqError &err)
Remove a tag.
void clear()
Clear all data.
Used to hold the error state and return it to the application.
TagType
The type of a tag.
msq_std::string name
Tag name.
size_t vertexCount
number of entries in vertexData
Attempt to create tag that already exists.
size_t elementCount
number of entries in elementData
double length(Vector3D *const v, int n)
bool tag_has_vertex_data(size_t index, MsqError &err)
Check if any vertices have tag.
invalid function argument passed
void get_vertex_data(size_t tag_handle, size_t num_indices, const size_t *elem_indices, void *tag_data, MsqError &err) const
Get tag data on vertices.
#define MSQ_SETERR(err)
Macro to set error - use err.clear() to clear.
blockLoc i
Definition: read.cpp:79
size_t create(const msq_std::string &name, Mesh::TagType type, unsigned length, const void *defval, MsqError &err)
Create a new tag.
void * defaultValue
Default value for tag.
void * vertexData
per-vertex data, or NULL if none has been set.
Iterate over list of valid tag handles.
Specified tag does not exist.
msq_std::vector< TagData * > tagList
void * elementData
per-element data, or NULL if none has been set.
bool tag_has_element_data(size_t index, MsqError &err)
Check if any elements have tag.
static size_t size_from_tag_type(Mesh::TagType type)
Get the size of the passed data type.
const TagDescription & properties(size_t tag_handle, MsqError &err) const
Get tag properties.
for(;;)
void set_vertex_data(size_t tag_handle, size_t num_indices, const size_t *elem_indices, const void *tag_data, MsqError &err)
Set tag data on vertices.
void set_element_data(size_t tag_handle, size_t num_indices, const size_t *elem_indices, const void *tag_data, MsqError &err)
Set tag data on elements.
size_t size
Size of tag data (sizeof(type)*array_length)
const TagDescription desc
tag meta data
void get_element_data(size_t tag_handle, size_t num_indices, const size_t *elem_indices, void *tag_data, MsqError &err) const
Get tag data on elements.
Mesh::TagType type
Tag data type.