1
// Aqsis main executable
12
#include "logging_streambufs.h"
15
#ifdef AQSIS_SYSTEM_WIN32
16
extern "C" __declspec(dllimport) void report_refcounts();
18
extern "C" void report_refcounts();
19
#endif // AQSIS_SYSTEM_WIN32
22
#if defined(AQSIS_SYSTEM_WIN32)
26
#if defined(AQSIS_SYSTEM_WIN32) || defined(AQSIS_SYSTEM_MACOSX)
30
#if defined(AQSIS_SYSTEM_WIN32) && defined(_DEBUG)
34
// Include libargparse
47
void RenderFile( FILE* file, std::string& name );
49
void ReleaseOptions();
52
// Set verbose stats if in debug mode
56
int g_endofframe = -1;
59
// Declare vars used by argparse
60
bool g_nostandard = 0;
64
bool g_environment = 0;
71
// Define strings used by argparse
72
ArgParse::apstring g_config = "";
73
ArgParse::apstring g_shaders = "";
74
ArgParse::apstring g_archives = "";
75
ArgParse::apstring g_textures = "";
76
ArgParse::apstring g_displays = "";
77
ArgParse::apstring g_base_path = "";
78
ArgParse::apstring g_dso_libs = "";
79
ArgParse::apstring g_procedurals = "";
80
ArgParse::apstring g_type = "";
81
ArgParse::apstring g_addtype = "";
82
ArgParse::apstring g_mode = "rgba";
83
ArgParse::apstring g_strprogress = "Frame (%f) %p%% complete [ %s secs / %S left ]";
85
#ifdef AQSIS_SYSTEM_POSIX
87
#endif // AQSIS_SYSTEM_POSIX
89
/** Function to print out the version to a std::ostream
91
void version( std::ostream& Stream )
93
#if defined(AQSIS_SYSTEM_WIN32) || defined(AQSIS_SYSTEM_MACOSX)
94
Stream << "aqsis version " << VERSION_STR << std::endl;
96
Stream << "aqsis version " << VERSION << std::endl;
101
/** Function to print the progress of the render.
102
Used as the callback function to a RiProgressHandler call.
104
RtVoid PrintProgress( RtFloat percent, RtInt FrameNo )
106
if ( ( g_progress == 0 ) && ( g_Progress == 0 ) )
109
// If g_Progress is set, 100% have to be reported. In all other cases the 100% are not displayed
110
if ( percent >= 100 && !g_Progress )
112
std::cout << " \r" << std::flush;
116
static long tick = 0;
124
// Calculate the various values for putting in the string.
125
#ifdef AQSIS_SYSTEM_MACOSX
126
TqFloat total_secs = ( RtFloat ) 100.0f * ( ( RtFloat ) ( now - tick ) / ( float ) CLOCKS_PER_SEC );
127
#elif AQSIS_SYSTEM_POSIX
128
TqFloat total_secs = ( RtFloat ) 1000000.0f * ( ( RtFloat ) ( now - tick ) / ( float ) CLOCKS_PER_SEC );
130
TqFloat total_secs = ( RtFloat ) 1000.0f * ( ( RtFloat ) ( now - tick ) / ( float ) CLOCKS_PER_SEC );
132
TqFloat total_mins = total_secs / 60.0f;
133
TqFloat total_hrs = total_mins / 60.0f;
134
TqFloat sub_secs = total_secs - ( ( TqInt ) total_mins * 60.0f );
135
TqFloat sub_mins = total_mins - ( ( TqInt ) total_hrs * 60.0f );
137
TqFloat total_secsleft = ( ( ( RtFloat ) 100 / percent ) * total_secs ) - total_secs;
138
TqFloat total_minsleft = total_secsleft / 60.0f;
139
TqFloat total_hrsleft = total_minsleft / 60.0f;
140
TqFloat sub_secsleft = total_secsleft - ( ( TqInt ) total_minsleft * 60.0f );
141
TqFloat sub_minsleft = total_minsleft - ( ( TqInt ) total_hrsleft * 60.0f );
143
// Now print the line with substitution.
146
std::string strProgress;
148
if ( g_Progress ) // Override the outputformat
150
strProgress = "R90000%p%%";
151
percent = static_cast<int>( percent );
153
else // Use the default style
155
strProgress = g_strprogress;
158
std::ostrstream strOutput;
159
strOutput.setf( std::ios::fixed );
163
itag = strProgress.find( '%', ipos );
164
if ( itag == std::string::npos )
166
strOutput << strProgress.substr( ipos ).c_str();
172
strOutput << strProgress.substr( ipos, itag - ipos ).c_str();
174
switch ( strProgress[ itag + 1 ] )
177
strOutput << std::setw( 6 ) << std::setfill( ' ' ) << std::setprecision( 2 ) << percent;
181
strOutput << std::setprecision( 0 ) << ( TqInt ) total_secs;
185
strOutput << std::setprecision( 0 ) << ( TqInt ) total_secsleft;
189
strOutput << std::setprecision( 0 ) << ( TqInt ) total_mins;
193
strOutput << std::setprecision( 0 ) << ( TqInt ) total_minsleft;
197
strOutput << std::setprecision( 0 ) << ( TqInt ) total_hrs;
201
strOutput << std::setprecision( 0 ) << ( TqInt ) total_hrsleft;
205
strOutput << std::setprecision( 0 ) << ( TqInt ) total_hrs << ":" << ( TqInt ) sub_mins << ":" << ( TqInt ) sub_secs;
209
strOutput << std::setprecision( 0 ) << ( TqInt ) total_hrsleft << ":" << ( TqInt ) sub_minsleft << ":" << ( TqInt ) sub_secsleft;
213
strOutput << std::setprecision( 0 ) << ( TqInt ) FrameNo;
223
if ( ipos >= strProgress.size() )
226
// Pad to the end of the line.
227
while ( strOutput.pcount() < 79 )
230
std::cout << std::string( strOutput.str(), strOutput.pcount() ).c_str();
237
strOutput.freeze( false );
238
std:: cout << std::flush;
242
/** Function to setup specific options needed after world loading but before rendering.
243
Used as the callback function to a RiPreWorldFunction call.
245
#ifdef AQSIS_SYSTEM_BEOS
246
RtVoid PreWorld( ... )
253
char * type = "framebuffer", *mode = "rgb";
254
RiDisplay( "aqsis", type, mode, NULL );
256
else if ( g_type.compare( "" ) != 0 )
258
char type[ 256 ], mode[ 256 ];
259
strcpy( type, g_type.c_str() );
260
strcpy( mode, g_mode.c_str() );
261
RiDisplay( "aqsis", type, mode, NULL );
263
else if ( g_addtype.compare( "" ) != 0 )
265
char type[ 256 ], mode[ 256 ];
266
strcpy( type, g_addtype.c_str() );
267
strcpy( mode, g_mode.c_str() );
268
RiDisplay( "+aqsis", type, mode, NULL );
270
else if ( g_endofframe >= 0 )
272
RiOption( "statistics", "endofframe", &g_endofframe, RI_NULL );
278
int main( int argc, const char** argv )
280
#if defined(AQSIS_SYSTEM_WIN32) && defined(_DEBUG)
281
std::ostringstream __buffer;
283
_CrtMemState __initialState;
284
_CrtMemCheckpoint(&__initialState);
289
ap.usageHeader( ArgParse::apstring( "Usage: " ) + argv[ 0 ] + " [options] files(s) to render" );
290
ap.argFlag( "help", "\aprint this help and exit", &g_help );
291
ap.argFlag( "version", "\aprint version information and exit", &g_version );
292
ap.argFlag( "pause", "\await for a keypress on completion", &g_pause );
293
ap.argFlag( "progress", "\aprint progress information", &g_progress );
294
ap.argFlag( "Progress", "\aprogress message matching prman \n\a(not influenced by progressformat)", &g_Progress );
295
ap.argString( "progressformat", "\astring representing the format of the progress message", &g_strprogress );
296
ap.argInt( "endofframe", "=integer\aequivalent to \"endofframe\" option", &g_endofframe );
297
ap.argFlag( "nostandard", "\adisable declaration of standard RenderMan parameters", &g_nostandard );
298
ap.argFlag( "verbose", "\aoutput more information during rendering", &g_verbose );
299
ap.alias( "verbose", "v" );
300
ap.argFlag( "renderinfo", "\aPrint out infos about base rendering settings", &g_rinfo );
301
ap.argFlag( "environment", "\aoutput environment information", &g_environment );
302
ap.argString( "type", "=string\aspecify a display device type to use", &g_type );
303
ap.argString( "addtype", "=string\aspecify a display device type to add", &g_addtype );
304
ap.argString( "mode", "=string\aspecify a display device mode to use", &g_mode );
305
ap.argFlag( "fb", "\aequivalent to --type=\"framebuffer\" --mode=\"rgb\"", &g_fb );
306
ap.alias( "fb", "d" );
307
ap.argString( "config", "=string\aspecify a configuration file to load", &g_config );
308
ap.argString( "base", "=string\aspecify a default base path", &g_base_path );
309
ap.argString( "shaders", "=string\aspecify a default shaders searchpath", &g_shaders );
310
ap.argString( "archives", "=string\aspecify a default archives searchpath", &g_archives );
311
ap.argString( "textures", "=string\aspecify a default textures searchpath", &g_textures );
312
ap.argString( "displays", "=string\aspecify a default displays searchpath", &g_displays );
313
ap.argString( "dsolibs", "=string\aspecify default DSO libraries", &g_dso_libs );
314
ap.argString( "procedurals", "=string\aspecify default searchpath for procedurals", &g_procedurals );
315
#ifdef AQSIS_SYSTEM_POSIX
316
ap.argFlag( "syslog", "\alog messages to syslog", &g_syslog );
317
#endif // AQSIS_SYSTEM_POSIX
318
ap.allowUnrecognizedOptions();
320
//_crtBreakAlloc = 1305;
322
if ( argc > 1 && !ap.parse( argc - 1, argv + 1 ) )
324
std::cerr << ap.errmsg() << std::endl << ap.usagemsg();
330
std::cout << ap.usagemsg();
336
version( std::cout );
337
std::cout << "compiled " << __DATE__ << " " << __TIME__ << std::endl;
345
std::cout << "config: " << g_config.c_str() << std::endl;
346
std::cout << "base: " << g_base_path.c_str() << std::endl;
347
std::cout << "shaders: " << g_shaders.c_str() << std::endl;
348
std::cout << "archives: " << g_archives.c_str() << std::endl;
349
std::cout << "textures: " << g_textures.c_str() << std::endl;
350
std::cout << "displays: " << g_displays.c_str() << std::endl;
351
std::cout << "dsolibs: " << g_dso_libs.c_str() << std::endl;
352
std::cout << "procedurals: " << g_procedurals.c_str() << std::endl;
355
std::auto_ptr<std::streambuf> reset_level( new Aqsis::reset_level_buf(std::cerr) );
356
std::auto_ptr<std::streambuf> show_timestamps( new Aqsis::timestamp_buf(std::cerr) );
357
std::auto_ptr<std::streambuf> fold_duplicates( new Aqsis::fold_duplicates_buf(std::cerr) );
358
std::auto_ptr<std::streambuf> show_level( new Aqsis::show_level_buf(std::cerr) );
359
std::auto_ptr<std::streambuf> filter_level( new Aqsis::filter_by_level_buf(Aqsis::WARNING, std::cerr) );
360
#ifdef AQSIS_SYSTEM_POSIX
362
std::auto_ptr<std::streambuf> use_syslog( new Aqsis::syslog_buf(std::cerr) );
363
#endif // AQSIS_SYSTEM_POSIX
365
if ( ap.leftovers().size() == 0 ) // If no files specified, take input from stdin.
367
std::string name("stdin");
368
RenderFile( stdin, name );
372
for ( ArgParse::apstringvec::const_iterator e = ap.leftovers().begin(); e != ap.leftovers().end(); e++ )
374
FILE *file = fopen( e->c_str(), "rb" );
377
std::string name(*e);
378
RenderFile( file, name );
383
std::cout << "Warning: Cannot open file \"" << *e << "\"" << std::endl;
391
#if defined(AQSIS_SYSTEM_WIN32) && defined(_DEBUG)
392
//_CrtDumpMemoryLeaks();
393
_CrtMemDumpAllObjectsSince(&__initialState);
396
#if defined(AQSIS_SYSTEM_WIN32)
399
MEMORY_BASIC_INFORMATION mbi;
402
SYSTEM_INFO SystemInfo;
404
memset( &SystemInfo, 0, sizeof( SYSTEM_INFO ) );
406
&SystemInfo // system information
408
memset( &mbi, 0, sizeof( MEMORY_BASIC_INFORMATION ) );
409
while ( VirtualQuery( pvAddress, &mbi, sizeof( MEMORY_BASIC_INFORMATION ) ) == sizeof( MEMORY_BASIC_INFORMATION ) )
411
if ( mbi.State == MEM_COMMIT && mbi.Type == MEM_PRIVATE )
412
dwMemUsed += mbi.RegionSize;
413
pvAddress = ( ( BYTE* ) mbi.BaseAddress ) + mbi.RegionSize;
415
std::cout << "Peak Memory Used " << dwMemUsed << std::endl;
430
// If --base not specified, check for env.
431
if ( g_base_path.compare( "" ) == 0 )
432
g_base_path = Aqsis::CqFile::GetSystemSetting( "base" );
434
// If --config not specified try to locate the config file.
435
if ( g_config.compare( "" ) == 0 )
436
g_config = Aqsis::CqFile::GetSystemSetting( "config" );
438
// if --shaders is not specified, try and get a default shaders searchpath.
439
if ( g_shaders.compare( "" ) == 0 )
440
g_shaders = Aqsis::CqFile::GetSystemSetting( "shaders" );
442
// if --archives is not specified, try and get a default archives searchpath.
443
if ( g_archives.compare( "" ) == 0 )
444
g_archives = Aqsis::CqFile::GetSystemSetting( "archives" );
446
// if --textures is not specified, try and get a default textures searchpath.
447
if ( g_textures.compare( "" ) == 0 )
448
g_textures = Aqsis::CqFile::GetSystemSetting( "textures" );
450
// if --displays is not specified, try and get a default displays searchpath.
451
if ( g_displays.compare( "" ) == 0 )
452
g_displays = Aqsis::CqFile::GetSystemSetting( "displays" );
454
// if --displays is not specified, try and get a default dso libraries.
455
if ( g_dso_libs.compare( "" ) == 0 )
456
g_dso_libs = Aqsis::CqFile::GetSystemSetting( "dsolibs" );
458
// if --displays is not specified, try and get a default procedurals searchpath.
459
if ( g_procedurals.compare( "" ) == 0 )
460
g_procedurals = Aqsis::CqFile::GetSystemSetting( "procedurals" );
464
void ReleaseOptions()
477
void RenderFile( FILE* file, std::string& name )
479
librib::RendermanInterface * renderengine = librib2ri::CreateRIBEngine();
481
RiBegin( "CRIBBER" );
484
librib::StandardDeclarations( *renderengine );
488
RiOption( "statistics", "renderinfo", &g_rinfo, RI_NULL );
493
RiOption( "statistics", "verbose", &g_rinfo, RI_NULL );
496
const char* popt[ 1 ];
497
popt[ 0 ] = g_shaders.c_str();
498
RiOption( "searchpath", "shader", &popt, RI_NULL );
499
popt[ 0 ] = g_archives.c_str();
500
RiOption( "searchpath", "archive", &popt, RI_NULL );
501
popt[ 0 ] = g_textures.c_str();
502
RiOption( "searchpath", "texture", &popt, RI_NULL );
503
popt[ 0 ] = g_displays.c_str();
504
RiOption( "searchpath", "display", &popt, RI_NULL );
505
popt[ 0 ] = g_dso_libs.c_str();
506
RiOption( "searchpath", "dsolibs", &popt, RI_NULL );
507
popt[ 0 ] = g_procedurals.c_str();
508
RiOption( "searchpath", "procedural", &popt, RI_NULL );
510
RiProgressHandler( &PrintProgress );
511
RiPreWorldFunction( &PreWorld );
513
if ( g_config.compare( "" ) )
515
FILE * cfgfile = fopen( g_config.c_str(), "rb" );
516
if ( cfgfile != NULL )
518
librib::Parse( cfgfile, "config", *renderengine, std::cerr, NULL );
521
else if ( g_environment )
523
#ifdef AQSIS_SYSTEM_WIN32
524
std::cout << "Warning: Config file not found in" << std::endl <<
525
"%AQSIS_CONFIG%" << std::endl <<
526
"%AQSIS_BASE_PATH%/.aqsisrc" << std::endl <<
527
"%HOME%/.aqsisrc" << std::endl <<
528
".aqsisrc" << std::endl;
530
std::cout << "Warning: Config file not found in" << std::endl <<
531
"$AQSIS_CONFIG" << std::endl <<
532
"$AQSIS_BASE_PATH/.aqsisrc" << std::endl <<
533
"$HOME/.aqsisrc" << std::endl <<
534
"/etc/.aqsisrc" << std::endl;
539
librib::Parse( file, name, *renderengine, std::cerr, NULL );
544
librib::CleanupDeclarations( *renderengine );
546
librib2ri::DestroyRIBEngine( renderengine );