Merge prusa 2.6.1

This commit is contained in:
QIDI TECH
2023-09-16 16:26:29 +08:00
parent 1338e60f8b
commit 963e22db99
203 changed files with 25254 additions and 6453 deletions

View File

@@ -792,8 +792,8 @@ std::string CoolingBuffer::apply_layer_cooldown(
if (int(layer_id) >= disable_fan_first_layers && int(layer_id) + 1 < full_fan_speed_layer) {
// Ramp up the fan speed from disable_fan_first_layers to full_fan_speed_layer.
float factor = float(int(layer_id + 1) - disable_fan_first_layers) / float(full_fan_speed_layer - disable_fan_first_layers);
fan_speed_new = std::clamp(int(float(fan_speed_new) * factor + 0.5f), 0, 255);
bridge_fan_speed = std::clamp(int(float(bridge_fan_speed) * factor + 0.5f), 0, 255);
fan_speed_new = std::clamp(int(float(fan_speed_new) * factor + 0.5f), 0, 100);
bridge_fan_speed = std::clamp(int(float(bridge_fan_speed) * factor + 0.5f), 0, 100);
custom_fan_speed_limits.second = fan_speed_new;
}
#undef EXTRUDER_CONFIG

View File

@@ -146,67 +146,68 @@ std::vector<ExtendedPoint> estimate_points_properties(const POINTS
std::vector<float> angles_for_curvature(points.size());
std::vector<float> distances_for_curvature(points.size());
for (int point_idx = 0; point_idx < int(points.size()); ++point_idx) {
for (size_t point_idx = 0; point_idx < points.size(); ++point_idx) {
ExtendedPoint &a = points[point_idx];
ExtendedPoint &prev = points[point_idx > 0 ? point_idx - 1 : point_idx];
size_t prev = prev_idx_modulo(point_idx, points.size());
size_t next = next_idx_modulo(point_idx, points.size());
int prev_point_idx = point_idx;
while (prev_point_idx > 0) {
prev_point_idx--;
if ((a.position - points[prev_point_idx].position).squaredNorm() > EPSILON) {
break;
}
int iter_limit = points.size();
while ((a.position - points[prev].position).squaredNorm() < 1 && iter_limit > 0) {
prev = prev_idx_modulo(prev, points.size());
iter_limit--;
}
int next_point_index = point_idx;
while (next_point_index < int(points.size()) - 1) {
next_point_index++;
if ((a.position - points[next_point_index].position).squaredNorm() > EPSILON) {
break;
}
while ((a.position - points[next].position).squaredNorm() < 1 && iter_limit > 0) {
next = next_idx_modulo(next, points.size());
iter_limit--;
}
distances_for_curvature[point_idx] = (prev.position - a.position).norm();
if (prev_point_idx != point_idx && next_point_index != point_idx) {
float alfa = angle(a.position - points[prev_point_idx].position, points[next_point_index].position - a.position);
angles_for_curvature[point_idx] = alfa;
} // else keep zero
distances_for_curvature[point_idx] = (points[prev].position - a.position).norm();
float alfa = angle(a.position - points[prev].position, points[next].position - a.position);
angles_for_curvature[point_idx] = alfa;
}
for (float window_size : {3.0f, 9.0f, 16.0f}) {
size_t tail_point = 0;
float tail_window_acc = 0;
float tail_angle_acc = 0;
if (std::accumulate(distances_for_curvature.begin(), distances_for_curvature.end(), 0) > EPSILON)
for (float window_size : {3.0f, 9.0f, 16.0f}) {
size_t tail_point = 0;
float tail_window_acc = 0;
float tail_angle_acc = 0;
size_t head_point = 0;
float head_window_acc = 0;
float head_angle_acc = 0;
size_t head_point = 0;
float head_window_acc = 0;
float head_angle_acc = 0;
for (int point_idx = 0; point_idx < int(points.size()); ++point_idx) {
if (point_idx > 0) {
tail_window_acc += distances_for_curvature[point_idx - 1];
tail_angle_acc += angles_for_curvature[point_idx - 1];
head_window_acc -= distances_for_curvature[point_idx - 1];
head_angle_acc -= angles_for_curvature[point_idx - 1];
}
while (tail_window_acc > window_size * 0.5 && int(tail_point) < point_idx) {
tail_window_acc -= distances_for_curvature[tail_point];
tail_angle_acc -= angles_for_curvature[tail_point];
tail_point++;
}
for (size_t point_idx = 0; point_idx < points.size(); ++point_idx) {
if (point_idx == 0) {
while (tail_window_acc < window_size * 0.5) {
tail_window_acc += distances_for_curvature[tail_point];
tail_angle_acc += angles_for_curvature[tail_point];
tail_point = prev_idx_modulo(tail_point, points.size());
}
}
while (tail_window_acc - distances_for_curvature[next_idx_modulo(tail_point, points.size())] > window_size * 0.5) {
tail_point = next_idx_modulo(tail_point, points.size());
tail_window_acc -= distances_for_curvature[tail_point];
tail_angle_acc -= angles_for_curvature[tail_point];
}
while (head_window_acc < window_size * 0.5 && int(head_point) < int(points.size()) - 1) {
head_window_acc += distances_for_curvature[head_point];
head_angle_acc += angles_for_curvature[head_point];
head_point++;
}
while (head_window_acc < window_size * 0.5) {
head_point = next_idx_modulo(head_point, points.size());
head_window_acc += distances_for_curvature[head_point];
head_angle_acc += angles_for_curvature[head_point];
}
float curvature = (tail_angle_acc + head_angle_acc) / (tail_window_acc + head_window_acc);
if (std::abs(curvature) > std::abs(points[point_idx].curvature)) {
points[point_idx].curvature = curvature;
float curvature = (tail_angle_acc + head_angle_acc) / window_size;
if (std::abs(curvature) > std::abs(points[point_idx].curvature)) {
points[point_idx].curvature = curvature;
}
tail_window_acc += distances_for_curvature[point_idx];
tail_angle_acc += angles_for_curvature[point_idx];
head_window_acc -= distances_for_curvature[point_idx];
head_angle_acc -= angles_for_curvature[point_idx];
}
}
}
return points;
}

View File

@@ -3610,7 +3610,8 @@ void GCodeProcessor::post_process()
while (rev_it != m_lines.rend() && rev_it->time > time_threshold_i && curr_cmd != cmd && curr_cmd != "G28" && curr_cmd != "G29") {
rev_it->line = line_replacer(rev_it->line);
++rev_it;
curr_cmd = GCodeReader::GCodeLine::extract_cmd(rev_it->line);
if (rev_it != m_lines.rend())
curr_cmd = GCodeReader::GCodeLine::extract_cmd(rev_it->line);
}
// we met the previous evenience of cmd, or a G28/G29 command. stop inserting lines

View File

@@ -16,7 +16,9 @@
// The standard Windows includes.
#define WIN32_LEAN_AND_MEAN
#ifndef NOMINMAX
#define NOMINMAX
#endif
#include <Windows.h>
#include <shellapi.h>

View File

@@ -169,6 +169,11 @@ ToolOrdering::ToolOrdering(const Print &print, unsigned int first_extruder, bool
this->fill_wipe_tower_partitions(print.config(), object_bottom_z, max_layer_height);
if (this->insert_wipe_tower_extruder()) {
// Now convert the 0-based list to 1-based again, because that is what reorder_extruder expects.
for (LayerTools& lt : m_layer_tools) {
for (auto& extruder : lt.extruders)
++extruder;
}
this->reorder_extruders(first_extruder);
this->fill_wipe_tower_partitions(print.config(), object_bottom_z, max_layer_height);
}
@@ -478,12 +483,7 @@ bool ToolOrdering::insert_wipe_tower_extruder()
sort_remove_duplicates(lt.extruders);
changed = true;
}
}
// Now convert the 0-based list to 1-based again.
for (LayerTools& lt : m_layer_tools) {
for (auto& extruder : lt.extruders)
++extruder;
}
}
}
return changed;
}

View File

@@ -516,7 +516,7 @@ WipeTower::ToolChangeResult WipeTower::construct_tcr(WipeTowerWriter& writer,
WipeTower::WipeTower(const PrintConfig& config, const std::vector<std::vector<float>>& wiping_matrix, size_t initial_tool) :
WipeTower::WipeTower(const PrintConfig& config, const PrintRegionConfig& default_region_config, const std::vector<std::vector<float>>& wiping_matrix, size_t initial_tool) :
m_semm(config.single_extruder_multi_material.value),
m_wipe_tower_pos(config.wipe_tower_x, config.wipe_tower_y),
m_wipe_tower_width(float(config.wipe_tower_width)),
@@ -530,6 +530,8 @@ WipeTower::WipeTower(const PrintConfig& config, const std::vector<std::vector<fl
m_no_sparse_layers(config.wipe_tower_no_sparse_layers),
m_gcode_flavor(config.gcode_flavor),
m_travel_speed(config.travel_speed),
m_infill_speed(default_region_config.infill_speed),
m_perimeter_speed(default_region_config.perimeter_speed),
m_current_tool(initial_tool),
wipe_volumes(wiping_matrix)
{
@@ -541,6 +543,13 @@ WipeTower::WipeTower(const PrintConfig& config, const std::vector<std::vector<fl
if (m_first_layer_speed == 0.f) // just to make sure autospeed doesn't break it.
m_first_layer_speed = default_speed / 2.f;
// Autospeed may be used...
if (m_infill_speed == 0.f)
m_infill_speed = 80.f;
if (m_perimeter_speed == 0.f)
m_perimeter_speed = 80.f;
// If this is a single extruder MM printer, we will use all the SE-specific config values.
// Otherwise, the defaults will be used to turn off the SE stuff.
if (m_semm) {
@@ -550,6 +559,7 @@ WipeTower::WipeTower(const PrintConfig& config, const std::vector<std::vector<fl
m_extra_loading_move = float(config.extra_loading_move);
m_set_extruder_trimpot = config.high_current_on_filament_swap;
}
// Calculate where the priming lines should be - very naive test not detecting parallelograms etc.
const std::vector<Vec2d>& bed_points = config.bed_shape.values;
BoundingBoxf bb(bed_points);
@@ -616,6 +626,24 @@ void WipeTower::set_extruder(size_t idx, const PrintConfig& config)
m_filpar[idx].ramming_step_multiplicator /= 100;
while (stream >> speed)
m_filpar[idx].ramming_speed.push_back(speed);
// ramming_speed now contains speeds to be used for every 0.25s piece of the ramming line.
// This allows to have the ramming flow variable. The 0.25s value is how it is saved in config
// and the same time step has to be used when the ramming is performed.
} else {
// We will use the same variables internally, but the correspondence to the configuration options will be different.
float vol = config.filament_multitool_ramming_volume.get_at(idx);
float flow = config.filament_multitool_ramming_flow.get_at(idx);
m_filpar[idx].multitool_ramming = config.filament_multitool_ramming.get_at(idx);
m_filpar[idx].ramming_line_width_multiplicator = 2.;
m_filpar[idx].ramming_step_multiplicator = 1.;
// Now the ramming speed vector. In this case it contains just one value (flow).
// The time is calculated and saved separately. This is here so that the MM ramming
// is not limited by the 0.25s granularity - it is not possible to create a SEMM-style
// ramming_speed vector that would respect both the volume and flow (because of
// rounding issues with small volumes and high flow).
m_filpar[idx].ramming_speed.push_back(flow);
m_filpar[idx].multitool_ramming_time = vol/flow;
}
m_used_filament_length.resize(std::max(m_used_filament_length.size(), idx + 1)); // makes sure that the vector is big enough so we don't have to check later
@@ -830,12 +858,17 @@ void WipeTower::toolchange_Unload(
float remaining = xr - xl ; // keeps track of distance to the next turnaround
float e_done = 0; // measures E move done from each segment
if (m_semm)
const bool do_ramming = m_semm || m_filpar[m_current_tool].multitool_ramming;
if (do_ramming) {
writer.travel(ramming_start_pos); // move to starting position
writer.disable_linear_advance();
}
else
writer.set_position(ramming_start_pos);
// if the ending point of the ram would end up in mid air, align it with the end of the wipe tower:
if (m_semm && (m_layer_info > m_plan.begin() && m_layer_info < m_plan.end() && (m_layer_info-1!=m_plan.begin() || !m_adhesion ))) {
if (do_ramming && (m_layer_info > m_plan.begin() && m_layer_info < m_plan.end() && (m_layer_info-1!=m_plan.begin() || !m_adhesion ))) {
// this is y of the center of previous sparse infill border
float sparse_beginning_y = 0.f;
@@ -863,16 +896,18 @@ void WipeTower::toolchange_Unload(
sum_of_depths += tch.required_depth;
}
}
writer.disable_linear_advance();
// now the ramming itself:
while (m_semm && i < m_filpar[m_current_tool].ramming_speed.size())
while (do_ramming && i < m_filpar[m_current_tool].ramming_speed.size())
{
const float x = volume_to_length(m_filpar[m_current_tool].ramming_speed[i] * 0.25f, line_width, m_layer_height);
const float e = m_filpar[m_current_tool].ramming_speed[i] * 0.25f / filament_area(); // transform volume per sec to E move;
const float dist = std::min(x - e_done, remaining); // distance to travel for either the next 0.25s, or to the next turnaround
const float actual_time = dist/x * 0.25f;
// The time step is different for SEMM ramming and the MM ramming. See comments in set_extruder() for details.
const float time_step = m_semm ? 0.25f : m_filpar[m_current_tool].multitool_ramming_time;
const float x = volume_to_length(m_filpar[m_current_tool].ramming_speed[i] * time_step, line_width, m_layer_height);
const float e = m_filpar[m_current_tool].ramming_speed[i] * time_step / filament_area(); // transform volume per sec to E move;
const float dist = std::min(x - e_done, remaining); // distance to travel for either the next time_step, or to the next turnaround
const float actual_time = dist/x * time_step;
writer.ram(writer.x(), writer.x() + (m_left_to_right ? 1.f : -1.f) * dist, 0.f, 0.f, e * (dist / x), dist / (actual_time / 60.f));
remaining -= dist;
@@ -944,7 +979,7 @@ void WipeTower::toolchange_Unload(
// this is to align ramming and future wiping extrusions, so the future y-steps can be uniform from the start:
// the perimeter_width will later be subtracted, it is there to not load while moving over just extruded material
Vec2f pos = Vec2f(end_of_ramming.x(), end_of_ramming.y() + (y_step/m_extra_spacing-m_perimeter_width) / 2.f + m_perimeter_width);
if (m_semm)
if (do_ramming)
writer.travel(pos, 2400.f);
else
writer.set_position(pos);
@@ -1031,10 +1066,11 @@ void WipeTower::toolchange_Wipe(
// the ordered volume, even if it means violating the box. This can later be removed and simply
// wipe until the end of the assigned area.
float x_to_wipe = volume_to_length(wipe_volume, m_perimeter_width, m_layer_height);
float dy = m_extra_spacing*m_perimeter_width;
float x_to_wipe = volume_to_length(wipe_volume, m_perimeter_width, m_layer_height) * (is_first_layer() ? m_extra_spacing : 1.f);
float dy = (is_first_layer() ? 1.f : m_extra_spacing) * m_perimeter_width; // Don't use the extra spacing for the first layer.
// All the calculations in all other places take the spacing into account for all the layers.
const float target_speed = is_first_layer() ? m_first_layer_speed * 60.f : 4800.f;
const float target_speed = is_first_layer() ? m_first_layer_speed * 60.f : m_infill_speed * 60.f;
float wipe_speed = 0.33f * target_speed;
// if there is less than 2.5*m_perimeter_width to the edge, advance straightaway (there is likely a blob anyway)
@@ -1103,7 +1139,7 @@ WipeTower::ToolChangeResult WipeTower::finish_layer()
// Slow down on the 1st layer.
bool first_layer = is_first_layer();
float feedrate = first_layer ? m_first_layer_speed * 60.f : 2900.f;
float feedrate = first_layer ? m_first_layer_speed * 60.f : m_infill_speed * 60.f;
float current_depth = m_layer_info->depth - m_layer_info->toolchanges_depth();
box_coordinates fill_box(Vec2f(m_perimeter_width, m_layer_info->depth-(current_depth-m_perimeter_width)),
m_wipe_tower_width - 2 * m_perimeter_width, current_depth-m_perimeter_width);
@@ -1203,7 +1239,7 @@ WipeTower::ToolChangeResult WipeTower::finish_layer()
// First generate vector of annotated point which form the boundary.
std::vector<std::pair<Vec2f, Type>> pts = {{wt_box.ru, Corner}};
if (double alpha_start = std::asin((0.5*w)/r); ! std::isnan(alpha_start) && r > 0.5*w+0.01) {
for (double alpha = alpha_start; alpha < M_PI-alpha_start+0.001; alpha+=(M_PI-2*alpha_start) / 20.)
for (double alpha = alpha_start; alpha < M_PI-alpha_start+0.001; alpha+=(M_PI-2*alpha_start) / 40.)
pts.emplace_back(Vec2f(center.x() + r*std::cos(alpha)/support_scale, center.y() + r*std::sin(alpha)), alpha == alpha_start ? ArcStart : Arc);
pts.back().second = ArcEnd;
}
@@ -1285,6 +1321,8 @@ WipeTower::ToolChangeResult WipeTower::finish_layer()
return poly;
};
feedrate = first_layer ? m_first_layer_speed * 60.f : m_perimeter_speed * 60.f;
// outer contour (always)
bool infill_cone = first_layer && m_wipe_tower_width > 2*spacing && m_wipe_tower_depth > 2*spacing;
Polygon poly = supported_rectangle(wt_box, feedrate, infill_cone);

View File

@@ -14,6 +14,7 @@ namespace Slic3r
class WipeTowerWriter;
class PrintConfig;
class PrintRegionConfig;
enum GCodeFlavor : unsigned char;
@@ -129,7 +130,10 @@ public:
// y -- y coordinates of wipe tower in mm ( left bottom corner )
// width -- width of wipe tower in mm ( default 60 mm - leave as it is )
// wipe_area -- space available for one toolchange in mm
WipeTower(const PrintConfig& config, const std::vector<std::vector<float>>& wiping_matrix, size_t initial_tool);
WipeTower(const PrintConfig& config,
const PrintRegionConfig& default_region_config,
const std::vector<std::vector<float>>& wiping_matrix,
size_t initial_tool);
// Set the extruder properties.
@@ -237,6 +241,8 @@ public:
std::vector<float> ramming_speed;
float nozzle_diameter;
float filament_area;
bool multitool_ramming;
float multitool_ramming_time = 0.f;
};
private:
@@ -269,6 +275,8 @@ private:
size_t m_max_color_changes = 0; // Maximum number of color changes per layer.
int m_old_temperature = -1; // To keep track of what was the last temp that we set (so we don't issue the command when not neccessary)
float m_travel_speed = 0.f;
float m_infill_speed = 0.f;
float m_perimeter_speed = 0.f;
float m_first_layer_speed = 0.f;
size_t m_first_layer_idx = size_t(-1);