bin/ltpict.pl
changeset 58 e4892d4ef026
parent 56 259ce6d95331
child 60 448b4b706fa5
--- a/bin/ltpict.pl	Mon Mar 10 20:15:36 2014 +0000
+++ b/bin/ltpict.pl	Mon Mar 10 20:16:57 2014 +0000
@@ -1,62 +1,71 @@
 #!/usr/bin/perl
 
-# Make a nice multi-view picture of a luminaire
+# Make a four-view picture of the photometry of a luminaire
 #
-# This is based on objpict.pl that renders four-view
+# This is inspired by objpict.pl that renders four-view
 # images of objects that are not light sources.
 #
-# Written by Axel Jacobs
+# Written by Axel Jacobs <axel@jaloxa.eu>
 
 use strict;
 use warnings;
 
 use File::Temp qw/ tempdir /;
-#my $td = tempdir( CLEANUP => 1 );
-my $td = "tmp";
+my $td = tempdir( CLEANUP => 1 );
+use File::Copy qw(copy);
 
-#my $xres = 1024;
-#my $yres = 1024;
-my $xres = 600;
-my $yres = 600;
+my $res = 1024;                # Default output image dimensions
 my $tiny = 0.01;
+my $maxsize = 0.001;           # max luminaire size after scaling
 my $is_ies = 0;
-my $rpict_cmd = "rpict -ab 0 -ds 0 -dv -av 0 0 0 -x $xres -y $yres";
-my $pcond_cmd = "pcond -l";
 
 my $ies = "$td/dist.ies";
-my $fittings = "$td/fitting.rad";
-my $material = "$td/lt.mat";
-my $testroom1 = "$td/testroom1.rad";
-my $testroom2 = "$td/testroom2.rad";
-my $testroom3 = "$td/testroom3.rad";
-my $testroom4 = "$td/testroom4.rad";
-my $octree1 = "$td/lt1.oct";
-my $octree2 = "$td/lt2.oct";
-my $octree3 = "$td/lt3.oct";
-my $octree4 = "$td/lt4.oct";
+my $lumi = "$td/lumi.rad";     # Fitting as given on cmd line, or as generated by ies2rad
+my $lumi2 = "$td/lumi2.rad";   # Fitting scaled to size
+my $mat = "$td/lt.mat";
+my $room1 = "$td/room1.rad";
+my $room2 = "$td/room2.rad";
+my $room3 = "$td/room3.rad";
+my $room4 = "$td/room4.rad";
+my $oct1 = "$td/lt1.oct";
+my $oct2 = "$td/lt2.oct";
+my $oct3 = "$td/lt3.oct";
+my $oct4 = "$td/lt4.oct";
 
 # Parse command line arguments
