Proper handling of interlaced layers in toolpaths preview
This commit is contained in:
parent
2632b2b30e
commit
f0a57a83fd
3 changed files with 110 additions and 49 deletions
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in a new issue