This commit is contained in:
cjw 2025-05-12 16:28:54 +08:00
parent e15c2fd88d
commit 599cd5ed72
9 changed files with 89 additions and 4 deletions

View File

@ -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<Fill> f = std::unique_ptr<Fill>(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<FillLightning::Filler*>(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());

View File

@ -90,8 +90,10 @@ bool Fill::use_bridge_flow(const InfillPattern type)
Polylines Fill::fill_surface(const Surface *surface, const FillParams &params)
{
// 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) {

View File

@ -106,6 +106,7 @@ public:
// BBS: all no overlap expolygons in same layer
ExPolygons no_overlap_expolygons;
std::map<int, Point> pointMap;
public:
virtual ~Fill() {}

View File

@ -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<MonotonicRegionLink> &path, c
bool FillRectilinear::fill_surface_by_lines(const Surface *surface, const FillParams &params, 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<float, Point> 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<double>(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<SegmentedIntersectionLine> 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<MonotonicRegion> 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;
}

View File

@ -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;

View File

@ -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);
};

View File

@ -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;

View File

@ -123,6 +123,7 @@
#include "Polygon.hpp"
#include "Polyline.hpp"
#include "SVG.hpp"
//#include "Bridge.hpp"
#include "libslic3r.h"
#include "libslic3r_version.h"

View File

@ -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<wxString, wxBitmap*>::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<wxString, std::pair<wxBitmap*, bool>>::iterator it = temp_presets.begin(); it != temp_presets.end(); ++it) {
int item_id = Append(it->first, *it->second.first);