Proper handling of interlaced layers in toolpaths preview

This commit is contained in:
Alessandro Ranellucci 2014-07-04 01:03:41 +02:00
parent 2632b2b30e
commit f0a57a83fd
3 changed files with 110 additions and 49 deletions

View file

@ -238,7 +238,7 @@ sub make_fill {
: EXTR_ROLE_FILL),
mm3_per_mm => $mm3_per_mm,
width => $flow->width,
height => $h,
height => ($is_bridge ? $flow->width : $h),
), @polylines,
);
push @fills_ordering_points, $polylines[0]->first_point;

View file

@ -5,8 +5,8 @@ use utf8;
use List::Util qw();
use Slic3r::Geometry qw();
use Wx qw(:misc :sizer :slider);
use Wx::Event qw(EVT_SLIDER);
use Wx qw(:misc :sizer :slider :statictext);
use Wx::Event qw(EVT_SLIDER EVT_KEY_DOWN);
use base 'Wx::Panel';
sub new {
@ -17,19 +17,10 @@ sub new {
# init print
$self->{print} = $print;
$self->{layers} = {}; # print_z => [ layer*, layer* ... ]
foreach my $object (@{$print->objects}) {
foreach my $layer (@{$object->layers}, @{$object->support_layers}) {
$self->{layers}{$layer->print_z} //= [];
push @{ $self->{layers}{$layer->print_z} }, $layer;
}
}
$self->{layers_z} = [ sort { $a <=> $b } keys %{$self->{layers}} ]; # [ z, z ... ]
$self->reload_print;
# init GUI elements
my $sizer = Wx::BoxSizer->new(wxHORIZONTAL);
my $canvas = $self->{canvas} = Slic3r::GUI::Plater::2DToolpaths::Canvas->new($self, $print);
$sizer->Add($canvas, 1, wxALL | wxEXPAND, 10);
my $slider = $self->{slider} = Wx::Slider->new(
$self, -1,
0, # default
@ -39,22 +30,62 @@ sub new {
wxDefaultSize,
wxVERTICAL | wxSL_INVERSE,
);
$sizer->Add($slider, 0, wxALL | wxEXPAND, 10);
my $z_label = $self->{z_label} = Wx::StaticText->new($self, -1, "", wxDefaultPosition,
[40,-1], wxALIGN_CENTRE_HORIZONTAL);
$z_label->SetFont($Slic3r::GUI::small_font);
my $vsizer = Wx::BoxSizer->new(wxVERTICAL);
$vsizer->Add($slider, 1, wxALL | wxEXPAND | wxALIGN_CENTER, 3);
$vsizer->Add($z_label, 0, wxALL | wxEXPAND | wxALIGN_CENTER, 3);
my $sizer = Wx::BoxSizer->new(wxHORIZONTAL);
$sizer->Add($canvas, 1, wxALL | wxEXPAND, 0);
$sizer->Add($vsizer, 0, wxTOP | wxBOTTOM | wxEXPAND, 5);
EVT_SLIDER($self, $slider, sub {
my $z = $self->{layers_z}[$slider->GetValue];
$canvas->set_layers($self->{layers}{$z});
$self->set_z($self->{layers_z}[$slider->GetValue]);
});
EVT_KEY_DOWN($canvas, sub {
my ($s, $event) = @_;
my $key = $event->GetKeyCode;
if ($key == 85 || $key == 315) {
$slider->SetValue($slider->GetValue + 1);
$self->set_z($self->{layers_z}[$slider->GetValue]);
} elsif ($key == 68 || $key == 317) {
$slider->SetValue($slider->GetValue - 1);
$self->set_z($self->{layers_z}[$slider->GetValue]);
}
});
$self->SetSizer($sizer);
$self->SetMinSize($self->GetSize);
$sizer->SetSizeHints($self);
$canvas->set_layers($self->{layers}{ $self->{layers_z}[0] });
$self->set_z($self->{layers_z}[0]);
return $self;
}
sub reload_print {
my ($self) = @_;
my %z = (); # z => 1
foreach my $object (@{$self->{print}->objects}) {
foreach my $layer (@{$object->layers}, @{$object->support_layers}) {
$z{$layer->print_z} = 1;
}
}
$self->{layers_z} = [ sort { $a <=> $b } keys %z ];
}
sub set_z {
my ($self, $z) = @_;
$self->{z_label}->SetLabel(sprintf '%.2f', $z);
$self->{canvas}->set_z($z);
}
package Slic3r::GUI::Plater::2DToolpaths::Canvas;
@ -62,10 +93,10 @@ use Wx::Event qw(EVT_PAINT EVT_SIZE EVT_ERASE_BACKGROUND EVT_IDLE EVT_MOUSEWHEEL
use OpenGL qw(:glconstants :glfunctions :glufunctions);
use base qw(Wx::GLCanvas Class::Accessor);
use Wx::GLCanvas qw(:all);
use List::Util qw(min);
use Slic3r::Geometry qw(scale unscale);
use List::Util qw(min first);
use Slic3r::Geometry qw(scale unscale epsilon);
__PACKAGE__->mk_accessors(qw(print layers init dirty bb));
__PACKAGE__->mk_accessors(qw(print z layers color init dirty bb));
# make OpenGL::Array thread-safe
{
@ -95,10 +126,32 @@ sub new {
return $self;
}
sub set_layers {
my ($self, $layers) = @_;
sub set_z {
my ($self, $z) = @_;
$self->layers($layers);
my $print = $self->print;
# can we have interlaced layers?
my $interlaced = (defined first { $_->config->support_material } @{$print->objects})
|| (defined first { $_->config->infill_every_layers > 1 } @{$print->regions});
my $max_layer_height = $print->max_layer_height;
my @layers = ();
foreach my $object (@{$print->objects}) {
foreach my $layer (@{$object->layers}, @{$object->support_layers}) {
if ($interlaced) {
push @layers, $layer
if $z > ($layer->print_z - $max_layer_height - epsilon)
&& $z <= $layer->print_z + epsilon;
} else {
push @layers, $layer if abs($layer->print_z - $z) < epsilon;
}
}
}
$self->z($z);
$self->layers([ @layers ]);
$self->dirty(1);
}
@ -136,18 +189,19 @@ sub Render {
foreach my $layer (@{$self->layers}) {
my $object = $layer->object;
my $print_z = $layer->print_z;
foreach my $layerm (@{$layer->regions}) {
glColor3f(0.7, 0, 0);
$self->_draw_extrusionpath($object, $_) for @{$layerm->perimeters};
$self->color([0.7, 0, 0]);
$self->_draw($object, $print_z, $_) for @{$layerm->perimeters};
glColor3f(0, 0, 0.7);
$self->_draw_extrusionpath($object, $_) for map @$_, @{$layerm->fills};
$self->color([0, 0, 0.7]);
$self->_draw($object, $print_z, $_) for map @$_, @{$layerm->fills};
}
if ($layer->isa('Slic3r::Layer::Support')) {
glColor3f(0, 0, 0);
$self->_draw_extrusionpath($object, $_) for @{$layer->support_fills};
$self->_draw_extrusionpath($object, $_) for @{$layer->support_interface_fills};
$self->color([0, 0, 0]);
$self->_draw($object, $print_z, $_) for @{$layer->support_fills};
$self->_draw($object, $print_z, $_) for @{$layer->support_interface_fills};
}
}
@ -155,16 +209,30 @@ sub Render {
$self->SwapBuffers;
}
sub _draw_extrusionpath {
my ($self, $object, $path) = @_;
sub _draw {
my ($self, $object, $print_z, $path) = @_;
my $polyline = $path->isa('Slic3r::ExtrusionLoop')
? $path->polygon->split_at_first_point
: $path->polyline;
my @paths = $path->isa('Slic3r::ExtrusionLoop')
? @$path
: ($path);
$self->_draw_path($object, $print_z, $_) for @paths;
}
sub _draw_path {
my ($self, $object, $print_z, $path) = @_;
return if $print_z - $path->height > $self->z - epsilon;
if (abs($print_z - $self->z) < epsilon) {
glColor3f(@{$self->color});
} else {
glColor3f(0.8, 0.8, 0.8);
}
glLineWidth(1);
foreach my $copy (@{ $object->_shifted_copies }) {
foreach my $line (@{$polyline->lines}) {
foreach my $line (@{$path->polyline->lines}) {
$line->translate(@$copy);
glBegin(GL_LINES);
glVertex2f(@{$line->a});
@ -180,8 +248,6 @@ sub InitGL {
return if $self->init;
return unless $self->GetContext;
$self->init(1);
}
sub GetContext {
@ -211,17 +277,7 @@ sub Resize {
$self->dirty(0);
$self->SetCurrent($self->GetContext);
my ($x1, $y1, $x2, $y2) = (0, 0, $x, $y);
if (0 && $x > $y) {
$x2 = $y;
$x1 = ($x - $y)/2;
}
if (0 && $y > $x) {
$y2 = $x;
$y1 = ($y - $x)/2;
}
glViewport($x1, $y1, $x2, $y2);
glViewport(0, 0, $x, $y);
}
sub line {

View file

@ -350,6 +350,11 @@ sub regions_count {
return scalar @{$self->regions};
}
sub max_layer_height {
my ($self) = @_;
return max(@{$self->config->nozzle_diameter});
}
sub bounding_box {
my $self = shift;