mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-10-26 18:21:18 -06:00
Implemented top_solid_min_thickness / bottom_solid_min_thickness.
The two new config keys define a minimum vertical shell thickness. The top shell thickness is calculated as a maximum of sum over top_solid_layers * layer heights and top_solid_min_thickness, the bottom shell thickness is calculated as a maximum of sum over bottom_solid_layers * layer heights and bottom_solid_min_thickness. The results of the formula above are shown at the Print parameter page below the two new values to hint the user about the interaction of the old versus new config values. top_solid_min_thickness has no meaning if top_solid_layers is zero, bottom_solid_min_thickness has no meaning if bottom_solid_layers is zero.
This commit is contained in:
parent
6f777264a1
commit
495a71ed00
14 changed files with 246 additions and 52 deletions
|
|
@ -233,22 +233,27 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig* config)
|
|||
"solid_infill_every_layers", "solid_infill_below_area", "infill_extruder" })
|
||||
toggle_field(el, have_infill);
|
||||
|
||||
bool have_solid_infill = config->opt_int("top_solid_layers") > 0 || config->opt_int("bottom_solid_layers") > 0;
|
||||
bool has_spiral_vase = config->opt_bool("spiral_vase");
|
||||
bool has_top_solid_infill = config->opt_int("top_solid_layers") > 0;
|
||||
bool has_bottom_solid_infill = config->opt_int("bottom_solid_layers") > 0;
|
||||
bool has_solid_infill = has_top_solid_infill || has_bottom_solid_infill;
|
||||
// solid_infill_extruder uses the same logic as in Print::extruders()
|
||||
for (auto el : { "top_fill_pattern", "bottom_fill_pattern", "infill_first", "solid_infill_extruder",
|
||||
"solid_infill_extrusion_width", "solid_infill_speed" })
|
||||
toggle_field(el, have_solid_infill);
|
||||
toggle_field(el, has_solid_infill);
|
||||
|
||||
for (auto el : { "fill_angle", "bridge_angle", "infill_extrusion_width",
|
||||
"infill_speed", "bridge_speed" })
|
||||
toggle_field(el, have_infill || have_solid_infill);
|
||||
toggle_field(el, have_infill || has_solid_infill);
|
||||
|
||||
toggle_field("top_solid_min_thickness", ! has_spiral_vase && has_top_solid_infill);
|
||||
toggle_field("bottom_solid_min_thickness", ! has_spiral_vase && has_bottom_solid_infill);
|
||||
|
||||
// Gap fill is newly allowed in between perimeter lines even for empty infill (see GH #1476).
|
||||
toggle_field("gap_fill_speed", have_perimeters);
|
||||
|
||||
bool have_top_solid_infill = config->opt_int("top_solid_layers") > 0;
|
||||
for (auto el : { "top_infill_extrusion_width", "top_solid_infill_speed" })
|
||||
toggle_field(el, have_top_solid_infill);
|
||||
toggle_field(el, has_top_solid_infill);
|
||||
|
||||
bool have_default_acceleration = config->opt_float("default_acceleration") > 0;
|
||||
for (auto el : { "perimeter_acceleration", "infill_acceleration",
|
||||
|
|
|
|||
|
|
@ -1980,7 +1980,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
|
|||
"extruder_colour", "filament_colour", "max_print_height", "printer_model", "printer_technology",
|
||||
// These values are necessary to construct SlicingParameters by the Canvas3D variable layer height editor.
|
||||
"layer_height", "first_layer_height", "min_layer_height", "max_layer_height",
|
||||
"brim_width", "perimeters", "perimeter_extruder", "fill_density", "infill_extruder", "top_solid_layers", "bottom_solid_layers", "solid_infill_extruder",
|
||||
"brim_width", "perimeters", "perimeter_extruder", "fill_density", "infill_extruder", "top_solid_layers",
|
||||
"support_material", "support_material_extruder", "support_material_interface_extruder", "support_material_contact_distance", "raft_layers"
|
||||
}))
|
||||
, sidebar(new Sidebar(q))
|
||||
|
|
|
|||
|
|
@ -386,7 +386,8 @@ void Preset::set_visible_from_appconfig(const AppConfig &app_config)
|
|||
const std::vector<std::string>& Preset::print_options()
|
||||
{
|
||||
static std::vector<std::string> s_opts {
|
||||
"layer_height", "first_layer_height", "perimeters", "spiral_vase", "slice_closing_radius", "top_solid_layers", "bottom_solid_layers",
|
||||
"layer_height", "first_layer_height", "perimeters", "spiral_vase", "slice_closing_radius",
|
||||
"top_solid_layers", "top_solid_min_thickness", "bottom_solid_layers", "bottom_solid_min_thickness",
|
||||
"extra_perimeters", "ensure_vertical_shell_thickness", "avoid_crossing_perimeters", "thin_walls", "overhangs",
|
||||
"seam_position", "external_perimeters_first", "fill_density", "fill_pattern", "top_fill_pattern", "bottom_fill_pattern",
|
||||
"infill_every_layers", "infill_only_where_needed", "solid_infill_every_layers", "fill_angle", "bridge_angle",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#include <cassert>
|
||||
|
||||
#include "libslic3r/Flow.hpp"
|
||||
#include "libslic3r/Slicing.hpp"
|
||||
#include "libslic3r/libslic3r.h"
|
||||
|
||||
#include "PresetBundle.hpp"
|
||||
|
|
@ -242,7 +243,7 @@ std::string PresetHints::recommended_thin_wall_thickness(const PresetBundle &pre
|
|||
float nozzle_diameter = float(printer_config.opt_float("nozzle_diameter", 0));
|
||||
|
||||
std::string out;
|
||||
if (layer_height <= 0.f){
|
||||
if (layer_height <= 0.f) {
|
||||
out += _utf8(L("Recommended object thin wall thickness: Not available due to invalid layer height."));
|
||||
return out;
|
||||
}
|
||||
|
|
@ -272,4 +273,70 @@ std::string PresetHints::recommended_thin_wall_thickness(const PresetBundle &pre
|
|||
return out;
|
||||
}
|
||||
|
||||
|
||||
// Produce a textual explanation of the combined effects of the top/bottom_solid_layers
|
||||
// versus top/bottom_min_shell_thickness. Which of the two values wins depends
|
||||
// on the active layer height.
|
||||
std::string PresetHints::top_bottom_shell_thickness_explanation(const PresetBundle &preset_bundle)
|
||||
{
|
||||
const DynamicPrintConfig &print_config = preset_bundle.prints .get_edited_preset().config;
|
||||
const DynamicPrintConfig &printer_config = preset_bundle.printers .get_edited_preset().config;
|
||||
|
||||
std::string out;
|
||||
|
||||
int top_solid_layers = print_config.opt_int("top_solid_layers");
|
||||
int bottom_solid_layers = print_config.opt_int("bottom_solid_layers");
|
||||
bool has_top_layers = top_solid_layers > 0;
|
||||
bool has_bottom_layers = bottom_solid_layers > 0;
|
||||
bool has_shell = has_top_layers && has_bottom_layers;
|
||||
double top_solid_min_thickness = print_config.opt_float("top_solid_min_thickness");
|
||||
double bottom_solid_min_thickness = print_config.opt_float("bottom_solid_min_thickness");
|
||||
double layer_height = print_config.opt_float("layer_height");
|
||||
bool variable_layer_height = printer_config.opt_bool("variable_layer_height");
|
||||
//FIXME the following lines take into account the 1st extruder only.
|
||||
double min_layer_height = (has_shell && variable_layer_height) ? Slicing::min_layer_height_from_nozzle(printer_config, 1) : layer_height;
|
||||
double max_layer_height = (has_shell && variable_layer_height) ? Slicing::max_layer_height_from_nozzle(printer_config, 1) : layer_height;
|
||||
|
||||
if (layer_height <= 0.f) {
|
||||
out += _utf8(L("Top / bottom shell thickness hint: Not available due to invalid layer height."));
|
||||
return out;
|
||||
}
|
||||
|
||||
if (has_top_layers) {
|
||||
double top_shell_thickness = top_solid_layers * layer_height;
|
||||
if (top_shell_thickness < top_solid_min_thickness) {
|
||||
// top_solid_min_shell_thickness triggers even in case of normal layer height. Round the top_shell_thickness up
|
||||
// to an integer multiply of layer_height.
|
||||
double n = ceil(top_solid_min_thickness / layer_height);
|
||||
top_shell_thickness = n * layer_height;
|
||||
}
|
||||
double top_shell_thickness_minimum = std::max(top_solid_min_thickness, top_solid_layers * min_layer_height);
|
||||
out += (boost::format(_utf8(L("Top shell is %1% mm thick for layer height %2% mm."))) % top_shell_thickness % layer_height).str();
|
||||
if (variable_layer_height && top_shell_thickness_minimum < top_shell_thickness) {
|
||||
out += " ";
|
||||
out += (boost::format(_utf8(L("Minimum top shell thickness is %1% mm."))) % top_shell_thickness_minimum).str();
|
||||
}
|
||||
}
|
||||
|
||||
if (has_bottom_layers) {
|
||||
double bottom_shell_thickness = bottom_solid_layers * layer_height;
|
||||
if (bottom_shell_thickness < bottom_solid_min_thickness) {
|
||||
// bottom_solid_min_shell_thickness triggers even in case of normal layer height. Round the bottom_shell_thickness up
|
||||
// to an integer multiply of layer_height.
|
||||
double n = ceil(bottom_solid_min_thickness / layer_height);
|
||||
bottom_shell_thickness = n * layer_height;
|
||||
}
|
||||
double bottom_shell_thickness_minimum = std::max(bottom_solid_min_thickness, bottom_solid_layers * min_layer_height);
|
||||
if (! out.empty())
|
||||
out += "\n";
|
||||
out += (boost::format(_utf8(L("Bottom shell is %1% mm thick for layer height %2% mm."))) % bottom_shell_thickness % layer_height).str();
|
||||
if (variable_layer_height && bottom_shell_thickness_minimum < bottom_shell_thickness) {
|
||||
out += " ";
|
||||
out += (boost::format(_utf8(L("Minimum bottom shell thickness is %1% mm."))) % bottom_shell_thickness_minimum).str();
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
}; // namespace Slic3r
|
||||
|
|
|
|||
|
|
@ -23,6 +23,11 @@ public:
|
|||
// Produce a textual description of a recommended thin wall thickness
|
||||
// from the provided number of perimeters and the external / internal perimeter width.
|
||||
static std::string recommended_thin_wall_thickness(const PresetBundle &preset_bundle);
|
||||
|
||||
// Produce a textual explanation of the combined effects of the top/bottom_solid_layers
|
||||
// versus top/bottom_min_shell_thickness. Which of the two values wins depends
|
||||
// on the active layer height.
|
||||
static std::string top_bottom_shell_thickness_explanation(const PresetBundle &preset_bundle);
|
||||
};
|
||||
|
||||
} // namespace Slic3r
|
||||
|
|
|
|||
|
|
@ -1056,6 +1056,16 @@ void TabPrint::build()
|
|||
line.append_option(optgroup->get_option("top_solid_layers"));
|
||||
line.append_option(optgroup->get_option("bottom_solid_layers"));
|
||||
optgroup->append_line(line);
|
||||
line = { _(L("Minimum shell thickness")), "" };
|
||||
line.append_option(optgroup->get_option("top_solid_min_thickness"));
|
||||
line.append_option(optgroup->get_option("bottom_solid_min_thickness"));
|
||||
optgroup->append_line(line);
|
||||
line = { "", "" };
|
||||
line.full_width = 1;
|
||||
line.widget = [this](wxWindow* parent) {
|
||||
return description_line_widget(parent, &m_top_bottom_shell_thickness_explanation);
|
||||
};
|
||||
optgroup->append_line(line);
|
||||
|
||||
optgroup = page->new_optgroup(_(L("Quality (slower slicing)")));
|
||||
optgroup->append_single_option_line("extra_perimeters");
|
||||
|
|
@ -1277,6 +1287,8 @@ void TabPrint::update()
|
|||
|
||||
m_recommended_thin_wall_thickness_description_line->SetText(
|
||||
from_u8(PresetHints::recommended_thin_wall_thickness(*m_preset_bundle)));
|
||||
m_top_bottom_shell_thickness_explanation->SetText(
|
||||
from_u8(PresetHints::top_bottom_shell_thickness_explanation(*m_preset_bundle)));
|
||||
Layout();
|
||||
|
||||
// Thaw();
|
||||
|
|
@ -1295,6 +1307,8 @@ void TabPrint::OnActivate()
|
|||
{
|
||||
m_recommended_thin_wall_thickness_description_line->SetText(
|
||||
from_u8(PresetHints::recommended_thin_wall_thickness(*m_preset_bundle)));
|
||||
m_top_bottom_shell_thickness_explanation->SetText(
|
||||
from_u8(PresetHints::top_bottom_shell_thickness_explanation(*m_preset_bundle)));
|
||||
Tab::OnActivate();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -327,8 +327,9 @@ public:
|
|||
Tab(parent, _(L("Print Settings")), Slic3r::Preset::TYPE_PRINT) {}
|
||||
~TabPrint() {}
|
||||
|
||||
ogStaticText* m_recommended_thin_wall_thickness_description_line;
|
||||
bool m_support_material_overhangs_queried = false;
|
||||
ogStaticText* m_recommended_thin_wall_thickness_description_line = nullptr;
|
||||
ogStaticText* m_top_bottom_shell_thickness_explanation = nullptr;
|
||||
bool m_support_material_overhangs_queried = false;
|
||||
|
||||
void build() override;
|
||||
void reload_config() override;
|
||||
|
|
@ -336,6 +337,7 @@ public:
|
|||
void OnActivate() override;
|
||||
bool supports_printer_technology(const PrinterTechnology tech) override { return tech == ptFFF; }
|
||||
};
|
||||
|
||||
class TabFilament : public Tab
|
||||
{
|
||||
ogStaticText* m_volumetric_speed_description_line;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue