16 #pragma warning( disable : 4786 )
19 #include "CGMConfig.h"
20 #include "GeometryQueryTool.hpp"
21 #include "ModelQueryEngine.hpp"
22 #include "RefEntityName.hpp"
25 #include "RefGroup.hpp"
26 #include "RefVolume.hpp"
27 #include "RefFace.hpp"
28 #include "RefEdge.hpp"
29 #include "RefVertex.hpp"
31 #include "SenseEntity.hpp"
32 #include "Surface.hpp"
35 #include "InitCGMA.hpp"
45 #include "CubitCompat.hpp"
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"
70 : geom_tag( 0 ), id_tag( 0 ), name_tag( 0 ), category_tag( 0 ), faceting_tol_tag( 0 ), geometry_resabs_tag( 0 )
72 assert( NULL != impl );
85 int negone = -1, zero = 0 ;
119 std::vector< int >& ,
128 double& faceting_tol,
131 bool& verbose_warnings,
132 bool& fatal_on_curves )
138 double DEFAULT_FACET_TOL = 0.001;
139 double DEFAULT_LEN_TOL = 0.0;
146 faceting_tol = DEFAULT_FACET_TOL;
154 const char* name =
"CGM_ATTRIBS";
155 const char* value =
"no";
165 const char geom_categories[][
CATEGORY_TAG_SIZE] = {
"Vertex\0",
"Curve\0",
"Surface\0",
"Volume\0",
"Group\0" };
166 const char*
const names[] = {
"Vertex",
"Curve",
"Surface",
"Volume" };
167 DLIList< RefEntity* > entlist;
172 GeometryQueryTool::instance()->ref_entity_list( names[
dim], entlist,
true );
175 for(
int i = entlist.size(); i--; )
177 RefEntity* ent = entlist.get_and_step();
184 entmap[
dim][ent] = handle;
205 DLIList< RefEntity* > entitylist;
206 std::map< RefEntity*, EntityHandle >::iterator ci;
210 for( ci = entitymap[
dim].begin(); ci != entitymap[
dim].end(); ++ci )
212 entitylist.clean_out();
213 ci->first->get_child_ref_entities( entitylist );
216 for(
int i = entitylist.size(); i--; )
218 RefEntity* ent = entitylist.get_and_step();
230 std::map< RefEntity*, EntityHandle >& volume_map )
233 std::map< RefEntity*, EntityHandle >::iterator ci;
235 for( ci = surface_map.begin(); ci != surface_map.end(); ++ci )
237 RefFace*
face = (RefFace*)( ci->first );
238 BasicTopologyEntity *forward = 0, *reverse = 0;
239 for( SenseEntity* cf =
face->get_first_sense_entity_ptr(); cf; cf = cf->next_on_bte() )
241 BasicTopologyEntity* vol = cf->get_parent_basic_topology_entity_ptr();
243 if( cf->get_sense() == CUBIT_UNKNOWN || cf->get_sense() !=
face->get_surface_ptr()->bridge_sense() )
248 std::cout <<
"Surface " <<
face->id() <<
" has reverse sense "
249 <<
"with multiple volume " << reverse->id() <<
" and "
250 <<
"volume " << vol->id() << std::endl;
255 if( cf->get_sense() == CUBIT_UNKNOWN || cf->get_sense() ==
face->get_surface_ptr()->bridge_sense() )
260 std::cout <<
"Surface " <<
face->id() <<
" has forward sense "
261 <<
"with multiple volume " << forward->id() <<
" and "
262 <<
"volume " << vol->id() << std::endl;
285 std::map< RefEntity*, EntityHandle >& surface_map )
288 std::vector< EntityHandle > ents;
289 std::vector< int > senses;
290 std::map< RefEntity*, EntityHandle >::iterator ci;
291 for( ci = curve_map.begin(); ci != curve_map.end(); ++ci )
293 RefEdge*
edge = (RefEdge*)( ci->first );
296 for( SenseEntity* ce =
edge->get_first_sense_entity_ptr(); ce; ce = ce->next_on_bte() )
298 BasicTopologyEntity* fac = ce->get_parent_basic_topology_entity_ptr();
300 if( ce->get_sense() == CUBIT_UNKNOWN || ce->get_sense() !=
edge->get_curve_ptr()->bridge_sense() )
302 ents.push_back(
face );
305 if( ce->get_sense() == CUBIT_UNKNOWN || ce->get_sense() ==
edge->get_curve_ptr()->bridge_sense() )
307 ents.push_back(
face );
308 senses.push_back( SENSE_FORWARD );
336 const char geom_categories[][
CATEGORY_TAG_SIZE] = {
"Vertex\0",
"Curve\0",
"Surface\0",
"Volume\0",
"Group\0" };
337 DLIList< RefEntity* > entitylist;
339 std::vector< Tag > extra_name_tags;
340 #if CGM_MAJOR_VERSION > 13
341 DLIList< CubitString > name_list;
343 DLIList< CubitString* > name_list;
345 entitylist.clean_out();
347 GeometryQueryTool::instance()->ref_entity_list(
"group", entitylist );
350 for(
int i = entitylist.size(); i--; )
353 RefEntity* grp = entitylist.get_and_step();
354 name_list.clean_out();
356 #if CGM_MAJOR_VERSION > 13
357 RefEntityName::instance()->get_refentity_name( grp, name_list );
361 RefEntityName::instance()->get_refentity_name( grp, name_list,
true );
363 if( name_list.size() == 0 )
continue;
366 #if CGM_MAJOR_VERSION > 13
367 CubitString name1 = name_list.get();
369 CubitString name1 = *name_list.get();
380 std::cout <<
"WARNING: group name '" << name1.c_str() <<
"' truncated to '" << namebuf <<
"'" << std::endl;
391 if( name_list.size() > 1 )
393 for(
int j = extra_name_tags.size(); j < name_list.size(); ++j )
400 extra_name_tags.push_back(
t );
403 for(
int j = 0; j < name_list.size(); ++j )
405 #if CGM_MAJOR_VERSION > 13
406 name1 = name_list.get_and_step();
408 name1 = *name_list.get_and_step();
413 std::cout <<
"WARNING: group name '" << name1.c_str() <<
"' truncated to '" << namebuf <<
"'"
429 DLIList< RefEntity* > entlist;
430 std::map< RefEntity*, EntityHandle >::iterator ci;
433 for( ci = entitymap[4].begin(); ci != entitymap[4].end(); ++ci )
435 RefGroup* grp = (RefGroup*)( ci->first );
437 grp->get_child_ref_entities( entlist );
440 while( entlist.size() )
442 RefEntity* ent = entlist.pop();
443 int dim = ent->dimension();
448 if( entitymap[4].find( ent ) != entitymap[4].end() )
451 entities.insert( entitymap[4][ent] );
453 else if( ( body =
dynamic_cast< Body*
>( ent ) ) != NULL )
457 DLIList< RefVolume* > vols;
458 body->ref_volumes( vols );
459 for(
int vi = vols.size(); vi--; )
461 RefVolume* vol = vols.get_and_step();
462 if( entitymap[3].find( vol ) != entitymap[3].end() )
464 entities.insert( entitymap[3][vol] );
468 std::cerr <<
"Warning: CGM Body has orphan RefVolume" << std::endl;
475 std::cerr <<
"Warning: A dim<0 entity is being ignored by ReadCGM." << std::endl;
480 if( entitymap[
dim].find( ent ) != entitymap[
dim].end() )
entities.insert( entitymap[
dim][ent] );
498 CGMApp::instance()->attrib_manager()->set_all_auto_read_flags( act_attributes );
499 CGMApp::instance()->attrib_manager()->set_all_auto_actuate_flags( act_attributes );
504 CGMApp::instance()->attrib_manager()->silent_flag(
true );
511 std::map< RefEntity*, EntityHandle >::iterator ci;
512 for( ci = vertex_map.begin(); ci != vertex_map.end(); ++ci )
514 CubitVector pos =
dynamic_cast< RefVertex*
>( ci->first )->coordinates();
515 double coords[3] = { pos.x(), pos.y(), pos.z() };
533 std::map< RefEntity*, EntityHandle >& vertex_map,
534 #
if CGM_MAJOR_VERSION > 12
541 bool fatal_on_curves )
548 int curve_warnings = 0;
551 std::map< RefEntity*, EntityHandle >::iterator ci;
555 for( ci = curve_map.begin(); ci != curve_map.end(); ++ci )
558 RefEdge*
edge =
dynamic_cast< RefEdge*
>( ci->first );
560 Curve* curve =
edge->get_curve_ptr();
564 #if CGM_MAJOR_VERSION > 12
565 s =
edge->get_graphics( data, norm_tol, faceting_tol );
567 s =
edge->get_graphics( data, faceting_tol );
570 if( s != CUBIT_SUCCESS )
573 if( fatal_on_curves )
575 std::cout <<
"Failed to facet the curve " <<
edge->id() << std::endl;
587 std::vector< CubitVector > points;
588 for(
int i = 0; i < data.pointListCount; ++i )
590 points.push_back( CubitVector( data.point_list()[i].x, data.point_list()[i].y, data.point_list()[i].z ) );
593 if( curve->bridge_sense() == CUBIT_REVERSED ) std::reverse( points.begin(), points.end() );
596 RefVertex *start_vtx, *end_vtx;
597 start_vtx =
edge->start_vertex();
598 end_vtx =
edge->end_vertex();
601 if( points.size() < 2 )
605 std::cerr <<
"Warning: No facetting for curve " <<
edge->id() << std::endl;
616 if( closed != ( start_vtx == end_vtx ) )
618 std::cerr <<
"Warning: topology and geometry inconsistant for possibly closed curve " <<
edge->id()
628 if( curve_warnings >= 0 || verbose_warn )
630 std::cerr <<
"Warning: vertices not at ends of curve " <<
edge->id() << std::endl;
631 if( curve_warnings == 0 && !verbose_warn )
633 std::cerr <<
" further instances of this warning will be suppressed..." << std::endl;
638 std::vector< EntityHandle > verts, edges;
639 verts.push_back( vertex_map[start_vtx] );
640 for(
size_t i = 1; i < points.size() - 1; ++i )
642 double coords[] = { points[i].x(), points[i].y(), points[i].z() };
647 verts.push_back( h );
649 verts.push_back( vertex_map[end_vtx] );
652 for(
size_t i = 0; i < verts.size() - 1; ++i )
657 edges.push_back( h );
661 if( verts.front() == verts.back() ) verts.pop_back();
669 if( !verbose_warn && curve_warnings < 0 )
671 std::cerr <<
"Suppressed " << -curve_warnings <<
" 'vertices not at ends of curve' warnings." << std::endl;
672 std::cerr <<
"To see all warnings, use reader param VERBOSE_CGM_WARNINGS." << std::endl;
679 std::map< RefEntity*, EntityHandle >& vertex_map,
685 std::map< RefEntity*, EntityHandle >::iterator ci;
687 #if( ( CGM_MAJOR_VERSION == 14 && CGM_MINOR_VERSION > 2 ) || CGM_MAJOR_VERSION >= 15 )
688 DLIList< TopologyEntity* > me_list;
690 DLIList< ModelEntity* > me_list;
695 for( ci = surface_map.begin(); ci != surface_map.end(); ++ci )
697 RefFace*
face =
dynamic_cast< RefFace*
>( ci->first );
700 s =
face->get_graphics( data, norm_tol, facet_tol, length_tol );
702 if( CUBIT_SUCCESS != s )
return MB_FAILURE;
705 std::vector< EntityHandle > verts( data.pointListCount, 0 );
709 ModelQueryEngine::instance()->query_model( *
face, DagType::ref_vertex_type(), me_list );
713 for(
int i = me_list.size(); i--; )
716 RefVertex* vtx =
dynamic_cast< RefVertex*
>( me_list.get_and_step() );
717 CubitVector pos = vtx->coordinates();
719 for(
int j = 0; j < data.pointListCount; ++j )
722 CubitVector vpos( data.point_list()[j].x, data.point_list()[j].y, data.point_list()[j].z );
727 if( verts[j] ) std::cerr <<
"Warning: Coincident vertices in surface " <<
face->id() << std::endl;
729 verts[j] = vertex_map[vtx];
736 for(
int i = 0; i < data.pointListCount; ++i )
740 double coords[] = { data.point_list()[i].x, data.point_list()[i].y, data.point_list()[i].z };
748 if( data.fListCount == 0 )
756 std::vector< EntityHandle > corners;
757 for(
int i = 0; i < data.fListCount; i += data.facet_list()[i] + 1 )
760 int* facet = data.facet_list() + i;
761 corners.resize( *facet );
762 for(
int j = 1; j <= *facet; ++j )
764 if( facet[j] >= (
int)verts.size() )
766 std::cerr <<
"ERROR: Invalid facet data for surface " <<
face->id() << std::endl;
769 corners[j - 1] = verts[facet[j]];
776 std::cerr <<
"Warning: non-triangle facet in surface " <<
face->id() << std::endl;
777 std::cerr <<
" entity has " << *facet <<
" edges" << std::endl;
823 bool verbose_warnings =
false;
824 bool fatal_on_curves =
false;
826 rval =
set_options( opts, norm_tol, faceting_tol, len_tol, act_att, verbose_warnings, fatal_on_curves );
839 InitCGMA::initialize_cgma();
847 const char* file_type = 0;
849 if( !file_type || !strcmp( file_type,
"CUBIT" ) )
return MB_FAILURE;
851 s = CubitCompat_import_solid_model( cgm_file_name, file_type );
852 if( CUBIT_SUCCESS != s )
854 MB_SET_ERR( MB_FAILURE, cgm_file_name <<
": Failed to read file of type \"" << file_type <<
"\"" );
858 std::map< RefEntity*, EntityHandle > entmap[5];
888 rval =
create_curve_facets( entmap[1], entmap[0], norm_tol, faceting_tol, verbose_warnings, fatal_on_curves );
915 std::cout <<
"***** Faceting Summary Information *****" << std::endl;
916 std::cout <<
"----- Curve Fail Information -----" << std::endl;
917 std::cout <<
"There were " <<
failed_curve_count <<
" curves that could not be faceted." << std::endl;
921 std::cout <<
"The curves were ";
925 if( ( i % 10 == 0 ) & ( i > 0 ) ) std::cout << std::endl;
928 std::cout << std::endl;
929 std::cout <<
"----- Facet Fail Information -----" << std::endl;
930 std::cout <<
"There were " <<
failed_surface_count <<
" surfaces that could not be faceted." << std::endl;
933 std::cout <<
"The surfaces were ";
937 if( ( i % 10 == 0 ) & ( i > 0 ) ) std::cout << std::endl;
940 std::cout << std::endl;
941 std::cout <<
"***** End of Faceting Summary Information *****" << std::endl;
948 const char* result = 0;
950 file = fopen( name,
"r" );
985 return !fseek( file, 0, SEEK_SET ) && fread(
buffer, 4, 1, file ) && !memcmp(
buffer,
"CUBE", 4 );
991 return !fseek( file, 0, SEEK_SET ) && fread(
buffer, 9, 1, file ) && !memcmp(
buffer,
"ISO-10303", 9 );
997 return !fseek( file, 72, SEEK_SET ) && fread(
buffer, 10, 1, file ) && !memcmp(
buffer,
"S 1", 8 );
1003 return !fseek( file, 0, SEEK_SET ) && fread(
buffer, 6, 1, file ) && !memcmp(
buffer,
"DBRep_", 6 );
1007 unsigned char buffer[10];
1008 return !fseek( file, 0, SEEK_SET ) && fread(
buffer, 10, 1, file ) && !memcmp(
buffer,
"MESH_BASED", 10 );
1011 void ReadCGM::tokenize(
const std::string& str, std::vector< std::string >& tokens,
const char* delimiters )
1013 std::string::size_type last = str.find_first_not_of( delimiters, 0 );
1014 std::string::size_type pos = str.find_first_of( delimiters, last );
1015 while( std::string::npos != pos && std::string::npos != last )
1017 tokens.push_back( str.substr( last, pos - last ) );
1018 last = str.find_first_not_of( delimiters, pos );
1019 pos = str.find_first_of( delimiters, last );
1020 if( std::string::npos == pos ) pos = str.size();