Merge remote-tracking branch 'origin/master' into profile_changes_reset

This commit is contained in:
YuSanka 2018-03-15 10:24:54 +01:00
commit d97a8f5740
19 changed files with 1032 additions and 445 deletions

View File

@ -52,18 +52,21 @@ endif()
add_subdirectory(xs)
get_filename_component(PERL_BIN_PATH "${PERL_EXECUTABLE}" DIRECTORY)
if (MSVC)
# By default the startup project in MSVC is the 'ALL_BUILD' cmake-created project,
# but we want 'slic3r' as the startup one because debugging run command is associated with it.
# (Unfortunatelly it cannot be associated with ALL_BUILD using CMake.)
# Note: For some reason this needs to be set in the top-level CMakeLists.txt
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT XS)
set(PERL_PROVE "${PERL_BIN_PATH}/prove.bat")
else ()
set(PERL_PROVE "${PERL_BIN_PATH}/prove")
endif ()
enable_testing ()
get_filename_component(PERL_BIN_PATH "${PERL_EXECUTABLE}" DIRECTORY)
add_test (NAME xs COMMAND "${PERL_EXECUTABLE}" ${PERL_BIN_PATH}/prove -I ${PROJECT_SOURCE_DIR}/local-lib/lib/perl5 WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/xs)
add_test (NAME integration COMMAND "${PERL_EXECUTABLE}" ${PERL_BIN_PATH}/prove WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
add_test (NAME xs COMMAND "${PERL_EXECUTABLE}" ${PERL_PROVE} -I ${PROJECT_SOURCE_DIR}/local-lib/lib/perl5 WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/xs)
add_test (NAME integration COMMAND "${PERL_EXECUTABLE}" ${PERL_PROVE} WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
install(PROGRAMS slic3r.pl DESTINATION bin RENAME slic3r-prusa3d)

View File

@ -67,13 +67,17 @@ $(TBB).tar.gz:
curl -L -o $@ https://github.com/wjakob/tbb/archive/$(TBB_SHA).tar.gz
# Note: libcurl build system seems to be a bit wonky about finding openssl (cf. #2378).
# It seems that currently the only working option is to set a prefix in the openssl build
# and use the `--with-ssl=...` option in libcurl.
# Additionally, pkg-config needs to be installed and openssl libs need to NOT be installed on the build system.
libopenssl: $(OPENSSL).tar.gz
tar -zxvf $(OPENSSL).tar.gz
cd $(OPENSSL) && ./config --openssldir=/etc/ssl shared no-ssl3-method no-dynamic-engine '-Wa,--noexecstack'
make -C $(OPENSSL) depend
make -C $(OPENSSL) -j$(NPROC)
make -C $(OPENSSL) install DESTDIR=$(DESTDIR)
cd $(OPENSSL) && ./config --prefix=$(DESTDIR)/usr/local no-shared no-ssl3-method no-dynamic-engine '-Wa,--noexecstack'
$(MAKE) -C $(OPENSSL) depend
$(MAKE) -C $(OPENSSL) -j$(NPROC)
$(MAKE) -C $(OPENSSL) install_sw
$(OPENSSL).tar.gz:
curl -L -o $@ 'https://github.com/openssl/openssl/archive/OpenSSL_1_1_0g.tar.gz'
@ -82,10 +86,9 @@ $(OPENSSL).tar.gz:
libcurl: libopenssl $(CURL).tar.gz
tar -zxvf $(CURL).tar.gz
# Note: It seems setting custom openssl path doesn't work when pkg-config and system openssl devel libs are installed
cd $(CURL) && ./configure \
--enable-static \
--enable-shared \
--disable-shared \
--with-ssl=$(DESTDIR)/usr/local \
--with-pic \
--enable-ipv6 \

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 {
@ -1300,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;
@ -1331,6 +1343,9 @@ sub Render {
glDisable(GL_BLEND);
}
# draw warning message
$self->draw_warning;
# draw gcode preview legend
$self->draw_legend;
@ -1349,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;
@ -1393,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);
@ -1412,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.
@ -1603,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);
}
}
}
@ -1696,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();
}
@ -1758,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
@ -1832,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);
@ -1844,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();
}
@ -1917,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;
@ -1942,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

@ -55,6 +55,7 @@ sub new {
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 extruder_colour filament_colour
max_print_height
)]);
# C++ Slic3r::Model with Perl extensions in Slic3r/Model.pm
$self->{model} = Slic3r::Model->new;
@ -113,6 +114,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;
@ -1741,6 +1743,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;
}
}

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->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

