--- ray/src/util/genBSDF.pl 2011/05/25 19:24:11 2.15 +++ ray/src/util/genBSDF.pl 2012/03/06 04:41:31 2.33 @@ -1,5 +1,5 @@ #!/usr/bin/perl -w -# RCSid $Id: genBSDF.pl,v 2.15 2011/05/25 19:24:11 greg Exp $ +# RCSid $Id: genBSDF.pl,v 2.33 2012/03/06 04:41:31 greg Exp $ # # Compute BSDF based on geometry and material description # @@ -8,20 +8,23 @@ use strict; use File::Temp qw/ :mktemp /; sub userror { - print STDERR "Usage: genBSDF [-n Nproc][-c Nsamp][-t{3|4} Nlog2][-r \"ropts\"][-dim xmin xmax ymin ymax zmin zmax][{+|-}f][{+|-}b][{+|-}mgf][{+|-}geom] [input ..]\n"; + print STDERR "Usage: genBSDF [-n Nproc][-c Nsamp][-t{3|4} Nlog2][-r \"ropts\"][-dim xmin xmax ymin ymax zmin zmax][{+|-}f][{+|-}b][{+|-}mgf][{+|-}geom units] [input ..]\n"; exit 1; } my $td = mkdtemp("/tmp/genBSDF.XXXXXX"); chomp $td; +my @savedARGV = @ARGV; my $tensortree = 0; my $ttlog2 = 4; -my $nsamp = 1000; +my $nsamp = 2000; my $rtargs = "-w -ab 5 -ad 700 -lw 3e-6"; my $mgfin = 0; my $geout = 1; my $nproc = 1; my $doforw = 0; my $doback = 1; +my $pctcull = 90; +my $gunit = "Meter"; my @dim; # Get options while ($#ARGV >= 0) { @@ -32,10 +35,19 @@ while ($#ARGV >= 0) { shift @ARGV; } elsif ("$ARGV[0]" =~ /^[-+]g/) { $geout = ("$ARGV[0]" =~ /^\+/); + $gunit = $ARGV[1]; + if ($gunit !~ /^(?i)(meter|foot|inch|centimeter|millimeter)$/) { + die "Illegal geometry unit '$gunit': must be meter, foot, inch, centimeter, or millimeter\n"; + } + shift @ARGV; } elsif ("$ARGV[0]" =~ /^[-+]f/) { $doforw = ("$ARGV[0]" =~ /^\+/); } elsif ("$ARGV[0]" =~ /^[-+]b/) { $doback = ("$ARGV[0]" =~ /^\+/); + } elsif ("$ARGV[0]" eq "-t") { + # Use value < 0 for rttree_reduce bypass + $pctcull = $ARGV[1]; + shift @ARGV; } elsif ("$ARGV[0]" =~ /^-t[34]$/) { $tensortree = substr($ARGV[0], 2, 1); $ttlog2 = $ARGV[1]; @@ -98,20 +110,23 @@ die "Could not compile scene\n" if ( $? ); print ' -System +'; +print "\n"; +print +'System Name Manufacturer '; -printf "\t\t%.3f\n", $dim[5] - $dim[4]; -printf "\t\t%.3f\n", $dim[1] - $dim[0]; -printf "\t\t%.3f\n", $dim[3] - $dim[2]; +printf "\t\t%.3f\n", $dim[5] - $dim[4]; +printf "\t\t%.3f\n", $dim[1] - $dim[0]; +printf "\t\t%.3f\n", $dim[3] - $dim[2]; print "\t\tIntegral\n"; # Output MGF description if requested if ( $geout ) { - print "\t\t\n"; + print "\t\t\n"; printf "xf -t %.6f %.6f 0\n", -($dim[0]+$dim[1])/2, -($dim[2]+$dim[3])/2; open(MGFSCN, "< $mgfscn"); while () { print $_; } @@ -139,27 +154,34 @@ print '; # Clean up temporary files and exit -if ( $persistfile ) { - open(PFI, "< $persistfile"); - while () { - s/^[^ ]* //; - kill('ALRM', $_); - last; +exec("rm -rf $td"); + +#-------------- End of main program segment --------------# + +#++++++++++++++ Kill persistent rtrace +++++++++++++++++++# +sub persist_end { + if ( $persistfile && open(PFI, "< $persistfile") ) { + while () { + s/^[^ ]* //; + kill('ALRM', $_); + last; + } + close PFI; } - close PFI; } -system "rm -rf $td"; -exit 0; -#-------------- End of main program segment --------------# #++++++++++++++ Tensor tree BSDF generation ++++++++++++++# sub do_tree_bsdf { # Get sampling rate and subdivide task my $ns2 = $ns; $ns2 /= 2 if ( $tensortree == 3 ); -@pdiv = (0, int($ns2/$nproc)); -my $nrem = $ns2 % $nproc; -for (my $i = 1; $i < $nproc; $i++) { +my $nsplice = $nproc; +$nsplice *= 10 if ($nproc > 1); +$nsplice = $ns2 if ($nsplice > $ns2); +$nsplice = 999 if ($nsplice > 999); +@pdiv = (0, int($ns2/$nsplice)); +my $nrem = $ns2 % $nsplice; +for (my $i = 1; $i < $nsplice; $i++) { my $nv = $pdiv[$i] + $pdiv[1]; ++$nv if ( $nrem-- > 0 ); push @pdiv, $nv; @@ -204,31 +226,48 @@ out_square_x = (out_square_a + 1)/2; out_square_y = (out_square_b + 1)/2; '; # Announce ourselves in XML output -print " \n"; -print " TensorTree$tensortree\n"; -print " \n"; +print "\t\n"; +print "\t\tTensorTree$tensortree\n"; +print "\t\n"; # Fork parallel rtcontrib processes to compute each side +my $npleft = $nproc; if ( $doback ) { - for (my $proc = 0; $proc < $nproc; $proc++) { - bg_tree_rtcontrib(0, $proc); + for (my $splice = 0; $splice < $nsplice; $splice++) { + if (! $npleft ) { + wait(); + die "rtcontrib process reported error" if ( $? ); + $npleft++; + } + bg_tree_rtcontrib(0, $splice); + $npleft--; } while (wait() >= 0) { die "rtcontrib process reported error" if ( $? ); + $npleft++; } + persist_end(); ttree_out(0); } if ( $doforw ) { - for (my $proc = 0; $proc < $nproc; $proc++) { - bg_tree_rtcontrib(1, $proc); + for (my $splice = 0; $splice < $nsplice; $splice++) { + if (! $npleft ) { + wait(); + die "rtcontrib process reported error" if ( $? ); + $npleft++; + } + bg_tree_rtcontrib(1, $splice); + $npleft--; } while (wait() >= 0) { die "rtcontrib process reported error" if ( $? ); + $npleft++; } + persist_end(); ttree_out(1); } } # end of sub do_tree_bsdf() -# Run i'th rtcontrib process for generating tensor tree samples +# Run rtcontrib process in background to generate tensor tree samples sub bg_tree_rtcontrib { my $pid = fork(); die "Cannot fork new process" unless defined $pid; @@ -249,7 +288,7 @@ sub bg_tree_rtcontrib { "| rcalc -e 'r1=rand(($pn+.8681)*recno-.673892)' " . "-e 'r2=rand(($pn-5.37138)*recno+67.1737811)' " . "-e 'r3=rand(($pn+3.17603772)*recno+83.766771)' " . - "-e 'Dx=1-($pbeg+\$1+r1)/$ns;Dy:0;Dz=sqrt(1-Dx*Dx)' " . + "-e 'Dx=1-2*($pbeg+\$1+r1)/$ns;Dy:0;Dz=sqrt(1-Dx*Dx)' " . "-e 'xp=(\$3+r2)*(($dim[1]-$dim[0])/$nx)+$dim[0]' " . "-e 'yp=(\$2+r3)*(($dim[3]-$dim[2])/$ny)+$dim[2]' " . "-e 'zp=$dim[5-$forw]' -e 'myDz=Dz*($forw*2-1)' " . @@ -283,6 +322,7 @@ sub bg_tree_rtcontrib { sub ttree_out { my $forw = shift; my $side = ("Back","Front")[$forw]; + my $cmd; # Only output one transmitted distribution, preferring backwards if ( !$forw || !$doback ) { print @@ -297,11 +337,18 @@ print BTDF '; -system "rcalc -if3 -e 'Omega:PI/($ns*$ns)' " . - q{-e '$1=(0.265*$1+0.670*$2+0.065*$3)/Omega' -of } . - "$td/" . ($bmodnm,$fmodnm)[$forw] . "_???.flt " . - "| rttree_reduce -h -ff -r $tensortree -g $ttlog2"; -die "Failure running rttree_reduce" if ( $? ); +$cmd = "rcalc -if3 -e 'Omega:PI/($ns*$ns)' " . + q{-e '$1=(0.265*$1+0.670*$2+0.065*$3)/Omega' }; +if ($pctcull >= 0) { + $cmd .= "-of $td/" . ($bmodnm,$fmodnm)[$forw] . "_???.flt " . + "| rttree_reduce -a -h -ff -t $pctcull -r $tensortree -g $ttlog2"; + system "$cmd" || die "Failure running rttree_reduce"; +} else { + $cmd .= "$td/" . ($bmodnm,$fmodnm)[$forw] . "_???.flt"; + print "{\n"; + system "$cmd" || die "Failure running rcalc"; + print "}\n"; +} print ' @@ -316,16 +363,25 @@ print CIE Illuminant D65 1nm.ssp ASTM E308 1931 Y.dsp - Reflection $side - LBNL/Shirley-Chiu +'; +print "\t\t\tReflection $side\n"; +print +' LBNL/Shirley-Chiu BRDF '; -system "rcalc -if3 -e 'Omega:PI/($ns*$ns)' " . - q{-e '$1=(0.265*$1+0.670*$2+0.065*$3)/Omega' -of } . - "$td/" . ($fmodnm,$bmodnm)[$forw] . "_???.flt " . - "| rttree_reduce -h -ff -r $tensortree -g $ttlog2"; -die "Failure running rttree_reduce" if ( $? ); +$cmd = "rcalc -if3 -e 'Omega:PI/($ns*$ns)' " . + q{-e '$1=(0.265*$1+0.670*$2+0.065*$3)/Omega' }; +if ($pctcull >= 0) { + $cmd .= "-of $td/" . ($fmodnm,$bmodnm)[$forw] . "_???.flt " . + "| rttree_reduce -a -h -ff -t $pctcull -r $tensortree -g $ttlog2"; + system "$cmd" || die "Failure running rttree_reduce"; +} else { + $cmd .= "$td/" . ($fmodnm,$bmodnm)[$forw] . "_???.flt"; + print "{\n"; + system "$cmd" || die "Failure running rcalc"; + print "}\n"; +} print ' @@ -363,9 +419,9 @@ KprojOmega = PI * if(Kbin-.5, $kcal = ' DEGREE : PI/180; abs(x) : if(x, x, -x); -Acos(x) : 1/DEGREE * if(x-1, 0, if(-1-x, 0, acos(x))); +Acos(x) : if(x-1, 0, if(-1-x, PI, acos(x))) / DEGREE; posangle(a) : if(-a, a + 2*PI, a); -Atan2(y,x) : 1/DEGREE * posangle(atan2(y,x)); +Atan2(y,x) : posangle(atan2(y,x)) / DEGREE; kpola(r) : select(r, 5, 15, 25, 35, 45, 55, 65, 75, 90); knaz(r) : select(r, 1, 8, 16, 20, 24, 24, 24, 16, 12); kaccum(r) : if(r-.5, knaz(r) + kaccum(r-1), 0); @@ -397,7 +453,7 @@ my $rtcmd = "rtcontrib $rtargs -h -ff -fo -n $nproc -c "-o '$td/%s.flt' -m $fmodnm -m $bmodnm $octree"; my $rccmd = "rcalc -e '$tcal' " . "-e 'mod(n,d):n-floor(n/d)*d' -e 'Kbin=mod(recno-.999,$ndiv)' " . - q{-if3 -e '$1=(0.265*$1+0.670*$2+0.065*$3)/KprojOmega'}; + q{-if3 -e '$1=(0.265*$1+0.670*$2+0.065*$3)/KprojOmega' }; if ( $doforw ) { $cmd = "cnt $ndiv $ny $nx | rcalc -of -e '$tcal' " . "-e 'xp=(\$3+rand(.12*recno+288))*(($dim[1]-$dim[0])/$nx)+$dim[0]' " . @@ -423,8 +479,10 @@ $cmd = "cnt $ndiv $ny $nx | rcalc -of -e '$tcal' " . system "$cmd" || die "Failure running: $cmd\n"; @tbarr = `$rccmd $td/$bmodnm.flt`; die "Failure running: $rccmd $td/$bmodnm.flt\n" if ( $? ); +chomp(@tbarr); @rbarr = `$rccmd $td/$fmodnm.flt`; die "Failure running: $rccmd $td/$fmodnm.flt\n" if ( $? ); +chomp(@rbarr); } # Output angle basis print @@ -524,7 +582,7 @@ print # Output front transmission (transposed order) for (my $od = 0; $od < $ndiv; $od++) { for (my $id = 0; $id < $ndiv; $id++) { - print $tfarr[$ndiv*$id + $od]; + print $tfarr[$ndiv*$id + $od], ",\n"; } print "\n"; } @@ -547,7 +605,7 @@ print # Output front reflection (transposed order) for (my $od = 0; $od < $ndiv; $od++) { for (my $id = 0; $id < $ndiv; $id++) { - print $rfarr[$ndiv*$id + $od]; + print $rfarr[$ndiv*$id + $od], ",\n"; } print "\n"; } @@ -574,7 +632,7 @@ print # Output back transmission (transposed order) for (my $od = 0; $od < $ndiv; $od++) { for (my $id = 0; $id < $ndiv; $id++) { - print $tbarr[$ndiv*$id + $od]; + print $tbarr[$ndiv*$id + $od], ",\n"; } print "\n"; } @@ -597,7 +655,7 @@ print # Output back reflection (transposed order) for (my $od = 0; $od < $ndiv; $od++) { for (my $id = 0; $id < $ndiv; $id++) { - print $rbarr[$ndiv*$id + $od]; + print $rbarr[$ndiv*$id + $od], ",\n"; } print "\n"; }