Merge branch 'master' into wipe_tower_improvements

This commit is contained in:
Lukas Matena 2018-03-16 14:06:23 +01:00
commit 3d6f6530c0
59 changed files with 4062 additions and 12410 deletions

View file

@ -15,7 +15,6 @@ use Slic3r::GUI::Controller;
use Slic3r::GUI::Controller::ManualControlDialog;
use Slic3r::GUI::Controller::PrinterPanel;
use Slic3r::GUI::MainFrame;
use Slic3r::GUI::Notifier;
use Slic3r::GUI::Plater;
use Slic3r::GUI::Plater::2D;
use Slic3r::GUI::Plater::2DToolpaths;
@ -34,7 +33,6 @@ use Slic3r::GUI::SystemInfo;
use Wx::Locale gettext => 'L';
our $have_OpenGL = eval "use Slic3r::GUI::3DScene; 1";
our $have_LWP = eval "use LWP::UserAgent; 1";
use Wx 0.9901 qw(:bitmap :dialog :icon :id :misc :systemsettings :toplevelwindow :filedialog :font);
use Wx::Event qw(EVT_IDLE EVT_COMMAND EVT_MENU);
@ -88,7 +86,6 @@ sub OnInit {
Slic3r::set_data_dir($datadir || Wx::StandardPaths::Get->GetUserDataDir);
Slic3r::GUI::set_wxapp($self);
$self->{notifier} = Slic3r::GUI::Notifier->new;
$self->{app_config} = Slic3r::GUI::AppConfig->new;
$self->{preset_bundle} = Slic3r::GUI::PresetBundle->new;
@ -117,6 +114,8 @@ sub OnInit {
}
eval { $self->{preset_bundle}->load_selections($self->{app_config}) };
$run_wizard = 1 if $self->{preset_bundle}->has_defauls_only;
Slic3r::GUI::set_preset_bundle($self->{preset_bundle});
# application frame
Wx::Image::FindHandlerType(wxBITMAP_TYPE_PNG) || Wx::Image::AddHandler(Wx::PNGHandler->new);
@ -270,7 +269,9 @@ sub notify {
$frame->RequestUserAttention(&Wx::wxMAC ? wxUSER_ATTENTION_ERROR : wxUSER_ATTENTION_INFO)
unless ($frame->IsActive);
$self->{notifier}->notify($message);
# There used to be notifier using a Growl application for OSX, but Growl is dead.
# The notifier also supported the Linux X D-bus notifications, but that support was broken.
#TODO use wxNotificationMessage?
}
# Called after the Preferences dialog is closed and the program settings are saved.

View file

@ -68,6 +68,7 @@ __PACKAGE__->mk_accessors( qw(_quat _dirty init
_zoom
_legend_enabled
_warning_enabled
_apply_zoom_to_volumes_filter
) );
@ -142,6 +143,7 @@ sub new {
$self->_sphi(45);
$self->_zoom(1);
$self->_legend_enabled(0);
$self->_warning_enabled(0);
$self->use_plain_shader(0);
$self->_apply_zoom_to_volumes_filter(0);
@ -217,7 +219,12 @@ sub new {
sub set_legend_enabled {
my ($self, $value) = @_;
$self->_legend_enabled($value);
$self->_legend_enabled($value);
}
sub set_warning_enabled {
my ($self, $value) = @_;
$self->_warning_enabled($value);
}
sub Destroy {
@ -400,6 +407,10 @@ sub mouse_event {
$self->Refresh;
$self->Update;
} else {
# The mouse_to_3d gets the Z coordinate from the Z buffer at the screen coordinate $pos->x,y,
# an converts the screen space coordinate to unscaled object space.
my $pos3d = ($volume_idx == -1) ? undef : $self->mouse_to_3d(@$pos);
# Select volume in this 3D canvas.
# Don't deselect a volume if layer editing is enabled. We want the object to stay selected
# during the scene manipulation.
@ -427,9 +438,6 @@ sub mouse_event {
if ($volume_idx != -1) {
if ($e->LeftDown && $self->enable_moving) {
# The mouse_to_3d gets the Z coordinate from the Z buffer at the screen coordinate $pos->x,y,
# an converts the screen space coordinate to unscaled object space.
my $pos3d = $self->mouse_to_3d(@$pos);
# Only accept the initial position, if it is inside the volume bounding box.
my $volume_bbox = $self->volumes->[$volume_idx]->transformed_bounding_box;
$volume_bbox->offset(1.);
@ -948,6 +956,9 @@ sub mulquats {
sub mouse_to_3d {
my ($self, $x, $y, $z) = @_;
return unless $self->GetContext;
$self->SetCurrent($self->GetContext);
my @viewport = glGetIntegerv_p(GL_VIEWPORT); # 4 items
my @mview = glGetDoublev_p(GL_MODELVIEW_MATRIX); # 16 items
my @proj = glGetDoublev_p(GL_PROJECTION_MATRIX); # 16 items
@ -1296,11 +1307,16 @@ sub Render {
}
glEnable(GL_LIGHTING);
# draw objects
if (! $self->use_plain_shader) {
$self->draw_volumes;
} elsif ($self->UseVBOs) {
if ($self->enable_picking) {
$self->mark_volumes_for_layer_height;
$self->volumes->set_print_box($self->bed_bounding_box->x_min, $self->bed_bounding_box->y_min, 0.0, $self->bed_bounding_box->x_max, $self->bed_bounding_box->y_max, $self->{config}->get('max_print_height'));
$self->volumes->update_outside_state($self->{config}, 0);
}
$self->{plain_shader}->enable if $self->{plain_shader};
$self->volumes->render_VBOs;
$self->{plain_shader}->disable;
@ -1327,6 +1343,9 @@ sub Render {
glDisable(GL_BLEND);
}
# draw warning message
$self->draw_warning;
# draw gcode preview legend
$self->draw_legend;
@ -1345,36 +1364,10 @@ sub draw_volumes {
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
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;
my $object_id = int($volume->select_group_id / 1000000);
if ($self->layer_editing_enabled && ! $fakecolor && $volume->selected && $self->{layer_height_edit_shader} &&
$volume->has_layer_height_texture && $object_id < $self->{print}->object_count) {
# Update the height texture if the ModelObject::layer_height_texture is invalid.
$volume->generate_layer_height_texture($self->{print}->get_object($object_id), 0);
$self->{layer_height_edit_shader}->enable;
$self->{layer_height_edit_shader}->set_uniform('z_to_texture_row', $volume->layer_height_texture_z_to_row_id);
$self->{layer_height_edit_shader}->set_uniform('z_texture_row_to_normalized', 1. / $volume->layer_height_texture_height);
$self->{layer_height_edit_shader}->set_uniform('z_cursor', $volume->bounding_box->z_max * $z_cursor_relative);
$self->{layer_height_edit_shader}->set_uniform('z_cursor_band_width', $self->{layer_height_edit_band_width});
glBindTexture(GL_TEXTURE_2D, $self->{layer_preview_z_texture_id});
# glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LEVEL, 0);
# glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
glTexImage2D_c(GL_TEXTURE_2D, 0, GL_RGBA8, $volume->layer_height_texture_width, $volume->layer_height_texture_height,
0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glTexImage2D_c(GL_TEXTURE_2D, 1, GL_RGBA8, $volume->layer_height_texture_width / 2, $volume->layer_height_texture_height / 2,
0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
# glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
# glPixelStorei(GL_UNPACK_ROW_LENGTH, $self->{layer_preview_z_texture_width});
glTexSubImage2D_c(GL_TEXTURE_2D, 0, 0, 0, $volume->layer_height_texture_width, $volume->layer_height_texture_height,
GL_RGBA, GL_UNSIGNED_BYTE, $volume->layer_height_texture_data_ptr_level0);
glTexSubImage2D_c(GL_TEXTURE_2D, 1, 0, 0, $volume->layer_height_texture_width / 2, $volume->layer_height_texture_height / 2,
GL_RGBA, GL_UNSIGNED_BYTE, $volume->layer_height_texture_data_ptr_level1);
$shader_active = 1;
} elsif ($fakecolor) {
if ($fakecolor) {
# Object picking mode. Render the object with a color encoding the object index.
my $r = ($volume_idx & 0x000000FF) >> 0;
my $g = ($volume_idx & 0x0000FF00) >> 8;
@ -1389,11 +1382,6 @@ sub draw_volumes {
}
$volume->render;
if ($shader_active) {
glBindTexture(GL_TEXTURE_2D, 0);
$self->{layer_height_edit_shader}->disable;
}
}
glDisableClientState(GL_NORMAL_ARRAY);
glDisable(GL_BLEND);
@ -1408,6 +1396,22 @@ sub draw_volumes {
glDisableClientState(GL_VERTEX_ARRAY);
}
sub mark_volumes_for_layer_height {
my ($self) = @_;
foreach my $volume_idx (0..$#{$self->volumes}) {
my $volume = $self->volumes->[$volume_idx];
my $object_id = int($volume->select_group_id / 1000000);
if ($self->layer_editing_enabled && $volume->selected && $self->{layer_height_edit_shader} &&
$volume->has_layer_height_texture && $object_id < $self->{print}->object_count) {
$volume->set_layer_height_texture_data($self->{layer_preview_z_texture_id}, $self->{layer_height_edit_shader}->shader_program_id,
$self->{print}->get_object($object_id), $self->_variable_layer_thickness_bar_mouse_cursor_z_relative, $self->{layer_height_edit_band_width});
} else {
$volume->reset_layer_height_texture_data();
}
}
}
sub _load_image_set_texture {
my ($self, $file_name) = @_;
# Load a PNG with an alpha channel.
@ -1599,31 +1603,65 @@ sub draw_active_object_annotations {
sub draw_legend {
my ($self) = @_;
if ($self->_legend_enabled)
{
# If the legend texture has not been loaded into the GPU, do it now.
my $tex_id = Slic3r::GUI::_3DScene::finalize_legend_texture;
if ($tex_id > 0)
{
my $tex_w = Slic3r::GUI::_3DScene::get_legend_texture_width;
my $tex_h = Slic3r::GUI::_3DScene::get_legend_texture_height;
if (($tex_w > 0) && ($tex_h > 0))
{
glDisable(GL_DEPTH_TEST);
glPushMatrix();
glLoadIdentity();
my ($cw, $ch) = $self->GetSizeWH;
my $l = (-0.5 * $cw) / $self->_zoom;
my $t = (0.5 * $ch) / $self->_zoom;
my $r = $l + $tex_w / $self->_zoom;
my $b = $t - $tex_h / $self->_zoom;
$self->_render_texture($tex_id, $l, $r, $b, $t);
if (!$self->_legend_enabled) {
return;
}
glPopMatrix();
glEnable(GL_DEPTH_TEST);
}
# If the legend texture has not been loaded into the GPU, do it now.
my $tex_id = Slic3r::GUI::_3DScene::finalize_legend_texture;
if ($tex_id > 0)
{
my $tex_w = Slic3r::GUI::_3DScene::get_legend_texture_width;
my $tex_h = Slic3r::GUI::_3DScene::get_legend_texture_height;
if (($tex_w > 0) && ($tex_h > 0))
{
glDisable(GL_DEPTH_TEST);
glPushMatrix();
glLoadIdentity();
my ($cw, $ch) = $self->GetSizeWH;
my $l = (-0.5 * $cw) / $self->_zoom;
my $t = (0.5 * $ch) / $self->_zoom;
my $r = $l + $tex_w / $self->_zoom;
my $b = $t - $tex_h / $self->_zoom;
$self->_render_texture($tex_id, $l, $r, $b, $t);
glPopMatrix();
glEnable(GL_DEPTH_TEST);
}
}
}
sub draw_warning {
my ($self) = @_;
if (!$self->_warning_enabled) {
return;
}
# If the warning texture has not been loaded into the GPU, do it now.
my $tex_id = Slic3r::GUI::_3DScene::finalize_warning_texture;
if ($tex_id > 0)
{
my $tex_w = Slic3r::GUI::_3DScene::get_warning_texture_width;
my $tex_h = Slic3r::GUI::_3DScene::get_warning_texture_height;
if (($tex_w > 0) && ($tex_h > 0))
{
glDisable(GL_DEPTH_TEST);
glPushMatrix();
glLoadIdentity();
my ($cw, $ch) = $self->GetSizeWH;
my $l = (-0.5 * $tex_w) / $self->_zoom;
my $t = (-0.5 * $ch + $tex_h) / $self->_zoom;
my $r = $l + $tex_w / $self->_zoom;
my $b = $t - $tex_h / $self->_zoom;
$self->_render_texture($tex_id, $l, $r, $b, $t);
glPopMatrix();
glEnable(GL_DEPTH_TEST);
}
}
}
@ -1692,57 +1730,77 @@ sub _vertex_shader_Gouraud {
return <<'VERTEX';
#version 110
#define INTENSITY_CORRECTION 0.7
#define INTENSITY_CORRECTION 0.6
#define LIGHT_TOP_DIR -0.6/1.31, 0.6/1.31, 1./1.31
// normalized values for (-0.6/1.31, 0.6/1.31, 1./1.31)
const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929);
#define LIGHT_TOP_DIFFUSE (0.8 * INTENSITY_CORRECTION)
#define LIGHT_TOP_SPECULAR (0.5 * INTENSITY_CORRECTION)
#define LIGHT_TOP_SHININESS 50.
#define LIGHT_TOP_SPECULAR (0.25 * INTENSITY_CORRECTION)
#define LIGHT_TOP_SHININESS 200.0
#define LIGHT_FRONT_DIR 1./1.43, 0.2/1.43, 1./1.43
// normalized values for (1./1.43, 0.2/1.43, 1./1.43)
const vec3 LIGHT_FRONT_DIR = vec3(0.6985074, 0.1397015, 0.6985074);
#define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION)
#define LIGHT_FRONT_SPECULAR (0.0 * INTENSITY_CORRECTION)
#define LIGHT_FRONT_SHININESS 50.
//#define LIGHT_FRONT_SPECULAR (0.0 * INTENSITY_CORRECTION)
//#define LIGHT_FRONT_SHININESS 5.0
#define INTENSITY_AMBIENT 0.3
varying float intensity_specular;
varying float intensity_tainted;
const vec3 ZERO = vec3(0.0, 0.0, 0.0);
struct PrintBoxDetection
{
vec3 min;
vec3 max;
// xyz contains the offset, if w == 1.0 detection needs to be performed
vec4 volume_origin;
};
uniform PrintBoxDetection print_box;
// x = tainted, y = specular;
varying vec2 intensity;
varying vec3 delta_box_min;
varying vec3 delta_box_max;
void main()
{
vec3 eye, normal, lightDir, viewVector, halfVector;
float NdotL, NdotHV;
vec3 eye = -normalize((gl_ModelViewMatrix * gl_Vertex).xyz);
eye = vec3(0., 0., 1.);
// First transform the normal into eye space and normalize the result.
normal = normalize(gl_NormalMatrix * gl_Normal);
// First transform the normal into camera space and normalize the result.
vec3 normal = normalize(gl_NormalMatrix * gl_Normal);
// Now normalize the light's direction. Note that according to the OpenGL specification, the light is stored in eye space.
// Also since we're talking about a directional light, the position field is actually direction.
lightDir = vec3(LIGHT_TOP_DIR);
halfVector = normalize(lightDir + eye);
vec3 halfVector = normalize(LIGHT_TOP_DIR + eye);
// Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex.
// Since these two are normalized the cosine is the dot product. We also need to clamp the result to the [0,1] range.
NdotL = max(dot(normal, lightDir), 0.0);
float NdotL = max(dot(normal, LIGHT_TOP_DIR), 0.0);
intensity_tainted = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE;
intensity_specular = 0.;
intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE;
intensity.y = 0.0;
if (NdotL > 0.0)
intensity_specular = LIGHT_TOP_SPECULAR * pow(max(dot(normal, halfVector), 0.0), LIGHT_TOP_SHININESS);
intensity.y += LIGHT_TOP_SPECULAR * pow(max(dot(normal, halfVector), 0.0), LIGHT_TOP_SHININESS);
// Perform the same lighting calculation for the 2nd light source.
lightDir = vec3(LIGHT_FRONT_DIR);
// halfVector = normalize(lightDir + eye);
NdotL = max(dot(normal, lightDir), 0.0);
intensity_tainted += NdotL * LIGHT_FRONT_DIFFUSE;
// Perform the same lighting calculation for the 2nd light source (no specular applied).
NdotL = max(dot(normal, LIGHT_FRONT_DIR), 0.0);
intensity.x += NdotL * LIGHT_FRONT_DIFFUSE;
// compute the specular term if NdotL is larger than zero
// if (NdotL > 0.0)
// intensity_specular += LIGHT_FRONT_SPECULAR * pow(max(dot(normal, halfVector), 0.0), LIGHT_FRONT_SHININESS);
// compute deltas for out of print volume detection (world coordinates)
if (print_box.volume_origin.w == 1.0)
{
vec3 v = gl_Vertex.xyz + print_box.volume_origin.xyz;
delta_box_min = v - print_box.min;
delta_box_max = v - print_box.max;
}
else
{
delta_box_min = ZERO;
delta_box_max = ZERO;
}
gl_Position = ftransform();
}
@ -1754,16 +1812,25 @@ sub _fragment_shader_Gouraud {
return <<'FRAGMENT';
#version 110
varying float intensity_specular;
varying float intensity_tainted;
const vec3 ZERO = vec3(0.0, 0.0, 0.0);
// x = tainted, y = specular;
varying vec2 intensity;
varying vec3 delta_box_min;
varying vec3 delta_box_max;
uniform vec4 uniform_color;
void main()
{
gl_FragColor =
vec4(intensity_specular, intensity_specular, intensity_specular, 0.) + uniform_color * intensity_tainted;
gl_FragColor.a = uniform_color.a;
gl_FragColor = vec4(intensity.y, intensity.y, intensity.y, 0.0) + uniform_color * intensity.x;
// if the fragment is outside the print volume darken it and set it as transparent
if (any(lessThan(delta_box_min, ZERO)) || any(greaterThan(delta_box_max, ZERO)))
gl_FragColor = vec4(mix(gl_FragColor.xyz, ZERO, 0.5), 0.5 * uniform_color.a);
else
gl_FragColor.a = uniform_color.a;
}
FRAGMENT
@ -1828,6 +1895,7 @@ void main() {
// compute the specular term into spec
// intensity_specular += LIGHT_FRONT_SPECULAR * pow(max(dot(h,normal), 0.0), LIGHT_FRONT_SHININESS);
}
gl_FragColor = max(
vec4(intensity_specular, intensity_specular, intensity_specular, 0.) + uniform_color * intensity_tainted,
INTENSITY_AMBIENT * uniform_color);
@ -1840,61 +1908,55 @@ sub _vertex_shader_variable_layer_height {
return <<'VERTEX';
#version 110
#define LIGHT_TOP_DIR 0., 1., 0.
#define LIGHT_TOP_DIFFUSE 0.2
#define LIGHT_TOP_SPECULAR 0.3
#define LIGHT_TOP_SHININESS 50.
#define INTENSITY_CORRECTION 0.6
#define LIGHT_FRONT_DIR 0., 0., 1.
#define LIGHT_FRONT_DIFFUSE 0.5
#define LIGHT_FRONT_SPECULAR 0.3
#define LIGHT_FRONT_SHININESS 50.
const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929);
#define LIGHT_TOP_DIFFUSE (0.8 * INTENSITY_CORRECTION)
#define LIGHT_TOP_SPECULAR (0.25 * INTENSITY_CORRECTION)
#define LIGHT_TOP_SHININESS 200.0
#define INTENSITY_AMBIENT 0.1
const vec3 LIGHT_FRONT_DIR = vec3(0.6985074, 0.1397015, 0.6985074);
#define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION)
//#define LIGHT_FRONT_SPECULAR (0.0 * INTENSITY_CORRECTION)
//#define LIGHT_FRONT_SHININESS 5.0
#define INTENSITY_AMBIENT 0.3
uniform float z_to_texture_row;
varying float intensity_specular;
varying float intensity_tainted;
// x = tainted, y = specular;
varying vec2 intensity;
varying float object_z;
void main()
{
vec3 eye, normal, lightDir, viewVector, halfVector;
float NdotL, NdotHV;
vec3 eye = -normalize((gl_ModelViewMatrix * gl_Vertex).xyz);
// eye = gl_ModelViewMatrixInverse[3].xyz;
eye = vec3(0., 0., 1.);
// First transform the normal into eye space and normalize the result.
normal = normalize(gl_NormalMatrix * gl_Normal);
// First transform the normal into camera space and normalize the result.
vec3 normal = normalize(gl_NormalMatrix * gl_Normal);
// Now normalize the light's direction. Note that according to the OpenGL specification, the light is stored in eye space.
// Also since we're talking about a directional light, the position field is actually direction.
lightDir = vec3(LIGHT_TOP_DIR);
halfVector = normalize(lightDir + eye);
vec3 halfVector = normalize(LIGHT_TOP_DIR + eye);
// Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex.
// Since these two are normalized the cosine is the dot product. We also need to clamp the result to the [0,1] range.
NdotL = max(dot(normal, lightDir), 0.0);
float NdotL = max(dot(normal, LIGHT_TOP_DIR), 0.0);
intensity_tainted = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE;
intensity_specular = 0.;
intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE;
intensity.y = 0.0;
// if (NdotL > 0.0)
// intensity_specular = LIGHT_TOP_SPECULAR * pow(max(dot(normal, halfVector), 0.0), LIGHT_TOP_SHININESS);
// Perform the same lighting calculation for the 2nd light source.
lightDir = vec3(LIGHT_FRONT_DIR);
halfVector = normalize(lightDir + eye);
NdotL = max(dot(normal, lightDir), 0.0);
intensity_tainted += NdotL * LIGHT_FRONT_DIFFUSE;
// compute the specular term if NdotL is larger than zero
if (NdotL > 0.0)
intensity_specular += LIGHT_FRONT_SPECULAR * pow(max(dot(normal, halfVector), 0.0), LIGHT_FRONT_SHININESS);
intensity.y += LIGHT_TOP_SPECULAR * pow(max(dot(normal, halfVector), 0.0), LIGHT_TOP_SHININESS);
// Perform the same lighting calculation for the 2nd light source (no specular)
NdotL = max(dot(normal, LIGHT_FRONT_DIR), 0.0);
intensity.x += NdotL * LIGHT_FRONT_DIFFUSE;
// Scaled to widths of the Z texture.
object_z = gl_Vertex.z / gl_Vertex.w;
object_z = gl_Vertex.z;
gl_Position = ftransform();
}
@ -1913,13 +1975,14 @@ uniform sampler2D z_texture;
// Scaling from the Z texture rows coordinate to the normalized texture row coordinate.
uniform float z_to_texture_row;
uniform float z_texture_row_to_normalized;
varying float intensity_specular;
varying float intensity_tainted;
varying float object_z;
uniform float z_cursor;
uniform float z_cursor_band_width;
// x = tainted, y = specular;
varying vec2 intensity;
varying float object_z;
void main()
{
float object_z_row = z_to_texture_row * object_z;
@ -1938,15 +2001,12 @@ void main()
float lod = clamp(0.5 * log2(max(dx_vtc*dx_vtc, dy_vtc*dy_vtc)), 0., 1.);
// Sample the Z texture. Texture coordinates are normalized to <0, 1>.
vec4 color =
(1. - lod) * texture2D(z_texture, vec2(z_texture_col, z_texture_row_to_normalized * (z_texture_row + 0.5 )), -10000.) +
lod * texture2D(z_texture, vec2(z_texture_col, z_texture_row_to_normalized * (z_texture_row * 2. + 1.)), 10000.);
mix(texture2D(z_texture, vec2(z_texture_col, z_texture_row_to_normalized * (z_texture_row + 0.5 )), -10000.),
texture2D(z_texture, vec2(z_texture_col, z_texture_row_to_normalized * (z_texture_row * 2. + 1.)), 10000.), lod);
// Mix the final color.
gl_FragColor =
vec4(intensity_specular, intensity_specular, intensity_specular, 1.) +
(1. - z_blend) * intensity_tainted * color +
z_blend * vec4(1., 1., 0., 0.);
// and reset the transparency.
gl_FragColor.a = 1.;
vec4(intensity.y, intensity.y, intensity.y, 1.0) + intensity.x * mix(color, vec4(1.0, 1.0, 0.0, 1.0), z_blend);
}
FRAGMENT

View file

@ -25,10 +25,6 @@ our $last_config;
our $VALUE_CHANGE_EVENT = Wx::NewEventType;
# 2) To inform about a preset selection change or a "modified" status change.
our $PRESETS_CHANGED_EVENT = Wx::NewEventType;
# 3) To inform about a click on Browse button
our $BUTTON_BROWSE_EVENT = Wx::NewEventType;
# 4) To inform about a click on Test button
our $BUTTON_TEST_EVENT = Wx::NewEventType;
sub new {
my ($class, %params) = @_;
@ -169,59 +165,7 @@ sub _init_tabpanel {
}
}
});
# The following event is emited by the C++ Tab implementation ,
# when the Browse button was clicked
EVT_COMMAND($self, -1, $BUTTON_BROWSE_EVENT, sub {
my ($self, $event) = @_;
my $msg = $event->GetString;
# look for devices
my $entries;
{
my $res = Net::Bonjour->new('http');
$res->discover;
$entries = [ $res->entries ];
}
if (@{$entries}) {
my $dlg = Slic3r::GUI::BonjourBrowser->new($self, $entries);
my $tab = Slic3r::GUI::get_preset_tab("printer");
$tab->load_key_value('octoprint_host', $dlg->GetValue . ":" . $dlg->GetPort)
if $dlg->ShowModal == wxID_OK;
} else {
Wx::MessageDialog->new($self, L('No Bonjour device found'), L('Device Browser'), wxOK | wxICON_INFORMATION)->ShowModal;
}
});
# The following event is emited by the C++ Tab implementation ,
# when the Test button was clicked
EVT_COMMAND($self, -1, $BUTTON_TEST_EVENT, sub {
my ($self, $event) = @_;
my $msg = $event->GetString;
my $ua = LWP::UserAgent->new;
$ua->timeout(10);
my $config = Slic3r::GUI::get_preset_tab("printer")->get_config;
my $res = $ua->get(
"http://" . $config->octoprint_host . "/api/version",
'X-Api-Key' => $config->octoprint_apikey,
);
if ($res->is_success) {
Slic3r::GUI::show_info($self, L("Connection to OctoPrint works correctly."), _L("Success!"));
} else {
Slic3r::GUI::show_error($self,
L("I wasn't able to connect to OctoPrint (") . $res->status_line .
L("). Check hostname and OctoPrint version (at least 1.1.0 is required)."));
}
});
# A variable to inform C++ Tab implementation about disabling of Browse button
$self->{is_disabled_button_browse} = (!eval "use Net::Bonjour; 1") ? 1 : 0 ;
# A variable to inform C++ Tab implementation about user_agent
$self->{is_user_agent} = (eval "use LWP::UserAgent; 1") ? 1 : 0 ;
Slic3r::GUI::create_preset_tabs(wxTheApp->{preset_bundle}, $self->{no_controller},
$self->{is_disabled_button_browse},
$self->{is_user_agent},
$VALUE_CHANGE_EVENT, $PRESETS_CHANGED_EVENT,
$BUTTON_BROWSE_EVENT, $BUTTON_TEST_EVENT);
Slic3r::GUI::create_preset_tabs($self->{no_controller}, $VALUE_CHANGE_EVENT, $PRESETS_CHANGED_EVENT);
$self->{options_tabs} = {};
for my $tab_name (qw(print filament printer)) {
$self->{options_tabs}{$tab_name} = Slic3r::GUI::get_preset_tab("$tab_name");

View file

@ -1,46 +0,0 @@
# Notify about the end of slicing.
# The notifications are sent out using the Growl protocol if installed, and using DBus XWindow protocol.
package Slic3r::GUI::Notifier;
use Moo;
has 'growler' => (is => 'rw');
my $icon = Slic3r::var("Slic3r.png");
sub BUILD {
my ($self) = @_;
if (eval 'use Growl::GNTP; 1') {
# register with growl
eval {
$self->growler(Growl::GNTP->new(AppName => 'Slic3r', AppIcon => $icon));
$self->growler->register([{Name => 'SKEIN_DONE', DisplayName => 'Slicing Done'}]);
};
# if register() fails (for example because of a timeout), disable growler at all
$self->growler(undef) if $@;
}
}
sub notify {
my ($self, $message) = @_;
my $title = 'Slicing Done!';
eval {
$self->growler->notify(Event => 'SKEIN_DONE', Title => $title, Message => $message)
if $self->growler;
};
# Net::DBus is broken in multithreaded environment
if (0 && eval 'use Net::DBus; 1') {
eval {
my $session = Net::DBus->session;
my $serv = $session->get_service('org.freedesktop.Notifications');
my $notifier = $serv->get_object('/org/freedesktop/Notifications',
'org.freedesktop.Notifications');
$notifier->Notify('Slic3r', 0, $icon, $title, $message, [], {}, -1);
undef $Net::DBus::bus_session;
};
}
}
1;

View file

@ -8,7 +8,6 @@ use utf8;
use File::Basename qw(basename dirname);
use List::Util qw(sum first max);
use Slic3r::Geometry qw(X Y Z scale unscale deg2rad rad2deg);
use LWP::UserAgent;
use threads::shared qw(shared_clone);
use Wx qw(:button :colour :cursor :dialog :filedialog :keycode :icon :font :id :listctrl :misc
:panel :sizer :toolbar :window wxTheApp :notebook :combobox wxNullBitmap);
@ -53,8 +52,9 @@ sub new {
$self->{config} = Slic3r::Config::new_from_defaults_keys([qw(
bed_shape complete_objects extruder_clearance_radius skirts skirt_distance brim_width variable_layer_height
serial_port serial_speed octoprint_host octoprint_apikey octoprint_cafile
nozzle_diameter single_extruder_multi_material
wipe_tower wipe_tower_x wipe_tower_y wipe_tower_width wipe_tower_per_color_wipe wipe_tower_rotation_angle extruder_colour filament_colour
nozzle_diameter single_extruder_multi_material wipe_tower wipe_tower_x wipe_tower_y wipe_tower_width
wipe_tower_per_color_wipe wipe_tower_rotation_angle extruder_colour filament_colour
max_print_height
)]);
# C++ Slic3r::Model with Perl extensions in Slic3r/Model.pm
$self->{model} = Slic3r::Model->new;
@ -113,6 +113,7 @@ sub new {
$self->{canvas3D}->set_on_decrease_objects(sub { $self->decrease() });
$self->{canvas3D}->set_on_remove_object(sub { $self->remove() });
$self->{canvas3D}->set_on_instances_moved($on_instances_moved);
$self->{canvas3D}->use_plain_shader(1);
$self->{canvas3D}->set_on_wipe_tower_moved(sub {
my ($new_pos_3f) = @_;
my $cfg = Slic3r::Config->new;
@ -389,9 +390,12 @@ sub new {
});
});
$presets->Add($text, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL | wxRIGHT, 4);
$presets->Add($choice, 1, wxALIGN_CENTER_VERTICAL | wxEXPAND | wxBOTTOM, 0);
$presets->Add($choice, 1, wxALIGN_CENTER_VERTICAL | wxEXPAND | wxBOTTOM, 1);
}
}
my $frequently_changed_parameters_sizer = Wx::BoxSizer->new(wxHORIZONTAL);
Slic3r::GUI::add_frequently_changed_parameters($self, $frequently_changed_parameters_sizer, $presets);
my $object_info_sizer;
{
@ -473,14 +477,15 @@ sub new {
my $right_sizer = Wx::BoxSizer->new(wxVERTICAL);
$right_sizer->Add($presets, 0, wxEXPAND | wxTOP, 10) if defined $presets;
$right_sizer->Add($frequently_changed_parameters_sizer, 0, wxEXPAND | wxTOP, 10) if defined $frequently_changed_parameters_sizer;
$right_sizer->Add($buttons_sizer, 0, wxEXPAND | wxBOTTOM, 5);
$right_sizer->Add($self->{list}, 1, wxEXPAND, 5);
$right_sizer->Add($object_info_sizer, 0, wxEXPAND, 0);
$right_sizer->Add($print_info_sizer, 0, wxEXPAND, 0);
# Callback for showing / hiding the print info box.
$self->{"print_info_box_show"} = sub {
if ($right_sizer->IsShown(4) != $_[0]) {
$right_sizer->Show(4, $_[0]);
if ($right_sizer->IsShown(5) != $_[0]) {
$right_sizer->Show(5, $_[0]);
$self->Layout
}
};
@ -1737,6 +1742,8 @@ sub on_config_change {
$update_scheduled = 1;
my $extruder_colors = $config->get('extruder_colour');
$self->{preview3D}->set_number_extruders(scalar(@{$extruder_colors}));
} elsif ($opt_key eq 'max_print_height') {
$update_scheduled = 1;
}
}
@ -1934,6 +1941,7 @@ sub selection_changed {
$self->{object_info_manifold_warning_icon}->SetToolTipString($message);
} else {
$self->{object_info_manifold}->SetLabel(L("Yes"));
$self->{object_info_manifold_warning_icon}->Hide;
}
} else {
$self->{object_info_facets}->SetLabel($object->facets);

View file

@ -8,6 +8,8 @@ use Wx qw(:misc :pen :brush :sizer :font :cursor :keycode wxTAB_TRAVERSAL);
use Wx::Event qw(EVT_KEY_DOWN EVT_CHAR);
use base qw(Slic3r::GUI::3DScene Class::Accessor);
use Wx::Locale gettext => 'L';
__PACKAGE__->mk_accessors(qw(
on_arrange on_rotate_object_left on_rotate_object_right on_scale_object_uniformly
on_remove_object on_increase_objects on_decrease_objects));
@ -208,6 +210,19 @@ sub reload_scene {
$self->{model}->bounding_box->z_max, $self->{config}->wipe_tower_rotation_angle, $self->UseVBOs);
}
}
# checks for geometry outside the print volume to render it accordingly
if (scalar @{$self->volumes} > 0)
{
if (!$self->{model}->fits_print_volume($self->{config})) {
$self->set_warning_enabled(1);
Slic3r::GUI::_3DScene::generate_warning_texture(L("Detected object outside print volume"));
} else {
$self->set_warning_enabled(0);
$self->volumes->update_outside_state($self->{config}, 1);
Slic3r::GUI::_3DScene::reset_warning_texture();
}
}
}
sub update_bed_size {

View file

@ -253,19 +253,19 @@ sub new {
# sets colors for gcode preview extrusion roles
my @extrusion_roles_colors = (
'Perimeter' => 'FFA500',
'External perimeter' => 'FFFF66',
'Perimeter' => 'FFFF66',
'External perimeter' => 'FFA500',
'Overhang perimeter' => '0000FF',
'Internal infill' => 'FF0000',
'Solid infill' => 'CD00CD',
'Top solid infill' => 'FF3333',
'Internal infill' => 'B1302A',
'Solid infill' => 'D732D7',
'Top solid infill' => 'FF1A1A',
'Bridge infill' => '9999FF',
'Gap fill' => 'FFFFFF',
'Skirt' => '7F0000',
'Skirt' => '845321',
'Support material' => '00FF00',
'Support material interface' => '008000',
'Wipe tower' => 'B3E3AB',
'Custom' => 'FFFF00',
'Custom' => '28CC94',
);
$self->gcode_preview_data->set_extrusion_paths_colors(\@extrusion_roles_colors);

View file

@ -7,7 +7,6 @@ require Exporter;
our @ISA = qw(Exporter);
our @EXPORT_OK = qw(_eq);
use IO::Scalar;
use List::Util qw(first);
use Slic3r::Geometry qw(epsilon X Y Z);