From 2a8cdc3414d2801e8fffc950216924071d9f4dd0 Mon Sep 17 00:00:00 2001 From: Wang YB <94800665+Gradbb@users.noreply.github.com> Date: Fri, 8 Mar 2024 09:11:53 +0800 Subject: [PATCH] add top surface gap_infill --- src/libslic3r/ExtrusionEntity.hpp | 4 + src/libslic3r/Fill/Fill.cpp | 210 ++++++++++++++++++++++++++- src/libslic3r/Fill/FillBase.hpp | 2 + src/libslic3r/Layer.cpp | 24 ++- src/libslic3r/Layer.hpp | 11 +- src/libslic3r/LayerRegion.cpp | 16 +- src/libslic3r/PerimeterGenerator.cpp | 63 ++++++-- src/libslic3r/PerimeterGenerator.hpp | 16 +- 8 files changed, 321 insertions(+), 25 deletions(-) diff --git a/src/libslic3r/ExtrusionEntity.hpp b/src/libslic3r/ExtrusionEntity.hpp index 085cd81..0d15d19 100644 --- a/src/libslic3r/ExtrusionEntity.hpp +++ b/src/libslic3r/ExtrusionEntity.hpp @@ -184,6 +184,10 @@ public: void collect_polylines(Polylines &dst) const override { if (! this->polyline.empty()) dst.emplace_back(this->polyline); } void collect_points(Points &dst) const override { append(dst, this->polyline.points); } double total_volume() const override { return m_attributes.mm3_per_mm * unscale(length()); } + //w21 + void set_width(float set_val) { m_attributes.width = set_val; } + void set_height(float set_val) { m_attributes.height = set_val; } + void set_mm3_per_mm(float set_val) { m_attributes.mm3_per_mm = set_val; } private: void _inflate_collection(const Polylines &polylines, ExtrusionEntityCollection* collection) const; diff --git a/src/libslic3r/Fill/Fill.cpp b/src/libslic3r/Fill/Fill.cpp index df9a7e0..f8fb4b2 100644 --- a/src/libslic3r/Fill/Fill.cpp +++ b/src/libslic3r/Fill/Fill.cpp @@ -17,6 +17,8 @@ #include "FillConcentric.hpp" #include "FillEnsuring.hpp" #include "Polygon.hpp" +//w21 +#include "../ShortestPath.hpp" //w11 #define NARROW_INFILL_AREA_THRESHOLD 3 #define NARROW_INFILL_AREA_THRESHOLD_MIN 0.5 @@ -113,6 +115,9 @@ struct SurfaceFill { Surface surface; ExPolygons expolygons; SurfaceFillParams params; + //w21 + std::vector region_id_group; + ExPolygons no_overlap_expolygons; }; //w11 static bool is_narrow_infill_area(const ExPolygon &expolygon) @@ -221,8 +226,18 @@ std::vector group_fills(const Layer &layer) fill.region_id = region_id; fill.surface = surface; fill.expolygons.emplace_back(std::move(fill.surface.expolygon)); - } else - fill.expolygons.emplace_back(surface.expolygon); + //w21 + fill.region_id_group.push_back(region_id); + fill.no_overlap_expolygons = layerm.fill_no_overlap_expolygons(); + } else { + //w21 + fill.expolygons.emplace_back(surface.expolygon); + auto t = find(fill.region_id_group.begin(), fill.region_id_group.end(), region_id); + if (t == fill.region_id_group.end()) { + fill.region_id_group.push_back(region_id); + fill.no_overlap_expolygons = union_ex(fill.no_overlap_expolygons, layerm.fill_no_overlap_expolygons()); + } + } } } } @@ -337,6 +352,11 @@ std::vector group_fills(const Layer &layer) } else { surface_fills[i].params.pattern = ipEnsuring; } + //w21 + if (narrow_expolygons_index.size() != expolygons_size && narrow_expolygons_index.size() != expolygons_size) { + surface_fills.back().region_id_group = surface_fills[i].region_id_group; + surface_fills.back().no_overlap_expolygons = surface_fills[i].no_overlap_expolygons; + } } } else { for (size_t surface_fill_id = 0; surface_fill_id < surface_fills.size(); ++surface_fill_id) @@ -541,11 +561,14 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive: for (ExPolygon &expoly : surface_fill.expolygons) { // Spacing is modified by the filler to indicate adjustments. Reset it for each expolygon. f->spacing = surface_fill.params.spacing; + //w21 + f->no_overlap_expolygons = intersection_ex(surface_fill.no_overlap_expolygons, ExPolygons() = {expoly}, ApplySafetyOffset::Yes); surface_fill.surface.expolygon = std::move(expoly); Polylines polylines; ThickPolylines thick_polylines; //w14 - if (this->object()->config().detect_narrow_internal_solid_infill && (surface_fill.params.pattern == ipConcentricInternal || surface_fill.params.pattern == ipEnsuring)) { + if (this->object()->config().detect_narrow_internal_solid_infill && + (surface_fill.params.pattern == ipConcentricInternal || surface_fill.params.pattern == ipEnsuring)) { layerm.region().config().infill_overlap.percent ? f->overlap = layerm.region().config().perimeter_extrusion_width * layerm.region().config().infill_overlap.value / 100 * (-1) : f->overlap = float(layerm.region().config().infill_overlap.value); @@ -605,6 +628,47 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive: ExtrusionAttributes{ surface_fill.params.extrusion_role, ExtrusionFlow{ flow_mm3_per_mm, float(flow_width), surface_fill.params.flow.height() } }); + //w21 + if (surface_fill.params.pattern == ipMonotonicLines && surface_fill.surface.surface_type == stTop) { + ExPolygons unextruded_areas = diff_ex(f->no_overlap_expolygons, union_ex(eec->polygons_covered_by_spacing(10))); + ExPolygons gapfill_areas = union_ex(unextruded_areas); + if (!f->no_overlap_expolygons.empty()) + gapfill_areas = intersection_ex(gapfill_areas, f->no_overlap_expolygons); + if (gapfill_areas.size() > 0 && params.density >= 1) { + Flow new_flow = surface_fill.params.flow.with_spacing(float(f->spacing)); + double min = 0.2 * new_flow.scaled_spacing() * (1 - INSET_OVERLAP_TOLERANCE); + double max = 2. * new_flow.scaled_spacing(); + ExPolygons gaps_ex = diff_ex(opening_ex(gapfill_areas, float(min / 2.)), + offset2_ex(gapfill_areas, -float(max / 2.), float(max / 2. + ClipperSafetyOffset))); + Points ordering_points; + ordering_points.reserve(gaps_ex.size()); + ExPolygons gaps_ex_sorted; + gaps_ex_sorted.reserve(gaps_ex.size()); + for (const ExPolygon &ex : gaps_ex) + ordering_points.push_back(ex.contour.first_point()); + std::vector order = chain_points(ordering_points); + for (size_t i : order) + gaps_ex_sorted.emplace_back(std::move(gaps_ex[i])); + + ThickPolylines polylines; + for (ExPolygon &ex : gaps_ex_sorted) { + ex.douglas_peucker(0.0125 / 0.000001 * 0.1); + ex.medial_axis(min, max, &polylines); + } + + if (!polylines.empty() && !surface_fill.params.extrusion_role.is_bridge()) { + ExtrusionEntityCollection gap_fill; + polylines.erase(std::remove_if(polylines.begin(), polylines.end(), + [&](const ThickPolyline &p) { + return p.length() < 0; // scale_(params.filter_out_gap_fill); + }), + polylines.end()); + + variable_width_gap(polylines, ExtrusionRole::GapFill, surface_fill.params.flow, gap_fill.entities); + eec->append(std::move(gap_fill.entities)); + } + } + } layerm.m_fills.entities.push_back(eec); } insert_fills_into_islands(*this, uint32_t(surface_fill.region_id), fill_begin, uint32_t(layerm.fills().size())); @@ -650,6 +714,146 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive: assert(dynamic_cast(e) != nullptr); #endif } +//w21 +void Layer::variable_width_gap(const ThickPolylines &polylines, ExtrusionRole role, const Flow &flow, std::vector &out) +{ + const float tolerance = float(scale_(0.05)); + for (const ThickPolyline &p : polylines) { + ExtrusionPaths paths = thick_polyline_to_extrusion_paths(p, role, flow, tolerance); + if (!paths.empty()) { + if (paths.front().first_point() == paths.back().last_point()) + out.emplace_back(new ExtrusionLoop(std::move(paths))); + else { + for (ExtrusionPath &path : paths) + out.emplace_back(new ExtrusionPath(std::move(path))); + } + } + } +} +//w21 +ExtrusionPaths Layer::thick_polyline_to_extrusion_paths(const ThickPolyline &thick_polyline, + ExtrusionRole role, + const Flow & flow, + const float tolerance) +{ + ExtrusionPaths paths; + ExtrusionPath path(role); + ThickLines lines = thick_polyline.thicklines(); + + size_t start_index = 0; + double max_width, min_width; + + for (int i = 0; i < (int) lines.size(); ++i) { + const ThickLine &line = lines[i]; + + if (i == 0) { + max_width = line.a_width; + min_width = line.a_width; + } + + const coordf_t line_len = line.length(); + if (line_len < SCALED_EPSILON) + continue; + + double thickness_delta = std::max(fabs(max_width - line.b_width), fabs(min_width - line.b_width)); + if (thickness_delta > tolerance) { + if (start_index != i) { + path = ExtrusionPath(role); + double length = lines[start_index].length(); + double sum = lines[start_index].length() * 0.5 * (lines[start_index].a_width + lines[start_index].b_width); + path.polyline.append(lines[start_index].a); + for (int idx = start_index + 1; idx < i; idx++) { + length += lines[idx].length(); + sum += lines[idx].length() * 0.5 * (lines[idx].a_width + lines[idx].b_width); + path.polyline.append(lines[idx].a); + } + path.polyline.append(lines[i].a); + if (length > SCALED_EPSILON) { + double w = sum / length; + Flow new_flow = flow.with_width(unscale(w) + flow.height() * float(1. - 0.25 * PI)); + + //path.mm3_per_mm = new_flow.mm3_per_mm(); + path.set_mm3_per_mm(new_flow.mm3_per_mm()); + //path.width = new_flow.width(); + path.set_width(new_flow.width()); + //path.height = new_flow.height(); + path.set_height(new_flow.height()); + paths.emplace_back(std::move(path)); + } + } + + start_index = i; + max_width = line.a_width; + min_width = line.a_width; + thickness_delta = fabs(line.a_width - line.b_width); + if (thickness_delta > tolerance) { + const unsigned int segments = (unsigned int) ceil(thickness_delta / tolerance); + const coordf_t seg_len = line_len / segments; + Points pp; + std::vector width; + { + pp.push_back(line.a); + width.push_back(line.a_width); + for (size_t j = 1; j < segments; ++j) { + pp.push_back( + (line.a.cast() + (line.b - line.a).cast().normalized() * (j * seg_len)).cast()); + + coordf_t w = line.a_width + (j * seg_len) * (line.b_width - line.a_width) / line_len; + width.push_back(w); + width.push_back(w); + } + pp.push_back(line.b); + width.push_back(line.b_width); + + assert(pp.size() == segments + 1u); + assert(width.size() == segments * 2); + } + + lines.erase(lines.begin() + i); + for (size_t j = 0; j < segments; ++j) { + ThickLine new_line(pp[j], pp[j + 1]); + new_line.a_width = width[2 * j]; + new_line.b_width = width[2 * j + 1]; + lines.insert(lines.begin() + i + j, new_line); + } + --i; + continue; + } + } + else { + max_width = std::max(max_width, std::max(line.a_width, line.b_width)); + min_width = std::min(min_width, std::min(line.a_width, line.b_width)); + } + } + size_t final_size = lines.size(); + if (start_index < final_size) { + path = ExtrusionPath(role); + double length = lines[start_index].length(); + double sum = lines[start_index].length() * lines[start_index].a_width; + path.polyline.append(lines[start_index].a); + for (int idx = start_index + 1; idx < final_size; idx++) { + length += lines[idx].length(); + sum += lines[idx].length() * lines[idx].a_width; + path.polyline.append(lines[idx].a); + } + path.polyline.append(lines[final_size - 1].b); + if (length > SCALED_EPSILON) { + double w = sum / length; + Flow new_flow = flow.with_width(unscale(w) + flow.height() * float(1. - 0.25 * PI)); + //path.mm3_per_mm = new_flow.mm3_per_mm(); + path.set_mm3_per_mm(new_flow.mm3_per_mm()); + //path.width = new_flow.width(); + path.set_width(new_flow.width()); + //path.height = new_flow.height(); + path.set_height(new_flow.height()); + paths.emplace_back(std::move(path)); + } + } + + return paths; +} + + Polylines Layer::generate_sparse_infill_polylines_for_anchoring(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive::Octree* support_fill_octree, FillLightning::Generator* lightning_generator) const { diff --git a/src/libslic3r/Fill/FillBase.hpp b/src/libslic3r/Fill/FillBase.hpp index 4130cc3..f830555 100644 --- a/src/libslic3r/Fill/FillBase.hpp +++ b/src/libslic3r/Fill/FillBase.hpp @@ -94,6 +94,8 @@ public: // PrintConfig and PrintObjectConfig are used by infills that use Arachne (Concentric and FillEnsuring). const PrintConfig *print_config = nullptr; const PrintObjectConfig *print_object_config = nullptr; + //w21 + ExPolygons no_overlap_expolygons; public: virtual ~Fill() {} diff --git a/src/libslic3r/Layer.cpp b/src/libslic3r/Layer.cpp index 2412bf9..8282ba8 100644 --- a/src/libslic3r/Layer.cpp +++ b/src/libslic3r/Layer.cpp @@ -621,6 +621,8 @@ void Layer::make_perimeters() std::vector layer_region_ids; std::vector> perimeter_and_gapfill_ranges; ExPolygons fill_expolygons; + //w21 + ExPolygons fill_no_overlap_expolygons; std::vector fill_expolygons_ranges; SurfacesPtr surfaces_to_merge; SurfacesPtr surfaces_to_merge_temp; @@ -651,6 +653,8 @@ void Layer::make_perimeters() fill_expolygons.clear(); fill_expolygons_ranges.clear(); surfaces_to_merge.clear(); + //w21 + fill_no_overlap_expolygons.clear(); // find compatible regions layer_region_ids.clear(); @@ -691,7 +695,8 @@ void Layer::make_perimeters() } if (layer_region_ids.size() == 1) { // optimization - (*layerm)->make_perimeters((*layerm)->slices(), perimeter_and_gapfill_ranges, fill_expolygons, fill_expolygons_ranges); + //w21 + (*layerm)->make_perimeters((*layerm)->slices(), perimeter_and_gapfill_ranges, fill_expolygons, fill_expolygons_ranges,fill_no_overlap_expolygons); this->sort_perimeters_into_islands((*layerm)->slices(), region_id, perimeter_and_gapfill_ranges, std::move(fill_expolygons), fill_expolygons_ranges, layer_region_ids); } else { SurfaceCollection new_slices; @@ -726,8 +731,23 @@ void Layer::make_perimeters() } } // make perimeters - layerm_config->make_perimeters(new_slices, perimeter_and_gapfill_ranges, fill_expolygons, fill_expolygons_ranges); + //w21 + layerm_config->make_perimeters(new_slices, perimeter_and_gapfill_ranges, fill_expolygons, fill_expolygons_ranges,fill_no_overlap_expolygons); this->sort_perimeters_into_islands(new_slices, region_id_config, perimeter_and_gapfill_ranges, std::move(fill_expolygons), fill_expolygons_ranges, layer_region_ids); + //w21 + if (!new_slices.surfaces.empty()) { + for (size_t idx : layer_region_ids) { + // Separate the fill surfaces. + LayerRegion &layer = *m_regions[idx]; + ExPolygons expp = intersection_ex(new_slices.surfaces, layer.slices().surfaces); + layer.m_fill_expolygons = std::move(expp); + if (!layer.m_fill_expolygons.empty()) { + layer.m_fill_surfaces.set(std::move(layer.m_fill_expolygons), layer.slices().surfaces.front()); + layer.m_fill_no_overlap_expolygons = intersection_ex(layer.slices().surfaces, fill_no_overlap_expolygons); + } + + } + } } } } diff --git a/src/libslic3r/Layer.hpp b/src/libslic3r/Layer.hpp index 5cfdf9c..9ec7ebf 100644 --- a/src/libslic3r/Layer.hpp +++ b/src/libslic3r/Layer.hpp @@ -132,6 +132,8 @@ public: // ordered collection of extrusion paths to fill surfaces // (this collection contains only ExtrusionEntityCollection objects) [[nodiscard]] const ExtrusionEntityCollection& fills() const { return m_fills; } + //w21 + [[nodiscard]] const ExPolygons &fill_no_overlap_expolygons() const { return m_fill_expolygons; } Flow flow(FlowRole role) const; Flow flow(FlowRole role, double layer_height) const; @@ -149,7 +151,9 @@ public: // All fill areas produced for all input slices above. ExPolygons &fill_expolygons, // Ranges of fill areas above per input slice. - std::vector &fill_expolygons_ranges); + std::vector &fill_expolygons_ranges, + //w21 + ExPolygons &fill_no_overlap_expolygons); void process_external_surfaces(const Layer *lower_layer, const Polygons *lower_layer_covered); double infill_area_threshold() const; // Trim surfaces by trimming polygons. Used by the elephant foot compensation at the 1st layer. @@ -228,6 +232,8 @@ private: // collection of expolygons representing the bridged areas (thus not // needing support material) // Polygons bridged; + //w21 + ExPolygons m_fill_no_overlap_expolygons; }; // LayerSlice contains one or more LayerIsland objects, @@ -386,6 +392,9 @@ public: // Is there any valid extrusion assigned to this LayerRegion? virtual bool has_extrusions() const { for (auto layerm : m_regions) if (layerm->has_extrusions()) return true; return false; } // virtual bool has_extrusions() const { for (const LayerSlice &lslice : lslices_ex) if (lslice.has_extrusions()) return true; return false; } + //w21 + void variable_width_gap(const ThickPolylines &polylines, ExtrusionRole role, const Flow &flow, std::vector &out); + ExtrusionPaths thick_polyline_to_extrusion_paths(const ThickPolyline &thick_polyline,ExtrusionRole role,const Flow & flow,const float tolerance); protected: friend class PrintObject; diff --git a/src/libslic3r/LayerRegion.cpp b/src/libslic3r/LayerRegion.cpp index 2274cfa..c296b01 100644 --- a/src/libslic3r/LayerRegion.cpp +++ b/src/libslic3r/LayerRegion.cpp @@ -73,7 +73,9 @@ void LayerRegion::make_perimeters( // All fill areas produced for all input slices above. ExPolygons &fill_expolygons, // Ranges of fill areas above per input slice. - std::vector &fill_expolygons_ranges) + std::vector &fill_expolygons_ranges, + //w21 + ExPolygons &fill_no_overlap_expolygons) { m_perimeters.clear(); m_thin_fills.clear(); @@ -132,7 +134,9 @@ void LayerRegion::make_perimeters( // output: m_perimeters, m_thin_fills, - fill_expolygons); + fill_expolygons, + //w21 + fill_no_overlap_expolygons); else PerimeterGenerator::process_arachne( // input: @@ -144,7 +148,9 @@ void LayerRegion::make_perimeters( // output: m_perimeters, m_thin_fills, - fill_expolygons); + fill_expolygons, + //w21 + fill_no_overlap_expolygons); else PerimeterGenerator::process_classic( @@ -159,7 +165,9 @@ void LayerRegion::make_perimeters( // output: m_perimeters, m_thin_fills, - fill_expolygons); + fill_expolygons, + //w21 + fill_no_overlap_expolygons); perimeter_and_gapfill_ranges.emplace_back( ExtrusionRange{ perimeters_begin, uint32_t(m_perimeters.size()) }, ExtrusionRange{ gap_fills_begin, uint32_t(m_thin_fills.size()) }); diff --git a/src/libslic3r/PerimeterGenerator.cpp b/src/libslic3r/PerimeterGenerator.cpp index b4cfe4e..85e747f 100644 --- a/src/libslic3r/PerimeterGenerator.cpp +++ b/src/libslic3r/PerimeterGenerator.cpp @@ -1079,7 +1079,9 @@ void PerimeterGenerator::add_infill_contour_for_arachne(ExPolygons infill_contou bool is_inner_part, const Parameters ¶ms, ExPolygons &infill_areas, - ExPolygons & out_fill_expolygons) + ExPolygons & out_fill_expolygons, + //w21 + ExPolygons & out_fill_no_overlap) { if (offset_ex(infill_contour, -float(spacing / 2.)).empty()) { infill_contour.clear(); @@ -1097,6 +1099,8 @@ void PerimeterGenerator::add_infill_contour_for_arachne(ExPolygons infill_contou float offset2 = insert + min_perimeter_infill_spacing / 2.; infill_areas = offset2_ex(inner_union, offset1, offset2); append(out_fill_expolygons, offset2_ex(union_ex(inner_pp), float(-min_perimeter_infill_spacing / 2.), float(insert + min_perimeter_infill_spacing / 2.))); + //w21 + append(out_fill_no_overlap,offset2_ex(inner_union, float(-min_perimeter_infill_spacing / 2.), float(min_perimeter_infill_spacing / 2.))); } @@ -1116,7 +1120,9 @@ void PerimeterGenerator::process_arachne( // Gaps without the thin walls ExtrusionEntityCollection & /* out_gap_fill */, // Infills without the gap fills - ExPolygons &out_fill_expolygons) + ExPolygons &out_fill_expolygons, + //w21 + ExPolygons &out_fill_no_overlap) { // other perimeters coord_t perimeter_spacing = params.perimeter_flow.scaled_spacing(); @@ -1360,7 +1366,8 @@ void PerimeterGenerator::process_arachne( infill_areas = diff_ex(infill_areas, filled_area); } } - + //w21 + append(out_fill_no_overlap, offset2_ex(union_ex(pp),float(-min_perimeter_infill_spacing / 2.), float(inset + min_perimeter_infill_spacing / 2.))); append(out_fill_expolygons, std::move(infill_areas)); } @@ -1380,7 +1387,9 @@ void PerimeterGenerator::process_with_one_wall_arachne( // Gaps without the thin walls ExtrusionEntityCollection & /* out_gap_fill */, // Infills without the gap fills - ExPolygons &out_fill_expolygons) + ExPolygons &out_fill_expolygons, + //w21 + ExPolygons &out_fill_no_overlap) { // other perimeters coord_t perimeter_spacing = params.perimeter_flow.scaled_spacing(); @@ -1686,16 +1695,21 @@ void PerimeterGenerator::process_with_one_wall_arachne( if (remain_loops >= 0) { + //w21 add_infill_contour_for_arachne(infill_contour, loop_number, ext_perimeter_spacing, perimeter_spacing, - min_perimeter_infill_spacing, spacing, true, params, infill_areas, out_fill_expolygons); + min_perimeter_infill_spacing, spacing, true, params, infill_areas, out_fill_expolygons,out_fill_no_overlap); } if (remain_loops >= 0) { if (!inner_infill_contour.empty()) + //w21 add_infill_contour_for_arachne(inner_infill_contour, remain_loops, ext_perimeter_spacing, perimeter_spacing, - min_perimeter_infill_spacing, spacing, true, params, infill_areas, out_fill_expolygons); + min_perimeter_infill_spacing, spacing, true, params, infill_areas, out_fill_expolygons,out_fill_no_overlap); } + //w21 + append(out_fill_no_overlap, + offset2_ex(union_ex(pp), float(-min_perimeter_infill_spacing / 2.), float(min_perimeter_infill_spacing / 2.))); append(out_fill_expolygons, std::move(infill_areas)); } else { infill_contour = union_ex(wallToolPaths.getInnerContour()); @@ -1732,7 +1746,8 @@ void PerimeterGenerator::process_with_one_wall_arachne( infill_areas = diff_ex(infill_areas, filled_area); } } - + //w21 + append(out_fill_no_overlap,offset2_ex(union_ex(pp), float(-min_perimeter_infill_spacing / 2.), float(min_perimeter_infill_spacing / 2.))); append(out_fill_expolygons, std::move(infill_areas)); } } @@ -1753,7 +1768,9 @@ void PerimeterGenerator::process_classic( // Gaps without the thin walls ExtrusionEntityCollection &out_gap_fill, // Infills without the gap fills - ExPolygons &out_fill_expolygons) + ExPolygons &out_fill_expolygons, + //w21 + ExPolygons &out_fill_no_overlap) { // other perimeters coord_t perimeter_width = params.perimeter_flow.scaled_width(); @@ -2058,9 +2075,14 @@ void PerimeterGenerator::process_classic( ext_perimeter_spacing / 2 : // two or more loops? perimeter_spacing / 2; + //w21 + coord_t infill_peri_overlap = 0; // only apply infill overlap if we actually have one perimeter - if (inset > 0) - inset -= coord_t(scale_(params.config.get_abs_value("infill_overlap", unscale(inset + solid_infill_spacing / 2)))); + //w21 + if (inset > 0) { + infill_peri_overlap = coord_t(scale_(params.config.get_abs_value("infill_overlap", unscale( solid_infill_spacing / 2)))); + inset -= infill_peri_overlap; + } // simplify infill contours according to resolution Polygons pp; for (ExPolygon &ex : last) @@ -2075,8 +2097,27 @@ void PerimeterGenerator::process_classic( float(min_perimeter_infill_spacing / 2.)); ExPolygons top_infill_exp = intersection_ex(fill_clip, offset_ex(top_fills, double(ext_perimeter_spacing / 2))); - + //w21 + if (!top_fills.empty()) { + infill_areas = union_ex(infill_areas, offset_ex(top_infill_exp, double(infill_peri_overlap))); + } append(out_fill_expolygons, std::move(top_infill_exp)); + //w21 + { + ExPolygons polyWithoutOverlap; + if (min_perimeter_infill_spacing / 2 > infill_peri_overlap) + polyWithoutOverlap = offset2_ex( + union_ex(pp), + float(-inset - min_perimeter_infill_spacing / 2.), + float(min_perimeter_infill_spacing / 2 - infill_peri_overlap)); + else + polyWithoutOverlap = offset_ex( + union_ex(pp), + double(-inset - infill_peri_overlap)); + if (!top_fills.empty()) + polyWithoutOverlap = union_ex(polyWithoutOverlap, top_infill_exp); + out_fill_no_overlap.insert(out_fill_no_overlap.end(), polyWithoutOverlap.begin(), polyWithoutOverlap.end()); + } if (lower_slices != nullptr && params.config.overhangs && params.config.extra_perimeters_on_overhangs && params.config.perimeters > 0 && params.layer_id > params.object_config.raft_layers) { diff --git a/src/libslic3r/PerimeterGenerator.hpp b/src/libslic3r/PerimeterGenerator.hpp index 13d9944..038aabb 100644 --- a/src/libslic3r/PerimeterGenerator.hpp +++ b/src/libslic3r/PerimeterGenerator.hpp @@ -81,7 +81,9 @@ void process_classic( // Gaps without the thin walls ExtrusionEntityCollection &out_gap_fill, // Infills without the gap fills - ExPolygons &out_fill_expolygons); + ExPolygons &out_fill_expolygons, + //w21 + ExPolygons &out_fill_no_overlap); void process_arachne( // Inputs: @@ -98,7 +100,9 @@ void process_arachne( // Gaps without the thin walls ExtrusionEntityCollection &out_gap_fill, // Infills without the gap fills - ExPolygons &out_fill_expolygons); + ExPolygons &out_fill_expolygons, + //w21 + ExPolygons &out_fill_no_overlap); void process_with_one_wall_arachne( // Inputs: @@ -116,7 +120,9 @@ void process_with_one_wall_arachne( // Gaps without the thin walls ExtrusionEntityCollection &out_gap_fill, // Infills without the gap fills - ExPolygons &out_fill_expolygons); + ExPolygons &out_fill_expolygons, + //w21 + ExPolygons &out_fill_no_overlap); //w16 void add_infill_contour_for_arachne(ExPolygons infill_contour, @@ -128,7 +134,9 @@ void add_infill_contour_for_arachne(ExPolygons infill_contour, bool is_inner_part, const Parameters ¶ms, ExPolygons & infill_areas, - ExPolygons & out_fill_expolygons); + ExPolygons & out_fill_expolygons, + //w21 + ExPolygons & out_fill_no_overlap); ExtrusionMultiPath thick_polyline_to_multi_path(const ThickPolyline &thick_polyline, ExtrusionRole role, const Flow &flow, float tolerance, float merge_tolerance);