--- a/bin/ltview.pl Tue Mar 11 00:29:36 2014 +0000
+++ b/bin/ltview.pl Tue Mar 11 00:30:15 2014 +0000
@@ -1,78 +1,44 @@
#!/usr/bin/perl
#
-# Make a nice view of a luminaire
-# Argument is the Radiance description of a luminaire, incl. distribution
+# Make an interactive preview of a luminaire
#
# This script is based on Radiance's objview.pl plus
# Rob Guglielmetti's ltview extension to his objview.rb
#
-# Axel Jacobs, 25 Dec 2013
+# Written by Axel Jacobs <axel@jaloxa.eu>
use strict;
use warnings;
+use Math::Trig;
+use File::Copy;
use File::Temp qw/ tempdir /;
-my $td = tempdir( CLEANUP => 1 );
-my $octree = "$td/lt$$.oct";
-my $room = "$td/rm$$.rad";
-my $rif = "$td/lt$$.rif";
-my $lumi = "$td/lt$$.rad";
-my $ambf = "$td/af$$.amb";
-my $raddev = "x11"; # default output device. Overwrite with -o
-my $up = "Z";
-my $vw = "XYZ"; # default view. See 'man rad' for details
-my $bubble = 0; # Box or bubble? 0..box, 1..bubble
-my $TINY = 0.01;
+my $td = tempdir( CLEANUP => 1 );
+my $oct = "$td/ltview.oct";
+my $room = "$td/room.rad";
+my $rdim; # Overall room dimensions
+my $rif = "$td/ltview.rif";
+my $lumi = "$td/lumi.rad";
+my $ies = "$td/lumi.ies";
+my $raddev = "x11"; # default output device. Overwrite with -o
+my $is_ies = 0; # input file is IES photometry, not a Radiance luminaire
-my $opts = ""; # Options common to rad and glrad
-my $rendopts = "-ab 1 -ds .15 -av 0 0 0"; # For render= line in rif file
-my $usegl = 0; # Run glrad instead of rad (Boolean).
-my $radopt = 0; # An option specific to rad was passed (Boolean).
-my $glradopt = 0; # An option specific to glrad was passed (Boolean).
+my $maxscale = 1; # Maximum luminiare dimension after scaling
+my $opts = ""; # Options common to rad and glrad
+my $render = "-ab 1 -ds .15 -av 0 0 0"; # render= line in rif file
+my $radopt = 0; # An option specific to rad was passed (Boolean).
while (@ARGV) {
$_ = $ARGV[0];
- if (m/-g/) { # OpenGL output
- if ( $^O =~ /MSWin32/ ) {
- # No meaningful error messages under Windows. Just ignore...
- #die("OpenGL view is not available under Windows.\n");
- } else {
- $usegl = 1;
- }
- } elsif (m/-u/) { # up direction
- $up = $ARGV[1];
- shift @ARGV;
- } elsif ((m/-s/) or (m/-w/)) { # silent, no warnings
- $opts .= " $_";
- } elsif (m/-b/) { # back face visibility
- $rendopts .= ' -bv';
- } elsif (m/-v/) { # standard view "[Xx]?[Yy]?[Zz]?[vlcahs]?"
- # Prepend view with '+' for custom view away from the luminaire, not at it.
- # This is not defined by rad's default views.
- $vw = $ARGV[1];
- shift @ARGV;
- } elsif (m/-N/) { # No. of parallel processes
- if ( $^O =~ /MSWin32/ ) {
- # Silently ignore this under Windoze
- #die("Multi-processor support is not available under Windows.\n");
- } else {
- $opts .= ' -N ' . $ARGV[1];
- }
- $radopt = 1;
- shift @ARGV;
+ if (m/-i/) {
+ $is_ies = 1;
} elsif (m/-o/) { # output device (rvu -devices)
$raddev = $ARGV[1];
$radopt = 1;
shift @ARGV;
- } elsif ((m/-V/) or (m/-e/)) { # print view, explicate variables
- # Think of those two as '-verbose'.
- $opts .= " $_";
- $radopt = 1;
- } elsif (m/-S/) { # full-screen stereo
- $opts .= " $_";
- $glradopt = 1;
- } elsif (m/-r/) { # spherical room rather than box
- $bubble = 1;
+ } elsif (m/-r/) {
+ $rdim = $ARGV[1]; # Room dimensions
+ shift @ARGV;
} elsif (m/^-\w/) {
die("objview: Bad option: $_\n");
} else {
@@ -81,143 +47,85 @@
shift @ARGV;
}
-# We need exactly one input file: a Radiance luminaires description
-#TODO: this could be expanded to handle Radiance .dat files and IES photometry files...
+# We need one Radiance luminaires description, or an IES file
if (! $#ARGV == 0) {
- die("ltview: Need one Radiance luminaire.\n");
-}
-
-# Make sure we don't confuse glrad and rad options.
-if ($usegl) {
- if ($radopt) {
- die("objview: glrad output requested, but rad option passed.\n");
- }
-} else {
- if ($glradopt) {
- die("objview: rad output requested, but glrad option passed.\n");
- }
+ die("ltview: Need one Radiance luminaire or IES file.\n");
}
open(FH, ">$room") or
die("ltview: Can't write to temporary file $room\n");
print FH "void plastic wall_mat 0 0 5 .2 .2 .2 0 0\n";
-if ($bubble == 1) {
- # Room is a bubble, not a box
- my $radius = sprintf "%.6f", 1.1*5 * 3**(1/3);
- print FH "wall_mat sphere orb 0 0 4 0 0 0 $radius\n";
+my $r;
+if (defined $rdim) {
+ # Room dimensions are giving explicitly. Don't touch the fitting.
+ $r = $rdim;
+
+ copy ($ARGV[0], $lumi);
} else {
- print FH <<EndOfRoom;
-# Don't rely on genbox here (named genrbox under Debian/Ubuntu)
-wall_mat polygon box.1540 0 0 12 5 -5 -5 5 -5 5 -5 -5 5 -5 -5 -5
-wall_mat polygon box.4620 0 0 12 -5 -5 5 -5 5 5 -5 5 -5 -5 -5 -5
-wall_mat polygon box.2310 0 0 12 -5 5 -5 5 5 -5 5 -5 -5 -5 -5 -5
-wall_mat polygon box.3267 0 0 12 5 5 -5 -5 5 -5 -5 5 5 5 5 5
-wall_mat polygon box.5137 0 0 12 5 -5 5 5 -5 -5 5 5 -5 5 5 5
-wall_mat polygon box.6457 0 0 12 -5 5 5 -5 -5 5 5 -5 5 5 5 5
-EndOfRoom
-}
-close(FH);
+ # Scale fitting so it fits nicely into our default test room.
+ $r = 5; # Default room dimension
+
+ # Work out how large the luminaire is and scale so that the longest
+ # axis-align dimension is $maxscale
+ my $dimstr = `getbbox -h $ARGV[0]`;
+ 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
-# Work out how large the luminaire is and scale so that the longest
-# axis-align dimension is one unit
-my $dimstr = `getbbox -h $ARGV[0]`;
-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 objects so centre is at origin
+ 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 $maxscale
+ my $scale = $maxscale / $size;
-# 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];
+ system "xform -t $xtrans $ytrans $ztrans -s $scale $ARGV[0] > $lumi";
+}
-# Move objects so centre is at origin
-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 = 1 / $size;
-
-my $cmd = "xform -t $xtrans $ytrans $ztrans -s $scale $ARGV[0] > $lumi";
-system "$cmd";
+print FH <<EndOfRoom;
+# Don't generate -y face so we can look into the box (could use clipping)
+#wall_mat polygon box.1540 0 0 12 $r -$r -$r $r -$r $r -$r -$r $r -$r -$r -$r
+wall_mat polygon box.4620 0 0 12 -$r -$r $r -$r $r $r -$r $r -$r -$r -$r -$r
+wall_mat polygon box.2310 0 0 12 -$r $r -$r $r $r -$r $r -$r -$r -$r -$r -$r
+wall_mat polygon box.3267 0 0 12 $r $r -$r -$r $r -$r -$r $r $r $r $r $r
+wall_mat polygon box.5137 0 0 12 $r -$r $r $r -$r -$r $r $r -$r $r $r $r
+wall_mat polygon box.6457 0 0 12 -$r $r $r -$r -$r $r $r -$r $r $r $r $r
+EndOfRoom
+close(FH);
my $scene = "$room $lumi";
# Make this work under Windoze
if ( $^O =~ /MSWin32/ ) {
$scene =~ s{\\}{/}g;
- $octree =~ s{\\}{/}g;
- $ambf =~ s{\\}{/}g;
+ $oct =~ s{\\}{/}g;
$raddev = "qt";
}
-my $custom_vw = $vw;
-$vw =~ s/^\+//;
+# Tweak bounding box so we get a nice view covering all of the box, without
+# having a wasteful black border around it. Must work for arbitrary box dims.
+my $zone = 1.1 * $r * ( 1 + 1/tan(22.5*pi/180) );
+
open(FH, ">$rif") or
die("ltview: Can't write to temporary file $rif\n");
print FH <<EndOfRif;
scene= $scene
EXPOSURE= 2
-ZONE= Interior -5 5 -5 5 -5 5
-UP= $up
-view= $vw
-OCTREE= $octree
+ZONE= Interior -$zone $zone -$zone $zone -$zone $zone
+UP= Z
+view= y
+OCTREE= $oct
oconv= -f
-AMBF= $ambf
-render= $rendopts
+render= $render
EndOfRif
close(FH);
-# Custom view: look away from the luminaire, not at it. This is indicated
-# by a leading '+' in front of the view (-v argument, default: XYZ)
-if ($custom_vw =~ m/^\+/) {
- # Get rad to spit out the -v* options for the default view requested
- my $view = `rad -V -n -s $rif`;
- $view =~ s/\n//;
- $view =~ s/^VIEW= //;
-
- my $x = 0;
- my $y = 0;
- my $z = 0;
- if ($vw =~ m/X/) {
- $x = $dims[0] - $TINY;
- } elsif ($vw =~ m/x/) {
- $x = $dims[1] + $TINY;
- }
- if ($vw =~ m/Y/) {
- $y = $dims[2] - $TINY;
- } elsif ($vw =~ m/y/) {
- $y = $dims[3] + $TINY;
- }
- if ($vw =~ m/Z/) {
- $z = $dims[4] - $TINY;
- } elsif ($vw =~ m/z/) {
- $z = $dims[5] + $TINY;
- }
-
- # Keep rad-generated standard view, but modify -vp
- $vw = "nice $view -vp $x $y $z";
-
- open(FH, ">$rif") or
- die("ltview: Can't write to temporary file $rif\n");
- print FH <<EndOfRif2;
-scene= $scene
-EXPOSURE= 2
-ZONE= Interior -5 5 -5 5 -5 5
-UP= $up
-view= $vw
-OCTREE= $octree
-oconv= -f
-AMBF= $ambf
-render= $rendopts
-EndOfRif2
- close(FH);
-}
-
-if ($usegl) {
- system "glrad $opts $rif";
-} else {
- system "rad -o $raddev $opts $rif";
-}
+system "rad -o $raddev $opts $rif";
#EOF