| 1 | #!/usr/bin/perl | 
| 2 | # RCSid $Id$ | 
| 3 | # | 
| 4 | # Make a nice multi-view picture of an object | 
| 5 | # Command line arguments contain materials and object files | 
| 6 | # | 
| 7 | # This is a re-write of Greg's objpict.csh and should be a drop-in | 
| 8 | # replacement, with no funcionality added or removed | 
| 9 |  | 
| 10 | use strict; | 
| 11 | use warnings; | 
| 12 |  | 
| 13 | use File::Temp qw/ tempdir /; | 
| 14 | my $td = tempdir( CLEANUP => 1 ); | 
| 15 |  | 
| 16 | my $xres = 1024; | 
| 17 | my $yres = 1024; | 
| 18 | my $rpict_cmd = "rpict -av .2 .2 .2 -x $xres -y $yres"; | 
| 19 |  | 
| 20 | my $testroom = "$td/testroom.rad"; | 
| 21 | my $octree = "$td/op.oct"; | 
| 22 |  | 
| 23 | # We need at least one Radiance file or a scene on STDIN (but not both) | 
| 24 | if ($#ARGV < 0) { | 
| 25 | open(FH, ">$td/stdin.rad") or | 
| 26 | die("objview: Can't write to temporary file $td/stdin.rad\n"); | 
| 27 | while (<>) { | 
| 28 | print FH; | 
| 29 | } | 
| 30 | # Pretend stdin.rad was passed as argument. | 
| 31 | @ARGV = ("$td/stdin.rad"); | 
| 32 | } | 
| 33 |  | 
| 34 | # Create some lights and a box as back drop. | 
| 35 | # The objects and view points will be inside the box. | 
| 36 | open(FH, ">$testroom") or | 
| 37 | die("Can\'t write to temporary file $testroom"); | 
| 38 | print FH <<EndOfTestroom; | 
| 39 | void plastic wall_mat  0  0  5  .681 .543 .686  0 .2 | 
| 40 | void light bright  0  0  3  3000 3000 3000 | 
| 41 |  | 
| 42 | bright sphere lamp0  0  0  4  4 4 -4  .1 | 
| 43 | bright sphere lamp1  0  0  4  4 0 4  .1 | 
| 44 | bright sphere lamp2  0  0  4  0 4 4  .1 | 
| 45 |  | 
| 46 | wall_mat polygon box.1540  0  0  12  5 -5 -5  5 -5 5  -5 -5 5  -5 -5 -5 | 
| 47 | wall_mat polygon box.4620  0  0  12  -5 -5 5  -5 5 5  -5 5 -5  -5 -5 -5 | 
| 48 | wall_mat polygon box.2310  0  0  12  -5 5 -5  5 5 -5  5 -5 -5  -5 -5 -5 | 
| 49 | wall_mat polygon box.3267  0  0  12  5 5 -5  -5 5 -5  -5 5 5  5 5 5 | 
| 50 | wall_mat polygon box.5137  0  0  12  5 -5 5  5 -5 -5  5 5 -5  5 5 5 | 
| 51 | wall_mat polygon box.6457  0  0  12  -5 5 5  -5 -5 5  5 -5 5  5 5 5 | 
| 52 | EndOfTestroom | 
| 53 | close(FH); | 
| 54 |  | 
| 55 | my $dimstr = `getbbox -h @ARGV`; | 
| 56 | chomp $dimstr; | 
| 57 | # Values returned by getbbox are indented and delimited with multiple spaces. | 
| 58 | $dimstr =~ s/^\s+//;   # remove leading spaces | 
| 59 | my @dims = split(/\s+/, $dimstr);   # convert to array | 
| 60 |  | 
| 61 | # Find largest axes-aligned dimension | 
| 62 | my @diffs = ($dims[1]-$dims[0], $dims[3]-$dims[2], $dims[5]-$dims[4]); | 
| 63 | @diffs = reverse sort { $a <=> $b } @diffs; | 
| 64 | my $size = $diffs[0]; | 
| 65 |  | 
| 66 | # Define the four views | 
| 67 | my $vw1 = "-vtl -vp 2 .5 .5 -vd -1 0 0 -vh 1 -vv 1"; | 
| 68 | my $vw2 = "-vtl -vp .5 2 .5 -vd 0 -1 0 -vh 1 -vv 1"; | 
| 69 | my $vw3 = "-vtl -vp .5 .5 2 -vd 0 0 -1 -vu -1 0 0 -vh 1 -vv 1"; | 
| 70 | my $vw4 = "-vp 3 3 3 -vd -1 -1 -1 -vh 20 -vv 20"; | 
| 71 |  | 
| 72 | # Move objects so centre is at origin | 
| 73 | my $xtrans = -1.0 * ($dims[0] + $dims[1]) / 2; | 
| 74 | my $ytrans = -1.0 * ($dims[2] + $dims[3]) / 2; | 
| 75 | my $ztrans = -1.0 * ($dims[4] + $dims[5]) / 2; | 
| 76 | # Scale so that largest object dimension is unity | 
| 77 | my $scale = 1 / $size; | 
| 78 |  | 
| 79 | my $cmd = "xform -t $xtrans $ytrans $ztrans -s $scale -t .5 .5 .5 @ARGV"; | 
| 80 | $cmd .= " |oconv $testroom - > $octree"; | 
| 81 | system "$cmd"; | 
| 82 |  | 
| 83 | # Render four different views of the objects | 
| 84 | system "$rpict_cmd $vw1 $octree > $td/right.hdr"; | 
| 85 | system "$rpict_cmd $vw2 $octree > $td/front.hdr"; | 
| 86 | system "$rpict_cmd $vw3 $octree > $td/down.hdr"; | 
| 87 | system "$rpict_cmd $vw4 $octree > $td/oblique.hdr"; | 
| 88 |  | 
| 89 | # Compose the four views into one image | 
| 90 | $cmd = "pcompos $td/down.hdr 0 $xres $td/oblique.hdr $xres $yres"; | 
| 91 | $cmd .= " $td/right.hdr 0 0 $td/front.hdr $xres 0"; | 
| 92 | $cmd .= " |pfilt -1 -r .6 -x /2 -y /2"; | 
| 93 | exec "$cmd"; | 
| 94 |  | 
| 95 | #EOF |