13 |
|
use File::Temp qw/ tempdir /; |
14 |
|
my $td = tempdir( CLEANUP => 1 ); |
15 |
|
|
16 |
< |
my $res = 1024; # Default output image dimensions. Same as objpict. |
16 |
> |
my $res = 1024; # Default output image dimensions. Same as objpict. |
17 |
|
my $tiny = 0.01; |
18 |
< |
my $maxsize = 0.001; # max luminaire size after scaling |
18 |
> |
my $maxsize = 0.001; # max luminaire size after scaling |
19 |
|
my $is_ies = 0; |
20 |
|
|
21 |
|
my $ies = "$td/dist.ies"; |
22 |
< |
my $lumi = "$td/lumi.rad"; # Fitting given on cmd line, or generated by ies2rad |
23 |
< |
my $lumi2 = "$td/lumi2.rad"; # Fitting scaled to size |
22 |
> |
my $lumi = "$td/lumi.rad"; # Fitting given on cmd line, or generated by ies2rad |
23 |
> |
my $lumi2 = "$td/lumi2.rad"; # Fitting scaled to size |
24 |
|
my $mat = "$td/lt.mat"; |
25 |
|
my $room1 = "$td/room1.rad"; |
26 |
|
my $room2 = "$td/room2.rad"; |
33 |
|
|
34 |
|
# Parse command line arguments |
35 |
|
while (@ARGV) { |
36 |
< |
$_ = $ARGV[0]; |
37 |
< |
if (m/-i/) { # File is an IES file, not a Radiance luminaire |
38 |
< |
$is_ies = 1; |
39 |
< |
} elsif (m/-d/) { # Resolution of the output HDR image |
40 |
< |
$res = $ARGV[1]; |
41 |
< |
shift @ARGV; |
42 |
< |
} elsif (m/^-\w/) { # Oops! Illegal option |
36 |
> |
$_ = $ARGV[0]; |
37 |
> |
if (m/-i/) { # File is an IES file, not a Radiance luminaire |
38 |
> |
$is_ies = 1; |
39 |
> |
} elsif (m/-d/) { # Resolution of the output HDR image |
40 |
> |
$res = $ARGV[1]; |
41 |
> |
shift @ARGV; |
42 |
> |
} elsif (m/^-\w/) { # Oops! Illegal option |
43 |
|
die("ltpict: bad option '$_'\n"); |
44 |
|
} else { |
45 |
< |
last; # No more options. What's left is the actual file name. |
46 |
< |
} |
45 |
> |
last; # No more options. What's left is the actual file name. |
46 |
> |
} |
47 |
|
shift @ARGV; |
48 |
|
} |
49 |
|
|
50 |
< |
if ($is_ies == 0) { |
51 |
< |
# Input file is a Radiance luminaire |
52 |
< |
$lumi = $ARGV[0]; |
50 |
> |
# We need exactly one Radiance luminaires or IES file |
51 |
> |
if ( !$#ARGV == 0 ) { |
52 |
> |
die("ltpict: Need one Radiance luminaire or IES file.\n"); |
53 |
> |
} elsif ( $is_ies == 0 ) { |
54 |
> |
|
55 |
> |
# Input file is a Radiance luminaire |
56 |
> |
$lumi = $ARGV[0]; |
57 |
|
} else { |
58 |
< |
# Input file is IES photometry |
59 |
< |
system "ies2rad -p $td -o lumi $ARGV[0]"; |
58 |
> |
|
59 |
> |
# Input file is IES photometry |
60 |
> |
system qq[ ies2rad -p $td -o lumi "$ARGV[0]" ]; |
61 |
|
} |
62 |
|
|
63 |
|
my $res2 = $res / 2; # Each rendering is half the size of final composite |
64 |
|
|
65 |
|
# Scale luminaire and center at origin |
66 |
< |
my $dimstr = `getbbox -h $lumi`; |
66 |
> |
my $dimstr = `getbbox -h "$lumi"`; |
67 |
|
chomp $dimstr; |
68 |
+ |
|
69 |
|
# Values returned by getbbox are indented and delimited with multiple spaces. |
70 |
< |
$dimstr =~ s/^\s+//; # remove leading spaces |
71 |
< |
my @dims = split(/\s+/, $dimstr); # convert to array |
70 |
> |
$dimstr =~ s/^\s+//; # remove leading spaces |
71 |
> |
my @dims = split( /\s+/, $dimstr ); # convert to array |
72 |
|
|
73 |
|
# Find largest axes-aligned dimension |
74 |
< |
my @diffs = ($dims[1]-$dims[0], $dims[3]-$dims[2], $dims[5]-$dims[4]); |
74 |
> |
my @diffs = ( $dims[1] - $dims[0], $dims[3] - $dims[2], $dims[5] - $dims[4] ); |
75 |
|
@diffs = reverse sort { $a <=> $b } @diffs; |
76 |
|
my $size = $diffs[0]; |
77 |
|
|
78 |
|
# Move luminaire so centre is at origin, and scale |
79 |
< |
my $xtrans = -1.0 * ($dims[0] + $dims[1]) / 2; |
80 |
< |
my $ytrans = -1.0 * ($dims[2] + $dims[3]) / 2; |
81 |
< |
my $ztrans = -1.0 * ($dims[4] + $dims[5]) / 2; |
82 |
< |
my $scale = $maxsize / $size; |
79 |
> |
my $xtrans = -1.0 * ( $dims[0] + $dims[1] ) / 2; |
80 |
> |
my $ytrans = -1.0 * ( $dims[2] + $dims[3] ) / 2; |
81 |
> |
my $ztrans = -1.0 * ( $dims[4] + $dims[5] ) / 2; |
82 |
> |
my $scale = $maxsize / $size; |
83 |
> |
system qq[ xform -t $xtrans $ytrans $ztrans "$lumi" > $lumi2 ]; |
84 |
|
|
78 |
– |
open(FH, ">$lumi2") or |
79 |
– |
die("ltpict: Cannot write to temporary file $lumi"); |
80 |
– |
print FH "!xform -t $xtrans $ytrans $ztrans -s $scale $lumi"; |
81 |
– |
close FH; |
82 |
– |
|
83 |
– |
|
85 |
|
# Material for the room |
86 |
< |
open(FH, ">$mat") or |
87 |
< |
die("ltpict: Cannot write to temporary file $mat"); |
86 |
> |
open( FH, ">$mat" ) |
87 |
> |
or die("ltpict: Cannot write to temporary file $mat"); |
88 |
|
print FH "void plastic wall_mat 0 0 5 .5 .5 .5 0 0"; |
89 |
|
close FH; |
90 |
|
|
90 |
– |
|
91 |
|
# Different 'room' geometry for different views |
92 |
< |
my $o = 0.1; # Offset |
92 |
> |
my $o = 0.1; # Offset |
93 |
|
|
94 |
|
# C0-C180 |
95 |
< |
open(FH, ">$room1") or |
96 |
< |
die("ltpict: Cannot write to temporary file $room1"); |
97 |
< |
print FH "wall_mat polygon box.4620 0 0 12 -$o -5 5 -$o 5 5 -$o 5 -5 -$o -5 -5"; |
95 |
> |
open( FH, ">$room1" ) |
96 |
> |
or die("ltpict: Cannot write to temporary file $room1"); |
97 |
> |
print FH |
98 |
> |
"wall_mat polygon box.4620 0 0 12 -$o -5 5 -$o 5 5 -$o 5 -5 -$o -5 -5"; |
99 |
|
close(FH); |
100 |
|
|
101 |
|
# C90-C270 |
102 |
< |
open(FH, ">$room2") or |
103 |
< |
die("ltpict: Cannot write to temporary file $room2"); |
104 |
< |
print FH "wall_mat polygon box.1540 0 0 12 5 $o -5 5 $o 5 -5 $o 5 -5 $o -5"; |
102 |
> |
open( FH, ">$room2" ) |
103 |
> |
or die("ltpict: Cannot write to temporary file $room2"); |
104 |
> |
print FH |
105 |
> |
"wall_mat polygon box.1540 0 0 12 5 $o -5 5 $o 5 -5 $o 5 -5 $o -5"; |
106 |
|
close(FH); |
107 |
|
|
108 |
|
# Lower hemisphere |
109 |
< |
open(FH, ">$room3") or |
110 |
< |
die("ltpict: Cannot write to temporary file $room3"); |
109 |
> |
open( FH, ">$room3" ) |
110 |
> |
or die("ltpict: Cannot write to temporary file $room3"); |
111 |
|
print FH "wall_mat bubble lower 0 0 4 0 0 $dims[4] 5"; |
112 |
|
close(FH); |
113 |
|
|
114 |
|
# Upper hemisphere |
115 |
< |
open(FH, ">$room4") or |
116 |
< |
die("ltpict: Cannot write to temporary file $room4"); |
115 |
> |
open( FH, ">$room4" ) |
116 |
> |
or die("ltpict: Cannot write to temporary file $room4"); |
117 |
|
print FH "wall_mat bubble upper 0 0 4 0 0 $dims[5] 5"; |
118 |
|
close(FH); |
119 |
|
|
118 |
– |
|
120 |
|
# Call bbox again, for the translated and scaled luminaire. |
121 |
|
$dimstr = `getbbox -h $lumi2`; |
122 |
|
chomp $dimstr; |
123 |
+ |
|
124 |
|
# Values returned by getbbox are indented and delimited with multiple spaces. |
125 |
< |
$dimstr =~ s/^\s+//; # remove leading spaces |
126 |
< |
@dims = split(/\s+/, $dimstr); # convert to array |
125 |
> |
$dimstr =~ s/^\s+//; # remove leading spaces |
126 |
> |
@dims = split( /\s+/, $dimstr ); # convert to array |
127 |
|
|
128 |
|
# Define the four views |
129 |
< |
my $vw1 = "-vtl -vp 4.5 0 0 -vd -1 0 0 -vh 10 -vv 10"; |
130 |
< |
my $vw2 = "-vtl -vp 0 -4.5 0 -vd 0 1 0 -vh 10 -vv 10"; |
129 |
> |
my $vw1 = "-vtl -vp 4.5 0 0 -vd -1 0 0 -vh 10 -vv 10"; |
130 |
> |
my $vw2 = "-vtl -vp 0 -4.5 0 -vd 0 1 0 -vh 10 -vv 10"; |
131 |
|
my $zcent3 = $dims[4] - $tiny; |
132 |
< |
my $vw3 = "-vta -vp 0 0 $zcent3 -vd 0 0 -1 -vu 0 1 0 -vh 180 -vv 180"; |
132 |
> |
my $vw3 = "-vta -vp 0 0 $zcent3 -vd 0 0 -1 -vu 0 1 0 -vh 180 -vv 180"; |
133 |
|
my $zcent4 = $dims[5] + $tiny; |
134 |
< |
my $vw4 = "-vta -vp 0 0 $zcent4 -vd 0 0 1 -vu 0 1 0 -vh 180 -vv 180"; |
134 |
> |
my $vw4 = "-vta -vp 0 0 $zcent4 -vd 0 0 1 -vu 0 1 0 -vh 180 -vv 180"; |
135 |
|
|
136 |
+ |
# Compile octrees |
137 |
|
system "oconv $mat $room1 $lumi2 > $oct1"; |
138 |
|
system "oconv $mat $room2 $lumi2 > $oct2"; |
139 |
|
system "oconv $mat $room3 $lumi2 > $oct3"; |
147 |
|
system "$rpict_cmd $vw4 $oct4 > $td/up.hdr"; |
148 |
|
|
149 |
|
# Compose the four views into one image |
150 |
< |
my $vtl = "$td/vtl.hdr"; # The two parallel views |
151 |
< |
my $vta = "$td/vta.hdr"; # The two fisheye views |
150 |
> |
my $vtl = "$td/vtl.hdr"; # The two parallel views |
151 |
> |
my $vta = "$td/vta.hdr"; # The two fisheye views |
152 |
|
|
153 |
|
# Auto-expose right/front and down/up pairs separately |
154 |
|
my $pcond_cmd = "pcond -l"; |