From 599cd5ed72f3ae87ffe3e1fca0f8eb5b1b9aeffc Mon Sep 17 00:00:00 2001 From: cjw Date: Mon, 12 May 2025 16:28:54 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9A=82=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- libslic3r/Fill/Fill.cpp | 11 +++++++++++ libslic3r/Fill/FillBase.cpp | 16 +++++++++++++++ libslic3r/Fill/FillBase.hpp | 1 + libslic3r/Fill/FillRectilinear.cpp | 31 ++++++++++++++++++++++++++++++ libslic3r/GCodeWriter.cpp | 27 ++++++++++++++++++++++++++ libslic3r/GCodeWriter.hpp | 1 + libslic3r/Polyline.hpp | 1 + libslic3r/pchheader.hpp | 1 + slic3r/GUI/PresetComboBoxes.cpp | 4 ---- 9 files changed, 89 insertions(+), 4 deletions(-) diff --git a/libslic3r/Fill/Fill.cpp b/libslic3r/Fill/Fill.cpp index 7b4f6a8..00ae52f 100644 --- a/libslic3r/Fill/Fill.cpp +++ b/libslic3r/Fill/Fill.cpp @@ -438,6 +438,7 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive: for (SurfaceFill &surface_fill : surface_fills) { // Create the filler object. + //创建填充对象。 std::unique_ptr f = std::unique_ptr(Fill::new_from_type(surface_fill.params.pattern)); f->set_bounding_box(bbox); f->layer_id = this->id(); @@ -459,6 +460,7 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive: dynamic_cast(f.get())->generator = lightning_generator; // calculate flow spacing for infill pattern generation + //计算填充图案生成的流间距 bool using_internal_flow = ! surface_fill.surface.is_solid() && ! surface_fill.params.bridge; double link_max_length = 0.; if (! surface_fill.params.bridge) { @@ -472,11 +474,14 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive: } // Maximum length of the perimeter segment linking two infill lines. + //连接两条填充线的周长段的最大长度。 f->link_max_length = (coord_t)scale_(link_max_length); // Used by the concentric infill pattern to clip the loops to create extrusion paths. + //由同心填充图案用于剪裁环以创建拉伸路径。 f->loop_clipping = coord_t(scale_(surface_fill.params.flow.nozzle_diameter()) * LOOP_CLIPPING_LENGTH_OVER_NOZZLE_DIAMETER); // apply half spacing using this flow's own spacing and generate infill + //使用此流自己的间距应用半间距并生成填充 FillParams params; params.density = float(0.01 * surface_fill.params.density); params.dont_adjust = false; // surface_fill.params.dont_adjust; @@ -497,9 +502,11 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive: for (ExPolygon& expoly : surface_fill.expolygons) { f->no_overlap_expolygons = intersection_ex(surface_fill.no_overlap_expolygons, ExPolygons() = {expoly}, ApplySafetyOffset::Yes); // Spacing is modified by the filler to indicate adjustments. Reset it for each expolygon. + //填充物会修改间距以表示调整。为每个expolygon重置它。 f->spacing = surface_fill.params.spacing; surface_fill.surface.expolygon = std::move(expoly); // BBS: make fill + //此处往里执行 f->fill_surface_extrusion(&surface_fill.surface, params, m_regions[surface_fill.region_id]->fills.entities); @@ -510,6 +517,10 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive: // Unpacks the collection, creates multiple collections per path. // The path type could be ExtrusionPath, ExtrusionLoop or ExtrusionEntityCollection. // Why the paths are unpacked? + //添加薄填充区域 + //解压缩集合,在每个路径上创建多个集合。 + //路径类型可以是ExtrusionPath、ExtrusionLoop或ExtrusionEntityCollection。 + //为什么路径被解包? for (LayerRegion *layerm : m_regions) for (const ExtrusionEntity *thin_fill : layerm->thin_fills.entities) { ExtrusionEntityCollection &collection = *(new ExtrusionEntityCollection()); diff --git a/libslic3r/Fill/FillBase.cpp b/libslic3r/Fill/FillBase.cpp index c6ffd8a..dab5456 100644 --- a/libslic3r/Fill/FillBase.cpp +++ b/libslic3r/Fill/FillBase.cpp @@ -90,8 +90,10 @@ bool Fill::use_bridge_flow(const InfillPattern type) Polylines Fill::fill_surface(const Surface *surface, const FillParams ¶ms) { // Perform offset. + //执行偏移。 Slic3r::ExPolygons expp = offset_ex(surface->expolygon, float(scale_(this->overlap - 0.5 * this->spacing))); // Create the infills for each of the regions. + //为每个区域创建填充。 Polylines polylines_out; for (size_t i = 0; i < expp.size(); ++ i) _fill_surface_single( @@ -115,6 +117,7 @@ ThickPolylines Fill::fill_surface_arachne(const Surface* surface, const FillPara } // BBS: this method is used to fill the ExtrusionEntityCollection. It call fill_surface by default +//BBS:此方法用于填充ExtrusionEntity集合。默认情况下,它调用fill_surface void Fill::fill_surface_extrusion(const Surface* surface, const FillParams& params, ExtrusionEntitiesPtr& out) { Polylines polylines; @@ -124,19 +127,31 @@ void Fill::fill_surface_extrusion(const Surface* surface, const FillParams& para if (params.use_arachne) thick_polylines = this->fill_surface_arachne(surface, params); else + //调用各fill下的方法 polylines = this->fill_surface(surface, params); } catch (InfillFailedException&) {} if (!polylines.empty() || !thick_polylines.empty()) { + if (!pointMap.empty()) { + Point tempPoint = pointMap.at(1); + Polyline firstPolyline = polylines.front(); + firstPolyline.append_before(tempPoint); + //Point firstPoint = firstPolyline.first_point(); + } + Polyline lastPolyline = polylines.back(); + Point lastPoint = lastPolyline.last_point(); + pointMap.insert(std::make_pair(1, lastPoint)); // calculate actual flow from spacing (which might have been adjusted by the infill // pattern generator) + //根据间距计算实际流量(可能已由填充生成器调整) double flow_mm3_per_mm = params.flow.mm3_per_mm(); double flow_width = params.flow.width(); if (params.using_internal_flow) { // if we used the internal flow we're not doing a solid infill // so we can safely ignore the slight variation that might have // been applied to f->spacing + //如果我们使用内部流,我们就不会进行实心填充,因此我们可以安全地忽略可能应用于f->间距的微小变化 } else { Flow new_flow = params.flow.with_spacing(this->spacing); @@ -147,6 +162,7 @@ void Fill::fill_surface_extrusion(const Surface* surface, const FillParams& para ExtrusionEntityCollection* eec = nullptr; out.push_back(eec = new ExtrusionEntityCollection()); // Only concentric fills are not sorted. + //只有同心填充没有排序。 eec->no_sort = this->no_sort(); size_t idx = eec->entities.size(); if (params.use_arachne) { diff --git a/libslic3r/Fill/FillBase.hpp b/libslic3r/Fill/FillBase.hpp index 5672d55..015291b 100644 --- a/libslic3r/Fill/FillBase.hpp +++ b/libslic3r/Fill/FillBase.hpp @@ -106,6 +106,7 @@ public: // BBS: all no overlap expolygons in same layer ExPolygons no_overlap_expolygons; + std::map pointMap; public: virtual ~Fill() {} diff --git a/libslic3r/Fill/FillRectilinear.cpp b/libslic3r/Fill/FillRectilinear.cpp index 5d5eb0a..f857df2 100644 --- a/libslic3r/Fill/FillRectilinear.cpp +++ b/libslic3r/Fill/FillRectilinear.cpp @@ -384,6 +384,8 @@ static SegmentIntersection phony_outer_intersection(SegmentIntersection::Segment // A container maintaining an expolygon with its inner offsetted polygon. // The purpose of the inner offsetted polygon is to provide segments to connect the infill lines. +//一种容器,其内部有偏移多边形,保持一个expolygon。 +//内部偏移多边形的目的是提供连接填充线的线段。 struct ExPolygonWithOffset { public: @@ -393,6 +395,8 @@ public: coord_t aoffset1, // If the 2nd offset is zero, then it is ignored and only OUTER_LOW / OUTER_HIGH intersections are // populated into vertical intersection lines. + //如果第二个偏移量为零,则忽略它,只有OUTER_LOW/OUTER_HIGH交点是 + //填充到垂直交叉线中。 coord_t aoffset2 = 0) { // Copy and rotate the source polygons. @@ -1356,6 +1360,7 @@ static void traverse_graph_generate_polylines( { // For each outer only chords, measure their maximum distance to the bow of the outer contour. // Mark an outer only chord as consumed, if the distance is low. + for (int i_vline = 0; i_vline < int(segs.size()); ++ i_vline) { SegmentedIntersectionLine &vline = segs[i_vline]; for (int i_intersection = 0; i_intersection + 1 < int(vline.intersections.size()); ++ i_intersection) { @@ -2739,14 +2744,18 @@ static void polylines_from_paths(const std::vector &path, c bool FillRectilinear::fill_surface_by_lines(const Surface *surface, const FillParams ¶ms, float angleBase, float pattern_shift, Polylines &polylines_out) { // At the end, only the new polylines will be rotated back. + //最后,只有新的多段线将被向后旋转。 size_t n_polylines_out_initial = polylines_out.size(); // Shrink the input polygon a bit first to not push the infill lines out of the perimeters. // const float INFILL_OVERLAP_OVER_SPACING = 0.3f; + //先稍微收缩输入多边形,不要将填充线推出周界。 +//常量浮点INFILL_OVERLAP_OVER_SPACING=0.3f; const float INFILL_OVERLAP_OVER_SPACING = 0.45f; assert(INFILL_OVERLAP_OVER_SPACING > 0 && INFILL_OVERLAP_OVER_SPACING < 0.5f); // Rotate polygons so that we can work with vertical lines here + //旋转多边形,以便我们可以在这里处理垂直线 std::pair rotate_vector = this->_infill_direction(surface); rotate_vector.first += angleBase; @@ -2754,6 +2763,7 @@ bool FillRectilinear::fill_surface_by_lines(const Surface *surface, const FillPa coord_t line_spacing = coord_t(scale_(this->spacing) / params.density); // On the polygons of poly_with_offset, the infill lines will be connected. + //在poly_with_offset的多边形上,填充线将被连接。 ExPolygonWithOffset poly_with_offset( surface->expolygon, - rotate_vector.first, @@ -2762,20 +2772,26 @@ bool FillRectilinear::fill_surface_by_lines(const Surface *surface, const FillPa if (poly_with_offset.n_contours_inner == 0) { // Not a single infill line fits. //FIXME maybe one shall trigger the gap fill here? + //没有一条填充线适合。 + //FIXME也许应该触发这里的空白填补? return true; } BoundingBox bounding_box = poly_with_offset.bounding_box_src(); // define flow spacing according to requested density + //根据要求的密度定义流间距 if (params.full_infill() && !params.dont_adjust) { line_spacing = this->_adjust_solid_spacing(bounding_box.size()(0), line_spacing); this->spacing = unscale(line_spacing); } else { // extend bounding box so that our pattern will be aligned with other layers // Transform the reference point to the rotated coordinate system. + //扩展边界框,使我们的图案与其他层对齐 + //将参考点变换到旋转坐标系。 Point refpt = rotate_vector.second.rotated(- rotate_vector.first); // align_to_grid will not work correctly with positive pattern_shift. + //align_to_grid在正向模式shift下无法正常工作。 coord_t pattern_shift_scaled = coord_t(scale_(pattern_shift)) % line_spacing; refpt.x() -= (pattern_shift_scaled >= 0) ? pattern_shift_scaled : (line_spacing + pattern_shift_scaled); bounding_box.merge(align_to_grid( @@ -2786,6 +2802,7 @@ bool FillRectilinear::fill_surface_by_lines(const Surface *surface, const FillPa // Intersect a set of euqally spaced vertical lines wiht expolygon. // n_vlines = ceil(bbox_width / line_spacing) + //用expolygon相交一组等距的垂直线。 size_t n_vlines = (bounding_box.max(0) - bounding_box.min(0) + line_spacing - 1) / line_spacing; coord_t x0 = bounding_box.min(0); if (params.full_infill()) @@ -2805,10 +2822,12 @@ bool FillRectilinear::fill_surface_by_lines(const Surface *surface, const FillPa std::vector segs = slice_region_by_vertical_lines(poly_with_offset, n_vlines, x0, line_spacing); // Connect by horizontal / vertical links, classify the links based on link_max_length as too long. + //通过水平/垂直链接连接,根据link_max_length将链接分类为太长。 connect_segment_intersections_by_contours(poly_with_offset, segs, params, link_max_length); #ifdef SLIC3R_DEBUG // Paint the segments and finalize the SVG file. + //绘制片段并最终确定SVG文件。 for (size_t i_seg = 0; i_seg < segs.size(); ++ i_seg) { SegmentedIntersectionLine &sil = segs[i_seg]; for (size_t i = 0; i < sil.intersections.size();) { @@ -2833,6 +2852,9 @@ bool FillRectilinear::fill_surface_by_lines(const Surface *surface, const FillPa // Sometimes the outer contour pinches the inner contour from both sides along a single vertical line. // This situation is not handled correctly by generate_montonous_regions(). // Insert phony OUTER_HIGH / OUTER_LOW pairs at the position where the contour is pinched. + //有时,外轮廓会沿着一条垂直线从两侧挤压内轮廓。 + //generate_montonos_regions()没有正确处理这种情况。 + //在轮廓被挤压的位置插入假OUTER_HIGH/OUTER_LOW对。 pinch_contours_insert_phony_outer_intersections(segs); std::vector regions = generate_montonous_regions(segs); #ifdef INFILL_DEBUG_OUTPUT @@ -2867,12 +2889,15 @@ bool FillRectilinear::fill_surface_by_lines(const Surface *surface, const FillPa #endif /* SLIC3R_DEBUG */ // paths must be rotated back + //路径必须向后旋转 for (Polylines::iterator it = polylines_out.begin() + n_polylines_out_initial; it != polylines_out.end(); ++ it) { // No need to translate, the absolute position is irrelevant. + //无需翻译,绝对位置无关紧要。 // it->translate(- rotate_vector.second(0), - rotate_vector.second(1)); assert(! it->has_duplicate_points()); it->rotate(rotate_vector.first); //FIXME rather simplify the paths to avoid very short edges? + //FIXME会简化路径以避免非常短的边吗? //assert(! it->has_duplicate_points()); it->remove_duplicate_points(); } @@ -2890,15 +2915,19 @@ void make_fill_lines(const ExPolygonWithOffset &poly_with_offset, Point refpt, d { BoundingBox bounding_box = poly_with_offset.bounding_box_src(); // Don't produce infill lines, which fully overlap with the infill perimeter. + //不要生成与填充周界完全重叠的填充线。 coord_t x_min = bounding_box.min.x() + x_margin; coord_t x_max = bounding_box.max.x() - x_margin; // extend bounding box so that our pattern will be aligned with other layers // align_to_grid will not work correctly with positive pattern_shift. + //扩展边界框,使我们的图案与其他层对齐 + //align_to_grid在正向模式shift下无法正常工作。 coord_t pattern_shift_scaled = pattern_shift % line_spacing; refpt.x() -= (pattern_shift_scaled >= 0) ? pattern_shift_scaled : (line_spacing + pattern_shift_scaled); bounding_box.merge(Slic3r::align_to_grid(bounding_box.min, Point(line_spacing, line_spacing), refpt)); // Intersect a set of euqally spaced vertical lines wiht expolygon. + //用expolygon相交一组等距的垂直线。 // n_vlines = ceil(bbox_width / line_spacing) const size_t n_vlines = (bounding_box.max.x() - bounding_box.min.x() + line_spacing - 1) / line_spacing; const double cos_a = cos(angle); @@ -2970,8 +2999,10 @@ Polylines FillMonotonic::fill_surface(const Surface *surface, const FillParams & FillParams params2 = params; params2.monotonic = true; Polylines polylines_out; + //polylines_out.back() if (! fill_surface_by_lines(surface, params2, 0.f, 0.f, polylines_out)) BOOST_LOG_TRIVIAL(error) << "FillMonotonous::fill_surface() failed to fill a region."; + return polylines_out; } diff --git a/libslic3r/GCodeWriter.cpp b/libslic3r/GCodeWriter.cpp index d97b6f9..8892462 100644 --- a/libslic3r/GCodeWriter.cpp +++ b/libslic3r/GCodeWriter.cpp @@ -435,6 +435,7 @@ std::string GCodeWriter::travel_to_xyz(const Vec3d &point, const std::string &co } else if (m_to_lift_type == LiftType::NormalLift) { slop_move = _travel_to_z(target.z(), "normal lift Z"); + slop_move = _travel_to_z_test(target.z(), "normal lift Z"); } } @@ -443,6 +444,11 @@ std::string GCodeWriter::travel_to_xyz(const Vec3d &point, const std::string &co GCodeG1Formatter w0; if (this->is_current_position_clear()) { w0.emit_xyz(target); + //auto dE = m_extruder->E(); + auto dE = 1; + if (dE > 0) { + w0.emit_e(dE); + } w0.emit_f(this->config.travel_speed.value * 60.0); w0.emit_comment(GCodeWriter::full_gcode_comment, comment); xy_z_move = w0.string(); @@ -538,6 +544,27 @@ std::string GCodeWriter::_travel_to_z(double z, const std::string &comment) return w.string(); } +std::string GCodeWriter::_travel_to_z_test(double z, const std::string& comment) +{ + m_pos(2) = z; + + double speed = this->config.travel_speed_z.value; + if (speed == 0.) + speed = this->config.travel_speed.value; + + GCodeG1Formatter w; + w.emit_z(z); + w.emit_f(speed * 60.0); + //auto dE = m_extruder->E(); + auto dE = 1; + if (dE > 0) { + w.emit_e(dE); + } + //BBS + w.emit_comment(GCodeWriter::full_gcode_comment, comment); + return w.string(); +} + std::string GCodeWriter::_spiral_travel_to_z(double z, const Vec2d &ij_offset, const std::string &comment) { m_pos(2) = z; diff --git a/libslic3r/GCodeWriter.hpp b/libslic3r/GCodeWriter.hpp index 77f4b39..8aa074a 100644 --- a/libslic3r/GCodeWriter.hpp +++ b/libslic3r/GCodeWriter.hpp @@ -144,6 +144,7 @@ private: std::string m_gcode_label_objects_end; std::string _travel_to_z(double z, const std::string &comment); + std::string _travel_to_z_test(double z, const std::string &comment); std::string _spiral_travel_to_z(double z, const Vec2d &ij_offset, const std::string &comment); std::string _retract(double length, double restart_extra, const std::string &comment); }; diff --git a/libslic3r/Polyline.hpp b/libslic3r/Polyline.hpp index 074db1a..4c9b4f5 100644 --- a/libslic3r/Polyline.hpp +++ b/libslic3r/Polyline.hpp @@ -106,6 +106,7 @@ public: const Point& operator[](Points::size_type idx) const { return this->points[idx]; } const Point& last_point() const override { return this->points.back(); } + //const Point& first_point() const override { return this->points.front(); } const Point& leftmost_point() const; Lines lines() const override; diff --git a/libslic3r/pchheader.hpp b/libslic3r/pchheader.hpp index e6591f5..2cb523b 100644 --- a/libslic3r/pchheader.hpp +++ b/libslic3r/pchheader.hpp @@ -123,6 +123,7 @@ #include "Polygon.hpp" #include "Polyline.hpp" #include "SVG.hpp" +//#include "Bridge.hpp" #include "libslic3r.h" #include "libslic3r_version.h" diff --git a/slic3r/GUI/PresetComboBoxes.cpp b/slic3r/GUI/PresetComboBoxes.cpp index eb88d71..1ac547b 100644 --- a/slic3r/GUI/PresetComboBoxes.cpp +++ b/slic3r/GUI/PresetComboBoxes.cpp @@ -1076,12 +1076,10 @@ void PlaterPresetComboBox::update() }*/ temp_presets.clear(); for (const auto& pair : nonsys_presets) { - if (m_fold) { wxString key = pair.first; if (key.Contains(lian_xu)) { temp_presets.emplace(pair); } - } } for (std::map::iterator it = temp_presets.begin(); it != temp_presets.end(); ++it) { SetItemTooltip(Append(it->first, *it->second), preset_descriptions[it->first]); @@ -1354,12 +1352,10 @@ void TabPresetComboBox::update() }*/ temp_presets.clear(); for (const auto& pair : nonsys_presets) { - if (m_fold) { wxString key = pair.first; if (key.Contains(lian_xu)) { temp_presets.emplace(pair); } - } } for (std::map>::iterator it = temp_presets.begin(); it != temp_presets.end(); ++it) { int item_id = Append(it->first, *it->second.first);