| 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 |