ENH: add precise_z_height

jira: none
Change-Id: Idb9fcf0063e773f1531a49961478460b91ded10f
This commit is contained in:
zhimin.zeng 2024-03-28 20:56:20 +08:00 committed by Lane.Wei
parent 708342effd
commit 309010fff2
10 changed files with 119 additions and 8 deletions

View File

@ -832,7 +832,7 @@ static std::vector<std::string> s_Preset_print_options {
"tree_support_branch_angle", "tree_support_wall_count", "tree_support_branch_distance",
"tree_support_branch_diameter","tree_support_brim_width",
"detect_narrow_internal_solid_infill",
"gcode_add_line_number", "enable_arc_fitting", "infill_combination", /*"adaptive_layer_height",*/
"gcode_add_line_number", "enable_arc_fitting", "precise_z_height", "infill_combination", /*"adaptive_layer_height",*/
"support_bottom_interface_spacing", "enable_overhang_speed", "overhang_1_4_speed", "overhang_2_4_speed", "overhang_3_4_speed", "overhang_4_4_speed",
"initial_layer_infill_speed", "top_one_wall_type", "top_area_threshold", "only_one_wall_first_layer",
"timelapse_type", "internal_bridge_support_thickness",

View File

@ -209,6 +209,7 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n
opt_key == "initial_layer_print_height"
|| opt_key == "nozzle_diameter"
|| opt_key == "resolution"
|| opt_key == "precise_z_height"
// Spiral Vase forces different kind of slicing than the normal model:
// In Spiral Vase mode, holes are closed and only the largest area contour is kept at each layer.
// Therefore toggling the Spiral Vase on / off requires complete reslicing.
@ -1143,8 +1144,9 @@ StringObjectException Print::validate(StringObjectException *warning, Polygons*
if (has_custom_layering) {
std::vector<std::vector<coordf_t>> layer_z_series;
layer_z_series.assign(m_objects.size(), std::vector<coordf_t>());
for (size_t idx_object = 0; idx_object < m_objects.size(); ++idx_object) {
layer_z_series[idx_object] = generate_object_layers(m_objects[idx_object]->slicing_parameters(), layer_height_profiles[idx_object]);
layer_z_series[idx_object] = generate_object_layers(m_objects[idx_object]->slicing_parameters(), layer_height_profiles[idx_object], m_objects[idx_object]->config().precise_z_height.value);
}
for (size_t idx_object = 0; idx_object < m_objects.size(); ++idx_object) {

View File

@ -1846,6 +1846,15 @@ void PrintConfigDef::init_fff_params()
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloat(30));
// BBS
def = this->add("precise_z_height", coBool);
def->label = L("Precise Z height");
def->tooltip = L("Enable this to get precise z height of object after slicing. "
"It will get the precise object height by fine-tuning the layer heights of the last few layers. "
"Note that this is an experimental parameter.");
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionBool(0));
// BBS
def = this->add("enable_arc_fitting", coBool);
def->label = L("Arc fitting");

View File

@ -760,6 +760,7 @@ PRINT_CONFIG_CLASS_DEFINE(
// OrcaSlicer
((ConfigOptionPercent, seam_gap))
((ConfigOptionPercent, wipe_speed))
((ConfigOptionBool, precise_z_height)) // BBS
)
// This object is mapped to Perl as Slic3r::Config::PrintRegion.

View File

@ -790,7 +790,7 @@ void PrintObject::slice()
m_print->throw_if_canceled();
m_typed_slices = false;
this->clear_layers();
m_layers = new_layers(this, generate_object_layers(m_slicing_params, layer_height_profile));
m_layers = new_layers(this, generate_object_layers(m_slicing_params, layer_height_profile, m_config.precise_z_height.value));
this->slice_volumes();
m_print->throw_if_canceled();
int firstLayerReplacedBy = 0;

View File

@ -629,10 +629,104 @@ void adjust_layer_height_profile(
#endif /* _DEBUG */
}
bool adjust_layer_series_to_align_object_height(const SlicingParameters &slicing_params, std::vector<coordf_t>& layer_series)
{
coordf_t object_height = slicing_params.object_print_z_height();
if (is_approx(layer_series.back(), object_height))
return true;
// need at least 5 + 1(first_layer) layers to adjust the height
size_t layer_size = layer_series.size();
if (layer_size < 12)
return false;
std::vector<coordf_t> last_5_layers_heght;
for (size_t i = 0; i < 5; ++i) {
last_5_layers_heght.emplace_back(layer_series[layer_size - 10 + 2 * i + 1] - layer_series[layer_size - 10 + 2 * i]);
}
coordf_t gap = abs(layer_series.back() - object_height);
std::vector<bool> can_adjust(5, true); // to record whether every layer can adjust layer height
bool taller_than_object = layer_series.back() < object_height;
auto get_valid_size = [&can_adjust]() -> int {
int valid_size = 0;
for (auto b_adjust : can_adjust) {
valid_size += b_adjust ? 1 : 0;
}
return valid_size;
};
auto adjust_layer_height = [&slicing_params, &last_5_layers_heght, &can_adjust, &get_valid_size, &taller_than_object](coordf_t gap) -> coordf_t {
coordf_t delta_gap = gap / get_valid_size();
coordf_t remain_gap = 0;
for (size_t i = 0; i < last_5_layers_heght.size(); ++i) {
coordf_t& l_height = last_5_layers_heght[i];
if (taller_than_object) {
if (can_adjust[i] && is_approx(l_height, slicing_params.max_layer_height)) {
remain_gap += delta_gap;
can_adjust[i] = false;
continue;
}
if (can_adjust[i] && l_height + delta_gap > slicing_params.max_layer_height) {
remain_gap += l_height + delta_gap - slicing_params.max_layer_height;
l_height = slicing_params.max_layer_height;
can_adjust[i] = false;
}
else {
l_height += delta_gap;
}
}
else {
if (can_adjust[i] && is_approx(l_height, slicing_params.min_layer_height)) {
remain_gap += delta_gap;
can_adjust[i] = false;
continue;
}
if (can_adjust[i] && l_height - delta_gap < slicing_params.min_layer_height) {
remain_gap += slicing_params.min_layer_height + delta_gap - l_height;
l_height = slicing_params.min_layer_height;
can_adjust[i] = false;
}
else {
l_height -= delta_gap;
}
}
}
return remain_gap;
};
while (gap > 0) {
int valid_size = get_valid_size();
if (valid_size == 0) {
// 5 layers can not adjust z within valid layer height
return false;
}
gap = adjust_layer_height(gap);
if (is_approx(gap, 0.0)) {
// adjust succeed
break;
}
}
for (size_t i = 0; i < last_5_layers_heght.size(); ++i) {
if (i > 0) {
layer_series[layer_size - 10 + 2 * i] = layer_series[layer_size - 10 + 2 * i - 1];
}
layer_series[layer_size - 10 + 2 * i + 1] = layer_series[layer_size - 10 + 2 * i] + last_5_layers_heght[i];
}
return true;
}
// Produce object layers as pairs of low / high layer boundaries, stored into a linear vector.
std::vector<coordf_t> generate_object_layers(
const SlicingParameters &slicing_params,
const std::vector<coordf_t> &layer_height_profile)
const std::vector<coordf_t> &layer_height_profile,
bool is_precise_z_height)
{
assert(! layer_height_profile.empty());
@ -681,7 +775,8 @@ std::vector<coordf_t> generate_object_layers(
out.push_back(print_z);
}
//FIXME Adjust the last layer to align with the top object layer exactly?
if (is_precise_z_height)
adjust_layer_series_to_align_object_height(slicing_params, out);
return out;
}

View File

@ -173,7 +173,8 @@ extern void adjust_layer_height_profile(
// The object layers are based at z=0, ignoring the raft layers.
extern std::vector<coordf_t> generate_object_layers(
const SlicingParameters &slicing_params,
const std::vector<coordf_t> &layer_height_profile);
const std::vector<coordf_t> &layer_height_profile,
bool is_precise_z_height);
// Check whether the layer height profile describes a fixed layer height profile.
bool check_object_layers_fixed(

View File

@ -591,7 +591,7 @@ void GLCanvas3D::LayersEditing::generate_layer_height_texture()
bool level_of_detail_2nd_level = true;
m_layers_texture.cells = Slic3r::generate_layer_height_texture(
*m_slicing_parameters,
Slic3r::generate_object_layers(*m_slicing_parameters, m_layer_height_profile),
Slic3r::generate_object_layers(*m_slicing_parameters, m_layer_height_profile, false),
m_layers_texture.data.data(), m_layers_texture.height, m_layers_texture.width, level_of_detail_2nd_level);
m_layers_texture.valid = true;
}

View File

@ -77,7 +77,9 @@ std::map<std::string, std::vector<SimpleSettingData>> SettingsFactory::OBJECT_C
{"wall_sequence","",2},
{"seam_position", "",3}, {"seam_gap", "",4}, {"wipe_speed", "",5},
{"slice_closing_radius", "",6}, {"resolution", "",7},
{"xy_hole_compensation", "",8}, {"xy_contour_compensation", "",9}, {"elefant_foot_compensation", "",10}
{"xy_hole_compensation", "",8}, {"xy_contour_compensation", "",9}, {"elefant_foot_compensation", "",10},
{"precise_z_height", "",10}
}},
{ L("Support"), {{"brim_type", "",1},{"brim_width", "",2},{"brim_object_gap", "",3},
{"enable_support", "",4},{"support_type", "",5},{"support_threshold_angle", "",6},{"support_on_build_plate_only", "",7},

View File

@ -1967,6 +1967,7 @@ void TabPrint::build()
optgroup->append_single_option_line("xy_hole_compensation", "xy-hole-contour-compensation");
optgroup->append_single_option_line("xy_contour_compensation", "xy-hole-contour-compensation");
optgroup->append_single_option_line("elefant_foot_compensation", "parameter/elephant-foot");
optgroup->append_single_option_line("precise_z_height");
optgroup = page->new_optgroup(L("Ironing"), L"param_ironing");
optgroup->append_single_option_line("ironing_type", "parameter/ironing");