CAD-Mesh3D
view release on metacpan or search on metacpan
t/STL-outputStl.t view on Meta::CPAN
my $mesh = createMesh();
my $tri = createFacet($lft, $mid, $rgt);
# note sprintf '%-8.8s = <%.9e,%.9e,%.9e> <%.9e,%.9e,%.9e> <%.9e,%.9e,%.9e>', floor => map { @$_ } @$tri;
push @$mesh, $tri;
$tri = createFacet($lft, $rgt, $top);
# note sprintf '%-8.8s = <%.9e,%.9e,%.9e> <%.9e,%.9e,%.9e> <%.9e,%.9e,%.9e>', front => map { @$_ } @$tri;
push @$mesh, $tri;
$tri = createFacet($rgt, $mid, $top);
# note sprintf '%-8.8s = <%.9e,%.9e,%.9e> <%.9e,%.9e,%.9e> <%.9e,%.9e,%.9e>', right => map { @$_ } @$tri;
push @$mesh, $tri;
$tri = createFacet($mid, $lft, $top);
# note sprintf '%-8.8s = <%.9e,%.9e,%.9e> <%.9e,%.9e,%.9e> <%.9e,%.9e,%.9e>', left => map { @$_ } @$tri;
push @$mesh, $tri;
# note '';
# note 'MESH:';
# note sprintf '%-8.8s <%.9e,%.9e,%.9e> <%.9e,%.9e,%.9e> <%.9e,%.9e,%.9e>', '', map { @$_ } @$_ for @$mesh;
# define the expected values for the binary tests
my $expected_ubin = qr"................................................................................................................................................................04000000........................0000000000000000000000000000003fd7b...
# expected unpacked bin. comments that follow help describe what's going on...
# "null header....................................................................................................................................................'########n1-----'n2-----'n3-----'a1-----'a2-----'a3-----'b1-----'b2-...
# if the bigendian pack fails, it will be
# "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000bf8000000000000000000000000000003f0000003f5...
# 2018-Sep-18: converted to regular expression, where the header and normal vectors can be anything (required, since I've lost control over those when I switched to using CAD::Format::STL)
# define the expected values for the ascii tests
my $exp_ascii_aref = do {
# automatically generate it: need to enforce roundoff, so match will be correct
# 2018-Sep-19: no longer need normals, since those aren't compared (cannot control whether underlying library will include normals in saves or not)
my @v = (
[0,0,0], [5.0e-1, 8.6602540e-1, 0], [1,0,0],
[0,0,0], [1,0,0], [5.0000000e-001,2.8867513e-001,8.1649658e-001],
[1.0000000e+000, 0.0000000e+000, 0.0000000e+000], [5.0000000e-001, 8.6602540e-001, 0.0000000e+000], [5.0000000e-001, 2.8867513e-001, 8.1649658e-001],
[5.0000000e-001, 8.6602540e-001, 0.0000000e+000], [0.0000000e+000, 0.0000000e+000, 0.0000000e+000], [5.0000000e-001, 2.8867513e-001, 8.1649658e-001],
);
# round the array coordinates
foreach my $i ( 0 .. $#v ) {
foreach my $j ( 0 .. 2 ) {
$v[$i][$j] = 0 + sprintf '%.8f', $v[$i][$j];
}
}
[@v];
};
# compare the expected values for the ascii tests
sub test_ascii {
my($ascii_string, $expect_aref, $test_name) = @_;
$test_name = "test_ascii::${test_name}";
note "\n", $test_name;
$ascii_string =~ s/\h+/ /gm; # normalize horizontal whitespace
$ascii_string =~ s/^\s+//gm; # trim leading whitespace on any line
$ascii_string =~ s/\s+$//gm; # trim trailing whitespace on any line
#note "-----\n", $ascii_string, "\n=====\n";
$ascii_string =~ m/^solid *(?<name>\V*?)$(?<content>.*)^endsolid *\g{name}*$/ms;
my $name = $+{name};
#note "\t", name => "\t", $name;
my $content = $+{content};
#note "\t", content => "\t", $content;
ok $content, "${test_name}: solid/endsolid has content";
my @facets = $content =~ m/^facet *(.*?)\R+^endfacet$/gms;
my $n = scalar @facets;
is $n, 4, "${test_name}: has 4 facets";
my @vectors;
foreach my $facet ( @facets ) {
#note "facet {\n", $facet, "\n}\n";
my @nv = $facet =~ m/normal (\S+) (\S+) (\S+)/gms;
#note "normal: [@nv]";
is scalar(@nv), 3, "${test_name}: facet normal has three coordinates";
$facet =~ m/^outer loop$(?<content>.*)^endloop$/ms;
$content = $+{content};
ok $content, "${test_name}: facet has loop content";
#note "\t", loop_content => "\t", $content;
my @verts = $facet =~ /^vertex \S+ \S+ \S+$/gms;
is scalar(@verts), 3, "${test_name}: facet has three vertexes";
foreach my $vstr ( @verts ) {
$vstr =~ m/\Avertex (?<x>\S+) (?<y>\S+) (?<z>\S+)\Z/ms;
my $pt = [map {0 + sprintf '%.8f', $_} @+{qw/x y z/}];
#note pt => "\t[@$pt] = $pt";
is scalar(@$pt), 3, "${test_name}: vertex has three coordinates";
push @vectors, $pt;
}
}
is scalar(@vectors), 12, "${test_name}: found a total of 12 vertices in all the facets";
is_deeply \@vectors, $expect_aref, "${test_name}: vertices ok" or diag explain \@vectors;
note "\n";
}
# loop through the mainline tests using in-memory file
foreach my $asc (undef, 0, qw(false binary bin true ascii asc), 1) {
my $memory = '';
open my $fh, '>', \$memory or die "in-memory handle failed: $!";
$mesh->output(STL => $fh, $asc);
close($fh);
my $expected;
my $is_ascii = 0;
while(1) {
my $nmesh = @$mesh;
my $count = unpack 'L<', substr($memory, 80, 4);
$is_ascii++, last unless $nmesh == $count;
my $exp_size =
+ 80 # eighty header bytes
+ 4 # four bytes for the length
+ $count * (
+ 4 # normal and three point vectors
* 3 # three values per vector
* 4 # four bytes per value
+ 2 # the trailing short (aka 'attribute byte count')
);
my $got_size = length($memory);
$is_ascii++, last unless $exp_size == $got_size;
last;
}
if($is_ascii) { # ascii
( run in 1.739 second using v1.01-cache-2.11-cpan-8f98c5d2c55 )