QoL: improve PA Line method

Signed-off-by: SoftFever <softfeverever@gmail.com>
This commit is contained in:
SoftFever 2023-09-25 20:39:02 +08:00
parent 7ef43f6849
commit f06b7cb526
2 changed files with 471 additions and 671 deletions

View file

@ -7,17 +7,18 @@
namespace Slic3r { namespace Slic3r {
// Calculate the optimal Pressure Advance speed // Calculate the optimal Pressure Advance speed
float CalibPressureAdvance::find_optimal_PA_speed(const DynamicPrintConfig &config, double line_width, double layer_height, float CalibPressureAdvance::find_optimal_PA_speed(const DynamicPrintConfig &config, double line_width, double layer_height, int filament_idx)
int filament_idx) { {
const double general_suggested_min_speed = 100.0; const double general_suggested_min_speed = 100.0;
double filament_max_volumetric_speed = config.option<ConfigOptionFloats>("filament_max_volumetric_speed")->get_at(0); double filament_max_volumetric_speed = config.option<ConfigOptionFloats>("filament_max_volumetric_speed")->get_at(0);
Flow pattern_line = Flow(line_width, layer_height, config.option<ConfigOptionFloats>("nozzle_diameter")->get_at(0)); Flow pattern_line = Flow(line_width, layer_height, config.option<ConfigOptionFloats>("nozzle_diameter")->get_at(0));
auto pa_speed = std::min(std::max(general_suggested_min_speed,config.option<ConfigOptionFloat>("outer_wall_speed")->value), filament_max_volumetric_speed / pattern_line.mm3_per_mm()); auto pa_speed = std::min(std::max(general_suggested_min_speed, config.option<ConfigOptionFloat>("outer_wall_speed")->value),
filament_max_volumetric_speed / pattern_line.mm3_per_mm());
return std::floor(pa_speed); return std::floor(pa_speed);
} }
std::string CalibPressureAdvance::move_to(Vec2d pt, GCodeWriter& writer, std::string comment) std::string CalibPressureAdvance::move_to(Vec2d pt, GCodeWriter &writer, std::string comment)
{ {
std::stringstream gcode; std::stringstream gcode;
@ -31,12 +32,7 @@ std::string CalibPressureAdvance::move_to(Vec2d pt, GCodeWriter& writer, std::st
} }
double CalibPressureAdvance::e_per_mm( double CalibPressureAdvance::e_per_mm(
double line_width, double line_width, double layer_height, float nozzle_diameter, float filament_diameter, float print_flow_ratio) const
double layer_height,
float nozzle_diameter,
float filament_diameter,
float print_flow_ratio
) const
{ {
const Flow line_flow = Flow(line_width, layer_height, nozzle_diameter); const Flow line_flow = Flow(line_width, layer_height, nozzle_diameter);
const double filament_area = M_PI * std::pow(filament_diameter / 2, 2); const double filament_area = M_PI * std::pow(filament_diameter / 2, 2);
@ -54,14 +50,7 @@ std::string CalibPressureAdvance::convert_number_to_string(double num) const
} }
std::string CalibPressureAdvance::draw_digit( std::string CalibPressureAdvance::draw_digit(
double startx, double startx, double starty, char c, CalibPressureAdvance::DrawDigitMode mode, double line_width, double e_per_mm, GCodeWriter &writer)
double starty,
char c,
CalibPressureAdvance::DrawDigitMode mode,
double line_width,
double e_per_mm,
GCodeWriter& writer
)
{ {
const double len = m_digit_segment_len; const double len = m_digit_segment_len;
const double gap = line_width / 2.0; const double gap = line_width / 2.0;
@ -191,23 +180,20 @@ std::string CalibPressureAdvance::draw_digit(
gcode << move_to(p4_5, writer, "Glyph: ."); gcode << move_to(p4_5, writer, "Glyph: .");
gcode << writer.extrude_to_xy(p4_5 + dot_direction, dE); gcode << writer.extrude_to_xy(p4_5 + dot_direction, dE);
break; break;
default: default: break;
break;
} }
return gcode.str(); return gcode.str();
} }
std::string CalibPressureAdvance::draw_number( std::string CalibPressureAdvance::draw_number(double startx,
double startx,
double starty, double starty,
double value, double value,
CalibPressureAdvance::DrawDigitMode mode, CalibPressureAdvance::DrawDigitMode mode,
double line_width, double line_width,
double e_per_mm, double e_per_mm,
double speed, double speed,
GCodeWriter& writer GCodeWriter &writer)
)
{ {
auto sNumber = convert_number_to_string(value); auto sNumber = convert_number_to_string(value);
std::stringstream gcode; std::stringstream gcode;
@ -219,26 +205,220 @@ std::string CalibPressureAdvance::draw_number(
} }
switch (mode) { switch (mode) {
case DrawDigitMode::Bottom_To_Top: case DrawDigitMode::Bottom_To_Top:
gcode << draw_digit( gcode << draw_digit(startx, starty + i * number_spacing(), sNumber[i], mode, line_width, e_per_mm, writer);
startx,
starty + i * number_spacing(),
sNumber[i],
mode,
line_width,
e_per_mm,
writer
);
break; break;
default: default: gcode << draw_digit(startx + i * number_spacing(), starty, sNumber[i], mode, line_width, e_per_mm, writer);
gcode << draw_digit( }
startx + i * number_spacing(), }
starty,
sNumber[i], return gcode.str();
mode, }
line_width,
e_per_mm,
writer double CalibPressureAdvance::get_distance(Vec2d from, Vec2d to) const
); {
return std::hypot((to.x() - from.x()), (to.y() - from.y()));
}
std::string CalibPressureAdvance::draw_line(
GCodeWriter &writer, Vec2d to_pt, double line_width, double layer_height, double speed, const std::string &comment)
{
const double e_per_mm = CalibPressureAdvance::e_per_mm(line_width, layer_height,
m_config.option<ConfigOptionFloats>("nozzle_diameter")->get_at(0),
m_config.option<ConfigOptionFloats>("filament_diameter")->get_at(0),
m_config.option<ConfigOptionFloats>("filament_flow_ratio")->get_at(0));
const double length = get_distance(Vec2d(m_last_pos.x(), m_last_pos.y()), to_pt);
auto dE = e_per_mm * length;
std::stringstream gcode;
gcode << writer.set_speed(speed);
gcode << writer.extrude_to_xy(to_pt, dE, comment);
m_last_pos = Vec3d(to_pt.x(), to_pt.y(), 0);
return gcode.str();
}
std::string CalibPressureAdvance::draw_box(GCodeWriter &writer, double min_x, double min_y, double size_x, double size_y, DrawBoxOptArgs opt_args)
{
std::stringstream gcode;
double x = min_x;
double y = min_y;
const double max_x = min_x + size_x;
const double max_y = min_y + size_y;
const double spacing = opt_args.line_width - opt_args.height * (1 - M_PI / 4);
// if number of perims exceeds size of box, reduce it to max
const int max_perimeters = std::min(
// this is the equivalent of number of perims for concentric fill
std::floor(size_x * std::sin(to_radians(45))) / (spacing / std::sin(to_radians(45))),
std::floor(size_y * std::sin(to_radians(45))) / (spacing / std::sin(to_radians(45))));
opt_args.num_perimeters = std::min(opt_args.num_perimeters, max_perimeters);
gcode << move_to(Vec2d(min_x, min_y), writer, "Move to box start");
// DrawLineOptArgs line_opt_args(*this);
auto line_arg_height = opt_args.height;
auto line_arg_line_width = opt_args.line_width;
auto line_arg_speed = opt_args.speed;
std::string comment = "";
for (int i = 0; i < opt_args.num_perimeters; ++i) {
if (i != 0) { // after first perimeter, step inwards to start next perimeter
x += spacing;
y += spacing;
gcode << move_to(Vec2d(x, y), writer, "Step inwards to print next perimeter");
}
y += size_y - i * spacing * 2;
comment = "Draw perimeter (up)";
gcode << draw_line(writer, Vec2d(x, y), line_arg_line_width, line_arg_height, line_arg_speed, comment);
x += size_x - i * spacing * 2;
comment = "Draw perimeter (right)";
gcode << draw_line(writer, Vec2d(x, y), line_arg_line_width, line_arg_height, line_arg_speed, comment);
y -= size_y - i * spacing * 2;
comment = "Draw perimeter (down)";
gcode << draw_line(writer, Vec2d(x, y), line_arg_line_width, line_arg_height, line_arg_speed, comment);
x -= size_x - i * spacing * 2;
comment = "Draw perimeter (left)";
gcode << draw_line(writer, Vec2d(x, y), line_arg_line_width, line_arg_height, line_arg_speed, comment);
}
if (!opt_args.is_filled) {
return gcode.str();
}
// create box infill
const double spacing_45 = spacing / std::sin(to_radians(45));
const double bound_modifier = (spacing * (opt_args.num_perimeters - 1)) + (opt_args.line_width * (1 - m_encroachment));
const double x_min_bound = min_x + bound_modifier;
const double x_max_bound = max_x - bound_modifier;
const double y_min_bound = min_y + bound_modifier;
const double y_max_bound = max_y - bound_modifier;
const int x_count = std::floor((x_max_bound - x_min_bound) / spacing_45);
const int y_count = std::floor((y_max_bound - y_min_bound) / spacing_45);
double x_remainder = std::fmod((x_max_bound - x_min_bound), spacing_45);
double y_remainder = std::fmod((y_max_bound - y_min_bound), spacing_45);
x = x_min_bound;
y = y_min_bound;
gcode << move_to(Vec2d(x, y), writer, "Move to fill start");
for (int i = 0; i < x_count + y_count + (x_remainder + y_remainder >= spacing_45 ? 1 : 0);
++i) { // this isn't the most robust way, but less expensive than finding line intersections
if (i < std::min(x_count, y_count)) {
if (i % 2 == 0) {
x += spacing_45;
y = y_min_bound;
gcode << move_to(Vec2d(x, y), writer, "Fill: Step right");
y += x - x_min_bound;
x = x_min_bound;
comment = "Fill: Print up/left";
gcode << draw_line(writer, Vec2d(x, y), line_arg_line_width, line_arg_height, line_arg_speed, comment);
} else {
y += spacing_45;
x = x_min_bound;
gcode << move_to(Vec2d(x, y), writer, "Fill: Step up");
x += y - y_min_bound;
y = y_min_bound;
comment = "Fill: Print down/right";
gcode << draw_line(writer, Vec2d(x, y), line_arg_line_width, line_arg_height, line_arg_speed, comment);
}
} else if (i < std::max(x_count, y_count)) {
if (x_count > y_count) {
// box is wider than tall
if (i % 2 == 0) {
x += spacing_45;
y = y_min_bound;
gcode << move_to(Vec2d(x, y), writer, "Fill: Step right");
x -= y_max_bound - y_min_bound;
y = y_max_bound;
comment = "Fill: Print up/left";
gcode << draw_line(writer, Vec2d(x, y), line_arg_line_width, line_arg_height, line_arg_speed, comment);
} else {
if (i == y_count) {
x += spacing_45 - y_remainder;
y_remainder = 0;
} else {
x += spacing_45;
}
y = y_max_bound;
gcode << move_to(Vec2d(x, y), writer, "Fill: Step right");
x += y_max_bound - y_min_bound;
y = y_min_bound;
comment = "Fill: Print down/right";
gcode << draw_line(writer, Vec2d(x, y), line_arg_line_width, line_arg_height, line_arg_speed, comment);
}
} else {
// box is taller than wide
if (i % 2 == 0) {
x = x_max_bound;
if (i == x_count) {
y += spacing_45 - x_remainder;
x_remainder = 0;
} else {
y += spacing_45;
}
gcode << move_to(Vec2d(x, y), writer, "Fill: Step up");
x = x_min_bound;
y += x_max_bound - x_min_bound;
comment = "Fill: Print up/left";
gcode << draw_line(writer, Vec2d(x, y), line_arg_line_width, line_arg_height, line_arg_speed, comment);
} else {
x = x_min_bound;
y += spacing_45;
gcode << move_to(Vec2d(x, y), writer, "Fill: Step up");
x = x_max_bound;
y -= x_max_bound - x_min_bound;
comment = "Fill: Print down/right";
gcode << draw_line(writer, Vec2d(x, y), line_arg_line_width, line_arg_height, line_arg_speed, comment);
}
}
} else {
if (i % 2 == 0) {
x = x_max_bound;
if (i == x_count) {
y += spacing_45 - x_remainder;
} else {
y += spacing_45;
}
gcode << move_to(Vec2d(x, y), writer, "Fill: Step up");
x -= y_max_bound - y;
y = y_max_bound;
comment = "Fill: Print up/left";
gcode << draw_line(writer, Vec2d(x, y), line_arg_line_width, line_arg_height, line_arg_speed, comment);
} else {
if (i == y_count) {
x += spacing_45 - y_remainder;
} else {
x += spacing_45;
}
y = y_max_bound;
gcode << move_to(Vec2d(x, y), writer, "Fill: Step right");
y -= x_max_bound - x;
x = x_max_bound;
comment = "Fill: Print down/right";
gcode << draw_line(writer, Vec2d(x, y), line_arg_line_width, line_arg_height, line_arg_speed, comment);
}
} }
} }
@ -268,40 +448,22 @@ std::string CalibPressureAdvanceLine::generate_test(double start_pa /*= 0*/, dou
return print_pa_lines(startx, starty, start_pa, step_pa, count); return print_pa_lines(startx, starty, start_pa, step_pa, count);
} }
bool CalibPressureAdvanceLine::is_delta() const bool CalibPressureAdvanceLine::is_delta() const { return mp_gcodegen->config().printable_area.values.size() > 4; }
{
return mp_gcodegen->config().printable_area.values.size() > 4;
}
std::string CalibPressureAdvanceLine::print_pa_lines(double start_x, double start_y, double start_pa, double step_pa, int num) std::string CalibPressureAdvanceLine::print_pa_lines(double start_x, double start_y, double start_pa, double step_pa, int num)
{ {
auto& writer = mp_gcodegen->writer(); auto &writer = mp_gcodegen->writer();
const auto& config = mp_gcodegen->config(); const auto &config = mp_gcodegen->config();
const auto filament_diameter = config.filament_diameter.get_at(0); const auto filament_diameter = config.filament_diameter.get_at(0);
const auto print_flow_ratio = config.print_flow_ratio; const auto print_flow_ratio = config.print_flow_ratio;
const double e_per_mm = CalibPressureAdvance::e_per_mm( const double e_per_mm = CalibPressureAdvance::e_per_mm(m_line_width, m_height_layer, m_nozzle_diameter, filament_diameter,
m_line_width, print_flow_ratio);
m_height_layer, const double thin_e_per_mm = CalibPressureAdvance::e_per_mm(m_thin_line_width, m_height_layer, m_nozzle_diameter, filament_diameter,
m_nozzle_diameter, print_flow_ratio);
filament_diameter, const double number_e_per_mm = CalibPressureAdvance::e_per_mm(m_number_line_width, m_height_layer, m_nozzle_diameter, filament_diameter,
print_flow_ratio print_flow_ratio);
);
const double thin_e_per_mm = CalibPressureAdvance::e_per_mm(
m_thin_line_width,
m_height_layer,
m_nozzle_diameter,
filament_diameter,
print_flow_ratio
);
const double number_e_per_mm = CalibPressureAdvance::e_per_mm(
m_number_line_width,
m_height_layer,
m_nozzle_diameter,
filament_diameter,
print_flow_ratio
);
const double fast = CalibPressureAdvance::speed_adjust(m_fast_speed); const double fast = CalibPressureAdvance::speed_adjust(m_fast_speed);
const double slow = CalibPressureAdvance::speed_adjust(m_slow_speed); const double slow = CalibPressureAdvance::speed_adjust(m_slow_speed);
@ -310,10 +472,10 @@ std::string CalibPressureAdvanceLine::print_pa_lines(double start_x, double star
double y_pos = start_y; double y_pos = start_y;
// prime line // prime line
auto prime_x = start_x - 2; auto prime_x = start_x;
gcode << move_to(Vec2d(prime_x, y_pos + (num - 4) * m_space_y), writer); gcode << move_to(Vec2d(prime_x, y_pos + (num) * m_space_y), writer);
gcode << writer.set_speed(slow); gcode << writer.set_speed(slow);
gcode << writer.extrude_to_xy(Vec2d(prime_x, y_pos + 3 * m_space_y), e_per_mm * m_space_y * num * 1.1); gcode << writer.extrude_to_xy(Vec2d(prime_x, y_pos), e_per_mm * m_space_y * num * 1.2);
for (int i = 0; i < num; ++i) { for (int i = 0; i < num; ++i) {
gcode << writer.set_pressure_advance(start_pa + i * step_pa); gcode << writer.set_pressure_advance(start_pa + i * step_pa);
@ -323,60 +485,52 @@ std::string CalibPressureAdvanceLine::print_pa_lines(double start_x, double star
gcode << writer.set_speed(fast); gcode << writer.set_speed(fast);
gcode << writer.extrude_to_xy(Vec2d(start_x + m_length_short + m_length_long, y_pos + i * m_space_y), e_per_mm * m_length_long); gcode << writer.extrude_to_xy(Vec2d(start_x + m_length_short + m_length_long, y_pos + i * m_space_y), e_per_mm * m_length_long);
gcode << writer.set_speed(slow); gcode << writer.set_speed(slow);
gcode << writer.extrude_to_xy(Vec2d(start_x + m_length_short + m_length_long + m_length_short, y_pos + i * m_space_y), e_per_mm * m_length_short); gcode << writer.extrude_to_xy(Vec2d(start_x + m_length_short + m_length_long + m_length_short, y_pos + i * m_space_y),
e_per_mm * m_length_short);
} }
gcode << writer.set_pressure_advance(0.0); gcode << writer.set_pressure_advance(0.0);
if (m_draw_numbers) { if (m_draw_numbers) {
// draw indicator lines
gcode << writer.set_speed(fast);
gcode << move_to(Vec2d(start_x + m_length_short, y_pos + (num - 1) * m_space_y + 2), writer);
gcode << writer.extrude_to_xy(Vec2d(start_x + m_length_short, y_pos + (num - 1) * m_space_y + 7), thin_e_per_mm * 7);
gcode << move_to(Vec2d(start_x + m_length_short + m_length_long, y_pos + (num - 1) * m_space_y + 7), writer);
gcode << writer.extrude_to_xy(Vec2d(start_x + m_length_short + m_length_long, y_pos + (num - 1) * m_space_y + 2), thin_e_per_mm * 7);
// Orca: skip drawing indicator lines
// gcode << writer.set_speed(fast);
// gcode << move_to(Vec2d(start_x + m_length_short, y_pos + (num - 1) * m_space_y + 2), writer);
// gcode << writer.extrude_to_xy(Vec2d(start_x + m_length_short, y_pos + (num - 1) * m_space_y + 7), thin_e_per_mm * 7);
// gcode << move_to(Vec2d(start_x + m_length_short + m_length_long, y_pos + (num - 1) * m_space_y + 7), writer);
// gcode << writer.extrude_to_xy(Vec2d(start_x + m_length_short + m_length_long, y_pos + (num - 1) * m_space_y + 2), thin_e_per_mm * 7);
DrawBoxOptArgs default_box_opt_args(2, m_height_layer, 0.6, fast);
default_box_opt_args.is_filled = true;
gcode << draw_box(writer, start_x + m_length_short + m_length_long + m_length_short, start_y-m_space_y, number_spacing() * 8,
num * m_space_y, default_box_opt_args);
gcode << writer.travel_to_z(m_height_layer*2);
for (int i = 0; i < num; i += 2) { for (int i = 0; i < num; i += 2) {
gcode << draw_number( gcode << draw_number(start_x + m_length_short + m_length_long + m_length_short + 3, y_pos + i * m_space_y + m_space_y / 2,
start_x + m_length_short + m_length_long + m_length_short + 3, start_pa + i * step_pa, m_draw_digit_mode, m_number_line_width, number_e_per_mm, 3600, writer);
y_pos + i * m_space_y + m_space_y / 2,
start_pa + i * step_pa,
m_draw_digit_mode,
m_number_line_width,
number_e_per_mm,
3600,
writer
);
} }
} }
return gcode.str(); return gcode.str();
} }
void CalibPressureAdvanceLine::delta_modify_start(double& startx, double& starty, int count) void CalibPressureAdvanceLine::delta_modify_start(double &startx, double &starty, int count)
{ {
startx = -startx; startx = -startx;
starty = -(count * m_space_y) / 2; starty = -(count * m_space_y) / 2;
} }
CalibPressureAdvancePattern::CalibPressureAdvancePattern( CalibPressureAdvancePattern::CalibPressureAdvancePattern(
const Calib_Params& params, const Calib_Params &params, const DynamicPrintConfig &config, bool is_bbl_machine, Model &model, const Vec3d &origin)
const DynamicPrintConfig& config, : m_params(params),CalibPressureAdvance(config)
bool is_bbl_machine,
Model& model,
const Vec3d& origin
) :
m_params(params)
{ {
this->m_draw_digit_mode = DrawDigitMode::Bottom_To_Top; this->m_draw_digit_mode = DrawDigitMode::Bottom_To_Top;
refresh_setup(config, is_bbl_machine, model, origin); refresh_setup(config, is_bbl_machine, model, origin);
}; };
void CalibPressureAdvancePattern::generate_custom_gcodes( void CalibPressureAdvancePattern::generate_custom_gcodes(const DynamicPrintConfig &config,
const DynamicPrintConfig& config,
bool is_bbl_machine, bool is_bbl_machine,
Model& model, Model &model,
const Vec3d& origin const Vec3d &origin)
)
{ {
std::stringstream gcode; std::stringstream gcode;
gcode << "; start pressure advance pattern for layer\n"; gcode << "; start pressure advance pattern for layer\n";
@ -387,31 +541,21 @@ void CalibPressureAdvancePattern::generate_custom_gcodes(
gcode << m_writer.travel_to_z(height_first_layer(), "Move to start Z position"); gcode << m_writer.travel_to_z(height_first_layer(), "Move to start Z position");
gcode << m_writer.set_pressure_advance(m_params.start); gcode << m_writer.set_pressure_advance(m_params.start);
const DrawBoxOptArgs default_box_opt_args(*this); const DrawBoxOptArgs default_box_opt_args(wall_count(), height_first_layer(), line_width_first_layer(),
speed_adjust(speed_first_layer()));
// create anchoring frame // create anchoring frame
gcode << draw_box( gcode << draw_box(m_writer, m_starting_point.x(), m_starting_point.y(), print_size_x(), frame_size_y(), default_box_opt_args);
m_starting_point.x(),
m_starting_point.y(),
print_size_x(),
frame_size_y(),
default_box_opt_args
);
// create tab for numbers // create tab for numbers
DrawBoxOptArgs draw_box_opt_args = default_box_opt_args; DrawBoxOptArgs draw_box_opt_args = default_box_opt_args;
draw_box_opt_args.is_filled = true; draw_box_opt_args.is_filled = true;
draw_box_opt_args.num_perimeters = wall_count(); draw_box_opt_args.num_perimeters = wall_count();
gcode << draw_box( gcode << draw_box(m_writer, m_starting_point.x(), m_starting_point.y() + frame_size_y() + line_spacing_first_layer(),
m_starting_point.x(),
m_starting_point.y() + frame_size_y() + line_spacing_first_layer(),
glyph_tab_max_x() - m_starting_point.x(), glyph_tab_max_x() - m_starting_point.x(),
max_numbering_height() + line_spacing_first_layer() + m_glyph_padding_vertical * 2, max_numbering_height() + line_spacing_first_layer() + m_glyph_padding_vertical * 2, draw_box_opt_args);
draw_box_opt_args
);
std::vector<CustomGCode::Item> gcode_items; std::vector<CustomGCode::Item> gcode_items;
const DrawLineOptArgs default_line_opt_args(*this);
const int num_patterns = get_num_patterns(); // "cache" for use in loops const int num_patterns = get_num_patterns(); // "cache" for use in loops
// draw pressure advance pattern // draw pressure advance pattern
@ -435,30 +579,19 @@ void CalibPressureAdvancePattern::generate_custom_gcodes(
if (i == 1) { if (i == 1) {
gcode << m_writer.set_pressure_advance(m_params.start); gcode << m_writer.set_pressure_advance(m_params.start);
double number_e_per_mm = e_per_mm( double number_e_per_mm = e_per_mm(line_width(), height_layer(),
line_width(),
height_layer(),
m_config.option<ConfigOptionFloats>("nozzle_diameter")->get_at(0), m_config.option<ConfigOptionFloats>("nozzle_diameter")->get_at(0),
m_config.option<ConfigOptionFloats>("filament_diameter")->get_at(0), m_config.option<ConfigOptionFloats>("filament_diameter")->get_at(0),
m_config.option<ConfigOptionFloats>("filament_flow_ratio")->get_at(0) m_config.option<ConfigOptionFloats>("filament_flow_ratio")->get_at(0));
);
// glyph on every other line // glyph on every other line
for (int j = 0; j < num_patterns; j += 2) { for (int j = 0; j < num_patterns; j += 2) {
gcode << draw_number( gcode << draw_number(glyph_start_x(j), m_starting_point.y() + frame_size_y() + m_glyph_padding_vertical + line_width(),
glyph_start_x(j), m_params.start + (j * m_params.step), m_draw_digit_mode, line_width(), number_e_per_mm,
m_starting_point.y() + frame_size_y() + m_glyph_padding_vertical + line_width(), speed_first_layer(), m_writer);
m_params.start + (j * m_params.step),
m_draw_digit_mode,
line_width(),
number_e_per_mm,
speed_first_layer(),
m_writer
);
} }
} }
DrawLineOptArgs draw_line_opt_args = default_line_opt_args;
double to_x = m_starting_point.x() + pattern_shift(); double to_x = m_starting_point.x() + pattern_shift();
double to_y = m_starting_point.y(); double to_y = m_starting_point.y();
@ -466,18 +599,11 @@ void CalibPressureAdvancePattern::generate_custom_gcodes(
// shrink first layer to fit inside frame // shrink first layer to fit inside frame
if (i == 0) { if (i == 0) {
double shrink = double shrink = (line_spacing_first_layer() * (wall_count() - 1) + (line_width_first_layer() * (1 - m_encroachment))) /
( std::sin(to_radians(m_corner_angle) / 2);
line_spacing_first_layer() * (wall_count() - 1) +
(line_width_first_layer() * (1 - m_encroachment))
) / std::sin(to_radians(m_corner_angle) / 2)
;
side_length = m_wall_side_length - shrink; side_length = m_wall_side_length - shrink;
to_x += shrink * std::sin(to_radians(90) - to_radians(m_corner_angle) / 2); to_x += shrink * std::sin(to_radians(90) - to_radians(m_corner_angle) / 2);
to_y += to_y += line_spacing_first_layer() * (wall_count() - 1) + (line_width_first_layer() * (1 - m_encroachment));
line_spacing_first_layer() * (wall_count() - 1) +
(line_width_first_layer() * (1 - m_encroachment))
;
} }
double initial_x = to_x; double initial_x = to_x;
@ -493,17 +619,16 @@ void CalibPressureAdvancePattern::generate_custom_gcodes(
to_x += std::cos(to_radians(m_corner_angle) / 2) * side_length; to_x += std::cos(to_radians(m_corner_angle) / 2) * side_length;
to_y += std::sin(to_radians(m_corner_angle) / 2) * side_length; to_y += std::sin(to_radians(m_corner_angle) / 2) * side_length;
draw_line_opt_args = default_line_opt_args; auto draw_line_arg_height = i == 0 ? height_first_layer() : height_layer();
draw_line_opt_args.height = i == 0 ? height_first_layer() : height_layer(); auto draw_line_arg_line_width = line_width(); // don't use line_width_first_layer so results are consistent across all layers
draw_line_opt_args.line_width = line_width(); // don't use line_width_first_layer so results are consistent across all layers auto draw_line_arg_speed = i == 0 ? speed_adjust(speed_first_layer()) : speed_adjust(speed_perimeter());
draw_line_opt_args.speed = i == 0 ? speed_adjust(speed_first_layer()) : speed_adjust(speed_perimeter()); auto draw_line_arg_comment = "Print pattern wall";
draw_line_opt_args.comment = "Print pattern wall"; gcode << draw_line(m_writer, Vec2d(to_x, to_y), draw_line_arg_line_width, draw_line_arg_height, draw_line_arg_speed, draw_line_arg_comment);
gcode << draw_line(Vec2d(to_x, to_y), draw_line_opt_args);
to_x -= std::cos(to_radians(m_corner_angle) / 2) * side_length; to_x -= std::cos(to_radians(m_corner_angle) / 2) * side_length;
to_y += std::sin(to_radians(m_corner_angle) / 2) * side_length; to_y += std::sin(to_radians(m_corner_angle) / 2) * side_length;
gcode << draw_line(Vec2d(to_x, to_y), draw_line_opt_args); gcode << draw_line(m_writer, Vec2d(to_x, to_y), draw_line_arg_line_width, draw_line_arg_height, draw_line_arg_speed, draw_line_arg_comment);
to_y = initial_y; to_y = initial_y;
if (k != wall_count() - 1) { if (k != wall_count() - 1) {
@ -541,12 +666,10 @@ void CalibPressureAdvancePattern::generate_custom_gcodes(
model.plates_custom_gcodes[model.curr_plate_index] = info; model.plates_custom_gcodes[model.curr_plate_index] = info;
} }
void CalibPressureAdvancePattern::refresh_setup( void CalibPressureAdvancePattern::refresh_setup(const DynamicPrintConfig &config,
const DynamicPrintConfig& config,
bool is_bbl_machine, bool is_bbl_machine,
const Model& model, const Model &model,
const Vec3d& origin const Vec3d &origin)
)
{ {
m_config = config; m_config = config;
m_config.apply(model.objects.front()->config.get(), true); m_config.apply(model.objects.front()->config.get(), true);
@ -558,15 +681,10 @@ void CalibPressureAdvancePattern::refresh_setup(
_refresh_writer(is_bbl_machine, model, origin); _refresh_writer(is_bbl_machine, model, origin);
} }
void CalibPressureAdvancePattern::_refresh_starting_point(const Model& model) void CalibPressureAdvancePattern::_refresh_starting_point(const Model &model)
{ {
ModelObject* obj = model.objects.front(); ModelObject *obj = model.objects.front();
BoundingBoxf3 bbox = BoundingBoxf3 bbox = obj->instance_bounding_box(*obj->instances.front(), false);
obj->instance_bounding_box(
*obj->instances.front(),
false
)
;
m_starting_point = Vec3d(bbox.min.x(), bbox.max.y(), 0); m_starting_point = Vec3d(bbox.min.x(), bbox.max.y(), 0);
m_starting_point.y() += m_handle_spacing; m_starting_point.y() += m_handle_spacing;
@ -577,11 +695,7 @@ void CalibPressureAdvancePattern::_refresh_starting_point(const Model& model)
} }
} }
void CalibPressureAdvancePattern::_refresh_writer( void CalibPressureAdvancePattern::_refresh_writer(bool is_bbl_machine, const Model &model, const Vec3d &origin)
bool is_bbl_machine,
const Model& model,
const Vec3d& origin
)
{ {
PrintConfig print_config; PrintConfig print_config;
print_config.apply(m_config, true); print_config.apply(m_config, true);
@ -591,249 +705,20 @@ void CalibPressureAdvancePattern::_refresh_writer(
m_writer.set_is_bbl_machine(is_bbl_machine); m_writer.set_is_bbl_machine(is_bbl_machine);
const unsigned int extruder_id = model.objects.front()->volumes.front()->extruder_id(); const unsigned int extruder_id = model.objects.front()->volumes.front()->extruder_id();
m_writer.set_extruders({ extruder_id }); m_writer.set_extruders({extruder_id});
m_writer.set_extruder(extruder_id); m_writer.set_extruder(extruder_id);
} }
std::string CalibPressureAdvancePattern::draw_line(
Vec2d to_pt,
DrawLineOptArgs opt_args
)
{
const double e_per_mm = CalibPressureAdvance::e_per_mm(
opt_args.line_width,
opt_args.height,
m_config.option<ConfigOptionFloats>("nozzle_diameter")->get_at(0),
m_config.option<ConfigOptionFloats>("filament_diameter")->get_at(0),
m_config.option<ConfigOptionFloats>("filament_flow_ratio")->get_at(0)
);
const double length = get_distance(Vec2d(m_last_pos.x(), m_last_pos.y()), to_pt);
auto dE = e_per_mm * length;
std::stringstream gcode;
gcode << m_writer.set_speed(opt_args.speed);
gcode << m_writer.extrude_to_xy(to_pt, dE, opt_args.comment);
m_last_pos = Vec3d(to_pt.x(), to_pt.y(), 0);
return gcode.str();
}
std::string CalibPressureAdvancePattern::draw_box(
double min_x,
double min_y,
double size_x,
double size_y,
DrawBoxOptArgs opt_args
)
{
std::stringstream gcode;
double x = min_x;
double y = min_y;
const double max_x = min_x + size_x;
const double max_y = min_y + size_y;
const double spacing = opt_args.line_width - opt_args.height * (1 - M_PI / 4);
// if number of perims exceeds size of box, reduce it to max
const int max_perimeters =
std::min(
// this is the equivalent of number of perims for concentric fill
std::floor(size_x * std::sin(to_radians(45))) / (spacing / std::sin(to_radians(45))),
std::floor(size_y * std::sin(to_radians(45))) / (spacing / std::sin(to_radians(45)))
)
;
opt_args.num_perimeters = std::min(opt_args.num_perimeters, max_perimeters);
gcode << move_to(Vec2d(min_x, min_y), m_writer, "Move to box start");
DrawLineOptArgs line_opt_args(*this);
line_opt_args.height = opt_args.height;
line_opt_args.line_width = opt_args.line_width;
line_opt_args.speed = opt_args.speed;
for (int i = 0; i < opt_args.num_perimeters; ++i) {
if (i != 0) { // after first perimeter, step inwards to start next perimeter
x += spacing;
y += spacing;
gcode << move_to(Vec2d(x, y), m_writer, "Step inwards to print next perimeter");
}
y += size_y - i * spacing * 2;
line_opt_args.comment = "Draw perimeter (up)";
gcode << draw_line(Vec2d(x, y), line_opt_args);
x += size_x - i * spacing * 2;
line_opt_args.comment = "Draw perimeter (right)";
gcode << draw_line(Vec2d(x, y), line_opt_args);
y -= size_y - i * spacing * 2;
line_opt_args.comment = "Draw perimeter (down)";
gcode << draw_line(Vec2d(x, y), line_opt_args);
x -= size_x - i * spacing * 2;
line_opt_args.comment = "Draw perimeter (left)";
gcode << draw_line(Vec2d(x, y), line_opt_args);
}
if (!opt_args.is_filled) {
return gcode.str();
}
// create box infill
const double spacing_45 = spacing / std::sin(to_radians(45));
const double bound_modifier =
(spacing * (opt_args.num_perimeters - 1)) +
(opt_args.line_width * (1 - m_encroachment))
;
const double x_min_bound = min_x + bound_modifier;
const double x_max_bound = max_x - bound_modifier;
const double y_min_bound = min_y + bound_modifier;
const double y_max_bound = max_y - bound_modifier;
const int x_count = std::floor((x_max_bound - x_min_bound) / spacing_45);
const int y_count = std::floor((y_max_bound - y_min_bound) / spacing_45);
double x_remainder = std::fmod((x_max_bound - x_min_bound), spacing_45);
double y_remainder = std::fmod((y_max_bound - y_min_bound), spacing_45);
x = x_min_bound;
y = y_min_bound;
gcode << move_to(Vec2d(x, y), m_writer, "Move to fill start");
for (int i = 0; i < x_count + y_count + (x_remainder + y_remainder >= spacing_45 ? 1 : 0); ++i) { // this isn't the most robust way, but less expensive than finding line intersections
if (i < std::min(x_count, y_count)) {
if (i % 2 == 0) {
x += spacing_45;
y = y_min_bound;
gcode << move_to(Vec2d(x, y), m_writer, "Fill: Step right");
y += x - x_min_bound;
x = x_min_bound;
line_opt_args.comment = "Fill: Print up/left";
gcode << draw_line(Vec2d(x, y), line_opt_args);
} else {
y += spacing_45;
x = x_min_bound;
gcode << move_to(Vec2d(x, y), m_writer, "Fill: Step up");
x += y - y_min_bound;
y = y_min_bound;
line_opt_args.comment = "Fill: Print down/right";
gcode << draw_line(Vec2d(x, y), line_opt_args);
}
} else if (i < std::max(x_count, y_count)) {
if (x_count > y_count) {
// box is wider than tall
if (i % 2 == 0) {
x += spacing_45;
y = y_min_bound;
gcode << move_to(Vec2d(x, y), m_writer, "Fill: Step right");
x -= y_max_bound - y_min_bound;
y = y_max_bound;
line_opt_args.comment = "Fill: Print up/left";
gcode << draw_line(Vec2d(x, y), line_opt_args);
} else {
if (i == y_count) {
x += spacing_45 - y_remainder;
y_remainder = 0;
} else {
x += spacing_45;
}
y = y_max_bound;
gcode << move_to(Vec2d(x, y), m_writer, "Fill: Step right");
x += y_max_bound - y_min_bound;
y = y_min_bound;
line_opt_args.comment = "Fill: Print down/right";
gcode << draw_line(Vec2d(x, y), line_opt_args);
}
} else {
// box is taller than wide
if (i % 2 == 0) {
x = x_max_bound;
if (i == x_count) {
y += spacing_45 - x_remainder;
x_remainder = 0;
} else {
y += spacing_45;
}
gcode << move_to(Vec2d(x, y), m_writer, "Fill: Step up");
x = x_min_bound;
y += x_max_bound - x_min_bound;
line_opt_args.comment = "Fill: Print up/left";
gcode << draw_line(Vec2d(x, y), line_opt_args);
} else {
x = x_min_bound;
y += spacing_45;
gcode << move_to(Vec2d(x, y), m_writer, "Fill: Step up");
x = x_max_bound;
y -= x_max_bound - x_min_bound;
line_opt_args.comment = "Fill: Print down/right";
gcode << draw_line(Vec2d(x, y), line_opt_args);
}
}
} else {
if (i % 2 == 0) {
x = x_max_bound;
if (i == x_count) {
y += spacing_45 - x_remainder;
} else {
y += spacing_45;
}
gcode << move_to(Vec2d(x, y), m_writer, "Fill: Step up");
x -= y_max_bound - y;
y = y_max_bound;
line_opt_args.comment = "Fill: Print up/left";
gcode << draw_line(Vec2d(x, y), line_opt_args);
} else {
if (i == y_count) {
x += spacing_45 - y_remainder;
} else {
x += spacing_45;
}
y = y_max_bound;
gcode << move_to(Vec2d(x, y), m_writer, "Fill: Step right");
y -= x_max_bound - x;
x = x_max_bound;
line_opt_args.comment = "Fill: Print down/right";
gcode << draw_line(Vec2d(x, y), line_opt_args);
}
}
}
return gcode.str();
}
double CalibPressureAdvancePattern::get_distance(Vec2d from, Vec2d to) const
{
return std::hypot((to.x() - from.x()), (to.y() - from.y()));
}
double CalibPressureAdvancePattern::object_size_x() const double CalibPressureAdvancePattern::object_size_x() const
{ {
return get_num_patterns() * ((wall_count() - 1) * line_spacing_angle()) + return get_num_patterns() * ((wall_count() - 1) * line_spacing_angle()) +
(get_num_patterns() - 1) * (m_pattern_spacing + line_width()) + (get_num_patterns() - 1) * (m_pattern_spacing + line_width()) + std::cos(to_radians(m_corner_angle) / 2) * m_wall_side_length +
std::cos(to_radians(m_corner_angle) / 2) * m_wall_side_length + line_spacing_first_layer() * wall_count();
line_spacing_first_layer() * wall_count()
;
} }
double CalibPressureAdvancePattern::object_size_y() const double CalibPressureAdvancePattern::object_size_y() const
{ {
return 2 * (std::sin(to_radians(m_corner_angle) / 2) * m_wall_side_length) + return 2 * (std::sin(to_radians(m_corner_angle) / 2) * m_wall_side_length) + max_numbering_height() + m_glyph_padding_vertical * 2 +
max_numbering_height() +
m_glyph_padding_vertical * 2 +
line_width_first_layer(); line_width_first_layer();
} }
@ -843,16 +728,14 @@ double CalibPressureAdvancePattern::glyph_start_x(int pattern_i) const
// align glyph's start with first perimeter of specified pattern // align glyph's start with first perimeter of specified pattern
double x = double x =
// starting offset // starting offset
m_starting_point.x() + m_starting_point.x() + pattern_shift() +
pattern_shift() +
// width of pattern extrusions // width of pattern extrusions
pattern_i * (wall_count() - 1) * line_spacing_angle() + // center to center distance of extrusions pattern_i * (wall_count() - 1) * line_spacing_angle() + // center to center distance of extrusions
pattern_i * line_width() + // endcaps. center to end on either side = 1 line width pattern_i * line_width() + // endcaps. center to end on either side = 1 line width
// space between each pattern // space between each pattern
pattern_i * m_pattern_spacing pattern_i * m_pattern_spacing;
;
// align to middle of pattern walls // align to middle of pattern walls
x += wall_count() * line_spacing_angle() / 2; x += wall_count() * line_spacing_angle() / 2;
@ -874,20 +757,13 @@ double CalibPressureAdvancePattern::glyph_tab_max_x() const
{ {
// only every other glyph is shown, starting with 1 // only every other glyph is shown, starting with 1
int num = get_num_patterns(); int num = get_num_patterns();
int max_num = int max_num = (num % 2 == 0) ? num - 1 : num;
(num % 2 == 0)
? num - 1
: num
;
// padding at end should be same as padding at start // padding at end should be same as padding at start
double padding = glyph_start_x(0) - m_starting_point.x(); double padding = glyph_start_x(0) - m_starting_point.x();
return return glyph_start_x(max_num - 1) + // glyph_start_x is zero-based
glyph_start_x(max_num - 1) + // glyph_start_x is zero-based (glyph_length_x() - line_width() / 2) + padding;
(glyph_length_x() - line_width() / 2) +
padding
;
} }
double CalibPressureAdvancePattern::max_numbering_height() const double CalibPressureAdvancePattern::max_numbering_height() const
@ -911,10 +787,6 @@ double CalibPressureAdvancePattern::max_numbering_height() const
double CalibPressureAdvancePattern::pattern_shift() const double CalibPressureAdvancePattern::pattern_shift() const
{ {
return return (wall_count() - 1) * line_spacing_first_layer() + line_width_first_layer() + m_glyph_padding_horizontal;
(wall_count() - 1) * line_spacing_first_layer() +
line_width_first_layer() +
m_glyph_padding_horizontal
;
} }
} // namespace Slic3r } // namespace Slic3r

View file

@ -1,4 +1,5 @@
#pragma once #pragma once
#include <string>
#define calib_pressure_advance_dd #define calib_pressure_advance_dd
#include "GCode.hpp" #include "GCode.hpp"
@ -23,24 +24,16 @@ enum class CalibMode : int {
Calib_Retraction_tower Calib_Retraction_tower
}; };
enum class CalibState { enum class CalibState { Start = 0, Preset, Calibration, CoarseSave, FineCalibration, Save, Finish };
Start = 0,
Preset,
Calibration,
CoarseSave,
FineCalibration,
Save,
Finish
};
struct Calib_Params { struct Calib_Params
Calib_Params() : mode(CalibMode::Calib_None) { }; {
Calib_Params() : mode(CalibMode::Calib_None){};
double start, end, step; double start, end, step;
bool print_numbers; bool print_numbers;
CalibMode mode; CalibMode mode;
}; };
class X1CCalibInfos class X1CCalibInfos
{ {
public: public:
@ -125,133 +118,130 @@ public:
int confidence; // 0: success 1: uncertain 2: failed int confidence; // 0: success 1: uncertain 2: failed
}; };
class CalibPressureAdvance { struct DrawBoxOptArgs
public: {
static float find_optimal_PA_speed(const DynamicPrintConfig &config, double line_width, double layer_height, DrawBoxOptArgs(int num_perimeters, double height, double line_width, double speed)
int filament_idx = 0); : num_perimeters{num_perimeters}, height{height}, line_width{line_width}, speed{speed} {};
DrawBoxOptArgs() = default;
protected: bool is_filled{false};
CalibPressureAdvance() =default; int num_perimeters;
~CalibPressureAdvance() =default; double height;
double line_width;
double speed;
};
class CalibPressureAdvance
{
public:
static float find_optimal_PA_speed(const DynamicPrintConfig &config, double line_width, double layer_height, int filament_idx = 0);
enum class DrawDigitMode { protected:
Left_To_Right, CalibPressureAdvance() = default;
Bottom_To_Top CalibPressureAdvance(const DynamicPrintConfig& config) : m_config(config){};
}; CalibPressureAdvance(const FullPrintConfig &config) { m_config.apply(config); };
~CalibPressureAdvance() = default;
void delta_scale_bed_ext(BoundingBoxf& bed_ext) const { bed_ext.scale(1.0f / 1.41421f); } enum class DrawDigitMode { Left_To_Right, Bottom_To_Top };
std::string move_to(Vec2d pt, GCodeWriter& writer, std::string comment = std::string()); void delta_scale_bed_ext(BoundingBoxf &bed_ext) const { bed_ext.scale(1.0f / 1.41421f); }
double e_per_mm(
double line_width, std::string move_to(Vec2d pt, GCodeWriter &writer, std::string comment = std::string());
double layer_height, double e_per_mm(double line_width, double layer_height, float nozzle_diameter, float filament_diameter, float print_flow_ratio) const;
float nozzle_diameter,
float filament_diameter,
float print_flow_ratio
) const;
double speed_adjust(int speed) const { return speed * 60; }; double speed_adjust(int speed) const { return speed * 60; };
std::string convert_number_to_string(double num) const; std::string convert_number_to_string(double num) const;
double number_spacing() const { return m_digit_segment_len + m_digit_gap_len; }; double number_spacing() const { return m_digit_segment_len + m_digit_gap_len; };
std::string draw_digit( std::string draw_digit(double startx,
double startx,
double starty, double starty,
char c, char c,
CalibPressureAdvance::DrawDigitMode mode, CalibPressureAdvance::DrawDigitMode mode,
double line_width, double line_width,
double e_per_mm, double e_per_mm,
GCodeWriter& writer GCodeWriter &writer);
); std::string draw_number(double startx,
std::string draw_number(
double startx,
double starty, double starty,
double value, double value,
CalibPressureAdvance::DrawDigitMode mode, CalibPressureAdvance::DrawDigitMode mode,
double line_width, double line_width,
double e_per_mm, double e_per_mm,
double speed, double speed,
GCodeWriter& writer GCodeWriter &writer);
);
std::string draw_line(
GCodeWriter &writer, Vec2d to_pt, double line_width, double layer_height, double speed, const std::string &comment = std::string());
std::string draw_box(GCodeWriter &writer, double min_x, double min_y, double size_x, double size_y, DrawBoxOptArgs opt_args);
double to_radians(double degrees) const { return degrees * M_PI / 180; };
double get_distance(Vec2d from, Vec2d to) const;
Vec3d m_last_pos; Vec3d m_last_pos;
DynamicPrintConfig m_config;
DrawDigitMode m_draw_digit_mode {DrawDigitMode::Left_To_Right}; const double m_encroachment{1. / 3.};
const double m_digit_segment_len {2}; DrawDigitMode m_draw_digit_mode{DrawDigitMode::Left_To_Right};
const double m_digit_gap_len {1}; const double m_digit_segment_len{2};
const std::string::size_type m_max_number_len {5}; const double m_digit_gap_len{1};
const std::string::size_type m_max_number_len{5};
}; };
class CalibPressureAdvanceLine : public CalibPressureAdvance { class CalibPressureAdvanceLine : public CalibPressureAdvance
{
public: public:
CalibPressureAdvanceLine(GCode* gcodegen) : CalibPressureAdvanceLine(GCode *gcodegen) : CalibPressureAdvance(gcodegen->config()), mp_gcodegen(gcodegen),m_nozzle_diameter(gcodegen->config().nozzle_diameter.get_at(0)){};
mp_gcodegen(gcodegen), ~CalibPressureAdvanceLine(){};
m_nozzle_diameter(gcodegen->config().nozzle_diameter.get_at(0))
{ };
~CalibPressureAdvanceLine() { };
std::string generate_test(double start_pa = 0, double step_pa = 0.002, int count = 50); std::string generate_test(double start_pa = 0, double step_pa = 0.002, int count = 50);
void set_speed(double fast = 100.0, double slow = 20.0) { void set_speed(double fast = 100.0, double slow = 20.0)
{
m_slow_speed = slow; m_slow_speed = slow;
m_fast_speed = fast; m_fast_speed = fast;
} }
const double& line_width() { return m_line_width; }; const double &line_width() { return m_line_width; };
bool is_delta() const; bool is_delta() const;
bool& draw_numbers() { return m_draw_numbers; } bool &draw_numbers() { return m_draw_numbers; }
private: private:
std::string print_pa_lines(double start_x, double start_y, double start_pa, double step_pa, int num); std::string print_pa_lines(double start_x, double start_y, double start_pa, double step_pa, int num);
void delta_modify_start(double& startx, double& starty, int count); void delta_modify_start(double &startx, double &starty, int count);
GCode* mp_gcodegen; GCode *mp_gcodegen;
double m_nozzle_diameter; double m_nozzle_diameter;
double m_slow_speed, m_fast_speed; double m_slow_speed, m_fast_speed;
const double m_height_layer {0.2}; const double m_height_layer{0.2};
const double m_line_width {0.6}; const double m_line_width{0.6};
const double m_thin_line_width {0.44}; const double m_thin_line_width{0.44};
const double m_number_line_width {0.48}; const double m_number_line_width{0.48};
const double m_space_y {3.5}; const double m_space_y{3.5};
double m_length_short {20.0}, m_length_long {40.0}; double m_length_short{20.0}, m_length_long{40.0};
bool m_draw_numbers {true}; bool m_draw_numbers{true};
}; };
struct SuggestedConfigCalibPAPattern { struct SuggestedConfigCalibPAPattern
const std::vector<std::pair<std::string, double>> float_pairs { {
{"initial_layer_print_height", 0.25}, const std::vector<std::pair<std::string, double>> float_pairs{{"initial_layer_print_height", 0.25},
{"layer_height", 0.2}, {"layer_height", 0.2},
{"initial_layer_speed", 30} {"initial_layer_speed", 30}};
};
const std::vector<std::pair<std::string, double>> nozzle_ratio_pairs { const std::vector<std::pair<std::string, double>> nozzle_ratio_pairs{{"line_width", 112.5}, {"initial_layer_line_width", 140}};
{"line_width", 112.5},
{"initial_layer_line_width", 140}
};
const std::vector<std::pair<std::string, int>> int_pairs { const std::vector<std::pair<std::string, int>> int_pairs{{"skirt_loops", 0}, {"wall_loops", 3}};
{"skirt_loops", 0},
{"wall_loops", 3}
};
const std::pair<std::string, BrimType> brim_pair {"brim_type", BrimType::btNoBrim}; const std::pair<std::string, BrimType> brim_pair{"brim_type", BrimType::btNoBrim};
}; };
class CalibPressureAdvancePattern : public CalibPressureAdvance { class CalibPressureAdvancePattern : public CalibPressureAdvance
friend struct DrawLineOptArgs; {
friend struct DrawBoxOptArgs; friend struct DrawBoxOptArgs;
public: public:
CalibPressureAdvancePattern( CalibPressureAdvancePattern(
const Calib_Params& params, const Calib_Params &params, const DynamicPrintConfig &config, bool is_bbl_machine, Model &model, const Vec3d &origin);
const DynamicPrintConfig& config,
bool is_bbl_machine,
Model& model,
const Vec3d& origin
);
double handle_xy_size() const { return m_handle_xy_size; }; double handle_xy_size() const { return m_handle_xy_size; };
double handle_spacing() const { return m_handle_spacing; }; double handle_spacing() const { return m_handle_spacing; };
@ -259,12 +249,7 @@ public:
double print_size_y() const { return object_size_y(); }; double print_size_y() const { return object_size_y(); };
double max_layer_z() const { return height_first_layer() + ((m_num_layers - 1) * height_layer()); }; double max_layer_z() const { return height_first_layer() + ((m_num_layers - 1) * height_layer()); };
void generate_custom_gcodes( void generate_custom_gcodes(const DynamicPrintConfig &config, bool is_bbl_machine, Model &model, const Vec3d &origin);
const DynamicPrintConfig& config,
bool is_bbl_machine,
Model& model,
const Vec3d& origin
);
protected: protected:
double speed_first_layer() const { return m_config.option<ConfigOptionFloat>("initial_layer_speed")->value; }; double speed_first_layer() const { return m_config.option<ConfigOptionFloat>("initial_layer_speed")->value; };
@ -274,68 +259,13 @@ protected:
int wall_count() const { return m_config.option<ConfigOptionInt>("wall_loops")->value; }; int wall_count() const { return m_config.option<ConfigOptionInt>("wall_loops")->value; };
private: private:
struct DrawLineOptArgs { void refresh_setup(const DynamicPrintConfig &config, bool is_bbl_machine, const Model &model, const Vec3d &origin);
DrawLineOptArgs(const CalibPressureAdvancePattern& p) : void _refresh_starting_point(const Model &model);
height {p.height_layer()}, void _refresh_writer(bool is_bbl_machine, const Model &model, const Vec3d &origin);
line_width {p.line_width()},
speed {p.speed_adjust(p.speed_perimeter())}
{ };
double height;
double line_width;
double speed;
std::string comment {"Print line"};
};
struct DrawBoxOptArgs {
DrawBoxOptArgs(const CalibPressureAdvancePattern& p) :
num_perimeters {p.wall_count()},
height {p.height_first_layer()},
line_width {p.line_width_first_layer()},
speed {p.speed_adjust(p.speed_first_layer())}
{ };
bool is_filled {false};
int num_perimeters;
double height;
double line_width;
double speed;
};
void refresh_setup(
const DynamicPrintConfig& config,
bool is_bbl_machine,
const Model& model,
const Vec3d& origin
);
void _refresh_starting_point(const Model& model);
void _refresh_writer(
bool is_bbl_machine,
const Model& model,
const Vec3d& origin
);
double height_first_layer() const { return m_config.option<ConfigOptionFloat>("initial_layer_print_height")->value; }; double height_first_layer() const { return m_config.option<ConfigOptionFloat>("initial_layer_print_height")->value; };
double height_layer() const { return m_config.option<ConfigOptionFloat>("layer_height")->value; }; double height_layer() const { return m_config.option<ConfigOptionFloat>("layer_height")->value; };
const int get_num_patterns() const const int get_num_patterns() const { return std::ceil((m_params.end - m_params.start) / m_params.step + 1); }
{
return std::ceil((m_params.end - m_params.start) / m_params.step + 1);
}
std::string draw_line(
Vec2d to_pt,
DrawLineOptArgs opt_args
);
std::string draw_box(
double min_x,
double min_y,
double size_x,
double size_y,
DrawBoxOptArgs opt_args
);
double to_radians(double degrees) const { return degrees * M_PI / 180; };
double get_distance(Vec2d from, Vec2d to) const;
/* /*
from slic3r documentation: spacing = extrusion_width - layer_height * (1 - PI/4) from slic3r documentation: spacing = extrusion_width - layer_height * (1 - PI/4)
@ -358,23 +288,21 @@ private:
double pattern_shift() const; double pattern_shift() const;
const Calib_Params& m_params; const Calib_Params &m_params;
DynamicPrintConfig m_config;
GCodeWriter m_writer; GCodeWriter m_writer;
bool m_is_delta; bool m_is_delta;
Vec3d m_starting_point; Vec3d m_starting_point;
const double m_handle_xy_size {5}; const double m_handle_xy_size{5};
const double m_handle_spacing {2}; const double m_handle_spacing{2};
const int m_num_layers {4}; const int m_num_layers{4};
const double m_wall_side_length {30.0}; const double m_wall_side_length{30.0};
const int m_corner_angle {90}; const int m_corner_angle{90};
const int m_pattern_spacing {2}; const int m_pattern_spacing{2};
const double m_encroachment {1. / 3.};
const double m_glyph_padding_horizontal {1}; const double m_glyph_padding_horizontal{1};
const double m_glyph_padding_vertical {1}; const double m_glyph_padding_vertical{1};
}; };
} // namespace Slic3r } // namespace Slic3r