@ -76,6 +76,7 @@ overhangs = 0
only_retract_when_crossing_perimeters = 0
ooze_prevention = 0
output_filename_format = [input_filename_base].gcode
perimeters = 2
perimeter_extruder = 1
perimeter_extrusion_width = 0.45
post_process =
@ -100,10 +101,13 @@ support_material_interface_extruder = 0
support_material_angle = 0
support_material_buildplate_only = 0
support_material_enforce_layers = 0
support_material_contact_distance = 0.15
support_material_interface_contact_loops = 0
support_material_interface_layers = 2
support_material_interface_spacing = 0.2
support_material_interface_speed = 100%
support_material_pattern = rectilinear
support_material_spacing = 2
support_material_speed = 50
support_material_synchronize_layers = 0
support_material_threshold = 45
@ -140,7 +144,7 @@ support_material_xy_spacing = 150%
external_perimeter_extrusion_width = 0.61
extrusion_width = 0.67
first_layer_extrusion_width = 0.65
infill_extrusion_width = 0.75
infill_extrusion_width = 0.7
perimeter_extrusion_width = 0.65
solid_infill_extrusion_width = 0.65
top_infill_extrusion_width = 0.6
@ -157,7 +161,6 @@ support_material_interface_spacing = 0.1
support_material_synchronize_layers = 1
support_material_threshold = 80
support_material_with_sheath = 1
support_material_xy_spacing = 120%
wipe_tower = 1
[print:*0.05mm*]
@ -167,7 +170,7 @@ bridge_acceleration = 300
bridge_flow_ratio = 0.7
default_acceleration = 500
external_perimeter_speed = 20
fill_density = 25%
fill_density = 20%
first_layer_acceleration = 500
gap_fill_speed = 20
infill_acceleration = 800
@ -176,30 +179,28 @@ max_print_speed = 80
small_perimeter_speed = 15
solid_infill_speed = 30
support_material_extrusion_width = 0.3
support_material_interface_spacing = 0.2
support_material_spacing = 1.5
layer_height = 0.05
perimeter_acceleration = 300
perimeter_speed = 30
perimeters = 3
support_material_contact_distance = 0.15
support_material_speed = 30
top_solid_infill_speed = 20
top_solid_layers = 15
[print:0.05mm DETAIL]
[print:0.05mm ULTRADETAIL]
inherits = *0.05mm*
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2.*/ and nozzle_diameter[0]==0.4 and num_extruders==1
infill_extrusion_width = 0.5
[print:0.05mm DETAIL MK3]
[print:0.05mm ULTRADETAIL MK3]
inherits = *0.05mm*
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ and nozzle_diameter[0]==0.4
fill_pattern = grid
top_infill_extrusion_width = 0.4
[print:0.05mm DETAIL 0.25 nozzle]
inherits = *0.05mm*; *0.25nozzle*
[print:0.05mm ULTRADETAIL 0.25 nozzle]
inherits = *0.05mm*
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2.*/ and nozzle_diameter[0]==0.25 and num_extruders==1
external_perimeter_extrusion_width = 0
extrusion_width = 0.28
@ -210,13 +211,18 @@ infill_speed = 20
max_print_speed = 100
perimeter_extrusion_width = 0
perimeter_speed = 20
perimeters = 4
small_perimeter_speed = 10
solid_infill_extrusion_width = 0
solid_infill_speed = 20
support_material_speed = 20
top_infill_extrusion_width = 0
[print:0.05mm ULTRADETAIL 0.25 nozzle MK3]
inherits = *0.05mm*; *0.25nozzle*
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ and nozzle_diameter[0]==0.25 and num_extruders==1
fill_pattern = grid
top_infill_extrusion_width = 0.4
[print:*0.10mm*]
inherits = *common*
bottom_solid_layers = 7
@ -224,9 +230,6 @@ bridge_flow_ratio = 0.7
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2.*/ and nozzle_diameter[0]==0.4 and num_extruders==1
layer_height = 0.1
perimeter_acceleration = 800
support_material_contact_distance = 0.15
support_material_interface_spacing = 0.2
support_material_spacing = 2
top_solid_layers = 9
[print:0.10mm DETAIL]
@ -236,40 +239,63 @@ external_perimeter_speed = 40
infill_acceleration = 2000
infill_speed = 60
perimeter_speed = 50
perimeters = 3
solid_infill_speed = 50
[print:0.10mm DETAIL MK3]
inherits = *0.10mm*
bridge_flow_ratio = 0.8
bridge_speed = 30
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ and nozzle_diameter[0]==0.4
external_perimeter_speed = 35
fill_pattern = grid
infill_acceleration = 1500
infill_speed = 170
max_print_speed = 170
max_print_speed = 200
perimeter_speed = 45
perimeters = 2
solid_infill_speed = 170
top_infill_extrusion_width = 0.4
top_solid_infill_speed = 50
[print:0.10mm DETAIL 0.25 nozzle]
inherits = *0.10mm*; *0.25nozzle*
inherits = *0.10mm*
bridge_acceleration = 600
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2.*/ and nozzle_diameter[0]==0.25
external_perimeter_speed = 20
fill_density = 15%
infill_acceleration = 1600
infill_speed = 40
perimeter_acceleration = 600
perimeter_speed = 25
perimeters = 4
small_perimeter_speed = 10
solid_infill_speed = 40
top_solid_infill_speed = 30
[print:0.10mm DETAIL 0.25 nozzle MK3]
inherits = *0.10mm*
bridge_speed = 30
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ and nozzle_diameter[0]==0.25
external_perimeter_speed = 35
fill_pattern = grid
infill_acceleration = 1500
infill_speed = 170
max_print_speed = 200
perimeter_speed = 45
solid_infill_speed = 170
top_infill_extrusion_width = 0.4
top_solid_infill_speed = 50
[print:0.10mm DETAIL 0.6 nozzle MK3]
inherits = *0.10mm*
bridge_speed = 30
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ and nozzle_diameter[0]==0.6
external_perimeter_speed = 35
fill_pattern = grid
infill_acceleration = 1500
infill_speed = 170
max_print_speed = 200
perimeter_speed = 45
solid_infill_speed = 170
top_infill_extrusion_width = 0.4
top_solid_infill_speed = 50
[print:*0.15mm*]
inherits = *common*
bottom_solid_layers = 5
@ -279,29 +305,22 @@ infill_speed = 60
layer_height = 0.15
perimeter_acceleration = 800
perimeter_speed = 50
perimeters = 3
solid_infill_speed = 50
support_material_contact_distance = 0.15
support_material_interface_spacing = 0.2
support_material_spacing = 2
top_infill_extrusion_width = 0.4
top_solid_layers = 7
[print:0.15mm 100mms Linear Advance]
inherits = *0.15mm*
bottom_solid_layers = 4
bridge_flow_ratio = 0.95
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2.*/ and nozzle_diameter[0]==0.4
external_perimeter_speed = 50
infill_speed = 100
max_print_speed = 150
perimeter_speed = 60
perimeters = 2
small_perimeter_speed = 30
solid_infill_speed = 100
support_material_speed = 60
top_solid_infill_speed = 70
top_solid_layers = 5
[print:0.15mm OPTIMAL]
inherits = *0.15mm*
@ -318,44 +337,38 @@ infill_acceleration = 1600
infill_speed = 40
perimeter_acceleration = 600
perimeter_speed = 25
perimeters = 2
small_perimeter_speed = 10
solid_infill_speed = 40
support_material_extrusion_width = 0.2
support_material_threshold = 35
top_solid_infill_speed = 30
[print:0.15mm OPTIMAL 0.6 nozzle]
inherits = *0.15mm*; *0.6nozzle*
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2.*/ and nozzle_diameter[0]==0.6
wipe_tower = 1
[print:0.15mm OPTIMAL MK3]
inherits = *0.15mm*
bridge_speed = 30
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ and nozzle_diameter[0]==0.4
external_perimeter_speed = 35
fill_pattern = grid
infill_acceleration = 1500
infill_speed = 170
max_print_speed = 170
perimeter_speed = 45
perimeters = 2
solid_infill_speed = 170
top_solid_infill_speed = 50
wipe_tower = 1
[print:0.15mm OPTIMAL SOLUBLE FULL]
inherits = *0.15mm*; *soluble_support*
bottom_solid_layers = 5
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2.*/ and nozzle_diameter[0]==0.4 and num_extruders>1
external_perimeter_speed = 25
notes = Set your solluble extruder in Multiple Extruders > Support material/raft/skirt extruder & Support material/raft interface extruder
perimeter_speed = 40
solid_infill_speed = 40
support_material_xy_spacing = 60%
top_infill_extrusion_width = 0.45
top_solid_infill_speed = 30
wipe_tower = 1
[print:0.15mm OPTIMAL SOLUBLE INTERFACE]
inherits = 0.15mm OPTIMAL SOLUBLE FULL
@ -363,8 +376,20 @@ notes = Set your solluble extruder in Multiple Extruders > Support material/raf
support_material_extruder = 0
support_material_interface_layers = 3
support_material_with_sheath = 0
support_material_xy_spacing = 120%
support_material_xy_spacing = 80%
[print:0.15mm OPTIMAL 0.25 nozzle MK3]
inherits = *0.15mm*
bridge_speed = 30
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ and nozzle_diameter[0]==0.25
external_perimeter_speed = 35
fill_pattern = grid
infill_acceleration = 1500
infill_speed = 170
max_print_speed = 170
perimeter_speed = 45
solid_infill_speed = 170
top_solid_infill_speed = 50
[print:*0.20mm*]
inherits = *common*
bottom_solid_layers = 4
@ -375,14 +400,22 @@ infill_speed = 60
layer_height = 0.2
perimeter_acceleration = 800
perimeter_speed = 50
perimeters = 2
solid_infill_speed = 50
support_material_contact_distance = 0.15
support_material_interface_spacing = 0.2
support_material_spacing = 2
top_infill_extrusion_width = 0.4
top_solid_layers = 5
wipe_tower = 1
[print:0.15mm OPTIMAL 0.6 nozzle MK3]
inherits = *0.15mm*
bridge_speed = 30
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ and nozzle_diameter[0]==0.6
external_perimeter_speed = 35
fill_pattern = grid
infill_acceleration = 1500
infill_speed = 170
max_print_speed = 170
perimeter_speed = 45
solid_infill_speed = 170
top_solid_infill_speed = 50
[print:0.20mm 100mms Linear Advance]
inherits = *0.20mm*
@ -399,8 +432,7 @@ top_solid_infill_speed = 70
[print:0.20mm FAST MK3]
inherits = *0.20mm*
bridge_speed = 30
bridge_flow_ratio = 0.8
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ and nozzle_diameter[0]==0.4
external_perimeter_speed = 35
fill_pattern = grid
infill_acceleration = 1500
@ -416,9 +448,7 @@ compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and
[print:0.20mm NORMAL 0.6 nozzle]
inherits = *0.20mm*; *0.6nozzle*
bridge_flow_ratio = 0.8
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2.*/ and nozzle_diameter[0]==0.6
perimeters = 3
[print:0.20mm NORMAL SOLUBLE FULL]
inherits = *0.20mm*; *soluble_support*
@ -435,6 +465,20 @@ notes = Set your solluble extruder in Multiple Extruders > Support material/raf
support_material_extruder = 0
support_material_interface_layers = 3
support_material_with_sheath = 0
support_material_xy_spacing = 80%
[print:0.20mm FAST 0.6 nozzle MK3]
inherits = *0.20mm*
bridge_speed = 30
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ and nozzle_diameter[0]==0.6
external_perimeter_speed = 35
fill_pattern = grid
infill_acceleration = 1500
infill_speed = 170
max_print_speed = 170
perimeter_speed = 45
solid_infill_speed = 170
top_solid_infill_speed = 50
[print:*0.35mm*]
inherits = *common*
@ -443,38 +487,28 @@ external_perimeter_extrusion_width = 0.6
external_perimeter_speed = 40
first_layer_extrusion_width = 0.75
infill_acceleration = 2000
infill_extrusion_width = 0.75
infill_speed = 60
layer_height = 0.35
perimeter_acceleration = 800
perimeter_extrusion_width = 0.65
perimeter_speed = 50
perimeters = 2
solid_infill_extrusion_width = 0.65
solid_infill_speed = 60
support_material_contact_distance = 0.15
support_material_interface_spacing = 0.2
support_material_spacing = 2
top_solid_infill_speed = 50
top_solid_layers = 4
wipe_tower = 1
[print:0.35mm FAST]
inherits = *0.35mm*
bridge_flow_ratio = 0.95
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2.*/ and nozzle_diameter[0]==0.4
first_layer_extrusion_width = 0.42
infill_extrusion_width = 0.7
perimeter_extrusion_width = 0.43
solid_infill_extrusion_width = 0.7
top_infill_extrusion_width = 0.43
[print:0.35mm FAST 0.6 nozzle]
inherits = *0.35mm*; *0.6nozzle*
bottom_solid_layers = 7
compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2.*/ and nozzle_diameter[0]==0.6
perimeters = 3
top_solid_layers = 9
[print:0.35mm FAST sol full 0.6 nozzle]
inherits = *0.35mm*; *0.6nozzle*; *soluble_support*
@ -485,14 +519,14 @@ notes = Set your solluble extruder in Multiple Extruders > Support material/raf
perimeter_speed = 40
support_material_extrusion_width = 0.55
support_material_interface_layers = 3
support_material_interface_spacing = 0.2
support_material_with_sheath = 0
support_material_xy_spacing = 120%
top_infill_extrusion_width = 0.57
[print:0.35mm FAST sol int 0.6 nozzle]
inherits = 0.35mm FAST sol full 0.6 nozzle
support_material_extruder = 0
support_material_interface_layers = 2
support_material_with_sheath = 0
support_material_xy_spacing = 150%
[filament:*common*]
@ -504,6 +538,7 @@ extrusion_multiplier = 1
filament_cost = 0
filament_density = 0
filament_diameter = 1.75
filament_notes = ""
filament_settings_id =
filament_soluble = 0
min_print_speed = 5
@ -534,7 +569,7 @@ disable_fan_first_layers = 3
fan_always_on = 1
fan_below_layer_time = 20
filament_colour = #FF8000
filament_max_volumetric_speed = 10
filament_max_volumetric_speed = 8
filament_type = PET
first_layer_bed_temperature = 85
first_layer_temperature = 230
@ -545,19 +580,19 @@ temperature = 240
[filament:*ABS*]
inherits = *common*
bed_temperature = 100
bed_temperature = 110
bridge_fan_speed = 30
cooling = 0
disable_fan_first_layers = 3
fan_always_on = 0
fan_below_layer_time = 20
filament_colour = #3A80CA
filament_max_volumetric_speed = 13
filament_max_volumetric_speed = 11
filament_type = ABS
first_layer_bed_temperature = 100
first_layer_temperature = 255
max_fan_speed = 30
min_fan_speed = 10
min_fan_speed = 20
temperature = 255
[filament:*FLEX*]
@ -569,6 +604,7 @@ disable_fan_first_layers = 1
extrusion_multiplier = 1.2
fan_always_on = 0
fan_below_layer_time = 100
filament_colour = #00CA0A
filament_max_volumetric_speed = 1.5
filament_type = FLEX
first_layer_bed_temperature = 50
@ -581,43 +617,28 @@ temperature = 240
[filament:ColorFabb Brass Bronze]
inherits = *PLA*
compatible_printers_condition = nozzle_diameter[0]>0.35
extrusion_multiplier = 1.3
extrusion_multiplier = 1.2
filament_colour = #804040
filament_max_volumetric_speed = 10
min_print_speed = 5
[filament:ColorFabb HT]
bed_temperature = 105
inherits = *PET*
bed_temperature = 110
bridge_fan_speed = 30
compatible_printers =
compatible_printers_condition =
cooling = 1
disable_fan_first_layers = 3
end_filament_gcode = "; Filament-specific end gcode"
extrusion_multiplier = 1
fan_always_on = 0
fan_below_layer_time = 10
filament_colour = #FF8000
filament_cost = 0
filament_density = 0
filament_diameter = 1.75
filament_max_volumetric_speed = 10
filament_notes = ""
filament_settings_id =
filament_soluble = 0
filament_type = PLA
first_layer_bed_temperature = 105
first_layer_temperature = 270
max_fan_speed = 20
min_fan_speed = 10
min_print_speed = 5
slowdown_below_layer_time = 20
start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}45{endif}; Filament gcode"
temperature = 270
[filament:ColorFabb PLA-PHA]
inherits = *PLA*
filament_colour = #FF3232
[filament:ColorFabb Woodfil]
inherits = *PLA*
@ -632,7 +653,6 @@ temperature = 200
[filament:ColorFabb XT]
inherits = *PET*
filament_colour = #FF8000
filament_type = PLA
first_layer_bed_temperature = 90
first_layer_temperature = 260
@ -653,21 +673,19 @@ inherits = *PET*
bridge_fan_speed = 40
fan_always_on = 0
fan_below_layer_time = 10
filament_colour = #FF8000
filament_type = NGEN
first_layer_temperature = 240
max_fan_speed = 35
min_fan_speed = 20
[filament:ColorFabb nGen flex]
inherits = *flex*
inherits = *FLEX*
bed_temperature = 85
bridge_fan_speed = 40
cooling = 1
disable_fan_first_layers = 3
extrusion_multiplier = 1
fan_below_layer_time = 10
filament_colour = #FF8000
filament_max_volumetric_speed = 5
first_layer_bed_temperature = 85
first_layer_temperature = 260
@ -677,31 +695,26 @@ temperature = 260
[filament:E3D Edge]
inherits = *PET*
filament_colour = #FF8000
filament_notes = "List of manufacturers tested with standart PET print settings for MK2:\n\nE3D Edge\nFillamentum CPE GH100\nPlasty Mladeč PETG"
[filament:E3D PC-ABS]
inherits = *ABS*
filament_colour = #3A80CA
first_layer_temperature = 270
temperature = 270
[filament:Fillamentum ABS]
inherits = *ABS*
filament_colour = #3A80CA
first_layer_temperature = 240
temperature = 240
[filament:Fillamentum ASA]
inherits = *ABS*
fan_always_on = 1
filament_colour = #3A80CA
first_layer_temperature = 265
temperature = 265
[filament:Fillamentum CPE HG100 HM100]
inherits = *PET*
disable_fan_first_layers = 1
filament_colour = #FF8000
filament_notes = "CPE HG100 , CPE HM100"
first_layer_bed_temperature = 90
first_layer_temperature = 275
@ -733,9 +746,9 @@ filament_notes = "List of materials tested with standart PLA print settings for
[filament:Polymaker PC-Max]
inherits = *ABS*
bed_temperature = 120
bed_temperature = 115
filament_colour = #3A80CA
first_layer_bed_temperature = 120
first_layer_bed_temperature = 100
first_layer_temperature = 270
temperature = 270
@ -778,38 +791,28 @@ filament_notes = "List of manufacturers tested with standart PET print settings
[filament:Prusa PLA]
inherits = *PLA*
filament_colour = #FF3232
filament_notes = "List of materials tested with standart PLA print settings for MK2:\n\nDas Filament\nEsun PLA\nEUMAKERS PLA\nFiberlogy HD-PLA\nFillamentum PLA\nFloreon3D\nHatchbox PLA\nPlasty Mladeč PLA\nPrimavalue PLA\nProto pasta Matte Fiber\nVerbatim PLA\nVerbatim BVOH"
[filament:SemiFlex or Flexfill 98A]
inherits = *flex*
inherits = *FLEX*
[filament:Taulman Bridge]
bed_temperature = 50
inherits = *common*
bed_temperature = 90
bridge_fan_speed = 40
compatible_printers =
compatible_printers_condition =
cooling = 0
disable_fan_first_layers = 3
end_filament_gcode = "; Filament-specific end gcode"
extrusion_multiplier = 1
fan_always_on = 0
fan_below_layer_time = 20
filament_colour = #DEE0E6
filament_cost = 0
filament_density = 0
filament_diameter = 1.75
filament_max_volumetric_speed = 10
filament_notes = ""
filament_settings_id =
filament_soluble = 0
filament_type = PLA
first_layer_bed_temperature = 90
filament_type = PET
first_layer_bed_temperature = 60
first_layer_temperature = 240
max_fan_speed = 5
min_fan_speed = 0
min_print_speed = 5
slowdown_below_layer_time = 20
start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode"
temperature = 250
@ -818,7 +821,6 @@ inherits = *PET*
bridge_fan_speed = 40
cooling = 0
fan_always_on = 0
filament_colour = #FF8000
first_layer_bed_temperature = 90
first_layer_temperature = 240
max_fan_speed = 5
@ -826,23 +828,17 @@ min_fan_speed = 0
start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}30{endif}; Filament gcode"
[filament:Verbatim BVOH]
inherits = *common*
bed_temperature = 60
bridge_fan_speed = 100
compatible_printers =
compatible_printers_condition =
cooling = 0
disable_fan_first_layers = 1
end_filament_gcode = "; Filament-specific end gcode"
extrusion_multiplier = 1
fan_always_on = 0
fan_below_layer_time = 100
filament_colour = #FFFFD7
filament_cost = 0
filament_density = 0
filament_diameter = 1.75
filament_max_volumetric_speed = 10
filament_notes = "List of materials tested with standart PLA print settings for MK2:\n\nDas Filament\nEsun PLA\nEUMAKERS PLA\nFiberlogy HD-PLA\nFillamentum PLA\nFloreon3D\nHatchbox PLA\nPlasty Mladeč PLA\nPrimavalue PLA\nProto pasta Matte Fiber\nVerbatim PLA\nVerbatim BVOH"
filament_settings_id =
filament_soluble = 1
filament_type = PLA
first_layer_bed_temperature = 60
@ -850,36 +846,27 @@ first_layer_temperature = 215
max_fan_speed = 100
min_fan_speed = 100
min_print_speed = 15
slowdown_below_layer_time = 20
start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode"
temperature = 210
[filament:Verbatim PP]
inherits = *common*
bed_temperature = 100
bridge_fan_speed = 100
compatible_printers =
compatible_printers_condition =
cooling = 1
disable_fan_first_layers = 2
end_filament_gcode = "; Filament-specific end gcode"
extrusion_multiplier = 1
fan_always_on = 1
fan_below_layer_time = 100
filament_colour = #DEE0E6
filament_cost = 0
filament_density = 0
filament_diameter = 1.75
filament_max_volumetric_speed = 5
filament_notes = "List of materials tested with standart PLA print settings for MK2:\n\nEsun PLA\nFiberlogy HD-PLA\nFillamentum PLA\nFloreon3D\nHatchbox PLA\nPlasty Mladeč PLA\nPrimavalue PLA\nProto pasta Matte Fiber\nEUMAKERS PLA"
filament_settings_id =
filament_soluble = 0
filament_type = PLA
first_layer_bed_temperature = 100
first_layer_temperature = 220
max_fan_speed = 100
min_fan_speed = 100
min_print_speed = 15
slowdown_below_layer_time = 20
start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode"
temperature = 220
@ -904,7 +891,7 @@ retract_before_travel = 1
retract_before_wipe = 0%
retract_layer_change = 1
retract_length = 0.8
retract_length_toolchange = 3
retract_length_toolchange = 4
retract_lift = 0.6
retract_lift_above = 0
retract_lift_below = 199
@ -934,7 +921,6 @@ retract_before_travel = 3
retract_before_wipe = 60%
retract_layer_change = 0
retract_length = 4
retract_length_toolchange = 4
retract_lift = 0.6
retract_lift_above = 0
retract_lift_below = 199
@ -1005,3 +991,23 @@ retract_lift_below = 209
start_gcode = M115 U3.1.1-RC5 ; tell printer latest fw version\nM201 X1000 Y1000 Z200 E5000 ; sets maximum accelerations, mm/sec^2\nM203 X200 Y200 Z12 E120 ; sets maximum feedrates, mm/sec\nM204 S1250 T1250 ; sets acceleration (S) and retract acceleration (T)\nM205 X10 Y10 Z0.4 E2.5 ; sets the jerk limits, mm/sec\nM205 S0 T0 ; sets the minimum extruding and travel feed rate, mm/sec\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0\nM221 S{if layer_height==0.05}100{else}95{endif}
printer_model = MK3
default_print_profile = 0.15mm OPTIMAL MK3
[printer:Original Prusa i3 MK3 0.25 nozzle]
inherits = *common*
nozzle_diameter = 0.25
end_gcode = G4 ; wait\nM221 S100\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nG1 X0 Y200; home X axis\nM84 ; disable motors
printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_PRUSA3D\nPRINTER_MODEL_MK3\n
retract_lift_below = 209
start_gcode = M115 U3.1.1-RC5 ; tell printer latest fw version\nM201 X1000 Y1000 Z200 E5000 ; sets maximum accelerations, mm/sec^2\nM203 X200 Y200 Z12 E120 ; sets maximum feedrates, mm/sec\nM204 S1250 T1250 ; sets acceleration (S) and retract acceleration (T)\nM205 X10 Y10 Z0.4 E2.5 ; sets the jerk limits, mm/sec\nM205 S0 T0 ; sets the minimum extruding and travel feed rate, mm/sec\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0\nM221 S{if layer_height==0.05}100{else}95{endif}
printer_model = MK3
default_print_profile = 0.10mm DETAIL MK3
[printer:Original Prusa i3 MK3 0.6 nozzle]
inherits = *common*
nozzle_diameter = 0.6
end_gcode = G4 ; wait\nM221 S100\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nG1 X0 Y200; home X axis\nM84 ; disable motors
printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_PRUSA3D\nPRINTER_MODEL_MK3\n
retract_lift_below = 209
start_gcode = M115 U3.1.1-RC5 ; tell printer latest fw version\nM201 X1000 Y1000 Z200 E5000 ; sets maximum accelerations, mm/sec^2\nM203 X200 Y200 Z12 E120 ; sets maximum feedrates, mm/sec\nM204 S1250 T1250 ; sets acceleration (S) and retract acceleration (T)\nM205 X10 Y10 Z0.4 E2.5 ; sets the jerk limits, mm/sec\nM205 S0 T0 ; sets the minimum extruding and travel feed rate, mm/sec\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0\nM221 S{if layer_height==0.05}100{else}95{endif}
printer_model = MK3
default_print_profile = 0.15mm OPTIMAL MK3