-if ("$ARGV[0]" eq '-i') {    # File is an IES file, not Radiance luminaire
-	$is_ies = 1;
-	shift @ARGV;
-}
-# We need at least one Radiance file or a scene on STDIN (but not both)
-if ($#ARGV < 0) {
-	open(FH, ">$td/stdin.rad") or 
-			die("objview: Can't write to temporary file $td/stdin.rad\n");
-	while (<>) {
-		print FH;
+while ($#ARGV >= 0) {
+	$_ = $ARGV[0];
+	if (m/-i/) {         # File is an IES file, not Radiance luminaire
+		$is_ies = 1;
+	} elsif (m/-d/) {    # Resolution of the output HDR image
+		$res = $ARGV[1];
+		shift @ARGV;
+
+    } elsif (m/^-/) { 	 # Oops! Illegal option
+        die("ltpict: bad option \"$ARGV[0]\"\n");
+    } else {
+		last;    # No more options.  What's left is the actual file name.
 	}
-	# Pretend stdin.rad was passed as argument.
-	@ARGV = ("$td/stdin.rad");
+    shift @ARGV;
 }
 
+# We need one Radiance luminaire or an IES file
+if ($is_ies == 0) {
+	# Input file is a Radiance luminaire
+	copy $ARGV[0], $lumi or
+			die("ltpict: Cannot copy file '$ARGV[0]' to $lumi\n");
+} else {
+	# Input file is IES photometry
+	system "ies2rad -p $td -o lumi $ARGV[0]";
+}
 
-# Scale fitting and center at origin
-my $dimstr = `getbbox -h @ARGV`;
+my $res2 = $res / 2;    # Each rendering is half the size of final composite
+
+# Scale luminaire and center at origin
+my $dimstr = `getbbox -h $lumi`;
 chomp $dimstr;
 # Values returned by getbbox are indented and delimited with multiple spaces.
-$dimstr =~ s/^\s+//;   # remove leading spaces
+$dimstr =~ s/^\s+//;                # remove leading spaces
 my @dims = split(/\s+/, $dimstr);   # convert to array
 
 # Find largest axes-aligned dimension
@@ -64,52 +73,51 @@
 @diffs = reverse sort { $a <=> $b } @diffs;
 my $size = $diffs[0];
 
-# Move fitting so centre is at origin
+# Move luminaire so centre is at origin, and scale
 my $xtrans = -1.0 * ($dims[0] + $dims[1]) / 2;
 my $ytrans = -1.0 * ($dims[2] + $dims[3]) / 2;
 my $ztrans = -1.0 * ($dims[4] + $dims[5]) / 2;
-# Scale so that largest object dimension is unity
-my $scale = 0.001 / $size;
+my $scale = $maxsize / $size;
 
-my $fitting = "$td/fitting.rad";
-open(FH, ">$fitting") or
-		die("Can\'t write to temporary file $fitting");
-print FH "!xform -t $xtrans $ytrans $ztrans -s $scale @ARGV";
+open(FH, ">$lumi2") or
+		die("ltpict: Cannot write to temporary file $lumi");
+print FH "!xform -t $xtrans $ytrans $ztrans -s $scale $lumi";
 close FH;
 
 
 # Material for the room
-open(FH, ">$material") or
-		die("Can\'t write to temporary file $material");
+open(FH, ">$mat") or
+		die("ltpict: Cannot write to temporary file $mat");
 print FH "void plastic wall_mat  0  0  5  .5 .5 .5  0 0";
 close FH;
 
 
 # Different 'room' geometry for different views
-my $OFFSET = 0.1;
-open(FH, ">$testroom1") or die("Can't write to temporary file $testroom1");
+my $offset = 0.1;
+
 # C0-C180
-print FH "wall_mat polygon box.4620  0  0  12  -$OFFSET -5 5  -$OFFSET 5 5  -$OFFSET 5 -5  -$OFFSET -5 -5";
+open(FH, ">$room1") or die("ltpict: Cannot write to temporary file $room1");
+print FH "wall_mat polygon box.4620  0  0  12  -$offset -5 5  -$offset 5 5  -$offset 5 -5  -$offset -5 -5";
 close(FH);
 
-open(FH, ">$testroom2") or die("Can't write to temporary file $testroom2");
 # C90-C270
-print FH "wall_mat polygon box.1540  0  0  12  5 $OFFSET -5  5 $OFFSET 5  -5 $OFFSET 5  -5 $OFFSET -5";
+open(FH, ">$room2") or die("ltpict: Cannot write to temporary file $room2");
+print FH "wall_mat polygon box.1540  0  0  12  5 $offset -5  5 $offset 5  -5 $offset 5  -5 $offset -5";
 close(FH);
 
-open(FH, ">$testroom3") or die("Can't write to temporary file $testroom3");
 # Lower hemisphere
+open(FH, ">$room3") or die("ltpict: Cannot write to temporary file $room3");
 print FH "wall_mat bubble lower  0  0  4 0 0 $dims[4] 5";
 close(FH);
 
-open(FH, ">$testroom4") or die("Can't write to temporary file $testroom4");
 # Upper hemisphere
+open(FH, ">$room4") or die("ltpict: Cannot write to temporary file $room4");
 print FH "wall_mat bubble upper  0  0  4 0 0 $dims[5] 5";
 close(FH);
 
 
-# Get bbox again, for the translated and scaled fitting.
-$dimstr = `getbbox -h $fitting`;
+# Get bbox again, for the translated and scaled luminaire.
+$dimstr = `getbbox -h $lumi2`;
 chomp $dimstr;
 # Values returned by getbbox are indented and delimited with multiple spaces.
 $dimstr =~ s/^\s+//;   # remove leading spaces
@@ -123,29 +131,30 @@
 my $zcent4 = $dims[5] + $tiny;
 my $vw4 = "-vta -vp 0 0 $zcent4 -vd 0 0 1 -vu 0 1 0 -vh 180 -vv 180";
 
-system "oconv $material $testroom1 $fitting > $octree1";
-system "oconv $material $testroom2 $fitting > $octree2";
-system "oconv $material $testroom3 $fitting > $octree3";
-system "oconv $material $testroom4 $fitting > $octree4";
+system "oconv $mat $room1 $lumi2 > $oct1";
+system "oconv $mat $room2 $lumi2 > $oct2";
+system "oconv $mat $room3 $lumi2 > $oct3";
+system "oconv $mat $room4 $lumi2 > $oct4";
 
 # Render four different views of the objects
-system "$rpict_cmd $vw1 $octree1 > $td/right.hdr";
-system "$rpict_cmd $vw2 $octree2 > $td/front.hdr";
-system "$rpict_cmd $vw3 $octree3 > $td/down.hdr";
-system "$rpict_cmd $vw4 $octree4 > $td/up.hdr";
+my $rpict_cmd = "rpict -ab 0 -ds 0 -dv -av 0 0 0 -x $res2 -y $res2";
+system "$rpict_cmd $vw1 $oct1 > $td/right.hdr";
+system "$rpict_cmd $vw2 $oct2 > $td/front.hdr";
+system "$rpict_cmd $vw3 $oct3 > $td/down.hdr";
+system "$rpict_cmd $vw4 $oct4 > $td/up.hdr";
 
 # Compose the four views into one image
-my $cmd;
-my $vtl = "$td/vtl.hdr";
-my $vta = "$td/vta.hdr";
+my $vtl = "$td/vtl.hdr";     # The two parallel views
+my $vta = "$td/vta.hdr";     # The two fisheye views
 
 # Auto-expose right/front and down/up pairs separately
-system "pcompos $td/right.hdr 0 0 $td/front.hdr $xres 0 > $td/rf.hdr";
+my $pcond_cmd = "pcond -l";
+system "pcompos -a 2 $td/right.hdr  $td/front.hdr > $td/rf.hdr";
 system "$pcond_cmd $td/rf.hdr > $vtl";
-system "pcompos $td/down.hdr 0 0 $td/up.hdr $xres 0 > $td/du.hdr";
+system "pcompos -a 2 $td/down.hdr $td/up.hdr > $td/du.hdr";
 system "$pcond_cmd $td/du.hdr > $vta";
 
-# Combine top two images with bottom row
+# Combine top two images with bottom row.  Output HDR.
 exec "pcompos -a 1 $vtl $vta";
 
 #EOF