shell bypass 403
=head1 NAME
PDL::Graphics::TriD::Objects - Simple Graph Objects for TriD
=head1 SYNOPSIS
Look in PDL/Demos/TkTriD_demo.pm for several examples, the code
in PDL/Demos/TriD1.pm and PDL/Demos/TriD2.pm also uses objects
but it hides them from the user.
=head1 DESCRIPTION
GObjects can be either stand-alone or in Graphs, scaled properly.
All the points used by the object must be in the member {Points}.
I guess we can afford to force data to be copied (X,Y,Z) -> (Points)...
=head1 OBJECTS
=head2 PDL::Graphics::TriD::GObject
Inherits from base PDL::Graphics::TriD::Object and adds fields Points, Colors and
Options. Need lots more here...
=cut
package PDL::Graphics::TriD::GObject;
use base qw/PDL::Graphics::TriD::Object/;
use fields qw/Points Colors Options/;
sub new {
my($type,$points,$colors,$options) = @_;
print "GObject new.. calling SUPER::new...\n" if($PDL::debug_trid);
my $this = $type->SUPER::new();
print "GObject new - back (SUPER::new returned $this)\n" if($PDL::debug_trid);
if(!defined $options and ref $colors eq "HASH") {
$options = $colors;
undef $colors;
}
print "GObject new - calling realcoords\n" if($PDL::debug_trid);
$points = PDL::Graphics::TriD::realcoords($type->r_type,$points);
print "GObject new - back from realcoords\n" if($PDL::debug_trid);
if(!defined $colors) {$colors = PDL->pdl(1,1,1);
$colors = $type->cdummies($colors,$points);
$options->{UseDefcols} = 1; # for VRML efficiency
} else {
$colors = PDL::Graphics::TriD::realcoords("COLOR",$colors);
}
$this->{Options} = $options;
$this->{Points} = $points;
$this->{Colors} = $colors;
$this->check_options();
print "GObject new - returning\n" if($PDL::debug_trid);
return $this;
}
sub check_options {
my($this) = @_;
my %newopts;
my $opts = $this->get_valid_options();
print "FETCHOPT: $this ".(join ',',%$opts)."\n" if $PDL::Graphics::TriD::verbose;
for(keys %$opts) {
if(!exists $this->{Options}{$_}) {
$newopts{$_} = $opts->{$_};
} else {
$newopts{$_} = delete $this->{Options}{$_};
}
}
if(keys %{$this->{Options}}) {
die("Invalid options left: ".(join ',',%{$this->{Options}}));
}
$this->{Options} = \%newopts;
}
sub set_colors {
my($this,$colors) = @_;
if(ref($colors) eq "ARRAY"){
$colors = PDL::Graphics::TriD::realcoords("COLOR",$colors);
}
$this->{Colors}=$colors;
$this->data_changed;
}
sub get_valid_options {
return {UseDefcols => 0};
}
sub get_points {
return $_[0]->{Points};
}
# In the future, have this happen automatically by the piddles.
sub data_changed {
my($this) = @_;
$this->changed();
}
sub cdummies {return $_[1];}
sub r_type { return ""; }
sub defcols {
return defined($_[0]->{Options}->{UseDefcols}) &&
$_[0]->{Options}->{UseDefcols};
}
1;
package PDL::Graphics::TriD::Points;
use base qw/PDL::Graphics::TriD::GObject/;
sub get_valid_options {
return {UseDefcols => 0, PointSize=> 1};
}
package PDL::Graphics::TriD::Spheres;
use base qw/PDL::Graphics::TriD::GObject/;
sub get_valid_options { # need to add radius
return {UseDefcols => 0, PointSize=> 1};
}
###########################################################################
################# JNK 15mar11 added section start #########################
# JNK 06dec00 -- edited from PDL::Graphics/TriD/GObject in file Objects.pm
# GObjects can be either stand-alone or in Graphs, scaled properly.
# All the points used by the object must be in the member {Points}.
# I guess we can afford to force data to be copied (X,Y,Z) -> (Points)...
# JNK: I don't like that last assumption for all cases..
# JNK 27nov00 new object type:
package PDL::Graphics::TriD::GPObject;
# @ISA=qw/PDL::Graphics::TriD::GObject/;
use base qw/PDL::Graphics::TriD::GObject/;
# use fields qw/.../;
sub new { my($type,$points,$faceidx,$colors,$options) = @_;
# faceidx is 2D pdl of indices into points for each face
if(!defined $options and ref $colors eq "HASH") {
$options = $colors;undef $colors; }
$points = PDL::Graphics::TriD::realcoords($type->r_type,$points);
$faces = $points->dice_axis(1,$faceidx->clump(-1))->splitdim(1,3);
# faces is 3D pdl slices of points, giving cart coords of face verts
if(!defined $colors) { $colors = PDL->pdl(1,1,1);
$colors = $type->cdummies($colors,$faces);
$options->{ UseDefcols } = 1; } # for VRML efficiency
else { $colors = PDL::Graphics::TriD::realcoords("COLOR",$colors); }
my $this = bless { Points => $points, Faceidx => $faceidx, Faces => $faces,
Colors => $colors, Options => $options},$type;
$this->check_options();return $this; }
sub get_valid_options {
return { UseDefcols=>0, Lines=>0, Smooth=>1, Material=>0 }; }
sub cdummies {
return $_[1]->dummy(1,$_[2]->getdim(2))->dummy(1,$_[2]->getdim(1)); }
# JNK 13dec00 new object type:
package PDL::Graphics::TriD::STrigrid_S;
# @ISA=qw/PDL::Graphics::TriD::GPObject/;
use base qw/PDL::Graphics::TriD::GPObject/;
# use fields qw/.../;
sub cdummies {
return $_[1]->dummy(1,$_[2]->getdim(2))->dummy(1,$_[2]->getdim(1)); }
sub get_valid_options {
return { UseDefcols=>0, Lines=>0, Smooth=>1, Material=>0 }; }
# calculate smooth normals
sub smoothn { my ($this,$ddd) = @_;
my $v=$this->{Points};my $f=$this->{Faces};my $fvi=$this->{Faceidx};
# ----------------------------------------------------------------------------
my @p = map { $f->slice(":,($_),:") } (0..(($fvi->dims)[0]-1));
# ----------------------------------------------------------------------------
# the following line assumes all faces are triangles
my $fn = ($p[1]-$p[0])->crossp($p[2]-$p[1])->norm;
# my $vfi = PDL::cat(map {PDL::cat(PDL::whichND($fvi==$_))->slice(':,(1)')}
# (0..(($v->dims)[1]-1)));
# the above, spread into several statements:
# my @vfi2=();for my $idx (0..($v->dims)[1]-1) {
# my @vfi0=PDL::whichND($fvi==$idx);
# my $vfi1=PDL::cat(@vfi0);
# $vfi2[$idx]=$vfi1->slice(':,(1)'); }
# my $vfi=PDL::cat(@vfi2);
# my $vmn = $fn->dice_axis(1,$vfi->clump(-1))->splitdim(1,($fvi->dims)[0]);
# my $vn = $vmn->mv(1,0)->sumover->norm;
# ----------------------------------------------------------------------------
my $vn=PDL::cat(
map { my $vfi=PDL::cat(PDL::whichND($fvi==$_))->slice(':,(1)');
$fn->dice_axis(1,$vfi)->mv(1,0)->sumover->norm }
(0..(($v->dims)[1]-1)) );
# ----------------------------------------------------------------------------
return $vn; }
# JNK 06dec00 new object type:
package PDL::Graphics::TriD::STrigrid;
# @ISA=qw/PDL::Graphics::TriD::GPObject/;
use base qw/PDL::Graphics::TriD::GPObject/;
# use fields qw/.../;
sub cdummies { # copied from SLattice_S; not yet modified...
# called with (type,colors,faces)
return $_[1]->dummy(1,$_[2]->getdim(2))->dummy(1,$_[2]->getdim(1)); }
sub get_valid_options { # copied from SLattice_S; not yet modified...
return { UseDefcols => 0, Lines => 1, Smooth => 0, Material => 0 }; }
################# JNK 15mar11 added section finis #########################
###########################################################################
package PDL::Graphics::TriD::Lattice;
use base qw/PDL::Graphics::TriD::GObject/;
sub r_type {return "SURF2D";}
sub cdummies { return $_[1]->dummy(1)->dummy(1); }
package PDL::Graphics::TriD::Lines;
use base qw/PDL::Graphics::TriD::GObject/;
sub cdummies { return $_[1]->dummy(1); }
sub r_type { return "SURF2D";}
sub get_valid_options { return {UseDefcols => 0, LineWidth => 1}; }
package PDL::Graphics::TriD::LineStrip;
use base qw/PDL::Graphics::TriD::GObject/;
sub cdummies { return $_[1]->dummy(1); }
sub r_type { return "SURF2D";}
sub get_valid_options { return {UseDefcols => 0, LineWidth => 1}; }
package PDL::Graphics::TriD::GObject_Lattice;
use base qw/PDL::Graphics::TriD::GObject/;
sub r_type {return "SURF2D";}
sub get_valid_options { return {UseDefcols => 0,Lines => 1}; }
# colors associated with vertices, smooth
package PDL::Graphics::TriD::SLattice;
use base qw/PDL::Graphics::TriD::GObject_Lattice/;
sub cdummies { return $_[1]->dummy(1,$_[2]->getdim(2))
-> dummy(1,$_[2]->getdim(1)); }
# colors associated with surfaces
package PDL::Graphics::TriD::SCLattice;
use base qw/PDL::Graphics::TriD::GObject_Lattice/;
sub cdummies { return $_[1]->dummy(1,$_[2]->getdim(2)-1)
-> dummy(1,$_[2]->getdim(1)-1); }
# colors associated with vertices
package PDL::Graphics::TriD::SLattice_S;
use base qw/PDL::Graphics::TriD::GObject_Lattice/;
use fields qw/Normals/;
sub cdummies { return $_[1]->dummy(1,$_[2]->getdim(2))
-> dummy(1,$_[2]->getdim(1)); }
sub get_valid_options { return {UseDefcols => 0,Lines => 1, Smooth => 0,
Material => 0}; }
# calculate smooth normals
sub smoothn {
my ($this,$p) = @_;
# coords of parallel sides (left and right via 'lags')
my $trip = $p->lags(1,1,2)->slice(':,:,:,1:-1') -
$p->lags(1,1,2)->slice(':,:,:,0:-2');
# coords of diagonals with dim 2 having original and reflected diags
my $tmp;
my $trid = ($p->slice(':,0:-2,1:-1')-$p->slice(':,1:-1,0:-2'))
->dummy(2,2);
# $ortho is a (3D,x-1,left/right triangle,y-1) array that enumerates
# all triangles
my $ortho = $trip->crossp($trid);
$ortho->norm($ortho); # normalise inplace
# now add to vertices to smooth
my $aver = ref($p)->zeroes($p->dims);
# step 1, upper right tri0, upper left tri1
($tmp=$aver->lags(1,1,2)->slice(':,:,:,1:-1')) += $ortho;
# step 2, lower right tri0, lower left tri1
($tmp=$aver->lags(1,1,2)->slice(':,:,:,0:-2')) += $ortho;
# step 3, upper left tri0
($tmp=$aver->slice(':,0:-2,1:-1')) += $ortho->slice(':,:,(0)');
# step 4, lower right tri1
($tmp=$aver->slice(':,1:-1,0:-2')) += $ortho->slice(':,:,(1)');
$aver->norm($aver);
return $aver;
}
1;