ENH: wipe tower support nozzle change
jira: none Change-Id: I398a508cbc8d02644b60e504405392254329ef10
This commit is contained in:
parent
9801a10f7f
commit
8b2a94ed5f
|
@ -288,6 +288,57 @@ static std::vector<Vec2d> get_path_of_change_filament(const Print& print)
|
|||
: gcodegen.config().nozzle_temperature.get_at(gcodegen.writer().filament()->id());
|
||||
}
|
||||
|
||||
std::string transform_gcode(const std::string &gcode, Vec2f pos, const Vec2f &translation, float angle)
|
||||
{
|
||||
Vec2f extruder_offset(0, 0);
|
||||
std::istringstream gcode_str(gcode);
|
||||
std::string gcode_out;
|
||||
std::string line;
|
||||
Vec2f transformed_pos = pos;
|
||||
Vec2f old_pos(-1000.1f, -1000.1f);
|
||||
|
||||
while (gcode_str) {
|
||||
std::getline(gcode_str, line); // we read the gcode line by line
|
||||
|
||||
if (line.find("G1 ") == 0) {
|
||||
bool never_skip = false;
|
||||
auto it = line.find(WipeTower::never_skip_tag());
|
||||
if (it != std::string::npos) {
|
||||
// remove the tag and remember we saw it
|
||||
never_skip = true;
|
||||
line.erase(it, it + WipeTower::never_skip_tag().size());
|
||||
}
|
||||
std::ostringstream line_out;
|
||||
std::istringstream line_str(line);
|
||||
line_str >> std::noskipws; // don't skip whitespace
|
||||
char ch = 0;
|
||||
while (line_str >> ch) {
|
||||
if (ch == 'X' || ch == 'Y')
|
||||
line_str >> (ch == 'X' ? pos.x() : pos.y());
|
||||
else
|
||||
line_out << ch;
|
||||
}
|
||||
|
||||
transformed_pos = Eigen::Rotation2Df(angle) * pos + translation;
|
||||
|
||||
if (transformed_pos != old_pos || never_skip) {
|
||||
line = line_out.str();
|
||||
std::ostringstream oss;
|
||||
oss << std::fixed << std::setprecision(3) << "G1 ";
|
||||
if (transformed_pos.x() != old_pos.x() || never_skip) oss << " X" << transformed_pos.x() - extruder_offset.x();
|
||||
if (transformed_pos.y() != old_pos.y() || never_skip) oss << " Y" << transformed_pos.y() - extruder_offset.y();
|
||||
oss << " ";
|
||||
line.replace(line.find("G1 "), 3, oss.str());
|
||||
old_pos = transformed_pos;
|
||||
}
|
||||
}
|
||||
|
||||
gcode_out += line + "\n";
|
||||
}
|
||||
return gcode_out;
|
||||
}
|
||||
|
||||
|
||||
std::string Wipe::wipe(GCode& gcodegen, bool toolchange, bool is_last)
|
||||
{
|
||||
std::string gcode;
|
||||
|
@ -441,6 +492,12 @@ static std::vector<Vec2d> get_path_of_change_filament(const Print& print)
|
|||
check_add_eol(end_filament_gcode_str);
|
||||
}
|
||||
}
|
||||
|
||||
std::string nozzle_change_gcode_trans;
|
||||
if (!tcr.nozzle_change_result.gcode.empty()) {
|
||||
nozzle_change_gcode_trans = transform_gcode(tcr.nozzle_change_result.gcode, tcr.start_pos, wipe_tower_offset, wipe_tower_rotation);
|
||||
}
|
||||
|
||||
//BBS: increase toolchange count
|
||||
gcodegen.m_toolchange_count++;
|
||||
|
||||
|
@ -532,6 +589,13 @@ static std::vector<Vec2d> get_path_of_change_filament(const Print& print)
|
|||
}
|
||||
}
|
||||
toolchange_gcode_str = gcodegen.placeholder_parser_process("change_filament_gcode", change_filament_gcode, new_filament_id, &config);
|
||||
|
||||
std::string target_str = ";nozzle_change_gcode";
|
||||
size_t pos = toolchange_gcode_str.find(target_str);
|
||||
if (pos != std::string::npos) {
|
||||
toolchange_gcode_str.replace(pos, target_str.length(), nozzle_change_gcode_trans);
|
||||
}
|
||||
|
||||
check_add_eol(toolchange_gcode_str);
|
||||
|
||||
// retract before toolchange
|
||||
|
|
|
@ -586,6 +586,7 @@ WipeTower::ToolChangeResult WipeTower::construct_tcr(WipeTowerWriter& writer,
|
|||
result.extrusions = std::move(writer.extrusions());
|
||||
result.wipe_path = std::move(writer.wipe_path());
|
||||
result.is_finish_first = is_finish;
|
||||
result.nozzle_change_result = m_nozzle_change_result;
|
||||
// BBS
|
||||
result.purge_volume = purge_volume;
|
||||
return result;
|
||||
|
@ -614,7 +615,8 @@ WipeTower::WipeTower(const PrintConfig& config, int plate_idx, Vec3d plate_origi
|
|||
m_current_tool(initial_tool),
|
||||
//wipe_volumes(flush_matrix)
|
||||
m_wipe_volume(prime_volume),
|
||||
m_enable_timelapse_print(config.timelapse_type.value == TimelapseType::tlSmooth)
|
||||
m_enable_timelapse_print(config.timelapse_type.value == TimelapseType::tlSmooth),
|
||||
m_nozzle_change_length(config.extruder_change_length.get_at(0))
|
||||
{
|
||||
// Read absolute value of first layer speed, if given as percentage,
|
||||
// it is taken over following default. Speeds from config are not
|
||||
|
@ -729,14 +731,49 @@ std::vector<WipeTower::ToolChangeResult> WipeTower::prime(
|
|||
return std::vector<ToolChangeResult>();
|
||||
}
|
||||
|
||||
Vec2f WipeTower::get_next_pos(const WipeTower::box_coordinates &cleaning_box, float wipe_length)
|
||||
{
|
||||
const float &xl = cleaning_box.ld.x();
|
||||
const float &xr = cleaning_box.rd.x();
|
||||
int line_count = wipe_length / (xr - xl);
|
||||
|
||||
float dy = m_layer_info->extra_spacing * m_perimeter_width;
|
||||
float y_offset = float(line_count) * dy;
|
||||
const Vec2f pos_offset = Vec2f(0.f, m_depth_traversed);
|
||||
|
||||
Vec2f res;
|
||||
int index = m_cur_layer_id % 4;
|
||||
switch (index % 4) {
|
||||
case 0:
|
||||
res = cleaning_box.ld + pos_offset;
|
||||
break;
|
||||
case 1:
|
||||
res = cleaning_box.rd + pos_offset + Vec2f(0, y_offset);
|
||||
break;
|
||||
case 2:
|
||||
res = cleaning_box.rd + pos_offset;
|
||||
break;
|
||||
case 3:
|
||||
res = cleaning_box.ld + pos_offset + Vec2f(0, y_offset);
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
WipeTower::ToolChangeResult WipeTower::tool_change(size_t tool, bool extrude_perimeter, bool first_toolchange_to_nonsoluble)
|
||||
{
|
||||
m_nozzle_change_result.gcode.clear();
|
||||
if (!m_filament_map.empty() && tool < m_filament_map.size() && m_filament_map[m_current_tool] != m_filament_map[tool]) {
|
||||
m_nozzle_change_result = nozzle_change(m_current_tool, tool);
|
||||
}
|
||||
|
||||
size_t old_tool = m_current_tool;
|
||||
|
||||
float wipe_depth = 0.f;
|
||||
float wipe_length = 0.f;
|
||||
float purge_volume = 0.f;
|
||||
|
||||
float nozzle_change_depth = 0.f;
|
||||
// Finds this toolchange info
|
||||
if (tool != (unsigned int)(-1))
|
||||
{
|
||||
|
@ -745,6 +782,7 @@ WipeTower::ToolChangeResult WipeTower::tool_change(size_t tool, bool extrude_per
|
|||
wipe_length = b.wipe_length;
|
||||
wipe_depth = b.required_depth;
|
||||
purge_volume = b.purge_volume;
|
||||
nozzle_change_depth = b.nozzle_change_depth;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -775,7 +813,7 @@ WipeTower::ToolChangeResult WipeTower::tool_change(size_t tool, bool extrude_per
|
|||
writer.speed_override_backup();
|
||||
writer.speed_override(100);
|
||||
|
||||
Vec2f initial_position = cleaning_box.ld + Vec2f(0.f, m_depth_traversed);
|
||||
Vec2f initial_position = get_next_pos(cleaning_box, wipe_length);
|
||||
writer.set_initial_position(initial_position, m_wipe_tower_width, m_wipe_tower_depth, m_internal_rotation);
|
||||
|
||||
// Increase the extruder driver current to allow fast ramming.
|
||||
|
@ -792,9 +830,17 @@ WipeTower::ToolChangeResult WipeTower::tool_change(size_t tool, bool extrude_per
|
|||
toolchange_Load(writer, cleaning_box);
|
||||
// BBS
|
||||
//writer.travel(writer.x(), writer.y()-m_perimeter_width); // cooling and loading were done a bit down the road
|
||||
|
||||
// ensure travel to initial_positoin
|
||||
{
|
||||
writer.travel(initial_position - Vec2f(0.5, 0.5));
|
||||
writer.travel(initial_position);
|
||||
}
|
||||
toolchange_Wipe(writer, cleaning_box, wipe_length); // Wipe the newly loaded filament until the end of the assigned wipe area.
|
||||
|
||||
if (extrude_perimeter) {
|
||||
box_coordinates wt_box(Vec2f(0.f, (m_current_shape == SHAPE_REVERSED) ? m_layer_info->toolchanges_depth() - m_layer_info->depth : 0.f),
|
||||
m_wipe_tower_width, m_layer_info->depth + m_perimeter_width);
|
||||
box_coordinates wt_box(Vec2f(0.f, (m_current_shape == SHAPE_REVERSED) ? m_layer_info->toolchanges_depth() - m_layer_info->depth : 0.f), m_wipe_tower_width,
|
||||
m_layer_info->depth + m_perimeter_width);
|
||||
// align the perimeter
|
||||
|
||||
Vec2f pos = initial_position;
|
||||
|
@ -829,7 +875,7 @@ WipeTower::ToolChangeResult WipeTower::tool_change(size_t tool, bool extrude_per
|
|||
} else
|
||||
toolchange_Unload(writer, cleaning_box, m_filpar[m_current_tool].material, m_filpar[m_current_tool].nozzle_temperature);
|
||||
|
||||
m_depth_traversed += wipe_depth;
|
||||
m_depth_traversed += (wipe_depth - nozzle_change_depth);
|
||||
|
||||
//BBS
|
||||
//if (m_set_extruder_trimpot)
|
||||
|
@ -849,6 +895,114 @@ WipeTower::ToolChangeResult WipeTower::tool_change(size_t tool, bool extrude_per
|
|||
return construct_tcr(writer, false, old_tool, false, purge_volume);
|
||||
}
|
||||
|
||||
WipeTower::NozzleChangeResult WipeTower::nozzle_change(int old_filament_id, int new_filament_id)
|
||||
{
|
||||
float wipe_depth = 0.f;
|
||||
float wipe_length = 0.f;
|
||||
float purge_volume = 0.f;
|
||||
int nozzle_change_line_count = 0;
|
||||
|
||||
// Finds this toolchange info
|
||||
if (new_filament_id != (unsigned int) (-1)) {
|
||||
for (const auto &b : m_layer_info->tool_changes)
|
||||
if (b.new_tool == new_filament_id) {
|
||||
wipe_length = b.wipe_length;
|
||||
wipe_depth = b.required_depth;
|
||||
purge_volume = b.purge_volume;
|
||||
nozzle_change_line_count = (b.nozzle_change_depth + WT_EPSILON) / m_perimeter_width;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// Otherwise we are going to Unload only. And m_layer_info would be invalid.
|
||||
}
|
||||
|
||||
float nozzle_change_speed = 60.0f * m_filpar[m_current_tool].max_e_speed / m_extrusion_flow;
|
||||
|
||||
WipeTowerWriter writer(m_layer_height, m_perimeter_width, m_gcode_flavor, m_filpar);
|
||||
writer.set_extrusion_flow(m_extrusion_flow)
|
||||
.set_z(m_z_pos)
|
||||
.set_initial_tool(m_current_tool)
|
||||
.set_extrusion_flow(m_extrusion_flow)
|
||||
.set_y_shift(m_y_shift + (new_filament_id != (unsigned int) (-1) && (m_current_shape == SHAPE_REVERSED) ? m_layer_info->depth - m_layer_info->toolchanges_depth() : 0.f))
|
||||
.append("; Nozzle change start\n");
|
||||
|
||||
writer.speed_override_backup();
|
||||
writer.speed_override(100);
|
||||
|
||||
box_coordinates cleaning_box(Vec2f(m_perimeter_width, m_perimeter_width),
|
||||
m_wipe_tower_width - 2 * m_perimeter_width,
|
||||
(new_filament_id != (unsigned int) (-1) ? wipe_depth + m_depth_traversed - m_perimeter_width : m_wipe_tower_depth - m_perimeter_width));
|
||||
|
||||
Vec2f initial_position = cleaning_box.ld + Vec2f(0.f, m_depth_traversed);
|
||||
writer.travel(initial_position, 30000);
|
||||
writer.append("G1 Z" + std::to_string(m_z_pos) + "\n");
|
||||
writer.append("G1 E2 F1800\n");
|
||||
writer.set_initial_position(initial_position, m_wipe_tower_width, m_wipe_tower_depth, m_internal_rotation);
|
||||
|
||||
const float &xl = cleaning_box.ld.x();
|
||||
const float &xr = cleaning_box.rd.x();
|
||||
|
||||
float dy = m_layer_info->extra_spacing * m_perimeter_width;
|
||||
|
||||
const float target_speed = 4800.f;
|
||||
float wipe_speed = std::max(target_speed, nozzle_change_speed);
|
||||
|
||||
float start_y = writer.y();
|
||||
|
||||
m_left_to_right = true;
|
||||
|
||||
bool need_change_flow = false;
|
||||
// now the wiping itself:
|
||||
for (int i = 0; true; ++i) {
|
||||
if (m_left_to_right)
|
||||
writer.extrude(xr + 0.25f * m_perimeter_width, writer.y(), wipe_speed);
|
||||
else
|
||||
writer.extrude(xl - 0.25f * m_perimeter_width, writer.y(), wipe_speed);
|
||||
|
||||
if (writer.y() - float(EPSILON) > cleaning_box.lu.y())
|
||||
break; // in case next line would not fit
|
||||
|
||||
if (i == nozzle_change_line_count - 1)
|
||||
break;
|
||||
|
||||
// stepping to the next line:
|
||||
writer.extrude(writer.x(), writer.y() + dy);
|
||||
m_left_to_right = !m_left_to_right;
|
||||
}
|
||||
|
||||
writer.set_extrusion_flow(m_extrusion_flow); // Reset the extrusion flow.
|
||||
|
||||
m_depth_traversed += (nozzle_change_line_count) * dy;
|
||||
|
||||
auto float_to_string_with_precision = [](float value, int precision) {
|
||||
std::ostringstream out;
|
||||
out << std::fixed << std::setprecision(precision) << value;
|
||||
return out.str();
|
||||
};
|
||||
|
||||
float wipe_distance = 2;
|
||||
Vec2f wipe_pos = writer.pos();
|
||||
if (m_left_to_right) {
|
||||
wipe_pos.x() -= wipe_distance;
|
||||
}
|
||||
else {
|
||||
wipe_pos.x() += wipe_distance;
|
||||
}
|
||||
writer.append("; WIPE_START\n");
|
||||
writer.extrude_explicit(wipe_pos, -2);
|
||||
writer.append("; WIPE_END\n");
|
||||
|
||||
std::string lift_gcode = "G2 Z" + float_to_string_with_precision(m_z_pos + 0.4, 3) + " I0.86 J0.86 P1 F10000\n";
|
||||
writer.append(lift_gcode);
|
||||
|
||||
writer.append("; Nozzle change end\n");
|
||||
|
||||
NozzleChangeResult result;
|
||||
result.start_pos = writer.start_pos_rotated();
|
||||
result.end_pos = writer.pos();
|
||||
result.gcode = std::move(writer.gcode());
|
||||
return result;
|
||||
}
|
||||
|
||||
// Ram the hot material out of the melt zone, retract the filament into the cooling tubes and let it cool.
|
||||
void WipeTower::toolchange_Unload(
|
||||
|
@ -1094,7 +1248,8 @@ void WipeTower::toolchange_Wipe(
|
|||
}
|
||||
#endif
|
||||
|
||||
m_left_to_right = true;
|
||||
m_left_to_right = ((m_cur_layer_id + 3) % 4 >= 2);
|
||||
bool is_from_up = (m_cur_layer_id % 2 == 1);
|
||||
|
||||
// BBS: do not need to move dy
|
||||
#if 0
|
||||
|
@ -1130,9 +1285,12 @@ void WipeTower::toolchange_Wipe(
|
|||
writer.append(";" + GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Height) + std::to_string(m_layer_height) + "\n");
|
||||
}
|
||||
|
||||
if (writer.y() - float(EPSILON) > cleaning_box.lu.y())
|
||||
if (!is_from_up && (writer.y() - float(EPSILON) > cleaning_box.lu.y()))
|
||||
break; // in case next line would not fit
|
||||
|
||||
if (is_from_up && (writer.y() + float(EPSILON) < cleaning_box.ld.y()))
|
||||
break;
|
||||
|
||||
x_to_wipe -= (xr - xl);
|
||||
if (x_to_wipe < WT_EPSILON) {
|
||||
// BBS: Delete some unnecessary travel
|
||||
|
@ -1140,7 +1298,11 @@ void WipeTower::toolchange_Wipe(
|
|||
break;
|
||||
}
|
||||
// stepping to the next line:
|
||||
writer.extrude(writer.x(), writer.y() + dy);
|
||||
if (is_from_up)
|
||||
writer.extrude(writer.x(), writer.y() - dy);
|
||||
else
|
||||
writer.extrude(writer.x(), writer.y() + dy);
|
||||
|
||||
m_left_to_right = !m_left_to_right;
|
||||
}
|
||||
|
||||
|
@ -1208,7 +1370,6 @@ WipeTower::ToolChangeResult WipeTower::finish_layer(bool extrude_perimeter, bool
|
|||
bool first_layer = is_first_layer();
|
||||
// BBS: speed up perimeter speed to 90mm/s for non-first layer
|
||||
float feedrate = first_layer ? std::min(m_first_layer_speed * 60.f, 5400.f) : std::min(60.0f * m_filpar[m_current_tool].max_e_speed / m_extrusion_flow, 5400.f);
|
||||
writer.feedrate(feedrate);
|
||||
float fill_box_y = m_layer_info->toolchanges_depth() + m_perimeter_width;
|
||||
box_coordinates fill_box(Vec2f(m_perimeter_width, fill_box_y),
|
||||
m_wipe_tower_width - 2 * m_perimeter_width, m_layer_info->depth - fill_box_y);
|
||||
|
@ -1319,7 +1480,7 @@ WipeTower::ToolChangeResult WipeTower::finish_layer(bool extrude_perimeter, bool
|
|||
box_coordinates box = wt_box;
|
||||
for (size_t i = 0; i < loops_num; ++i) {
|
||||
box.expand(spacing);
|
||||
writer.rectangle(box);
|
||||
writer.rectangle(box, feedrate);
|
||||
}
|
||||
|
||||
if (first_layer) {
|
||||
|
@ -1399,7 +1560,17 @@ void WipeTower::plan_toolchange(float z_par, float layer_height_par, unsigned in
|
|||
depth += std::ceil(length_to_extrude / width) * m_perimeter_width;
|
||||
//depth *= m_extra_spacing;
|
||||
|
||||
m_plan.back().tool_changes.push_back(WipeTowerInfo::ToolChange(old_tool, new_tool, depth, 0.f, 0.f, wipe_volume, length_to_extrude, purge_volume));
|
||||
float nozzle_change_depth = 0;
|
||||
if (!m_filament_map.empty() && m_filament_map[old_tool] != m_filament_map[new_tool]) {
|
||||
double e_flow = extrusion_flow(0.2);
|
||||
double length = m_nozzle_change_length / e_flow;
|
||||
int nozzle_change_line_count = length / (m_wipe_tower_width - m_perimeter_width) + 1;
|
||||
nozzle_change_depth = nozzle_change_line_count * m_perimeter_width;
|
||||
depth += nozzle_change_depth;
|
||||
}
|
||||
WipeTowerInfo::ToolChange tool_change = WipeTowerInfo::ToolChange(old_tool, new_tool, depth, 0.f, 0.f, wipe_volume, length_to_extrude, purge_volume);
|
||||
tool_change.nozzle_change_depth = nozzle_change_depth;
|
||||
m_plan.back().tool_changes.push_back(tool_change);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1467,6 +1638,12 @@ void WipeTower::plan_tower()
|
|||
x_to_wipe_new = std::max(x_to_wipe_new, x_to_wipe);
|
||||
|
||||
int line_count = std::ceil((x_to_wipe_new - WT_EPSILON) / line_len);
|
||||
|
||||
{ // nozzle change length
|
||||
int nozzle_change_line_count = (toolchange.nozzle_change_depth + WT_EPSILON) / m_perimeter_width;
|
||||
line_count += nozzle_change_line_count;
|
||||
}
|
||||
|
||||
toolchange.required_depth = line_count * m_perimeter_width;
|
||||
toolchange.wipe_volume = x_to_wipe_new / x_to_wipe * toolchange.wipe_volume;
|
||||
toolchange.wipe_length = x_to_wipe_new;
|
||||
|
@ -1490,7 +1667,7 @@ void WipeTower::plan_tower()
|
|||
float max_depth_for_all = 0;
|
||||
for (int layer_index = int(m_plan.size()) - 1; layer_index >= 0; --layer_index)
|
||||
{
|
||||
float this_layer_depth = std::max(m_plan[layer_index].depth, m_plan[layer_index].toolchanges_depth());
|
||||
float this_layer_depth = std::max(m_plan[layer_index].depth, m_plan[layer_index].toolchanges_depth());
|
||||
if (m_enable_timelapse_print && this_layer_depth < EPSILON)
|
||||
this_layer_depth = min_wipe_tower_depth;
|
||||
|
||||
|
@ -1615,6 +1792,7 @@ void WipeTower::generate(std::vector<std::vector<WipeTower::ToolChangeResult>> &
|
|||
m_old_temperature = -1; // reset last temperature written in the gcode
|
||||
int index = 0;
|
||||
std::vector<WipeTower::ToolChangeResult> layer_result;
|
||||
int index = 0;
|
||||
for (auto layer : m_plan)
|
||||
{
|
||||
m_cur_layer_id = index++;
|
||||
|
|
|
@ -17,7 +17,6 @@ class PrintConfig;
|
|||
enum GCodeFlavor : unsigned char;
|
||||
|
||||
|
||||
|
||||
class WipeTower
|
||||
{
|
||||
public:
|
||||
|
@ -38,6 +37,16 @@ public:
|
|||
unsigned int tool;
|
||||
};
|
||||
|
||||
struct NozzleChangeResult
|
||||
{
|
||||
std::string gcode;
|
||||
|
||||
Vec2f start_pos;
|
||||
Vec2f end_pos;
|
||||
|
||||
std::vector<Vec2f> wipe_path;
|
||||
};
|
||||
|
||||
struct ToolChangeResult
|
||||
{
|
||||
// Print heigh of this tool change.
|
||||
|
@ -81,6 +90,8 @@ public:
|
|||
// executing the gcode finish_layer_tcr.
|
||||
bool is_finish_first = false;
|
||||
|
||||
NozzleChangeResult nozzle_change_result;
|
||||
|
||||
// Sum the total length of the extrusion.
|
||||
float total_extrusion_length_in_plane() {
|
||||
float e_length = 0.f;
|
||||
|
@ -190,7 +201,7 @@ public:
|
|||
m_num_tool_changes = 0;
|
||||
} else
|
||||
++ m_num_layer_changes;
|
||||
|
||||
|
||||
// Calculate extrusion flow from desired line width, nozzle diameter, filament diameter and layer_height:
|
||||
m_extrusion_flow = extrusion_flow(layer_height);
|
||||
|
||||
|
@ -209,7 +220,7 @@ public:
|
|||
// Returns gcode to prime the nozzles at the front edge of the print bed.
|
||||
std::vector<ToolChangeResult> prime(
|
||||
// print_z of the first layer.
|
||||
float initial_layer_print_height,
|
||||
float initial_layer_print_height,
|
||||
// Extruder indices, in the order to be primed. The last extruder will later print the wipe tower brim, print brim and the object.
|
||||
const std::vector<unsigned int> &tools,
|
||||
// If true, the last priming are will be the same as the other priming areas, and the rest of the wipe will be performed inside the wipe tower.
|
||||
|
@ -221,6 +232,8 @@ public:
|
|||
// BBS
|
||||
ToolChangeResult tool_change(size_t new_tool, bool extrude_perimeter = false, bool first_toolchange_to_nonsoluble = false);
|
||||
|
||||
NozzleChangeResult nozzle_change(int old_filament_id, int new_filament_id);
|
||||
|
||||
// Fill the unfilled space with a sparse infill.
|
||||
// Call this method only if layer_finished() is false.
|
||||
ToolChangeResult finish_layer(bool extruder_perimeter = true, bool extruder_fill = true);
|
||||
|
@ -244,6 +257,8 @@ public:
|
|||
std::vector<float> get_used_filament() const { return m_used_filament_length; }
|
||||
int get_number_of_toolchanges() const { return m_num_tool_changes; }
|
||||
|
||||
void set_filament_map(const std::vector<int> &filament_map) { m_filament_map = filament_map; }
|
||||
|
||||
struct FilamentParameters {
|
||||
std::string material = "PLA";
|
||||
bool is_soluble = false;
|
||||
|
@ -300,7 +315,12 @@ private:
|
|||
float m_travel_speed = 0.f;
|
||||
float m_first_layer_speed = 0.f;
|
||||
size_t m_first_layer_idx = size_t(-1);
|
||||
size_t m_cur_layer_id;
|
||||
|
||||
double m_nozzle_change_length = 10;
|
||||
size_t m_cur_layer_id;
|
||||
NozzleChangeResult m_nozzle_change_result;
|
||||
std::vector<int> m_filament_map;
|
||||
|
||||
// G-code generator parameters.
|
||||
// BBS: remove useless config
|
||||
//float m_cooling_tube_retraction = 0.f;
|
||||
|
@ -360,6 +380,8 @@ private:
|
|||
// Goes through m_plan and recalculates depths and width of the WT to make it exactly square - experimental
|
||||
void make_wipe_tower_square();
|
||||
|
||||
Vec2f get_next_pos(const WipeTower::box_coordinates &cleaning_box, float wipe_length);
|
||||
|
||||
// Goes through m_plan, calculates border and finish_layer extrusions and subtracts them from last wipe
|
||||
void save_on_last_wipe();
|
||||
|
||||
|
@ -377,6 +399,7 @@ private:
|
|||
float first_wipe_line;
|
||||
float wipe_volume;
|
||||
float wipe_length;
|
||||
float nozzle_change_depth{0};
|
||||
// BBS
|
||||
float purge_volume;
|
||||
ToolChange(size_t old, size_t newtool, float depth=0.f, float ramming_depth=0.f, float fwl=0.f, float wv=0.f, float wl = 0, float pv = 0)
|
||||
|
@ -409,7 +432,7 @@ private:
|
|||
|
||||
void toolchange_Unload(
|
||||
WipeTowerWriter &writer,
|
||||
const box_coordinates &cleaning_box,
|
||||
const box_coordinates &cleaning_box,
|
||||
const std::string& current_material,
|
||||
const int new_temperature);
|
||||
|
||||
|
@ -417,11 +440,11 @@ private:
|
|||
WipeTowerWriter &writer,
|
||||
const size_t new_tool,
|
||||
const std::string& new_material);
|
||||
|
||||
|
||||
void toolchange_Load(
|
||||
WipeTowerWriter &writer,
|
||||
const box_coordinates &cleaning_box);
|
||||
|
||||
|
||||
void toolchange_Wipe(
|
||||
WipeTowerWriter &writer,
|
||||
const box_coordinates &cleaning_box,
|
||||
|
@ -433,4 +456,4 @@ private:
|
|||
|
||||
} // namespace Slic3r
|
||||
|
||||
#endif // WipeTowerPrusaMM_hpp_
|
||||
#endif // WipeTowerPrusaMM_hpp_
|
||||
|
|
|
@ -952,7 +952,7 @@ static std::vector<std::string> s_Preset_printer_options {
|
|||
// BBS
|
||||
"scan_first_layer", "machine_load_filament_time", "machine_unload_filament_time", "machine_pause_gcode", "template_custom_gcode",
|
||||
"nozzle_type","auxiliary_fan", "nozzle_volume","upward_compatible_machine", "z_hop_types","support_chamber_temp_control","support_air_filtration","printer_structure","thumbnail_size",
|
||||
"best_object_pos","head_wrap_detect_zone","printer_notes",
|
||||
"best_object_pos","extruder_change_length","head_wrap_detect_zone","printer_notes",
|
||||
"enable_long_retraction_when_cut","long_retractions_when_cut","retraction_distances_when_cut",
|
||||
//OrcaSlicer
|
||||
"host_type", "print_host", "printhost_apikey",
|
||||
|
|
|
@ -2456,6 +2456,7 @@ void Print::_make_wipe_tower()
|
|||
WipeTower wipe_tower(m_config, m_plate_index, m_origin, m_config.prime_volume, m_wipe_tower_data.tool_ordering.first_extruder(),
|
||||
m_wipe_tower_data.tool_ordering.empty() ? 0.f : m_wipe_tower_data.tool_ordering.back().print_z);
|
||||
|
||||
wipe_tower.set_filament_map(this->get_filament_maps());
|
||||
// Set the extruder & material properties at the wipe tower object.
|
||||
for (size_t i = 0; i < number_of_extruders; ++ i)
|
||||
wipe_tower.set_extruder(i, m_config);
|
||||
|
|
|
@ -3087,6 +3087,14 @@ void PrintConfigDef::init_fff_params()
|
|||
def->set_default_value(new ConfigOptionStrings { "Direct Drive Normal" });
|
||||
def->cli = ConfigOptionDef::nocli;
|
||||
|
||||
def = this->add("extruder_change_length", coFloats);
|
||||
def->label = L("Extruder change length");
|
||||
def->tooltip = L("Extruder change length");
|
||||
def->sidetext = L("mm");
|
||||
def->min = 0;
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionFloats{10});
|
||||
|
||||
def = this->add("extruder_ams_count", coStrings);
|
||||
def->label = "Extruder ams count";
|
||||
def->tooltip = "Ams counts of per extruder";
|
||||
|
|
|
@ -1054,6 +1054,7 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE(
|
|||
((ConfigOptionBool, reduce_crossing_wall))
|
||||
((ConfigOptionFloatOrPercent, max_travel_detour_distance))
|
||||
((ConfigOptionPoints, printable_area))
|
||||
((ConfigOptionFloats, extruder_change_length))
|
||||
//BBS: add bed_exclude_area
|
||||
((ConfigOptionPoints, bed_exclude_area))
|
||||
((ConfigOptionPoints, head_wrap_detect_zone))
|
||||
|
|
|
@ -3052,7 +3052,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
|
|||
"brim_width", "wall_loops", "wall_filament", "sparse_infill_density", "sparse_infill_filament", "top_shell_layers",
|
||||
"enable_support", "support_filament", "support_interface_filament",
|
||||
"support_top_z_distance", "support_bottom_z_distance", "raft_layers",
|
||||
"best_object_pos"
|
||||
"best_object_pos", "extruder_change_length"
|
||||
}))
|
||||
, sidebar(new Sidebar(q))
|
||||
, notification_manager(std::make_unique<NotificationManager>(q))
|
||||
|
|
|
@ -3546,6 +3546,8 @@ void TabPrinter::build_fff()
|
|||
optgroup->append_single_option_line("printable_height");
|
||||
optgroup->append_single_option_line("nozzle_volume");
|
||||
optgroup->append_single_option_line("best_object_pos");
|
||||
// todo: for multi_extruder test
|
||||
optgroup->append_single_option_line("extruder_change_length");
|
||||
// BBS
|
||||
#if 0
|
||||
//optgroup->append_single_option_line("z_offset");
|
||||
|
|
Loading…
Reference in New Issue