Mesh Oriented datABase  (version 5.6.0)
An array-based unstructured mesh library
QuadTriConv.cpp File Reference

Example demonstrating conversion of repeated-vertex cells to triangles/quads/polygons. More...

#include <iostream>
#include <vector>
#include "moab/Core.hpp"
#include "MBTagConventions.hpp"
+ Include dependency graph for QuadTriConv.cpp:

Go to the source code of this file.

Functions

int main (int argc, char **argv)
 

Detailed Description

Example demonstrating conversion of repeated-vertex cells to triangles/quads/polygons.

This example shows how to:

  • Load a mesh file with repeated vertices in 2D cells (e.g., at poles)
  • Merge repeated vertices in cell connectivity
  • Convert cells to triangles, quads, or polygons as appropriate
  • Preserve global ID tags during conversion
  • Write the modified mesh to a new file

This is useful for cleaning up rll meshes or other grids with repeated vertices at the poles or other singularities.

Author
MOAB Development Team
Date
2024

Merge vertices in 2d cell, if they are repeated
To run: QuadTriConv input_file output_file
In this example, a mesh that has vertices repeated due to south or north pole, for example in an rll mesh, need to be converted to triangles, preserving GLOBAL_ID tag

Parameters
argcNumber of command line arguments
argvCommand line arguments array
Returns
0 on success, 1 on failure

Definition in file QuadTriConv.cpp.

Function Documentation

◆ main()

int main ( int  argc,
char **  argv 
)

Definition at line 41 of file QuadTriConv.cpp.

42 {
43  // Get MOAB instance
44  Interface* mb = new( std::nothrow ) Core;
45  if( NULL == mb ) return 1;
46 
47  std::string filename, outfile;
48  outfile = string( "out.h5m" );
49  if( argc == 1 ) return 0;
50  if( argc > 1 ) filename = string( argv[1] );
51  if( argc > 2 ) outfile = string( argv[2] );
52 
53  // This file is in the mesh files directory
54  MB_CHK_SET_ERR( mb->load_file( filename.c_str() ), "Failed to read" );
55 
56  // get all cells of dimension 2;
57  Range cells;
58  MB_CHK_SET_ERR( mb->get_entities_by_dimension( 0, 2, cells ), "Failed to get cells" );
59 
60  cout << " number of cells : " << cells.size() << "\n";
61 
62  Tag gid; // global id tag
63  MB_CHK_SET_ERR( mb->tag_get_handle( "GLOBAL_ID", gid ), "Failed to get Global ID tag" );
64 
65  Range modifiedCells; // will be deleted at the end; keep the gid
66 
67  for( Range::iterator cit = cells.begin(); cit != cells.end(); cit++ )
68  {
69  EntityHandle cell = *cit;
70  const EntityHandle* connec = NULL;
71  int num_verts = 0;
72  MB_CHK_SET_ERR( mb->get_connectivity( cell, connec, num_verts ), "Failed to get connectivity" );
73 
74  vector< EntityHandle > newConnec;
75  newConnec.push_back( connec[0] ); // at least one vertex
76  int index = 0;
77  int new_size = 1;
78  while( index < num_verts - 2 )
79  {
80  int next_index = ( index + 1 );
81  if( connec[next_index] != newConnec[new_size - 1] )
82  {
83  newConnec.push_back( connec[next_index] );
84  new_size++;
85  }
86  index++;
87  }
88  // add the last one only if different from previous and first node
89  if( ( connec[num_verts - 1] != connec[num_verts - 2] ) && ( connec[num_verts - 1] != connec[0] ) )
90  {
91  newConnec.push_back( connec[num_verts - 1] );
92  new_size++;
93  }
94  if( new_size < num_verts )
95  {
96  // cout << "new cell from " << cell << " has only " << new_size << " vertices \n";
97  modifiedCells.insert( cell );
98  // create a new cell with type triangle, quad or polygon
99  EntityType type = MBTRI;
100  if( new_size == 3 )
101  type = MBTRI;
102  else if( new_size == 4 )
103  type = MBQUAD;
104  else if( new_size > 4 )
105  type = MBPOLYGON;
106 
107  // create new cell
108  EntityHandle newCell;
109  MB_CHK_SET_ERR( mb->create_element( type, &newConnec[0], new_size, newCell ), "Failed to create new cell" );
110  // set the old id to the new element
111  int id;
112  MB_CHK_SET_ERR( mb->tag_get_data( gid, &cell, 1, &id ), "Failed to get global id" );
113  MB_CHK_SET_ERR( mb->tag_set_data( gid, &newCell, 1, &id ), "Failed to set global id on new cell" );
114  }
115  }
116 
117  mb->delete_entities( modifiedCells );
118  // in case global ids are not set for vertices, set them, in order;
119  // they are needed for migrating later on
120  //
121  Range verts;
122  MB_CHK_SET_ERR( mb->get_entities_by_dimension( 0, 0, verts ), "Failed to get vertices" );
123 
124  vector< int > gids;
125  gids.resize( verts.size() );
126  MB_CHK_SET_ERR( mb->tag_get_data( gid, verts, &gids[0] ), "Failed to get gids on vertices" );
127  if( gids[0] <= 0 )
128  {
129  // gids were never set, assign them
130  for( size_t i = 1; i <= verts.size(); i++ )
131  gids[i - 1] = (int)i;
132  MB_CHK_SET_ERR( mb->tag_set_data( gid, verts, &gids[0] ), "Failed to set gids on vertices" );
133  }
134  MB_CHK_SET_ERR( mb->write_file( outfile.c_str() ), "Failed to write new file" );
135 
136  cout << " wrote file " << outfile << " with " << modifiedCells.size() << " modified cells\n";
137 
138  delete mb;
139  return 0;
140 }

References moab::Range::begin(), moab::Core::create_element(), moab::Core::delete_entities(), moab::Range::end(), moab::Core::get_connectivity(), moab::Core::get_entities_by_dimension(), moab::index, moab::Range::insert(), moab::Core::load_file(), mb, MB_CHK_SET_ERR, MBPOLYGON, MBQUAD, MBTRI, moab::Range::size(), moab::Core::tag_get_data(), moab::Core::tag_get_handle(), moab::Core::tag_set_data(), and moab::Core::write_file().