Some more unit tests for arc fitting
This commit is contained in:
parent
1d35701f99
commit
e4709068b9
2 changed files with 35 additions and 19 deletions
|
@ -6,9 +6,10 @@ use Slic3r::Geometry qw(X Y PI scale unscale epsilon scaled_epsilon deg2rad angl
|
||||||
extends 'Slic3r::GCode::Reader';
|
extends 'Slic3r::GCode::Reader';
|
||||||
has 'config' => (is => 'ro', required => 0);
|
has 'config' => (is => 'ro', required => 0);
|
||||||
has 'min_segments' => (is => 'rw', default => sub { 2 });
|
has 'min_segments' => (is => 'rw', default => sub { 2 });
|
||||||
has 'max_angle' => (is => 'rw', default => sub { deg2rad(15) });
|
has 'min_total_angle' => (is => 'rw', default => sub { deg2rad(30) });
|
||||||
has 'len_epsilon' => (is => 'rw', default => sub { scale 0.1 });
|
has 'max_relative_angle' => (is => 'rw', default => sub { deg2rad(15) });
|
||||||
has 'angle_epsilon' => (is => 'rw', default => sub { abs(deg2rad(1)) });
|
has 'len_epsilon' => (is => 'rw', default => sub { scale 0.2 });
|
||||||
|
has 'angle_epsilon' => (is => 'rw', default => sub { abs(deg2rad(10)) });
|
||||||
has '_extrusion_axis' => (is => 'lazy');
|
has '_extrusion_axis' => (is => 'lazy');
|
||||||
has '_path' => (is => 'rw');
|
has '_path' => (is => 'rw');
|
||||||
has '_cur_F' => (is => 'rw');
|
has '_cur_F' => (is => 'rw');
|
||||||
|
@ -131,22 +132,28 @@ sub detect_arcs {
|
||||||
# we need at least three points to check whether they form an arc
|
# we need at least three points to check whether they form an arc
|
||||||
if ($i < $#points) {
|
if ($i < $#points) {
|
||||||
my $len = $points[$i-1]->distance_to($points[$i]);
|
my $len = $points[$i-1]->distance_to($points[$i]);
|
||||||
my $rel_angle = angle3points(@points[$i, $i-1, $i+1]);
|
my $rel_angle = PI - angle3points(@points[$i, $i-1, $i+1]);
|
||||||
for (my $j = $i+1; $j <= $#points; ++$j) {
|
if (abs($rel_angle) <= $self->max_relative_angle) {
|
||||||
# check whether @points[($i-1)..$j] form an arc
|
for (my $j = $i+1; $j <= $#points; ++$j) {
|
||||||
last if abs($points[$j-1]->distance_to($points[$j]) - $len) > $self->len_epsilon;
|
# check whether @points[($i-1)..$j] form an arc
|
||||||
last if abs(angle3points(@points[$j-1, $j-2, $j]) - $rel_angle) > $self->angle_epsilon;
|
last if abs($points[$j-1]->distance_to($points[$j]) - $len) > $self->len_epsilon;
|
||||||
|
last if abs(PI - angle3points(@points[$j-1, $j-2, $j]) - $rel_angle) > $self->angle_epsilon;
|
||||||
$end = $j;
|
|
||||||
|
$end = $j;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (defined $end && ($end - $i + 1) >= $self->min_segments) {
|
if (defined $end && ($end - $i + 1) >= $self->min_segments) {
|
||||||
push @chunks, polyline_to_arc(Slic3r::Polyline->new(@points[($i-1)..$end]));
|
my $arc = polyline_to_arc(Slic3r::Polyline->new(@points[($i-1)..$end]));
|
||||||
|
|
||||||
# continue scanning after arc points
|
if (1||$arc->angle >= $self->min_total_angle) {
|
||||||
$i = $end;
|
push @chunks, $arc;
|
||||||
next;
|
|
||||||
|
# continue scanning after arc points
|
||||||
|
$i = $end;
|
||||||
|
next;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# if last chunk was a polyline, append to it
|
# if last chunk was a polyline, append to it
|
||||||
|
|
19
t/arcs.t
19
t/arcs.t
|
@ -2,7 +2,7 @@ use Test::More;
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
|
|
||||||
plan tests => 20;
|
plan tests => 24;
|
||||||
|
|
||||||
BEGIN {
|
BEGIN {
|
||||||
use FindBin;
|
use FindBin;
|
||||||
|
@ -44,20 +44,27 @@ use Slic3r::Geometry qw(scaled_epsilon epsilon scale unscale X Y deg2rad);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
exit;
|
|
||||||
|
|
||||||
#==========================================================
|
#==========================================================
|
||||||
|
|
||||||
{
|
{
|
||||||
my $path = Slic3r::Polyline->new(
|
my $path = Slic3r::Polyline->new_scale(
|
||||||
[135322.42,26654.96], [187029.11,99546.23], [222515.14,92381.93], [258001.16,99546.23],
|
[135322.42,26654.96], [187029.11,99546.23], [222515.14,92381.93], [258001.16,99546.23],
|
||||||
[286979.42,119083.91], [306517.1,148062.17], [313681.4,183548.2],
|
[286979.42,119083.91], [306517.1,148062.17], [313681.4,183548.2],
|
||||||
[306517.1,219034.23], [286979.42,248012.49], [258001.16,267550.17], [222515.14,274714.47],
|
[306517.1,219034.23], [286979.42,248012.49], [258001.16,267550.17], [222515.14,274714.47],
|
||||||
[187029.11,267550.17], [158050.85,248012.49], [138513.17,219034.23], [131348.87,183548.2],
|
[187029.11,267550.17], [158050.85,248012.49], [138513.17,219034.23], [131348.87,183548.2],
|
||||||
[86948.77,175149.09], [119825.35,100585],
|
[86948.77,175149.09], [119825.35,100585],
|
||||||
);
|
);
|
||||||
|
$path->scale(1/10000);
|
||||||
|
|
||||||
my $af = Slic3r::GCode::ArcFitting->new;
|
if (0) {
|
||||||
|
require "Slic3r::SVG";
|
||||||
|
Slic3r::SVG::output(
|
||||||
|
"arc.svg",
|
||||||
|
polylines => [$path],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
my $af = Slic3r::GCode::ArcFitting->new(max_relative_angle => deg2rad(30));
|
||||||
my @chunks = $af->detect_arcs($path);
|
my @chunks = $af->detect_arcs($path);
|
||||||
|
|
||||||
is scalar(@chunks), 3, 'path collection now contains three paths';
|
is scalar(@chunks), 3, 'path collection now contains three paths';
|
||||||
|
@ -66,6 +73,8 @@ exit;
|
||||||
isa_ok $chunks[2], 'Slic3r::Polyline', 'third one is polyline';
|
isa_ok $chunks[2], 'Slic3r::Polyline', 'third one is polyline';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exit;
|
||||||
|
|
||||||
#==========================================================
|
#==========================================================
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Reference in a new issue