mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-05-22 12:45:17 +00:00
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:
@@ -52,7 +52,17 @@ If this value is set to 0, the ironing toolpath will start directly at the perim
|
||||
|
||||
## Angle Offset
|
||||
|
||||
The angle of ironing lines offset relative to the top surface solid infill direction. Commonly used ironing angle offsets are 0°, 45°, and 90° each producing a [different surface finish](https://github.com/SoftFever/OrcaSlicer/issues/10834#issuecomment-3322628589) which will depend on your printer nozzle.
|
||||
The angle of ironing lines offset relative to the top surface solid infill direction.
|
||||
|
||||
Commonly used ironing angle offsets are 0°, 45°, and 90° each producing a [different surface finish](https://github.com/SoftFever/OrcaSlicer/issues/10834#issuecomment-3322628589) which will depend on your printer nozzle.
|
||||
|
||||
## Fixed Angle
|
||||
|
||||
Use a fixed absolute angle for ironing that is not offset from the top surface infill direction. This results in an ironing finish that does not have alternating line directions and may result in a more uniform surface finish and reduced tiger striping effect when reflecting light.
|
||||
|
||||
Set the Ironing Angle Offset to an angle with optimal ironing angle offsets from all affected top surface solid infill directions.
|
||||
|
||||
Suggested fixed ironing angles are 0° and 90° if you are using the default solid infill direction of 45°.
|
||||
|
||||
## Speed
|
||||
|
||||
|
||||
@@ -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 ®ion_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));
|
||||
|
||||
@@ -304,10 +304,9 @@ 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)
|
||||
//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");
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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.");
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user