Mesh Oriented datABase  (version 5.6.0)
An array-based unstructured mesh library
addPCdata.cpp
Go to the documentation of this file.
1 /**
2  * @file addPCdata.cpp
3  * @brief Example demonstrating addition of point cloud data to mesh files
4  *
5  * This example shows how to:
6  * - Load mesh files and point cloud data from H5M files
7  * - Match entities between different meshes using global IDs
8  * - Copy tag data from point cloud to mesh entities
9  * - Handle different data types (integer, double)
10  * - Support dual mesh operations for polygon data
11  * - Create new mesh files with enhanced data
12  * - Write enhanced meshes for visualization
13  *
14  * This tool is useful for adding point cloud data to mesh files
15  * for better visualization and analysis in tools like VisIt.
16  *
17  * @author MOAB Development Team
18  * @date 2024
19  *
20 
21  * this tool will take an existing h5m fine atm mesh file and add data from an h5m type file with
22  * point cloud mesh will support mainly showing the data with Visit
23  *
24  * example of usage:
25  * ./mbaddpcdata -i wholeFineATM.h5m -s wholeLND_proj01.h5m -o atm_a2l.h5m -v a2lTbot_proj
26  *
27  * it should work also for pentagon file style data
28  * ./mbaddpcdata -i \c MOABsource/MeshFiles/unittest/penta3d.h5m -s wholeLND_proj01.h5m -o
29  * atm_a2l.h5m -v a2lTbot_proj -p 1
30  *
31  * Basically, will output a new h5m file (atm_a2l.h5m), which has an extra tag, corresponding to the
32  * variable a2lTbot_proj from the file wholeLND_proj01.h5m; matching is based on the global ids
33  * between what we think is the order on the original file (wholeFineATM.h5m) and the order of
34  * surfdata_ne11np4_simyr1850_c160614.nc
35  *
36  * file wholeFineATM.h5m is obtained from a coupled run in e3sm, with the ne 11, np 4,
37  *
38  * @param argc Number of command line arguments
39  * @param argv Command line arguments array
40  * @return 0 on success, 1 on failure
41  */
42 #include "moab/ProgOptions.hpp"
43 #include "moab/Core.hpp"
44 
45 #include <cmath>
46 #include <sstream>
47 
48 using namespace moab;
49 
50 int main( int argc, char* argv[] )
51 {
52 
53  ProgOptions opts;
54 
55  std::string inputfile, outfile( "out.h5m" ), sourcefile, variable_name;
56  int dual_mesh = 0;
57  opts.addOpt< std::string >( "input,i", "input mesh filename", &inputfile );
58  opts.addOpt< std::string >( "source,s", "h5m file aligned with the mesh input file", &sourcefile );
59  opts.addOpt< std::string >( "output,o", "output mesh filename", &outfile );
60 
61  opts.addOpt< std::string >( "var,v", "variable to extract and add to output file", &variable_name );
62  opts.addOpt< int >( "pentagon,p", "switch for dual mesh ", &dual_mesh );
63 
64  opts.parseCommandLine( argc, argv );
65 
66  std::cout << "input file: " << inputfile << "\n";
67  std::cout << "source file: " << sourcefile << "\n";
68  std::cout << "variable to copy: " << variable_name << "\n";
69  std::cout << "output file: " << outfile << "\n";
70 
71  if( inputfile.empty() )
72  {
73  opts.printHelp();
74  return 0;
75  }
76  ErrorCode rval;
77  Core* mb = new Core();
78 
79  MB_CHK_SET_ERR( mb->load_file( inputfile.c_str() ), "can't load input file" );
80 
81  Core* mb2 = new Core();
82  MB_CHK_SET_ERR( mb2->load_file( sourcefile.c_str() ), "can't load source file" );
83 
84  Tag sourceTag;
85  MB_CHK_SET_ERR( mb2->tag_get_handle( variable_name.c_str(), sourceTag ), "can't get tag from file" );
86 
87  int sizeTag = 0;
88  MB_CHK_SET_ERR( mb2->tag_get_length( sourceTag, sizeTag ), "can't get size of tag " );
89 
90  DataType type;
91  MB_CHK_SET_ERR( mb2->tag_get_data_type( sourceTag, type ), "can't get type of tag " );
92 
93  int sizeInBytes = 0;
94  MB_CHK_SET_ERR( mb2->tag_get_bytes( sourceTag, sizeInBytes ), "can't get size in bytes of tag " );
95 
96  Tag newTag;
97  /*
98  * ErrorCode tag_get_handle( const char* name,
99  int size,
100  DataType type,
101  Tag& tag_handle,
102  unsigned flags = 0,
103  const void* default_value = 0 )
104  */
105  void* defVal;
106  int defInt = -100000;
107  double defDouble = -1.e10;
108  if( type == MB_TYPE_INTEGER )
109  {
110  defVal = (void*)( &defInt );
111  }
112  else if( type == MB_TYPE_DOUBLE )
113  {
114  defVal = (void*)( &defDouble );
115  }
116 
117  MB_CHK_SET_ERR( mb->tag_get_handle( variable_name.c_str(), sizeTag, type, newTag, MB_TAG_DENSE | MB_TAG_CREAT,
118  defVal ),
119  "can't create new tag " );
120 
121  // get vertices on ini mesh; get global id on ini mesh
122  // get global id on source mesh
123  Tag gid;
124  Tag gid2;
125  MB_CHK_SET_ERR( mb->tag_get_handle( "GLOBAL_ID", gid ), "can't get GLOBAL_ID tag on ini mesh " );
126  MB_CHK_SET_ERR( mb2->tag_get_handle( "GLOBAL_ID", gid2 ), "can't get GLOBAL_ID tag on source mesh " );
127 
128  // get vertices on ini mesh; build
129  Range iniVerts;
130  MB_CHK_SET_ERR( mb->get_entities_by_dimension( 0, 0, iniVerts ), "can't get verts on initial mesh " );
131  if( 0 != dual_mesh )
132  {
133  // verts will be polygons
134  MB_CHK_SET_ERR( mb->get_entities_by_dimension( 0, 2, iniVerts ), "can't get polygons on initial mesh " );
135  }
136  std::vector< int > gids;
137  gids.resize( iniVerts.size() );
138  MB_CHK_SET_ERR( mb->tag_get_data( gid, iniVerts, &( gids[0] ) ), "can't get gid on initial verts " );
139  // build now the map
140  std::map< int, EntityHandle > fromGidToEh;
141  int i = 0;
142  for( Range::iterator vit = iniVerts.begin(); vit != iniVerts.end(); vit++, i++ )
143  {
144  fromGidToEh[gids[i]] = *vit;
145  }
146  // now get the source verts, and tags, and set it on new mesh
147 
148  char* valTag = new char[sizeInBytes];
149 
150  std::cout << " size of tag in bytes:" << sizeInBytes << "\n";
151  Range sourceVerts;
152  MB_CHK_SET_ERR( mb2->get_entities_by_dimension( 0, 0, sourceVerts ), "can't get verts on source mesh " );
153  for( Range::iterator sit = sourceVerts.begin(); sit != sourceVerts.end(); sit++ )
154  {
155  int globalId = 0;
156  EntityHandle sourceHandle = *sit;
157  MB_CHK_SET_ERR( mb2->tag_get_data( gid2, &sourceHandle, 1, &globalId ), "can't get id on source mesh " );
158  // iniVert could be a polygon, actually
159  EntityHandle iniVert = fromGidToEh[globalId];
160  // find the value of source tag
161  MB_CHK_SET_ERR( mb2->tag_get_data( sourceTag, &sourceHandle, 1, (void*)valTag ),
162  "can't get value on source tag " );
163 
164  MB_CHK_SET_ERR( mb->tag_set_data( newTag, &iniVert, 1, (void*)valTag ),
165  "can't set value on initial mesh, new tag " );
166  }
167 
168  // save file
169  MB_CHK_SET_ERR( mb->write_file( outfile.c_str() ), "can't write file" );
170 
171  delete[] valTag;
172  delete mb;
173  delete mb2;
174 
175  return 0;
176 }