LCOV - code coverage report
Current view: top level - src/io - ReadCGM.cpp (source / functions) Hit Total Coverage
Test: coverage_sk.info Lines: 93 452 20.6 %
Date: 2020-12-16 07:07:30 Functions: 15 30 50.0 %
Branches: 69 1199 5.8 %

           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                 :            : #ifdef WIN32
      16                 :            : #pragma warning( disable : 4786 )
      17                 :            : #endif
      18                 :            : 
      19                 :            : #include "CGMConfig.h"
      20                 :            : #include "GeometryQueryTool.hpp"
      21                 :            : #include "ModelQueryEngine.hpp"
      22                 :            : #include "RefEntityName.hpp"
      23                 :            : #include "GMem.hpp"
      24                 :            : 
      25                 :            : #include "RefGroup.hpp"
      26                 :            : #include "RefVolume.hpp"
      27                 :            : #include "RefFace.hpp"
      28                 :            : #include "RefEdge.hpp"
      29                 :            : #include "RefVertex.hpp"
      30                 :            : 
      31                 :            : #include "SenseEntity.hpp"
      32                 :            : #include "Surface.hpp"
      33                 :            : #include "Curve.hpp"
      34                 :            : #include "Body.hpp"
      35                 :            : #include "InitCGMA.hpp"
      36                 :            : 
      37                 :            : #include "moab/Core.hpp"
      38                 :            : #include "moab/Interface.hpp"
      39                 :            : #include "moab/Range.hpp"
      40                 :            : #include "MBTagConventions.hpp"
      41                 :            : #include "moab/FileOptions.hpp"
      42                 :            : 
      43                 :            : #include "moab/GeomTopoTool.hpp"
      44                 :            : 
      45                 :            : #include "CubitCompat.hpp"
      46                 :            : 
      47                 :            : #include <stdio.h>
      48                 :            : #include <algorithm>
      49                 :            : #include <assert.h>
      50                 :            : #include <iostream>
      51                 :            : 
      52                 :            : #include "ReadCGM.hpp"
      53                 :            : #include "moab/ReadUtilIface.hpp"
      54                 :            : 
      55                 :            : namespace moab
      56                 :            : {
      57                 :            : 
      58                 :            : #define GF_CUBIT_FILE_TYPE    "CUBIT"
      59                 :            : #define GF_STEP_FILE_TYPE     "STEP"
      60                 :            : #define GF_IGES_FILE_TYPE     "IGES"
      61                 :            : #define GF_OCC_BREP_FILE_TYPE "OCC"
      62                 :            : #define GF_FACET_FILE_TYPE    "FACET"
      63                 :            : 
      64                 :          3 : ReaderIface* ReadCGM::factory( Interface* iface )
      65                 :            : {
      66         [ +  - ]:          3 :     return new ReadCGM( iface );
      67                 :            : }
      68                 :            : 
      69                 :          3 : ReadCGM::ReadCGM( Interface* impl )
      70 [ +  - ][ +  - ]:          3 :     : geom_tag( 0 ), id_tag( 0 ), name_tag( 0 ), category_tag( 0 ), faceting_tol_tag( 0 ), geometry_resabs_tag( 0 )
      71                 :            : {
      72         [ -  + ]:          3 :     assert( NULL != impl );
      73                 :          3 :     mdbImpl    = impl;
      74 [ +  - ][ +  - ]:          3 :     myGeomTool = new GeomTopoTool( impl );
      75         [ +  - ]:          3 :     impl->query_interface( readUtilIface );
      76         [ -  + ]:          3 :     assert( NULL != readUtilIface );
      77                 :            : 
      78                 :            :     // initialise counters
      79                 :          3 :     failed_curve_count   = 0;
      80                 :          3 :     failed_surface_count = 0;
      81                 :            : 
      82                 :            :     ErrorCode rval;
      83                 :            : 
      84                 :            :     // get some tag handles
      85                 :          3 :     int negone = -1, zero = 0 /*, negonearr[] = {-1, -1, -1, -1}*/;
      86                 :            :     rval = mdbImpl->tag_get_handle( GEOM_DIMENSION_TAG_NAME, 1, MB_TYPE_INTEGER, geom_tag, MB_TAG_SPARSE | MB_TAG_CREAT,
      87         [ +  - ]:          3 :                                     &negone );
      88         [ -  + ]:          3 :     assert( !rval );
      89         [ +  - ]:          3 :     id_tag = mdbImpl->globalId_tag();
      90                 :            : 
      91                 :            :     rval =
      92         [ +  - ]:          3 :         mdbImpl->tag_get_handle( NAME_TAG_NAME, NAME_TAG_SIZE, MB_TYPE_OPAQUE, name_tag, MB_TAG_SPARSE | MB_TAG_CREAT );
      93         [ -  + ]:          3 :     assert( !rval );
      94                 :            : 
      95                 :            :     rval = mdbImpl->tag_get_handle( CATEGORY_TAG_NAME, CATEGORY_TAG_SIZE, MB_TYPE_OPAQUE, category_tag,
      96         [ +  - ]:          3 :                                     MB_TAG_SPARSE | MB_TAG_CREAT );
      97         [ -  + ]:          3 :     assert( !rval );
      98         [ +  - ]:          3 :     rval = mdbImpl->tag_get_handle( "FACETING_TOL", 1, MB_TYPE_DOUBLE, faceting_tol_tag, MB_TAG_SPARSE | MB_TAG_CREAT );
      99         [ -  + ]:          3 :     assert( !rval );
     100                 :            :     rval = mdbImpl->tag_get_handle( "GEOMETRY_RESABS", 1, MB_TYPE_DOUBLE, geometry_resabs_tag,
     101         [ +  - ]:          3 :                                     MB_TAG_SPARSE | MB_TAG_CREAT );
     102         [ -  + ]:          3 :     assert( !rval );
     103                 :            : #ifdef NDEBUG
     104                 :            :     if( !rval ) {};  // Line to avoid compiler warning about variable set but not used
     105                 :            : #endif
     106                 :          3 : }
     107                 :            : 
     108                 :          9 : ReadCGM::~ReadCGM()
     109                 :            : {
     110                 :          3 :     mdbImpl->release_interface( readUtilIface );
     111         [ +  - ]:          3 :     delete myGeomTool;
     112         [ -  + ]:          6 : }
     113                 :            : 
     114                 :          0 : ErrorCode ReadCGM::read_tag_values( const char* /* file_name */, const char* /* tag_name */,
     115                 :            :                                     const FileOptions& /* opts */, std::vector< int >& /* tag_values_out */,
     116                 :            :                                     const SubsetList* /* subset_list */ )
     117                 :            : {
     118                 :          0 :     return MB_NOT_IMPLEMENTED;
     119                 :            : }
     120                 :            : 
     121                 :            : // Sets options passed into ReadCGM::load_file
     122                 :          3 : ErrorCode ReadCGM::set_options( const FileOptions& opts, int& norm_tol, double& faceting_tol, double& len_tol,
     123                 :            :                                 bool& act_att, bool& verbose_warnings, bool& fatal_on_curves )
     124                 :            : {
     125                 :            :     ErrorCode rval;
     126                 :            : 
     127                 :            :     // Default Values
     128                 :          3 :     int DEFAULT_NORM         = 5;
     129                 :          3 :     double DEFAULT_FACET_TOL = 0.001;
     130                 :          3 :     double DEFAULT_LEN_TOL   = 0.0;
     131                 :          3 :     act_att                  = true;
     132                 :            : 
     133                 :            :     // Check for the options.
     134         [ +  - ]:          3 :     if( MB_SUCCESS != opts.get_int_option( "FACET_NORMAL_TOLERANCE", norm_tol ) ) norm_tol = DEFAULT_NORM;
     135                 :            : 
     136         [ +  - ]:          3 :     if( MB_SUCCESS != opts.get_real_option( "FACET_DISTANCE_TOLERANCE", faceting_tol ) )
     137                 :          3 :         faceting_tol = DEFAULT_FACET_TOL;
     138                 :            : 
     139         [ +  - ]:          3 :     if( MB_SUCCESS != opts.get_real_option( "MAX_FACET_EDGE_LENGTH", len_tol ) ) len_tol = DEFAULT_LEN_TOL;
     140                 :            : 
     141         [ -  + ]:          3 :     if( MB_SUCCESS == opts.get_null_option( "VERBOSE_CGM_WARNINGS" ) ) verbose_warnings = true;
     142                 :            : 
     143         [ -  + ]:          3 :     if( MB_SUCCESS == opts.get_null_option( "FATAL_ON_CURVES" ) ) fatal_on_curves = true;
     144                 :            : 
     145                 :          3 :     const char* name  = "CGM_ATTRIBS";
     146                 :          3 :     const char* value = "no";
     147                 :          3 :     rval              = opts.match_option( name, value );
     148         [ -  + ]:          3 :     if( MB_SUCCESS == rval ) act_att = false;
     149                 :            : 
     150                 :          3 :     return MB_SUCCESS;
     151                 :            : }
     152                 :            : 
     153                 :          0 : ErrorCode ReadCGM::create_entity_sets( std::map< RefEntity*, EntityHandle > ( &entmap )[5] )
     154                 :            : {
     155                 :            :     ErrorCode rval;
     156                 :          0 :     const char geom_categories[][CATEGORY_TAG_SIZE] = { "Vertex\0", "Curve\0", "Surface\0", "Volume\0", "Group\0" };
     157                 :          0 :     const char* const names[]                       = { "Vertex", "Curve", "Surface", "Volume" };
     158         [ #  # ]:          0 :     DLIList< RefEntity* > entlist;
     159                 :            : 
     160         [ #  # ]:          0 :     for( int dim = 0; dim < 4; dim++ )
     161                 :            :     {
     162         [ #  # ]:          0 :         entlist.clean_out();
     163 [ #  # ][ #  # ]:          0 :         GeometryQueryTool::instance()->ref_entity_list( names[dim], entlist, true );
     164         [ #  # ]:          0 :         entlist.reset();
     165                 :            : 
     166 [ #  # ][ #  # ]:          0 :         for( int i = entlist.size(); i--; )
     167                 :            :         {
     168         [ #  # ]:          0 :             RefEntity* ent = entlist.get_and_step();
     169                 :            :             EntityHandle handle;
     170                 :            :             // Create the new meshset
     171 [ #  # ][ #  # ]:          0 :             rval = mdbImpl->create_meshset( dim == 1 ? MESHSET_ORDERED : MESHSET_SET, handle );
     172         [ #  # ]:          0 :             if( MB_SUCCESS != rval ) return rval;
     173                 :            : 
     174                 :            :             // Map the geom reference entity to the corresponding moab meshset
     175         [ #  # ]:          0 :             entmap[dim][ent] = handle;
     176                 :            : 
     177                 :            :             // Create tags for the new meshset
     178         [ #  # ]:          0 :             rval = mdbImpl->tag_set_data( geom_tag, &handle, 1, &dim );
     179         [ #  # ]:          0 :             if( MB_SUCCESS != rval ) return rval;
     180                 :            : 
     181         [ #  # ]:          0 :             int id = ent->id();
     182         [ #  # ]:          0 :             rval   = mdbImpl->tag_set_data( id_tag, &handle, 1, &id );
     183         [ #  # ]:          0 :             if( MB_SUCCESS != rval ) return rval;
     184                 :            : 
     185         [ #  # ]:          0 :             rval = mdbImpl->tag_set_data( category_tag, &handle, 1, &geom_categories[dim] );
     186         [ #  # ]:          0 :             if( MB_SUCCESS != rval ) return rval;
     187                 :            :         }
     188                 :            :     }
     189                 :            : 
     190                 :          0 :     return MB_SUCCESS;
     191                 :            : }
     192                 :            : 
     193                 :          0 : ErrorCode ReadCGM::create_topology( std::map< RefEntity*, EntityHandle > ( &entitymap )[5] )
     194                 :            : {
     195                 :            :     ErrorCode rval;
     196         [ #  # ]:          0 :     DLIList< RefEntity* > entitylist;
     197         [ #  # ]:          0 :     std::map< RefEntity*, EntityHandle >::iterator ci;
     198                 :            : 
     199         [ #  # ]:          0 :     for( int dim = 1; dim < 4; ++dim )
     200                 :            :     {
     201 [ #  # ][ #  # ]:          0 :         for( ci = entitymap[dim].begin(); ci != entitymap[dim].end(); ++ci )
                 [ #  # ]
     202                 :            :         {
     203         [ #  # ]:          0 :             entitylist.clean_out();
     204 [ #  # ][ #  # ]:          0 :             ci->first->get_child_ref_entities( entitylist );
     205                 :            : 
     206         [ #  # ]:          0 :             entitylist.reset();
     207 [ #  # ][ #  # ]:          0 :             for( int i = entitylist.size(); i--; )
     208                 :            :             {
     209         [ #  # ]:          0 :                 RefEntity* ent = entitylist.get_and_step();
     210         [ #  # ]:          0 :                 EntityHandle h = entitymap[dim - 1][ent];
     211 [ #  # ][ #  # ]:          0 :                 rval           = mdbImpl->add_parent_child( ci->second, h );
     212         [ #  # ]:          0 :                 if( MB_SUCCESS != rval ) return rval;
     213                 :            :             }
     214                 :            :         }
     215                 :            :     }
     216                 :            : 
     217                 :          0 :     return MB_SUCCESS;
     218                 :            : }
     219                 :            : 
     220                 :          0 : ErrorCode ReadCGM::store_surface_senses( std::map< RefEntity*, EntityHandle >& surface_map,
     221                 :            :                                          std::map< RefEntity*, EntityHandle >& volume_map )
     222                 :            : {
     223                 :            :     ErrorCode rval;
     224         [ #  # ]:          0 :     std::map< RefEntity*, EntityHandle >::iterator ci;
     225                 :            : 
     226 [ #  # ][ #  # ]:          0 :     for( ci = surface_map.begin(); ci != surface_map.end(); ++ci )
                 [ #  # ]
     227                 :            :     {
     228 [ #  # ][ #  # ]:          0 :         RefFace* face                = (RefFace*)( ci->first );
     229                 :          0 :         BasicTopologyEntity *forward = 0, *reverse = 0;
     230 [ #  # ][ #  # ]:          0 :         for( SenseEntity* cf = face->get_first_sense_entity_ptr(); cf; cf = cf->next_on_bte() )
                 [ #  # ]
     231                 :            :         {
     232         [ #  # ]:          0 :             BasicTopologyEntity* vol = cf->get_parent_basic_topology_entity_ptr();
     233                 :            :             // Allocate vol to the proper topology entity (forward or reverse)
     234 [ #  # ][ #  # ]:          0 :             if( cf->get_sense() == CUBIT_UNKNOWN || cf->get_sense() != face->get_surface_ptr()->bridge_sense() )
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     235                 :            :             {
     236                 :            :                 // Check that each surface has a sense for only one volume
     237         [ #  # ]:          0 :                 if( reverse )
     238                 :            :                 {
     239 [ #  # ][ #  # ]:          0 :                     std::cout << "Surface " << face->id() << " has reverse sense "
         [ #  # ][ #  # ]
     240 [ #  # ][ #  # ]:          0 :                               << "with multiple volume " << reverse->id() << " and "
         [ #  # ][ #  # ]
     241 [ #  # ][ #  # ]:          0 :                               << "volume " << vol->id() << std::endl;
         [ #  # ][ #  # ]
     242                 :          0 :                     return MB_FAILURE;
     243                 :            :                 }
     244                 :          0 :                 reverse = vol;
     245                 :            :             }
     246 [ #  # ][ #  # ]:          0 :             if( cf->get_sense() == CUBIT_UNKNOWN || cf->get_sense() == face->get_surface_ptr()->bridge_sense() )
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     247                 :            :             {
     248                 :            :                 // Check that each surface has a sense for only one volume
     249         [ #  # ]:          0 :                 if( forward )
     250                 :            :                 {
     251 [ #  # ][ #  # ]:          0 :                     std::cout << "Surface " << face->id() << " has forward sense "
         [ #  # ][ #  # ]
     252 [ #  # ][ #  # ]:          0 :                               << "with multiple volume " << forward->id() << " and "
         [ #  # ][ #  # ]
     253 [ #  # ][ #  # ]:          0 :                               << "volume " << vol->id() << std::endl;
         [ #  # ][ #  # ]
     254                 :          0 :                     return MB_FAILURE;
     255                 :            :                 }
     256                 :          0 :                 forward = vol;
     257                 :            :             }
     258                 :            :         }
     259                 :            : 
     260         [ #  # ]:          0 :         if( forward )
     261                 :            :         {
     262 [ #  # ][ #  # ]:          0 :             rval = myGeomTool->set_sense( ci->second, volume_map[forward], SENSE_FORWARD );
         [ #  # ][ #  # ]
     263         [ #  # ]:          0 :             if( MB_SUCCESS != rval ) return rval;
     264                 :            :         }
     265         [ #  # ]:          0 :         if( reverse )
     266                 :            :         {
     267 [ #  # ][ #  # ]:          0 :             rval = myGeomTool->set_sense( ci->second, volume_map[reverse], SENSE_REVERSE );
         [ #  # ][ #  # ]
     268         [ #  # ]:          0 :             if( MB_SUCCESS != rval ) return rval;
     269                 :            :         }
     270                 :            :     }
     271                 :            : 
     272                 :          0 :     return MB_SUCCESS;
     273                 :            : }
     274                 :            : 
     275                 :          0 : ErrorCode ReadCGM::store_curve_senses( std::map< RefEntity*, EntityHandle >& curve_map,
     276                 :            :                                        std::map< RefEntity*, EntityHandle >& surface_map )
     277                 :            : {
     278                 :            :     ErrorCode rval;
     279         [ #  # ]:          0 :     std::vector< EntityHandle > ents;
     280         [ #  # ]:          0 :     std::vector< int > senses;
     281         [ #  # ]:          0 :     std::map< RefEntity*, EntityHandle >::iterator ci;
     282 [ #  # ][ #  # ]:          0 :     for( ci = curve_map.begin(); ci != curve_map.end(); ++ci )
                 [ #  # ]
     283                 :            :     {
     284 [ #  # ][ #  # ]:          0 :         RefEdge* edge = (RefEdge*)( ci->first );
     285                 :          0 :         ents.clear();
     286                 :          0 :         senses.clear();
     287 [ #  # ][ #  # ]:          0 :         for( SenseEntity* ce = edge->get_first_sense_entity_ptr(); ce; ce = ce->next_on_bte() )
                 [ #  # ]
     288                 :            :         {
     289         [ #  # ]:          0 :             BasicTopologyEntity* fac = ce->get_parent_basic_topology_entity_ptr();
     290 [ #  # ][ #  # ]:          0 :             EntityHandle face        = surface_map[fac];
     291 [ #  # ][ #  # ]:          0 :             if( ce->get_sense() == CUBIT_UNKNOWN || ce->get_sense() != edge->get_curve_ptr()->bridge_sense() )
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     292                 :            :             {
     293         [ #  # ]:          0 :                 ents.push_back( face );
     294         [ #  # ]:          0 :                 senses.push_back( SENSE_REVERSE );
     295                 :            :             }
     296 [ #  # ][ #  # ]:          0 :             if( ce->get_sense() == CUBIT_UNKNOWN || ce->get_sense() == edge->get_curve_ptr()->bridge_sense() )
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     297                 :            :             {
     298         [ #  # ]:          0 :                 ents.push_back( face );
     299         [ #  # ]:          0 :                 senses.push_back( SENSE_FORWARD );
     300                 :            :             }
     301                 :            :         }
     302                 :            : 
     303 [ #  # ][ #  # ]:          0 :         rval = myGeomTool->set_senses( ci->second, ents, senses );
     304         [ #  # ]:          0 :         if( MB_SUCCESS != rval ) return rval;
     305                 :            :     }
     306                 :          0 :     return MB_SUCCESS;
     307                 :            : }
     308                 :            : 
     309                 :          0 : ErrorCode ReadCGM::store_groups( std::map< RefEntity*, EntityHandle > ( &entitymap )[5] )
     310                 :            : {
     311                 :            :     ErrorCode rval;
     312                 :            : 
     313                 :            :     // Create entity sets for all ref groups
     314                 :          0 :     rval = create_group_entsets( entitymap[4] );
     315         [ #  # ]:          0 :     if( rval != MB_SUCCESS ) return rval;
     316                 :            : 
     317                 :            :     // Store group names and entities in the mesh
     318                 :          0 :     rval = store_group_content( entitymap );
     319         [ #  # ]:          0 :     if( rval != MB_SUCCESS ) return rval;
     320                 :            : 
     321                 :          0 :     return MB_SUCCESS;
     322                 :            : }
     323                 :            : 
     324                 :          0 : ErrorCode ReadCGM::create_group_entsets( std::map< RefEntity*, EntityHandle >& group_map )
     325                 :            : {
     326                 :            :     ErrorCode rval;
     327                 :          0 :     const char geom_categories[][CATEGORY_TAG_SIZE] = { "Vertex\0", "Curve\0", "Surface\0", "Volume\0", "Group\0" };
     328         [ #  # ]:          0 :     DLIList< RefEntity* > entitylist;
     329                 :            :     // Create entity sets for all ref groups
     330         [ #  # ]:          0 :     std::vector< Tag > extra_name_tags;
     331                 :            : #if CGM_MAJOR_VERSION > 13
     332         [ #  # ]:          0 :     DLIList< CubitString > name_list;
     333                 :            : #else
     334                 :            :     DLIList< CubitString* > name_list;
     335                 :            : #endif
     336         [ #  # ]:          0 :     entitylist.clean_out();
     337                 :            :     // Get all entity groups from the CGM model
     338 [ #  # ][ #  # ]:          0 :     GeometryQueryTool::instance()->ref_entity_list( "group", entitylist );
     339         [ #  # ]:          0 :     entitylist.reset();
     340                 :            :     // Loop over all groups
     341 [ #  # ][ #  # ]:          0 :     for( int i = entitylist.size(); i--; )
     342                 :            :     {
     343                 :            :         // Take the next group
     344         [ #  # ]:          0 :         RefEntity* grp = entitylist.get_and_step();
     345         [ #  # ]:          0 :         name_list.clean_out();
     346                 :            : // Get the names of all entities in this group from the solid model
     347                 :            : #if CGM_MAJOR_VERSION > 13
     348 [ #  # ][ #  # ]:          0 :         RefEntityName::instance()->get_refentity_name( grp, name_list );
     349                 :            : #else
     350                 :            :         // True argument is optional, but for large multi-names situation, it should save
     351                 :            :         // some cpu time
     352                 :            :         RefEntityName::instance()->get_refentity_name( grp, name_list, true );
     353                 :            : #endif
     354 [ #  # ][ #  # ]:          0 :         if( name_list.size() == 0 ) continue;
     355                 :            :         // Set pointer to first name of the group and set the first name to name1
     356         [ #  # ]:          0 :         name_list.reset();
     357                 :            : #if CGM_MAJOR_VERSION > 13
     358 [ #  # ][ #  # ]:          0 :         CubitString name1 = name_list.get();
     359                 :            : #else
     360                 :            :         CubitString name1 = *name_list.get();
     361                 :            : #endif
     362                 :            :         // Create entity handle for the group
     363                 :            :         EntityHandle h;
     364         [ #  # ]:          0 :         rval = mdbImpl->create_meshset( MESHSET_SET, h );
     365         [ #  # ]:          0 :         if( MB_SUCCESS != rval ) return rval;
     366                 :            :         // Set tag data for the group
     367                 :            :         char namebuf[NAME_TAG_SIZE];
     368                 :          0 :         memset( namebuf, '\0', NAME_TAG_SIZE );
     369         [ #  # ]:          0 :         strncpy( namebuf, name1.c_str(), NAME_TAG_SIZE - 1 );
     370 [ #  # ][ #  # ]:          0 :         if( name1.length() >= (unsigned)NAME_TAG_SIZE )
     371 [ #  # ][ #  # ]:          0 :             std::cout << "WARNING: group name '" << name1.c_str() << "' truncated to '" << namebuf << "'" << std::endl;
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     372         [ #  # ]:          0 :         rval = mdbImpl->tag_set_data( name_tag, &h, 1, namebuf );
     373         [ #  # ]:          0 :         if( MB_SUCCESS != rval ) return MB_FAILURE;
     374                 :            : 
     375         [ #  # ]:          0 :         int id = grp->id();
     376         [ #  # ]:          0 :         rval   = mdbImpl->tag_set_data( id_tag, &h, 1, &id );
     377         [ #  # ]:          0 :         if( MB_SUCCESS != rval ) return MB_FAILURE;
     378                 :            : 
     379         [ #  # ]:          0 :         rval = mdbImpl->tag_set_data( category_tag, &h, 1, &geom_categories[4] );
     380         [ #  # ]:          0 :         if( MB_SUCCESS != rval ) return MB_FAILURE;
     381                 :            :         // Check for extra group names
     382 [ #  # ][ #  # ]:          0 :         if( name_list.size() > 1 )
     383                 :            :         {
     384 [ #  # ][ #  # ]:          0 :             for( int j = extra_name_tags.size(); j < name_list.size(); ++j )
     385                 :            :             {
     386                 :          0 :                 sprintf( namebuf, "EXTRA_%s%d", NAME_TAG_NAME, j );
     387                 :            :                 Tag t;
     388                 :            :                 rval =
     389         [ #  # ]:          0 :                     mdbImpl->tag_get_handle( namebuf, NAME_TAG_SIZE, MB_TYPE_OPAQUE, t, MB_TAG_SPARSE | MB_TAG_CREAT );
     390         [ #  # ]:          0 :                 assert( !rval );
     391         [ #  # ]:          0 :                 extra_name_tags.push_back( t );
     392                 :            :             }
     393                 :            :             // Add extra group names to the group handle
     394 [ #  # ][ #  # ]:          0 :             for( int j = 0; j < name_list.size(); ++j )
     395                 :            :             {
     396                 :            : #if CGM_MAJOR_VERSION > 13
     397 [ #  # ][ #  # ]:          0 :                 name1 = name_list.get_and_step();
     398                 :            : #else
     399                 :            :                 name1 = *name_list.get_and_step();
     400                 :            : #endif
     401                 :          0 :                 memset( namebuf, '\0', NAME_TAG_SIZE );
     402         [ #  # ]:          0 :                 strncpy( namebuf, name1.c_str(), NAME_TAG_SIZE - 1 );
     403 [ #  # ][ #  # ]:          0 :                 if( name1.length() >= (unsigned)NAME_TAG_SIZE )
     404 [ #  # ][ #  # ]:          0 :                     std::cout << "WARNING: group name '" << name1.c_str() << "' truncated to '" << namebuf << "'"
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     405         [ #  # ]:          0 :                               << std::endl;
     406 [ #  # ][ #  # ]:          0 :                 rval = mdbImpl->tag_set_data( extra_name_tags[j], &h, 1, namebuf );
     407         [ #  # ]:          0 :                 if( MB_SUCCESS != rval ) return MB_FAILURE;
     408                 :            :             }
     409                 :            :         }
     410                 :            :         // Add the group handle
     411 [ #  # ][ #  # ]:          0 :         group_map[grp] = h;
     412                 :          0 :     }
     413                 :            : 
     414                 :          0 :     return MB_SUCCESS;
     415                 :            : }
     416                 :            : 
     417                 :          0 : ErrorCode ReadCGM::store_group_content( std::map< RefEntity*, EntityHandle > ( &entitymap )[5] )
     418                 :            : {
     419                 :            :     ErrorCode rval;
     420         [ #  # ]:          0 :     DLIList< RefEntity* > entlist;
     421         [ #  # ]:          0 :     std::map< RefEntity*, EntityHandle >::iterator ci;
     422                 :            :     // Store contents for each group
     423         [ #  # ]:          0 :     entlist.reset();
     424 [ #  # ][ #  # ]:          0 :     for( ci = entitymap[4].begin(); ci != entitymap[4].end(); ++ci )
                 [ #  # ]
     425                 :            :     {
     426         [ #  # ]:          0 :         RefGroup* grp = (RefGroup*)( ci->first );
     427         [ #  # ]:          0 :         entlist.clean_out();
     428         [ #  # ]:          0 :         grp->get_child_ref_entities( entlist );
     429                 :            : 
     430         [ #  # ]:          0 :         Range entities;
     431 [ #  # ][ #  # ]:          0 :         while( entlist.size() )
     432                 :            :         {
     433         [ #  # ]:          0 :             RefEntity* ent = entlist.pop();
     434         [ #  # ]:          0 :             int dim        = ent->dimension();
     435                 :            : 
     436         [ #  # ]:          0 :             if( dim < 0 )
     437                 :            :             {
     438                 :            :                 Body* body;
     439 [ #  # ][ #  # ]:          0 :                 if( entitymap[4].find( ent ) != entitymap[4].end() )
                 [ #  # ]
     440                 :            :                 {
     441                 :            :                     // Child is another group; examine its contents
     442 [ #  # ][ #  # ]:          0 :                     entities.insert( entitymap[4][ent] );
     443                 :            :                 }
     444 [ #  # ][ #  # ]:          0 :                 else if( ( body = dynamic_cast< Body* >( ent ) ) != NULL )
     445                 :            :                 {
     446                 :            :                     // Child is a CGM Body, which presumably comprises some volumes--
     447                 :            :                     // extract volumes as if they belonged to group.
     448         [ #  # ]:          0 :                     DLIList< RefVolume* > vols;
     449         [ #  # ]:          0 :                     body->ref_volumes( vols );
     450 [ #  # ][ #  # ]:          0 :                     for( int vi = vols.size(); vi--; )
     451                 :            :                     {
     452         [ #  # ]:          0 :                         RefVolume* vol = vols.get_and_step();
     453 [ #  # ][ #  # ]:          0 :                         if( entitymap[3].find( vol ) != entitymap[3].end() ) { entities.insert( entitymap[3][vol] ); }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     454                 :            :                         else
     455                 :            :                         {
     456 [ #  # ][ #  # ]:          0 :                             std::cerr << "Warning: CGM Body has orphan RefVolume" << std::endl;
     457                 :            :                         }
     458                 :          0 :                     }
     459                 :            :                 }
     460                 :            :                 else
     461                 :            :                 {
     462                 :            :                     // Otherwise, warn user.
     463 [ #  # ][ #  # ]:          0 :                     std::cerr << "Warning: A dim<0 entity is being ignored by ReadCGM." << std::endl;
     464                 :            :                 }
     465                 :            :             }
     466         [ #  # ]:          0 :             else if( dim < 4 )
     467                 :            :             {
     468 [ #  # ][ #  # ]:          0 :                 if( entitymap[dim].find( ent ) != entitymap[dim].end() ) entities.insert( entitymap[dim][ent] );
         [ #  # ][ #  # ]
                 [ #  # ]
     469                 :            :             }
     470                 :            :         }
     471                 :            : 
     472 [ #  # ][ #  # ]:          0 :         if( !entities.empty() )
     473                 :            :         {
     474 [ #  # ][ #  # ]:          0 :             rval = mdbImpl->add_entities( ci->second, entities );
     475 [ #  # ][ #  # ]:          0 :             if( MB_SUCCESS != rval ) return MB_FAILURE;
     476                 :            :         }
     477                 :          0 :     }
     478                 :            : 
     479                 :          0 :     return MB_SUCCESS;
     480                 :            : }
     481                 :            : 
     482                 :          3 : void ReadCGM::set_cgm_attributes( bool const act_attributes, bool const verbose )
     483                 :            : {
     484         [ +  - ]:          3 :     if( act_attributes )
     485                 :            :     {
     486                 :          3 :         CGMApp::instance()->attrib_manager()->set_all_auto_read_flags( act_attributes );
     487                 :          3 :         CGMApp::instance()->attrib_manager()->set_all_auto_actuate_flags( act_attributes );
     488                 :            :     }
     489                 :            : 
     490         [ +  - ]:          3 :     if( !verbose ) { CGMApp::instance()->attrib_manager()->silent_flag( true ); }
     491                 :          3 : }
     492                 :            : 
     493                 :          0 : ErrorCode ReadCGM::create_vertices( std::map< RefEntity*, EntityHandle >& vertex_map )
     494                 :            : {
     495                 :            :     ErrorCode rval;
     496         [ #  # ]:          0 :     std::map< RefEntity*, EntityHandle >::iterator ci;
     497 [ #  # ][ #  # ]:          0 :     for( ci = vertex_map.begin(); ci != vertex_map.end(); ++ci )
                 [ #  # ]
     498                 :            :     {
     499 [ #  # ][ #  # ]:          0 :         CubitVector pos  = dynamic_cast< RefVertex* >( ci->first )->coordinates();
                 [ #  # ]
     500 [ #  # ][ #  # ]:          0 :         double coords[3] = { pos.x(), pos.y(), pos.z() };
                 [ #  # ]
     501                 :            :         EntityHandle vh;
     502         [ #  # ]:          0 :         rval = mdbImpl->create_vertex( coords, vh );
     503         [ #  # ]:          0 :         if( MB_SUCCESS != rval ) return MB_FAILURE;
     504                 :            : 
     505                 :            :         // Add the vertex to its tagged meshset
     506 [ #  # ][ #  # ]:          0 :         rval = mdbImpl->add_entities( ci->second, &vh, 1 );
     507         [ #  # ]:          0 :         if( MB_SUCCESS != rval ) return MB_FAILURE;
     508                 :            : 
     509                 :            :         // Replace the meshset handle with the vertex handle
     510                 :            :         // This makes adding the vertex to higher dim sets easier
     511         [ #  # ]:          0 :         ci->second = vh;
     512                 :            :     }
     513                 :            : 
     514                 :          0 :     return MB_SUCCESS;
     515                 :            : }
     516                 :            : 
     517                 :          0 : ErrorCode ReadCGM::create_curve_facets( std::map< RefEntity*, EntityHandle >& curve_map,
     518                 :            :                                         std::map< RefEntity*, EntityHandle >& vertex_map,
     519                 :            : #if CGM_MAJOR_VERSION > 12
     520                 :            :                                         int norm_tol,
     521                 :            : #else
     522                 :            :                                         int /* norm_tol */,
     523                 :            : #endif
     524                 :            :                                         double faceting_tol, bool verbose_warn, bool fatal_on_curves )
     525                 :            : {
     526                 :            :     ErrorCode rval;
     527                 :            :     CubitStatus s;
     528                 :            :     // Maximum allowable curve-endpoint proximity warnings
     529                 :            :     // If this integer becomes negative, then abs(curve_warnings) is the
     530                 :            :     // number of warnings that were suppressed.
     531                 :          0 :     int curve_warnings = 0;
     532                 :            : 
     533                 :            :     // Map iterator
     534         [ #  # ]:          0 :     std::map< RefEntity*, EntityHandle >::iterator ci;
     535                 :            : 
     536                 :            :     // Create geometry for all curves
     537         [ #  # ]:          0 :     GMem data;
     538 [ #  # ][ #  # ]:          0 :     for( ci = curve_map.begin(); ci != curve_map.end(); ++ci )
                 [ #  # ]
     539                 :            :     {
     540                 :            :         // Get the start and end points of the curve in the form of a reference edge
     541 [ #  # ][ #  # ]:          0 :         RefEdge* edge = dynamic_cast< RefEdge* >( ci->first );
     542                 :            :         // Get the edge's curve information
     543         [ #  # ]:          0 :         Curve* curve = edge->get_curve_ptr();
     544                 :            :         // Clean out previous curve information
     545         [ #  # ]:          0 :         data.clean_out();
     546                 :            :         // Facet curve according to parameters and CGM version
     547                 :            : #if CGM_MAJOR_VERSION > 12
     548         [ #  # ]:          0 :         s = edge->get_graphics( data, norm_tol, faceting_tol );
     549                 :            : #else
     550                 :            :         s = edge->get_graphics( data, faceting_tol );
     551                 :            : #endif
     552                 :            : 
     553         [ #  # ]:          0 :         if( s != CUBIT_SUCCESS )
     554                 :            :         {
     555                 :            :             // if we fatal on curves
     556         [ #  # ]:          0 :             if( fatal_on_curves )
     557                 :            :             {
     558 [ #  # ][ #  # ]:          0 :                 std::cout << "Failed to facet the curve " << edge->id() << std::endl;
         [ #  # ][ #  # ]
     559                 :          0 :                 return MB_FAILURE;
     560                 :            :             }
     561                 :            :             // otherwise record them
     562                 :            :             else
     563                 :            :             {
     564                 :          0 :                 failed_curve_count++;
     565 [ #  # ][ #  # ]:          0 :                 failed_curves.push_back( edge->id() );
     566                 :            :             }
     567                 :          0 :             continue;
     568                 :            :         }
     569                 :            : 
     570         [ #  # ]:          0 :         std::vector< CubitVector > points;
     571         [ #  # ]:          0 :         for( int i = 0; i < data.pointListCount; ++i )
     572                 :            :             // Add Cubit vertext points to a list
     573 [ #  # ][ #  # ]:          0 :             points.push_back( CubitVector( data.point_list()[i].x, data.point_list()[i].y, data.point_list()[i].z ) );
         [ #  # ][ #  # ]
                 [ #  # ]
     574                 :            : 
     575                 :            :         // Need to reverse data?
     576 [ #  # ][ #  # ]:          0 :         if( curve->bridge_sense() == CUBIT_REVERSED ) std::reverse( points.begin(), points.end() );
                 [ #  # ]
     577                 :            : 
     578                 :            :         // Check for closed curve
     579                 :            :         RefVertex *start_vtx, *end_vtx;
     580         [ #  # ]:          0 :         start_vtx = edge->start_vertex();
     581         [ #  # ]:          0 :         end_vtx   = edge->end_vertex();
     582                 :            : 
     583                 :            :         // Special case for point curve
     584         [ #  # ]:          0 :         if( points.size() < 2 )
     585                 :            :         {
     586 [ #  # ][ #  # ]:          0 :             if( start_vtx != end_vtx || curve->measure() > GEOMETRY_RESABS )
         [ #  # ][ #  # ]
     587                 :            :             {
     588 [ #  # ][ #  # ]:          0 :                 std::cerr << "Warning: No facetting for curve " << edge->id() << std::endl;
         [ #  # ][ #  # ]
     589                 :          0 :                 continue;
     590                 :            :             }
     591 [ #  # ][ #  # ]:          0 :             EntityHandle h = vertex_map[start_vtx];
     592 [ #  # ][ #  # ]:          0 :             rval           = mdbImpl->add_entities( ci->second, &h, 1 );
     593         [ #  # ]:          0 :             if( MB_SUCCESS != rval ) return MB_FAILURE;
     594                 :          0 :             continue;
     595                 :            :         }
     596                 :            :         // Check to see if the first and last interior vertices are considered to be
     597                 :            :         // coincident by CUBIT
     598 [ #  # ][ #  # ]:          0 :         const bool closed = ( points.front() - points.back() ).length() < GEOMETRY_RESABS;
         [ #  # ][ #  # ]
     599         [ #  # ]:          0 :         if( closed != ( start_vtx == end_vtx ) )
     600                 :            :         {
     601 [ #  # ][ #  # ]:          0 :             std::cerr << "Warning: topology and geometry inconsistant for possibly closed curve " << edge->id()
                 [ #  # ]
     602         [ #  # ]:          0 :                       << std::endl;
     603                 :            :         }
     604                 :            : 
     605                 :            :         // Check proximity of vertices to end coordinates
     606 [ #  # ][ #  # ]:          0 :         if( ( start_vtx->coordinates() - points.front() ).length() > GEOMETRY_RESABS ||
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
           [ #  #  #  #  
                   #  # ]
     607 [ #  # ][ #  # ]:          0 :             ( end_vtx->coordinates() - points.back() ).length() > GEOMETRY_RESABS )
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
           [ #  #  #  # ]
     608                 :            :         {
     609                 :            : 
     610                 :          0 :             curve_warnings--;
     611 [ #  # ][ #  # ]:          0 :             if( curve_warnings >= 0 || verbose_warn )
     612                 :            :             {
     613 [ #  # ][ #  # ]:          0 :                 std::cerr << "Warning: vertices not at ends of curve " << edge->id() << std::endl;
         [ #  # ][ #  # ]
     614 [ #  # ][ #  # ]:          0 :                 if( curve_warnings == 0 && !verbose_warn )
     615 [ #  # ][ #  # ]:          0 :                 { std::cerr << "         further instances of this warning will be suppressed..." << std::endl; }
     616                 :            :             }
     617                 :            :         }
     618                 :            :         // Create interior points
     619 [ #  # ][ #  # ]:          0 :         std::vector< EntityHandle > verts, edges;
                 [ #  # ]
              [ #  #  # ]
     620 [ #  # ][ #  # ]:          0 :         verts.push_back( vertex_map[start_vtx] );
                 [ #  # ]
     621         [ #  # ]:          0 :         for( size_t i = 1; i < points.size() - 1; ++i )
     622                 :            :         {
     623 [ #  # ][ #  # ]:          0 :             double coords[] = { points[i].x(), points[i].y(), points[i].z() };
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     624                 :            :             EntityHandle h;
     625                 :            :             // Create vertex entity
     626         [ #  # ]:          0 :             rval = mdbImpl->create_vertex( coords, h );
     627         [ #  # ]:          0 :             if( MB_SUCCESS != rval ) return MB_FAILURE;
     628         [ #  # ]:          0 :             verts.push_back( h );
     629                 :            :         }
     630 [ #  # ][ #  # ]:          0 :         verts.push_back( vertex_map[end_vtx] );
                 [ #  # ]
     631                 :            : 
     632                 :            :         // Create edges
     633         [ #  # ]:          0 :         for( size_t i = 0; i < verts.size() - 1; ++i )
     634                 :            :         {
     635                 :            :             EntityHandle h;
     636 [ #  # ][ #  # ]:          0 :             rval = mdbImpl->create_element( MBEDGE, &verts[i], 2, h );
     637         [ #  # ]:          0 :             if( MB_SUCCESS != rval ) return MB_FAILURE;
     638         [ #  # ]:          0 :             edges.push_back( h );
     639                 :            :         }
     640                 :            : 
     641                 :            :         // If closed, remove duplicate
     642 [ #  # ][ #  # ]:          0 :         if( verts.front() == verts.back() ) verts.pop_back();
         [ #  # ][ #  # ]
     643                 :            :         // Add entities to the curve meshset from entitymap
     644 [ #  # ][ #  # ]:          0 :         rval = mdbImpl->add_entities( ci->second, &verts[0], verts.size() );
                 [ #  # ]
     645         [ #  # ]:          0 :         if( MB_SUCCESS != rval ) return MB_FAILURE;
     646 [ #  # ][ #  # ]:          0 :         rval = mdbImpl->add_entities( ci->second, &edges[0], edges.size() );
                 [ #  # ]
     647 [ #  # ][ #  # ]:          0 :         if( MB_SUCCESS != rval ) return MB_FAILURE;
     648                 :          0 :     }
     649                 :            : 
     650 [ #  # ][ #  # ]:          0 :     if( !verbose_warn && curve_warnings < 0 )
     651                 :            :     {
     652 [ #  # ][ #  # ]:          0 :         std::cerr << "Suppressed " << -curve_warnings << " 'vertices not at ends of curve' warnings." << std::endl;
         [ #  # ][ #  # ]
     653 [ #  # ][ #  # ]:          0 :         std::cerr << "To see all warnings, use reader param VERBOSE_CGM_WARNINGS." << std::endl;
     654                 :            :     }
     655                 :            : 
     656                 :          0 :     return MB_SUCCESS;
     657                 :            : }
     658                 :            : 
     659                 :          0 : ErrorCode ReadCGM::create_surface_facets( std::map< RefEntity*, EntityHandle >& surface_map,
     660                 :            :                                           std::map< RefEntity*, EntityHandle >& vertex_map, int norm_tol,
     661                 :            :                                           double facet_tol, double length_tol )
     662                 :            : {
     663                 :            :     ErrorCode rval;
     664         [ #  # ]:          0 :     std::map< RefEntity*, EntityHandle >::iterator ci;
     665                 :            :     CubitStatus s;
     666                 :            : #if( ( CGM_MAJOR_VERSION == 14 && CGM_MINOR_VERSION > 2 ) || CGM_MAJOR_VERSION >= 15 )
     667         [ #  # ]:          0 :     DLIList< TopologyEntity* > me_list;
     668                 :            : #else
     669                 :            :     DLIList< ModelEntity* > me_list;
     670                 :            : #endif
     671                 :            : 
     672         [ #  # ]:          0 :     GMem data;
     673                 :            :     // Create geometry for all surfaces
     674 [ #  # ][ #  # ]:          0 :     for( ci = surface_map.begin(); ci != surface_map.end(); ++ci )
                 [ #  # ]
     675                 :            :     {
     676 [ #  # ][ #  # ]:          0 :         RefFace* face = dynamic_cast< RefFace* >( ci->first );
     677                 :            : 
     678         [ #  # ]:          0 :         data.clean_out();
     679         [ #  # ]:          0 :         s = face->get_graphics( data, norm_tol, facet_tol, length_tol );
     680                 :            : 
     681         [ #  # ]:          0 :         if( CUBIT_SUCCESS != s ) return MB_FAILURE;
     682                 :            : 
     683                 :            :         // Declare array of all vertex handles
     684         [ #  # ]:          0 :         std::vector< EntityHandle > verts( data.pointListCount, 0 );
     685                 :            : 
     686                 :            :         // Get list of geometric vertices in surface
     687         [ #  # ]:          0 :         me_list.clean_out();
     688 [ #  # ][ #  # ]:          0 :         ModelQueryEngine::instance()->query_model( *face, DagType::ref_vertex_type(), me_list );
                 [ #  # ]
     689                 :            : 
     690                 :            :         // For each geometric vertex, find a single coincident point in facets
     691                 :            :         // Otherwise, print a warning
     692 [ #  # ][ #  # ]:          0 :         for( int i = me_list.size(); i--; )
     693                 :            :         {
     694                 :            :             // Assign geometric vertex
     695 [ #  # ][ #  # ]:          0 :             RefVertex* vtx  = dynamic_cast< RefVertex* >( me_list.get_and_step() );
     696         [ #  # ]:          0 :             CubitVector pos = vtx->coordinates();
     697                 :            : 
     698         [ #  # ]:          0 :             for( int j = 0; j < data.pointListCount; ++j )
     699                 :            :             {
     700                 :            :                 // Assign facet vertex
     701 [ #  # ][ #  # ]:          0 :                 CubitVector vpos( data.point_list()[j].x, data.point_list()[j].y, data.point_list()[j].z );
         [ #  # ][ #  # ]
     702                 :            :                 // Check to see if they are considered coincident
     703 [ #  # ][ #  # ]:          0 :                 if( ( pos - vpos ).length_squared() < GEOMETRY_RESABS * GEOMETRY_RESABS )
                 [ #  # ]
     704                 :            :                 {
     705                 :            :                     // If this facet vertex has already been found coincident, print warning
     706 [ #  # ][ #  # ]:          0 :                     if( verts[j] ) std::cerr << "Warning: Coincident vertices in surface " << face->id() << std::endl;
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     707                 :            :                     // If a coincidence is found, keep track of it in the verts vector
     708 [ #  # ][ #  # ]:          0 :                     verts[j] = vertex_map[vtx];
                 [ #  # ]
     709                 :          0 :                     break;
     710                 :            :                 }
     711                 :            :             }
     712                 :            :         }
     713                 :            : 
     714                 :            :         // Now create vertices for the remaining points in the facetting
     715         [ #  # ]:          0 :         for( int i = 0; i < data.pointListCount; ++i )
     716                 :            :         {
     717 [ #  # ][ #  # ]:          0 :             if( verts[i] )  // If a geometric vertex
     718                 :          0 :                 continue;
     719 [ #  # ][ #  # ]:          0 :             double coords[] = { data.point_list()[i].x, data.point_list()[i].y, data.point_list()[i].z };
                 [ #  # ]
     720                 :            :             // Return vertex handle to verts to fill in all remaining facet
     721                 :            :             // vertices
     722 [ #  # ][ #  # ]:          0 :             rval = mdbImpl->create_vertex( coords, verts[i] );
     723         [ #  # ]:          0 :             if( MB_SUCCESS != rval ) return rval;
     724                 :            :         }
     725                 :            : 
     726                 :            :         // record the failures for information
     727         [ #  # ]:          0 :         if( data.fListCount == 0 )
     728                 :            :         {
     729                 :          0 :             failed_surface_count++;
     730 [ #  # ][ #  # ]:          0 :             failed_surfaces.push_back( face->id() );
     731                 :            :         }
     732                 :            : 
     733                 :            :         // Now create facets
     734 [ #  # ][ #  # ]:          0 :         Range facets;
     735 [ #  # ][ #  # ]:          0 :         std::vector< EntityHandle > corners;
     736 [ #  # ][ #  # ]:          0 :         for( int i = 0; i < data.fListCount; i += data.facet_list()[i] + 1 )
     737                 :            :         {
     738                 :            :             // Get number of facet verts
     739         [ #  # ]:          0 :             int* facet = data.facet_list() + i;
     740         [ #  # ]:          0 :             corners.resize( *facet );
     741         [ #  # ]:          0 :             for( int j = 1; j <= *facet; ++j )
     742                 :            :             {
     743         [ #  # ]:          0 :                 if( facet[j] >= (int)verts.size() )
     744                 :            :                 {
     745 [ #  # ][ #  # ]:          0 :                     std::cerr << "ERROR: Invalid facet data for surface " << face->id() << std::endl;
         [ #  # ][ #  # ]
     746                 :          0 :                     return MB_FAILURE;
     747                 :            :                 }
     748 [ #  # ][ #  # ]:          0 :                 corners[j - 1] = verts[facet[j]];
     749                 :            :             }
     750                 :            :             EntityType type;
     751         [ #  # ]:          0 :             if( *facet == 3 )
     752                 :          0 :                 type = MBTRI;
     753                 :            :             else
     754                 :            :             {
     755 [ #  # ][ #  # ]:          0 :                 std::cerr << "Warning: non-triangle facet in surface " << face->id() << std::endl;
         [ #  # ][ #  # ]
     756 [ #  # ][ #  # ]:          0 :                 std::cerr << "  entity has " << *facet << " edges" << std::endl;
         [ #  # ][ #  # ]
     757         [ #  # ]:          0 :                 if( *facet == 4 )
     758                 :          0 :                     type = MBQUAD;
     759                 :            :                 else
     760                 :          0 :                     type = MBPOLYGON;
     761                 :            :             }
     762                 :            : 
     763                 :            :             // if (surf->bridge_sense() == CUBIT_REVERSED)
     764                 :            :             // std::reverse(corners.begin(), corners.end());
     765                 :            : 
     766                 :            :             EntityHandle h;
     767 [ #  # ][ #  # ]:          0 :             rval = mdbImpl->create_element( type, &corners[0], corners.size(), h );
     768         [ #  # ]:          0 :             if( MB_SUCCESS != rval ) return MB_FAILURE;
     769                 :            : 
     770         [ #  # ]:          0 :             facets.insert( h );
     771                 :            :         }
     772                 :            : 
     773                 :            :         // Add vertices and facets to surface set
     774 [ #  # ][ #  # ]:          0 :         rval = mdbImpl->add_entities( ci->second, &verts[0], verts.size() );
                 [ #  # ]
     775         [ #  # ]:          0 :         if( MB_SUCCESS != rval ) return MB_FAILURE;
     776 [ #  # ][ #  # ]:          0 :         rval = mdbImpl->add_entities( ci->second, facets );
     777 [ #  # ][ #  # ]:          0 :         if( MB_SUCCESS != rval ) return MB_FAILURE;
     778                 :          0 :     }
     779                 :            : 
     780                 :          0 :     return MB_SUCCESS;
     781                 :            : }
     782                 :            : 
     783                 :            : // Copy geometry into mesh database
     784                 :          3 : ErrorCode ReadCGM::load_file( const char* cgm_file_name, const EntityHandle* file_set, const FileOptions& opts,
     785                 :            :                               const ReaderIface::SubsetList* subset_list, const Tag* /*file_id_tag*/ )
     786                 :            : {
     787                 :            :     // Blocks_to_load and num_blocks are ignored.
     788                 :            :     ErrorCode rval;
     789                 :            : 
     790 [ -  + ][ #  # ]:          3 :     if( subset_list ) { MB_SET_ERR( MB_UNSUPPORTED_OPERATION, "Reading subset of files not supported for CGM data" ); }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     791                 :            : 
     792                 :            :     int norm_tol;
     793                 :            :     double faceting_tol;
     794                 :            :     double len_tol;
     795                 :          3 :     bool act_att          = true;
     796                 :          3 :     bool verbose_warnings = false;
     797                 :          3 :     bool fatal_on_curves  = false;
     798                 :            : 
     799         [ +  - ]:          3 :     rval = set_options( opts, norm_tol, faceting_tol, len_tol, act_att, verbose_warnings, fatal_on_curves );
     800         [ -  + ]:          3 :     if( MB_SUCCESS != rval ) return rval;
     801                 :            : 
     802                 :            :     // Always tag with the faceting_tol and geometry absolute resolution
     803                 :            :     // If file_set is defined, use that, otherwise (file_set == NULL) tag the interface
     804         [ -  + ]:          3 :     EntityHandle set = file_set ? *file_set : 0;
     805         [ +  - ]:          3 :     rval             = mdbImpl->tag_set_data( faceting_tol_tag, &set, 1, &faceting_tol );
     806         [ -  + ]:          3 :     if( MB_SUCCESS != rval ) return rval;
     807                 :            : 
     808         [ +  - ]:          3 :     rval = mdbImpl->tag_set_data( geometry_resabs_tag, &set, 1, &GEOMETRY_RESABS );
     809         [ -  + ]:          3 :     if( MB_SUCCESS != rval ) return rval;
     810                 :            : 
     811                 :            :     // Initialize CGM
     812         [ +  - ]:          3 :     InitCGMA::initialize_cgma();
     813                 :            : 
     814                 :            :     // Determine CGM settings and amount of output
     815         [ +  - ]:          3 :     set_cgm_attributes( act_att, verbose_warnings );
     816                 :            : 
     817                 :            :     CubitStatus s;
     818                 :            : 
     819                 :            :     // Get CGM file type
     820                 :          3 :     const char* file_type = 0;
     821         [ +  - ]:          3 :     file_type             = get_geom_file_type( cgm_file_name );
     822 [ -  + ][ #  # ]:          3 :     if( !file_type || !strcmp( file_type, "CUBIT" ) ) return MB_FAILURE;
     823                 :            : 
     824         [ #  # ]:          0 :     s = CubitCompat_import_solid_model( cgm_file_name, file_type );
     825         [ #  # ]:          0 :     if( CUBIT_SUCCESS != s )
     826 [ #  # ][ #  # ]:          0 :     { MB_SET_ERR( MB_FAILURE, cgm_file_name << ": Failed to read file of type \"" << file_type << "\"" ); }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     827                 :            : 
     828                 :            :     // Create entity sets for all geometric entities
     829 [ #  # ][ #  # ]:          0 :     std::map< RefEntity*, EntityHandle > entmap[5];  // One for each dim, and one for groups
                 [ #  # ]
     830                 :            : 
     831         [ #  # ]:          0 :     rval = create_entity_sets( entmap );
     832         [ #  # ]:          0 :     if( rval != MB_SUCCESS ) return rval;
     833                 :            : 
     834                 :            :     // Create topology for all geometric entities
     835         [ #  # ]:          0 :     rval = create_topology( entmap );
     836         [ #  # ]:          0 :     if( rval != MB_SUCCESS ) return rval;
     837                 :            : 
     838                 :            :     // Store CoFace senses
     839         [ #  # ]:          0 :     rval = store_surface_senses( entmap[2], entmap[3] );
     840         [ #  # ]:          0 :     if( rval != MB_SUCCESS ) return rval;
     841                 :            : 
     842                 :            :     // Store CoEdge senses
     843         [ #  # ]:          0 :     rval = store_curve_senses( entmap[1], entmap[2] );
     844         [ #  # ]:          0 :     if( rval != MB_SUCCESS ) return rval;
     845                 :            : 
     846                 :            :     // Get group information and store it in the mesh
     847         [ #  # ]:          0 :     rval = store_groups( entmap );
     848         [ #  # ]:          0 :     if( rval != MB_SUCCESS ) return rval;
     849                 :            : 
     850                 :            :     // Done with volumes and groups
     851                 :          0 :     entmap[3].clear();
     852                 :          0 :     entmap[4].clear();
     853                 :            : 
     854                 :            :     // Create geometry for all vertices and replace
     855         [ #  # ]:          0 :     rval = create_vertices( entmap[0] );
     856         [ #  # ]:          0 :     if( rval != MB_SUCCESS ) return rval;
     857                 :            : 
     858                 :            :     // Create facets for all curves
     859         [ #  # ]:          0 :     rval = create_curve_facets( entmap[1], entmap[0], norm_tol, faceting_tol, verbose_warnings, fatal_on_curves );
     860         [ #  # ]:          0 :     if( rval != MB_SUCCESS ) return rval;
     861                 :            : 
     862                 :            :     // Create facets for surfaces
     863         [ #  # ]:          0 :     rval = create_surface_facets( entmap[2], entmap[0], norm_tol, faceting_tol, len_tol );
     864         [ #  # ]:          0 :     if( rval != MB_SUCCESS ) return rval;
     865                 :            : 
     866                 :            :     // print the fail information
     867         [ #  # ]:          0 :     dump_fail_counts();
     868                 :            : 
     869 [ #  # ][ #  # ]:          3 :     return MB_SUCCESS;
     870                 :            : }
     871                 :            : 
     872                 :            : // return the number of curves that failed to facet
     873                 :          0 : int ReadCGM::get_failed_curve_count()
     874                 :            : {
     875                 :          0 :     return failed_curve_count;
     876                 :            : }
     877                 :            : 
     878                 :            : // return the number of surfaces that failed to facet
     879                 :          0 : int ReadCGM::get_failed_surface_count()
     880                 :            : {
     881                 :          0 :     return failed_surface_count;
     882                 :            : }
     883                 :            : 
     884                 :          0 : void ReadCGM::dump_fail_counts()
     885                 :            : {
     886                 :          0 :     std::cout << "***** Faceting Summary Information *****" << std::endl;
     887                 :          0 :     std::cout << "----- Curve Fail Information -----" << std::endl;
     888                 :          0 :     std::cout << "There were " << failed_curve_count << " curves that could not be faceted." << std::endl;
     889                 :            : 
     890         [ #  # ]:          0 :     if( failed_curve_count > 0 )
     891                 :            :     {
     892                 :          0 :         std::cout << "The curves were ";
     893         [ #  # ]:          0 :         for( int i = 0; i < failed_curve_count; i++ )
     894                 :            :         {
     895                 :          0 :             std::cout << failed_curves[i] << " ";
     896         [ #  # ]:          0 :             if( ( i % 10 == 0 ) & ( i > 0 ) ) std::cout << std::endl;
     897                 :            :         }
     898                 :            :     }
     899                 :          0 :     std::cout << std::endl;
     900                 :          0 :     std::cout << "----- Facet Fail Information -----" << std::endl;
     901                 :          0 :     std::cout << "There were " << failed_surface_count << " surfaces that could not be faceted." << std::endl;
     902         [ #  # ]:          0 :     if( failed_surface_count > 0 )
     903                 :            :     {
     904                 :          0 :         std::cout << "The surfaces were ";
     905         [ #  # ]:          0 :         for( int i = 0; i < failed_surface_count; i++ )
     906                 :            :         {
     907                 :          0 :             std::cout << failed_surfaces[i] << " ";
     908         [ #  # ]:          0 :             if( ( i % 10 == 0 ) & ( i > 0 ) ) std::cout << std::endl;
     909                 :            :         }
     910                 :            :     }
     911                 :          0 :     std::cout << std::endl;
     912                 :          0 :     std::cout << "***** End of Faceting Summary Information *****" << std::endl;
     913                 :          0 :     return;
     914                 :            : }
     915                 :            : 
     916                 :          3 : const char* ReadCGM::get_geom_file_type( const char* name )
     917                 :            : {
     918                 :            :     FILE* file;
     919                 :          3 :     const char* result = 0;
     920                 :            : 
     921                 :          3 :     file = fopen( name, "r" );
     922         [ +  - ]:          3 :     if( file )
     923                 :            :     {
     924                 :          3 :         result = get_geom_fptr_type( file );
     925                 :          3 :         fclose( file );
     926                 :            :     }
     927                 :            : 
     928                 :          3 :     return result;
     929                 :            : }
     930                 :            : 
     931                 :          3 : const char* ReadCGM::get_geom_fptr_type( FILE* file )
     932                 :            : {
     933                 :            :     static const char* CUBIT_NAME = GF_CUBIT_FILE_TYPE;
     934                 :            :     static const char* STEP_NAME  = GF_STEP_FILE_TYPE;
     935                 :            :     static const char* IGES_NAME  = GF_IGES_FILE_TYPE;
     936                 :            :     static const char* BREP_NAME  = GF_OCC_BREP_FILE_TYPE;
     937                 :            :     static const char* FACET_NAME = GF_FACET_FILE_TYPE;
     938                 :            : 
     939         [ -  + ]:          3 :     if( is_cubit_file( file ) )
     940                 :          0 :         return CUBIT_NAME;
     941         [ -  + ]:          3 :     else if( is_step_file( file ) )
     942                 :          0 :         return STEP_NAME;
     943         [ -  + ]:          3 :     else if( is_iges_file( file ) )
     944                 :          0 :         return IGES_NAME;
     945         [ -  + ]:          3 :     else if( is_occ_brep_file( file ) )
     946                 :          0 :         return BREP_NAME;
     947         [ -  + ]:          3 :     else if( is_facet_file( file ) )
     948                 :          0 :         return FACET_NAME;
     949                 :            :     else
     950                 :          3 :         return NULL;
     951                 :            : }
     952                 :            : 
     953                 :          3 : int ReadCGM::is_cubit_file( FILE* file )
     954                 :            : {
     955                 :            :     unsigned char buffer[4];
     956 [ +  - ][ +  - ]:          3 :     return !fseek( file, 0, SEEK_SET ) && fread( buffer, 4, 1, file ) && !memcmp( buffer, "CUBE", 4 );
         [ +  - ][ -  + ]
     957                 :            : }
     958                 :            : 
     959                 :          3 : int ReadCGM::is_step_file( FILE* file )
     960                 :            : {
     961                 :            :     unsigned char buffer[9];
     962 [ +  - ][ +  - ]:          3 :     return !fseek( file, 0, SEEK_SET ) && fread( buffer, 9, 1, file ) && !memcmp( buffer, "ISO-10303", 9 );
         [ +  - ][ -  + ]
     963                 :            : }
     964                 :            : 
     965                 :          3 : int ReadCGM::is_iges_file( FILE* file )
     966                 :            : {
     967                 :            :     unsigned char buffer[10];
     968 [ +  - ][ +  - ]:          3 :     return !fseek( file, 72, SEEK_SET ) && fread( buffer, 10, 1, file ) && !memcmp( buffer, "S      1", 8 );
         [ +  - ][ -  + ]
     969                 :            : }
     970                 :            : 
     971                 :          3 : int ReadCGM::is_occ_brep_file( FILE* file )
     972                 :            : {
     973                 :            :     unsigned char buffer[6];
     974 [ +  - ][ +  - ]:          3 :     return !fseek( file, 0, SEEK_SET ) && fread( buffer, 6, 1, file ) && !memcmp( buffer, "DBRep_", 6 );
         [ +  - ][ -  + ]
     975                 :            : }
     976                 :          3 : int ReadCGM::is_facet_file( FILE* file )
     977                 :            : {
     978                 :            :     unsigned char buffer[10];
     979 [ +  - ][ +  - ]:          3 :     return !fseek( file, 0, SEEK_SET ) && fread( buffer, 10, 1, file ) && !memcmp( buffer, "MESH_BASED", 10 );
         [ +  - ][ -  + ]
     980                 :            : }
     981                 :            : 
     982                 :          0 : void ReadCGM::tokenize( const std::string& str, std::vector< std::string >& tokens, const char* delimiters )
     983                 :            : {
     984                 :          0 :     std::string::size_type last = str.find_first_not_of( delimiters, 0 );
     985                 :          0 :     std::string::size_type pos  = str.find_first_of( delimiters, last );
     986 [ #  # ][ #  # ]:          0 :     while( std::string::npos != pos && std::string::npos != last )
     987                 :            :     {
     988         [ #  # ]:          0 :         tokens.push_back( str.substr( last, pos - last ) );
     989                 :          0 :         last = str.find_first_not_of( delimiters, pos );
     990                 :          0 :         pos  = str.find_first_of( delimiters, last );
     991         [ #  # ]:          0 :         if( std::string::npos == pos ) pos = str.size();
     992                 :            :     }
     993                 :          0 : }
     994                 :            : 
     995 [ +  - ][ +  - ]:        228 : }  // namespace moab

Generated by: LCOV version 1.11