ENH: add precise_outer_wall parameter

This modification is cherry-picked from OrcaSlicer, Thanks to OrcaSlicer.
jira: STUDIO-11619

Change-Id: I54bedc5552230a42b0593eba8ab41e94626023e9
This commit is contained in:
zhimin.zeng 2025-04-24 10:24:22 +08:00 committed by lane.wei
parent 4f14441703
commit 0dba698809
6 changed files with 29 additions and 9 deletions

View File

@ -1205,7 +1205,12 @@ void PerimeterGenerator::process_classic()
m_ext_mm3_per_mm = this->ext_perimeter_flow.mm3_per_mm();
coord_t ext_perimeter_width = this->ext_perimeter_flow.scaled_width();
coord_t ext_perimeter_spacing = this->ext_perimeter_flow.scaled_spacing();
coord_t ext_perimeter_spacing2 = scaled<coord_t>(0.5f * (this->ext_perimeter_flow.spacing() + this->perimeter_flow.spacing()));
coord_t ext_perimeter_spacing2;
// Orca: ignore precise_outer_wall if wall_sequence is not InnerOuter
if (config->precise_outer_wall)
ext_perimeter_spacing2 = scaled<coord_t>(0.5f * (this->ext_perimeter_flow.width() + this->perimeter_flow.width()));
else
ext_perimeter_spacing2 = scaled<coord_t>(0.5f * (this->ext_perimeter_flow.spacing() + this->perimeter_flow.spacing()));
// overhang perimeters
m_mm3_per_mm_overhang = this->overhang_flow.mm3_per_mm();
@ -1843,12 +1848,15 @@ void PerimeterGenerator::process_arachne()
// we need to process each island separately because we might have different
// extra perimeters for each one
bool apply_precise_outer_wall = config->precise_outer_wall;
for (const Surface& surface : this->slices->surfaces) {
// detect how many perimeters must be generated for this island
int loop_number = this->config->wall_loops + surface.extra_perimeters - 1; // 0-indexed loops
bool apply_circle_compensation = true;
ExPolygons last = offset_ex(surface.expolygon.simplify_p(surface_simplify_resolution), -float(ext_perimeter_width / 2. - ext_perimeter_spacing / 2.));
// Orca: properly adjust offset for the outer wall if precise_outer_wall is enabled.
ExPolygons last = offset_ex(surface.expolygon.simplify_p(surface_simplify_resolution),
apply_precise_outer_wall ? -float(ext_perimeter_width - ext_perimeter_spacing) : - float(ext_perimeter_width / 2. - ext_perimeter_spacing / 2.));
int new_size = std::accumulate(last.begin(), last.end(), 0, [](int prev, const ExPolygon& expoly) { return prev + expoly.num_contours(); });
if (last.size() != 1 || new_size != surface.expolygon.num_contours())
apply_circle_compensation = false;
@ -1896,9 +1904,13 @@ void PerimeterGenerator::process_arachne()
std::vector<Arachne::VariableWidthLines> first_perimeters;
ExPolygons infill_contour_by_one_wall;
coord_t wall_0_inset = 0;
if (apply_precise_outer_wall)
wall_0_inset = -coord_t(ext_perimeter_width / 2 - ext_perimeter_spacing / 2);
// do detail check whether to enable one wall
if (seperate_wall_generation) {
Arachne::WallToolPaths one_wall_paths(last_p, ext_perimeter_spacing, perimeter_spacing, 1, 0, layer_height, input_params);
Arachne::WallToolPaths one_wall_paths(last_p, ext_perimeter_spacing, perimeter_spacing, 1, wall_0_inset, layer_height, input_params);
if (apply_circle_compensation)
one_wall_paths.EnableHoleCompensation(true, circle_poly_indices);
@ -1932,7 +1944,7 @@ void PerimeterGenerator::process_arachne()
if (loop_number > 0) {
last = diff_ex(infill_contour_by_one_wall, top_expolys_by_one_wall);
last_p = to_polygons(last); // disable contour compensation in remaining walls
Arachne::WallToolPaths paths_new(last_p, perimeter_spacing, perimeter_spacing, loop_number, 0, layer_height, input_params);
Arachne::WallToolPaths paths_new(last_p, perimeter_spacing, perimeter_spacing, loop_number, wall_0_inset, layer_height, input_params);
auto new_perimeters = paths_new.getToolPaths();
for (auto& perimeters : new_perimeters) {
if (!perimeters.empty()) {
@ -1949,7 +1961,7 @@ void PerimeterGenerator::process_arachne()
else {
if (is_one_wall) {
// plan wall width as one wall
Arachne::WallToolPaths one_wall_paths(last_p, ext_perimeter_spacing, perimeter_spacing, 1, 0, layer_height, input_params);
Arachne::WallToolPaths one_wall_paths(last_p, ext_perimeter_spacing, perimeter_spacing, 1, wall_0_inset, layer_height, input_params);
if (apply_circle_compensation)
one_wall_paths.EnableHoleCompensation(true, circle_poly_indices);
total_perimeters = one_wall_paths.getToolPaths();
@ -1957,7 +1969,7 @@ void PerimeterGenerator::process_arachne()
}
else {
// plan wall width as noraml
Arachne::WallToolPaths normal_paths(last_p, ext_perimeter_spacing, perimeter_spacing, loop_number + 1, 0, layer_height, input_params);
Arachne::WallToolPaths normal_paths(last_p, ext_perimeter_spacing, perimeter_spacing, loop_number + 1, wall_0_inset, layer_height, input_params);
if (apply_circle_compensation)
normal_paths.EnableHoleCompensation(true, circle_poly_indices);
total_perimeters = normal_paths.getToolPaths();

View File

@ -903,7 +903,7 @@ static std::vector<std::string> s_Preset_print_options {
"print_flow_ratio",
//Orca
"exclude_object", /*"seam_slope_type",*/ "seam_slope_conditional", "scarf_angle_threshold", /*"seam_slope_start_height", */"seam_slope_entire_loop",/* "seam_slope_min_length",*/
"seam_slope_steps", "seam_slope_inner_walls", "role_base_wipe_speed"/*, "seam_slope_gap"*/,
"seam_slope_steps", "seam_slope_inner_walls", "role_base_wipe_speed" /*, "seam_slope_gap"*/, "precise_outer_wall",
"interlocking_beam", "interlocking_orientation", "interlocking_beam_layer_count", "interlocking_depth", "interlocking_boundary_avoidance", "interlocking_beam_width"};
static std::vector<std::string> s_Preset_filament_options {

View File

@ -2307,6 +2307,12 @@ void PrintConfigDef::init_fff_params()
def->mode = comDevelop;
def->set_default_value(new ConfigOptionFloat(0));
def = this->add("precise_outer_wall", coBool);
def->label = L("Precise wall");
def->category = L("Quality");
def->tooltip = L("Improve shell precision by adjusting outer wall spacing. This also improves layer consistency.");
def->set_default_value(new ConfigOptionBool{false});
def = this->add("gap_infill_speed", coFloats);
def->label = L("Gap infill");
def->category = L("Speed");

View File

@ -965,6 +965,7 @@ PRINT_CONFIG_CLASS_DEFINE(
((ConfigOptionFloat, top_solid_infill_flow_ratio))
((ConfigOptionFloat, initial_layer_flow_ratio))
((ConfigOptionFloat, filter_out_gap_fill))
((ConfigOptionBool, precise_outer_wall))
//calib
((ConfigOptionFloat, print_flow_ratio))
// Orca: seam slopes

View File

@ -1124,7 +1124,8 @@ bool PrintObject::invalidate_state_by_config_options(
|| opt_key == "detect_overhang_wall"
//BBS
|| opt_key == "enable_overhang_speed"
|| opt_key == "detect_thin_wall") {
|| opt_key == "detect_thin_wall"
|| opt_key == "precise_outer_wall") {
steps.emplace_back(posPerimeters);
steps.emplace_back(posSupportMaterial);
} else if (opt_key == "bridge_flow") {

View File

@ -2090,7 +2090,7 @@ void TabPrint::build()
optgroup->append_single_option_line("circle_compensation_manual_offset");
optgroup->append_single_option_line("elefant_foot_compensation", "parameter/elephant-foot");
optgroup->append_single_option_line("precise_outer_wall");
optgroup->append_single_option_line("precise_z_height");
optgroup = page->new_optgroup(L("Ironing"), L"param_ironing");