Add fixed Ironing Angle setting for uniform surface finish (#11195)

* Initial working fixed ironing angle implemented with new Fixed ironing angle setting

* update documentation

* Combine Fill.is_using_template_angle and Fill.alternate_fill_direction into Fill.fixed_angle

* Rename SurfaceFillParams.is_using_template_angle to SurfaceFillParam.fixed_angle.
This commit is contained in:
Anson Liu
2025-11-03 01:21:01 -08:00
committed by GitHub
parent c105d42d09
commit c6e4ac1c4d
8 changed files with 43 additions and 24 deletions

View File

@@ -227,8 +227,8 @@ struct SurfaceFillParams
coordf_t overlap = 0.;
// Angle as provided by the region config, in radians.
float angle = 0.f;
// Orca: is_using_template_angle
bool is_using_template_angle = false;
// Orca: fixed_angle
bool fixed_angle = false;
// Is bridging used for this fill? Bridging parameters may be used even if this->flow.bridge() is not set.
bool bridge;
// Non-negative for a bridge.
@@ -284,7 +284,7 @@ struct SurfaceFillParams
RETURN_COMPARE_NON_EQUAL(spacing);
RETURN_COMPARE_NON_EQUAL(overlap);
RETURN_COMPARE_NON_EQUAL(angle);
RETURN_COMPARE_NON_EQUAL(is_using_template_angle);
RETURN_COMPARE_NON_EQUAL(fixed_angle);
RETURN_COMPARE_NON_EQUAL(density);
RETURN_COMPARE_NON_EQUAL(multiline);
// RETURN_COMPARE_NON_EQUAL_TYPED(unsigned, dont_adjust);
@@ -313,7 +313,7 @@ struct SurfaceFillParams
this->spacing == rhs.spacing &&
this->overlap == rhs.overlap &&
this->angle == rhs.angle &&
this->is_using_template_angle == rhs.is_using_template_angle &&
this->fixed_angle == rhs.fixed_angle &&
this->bridge == rhs.bridge &&
this->bridge_angle == rhs.bridge_angle &&
this->density == rhs.density &&
@@ -902,11 +902,11 @@ std::vector<SurfaceFill> group_fills(const Layer &layer, LockRegionParam &lock_p
if (params.extrusion_role == erInternalInfill) {
params.angle = calculate_infill_rotation_angle(layer.object(), layer.id(), region_config.infill_direction.value,
region_config.sparse_infill_rotate_template.value);
params.is_using_template_angle = !region_config.sparse_infill_rotate_template.value.empty();
params.fixed_angle = !region_config.sparse_infill_rotate_template.value.empty();
} else {
params.angle = calculate_infill_rotation_angle(layer.object(), layer.id(), region_config.solid_infill_direction.value,
region_config.solid_infill_rotate_template.value);
params.is_using_template_angle = !region_config.solid_infill_rotate_template.value.empty();
params.fixed_angle = !region_config.solid_infill_rotate_template.value.empty();
}
params.bridge_angle = float(surface.bridge_angle);
@@ -1094,7 +1094,7 @@ std::vector<SurfaceFill> group_fills(const Layer &layer, LockRegionParam &lock_p
const PrintRegionConfig &region_config = layerm.region().config();
params.angle = calculate_infill_rotation_angle(layer.object(), layer.id(), region_config.solid_infill_direction.value,
region_config.solid_infill_rotate_template.value);
params.is_using_template_angle = !region_config.solid_infill_rotate_template.value.empty();
params.fixed_angle = !region_config.solid_infill_rotate_template.value.empty();
// calculate the actual flow we'll be using for this infill
params.flow = layerm.flow(frSolidInfill);
@@ -1199,7 +1199,7 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive:
f->layer_id = this->id();
f->z = this->print_z;
f->angle = surface_fill.params.angle;
f->is_using_template_angle = surface_fill.params.is_using_template_angle;
f->fixed_angle = surface_fill.params.fixed_angle;
f->adapt_fill_octree = (surface_fill.params.pattern == ipSupportCubic) ? support_fill_octree : adaptive_fill_octree;
f->print_config = &this->object()->print()->config();
f->print_object_config = &this->object()->config();
@@ -1389,7 +1389,7 @@ Polylines Layer::generate_sparse_infill_polylines_for_anchoring(FillAdaptive::Oc
f->layer_id = this->id() - this->object()->get_layer(0)->id(); // We need to subtract raft layers.
f->z = this->print_z;
f->angle = surface_fill.params.angle;
f->is_using_template_angle = surface_fill.params.is_using_template_angle;
f->fixed_angle = surface_fill.params.fixed_angle;
f->adapt_fill_octree = (surface_fill.params.pattern == ipSupportCubic) ? support_fill_octree : adaptive_fill_octree;
f->print_config = &this->object()->print()->config();
f->print_object_config = &this->object()->config();
@@ -1462,7 +1462,7 @@ void Layer::make_ironing()
double height;
double speed;
double angle;
bool is_using_template_angle;
bool fixed_angle;
double inset;
bool operator<(const IroningParams &rhs) const {
@@ -1472,7 +1472,7 @@ void Layer::make_ironing()
RETURN_COMPARE_NON_EQUAL(height);
RETURN_COMPARE_NON_EQUAL(speed);
RETURN_COMPARE_NON_EQUAL(angle);
RETURN_COMPARE_NON_EQUAL(is_using_template_angle);
RETURN_COMPARE_NON_EQUAL(fixed_angle);
RETURN_COMPARE_NON_EQUAL(inset);
return false;
}
@@ -1484,7 +1484,7 @@ void Layer::make_ironing()
this->height == rhs.height &&
this->speed == rhs.speed &&
this->angle == rhs.angle &&
this->is_using_template_angle == rhs.is_using_template_angle &&
this->fixed_angle == rhs.fixed_angle &&
this->pattern == rhs.pattern &&
this->inset == rhs.inset;
}
@@ -1533,8 +1533,8 @@ void Layer::make_ironing()
ironing_params.inset = config.ironing_inset;
ironing_params.height = default_layer_height * 0.01 * config.ironing_flow;
ironing_params.speed = config.ironing_speed;
ironing_params.angle = calculate_infill_rotation_angle(this->object(), this->id(), config.solid_infill_direction.value, config.solid_infill_rotate_template.value) + config.ironing_angle * M_PI / 180.;
ironing_params.is_using_template_angle = !config.solid_infill_rotate_template.value.empty();
ironing_params.angle = (config.ironing_angle_fixed ? 0 : calculate_infill_rotation_angle(this->object(), this->id(), config.solid_infill_direction.value, config.solid_infill_rotate_template.value)) + config.ironing_angle * M_PI / 180.;
ironing_params.fixed_angle = config.ironing_angle_fixed || !config.solid_infill_rotate_template.value.empty();
ironing_params.pattern = config.ironing_pattern;
ironing_params.layerm = layerm;
by_extruder.emplace_back(ironing_params);
@@ -1630,7 +1630,7 @@ void Layer::make_ironing()
// Create the filler object.
f->spacing = ironing_params.line_spacing;
f->angle = float(ironing_params.angle);
f->is_using_template_angle = ironing_params.is_using_template_angle;
f->fixed_angle = ironing_params.fixed_angle;
f->link_max_length = (coord_t) scale_(3. * f->spacing);
double extrusion_height = ironing_params.height * f->spacing / nozzle_dmr;
float extrusion_width = Flow::rounded_rectangle_extrusion_width_from_spacing(float(nozzle_dmr), float(extrusion_height));

View File

@@ -304,11 +304,10 @@ std::pair<float, Point> Fill::_infill_direction(const Surface *surface) const
printf("Filling bridge with angle %f\n", surface->bridge_angle);
#endif /* SLIC3R_DEBUG */
out_angle = float(surface->bridge_angle);
} else if (this->layer_id != size_t(-1)) {
} else if (this->layer_id != size_t(-1) && !fixed_angle) {
// alternate fill direction
//Orca: if template angle is not empty, don't apply layer angle
if(!is_using_template_angle)
out_angle += this->_layer_angle(this->layer_id / surface->thickness_layers);
//Orca: Do not alternate direction if Fill.fixed_angle is true
out_angle += this->_layer_angle(this->layer_id / surface->thickness_layers);
} else {
// printf("Layer_ID undefined!\n");
}

View File

@@ -119,8 +119,9 @@ public:
coordf_t overlap;
// in radians, ccw, 0 = East
float angle;
// Orca: is_using_template_angle
bool is_using_template_angle{false};
// Orca: Fill direction is fixed absolute angle if SurfaceFillParams.fixed_angle or config.ironing_angle_fixed
bool fixed_angle{false};
// In scaled coordinates. Maximum lenght of a perimeter segment connecting two infill lines.
// Used by the FillRectilinear2, FillGrid2, FillTriangles, FillStars and FillCubic.
// If left to zero, the links will not be limited.
@@ -203,7 +204,7 @@ protected:
ExPolygon expolygon,
ThickPolylines& thick_polylines_out) {}
virtual float _layer_angle(size_t idx) const { return is_using_template_angle ? 0.f : (idx & 1) ? float(M_PI/2.) : 0.f; }
virtual float _layer_angle(size_t idx) const { return fixed_angle ? 0.f : (idx & 1) ? float(M_PI/2.) : 0.f; }
virtual std::pair<float, Point> _infill_direction(const Surface *surface) const;

View File

@@ -888,7 +888,7 @@ static std::vector<std::string> s_Preset_print_options {
"infill_direction", "solid_infill_direction", "counterbore_hole_bridging","infill_shift_step", "sparse_infill_rotate_template", "solid_infill_rotate_template", "symmetric_infill_y_axis","skeleton_infill_density", "infill_lock_depth", "skin_infill_depth", "skin_infill_density",
"align_infill_direction_to_model", "extra_solid_infills",
"minimum_sparse_infill_area", "reduce_infill_retraction","internal_solid_infill_pattern","gap_fill_target",
"ironing_type", "ironing_pattern", "ironing_flow", "ironing_speed", "ironing_spacing", "ironing_angle", "ironing_inset",
"ironing_type", "ironing_pattern", "ironing_flow", "ironing_speed", "ironing_spacing", "ironing_angle", "ironing_angle_fixed", "ironing_inset",
"support_ironing", "support_ironing_pattern", "support_ironing_flow", "support_ironing_spacing",
"max_travel_detour_distance",
"fuzzy_skin", "fuzzy_skin_thickness", "fuzzy_skin_point_distance", "fuzzy_skin_first_layer", "fuzzy_skin_noise_type", "fuzzy_skin_mode", "fuzzy_skin_scale", "fuzzy_skin_octaves", "fuzzy_skin_persistence",

View File

@@ -3887,6 +3887,13 @@ void PrintConfigDef::init_fff_params()
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloat(0));
def = this->add("ironing_angle_fixed", coBool);
def->label = L("Fixed ironing angle");
def->category = L("Quality");
def->tooltip = L("Use a fixed absolute angle for ironing.");
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionBool(false));
def = this->add("layer_change_gcode", coString);
def->label = L("Layer change G-code");
def->tooltip = L("This G-code is inserted at every layer change after the Z lift.");

View File

@@ -1084,6 +1084,7 @@ PRINT_CONFIG_CLASS_DEFINE(
((ConfigOptionFloat, ironing_direction))
((ConfigOptionFloat, ironing_speed))
((ConfigOptionFloat, ironing_angle))
((ConfigOptionBool, ironing_angle_fixed))
// Detect bridging perimeters
((ConfigOptionBool, detect_overhang_wall))
((ConfigOptionInt, wall_filament))

View File

@@ -2339,6 +2339,7 @@ void TabPrint::build()
optgroup->append_single_option_line("ironing_spacing", "quality_settings_ironing#line-spacing");
optgroup->append_single_option_line("ironing_inset", "quality_settings_ironing#inset");
optgroup->append_single_option_line("ironing_angle", "quality_settings_ironing#angle-offset");
optgroup->append_single_option_line("ironing_angle_fixed", "quality_settings_ironing#fixed-angle");
optgroup = page->new_optgroup(L("Wall generator"), L"param_wall_generator");
optgroup->append_single_option_line("wall_generator", "quality_settings_wall_generator");