MOAB: Mesh Oriented datABase  (version 5.4.0)
ReadRTT.cpp
Go to the documentation of this file.
00001 /**
00002  * MOAB, a Mesh-Oriented datABase, is a software component for creating,
00003  * storing and accessing finite element mesh data.
00004  *
00005  * Copyright 2004 Sandia Corporation.  Under the terms of Contract
00006  * DE-AC04-94AL85000 with Sandia Coroporation, the U.S. Government
00007  * retains certain rights in this software.
00008  *
00009  * This library is free software; you can redistribute it and/or
00010  * modify it under the terms of the GNU Lesser General Public
00011  * License as published by the Free Software Foundation; either
00012  * version 2.1 of the License, or (at your option) any later version.
00013  *
00014  */
00015 
00016 /**
00017  * \class ReadRTT
00018  * \brief ReadRTT based on ReadNASTRAN
00019  *
00020  * See:
00021  *
00022  * \author Andrew Davis
00023  */
00024 
00025 #include "ReadRTT.hpp"
00026 
00027 #include <iostream>
00028 #include <sstream>
00029 #include <fstream>
00030 #include <vector>
00031 #include <cstdlib>
00032 #include <map>
00033 #include <cassert>
00034 #include <cmath>
00035 
00036 #include "moab/Interface.hpp"
00037 #include "moab/ReadUtilIface.hpp"
00038 #include "Internals.hpp"  // for MB_START_ID
00039 #include "moab/Range.hpp"
00040 #include "moab/FileOptions.hpp"
00041 #include "FileTokenizer.hpp"
00042 #include "MBTagConventions.hpp"
00043 #include "moab/CN.hpp"
00044 #include "moab/ErrorHandler.hpp"
00045 #include "moab/GeomTopoTool.hpp"
00046 
00047 namespace moab
00048 {
00049 
00050 ReaderIface* ReadRTT::factory( Interface* iface )
00051 {
00052     return new ReadRTT( iface );
00053 }
00054 
00055 // constructor
00056 ReadRTT::ReadRTT( Interface* impl )
00057     : MBI( impl ), geom_tag( 0 ), id_tag( 0 ), name_tag( 0 ), category_tag( 0 ), faceting_tol_tag( 0 )
00058 {
00059     assert( NULL != impl );
00060     myGeomTool = new GeomTopoTool( impl );
00061     MBI->query_interface( readMeshIface );
00062     assert( NULL != readMeshIface );
00063 
00064     // this section copied from ReadCGM initalisation
00065     int negone  = -1;
00066     double zero = 0.;
00067     ErrorCode rval;
00068     rval = MBI->tag_get_handle( GEOM_DIMENSION_TAG_NAME, 1, MB_TYPE_INTEGER, geom_tag, MB_TAG_SPARSE | MB_TAG_CREAT,
00069                                 &negone );
00070     assert( !rval );
00071     id_tag = MBI->globalId_tag();
00072     rval = MBI->tag_get_handle( NAME_TAG_NAME, NAME_TAG_SIZE, MB_TYPE_OPAQUE, name_tag, MB_TAG_SPARSE | MB_TAG_CREAT );
00073     assert( !rval );
00074     rval = MBI->tag_get_handle( CATEGORY_TAG_NAME, CATEGORY_TAG_SIZE, MB_TYPE_OPAQUE, category_tag,
00075                                 MB_TAG_SPARSE | MB_TAG_CREAT );
00076     assert( !rval );
00077     rval =
00078         MBI->tag_get_handle( "FACETING_TOL", 1, MB_TYPE_DOUBLE, faceting_tol_tag, MB_TAG_SPARSE | MB_TAG_CREAT, &zero );
00079     assert( !rval );
00080 #ifdef NDEBUG
00081     if( !rval )
00082     {
00083     };  // Line to avoid compiler warning about variable set but not used
00084 #endif
00085 }
00086 
00087 // destructor
00088 ReadRTT::~ReadRTT()
00089 {
00090     if( readMeshIface )
00091     {
00092         MBI->release_interface( readMeshIface );
00093         readMeshIface = 0;
00094     }
00095 
00096     delete myGeomTool;
00097 }
00098 
00099 ErrorCode ReadRTT::read_tag_values( const char* /*file_name*/,
00100                                     const char* /*tag_name*/,
00101                                     const FileOptions& /*opts*/,
00102                                     std::vector< int >& /*tag_values_out*/,
00103                                     const SubsetList* /*subset_list*/ )
00104 {
00105     return MB_NOT_IMPLEMENTED;
00106 }
00107 
00108 // load the file as called by the Interface function
00109 ErrorCode ReadRTT::load_file( const char* filename,
00110                               const EntityHandle*,
00111                               const FileOptions&,
00112                               const ReaderIface::SubsetList* subset_list,
00113                               const Tag* /*file_id_tag*/ )
00114 {
00115     ErrorCode rval;
00116 
00117     // at this time there is no support for reading a subset of the file
00118     if( subset_list )
00119     {
00120         std::cout << "Subset reading not supported for RTT meshes" << std::endl;
00121         return MB_UNSUPPORTED_OPERATION;
00122     }
00123 
00124     // test to see if file exists
00125     FILE* file = NULL;
00126     file       = fopen( filename, "r" );
00127     if( file == NULL ) return MB_FILE_DOES_NOT_EXIST;
00128     // otherwise close the file
00129     fclose( file );
00130 
00131     // read the header
00132     rval = ReadRTT::read_header( filename );
00133     if( rval != MB_SUCCESS ) return rval;
00134 
00135     // read the side_flag data
00136     std::vector< side > side_data;
00137     rval = ReadRTT::read_sides( filename, side_data );
00138     if( rval != MB_SUCCESS ) return rval;
00139 
00140     // read the cell data
00141     std::vector< cell > cell_data;
00142     rval = ReadRTT::read_cells( filename, cell_data );
00143     if( rval != MB_SUCCESS ) return rval;
00144 
00145     // read the node data
00146     std::vector< node > node_data;
00147     rval = ReadRTT::read_nodes( filename, node_data );
00148     if( rval != MB_SUCCESS ) return rval;
00149 
00150     // read the facet data
00151     std::vector< facet > facet_data;
00152     rval = ReadRTT::read_facets( filename, facet_data );
00153     if( rval != MB_SUCCESS ) return rval;
00154 
00155     // read the tetrahedra data
00156     std::vector< tet > tet_data;
00157     rval = ReadRTT::read_tets( filename, tet_data );
00158     if( rval != MB_SUCCESS ) return rval;
00159 
00160     // make the map of surface number in the rttmesh to the surface meshset
00161     std::map< int, EntityHandle > surface_map;  // corrsespondance of surface number to entity handle
00162     rval = ReadRTT::generate_topology( side_data, cell_data, surface_map );
00163     if( rval != MB_SUCCESS ) return rval;
00164 
00165     // generate the rest of the database, triangles to surface meshsets etc
00166     rval = ReadRTT::build_moab( node_data, facet_data, tet_data, surface_map );
00167     if( rval != MB_SUCCESS ) return rval;
00168 
00169     return MB_SUCCESS;
00170 }
00171 
00172 /*
00173  * builds the topology of the problem
00174  */
00175 ErrorCode ReadRTT::generate_topology( std::vector< side > side_data,
00176                                       std::vector< cell > cell_data,
00177                                       std::map< int, EntityHandle >& surface_map )
00178 {
00179 
00180     ErrorCode rval;
00181     std::vector< EntityHandle > entmap[4];
00182     int num_ents[4];  // number of entities in each dimension
00183 
00184     const char geom_categories[][CATEGORY_TAG_SIZE] = { "Vertex\0", "Curve\0", "Surface\0", "Volume\0", "Group\0" };
00185 
00186     std::vector< int > surface_numbers;  // the surface numbers in the problem
00187 
00188     // corresponds to number of cad like surfaces and cad like volumes
00189     num_ents[2] = side_data.size();
00190     num_ents[3] = cell_data.size();
00191 
00192     // loop over surfaces & volumes
00193     for( int dim = 2; dim <= 3; dim++ )
00194     {
00195         for( int i = 0; i != num_ents[dim]; i++ )
00196         {
00197             EntityHandle handle;
00198             // create a meshset for each entity surface/volume
00199             rval = MBI->create_meshset( dim == 1 ? MESHSET_ORDERED : MESHSET_SET, handle );
00200             // if failure
00201             if( rval != MB_SUCCESS ) return rval;
00202 
00203             // collect the entity handles into an
00204             entmap[dim].push_back( handle );
00205 
00206             // set the dimension tag
00207             rval = MBI->tag_set_data( geom_tag, &handle, 1, &dim );
00208             // if fail
00209             if( MB_SUCCESS != rval ) return rval;
00210             // if we are a surface
00211             if( dim == 2 )
00212             {
00213                 // tag the id onto the surface meshset
00214                 rval = MBI->tag_set_data( id_tag, &handle, 1, &side_data[i].id );
00215                 // inesert entity into the map
00216                 surface_map[side_data[i].id] = handle;
00217             }
00218             else
00219             {
00220                 // otherwise we set the volume tag data, loop is only 2 & 3 dim
00221                 rval = MBI->tag_set_data( id_tag, &handle, 1, &cell_data[i].id );
00222             }
00223             // if fail
00224             if( MB_SUCCESS != rval ) return rval;
00225             // set the category tag
00226             rval = MBI->tag_set_data( category_tag, &handle, 1, &geom_categories[dim] );
00227             if( MB_SUCCESS != rval ) return rval;
00228         }
00229     }
00230 
00231     // generate parent child links
00232     // best to loop over the surfaces and assign them to volumes, we can then assign facets to
00233     // to each surface
00234     generate_parent_child_links( num_ents, entmap, side_data, cell_data );
00235 
00236     // set the surface senses
00237     set_surface_senses( num_ents, entmap, side_data, cell_data );
00238 
00239     // set the group data
00240     rval = setup_group_data( entmap );
00241 
00242     return MB_SUCCESS;
00243 }
00244 
00245 /*
00246  * builds the moab representation of the mesh
00247  */
00248 ErrorCode ReadRTT::build_moab( std::vector< node > node_data,
00249                                std::vector< facet > facet_data,
00250                                std::vector< tet > tet_data,
00251                                std::map< int, EntityHandle > surface_map )
00252 {
00253 
00254     ErrorCode rval;         // reusable return value
00255     EntityHandle file_set;  // the file handle
00256     // create the file set
00257     rval = MBI->create_meshset( MESHSET_SET, file_set );
00258     if( MB_SUCCESS != rval ) return rval;
00259 
00260     // create the vertices
00261     EntityHandle handle;
00262     std::vector< node >::iterator it;  // iterate over the nodes
00263     Range mb_coords;                   // range of coordinates
00264     for( it = node_data.begin(); it != node_data.end(); ++it )
00265     {
00266         node tmp         = *it;
00267         double coords[3] = { tmp.x, tmp.y, tmp.z };
00268         rval             = MBI->create_vertex( coords, handle );
00269         if( MB_SUCCESS != rval ) return rval;
00270         mb_coords.insert( handle );  // inesert handle into the coordinate range
00271     }
00272 
00273     // add verts to set
00274     rval = MBI->add_entities( file_set, mb_coords );
00275 
00276     // create sense tag
00277     Tag side_id_tag, surface_number_tag;
00278     //  int zero = 0;
00279     rval = MBI->tag_get_handle( "SIDEID_TAG", 1, MB_TYPE_INTEGER, side_id_tag, MB_TAG_SPARSE | MB_TAG_CREAT );
00280     rval =
00281         MBI->tag_get_handle( "SURFACE_NUMBER", 1, MB_TYPE_INTEGER, surface_number_tag, MB_TAG_SPARSE | MB_TAG_CREAT );
00282 
00283     // create the facets
00284     EntityHandle triangle;
00285     std::vector< facet >::iterator it_f;
00286     // range of triangles
00287     Range mb_tris;
00288     // loop over the facet data
00289     for( it_f = facet_data.begin(); it_f != facet_data.end(); ++it_f )
00290     {
00291         facet tmp = *it_f;
00292         // get the nodes for the triangle
00293         EntityHandle tri_nodes[3] = { mb_coords[tmp.connectivity[0] - 1], mb_coords[tmp.connectivity[1] - 1],
00294                                       mb_coords[tmp.connectivity[2] - 1] };
00295         // create a triangle element
00296         rval = MBI->create_element( MBTRI, tri_nodes, 3, triangle );
00297         // tag in side id on the triangle
00298         rval = MBI->tag_set_data( side_id_tag, &triangle, 1, &tmp.side_id );
00299         // tag the surface number on the triangle
00300         rval = MBI->tag_set_data( surface_number_tag, &triangle, 1, &tmp.surface_number );
00301         // insert vertices and triangles into the appropriate surface meshset
00302         EntityHandle meshset_handle = surface_map[tmp.surface_number];
00303         // also set surface tag
00304         rval = MBI->tag_set_data( side_id_tag, &meshset_handle, 1, &tmp.side_id );
00305         rval = MBI->tag_set_data( surface_number_tag, &meshset_handle, 1, &tmp.surface_number );
00306         // add vertices to the mesh
00307         rval = MBI->add_entities( meshset_handle, &( *tri_nodes ), 3 );
00308         // add triangles to the meshset
00309         rval = MBI->add_entities( meshset_handle, &triangle, 1 );
00310         // ineter triangles into large run
00311         mb_tris.insert( triangle );
00312     }
00313     // add tris to set to fileset
00314     rval = MBI->add_entities( file_set, mb_tris );
00315 
00316     // create material number tag
00317     Tag mat_num_tag;
00318     //  int zero = 0;
00319     rval = MBI->tag_get_handle( "MATERIAL_NUMBER", 1, MB_TYPE_INTEGER, mat_num_tag, MB_TAG_SPARSE | MB_TAG_CREAT );
00320 
00321     // create the tets
00322     EntityHandle tetra;  // handle for a specific tet
00323     std::vector< tet >::iterator it_t;
00324     Range mb_tets;
00325     // loop over all tets
00326     for( it_t = tet_data.begin(); it_t != tet_data.end(); ++it_t )
00327     {
00328         tet tmp = *it_t;
00329         // get the handles for the tet
00330         EntityHandle tet_nodes[4] = { mb_coords[tmp.connectivity[0] - 1], mb_coords[tmp.connectivity[1] - 1],
00331                                       mb_coords[tmp.connectivity[2] - 1], mb_coords[tmp.connectivity[3] - 1] };
00332         // create the tet
00333         rval           = MBI->create_element( MBTET, tet_nodes, 4, tetra );
00334         int mat_number = tmp.material_number;
00335         // tag the tet with the material number
00336         rval = MBI->tag_set_data( mat_num_tag, &tetra, 1, &mat_number );
00337         // set the tag data
00338         mb_tets.insert( tetra );
00339     }
00340     // add tris to set
00341     rval = MBI->add_entities( file_set, mb_tets );
00342 
00343     return MB_SUCCESS;
00344 }
00345 
00346 /*
00347  * read the header data from the filename pointed to
00348  */
00349 ErrorCode ReadRTT::read_header( const char* filename )
00350 {
00351     std::ifstream input_file( filename );  // filename for rtt file
00352     // file ok?
00353     if( !input_file.good() )
00354     {
00355         std::cout << "Problems reading file = " << filename << std::endl;
00356         return MB_FAILURE;
00357     }
00358 
00359     // if it works
00360     std::string line;
00361     moab::ErrorCode rval = MB_FAILURE;
00362     if( input_file.is_open() )
00363     {
00364         while( std::getline( input_file, line ) )
00365         {
00366             if( line.compare( "header" ) == 0 )
00367             {
00368                 rval = get_header_data( input_file );
00369             }
00370         }
00371         input_file.close();
00372     }
00373     return rval;
00374 }
00375 
00376 /*
00377  * reads the side data from the filename pointed to
00378  */
00379 ErrorCode ReadRTT::read_sides( const char* filename, std::vector< side >& side_data )
00380 {
00381     std::string line;                      // the current line being read
00382     std::ifstream input_file( filename );  // filestream for rttfile
00383     // file ok?
00384     if( !input_file.good() )
00385     {
00386         std::cout << "Problems reading file = " << filename << std::endl;
00387         return MB_FAILURE;
00388     }
00389     // if it works
00390     if( input_file.is_open() )
00391     {
00392         while( std::getline( input_file, line ) )
00393         {
00394             if( line.compare( "  2 FACES\0" ) == 0 )
00395             {
00396                 // read lines until find end nodes
00397                 while( std::getline( input_file, line ) )
00398                 {
00399                     if( line.compare( "end_side_flags\0" ) == 0 ) break;
00400                     side data = ReadRTT::get_side_data( line );
00401                     side_data.push_back( data );
00402                 }
00403             }
00404         }
00405         input_file.close();
00406     }
00407     if( side_data.size() == 0 ) return MB_FAILURE;
00408     return MB_SUCCESS;
00409 }
00410 
00411 /*
00412  * reads the cell data from the filename pointed to
00413  */
00414 ErrorCode ReadRTT::read_cells( const char* filename, std::vector< cell >& cell_data )
00415 {
00416     std::string line;                      // the current line being read
00417     std::ifstream input_file( filename );  // filestream for rttfile
00418     // file ok?
00419     if( !input_file.good() )
00420     {
00421         std::cout << "Problems reading file = " << filename << std::endl;
00422         return MB_FAILURE;
00423     }
00424     // if it works
00425     if( input_file.is_open() )
00426     {
00427         while( std::getline( input_file, line ) )
00428         {
00429             if( line.compare( "  1 REGIONS\0" ) == 0 )
00430             {
00431                 // read lines until find end nodes
00432                 while( std::getline( input_file, line ) )
00433                 {
00434                     if( line.compare( "end_cell_flags\0" ) == 0 ) break;
00435                     cell data = ReadRTT::get_cell_data( line );
00436                     cell_data.push_back( data );
00437                 }
00438             }
00439         }
00440         input_file.close();
00441     }
00442     if( cell_data.size() == 0 ) return MB_FAILURE;
00443     return MB_SUCCESS;
00444 }
00445 
00446 /*
00447  * Reads the node data fromt the filename pointed to
00448  */
00449 ErrorCode ReadRTT::read_nodes( const char* filename, std::vector< node >& node_data )
00450 {
00451     std::string line;                      // the current line being read
00452     std::ifstream input_file( filename );  // filestream for rttfile
00453     // file ok?
00454     if( !input_file.good() )
00455     {
00456         std::cout << "Problems reading file = " << filename << std::endl;
00457         return MB_FAILURE;
00458     }
00459 
00460     // if it works
00461     if( input_file.is_open() )
00462     {
00463         while( std::getline( input_file, line ) )
00464         {
00465             if( line.compare( "nodes\0" ) == 0 )
00466             {
00467                 // read lines until find end nodes
00468                 while( std::getline( input_file, line ) )
00469                 {
00470                     if( line.compare( "end_nodes\0" ) == 0 ) break;
00471                     node data = ReadRTT::get_node_data( line );
00472                     node_data.push_back( data );
00473                 }
00474             }
00475         }
00476         input_file.close();
00477     }
00478     if( node_data.size() == 0 ) return MB_FAILURE;
00479     return MB_SUCCESS;
00480 }
00481 
00482 /*
00483  * Reads the facet data fromt the filename pointed to
00484  */
00485 ErrorCode ReadRTT::read_facets( const char* filename, std::vector< facet >& facet_data )
00486 {
00487     std::string line;                      // the current line being read
00488     std::ifstream input_file( filename );  // filestream for rttfile
00489     // file ok?
00490     if( !input_file.good() )
00491     {
00492         std::cout << "Problems reading file = " << filename << std::endl;
00493         return MB_FAILURE;
00494     }
00495 
00496     // if it works
00497     if( input_file.is_open() )
00498     {
00499         while( std::getline( input_file, line ) )
00500         {
00501             if( line.compare( "sides\0" ) == 0 )
00502             {
00503                 // read lines until find end nodes
00504                 while( std::getline( input_file, line ) )
00505                 {
00506                     if( line.compare( "end_sides\0" ) == 0 ) break;
00507                     facet data = ReadRTT::get_facet_data( line );
00508                     facet_data.push_back( data );
00509                 }
00510             }
00511         }
00512         input_file.close();
00513     }
00514     if( facet_data.size() == 0 ) return MB_FAILURE;
00515     return MB_SUCCESS;
00516 }
00517 
00518 /*
00519  * Reads the facet data fromt the filename pointed to
00520  */
00521 ErrorCode ReadRTT::read_tets( const char* filename, std::vector< tet >& tet_data )
00522 {
00523     std::string line;                      // the current line being read
00524     std::ifstream input_file( filename );  // filestream for rttfile
00525     // file ok?
00526     if( !input_file.good() )
00527     {
00528         std::cout << "Problems reading file = " << filename << std::endl;
00529         return MB_FAILURE;
00530     }
00531     // if it works
00532     if( input_file.is_open() )
00533     {
00534         while( std::getline( input_file, line ) )
00535         {
00536             if( line.compare( "cells\0" ) == 0 )
00537             {
00538                 // read lines until find end nodes
00539                 while( std::getline( input_file, line ) )
00540                 {
00541                     if( line.compare( "end_cells\0" ) == 0 ) break;
00542                     tet data = ReadRTT::get_tet_data( line );
00543                     tet_data.push_back( data );
00544                 }
00545             }
00546         }
00547         input_file.close();
00548     }
00549     if( tet_data.size() == 0 ) return MB_FAILURE;
00550     return MB_SUCCESS;
00551 }
00552 
00553 /*
00554  * given the open file handle read until we find
00555  */
00556 ErrorCode ReadRTT::get_header_data( std::ifstream& input_file )
00557 {
00558     std::string line;
00559     while( std::getline( input_file, line ) )
00560     {
00561 
00562         // tokenize the line
00563         std::istringstream iss( line );
00564         std::vector< std::string > split_string;
00565         do
00566         {
00567             std::string sub_string;
00568             iss >> sub_string;
00569             split_string.push_back( sub_string );
00570         } while( iss );
00571 
00572         // if we find version
00573         if( line.find( "version" ) != std::string::npos )
00574         {
00575             if( split_string[1].find( "v" ) != std::string::npos &&
00576                 split_string[0].find( "version" ) != std::string::npos )
00577             {
00578                 header_data.version = split_string[1];
00579             }
00580         }
00581 
00582         if( line.find( "title" ) != std::string::npos )
00583         {
00584             header_data.title = split_string[1];
00585         }
00586         if( line.find( "date" ) != std::string::npos )
00587         {
00588             header_data.date = split_string[1];
00589         }
00590         if( line.find( "end_header" ) != std::string::npos )
00591         {
00592             return MB_SUCCESS;
00593         }
00594     }
00595 
00596     // otherwise we never found the end_header keyword
00597     return MB_FAILURE;
00598 }
00599 
00600 /*
00601  * given the string sidedata, get the id number, senses and names of the sides
00602  */
00603 ReadRTT::side ReadRTT::get_side_data( std::string sidedata )
00604 {
00605     side new_side;
00606     std::vector< std::string > tokens;
00607     tokens = ReadRTT::split_string( sidedata, ' ' );
00608 
00609     // set the side id
00610     if( tokens.size() != 2 )
00611     {
00612         MB_SET_ERR_RET_VAL( "Error, too many tokens found from side_data", new_side );
00613     }
00614     // create the new side
00615     new_side.id = std::atoi( tokens[0].c_str() );
00616 
00617     std::vector< std::string > cell_names = ReadRTT::split_string( tokens[1], '/' );
00618     // get the boundary
00619     boundary new_bnd = ReadRTT::split_name( cell_names[0] );
00620     // set the surface sense and name
00621     new_side.senses[0] = new_bnd.sense;
00622     new_side.names[0]  = new_bnd.name;
00623     //
00624     if( cell_names.size() > 1 )
00625     {
00626         boundary bnd       = ReadRTT::split_name( cell_names[1] );
00627         new_side.senses[1] = bnd.sense;
00628         new_side.names[1]  = bnd.name;
00629     }
00630     else
00631     {
00632         new_side.senses[1] = 0;
00633         new_side.names[1]  = "\0";
00634     }
00635 
00636     return new_side;
00637 }
00638 
00639 /*
00640  * given the string celldata, get the id number and name of each cell
00641  */
00642 ReadRTT::cell ReadRTT::get_cell_data( std::string celldata )
00643 {
00644     cell new_cell;
00645     std::vector< std::string > tokens;
00646     tokens = ReadRTT::split_string( celldata, ' ' );
00647 
00648     // set the side id
00649     if( tokens.size() != 2 )
00650     {
00651         MB_SET_ERR_RET_VAL( "Error, too many tokens found from cell_data", new_cell );
00652     }
00653     // create the new side
00654     new_cell.id   = std::atoi( tokens[0].c_str() );
00655     new_cell.name = tokens[1];
00656 
00657     return new_cell;
00658 }
00659 
00660 /*
00661  * given the string nodedata, get the id number and coordinates of the node
00662  */
00663 ReadRTT::node ReadRTT::get_node_data( std::string nodedata )
00664 {
00665     node new_node;
00666     std::vector< std::string > tokens;
00667     tokens = ReadRTT::split_string( nodedata, ' ' );
00668 
00669     // set the side id
00670     if( tokens.size() != 5 )
00671     {
00672         MB_SET_ERR_RET_VAL( "Error, too many tokens found from get_node_data", new_node );
00673     }
00674     new_node.id = std::atoi( tokens[0].c_str() );
00675     new_node.x  = std::atof( tokens[1].c_str() );
00676     new_node.y  = std::atof( tokens[2].c_str() );
00677     new_node.z  = std::atof( tokens[3].c_str() );
00678     return new_node;
00679 }
00680 
00681 /*
00682  * given the string nodedata, get the id number, connectivity and sense data
00683  */
00684 ReadRTT::facet ReadRTT::get_facet_data( std::string facetdata )
00685 {
00686     facet new_facet;
00687     std::vector< std::string > tokens;
00688     tokens = ReadRTT::split_string( facetdata, ' ' );
00689 
00690     // set the side id
00691     if( tokens.size() != 7 )
00692     {
00693         MB_SET_ERR_RET_VAL( "Error, too many tokens found from get_facet_data", new_facet );
00694     }
00695 
00696     new_facet.id = std::atoi( tokens[0].c_str() );
00697     // branch on the rtt version number
00698     if( header_data.version == "v1.0.0" )
00699     {
00700         new_facet.connectivity[0] = std::atoi( tokens[1].c_str() );
00701         new_facet.connectivity[1] = std::atoi( tokens[2].c_str() );
00702         new_facet.connectivity[2] = std::atoi( tokens[3].c_str() );
00703         new_facet.side_id         = std::atoi( tokens[4].c_str() );
00704         new_facet.surface_number  = std::atoi( tokens[5].c_str() );
00705     }
00706     else if( header_data.version == "v1.0.1" )
00707     {
00708         new_facet.connectivity[0] = std::atoi( tokens[2].c_str() );
00709         new_facet.connectivity[1] = std::atoi( tokens[3].c_str() );
00710         new_facet.connectivity[2] = std::atoi( tokens[4].c_str() );
00711         new_facet.side_id         = std::atoi( tokens[5].c_str() );
00712         new_facet.surface_number  = std::atoi( tokens[6].c_str() );
00713     }
00714     else
00715     {
00716         MB_SET_ERR_RET_VAL( "Error, version number not understood", new_facet );
00717     }
00718 
00719     return new_facet;
00720 }
00721 
00722 /*
00723  * given the string tetdata, get the id number, connectivity and mat num of the tet
00724  */
00725 ReadRTT::tet ReadRTT::get_tet_data( std::string tetdata )
00726 {
00727     tet new_tet;
00728     std::vector< std::string > tokens;
00729     tokens = ReadRTT::split_string( tetdata, ' ' );
00730 
00731     // set the side id
00732     if( tokens.size() != 7 )
00733     {
00734         MB_SET_ERR_RET_VAL( "Error, too many tokens found from get_tet_data", new_tet );
00735     }
00736     new_tet.id = std::atoi( tokens[0].c_str() );
00737     // branch on the version number
00738     if( header_data.version == "v1.0.0" )
00739     {
00740         new_tet.connectivity[0] = std::atoi( tokens[1].c_str() );
00741         new_tet.connectivity[1] = std::atoi( tokens[2].c_str() );
00742         new_tet.connectivity[2] = std::atoi( tokens[3].c_str() );
00743         new_tet.connectivity[3] = std::atoi( tokens[4].c_str() );
00744         new_tet.material_number = std::atoi( tokens[5].c_str() );
00745     }
00746     else if( header_data.version == "v1.0.1" )
00747     {
00748         new_tet.connectivity[0] = std::atoi( tokens[2].c_str() );
00749         new_tet.connectivity[1] = std::atoi( tokens[3].c_str() );
00750         new_tet.connectivity[2] = std::atoi( tokens[4].c_str() );
00751         new_tet.connectivity[3] = std::atoi( tokens[5].c_str() );
00752         new_tet.material_number = std::atoi( tokens[6].c_str() );
00753     }
00754     else
00755     {
00756         MB_SET_ERR_RET_VAL( "Error, version number not supported", new_tet );
00757     }
00758 
00759     return new_tet;
00760 }
00761 
00762 /*
00763  * splits string into sense and name, to later facilitate the building
00764  * of sense data, strips off the tailing @ if it exists
00765  */
00766 ReadRTT::boundary ReadRTT::split_name( std::string atilla_cellname )
00767 {
00768     boundary new_boundary;
00769     // default initialisation
00770     new_boundary.sense = 0;
00771     new_boundary.name  = "\0";
00772     // +ve sense
00773     if( atilla_cellname.find( "+" ) != std::string::npos )
00774     {
00775         new_boundary.sense = 1;
00776         // look for the @# we do not want it
00777         std::size_t found = atilla_cellname.find( "@" );
00778         if( found != std::string::npos )
00779             new_boundary.name = atilla_cellname.substr( 3, found );
00780         else
00781             new_boundary.name = atilla_cellname.substr( 3, atilla_cellname.length() );
00782     }
00783     else if( atilla_cellname.find( "-" ) != std::string::npos )
00784     {
00785         // negative sense
00786         new_boundary.sense = -1;
00787         new_boundary.name  = atilla_cellname.substr( 3, atilla_cellname.length() );
00788     }
00789     return new_boundary;
00790 }
00791 
00792 /*
00793  * splits a string in a vector of strings split by spaces
00794  */
00795 std::vector< std::string > ReadRTT::split_string( std::string string_to_split, char split_char )
00796 {
00797     std::istringstream ss( string_to_split );
00798     std::vector< std::string > tokens;
00799     while( !ss.eof() )
00800     {
00801         std::string x;                      // here's a nice, empty string
00802         std::getline( ss, x, split_char );  // try to read the next field into it
00803         tokens.push_back( x );
00804     }
00805 
00806     // remove empty tokens
00807     std::vector< std::string >::iterator it;
00808     for( it = tokens.begin(); it != tokens.end(); )
00809     {
00810         std::string string = *it;
00811         if( string.compare( "\0" ) == 0 )
00812             it = tokens.erase( it );
00813         else
00814             ++it;
00815     }
00816     return tokens;
00817 }
00818 
00819 /*
00820  * Generate the parent-child links bwetween the cell and surface meshsets
00821  */
00822 void ReadRTT::generate_parent_child_links( int num_ents[4],
00823                                            std::vector< EntityHandle > entity_map[4],
00824                                            std::vector< side > side_data,
00825                                            std::vector< cell > cell_data )
00826 {
00827     ErrorCode rval;  // return value
00828     // loop over the number of surfaces
00829     for( int i = 0; i < num_ents[2]; i++ )
00830     {
00831         // get the surface handle
00832         EntityHandle surf_handle = entity_map[2][i];
00833         // there are volumes that share this face
00834         for( unsigned int shared = 0; shared <= 1; shared++ )
00835         {
00836             std::string parent_name = side_data[i].names[shared];
00837             // find the @ sign
00838             unsigned pos = parent_name.find( "@" );
00839             parent_name  = parent_name.substr( 0, pos );
00840 
00841             // loop over tets looking for matching name
00842             for( int j = 0; j < num_ents[3]; j++ )
00843             {
00844                 // if match found
00845                 if( cell_data[j].name.compare( parent_name ) == 0 )
00846                 {
00847                     EntityHandle cell_handle = entity_map[3][j];
00848                     // parent
00849                     rval = MBI->add_parent_child( cell_handle, surf_handle );
00850                     if( rval != MB_SUCCESS )
00851                     {
00852                         std::cerr << "Failed to add parent child relationship" << std::endl;
00853                     }
00854                 }
00855             }
00856         }
00857     }
00858     return;
00859 }
00860 
00861 /*
00862  * sets the sense of the surfaces wrt to volumes using geom topo tool
00863  */
00864 void ReadRTT::set_surface_senses( int num_ents[4],
00865                                   std::vector< EntityHandle > entity_map[4],
00866                                   std::vector< side > side_data,
00867                                   std::vector< cell > cell_data )
00868 {
00869 
00870     ErrorCode rval;  // return value
00871     // loop over the number of surfaces
00872     for( int i = 0; i < num_ents[2]; i++ )
00873     {
00874         EntityHandle surf_handle = entity_map[2][i];
00875         // there are 2 volumes that share this face
00876         for( unsigned int shared = 0; shared <= 1; shared++ )
00877         {
00878             std::string parent_name = side_data[i].names[shared];
00879             unsigned pos            = parent_name.find( "@" );
00880             parent_name             = parent_name.substr( 0, pos );
00881             // loop over tets looking for matching name
00882             for( int j = 0; j < num_ents[3]; j++ )
00883             {
00884                 // if match found
00885                 if( cell_data[j].name.compare( parent_name ) == 0 )
00886                 {
00887                     EntityHandle cell_handle = entity_map[3][j];
00888                     // in rtt mesh +represents the inside and -represents outside
00889                     // in moab reverse is outside and forward is inside
00890                     if( side_data[i].senses[shared] == 1 )
00891                         rval = myGeomTool->set_sense( surf_handle, cell_handle, SENSE_FORWARD );
00892                     else if( side_data[i].senses[shared] == -1 )
00893                         rval = myGeomTool->set_sense( surf_handle, cell_handle, SENSE_REVERSE );
00894                     else
00895                         rval = myGeomTool->set_sense( surf_handle, 0, SENSE_REVERSE );
00896 
00897                     if( rval != MB_SUCCESS )
00898                     {
00899                         std::cerr << "Failed to set sense appropriately" << std::endl;
00900                     }
00901                 }
00902             }
00903         }
00904     }
00905     return;
00906 }
00907 
00908 /*
00909  * Add all entities that are to be part of the graveyard
00910  */
00911 ErrorCode ReadRTT::setup_group_data( std::vector< EntityHandle > entity_map[4] )
00912 {
00913     ErrorCode rval;  // error codes
00914     EntityHandle handle;
00915     handle = create_group( "graveyard_comp", 1 );
00916 
00917     // add any volume to group graveyard, it is ignored by dag
00918     EntityHandle vol_handle = entity_map[3][0];
00919     rval                    = MBI->add_entities( handle, &vol_handle, 1 );
00920     return rval;
00921 }
00922 
00923 /*
00924  * create a new group of with the name group name and id
00925  */
00926 EntityHandle ReadRTT::create_group( std::string group_name, int id )
00927 {
00928     ErrorCode rval;
00929     // category tags
00930     const char geom_categories[][CATEGORY_TAG_SIZE] = { "Vertex\0", "Curve\0", "Surface\0", "Volume\0", "Group\0" };
00931 
00932     EntityHandle handle;
00933     rval = MBI->create_meshset( MESHSET_SET, handle );
00934     if( MB_SUCCESS != rval ) return rval;
00935 
00936     rval = MBI->tag_set_data( name_tag, &handle, 1, group_name.c_str() );
00937     if( MB_SUCCESS != rval ) return MB_FAILURE;
00938 
00939     rval = MBI->tag_set_data( id_tag, &handle, 1, &id );
00940     if( MB_SUCCESS != rval ) return MB_FAILURE;
00941 
00942     rval = MBI->tag_set_data( category_tag, &handle, 1, &geom_categories[4] );
00943     if( MB_SUCCESS != rval ) return MB_FAILURE;
00944 
00945     return handle;
00946 }
00947 
00948 }  // namespace moab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines