From 872726abed4f73ff0fc946f92b29a202d61efe7a Mon Sep 17 00:00:00 2001 From: "qing.zhang" Date: Wed, 12 Feb 2025 17:39:38 +0800 Subject: [PATCH] ENH: add cross zag pattern Jira: none Signed-off-by: qing.zhang Change-Id: If11f423db443b3f31f2181d4b0c56eaeb9a7ca5d --- .../BBL/process/fdm_process_common.json | 4 ++- src/libslic3r/Fill/Fill.cpp | 28 +++++++++++++++++-- src/libslic3r/Fill/FillBase.cpp | 1 + src/libslic3r/Fill/FillBase.hpp | 2 ++ src/libslic3r/Fill/FillRectilinear.cpp | 7 +++++ src/libslic3r/Fill/FillRectilinear.hpp | 10 +++++++ src/libslic3r/Preset.cpp | 2 +- src/libslic3r/PrintConfig.cpp | 25 ++++++++++++++++- src/libslic3r/PrintConfig.hpp | 4 ++- src/libslic3r/PrintObject.cpp | 4 ++- src/slic3r/GUI/ConfigManipulation.cpp | 7 ++++- src/slic3r/GUI/Tab.cpp | 2 ++ 12 files changed, 87 insertions(+), 9 deletions(-) diff --git a/resources/profiles/BBL/process/fdm_process_common.json b/resources/profiles/BBL/process/fdm_process_common.json index 808caaa1f..4534cf6d6 100644 --- a/resources/profiles/BBL/process/fdm_process_common.json +++ b/resources/profiles/BBL/process/fdm_process_common.json @@ -134,5 +134,7 @@ "xy_hole_compensation": "0", "z_direction_outwall_speed_continuous": "0", "enable_circle_compensation": "0", - "circle_compensation_manual_offset": "0" + "circle_compensation_manual_offset": "0", + "crosszag_move_step": "0.4", + "zigzag_angle_step": "0" } \ No newline at end of file diff --git a/src/libslic3r/Fill/Fill.cpp b/src/libslic3r/Fill/Fill.cpp index 2a2dad1af..73936e3d5 100644 --- a/src/libslic3r/Fill/Fill.cpp +++ b/src/libslic3r/Fill/Fill.cpp @@ -62,6 +62,8 @@ struct SurfaceFillParams float sparse_infill_speed = 0; float top_surface_speed = 0; float solid_infill_speed = 0; + float crosszag_move_step = 0;// param for cross zag + float zigzag_angle_step = 0; // param for zig zag to get cross texture bool operator<(const SurfaceFillParams &rhs) const { #define RETURN_COMPARE_NON_EQUAL(KEY) if (this->KEY < rhs.KEY) return true; if (this->KEY > rhs.KEY) return false; @@ -88,6 +90,8 @@ struct SurfaceFillParams RETURN_COMPARE_NON_EQUAL(sparse_infill_speed); RETURN_COMPARE_NON_EQUAL(top_surface_speed); RETURN_COMPARE_NON_EQUAL(solid_infill_speed); + RETURN_COMPARE_NON_EQUAL(crosszag_move_step); + RETURN_COMPARE_NON_EQUAL(zigzag_angle_step); return false; } @@ -108,7 +112,9 @@ struct SurfaceFillParams this->extrusion_role == rhs.extrusion_role && this->sparse_infill_speed == rhs.sparse_infill_speed && this->top_surface_speed == rhs.top_surface_speed && - this->solid_infill_speed == rhs.solid_infill_speed; + this->solid_infill_speed == rhs.solid_infill_speed && + this->crosszag_move_step == rhs.crosszag_move_step && + this->zigzag_angle_step == rhs.zigzag_angle_step; } }; @@ -157,6 +163,10 @@ std::vector group_fills(const Layer &layer) params.extruder = layerm.region().extruder(extrusion_role); params.pattern = region_config.sparse_infill_pattern.value; params.density = float(region_config.sparse_infill_density); + if (params.pattern == ipCrossZag) + params.crosszag_move_step = scale_(region_config.crosszag_move_step); + if (params.pattern == ipZigZag) + params.zigzag_angle_step = region_config.zigzag_angle_step * M_PI / 360; if (surface.is_solid()) { params.density = 100.f; @@ -444,7 +454,12 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive: f->z = this->print_z; f->angle = surface_fill.params.angle; f->adapt_fill_octree = (surface_fill.params.pattern == ipSupportCubic) ? support_fill_octree : adaptive_fill_octree; - + if (surface_fill.params.pattern == ipZigZag) { + if (f->layer_id % 2 == 0) + f->angle -= surface_fill.params.zigzag_angle_step * (f->layer_id / 2); + else + f->angle += surface_fill.params.zigzag_angle_step * (f->layer_id / 2); + } if (surface_fill.params.pattern == ipConcentricInternal) { FillConcentricInternal *fill_concentric = dynamic_cast(f.get()); assert(fill_concentric != nullptr); @@ -491,6 +506,12 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive: params.extrusion_role = surface_fill.params.extrusion_role; params.using_internal_flow = using_internal_flow; params.no_extrusion_overlap = surface_fill.params.overlap; + if (surface_fill.params.pattern == ipCrossZag) { + if (f->layer_id % 2 == 0) + params.horiz_move -= surface_fill.params.crosszag_move_step * (f->layer_id / 2); + else + params.horiz_move += surface_fill.params.crosszag_move_step * (f->layer_id / 2); + } if (surface_fill.params.pattern == ipGrid) params.can_reverse = false; LayerRegion* layerm = this->m_regions[surface_fill.region_id]; @@ -559,7 +580,8 @@ Polylines Layer::generate_sparse_infill_polylines_for_anchoring(FillAdaptive::Oc case ipHilbertCurve: case ipArchimedeanChords: case ipOctagramSpiral: - case ipZigZag: break; + case ipZigZag: + case ipCrossZag: break; } // Create the filler object. diff --git a/src/libslic3r/Fill/FillBase.cpp b/src/libslic3r/Fill/FillBase.cpp index f37a857de..a8278e346 100644 --- a/src/libslic3r/Fill/FillBase.cpp +++ b/src/libslic3r/Fill/FillBase.cpp @@ -57,6 +57,7 @@ Fill* Fill::new_from_type(const InfillPattern type) // BBS: for bottom and top surface only case ipMonotonicLine: return new FillMonotonicLineWGapFill(); case ipZigZag: return new FillZigZag(); + case ipCrossZag: return new FillCrossZag(); default: throw Slic3r::InvalidArgument("unknown type"); } } diff --git a/src/libslic3r/Fill/FillBase.hpp b/src/libslic3r/Fill/FillBase.hpp index 4fbe5c367..647738bd6 100644 --- a/src/libslic3r/Fill/FillBase.hpp +++ b/src/libslic3r/Fill/FillBase.hpp @@ -76,6 +76,8 @@ struct FillParams float no_extrusion_overlap{ 0.0 }; bool dont_sort{ false }; // do not sort the lines, just simply connect them bool can_reverse{true}; + + float horiz_move{0.0}; //move infill to get cross zag pattern }; static_assert(IsTriviallyCopyable::value, "FillParams class is not POD (and it should be - see constructor)."); diff --git a/src/libslic3r/Fill/FillRectilinear.cpp b/src/libslic3r/Fill/FillRectilinear.cpp index 6640501a1..2dbf1d17a 100644 --- a/src/libslic3r/Fill/FillRectilinear.cpp +++ b/src/libslic3r/Fill/FillRectilinear.cpp @@ -2806,6 +2806,13 @@ bool FillRectilinear::fill_surface_by_lines(const Surface *surface, const FillPa if (params.full_infill()) x0 += (line_spacing + coord_t(SCALED_EPSILON)) / 2; + int gap_line = params.horiz_move / line_spacing; + if (gap_line % 2 == 0) { + x0 += params.horiz_move - gap_line * line_spacing; + } else { + x0 += params.horiz_move - (gap_line - 1) * line_spacing; + n_vlines += 1; + } #ifdef SLIC3R_DEBUG static int iRun = 0; BoundingBox bbox_svg = poly_with_offset.bounding_box_outer(); diff --git a/src/libslic3r/Fill/FillRectilinear.hpp b/src/libslic3r/Fill/FillRectilinear.hpp index 1655d3119..c7d6da974 100644 --- a/src/libslic3r/Fill/FillRectilinear.hpp +++ b/src/libslic3r/Fill/FillRectilinear.hpp @@ -150,6 +150,16 @@ public: bool has_consistent_pattern() const override { return true; } }; +class FillCrossZag : public FillRectilinear +{ +public: + Fill *clone() const override { return new FillCrossZag(*this); } + ~FillCrossZag() override = default; + + bool has_consistent_pattern() const override { return true; } +}; + + Points sample_grid_pattern(const ExPolygon &expolygon, coord_t spacing, const BoundingBox &global_bounding_box); Points sample_grid_pattern(const ExPolygons &expolygons, coord_t spacing, const BoundingBox &global_bounding_box); Points sample_grid_pattern(const Polygons &polygons, coord_t spacing, const BoundingBox &global_bounding_box); diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index d633926fa..a000f5c70 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -849,7 +849,7 @@ static std::vector s_Preset_print_options { "detect_overhang_wall", "smooth_speed_discontinuity_area","smooth_coefficient", "seam_position", "wall_sequence", "is_infill_first", "sparse_infill_density", "sparse_infill_pattern", "sparse_infill_anchor", "sparse_infill_anchor_max", - "top_surface_pattern", "bottom_surface_pattern", "internal_solid_infill_pattern", "infill_direction", "bridge_angle", + "top_surface_pattern", "bottom_surface_pattern", "internal_solid_infill_pattern", "infill_direction", "bridge_angle","crosszag_move_step", "zigzag_angle_step", "minimum_sparse_infill_area", "reduce_infill_retraction", "ironing_pattern", "ironing_type", "ironing_flow", "ironing_speed", "ironing_spacing","ironing_direction", "ironing_inset", "max_travel_detour_distance", diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 2e17d5a23..132f9572e 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -149,7 +149,8 @@ static t_config_enum_values s_keys_map_InfillPattern { { "supportcubic", ipSupportCubic }, { "lightning", ipLightning }, { "crosshatch", ipCrossHatch}, - { "zigzag", ipZigZag } + { "zigzag", ipZigZag }, + { "crosszag", ipCrossZag } }; CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(InfillPattern) @@ -1965,6 +1966,7 @@ void PrintConfigDef::init_fff_params() def->enum_values.push_back("lightning"); def->enum_values.push_back("crosshatch"); def->enum_values.push_back("zigzag"); + def->enum_values.push_back("crosszag"); def->enum_labels.push_back(L("Concentric")); def->enum_labels.push_back(L("Rectilinear")); def->enum_labels.push_back(L("Grid")); @@ -1984,6 +1986,7 @@ void PrintConfigDef::init_fff_params() def->enum_labels.push_back(L("Lightning")); def->enum_labels.push_back(L("Cross Hatch")); def->enum_labels.push_back(L("Zig Zag")); + def->enum_labels.push_back(L("Cross Zag")); def->set_default_value(new ConfigOptionEnum(ipCubic)); def = this->add("top_surface_acceleration", coFloats); @@ -2374,6 +2377,26 @@ void PrintConfigDef::init_fff_params() def->mode = comAdvanced; def->set_default_value(new ConfigOptionBool(false)); + def = this->add("crosszag_move_step", coFloat); + def->label = L("Cross Zag Move Step"); + def->category = L("Strength"); + def->tooltip = L("move infill a bit to get cross texture."); + def->sidetext = L("mm"); + def->min = 0; + def->max = 10; + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionFloat(0.4)); + + def = this->add("zigzag_angle_step", coFloat); + def->label = L("Zig Zag Angle Step"); + def->category = L("Strength"); + def->tooltip = L("rotate infill of each layer to get cross texture."); + def->sidetext = L("°"); + def->min = 0; + def->max = 360; + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionFloat(0)); + auto def_infill_anchor_min = def = this->add("sparse_infill_anchor", coFloatOrPercent); def->label = L("Length of sparse infill anchor"); def->category = L("Strength"); diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index ee807bd2a..42539af50 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -54,7 +54,7 @@ enum AuthorizationType { enum InfillPattern : int { ipConcentric, ipRectilinear, ipGrid, ipLine, ipCubic, ipTriangles, ipStars, ipGyroid, ipHoneycomb, ipAdaptiveCubic, ipMonotonic, ipMonotonicLine, ipAlignedRectilinear, ip3DHoneycomb, ipHilbertCurve, ipArchimedeanChords, ipOctagramSpiral, ipSupportCubic, ipSupportBase, ipConcentricInternal, - ipLightning, ipCrossHatch, ipZigZag, + ipLightning, ipCrossHatch, ipZigZag, ipCrossZag, ipCount, }; @@ -896,6 +896,8 @@ PRINT_CONFIG_CLASS_DEFINE( ((ConfigOptionFloat, outer_wall_line_width)) ((ConfigOptionFloatsNullable, outer_wall_speed)) ((ConfigOptionFloat, infill_direction)) + ((ConfigOptionFloat, crosszag_move_step)) + ((ConfigOptionFloat, zigzag_angle_step)) ((ConfigOptionPercent, sparse_infill_density)) ((ConfigOptionEnum, sparse_infill_pattern)) ((ConfigOptionEnum, fuzzy_skin)) diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index 4e281d352..d0fc93416 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -1087,7 +1087,9 @@ bool PrintObject::invalidate_state_by_config_options( || opt_key == "top_surface_line_width" || opt_key == "initial_layer_line_width") { steps.emplace_back(posInfill); - } else if (opt_key == "sparse_infill_pattern") { + } else if (opt_key == "sparse_infill_pattern" + || opt_key == "crosszag_move_step" + || opt_key == "zigzag_angle_step") { steps.emplace_back(posPrepareInfill); } else if (opt_key == "sparse_infill_density") { // One likely wants to reslice only when switching between zero infill to simulate boolean difference (subtracting volumes), diff --git a/src/slic3r/GUI/ConfigManipulation.cpp b/src/slic3r/GUI/ConfigManipulation.cpp index bee04661b..66d1d247a 100644 --- a/src/slic3r/GUI/ConfigManipulation.cpp +++ b/src/slic3r/GUI/ConfigManipulation.cpp @@ -558,12 +558,17 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, in bool have_infill = config->option("sparse_infill_density")->value > 0; // sparse_infill_filament uses the same logic as in Print::extruders() for (auto el : { "sparse_infill_pattern", "sparse_infill_anchor_max", "infill_combination", - "minimum_sparse_infill_area", "sparse_infill_filament"}) + "minimum_sparse_infill_area", "sparse_infill_filament","crosszag_move_step","zigzag_angle_step"}) toggle_line(el, have_infill); // Only allow configuration of open anchors if the anchoring is enabled. bool has_infill_anchors = have_infill && config->option("sparse_infill_anchor_max")->value > 0; toggle_line("sparse_infill_anchor", has_infill_anchors); + //cross zag + toggle_line("crosszag_move_step", config->option>("sparse_infill_pattern")->value == InfillPattern::ipCrossZag); + + toggle_line("zigzag_angle_step", config->option>("sparse_infill_pattern")->value == InfillPattern::ipZigZag); + bool has_spiral_vase = config->opt_bool("spiral_mode"); toggle_line("spiral_mode_smooth", has_spiral_vase); toggle_line("spiral_mode_max_xy_smoothing", config->opt_bool("spiral_mode_smooth")); diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 95443f88d..8041faa90 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -2094,6 +2094,8 @@ void TabPrint::build() optgroup = page->new_optgroup(L("Sparse infill"), L"param_infill"); optgroup->append_single_option_line("sparse_infill_density"); optgroup->append_single_option_line("sparse_infill_pattern", "fill-patterns#infill types and their properties of sparse"); + optgroup->append_single_option_line("crosszag_move_step"); + optgroup->append_single_option_line("zigzag_angle_step"); optgroup->append_single_option_line("sparse_infill_anchor"); optgroup->append_single_option_line("sparse_infill_anchor_max"); optgroup->append_single_option_line("filter_out_gap_fill");