33 #ifndef __INCLUDE_MIST_STL__
34 #define __INCLUDE_MIST_STL__
37 #ifndef __INCLUDE_MIST_H__
42 #ifndef __INCLUDE_MIST_FACET__
56 namespace __stl_controller__
79 typedef facet_list< T > facet_list_type;
80 typedef typename facet_list_type::facet_type facet_type;
81 typedef typename facet_type::vector_type vector_type;
82 typedef typename facet_type::size_type size_type;
84 static const unsigned char *get_line(
const unsigned char *s,
const unsigned char *e, std::string &line )
91 if( s + 1 != e && s[ 1 ] ==
'\n' )
101 else if( s[ 0 ] ==
'\n' )
109 return( s > e ? e : s );
112 static const unsigned char *get_value(
const unsigned char *s,
const unsigned char *e, std::string &line,
bool &flag )
118 if( flag && s[ 0 ] ==
'#' )
125 if( s + 1 != e && s[ 1 ] ==
'\n' )
135 else if( s[ 0 ] ==
'\n' )
143 else if( s[ 0 ] ==
'\r' )
145 if( s + 1 != e && s[ 1 ] ==
'\n' )
155 else if( s[ 0 ] ==
'\n' )
160 else if( s[ 0 ] ==
' ' || s[ 0 ] ==
'\t' )
176 if( s + 1 != e && s[ 1 ] ==
'\n' )
187 else if( s[ 0 ] ==
'\n' )
193 else if( s[ 0 ] ==
' ' || s[ 0 ] ==
'\t' )
201 return( s > e ? e : s );
204 static size_type split_string(
const std::string &line,
const char ch, std::vector< std::string > &elements )
206 std::string str =
"";
209 while( i < line.size( ) )
211 for( ; i < line.size( ) && line[ i ] == ch ; i++ );
214 for( ; i < line.size( ) && line[ i ] != ch ; i++ )
221 elements.push_back( str );
224 return( elements.size( ) );
227 static std::string to_lower( std::string line )
229 for(
size_t i = 0 ; i < line.size( ) ; i++ )
231 if(
'A' <= line[ i ] && line[ i ] <=
'Z' )
233 line[ i ] +=
'a' -
'A';
239 static bool convert_from_stl_ascii_data( facet_list_type &facets,
const unsigned char *buff, size_type len )
241 const unsigned char *p = buff;
242 const unsigned char *e = buff + len;
243 std::string line =
"";
244 std::vector< std::string > elements;
253 p = get_value( p, e, line, eol );
254 line = to_lower( line );
259 if( line ==
"solid" )
264 p = get_line( p, e, facets.name );
270 std::cerr <<
"File does not start with 'solid'" << std::endl;
276 if( line ==
"endsolid" )
281 else if( line ==
"facet" )
285 facet.normal = vector_type( 0, 0, 1 );
286 facet.p1 = facet.p2 = facet.p3 = vector_type( );
290 p = get_line( p, e, line );
292 std::vector< std::string > elements;
293 split_string( line,
' ', elements );
295 if( elements.size( ) == 4 )
297 if( to_lower( elements[ 0 ] ) ==
"normal" )
299 facet.normal.x = atof( elements[ 1 ].c_str( ) );
300 facet.normal.y = atof( elements[ 2 ].c_str( ) );
301 facet.normal.z = atof( elements[ 3 ].c_str( ) );
305 std::cerr <<
"'facet' does not have 'normal'" << std::endl;
310 std::cerr <<
"'facet' does not have 'normal'" << std::endl;
315 std::cerr <<
"'facet' does not have 'normal'" << std::endl;
321 std::cerr <<
"Line does not start with 'facet'" << std::endl;
327 if( line ==
"endfacet" )
334 if( facet.normal.inner( ( facet.p2 - facet.p1 ).outer( facet.p3 - facet.p1 ) ) < 0 )
336 vector_type tmp = facet.p2;
341 facets.push_back( facet );
345 std::cerr <<
"Facet does not have enough vertices" << std::endl;
349 else if( line ==
"outer" )
354 p = get_value( p, e, line, eol );
355 line = to_lower( line );
359 std::cerr <<
"Line does not start with 'outer loop'" << std::endl;
365 std::cerr <<
"Line does not start with 'outer loop'" << std::endl;
371 if( line ==
"endloop" )
375 else if( line ==
"vertex" )
379 p = get_line( p, e, line );
381 std::vector< std::string > elements;
382 split_string( line,
' ', elements );
384 if( elements.size( ) == 3 )
389 facet.p1.x = atof( elements[ 0 ].c_str( ) );
390 facet.p1.y = atof( elements[ 1 ].c_str( ) );
391 facet.p1.z = atof( elements[ 2 ].c_str( ) );
395 facet.p2.x = atof( elements[ 0 ].c_str( ) );
396 facet.p2.y = atof( elements[ 1 ].c_str( ) );
397 facet.p2.z = atof( elements[ 2 ].c_str( ) );
401 facet.p3.x = atof( elements[ 0 ].c_str( ) );
402 facet.p3.y = atof( elements[ 1 ].c_str( ) );
403 facet.p3.z = atof( elements[ 2 ].c_str( ) );
414 std::cerr <<
"'facet' does not have 'vertex'" << std::endl;
419 std::cerr <<
"'facet' does not have 'vertex'" << std::endl;
426 std::cerr <<
"Line does not start with 'vertex'" << std::endl;
432 std::cerr <<
"Unknown error occured" << std::endl;
439 p = get_line( p, e, line );
446 static bool convert_from_stl_binary_data( facet_list_type &facets,
const unsigned char *buff, size_type len )
448 const unsigned char *p = buff;
449 const unsigned char *e = buff + len;
456 size_type num_facets = ( (
unsigned int * )( buff + 80 ) )[ 0 ];
458 if( len < 80 + 4 + num_facets * _facet_::bytes )
463 facets.name = std::string( ( std::string::value_type * )buff, 80 );
465 for( size_type i = 0 ; i < num_facets ; i++ )
467 _facet_ *F = ( _facet_ * )( buff + 80 + 4 + _facet_::bytes * i );
468 facet_type f( vector_type( F->nX, F->nY, F->nZ ), vector_type( F->p1X, F->p1Y, F->p1Z ), vector_type( F->p2X, F->p2Y, F->p2Z ), vector_type( F->p3X, F->p3Y, F->p3Z ) );
470 if( f.normal.length( ) == 0 )
472 f.normal = ( ( f.p2 - f.p1 ).outer( f.p3 - f.p1 ) ).unit( );
474 else if( f.normal.inner( ( f.p2 - f.p1 ).outer( f.p3 - f.p1 ) ) < 0 )
476 vector_type tmp = f.p2;
481 facets.push_back( f );
487 static bool read( facet_list_type &facets,
const std::string &filename )
494 if( ( fp = fopen( filename.c_str( ),
"rb" ) ) == NULL )
return(
false );
496 fseek( fp, 0, SEEK_END );
497 filesize = ftell( fp );
498 fseek( fp, 0, SEEK_SET );
501 unsigned char *buff =
new unsigned char[ filesize + 1 ];
502 unsigned char *pointer = buff;
503 size_type read_size = 0;
504 while( feof( fp ) == 0 )
506 read_size = fread( pointer,
sizeof(
unsigned char ), 1024, fp );
507 if( read_size < 1024 )
511 pointer += read_size;
519 std::string sss = to_lower( std::string( (
char * )buff, 5 ) );
522 convert_from_stl_ascii_data( facets, buff, filesize );
526 convert_from_stl_binary_data( facets, buff, filesize );
535 static bool write(
const facet_list_type &facets,
const std::string &filename,
bool use_ascii_format )
537 if( facets.empty( ) )
539 std::cerr <<
"There is no facet!" << std::endl;
543 if( use_ascii_format )
546 if( ( fp = fopen( filename.c_str( ),
"wt" ) ) == NULL )
551 fprintf( fp,
"solid %s\n", facets.name.c_str( ) );
553 for( size_type i = 0 ; i < facets.size( ) ; i++ )
555 const facet_type &f = facets[ i ];
556 fprintf( fp,
"\tfacet normal %f %f %f\n", f.normal.x, f.normal.y, f.normal.z );
557 fprintf( fp,
"\t\touter loop\n" );
559 if( f.normal.inner( ( f.p2 - f.p1 ).outer( f.p3 - f.p1 ) ) >= 0 )
561 fprintf( fp,
"\t\t\tvertex %f %f %f\n", f.p1.x, f.p1.y, f.p1.z );
562 fprintf( fp,
"\t\t\tvertex %f %f %f\n", f.p2.x, f.p2.y, f.p2.z );
563 fprintf( fp,
"\t\t\tvertex %f %f %f\n", f.p3.x, f.p3.y, f.p3.z );
567 fprintf( fp,
"\t\t\tvertex %f %f %f\n", f.p1.x, f.p1.y, f.p1.z );
568 fprintf( fp,
"\t\t\tvertex %f %f %f\n", f.p3.x, f.p3.y, f.p3.z );
569 fprintf( fp,
"\t\t\tvertex %f %f %f\n", f.p2.x, f.p2.y, f.p2.z );
572 fprintf( fp,
"\t\tendloop\n" );
573 fprintf( fp,
"\tendfacet\n" );
576 fprintf( fp,
"endsolid %s\n", facets.name.c_str( ) );
583 if( ( fp = fopen( filename.c_str( ),
"wb" ) ) == NULL )
588 unsigned int num_facets =
static_cast< unsigned int >( facets.size( ) );
589 unsigned char dmy[ 80 ];
590 memset( dmy, 0,
sizeof(
unsigned char ) * 80 );
593 std::string tmp = std::string(
"Binary STL output by MIST: " ) + facets.name;
594 if( tmp.size( ) < 80 )
596 memcpy( dmy, tmp.c_str( ), tmp.size( ) );
600 memcpy( dmy, tmp.c_str( ), 80 );
605 fwrite( dmy,
sizeof(
unsigned char ), 80, fp );
606 fwrite( &num_facets,
sizeof(
unsigned int ), 1, fp );
609 for( size_type i = 0 ; i < facets.size( ) ; i++ )
611 const facet_type &f = facets[ i ];
613 F.nX = ( float )f.normal.x;
614 F.nY = (
float )f.normal.y;
615 F.nZ = ( float )f.normal.z;
616 F.p1X = (
float )f.p1.x;
617 F.p1Y = ( float )f.p1.y;
618 F.p1Z = (
float )f.p1.z;
619 F.p2X = ( float )f.p2.x;
620 F.p2Y = (
float )f.p2.y;
621 F.p2Z = ( float )f.p2.z;
622 F.p3X = (
float )f.p3.x;
623 F.p3Y = ( float )f.p3.y;
624 F.p3Z = (
float )f.p3.z;
627 fwrite( &F, 1, _facet_::bytes, fp );
681 return( __stl_controller__::stl_controller< T >::read( facets, filename ) );
715 return( __stl_controller__::stl_controller< T >::write( facets, filename, use_ascii_format ) );
731 #endif // __INCLUDE_MIST_STL__