bin/ltpict.pl
changeset 58 e4892d4ef026
parent 56 259ce6d95331
child 60 448b4b706fa5
equal deleted inserted replaced
57:ce1ccea91e6c 58:e4892d4ef026
     1 #!/usr/bin/perl
     1 #!/usr/bin/perl
     2 
     2 
     3 # Make a nice multi-view picture of a luminaire
     3 # Make a four-view picture of the photometry of a luminaire
     4 #
     4 #
     5 # This is based on objpict.pl that renders four-view
     5 # This is inspired by objpict.pl that renders four-view
     6 # images of objects that are not light sources.
     6 # images of objects that are not light sources.
     7 #
     7 #
     8 # Written by Axel Jacobs
     8 # Written by Axel Jacobs <axel@jaloxa.eu>
     9 
     9 
    10 use strict;
    10 use strict;
    11 use warnings;
    11 use warnings;
    12 
    12 
    13 use File::Temp qw/ tempdir /;
    13 use File::Temp qw/ tempdir /;
    14 #my $td = tempdir( CLEANUP => 1 );
    14 my $td = tempdir( CLEANUP => 1 );
    15 my $td = "tmp";
    15 use File::Copy qw(copy);
    16 
    16 
    17 #my $xres = 1024;
    17 my $res = 1024;                # Default output image dimensions
    18 #my $yres = 1024;
       
    19 my $xres = 600;
       
    20 my $yres = 600;
       
    21 my $tiny = 0.01;
    18 my $tiny = 0.01;
       
    19 my $maxsize = 0.001;           # max luminaire size after scaling
    22 my $is_ies = 0;
    20 my $is_ies = 0;
    23 my $rpict_cmd = "rpict -ab 0 -ds 0 -dv -av 0 0 0 -x $xres -y $yres";
       
    24 my $pcond_cmd = "pcond -l";
       
    25 
    21 
    26 my $ies = "$td/dist.ies";
    22 my $ies = "$td/dist.ies";
    27 my $fittings = "$td/fitting.rad";
    23 my $lumi = "$td/lumi.rad";     # Fitting as given on cmd line, or as generated by ies2rad
    28 my $material = "$td/lt.mat";
    24 my $lumi2 = "$td/lumi2.rad";   # Fitting scaled to size
    29 my $testroom1 = "$td/testroom1.rad";
    25 my $mat = "$td/lt.mat";
    30 my $testroom2 = "$td/testroom2.rad";
    26 my $room1 = "$td/room1.rad";
    31 my $testroom3 = "$td/testroom3.rad";
    27 my $room2 = "$td/room2.rad";
    32 my $testroom4 = "$td/testroom4.rad";
    28 my $room3 = "$td/room3.rad";
    33 my $octree1 = "$td/lt1.oct";
    29 my $room4 = "$td/room4.rad";
    34 my $octree2 = "$td/lt2.oct";
    30 my $oct1 = "$td/lt1.oct";
    35 my $octree3 = "$td/lt3.oct";
    31 my $oct2 = "$td/lt2.oct";
    36 my $octree4 = "$td/lt4.oct";
    32 my $oct3 = "$td/lt3.oct";
       
    33 my $oct4 = "$td/lt4.oct";
    37 
    34 
    38 # Parse command line arguments
    35 # Parse command line arguments
    39 if ("$ARGV[0]" eq '-i') {    # File is an IES file, not Radiance luminaire
    36 while ($#ARGV >= 0) {
    40 	$is_ies = 1;
    37 	$_ = $ARGV[0];
    41 	shift @ARGV;
    38 	if (m/-i/) {         # File is an IES file, not Radiance luminaire
    42 }
    39 		$is_ies = 1;
    43 # We need at least one Radiance file or a scene on STDIN (but not both)
    40 	} elsif (m/-d/) {    # Resolution of the output HDR image
    44 if ($#ARGV < 0) {
    41 		$res = $ARGV[1];
    45 	open(FH, ">$td/stdin.rad") or 
    42 		shift @ARGV;
    46 			die("objview: Can't write to temporary file $td/stdin.rad\n");
    43 
    47 	while (<>) {
    44     } elsif (m/^-/) { 	 # Oops! Illegal option
    48 		print FH;
    45         die("ltpict: bad option \"$ARGV[0]\"\n");
       
    46     } else {
       
    47 		last;    # No more options.  What's left is the actual file name.
    49 	}
    48 	}
    50 	# Pretend stdin.rad was passed as argument.
    49     shift @ARGV;
    51 	@ARGV = ("$td/stdin.rad");
       
    52 }
    50 }
    53 
    51 
       
    52 # We need one Radiance luminaire or an IES file
       
    53 if ($is_ies == 0) {
       
    54 	# Input file is a Radiance luminaire
       
    55 	copy $ARGV[0], $lumi or
       
    56 			die("ltpict: Cannot copy file '$ARGV[0]' to $lumi\n");
       
    57 } else {
       
    58 	# Input file is IES photometry
       
    59 	system "ies2rad -p $td -o lumi $ARGV[0]";
       
    60 }
    54 
    61 
    55 # Scale fitting and center at origin
    62 my $res2 = $res / 2;    # Each rendering is half the size of final composite
    56 my $dimstr = `getbbox -h @ARGV`;
    63 
       
    64 # Scale luminaire and center at origin
       
    65 my $dimstr = `getbbox -h $lumi`;
    57 chomp $dimstr;
    66 chomp $dimstr;
    58 # Values returned by getbbox are indented and delimited with multiple spaces.
    67 # Values returned by getbbox are indented and delimited with multiple spaces.
    59 $dimstr =~ s/^\s+//;   # remove leading spaces
    68 $dimstr =~ s/^\s+//;                # remove leading spaces
    60 my @dims = split(/\s+/, $dimstr);   # convert to array
    69 my @dims = split(/\s+/, $dimstr);   # convert to array
    61 
    70 
    62 # Find largest axes-aligned dimension
    71 # Find largest axes-aligned dimension
    63 my @diffs = ($dims[1]-$dims[0], $dims[3]-$dims[2], $dims[5]-$dims[4]);
    72 my @diffs = ($dims[1]-$dims[0], $dims[3]-$dims[2], $dims[5]-$dims[4]);
    64 @diffs = reverse sort { $a <=> $b } @diffs;
    73 @diffs = reverse sort { $a <=> $b } @diffs;
    65 my $size = $diffs[0];
    74 my $size = $diffs[0];
    66 
    75 
    67 # Move fitting so centre is at origin
    76 # Move luminaire so centre is at origin, and scale
    68 my $xtrans = -1.0 * ($dims[0] + $dims[1]) / 2;
    77 my $xtrans = -1.0 * ($dims[0] + $dims[1]) / 2;
    69 my $ytrans = -1.0 * ($dims[2] + $dims[3]) / 2;
    78 my $ytrans = -1.0 * ($dims[2] + $dims[3]) / 2;
    70 my $ztrans = -1.0 * ($dims[4] + $dims[5]) / 2;
    79 my $ztrans = -1.0 * ($dims[4] + $dims[5]) / 2;
    71 # Scale so that largest object dimension is unity
    80 my $scale = $maxsize / $size;
    72 my $scale = 0.001 / $size;
       
    73 
    81 
    74 my $fitting = "$td/fitting.rad";
    82 open(FH, ">$lumi2") or
    75 open(FH, ">$fitting") or
    83 		die("ltpict: Cannot write to temporary file $lumi");
    76 		die("Can\'t write to temporary file $fitting");
    84 print FH "!xform -t $xtrans $ytrans $ztrans -s $scale $lumi";
    77 print FH "!xform -t $xtrans $ytrans $ztrans -s $scale @ARGV";
       
    78 close FH;
    85 close FH;
    79 
    86 
    80 
    87 
    81 # Material for the room
    88 # Material for the room
    82 open(FH, ">$material") or
    89 open(FH, ">$mat") or
    83 		die("Can\'t write to temporary file $material");
    90 		die("ltpict: Cannot write to temporary file $mat");
    84 print FH "void plastic wall_mat  0  0  5  .5 .5 .5  0 0";
    91 print FH "void plastic wall_mat  0  0  5  .5 .5 .5  0 0";
    85 close FH;
    92 close FH;
    86 
    93 
    87 
    94 
    88 # Different 'room' geometry for different views
    95 # Different 'room' geometry for different views
    89 my $OFFSET = 0.1;
    96 my $offset = 0.1;
    90 open(FH, ">$testroom1") or die("Can't write to temporary file $testroom1");
    97 
    91 # C0-C180
    98 # C0-C180
    92 print FH "wall_mat polygon box.4620  0  0  12  -$OFFSET -5 5  -$OFFSET 5 5  -$OFFSET 5 -5  -$OFFSET -5 -5";
    99 open(FH, ">$room1") or die("ltpict: Cannot write to temporary file $room1");
       
   100 print FH "wall_mat polygon box.4620  0  0  12  -$offset -5 5  -$offset 5 5  -$offset 5 -5  -$offset -5 -5";
    93 close(FH);
   101 close(FH);
    94 
   102 
    95 open(FH, ">$testroom2") or die("Can't write to temporary file $testroom2");
       
    96 # C90-C270
   103 # C90-C270
    97 print FH "wall_mat polygon box.1540  0  0  12  5 $OFFSET -5  5 $OFFSET 5  -5 $OFFSET 5  -5 $OFFSET -5";
   104 open(FH, ">$room2") or die("ltpict: Cannot write to temporary file $room2");
       
   105 print FH "wall_mat polygon box.1540  0  0  12  5 $offset -5  5 $offset 5  -5 $offset 5  -5 $offset -5";
    98 close(FH);
   106 close(FH);
    99 
   107 
   100 open(FH, ">$testroom3") or die("Can't write to temporary file $testroom3");
       
   101 # Lower hemisphere
   108 # Lower hemisphere
       
   109 open(FH, ">$room3") or die("ltpict: Cannot write to temporary file $room3");
   102 print FH "wall_mat bubble lower  0  0  4 0 0 $dims[4] 5";
   110 print FH "wall_mat bubble lower  0  0  4 0 0 $dims[4] 5";
   103 close(FH);
   111 close(FH);
   104 
   112 
   105 open(FH, ">$testroom4") or die("Can't write to temporary file $testroom4");
       
   106 # Upper hemisphere
   113 # Upper hemisphere
       
   114 open(FH, ">$room4") or die("ltpict: Cannot write to temporary file $room4");
   107 print FH "wall_mat bubble upper  0  0  4 0 0 $dims[5] 5";
   115 print FH "wall_mat bubble upper  0  0  4 0 0 $dims[5] 5";
   108 close(FH);
   116 close(FH);
   109 
   117 
   110 
   118 
   111 # Get bbox again, for the translated and scaled fitting.
   119 # Get bbox again, for the translated and scaled luminaire.
   112 $dimstr = `getbbox -h $fitting`;
   120 $dimstr = `getbbox -h $lumi2`;
   113 chomp $dimstr;
   121 chomp $dimstr;
   114 # Values returned by getbbox are indented and delimited with multiple spaces.
   122 # Values returned by getbbox are indented and delimited with multiple spaces.
   115 $dimstr =~ s/^\s+//;   # remove leading spaces
   123 $dimstr =~ s/^\s+//;   # remove leading spaces
   116 @dims = split(/\s+/, $dimstr);   # convert to array
   124 @dims = split(/\s+/, $dimstr);   # convert to array
   117 
   125 
   121 my $zcent3 = $dims[4] - $tiny;
   129 my $zcent3 = $dims[4] - $tiny;
   122 my $vw3 = "-vta -vp 0 0 $zcent3 -vd 0 0 -1 -vu 0 1 0 -vh 180 -vv 180";
   130 my $vw3 = "-vta -vp 0 0 $zcent3 -vd 0 0 -1 -vu 0 1 0 -vh 180 -vv 180";
   123 my $zcent4 = $dims[5] + $tiny;
   131 my $zcent4 = $dims[5] + $tiny;
   124 my $vw4 = "-vta -vp 0 0 $zcent4 -vd 0 0 1 -vu 0 1 0 -vh 180 -vv 180";
   132 my $vw4 = "-vta -vp 0 0 $zcent4 -vd 0 0 1 -vu 0 1 0 -vh 180 -vv 180";
   125 
   133 
   126 system "oconv $material $testroom1 $fitting > $octree1";
   134 system "oconv $mat $room1 $lumi2 > $oct1";
   127 system "oconv $material $testroom2 $fitting > $octree2";
   135 system "oconv $mat $room2 $lumi2 > $oct2";
   128 system "oconv $material $testroom3 $fitting > $octree3";
   136 system "oconv $mat $room3 $lumi2 > $oct3";
   129 system "oconv $material $testroom4 $fitting > $octree4";
   137 system "oconv $mat $room4 $lumi2 > $oct4";
   130 
   138 
   131 # Render four different views of the objects
   139 # Render four different views of the objects
   132 system "$rpict_cmd $vw1 $octree1 > $td/right.hdr";
   140 my $rpict_cmd = "rpict -ab 0 -ds 0 -dv -av 0 0 0 -x $res2 -y $res2";
   133 system "$rpict_cmd $vw2 $octree2 > $td/front.hdr";
   141 system "$rpict_cmd $vw1 $oct1 > $td/right.hdr";
   134 system "$rpict_cmd $vw3 $octree3 > $td/down.hdr";
   142 system "$rpict_cmd $vw2 $oct2 > $td/front.hdr";
   135 system "$rpict_cmd $vw4 $octree4 > $td/up.hdr";
   143 system "$rpict_cmd $vw3 $oct3 > $td/down.hdr";
       
   144 system "$rpict_cmd $vw4 $oct4 > $td/up.hdr";
   136 
   145 
   137 # Compose the four views into one image
   146 # Compose the four views into one image
   138 my $cmd;
   147 my $vtl = "$td/vtl.hdr";     # The two parallel views
   139 my $vtl = "$td/vtl.hdr";
   148 my $vta = "$td/vta.hdr";     # The two fisheye views
   140 my $vta = "$td/vta.hdr";
       
   141 
   149 
   142 # Auto-expose right/front and down/up pairs separately
   150 # Auto-expose right/front and down/up pairs separately
   143 system "pcompos $td/right.hdr 0 0 $td/front.hdr $xres 0 > $td/rf.hdr";
   151 my $pcond_cmd = "pcond -l";
       
   152 system "pcompos -a 2 $td/right.hdr  $td/front.hdr > $td/rf.hdr";
   144 system "$pcond_cmd $td/rf.hdr > $vtl";
   153 system "$pcond_cmd $td/rf.hdr > $vtl";
   145 system "pcompos $td/down.hdr 0 0 $td/up.hdr $xres 0 > $td/du.hdr";
   154 system "pcompos -a 2 $td/down.hdr $td/up.hdr > $td/du.hdr";
   146 system "$pcond_cmd $td/du.hdr > $vta";
   155 system "$pcond_cmd $td/du.hdr > $vta";
   147 
   156 
   148 # Combine top two images with bottom row
   157 # Combine top two images with bottom row.  Output HDR.
   149 exec "pcompos -a 1 $vtl $vta";
   158 exec "pcompos -a 1 $vtl $vta";
   150 
   159 
   151 #EOF
   160 #EOF