View File

@ -94,6 +94,14 @@ public:
void translate(const Pointf3 &pos) { this->translate(pos.x, pos.y, pos.z); }
void offset(coordf_t delta);
PointClass center() const;
bool contains(const PointClass &point) const {
return BoundingBoxBase<PointClass>::contains(point) && point.z >= this->min.z && point.z <= this->max.z;
}
bool contains(const BoundingBox3Base<PointClass>& other) const {
return contains(other.min) && contains(other.max);
}
};
class BoundingBox : public BoundingBoxBase<Point>

View File

@ -222,7 +222,7 @@ bool Model::add_default_instances()
}
// this returns the bounding box of the *transformed* instances
BoundingBoxf3 Model::bounding_box()
BoundingBoxf3 Model::bounding_box() const
{
BoundingBoxf3 bb;
for (ModelObject *o : this->objects)
@ -230,6 +230,14 @@ BoundingBoxf3 Model::bounding_box()
return bb;
}
BoundingBoxf3 Model::transformed_bounding_box() const
{
BoundingBoxf3 bb;
for (const ModelObject* obj : this->objects)
bb.merge(obj->tight_bounding_box(false));
return bb;
}
void Model::center_instances_around_point(const Pointf &point)
{
// BoundingBoxf3 bb = this->bounding_box();
@ -428,6 +436,32 @@ void Model::adjust_min_z()
}
}
bool Model::fits_print_volume(const DynamicPrintConfig* config) const
{
if (config == nullptr)
return false;
if (objects.empty())
return true;
const ConfigOptionPoints* opt = dynamic_cast<const ConfigOptionPoints*>(config->option("bed_shape"));
if (opt == nullptr)
return false;
BoundingBox bed_box_2D = get_extents(Polygon::new_scale(opt->values));
BoundingBoxf3 print_volume(Pointf3(unscale(bed_box_2D.min.x), unscale(bed_box_2D.min.y), 0.0), Pointf3(unscale(bed_box_2D.max.x), unscale(bed_box_2D.max.y), config->opt_float("max_print_height")));
return print_volume.contains(transformed_bounding_box());
}
bool Model::fits_print_volume(const FullPrintConfig &config) const
{
if (objects.empty())
return true;
BoundingBox bed_box_2D = get_extents(Polygon::new_scale(config.bed_shape.values));
BoundingBoxf3 print_volume(Pointf3(unscale(bed_box_2D.min.x), unscale(bed_box_2D.min.y), 0.0), Pointf3(unscale(bed_box_2D.max.x), unscale(bed_box_2D.max.y), config.max_print_height));
return print_volume.contains(transformed_bounding_box());
}
ModelObject::ModelObject(Model *model, const ModelObject &other, bool copy_volumes) :
name(other.name),
input_file(other.input_file),
@ -558,7 +592,7 @@ void ModelObject::clear_instances()
// Returns the bounding box of the transformed instances.
// This bounding box is approximate and not snug.
BoundingBoxf3 ModelObject::bounding_box()
const BoundingBoxf3& ModelObject::bounding_box()
{
if (! m_bounding_box_valid) {
BoundingBoxf3 raw_bbox;
@ -574,6 +608,54 @@ BoundingBoxf3 ModelObject::bounding_box()
return m_bounding_box;
}
BoundingBoxf3 ModelObject::tight_bounding_box(bool include_modifiers) const
{
BoundingBoxf3 bb;
for (const ModelVolume* vol : this->volumes)
{
if (include_modifiers || !vol->modifier)
{
for (const ModelInstance* inst : this->instances)
{
double c = cos(inst->rotation);
double s = sin(inst->rotation);
for (int f = 0; f < vol->mesh.stl.stats.number_of_facets; ++f)
{
const stl_facet& facet = vol->mesh.stl.facet_start[f];
for (int i = 0; i < 3; ++i)
{
// original point
const stl_vertex& v = facet.vertex[i];
Pointf3 p((double)v.x, (double)v.y, (double)v.z);
// scale
p.x *= inst->scaling_factor;
p.y *= inst->scaling_factor;
p.z *= inst->scaling_factor;
// rotate Z
double x = p.x;
double y = p.y;
p.x = c * x - s * y;
p.y = s * x + c * y;
// translate
p.x += inst->offset.x;
p.y += inst->offset.y;
bb.merge(p);
}
}
}
}
}
return bb;
}
// A mesh containing all transformed instances of this object.
TriangleMesh ModelObject::mesh() const
{
@ -690,10 +772,7 @@ void ModelObject::transform(const float* matrix3x4)
v->mesh.transform(matrix3x4);
}
//#####################################################################################################
origin_translation = Pointf3(0.0, 0.0, 0.0);
// origin_translation = Pointf3(0.0f, 0.0f, 0.0f);
//#####################################################################################################
invalidate_bounding_box();
}

