Mesh Oriented datABase  (version 5.5.1)
An array-based unstructured mesh library
QuadTriConv.cpp
Go to the documentation of this file.
1 /** @example QuadTriConv.cpp \n
2  * \brief Merge vertices in 2d cell, if they are repeated \n
3  * <b>To run</b>: QuadTriConv input_file output_file \n
4  *
5  * In this example, a mesh that has vertices repeated due to south or north pole, for
6  * example in an rll mesh, need to be converted to triangles, preserving GLOBAL_ID tag
7  */
8 
9 #include <iostream>
10 #include <vector>
11 //#include <string>
12 
13 // Include header for MOAB instance and tag conventions for
14 #include "moab/Core.hpp"
15 #include "MBTagConventions.hpp"
16 
17 using namespace moab;
18 using namespace std;
19 
20 int main( int argc, char** argv )
21 {
22  // Get MOAB instance
23  Interface* mb = new( std::nothrow ) Core;
24  if( NULL == mb ) return 1;
25 
26  std::string filename, outfile;
27  outfile = string( "out.h5m" );
28  if( argc == 1 ) return 0;
29  if( argc > 1 ) filename = string( argv[1] );
30  if( argc > 2 ) outfile = string( argv[2] );
31 
32  // This file is in the mesh files directory
33  ErrorCode rval = mb->load_file( filename.c_str() );MB_CHK_SET_ERR( rval, "Failed to read" );
34 
35  // get all cells of dimension 2;
36  Range cells;
37  rval = mb->get_entities_by_dimension( 0, 2, cells );MB_CHK_SET_ERR( rval, "Failed to get cells" );
38 
39  cout << " number of cells : " << cells.size() << "\n";
40 
41  Tag gid; // global id tag
42  rval = mb->tag_get_handle( "GLOBAL_ID", gid );MB_CHK_SET_ERR( rval, "Failed to get Global ID tag" );
43 
44  Range modifiedCells; // will be deleted at the end; keep the gid
45 
46  for( Range::iterator cit = cells.begin(); cit != cells.end(); cit++ )
47  {
48  EntityHandle cell = *cit;
49  const EntityHandle* connec = NULL;
50  int num_verts = 0;
51  rval = mb->get_connectivity( cell, connec, num_verts );MB_CHK_SET_ERR( rval, "Failed to get connectivity" );
52 
53  vector< EntityHandle > newConnec;
54  newConnec.push_back( connec[0] ); // at least one vertex
55  int index = 0;
56  int new_size = 1;
57  while( index < num_verts - 2 )
58  {
59  int next_index = ( index + 1 );
60  if( connec[next_index] != newConnec[new_size - 1] )
61  {
62  newConnec.push_back( connec[next_index] );
63  new_size++;
64  }
65  index++;
66  }
67  // add the last one only if different from previous and first node
68  if( ( connec[num_verts - 1] != connec[num_verts - 2] ) && ( connec[num_verts - 1] != connec[0] ) )
69  {
70  newConnec.push_back( connec[num_verts - 1] );
71  new_size++;
72  }
73  if( new_size < num_verts )
74  {
75  // cout << "new cell from " << cell << " has only " << new_size << " vertices \n";
76  modifiedCells.insert( cell );
77  // create a new cell with type triangle, quad or polygon
78  EntityType type = MBTRI;
79  if( new_size == 3 )
80  type = MBTRI;
81  else if( new_size == 4 )
82  type = MBQUAD;
83  else if( new_size > 4 )
84  type = MBPOLYGON;
85 
86  // create new cell
87  EntityHandle newCell;
88  rval = mb->create_element( type, &newConnec[0], new_size, newCell );MB_CHK_SET_ERR( rval, "Failed to create new cell" );
89  // set the old id to the new element
90  int id;
91  rval = mb->tag_get_data( gid, &cell, 1, &id );MB_CHK_SET_ERR( rval, "Failed to get global id" );
92  rval = mb->tag_set_data( gid, &newCell, 1, &id );MB_CHK_SET_ERR( rval, "Failed to set global id on new cell" );
93  }
94  }
95 
96  mb->delete_entities( modifiedCells );
97  // in case global ids are not set for vertices, set them, in order;
98  // they are needed for migrating later on
99  //
100  Range verts;
101  rval = mb->get_entities_by_dimension( 0, 0, verts );MB_CHK_SET_ERR( rval, "Failed to get vertices" );
102 
103  vector< int > gids;
104  gids.resize( verts.size() );
105  rval = mb->tag_get_data( gid, verts, &gids[0] );MB_CHK_SET_ERR( rval, "Failed to get gids on vertices" );
106  if( gids[0] <= 0 )
107  {
108  // gids were never set, assign them
109  for( size_t i = 1; i <= verts.size(); i++ )
110  gids[i - 1] = (int)i;
111  rval = mb->tag_set_data( gid, verts, &gids[0] );MB_CHK_SET_ERR( rval, "Failed to set gids on vertices" );
112  }
113  rval = mb->write_file( outfile.c_str() );MB_CHK_SET_ERR( rval, "Failed to write new file" );
114 
115  cout << " wrote file " << outfile << " with " << modifiedCells.size() << " modified cells\n";
116 
117  delete mb;
118  return 0;
119 }