8 # Written by Axel Jacobs <axel@jaloxa.eu> |
8 # Written by Axel Jacobs <axel@jaloxa.eu> |
9 |
9 |
10 use strict; |
10 use strict; |
11 use warnings; |
11 use warnings; |
12 use Math::Trig; |
12 use Math::Trig; |
13 use File::Copy qw(copy); |
|
14 use File::Temp qw/ tempdir /; |
13 use File::Temp qw/ tempdir /; |
15 |
14 |
16 my $td = tempdir( CLEANUP => 1 ); |
15 my $td = tempdir( CLEANUP => 1 ); |
17 my $oct = "$td/ltview.oct"; |
16 my $oct = "$td/ltview.oct"; |
18 my $room = "$td/room.rad"; |
17 my $room = "$td/room.rad"; |
19 my $box; # Overall box dimensions |
18 my $box; # Overall box dimensions |
20 my $default_box = 10; # Default box dimensions |
|
21 my $rif = "$td/ltview.rif"; |
19 my $rif = "$td/ltview.rif"; |
22 my $lumi = "$td/lumi.rad"; # Fitting as given on cmd line, or generated by ies2rad |
20 my $lumi = "$td/lumi.rad"; # Fitting as given on cmd line, or generated by ies2rad |
23 my $lumi2 = "$td/lumi2.rad"; # Fitting scaled to max unity |
21 my $lumi2 = "$td/lumi2.rad"; # Fitting centred at origin |
24 my $raddev = "x11"; # default output device. Overwrite with -o |
22 my $raddev = "x11"; # Default output device. Overwrite with -o |
25 my $is_ies = 0; # input file is IES photometry, not a Radiance luminaire |
23 my $is_ies = 0; # Input file is IES photometry, not a Radiance luminaire |
26 |
|
27 my $maxscale = 1; # Maximum luminiare dimension after scaling |
|
28 my $opts = ""; # Options common to rad and glrad |
|
29 my $render = "-ab 1 -ds .15 -av 0 0 0"; # render= line in rif file |
|
30 my $radopt = 0; # An option specific to rad was passed (Boolean). |
|
31 |
24 |
32 while (@ARGV) { |
25 while (@ARGV) { |
33 $_ = $ARGV[0]; |
26 $_ = $ARGV[0]; |
34 if (m/-i/) { |
27 if (m/-i/) { |
35 $is_ies = 1; |
28 $is_ies = 1; |
36 } elsif (m/-o/) { # output device (rvu -devices) |
29 } elsif (m/-o/) { # output device (rvu -devices) |
37 $raddev = $ARGV[1]; |
30 $raddev = $ARGV[1]; |
38 $radopt = 1; |
|
39 shift @ARGV; |
31 shift @ARGV; |
40 } elsif (m/-b/) { |
32 } elsif (m/-b/) { |
41 $box = $ARGV[1]; # Box dimensions |
33 $box = $ARGV[1]; # Box dimensions |
42 shift @ARGV; |
34 shift @ARGV; |
43 } elsif (m/^-\w/) { |
35 } elsif (m/^-\w/) { |
44 die("objview: Bad option: '$_'\n"); |
36 die("ltview: Bad option: '$_'\n"); |
45 } else { |
37 } else { |
46 last; |
38 last; |
47 } |
39 } |
48 shift @ARGV; |
40 shift @ARGV; |
49 } |
41 } |
50 |
42 |
51 # We need exactly one Radiance luminaires or IES file |
43 # We need exactly one Radiance luminaires or IES file |
52 if (! $#ARGV == 0) { |
44 if (! $#ARGV == 0) { |
53 die("ltview: Need one Radiance luminaire or IES file.\n"); |
45 die("ltview: Need one Radiance luminaire or IES file.\n"); |
54 } |
46 } elsif ($is_ies == 0) { |
55 |
|
56 if ($is_ies == 0) { |
|
57 # Input file is a Radiance luminaire |
47 # Input file is a Radiance luminaire |
58 $lumi = $ARGV[0]; |
48 $lumi = $ARGV[0]; |
59 } else { |
49 } else { |
60 # Input file is IES photometry |
50 # Input file is IES photometry |
61 system "ies2rad -p $td -o lumi $ARGV[0]"; |
51 system qq[ ies2rad -p $td -o lumi "$ARGV[0]" ]; |
62 } |
52 } |
63 |
53 |
64 |
54 |
|
55 # Work out centre of luminaire |
|
56 my $dimstr = `getbbox -h "$lumi"`; |
|
57 chomp $dimstr; |
|
58 # Values returned by getbbox are indented and delimited with multiple spaces. |
|
59 $dimstr =~ s/^\s+//; # remove leading spaces |
|
60 my @dims = split(/\s+/, $dimstr); # convert to array |
|
61 |
|
62 # Find largest axes-aligned luminaire dimension |
|
63 # The box will be ten times as large, unless overwritten with -b option. |
|
64 my @diffs = reverse sort { $a <=> $b } ($dims[1]-$dims[0], $dims[3]-$dims[2], $dims[5]-$dims[4]); |
|
65 my $lsize = $diffs[0]; |
|
66 |
|
67 # Centre fitting at origin |
|
68 my $xtrans = -1.0 * ($dims[0] + $dims[1]) / 2; |
|
69 my $ytrans = -1.0 * ($dims[2] + $dims[3]) / 2; |
|
70 my $ztrans = -1.0 * ($dims[4] + $dims[5]) / 2; |
|
71 system qq[ xform -t $xtrans $ytrans $ztrans "$lumi" > $lumi2 ]; |
|
72 |
|
73 |
|
74 # Make the enclosing box |
|
75 my $b2; |
|
76 if (defined $box) { |
|
77 # Room dimensions are giving explicitly. |
|
78 $b2 = $box / 2; |
|
79 } else { |
|
80 # Box dimensions are ten times largest luminaire bbox dimensions. |
|
81 $b2 = $lsize * 10.0 / 2.0; |
|
82 } |
|
83 |
65 open(FH, ">$room") or |
84 open(FH, ">$room") or |
66 die("ltview: Can't write to temporary file '$room'\n"); |
85 die("ltview: Can't write to temporary file '$room'\n"); |
67 print FH "void plastic wall_mat 0 0 5 .2 .2 .2 0 0\n"; |
86 print FH <<EndOfRoom; |
|
87 void plastic wall_mat 0 0 5 .2 .2 .2 0 0 |
68 |
88 |
69 my $b2; |
89 # Don't generate -y face so we can look into the box |
70 if (defined $box) { |
|
71 # Room dimensions are giving explicitly. Don't touch the fitting. |
|
72 $b2 = $box / 2; |
|
73 |
|
74 $lumi2 = $ARGV[0]; |
|
75 } else { |
|
76 # Scale fitting so it fits nicely into our default test room. |
|
77 $b2 = $default_box; # Default room dimension |
|
78 |
|
79 # Work out how large the luminaire is and scale so that the longest |
|
80 # axis-align dimension is $maxscale |
|
81 my $dimstr = `getbbox -h $lumi`; |
|
82 chomp $dimstr; |
|
83 # Values returned by getbbox are indented and delimited with multiple spaces. |
|
84 $dimstr =~ s/^\s+//; # remove leading spaces |
|
85 my @dims = split(/\s+/, $dimstr); # convert to array |
|
86 |
|
87 # Find largest axes-aligned dimension |
|
88 my @diffs = ($dims[1]-$dims[0], $dims[3]-$dims[2], $dims[5]-$dims[4]); |
|
89 @diffs = reverse sort { $a <=> $b } @diffs; |
|
90 my $size = $diffs[0]; |
|
91 |
|
92 # Move objects so centre is at origin |
|
93 my $xtrans = -1.0 * ($dims[0] + $dims[1]) / 2; |
|
94 my $ytrans = -1.0 * ($dims[2] + $dims[3]) / 2; |
|
95 my $ztrans = -1.0 * ($dims[4] + $dims[5]) / 2; |
|
96 # Scale so that largest object dimension is $maxscale |
|
97 my $scale = $maxscale / $size; |
|
98 |
|
99 #system "xform -t $xtrans $ytrans $ztrans -s $scale $ARGV[0] > $lumi"; |
|
100 system "xform -t $xtrans $ytrans $ztrans -s $scale $lumi > $lumi2"; |
|
101 } |
|
102 |
|
103 print FH <<EndOfRoom; |
|
104 # Don't generate -y face so we can look into the box (could use clipping) |
|
105 #wall_mat polygon box.1540 0 0 12 $b2 -$b2 -$b2 $b2 -$b2 $b2 -$b2 -$b2 $b2 -$b2 -$b2 -$b2 |
90 #wall_mat polygon box.1540 0 0 12 $b2 -$b2 -$b2 $b2 -$b2 $b2 -$b2 -$b2 $b2 -$b2 -$b2 -$b2 |
106 wall_mat polygon box.4620 0 0 12 -$b2 -$b2 $b2 -$b2 $b2 $b2 -$b2 $b2 -$b2 -$b2 -$b2 -$b2 |
91 wall_mat polygon box.4620 0 0 12 -$b2 -$b2 $b2 -$b2 $b2 $b2 -$b2 $b2 -$b2 -$b2 -$b2 -$b2 |
107 wall_mat polygon box.2310 0 0 12 -$b2 $b2 -$b2 $b2 $b2 -$b2 $b2 -$b2 -$b2 -$b2 -$b2 -$b2 |
92 wall_mat polygon box.2310 0 0 12 -$b2 $b2 -$b2 $b2 $b2 -$b2 $b2 -$b2 -$b2 -$b2 -$b2 -$b2 |
108 wall_mat polygon box.3267 0 0 12 $b2 $b2 -$b2 -$b2 $b2 -$b2 -$b2 $b2 $b2 $b2 $b2 $b2 |
93 wall_mat polygon box.3267 0 0 12 $b2 $b2 -$b2 -$b2 $b2 -$b2 -$b2 $b2 $b2 $b2 $b2 $b2 |
109 wall_mat polygon box.5137 0 0 12 $b2 -$b2 $b2 $b2 -$b2 -$b2 $b2 $b2 -$b2 $b2 $b2 $b2 |
94 wall_mat polygon box.5137 0 0 12 $b2 -$b2 $b2 $b2 -$b2 -$b2 $b2 $b2 -$b2 $b2 $b2 $b2 |
110 wall_mat polygon box.6457 0 0 12 -$b2 $b2 $b2 -$b2 -$b2 $b2 $b2 -$b2 $b2 $b2 $b2 $b2 |
95 wall_mat polygon box.6457 0 0 12 -$b2 $b2 $b2 -$b2 -$b2 $b2 $b2 -$b2 $b2 $b2 $b2 $b2 |
111 EndOfRoom |
96 EndOfRoom |
112 close(FH); |
97 close(FH); |
113 |
98 |
114 my $scene = "$room $lumi"; |
99 my $scene = "$room $lumi2"; |
115 # Make this work under Windoze |
100 # Make this work under Windoze |
116 if ( $^O =~ /MSWin32/ ) { |
101 if ( $^O =~ /MSWin32/ ) { |
117 $scene =~ s{\\}{/}g; |
102 $scene =~ s{\\}{/}g; |
118 $oct =~ s{\\}{/}g; |
103 $oct =~ s{\\}{/}g; |
119 $raddev = "qt"; |
104 $raddev = "qt"; |
120 } |
105 } |
121 |
106 |
122 # Tweak bounding box so we get a nice view covering all of the box, without |
107 # Tweak scene bounding box so we get a nice view covering all of the box, without |
123 # having a wasteful black border around it. Must work for arbitrary box dims. |
108 # having a wasteful black border around it. Must work for arbitrary box dims. |
124 my $zone = 1.1 * $b2 * ( 1 + 1/tan(22.5*pi/180) ); |
109 my $zone = 1.1 * $b2 * ( 1 + 1/tan(22.5*pi/180) ); |
125 |
110 |
126 open(FH, ">$rif") or |
111 open(FH, ">$rif") or |
127 die("ltview: Can't write to temporary file '$rif'\n"); |
112 die("ltview: Can't write to temporary file '$rif'\n"); |
128 print FH <<EndOfRif; |
113 print FH <<EndOfRif; |
129 scene= $scene |
114 scene= $scene |
130 EXPOSURE= 2 |
|
131 ZONE= Interior -$zone $zone -$zone $zone -$zone $zone |
115 ZONE= Interior -$zone $zone -$zone $zone -$zone $zone |
132 UP= Z |
116 UP= Z |
133 view= y |
117 view= y |
134 OCTREE= $oct |
118 OCTREE= $oct |
135 oconv= -f |
119 oconv= -f |
136 render= $render |
120 render= -av 0 0 0 |
|
121 INDIRECT= 0 |
|
122 QUALITY= Med |
|
123 DETAIL= Low |
|
124 VARIABILITY= Med |
137 EndOfRif |
125 EndOfRif |
138 close(FH); |
126 close(FH); |
139 |
127 |
140 exec "rad -o $raddev $opts $rif"; |
128 exec "rad -o $raddev $rif"; |
141 |
129 |
142 #EOF |
130 #EOF |