Skip to content

Commit 3f0c192

Browse files
committed
Lattice to pre-calculate and pass FaceNormals
1 parent 271a025 commit 3f0c192

File tree

3 files changed

+40
-37
lines changed

3 files changed

+40
-37
lines changed

demos/test5.p

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ my @objs = (
1818
['Lattice', {Shading=>0}],
1919
['Lattice', {Shading=>1}],
2020
['Lattice', {Shading=>2}],
21-
['Lattice', {Shading=>3, Lighting => 1}],
21+
['Lattice', {Shading=>3, Lighting => 1, ShowNormals => 1}],
2222
['Lattice', {Shading=>3, Lighting => 1, ShowNormals => 1, Smooth=>1}],
2323
);
2424
my $i = 0;

lib/PDL/Graphics/TriD/GL.pm

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -194,24 +194,39 @@ sub PDL::Graphics::TriD::Lattice::gdraw {
194194
if grep $_->ndims < 3, $points, $this->{Colors};
195195
my $options = $this->{Options};
196196
my $shading = $options->{Shading};
197+
my $faces = !defined $this->{Faceidx} ? undef : $points->clump(1..$points->ndims-1)->dice_axis(1,$this->{Faceidx}->flat)->splitdim(1,3);
198+
my $colours = !defined $this->{Faceidx} ? undef : $this->{Colors}->clump(1..$this->{Colors}->ndims-1)->dice_axis(1,$this->{Faceidx}->flat)->splitdim(1,3);
197199
if ($shading == 0) {
198200
$this->_lattice_lines($points,$this->{Colors});
199201
} else {
200202
glShadeModel($shading == 1 ? GL_FLAT : GL_SMOOTH);
201203
my $f = 'PDL::gl_triangles';
202-
$f .= '_' . ($this->{Options}{Smooth} ? 'w' : '') . 'n' if $shading > 2;
204+
$f .= '_wn' if $shading > 2;
203205
{ no strict 'refs'; $f = \&$f; }
204206
if ($shading > 2) { glColorMaterial(GL_FRONT_AND_BACK,GL_DIFFUSE); glEnable(GL_COLOR_MATERIAL); }
205-
_lattice_slice($f, $points, $this->{Options}{Smooth} ? $this->{VertexNormals} : (), $this->{Colors});
207+
my $tmpn = $shading <= 2 ? undef : $options->{Smooth}
208+
? $this->{VertexNormals}->dice_axis(1,$this->{Faceidx}->flat)
209+
->splitdim(1,$this->{Faceidx}->dim(0)) : $this->{FaceNormals}->dummy(1,3);
210+
$f->(map $_->mv(1,-1)->dog, $faces, $shading > 2 ? $tmpn : (), $colours);
206211
if ($shading > 2) { glDisable(GL_COLOR_MATERIAL); }
207-
$this->_lattice_lines($points) if $this->{Options}{Lines};
212+
$this->_lattice_lines($points) if $options->{Lines};
208213
}
209214
if ($options->{ShowNormals}) {
210-
die "No normals to show!" if !defined $this->{VertexNormals};
211-
my $arrows = $points->append($points + $this->{VertexNormals}*0.1)->splitdim(0,3);
212-
glDisable(GL_LIGHTING);
213-
glColor3d(1,1,1);
214-
PDL::Graphics::OpenGLQ::gl_arrows($arrows, 0, 1, 0.5, 0.02);
215+
die "No normals to show!" if !grep defined $this->{$_}, qw(FaceNormals VertexNormals);
216+
if (defined $this->{VertexNormals}) {
217+
my $points_clumped = $points->clump(1..$points->ndims-1);
218+
my $arrows = $points_clumped->append($points_clumped + $this->{VertexNormals}*0.1)->splitdim(0,3);
219+
glDisable(GL_LIGHTING);
220+
glColor3d(1,1,1);
221+
PDL::Graphics::OpenGLQ::gl_arrows($arrows, 0, 1, 0.5, 0.02);
222+
}
223+
if (defined $this->{FaceNormals}) {
224+
my $facecentres = $faces->transpose->avgover;
225+
my $facearrows = $facecentres->append($facecentres + $this->{FaceNormals}*0.1)->splitdim(0,3);
226+
glDisable(GL_LIGHTING);
227+
glColor3d(0.5,0.5,0.5);
228+
PDL::Graphics::OpenGLQ::gl_arrows($facearrows, 0, 1, 0.5, 0.02);
229+
}
215230
}
216231
}
217232

lib/PDL/Graphics/TriD/Objects.pm

Lines changed: 16 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -163,9 +163,13 @@ sub get_valid_options { +{
163163
}}
164164
sub 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
166169
package PDL::Graphics::TriD::Lattice;
170+
use PDL::Graphics::OpenGLQ;
167171
use base qw/PDL::Graphics::TriD::GObject/;
168-
use fields qw/VertexNormals/;
172+
use fields qw/VertexNormals Faceidx FaceNormals/;
169173
sub cdummies {
170174
my $shading = $_[0]{Options}{Shading};
171175
!$shading ? $_[1]->dummy(1)->dummy(1) :
@@ -184,34 +188,18 @@ sub get_valid_options { +{
184188
sub 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

217205
1;

0 commit comments

Comments
 (0)