mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-08-07 22:14:00 -06:00
Store / retrieve layer height profile from the AMF file.
Reset the layer height profile when changing a print profile to an incompatible one. Reset button on the layer height bar. Fixed an update issue on zooming by a scroll wheel. Fixed an issue when loading an AMF file: Object names are now retained.
This commit is contained in:
parent
61c0ae4e94
commit
88e34ff5de
14 changed files with 379 additions and 154 deletions
|
@ -43,6 +43,7 @@ __PACKAGE__->mk_accessors( qw(_quat _dirty init
|
|||
on_double_click
|
||||
on_right_click
|
||||
on_move
|
||||
on_model_update
|
||||
volumes
|
||||
_sphi _stheta
|
||||
cutting_plane_z
|
||||
|
@ -94,6 +95,9 @@ use constant MANIPULATION_LAYER_HEIGHT => 2;
|
|||
|
||||
use constant GIMBALL_LOCK_THETA_MAX => 170;
|
||||
|
||||
use constant VARIABLE_LAYER_THICKNESS_BAR_WIDTH => 70;
|
||||
use constant VARIABLE_LAYER_THICKNESS_RESET_BUTTON_HEIGHT => 22;
|
||||
|
||||
# make OpenGL::Array thread-safe
|
||||
{
|
||||
no warnings 'redefine';
|
||||
|
@ -171,7 +175,7 @@ sub new {
|
|||
$self->{layer_height_edit_timer} = Wx::Timer->new($self, $self->{layer_height_edit_timer_id});
|
||||
EVT_TIMER($self, $self->{layer_height_edit_timer_id}, sub {
|
||||
my ($self, $event) = @_;
|
||||
return if ! $self->_layer_height_edited;
|
||||
return if $self->_layer_height_edited != 1;
|
||||
return if $self->{layer_height_edit_last_object_id} == -1;
|
||||
$self->_variable_layer_thickness_action(undef);
|
||||
});
|
||||
|
@ -197,25 +201,60 @@ sub _first_selected_object_id {
|
|||
}
|
||||
|
||||
# Returns an array with (left, top, right, bottom) of the variable layer thickness bar on the screen.
|
||||
sub _variable_layer_thickness_bar_rect {
|
||||
sub _variable_layer_thickness_bar_rect_screen {
|
||||
my ($self) = @_;
|
||||
my ($cw, $ch) = $self->GetSizeWH;
|
||||
my $bar_width = 70;
|
||||
return ($cw - $bar_width, 0, $cw, $ch);
|
||||
return ($cw - VARIABLE_LAYER_THICKNESS_BAR_WIDTH, 0, $cw, $ch - VARIABLE_LAYER_THICKNESS_RESET_BUTTON_HEIGHT);
|
||||
}
|
||||
|
||||
sub _variable_layer_thickness_bar_rect_viewport {
|
||||
my ($self) = @_;
|
||||
my ($cw, $ch) = $self->GetSizeWH;
|
||||
return ((0.5*$cw-VARIABLE_LAYER_THICKNESS_BAR_WIDTH)/$self->_zoom, (-0.5*$ch+VARIABLE_LAYER_THICKNESS_RESET_BUTTON_HEIGHT)/$self->_zoom, $cw/(2*$self->_zoom), $ch/(2*$self->_zoom));
|
||||
}
|
||||
|
||||
# Returns an array with (left, top, right, bottom) of the variable layer thickness bar on the screen.
|
||||
sub _variable_layer_thickness_reset_rect_screen {
|
||||
my ($self) = @_;
|
||||
my ($cw, $ch) = $self->GetSizeWH;
|
||||
return ($cw - VARIABLE_LAYER_THICKNESS_BAR_WIDTH, $ch - VARIABLE_LAYER_THICKNESS_RESET_BUTTON_HEIGHT, $cw, $ch);
|
||||
}
|
||||
|
||||
sub _variable_layer_thickness_reset_rect_viewport {
|
||||
my ($self) = @_;
|
||||
my ($cw, $ch) = $self->GetSizeWH;
|
||||
return ((0.5*$cw-VARIABLE_LAYER_THICKNESS_BAR_WIDTH)/$self->_zoom, -$ch/(2*$self->_zoom), $cw/(2*$self->_zoom), (-0.5*$ch+VARIABLE_LAYER_THICKNESS_RESET_BUTTON_HEIGHT)/$self->_zoom);
|
||||
}
|
||||
|
||||
sub _variable_layer_thickness_bar_rect_mouse_inside {
|
||||
my ($self, $mouse_evt) = @_;
|
||||
my ($bar_left, $bar_top, $bar_right, $bar_bottom) = $self->_variable_layer_thickness_bar_rect;
|
||||
my ($bar_left, $bar_top, $bar_right, $bar_bottom) = $self->_variable_layer_thickness_bar_rect_screen;
|
||||
return $mouse_evt->GetX >= $bar_left && $mouse_evt->GetX <= $bar_right && $mouse_evt->GetY >= $bar_top && $mouse_evt->GetY <= $bar_bottom;
|
||||
}
|
||||
|
||||
sub _variable_layer_thickness_reset_rect_mouse_inside {
|
||||
my ($self, $mouse_evt) = @_;
|
||||
my ($bar_left, $bar_top, $bar_right, $bar_bottom) = $self->_variable_layer_thickness_reset_rect_screen;
|
||||
return $mouse_evt->GetX >= $bar_left && $mouse_evt->GetX <= $bar_right && $mouse_evt->GetY >= $bar_top && $mouse_evt->GetY <= $bar_bottom;
|
||||
}
|
||||
|
||||
sub _variable_layer_thickness_bar_mouse_cursor_z {
|
||||
my ($self, $object_idx, $mouse_evt) = @_;
|
||||
my ($bar_left, $bar_top, $bar_right, $bar_bottom) = $self->_variable_layer_thickness_bar_rect;
|
||||
my ($bar_left, $bar_top, $bar_right, $bar_bottom) = $self->_variable_layer_thickness_bar_rect_screen;
|
||||
return unscale($self->{print}->get_object($object_idx)->size->z) * ($bar_bottom - $mouse_evt->GetY - 1.) / ($bar_bottom - $bar_top);
|
||||
}
|
||||
|
||||
sub _variable_layer_thickness_bar_mouse_cursor_z_relative {
|
||||
my ($self) = @_;
|
||||
my $mouse_pos = $self->ScreenToClientPoint(Wx::GetMousePosition());
|
||||
my ($bar_left, $bar_top, $bar_right, $bar_bottom) = $self->_variable_layer_thickness_bar_rect_screen;
|
||||
return ($mouse_pos->x >= $bar_left && $mouse_pos->x <= $bar_right && $mouse_pos->y >= $bar_top && $mouse_pos->y <= $bar_bottom) ?
|
||||
# Inside the bar.
|
||||
($bar_bottom - $mouse_pos->y - 1.) / ($bar_bottom - $bar_top - 1) :
|
||||
# Outside the bar.
|
||||
-1000.;
|
||||
}
|
||||
|
||||
sub _variable_layer_thickness_action {
|
||||
my ($self, $mouse_event, $do_modification) = @_;
|
||||
# A volume is selected. Test, whether hovering over a layer thickness bar.
|
||||
|
@ -224,6 +263,8 @@ sub _variable_layer_thickness_action {
|
|||
$self->{layer_height_edit_last_action} = $mouse_event->ShiftDown ? ($mouse_event->RightIsDown ? 3 : 2) : ($mouse_event->RightIsDown ? 0 : 1);
|
||||
}
|
||||
if ($self->{layer_height_edit_last_object_id} != -1) {
|
||||
# Mark the volume as modified, so Print will pick its layer height profile? Where to mark it?
|
||||
# Start a timer to refresh the print? schedule_background_process() ?
|
||||
$self->{print}->get_object($self->{layer_height_edit_last_object_id})->adjust_layer_height_profile(
|
||||
$self->{layer_height_edit_last_z},
|
||||
$self->{layer_height_edit_strength},
|
||||
|
@ -263,6 +304,11 @@ sub mouse_event {
|
|||
# Start editing the layer height.
|
||||
$self->_layer_height_edited(1);
|
||||
$self->_variable_layer_thickness_action($e);
|
||||
} elsif ($object_idx_selected != -1 && $self->_variable_layer_thickness_reset_rect_mouse_inside($e)) {
|
||||
$self->{print}->get_object($self->{layer_height_edit_last_object_id})->reset_layer_height_profile;
|
||||
# Index 2 means no editing, just wait for mouse up event.
|
||||
$self->_layer_height_edited(2);
|
||||
$self->Refresh;
|
||||
} else {
|
||||
# Select volume in this 3D canvas.
|
||||
# Don't deselect a volume if layer editing is enabled. We want the object to stay selected
|
||||
|
@ -325,7 +371,7 @@ sub mouse_event {
|
|||
$self->Refresh;
|
||||
} elsif ($e->Dragging) {
|
||||
if ($self->_layer_height_edited && $object_idx_selected != -1) {
|
||||
$self->_variable_layer_thickness_action($e);
|
||||
$self->_variable_layer_thickness_action($e) if ($self->_layer_height_edited == 1);
|
||||
} elsif ($e->LeftIsDown) {
|
||||
# if dragging over blank area with left button, rotate
|
||||
if (defined $self->_drag_start_pos) {
|
||||
|
@ -365,7 +411,12 @@ sub mouse_event {
|
|||
$self->_drag_start_xy($pos);
|
||||
}
|
||||
} elsif ($e->LeftUp || $e->MiddleUp || $e->RightUp) {
|
||||
if ($self->on_move && defined($self->_drag_volume_idx) && $self->_dragged) {
|
||||
if ($self->_layer_height_edited) {
|
||||
$self->_layer_height_edited(undef);
|
||||
$self->{layer_height_edit_timer}->Stop;
|
||||
$self->on_model_update->()
|
||||
if ($object_idx_selected != -1 && $self->on_model_update);
|
||||
} elsif ($self->on_move && defined($self->_drag_volume_idx) && $self->_dragged) {
|
||||
# get all volumes belonging to the same group, if any
|
||||
my @volume_idxs;
|
||||
my $group_id = $self->volumes->[$self->_drag_volume_idx]->drag_group_id;
|
||||
|
@ -381,8 +432,6 @@ sub mouse_event {
|
|||
$self->_drag_start_pos(undef);
|
||||
$self->_drag_start_xy(undef);
|
||||
$self->_dragged(undef);
|
||||
$self->_layer_height_edited(undef);
|
||||
$self->{layer_height_edit_timer}->Stop;
|
||||
} elsif ($e->Moving) {
|
||||
$self->_mouse_pos($pos);
|
||||
# Only refresh if picking is enabled, in that case the objects may get highlighted if the mouse cursor
|
||||
|
@ -432,7 +481,7 @@ sub mouse_wheel_event {
|
|||
0,
|
||||
) if 0;
|
||||
$self->on_viewport_changed->() if $self->on_viewport_changed;
|
||||
$self->_dirty(1);
|
||||
$self->Resize($self->GetSizeWH) if $self->IsShownOnScreen;
|
||||
$self->Refresh;
|
||||
}
|
||||
|
||||
|
@ -1111,29 +1160,21 @@ sub draw_volumes {
|
|||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_NORMAL_ARRAY);
|
||||
|
||||
# The viewport and camera are set to complete view and glOrtho(-$x/2, $x/2, -$y/2, $y/2, -$depth, $depth),
|
||||
# where x, y is the window size divided by $self->_zoom.
|
||||
my ($cw, $ch) = $self->GetSizeWH;
|
||||
my $bar_width = 70;
|
||||
my ($bar_left, $bar_right) = ((0.5 * $cw - $bar_width)/$self->_zoom, $cw/(2*$self->_zoom));
|
||||
my ($bar_bottom, $bar_top) = (-$ch/(2*$self->_zoom), $ch/(2*$self->_zoom));
|
||||
my $mouse_pos = $self->ScreenToClientPoint(Wx::GetMousePosition());
|
||||
my $z_cursor_relative = ($mouse_pos->x < $cw - $bar_width) ? -1000. :
|
||||
($ch - $mouse_pos->y - 1.) / ($ch - 1);
|
||||
|
||||
my $z_cursor_relative = $self->_variable_layer_thickness_bar_mouse_cursor_z_relative;
|
||||
foreach my $volume_idx (0..$#{$self->volumes}) {
|
||||
my $volume = $self->volumes->[$volume_idx];
|
||||
|
||||
my $shader_active = 0;
|
||||
if ($self->layer_editing_enabled && ! $fakecolor && $volume->selected && $self->{shader} && $volume->{layer_height_texture_data}) {
|
||||
my $print_object = $self->{print}->get_object(int($volume->select_group_id / 1000000));
|
||||
if (! defined($volume->{layer_height_texture_cells}) || $print_object->update_layer_height_profile) {
|
||||
# Layer height profile was invalid before, now filled in with default data from layer height configuration
|
||||
# and possibly from the layer height modifiers. Update the height texture.
|
||||
$volume->{layer_height_texture_cells} = $print_object->generate_layer_height_texture(
|
||||
{
|
||||
# Update the height texture if the ModelObject::layer_height_texture is invalid.
|
||||
my $ncells = $print_object->generate_layer_height_texture(
|
||||
$volume->{layer_height_texture_data}->ptr,
|
||||
$self->{layer_preview_z_texture_height},
|
||||
$self->{layer_preview_z_texture_width});
|
||||
$self->{layer_preview_z_texture_width},
|
||||
!defined($volume->{layer_height_texture_cells}));
|
||||
$volume->{layer_height_texture_cells} = $ncells if $ncells > 0;
|
||||
}
|
||||
$self->{shader}->Enable;
|
||||
my $z_to_texture_row_id = $self->{shader}->Map('z_to_texture_row');
|
||||
|
@ -1272,45 +1313,77 @@ sub draw_volumes {
|
|||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
}
|
||||
|
||||
sub _load_image_set_texture {
|
||||
my ($self, $file_name) = @_;
|
||||
# Load a PNG with an alpha channel.
|
||||
my $img = Wx::Image->new;
|
||||
$img->LoadFile($Slic3r::var->($file_name), wxBITMAP_TYPE_PNG);
|
||||
# Get RGB & alpha raw data from wxImage, interleave them into a Perl array.
|
||||
my @rgb = unpack 'C*', $img->GetData();
|
||||
my @alpha = $img->HasAlpha ? unpack 'C*', $img->GetAlpha() : (255) x (int(@rgb) / 3);
|
||||
# my @alpha = unpack 'C*', $img->GetAlpha();
|
||||
my $n_pixels = int(@alpha);
|
||||
my @data = (0)x($n_pixels * 4);
|
||||
for (my $i = 0; $i < $n_pixels; $i += 1) {
|
||||
$data[$i*4 ] = $rgb[$i*3];
|
||||
$data[$i*4+1] = $rgb[$i*3+1];
|
||||
$data[$i*4+2] = $rgb[$i*3+2];
|
||||
$data[$i*4+3] = $alpha[$i];
|
||||
}
|
||||
# Initialize a raw bitmap data.
|
||||
my $params = {
|
||||
loaded => 1,
|
||||
valid => $n_pixels > 0,
|
||||
width => $img->GetWidth,
|
||||
height => $img->GetHeight,
|
||||
data => OpenGL::Array->new_list(GL_UNSIGNED_BYTE, @data),
|
||||
texture_id => glGenTextures_p(1)
|
||||
};
|
||||
# Create and initialize a texture with the raw data.
|
||||
glBindTexture(GL_TEXTURE_2D, $params->{texture_id});
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
|
||||
glTexImage2D_c(GL_TEXTURE_2D, 0, GL_RGBA8, $params->{width}, $params->{height}, 0, GL_RGBA, GL_UNSIGNED_BYTE, $params->{data}->ptr);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
return $params;
|
||||
}
|
||||
|
||||
sub _variable_layer_thickness_load_overlay_image {
|
||||
my ($self) = @_;
|
||||
|
||||
if (! $self->{layer_preview_annotation}->{loaded}) {
|
||||
# Load a PNG with an alpha channel.
|
||||
my $img = Wx::Image->new;
|
||||
$img->LoadFile($Slic3r::var->("variable_layer_height_tooltip.png"), wxBITMAP_TYPE_PNG);
|
||||
# Get RGB & alpha raw data from wxImage, interleave them into a Perl array.
|
||||
my @rgb = unpack 'C*', $img->GetData();
|
||||
my @alpha = unpack 'C*', $img->GetAlpha();
|
||||
my $n_pixels = int(@alpha);
|
||||
my @data = (0)x($n_pixels * 4);
|
||||
for (my $i = 0; $i < $n_pixels; $i += 1) {
|
||||
$data[$i*4 ] = $rgb[$i*3];
|
||||
$data[$i*4+1] = $rgb[$i*3+1];
|
||||
$data[$i*4+2] = $rgb[$i*3+2];
|
||||
$data[$i*4+3] = $alpha[$i];
|
||||
}
|
||||
# Initialize a raw bitmap data.
|
||||
my $params = $self->{layer_preview_annotation} = {
|
||||
loaded => 1,
|
||||
valid => $n_pixels > 0,
|
||||
width => $img->GetWidth,
|
||||
height => $img->GetHeight,
|
||||
data => OpenGL::Array->new_list(GL_UNSIGNED_BYTE, @data),
|
||||
texture_id => glGenTextures_p(1)
|
||||
};
|
||||
# Create and initialize a texture with the raw data.
|
||||
glBindTexture(GL_TEXTURE_2D, $params->{texture_id});
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
|
||||
glTexImage2D_c(GL_TEXTURE_2D, 0, GL_RGBA8, $params->{width}, $params->{height}, 0, GL_RGBA, GL_UNSIGNED_BYTE, $params->{data}->ptr);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
$self->{layer_preview_annotation} = $self->_load_image_set_texture('variable_layer_height_tooltip.png')
|
||||
if (! $self->{layer_preview_annotation}->{loaded});
|
||||
return $self->{layer_preview_annotation}->{valid};
|
||||
}
|
||||
|
||||
sub _variable_layer_thickness_load_reset_image {
|
||||
my ($self) = @_;
|
||||
$self->{layer_preview_reset_image} = $self->_load_image_set_texture('variable_layer_height_reset.png')
|
||||
if (! $self->{layer_preview_reset_image}->{loaded});
|
||||
return $self->{layer_preview_reset_image}->{valid};
|
||||
}
|
||||
|
||||
# Paint the tooltip.
|
||||
sub _render_image {
|
||||
my ($self, $image, $l, $r, $b, $t) = @_;
|
||||
glColor4f(1.,1.,1.,1.);
|
||||
glDisable(GL_LIGHTING);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, $image->{texture_id});
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2d(0.,1.); glVertex3f($l, $b, 0);
|
||||
glTexCoord2d(1.,1.); glVertex3f($r, $b, 0);
|
||||
glTexCoord2d(1.,0.); glVertex3f($r, $t, 0);
|
||||
glTexCoord2d(0.,0.); glVertex3f($l, $t, 0);
|
||||
glEnd();
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glDisable(GL_BLEND);
|
||||
glEnable(GL_LIGHTING);
|
||||
}
|
||||
|
||||
sub draw_active_object_annotations {
|
||||
# $fakecolor is a boolean indicating, that the objects shall be rendered in a color coding the object index for picking.
|
||||
my ($self) = @_;
|
||||
|
@ -1329,13 +1402,9 @@ sub draw_active_object_annotations {
|
|||
|
||||
# The viewport and camera are set to complete view and glOrtho(-$x/2, $x/2, -$y/2, $y/2, -$depth, $depth),
|
||||
# where x, y is the window size divided by $self->_zoom.
|
||||
my ($cw, $ch) = $self->GetSizeWH;
|
||||
my $bar_width = 70;
|
||||
my ($bar_left, $bar_right) = ((0.5 * $cw - $bar_width)/$self->_zoom, $cw/(2*$self->_zoom));
|
||||
my ($bar_bottom, $bar_top) = (-$ch/(2*$self->_zoom), $ch/(2*$self->_zoom));
|
||||
my $mouse_pos = $self->ScreenToClientPoint(Wx::GetMousePosition());
|
||||
my $z_cursor_relative = ($mouse_pos->x < $cw - $bar_width) ? -1000. :
|
||||
($ch - $mouse_pos->y - 1.) / ($ch - 1);
|
||||
my ($bar_left, $bar_bottom, $bar_right, $bar_top) = $self->_variable_layer_thickness_bar_rect_viewport;
|
||||
my ($reset_left, $reset_bottom, $reset_right, $reset_top) = $self->_variable_layer_thickness_reset_rect_viewport;
|
||||
my $z_cursor_relative = $self->_variable_layer_thickness_bar_mouse_cursor_z_relative;
|
||||
|
||||
$self->{shader}->Enable;
|
||||
my $z_to_texture_row_id = $self->{shader}->Map('z_to_texture_row');
|
||||
|
@ -1374,31 +1443,23 @@ sub draw_active_object_annotations {
|
|||
|
||||
# Paint the tooltip.
|
||||
if ($self->_variable_layer_thickness_load_overlay_image) {
|
||||
glColor4f(1.,1.,1.,1.);
|
||||
glDisable(GL_LIGHTING);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, $self->{layer_preview_annotation}->{texture_id});
|
||||
glBegin(GL_QUADS);
|
||||
my $gap = 10/$self->_zoom;
|
||||
my ($l, $r, $t, $b) = ($bar_left - $self->{layer_preview_annotation}->{width}/$self->_zoom - $gap, $bar_left - $gap, $bar_bottom + $self->{layer_preview_annotation}->{height}/$self->_zoom + $gap, $bar_bottom + $gap);
|
||||
glTexCoord2d(0.,1.); glVertex3f($l, $b, 0);
|
||||
glTexCoord2d(1.,1.); glVertex3f($r, $b, 0);
|
||||
glTexCoord2d(1.,0.); glVertex3f($r, $t, 0);
|
||||
glTexCoord2d(0.,0.); glVertex3f($l, $t, 0);
|
||||
glEnd();
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glDisable(GL_BLEND);
|
||||
glEnable(GL_LIGHTING);
|
||||
my ($l, $r, $b, $t) = ($bar_left - $self->{layer_preview_annotation}->{width}/$self->_zoom - $gap, $bar_left - $gap, $reset_bottom + $self->{layer_preview_annotation}->{height}/$self->_zoom + $gap, $reset_bottom + $gap);
|
||||
$self->_render_image($self->{layer_preview_annotation}, $l, $r, $t, $b);
|
||||
}
|
||||
|
||||
# Paint the reset button.
|
||||
if ($self->_variable_layer_thickness_load_reset_image) {
|
||||
$self->_render_image($self->{layer_preview_reset_image}, $reset_left, $reset_right, $reset_bottom, $reset_top);
|
||||
}
|
||||
|
||||
# Paint the graph.
|
||||
#FIXME use the min / maximum layer height
|
||||
#FIXME show some kind of legend.
|
||||
my $object_idx = int($volume->select_group_id / 1000000);
|
||||
my $print_object = $self->{print}->get_object($object_idx);
|
||||
my $max_z = unscale($print_object->size->z);
|
||||
my $profile = $print_object->layer_height_profile;
|
||||
my $profile = $print_object->model_object->layer_height_profile;
|
||||
my $layer_height = $print_object->config->get('layer_height');
|
||||
# Baseline
|
||||
glColor3f(0., 0., 0.);
|
||||
|
@ -1686,7 +1747,6 @@ sub load_object {
|
|||
# not correspond to the color of the filament.
|
||||
my $color = [ @{COLORS->[ $color_idx % scalar(@{&COLORS}) ]} ];
|
||||
$color->[3] = $volume->modifier ? 0.5 : 1;
|
||||
print "Reloading object $volume_idx, $instance_idx\n";
|
||||
push @{$self->volumes}, my $v = Slic3r::GUI::3DScene::Volume->new(
|
||||
bounding_box => $mesh->bounding_box,
|
||||
color => $color,
|
||||
|
|
|
@ -104,6 +104,12 @@ sub new {
|
|||
$self->{canvas3D}->set_on_double_click($on_double_click);
|
||||
$self->{canvas3D}->set_on_right_click(sub { $on_right_click->($self->{canvas3D}, @_); });
|
||||
$self->{canvas3D}->set_on_instances_moved($on_instances_moved);
|
||||
$self->{canvas3D}->set_on_model_update(sub {
|
||||
if ($Slic3r::GUI::Settings->{_}{background_processing}) {
|
||||
$self->{apply_config_timer}->Stop if defined $self->{apply_config_timer};
|
||||
$self->async_apply_config();
|
||||
}
|
||||
});
|
||||
$self->{canvas3D}->on_viewport_changed(sub {
|
||||
$self->{preview3D}->canvas->set_viewport_from_scene($self->{canvas3D});
|
||||
});
|
||||
|
@ -651,10 +657,9 @@ sub load_model_objects {
|
|||
my @obj_idx = ();
|
||||
foreach my $model_object (@model_objects) {
|
||||
my $o = $self->{model}->add_object($model_object);
|
||||
|
||||
push @{ $self->{objects} }, Slic3r::GUI::Plater::Object->new(
|
||||
name => basename($model_object->input_file),
|
||||
);
|
||||
my $object_name = $model_object->name;
|
||||
$object_name = basename($model_object->input_file) if ($object_name eq '');
|
||||
push @{ $self->{objects} }, Slic3r::GUI::Plater::Object->new(name => $object_name);
|
||||
push @obj_idx, $#{ $self->{objects} };
|
||||
|
||||
if ($model_object->instances_count == 0) {
|
||||
|
@ -1088,6 +1093,9 @@ sub async_apply_config {
|
|||
|
||||
# apply new config
|
||||
my $invalidated = $self->{print}->apply_config($self->GetFrame->config);
|
||||
|
||||
# $self->{canvas3D}->Refresh if ($invalidated && $self->{canvas3D}->layer_editing_enabled);
|
||||
$self->{canvas3D}->Refresh if ($self->{canvas3D}->layer_editing_enabled);
|
||||
|
||||
return if !$Slic3r::GUI::Settings->{_}{background_processing};
|
||||
|
||||
|
@ -1200,7 +1208,10 @@ sub reslice {
|
|||
my ($self) = @_;
|
||||
# Don't reslice if export of G-code or sending to OctoPrint is running.
|
||||
if ($Slic3r::have_threads && ! defined($self->{export_gcode_output_file}) && ! defined($self->{send_gcode_file})) {
|
||||
# Stop the background processing threads, stop the async update timer.
|
||||
$self->stop_background_process;
|
||||
# Rather perform one additional unnecessary update of the print object instead of skipping a pending async update.
|
||||
$self->async_apply_config;
|
||||
$self->statusbar->SetCancelCallback(sub {
|
||||
$self->stop_background_process;
|
||||
$self->statusbar->SetStatusText("Slicing cancelled");
|
||||
|
@ -1534,8 +1545,6 @@ sub on_thumbnail_made {
|
|||
sub update {
|
||||
my ($self, $force_autocenter) = @_;
|
||||
|
||||
print "Platter - update\n";
|
||||
|
||||
if ($Slic3r::GUI::Settings->{_}{autocenter} || $force_autocenter) {
|
||||
$self->{model}->center_instances_around_point($self->bed_centerf);
|
||||
}
|
||||
|
|
|
@ -83,6 +83,11 @@ sub set_on_instances_moved {
|
|||
$self->{on_instances_moved} = $cb;
|
||||
}
|
||||
|
||||
sub set_on_model_update {
|
||||
my ($self, $cb) = @_;
|
||||
$self->on_model_update($cb);
|
||||
}
|
||||
|
||||
sub update {
|
||||
my ($self) = @_;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue