LCOV - code coverage report
Current view: top level - src/io - ReadOBJ.cpp (source / functions) Hit Total Coverage
Test: coverage_sk.info Lines: 96 193 49.7 %
Date: 2020-12-16 07:07:30 Functions: 9 16 56.2 %
Branches: 139 777 17.9 %

           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 "ReadOBJ.hpp"
      17                 :            : #include <iostream>
      18                 :            : #include <sstream>
      19                 :            : #include <fstream>
      20                 :            : #include <vector>
      21                 :            : #include <cstdlib>
      22                 :            : #include <map>
      23                 :            : #include <assert.h>
      24                 :            : #include <cmath>
      25                 :            : 
      26                 :            : #include "moab/Core.hpp"
      27                 :            : #include "moab/Interface.hpp"
      28                 :            : #include "moab/ReadUtilIface.hpp"
      29                 :            : #include "Internals.hpp"
      30                 :            : #include "moab/Range.hpp"
      31                 :            : #include "moab/CartVect.hpp"
      32                 :            : #include "moab/FileOptions.hpp"
      33                 :            : #include "FileTokenizer.hpp"
      34                 :            : #include "MBTagConventions.hpp"
      35                 :            : #include "moab/CN.hpp"
      36                 :            : #include "moab/GeomTopoTool.hpp"
      37                 :            : 
      38                 :            : namespace moab
      39                 :            : {
      40                 :            : 
      41                 :          1 : ReaderIface* ReadOBJ::factory( Interface* iface )
      42                 :            : {
      43         [ +  - ]:          1 :     return new ReadOBJ( iface );
      44                 :            : }
      45                 :            : 
      46                 :            : // Subset of starting tokens currently supported
      47                 :            : const char* ReadOBJ::delimiters = " ";
      48                 :            : const char* object_start_token  = "o";
      49                 :            : const char* group_start_token   = "g";
      50                 :            : const char* vertex_start_token  = "v";
      51                 :            : const char* face_start_token    = "f";
      52                 :            : 
      53                 :            : #define OBJ_AMBIGUOUS "AMBIGUOUS"
      54                 :            : #define OBJ_UNDEFINED "UNDEFINED"
      55                 :            : 
      56                 :            : // Name of geometric entities
      57                 :            : const char* const geom_name[] = { "Vertex\0", "Curve\0", "Surface\0", "Volume\0" };
      58                 :            : 
      59                 :            : // Geometric Categories
      60                 :            : const char geom_category[][CATEGORY_TAG_SIZE] = { "Vertex\0", "Curve\0", "Surface\0", "Volume\0", "Group\0" };
      61                 :            : 
      62                 :            : // Constructor
      63                 :          1 : ReadOBJ::ReadOBJ( Interface* impl )
      64                 :            :     : MBI( impl ), geom_tag( 0 ), id_tag( 0 ), name_tag( 0 ), category_tag( 0 ), faceting_tol_tag( 0 ),
      65                 :          1 :       geometry_resabs_tag( 0 ), obj_name_tag( 0 )
      66                 :            : {
      67         [ -  + ]:          1 :     assert( NULL != impl );
      68         [ +  - ]:          1 :     MBI->query_interface( readMeshIface );
      69 [ +  - ][ +  - ]:          1 :     myGeomTool = new GeomTopoTool( impl );
      70         [ -  + ]:          1 :     assert( NULL != readMeshIface );
      71                 :            : 
      72                 :            :     // Get all handles
      73                 :          1 :     int negone = -1;
      74                 :            :     ErrorCode rval;
      75                 :            :     rval = MBI->tag_get_handle( GEOM_DIMENSION_TAG_NAME, 1, MB_TYPE_INTEGER, geom_tag, MB_TAG_SPARSE | MB_TAG_CREAT,
      76 [ +  - ][ -  + ]:          2 :                                 &negone );MB_CHK_ERR_RET( rval );
         [ #  # ][ #  # ]
      77                 :            : 
      78         [ +  - ]:          1 :     id_tag = MBI->globalId_tag();
      79                 :            : 
      80 [ +  - ][ -  + ]:          1 :     rval = MBI->tag_get_handle( NAME_TAG_NAME, NAME_TAG_SIZE, MB_TYPE_OPAQUE, name_tag, MB_TAG_SPARSE | MB_TAG_CREAT );MB_CHK_ERR_RET( rval );
         [ #  # ][ #  # ]
      81                 :            : 
      82                 :            :     rval = MBI->tag_get_handle( CATEGORY_TAG_NAME, CATEGORY_TAG_SIZE, MB_TYPE_OPAQUE, category_tag,
      83 [ +  - ][ -  + ]:          1 :                                 MB_TAG_SPARSE | MB_TAG_CREAT );MB_CHK_ERR_RET( rval );
         [ #  # ][ #  # ]
      84                 :            : 
      85 [ +  - ][ -  + ]:          1 :     rval = MBI->tag_get_handle( "OBJECT_NAME", 32, MB_TYPE_OPAQUE, obj_name_tag, MB_TAG_SPARSE | MB_TAG_CREAT );MB_CHK_ERR_RET( rval );
         [ #  # ][ #  # ]
      86                 :            : 
      87 [ +  - ][ -  + ]:          1 :     rval = MBI->tag_get_handle( "FACETING_TOL", 1, MB_TYPE_DOUBLE, faceting_tol_tag, MB_TAG_SPARSE | MB_TAG_CREAT );MB_CHK_ERR_RET( rval );
         [ #  # ][ #  # ]
      88                 :            : 
      89                 :            :     rval =
      90 [ +  - ][ -  + ]:          1 :         MBI->tag_get_handle( "GEOMETRY_RESABS", 1, MB_TYPE_DOUBLE, geometry_resabs_tag, MB_TAG_SPARSE | MB_TAG_CREAT );MB_CHK_ERR_RET( rval );
         [ #  # ][ #  # ]
      91                 :            : }
      92                 :            : 
      93                 :            : // Destructor
      94                 :          3 : ReadOBJ::~ReadOBJ()
      95                 :            : {
      96         [ +  - ]:          1 :     if( readMeshIface )
      97                 :            :     {
      98                 :          1 :         MBI->release_interface( readMeshIface );
      99                 :          1 :         readMeshIface = 0;
     100                 :            :     }
     101                 :            : 
     102         [ +  - ]:          1 :     delete myGeomTool;
     103         [ -  + ]:          2 : }
     104                 :            : 
     105                 :          0 : ErrorCode ReadOBJ::read_tag_values( const char* /*file_name*/, const char* /*tag_name*/, const FileOptions& /*opts*/,
     106                 :            :                                     std::vector< int >& /*tag_values_out*/, const SubsetList* /*subset_list*/ )
     107                 :            : {
     108                 :          0 :     return MB_NOT_IMPLEMENTED;
     109                 :            : }
     110                 :            : 
     111                 :            : // Load the file as called by the Interface function
     112                 :          1 : ErrorCode ReadOBJ::load_file( const char* filename, const EntityHandle*, const FileOptions&,
     113                 :            :                               const ReaderIface::SubsetList* subset_list, const Tag* /*file_id_tag*/ )
     114                 :            : {
     115                 :            :     ErrorCode rval;
     116                 :          1 :     int ignored = 0;   // Number of lines not beginning with o, v, or f
     117         [ +  - ]:          1 :     std::string line;  // The current line being read
     118                 :            :     EntityHandle vert_meshset;
     119                 :            :     EntityHandle curr_meshset;  // Current object meshset
     120         [ +  - ]:          2 :     std::string object_name;
     121         [ +  - ]:          2 :     std::vector< EntityHandle > vertex_list;
     122                 :          1 :     int object_id = 0, group_id = 0;  // ID number for each volume/surface
     123                 :            :     int num_groups;
     124                 :            : 
     125                 :            :     // At this time, there is no support for reading a subset of the file
     126 [ -  + ][ #  # ]:          1 :     if( subset_list ) { MB_SET_ERR( MB_UNSUPPORTED_OPERATION, "Reading subset of files not supported for OBJ." ); }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     127                 :            : 
     128         [ +  - ]:          2 :     std::ifstream input_file( filename );  // Filestream for OBJ file
     129                 :            : 
     130                 :            :     // Check that the file can be read
     131 [ +  - ][ -  + ]:          1 :     if( !input_file.good() )
     132                 :            :     {
     133 [ #  # ][ #  # ]:          0 :         std::cout << "Problems reading file = " << filename << std::endl;
                 [ #  # ]
     134                 :          0 :         return MB_FILE_DOES_NOT_EXIST;
     135                 :            :     }
     136                 :            : 
     137                 :            :     // If the file can be read
     138 [ +  - ][ +  - ]:          1 :     if( input_file.is_open() )
     139                 :            :     {
     140                 :            : 
     141                 :            :         // create meshset for global vertices
     142 [ +  - ][ -  + ]:          1 :         rval = MBI->create_meshset( MESHSET_SET, vert_meshset );MB_CHK_SET_ERR( rval, "Failed to create global vert meshset." );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     143                 :            : 
     144 [ +  - ][ +  - ]:          1 :         while( std::getline( input_file, line ) )
                 [ +  - ]
     145                 :            :         {
     146                 :            :             // Skip blank lines in file
     147         [ -  + ]:          2 :             if( line.length() == 0 ) continue;
     148                 :            : 
     149                 :            :             // Tokenize the line
     150         [ +  - ]:          1 :             std::vector< std::string > tokens;
     151         [ +  - ]:          1 :             tokenize( line, tokens, delimiters );
     152                 :            : 
     153                 :            :             // Each group and object line must have a name, token size is at least 2
     154                 :            :             // Each vertex and face line should have token size of at least 4
     155         [ -  + ]:          1 :             if( tokens.size() < 2 ) continue;
     156                 :            : 
     157 [ +  - ][ +  - ]:          1 :             switch( get_keyword( tokens ) )
           [ -  -  -  -  
                   -  + ]
     158                 :            :             {
     159                 :            :                 // Object line
     160                 :            :                 case object_start: {
     161                 :          0 :                     object_id++;
     162 [ #  # ][ #  # ]:          0 :                     object_name = tokens[1];  // Get name of object
     163                 :            : 
     164                 :            :                     // Create new meshset for object
     165 [ #  # ][ #  # ]:          0 :                     rval = create_new_object( object_name, object_id, curr_meshset );MB_CHK_ERR( rval );
         [ #  # ][ #  # ]
                 [ #  # ]
     166                 :          0 :                     break;
     167                 :            :                 }
     168                 :            : 
     169                 :            :                 // Group line
     170                 :            :                 case group_start: {
     171                 :          0 :                     group_id++;
     172                 :          0 :                     num_groups             = tokens.size() - 1;
     173         [ #  # ]:          0 :                     std::string group_name = "Group";
     174         [ #  # ]:          0 :                     for( int i = 0; i < num_groups; i++ )
     175                 :            :                     {
     176 [ #  # ][ #  # ]:          0 :                         group_name = group_name + '_' + tokens[i + 1];
         [ #  # ][ #  # ]
     177                 :            :                     }
     178                 :            : 
     179                 :            :                     // Create new meshset for group
     180 [ #  # ][ #  # ]:          0 :                     rval = create_new_group( group_name, group_id, curr_meshset );MB_CHK_ERR( rval );
         [ #  # ][ #  # ]
                 [ #  # ]
     181         [ #  # ]:          0 :                     break;
     182                 :            :                 }
     183                 :            : 
     184                 :            :                 // Vertex line
     185                 :            :                 case vertex_start: {
     186                 :            :                     // Read vertex and return EH
     187                 :            :                     EntityHandle new_vertex_eh;
     188 [ #  # ][ #  # ]:          0 :                     rval = create_new_vertex( tokens, new_vertex_eh );MB_CHK_ERR( rval );
         [ #  # ][ #  # ]
                 [ #  # ]
     189                 :            : 
     190                 :            :                     // Add new vertex EH to list
     191         [ #  # ]:          0 :                     vertex_list.push_back( new_vertex_eh );
     192                 :            : 
     193                 :            :                     // Add new vertex EH to the meshset
     194 [ #  # ][ #  # ]:          0 :                     MBI->add_entities( vert_meshset, &new_vertex_eh, 1 );MB_CHK_SET_ERR( rval, "Failed to add vertex to global meshset." );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     195                 :          0 :                     break;
     196                 :            :                 }
     197                 :            : 
     198                 :            :                 // Face line
     199                 :            :                 case face_start: {
     200                 :            :                     // Faces in .obj file can have 2, 3, or 4 vertices. If the face has
     201                 :            :                     // 3 vertices, the EH will be immediately added to the meshset.
     202                 :            :                     // If 4, face is split into triangles.  Anything else is ignored.
     203                 :            :                     EntityHandle new_face_eh;
     204                 :            : 
     205         [ #  # ]:          0 :                     if( tokens.size() == 4 )
     206                 :            :                     {
     207 [ #  # ][ #  # ]:          0 :                         rval = create_new_face( tokens, vertex_list, new_face_eh );MB_CHK_ERR( rval );
         [ #  # ][ #  # ]
                 [ #  # ]
     208                 :            : 
     209         [ #  # ]:          0 :                         if( rval == MB_SUCCESS )
     210                 :            :                         {
     211                 :            :                             // Add new face EH to the meshset
     212         [ #  # ]:          0 :                             MBI->add_entities( curr_meshset, &new_face_eh, 1 );
     213                 :            :                         }
     214                 :            :                     }
     215                 :            : 
     216         [ #  # ]:          0 :                     else if( tokens.size() == 5 )
     217                 :            :                     {
     218                 :            :                         // Split_quad fxn will create 2 new triangles from 1 quad
     219         [ #  # ]:          0 :                         Range new_faces_eh;
     220 [ #  # ][ #  # ]:          0 :                         rval = split_quad( tokens, vertex_list, new_faces_eh );MB_CHK_ERR( rval );
         [ #  # ][ #  # ]
                 [ #  # ]
     221                 :            : 
     222                 :            :                         // Add new faces created by split quad to meshset
     223 [ #  # ][ #  # ]:          0 :                         if( rval == MB_SUCCESS ) { MBI->add_entities( curr_meshset, new_faces_eh ); }
                 [ #  # ]
     224                 :            :                     }
     225                 :            : 
     226                 :            :                     else
     227                 :            :                     {
     228 [ #  # ][ #  # ]:          0 :                         std::cout << "Neither tri nor a quad: " << line << std::endl;
                 [ #  # ]
     229                 :            :                     }
     230                 :            : 
     231                 :          0 :                     break;
     232                 :            :                 }
     233                 :            : 
     234                 :            :                 case valid_unsupported: {
     235                 :            :                     // First token is not recognized as a supported character
     236                 :          0 :                     ++ignored;
     237                 :          0 :                     break;
     238                 :            :                 }
     239                 :            : 
     240                 :            :                 default: {
     241 [ +  - ][ +  - ]:          1 :                     MB_SET_ERR( MB_FAILURE, "Invalid/unrecognized line" );
         [ +  - ][ -  + ]
                 [ +  - ]
              [ -  -  + ]
     242                 :            :                 }
     243                 :            :             }
     244                 :          0 :         }
     245                 :            :     }
     246                 :            : 
     247                 :            :     // If no object lines are read (those beginning w/ 'o'), file is not obj type
     248 [ #  # ][ #  # ]:          0 :     if( object_id == 0 && group_id == 0 ) { MB_SET_ERR( MB_FAILURE, "This is not an obj file. " ); }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     249                 :            : 
     250 [ #  # ][ #  # ]:          0 :     std::cout << "There were " << ignored << " ignored lines in this file." << std::endl;
         [ #  # ][ #  # ]
     251                 :            : 
     252         [ #  # ]:          0 :     input_file.close();
     253                 :            : 
     254                 :          1 :     return MB_SUCCESS;
     255                 :            : }
     256                 :            : 
     257                 :            : /* The tokenize function will split an input line
     258                 :            :  * into a vector of strings based upon the delimiter
     259                 :            :  */
     260                 :          1 : void ReadOBJ::tokenize( const std::string& str, std::vector< std::string >& tokens, const char* delimiters2 )
     261                 :            : {
     262                 :          1 :     tokens.clear();
     263                 :            : 
     264                 :          1 :     std::string::size_type next_token_end, next_token_start = str.find_first_not_of( delimiters2, 0 );
     265                 :            : 
     266         [ +  + ]:          4 :     while( std::string::npos != next_token_start )
     267                 :            :     {
     268                 :          3 :         next_token_end = str.find_first_of( delimiters2, next_token_start );
     269         [ +  + ]:          3 :         if( std::string::npos == next_token_end )
     270                 :            :         {
     271         [ +  - ]:          1 :             tokens.push_back( str.substr( next_token_start ) );
     272                 :          1 :             next_token_start = std::string::npos;
     273                 :            :         }
     274                 :            :         else
     275                 :            :         {
     276         [ +  - ]:          2 :             tokens.push_back( str.substr( next_token_start, next_token_end - next_token_start ) );
     277                 :          2 :             next_token_start = str.find_first_not_of( delimiters2, next_token_end );
     278                 :            :         }
     279                 :            :     }
     280                 :          1 : }
     281                 :            : 
     282                 :          1 : keyword_type ReadOBJ::get_keyword( std::vector< std::string > tokens )
     283                 :            : {
     284         [ +  - ]:          1 :     std::map< std::string, keyword_type > keywords;
     285                 :            : 
     286                 :            :     // currently supported
     287 [ +  - ][ +  - ]:          1 :     keywords["o"] = object_start;
     288 [ +  - ][ +  - ]:          1 :     keywords["g"] = group_start;
     289 [ +  - ][ +  - ]:          1 :     keywords["f"] = face_start;
     290 [ +  - ][ +  - ]:          1 :     keywords["v"] = vertex_start;
     291                 :            : 
     292                 :            :     // not currently supported, will be ignored
     293 [ +  - ][ +  - ]:          1 :     keywords["vn"]         = valid_unsupported;
     294 [ +  - ][ +  - ]:          1 :     keywords["vt"]         = valid_unsupported;
     295 [ +  - ][ +  - ]:          1 :     keywords["vp"]         = valid_unsupported;
     296 [ +  - ][ +  - ]:          1 :     keywords["s"]          = valid_unsupported;
     297 [ +  - ][ +  - ]:          1 :     keywords["mtllib"]     = valid_unsupported;
     298 [ +  - ][ +  - ]:          1 :     keywords["usemtl"]     = valid_unsupported;
     299 [ +  - ][ +  - ]:          1 :     keywords["#"]          = valid_unsupported;
     300 [ +  - ][ +  - ]:          1 :     keywords["cstype"]     = valid_unsupported;
     301 [ +  - ][ +  - ]:          1 :     keywords["deg"]        = valid_unsupported;
     302 [ +  - ][ +  - ]:          1 :     keywords["bmat"]       = valid_unsupported;
     303 [ +  - ][ +  - ]:          1 :     keywords["step"]       = valid_unsupported;
     304 [ +  - ][ +  - ]:          1 :     keywords["p"]          = valid_unsupported;
     305 [ +  - ][ +  - ]:          1 :     keywords["l"]          = valid_unsupported;
     306 [ +  - ][ +  - ]:          1 :     keywords["curv"]       = valid_unsupported;
     307 [ +  - ][ +  - ]:          1 :     keywords["curv2"]      = valid_unsupported;
     308 [ +  - ][ +  - ]:          1 :     keywords["surf"]       = valid_unsupported;
     309 [ +  - ][ +  - ]:          1 :     keywords["parm"]       = valid_unsupported;
     310 [ +  - ][ +  - ]:          1 :     keywords["trim"]       = valid_unsupported;
     311 [ +  - ][ +  - ]:          1 :     keywords["hole"]       = valid_unsupported;
     312 [ +  - ][ +  - ]:          1 :     keywords["scrv"]       = valid_unsupported;
     313 [ +  - ][ +  - ]:          1 :     keywords["sp"]         = valid_unsupported;
     314 [ +  - ][ +  - ]:          1 :     keywords["end"]        = valid_unsupported;
     315 [ +  - ][ +  - ]:          1 :     keywords["mg"]         = valid_unsupported;
     316 [ +  - ][ +  - ]:          1 :     keywords["bevel"]      = valid_unsupported;
     317 [ +  - ][ +  - ]:          1 :     keywords["c_interp"]   = valid_unsupported;
     318 [ +  - ][ +  - ]:          1 :     keywords["d_interp"]   = valid_unsupported;
     319 [ +  - ][ +  - ]:          1 :     keywords["lod"]        = valid_unsupported;
     320 [ +  - ][ +  - ]:          1 :     keywords["shadow_obj"] = valid_unsupported;
     321 [ +  - ][ +  - ]:          1 :     keywords["trace_obj"]  = valid_unsupported;
     322 [ +  - ][ +  - ]:          1 :     keywords["ctech"]      = valid_unsupported;
     323 [ +  - ][ +  - ]:          1 :     keywords["stech"]      = valid_unsupported;
     324                 :            : 
     325 [ +  - ][ +  - ]:          1 :     return keywords[match( tokens[0], keywords )];
                 [ +  - ]
     326                 :            : }
     327                 :            : 
     328                 :            : template < typename T >
     329                 :          1 : std::string ReadOBJ::match( const std::string& token, std::map< std::string, T >& tokenList )
     330                 :            : {
     331                 :            :     // Initialize with no match and obj_undefined as return string
     332         [ +  - ]:          1 :     std::string best_match = OBJ_UNDEFINED;
     333                 :            : 
     334                 :            :     // Search the map
     335 [ +  - ][ +  - ]:         36 :     for( typename std::map< std::string, T >::iterator thisToken = tokenList.begin(); thisToken != tokenList.end();
                 [ +  + ]
     336                 :            :          ++thisToken )
     337                 :            :     {
     338                 :            :         // If a perfect match break the loop (assume keyword list is unambiguous)
     339 [ +  - ][ +  - ]:         35 :         if( token == ( *thisToken ).first )
                 [ -  + ]
     340                 :            :         {
     341         [ #  # ]:          0 :             best_match = token;
     342                 :          0 :             break;
     343                 :            :         }
     344                 :            :     }
     345                 :            : 
     346                 :            :     // Possible return values: OBJ_UNDEFINED, keyword from list
     347                 :          1 :     return best_match;
     348                 :            : }
     349                 :            : 
     350                 :            : /*
     351                 :            :  * The create_new_object function starts a new meshset for each object
     352                 :            :  * that will contain all faces that make up the object.
     353                 :            :  */
     354                 :          0 : ErrorCode ReadOBJ::create_new_object( std::string object_name, int curr_object, EntityHandle& object_meshset )
     355                 :            : {
     356                 :            :     ErrorCode rval;
     357                 :            : 
     358                 :            :     // Create meshset to store object
     359                 :            :     // This is also referred to as the surface meshset
     360 [ #  # ][ #  # ]:          0 :     rval = MBI->create_meshset( MESHSET_SET, object_meshset );MB_CHK_SET_ERR( rval, "Failed to generate object mesh set." );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     361                 :            : 
     362                 :            :     // Set surface meshset tags
     363 [ #  # ][ #  # ]:          0 :     rval = MBI->tag_set_data( name_tag, &object_meshset, 1, object_name.c_str() );MB_CHK_SET_ERR( rval, "Failed to set mesh set name tag." );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     364                 :            : 
     365 [ #  # ][ #  # ]:          0 :     rval = MBI->tag_set_data( id_tag, &object_meshset, 1, &( curr_object ) );MB_CHK_SET_ERR( rval, "Failed to set mesh set ID tag." );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     366                 :            : 
     367                 :          0 :     int dim = 2;
     368 [ #  # ][ #  # ]:          0 :     rval    = MBI->tag_set_data( geom_tag, &object_meshset, 1, &( dim ) );MB_CHK_SET_ERR( rval, "Failed to set mesh set dim tag." );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     369                 :            : 
     370 [ #  # ][ #  # ]:          0 :     rval = MBI->tag_set_data( category_tag, &object_meshset, 1, geom_category[2] );MB_CHK_SET_ERR( rval, "Failed to set mesh set category tag." );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     371                 :            : 
     372                 :            :     /* Create volume entity set corresponding to surface
     373                 :            :        The volume meshset will have one child--
     374                 :            :        the meshset of the surface that bounds the object.
     375                 :            :      */
     376                 :            :     EntityHandle vol_meshset;
     377 [ #  # ][ #  # ]:          0 :     rval = MBI->create_meshset( MESHSET_SET, vol_meshset );MB_CHK_SET_ERR( rval, "Failed to create volume mesh set." );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     378                 :            : 
     379 [ #  # ][ #  # ]:          0 :     rval = MBI->add_parent_child( vol_meshset, object_meshset );MB_CHK_SET_ERR( rval, "Failed to add object mesh set as child of volume mesh set." );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     380                 :            : 
     381                 :            :     /* Set volume meshset tags
     382                 :            :        The volume meshset is tagged with the same name as the surface meshset
     383                 :            :        for each object because of the direct relation between these entities.
     384                 :            :      */
     385 [ #  # ][ #  # ]:          0 :     rval = MBI->tag_set_data( obj_name_tag, &vol_meshset, 1, object_name.c_str() );MB_CHK_SET_ERR( rval, "Failed to set mesh set name tag." );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     386                 :            : 
     387 [ #  # ][ #  # ]:          0 :     rval = MBI->tag_set_data( id_tag, &vol_meshset, 1, &( curr_object ) );MB_CHK_SET_ERR( rval, "Failed to set mesh set ID tag." );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     388                 :            : 
     389                 :          0 :     dim  = 3;
     390 [ #  # ][ #  # ]:          0 :     rval = MBI->tag_set_data( geom_tag, &vol_meshset, 1, &( dim ) );MB_CHK_SET_ERR( rval, "Failed to set mesh set dim tag." );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     391                 :            : 
     392 [ #  # ][ #  # ]:          0 :     rval = MBI->tag_set_data( name_tag, &vol_meshset, 1, geom_name[3] );MB_CHK_SET_ERR( rval, "Failed to set mesh set name tag." );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     393                 :            : 
     394 [ #  # ][ #  # ]:          0 :     rval = MBI->tag_set_data( category_tag, &vol_meshset, 1, geom_category[3] );MB_CHK_SET_ERR( rval, "Failed to set mesh set category tag." );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     395                 :            : 
     396 [ #  # ][ #  # ]:          0 :     rval = myGeomTool->set_sense( object_meshset, vol_meshset, SENSE_FORWARD );MB_CHK_SET_ERR( rval, "Failed to set surface sense." );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     397                 :            : 
     398                 :          0 :     return rval;
     399                 :            : }
     400                 :            : 
     401                 :            : /*
     402                 :            :  * The create_new_group function starts a new meshset for each group
     403                 :            :  * that will contain all faces that make up the group
     404                 :            :  */
     405                 :          0 : ErrorCode ReadOBJ::create_new_group( std::string group_name, int curr_group, EntityHandle& group_meshset )
     406                 :            : {
     407                 :            :     ErrorCode rval;
     408                 :            : 
     409                 :            :     // Create meshset to store group
     410 [ #  # ][ #  # ]:          0 :     rval = MBI->create_meshset( MESHSET_SET, group_meshset );MB_CHK_SET_ERR( rval, "Failed to generate group mesh set." );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     411                 :            : 
     412                 :            :     // Set meshset tags
     413 [ #  # ][ #  # ]:          0 :     rval = MBI->tag_set_data( name_tag, &group_meshset, 1, group_name.c_str() );MB_CHK_SET_ERR( rval, "Failed to set mesh set name tag." );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     414                 :            : 
     415 [ #  # ][ #  # ]:          0 :     rval = MBI->tag_set_data( id_tag, &group_meshset, 1, &( curr_group ) );MB_CHK_SET_ERR( rval, "Failed to set mesh set ID tag." );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     416                 :            : 
     417                 :          0 :     return rval;
     418                 :            : }
     419                 :            : 
     420                 :            : /* The create_new_vertex function converts a vector
     421                 :            :    of tokens (v x y z) to
     422                 :            :    the vertex format; a structure that has the three
     423                 :            :    coordinates as members.
     424                 :            :  */
     425                 :          0 : ErrorCode ReadOBJ::create_new_vertex( std::vector< std::string > v_tokens, EntityHandle& vertex_eh )
     426                 :            : {
     427                 :            :     ErrorCode rval;
     428                 :            :     vertex next_vertex;
     429                 :            : 
     430         [ #  # ]:          0 :     for( int i = 1; i < 4; i++ )
     431         [ #  # ]:          0 :         next_vertex.coord[i - 1] = atof( v_tokens[i].c_str() );
     432                 :            : 
     433 [ #  # ][ #  # ]:          0 :     rval = MBI->create_vertex( next_vertex.coord, vertex_eh );MB_CHK_SET_ERR( rval, "Unbale to create vertex." );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     434                 :            : 
     435                 :          0 :     return rval;
     436                 :            : }
     437                 :            : 
     438                 :            : /* The create_new_face function converts a vector
     439                 :            :    of tokens ( f v1 v2 v3) ) to the face format;
     440                 :            :    a structure that has the three
     441                 :            :    connectivity points as members.
     442                 :            :  */
     443                 :          0 : ErrorCode ReadOBJ::create_new_face( std::vector< std::string > f_tokens, const std::vector< EntityHandle >& vertex_list,
     444                 :            :                                     EntityHandle& face_eh )
     445                 :            : {
     446                 :            :     face next_face;
     447                 :            :     ErrorCode rval;
     448                 :            : 
     449         [ #  # ]:          0 :     for( int i = 1; i < 4; i++ )
     450                 :            :     {
     451         [ #  # ]:          0 :         int vertex_id = atoi( f_tokens[i].c_str() );
     452                 :            : 
     453                 :            :         // Some faces contain format 'vertex/texture'
     454                 :            :         // Remove the '/texture' and add the vertex to the list
     455         [ #  # ]:          0 :         std::size_t slash = f_tokens[i].find( '/' );
     456         [ #  # ]:          0 :         if( slash != std::string::npos )
     457                 :            :         {
     458 [ #  # ][ #  # ]:          0 :             std::string face = f_tokens[i].substr( 0, slash );
     459                 :          0 :             vertex_id        = atoi( face.c_str() );
     460                 :            :         }
     461                 :            : 
     462         [ #  # ]:          0 :         next_face.conn[i - 1] = vertex_list[vertex_id - 1];
     463                 :            :     }
     464                 :            : 
     465 [ #  # ][ #  # ]:          0 :     rval = MBI->create_element( MBTRI, next_face.conn, 3, face_eh );MB_CHK_SET_ERR( rval, "Unable to create new face." );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     466                 :            : 
     467                 :          0 :     return rval;
     468                 :            : }
     469                 :            : 
     470                 :            : // The split_quad function divides a quad face into 4 tri faces.
     471                 :          0 : ErrorCode ReadOBJ::split_quad( std::vector< std::string > f_tokens, std::vector< EntityHandle >& vertex_list,
     472                 :            :                                Range& face_eh )
     473                 :            : {
     474                 :            :     ErrorCode rval;
     475         [ #  # ]:          0 :     std::vector< EntityHandle > quad_vert_eh;
     476                 :            : 
     477                 :            :     // Loop over quad connectivity getting vertex EHs
     478         [ #  # ]:          0 :     for( int i = 1; i < 5; i++ )
     479                 :            :     {
     480         [ #  # ]:          0 :         int vertex_id     = atoi( f_tokens[i].c_str() );
     481         [ #  # ]:          0 :         std::size_t slash = f_tokens[i].find( '/' );
     482         [ #  # ]:          0 :         if( slash != std::string::npos )
     483                 :            :         {
     484 [ #  # ][ #  # ]:          0 :             std::string face = f_tokens[i].substr( 0, slash );
     485                 :          0 :             vertex_id        = atoi( face.c_str() );
     486                 :            :         }
     487                 :            : 
     488 [ #  # ][ #  # ]:          0 :         quad_vert_eh.push_back( vertex_list[vertex_id - 1] );
     489                 :            :     }
     490                 :            : 
     491                 :            :     // Create new tri faces
     492 [ #  # ][ #  # ]:          0 :     rval = create_tri_faces( quad_vert_eh, face_eh );MB_CHK_SET_ERR( rval, "Failed to create triangles when splitting quad." );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     493                 :            : 
     494                 :          0 :     return rval;
     495                 :            : }
     496                 :            : 
     497                 :          0 : ErrorCode ReadOBJ::create_tri_faces( std::vector< EntityHandle > quad_vert_eh,
     498                 :            :                                      //                                EntityHandle center_vertex_eh,
     499                 :            :                                      Range& face_eh )
     500                 :            : {
     501                 :            :     ErrorCode rval;
     502                 :            :     EntityHandle connectivity[3];
     503                 :            :     EntityHandle new_face;
     504                 :            : 
     505         [ #  # ]:          0 :     connectivity[0] = quad_vert_eh[0];
     506         [ #  # ]:          0 :     connectivity[1] = quad_vert_eh[1];
     507         [ #  # ]:          0 :     connectivity[2] = quad_vert_eh[2];
     508         [ #  # ]:          0 :     rval            = MBI->create_element( MBTRI, connectivity, 3, new_face );
     509         [ #  # ]:          0 :     face_eh.insert( new_face );
     510                 :            : 
     511         [ #  # ]:          0 :     connectivity[0] = quad_vert_eh[2];
     512         [ #  # ]:          0 :     connectivity[1] = quad_vert_eh[3];
     513         [ #  # ]:          0 :     connectivity[2] = quad_vert_eh[0];
     514         [ #  # ]:          0 :     rval            = MBI->create_element( MBTRI, connectivity, 3, new_face );
     515         [ #  # ]:          0 :     face_eh.insert( new_face );
     516                 :            : 
     517                 :          0 :     return rval;
     518                 :            : }
     519                 :            : 
     520 [ +  - ][ +  - ]:        228 : }  // namespace moab

Generated by: LCOV version 1.11