Rocstar  1.0
Rocstar multiphysics simulation application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MeshTSTT.cpp
Go to the documentation of this file.
1 /* *****************************************************************
2  MESQUITE -- The Mesh Quality Improvement Toolkit
3 
4  Copyright 2004 Sandia Corporation and Argonne National
5  Laboratory. Under the terms of Contract DE-AC04-94AL85000
6  with Sandia Corporation, the U.S. Government 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  diachin2@llnl.gov, djmelan@sandia.gov, mbrewer@sandia.gov,
24  pknupp@sandia.gov, tleurent@mcs.anl.gov, tmunson@mcs.anl.gov
25 
26  ***************************************************************** */
36 #include <sidl_cxx.hh>
37 #include "TSTTB.hh"
38 #include "TSTTM.hh"
39 #include "MeshTSTT.hpp"
40 #include "MsqDebug.hpp"
41 #include "MsqVertex.hpp"
42 #include "MsqError.hpp"
43 #include "MeshInterface.hpp"
44 #include "TSTTUtil.hpp"
45 
46 #ifdef MSQ_USE_OLD_STD_HEADERS
47 # include <map.h>
48 # include <set.h>
49 #else
50 # include <map>
51 # include <set>
52 #endif
53 
54 #define OPAQUE_TYPE_OPAQUE_PADDED 0
55 #define OPAQUE_TYPE_OPAQUE_PACKED 1
56 #define OPAQUE_TYPE_CHAR 2
57 #define OPAQUE_TYPE_UCHAR 3
58 #define OPAQUE_TYPE_BYTE OPAQUE_TYPE_UCHAR
59 #define TSTT_OPAQUE_TAG_TYPE OPAQUE_TYPE_CHAR
60 
61 
62 namespace Mesquite
63 {
64 
65 
66 
67 /*************************************************************************
68  * Iterator Definitions
69  *
70  * This file contains three alternate iterator implementations. After
71  * some performance testing, two should be removed.
72  ************************************************************************/
73 
76 {
77  private:
78  TSTTM::Entity tsttMesh;
79  void* tsttIter;
80  bool notAtEnd;
81  void* entityHandle;
87  inline void get_next_entity()
88  { notAtEnd = tsttMesh.getNextEntIter( tsttIter, entityHandle ); }
89 
90  public:
91 
98  TSTTIterator( TSTTM::Entity& mesh,
99  void* meshset,
100  TSTTM::EntityType type,
102  MsqError& err );
104  virtual void restart();
106  virtual Mesh::EntityHandle operator*() const;
108  virtual bool is_at_end() const;
110  virtual void operator++();
111 
112  virtual ~TSTTIterator();
113 };
114 
115 
116 
117 TSTTIterator::TSTTIterator( TSTTM::Entity& mesh, void* meshset,
118  TSTTM::EntityType type, TSTTM::EntityTopology topo,
119  MsqError& err )
120  : tsttMesh(mesh), tsttIter(0), notAtEnd(true), entityHandle(0)
121 {
122  try {
123  tsttMesh.initEntIter( meshset, type, topo, tsttIter );
124  get_next_entity();
125  }
126  catch (TSTTB::Error& tstt_err) {
128  }
129 }
130 
132 {
133  if (tsttIter)
134  tsttMesh.endEntIter( tsttIter );
135 }
136 
138 {
139  try {
140  tsttMesh.resetEntIter( tsttIter );
141  get_next_entity();
142  }
143  catch (TSTTB::Error& tstt_err) {
144  process_tstt_error( tstt_err );
145  throw;
146  }
147 }
148 
150 {
151  return entityHandle;
152 }
153 
155 {
156  return !notAtEnd;
157 }
158 
160 {
161  try {
162  get_next_entity();
163  }
164  catch (TSTTB::Error& tstt_err) {
165  process_tstt_error( tstt_err );
166  throw;
167  }
168 }
169 
170 
173 {
174  private:
175  sidl::array<void*>::const_iterator iter;
176  const sidl::array<void*> array;
177 
178  public:
179 
181  SIDLIterator( const sidl::array<void*>& a )
182  : iter( a.begin() ), array( a ) {}
183 
185  virtual void restart() { iter = array.begin(); }
186 
188  virtual Mesh::EntityHandle operator*() const { return *iter; }
189 
191  virtual bool is_at_end() const { return iter == array.end(); }
192 
194  virtual void operator++() { ++iter; }
195 };
196 
199 {
200  private:
201 
202  sidl::array<void*> handleArray;
203  void* tsttIter;
204  int index, count;
205  bool notAtEnd;
206  TSTTM::Arr& myMesh;
207 
208  inline void get_next_array()
209  {
210  index = count = 0;
211  notAtEnd = myMesh.getEntArrNextIter( tsttIter, handleArray, count ) && count;
212  }
213 
214  public:
215 
216  TSTTArrIter( TSTTM::Arr& mesh,
217  void* meshset,
218  TSTTM::EntityType type,
220  unsigned buffer_count = 1024 );
221 
223  virtual void restart();
225  virtual Mesh::EntityHandle operator*() const;
227  virtual bool is_at_end() const;
229  virtual void operator++();
230 
231  virtual ~TSTTArrIter();
232 };
233 
234 TSTTArrIter::TSTTArrIter( TSTTM::Arr& mesh,
235  void* meshset,
236  TSTTM::EntityType type,
238  unsigned buffer_count )
239  : handleArray( alloc_sidl_vector<void*>(buffer_count) ),
240  tsttIter(0),
241  index(0),
242  count(0),
243  notAtEnd(false),
244  myMesh( mesh )
245 {
246  mesh.initEntArrIter( meshset, type, topo, buffer_count, tsttIter );
247  get_next_array();
248 }
249 
251 {
252  try {
253  if (tsttIter)
254  myMesh.endEntArrIter( tsttIter );
255  }
256  catch (TSTTB::Error& tstt_err) {
257  process_tstt_error( tstt_err );
258  throw;
259  }
260 }
261 
263 {
264  try {
265  myMesh.resetEntArrIter( tsttIter );
266  get_next_array();
267  }
268  catch (TSTTB::Error& tstt_err) {
269  process_tstt_error( tstt_err );
270  throw;
271  }
272 }
273 
275 {
276  return handleArray.get(index);
277 }
278 
280 {
281  return index == count && !notAtEnd;
282 }
283 
285 {
286  try {
287  ++index;
288  if (index == count && notAtEnd)
289  get_next_array();
290  }
291  catch (TSTTB::Error& tstt_err) {
292  process_tstt_error( tstt_err );
293  throw;
294  }
295 }
296 
297 
298 
299 
300 
301 /*************************************************************************
302  * Mesh Interface
303  ************************************************************************/
304 
307  class MeshTSTTImpl : public MeshTSTT
308  {
309  public:
310 
311  MeshTSTTImpl(TSTTM::Mesh& tstt_mesh, MsqError &err);
312  virtual ~MeshTSTTImpl();
313 
325  virtual void set_active_set( void* element_set, MsqError& );
326 
327 
329  virtual int get_geometric_dimension(Mesquite::MsqError &/*err*/);
330 
341  virtual void get_all_sizes( size_t& vertex_count,
342  size_t& element_count,
343  size_t& vertex_use_count,
344  MsqError& err );
345 
364  virtual void get_all_mesh( VertexHandle* vert_array, size_t vert_len,
365  ElementHandle* elem_array, size_t elem_len,
366  size_t* elem_conn_offsets, size_t offset_len,
367  size_t* elem_conn_indices, size_t index_len,
368  MsqError& err );
369 
371  virtual VertexIterator* vertex_iterator(MsqError &err);
372 
375 
377  virtual bool vertex_is_fixed(VertexHandle vertex, MsqError &err);
378 
380  virtual void vertices_are_on_boundary(VertexHandle vert_array[], bool on_bnd[],
381  size_t num_vtx, MsqError &err);
382 
384  virtual void vertices_get_coordinates(const VertexHandle vert_array[],
385  MsqVertex* coordinates,
386  size_t num_vtx, MsqError &err);
388  virtual void vertex_set_coordinates(VertexHandle vertex,
389  const Vector3D &coordinates, MsqError &err);
390 
392  virtual void vertex_set_byte (VertexHandle vertex,
393  unsigned char byte, MsqError &err);
395  virtual void vertices_set_byte (VertexHandle *vert_array,
396  unsigned char *byte_array,
397  size_t array_size, MsqError &err);
398 
400  virtual void vertex_get_byte(VertexHandle vertex,
401  unsigned char *byte, MsqError &err);
403  virtual void vertices_get_byte(VertexHandle *vert_array,
404  unsigned char *byte_array,
405  size_t array_size, MsqError &err);
406 
408  virtual size_t vertex_get_attached_element_count(VertexHandle vertex, MsqError &err);
409 
411  virtual void vertex_get_attached_elements(VertexHandle vertex,
412  ElementHandle* elem_array,
413  size_t sizeof_elem_array,
414  MsqError &err);
415 
418  MsqError &err);
419 
420  virtual size_t get_vertex_use_count( ElementHandle* array,
421  size_t length,
422  MsqError& err );
423 
459  virtual void elements_get_attached_vertices(ElementHandle *elem_handles,
460  size_t num_elems,
461  VertexHandle *vert_handles,
462  size_t &sizeof_vert_handles,
463  size_t *csr_data,
464  size_t &sizeof_csr_data,
465  size_t *csr_offsets,
466  MsqError &err);
467 
468 
470  virtual EntityTopology element_get_topology(ElementHandle entity_handle,
471  MsqError &err);
473  virtual void elements_get_topologies(ElementHandle *element_handle_array,
474  EntityTopology *element_topologies,
475  size_t num_elements, MsqError &err);
476 
477 //**************** Memory Management ****************
479  virtual void release_entity_handles(EntityHandle *handle_array,
480  size_t num_handles, MsqError &err);
481 
482  // Instead of deleting a Mesh when you think you are done,
483  // call release(). In simple cases, the implementation could
484  // just call the destructor. More sophisticated implementations
485  // may want to keep the Mesh object to live longer than Mesquite
486  // is using it.
487  virtual void release();
488 
489 //*************** Tags ***********
490 
503  virtual TagHandle tag_create( const msq_std::string& tag_name,
504  TagType type, unsigned length,
505  const void* default_value,
506  MsqError &err);
507 
512  virtual void tag_delete( TagHandle handle, MsqError& err );
513 
514 
516  virtual TagHandle tag_get( const msq_std::string& name,
517  MsqError& err );
518 
527  virtual void tag_properties( TagHandle handle,
528  msq_std::string& name_out,
529  TagType& type_out,
530  unsigned& length_out,
531  MsqError& err );
532 
543  virtual void tag_set_element_data( TagHandle handle,
544  size_t num_elems,
545  const ElementHandle* elem_array,
546  const void* tag_data,
547  MsqError& err );
548 
559  virtual void tag_set_vertex_data ( TagHandle handle,
560  size_t num_elems,
561  const VertexHandle* node_array,
562  const void* tag_data,
563  MsqError& err );
564 
565 
576  virtual void tag_get_element_data( TagHandle handle,
577  size_t num_elems,
578  const ElementHandle* elem_array,
579  void* tag_data,
580  MsqError& err );
581 
592  virtual void tag_get_vertex_data ( TagHandle handle,
593  size_t num_elems,
594  const VertexHandle* node_array,
595  void* tag_data,
596  MsqError& err );
597 
598  protected:
599 
600  void set_int_tag( void* tag, void* meshset, int value, MsqError& err );
601 
603  void popupate_input_elements( ) throw( TSTTB::Error );
604 
605  private:
607  void tag_set_data ( TagHandle handle,
608  size_t num_elems,
609  const EntityHandle* handle_array,
610  const void* tag_data,
611  MsqError& err );
612 
614  void tag_get_data( TagHandle handle,
615  size_t num_elems,
616  const EntityHandle* handle_array,
617  void* tag_data,
618  MsqError& err );
619 
621  TSTTM::Mesh meshIFace;
623  TSTTM::Entity entIFace;
624  TSTTB::EntTag tagIFace;
626  TSTTM::Arr arrIFace;
627  TSTTB::ArrTag arrTagIFace;
629  TSTTM::Modify modIFace;
631  TSTTB::EntSet setIFace;
632 
634  bool haveMesh;
636  void* elementSet;
638  void* nodeSet;
643  msq_std::set<void*> inputElements;
644 
651  TSTTM::EntityType inputSetType;
652 
662 // TagHandle vertexIndexTag;
664 // bool createdVertexIndexTag;
665 
667  EntityTopology topologyMap[TSTTM::EntityTopology_ALL_TOPOLOGIES+1];
668 
670  sidl::array<void*> vertexAdjElements;
676  void cache_adjacent_elements( void* vertex_handle, MsqError& err );
677  };
678 
679 /*************************************************************************
680  * Mesh Definition
681  ************************************************************************/
682 
683 MeshTSTT* MeshTSTT::create( TSTTM::Mesh& mesh, void* meshset, MsqError& err )
684 {
685  MeshTSTT* result = new MeshTSTTImpl( mesh, err );
686  if (MSQ_CHKERR(err))
687  {
688  delete result;
689  return 0;
690  }
691  result->set_active_set( meshset, err );
692  if (MSQ_CHKERR(err))
693  {
694  delete result;
695  return 0;
696  }
697  return result;
698 }
699 
700 MeshTSTT* MeshTSTT::create( TSTTM::Mesh& mesh, MsqError& err )
701 {
702  MeshTSTT* result = new MeshTSTTImpl( mesh, err );
703  if (MSQ_CHKERR(err))
704  {
705  delete result;
706  return 0;
707  }
708  return result;
709 }
710 
712 
713 
714 MeshTSTTImpl::MeshTSTTImpl(TSTTM::Mesh& tstt_mesh, Mesquite::MsqError& err)
715  : meshIFace(tstt_mesh),
716  elementSet(0), nodeSet(0),
717  inputSetType( TSTTM::EntityType_ALL_TYPES ),
718  byteTag(0), createdByteTag(false),
719  fixedTag(0), createdFixedTag(false),
720  vertexAdjElementSize(0), cachedAdjVertex(0)
721 // ,vertexIndexTag(0), createdVertexIndexTag(false)
722 {
723  // Initialize topology map
724 
725  const size_t mapsize = sizeof(topologyMap) / sizeof(Mesquite::EntityTopology);
726  if (mapsize < TSTTM::EntityTopology_ALL_TOPOLOGIES)
727  {
728  MSQ_SETERR(err)("MeshTSTT needs to be updated for new TSTT element topologies.",
730  return;
731  }
732 
733  for (size_t i = 0; i <= TSTTM::EntityTopology_ALL_TOPOLOGIES; ++i)
735 
736  topologyMap[TSTTM::EntityTopology_TRIANGLE ] = Mesquite::TRIANGLE;
737  topologyMap[TSTTM::EntityTopology_QUADRILATERAL] = Mesquite::QUADRILATERAL;
738  topologyMap[TSTTM::EntityTopology_TETRAHEDRON ] = Mesquite::TETRAHEDRON;
739  topologyMap[TSTTM::EntityTopology_HEXAHEDRON ] = Mesquite::HEXAHEDRON;
740  topologyMap[TSTTM::EntityTopology_PRISM ] = Mesquite::PRISM;
741  topologyMap[TSTTM::EntityTopology_PYRAMID ] = Mesquite::PYRAMID;
742 
743  try {
744  // Attempt to cast to single-entity query interface
745  entIFace = tstt_mesh;
746  if (!entIFace)
747  {
748  MSQ_SETERR(err)( "TSTTM::Mesh does not implement TSTTM::EntTag",
750  return;
751  }
752  // Attempt cast to multi-entity query interface
753  arrIFace = tstt_mesh;
754  if (!arrIFace)
755  {
756  MSQ_SETERR(err)( "TSTTM::Mesh does not implement TSTTM::ArrTag",
758  return;
759  }
760  // Attempt cast to modify interface
761  modIFace = tstt_mesh;
762  if (!arrIFace)
763  {
764  MSQ_SETERR(err)( "TSTTM::Mesh does not implement TSTTM::Modify",
766  return;
767  }
768  // Attempt cast to entity set interface
769  setIFace = tstt_mesh;
770  if (!arrIFace)
771  {
772  MSQ_SETERR(err)( "TSTTM::Mesh does not implement TSTTM::EntSet",
774  return;
775  }
776  // Get tag interface
777  tagIFace = tstt_mesh;
778  if (!tagIFace)
779  {
780  MSQ_SETERR(err)( "TSTTM::Mesh does not implement TSTTB::EntTag",
782  return;
783  }
784  // Get tag interface
785  arrTagIFace = tstt_mesh;
786  if (!arrTagIFace)
787  {
788  MSQ_SETERR(err)( "TSTTM::Mesh does not implement TSTTB::ArrTag",
790  return;
791  }
792 
793  // Get tag for fixed flag
794  try {
795  fixedTag = tagIFace.getTagHandle( VERTEX_FIXED_TAG_NAME );
796 
797  // Double-check types incase tag already existed
798  if (tagIFace.getTagSize(fixedTag) != sizeof(int) ||
799  tagIFace.getTagType(fixedTag) != TSTTB::TagValueType_INTEGER)
800  {
802  "Tag \"%s\" exists with invalid type/size",
804  return;
805  }
806  } catch (...) {
807  fixedTag = 0;
808  }
809 
810  // Get/create tag for vertex byte
811  try {
812  byteTag = tagIFace.getTagHandle( VERTEX_BYTE_TAG_NAME );
813  } catch (...) {}
814 
815  if (!byteTag) {
816  tagIFace.createTag( VERTEX_BYTE_TAG_NAME, sizeof(int), TSTTB::TagValueType_INTEGER, byteTag );
817  createdByteTag = true;
818  }
819  // Double-check types incase tag already existed
820  if (tagIFace.getTagSize(byteTag) != sizeof(int) ||
821  tagIFace.getTagType(byteTag) != TSTTB::TagValueType_INTEGER)
822  {
824  "Tag \"%s\" exists with invalid type/size",
826  return;
827  }
828 
829  // Clear vertex byte tag
830  set_int_tag( byteTag, nodeSet, 0, err );
831  if (err)
832  return;
833 
834  // Get/create tag for vertex index
835 /*
836  //try {
837  // vertexIndexTag = tagIFace.getTagHandle( VERTEX_INDEX_TAG_NAME );
838  //} catch (...) {}
839 
840  if (!vertexIndexTag) {
841  tagIFace.createTag( VERTEX_INDEX_TAG_NAME, sizeof(int), TSTTB::TagValueType_INTEGER, byteTag );
842  createdVertexIndexTag = true;
843  }
844  // Double-check types incase tag already existed
845  if (tagIFace.getTagSize(vertexIndexTag) != sizeof(int) ||
846  tagIFace.getTagType(vertexIndexTag) != TSTTB::TagValueType_INTEGER)
847  {
848  MSQ_SETERR(err)( MsqError::INVALID_STATE,
849  "Tag \"%s\" exists with invalid type/size",
850  VERTEX_INDEX_TAG_NAME );
851  return;
852  }
853 */
854  }
855  catch (TSTTB::Error &tstt_err) {
857  try {
858  if (createdFixedTag)
859  tagIFace.destroyTag( fixedTag, false );
860  if (createdByteTag)
861  tagIFace.destroyTag( byteTag, false );
862 // if (createdVertexIndexTag)
863 // tagIFace.destroyTag( vertexIndexTag, false );
864  }
865  catch (...) {}
866  }
867  catch(...) {
868  MSQ_SETERR(err)("Uknown exception",MsqError::INTERNAL_ERROR);
869  }
870 }
871 
873 {
874  try {
875  if (elementSet)
876  setIFace.destroyEntSet( elementSet );
877  if (nodeSet)
878  setIFace.destroyEntSet( nodeSet );
879 
880  if (createdFixedTag)
881  tagIFace.destroyTag( fixedTag, false );
882  if (createdByteTag)
883  tagIFace.destroyTag( byteTag, false );
884 // if (createdVertexIndexTag)
885 // tagIFace.destroyTag( vertexIndexTag, false );
886  }
887  catch (TSTTB::Error& tstt_err ) {
888  process_tstt_error(tstt_err);
889  throw;
890  }
891 }
892 
893 
895  void* elem_set,
896  int value,
897  MsqError& err )
898 {
899  const unsigned BUFFER_COUNT = 1024;
900 
901  sidl::array<int> value_array( alloc_sidl_vector<int>( BUFFER_COUNT, value ) );
902 
903  sidl::array<void*> handle_array( alloc_sidl_vector<void*>( BUFFER_COUNT ) );
904  int count = BUFFER_COUNT;
905  void* iter = 0;
906  bool more;
907 
908  try {
909 
910  arrIFace.initEntArrIter( elem_set,
911  TSTTM::EntityType_VERTEX,
912  TSTTM::EntityTopology_POINT,
913  BUFFER_COUNT, iter );
914 
915  do {
916  more = arrIFace.getEntArrNextIter( iter, handle_array, count );
917  if (count > 0)
918  arrTagIFace.setIntArrData( handle_array, count, tag, value_array, count );
919  } while (more);
920 
921  arrIFace.endEntArrIter( iter );
922  }
923 
924  catch (TSTTB::Error &tstt_err) {
925  if( iter ) try { arrIFace.endEntArrIter( iter ); } catch (...) {}
927  }
928 }
929 
930 
931 void MeshTSTTImpl::set_active_set( void* elem_set, MsqError& err )
932 {
933  const int ELEM_BUFFER_SIZE = 1024;
934  const int NODE_BUFFER_SIZE = 27 * ELEM_BUFFER_SIZE;
935  sidl::array<void*> elements( alloc_sidl_vector<void*>( ELEM_BUFFER_SIZE ) );
936  sidl::array<void*> nodes( alloc_sidl_vector<void*>( NODE_BUFFER_SIZE ) );
937  sidl::array<int> offsets( alloc_sidl_vector<int >( ELEM_BUFFER_SIZE ) );
938  void* iter = 0;
939 
940  try {
941 
942  // Create new sets for nodes and elements
943  if (elementSet)
944  {
945  setIFace.destroyEntSet( elementSet );
946  elementSet = 0;
947  }
948  if (nodeSet)
949  {
950  setIFace.destroyEntSet( nodeSet );
951  nodeSet = 0;
952  }
953  setIFace.createEntSet( false, elementSet );
954  setIFace.createEntSet( false, nodeSet );
955 
956  // Iterate over set twice, once for FACEs and once for REGIONs
957  bool have_faces = false, have_regions = false;
958  for (int i = 0; i < 2; ++i)
959  {
960  TSTTM::EntityType type = i ? TSTTM::EntityType_REGION :
961  TSTTM::EntityType_FACE;
962  bool& have_some = i ? have_regions : have_faces;
963 
964  arrIFace.initEntArrIter( elem_set,
965  type,
966  TSTTM::EntityTopology_ALL_TOPOLOGIES,
967  ELEM_BUFFER_SIZE,
968  iter );
969 
970  int count = 0;
971  bool more = false;
972  do {
973  // Add elements to element set
974  more = arrIFace.getEntArrNextIter( iter, elements, count );
975  if (!count) break;
976  setIFace.addEntArrToSet( elements, count, elementSet );
977 
978  // Add nodes to node set
979  int num_nodes, num_offsets;
980  arrIFace.getEntArrAdj( elements, count, TSTTM::EntityType_VERTEX,
981  nodes, num_nodes, offsets, num_offsets );
982  setIFace.addEntArrToSet( nodes, num_nodes, nodeSet );
983 
984  have_some = true;
985  } while (more);
986 
987  arrIFace.endEntArrIter( iter );
988  iter = 0;
989 
990  } // for (type)
991 
992  if (!have_faces)
993  inputSetType = TSTTM::EntityType_REGION;
994  else if (!have_regions)
995  inputSetType = TSTTM::EntityType_FACE;
996  else
997  inputSetType = TSTTM::EntityType_ALL_TYPES;
998 
999  //set_fixed_tag( nodeSet, false, err ); MSQ_ERRRTN(err);
1000  }
1001  catch (TSTTB::Error &tstt_err) {
1002  // If an error occured, try to clean up anything created above
1003 
1004  try {
1005  if (iter) {
1006  arrIFace.endEntArrIter( iter );
1007  iter = 0;
1008  }
1009  }
1010  catch( ... ) {}
1011 
1012  try {
1013  if (elementSet) {
1014  setIFace.destroyEntSet( elementSet );
1015  elementSet = 0;
1016  }
1017  }
1018  catch( ... ) {}
1019 
1020  try {
1021  if (nodeSet) {
1022  setIFace.destroyEntSet( nodeSet );
1023  nodeSet = 0;
1024  }
1025  }
1026  catch( ... ) {}
1027 
1029  }
1030 
1031  // clear cached data
1032  inputElements.clear();
1034  cachedAdjVertex = 0;
1035 }
1036 
1037 void MeshTSTTImpl::popupate_input_elements( ) throw( TSTTB::Error )
1038 {
1039  const int ELEM_BUFFER_SIZE = 1024;
1040  void* handle_array[ELEM_BUFFER_SIZE];
1041  sidl::array<void*> handles = convert_to_sidl_vector( handle_array, ELEM_BUFFER_SIZE );
1042  void* iter;
1043 
1044  inputElements.clear();
1045 
1046  arrIFace.initEntArrIter( elementSet,
1047  TSTTM::EntityType_ALL_TYPES,
1048  TSTTM::EntityTopology_ALL_TOPOLOGIES,
1049  ELEM_BUFFER_SIZE,
1050  iter );
1051 
1052  int count = 0;
1053  bool more = false;
1054  do {
1055  // Add elements to element set
1056  more = arrIFace.getEntArrNextIter( iter, handles, count );
1057  if (!count) break;
1058  setIFace.addEntArrToSet( handles, count, elementSet );
1059 
1060  void** const end_ptr = handle_array + count;
1061  for (void** ptr = handle_array; ptr != end_ptr; ++ptr)
1062  inputElements.insert( *ptr );
1063 
1064  } while (more);
1065 
1066  arrIFace.endEntArrIter( iter );
1067 }
1068 
1069 
1070 
1071 // Returns whether this mesh lies in a 2D or 3D coordinate system.
1073 {
1074  try {
1075  return meshIFace.getGeometricDim();
1076  }
1077  catch (TSTTB::Error &tstt_err) {
1079  return 0;
1080  }
1081 }
1082 
1083 
1084 // Returns a pointer to an iterator that iterates over the
1085 // set of all vertices in this mesh. The calling code should
1086 // delete the returned iterator when it is finished with it.
1087 // If vertices are added or removed from the Mesh after obtaining
1088 // an iterator, the behavior of that iterator is undefined.
1090 {
1091  try {
1092  return new TSTTArrIter( arrIFace,
1093  nodeSet,
1094  TSTTM::EntityType_ALL_TYPES,
1095  TSTTM::EntityTopology_ALL_TOPOLOGIES );
1096  }
1097  catch (TSTTB::Error &tstt_err) {
1099  return 0;
1100  }
1101 }
1102 
1103 // Returns a pointer to an iterator that iterates over the
1104 // set of all top-level elements in this mesh. The calling code should
1105 // delete the returned iterator when it is finished with it.
1106 // If elements are added or removed from the Mesh after obtaining
1107 // an iterator, the behavior of that iterator is undefined.
1109 {
1110  try {
1111  return new TSTTArrIter( arrIFace,
1112  elementSet,
1113  TSTTM::EntityType_ALL_TYPES,
1114  TSTTM::EntityTopology_ALL_TOPOLOGIES );
1115  }
1116  catch (TSTTB::Error &tstt_err) {
1118  return 0;
1119  }
1120 }
1121 
1122 //************ Vertex Properties ********************
1123 // Returns true or false, indicating whether the vertex
1124 // is allowed to be repositioned. True indicates that the vertex
1125 // is fixed and cannot be moved. Note that this is a read-only
1126 // property; this flag can't be modified by users of the
1127 // Mesquite::Mesh interface.
1129 {
1130  // If mesh does not contain a fixed tag, assume no vertices are fixed
1131  if (!fixedTag)
1132  return false;
1133 
1134  try {
1135  return (bool)tagIFace.getIntData( vertex, fixedTag );
1136  }
1137  catch( TSTTB::Error& tstt_err ) {
1139  return true;
1140  }
1141 }
1142 
1143 // Returns true or false, indicating whether the vertex
1144 // is on the boundary. Boundary nodes may be treated as
1145 // a special case by some algorithms or culling methods.
1146 // Note that this is a read-only
1147 // property; this flag can't be modified by users of the
1148 // Mesquite::Mesh interface.
1150  VertexHandle vert_array[],
1151  bool bool_array[],
1152  size_t num_vtx, MsqError &err)
1153 {
1154  // If mesh does not contain a fixed tag, assume no vertices are fixed
1155  if (!fixedTag) {
1156  memset( bool_array, 0, num_vtx * sizeof(bool) );
1157  return;
1158  }
1159 
1160  // Get per-vertex flags from fixedTag
1161  try {
1162  sidl::array<void*> vert_wrapper( convert_to_sidl_vector( vert_array, num_vtx ) );
1163  sidl::array<int> bools = alloc_sidl_vector<int>(num_vtx);
1164 
1165  int num_bools = num_vtx;
1166  arrTagIFace.getIntArrData( vert_wrapper, num_vtx, fixedTag, bools, num_bools );
1167  if (num_vtx != (unsigned)num_bools)
1169 
1170  for (size_t i = 0; i < num_vtx; ++i)
1171  bool_array[i] = bools.get(i);
1172  }
1173  catch(::TSTTB::Error &tstt_err) {
1175  }
1176 }
1177 
1178 // Get vertex coordinates
1180  const Mesquite::Mesh::VertexHandle vert_array[],
1181  MsqVertex* coordinates,
1182  size_t num_vtx,
1183  MsqError &err)
1184 {
1185  double* dbl_array = 0;
1186 
1187  try {
1188  int dim = meshIFace.getGeometricDim();
1189  int dbl_len = dim * num_vtx;
1190 
1191  sidl::array<void*> vertex_wrapper(
1192  convert_to_sidl_vector( const_cast<void**>(vert_array), num_vtx ) );
1193  dbl_array = new double[dbl_len];
1194  sidl::array<double> dbl_wrapper( convert_to_sidl_vector( dbl_array, dbl_len ));
1195 
1196  TSTTM::StorageOrder order = TSTTM::StorageOrder_UNDETERMINED;
1197  meshIFace.getVtxArrCoords( vertex_wrapper, num_vtx, order, dbl_wrapper, dbl_len );
1198  if ((unsigned)dbl_len != dim*num_vtx) {
1200  delete [] dbl_array;
1201  return;
1202  }
1203 
1204  if (dim == 2)
1205  {
1206  if (order == TSTTM::StorageOrder_INTERLEAVED)
1207  {
1208  double* iter = dbl_array;
1209  for (size_t i = 0; i < num_vtx; ++i)
1210  {
1211  coordinates[i].x(*iter); ++iter;
1212  coordinates[i].y(*iter); ++iter;
1213  coordinates[i].z(0);
1214  }
1215  }
1216  else
1217  {
1218  double *xiter = dbl_array;
1219  double *yiter = dbl_array + num_vtx;
1220  for (size_t i = 0; i < num_vtx; ++i)
1221  {
1222  coordinates[i].x(*xiter); ++xiter;
1223  coordinates[i].y(*yiter); ++yiter;
1224  coordinates[i].z(0);
1225  }
1226  }
1227  }
1228  else if(dim == 3)
1229  {
1230  if (order == TSTTM::StorageOrder_INTERLEAVED)
1231  {
1232  double* iter = dbl_array;
1233  for (size_t i = 0; i < num_vtx; ++i)
1234  {
1235  coordinates[i].set(iter);
1236  iter += 3;
1237  }
1238  }
1239  else
1240  {
1241  double *xiter = dbl_array;
1242  double *yiter = dbl_array + num_vtx;
1243  double *ziter = dbl_array + 2*num_vtx;
1244  for (size_t i = 0; i < num_vtx; ++i)
1245  {
1246  coordinates[i].x(*xiter); ++xiter;
1247  coordinates[i].y(*yiter); ++yiter;
1248  coordinates[i].z(*ziter); ++ziter;
1249  }
1250  }
1251  }
1252  else
1253  {
1254  MSQ_SETERR(err)(MsqError::INVALID_STATE, "TSTTB database dimension = %d", dim);
1255  delete [] dbl_array;
1256  return;
1257  }
1258 
1259  }
1260  catch(::TSTTB::Error &tstt_err) {
1262  }
1263 
1264  delete [] dbl_array;
1265 }
1266 
1269  const Vector3D &coordinates, MsqError &err)
1270 {
1271  try {
1272  sidl::array<double> coords(
1273  convert_to_sidl_vector( const_cast<double*>(coordinates.to_array()), 3 ) );
1274  modIFace.setVtxCoords( vertex, coords, 1 );
1275  }
1276  catch(::TSTTB::Error &tstt_err) {
1278  }
1279 }
1280 
1281 // Each vertex has a byte-sized flag that can be used to store
1282 // flags. This byte's value is neither set nor used by the mesh
1283 // implementation. It is intended to be used by Mesquite algorithms.
1284 // Until a vertex's byte has been explicitly set, its value is 0.
1287  unsigned char byte, MsqError &err)
1288 {
1289  try {
1290  int value = byte;
1291  tagIFace.setIntData( vertex, byteTag, value );
1292  }
1293  catch(::TSTTB::Error &tstt_err) {
1295  }
1296 }
1297 
1299  VertexHandle *vert_array,
1300  unsigned char *byte_array,
1301  size_t array_size, MsqError &err)
1302 {
1303  // TSTT implementations seem to be inconsistant with
1304  // regard to setting opaque tags. Set one at a time
1305  // to be safe. This would be much easier if Mesquite
1306  // used a TSTT-defined type for the data, rather than
1307  // a single byte.
1308  try {
1309  sidl::array<void*> handles( convert_to_sidl_vector( vert_array, array_size ));
1310  sidl::array<int> data(alloc_sidl_vector<int>(array_size));
1311  for (size_t i = 0; i < array_size; ++i)
1312  data.set( i, byte_array[i] );
1313  arrTagIFace.setIntArrData( handles, array_size, byteTag, data, array_size );
1314  }
1315  catch(::TSTTB::Error &tstt_err) {
1317  }
1318 }
1319 
1320 // Retrieve the byte value for the specified vertex or vertices.
1321 // The byte value is 0 if it has not yet been set via one of the
1322 // *_set_byte() functions.
1325  unsigned char *byte, MsqError &err)
1326 {
1327  try {
1328  *byte = (unsigned char)tagIFace.getIntData( vertex, byteTag );
1329  }
1330  catch(::TSTTB::Error &tstt_err) {
1332  }
1333 }
1334 
1336  VertexHandle *vert_array,
1337  unsigned char *byte_array,
1338  size_t array_size, MsqError &err)
1339 {
1340  // TSTT implementations seem to be inconsistant with
1341  // regard to setting opaque tags. Set one at a time
1342  // to be safe. This would be much easier if Mesquite
1343  // used a TSTT-defined type for the data, rather than
1344  // a single byte.
1345  try {
1346  sidl::array<void*> handles( convert_to_sidl_vector( vert_array, array_size ));
1347  sidl::array<int> data( alloc_sidl_vector<int>(array_size) );
1348  int32_t junk;
1349  arrTagIFace.getIntArrData( handles, array_size, byteTag, data, junk );
1350 
1351  for (size_t i = 0; i< array_size; ++i )
1352  byte_array[i] = (unsigned char)data.get(i);
1353  }
1354  catch(::TSTTB::Error &tstt_err) {
1356  }
1357 }
1358 
1359 
1360 //**************** Vertex Topology *****************
1361 
1363 {
1364  // If already have data cached for this vertex, just return
1365  if (vtx == cachedAdjVertex)
1366  return;
1367 
1368  // make sure to clear this so that if we fail in the middle,
1369  // we don't end up with invlaid cache data for the prev vertex.
1370  cachedAdjVertex = 0;
1372 
1373  try {
1374  // First try using current array size
1375  bool success;
1376  try {
1378  success = true;
1379  }
1380  catch( ... ) {
1381  success = false;
1382  }
1383 
1384  // If failed, try again and let implementation allocate storage
1385  if (!success) {
1386  vertexAdjElements = sidl::array<void*>();
1388  }
1389 
1390  // Store which vertex we have cached adj data for
1391  cachedAdjVertex = vtx;
1392 
1393  // We need to use inputElements. Fill it if it hasn't
1394  // been filled yet.
1395  if (inputElements.empty())
1397  }
1398  catch(::TSTTB::Error &tstt_err) {
1400  return;
1401  }
1402 
1403  // Remove from list any elements not in the input set
1404  void** write_ptr = convert_from_sidl_vector( vertexAdjElements );
1405  void** const end_ptr = write_ptr + vertexAdjElementSize;
1406  for (void** read_ptr = write_ptr; read_ptr != end_ptr; ++read_ptr)
1407  {
1408  if (inputElements.find( *read_ptr ) != inputElements.end())
1409  {
1410  *write_ptr = *read_ptr;
1411  ++write_ptr;
1412  }
1413  }
1414 
1415  vertexAdjElementSize = write_ptr - convert_from_sidl_vector( vertexAdjElements );
1416 }
1417 
1418 
1419 
1420 
1421 // Gets the number of elements attached to this vertex.
1422 // Useful to determine how large the "elem_array" parameter
1423 // of the vertex_get_attached_elements() function must be.
1425  VertexHandle vertex, MsqError &err)
1426 {
1427  cache_adjacent_elements( vertex, err ); MSQ_ERRZERO(err);
1428  return vertexAdjElementSize;
1429 }
1430 
1431 // Gets the elements attached to this vertex.
1433  VertexHandle vertex,
1434  ElementHandle* elem_array,
1435  size_t sizeof_elem_array, MsqError &err)
1436 {
1437  cache_adjacent_elements( vertex, err ); MSQ_ERRRTN(err);
1438  if (sizeof_elem_array < (unsigned)vertexAdjElementSize) {
1439  MSQ_SETERR(err)("Insufficient space in array.", MsqError::INVALID_ARG);
1440  return;
1441  }
1442 
1443  assert( sizeof(ElementHandle) == sizeof(void*) );
1444  void** array = convert_from_sidl_vector( vertexAdjElements );
1445  memcpy( elem_array, array, vertexAdjElementSize * sizeof(void*) );
1446 }
1447 
1448 
1449 // Gets the number of vertices in this element.
1450 // This data can also be found by querying the
1451 // element's topology and getting the number
1452 // of vertices per element for that topology type.
1454  ElementHandle elem,
1455  MsqError &err)
1456 {
1457  try {
1458  sidl::array<void*> junk;
1459  int result = 0;
1460  entIFace.getEntAdj( elem, TSTTM::EntityType_VERTEX, junk, result );
1461  return result;
1462  }
1463  catch(::TSTTB::Error &tstt_err) {
1465  return 0;
1466  }
1467 }
1468 
1470  size_t length,
1471  MsqError& err )
1472 {
1473  try {
1474  sidl::array<void*> handles( convert_to_sidl_vector( array, length ) );
1475  sidl::array<void*> adj;
1476  sidl::array<int> offsets;
1477  int32_t adj_size, off_size;
1478  arrIFace.getEntArrAdj( handles, length, TSTTM::EntityType_VERTEX, adj, adj_size, offsets, off_size );
1479  return adj_size;
1480  }
1481  catch(::TSTTB::Error &tstt_err) {
1483  return 0;
1484  }
1485 }
1486 
1496  ElementHandle *elements,
1497  size_t num_elems,
1498  VertexHandle *vertices,
1499  size_t &vert_len,
1500  size_t *indices,
1501  size_t &indices_len,
1502  size_t *offsets,
1503  Mesquite::MsqError &err)
1504 {
1505  if (num_elems == 0)
1506  return;
1507 
1508  try {
1509  // Constuct arguments to TSTT
1510  int vert_count, off_count;
1511  sidl::array<void*> elem_arr( convert_to_sidl_vector( elements, num_elems ) );
1512  sidl::array<void*> vert_arr( convert_to_sidl_vector( (void**)indices, indices_len ) );
1513  sidl::array<int> off_arr;
1514  if (sizeof(size_t) == sizeof(int))
1515  off_arr = convert_to_sidl_vector( (int*)offsets, num_elems + 1 );
1516  else
1517  off_arr = alloc_sidl_vector<int>( num_elems + 1 );
1518 
1519  // Query TSTT for element connectivity
1520  arrIFace.getEntArrAdj( elem_arr, num_elems,
1521  TSTTM::EntityType_VERTEX,
1522  vert_arr, vert_count,
1523  off_arr, off_count );
1524 
1525  indices_len = vert_count;
1526  // If couldn't do array borrow, copy offsets into output array
1527  if (sizeof(size_t) != sizeof(int))
1528  copy_from_sidl( off_arr, offsets );
1529 
1530  // Mesquite expects index array length as last value in offset array.
1531  // If TSTT mesh doesn't return it, then add it.
1532  if ((unsigned)off_count == num_elems)
1533  offsets[num_elems] = vert_count;
1534  else
1535  assert( (unsigned)off_count == num_elems+1 );
1536  }
1537  catch(::TSTTB::Error &tstt_err) {
1539  return;
1540  }
1541 
1542  // Construct unique list of vertex handles
1543  vert_len = 0;
1544  msq_std::map<VertexHandle,size_t> index_map;
1545  const size_t* end = indices + indices_len;
1546  /*
1547  for (size_t* iter = indices; iter != end; ++iter)
1548  {
1549  VertexHandle vertex = *(VertexHandle*)iter;
1550  msq_std::map<VertexHandle,size_t>::iterator pos = index_map.find( vertex );
1551  size_t index;
1552  if (pos == index_map.end())
1553  index_map[vertex] = index = vert_len++;
1554  else
1555  index = pos->second;
1556 
1557  vertices[index] = vertex;
1558  *iter = index;
1559  }
1560  */
1561  // Rather than the above simple code, do the following more complicated
1562  // code so the resulting list of vertices are sorted (easier to debug)
1563  for (size_t* iter = indices; iter != end; ++iter)
1564  {
1565  VertexHandle vertex = *(VertexHandle*)iter;
1566  msq_std::map<VertexHandle,size_t>::iterator pos = index_map.find( vertex );
1567  if (pos == index_map.end())
1568  index_map[vertex] = 0;
1569  }
1570  for (msq_std::map<VertexHandle,size_t>::iterator m_iter = index_map.begin();
1571  m_iter != index_map.end(); ++m_iter)
1572  {
1573  vertices[vert_len] = m_iter->first;
1574  m_iter->second = vert_len++;
1575  }
1576  for (size_t* iter = indices; iter != end; ++iter)
1577  {
1578  VertexHandle vertex = *(VertexHandle*)iter;
1579  msq_std::map<VertexHandle,size_t>::iterator pos = index_map.find( vertex );
1580  *iter = pos->second;
1581  }
1582 
1583 
1584 }
1585 
1586 void MeshTSTTImpl::get_all_sizes( size_t& vertex_count,
1587  size_t& element_count,
1588  size_t& vertex_use_count,
1589  MsqError& err )
1590 {
1591  try {
1592 
1593  // Get number of vertices
1594  vertex_count = meshIFace.getNumOfType( nodeSet, TSTTM::EntityType_VERTEX );
1595 
1596  // Get number of elements
1597  element_count = meshIFace.getNumOfType( elementSet, TSTTM::EntityType_FACE );
1598  element_count += meshIFace.getNumOfType( elementSet, TSTTM::EntityType_REGION );
1599 
1600  // Get number of vertex uses
1601  sidl::array<void*> handles1, handles2;
1602  sidl::array<int> offsets1, offsets2;
1603  sidl::array<int> flags1, flags2;
1604  int num_handles, num_offsets, num_flags;
1605  // Face elements
1606  meshIFace.getAdjEntities( elementSet,
1607  TSTTM::EntityType_FACE,
1608  TSTTM::EntityTopology_ALL_TOPOLOGIES,
1609  TSTTM::EntityType_VERTEX,
1610  handles1, num_handles,
1611  offsets1, num_offsets,
1612  flags1 , num_flags );
1613  vertex_use_count = num_handles;
1614  // Region elements
1615  meshIFace.getAdjEntities( elementSet,
1616  TSTTM::EntityType_REGION,
1617  TSTTM::EntityTopology_ALL_TOPOLOGIES,
1618  TSTTM::EntityType_VERTEX,
1619  handles2, num_handles,
1620  offsets2, num_offsets,
1621  flags2 , num_flags );
1622  vertex_use_count += num_handles;
1623  }
1624  catch(::TSTTB::Error &tstt_err) {
1626  }
1627 }
1628 
1629 void MeshTSTTImpl::get_all_mesh( VertexHandle* vert_array, size_t vert_len,
1630  ElementHandle* elem_array, size_t elem_len,
1631  size_t* offset_array, size_t offset_len,
1632  size_t* conn_array, size_t conn_len ,
1633  MsqError& err )
1634 {
1635  int num_elem;
1636  try {
1637  sidl::array<void*> elements( convert_to_sidl_vector( elem_array, elem_len ) );
1638  meshIFace.getEntities( elementSet,
1639  TSTTM::EntityType_ALL_TYPES,
1640  TSTTM::EntityTopology_ALL_TOPOLOGIES,
1641  elements,
1642  num_elem );
1643  if ((unsigned)num_elem > elem_len)
1644  {
1645  MSQ_SETERR(err)("Insufficient space in array", MsqError::OUT_OF_MEMORY);
1646  return;
1647  }
1648  }
1649  catch(::TSTTB::Error &tstt_err) {
1651  return;
1652  }
1653 
1654  if (offset_len <= (unsigned)num_elem)
1655  {
1656  MSQ_SETERR(err)("Insufficient space in array", MsqError::OUT_OF_MEMORY);
1657  return;
1658  }
1659 
1660  elements_get_attached_vertices( elem_array, num_elem,
1661  vert_array, vert_len,
1662  conn_array, conn_len,
1663  offset_array, err );
1664 }
1665 
1666 
1667 // Returns the topology of the given entity.
1669  ElementHandle element, MsqError &err)
1670 {
1671  try {
1672  TSTTM::EntityTopology topo = entIFace.getEntTopo( element );
1673  return topologyMap[topo];
1674  }
1675  catch(::TSTTB::Error &tstt_err) {
1677  return MIXED;
1678  }
1679 }
1680 
1681 // Returns the topologies of the given entities. The "entity_topologies"
1682 // array must be at least "num_elements" in size.
1684  ElementHandle *element_handle_array,
1685  EntityTopology *element_topologies,
1686  size_t num_elements, MsqError &err)
1687 {
1688  try {
1689 
1690  sidl::array<TSTTM::EntityTopology> topologies( alloc_sidl_vector<TSTTM::EntityTopology>( num_elements ) );
1691  sidl::array<void*> handles( convert_to_sidl_vector( element_handle_array, num_elements ) );
1692  int topo_len_out;
1693  arrIFace.getEntArrTopo( handles, num_elements, topologies, topo_len_out );
1694  if ((size_t)topo_len_out != num_elements) {
1696  return;
1697  }
1698 
1699  for (unsigned i = 0; i < num_elements; ++i)
1700  element_topologies[i] = topologyMap[topologies.get(i)];
1701  }
1702  catch(::TSTTB::Error &tstt_err) {
1704  }
1705 }
1706 
1707 //**************** Memory Management ****************
1708 // Tells the mesh that the client is finished with a given
1709 // entity handle.
1711  Mesquite::Mesh::EntityHandle */*handle_array*/,
1712  size_t /*num_handles*/, MsqError &/*err*/)
1713 {
1714  // Do nothing
1715 }
1716 
1717 // Instead of deleting a Mesh when you think you are done,
1718 // call release(). In simple cases, the implementation could
1719 // just call the destructor. More sophisticated implementations
1720 // may want to keep the Mesh object to live longer than Mesquite
1721 // is using it.
1723 {
1724 }
1725 
1726 //**************** Tags ****************
1727 TagHandle MeshTSTTImpl::tag_create( const msq_std::string& name,
1728  TagType type, unsigned length,
1729  const void* default_val,
1730  MsqError& err )
1731 {
1732  TSTTB::TagValueType tstt_type;
1733  size_t size = 0;
1734  switch (type) {
1735  case Mesquite::Mesh::BYTE: size = sizeof(char ); tstt_type = TSTTB::TagValueType_OPAQUE; break;
1736  case Mesquite::Mesh::INT: size = sizeof(int ); tstt_type = TSTTB::TagValueType_INTEGER; break;
1737  case Mesquite::Mesh::DOUBLE: size = sizeof(double); tstt_type = TSTTB::TagValueType_DOUBLE; break;
1738  case Mesquite::Mesh::HANDLE: size = sizeof(void* ); tstt_type = TSTTB::TagValueType_ENTITY_HANDLE; break;
1739  default:
1740  MSQ_SETERR(err)("Invalid tag type", MsqError::INVALID_ARG );
1741  return 0;
1742  }
1743  size *= length;
1744 
1745  try {
1746  void* handle = 0;
1747  tagIFace.createTag( name, size, tstt_type, handle );
1748  return handle;
1749  }
1750  catch(::TSTTB::Error &tstt_err) {
1752  return 0;
1753  }
1754 }
1755 
1757 {
1758  try {
1759  tagIFace.destroyTag( handle, true );
1760  }
1761  catch(::TSTTB::Error &tstt_err) {
1763  }
1764 }
1765 
1766 TagHandle MeshTSTTImpl::tag_get( const msq_std::string& name, MsqError& err )
1767 {
1768  try {
1769  return tagIFace.getTagHandle( name );
1770  }
1771  catch(::TSTTB::Error &tstt_err) {
1772  if (tstt_err.getErrorType() != TSTTB::ErrorType_TAG_NOT_FOUND) {
1774  }
1775  return 0;
1776  }
1777 }
1778 
1780  msq_std::string& name,
1781  TagType& type_out,
1782  unsigned& length_out,
1783  MsqError& err )
1784 {
1785  size_t size;
1786  TSTTB::TagValueType type;
1787  try {
1788  name = tagIFace.getTagName( handle );
1789  size = tagIFace.getTagSize( handle );
1790  type = tagIFace.getTagType( handle );
1791  }
1792  catch(::TSTTB::Error &tstt_err) {
1794  return;
1795  }
1796 
1797  size_t tsize;
1798  switch (type) {
1799  case TSTTB::TagValueType_OPAQUE : tsize = sizeof(char ); type_out = Mesquite::Mesh::BYTE ; break;
1800  case TSTTB::TagValueType_INTEGER : tsize = sizeof(int ); type_out = Mesquite::Mesh::INT ; break;
1801  case TSTTB::TagValueType_DOUBLE : tsize = sizeof(double); type_out = Mesquite::Mesh::DOUBLE; break;
1802  case TSTTB::TagValueType_ENTITY_HANDLE: tsize = sizeof(void* ); type_out = Mesquite::Mesh::HANDLE; break;
1803  default:
1804  MSQ_SETERR(err)("Unsupported TSTT tag type", MsqError::NOT_IMPLEMENTED );
1805  return;
1806  }
1807 
1808  if (size % tsize != 0)
1809  {
1810  MSQ_SETERR(err)("Invalid TSTT tag size", MsqError::INTERNAL_ERROR );
1811  return;
1812  }
1813 
1814  length_out = size / tsize;
1815 }
1816 
1818  size_t num_elems,
1819  const ElementHandle* array,
1820  const void* data,
1821  MsqError& err )
1822 {
1823  tag_set_data( tag, num_elems, array, data, err );
1824 }
1825 
1827  size_t num_elems,
1828  const VertexHandle* array,
1829  const void* data,
1830  MsqError& err )
1831 {
1832  tag_set_data( tag, num_elems, array, data, err );
1833 }
1834 
1836  size_t num_elems,
1837  const EntityHandle* array,
1838  const void* data,
1839  MsqError& err )
1840 {
1841  try {
1842  size_t len, size = tagIFace.getTagSize( tag );
1843  int count;
1844  sidl::array<void*> handles( convert_to_sidl_vector( (void**)array, num_elems ) );
1845  switch (tagIFace.getTagType( tag ))
1846  {
1847  case TSTTB::TagValueType_ENTITY_HANDLE:
1848  {
1849  len = size / sizeof(void*);
1850  sidl::array<void*> sdata( convert_to_sidl_vector( (void**)data, len*num_elems ));
1851  arrTagIFace.setEHArrData( handles, num_elems, tag, sdata, count );
1852  }
1853  break;
1854 
1855  case TSTTB::TagValueType_DOUBLE:
1856  {
1857  len = size / sizeof(double);
1858  sidl::array<double> sdata( convert_to_sidl_vector( (double*)data, len*num_elems ));
1859  arrTagIFace.setDblArrData( handles, num_elems, tag, sdata, count );
1860  }
1861  break;
1862 
1863  case TSTTB::TagValueType_INTEGER:
1864  {
1865  len = size / sizeof(int);
1866  sidl::array<int> sdata( convert_to_sidl_vector( (int*)data, len*num_elems ));
1867  arrTagIFace.setIntArrData( handles, num_elems, tag, sdata, count );
1868  }
1869  break;
1870 
1871  default:
1872  {
1873 #if TSTT_OPAQUE_TAG_TYPE == OPAQUE_TYPE_OPAQUE_PACKED
1874  len = num_elems / sizeof(void*);
1875  if (num_elems % sizeof(void*))
1876  ++len;
1877  sidl::array<void*> sdata( convert_to_sidl_vector( (void**)data, len ) );
1878 #elif TSTT_OPAQUE_TAG_TYPE == OPAQUE_TYPE_OPAQUE_PADDED
1879  assert( size <= sizeof(void*) );
1880  sidl::array<void*> sdata( alloc_sidl_vector<void*>(num_elems) );
1881  const char* ptr = reinterpret_cast<const char*>(data);
1882  for (size_t i = 0; i < num_elems; ++i)
1883  sdata.set( i, reinterpret_cast<void*>(*(ptr + i*size)) );
1884 #elif TSTT_OPAQUE_TAG_TYPE == OPAQUE_TYPE_CHAR
1885  len = size * num_elems;
1886  sidl::array<char> sdata( convert_to_sidl_vector( (char*)data, len ) );
1887 #elif TSTT_OPAQUE_TAG_TYPE == OPAQUE_TYPE_UCHAR \
1888  || TSTT_OPAQUE_TAG_TYPE == OPAQUE_TYPE_BYTE
1889  len = size * num_elems;
1890  sidl::array<unsigned char> sdata( alloc_sidl_vector( (unsigned char*)data, len ) );
1891 #else
1892 #error
1893 #endif
1894  arrTagIFace.setArrData( handles, num_elems, tag, sdata, count, size );
1895  }
1896  }
1897  }
1898  catch(::TSTTB::Error &tstt_err) {
1900  }
1901 }
1902 
1903 
1905  size_t num_elems,
1906  const ElementHandle* array,
1907  void* data,
1908  MsqError& err )
1909 {
1910  tag_get_data( tag, num_elems, array, data, err );
1911 }
1912 
1914  size_t num_elems,
1915  const VertexHandle* array,
1916  void* data,
1917  MsqError& err )
1918 {
1919  tag_get_data( tag, num_elems, array, data, err );
1920 }
1921 
1923  size_t num_elems,
1924  const EntityHandle* array,
1925  void* data,
1926  MsqError& err )
1927 {
1928  try {
1929  size_t len, size = tagIFace.getTagSize( tag );
1930  int32_t lower = 0, upper = num_elems - 1, stride = 1, count = num_elems;
1931  sidl::array<void*> handles;
1932  handles.borrow( const_cast<void**>(array), 1, &lower, &upper, &stride );
1933  switch (tagIFace.getTagType( tag ))
1934  {
1935  case TSTTB::TagValueType_ENTITY_HANDLE:
1936  {
1937  len = size / sizeof(void*);
1938  sidl::array<void*> sdata( convert_to_sidl_vector( (void**)data, len*num_elems ));
1939  arrTagIFace.getEHArrData( handles, num_elems, tag, sdata, count );
1940  }
1941  break;
1942 
1943  case TSTTB::TagValueType_DOUBLE:
1944  {
1945  len = size / sizeof(double);
1946  sidl::array<double> sdata( convert_to_sidl_vector( (double*)data, len*num_elems ));
1947  arrTagIFace.getDblArrData( handles, num_elems, tag, sdata, count );
1948  }
1949  break;
1950 
1951  case TSTTB::TagValueType_INTEGER:
1952  {
1953  len = size / sizeof(int);
1954  sidl::array<int> sdata( convert_to_sidl_vector( (int*)data, len*num_elems ));
1955  arrTagIFace.getIntArrData( handles, num_elems, tag, sdata, count );
1956  }
1957  break;
1958 
1959  default:
1960  {
1961 #if TSTT_OPAQUE_TAG_TYPE == OPAQUE_TYPE_OPAQUE_PACKED
1962  len = num_elems / sizeof(void*);
1963  if (num_elems % sizeof(void*))
1964  ++len;
1965  sidl::array<void*> sdata( convert_to_sidl_vector( (void**)data, len ) );
1966 #elif TSTT_OPAQUE_TAG_TYPE == OPAQUE_TYPE_OPAQUE_PADDED
1967  assert( size <= sizeof(void*) );
1968  sidl::array<void*> sdata( alloc_sidl_vector<void*>(num_elems) );
1969 #elif TSTT_OPAQUE_TAG_TYPE == OPAQUE_TYPE_CHAR
1970  len = size * num_elems;
1971  sidl::array<char> sdata( convert_to_sidl_vector( (char*)data, len ) );
1972 #elif TSTT_OPAQUE_TAG_TYPE == OPAQUE_TYPE_UCHAR \
1973  || TSTT_OPAQUE_TAG_TYPE == OPAQUE_TYPE_BYTE
1974  len = size * num_elems;
1975  sidl::array<unsigned char> sdata( alloc_sidl_vector( (unsigned char*)data, len ) );
1976 #else
1977 #error
1978 #endif
1979  int32_t junk;
1980  arrTagIFace.getArrData( handles, num_elems, tag, sdata, count, junk );
1981 
1982 #if TSTT_OPAQUE_TAG_TYPE == OPAQUE_TYPE_OPAQUE_PADDED
1983  const char* ptr = reinterpret_cast<const char*>(data);
1984  for (size_t i = 0; i < num_elems; ++i)
1985  sdata.set( i, reinterpret_cast<void*>(*(ptr + i*size)) );
1986 #endif
1987  }
1988  }
1989  }
1990  catch(::TSTTB::Error &tstt_err) {
1992  }
1993 }
1994 
1995 } // namespace Mesquite
void cache_adjacent_elements(void *vertex_handle, MsqError &err)
Get elements adjacent to vertex and store in vertexAdjElements.
Definition: MeshTSTT.cpp:1362
unable to allocate the necessary memory
Iterates through a set of entities. An EntityIterator is typically obtained via Mesh::vertex_iterator...
virtual void set_active_set(void *element_set, MsqError &)
set mesh to be smoothed.
Definition: MeshTSTT.cpp:931
bool createdByteTag
Tag was created in constructor.
Definition: MeshTSTT.cpp:656
#define MSQ_ERRZERO(err)
Return zero/NULL on error.
TSTTM::Entity tsttMesh
TSTT mesh interface.
Definition: MeshTSTT.cpp:78
virtual void vertices_are_on_boundary(VertexHandle vert_array[], bool on_bnd[], size_t num_vtx, MsqError &err)
Query &quot;boundary&quot; flag for an array of vertices.
Definition: MeshTSTT.cpp:1149
virtual void tag_get_vertex_data(TagHandle handle, size_t num_elems, const VertexHandle *node_array, void *tag_data, MsqError &err)
Get tag values on vertices.
Definition: MeshTSTT.cpp:1913
void tag_set_data(TagHandle handle, size_t num_elems, const EntityHandle *handle_array, const void *tag_data, MsqError &err)
Set tag values.
Definition: MeshTSTT.cpp:1835
virtual void operator++()
step
Definition: MeshTSTT.cpp:194
static sidl::array< T > alloc_sidl_vector(size_t size)
int vertexAdjElementSize
Number of valid entries vertexAdjElements.
Definition: MeshTSTT.cpp:672
virtual void vertex_set_coordinates(VertexHandle vertex, const Vector3D &coordinates, MsqError &err)
Set vertex coordinates.
Definition: MeshTSTT.cpp:1267
virtual size_t get_vertex_use_count(ElementHandle *array, size_t length, MsqError &err)
Definition: MeshTSTT.cpp:1469
Used to hold the error state and return it to the application.
virtual ElementIterator * element_iterator(MsqError &err)
Create iterator for elements in active set.
Definition: MeshTSTT.cpp:1108
TagType
The type of a tag.
EntityTopology
Definition: Mesquite.hpp:92
void * nodeSet
TSTTM entity set handle for nodes to move.
Definition: MeshTSTT.cpp:638
virtual void tag_set_element_data(TagHandle handle, size_t num_elems, const ElementHandle *elem_array, const void *tag_data, MsqError &err)
Set tag values on elements.
Definition: MeshTSTT.cpp:1817
TagHandle fixedTag
Handle for tag used to hold vertex-fixed flag.
Definition: MeshTSTT.cpp:658
bool createdFixedTag
Fixed tag was created in constructor.
Definition: MeshTSTT.cpp:660
virtual ~MeshTSTT()
Definition: MeshTSTT.cpp:711
TSTTM::Modify modIFace
TSTT interface for modifying mesh.
Definition: MeshTSTT.cpp:629
virtual void tag_delete(TagHandle handle, MsqError &err)
Remove a tag and all corresponding data.
Definition: MeshTSTT.cpp:1756
virtual TagHandle tag_get(const msq_std::string &name, MsqError &err)
Get handle for existing tag, by name.
Definition: MeshTSTT.cpp:1766
virtual void get_all_mesh(VertexHandle *vert_array, size_t vert_len, ElementHandle *elem_array, size_t elem_len, size_t *elem_conn_offsets, size_t offset_len, size_t *elem_conn_indices, size_t index_len, MsqError &err)
Get entities and connectivity.
Definition: MeshTSTT.cpp:1629
requested functionality is not (yet) implemented
EntityHandle VertexHandle
TSTTArrIter(TSTTM::Arr &mesh, void *meshset, TSTTM::EntityType type, TSTTM::EntityTopology topo, unsigned buffer_count=1024)
Definition: MeshTSTT.cpp:234
sidl::array< void * >::const_iterator iter
Definition: MeshTSTT.cpp:175
const char *const VERTEX_BYTE_TAG_NAME
The name of the tag (integer) that Mesquite will use to store internal data.
EntityHandle ElementHandle
TSTTM::EntityType inputSetType
The type of elements contained in the input element set.
Definition: MeshTSTT.cpp:651
virtual Mesh::EntityHandle operator*() const
get current entity handle
Definition: MeshTSTT.cpp:188
This file contains the Mesquite mesh interface. Many users will want to implement a concrete class de...
Vector3D is the object that effeciently stores information about about three-deminsional vectors...
The name of the tag (integer) used internally by MeshTSTT to eliminate duplicate vertices.
void set_int_tag(void *tag, void *meshset, int value, MsqError &err)
Definition: MeshTSTT.cpp:894
void * EntityHandle
Opaque EntityHandle type and tag type.
virtual void restart()
reset iterator
Definition: MeshTSTT.cpp:262
void * elementSet
TSTTM entity set handle for elements to improve.
Definition: MeshTSTT.cpp:636
double length(Vector3D *const v, int n)
sidl::array< void * > handleArray
Definition: MeshTSTT.cpp:202
static T * convert_from_sidl_vector(sidl::array< T > &array)
virtual void release()
Instead of deleting a Mesh when you think you are done, call release().
Definition: MeshTSTT.cpp:1722
sidl::array< void * > vertexAdjElements
Cached result for vertex-&gt;element query.
Definition: MeshTSTT.cpp:670
const int num_nodes
Definition: ex1.C:96
virtual void restart()
reset iterator
Definition: MeshTSTT.cpp:137
static sidl::array< T > convert_to_sidl_vector(T *array, size_t size)
virtual ~TSTTArrIter()
Definition: MeshTSTT.cpp:250
invalid function argument passed
TSTT iterator using array-iterator interface and buffer of handles.
Definition: MeshTSTT.cpp:198
virtual void operator++()
step
Definition: MeshTSTT.cpp:284
SIDLIterator(const sidl::array< void * > &a)
Definition: MeshTSTT.cpp:181
TSTTB::ArrTag arrTagIFace
Definition: MeshTSTT.cpp:627
TagHandle byteTag
Handle for tag used to hold vertex byte.
Definition: MeshTSTT.cpp:654
virtual bool is_at_end() const
check if any remaining entity handles
Definition: MeshTSTT.cpp:279
void popupate_input_elements()
Populate inputElements from elemetnSet.
Definition: MeshTSTT.cpp:1037
#define MSQ_CHKERR(err)
Mesquite&#39;s Error Checking macro.
void * tsttIter
TSTT iterator handle.
Definition: MeshTSTT.cpp:79
bool haveMesh
Have mesh.
Definition: MeshTSTT.cpp:634
static void copy_from_sidl(sidl::array< S > &source, T *target)
#define MSQ_SETERR(err)
Macro to set error - use err.clear() to clear.
blockLoc i
Definition: read.cpp:79
TSTTM::Mesh meshIFace
TSTT basic mesh interface instance.
Definition: MeshTSTT.cpp:621
TSTTB::EntTag tagIFace
Definition: MeshTSTT.cpp:624
virtual void release_entity_handles(EntityHandle *handle_array, size_t num_handles, MsqError &err)
no-op
Definition: MeshTSTT.cpp:1710
bool notAtEnd
Flag to mark if end of iterator had been reached.
Definition: MeshTSTT.cpp:80
const sidl::array< void * > array
Definition: MeshTSTT.cpp:176
virtual void restart()
reset iterator
Definition: MeshTSTT.cpp:185
TSTTM::Arr & myMesh
Definition: MeshTSTT.cpp:206
Wrapper around single-entity TSTT interator.
Definition: MeshTSTT.cpp:75
virtual void set_active_set(void *element_set, MsqError &)=0
set mesh to be smoothed.
void * cachedAdjVertex
Vertex for which vertexAdjElements is cached.
Definition: MeshTSTT.cpp:674
msq_std::set< void * > inputElements
std::set containing elements in elementSet, used to constrain vertex-&gt;element adjaceny queries to onl...
Definition: MeshTSTT.cpp:643
virtual Mesh::EntityHandle operator*() const
get current entity handle
Definition: MeshTSTT.cpp:274
virtual void vertices_set_byte(VertexHandle *vert_array, unsigned char *byte_array, size_t array_size, MsqError &err)
Set vertex mark.
Definition: MeshTSTT.cpp:1298
virtual void vertex_set_byte(VertexHandle vertex, unsigned char byte, MsqError &err)
Set vertex mark.
Definition: MeshTSTT.cpp:1285
void * entityHandle
Current TSTT entity handle.
Definition: MeshTSTT.cpp:81
virtual void tag_properties(TagHandle handle, msq_std::string &name_out, TagType &type_out, unsigned &length_out, MsqError &err)
Get properites of tag.
Definition: MeshTSTT.cpp:1779
virtual void vertex_get_attached_elements(VertexHandle vertex, ElementHandle *elem_array, size_t sizeof_elem_array, MsqError &err)
Get vertex adjacencies.
Definition: MeshTSTT.cpp:1432
TSTTIterator(TSTTM::Entity &mesh, void *meshset, TSTTM::EntityType type, TSTTM::EntityTopology topo, MsqError &err)
Definition: MeshTSTT.cpp:117
static MeshTSTT * create(TSTTM::Mesh &mesh, void *meshset, MsqError &err)
factory method
Definition: MeshTSTT.cpp:683
virtual TagHandle tag_create(const msq_std::string &tag_name, TagType type, unsigned length, const void *default_value, MsqError &err)
Create a tag.
Definition: MeshTSTT.cpp:1727
void tag_get_data(TagHandle handle, size_t num_elems, const EntityHandle *handle_array, void *tag_data, MsqError &err)
Get tag values.
Definition: MeshTSTT.cpp:1922
const char *const VERTEX_FIXED_TAG_NAME
The name of the tag (integer) Mesquite expects to be non-zero for vertices which are not to be moved ...
object is in an invalid state
const double * to_array() const
virtual bool is_at_end() const
check if any remaining entity handles
Definition: MeshTSTT.cpp:191
virtual void elements_get_topologies(ElementHandle *element_handle_array, EntityTopology *element_topologies, size_t num_elements, MsqError &err)
Return topology type enum for an array of elements.
Definition: MeshTSTT.cpp:1683
void * TagHandle
Type used to refer to a tag defintion.
void set(const double x, const double y, const double z)
virtual void operator++()
step
Definition: MeshTSTT.cpp:159
virtual EntityTopology element_get_topology(ElementHandle entity_handle, MsqError &err)
Return topology type enum for specified element.
Definition: MeshTSTT.cpp:1668
virtual Mesh::EntityHandle operator*() const
get current entity handle
Definition: MeshTSTT.cpp:149
virtual size_t element_get_attached_vertex_count(ElementHandle elem, MsqError &err)
Get length of connectivity list
Definition: MeshTSTT.cpp:1453
virtual void tag_get_element_data(TagHandle handle, size_t num_elems, const ElementHandle *elem_array, void *tag_data, MsqError &err)
Get tag values on elements.
Definition: MeshTSTT.cpp:1904
virtual size_t vertex_get_attached_element_count(VertexHandle vertex, MsqError &err)
Get vertex adjacencies.
Definition: MeshTSTT.cpp:1424
virtual bool is_at_end() const
check if any remaining entity handles
Definition: MeshTSTT.cpp:154
TSTTB::EntSet setIFace
TSTT interface for entity set operations.
Definition: MeshTSTT.cpp:631
EntityTopology topologyMap[TSTTM::EntityTopology_ALL_TOPOLOGIES+1]
Handle for the tag used internally to remove duplicates from lists.
Definition: MeshTSTT.cpp:667
TSTTM::Arr arrIFace
TSTT interface for multi-entity (array) queries.
Definition: MeshTSTT.cpp:626
MeshTSTTImpl(TSTTM::Mesh &tstt_mesh, MsqError &err)
Definition: MeshTSTT.cpp:714
MsqVertex is the Mesquite object that stores information about the vertices in the mesh...
virtual VertexIterator * vertex_iterator(MsqError &err)
Create iterator for vertices in active set.
Definition: MeshTSTT.cpp:1089
Iterate over a sidl array of TSTT entity handles.
Definition: MeshTSTT.cpp:172
#define MSQ_ERRRTN(err)
If passed error is true, return from a void function.
virtual void get_all_sizes(size_t &vertex_count, size_t &element_count, size_t &vertex_use_count, MsqError &err)
get sizes for calling get_all_mesh
Definition: MeshTSTT.cpp:1586
virtual void vertex_get_byte(VertexHandle vertex, unsigned char *byte, MsqError &err)
Get vertex mark.
Definition: MeshTSTT.cpp:1323
virtual void vertices_get_coordinates(const VertexHandle vert_array[], MsqVertex *coordinates, size_t num_vtx, MsqError &err)
Get vertex coordinates.
Definition: MeshTSTT.cpp:1179
void get_next_entity()
Advance the iterator to the next entity.
Definition: MeshTSTT.cpp:87
virtual bool vertex_is_fixed(VertexHandle vertex, MsqError &err)
Query &quot;fixed&quot; flag for a vertex.
Definition: MeshTSTT.cpp:1128
TSTTM::Entity entIFace
TSTT interface for per-entity queries.
Definition: MeshTSTT.cpp:623
Implementation of MeshTSTT.
Definition: MeshTSTT.cpp:307
virtual void elements_get_attached_vertices(ElementHandle *elem_handles, size_t num_elems, VertexHandle *vert_handles, size_t &sizeof_vert_handles, size_t *csr_data, size_t &sizeof_csr_data, size_t *csr_offsets, MsqError &err)
Get element connectivity in overly-complex CSR rep.
Definition: MeshTSTT.cpp:1495
static msq_std::string process_tstt_error(TSTTB::Error &tstt_err)
virtual void vertices_get_byte(VertexHandle *vert_array, unsigned char *byte_array, size_t array_size, MsqError &err)
Get vertex mark.
Definition: MeshTSTT.cpp:1335
virtual int get_geometric_dimension(Mesquite::MsqError &)
Get dimension of vertex coordinates (2D vs.
Definition: MeshTSTT.cpp:1072
virtual void tag_set_vertex_data(TagHandle handle, size_t num_elems, const VertexHandle *node_array, const void *tag_data, MsqError &err)
Set tag values on vertices.
Definition: MeshTSTT.cpp:1826