Merge branch 'main' into bugfox/bed-shape-orientation

This commit is contained in:
Noisyfox
2025-04-26 12:35:23 +08:00
committed by GitHub
58 changed files with 1192 additions and 286 deletions

View File

@@ -34,7 +34,9 @@ public:
double unretract();
double E() const { return m_share_extruder ? m_share_E : m_E; }
void reset_E() { m_E = 0.; m_share_E = 0.; }
// e_per_mm is extrusion_per_mm = geometric volume * (filament flow ratio / cross-sectional area) [Doesn't account for print_flow_ratio, or modifiers like bridge flow ratio etc.]
double e_per_mm(double mm3_per_mm) const { return mm3_per_mm * m_e_per_mm3; }
// e_per_mm3 is extrusion_per_mm3 = filament flow ratio / cross-sectional area [Doesn't account for print_flow_ratio, or modifiers like bridge flow ratio etc.]
double e_per_mm3() const { return m_e_per_mm3; }
// Used filament volume in mm^3.
double extruded_volume() const;

View File

@@ -273,10 +273,7 @@ void Fill3DHoneycomb::_fill_surface_single(
if (!polylines.empty()) {
int infill_start_idx = polylines_out.size(); // only rotate what belongs to us.
// connect lines
if (params.dont_connect() || polylines.size() <= 1)
append(polylines_out, chain_polylines(std::move(polylines)));
else
this->connect_infill(std::move(polylines), expolygon, polylines_out, this->spacing, params);
chain_or_connect_infill(std::move(polylines), expolygon, polylines_out, this->spacing, params);
// rotate back
if (std::abs(infill_angle) >= EPSILON) {

View File

@@ -1401,10 +1401,7 @@ void Filler::_fill_surface_single(
}
#endif /* ADAPTIVE_CUBIC_INFILL_DEBUG_OUTPUT */
if (params.dont_connect() || all_polylines_with_hooks.size() <= 1)
append(polylines_out, chain_polylines(std::move(all_polylines_with_hooks)));
else
connect_infill(std::move(all_polylines_with_hooks), expolygon, polylines_out, this->spacing, params);
chain_or_connect_infill(std::move(all_polylines_with_hooks), expolygon, polylines_out, this->spacing, params);
#ifdef ADAPTIVE_CUBIC_INFILL_DEBUG_OUTPUT
{

View File

@@ -1787,6 +1787,18 @@ void Fill::connect_infill(Polylines &&infill_ordered, const std::vector<const Po
polylines_out.emplace_back(std::move(pl));
}
void Fill::chain_or_connect_infill(Polylines &&infill_ordered, const ExPolygon &boundary, Polylines &polylines_out, const double spacing, const FillParams &params)
{
if (!infill_ordered.empty()) {
if (params.dont_connect()) {
if (infill_ordered.size() > 1)
infill_ordered = chain_polylines(std::move(infill_ordered));
append(polylines_out, std::move(infill_ordered));
} else
connect_infill(std::move(infill_ordered), boundary, polylines_out, spacing, params);
}
}
// Extend the infill lines along the perimeters, this is mainly useful for grid aligned support, where a perimeter line may be nearly
// aligned with the infill lines.
static inline void base_support_extend_infill_lines(Polylines &infill, BoundaryInfillGraph &graph, const double spacing, const FillParams &params)

View File

@@ -191,6 +191,8 @@ public:
static void connect_infill(Polylines &&infill_ordered, const Polygons &boundary, const BoundingBox& bbox, Polylines &polylines_out, const double spacing, const FillParams &params);
static void connect_infill(Polylines &&infill_ordered, const std::vector<const Polygon*> &boundary, const BoundingBox &bbox, Polylines &polylines_out, double spacing, const FillParams &params);
static void chain_or_connect_infill(Polylines &&infill_ordered, const ExPolygon &boundary, Polylines &polylines_out, const double spacing, const FillParams &params);
static void connect_base_support(Polylines &&infill_ordered, const std::vector<const Polygon*> &boundary_src, const BoundingBox &bbox, Polylines &polylines_out, const double spacing, const FillParams &params);
static void connect_base_support(Polylines &&infill_ordered, const Polygons &boundary_src, const BoundingBox &bbox, Polylines &polylines_out, const double spacing, const FillParams &params);

View File

@@ -218,10 +218,7 @@ void FillCrossHatch ::_fill_surface_single(
if (!polylines.empty()) {
int infill_start_idx = polylines_out.size(); // only rotate what belongs to us.
// connect lines
if (params.dont_connect() || polylines.size() <= 1)
append(polylines_out, chain_polylines(std::move(polylines)));
else
this->connect_infill(std::move(polylines), expolygon, polylines_out, this->spacing, params);
chain_or_connect_infill(std::move(polylines), expolygon, polylines_out, this->spacing, params);
// rotate back
if (std::abs(infill_angle) >= EPSILON) {

View File

@@ -194,10 +194,7 @@ void FillGyroid::_fill_surface_single(
if (! polylines.empty()) {
// connect lines
size_t polylines_out_first_idx = polylines_out.size();
if (params.dont_connect())
append(polylines_out, chain_polylines(polylines));
else
this->connect_infill(std::move(polylines), expolygon, polylines_out, this->spacing, params);
chain_or_connect_infill(std::move(polylines), expolygon, polylines_out, this->spacing, params);
// new paths must be rotated back
if (std::abs(infill_angle) >= EPSILON) {

View File

@@ -74,10 +74,7 @@ void FillHoneycomb::_fill_surface_single(
}
all_polylines = intersection_pl(std::move(all_polylines), expolygon);
if (params.dont_connect() || all_polylines.size() <= 1)
append(polylines_out, chain_polylines(std::move(all_polylines)));
else
connect_infill(std::move(all_polylines), expolygon, polylines_out, this->spacing, params);
chain_or_connect_infill(std::move(all_polylines), expolygon, polylines_out, this->spacing, params);
}
} // namespace Slic3r

View File

@@ -16,10 +16,7 @@ void Filler::_fill_surface_single(
const Layer &layer = generator->getTreesForLayer(this->layer_id);
Polylines fill_lines = layer.convertToLines(to_polygons(expolygon), scaled<coord_t>(0.5 * this->spacing - this->overlap));
if (params.dont_connect() || fill_lines.size() <= 1) {
append(polylines_out, chain_polylines(std::move(fill_lines)));
} else
connect_infill(std::move(fill_lines), expolygon, polylines_out, this->spacing, params);
chain_or_connect_infill(std::move(fill_lines), expolygon, polylines_out, this->spacing, params);
}
void GeneratorDeleter::operator()(Generator *p) {

View File

@@ -119,42 +119,44 @@ void FillPlanePath::_fill_surface_single(
if (polyline.size() >= 2) {
Polylines polylines = intersection_pl(polyline, expolygon);
Polylines chained;
if (params.dont_connect() || params.density > 0.5 || polylines.size() <= 1) {
// ORCA: special flag for flow rate calibration
auto is_flow_calib = params.extrusion_role == erTopSolidInfill &&
this->print_object_config->has("calib_flowrate_topinfill_special_order") &&
this->print_object_config->option("calib_flowrate_topinfill_special_order")->getBool() &&
dynamic_cast<FillArchimedeanChords*>(this);
if (is_flow_calib) {
// We want the spiral part to be printed inside-out
// Find the center spiral line first, by looking for the longest one
auto it = std::max_element(polylines.begin(), polylines.end(), [](const Polyline& a, const Polyline& b) { return a.length() < b.length(); });
Polyline center_spiral = std::move(*it);
if (!polylines.empty()) {
Polylines chained;
if (params.dont_connect() || params.density > 0.5) {
// ORCA: special flag for flow rate calibration
auto is_flow_calib = params.extrusion_role == erTopSolidInfill &&
this->print_object_config->has("calib_flowrate_topinfill_special_order") &&
this->print_object_config->option("calib_flowrate_topinfill_special_order")->getBool() &&
dynamic_cast<FillArchimedeanChords*>(this);
if (is_flow_calib) {
// We want the spiral part to be printed inside-out
// Find the center spiral line first, by looking for the longest one
auto it = std::max_element(polylines.begin(), polylines.end(),
[](const Polyline& a, const Polyline& b) { return a.length() < b.length(); });
Polyline center_spiral = std::move(*it);
// Ensure the spiral is printed from inside to out
if (center_spiral.first_point().squaredNorm() > center_spiral.last_point().squaredNorm()) {
center_spiral.reverse();
// Ensure the spiral is printed from inside to out
if (center_spiral.first_point().squaredNorm() > center_spiral.last_point().squaredNorm()) {
center_spiral.reverse();
}
// Chain the other polylines
polylines.erase(it);
chained = chain_polylines(std::move(polylines));
// Then add the center spiral back
chained.push_back(std::move(center_spiral));
} else {
chained = chain_polylines(std::move(polylines));
}
// Chain the other polylines
polylines.erase(it);
chained = chain_polylines(std::move(polylines));
// Then add the center spiral back
chained.push_back(std::move(center_spiral));
} else {
chained = chain_polylines(std::move(polylines));
} else
connect_infill(std::move(polylines), expolygon, chained, this->spacing, params);
// paths must be repositioned and rotated back
for (Polyline& pl : chained) {
pl.translate(shift.x(), shift.y());
pl.rotate(direction.first);
}
append(polylines_out, std::move(chained));
}
else
connect_infill(std::move(polylines), expolygon, chained, this->spacing, params);
// paths must be repositioned and rotated back
for (Polyline &pl : chained) {
pl.translate(shift.x(), shift.y());
pl.rotate(direction.first);
}
append(polylines_out, std::move(chained));
}
}

View File

@@ -2928,7 +2928,7 @@ void make_fill_lines(const ExPolygonWithOffset &poly_with_offset, Point refpt, d
bool FillRectilinear::fill_surface_by_multilines(const Surface *surface, FillParams params, const std::initializer_list<SweepParams> &sweep_params, Polylines &polylines_out)
{
assert(sweep_params.size() > 1);
assert(sweep_params.size() >= 1);
assert(! params.full_infill());
params.density /= double(sweep_params.size());
assert(params.density > 0.0001f && params.density <= 1.f);
@@ -2948,12 +2948,14 @@ bool FillRectilinear::fill_surface_by_multilines(const Surface *surface, FillPar
make_fill_lines(ExPolygonWithOffset(poly_with_offset_base, - angle), rotate_vector.second.rotated(-angle), angle, line_width + coord_t(SCALED_EPSILON), line_spacing, coord_t(scale_(sweep.pattern_shift)), fill_lines);
}
if (params.dont_connect() || fill_lines.size() <= 1) {
if (fill_lines.size() > 1)
fill_lines = chain_polylines(std::move(fill_lines));
append(polylines_out, std::move(fill_lines));
} else
connect_infill(std::move(fill_lines), poly_with_offset_base.polygons_outer, get_extents(surface->expolygon.contour), polylines_out, this->spacing, params);
if (!fill_lines.empty()) {
if (params.dont_connect()) {
if (fill_lines.size() > 1)
fill_lines = chain_polylines(std::move(fill_lines));
append(polylines_out, std::move(fill_lines));
} else
connect_infill(std::move(fill_lines), poly_with_offset_base.polygons_outer, get_extents(surface->expolygon.contour), polylines_out, this->spacing, params);
}
return true;
}
@@ -2961,8 +2963,13 @@ bool FillRectilinear::fill_surface_by_multilines(const Surface *surface, FillPar
Polylines FillRectilinear::fill_surface(const Surface *surface, const FillParams &params)
{
Polylines polylines_out;
if (! fill_surface_by_lines(surface, params, 0.f, 0.f, polylines_out))
BOOST_LOG_TRIVIAL(error) << "FillRectilinear::fill_surface() failed to fill a region.";
if (params.full_infill()) {
if (!fill_surface_by_lines(surface, params, 0.f, 0.f, polylines_out))
BOOST_LOG_TRIVIAL(error) << "FillRectilinear::fill_surface() fill_surface_by_lines() failed to fill a region.";
} else {
if (!fill_surface_by_multilines(surface, params, {{0.f, 0.f}}, polylines_out))
BOOST_LOG_TRIVIAL(error) << "FillRectilinear::fill_surface() fill_surface_by_multilines() failed to fill a region.";
}
return polylines_out;
}

View File

@@ -5270,8 +5270,11 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
gcode += m_writer.set_jerk_xy(jerk);
}
// calculate extrusion length per distance unit
// calculate effective extrusion length per distance unit (e_per_mm)
double filament_flow_ratio = m_config.option<ConfigOptionFloats>("filament_flow_ratio")->get_at(0);
// We set _mm3_per_mm to effectove flow = Geometric volume * print flow ratio * filament flow ratio * role-based-flow-ratios
auto _mm3_per_mm = path.mm3_per_mm * this->config().print_flow_ratio;
_mm3_per_mm *= filament_flow_ratio;
if (path.role() == erTopSolidInfill)
_mm3_per_mm *= m_config.top_solid_infill_flow_ratio;
else if (path.role() == erBottomSurface)
@@ -5280,9 +5283,12 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
_mm3_per_mm *= m_config.internal_bridge_flow;
else if(sloped)
_mm3_per_mm *= m_config.scarf_joint_flow_ratio;
// Effective extrusion length per distance unit = (filament_flow_ratio/cross_section) * mm3_per_mm / print flow ratio
// m_writer.extruder()->e_per_mm3() below is (filament flow ratio / cross-sectional area)
double e_per_mm = m_writer.extruder()->e_per_mm3() * _mm3_per_mm;
e_per_mm /= filament_flow_ratio;
// set speed
if (speed == -1) {

View File

@@ -1150,6 +1150,7 @@ void GCodeProcessor::reset()
m_forced_width = 0.0f;
m_forced_height = 0.0f;
m_mm3_per_mm = 0.0f;
m_travel_dist = 0.0f;
m_fan_speed = 0.0f;
m_z_offset = 0.0f;
@@ -2648,7 +2649,8 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line, const std::o
EMoveType type = move_type(delta_pos);
if (type == EMoveType::Extrude) {
float delta_xyz = std::sqrt(sqr(delta_pos[X]) + sqr(delta_pos[Y]) + sqr(delta_pos[Z]));
const float delta_xyz = std::sqrt(sqr(delta_pos[X]) + sqr(delta_pos[Y]) + sqr(delta_pos[Z]));
m_travel_dist = delta_xyz;
float volume_extruded_filament = area_filament_cross_section * delta_pos[E];
float area_toolpath_cross_section = volume_extruded_filament / delta_xyz;
@@ -3125,7 +3127,8 @@ void GCodeProcessor::process_G2_G3(const GCodeReader::GCodeLine& line)
EMoveType type = move_type(delta_pos[E]);
float delta_xyz = std::sqrt(sqr(arc_length) + sqr(delta_pos[Z]));
const float delta_xyz = std::sqrt(sqr(arc_length) + sqr(delta_pos[Z]));
m_travel_dist = delta_xyz;
if (type == EMoveType::Extrude) {
float volume_extruded_filament = area_filament_cross_section * delta_pos[E];
float area_toolpath_cross_section = volume_extruded_filament / delta_xyz;
@@ -4783,6 +4786,7 @@ void GCodeProcessor::store_move_vertex(EMoveType type, EMovePathType path_type)
m_width,
m_height,
m_mm3_per_mm,
m_travel_dist,
m_fan_speed,
m_extruder_temps[m_extruder_id],
static_cast<float>(m_result.moves.size()),

View File

@@ -162,6 +162,7 @@ class Print;
float width{ 0.0f }; // mm
float height{ 0.0f }; // mm
float mm3_per_mm{ 0.0f };
float travel_dist{ 0.0f }; // mm
float fan_speed{ 0.0f }; // percentage
float temperature{ 0.0f }; // Celsius degrees
float time{ 0.0f }; // s
@@ -704,6 +705,7 @@ class Print;
float m_forced_width; // mm
float m_forced_height; // mm
float m_mm3_per_mm;
float m_travel_dist; // mm
float m_fan_speed; // percentage
float m_z_offset; // mm
ExtrusionRole m_extrusion_role;