bin/ltpict.pl
author Axel Jacobs <axel@jaloxa.eu>
Tue, 15 Apr 2014 21:13:47 +0100
changeset 75 e02e199c8c71
parent 68 67aa83bdbddd
child 79 0f5dabeed505
permissions -rwxr-xr-x
falsecolor: get latest Radiance HEAD 4 Apr 2013

#!/usr/bin/perl

# Make a four-view picture of the photometry of a luminaire
#
# This is inspired by objpict.pl that renders four-view
# images of objects that are not light sources.
#
# Written by Axel Jacobs <axel@jaloxa.eu>

use strict;
use warnings;

use File::Temp qw/ tempdir /;
my $td = tempdir( CLEANUP => 1 );

my $res     = 1024;            # Default output image dimensions. Same as objpict.
my $tiny    = 0.01;
my $maxsize = 0.001;           # max luminaire size after scaling
my $is_ies  = 0;

my $ies   = "$td/dist.ies";
my $lumi  = "$td/lumi.rad";    # Fitting given on cmd line, or 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
while (@ARGV) {
	$_ = $ARGV[0];
	if (m/-i/) {         # File is an IES file, not a Radiance luminaire
		$is_ies = 1;
	} elsif (m/-d/) {    # Resolution of the output HDR image
		$res = $ARGV[1];
		shift @ARGV;
    } elsif (m/^-\w/) { 	 # Oops! Illegal option
        die("ltpict: bad option '$_'\n");
    } else {
		last;    # No more options.  What's left is the actual file name.
	}
    shift @ARGV;
}

# We need exactly one Radiance luminaires or IES file
if (! $#ARGV == 0) {
	die("ltpict: Need one Radiance luminaire or IES file.\n");
} elsif ($is_ies == 0) {
	# Input file is a Radiance luminaire
	$lumi = $ARGV[0];
} else {
	# Input file is IES photometry
	system qq[ ies2rad -p $td -o lumi "$ARGV[0]" ];
}

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
my @dims = split(/\s+/, $dimstr);   # convert to array

# Find largest axes-aligned dimension
my @diffs = ($dims[1]-$dims[0], $dims[3]-$dims[2], $dims[5]-$dims[4]);
@diffs = reverse sort { $a <=> $b } @diffs;
my $size = $diffs[0];

# 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;
my $scale = $maxsize / $size;
system qq[ xform -t $xtrans $ytrans $ztrans "$lumi" > $lumi2 ];


# Material for the room
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 $o = 0.1;   # Offset

# C0-C180
open(FH, ">$room1") or
		die("ltpict: Cannot write to temporary file $room1");
print FH "wall_mat polygon box.4620  0  0  12  -$o -5 5  -$o 5 5  -$o 5 -5  -$o -5 -5";
close(FH);

# C90-C270
open(FH, ">$room2") or
		die("ltpict: Cannot write to temporary file $room2");
print FH "wall_mat polygon box.1540  0  0  12  5 $o -5  5 $o 5  -5 $o 5  -5 $o -5";
close(FH);

# 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);

# 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);


# Call 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
@dims = split(/\s+/, $dimstr);   # convert to array


# Define the four views
my $vw1 = "-vtl -vp 4.5 0 0 -vd -1 0 0 -vh 10 -vv 10";
my $vw2 = "-vtl -vp 0 -4.5 0 -vd 0 1 0 -vh 10 -vv 10";
my $zcent3 = $dims[4] - $tiny;
my $vw3 = "-vta -vp 0 0 $zcent3 -vd 0 0 -1 -vu 0 1 0 -vh 180 -vv 180";
my $zcent4 = $dims[5] + $tiny;
my $vw4 = "-vta -vp 0 0 $zcent4 -vd 0 0 1 -vu 0 1 0 -vh 180 -vv 180";


# Compile octrees
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
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 $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
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 -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.  Output HDR.
exec "pcompos -a 1 $vtl $vta";

#EOF