LCOV - code coverage report
Current view: top level - src/io - ReadNASTRAN.cpp (source / functions) Hit Total Coverage
Test: coverage_sk.info Lines: 58 197 29.4 %
Date: 2020-12-16 07:07:30 Functions: 9 15 60.0 %
Branches: 46 382 12.0 %

           Branch data     Line data    Source code
       1                 :            : /**
       2                 :            :  * MOAB, a Mesh-Oriented datABase, is a software component for creating,
       3                 :            :  * storing and accessing finite element mesh data.
       4                 :            :  *
       5                 :            :  * Copyright 2004 Sandia Corporation.  Under the terms of Contract
       6                 :            :  * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government
       7                 :            :  * retains certain 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                 :            :  */
      15                 :            : 
      16                 :            : #include "ReadNASTRAN.hpp"
      17                 :            : 
      18                 :            : #include <iostream>
      19                 :            : #include <sstream>
      20                 :            : #include <fstream>
      21                 :            : #include <vector>
      22                 :            : #include <cstdlib>
      23                 :            : #include <assert.h>
      24                 :            : #include <cmath>
      25                 :            : 
      26                 :            : #include "moab/Interface.hpp"
      27                 :            : #include "moab/ReadUtilIface.hpp"
      28                 :            : #include "Internals.hpp"  // For MB_START_ID
      29                 :            : #include "moab/Range.hpp"
      30                 :            : #include "moab/FileOptions.hpp"
      31                 :            : #include "FileTokenizer.hpp"
      32                 :            : #include "MBTagConventions.hpp"
      33                 :            : #include "moab/CN.hpp"
      34                 :            : 
      35                 :            : namespace moab
      36                 :            : {
      37                 :            : 
      38                 :          1 : ReaderIface* ReadNASTRAN::factory( Interface* iface )
      39                 :            : {
      40         [ +  - ]:          1 :     return new ReadNASTRAN( iface );
      41                 :            : }
      42                 :            : 
      43                 :            : // Constructor
      44 [ +  - ][ +  - ]:          2 : ReadNASTRAN::ReadNASTRAN( Interface* impl ) : MBI( impl )
      45                 :            : {
      46         [ -  + ]:          1 :     assert( NULL != impl );
      47         [ +  - ]:          1 :     MBI->query_interface( readMeshIface );
      48         [ -  + ]:          1 :     assert( NULL != readMeshIface );
      49                 :          1 : }
      50                 :            : 
      51                 :            : // Destructor
      52                 :          3 : ReadNASTRAN::~ReadNASTRAN()
      53                 :            : {
      54         [ +  - ]:          1 :     if( readMeshIface )
      55                 :            :     {
      56                 :          1 :         MBI->release_interface( readMeshIface );
      57                 :          1 :         readMeshIface = 0;
      58                 :            :     }
      59         [ -  + ]:          2 : }
      60                 :            : 
      61                 :          0 : ErrorCode ReadNASTRAN::read_tag_values( const char* /*file_name*/, const char* /*tag_name*/,
      62                 :            :                                         const FileOptions& /*opts*/, std::vector< int >& /*tag_values_out*/,
      63                 :            :                                         const SubsetList* /*subset_list*/ )
      64                 :            : {
      65                 :          0 :     return MB_NOT_IMPLEMENTED;
      66                 :            : }
      67                 :            : 
      68                 :            : // Load the file as called by the Interface function
      69                 :          1 : ErrorCode ReadNASTRAN::load_file( const char* filename, const EntityHandle* /* file_set */,
      70                 :            :                                   const FileOptions& /* opts */, const ReaderIface::SubsetList* subset_list,
      71                 :            :                                   const Tag* file_id_tag )
      72                 :            : {
      73                 :            :     // At this time there is no support for reading a subset of the file
      74 [ -  + ][ #  # ]:          1 :     if( subset_list ) { MB_SET_ERR( MB_UNSUPPORTED_OPERATION, "Reading subset of files not supported for NASTRAN" ); }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
      75                 :            : 
      76         [ +  - ]:          1 :     nodeIdMap.clear();
      77         [ +  - ]:          1 :     elemIdMap.clear();
      78                 :            : 
      79                 :          1 :     bool debug = false;
      80 [ -  + ][ #  # ]:          1 :     if( debug ) std::cout << "begin ReadNASTRAN::load_file" << std::endl;
                 [ #  # ]
      81                 :            :     ErrorCode result;
      82                 :            : 
      83                 :            :     // Count the entities of each type in the file. This is used to allocate the node array.
      84                 :            :     int entity_count[MBMAXTYPE];
      85         [ +  + ]:         13 :     for( int i = 0; i < MBMAXTYPE; i++ )
      86                 :         12 :         entity_count[i] = 0;
      87                 :            : 
      88                 :            :     /* Determine the line_format of the first line. Assume that the entire file
      89                 :            :        has the same format. */
      90         [ +  - ]:          1 :     std::string line;
      91         [ +  - ]:          2 :     std::ifstream file( filename );
      92 [ +  - ][ +  - ]:          1 :     if( !getline( file, line ) ) return MB_FILE_DOES_NOT_EXIST;
                 [ -  + ]
      93                 :            :     line_format format;
      94         [ +  - ]:          1 :     result = determine_line_format( line, format );
      95         [ -  + ]:          1 :     if( MB_SUCCESS != result ) return result;
      96                 :            : 
      97                 :            :     /* Count the number of each entity in the file. This allows one to allocate
      98                 :            :        a sequential array of vertex handles. */
      99 [ +  - ][ +  - ]:          1 :     while( !file.eof() )
     100                 :            :     {
     101                 :            :         // Cut the line into fields as determined by the line format.
     102                 :            :         // Use a vector to allow for an unknown number of tokens (continue lines).
     103                 :            :         // Continue lines are not implemented.
     104         [ +  - ]:          1 :         std::vector< std::string > tokens;
     105         [ +  - ]:          1 :         tokens.reserve( 10 );  // assume 10 fields to avoid extra vector resizing
     106         [ +  - ]:          1 :         result = tokenize_line( line, format, tokens );
     107         [ -  + ]:          1 :         if( MB_SUCCESS != result ) return result;
     108                 :            : 
     109                 :            :         // Process the tokens of the line. The first token describes the entity type.
     110                 :            :         EntityType type;
     111 [ -  + ][ #  # ]:          1 :         result = determine_entity_type( ( tokens.empty() ) ? "" : tokens.front(), type );
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
                 [ #  # ]
     112         [ +  - ]:          1 :         if( MB_SUCCESS != result ) return result;
     113                 :          0 :         entity_count[type]++;
     114 [ #  # ][ -  + ]:          1 :         getline( file, line );
     115                 :          1 :     }
     116                 :            : 
     117         [ #  # ]:          0 :     if( debug )
     118                 :            :     {
     119         [ #  # ]:          0 :         for( int i = 0; i < MBMAXTYPE; i++ )
     120                 :            :         {
     121 [ #  # ][ #  # ]:          0 :             std::cout << "entity_count[" << i << "]=" << entity_count[i] << std::endl;
         [ #  # ][ #  # ]
                 [ #  # ]
     122                 :            :         }
     123                 :            :     }
     124                 :            : 
     125                 :            :     // Keep list of material sets
     126         [ #  # ]:          0 :     std::vector< Range > materials;
     127                 :            : 
     128                 :            :     // Now that the number of vertices is known, create the vertices.
     129                 :          0 :     EntityHandle start_vert = 0;
     130         [ #  # ]:          0 :     std::vector< double* > coord_arrays( 3 );
     131         [ #  # ]:          0 :     result = readMeshIface->get_node_coords( 3, entity_count[0], MB_START_ID, start_vert, coord_arrays );
     132         [ #  # ]:          0 :     if( MB_SUCCESS != result ) return result;
     133         [ #  # ]:          0 :     if( 0 == start_vert ) return MB_FAILURE;  // check for NULL
     134                 :          0 :     int id, vert_index = 0;
     135 [ #  # ][ #  # ]:          0 :     if( debug ) std::cout << "allocated coord arrays" << std::endl;
                 [ #  # ]
     136                 :            : 
     137                 :            :     // Read the file again to create the entities.
     138         [ #  # ]:          0 :     file.clear();     // Clear eof state from object
     139 [ #  # ][ #  # ]:          0 :     file.seekg( 0 );  // Rewind file
     140 [ #  # ][ #  # ]:          0 :     while( !file.eof() )
     141                 :            :     {
     142         [ #  # ]:          0 :         getline( file, line );
     143                 :            : 
     144                 :            :         // Cut the line into fields as determined by the line format.
     145                 :            :         // Use a vector to allow for an unknown number of tokens (continue lines).
     146                 :            :         // Continue lines are not implemented.
     147         [ #  # ]:          0 :         std::vector< std::string > tokens;
     148         [ #  # ]:          0 :         tokens.reserve( 10 );  // assume 10 fields to avoid extra vector resizing
     149         [ #  # ]:          0 :         result = tokenize_line( line, format, tokens );
     150         [ #  # ]:          0 :         if( MB_SUCCESS != result ) return result;
     151                 :            : 
     152                 :            :         // Process the tokens of the line. The first token describes the entity type.
     153                 :            :         EntityType type;
     154 [ #  # ][ #  # ]:          0 :         result = determine_entity_type( tokens.front(), type );
     155         [ #  # ]:          0 :         if( MB_SUCCESS != result ) return result;
     156                 :            : 
     157                 :            :         // Create the entity.
     158         [ #  # ]:          0 :         if( MBVERTEX == type )
     159                 :            :         {
     160 [ #  # ][ #  # ]:          0 :             double* coords[3] = { coord_arrays[0] + vert_index, coord_arrays[1] + vert_index,
     161         [ #  # ]:          0 :                                   coord_arrays[2] + vert_index };
     162         [ #  # ]:          0 :             result            = read_node( tokens, debug, coords, id );
     163         [ #  # ]:          0 :             if( MB_SUCCESS != result ) return result;
     164 [ #  # ][ #  # ]:          0 :             if( !nodeIdMap.insert( id, start_vert + vert_index, 1 ).second ) return MB_FAILURE;  // Duplicate IDs!
     165                 :          0 :             ++vert_index;
     166                 :            :         }
     167                 :            :         else
     168                 :            :         {
     169         [ #  # ]:          0 :             result = read_element( tokens, materials, type, debug );
     170 [ #  # ][ #  # ]:          0 :             if( MB_SUCCESS != result ) return result;
     171                 :            :         }
     172                 :          0 :     }
     173                 :            : 
     174         [ #  # ]:          0 :     result = create_materials( materials );
     175         [ #  # ]:          0 :     if( MB_SUCCESS != result ) return result;
     176                 :            : 
     177         [ #  # ]:          0 :     result = assign_ids( file_id_tag );
     178         [ #  # ]:          0 :     if( MB_SUCCESS != result ) return result;
     179                 :            : 
     180         [ #  # ]:          0 :     file.close();
     181         [ #  # ]:          0 :     nodeIdMap.clear();
     182         [ #  # ]:          0 :     elemIdMap.clear();
     183                 :          1 :     return MB_SUCCESS;
     184                 :            : }
     185                 :            : 
     186                 :            : /* Determine the type of NASTRAN line: small field, large field, or free field.
     187                 :            :    small field: each line has 10 fields of 8 characters
     188                 :            :    large field: 1x8, 4x16, 1x8. Field 1 must have an asterisk following the character string
     189                 :            :    free field: each line entry must be separated by a comma
     190                 :            :    Implementation tries to avoid more searches than necessary. */
     191                 :          1 : ErrorCode ReadNASTRAN::determine_line_format( const std::string& line, line_format& format )
     192                 :            : {
     193                 :          1 :     std::string::size_type found_asterisk = line.find( "*" );
     194         [ -  + ]:          1 :     if( std::string::npos != found_asterisk )
     195                 :            :     {
     196                 :          0 :         format = LARGE_FIELD;
     197                 :          0 :         return MB_SUCCESS;
     198                 :            :     }
     199                 :            :     else
     200                 :            :     {
     201                 :          1 :         std::string::size_type found_comma = line.find( "," );
     202         [ -  + ]:          1 :         if( std::string::npos != found_comma )
     203                 :            :         {
     204                 :          0 :             format = FREE_FIELD;
     205                 :          0 :             return MB_SUCCESS;
     206                 :            :         }
     207                 :            :         else
     208                 :            :         {
     209                 :          1 :             format = SMALL_FIELD;
     210                 :          1 :             return MB_SUCCESS;
     211                 :            :         }
     212                 :            :     }
     213                 :            : }
     214                 :            : 
     215                 :            : /* Tokenize the line. Continue-lines have not been implemented. */
     216                 :          1 : ErrorCode ReadNASTRAN::tokenize_line( const std::string& line, const line_format format,
     217                 :            :                                       std::vector< std::string >& tokens )
     218                 :            : {
     219                 :          1 :     size_t line_size = line.size();
     220   [ +  -  -  - ]:          1 :     switch( format )
     221                 :            :     {
     222                 :            :         case SMALL_FIELD: {
     223                 :            :             // Expect 10 fields of 8 characters.
     224                 :            :             // The sample file does not have all 10 fields in each line
     225                 :          1 :             const int field_length = 8;
     226                 :          1 :             unsigned int n_tokens  = line_size / field_length;
     227         [ +  + ]:         83 :             for( unsigned int i = 0; i < n_tokens; i++ )
     228                 :            :             {
     229         [ +  - ]:         82 :                 tokens.push_back( line.substr( i * field_length, field_length ) );
     230                 :            :             }
     231                 :          1 :             break;
     232                 :            :         }
     233                 :            :         case LARGE_FIELD:
     234                 :          0 :             return MB_NOT_IMPLEMENTED;
     235                 :            :         case FREE_FIELD:
     236                 :          0 :             return MB_NOT_IMPLEMENTED;
     237                 :            :         default:
     238                 :          0 :             return MB_FAILURE;
     239                 :            :     }
     240                 :            : 
     241                 :          1 :     return MB_SUCCESS;
     242                 :            : }
     243                 :            : 
     244                 :          1 : ErrorCode ReadNASTRAN::determine_entity_type( const std::string& first_token, EntityType& type )
     245                 :            : {
     246         [ -  + ]:          1 :     if( 0 == first_token.compare( "GRID    " ) )
     247                 :          0 :         type = MBVERTEX;
     248         [ -  + ]:          1 :     else if( 0 == first_token.compare( "CTETRA  " ) )
     249                 :          0 :         type = MBTET;
     250         [ -  + ]:          1 :     else if( 0 == first_token.compare( "CPENTA  " ) )
     251                 :          0 :         type = MBPRISM;
     252         [ -  + ]:          1 :     else if( 0 == first_token.compare( "CHEXA   " ) )
     253                 :          0 :         type = MBHEX;
     254                 :            :     else
     255                 :          1 :         return MB_NOT_IMPLEMENTED;
     256                 :            : 
     257                 :          0 :     return MB_SUCCESS;
     258                 :            : }
     259                 :            : 
     260                 :            : /* Some help from Jason:
     261                 :            :    Nastran floats must contain a decimal point, may contain
     262                 :            :    a leading '-' and may contain an exponent. The 'E' is optional
     263                 :            :    when specifying an exponent.  A '-' or '+' at any location other
     264                 :            :    than the first position indicates an exponent.  For a positive
     265                 :            :    exponent, either a '+' or an 'E' must be specified.  For a
     266                 :            :    negative exponent, the 'E' is option and the '-' is always specified.
     267                 :            :    Examples for the real value 7.0 from mcs2006 quick reference guide:
     268                 :            :    7.0  .7E1  0.7+1  .70+1  7.E+0  70.-1
     269                 :            : 
     270                 :            :    From the test file created in SC/Tetra:
     271                 :            :    GRID           1       03.9804546.9052-15.6008-1
     272                 :            :    has the coordinates: ( 3.980454, 6.9052e-1, 5.6008e-1 )
     273                 :            :    GRID      200005       04.004752-3.985-15.4955-1
     274                 :            :    has the coordinates: ( 4.004752, -3.985e-1, 5.4955e-1 ) */
     275                 :          0 : ErrorCode ReadNASTRAN::get_real( const std::string& token, double& real )
     276                 :            : {
     277         [ #  # ]:          0 :     std::string significand = token;
     278         [ #  # ]:          0 :     std::string exponent    = "0";
     279                 :            : 
     280                 :            :     // Cut off the first digit because a "-" could be here indicating a negative
     281                 :            :     // number. Instead we are looking for a negative exponent.
     282         [ #  # ]:          0 :     std::string back_token = token.substr( 1 );
     283                 :            : 
     284                 :            :     // A minus that is not the first digit is always a negative exponent
     285         [ #  # ]:          0 :     std::string::size_type found_minus = back_token.find( "-" );
     286         [ #  # ]:          0 :     if( std::string::npos != found_minus )
     287                 :            :     {
     288                 :            :         // separate the significand from the exponent at the "-"
     289 [ #  # ][ #  # ]:          0 :         exponent    = token.substr( found_minus + 1 );
     290 [ #  # ][ #  # ]:          0 :         significand = token.substr( 0, found_minus + 1 );
     291                 :            : 
     292                 :            :         // If the significand has an "E", remove it
     293 [ #  # ][ #  # ]:          0 :         if( std::string::npos != significand.find( "E" ) )
     294                 :            :             // Assume the "E" is at the end of the significand.
     295 [ #  # ][ #  # ]:          0 :             significand = significand.substr( 1, significand.size() - 2 );
     296                 :            : 
     297                 :            :         // If a minus does not exist past the 1st digit, but an "E" or "+" does, then
     298                 :            :         // it is a positive exponent. First look for an "E",
     299                 :            :     }
     300                 :            :     else
     301                 :            :     {
     302         [ #  # ]:          0 :         std::string::size_type found_E = token.find( "E" );
     303         [ #  # ]:          0 :         if( std::string::npos != found_E )
     304                 :            :         {
     305 [ #  # ][ #  # ]:          0 :             significand = token.substr( 0, found_E - 1 );
     306 [ #  # ][ #  # ]:          0 :             exponent    = token.substr( found_E + 1 );
     307                 :            :             // If there is a "+" on the exponent, cut it off
     308         [ #  # ]:          0 :             std::size_t found_plus = exponent.find( "+" );
     309 [ #  # ][ #  # ]:          0 :             if( std::string::npos != found_plus ) { exponent = exponent.substr( found_plus + 1 ); }
                 [ #  # ]
     310                 :            :         }
     311                 :            :         else
     312                 :            :         {
     313                 :            :             // If there is a "+" on the exponent, cut it off
     314         [ #  # ]:          0 :             std::size_t found_plus = token.find( "+" );
     315         [ #  # ]:          0 :             if( std::string::npos != found_plus )
     316                 :            :             {
     317 [ #  # ][ #  # ]:          0 :                 significand = token.substr( 0, found_plus - 1 );
     318 [ #  # ][ #  # ]:          0 :                 exponent    = token.substr( found_plus + 1 );
     319                 :            :             }
     320                 :            :         }
     321                 :            :     }
     322                 :            : 
     323                 :            :     // Now assemble the real number
     324                 :          0 :     double signi = atof( significand.c_str() );
     325                 :          0 :     double expon = atof( exponent.c_str() );
     326                 :            : 
     327 [ #  # ][ #  # ]:          0 :     if( HUGE_VAL == signi || HUGE_VAL == expon ) return MB_FAILURE;
     328                 :            : 
     329                 :          0 :     real = signi * pow( 10, expon );
     330                 :            : 
     331                 :          0 :     return MB_SUCCESS;
     332                 :            : }
     333                 :            : 
     334                 :            : /* It has been determined that this line is a vertex. Read the rest of
     335                 :            :    the line and create the vertex. */
     336                 :          0 : ErrorCode ReadNASTRAN::read_node( const std::vector< std::string >& tokens, const bool debug, double* coords[3],
     337                 :            :                                   int& id )
     338                 :            : {
     339                 :            :     // Read the node's id (unique)
     340                 :            :     ErrorCode result;
     341                 :          0 :     id = atoi( tokens[1].c_str() );
     342                 :            : 
     343                 :            :     // Read the node's coordinate system number
     344                 :            :     // "0" or blank refers to the basic coordinate system.
     345                 :          0 :     int coord_system = atoi( tokens[2].c_str() );
     346         [ #  # ]:          0 :     if( 0 != coord_system )
     347                 :            :     {
     348                 :          0 :         std::cerr << "ReadNASTRAN: alternative coordinate systems not implemented" << std::endl;
     349                 :          0 :         return MB_NOT_IMPLEMENTED;
     350                 :            :     }
     351                 :            : 
     352                 :            :     // Read the coordinates
     353         [ #  # ]:          0 :     for( unsigned int i = 0; i < 3; i++ )
     354                 :            :     {
     355                 :          0 :         result = get_real( tokens[i + 3], *coords[i] );
     356         [ #  # ]:          0 :         if( MB_SUCCESS != result ) return result;
     357         [ #  # ]:          0 :         if( debug ) std::cout << "read_node: coords[" << i << "]=" << coords[i] << std::endl;
     358                 :            :     }
     359                 :            : 
     360                 :          0 :     return MB_SUCCESS;
     361                 :            : }
     362                 :            : 
     363                 :            : /* The type of element has already been identified. Read the rest of the
     364                 :            :    line and create the element. Assume that all of the nodes have already
     365                 :            :    been created. */
     366                 :          0 : ErrorCode ReadNASTRAN::read_element( const std::vector< std::string >& tokens, std::vector< Range >& materials,
     367                 :            :                                      const EntityType element_type, const bool /*debug*/ )
     368                 :            : {
     369                 :            :     // Read the element's id (unique) and material set
     370                 :            :     ErrorCode result;
     371         [ #  # ]:          0 :     int id       = atoi( tokens[1].c_str() );
     372         [ #  # ]:          0 :     int material = atoi( tokens[2].c_str() );
     373                 :            : 
     374                 :            :     // Resize materials list if necessary. This code is somewhat complicated
     375                 :            :     // so as to avoid copying of Ranges
     376         [ #  # ]:          0 :     if( material >= (int)materials.size() )
     377                 :            :     {
     378         [ #  # ]:          0 :         if( (int)materials.capacity() < material )
     379         [ #  # ]:          0 :             materials.resize( material + 1 );
     380                 :            :         else
     381                 :            :         {
     382         [ #  # ]:          0 :             std::vector< Range > new_mat( material + 1 );
     383         [ #  # ]:          0 :             for( size_t i = 0; i < materials.size(); ++i )
     384 [ #  # ][ #  # ]:          0 :                 new_mat[i].swap( materials[i] );
                 [ #  # ]
     385                 :          0 :             materials.swap( new_mat );
     386                 :            :         }
     387                 :            :     }
     388                 :            : 
     389                 :            :     // The size of the connectivity array depends on the element type
     390         [ #  # ]:          0 :     int n_conn = CN::VerticesPerEntity( element_type );
     391                 :            :     EntityHandle conn_verts[27];
     392         [ #  # ]:          0 :     assert( n_conn <= (int)( sizeof( conn_verts ) / sizeof( EntityHandle ) ) );
     393                 :            : 
     394                 :            :     // Read the connected node ids from the file
     395         [ #  # ]:          0 :     for( int i = 0; i < n_conn; i++ )
     396                 :            :     {
     397         [ #  # ]:          0 :         int n         = atoi( tokens[3 + i].c_str() );
     398         [ #  # ]:          0 :         conn_verts[i] = nodeIdMap.find( n );
     399         [ #  # ]:          0 :         if( !conn_verts[i] )  // invalid vertex id
     400                 :          0 :             return MB_FAILURE;
     401                 :            :     }
     402                 :            : 
     403                 :            :     // Create the element and set the global id from the NASTRAN file
     404                 :            :     EntityHandle element;
     405         [ #  # ]:          0 :     result = MBI->create_element( element_type, conn_verts, n_conn, element );
     406         [ #  # ]:          0 :     if( MB_SUCCESS != result ) return result;
     407         [ #  # ]:          0 :     elemIdMap.insert( id, element, 1 );
     408                 :            : 
     409 [ #  # ][ #  # ]:          0 :     materials[material].insert( element );
     410                 :          0 :     return MB_SUCCESS;
     411                 :            : }
     412                 :            : 
     413                 :          0 : ErrorCode ReadNASTRAN::create_materials( const std::vector< Range >& materials )
     414                 :            : {
     415                 :            :     ErrorCode result;
     416                 :            :     Tag material_tag;
     417                 :          0 :     int negone = -1;
     418                 :            :     result = MBI->tag_get_handle( MATERIAL_SET_TAG_NAME, 1, MB_TYPE_INTEGER, material_tag, MB_TAG_SPARSE | MB_TAG_CREAT,
     419         [ #  # ]:          0 :                                   &negone );
     420         [ #  # ]:          0 :     if( MB_SUCCESS != result ) return result;
     421                 :            : 
     422         [ #  # ]:          0 :     for( size_t i = 0; i < materials.size(); ++i )
     423                 :            :     {
     424 [ #  # ][ #  # ]:          0 :         if( materials[i].empty() ) continue;
                 [ #  # ]
     425                 :            : 
     426                 :            :         // Merge with existing or create new?  Original code effectively
     427                 :            :         // created new by only merging with existing in current file set,
     428                 :            :         // so do the same here. - j.kraftcheck
     429                 :            : 
     430                 :            :         EntityHandle handle;
     431         [ #  # ]:          0 :         result = MBI->create_meshset( MESHSET_SET, handle );
     432         [ #  # ]:          0 :         if( MB_SUCCESS != result ) return result;
     433                 :            : 
     434 [ #  # ][ #  # ]:          0 :         result = MBI->add_entities( handle, materials[i] );
     435         [ #  # ]:          0 :         if( MB_SUCCESS != result ) return result;
     436                 :            : 
     437                 :          0 :         int id = i;
     438         [ #  # ]:          0 :         result = MBI->tag_set_data( material_tag, &handle, 1, &id );
     439         [ #  # ]:          0 :         if( MB_SUCCESS != result ) return result;
     440                 :            :     }
     441                 :            : 
     442                 :          0 :     return MB_SUCCESS;
     443                 :            : }
     444                 :            : 
     445                 :          0 : ErrorCode ReadNASTRAN::assign_ids( const Tag* file_id_tag )
     446                 :            : {
     447                 :            :     // Create tag
     448                 :            :     ErrorCode result;
     449         [ #  # ]:          0 :     Tag id_tag = MBI->globalId_tag();
     450                 :            : 
     451                 :          0 :     RangeMap< int, EntityHandle >::iterator i;
     452         [ #  # ]:          0 :     for( int t = 0; t < 2; ++t )
     453                 :            :     {
     454         [ #  # ]:          0 :         RangeMap< int, EntityHandle >& fileIdMap = t ? elemIdMap : nodeIdMap;
     455 [ #  # ][ #  # ]:          0 :         for( i = fileIdMap.begin(); i != fileIdMap.end(); ++i )
         [ #  # ][ #  # ]
                 [ #  # ]
     456                 :            :         {
     457 [ #  # ][ #  # ]:          0 :             Range range( i->value, i->value + i->count - 1 );
         [ #  # ][ #  # ]
     458                 :            : 
     459 [ #  # ][ #  # ]:          0 :             result = readMeshIface->assign_ids( id_tag, range, i->begin );
     460         [ #  # ]:          0 :             if( MB_SUCCESS != result ) return result;
     461                 :            : 
     462 [ #  # ][ #  # ]:          0 :             if( file_id_tag && *file_id_tag != id_tag )
     463                 :            :             {
     464 [ #  # ][ #  # ]:          0 :                 result = readMeshIface->assign_ids( *file_id_tag, range, i->begin );
     465 [ #  # ][ #  # ]:          0 :                 if( MB_SUCCESS != result ) return result;
     466                 :            :             }
     467                 :          0 :         }
     468                 :            :     }
     469                 :            : 
     470                 :          0 :     return MB_SUCCESS;
     471                 :            : }
     472                 :            : 
     473 [ +  - ][ +  - ]:        228 : }  // namespace moab

Generated by: LCOV version 1.11