mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-03 03:10:37 +08:00
Menu option for coloring toolpaths by extruder using the configured filament colors
This commit is contained in:
parent
a19cc10b8e
commit
9dbe2eea37
@ -75,6 +75,7 @@ our $Settings = {
|
||||
# If set, the "Controller" tab for the control of the printer over serial line and the serial port settings are hidden.
|
||||
no_controller => 0,
|
||||
threads => $Slic3r::Config::Options->{threads}{default},
|
||||
color_toolpaths_by => 'role',
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -748,10 +748,10 @@ sub InitGL {
|
||||
# Enables Smooth Color Shading; try GL_FLAT for (lack of) fun.
|
||||
glShadeModel(GL_SMOOTH);
|
||||
|
||||
glMaterialfv_p(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, 0.5, 0.3, 0.3, 1);
|
||||
glMaterialfv_p(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, 0.3, 0.3, 0.3, 1);
|
||||
glMaterialfv_p(GL_FRONT_AND_BACK, GL_SPECULAR, 1, 1, 1, 1);
|
||||
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 50);
|
||||
glMaterialfv_p(GL_FRONT_AND_BACK, GL_EMISSION, 0.1, 0, 0, 0.9);
|
||||
glMaterialfv_p(GL_FRONT_AND_BACK, GL_EMISSION, 0.1, 0.1, 0.1, 0.9);
|
||||
|
||||
# A handy trick -- have surface material mirror the color.
|
||||
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
|
||||
@ -1152,21 +1152,25 @@ use List::Util qw(first min max);
|
||||
use Slic3r::Geometry qw(scale unscale epsilon);
|
||||
use Slic3r::Print::State ':steps';
|
||||
|
||||
use constant COLORS => [ [1,1,0,1], [1,0.5,0.5,1], [0.5,1,0.5,1], [0.5,0.5,1,1] ];
|
||||
|
||||
__PACKAGE__->mk_accessors(qw(
|
||||
colors
|
||||
color_by
|
||||
color_toolpaths_by
|
||||
select_by
|
||||
drag_by
|
||||
volumes_by_object
|
||||
_objects_by_volumes
|
||||
));
|
||||
|
||||
sub default_colors { [1,0.95,0.2,1], [1,0.45,0.45,1], [0.5,1,0.5,1], [0.5,0.5,1,1] }
|
||||
|
||||
sub new {
|
||||
my $class = shift;
|
||||
|
||||
my $self = $class->SUPER::new(@_);
|
||||
$self->colors([ $self->default_colors ]);
|
||||
$self->color_by('volume'); # object | volume
|
||||
$self->color_toolpaths_by('role'); # role | extruder
|
||||
$self->select_by('object'); # object | volume | instance
|
||||
$self->drag_by('instance'); # object | instance
|
||||
$self->volumes_by_object({}); # obj_idx => [ volume_idx, volume_idx ... ]
|
||||
@ -1204,7 +1208,7 @@ sub load_object {
|
||||
$color_idx = $obj_idx;
|
||||
}
|
||||
|
||||
my $color = [ @{COLORS->[ $color_idx % scalar(@{&COLORS}) ]} ];
|
||||
my $color = [ @{$self->colors->[ $color_idx % scalar(@{$self->colors}) ]} ];
|
||||
$color->[3] = $volume->modifier ? 0.5 : 1;
|
||||
push @{$self->volumes}, my $v = Slic3r::GUI::3DScene::Volume->new(
|
||||
bounding_box => $mesh->bounding_box,
|
||||
@ -1281,7 +1285,7 @@ sub load_print_object_slices {
|
||||
|
||||
push @{$self->volumes}, my $v = Slic3r::GUI::3DScene::Volume->new(
|
||||
bounding_box => $bb,
|
||||
color => COLORS->[0],
|
||||
color => $self->colors->[0],
|
||||
verts => OpenGL::Array->new_list(GL_FLOAT, @verts),
|
||||
norms => OpenGL::Array->new_list(GL_FLOAT, @norms),
|
||||
quad_verts => OpenGL::Array->new_list(GL_FLOAT, @quad_verts),
|
||||
@ -1299,66 +1303,75 @@ sub load_print_toolpaths {
|
||||
&& $print->config->interior_brim_width == 0
|
||||
&& $print->config->brim_connections_width == 0;
|
||||
|
||||
my $qverts = Slic3r::GUI::_3DScene::GLVertexArray->new;
|
||||
my $tverts = Slic3r::GUI::_3DScene::GLVertexArray->new;
|
||||
my %offsets = (); # print_z => [ qverts, tverts ]
|
||||
|
||||
my $skirt_height = 0; # number of layers
|
||||
if ($print->has_infinite_skirt) {
|
||||
$skirt_height = $print->total_layer_count;
|
||||
} else {
|
||||
$skirt_height = min($print->config->skirt_height, $print->total_layer_count);
|
||||
}
|
||||
$skirt_height ||= 1 if $print->config->brim_width > 0 || $print->config->interior_brim_width;
|
||||
|
||||
# get first $skirt_height layers (maybe this should be moved to a PrintObject method?)
|
||||
my $object0 = $print->get_object(0);
|
||||
my @layers = ();
|
||||
push @layers, map $object0->get_layer($_-1), 1..min($skirt_height, $object0->layer_count);
|
||||
push @layers, map $object0->get_support_layer($_-1), 1..min($skirt_height, $object0->support_layer_count);
|
||||
@layers = sort { $a->print_z <=> $b->print_z } @layers;
|
||||
@layers = @layers[0..($skirt_height-1)];
|
||||
|
||||
foreach my $i (0..($skirt_height-1)) {
|
||||
my $top_z = $layers[$i]->print_z;
|
||||
$offsets{$top_z} = [$qverts->size, $tverts->size];
|
||||
|
||||
if ($i == 0) {
|
||||
$self->_extrusionentity_to_verts($print->brim, $top_z, Slic3r::Point->new(0,0), $qverts, $tverts);
|
||||
}
|
||||
|
||||
$self->_extrusionentity_to_verts($print->skirt, $top_z, Slic3r::Point->new(0,0), $qverts, $tverts);
|
||||
}
|
||||
|
||||
my $bb = Slic3r::Geometry::BoundingBoxf3->new;
|
||||
{
|
||||
my $pbb = $print->bounding_box;
|
||||
$bb->merge_point(Slic3r::Pointf3->new_unscale(@{$pbb->min_point}));
|
||||
$bb->merge_point(Slic3r::Pointf3->new_unscale(@{$pbb->max_point}));
|
||||
}
|
||||
push @{$self->volumes}, Slic3r::GUI::3DScene::Volume->new(
|
||||
bounding_box => $bb,
|
||||
color => COLORS->[2],
|
||||
qverts => $qverts,
|
||||
tverts => $tverts,
|
||||
offsets => { %offsets },
|
||||
);
|
||||
|
||||
my $color_by_extruder = $self->color_toolpaths_by eq 'extruder';
|
||||
|
||||
if (!$print->brim->empty) {
|
||||
my $color = $color_by_extruder
|
||||
? $self->colors->[ ($print->brim_extruder-1) % @{$self->colors} ]
|
||||
: $self->colors->[2];
|
||||
|
||||
push @{$self->volumes}, my $volume = Slic3r::GUI::3DScene::Volume->new(
|
||||
bounding_box => $bb,
|
||||
color => $color,
|
||||
qverts => Slic3r::GUI::_3DScene::GLVertexArray->new,
|
||||
tverts => Slic3r::GUI::_3DScene::GLVertexArray->new,
|
||||
offsets => {}, # print_z => [ qverts, tverts ]
|
||||
);
|
||||
|
||||
my $top_z = $print->get_object(0)->get_layer(0)->print_z;
|
||||
$volume->offsets->{$top_z} = [0, 0];
|
||||
$self->_extrusionentity_to_verts($print->brim, $top_z, Slic3r::Point->new(0,0),
|
||||
$volume->qverts, $volume->tverts);
|
||||
}
|
||||
|
||||
if (!$print->skirt->empty) {
|
||||
# TODO: it's a bit difficult to predict skirt extruders with the current skirt logic.
|
||||
# We need to rewrite it anyway.
|
||||
my $color = +($self->default_colors)[0];
|
||||
push @{$self->volumes}, my $volume = Slic3r::GUI::3DScene::Volume->new(
|
||||
bounding_box => $bb,
|
||||
color => $color,
|
||||
qverts => Slic3r::GUI::_3DScene::GLVertexArray->new,
|
||||
tverts => Slic3r::GUI::_3DScene::GLVertexArray->new,
|
||||
offsets => {}, # print_z => [ qverts, tverts ]
|
||||
);
|
||||
|
||||
my $skirt_height = 0; # number of layers
|
||||
if ($print->has_infinite_skirt) {
|
||||
$skirt_height = $print->total_layer_count;
|
||||
} else {
|
||||
$skirt_height = min($print->config->skirt_height, $print->total_layer_count);
|
||||
}
|
||||
$skirt_height ||= 1 if $print->config->brim_width > 0 || $print->config->interior_brim_width;
|
||||
|
||||
# get first $skirt_height layers (maybe this should be moved to a PrintObject method?)
|
||||
my $object0 = $print->get_object(0);
|
||||
my @layers = ();
|
||||
push @layers, map $object0->get_layer($_-1), 1..min($skirt_height, $object0->layer_count);
|
||||
push @layers, map $object0->get_support_layer($_-1), 1..min($skirt_height, $object0->support_layer_count);
|
||||
@layers = sort { $a->print_z <=> $b->print_z } @layers;
|
||||
@layers = @layers[0..($skirt_height-1)];
|
||||
|
||||
foreach my $i (0..($skirt_height-1)) {
|
||||
my $top_z = $layers[$i]->print_z;
|
||||
$volume->offsets->{$top_z} = [$volume->qverts->size, $volume->tverts->size];
|
||||
|
||||
$self->_extrusionentity_to_verts($print->skirt, $top_z, Slic3r::Point->new(0,0),
|
||||
$volume->qverts, $volume->tverts);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub load_print_object_toolpaths {
|
||||
my ($self, $object) = @_;
|
||||
|
||||
my $perim_qverts = Slic3r::GUI::_3DScene::GLVertexArray->new;
|
||||
my $perim_tverts = Slic3r::GUI::_3DScene::GLVertexArray->new;
|
||||
my $infill_qverts = Slic3r::GUI::_3DScene::GLVertexArray->new;
|
||||
my $infill_tverts = Slic3r::GUI::_3DScene::GLVertexArray->new;
|
||||
my $support_qverts = Slic3r::GUI::_3DScene::GLVertexArray->new;
|
||||
my $support_tverts = Slic3r::GUI::_3DScene::GLVertexArray->new;
|
||||
|
||||
my %perim_offsets = (); # print_z => [ qverts, tverts ]
|
||||
my %infill_offsets = ();
|
||||
my %support_offsets = ();
|
||||
|
||||
# order layers by print_z
|
||||
my @layers = sort { $a->print_z <=> $b->print_z }
|
||||
@{$object->layers}, @{$object->support_layers};
|
||||
@ -1375,121 +1388,90 @@ sub load_print_object_toolpaths {
|
||||
}
|
||||
}
|
||||
|
||||
my %volumes = (); # color => Volume
|
||||
|
||||
# Maximum size of an allocation block: 32MB / sizeof(float)
|
||||
my $alloc_size_max = 32 * 1048576 / 4;
|
||||
|
||||
my $add = sub {
|
||||
my ($coll, $top_z, $copy, $color) = @_;
|
||||
|
||||
my $volume = $volumes{$color};
|
||||
if (!$volume) {
|
||||
push @{$self->volumes}, $volumes{$color} = $volume = Slic3r::GUI::3DScene::Volume->new(
|
||||
bounding_box => $bb,
|
||||
color => $color,
|
||||
qverts => Slic3r::GUI::_3DScene::GLVertexArray->new,
|
||||
tverts => Slic3r::GUI::_3DScene::GLVertexArray->new,
|
||||
offsets => {}, # print_z => [ qverts, tverts ]
|
||||
);
|
||||
}
|
||||
|
||||
$volume->offsets->{$top_z} //= [ $volume->qverts->size, $volume->tverts->size ];
|
||||
$self->_extrusionentity_to_verts($coll, $top_z, $copy, $volume->qverts, $volume->tverts);
|
||||
};
|
||||
|
||||
my $color_by_extruder = $self->color_toolpaths_by eq 'extruder';
|
||||
|
||||
foreach my $layer (@layers) {
|
||||
my $top_z = $layer->print_z;
|
||||
|
||||
if (!exists $perim_offsets{$top_z}) {
|
||||
$perim_offsets{$top_z} = [
|
||||
$perim_qverts->size, $perim_tverts->size,
|
||||
];
|
||||
}
|
||||
if (!exists $infill_offsets{$top_z}) {
|
||||
$infill_offsets{$top_z} = [
|
||||
$infill_qverts->size, $infill_tverts->size,
|
||||
];
|
||||
}
|
||||
if (!exists $support_offsets{$top_z}) {
|
||||
$support_offsets{$top_z} = [
|
||||
$support_qverts->size, $support_tverts->size,
|
||||
];
|
||||
}
|
||||
|
||||
foreach my $copy (@{ $object->_shifted_copies }) {
|
||||
foreach my $layerm (@{$layer->regions}) {
|
||||
if ($object->step_done(STEP_PERIMETERS)) {
|
||||
$self->_extrusionentity_to_verts($layerm->perimeters, $top_z, $copy,
|
||||
$perim_qverts, $perim_tverts);
|
||||
my $color = $color_by_extruder
|
||||
? $self->colors->[ ($layerm->region->config->perimeter_extruder-1) % @{$self->colors} ]
|
||||
: $self->colors->[0];
|
||||
$add->($layerm->perimeters, $top_z, $copy, $color);
|
||||
}
|
||||
|
||||
if ($object->step_done(STEP_INFILL)) {
|
||||
$self->_extrusionentity_to_verts($layerm->fills, $top_z, $copy,
|
||||
$infill_qverts, $infill_tverts);
|
||||
my $color = $color_by_extruder
|
||||
? $self->colors->[ ($layerm->region->config->infill_extruder-1) % @{$self->colors} ]
|
||||
: $self->colors->[1];
|
||||
|
||||
if ($color_by_extruder && $layerm->region->config->infill_extruder != $layerm->region->config->solid_infill_extruder) {
|
||||
# divide solid and non-solid infill
|
||||
my $solid = Slic3r::ExtrusionPath::Collection->new;
|
||||
my $non_solid = Slic3r::ExtrusionPath::Collection->new;
|
||||
foreach my $fill (@{$layerm->fills}) {
|
||||
if ($fill->[0]->is_solid_infill) {
|
||||
$solid->append($fill);
|
||||
} else {
|
||||
$non_solid->append($fill);
|
||||
}
|
||||
}
|
||||
$add->($non_solid, $top_z, $copy, $color);
|
||||
$color = $self->colors->[ ($layerm->region->config->solid_infill_extruder-1) % @{&COLORS} ];
|
||||
$add->($solid, $top_z, $copy, $color);
|
||||
} else {
|
||||
$add->($layerm->fills, $top_z, $copy, $color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($layer->isa('Slic3r::Layer::Support') && $object->step_done(STEP_SUPPORTMATERIAL)) {
|
||||
$self->_extrusionentity_to_verts($layer->support_fills, $top_z, $copy,
|
||||
$support_qverts, $support_tverts);
|
||||
|
||||
$self->_extrusionentity_to_verts($layer->support_interface_fills, $top_z, $copy,
|
||||
$support_qverts, $support_tverts);
|
||||
{
|
||||
my $color = $color_by_extruder
|
||||
? $self->colors->[ ($layer->object->config->support_material_extruder-1) % @{$self->colors} ]
|
||||
: $self->colors->[2];
|
||||
$add->($layer->support_fills, $top_z, $copy, $color);
|
||||
}
|
||||
{
|
||||
my $color = ($color_by_extruder)
|
||||
? $self->colors->[ ($layer->object->config->support_material_interface_extruder-1) % @{$self->colors} ]
|
||||
: $self->colors->[2];
|
||||
$add->($layer->support_interface_fills, $top_z, $copy, $color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($perim_qverts->size() > $alloc_size_max || $perim_tverts->size() > $alloc_size_max) {
|
||||
# Store the vertex arrays and restart their containers.
|
||||
push @{$self->volumes}, Slic3r::GUI::3DScene::Volume->new(
|
||||
bounding_box => $bb,
|
||||
color => COLORS->[0],
|
||||
qverts => $perim_qverts,
|
||||
tverts => $perim_tverts,
|
||||
offsets => { %perim_offsets },
|
||||
);
|
||||
$perim_qverts = Slic3r::GUI::_3DScene::GLVertexArray->new;
|
||||
$perim_tverts = Slic3r::GUI::_3DScene::GLVertexArray->new;
|
||||
%perim_offsets = ();
|
||||
foreach my $color (keys %volumes) {
|
||||
my $volume = $volumes{$color};
|
||||
if ($volume->qverts->size() > $alloc_size_max || $volume->tverts->size() > $alloc_size_max) {
|
||||
# stop appending to this volume; create a new one next time
|
||||
delete $volumes{$color};
|
||||
}
|
||||
}
|
||||
|
||||
if ($infill_qverts->size() > $alloc_size_max || $infill_tverts->size() > $alloc_size_max) {
|
||||
# Store the vertex arrays and restart their containers.
|
||||
push @{$self->volumes}, Slic3r::GUI::3DScene::Volume->new(
|
||||
bounding_box => $bb,
|
||||
color => COLORS->[1],
|
||||
qverts => $infill_qverts,
|
||||
tverts => $infill_tverts,
|
||||
offsets => { %infill_offsets },
|
||||
);
|
||||
$infill_qverts = Slic3r::GUI::_3DScene::GLVertexArray->new;
|
||||
$infill_tverts = Slic3r::GUI::_3DScene::GLVertexArray->new;
|
||||
%infill_offsets = ();
|
||||
}
|
||||
|
||||
if ($support_qverts->size() > $alloc_size_max || $support_tverts->size() > $alloc_size_max) {
|
||||
# Store the vertex arrays and restart their containers.
|
||||
push @{$self->volumes}, Slic3r::GUI::3DScene::Volume->new(
|
||||
bounding_box => $bb,
|
||||
color => COLORS->[2],
|
||||
qverts => $support_qverts,
|
||||
tverts => $support_tverts,
|
||||
offsets => { %support_offsets },
|
||||
);
|
||||
$support_qverts = Slic3r::GUI::_3DScene::GLVertexArray->new;
|
||||
$support_tverts = Slic3r::GUI::_3DScene::GLVertexArray->new;
|
||||
%support_offsets = ();
|
||||
}
|
||||
}
|
||||
|
||||
if ($perim_qverts->size() > 0 || $perim_tverts->size() > 0) {
|
||||
push @{$self->volumes}, Slic3r::GUI::3DScene::Volume->new(
|
||||
bounding_box => $bb,
|
||||
color => COLORS->[0],
|
||||
qverts => $perim_qverts,
|
||||
tverts => $perim_tverts,
|
||||
offsets => { %perim_offsets },
|
||||
);
|
||||
}
|
||||
|
||||
if ($infill_qverts->size() > 0 || $infill_tverts->size() > 0) {
|
||||
push @{$self->volumes}, Slic3r::GUI::3DScene::Volume->new(
|
||||
bounding_box => $bb,
|
||||
color => COLORS->[1],
|
||||
qverts => $infill_qverts,
|
||||
tverts => $infill_tverts,
|
||||
offsets => { %infill_offsets },
|
||||
);
|
||||
}
|
||||
|
||||
if ($support_qverts->size() > 0 || $support_tverts->size() > 0) {
|
||||
push @{$self->volumes}, Slic3r::GUI::3DScene::Volume->new(
|
||||
bounding_box => $bb,
|
||||
color => COLORS->[2],
|
||||
qverts => $support_qverts,
|
||||
tverts => $support_tverts,
|
||||
offsets => { %support_offsets },
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -303,6 +303,32 @@ sub _init_menubar {
|
||||
$self->_append_menu_item($self->{viewMenu}, "Rear" , 'Rear View' , sub { $self->select_view('rear' ); });
|
||||
$self->_append_menu_item($self->{viewMenu}, "Left" , 'Left View' , sub { $self->select_view('left' ); });
|
||||
$self->_append_menu_item($self->{viewMenu}, "Right" , 'Right View' , sub { $self->select_view('right' ); });
|
||||
$self->{viewMenu}->AppendSeparator();
|
||||
$self->{color_toolpaths_by_role} = $self->_append_menu_item($self->{viewMenu},
|
||||
"Color Toolpaths by Role",
|
||||
'Color toolpaths according to perimeter/infill/support material',
|
||||
sub {
|
||||
$Slic3r::GUI::Settings->{_}{color_toolpaths_by} = 'role';
|
||||
wxTheApp->save_settings;
|
||||
$self->{plater}{preview3D}->reload_print;
|
||||
},
|
||||
undef, undef, wxITEM_RADIO
|
||||
);
|
||||
$self->{color_toolpaths_by_extruder} = $self->_append_menu_item($self->{viewMenu},
|
||||
"Color Toolpaths by Filament",
|
||||
'Color toolpaths using the configured extruder/filament color',
|
||||
sub {
|
||||
$Slic3r::GUI::Settings->{_}{color_toolpaths_by} = 'extruder';
|
||||
wxTheApp->save_settings;
|
||||
$self->{plater}{preview3D}->reload_print;
|
||||
},
|
||||
undef, undef, wxITEM_RADIO
|
||||
);
|
||||
if ($Slic3r::GUI::Settings->{_}{color_toolpaths_by} eq 'role') {
|
||||
$self->{color_toolpaths_by_role}->Check(1);
|
||||
} else {
|
||||
$self->{color_toolpaths_by_extruder}->Check(1);
|
||||
}
|
||||
}
|
||||
|
||||
# Help menu
|
||||
@ -800,10 +826,10 @@ sub select_view {
|
||||
}
|
||||
|
||||
sub _append_menu_item {
|
||||
my ($self, $menu, $string, $description, $cb, $id, $icon) = @_;
|
||||
my ($self, $menu, $string, $description, $cb, $id, $icon, $kind) = @_;
|
||||
|
||||
$id //= &Wx::NewId();
|
||||
my $item = $menu->Append($id, $string, $description);
|
||||
my $item = $menu->Append($id, $string, $description, $kind);
|
||||
$self->_set_menu_item_icon($item, $icon);
|
||||
|
||||
EVT_MENU($self, $id, $cb);
|
||||
|
@ -50,7 +50,7 @@ sub new {
|
||||
my $self = $class->SUPER::new($parent, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
|
||||
$self->{config} = Slic3r::Config->new_from_defaults(qw(
|
||||
bed_shape complete_objects extruder_clearance_radius skirts skirt_distance brim_width
|
||||
serial_port serial_speed octoprint_host octoprint_apikey
|
||||
serial_port serial_speed octoprint_host octoprint_apikey filament_colour
|
||||
));
|
||||
$self->{model} = Slic3r::Model->new;
|
||||
$self->{print} = Slic3r::Print->new;
|
||||
@ -90,7 +90,7 @@ sub new {
|
||||
$menu->Destroy;
|
||||
};
|
||||
my $on_instances_moved = sub {
|
||||
$self->update;
|
||||
$self->on_model_change;
|
||||
};
|
||||
|
||||
# Initialize 3D plater
|
||||
@ -374,7 +374,7 @@ sub new {
|
||||
if ($self->{preview3D}) {
|
||||
$self->{preview3D}->set_bed_shape($self->{config}->bed_shape);
|
||||
}
|
||||
$self->update;
|
||||
$self->on_model_change;
|
||||
|
||||
{
|
||||
my $presets;
|
||||
@ -522,13 +522,12 @@ sub _on_select_preset {
|
||||
$Slic3r::GUI::Settings->{presets}{"filament_${_}"} = $choice->GetString($filament_presets[$_])
|
||||
for 1 .. $#filament_presets;
|
||||
wxTheApp->save_settings;
|
||||
return;
|
||||
} else {
|
||||
# call GetSelection() in scalar context as it's context-aware
|
||||
$self->{on_select_preset}->($group, scalar $choice->GetSelection)
|
||||
if $self->{on_select_preset};
|
||||
}
|
||||
|
||||
# call GetSelection() in scalar context as it's context-aware
|
||||
$self->{on_select_preset}->($group, scalar $choice->GetSelection)
|
||||
if $self->{on_select_preset};
|
||||
|
||||
# get new config and generate on_config_change() event for updating plater and other things
|
||||
$self->on_config_change($self->GetFrame->config);
|
||||
}
|
||||
@ -735,7 +734,7 @@ sub load_model_objects {
|
||||
$self->make_thumbnail($obj_idx);
|
||||
}
|
||||
$self->arrange if $need_arrange;
|
||||
$self->update;
|
||||
$self->on_model_change;
|
||||
|
||||
# zoom to objects
|
||||
$self->{canvas3D}->zoom_to_volumes
|
||||
@ -745,8 +744,6 @@ sub load_model_objects {
|
||||
$self->{list}->Select($obj_idx[-1], 1);
|
||||
$self->object_list_changed;
|
||||
|
||||
$self->schedule_background_process;
|
||||
|
||||
return @obj_idx;
|
||||
}
|
||||
|
||||
@ -780,8 +777,7 @@ sub remove {
|
||||
$self->object_list_changed;
|
||||
|
||||
$self->select_object(undef);
|
||||
$self->update;
|
||||
$self->schedule_background_process;
|
||||
$self->on_model_change;
|
||||
}
|
||||
|
||||
sub reset {
|
||||
@ -800,7 +796,7 @@ sub reset {
|
||||
$self->object_list_changed;
|
||||
|
||||
$self->select_object(undef);
|
||||
$self->update;
|
||||
$self->on_model_change;
|
||||
}
|
||||
|
||||
sub increase {
|
||||
@ -825,9 +821,8 @@ sub increase {
|
||||
if ($Slic3r::GUI::Settings->{_}{autocenter}) {
|
||||
$self->arrange;
|
||||
} else {
|
||||
$self->update;
|
||||
$self->on_model_change;
|
||||
}
|
||||
$self->schedule_background_process;
|
||||
}
|
||||
|
||||
sub decrease {
|
||||
@ -852,8 +847,7 @@ sub decrease {
|
||||
$self->{list}->Select($obj_idx, 0);
|
||||
$self->{list}->Select($obj_idx, 1);
|
||||
}
|
||||
$self->update;
|
||||
$self->schedule_background_process;
|
||||
$self->on_model_change;
|
||||
}
|
||||
|
||||
sub set_number_of_copies {
|
||||
@ -925,8 +919,7 @@ sub rotate {
|
||||
$self->{print}->add_model_object($model_object, $obj_idx);
|
||||
|
||||
$self->selection_changed; # refresh info (size etc.)
|
||||
$self->update;
|
||||
$self->schedule_background_process;
|
||||
$self->on_model_change;
|
||||
}
|
||||
|
||||
sub mirror {
|
||||
@ -953,8 +946,7 @@ sub mirror {
|
||||
$self->{print}->add_model_object($model_object, $obj_idx);
|
||||
|
||||
$self->selection_changed; # refresh info (size etc.)
|
||||
$self->update;
|
||||
$self->schedule_background_process;
|
||||
$self->on_model_change;
|
||||
}
|
||||
|
||||
sub changescale {
|
||||
@ -1035,8 +1027,7 @@ sub changescale {
|
||||
$self->{print}->add_model_object($model_object, $obj_idx);
|
||||
|
||||
$self->selection_changed(1); # refresh info (size, volume etc.)
|
||||
$self->update;
|
||||
$self->schedule_background_process;
|
||||
$self->on_model_change;
|
||||
}
|
||||
|
||||
sub arrange {
|
||||
@ -1049,7 +1040,7 @@ sub arrange {
|
||||
# ignore arrange failures on purpose: user has visual feedback and we don't need to warn him
|
||||
# when parts don't fit in print bed
|
||||
|
||||
$self->update(1);
|
||||
$self->on_model_change(1);
|
||||
}
|
||||
|
||||
sub split_object {
|
||||
@ -1099,14 +1090,10 @@ sub split_object {
|
||||
sub schedule_background_process {
|
||||
my ($self) = @_;
|
||||
|
||||
$self->{processed} = 0;
|
||||
warn 'schedule_background_process() is not supposed to be called when background processing is disabled'
|
||||
if !$Slic3r::GUI::Settings->{_}{background_processing};
|
||||
|
||||
if (!$Slic3r::GUI::Settings->{_}{background_processing}) {
|
||||
my $sel = $self->{preview_notebook}->GetSelection;
|
||||
if ($sel == $self->{preview3D_page_idx} || $sel == $self->{toolpaths2D_page_idx}) {
|
||||
$self->{preview_notebook}->SetSelection(0);
|
||||
}
|
||||
}
|
||||
$self->{processed} = 0;
|
||||
|
||||
if (defined $self->{apply_config_timer}) {
|
||||
$self->{apply_config_timer}->Start(PROCESS_DELAY, 1); # 1 = one shot
|
||||
@ -1118,10 +1105,6 @@ sub schedule_background_process {
|
||||
sub async_apply_config {
|
||||
my ($self) = @_;
|
||||
|
||||
# reset preview canvases
|
||||
$self->{toolpaths2D}->reload_print if $self->{toolpaths2D};
|
||||
$self->{preview3D}->reload_print if $self->{preview3D};
|
||||
|
||||
# pause process thread before applying new config
|
||||
# since we don't want to touch data that is being used by the threads
|
||||
$self->pause_background_process;
|
||||
@ -1129,9 +1112,16 @@ sub async_apply_config {
|
||||
# apply new config
|
||||
my $invalidated = $self->{print}->apply_config($self->GetFrame->config);
|
||||
|
||||
return if !$Slic3r::GUI::Settings->{_}{background_processing};
|
||||
# reset preview canvases (invalidated contents will be hidden)
|
||||
$self->{toolpaths2D}->reload_print if $self->{toolpaths2D};
|
||||
$self->{preview3D}->reload_print if $self->{preview3D};
|
||||
|
||||
if ($invalidated) {
|
||||
if (!$Slic3r::GUI::Settings->{_}{background_processing}) {
|
||||
$self->hide_preview;
|
||||
return;
|
||||
}
|
||||
|
||||
# kill current thread if any
|
||||
$self->stop_background_process;
|
||||
# remove the sliced statistics box because something changed.
|
||||
@ -1629,30 +1619,45 @@ sub on_thumbnail_made {
|
||||
|
||||
# this method gets called whenever print center is changed or the objects' bounding box changes
|
||||
# (i.e. when an object is added/removed/moved/rotated/scaled)
|
||||
sub update {
|
||||
sub on_model_change {
|
||||
my ($self, $force_autocenter) = @_;
|
||||
|
||||
my $running = $self->pause_background_process;
|
||||
|
||||
if ($Slic3r::GUI::Settings->{_}{autocenter} || $force_autocenter) {
|
||||
$self->{model}->center_instances_around_point($self->bed_centerf);
|
||||
}
|
||||
$self->refresh_canvases;
|
||||
|
||||
my $running = $self->pause_background_process;
|
||||
my $invalidated = $self->{print}->reload_model_instances();
|
||||
|
||||
# The mere fact that no steps were invalidated when reloading model instances
|
||||
# doesn't mean that all steps were done: for example, validation might have
|
||||
# failed upon previous instance move, so we have no running thread and no steps
|
||||
# are invalidated on this move, thus we need to schedule a new run.
|
||||
if ($invalidated || !$running) {
|
||||
$self->schedule_background_process;
|
||||
if ($Slic3r::GUI::Settings->{_}{background_processing}) {
|
||||
if ($invalidated || !$running) {
|
||||
# The mere fact that no steps were invalidated when reloading model instances
|
||||
# doesn't mean that all steps were done: for example, validation might have
|
||||
# failed upon previous instance move, so we have no running thread and no steps
|
||||
# are invalidated on this move, thus we need to schedule a new run.
|
||||
$self->schedule_background_process;
|
||||
if ($self->{"right_sizer"}) {
|
||||
$self->{"right_sizer"}->Hide($self->{"sliced_info_box"});
|
||||
$self->{"right_sizer"}->Layout;
|
||||
}
|
||||
} else {
|
||||
$self->resume_background_process;
|
||||
}
|
||||
} else {
|
||||
$self->resume_background_process;
|
||||
$self->hide_preview;
|
||||
}
|
||||
if ($self->{"right_sizer"}) {
|
||||
$self->{"right_sizer"}->Hide($self->{"sliced_info_box"});
|
||||
$self->{"right_sizer"}->Layout;
|
||||
}
|
||||
|
||||
sub hide_preview {
|
||||
my ($self) = @_;
|
||||
|
||||
my $sel = $self->{preview_notebook}->GetSelection;
|
||||
if ($sel == $self->{preview3D_page_idx} || $sel == $self->{toolpaths2D_page_idx}) {
|
||||
$self->{preview_notebook}->SetSelection(0);
|
||||
}
|
||||
$self->refresh_canvases;
|
||||
$self->{processed} = 0;
|
||||
}
|
||||
|
||||
sub on_extruders_change {
|
||||
@ -1701,6 +1706,7 @@ sub on_config_change {
|
||||
my $self = shift;
|
||||
my ($config) = @_;
|
||||
|
||||
# Apply changes to the plater-specific config options.
|
||||
foreach my $opt_key (@{$self->{config}->diff($config)}) {
|
||||
$self->{config}->set($opt_key, $config->get($opt_key));
|
||||
if ($opt_key eq 'bed_shape') {
|
||||
@ -1708,7 +1714,7 @@ sub on_config_change {
|
||||
$self->{canvas3D}->update_bed_size if $self->{canvas3D};
|
||||
$self->{preview3D}->set_bed_shape($self->{config}->bed_shape)
|
||||
if $self->{preview3D};
|
||||
$self->update;
|
||||
$self->on_model_change;
|
||||
} elsif ($opt_key eq 'serial_port') {
|
||||
if ($config->get('serial_port')) {
|
||||
$self->{btn_print}->Show;
|
||||
@ -1723,8 +1729,12 @@ sub on_config_change {
|
||||
$self->{btn_send_gcode}->Hide;
|
||||
}
|
||||
$self->Layout;
|
||||
} elsif (0 && $opt_key eq 'filament_colour') {
|
||||
$self->{print}->config->set('filament_colour', $config->filament_colour);
|
||||
$self->{preview3D}->reload_print if $self->{preview3D};
|
||||
}
|
||||
}
|
||||
|
||||
if ($self->{"right_sizer"}) {
|
||||
$self->{"right_sizer"}->Hide($self->{"sliced_info_box"});
|
||||
$self->{"right_sizer"}->Layout;
|
||||
@ -1732,8 +1742,12 @@ sub on_config_change {
|
||||
|
||||
return if !$self->GetFrame->is_loaded;
|
||||
|
||||
# (re)start timer
|
||||
$self->schedule_background_process;
|
||||
if ($Slic3r::GUI::Settings->{_}{background_processing}) {
|
||||
# (re)start timer
|
||||
$self->schedule_background_process;
|
||||
} else {
|
||||
$self->async_apply_config;
|
||||
}
|
||||
}
|
||||
|
||||
sub list_item_deselected {
|
||||
|
@ -117,6 +117,16 @@ sub load_print {
|
||||
}
|
||||
|
||||
if ($self->IsShown) {
|
||||
# set colors
|
||||
$self->canvas->color_toolpaths_by($Slic3r::GUI::Settings->{_}{color_toolpaths_by});
|
||||
if ($self->canvas->color_toolpaths_by eq 'extruder') {
|
||||
my @filament_colors = map { s/^#//; [ map $_/255, (unpack 'C*', pack 'H*', $_), 255 ] }
|
||||
@{$self->print->config->filament_colour};
|
||||
$self->canvas->colors->[$_] = $filament_colors[$_] for 0..$#filament_colors;
|
||||
} else {
|
||||
$self->canvas->colors([ $self->canvas->default_colors ]);
|
||||
}
|
||||
|
||||
# load skirt and brim
|
||||
$self->canvas->load_print_toolpaths($self->print);
|
||||
|
||||
|
@ -462,11 +462,7 @@ sub process_layer {
|
||||
|
||||
# extrude brim
|
||||
if (!$self->_brim_done) {
|
||||
my $extr = $self->print->regions->[0]->config->perimeter_extruder-1;
|
||||
if (my $o = first { $_->config->raft_layers > 0 } @{$self->objects}) {
|
||||
$extr = $o->config->support_material_extruder-1;
|
||||
}
|
||||
$gcode .= $self->_gcodegen->set_extruder($extr);
|
||||
$gcode .= $self->_gcodegen->set_extruder($self->print->brim_extruder-1);
|
||||
$self->_gcodegen->set_origin(Slic3r::Pointf->new(0,0));
|
||||
$self->_gcodegen->avoid_crossing_perimeters->set_use_external_mp(1);
|
||||
$gcode .= $self->_gcodegen->extrude($_, 'brim', $object->config->support_material_speed)
|
||||
|
@ -187,6 +187,7 @@ Print::invalidate_state_by_config_options(const std::vector<t_config_option_key>
|
||||
|| *opt_key == "extrusion_multiplier"
|
||||
|| *opt_key == "fan_always_on"
|
||||
|| *opt_key == "fan_below_layer_time"
|
||||
|| *opt_key == "filament_colour"
|
||||
|| *opt_key == "filament_diameter"
|
||||
|| *opt_key == "first_layer_acceleration"
|
||||
|| *opt_key == "first_layer_bed_temperature"
|
||||
@ -348,6 +349,17 @@ Print::extruders() const
|
||||
return extruders;
|
||||
}
|
||||
|
||||
size_t
|
||||
Print::brim_extruder() const
|
||||
{
|
||||
size_t e = this->get_region(0)->config.perimeter_extruder;
|
||||
for (const PrintObject* object : this->objects) {
|
||||
if (object->config.raft_layers > 0)
|
||||
e = object->config.support_material_extruder;
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
||||
void
|
||||
Print::_simplify_slices(double distance)
|
||||
{
|
||||
|
@ -214,6 +214,7 @@ class Print
|
||||
std::set<size_t> object_extruders() const;
|
||||
std::set<size_t> support_material_extruders() const;
|
||||
std::set<size_t> extruders() const;
|
||||
size_t brim_extruder() const;
|
||||
void _simplify_slices(double distance);
|
||||
double max_allowed_layer_height() const;
|
||||
bool has_support_material() const;
|
||||
|
@ -224,6 +224,7 @@ _constant()
|
||||
RETVAL.push_back(*e);
|
||||
}
|
||||
%};
|
||||
int brim_extruder();
|
||||
void clear_filament_stats()
|
||||
%code%{
|
||||
THIS->filament_stats.clear();
|
||||
|
Loading…
x
Reference in New Issue
Block a user