From 41c0fb19d77ee81356c3c8076d37a42e265e5073 Mon Sep 17 00:00:00 2001 From: supermerill Date: Sat, 30 Oct 2021 16:33:19 +0200 Subject: [PATCH] max_layer_height & min_layer_height now can be percent. Also some fixes on crash that may happens when using them. --- src/libslic3r/Config.hpp | 3 ++ src/libslic3r/GCode.cpp | 12 +++-- src/libslic3r/GCode/ToolOrdering.cpp | 2 +- src/libslic3r/Print.cpp | 6 +-- src/libslic3r/PrintConfig.cpp | 20 ++++---- src/libslic3r/PrintConfig.hpp | 4 +- src/libslic3r/Slicing.cpp | 49 ++++++++++++------- src/libslic3r/Slicing.hpp | 8 ++-- src/libslic3r/SupportMaterial.cpp | 6 ++- src/slic3r/GUI/CalibrationBridgeDialog.cpp | 2 +- src/slic3r/GUI/GLCanvas3D.cpp | 56 +++++++++++----------- src/slic3r/GUI/GUI_ObjectList.cpp | 4 +- src/slic3r/GUI/PresetHints.cpp | 2 +- src/slic3r/GUI/Tab.cpp | 39 ++++++++------- 14 files changed, 123 insertions(+), 90 deletions(-) diff --git a/src/libslic3r/Config.hpp b/src/libslic3r/Config.hpp index 92b312575..e4211c6e0 100644 --- a/src/libslic3r/Config.hpp +++ b/src/libslic3r/Config.hpp @@ -1108,9 +1108,12 @@ private: struct FloatOrPercent { +public: double value; bool percent; + double get_abs_value(double ratio) const { return percent ? value * ratio : value; } + private: friend class cereal::access; template void serialize(Archive & ar) {ar(this->value); ar(this->percent); } diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 485db613e..8fba3a41a 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -518,8 +518,10 @@ std::vector GCode::collect_layers_to_print(const PrintObjec gap_over_supports = std::max(0., gap_over_supports); // Not a soluble support, double support_layer_height_min = 1000000.; - for (auto lh : object.print()->config().min_layer_height.values) - support_layer_height_min = std::min(support_layer_height_min, std::max(0.01, lh)); + const ConfigOptionFloatsOrPercents& min_layer_height = object.print()->config().min_layer_height; + const ConfigOptionFloats& nozzle_diameter = object.print()->config().nozzle_diameter; + for(int extr_id = 0; extr_id < min_layer_height.values.size(); ++extr_id) + support_layer_height_min = std::min(support_layer_height_min, std::max(nozzle_diameter.values[extr_id]/40, min_layer_height.get_abs_value(extr_id, nozzle_diameter.values[extr_id]))); gap_over_supports += support_layer_height_min; } @@ -2915,9 +2917,9 @@ std::string GCode::extrude_loop_vase(const ExtrusionLoop &original_loop, const s } //all in unscaled coordinates (hence why it's coordf_t and not coord_t) - const coordf_t min_height = EXTRUDER_CONFIG_WITH_DEFAULT(min_layer_height, this->m_layer->height); + const coordf_t min_height = m_config.min_layer_height.get_abs_value(m_writer.tool()->id(), m_config.nozzle_diameter.get_at(m_writer.tool()->id())); const coordf_t bot_init_z = - this->m_layer->height; - //const coordf_t bot_last_z = bot_init_z + this->m_layer->height - EXTRUDER_CONFIG(min_layer_height); + //const coordf_t bot_last_z = bot_init_z + this->m_layer->height - m_config.min_layer_height.get_abs_value(m_writer.tool()->id(), m_config.nozzle_diameter.get_at(m_writer.tool()->id())); const coordf_t init_z = bot_init_z + min_height; //const coordf_t last_z = bot_init_z + this->m_layer->height; @@ -3157,7 +3159,7 @@ std::string GCode::extrude_loop(const ExtrusionLoop &original_loop, const std::s //but not for the first layer && this->m_layer->id() > 0 //exclude if min_layer_height * 2 > layer_height (increase from 2 to 3 because it's working but uses in-between) - && this->m_layer->height >= EXTRUDER_CONFIG_WITH_DEFAULT(min_layer_height, 0) * 2 - EPSILON + && this->m_layer->height >= m_config.min_layer_height.get_abs_value(m_writer.tool()->id(), m_config.nozzle_diameter.get_at(m_writer.tool()->id())) * 2 - EPSILON ) { return extrude_loop_vase(original_loop, description, speed, lower_layer_edge_grid); } diff --git a/src/libslic3r/GCode/ToolOrdering.cpp b/src/libslic3r/GCode/ToolOrdering.cpp index 21792aa78..d7f82fd78 100644 --- a/src/libslic3r/GCode/ToolOrdering.cpp +++ b/src/libslic3r/GCode/ToolOrdering.cpp @@ -349,7 +349,7 @@ void ToolOrdering::fill_wipe_tower_partitions(const PrintConfig &config, coordf_ // Test for a raft, insert additional wipe tower layer to fill in the raft separation gap. double max_layer_height = std::numeric_limits::max(); for (size_t i = 0; i < config.nozzle_diameter.values.size(); ++ i) { - double mlh = config.max_layer_height.values[i]; + double mlh = config.max_layer_height.get_abs_value(i, config.nozzle_diameter.values[i]); if (mlh == 0.) mlh = 0.75 * config.nozzle_diameter.values[i]; max_layer_height = std::min(max_layer_height, mlh); diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index a76893662..952ac607f 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -1595,9 +1595,9 @@ std::pair Print::validate() const PrintRegion::collect_object_printing_extruders(config(), object->config(), region->config(), object_extruders); double layer_height = object->config().layer_height.value; for (uint16_t extruder_id : object_extruders) { - double min_layer_height = config().min_layer_height.values[extruder_id]; - double max_layer_height = config().max_layer_height.values[extruder_id]; - double nozzle_diameter = config().nozzle_diameter.values[extruder_id]; + double nozzle_diameter = config().nozzle_diameter.get_at(extruder_id); + double min_layer_height = config().min_layer_height.get_abs_value(extruder_id, nozzle_diameter); + double max_layer_height = config().max_layer_height.get_abs_value(extruder_id, nozzle_diameter); if (max_layer_height < EPSILON) max_layer_height = nozzle_diameter * 0.75; if (min_layer_height > max_layer_height) return { PrintBase::PrintValidationError::pveWrongSettings, L("Min layer height can't be greater than Max layer height") }; if (max_layer_height > nozzle_diameter) return { PrintBase::PrintValidationError::pveWrongSettings, L("Max layer height can't be greater than nozzle diameter") }; diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 09dd27135..4a712c5cc 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -2732,19 +2732,21 @@ void PrintConfigDef::init_fff_params() def->is_vector_extruder = true; def->set_default_value(new ConfigOptionInts { 100 }); - def = this->add("max_layer_height", coFloats); + def = this->add("max_layer_height", coFloatsOrPercents); def->label = L("Max"); def->full_label = L("Max layer height"); def->category = OptionCategory::general; def->tooltip = L("This is the highest printable layer height for this extruder, used to cap " "the variable layer height and support layer height. Maximum recommended layer height " "is 75% of the extrusion width to achieve reasonable inter-layer adhesion. " - "If set to 0, layer height is limited to 75% of the nozzle diameter."); - def->sidetext = L("mm"); + "\nCan be a % of the nozzle diameter." + "\nIf set to 0, layer height is limited to 75% of the nozzle diameter."); + def->sidetext = L("mm or %"); + def->ratio_over = "nozzle_diameter"; def->min = 0; def->mode = comSimple; def->is_vector_extruder = true; - def->set_default_value(new ConfigOptionFloats { 0. }); + def->set_default_value(new ConfigOptionFloatsOrPercents{ FloatOrPercent{ 75, true} }); def = this->add("max_print_speed", coFloat); def->label = L("Max print speed"); @@ -2824,17 +2826,19 @@ void PrintConfigDef::init_fff_params() def->mode = comAdvanced; def->set_default_value(new ConfigOptionBool(false)); - def = this->add("min_layer_height", coFloats); + def = this->add("min_layer_height", coFloatsOrPercents); def->label = L("Min"); def->full_label = L("Min layer height"); def->category = OptionCategory::extruders; def->tooltip = L("This is the lowest printable layer height for this extruder and limits " - "the resolution for variable layer height. Typical values are between 0.05 mm and 0.1 mm."); - def->sidetext = L("mm"); + "the resolution for variable layer height. Typical values are between 0.05 mm and 0.1 mm." + "\nCan be a % of the nozzle diameter."); + def->sidetext = L("mm or %"); + def->ratio_over = "nozzle_diameter"; def->min = 0; def->mode = comSimple; def->is_vector_extruder = true; - def->set_default_value(new ConfigOptionFloats { 0.07 }); + def->set_default_value(new ConfigOptionFloatsOrPercents{ FloatOrPercent{ 5, true} }); def = this->add("min_length", coFloat); def->label = L("Minimum extrusion length"); diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index cf4472bad..f8b0984b1 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -1339,7 +1339,7 @@ public: ConfigOptionInts full_fan_speed_layer; ConfigOptionFloatOrPercent infill_acceleration; ConfigOptionInts max_fan_speed; - ConfigOptionFloats max_layer_height; + ConfigOptionFloatsOrPercents max_layer_height; ConfigOptionFloat max_print_height; ConfigOptionPercents max_speed_reduction; ConfigOptionFloats milling_diameter; @@ -1348,7 +1348,7 @@ public: //ConfigOptionPoints milling_offset; //ConfigOptionFloats milling_z_offset; ConfigOptionInts min_fan_speed; - ConfigOptionFloats min_layer_height; + ConfigOptionFloatsOrPercents min_layer_height; ConfigOptionFloats min_print_speed; ConfigOptionFloat min_skirt_length; ConfigOptionString notes; diff --git a/src/libslic3r/Slicing.cpp b/src/libslic3r/Slicing.cpp index 6423f750a..b11a68b86 100644 --- a/src/libslic3r/Slicing.cpp +++ b/src/libslic3r/Slicing.cpp @@ -39,36 +39,40 @@ inline bool test_z_step(const coordf_t val, const coordf_t z_step) { } // Minimum layer height for the variable layer height algorithm. -inline coordf_t min_layer_height_from_nozzle(const PrintConfig &print_config, int idx_nozzle) +// idx_nozzle began at 0 +inline coordf_t min_layer_height_from_nozzle(const PrintConfig &print_config, uint16_t idx_nozzle) { - coordf_t min_layer_height = print_config.min_layer_height.get_at(idx_nozzle - 1); + coordf_t min_layer_height = print_config.min_layer_height.get_abs_value(idx_nozzle, print_config.nozzle_diameter.get_at(idx_nozzle)); return check_z_step( (min_layer_height == 0.) ? (MIN_LAYER_HEIGHT_DEFAULT) : std::max(MIN_LAYER_HEIGHT, min_layer_height), print_config.z_step); } // Maximum layer height for the variable layer height algorithm, 3/4 of a nozzle dimaeter by default, // it should not be smaller than the minimum layer height. -inline coordf_t max_layer_height_from_nozzle(const PrintConfig &print_config, int idx_nozzle) +// idx_nozzle began at 0 +inline coordf_t max_layer_height_from_nozzle(const PrintConfig &print_config, uint16_t idx_nozzle) { coordf_t min_layer_height = min_layer_height_from_nozzle(print_config, idx_nozzle); - coordf_t max_layer_height = print_config.max_layer_height.get_at(idx_nozzle - 1); - coordf_t nozzle_dmr = print_config.nozzle_diameter.get_at(idx_nozzle - 1); + coordf_t nozzle_dmr = print_config.nozzle_diameter.get_at(idx_nozzle); + coordf_t max_layer_height = print_config.max_layer_height.get_abs_value(idx_nozzle, nozzle_dmr); return check_z_step(std::max(min_layer_height, (max_layer_height == 0.) ? (0.75 * nozzle_dmr) : max_layer_height), print_config.z_step); } // Minimum layer height for the variable layer height algorithm. -coordf_t Slicing::min_layer_height_from_nozzle(const DynamicPrintConfig &print_config, int idx_nozzle) +// idx_nozzle began at 0 +coordf_t Slicing::min_layer_height_from_nozzle(const DynamicPrintConfig &print_config, uint16_t idx_nozzle) { - coordf_t min_layer_height = print_config.opt_float("min_layer_height", idx_nozzle - 1); + coordf_t min_layer_height = print_config.get_computed_value("min_layer_height", idx_nozzle); return check_z_step((min_layer_height == 0.) ? (MIN_LAYER_HEIGHT_DEFAULT) : std::max(MIN_LAYER_HEIGHT, min_layer_height), print_config.opt_float("z_step")); } // Maximum layer height for the variable layer height algorithm, 3/4 of a nozzle dimaeter by default, // it should not be smaller than the minimum layer height. -coordf_t Slicing::max_layer_height_from_nozzle(const DynamicPrintConfig &print_config, int idx_nozzle) +// idx_nozzle began at 0 +coordf_t Slicing::max_layer_height_from_nozzle(const DynamicPrintConfig &print_config, uint16_t idx_nozzle) { coordf_t min_layer_height = min_layer_height_from_nozzle(print_config, idx_nozzle); - coordf_t max_layer_height = print_config.opt_float("max_layer_height", idx_nozzle - 1); - coordf_t nozzle_dmr = print_config.opt_float("nozzle_diameter", idx_nozzle - 1); + coordf_t max_layer_height = print_config.get_computed_value("max_layer_height", idx_nozzle); + coordf_t nozzle_dmr = print_config.opt_float("nozzle_diameter", idx_nozzle); return check_z_step(std::max(min_layer_height, (max_layer_height == 0.) ? (0.75 * nozzle_dmr) : max_layer_height), print_config.opt_float("z_step")); } @@ -124,18 +128,26 @@ SlicingParameters SlicingParameters::create_from_config( if (params.object_print_z_max < object_height) params.object_print_z_max += params.z_step; // Miniumum/maximum of the minimum layer height over all extruders. - params.min_layer_height = MIN_LAYER_HEIGHT; + params.min_layer_height = 0; params.max_layer_height = std::numeric_limits::max(); + params.max_suport_layer_height = 0; params.exact_last_layer_height = object_config.exact_last_layer_height.value; if (object_config.support_material.value || params.base_raft_layers > 0) { // Has some form of support. Add the support layers to the minimum / maximum layer height limits. - params.min_layer_height = std::max( - min_layer_height_from_nozzle(print_config, object_config.support_material_extruder), - min_layer_height_from_nozzle(print_config, object_config.support_material_interface_extruder)); - params.max_layer_height = std::min( - max_layer_height_from_nozzle(print_config, object_config.support_material_extruder), - max_layer_height_from_nozzle(print_config, object_config.support_material_interface_extruder)); - params.max_suport_layer_height = params.max_layer_height; + if (object_config.support_material_extruder > 0) + params.min_layer_height = std::max(params.min_layer_height, + min_layer_height_from_nozzle(print_config, object_config.support_material_extruder - 1)); + if (object_config.support_material_interface_extruder > 0) + params.min_layer_height = std::max(params.min_layer_height, + min_layer_height_from_nozzle(print_config, object_config.support_material_interface_extruder - 1)); + if (object_config.support_material_extruder > 0) + params.max_layer_height = std::min(params.max_layer_height, + max_layer_height_from_nozzle(print_config, object_config.support_material_extruder - 1)); + if (object_config.support_material_interface_extruder > 0) + params.max_layer_height = std::min(params.max_layer_height, + max_layer_height_from_nozzle(print_config, object_config.support_material_interface_extruder - 1)); + if (params.max_layer_height < std::numeric_limits::max()) + params.max_suport_layer_height = params.max_layer_height; } if (object_extruders.empty()) { params.min_layer_height = std::max(params.min_layer_height, min_layer_height_from_nozzle(print_config, 0)); @@ -151,6 +163,7 @@ SlicingParameters SlicingParameters::create_from_config( //apply z_step to min/max params.min_layer_height = check_z_step(params.min_layer_height, params.z_step); params.max_layer_height = check_z_step(params.max_layer_height, params.z_step); + if (params.max_suport_layer_height == 0) params.max_suport_layer_height = params.max_layer_height; params.max_suport_layer_height = check_z_step(params.max_suport_layer_height, params.z_step); if (! soluble_interface) { diff --git a/src/libslic3r/Slicing.hpp b/src/libslic3r/Slicing.hpp index 4d18e342f..13a1145f0 100644 --- a/src/libslic3r/Slicing.hpp +++ b/src/libslic3r/Slicing.hpp @@ -188,13 +188,13 @@ extern int generate_layer_height_texture( void *data, int rows, int cols, bool level_of_detail_2nd_level); namespace Slicing { - // Minimum layer height for the variable layer height algorithm. Nozzle index is 1 based. - coordf_t min_layer_height_from_nozzle(const DynamicPrintConfig &print_config, int idx_nozzle); + // Minimum layer height for the variable layer height algorithm. Nozzle index is 0 based. + coordf_t min_layer_height_from_nozzle(const DynamicPrintConfig &print_config, uint16_t idx_nozzle); // Maximum layer height for the variable layer height algorithm, 3/4 of a nozzle dimaeter by default, // it should not be smaller than the minimum layer height. - // Nozzle index is 1 based. - coordf_t max_layer_height_from_nozzle(const DynamicPrintConfig &print_config, int idx_nozzle); + // Nozzle index is 0 based. + coordf_t max_layer_height_from_nozzle(const DynamicPrintConfig &print_config, uint16_t idx_nozzle); } // namespace Slicing } // namespace Slic3r diff --git a/src/libslic3r/SupportMaterial.cpp b/src/libslic3r/SupportMaterial.cpp index c8e8d2f2a..3b5829f42 100644 --- a/src/libslic3r/SupportMaterial.cpp +++ b/src/libslic3r/SupportMaterial.cpp @@ -152,8 +152,10 @@ PrintObjectSupportMaterial::PrintObjectSupportMaterial(const PrintObject *object { // Calculate a minimum support layer height as a minimum over all extruders, but not smaller than 10um. m_support_layer_height_min = 1000000.; - for (auto lh : m_print_config->min_layer_height.values) - m_support_layer_height_min = std::min(m_support_layer_height_min, std::max(0.01, lh)); + const ConfigOptionFloatsOrPercents& min_layer_height = m_print_config->min_layer_height; + const ConfigOptionFloats& nozzle_diameter = m_print_config->nozzle_diameter; + for (int extr_id = 0; extr_id < min_layer_height.values.size(); ++extr_id) + m_support_layer_height_min = std::min(m_support_layer_height_min, std::max(0.01, min_layer_height.get_abs_value(extr_id, nozzle_diameter.get_at(extr_id)))); if (m_object_config->support_material_interface_layers.value == 0) { // No interface layers allowed, print everything with the base support pattern. diff --git a/src/slic3r/GUI/CalibrationBridgeDialog.cpp b/src/slic3r/GUI/CalibrationBridgeDialog.cpp index 9f98f855a..ba49b5099 100644 --- a/src/slic3r/GUI/CalibrationBridgeDialog.cpp +++ b/src/slic3r/GUI/CalibrationBridgeDialog.cpp @@ -150,7 +150,7 @@ void CalibrationBridgeDialog::create_geometry(std::string setting_to_test, bool double z_step = printer_config->option("z_step")->value; if (z_step == 0) z_step = 0.1; - double max_height = printer_config->option("max_layer_height")->values[0]; + double max_height = printer_config->get_computed_value("max_layer_height",0); if (max_height > first_layer_height + z_step) for (size_t i = 0; i < nb_items; i++) model.objects[objs_idx[i]]->config.set_key_value("first_layer_height", new ConfigOptionFloatOrPercent(first_layer_height + z_step, false)); diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 34c2f9823..f79a3d2b4 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -461,36 +461,36 @@ void GLCanvas3D::LayersEditing::render_volumes(const GLCanvas3D& canvas, const G // The layer editing shader was already active. current_shader = nullptr; - const_cast(this)->generate_layer_height_texture(); + const_cast(this)->generate_layer_height_texture(); - // Uniforms were resolved, go ahead using the layer editing shader. + // Uniforms were resolved, go ahead using the layer editing shader. shader->set_uniform("z_to_texture_row", float(m_layers_texture.cells - 1) / (float(m_layers_texture.width) * float(m_object_max_z))); shader->set_uniform("z_texture_row_to_normalized", 1.0f / float(m_layers_texture.height)); shader->set_uniform("z_cursor", float(m_object_max_z) * float(this->get_cursor_z_relative(canvas))); shader->set_uniform("z_cursor_band_width", float(this->band_width)); - // Initialize the layer height texture mapping. - GLsizei w = (GLsizei)m_layers_texture.width; - GLsizei h = (GLsizei)m_layers_texture.height; - GLsizei half_w = w / 2; - GLsizei half_h = h / 2; - glsafe(::glPixelStorei(GL_UNPACK_ALIGNMENT, 1)); - glsafe(::glBindTexture(GL_TEXTURE_2D, m_z_texture_id)); - glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0)); - glsafe(::glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, half_w, half_h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0)); - glsafe(::glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, m_layers_texture.data.data())); - glsafe(::glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, half_w, half_h, GL_RGBA, GL_UNSIGNED_BYTE, m_layers_texture.data.data() + m_layers_texture.width * m_layers_texture.height * 4)); - for (const GLVolume* glvolume : volumes.volumes) { - // Render the object using the layer editing shader and texture. - if (! glvolume->is_active || glvolume->composite_id.object_id != this->last_object_id || glvolume->is_modifier) - continue; + // Initialize the layer height texture mapping. + GLsizei w = (GLsizei)m_layers_texture.width; + GLsizei h = (GLsizei)m_layers_texture.height; + GLsizei half_w = w / 2; + GLsizei half_h = h / 2; + glsafe(::glPixelStorei(GL_UNPACK_ALIGNMENT, 1)); + glsafe(::glBindTexture(GL_TEXTURE_2D, m_z_texture_id)); + glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0)); + glsafe(::glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, half_w, half_h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0)); + glsafe(::glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, m_layers_texture.data.data())); + glsafe(::glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, half_w, half_h, GL_RGBA, GL_UNSIGNED_BYTE, m_layers_texture.data.data() + m_layers_texture.width * m_layers_texture.height * 4)); + for (const GLVolume* glvolume : volumes.volumes) { + // Render the object using the layer editing shader and texture. + if (! glvolume->is_active || glvolume->composite_id.object_id != this->last_object_id || glvolume->is_modifier) + continue; - shader->set_uniform("volume_world_matrix", glvolume->world_matrix()); - shader->set_uniform("object_max_z", GLfloat(0)); - glvolume->render(); - } - // Revert back to the previous shader. - glBindTexture(GL_TEXTURE_2D, 0); + shader->set_uniform("volume_world_matrix", glvolume->world_matrix()); + shader->set_uniform("object_max_z", GLfloat(0)); + glvolume->render(); + } + // Revert back to the previous shader. + glBindTexture(GL_TEXTURE_2D, 0); if (current_shader != nullptr) current_shader->start_using(); } @@ -1527,10 +1527,12 @@ bool GLCanvas3D::is_layers_editing_allowed() const void GLCanvas3D::reset_layer_height_profile() { - wxGetApp().plater()->take_snapshot(_L("Variable layer height - Reset")); - m_layers_editing.reset_layer_height_profile(*this); - m_layers_editing.state = LayersEditing::Completed; - m_dirty = true; + if (is_layers_editing_enabled()) { + wxGetApp().plater()->take_snapshot(_L("Variable layer height - Reset")); + m_layers_editing.reset_layer_height_profile(*this); + m_layers_editing.state = LayersEditing::Completed; + m_dirty = true; + } } void GLCanvas3D::adaptive_layer_height_profile(float quality_factor) diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index a06231ef5..bcc1eef24 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -3401,14 +3401,14 @@ void ObjectList::del_layer_range(const t_layer_height_range& range) static double get_min_layer_height(const int extruder_idx) { const DynamicPrintConfig& config = wxGetApp().preset_bundle->printers.get_edited_preset().config; - return config.opt_float("min_layer_height", std::max(0, extruder_idx - 1)); + return config.get_computed_value("min_layer_height", std::max(0, extruder_idx - 1)); } static double get_max_layer_height(const int extruder_idx) { const DynamicPrintConfig& config = wxGetApp().preset_bundle->printers.get_edited_preset().config; int extruder_idx_zero_based = std::max(0, extruder_idx - 1); - double max_layer_height = config.opt_float("max_layer_height", extruder_idx_zero_based); + double max_layer_height = config.get_computed_value("max_layer_height", extruder_idx_zero_based); // In case max_layer_height is set to zero, it should default to 75 % of nozzle diameter: if (max_layer_height < EPSILON) diff --git a/src/slic3r/GUI/PresetHints.cpp b/src/slic3r/GUI/PresetHints.cpp index bd48e04ff..92538aaaf 100644 --- a/src/slic3r/GUI/PresetHints.cpp +++ b/src/slic3r/GUI/PresetHints.cpp @@ -496,7 +496,7 @@ std::string PresetHints::top_bottom_shell_thickness_explanation(const PresetBund double layer_height = print_config.opt_float("layer_height"); bool variable_layer_height = printer_config.opt_bool("variable_layer_height"); //FIXME the following line takes into account the 1st extruder only. - double min_layer_height = variable_layer_height ? Slicing::min_layer_height_from_nozzle(printer_config, 1) : layer_height; + double min_layer_height = variable_layer_height ? Slicing::min_layer_height_from_nozzle(printer_config, 0) : layer_height; if (layer_height <= 0.f) { out += _utf8(L("Top / bottom shell thickness hint: Not available due to invalid layer height.")); diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 02868bc48..b915b279d 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -1191,6 +1191,11 @@ void Tab::on_value_change(const std::string& opt_key, const boost::any& value) wxGetApp().mainframe->plater()->canvas3D()->set_arrange_settings(m_presets->get_edited_preset().config, m_presets->get_edited_preset().printer_technology()); } + // reset variable layer height if min/max has changed, as it's probably now invalid. + if (opt_key.find("min_layer_height") == 0 || opt_key.find("max_layer_height") == 0) { + wxPostEvent((wxEvtHandler*)wxGetApp().mainframe->plater()->canvas3D()->get_wxglcanvas(), SimpleEvent(EVT_GLCANVAS_RESET_LAYER_HEIGHT_PROFILE)); + } + //wxGetApp().preset_bundle->value_changed(opt_key); // update phony fields @@ -3036,24 +3041,26 @@ void TabPrinter::toggle_options() int64_t z_step_Mlong = (int64_t)(z_step * 1000000.); DynamicPrintConfig new_conf; bool has_changed = false; - const std::vector& min_layer_height = m_config->option("min_layer_height")->values; - for (int i = 0; i < min_layer_height.size(); i++) { - if (min_layer_height[i] != 0 && (int64_t)(min_layer_height[i] * 1000000.) % z_step_Mlong != 0) { - if (!has_changed) - new_conf = *m_config; - new_conf.option("min_layer_height")->values[i] = std::max(z_step, Slic3r::check_z_step(new_conf.option("min_layer_height")->values[i], z_step)); - has_changed = true; - } - } const std::vector& nozzle_diameters = m_config->option("nozzle_diameter")->values; - std::vector max_layer_height = m_config->option("max_layer_height")->values; + const std::vector& min_layer_height = m_config->option("min_layer_height")->values; + for (int i = 0; i < min_layer_height.size(); i++) { + if(!min_layer_height[i].percent) + if (min_layer_height[i].get_abs_value(nozzle_diameters[i]) != 0 && (int64_t)(min_layer_height[i].get_abs_value(nozzle_diameters[i]) * 1000000.) % z_step_Mlong != 0) { + if (!has_changed) + new_conf = *m_config; + new_conf.option("min_layer_height")->values[i] = FloatOrPercent{ std::max(z_step, Slic3r::check_z_step(min_layer_height[i].get_abs_value(nozzle_diameters[i]), z_step)), false }; + has_changed = true; + } + } + std::vector max_layer_height = m_config->option("max_layer_height")->values; for (int i = 0; i < max_layer_height.size(); i++) { - if ((int64_t)(max_layer_height[i] * 1000000.) % z_step_Mlong != 0) { - if (!has_changed) - new_conf = *m_config; - new_conf.option("max_layer_height")->values[i] = std::max(z_step, Slic3r::check_z_step(new_conf.option("max_layer_height")->values[i], z_step)); - has_changed = true; - } + if (!max_layer_height[i].percent) + if ((int64_t)(max_layer_height[i].get_abs_value(nozzle_diameters[i]) * 1000000.) % z_step_Mlong != 0) { + if (!has_changed) + new_conf = *m_config; + new_conf.option("max_layer_height")->values[i] = FloatOrPercent{ std::max(z_step, Slic3r::check_z_step(new_conf.option("max_layer_height")->values[i], z_step)), false }; + has_changed = true; + } } if (has_changed) { load_config(new_conf);