View File

@ -102,8 +102,12 @@ public:
// Returns the bounding box of the transformed instances.
// This bounding box is approximate and not snug.
BoundingBoxf3 bounding_box();
// This bounding box is being cached.
const BoundingBoxf3& bounding_box();
void invalidate_bounding_box() { m_bounding_box_valid = false; }
// Returns a snug bounding box of the transformed instances.
// This bounding box is not being cached.
BoundingBoxf3 tight_bounding_box(bool include_modifiers) const;
// A mesh containing all transformed instances of this object.
TriangleMesh mesh() const;
@ -260,7 +264,10 @@ public:
void delete_material(t_model_material_id material_id);
void clear_materials();
bool add_default_instances();
BoundingBoxf3 bounding_box();
// Returns approximate axis aligned bounding box of this model
BoundingBoxf3 bounding_box() const;
// Returns tight axis aligned bounding box of this model
BoundingBoxf3 transformed_bounding_box() const;
void center_instances_around_point(const Pointf &point);
void translate(coordf_t x, coordf_t y, coordf_t z) { for (ModelObject *o : this->objects) o->translate(x, y, z); }
TriangleMesh mesh() const;
@ -276,6 +283,10 @@ public:
// Ensures that the min z of the model is not negative
void adjust_min_z();
// Returs true if this model is contained into the print volume defined inside the given config
bool fits_print_volume(const DynamicPrintConfig* config) const;
bool fits_print_volume(const FullPrintConfig &config) const;
void print_info() const { for (const ModelObject *o : this->objects) o->print_info(); }
};

View File

