#!/usr/bin/perl
#
# what is the povray executable?
 $POVRAY=povray;

# This script will use rsh; you need to modify the host you
# want to use for rendering below and put its name in
# your .rhosts file located in your home directory.
# also you must change the include directory to point
# on the PovRay include directory on your system
#
# You will need some programs: povray
# but also combine and display (from the imageMagick suite).
#
# by default, only one (local) CPU is used, but
# you can split the job among several CPUs
# by providing a list of CPUs (machine names) to use
# as in the example below:
 @CPU_LIST = ("localhost","renderer1","renderer2","renderer3");

#
# multi CPU has an overhead (network, pasting image chunks,
# therefore, you can require multi-cpu only when the
# number of pixels to render is bigger than a certain size
# as set in the following variable

 $minPixelsToGoMultiCPU = 640*480;

#
#

# set this to the povray include files
$include = "/usr/local/lib/povray:/usr/local/lib/povray/include";

$PPOVDIR = $ENV{"SPDBV_POV_PATH"};

chdir("$PPOVDIR") || die "Cannot change working dir to $PPOVDIR";

# -------------------------------------
# -------- retrieve arguments ---------
# -------------------------------------
if ($#ARGV == -1) 
        { print "v1.0  usage: ppov [-a] -w width -h height filename\n"; exit; }

$antialias = "";
while ($#ARGV > 0)
{
        if ($ARGV[0] eq "-w") { shift(@ARGV); $w = @ARGV[0]; shift(@ARGV);next;}
        if ($ARGV[0] eq "-h") { shift(@ARGV); $h = @ARGV[0]; shift(@ARGV);next;}
        if ($ARGV[0] eq "-a") { $antialias  = "+A +R2"; shift(@ARGV);next;}
        if ($ARGV[0] eq "-s") { print "stereo not supported yet. You need to edit the .pov file"; shift(@ARGV);next;}
        if ($ARGV[0] eq "&") { shift(@ARGV);next;}
}
$in = @ARGV[0];
($outname) = split(/\./,$in);

$nbChunks = 1+$#CPU_LIST;
$nbPixels = $w*$h;
if (($nbChunks < 2) || ($nbPixels < $minPixelsToGoMultiCPU))
{ $nbChunks = 1 };

print "===================================================\n";
print "Rendering will be done in $nbChunks parts          \n";
print "===================================================\n";

system("\\rm *.OUT");
if ($nbChunks == 1)  # one CPU
{
	system("cd $PPOVDIR; $POVRAY +L$include +I$in +O$outname +W$w +H$h +FT -V $antialias +GS$outname.OUT +FT");
}
else # several CPUs
{
	# --------------------------------------------------------------------
	#             -------- segment for nbChunks cpus ---------
	# --------------------------------------------------------------------
	$part[0] == 0;
	$to[0] = $h/$nbChunks;
	$from[0] = 1;
	for ($i = 1; $i<$nbChunks; $i++)
	{
		$part[$i] = 0;
		$to[$i] = ($i+1)*$to[0];
		$from[$i] = $to[$i-1]+1;
	}
	# --------------------------------------------
	# -----------  launch ray-trace --------------
	# --------------------------------------------
	for ($i = 0; $i<$nbChunks; $i++)
	{
		print("\nEXECUTING: rsh $CPU_LIST[$i] -n \"cd $PPOVDIR; $POVRAY +L$include +I$in +O$outname$i.tga +W$w +H$h +FT +S$from[$i] +E$to[$i] -V $antialias +GSPART$i.OUT +FT \"&\n\n");
		system("rsh $CPU_LIST[$i] -n \"cd $PPOVDIR; $POVRAY +L$include +I$in +O$outname$i.tga +W$w +H$h +FT +S$from[$i] +E$to[$i] -V $antialias +GSPART$i.OUT +FT \"&");
		$from[$i]--;
	}
	# --------------------------------------------------------------------
	# -----  wait for everybody to finish and assemble chunks ------------
	# --------------------------------------------------------------------
	while ($part[0] == 0)
	{
		open (TEXT,"PART0.OUT");
		while(<TEXT>)
		{
			if (substr($_,0,4) eq "Time")
				{ $part[0] = 1; print " ******        part 0 done     *******\n"; last;}
		}
		close TEXT;
		if ($part[0] == 0) {sleep  3;} else {last;}
	}
	$i=0;
	system("\\mv $outname$i.tga mnt0.tga");
	for ($i = 1; $i<$nbChunks; $i++)
	{
		while ($part[$i] == 0)
		{
			open (TEXT,"PART$i.OUT");
			while(<TEXT>)
			{
				if (substr($_,0,4) eq "Time")  
					{ $part[$i] = 1;}
			}
			close TEXT;
			if ($part[$i] == 0) {sleep  5;} else {last;}
		}
		$j = $i-1;
	 	print " ****** adding part $i to image *******\n";
		system("combine -geometry +0+$from[$i] mnt$j.tga $outname$i.tga mnt$i.tga");
	}
	$nbChunks--;
#	system("\\rm $outname*.tga");
	system("\\mv mnt$nbChunks.tga $outname.tga");
#	system("\\rm mnt*.tga");
}

#system("\\rm *.OUT");
system("display $outname.tga &");
