@@ -163,9 +163,13 @@ sub get_valid_options { +{
163163}}
164164sub cdummies { $_ [1]-> dummy(1,$_ [2]-> getdim(1)); }
165165
166+ # lattice -> triangle vertices:
167+ # 4 5 6 7 -> formula: origin coords + sequence of orig size minus top+right
168+ # 0 1 2 3 4,0,1,1,5,4 5,1,2,2,6,5 6,2,3,3,7,6
166169package PDL::Graphics::TriD::Lattice ;
170+ use PDL::Graphics::OpenGLQ;
167171use base qw/ PDL::Graphics::TriD::GObject/ ;
168- use fields qw/ VertexNormals/ ;
172+ use fields qw/ VertexNormals Faceidx FaceNormals / ;
169173sub cdummies {
170174 my $shading = $_ [0]{Options }{Shading };
171175 !$shading ? $_ [1]-> dummy(1)-> dummy(1) :
@@ -184,34 +188,18 @@ sub get_valid_options { +{
184188sub new {
185189 my ($class ,$points ,$colors ,$options ) = @_ ;
186190 my $this = $class -> SUPER::new($points ,$colors ,$options );
187- $this -> {VertexNormals } //= $this -> smoothn($this -> {Points }) if $this -> {Options }{Smooth };
191+ ($points , $options ) = @$this {qw( Points Options) };
192+ if ($options -> {Shading } or $options -> {ShowNormals }) {
193+ my (undef , $x , $y , @extradims ) = $points -> dims;
194+ my $inds = PDL::ulong(0,1,$x ,$x +1,$x ,1)-> slice(' ,*' .($x -1).' ,*' .($y -1));
195+ $inds = $inds -> dupN(1,1,@extradims ) if @extradims ;
196+ my $indadd = PDL-> sequence($x ,$y ,@extradims )-> slice(' *1,:-2,:-2' );
197+ my $faceidx = $this -> {Faceidx } = ($inds + $indadd )-> splitdim(0,3)-> clump(1..3+@extradims );
198+ my ($fn , $vn ) = triangle_normals($points -> clump(1..2+@extradims ), $faceidx );
199+ $this -> {VertexNormals } = $vn if $options -> {Smooth } or $options -> {ShowNormals };
200+ $this -> {FaceNormals } = $fn if !$options -> {Smooth } or $options -> {ShowNormals };
201+ }
188202 $this ;
189203}
190- # calculate smooth normals
191- sub smoothn {
192- my ($this ,$p ) = @_ ;
193- # coords of parallel sides (left and right via 'lags')
194- my $trip = $p -> lags(1,1,2)-> slice(' :,:,:,1:-1' ) -
195- $p -> lags(1,1,2)-> slice(' :,:,:,0:-2' );
196- # coords of diagonals with dim 2 having original and reflected diags
197- my $trid = ($p -> slice(' :,0:-2,1:-1' )-$p -> slice(' :,1:-1,0:-2' ))
198- -> dummy(2,2);
199- # $ortho is a (3D,x-1,left/right triangle,y-1) array that enumerates
200- # all triangles
201- my $ortho = $trip -> crossp($trid );
202- $ortho -> norm($ortho ); # normalise inplace
203- # now add to vertices to smooth
204- my $aver = ref ($p )-> zeroes(PDL::float(), $p -> dims);
205- # step 1, upper right tri0, upper left tri1
206- $aver -> lags(1,1,2)-> slice(' :,:,:,1:-1' ) += $ortho ;
207- # step 2, lower right tri0, lower left tri1
208- $aver -> lags(1,1,2)-> slice(' :,:,:,0:-2' ) += $ortho ;
209- # step 3, upper left tri0
210- $aver -> slice(' :,0:-2,1:-1' ) += $ortho -> slice(' :,:,(0)' );
211- # step 4, lower right tri1
212- $aver -> slice(' :,1:-1,0:-2' ) += $ortho -> slice(' :,:,(1)' );
213- $aver -> norm($aver );
214- return $aver ;
215- }
216204
2172051;
0 commit comments