@ -120,6 +120,7 @@ bool Print::invalidate_state_by_config_options(const std::vector<t_config_option
"layer_gcode",
"min_fan_speed",
"max_fan_speed",
"max_print_height",
"min_print_speed",
"max_print_speed",
"max_volumetric_speed",
@ -507,6 +508,15 @@ bool Print::has_skirt() const
std::string Print::validate() const
{
BoundingBox bed_box_2D = get_extents(Polygon::new_scale(config.bed_shape.values));
BoundingBoxf3 print_volume(Pointf3(unscale(bed_box_2D.min.x), unscale(bed_box_2D.min.y), 0.0), Pointf3(unscale(bed_box_2D.max.x), unscale(bed_box_2D.max.y), config.max_print_height));
// Allow the objects to protrude below the print bed, only the part of the object above the print bed will be sliced.
print_volume.min.z = -1e10;
for (PrintObject *po : this->objects) {
if (! print_volume.contains(po->model_object()->tight_bounding_box(false)))
return "Some objects are outside of the print volume.";
}
if (this->config.complete_objects) {
// Check horizontal clearance.
{

View File

@ -822,6 +822,13 @@ PrintConfigDef::PrintConfigDef()
def->min = 0;
def->default_value = new ConfigOptionFloats { 0. };
def = this->add("max_print_height", coFloat);
def->label = L("Max print height");
def->tooltip = L("Set this to the maximum height that can be reached by your extruder while printing.");
def->sidetext = L("mm");
def->cli = "max-print-height=f";
def->default_value = new ConfigOptionFloat(200.0);
def = this->add("max_print_speed", coFloat);
def->label = L("Max print speed");
def->tooltip = L("When setting other speed settings to 0 Slic3r will autocalculate the optimal speed "
@ -1554,12 +1561,10 @@ PrintConfigDef::PrintConfigDef()
def->enum_values.push_back("rectilinear");
def->enum_values.push_back("rectilinear-grid");
def->enum_values.push_back("honeycomb");
def->enum_values.push_back("pillars");
def->enum_labels.push_back("rectilinear");
def->enum_labels.push_back("rectilinear grid");
def->enum_labels.push_back("honeycomb");
def->enum_labels.push_back("pillars");
def->default_value = new ConfigOptionEnum<SupportMaterialPattern>(smpPillars);
def->default_value = new ConfigOptionEnum<SupportMaterialPattern>(smpRectilinear);
def = this->add("support_material_spacing", coFloat);
def->label = L("Pattern spacing");
@ -1831,6 +1836,9 @@ void PrintConfigDef::handle_legacy(t_config_option_key &opt_key, std::string &va
values is a dirty hack and will need to be removed sometime in the future, but it
will avoid lots of complaints for now. */
value = "0";
} else if (opt_key == "support_material_pattern" && value == "pillars") {
// Slic3r PE does not support the pillars. They never worked well.
value = "rectilinear";
} else if (opt_key == "support_material_threshold" && value == "0") {
// 0 used to be automatic threshold, but we introduced percent values so let's
// transform it into the default value

View File

@ -33,7 +33,7 @@ enum InfillPattern {
};
enum SupportMaterialPattern {
smpRectilinear, smpRectilinearGrid, smpHoneycomb, smpPillars,
smpRectilinear, smpRectilinearGrid, smpHoneycomb,
};
enum SeamPosition {
@ -87,7 +87,6 @@ template<> inline t_config_enum_values& ConfigOptionEnum<SupportMaterialPattern>
keys_map["rectilinear"] = smpRectilinear;
keys_map["rectilinear-grid"] = smpRectilinearGrid;
keys_map["honeycomb"] = smpHoneycomb;
keys_map["pillars"] = smpPillars;
}
return keys_map;
}
@ -583,6 +582,7 @@ public:
ConfigOptionFloats max_layer_height;
ConfigOptionInts min_fan_speed;
ConfigOptionFloats min_layer_height;
ConfigOptionFloat max_print_height;
ConfigOptionFloats min_print_speed;
ConfigOptionFloat min_skirt_length;
ConfigOptionString notes;
@ -647,6 +647,7 @@ protected:
OPT_PTR(max_layer_height);
OPT_PTR(min_fan_speed);
OPT_PTR(min_layer_height);
OPT_PTR(max_print_height);
OPT_PTR(min_print_speed);
OPT_PTR(min_skirt_length);
OPT_PTR(notes);

View File

@ -2491,7 +2491,6 @@ void PrintObjectSupportMaterial::generate_toolpaths(
infill_pattern = ipRectilinear;
break;
case smpHoneycomb:
case smpPillars:
infill_pattern = ipHoneycomb;
break;
}

View File

@ -46,6 +46,25 @@ void GLIndexedVertexArray::load_mesh_flat_shading(const TriangleMesh &mesh)
}
}
void GLIndexedVertexArray::load_mesh_full_shading(const TriangleMesh &mesh)
{
assert(triangle_indices.empty() && vertices_and_normals_interleaved_size == 0);
assert(quad_indices.empty() && triangle_indices_size == 0);
assert(vertices_and_normals_interleaved.size() % 6 == 0 && quad_indices_size == vertices_and_normals_interleaved.size());
this->vertices_and_normals_interleaved.reserve(this->vertices_and_normals_interleaved.size() + 3 * 3 * 2 * mesh.facets_count());
unsigned int vertices_count = 0;
for (int i = 0; i < mesh.stl.stats.number_of_facets; ++i) {
const stl_facet &facet = mesh.stl.facet_start[i];
for (int j = 0; j < 3; ++j)
this->push_geometry(facet.vertex[j].x, facet.vertex[j].y, facet.vertex[j].z, facet.normal.x, facet.normal.y, facet.normal.z);
this->push_triangle(vertices_count, vertices_count + 1, vertices_count + 2);
vertices_count += 3;
}
}
void GLIndexedVertexArray::finalize_geometry(bool use_VBOs)
{
assert(this->vertices_and_normals_interleaved_VBO_id == 0);
@ -173,6 +192,45 @@ void GLIndexedVertexArray::render(
glDisableClientState(GL_NORMAL_ARRAY);
}
const float GLVolume::SELECTED_COLOR[4] = { 0.0f, 1.0f, 0.0f, 1.0f };
const float GLVolume::HOVER_COLOR[4] = { 0.4f, 0.9f, 0.1f, 1.0f };
const float GLVolume::OUTSIDE_COLOR[4] = { 0.75f, 0.0f, 0.75f, 1.0f };
const float GLVolume::SELECTED_OUTSIDE_COLOR[4] = { 1.0f, 0.0f, 1.0f, 1.0f };
void GLVolume::set_render_color(float r, float g, float b, float a)
{
render_color[0] = r;
render_color[1] = g;
render_color[2] = b;
render_color[3] = a;
}
void GLVolume::set_render_color(const float* rgba, unsigned int size)
{
size = std::min((unsigned int)4, size);
for (int i = 0; i < size; ++i)
{
render_color[i] = rgba[i];
}
}
void GLVolume::set_render_color()
{
if (selected)
{
if (is_outside)
set_render_color(SELECTED_OUTSIDE_COLOR, 4);
else
set_render_color(SELECTED_COLOR, 4);
}
else if (hover)
set_render_color(HOVER_COLOR, 4);
else if (is_outside)
set_render_color(OUTSIDE_COLOR, 4);
else
set_render_color(color, 4);
}
void GLVolume::set_range(double min_z, double max_z)
{
this->qverts_range.first = 0;
@ -223,6 +281,51 @@ void GLVolume::render() const
glPopMatrix();
}
void GLVolume::render_using_layer_height() const
{
if (!is_active)
return;
GLint current_program_id;
glGetIntegerv(GL_CURRENT_PROGRAM, &current_program_id);
if ((layer_height_texture_data.shader_id > 0) && (layer_height_texture_data.shader_id != current_program_id))
glUseProgram(layer_height_texture_data.shader_id);
GLint z_to_texture_row_id = (layer_height_texture_data.shader_id > 0) ? glGetUniformLocation(layer_height_texture_data.shader_id, "z_to_texture_row") : -1;
GLint z_texture_row_to_normalized_id = (layer_height_texture_data.shader_id > 0) ? glGetUniformLocation(layer_height_texture_data.shader_id, "z_texture_row_to_normalized") : -1;
GLint z_cursor_id = (layer_height_texture_data.shader_id > 0) ? glGetUniformLocation(layer_height_texture_data.shader_id, "z_cursor") : -1;
GLint z_cursor_band_width_id = (layer_height_texture_data.shader_id > 0) ? glGetUniformLocation(layer_height_texture_data.shader_id, "z_cursor_band_width") : -1;
if (z_to_texture_row_id >= 0)
glUniform1f(z_to_texture_row_id, (GLfloat)layer_height_texture_z_to_row_id());
if (z_texture_row_to_normalized_id >= 0)
glUniform1f(z_texture_row_to_normalized_id, (GLfloat)(1.0f / layer_height_texture_height()));
if (z_cursor_id >= 0)
glUniform1f(z_cursor_id, (GLfloat)(bounding_box.max.z * layer_height_texture_data.z_cursor_relative));
if (z_cursor_band_width_id >= 0)
glUniform1f(z_cursor_band_width_id, (GLfloat)layer_height_texture_data.edit_band_width);
unsigned int w = layer_height_texture_width();
unsigned int h = layer_height_texture_height();
glBindTexture(GL_TEXTURE_2D, layer_height_texture_data.texture_id);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, w / 2, h / 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, layer_height_texture_data_ptr_level0());
glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, w / 2, h / 2, GL_RGBA, GL_UNSIGNED_BYTE, layer_height_texture_data_ptr_level1());
render();
glBindTexture(GL_TEXTURE_2D, 0);
if ((current_program_id > 0) && (layer_height_texture_data.shader_id != current_program_id))
glUseProgram(current_program_id);
}
void GLVolume::generate_layer_height_texture(PrintObject *print_object, bool force)
{
GLTexture *tex = this->layer_height_texture.get();
@ -288,7 +391,11 @@ std::vector<int> GLVolumeCollection::load_object(
color[3] = model_volume->modifier ? 0.5f : 1.f;
this->volumes.emplace_back(new GLVolume(color));
GLVolume &v = *this->volumes.back();
v.indexed_vertex_array.load_mesh_flat_shading(mesh);
if (use_VBOs)
v.indexed_vertex_array.load_mesh_full_shading(mesh);
else
v.indexed_vertex_array.load_mesh_flat_shading(mesh);
// finalize_geometry() clears the vertex arrays, therefore the bounding box has to be computed before finalize_geometry().
v.bounding_box = v.indexed_vertex_array.bounding_box();
v.indexed_vertex_array.finalize_geometry(use_VBOs);
@ -319,7 +426,11 @@ int GLVolumeCollection::load_wipe_tower_preview(
this->volumes.emplace_back(new GLVolume(color));
GLVolume &v = *this->volumes.back();
auto mesh = make_cube(width, depth, height);
v.indexed_vertex_array.load_mesh_flat_shading(mesh);
if (use_VBOs)
v.indexed_vertex_array.load_mesh_full_shading(mesh);
else
v.indexed_vertex_array.load_mesh_flat_shading(mesh);
v.origin = Pointf3(pos_x, pos_y, 0.);
// finalize_geometry() clears the vertex arrays, therefore the bounding box has to be computed before finalize_geometry().
v.bounding_box = v.indexed_vertex_array.bounding_box();
@ -332,15 +443,19 @@ int GLVolumeCollection::load_wipe_tower_preview(
void GLVolumeCollection::render_VBOs() const
{
// glEnable(GL_BLEND);
// glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glCullFace(GL_BACK);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
::glEnable(GL_BLEND);
::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
::glCullFace(GL_BACK);
::glEnableClientState(GL_VERTEX_ARRAY);
::glEnableClientState(GL_NORMAL_ARRAY);
GLint current_program_id;
glGetIntegerv(GL_CURRENT_PROGRAM, &current_program_id);
::glGetIntegerv(GL_CURRENT_PROGRAM, &current_program_id);
GLint color_id = (current_program_id > 0) ? glGetUniformLocation(current_program_id, "uniform_color") : -1;
GLint print_box_min_id = (current_program_id > 0) ? glGetUniformLocation(current_program_id, "print_box.min") : -1;
GLint print_box_max_id = (current_program_id > 0) ? glGetUniformLocation(current_program_id, "print_box.max") : -1;
GLint print_box_origin_id = (current_program_id > 0) ? glGetUniformLocation(current_program_id, "print_box.volume_origin") : -1;
for (GLVolume *volume : this->volumes) {
if (!volume->is_active)
@ -348,61 +463,110 @@ void GLVolumeCollection::render_VBOs() const
if (!volume->indexed_vertex_array.vertices_and_normals_interleaved_VBO_id)
continue;
if (volume->layer_height_texture_data.can_use())
{
::glDisableClientState(GL_VERTEX_ARRAY);
::glDisableClientState(GL_NORMAL_ARRAY);
volume->generate_layer_height_texture(volume->layer_height_texture_data.print_object, false);
volume->render_using_layer_height();
::glEnableClientState(GL_VERTEX_ARRAY);
::glEnableClientState(GL_NORMAL_ARRAY);
continue;
}
volume->set_render_color();
GLsizei n_triangles = GLsizei(std::min(volume->indexed_vertex_array.triangle_indices_size, volume->tverts_range.second - volume->tverts_range.first));
GLsizei n_quads = GLsizei(std::min(volume->indexed_vertex_array.quad_indices_size, volume->qverts_range.second - volume->qverts_range.first));
if (n_triangles + n_quads == 0)
{
if (_render_interleaved_only_volumes.enabled)
::glDisableClientState(GL_VERTEX_ARRAY);
::glDisableClientState(GL_NORMAL_ARRAY);
if (color_id >= 0)
{
::glDisableClientState(GL_VERTEX_ARRAY);
::glDisableClientState(GL_NORMAL_ARRAY);
::glEnable(GL_BLEND);
::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
if (color_id >= 0)
{
float color[4];
::memcpy((void*)color, (const void*)volume->color, 3 * sizeof(float));
color[3] = _render_interleaved_only_volumes.alpha;
::glUniform4fv(color_id, 1, (const GLfloat*)color);
}
else
::glColor4f(volume->color[0], volume->color[1], volume->color[2], _render_interleaved_only_volumes.alpha);
volume->render();
::glDisable(GL_BLEND);
::glEnableClientState(GL_VERTEX_ARRAY);
::glEnableClientState(GL_NORMAL_ARRAY);
float color[4];
::memcpy((void*)color, (const void*)volume->render_color, 4 * sizeof(float));
::glUniform4fv(color_id, 1, (const GLfloat*)color);
}
else
::glColor4f(volume->render_color[0], volume->render_color[1], volume->render_color[2], volume->render_color[3]);
if (print_box_min_id != -1)
::glUniform3fv(print_box_min_id, 1, (const GLfloat*)print_box_min);
if (print_box_max_id != -1)
::glUniform3fv(print_box_max_id, 1, (const GLfloat*)print_box_max);
if (print_box_origin_id != -1)
{
float origin[4] = { (float)volume->origin.x, (float)volume->origin.y, (float)volume->origin.z, volume->outside_printer_detection_enabled ? 1.0f : 0.0f };
::glUniform4fv(print_box_origin_id, 1, (const GLfloat*)origin);
}
volume->render();
::glEnableClientState(GL_VERTEX_ARRAY);
::glEnableClientState(GL_NORMAL_ARRAY);
continue;
}
if (color_id >= 0)
glUniform4fv(color_id, 1, (const GLfloat*)volume->color);
::glUniform4fv(color_id, 1, (const GLfloat*)volume->render_color);
else
glColor4f(volume->color[0], volume->color[1], volume->color[2], volume->color[3]);
glBindBuffer(GL_ARRAY_BUFFER, volume->indexed_vertex_array.vertices_and_normals_interleaved_VBO_id);
glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), (const void*)(3 * sizeof(float)));
glNormalPointer(GL_FLOAT, 6 * sizeof(float), nullptr);
::glColor4f(volume->render_color[0], volume->render_color[1], volume->render_color[2], volume->render_color[3]);
if (print_box_min_id != -1)
::glUniform3fv(print_box_min_id, 1, (const GLfloat*)print_box_min);
if (print_box_max_id != -1)
::glUniform3fv(print_box_max_id, 1, (const GLfloat*)print_box_max);
if (print_box_origin_id != -1)
{
float origin[4] = { (float)volume->origin.x, (float)volume->origin.y, (float)volume->origin.z, volume->outside_printer_detection_enabled ? 1.0f : 0.0f };
::glUniform4fv(print_box_origin_id, 1, (const GLfloat*)origin);
}
::glBindBuffer(GL_ARRAY_BUFFER, volume->indexed_vertex_array.vertices_and_normals_interleaved_VBO_id);
::glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), (const void*)(3 * sizeof(float)));
::glNormalPointer(GL_FLOAT, 6 * sizeof(float), nullptr);
bool has_offset = (volume->origin.x != 0) || (volume->origin.y != 0) || (volume->origin.z != 0);
if (has_offset) {
::glPushMatrix();
::glTranslated(volume->origin.x, volume->origin.y, volume->origin.z);
}
if (n_triangles > 0) {
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, volume->indexed_vertex_array.triangle_indices_VBO_id);
glDrawElements(GL_TRIANGLES, n_triangles, GL_UNSIGNED_INT, (const void*)(volume->tverts_range.first * 4));
::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, volume->indexed_vertex_array.triangle_indices_VBO_id);
::glDrawElements(GL_TRIANGLES, n_triangles, GL_UNSIGNED_INT, (const void*)(volume->tverts_range.first * 4));
}
if (n_quads > 0) {
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, volume->indexed_vertex_array.quad_indices_VBO_id);
glDrawElements(GL_QUADS, n_quads, GL_UNSIGNED_INT, (const void*)(volume->qverts_range.first * 4));
::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, volume->indexed_vertex_array.quad_indices_VBO_id);
::glDrawElements(GL_QUADS, n_quads, GL_UNSIGNED_INT, (const void*)(volume->qverts_range.first * 4));
}
if (has_offset)
::glPopMatrix();
}
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
// glDisable(GL_BLEND);
::glBindBuffer(GL_ARRAY_BUFFER, 0);
::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
::glDisableClientState(GL_VERTEX_ARRAY);
::glDisableClientState(GL_NORMAL_ARRAY);
::glDisable(GL_BLEND);
}
void GLVolumeCollection::render_legacy() const
{
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glCullFace(GL_BACK);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
@ -412,27 +576,25 @@ void GLVolumeCollection::render_legacy() const
if (!volume->is_active)
continue;
volume->set_render_color();
GLsizei n_triangles = GLsizei(std::min(volume->indexed_vertex_array.triangle_indices_size, volume->tverts_range.second - volume->tverts_range.first));
GLsizei n_quads = GLsizei(std::min(volume->indexed_vertex_array.quad_indices_size, volume->qverts_range.second - volume->qverts_range.first));
if (n_triangles + n_quads == 0)
{
if (_render_interleaved_only_volumes.enabled)
{
::glDisableClientState(GL_VERTEX_ARRAY);
::glDisableClientState(GL_NORMAL_ARRAY);
::glEnable(GL_BLEND);
::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
::glDisableClientState(GL_VERTEX_ARRAY);
::glDisableClientState(GL_NORMAL_ARRAY);
::glColor4f(volume->color[0], volume->color[1], volume->color[2], _render_interleaved_only_volumes.alpha);
volume->render();
::glColor4f(volume->render_color[0], volume->render_color[1], volume->render_color[2], volume->render_color[3]);
volume->render();
::glEnableClientState(GL_VERTEX_ARRAY);
::glEnableClientState(GL_NORMAL_ARRAY);
::glDisable(GL_BLEND);
::glEnableClientState(GL_VERTEX_ARRAY);
::glEnableClientState(GL_NORMAL_ARRAY);
}
continue;
}
glColor4f(volume->color[0], volume->color[1], volume->color[2], volume->color[3]);
glColor4f(volume->render_color[0], volume->render_color[1], volume->render_color[2], volume->render_color[3]);
glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), volume->indexed_vertex_array.vertices_and_normals_interleaved.data() + 3);
glNormalPointer(GL_FLOAT, 6 * sizeof(float), volume->indexed_vertex_array.vertices_and_normals_interleaved.data());
bool has_offset = volume->origin.x != 0 || volume->origin.y != 0 || volume->origin.z != 0;
@ -445,11 +607,37 @@ void GLVolumeCollection::render_legacy() const
if (n_quads > 0)
glDrawElements(GL_QUADS, n_quads, GL_UNSIGNED_INT, volume->indexed_vertex_array.quad_indices.data() + volume->qverts_range.first);
if (has_offset)
glPushMatrix();
glPopMatrix();
}
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisable(GL_BLEND);
}
void GLVolumeCollection::update_outside_state(const DynamicPrintConfig* config, bool all_inside)
{
if (config == nullptr)
return;
const ConfigOptionPoints* opt = dynamic_cast<const ConfigOptionPoints*>(config->option("bed_shape"));
if (opt == nullptr)
return;
BoundingBox bed_box_2D = get_extents(Polygon::new_scale(opt->values));
BoundingBoxf3 print_volume(Pointf3(unscale(bed_box_2D.min.x), unscale(bed_box_2D.min.y), 0.0), Pointf3(unscale(bed_box_2D.max.x), unscale(bed_box_2D.max.y), config->opt_float("max_print_height")));
for (GLVolume* volume : this->volumes)
{
if (all_inside)
{
volume->is_outside = false;
continue;
}
volume->is_outside = !print_volume.contains(volume->transformed_bounding_box());
}
}
std::vector<double> GLVolumeCollection::get_current_print_zs() const
@ -1133,6 +1321,100 @@ static void point3_to_verts(const Point3& point, double width, double height, GL
_3DScene::GCodePreviewVolumeIndex _3DScene::s_gcode_preview_volume_index;
_3DScene::LegendTexture _3DScene::s_legend_texture;
_3DScene::WarningTexture _3DScene::s_warning_texture;
unsigned int _3DScene::TextureBase::finalize()
{
if (!m_data.empty()) {
// sends buffer to gpu
::glGenTextures(1, &m_tex_id);
::glBindTexture(GL_TEXTURE_2D, m_tex_id);
::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, (GLsizei)m_tex_width, (GLsizei)m_tex_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const GLvoid*)m_data.data());
::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);
::glBindTexture(GL_TEXTURE_2D, 0);
m_data.clear();
}
return (m_tex_width > 0 && m_tex_height > 0) ? m_tex_id : 0;
}
void _3DScene::TextureBase::_destroy_texture()
{
if (m_tex_id > 0)
{
::glDeleteTextures(1, &m_tex_id);
m_tex_id = 0;
m_tex_height = 0;
m_tex_width = 0;
}
m_data.clear();
}
const unsigned char _3DScene::WarningTexture::Background_Color[3] = { 9, 91, 134 };
const unsigned char _3DScene::WarningTexture::Opacity = 255;
// Generate a texture data, but don't load it into the GPU yet, as the GPU context may not yet be valid.
bool _3DScene::WarningTexture::generate(const std::string& msg)
{
// Mark the texture as released, but don't release the texture from the GPU yet.
m_tex_width = m_tex_height = 0;
m_data.clear();
if (msg.empty())
return false;
wxMemoryDC memDC;
// select default font
memDC.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
// calculates texture size
wxCoord w, h;
memDC.GetTextExtent(msg, &w, &h);
m_tex_width = (unsigned int)w;
m_tex_height = (unsigned int)h;
// generates bitmap
wxBitmap bitmap(m_tex_width, m_tex_height);
#if defined(__APPLE__) || defined(_MSC_VER)
bitmap.UseAlpha();
#endif
memDC.SelectObject(bitmap);
memDC.SetBackground(wxBrush(wxColour(Background_Color[0], Background_Color[1], Background_Color[2])));
memDC.Clear();
memDC.SetTextForeground(*wxWHITE);
// draw message
memDC.DrawText(msg, 0, 0);
memDC.SelectObject(wxNullBitmap);
// Convert the bitmap into a linear data ready to be loaded into the GPU.
{
wxImage image = bitmap.ConvertToImage();
image.SetMaskColour(Background_Color[0], Background_Color[1], Background_Color[2]);
// prepare buffer
m_data.assign(4 * m_tex_width * m_tex_height, 0);
for (unsigned int h = 0; h < m_tex_height; ++h)
{
unsigned int hh = h * m_tex_width;
unsigned char* px_ptr = m_data.data() + 4 * hh;
for (unsigned int w = 0; w < m_tex_width; ++w)
{
*px_ptr++ = image.GetRed(w, h);
*px_ptr++ = image.GetGreen(w, h);
*px_ptr++ = image.GetBlue(w, h);
*px_ptr++ = image.IsTransparent(w, h) ? 0 : Opacity;
}
}
}
return true;
}
const unsigned char _3DScene::LegendTexture::Squares_Border_Color[3] = { 64, 64, 64 };
const unsigned char _3DScene::LegendTexture::Background_Color[3] = { 9, 91, 134 };
@ -1276,34 +1558,6 @@ bool _3DScene::LegendTexture::generate(const GCodePreviewData& preview_data, con
return true;
}
unsigned int _3DScene::LegendTexture::finalize()
{
if (! m_data.empty()) {
// sends buffer to gpu
::glGenTextures(1, &m_tex_id);
::glBindTexture(GL_TEXTURE_2D, m_tex_id);
::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, (GLsizei)m_tex_width, (GLsizei)m_tex_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const GLvoid*)m_data.data());
::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);
::glBindTexture(GL_TEXTURE_2D, 0);
m_data.clear();
}
return (m_tex_width > 0 && m_tex_height > 0) ? m_tex_id : 0;
}
void _3DScene::LegendTexture::_destroy_texture()
{
if (m_tex_id > 0)
{
::glDeleteTextures(1, &m_tex_id);
m_tex_id = 0;
m_tex_height = 0;
m_tex_width = 0;
}
m_data.clear();
}
void _3DScene::_glew_init()
{
glewInit();
@ -1353,27 +1607,17 @@ void _3DScene::load_gcode_preview(const Print* print, const GCodePreviewData* pr
_load_gcode_unretractions(*preview_data, *volumes, use_VBOs);
if (volumes->empty())
{
reset_legend_texture();
volumes->set_render_interleaved_only_volumes(GLVolumeCollection::RenderInterleavedOnlyVolumes(false, 0.0f));
}
else
{
_generate_legend_texture(*preview_data, tool_colors);
_load_shells(*print, *volumes, use_VBOs);
volumes->set_render_interleaved_only_volumes(GLVolumeCollection::RenderInterleavedOnlyVolumes(true, 0.25f));
}
}
_update_gcode_volumes_visibility(*preview_data, *volumes);
}
unsigned int _3DScene::get_legend_texture_id()
{
return s_legend_texture.get_texture_id();
}
unsigned int _3DScene::get_legend_texture_width()
{
return s_legend_texture.get_texture_width();
@ -1389,6 +1633,36 @@ void _3DScene::reset_legend_texture()
s_legend_texture.reset_texture();
}
unsigned int _3DScene::finalize_legend_texture()
{
return s_legend_texture.finalize();
}
unsigned int _3DScene::get_warning_texture_width()
{
return s_warning_texture.get_texture_width();
}
unsigned int _3DScene::get_warning_texture_height()
{
return s_warning_texture.get_texture_height();
}
void _3DScene::generate_warning_texture(const std::string& msg)
{
s_warning_texture.generate(msg);
}
void _3DScene::reset_warning_texture()
{
s_warning_texture.reset_texture();
}
unsigned int _3DScene::finalize_warning_texture()
{
return s_warning_texture.finalize();
}
// Create 3D thick extrusion lines for a skirt and brim.
// Adds a new Slic3r::GUI::3DScene::Volume to volumes.
void _3DScene::_load_print_toolpaths(
@ -1501,6 +1775,7 @@ void _3DScene::_load_print_object_toolpaths(
auto new_volume = [volumes, &new_volume_mutex](const float *color) -> GLVolume* {
auto *volume = new GLVolume(color);
new_volume_mutex.lock();
volume->outside_printer_detection_enabled = false;
volumes->volumes.emplace_back(volume);
new_volume_mutex.unlock();
return volume;
@ -1651,6 +1926,7 @@ void _3DScene::_load_wipe_tower_toolpaths(
auto new_volume = [volumes, &new_volume_mutex](const float *color) -> GLVolume* {
auto *volume = new GLVolume(color);
new_volume_mutex.lock();
volume->outside_printer_detection_enabled = false;
volumes->volumes.emplace_back(volume);
new_volume_mutex.unlock();
return volume;
@ -2221,6 +2497,7 @@ void _3DScene::_update_gcode_volumes_visibility(const GCodePreviewData& preview_
for (std::vector<GLVolume*>::iterator it = begin; it != end; ++it)
{
GLVolume* volume = *it;
volume->outside_printer_detection_enabled = false;
switch (s_gcode_preview_volume_index.first_volumes[i].type)
{
@ -2253,6 +2530,7 @@ void _3DScene::_update_gcode_volumes_visibility(const GCodePreviewData& preview_
case GCodePreviewVolumeIndex::Shell:
{
volume->is_active = preview_data.shell.is_visible;
volume->color[3] = 0.25f;
volume->zoom_to_volumes = false;
break;
}
@ -2272,11 +2550,6 @@ void _3DScene::_generate_legend_texture(const GCodePreviewData& preview_data, co
s_legend_texture.generate(preview_data, tool_colors);
}
unsigned int _3DScene::finalize_legend_texture()
{
return s_legend_texture.finalize();
}
void _3DScene::_load_shells(const Print& print, GLVolumeCollection& volumes, bool use_VBOs)
{
size_t initial_volumes_count = volumes.volumes.size();

View File

@ -16,6 +16,7 @@ class PrintObject;
class Model;
class ModelObject;
class GCodePreviewData;
class DynamicPrintConfig;
// A container for interleaved arrays of 3D vertices and normals,
// possibly indexed by triangles and / or quads.
@ -85,6 +86,7 @@ public:
unsigned int quad_indices_VBO_id;
void load_mesh_flat_shading(const TriangleMesh &mesh);
void load_mesh_full_shading(const TriangleMesh &mesh);
inline bool has_VBOs() const { return vertices_and_normals_interleaved_VBO_id != 0; }
@ -208,7 +210,38 @@ public:
};
class GLVolume {
struct LayerHeightTextureData
{
// ID of the layer height texture
unsigned int texture_id;
// ID of the shader used to render with the layer height texture
unsigned int shader_id;
// The print object to update when generating the layer height texture
PrintObject* print_object;
float z_cursor_relative;
float edit_band_width;
LayerHeightTextureData() { reset(); }
void reset()
{
texture_id = 0;
shader_id = 0;
print_object = nullptr;
z_cursor_relative = 0.0f;
edit_band_width = 0.0f;
}
bool can_use() { return (texture_id > 0) && (shader_id > 0) && (print_object != nullptr); }
};
public:
static const float SELECTED_COLOR[4];
static const float HOVER_COLOR[4];
static const float OUTSIDE_COLOR[4];
static const float SELECTED_OUTSIDE_COLOR[4];
GLVolume(float r = 1.f, float g = 1.f, float b = 1.f, float a = 1.f) :
composite_id(-1),
select_group_id(-1),
@ -216,6 +249,8 @@ public:
selected(false),
is_active(true),
zoom_to_volumes(true),
outside_printer_detection_enabled(true),
is_outside(false),
hover(false),
tverts_range(0, size_t(-1)),
qverts_range(0, size_t(-1))
@ -224,6 +259,7 @@ public:
color[1] = g;
color[2] = b;
color[3] = a;
set_render_color(r, g, b, a);
}
GLVolume(const float *rgba) : GLVolume(rgba[0], rgba[1], rgba[2], rgba[3]) {}
@ -243,7 +279,8 @@ public:
Pointf3 origin;
// Color of the triangles / quads held by this volume.
float color[4];
// Color used to render this volume.
float render_color[4];
// An ID containing the object ID, volume ID and instance ID.
int composite_id;
// An ID for group selection. It may be the same for all meshes of all object instances, or for just a single object instance.
@ -256,6 +293,10 @@ public:
bool is_active;
// Whether or not to use this volume when applying zoom_to_volumes()
bool zoom_to_volumes;
// Wheter or not this volume is enabled for outside print volume detection.
bool outside_printer_detection_enabled;
// Wheter or not this volume is outside print volume.
bool is_outside;
// Boolean: Is mouse over this object?
bool hover;
@ -271,6 +312,10 @@ public:
// Offset into qverts & tverts, or offsets into indices stored into an OpenGL name_index_buffer.
std::vector<size_t> offsets;
void set_render_color(float r, float g, float b, float a);
void set_render_color(const float* rgba, unsigned int size);
// Sets render color in dependence of current state
void set_render_color();
int object_idx() const { return this->composite_id / 1000000; }
int volume_idx() const { return (this->composite_id / 1000) % 1000; }
@ -282,11 +327,14 @@ public:
void set_range(coordf_t low, coordf_t high);
void render() const;
void render_using_layer_height() const;
void finalize_geometry(bool use_VBOs) { this->indexed_vertex_array.finalize_geometry(use_VBOs); }
void release_geometry() { this->indexed_vertex_array.release_geometry(); }
/************************************************ Layer height texture ****************************************************/
std::shared_ptr<GLTexture> layer_height_texture;
// Data to render this volume using the layer height texture
LayerHeightTextureData layer_height_texture_data;
bool has_layer_height_texture() const
{ return this->layer_height_texture.get() != nullptr; }
@ -296,11 +344,11 @@ public:
{ return (this->layer_height_texture.get() == nullptr) ? 0 : this->layer_height_texture->height; }
size_t layer_height_texture_cells() const
{ return (this->layer_height_texture.get() == nullptr) ? 0 : this->layer_height_texture->cells; }
void* layer_height_texture_data_ptr_level0() {
void* layer_height_texture_data_ptr_level0() const {
return (layer_height_texture.get() == nullptr) ? 0 :
(void*)layer_height_texture->data.data();
}
void* layer_height_texture_data_ptr_level1() {
void* layer_height_texture_data_ptr_level1() const {
return (layer_height_texture.get() == nullptr) ? 0 :
(void*)(layer_height_texture->data.data() + layer_height_texture->width * layer_height_texture->height * 4);
}
@ -309,31 +357,24 @@ public:
double(this->layer_height_texture->cells - 1) / (double(this->layer_height_texture->width) * bounding_box.max.z);
}
void generate_layer_height_texture(PrintObject *print_object, bool force);
void set_layer_height_texture_data(unsigned int texture_id, unsigned int shader_id, PrintObject* print_object, float z_cursor_relative, float edit_band_width)
{
layer_height_texture_data.texture_id = texture_id;
layer_height_texture_data.shader_id = shader_id;
layer_height_texture_data.print_object = print_object;
layer_height_texture_data.z_cursor_relative = z_cursor_relative;
layer_height_texture_data.edit_band_width = edit_band_width;
}
void reset_layer_height_texture_data() { layer_height_texture_data.reset(); }
};
class GLVolumeCollection
{
public:
struct RenderInterleavedOnlyVolumes
{
bool enabled;
float alpha; // [0..1]
RenderInterleavedOnlyVolumes()
: enabled(false)
, alpha(0.0f)
{
}
RenderInterleavedOnlyVolumes(bool enabled, float alpha)
: enabled(enabled)
, alpha(alpha)
{
}
};
private:
RenderInterleavedOnlyVolumes _render_interleaved_only_volumes;
// min and max vertex of the print box volume
float print_box_min[3];
float print_box_max[3];
public:
std::vector<GLVolume*> volumes;
@ -370,7 +411,12 @@ public:
bool empty() const { return volumes.empty(); }
void set_range(double low, double high) { for (GLVolume *vol : this->volumes) vol->set_range(low, high); }
void set_render_interleaved_only_volumes(const RenderInterleavedOnlyVolumes& render_interleaved_only_volumes) { _render_interleaved_only_volumes = render_interleaved_only_volumes; }
void set_print_box(float min_x, float min_y, float min_z, float max_x, float max_y, float max_z) {
print_box_min[0] = min_x; print_box_min[1] = min_y; print_box_min[2] = min_z;
print_box_max[0] = max_x; print_box_max[1] = max_y; print_box_max[2] = max_z;
}
void update_outside_state(const DynamicPrintConfig* config, bool all_inside);
// Returns a vector containing the sorted list of all the print_zs of the volumes contained in this collection
std::vector<double> get_current_print_zs() const;
@ -411,27 +457,20 @@ class _3DScene
static GCodePreviewVolumeIndex s_gcode_preview_volume_index;
class LegendTexture
class TextureBase
{
static const unsigned int Px_Title_Offset = 5;
static const unsigned int Px_Text_Offset = 5;
static const unsigned int Px_Square = 20;
static const unsigned int Px_Square_Contour = 1;
static const unsigned int Px_Border = Px_Square / 2;
static const unsigned char Squares_Border_Color[3];
static const unsigned char Background_Color[3];
static const unsigned char Opacity;
protected:
unsigned int m_tex_id;
unsigned int m_tex_width;
unsigned int m_tex_height;
// generate() fills in m_data with the pixels, while finalize() moves the data to the GPU before rendering.
std::vector<unsigned char> m_data;
public:
LegendTexture() : m_tex_id(0), m_tex_width(0), m_tex_height(0) {}
~LegendTexture() { _destroy_texture(); }
// Generate a texture data, but don't load it into the GPU yet, as the glcontext may not be valid yet.
bool generate(const GCodePreviewData& preview_data, const std::vector<float>& tool_colors);
TextureBase() : m_tex_id(0), m_tex_width(0), m_tex_height(0) {}
virtual ~TextureBase() { _destroy_texture(); }
// If not loaded, load the texture data into the GPU. Return a texture ID or 0 if the texture has zero size.
unsigned int finalize();
@ -442,26 +481,61 @@ class _3DScene
void reset_texture() { _destroy_texture(); }
private:
bool _create_texture(const GCodePreviewData& preview_data, const wxBitmap& bitmap);
void _destroy_texture();
// generate() fills in m_data with the pixels, while finalize() moves the data to the GPU before rendering.
std::vector<unsigned char> m_data;
};
class WarningTexture : public TextureBase
{
static const unsigned char Background_Color[3];
static const unsigned char Opacity;
public:
WarningTexture() : TextureBase() {}
// Generate a texture data, but don't load it into the GPU yet, as the glcontext may not be valid yet.
bool generate(const std::string& msg);
};
class LegendTexture : public TextureBase
{
static const unsigned int Px_Title_Offset = 5;
static const unsigned int Px_Text_Offset = 5;
static const unsigned int Px_Square = 20;
static const unsigned int Px_Square_Contour = 1;
static const unsigned int Px_Border = Px_Square / 2;
static const unsigned char Squares_Border_Color[3];
static const unsigned char Background_Color[3];
static const unsigned char Opacity;
public:
LegendTexture() : TextureBase() {}
// Generate a texture data, but don't load it into the GPU yet, as the glcontext may not be valid yet.
bool generate(const GCodePreviewData& preview_data, const std::vector<float>& tool_colors);
};
static LegendTexture s_legend_texture;
static WarningTexture s_warning_texture;
public:
static void _glew_init();
static void load_gcode_preview(const Print* print, const GCodePreviewData* preview_data, GLVolumeCollection* volumes, const std::vector<std::string>& str_tool_colors, bool use_VBOs);
static unsigned int get_legend_texture_id();
static unsigned int get_legend_texture_width();
static unsigned int get_legend_texture_height();
static void reset_legend_texture();
static unsigned int finalize_legend_texture();
static unsigned int get_warning_texture_width();
static unsigned int get_warning_texture_height();
// generates a warning texture containing the given message
static void generate_warning_texture(const std::string& msg);
static void reset_warning_texture();
static unsigned int finalize_warning_texture();
static void _load_print_toolpaths(
const Print *print,
GLVolumeCollection *volumes,

View File

@ -1029,7 +1029,8 @@ void TabPrinter::build()
return sizer;
};
optgroup->append_line(line);
optgroup->append_single_option_line("z_offset");
optgroup->append_single_option_line("max_print_height");
optgroup->append_single_option_line("z_offset");
optgroup = page->new_optgroup(_(L("Capabilities")));
ConfigOptionDef def;

View File

@ -99,8 +99,8 @@ foreach my $config (Slic3r::Config->new, Slic3r::Config::Static::new_FullPrintCo
$config->set_deserialize('fill_pattern', 'line');
is $config->get('fill_pattern'), 'line', 'deserialize enum (fill_pattern)';
$config->set_deserialize('support_material_pattern', 'pillars');
is $config->get('support_material_pattern'), 'pillars', 'deserialize enum (support_material_pattern)';
$config->set_deserialize('support_material_pattern', 'rectilinear');
is $config->get('support_material_pattern'), 'rectilinear', 'deserialize enum (support_material_pattern)';
$config->set('extruder_offset', [[10,20],[30,45]]);
is_deeply [ map $_->pp, @{$config->get('extruder_offset')} ], [[10,20],[30,45]], 'set/get points';

View File

@ -19,6 +19,9 @@
void enable() const;
void disable() const;
int shader_program_id() const
%code%{ RETVAL = THIS->shader_program_id; %};
std::string last_error() const
%code%{ RETVAL = THIS->last_error; %};
};
@ -45,6 +48,9 @@
int zoom_to_volumes()
%code%{ RETVAL = THIS->zoom_to_volumes; %};
void set_layer_height_texture_data(unsigned int texture_id, unsigned int shader_id, PrintObject* print_object, float z_cursor_relative, float edit_band_width);
void reset_layer_height_texture_data();
int object_idx() const;
int volume_idx() const;
int instance_idx() const;
@ -97,6 +103,9 @@
void finalize_geometry(bool use_VBOs);
void release_geometry();
void set_print_box(float min_x, float min_y, float min_z, float max_x, float max_y, float max_z);
void update_outside_state(DynamicPrintConfig* config, bool all_inside);
bool move_volume_up(int idx)
%code%{
if (idx > 0 && idx < int(THIS->volumes.size())) {
@ -154,13 +163,6 @@ finalize_legend_texture()
OUTPUT:
RETVAL
unsigned int
get_legend_texture_id()
CODE:
RETVAL = _3DScene::get_legend_texture_id();
OUTPUT:
RETVAL
unsigned int
get_legend_texture_width()
CODE:
@ -179,7 +181,38 @@ void
reset_legend_texture()
CODE:
_3DScene::reset_legend_texture();
void
generate_warning_texture(std::string msg)
CODE:
_3DScene::generate_warning_texture(msg);
unsigned int
finalize_warning_texture()
CODE:
RETVAL = _3DScene::finalize_warning_texture();
OUTPUT:
RETVAL
unsigned int
get_warning_texture_width()
CODE:
RETVAL = _3DScene::get_warning_texture_width();
OUTPUT:
RETVAL
unsigned int
get_warning_texture_height()
CODE:
RETVAL = _3DScene::get_warning_texture_height();
OUTPUT:
RETVAL
void
reset_warning_texture()
CODE:
_3DScene::reset_warning_texture();
void
_load_print_toolpaths(print, volumes, tool_colors, use_VBOs)
Print *print;

View File

@ -99,6 +99,9 @@
void print_info() const;
bool fits_print_volume(DynamicPrintConfig* config) const
%code%{ RETVAL = THIS->fits_print_volume(config); %};
bool store_stl(char *path, bool binary)
%code%{ TriangleMesh mesh = THIS->mesh(); RETVAL = Slic3r::store_stl(path, &mesh, binary); %};
bool store_amf(char *path, Print* print)
@ -361,9 +364,9 @@ ModelMaterial::attributes()
%code%{ RETVAL = &THIS->offset; %};
void set_rotation(double val)
%code%{ THIS->rotation = val; %};
%code%{ THIS->rotation = val; THIS->get_object()->invalidate_bounding_box(); %};
void set_scaling_factor(double val)
%code%{ THIS->scaling_factor = val; %};
%code%{ THIS->scaling_factor = val; THIS->get_object()->invalidate_bounding_box(); %};
void set_offset(Pointf *offset)
%code%{ THIS->offset = *offset; %};