Restructure calib

This commit is contained in:
thewildmage
2023-06-20 16:45:13 -06:00
parent e5d8e25e4f
commit cc1f8abd47
2 changed files with 484 additions and 557 deletions

View File

@@ -6,38 +6,40 @@
namespace Slic3r {
CalibPressureAdvance::CalibPressureAdvance(GCode* gcodegen) :
mp_gcodegen(gcodegen),
m_draw_digit_mode(DrawDigitMode::Left_To_Right),
m_digit_segment_len(2),
m_digit_gap_len(1),
m_max_number_len(5)
{
this->m_nozzle_diameter = gcodegen->config().nozzle_diameter.get_at(0);
mp_gcodegen(gcodegen)
{
if (gcodegen != nullptr) {
m_nozzle_diameter = gcodegen->config().nozzle_diameter.get_at(0);
}
;
};
bool CalibPressureAdvance::is_delta() const
{
return mp_gcodegen->config().printable_area.values.size() > 4;
}
std::string CalibPressureAdvance::move_to(Vec2d pt, std::string comment)
{
std::stringstream gcode;
GCodeWriter& writer = mp_gcodegen->writer();
gcode << mp_gcodegen->retract();
if (comment.empty()) {
gcode << mp_gcodegen->writer().travel_to_xy(pt);
} else {
gcode << mp_gcodegen->writer().travel_to_xy(pt, comment);
}
gcode << mp_gcodegen->unretract();
gcode << writer.retract();
gcode << writer.travel_to_xy(pt, comment);
gcode << writer.unretract();
return gcode.str();
return gcode.str();
}
double CalibPressureAdvance::e_per_mm(double line_width, double layer_height) {
const auto& config = mp_gcodegen->config();
double CalibPressureAdvance::e_per_mm(
double line_width,
double layer_height,
float filament_diameter,
float print_flow_ratio
) {
const Flow line_flow = Flow(line_width, layer_height, m_nozzle_diameter);
const double filament_area = M_PI * std::pow(config.filament_diameter.get_at(0) / 2, 2);
const double filament_area = M_PI * std::pow(filament_diameter / 2, 2);
return line_flow.mm3_per_mm() / filament_area * config.print_flow_ratio;
return line_flow.mm3_per_mm() / filament_area * print_flow_ratio;
}
std::string CalibPressureAdvance::convert_number_to_string(double num)
@@ -55,12 +57,9 @@ std::string CalibPressureAdvance::draw_digit(
char c,
CalibPressureAdvance::DrawDigitMode mode,
double line_width,
double layer_height
double e_per_mm
)
{
auto& writer = mp_gcodegen->writer();
std::stringstream gcode;
const double e_per_mm = CalibPressureAdvance::e_per_mm(line_width, layer_height);
const double len = m_digit_segment_len;
const double gap = line_width / 2.0;
@@ -111,6 +110,9 @@ std::string CalibPressureAdvance::draw_digit(
dot_direction = Vec2d(0, len / 2);
}
std::stringstream gcode;
GCodeWriter& writer = mp_gcodegen->writer();
switch (c) {
case '0':
gcode << move_to(p0);
@@ -200,7 +202,7 @@ std::string CalibPressureAdvance::draw_number(
double value,
CalibPressureAdvance::DrawDigitMode mode,
double line_width,
double layer_height
double e_per_mm
)
{
auto sNumber = convert_number_to_string(value);
@@ -213,32 +215,35 @@ std::string CalibPressureAdvance::draw_number(
}
switch (mode) {
case DrawDigitMode::Bottom_To_Top:
gcode << draw_digit(startx, starty + i * number_spacing(), sNumber[i], mode, line_width, layer_height);
gcode << draw_digit(startx, starty + i * number_spacing(), sNumber[i], mode, line_width, e_per_mm);
break;
default:
gcode << draw_digit(startx + i * number_spacing(), starty, sNumber[i], mode, line_width, layer_height);
gcode << draw_digit(startx + i * number_spacing(), starty, sNumber[i], mode, line_width, e_per_mm);
}
}
return gcode.str();
}
bool CalibPressureAdvance::is_delta()
{
return mp_gcodegen->config().printable_area.values.size() > 4;
}
void CalibPressureAdvance::delta_scale_bed_ext(BoundingBoxf& bed_ext)
{
bed_ext.scale(1.0f / 1.41421f);
}
CalibPressureAdvanceLine::CalibPressureAdvanceLine(GCode* gcodegen) :
CalibPressureAdvance(gcodegen),
m_thin_line_width(0.44),
m_length_short(20.0),
m_length_long(40.0),
m_space_y(3.5),
m_draw_numbers(true)
{
this->m_line_width = 0.6;
this->m_number_line_width = 0.48;
this->m_height_layer = 0.2;
}
;
std::string CalibPressureAdvanceLine::generate_test(double start_pa /*= 0*/, double step_pa /*= 0.002*/, int count /*= 10*/)
{
BoundingBoxf bed_ext = get_extents(mp_gcodegen->config().printable_area.values);
const bool is_delta = CalibPressureAdvance::is_delta();
if (is_delta) {
delta_scale_bed_ext(bed_ext);
if (is_delta()) {
CalibPressureAdvanceLine::delta_scale_bed_ext(bed_ext);
}
auto bed_sizes = mp_gcodegen->config().printable_area.values;
@@ -250,30 +255,38 @@ std::string CalibPressureAdvanceLine::generate_test(double start_pa /*= 0*/, dou
auto startx = (w - m_length_short * 2 - m_length_long - 20) / 2;
auto starty = (h - count * m_space_y) / 2;
if (is_delta) {
delta_modify_start(startx, starty, count);
if (is_delta()) {
CalibPressureAdvanceLine::delta_modify_start(startx, starty, count);
}
return print_pa_lines(startx, starty, start_pa, step_pa, count);
}
void CalibPressureAdvanceLine::delta_modify_start(double& startx, double& starty, int count)
{
startx = -startx;
starty = -(count * m_space_y) / 2;
}
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();
const auto& config = mp_gcodegen->config();
const double e_per_mm = CalibPressureAdvance::e_per_mm(m_line_width, m_layer_height);
const double thin_e_per_mm = CalibPressureAdvance::e_per_mm(m_thin_line_width, m_layer_height);
const auto filament_diameter = config.filament_diameter.get_at(0);
const auto print_flow_ratio = config.print_flow_ratio;
const double e_per_mm = CalibPressureAdvance::e_per_mm(
m_line_width,
m_height_layer,
filament_diameter,
print_flow_ratio
);
const double thin_e_per_mm = CalibPressureAdvance::e_per_mm(
m_thin_line_width,
m_height_layer,
filament_diameter,
print_flow_ratio
);
const double fast = CalibPressureAdvance::speed_adjust(m_fast_speed);
const double slow = CalibPressureAdvance::speed_adjust(m_slow_speed);
std::stringstream gcode;
gcode << mp_gcodegen->writer().travel_to_z(m_layer_height);
gcode << mp_gcodegen->writer().travel_to_z(m_height_layer);
double y_pos = start_y;
// prime line
@@ -309,185 +322,226 @@ std::string CalibPressureAdvanceLine::print_pa_lines(double start_x, double star
start_pa + i * step_pa,
DrawDigitMode::Left_To_Right,
m_number_line_width,
m_layer_height
m_height_layer
);
}
}
return gcode.str();
}
std::vector<std::string> CalibPressureAdvancePattern::generate_test(double start_pa, double end_pa, double step_pa)
void CalibPressureAdvanceLine::delta_modify_start(double& startx, double& starty, int count)
{
BoundingBoxf bed_ext = get_extents(
m_printer_config->opt<ConfigOptionPoints>("printable_area")->values
);
if (is_delta()) {
delta_scale_bed_ext(bed_ext);
}
const auto &w = bed_ext.size().x();
const auto &h = bed_ext.size().y();
const auto center_x = w / 2;
const auto center_y = h / 2;
const int num_patterns = std::ceil((end_pa - start_pa) / step_pa + 1);
auto start_x = pattern_start_x(num_patterns, center_x);
auto start_y = pattern_start_y(start_pa, step_pa, num_patterns, center_y);
CalibPressureAdvancePattern::PatternCalc pattern_calc(
start_pa,
step_pa,
num_patterns,
center_x,
center_y,
start_x,
start_y,
print_size_x(num_patterns, center_x),
frame_size_y(),
glyph_end_x(num_patterns, center_x),
glyph_tab_max_x(num_patterns, center_x)
);
if (is_delta()) {
delta_modify_start(pattern_calc);
}
return print_pa_pattern(pattern_calc);
startx = -startx;
starty = -(count * m_space_y) / 2;
}
std::vector<double> CalibPressureAdvancePattern::layer_z() {
std::vector<double> layer_z;
for (int i = 0; i < m_num_layers; ++i) {
layer_z.push_back(m_height_first_layer + (i * m_layer_height));
}
return layer_z;
}
CalibPressureAdvancePattern::PatternSettings::PatternSettings() {
DynamicPrintConfig a, b, c;
const CalibPressureAdvancePattern cpap(&a, &b, &c);
PatternSettings::PatternSettings(const CalibPressureAdvancePattern& cpap) {
anchor_line_width = cpap.line_width_anchor();
anchor_perimeters = cpap.m_anchor_perimeters;
encroachment = cpap.m_encroachment;
first_layer_height = cpap.m_height_first_layer;
first_layer_speed = cpap.speed_adjust(cpap.m_speed_first_layer);
layer_height = cpap.m_layer_height;
anchor_perimeters = cpap.anchor_perimeters();
encroachment = cpap.encroachment();
first_layer_height = cpap.height_first_layer();
first_layer_speed = cpap.speed_adjust(cpap.speed_first_layer());
layer_height = cpap.height_layer();
line_width = cpap.line_width();
perim_speed = cpap.speed_adjust(cpap.m_speed_perimeter);
perim_speed = cpap.speed_adjust(cpap.speed_perimeter());
}
void CalibPressureAdvancePattern::delta_modify_start(PatternCalc& pc)
{
pc.pattern_start_x = -pc.pattern_start_x;
pc.pattern_start_y = -(frame_size_y() / 2);
CalibPressureAdvancePattern::CalibPressureAdvancePattern(const Calib_Params& params) :
CalibPressureAdvancePattern(params, nullptr)
{ };
CalibPressureAdvancePattern::CalibPressureAdvancePattern(const Calib_Params& params, GCode* gcodegen) :
CalibPressureAdvance(gcodegen),
m_start_pa(params.start),
m_end_pa(params.end),
m_step_pa(params.step)
{
this->m_draw_digit_mode = DrawDigitMode::Bottom_To_Top;
this->m_line_width = line_width();
this->m_height_layer = 0.2;
}
double CalibPressureAdvancePattern::get_distance(double cur_x, double cur_y, double to_x, double to_y)
CustomGCode::Info CalibPressureAdvancePattern::generate_gcodes()
{
return std::hypot((to_x - cur_x), (to_y - cur_y));
}
assert(mp_gcodegen != nullptr);
double CalibPressureAdvancePattern::max_numbering_height(double start_pa, double step_pa, int num_patterns)
{
std::string::size_type most_characters = 0;
std::stringstream gcode;
GCodeWriter& writer = mp_gcodegen->writer();
// note: only every other number is printed
for (std::string::size_type i = 0; i < num_patterns; i += 2) {
std::string sNumber = convert_number_to_string(start_pa + (i * step_pa));
gcode << writer.travel_to_xyz(
Vec3d(pattern_start_x(), pattern_start_y(), m_height_first_layer),
"Move to start position"
);
if (sNumber.length() > most_characters) {
most_characters = sNumber.length();
gcode << writer.set_pressure_advance(m_start_pa);
const PatternSettings pattern_settings(*this);
const DrawBoxOptArgs default_box_opt_args(pattern_settings);
// create anchor frame
gcode << draw_box(
pattern_start_x(),
pattern_start_y(),
print_size_x(),
frame_size_y(),
default_box_opt_args
);
// create tab for numbers
DrawBoxOptArgs draw_box_opt_args = default_box_opt_args;
draw_box_opt_args.is_filled = true;
draw_box_opt_args.num_perimeters = m_anchor_perimeters;
gcode << draw_box(
pattern_start_x(),
pattern_start_y() + frame_size_y() + line_spacing_anchor(),
glyph_tab_max_x() - pattern_start_x(),
max_numbering_height() + line_spacing_anchor() + m_glyph_padding_vertical * 2,
draw_box_opt_args
);
std::vector<CustomGCode::Item> gcode_items;
const DrawLineOptArgs default_line_opt_args(pattern_settings);
const int num_patterns = get_num_patterns(); // "cache" for use in loops
// draw pressure advance pattern
for (int i = 0; i < m_num_layers; ++i) {
if (i > 0) {
CustomGCode::Item item;
item.print_z = i == 1 ? m_height_first_layer : m_height_layer;
item.type = CustomGCode::Type::Custom;
item.extra = gcode.str();
gcode_items.push_back(item);
gcode = std::stringstream(); // reset for next layer contents
}
// // line numbering
if (i == 1) {
gcode << writer.set_pressure_advance(m_start_pa);
// glyph on every other line
for (int j = 0; j < num_patterns; j += 2) {
double current_glyph_start_x =
pattern_start_x() +
(j * (m_pattern_spacing + line_width())) +
(j * ((m_wall_count - 1) * line_spacing_angle())) // this aligns glyph starts with first pattern perim
;
// shift glyph center to middle of pattern walls. m_digit_segment_len = half of x width of glyph
current_glyph_start_x +=
(((m_wall_count - 1) / 2) * line_spacing_angle()) - m_digit_segment_len
;
current_glyph_start_x += pattern_shift();
gcode << draw_number(
current_glyph_start_x,
pattern_start_y() + frame_size_y() + m_glyph_padding_vertical + line_width(),
m_start_pa + (j * m_step_pa),
DrawDigitMode::Bottom_To_Top,
m_line_width,
m_height_layer
);
}
}
DrawLineOptArgs draw_line_opt_args = default_line_opt_args;
double to_x = pattern_start_x() + pattern_shift();
double to_y = pattern_start_y();
double side_length = m_wall_side_length;
if (i == 0) {
// shrink first layer to fit inside frame
double shrink =
(
line_spacing_anchor() * (m_anchor_perimeters - 1) +
(line_width_anchor() * (1 - m_encroachment))
) / std::sin(to_radians(m_corner_angle) / 2)
;
side_length = m_wall_side_length - shrink;
to_x += shrink * std::sin(to_radians(90) - to_radians(m_corner_angle) / 2);
to_y +=
line_spacing_anchor() * (m_anchor_perimeters - 1) +
(line_width_anchor() * (1 - m_encroachment))
;
}
double initial_x = to_x;
double initial_y = to_y;
gcode << move_to(Vec2d(to_x, to_y), "Move to pattern start");
for (int j = 0; j < num_patterns; ++j) {
// increment pressure advance
gcode << writer.set_pressure_advance(m_start_pa + (j * m_step_pa));
for (int k = 0; k < m_wall_count; ++k) {
to_x += std::cos(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;
draw_line_opt_args.height = i == 0 ? m_height_first_layer : m_height_layer;
draw_line_opt_args.speed = i == 0 ? m_speed_first_layer : m_speed_perimeter;
draw_line_opt_args.comment = "Print pattern wall";
gcode << draw_line(to_x, to_y, draw_line_opt_args);
to_x -= std::cos(to_radians(m_corner_angle) / 2) * side_length;
to_y += std::sin(to_radians(m_corner_angle) / 2) * side_length;
gcode << draw_line(to_x, to_y, draw_line_opt_args);
to_y = initial_y;
if (k != m_wall_count - 1) {
// perimeters not done yet. move to next perimeter
to_x += line_spacing_angle();
gcode << move_to(Vec2d(to_x, to_y), "Move to start next pattern wall");
} else if (j != num_patterns - 1) {
// patterns not done yet. move to next pattern
to_x += m_pattern_spacing + line_width();
gcode << move_to(Vec2d(to_x, to_y), "Move to next pattern");
} else if (i != m_num_layers - 1) {
// layers not done yet. move back to start
to_x = initial_x;
gcode << move_to(Vec2d(to_x, to_y), "Move back to start position");
} else {
// everything done
}
}
}
}
most_characters = std::min(most_characters, m_max_number_len);
// set pressure advance back to start value
gcode << writer.set_pressure_advance(m_start_pa);
return (most_characters * m_digit_segment_len) + ((most_characters - 1) * m_digit_gap_len);
}
CustomGCode::Item item;
item.print_z = m_height_layer;
item.type = CustomGCode::Type::Custom;
item.extra = gcode.str();
double CalibPressureAdvancePattern::object_size_x(int num_patterns)
{
return num_patterns * ((m_wall_count - 1) * line_spacing_angle()) +
(num_patterns - 1) * (m_pattern_spacing + line_width()) +
std::cos(to_radians(m_corner_angle) / 2) * m_wall_side_length +
line_spacing_anchor() * m_anchor_perimeters
;
}
gcode_items.push_back(item);
double CalibPressureAdvancePattern::object_size_y(double start_pa, double step_pa, int num_patterns)
{
return 2 * (std::sin(to_radians(m_corner_angle) / 2) * m_wall_side_length) +
max_numbering_height(start_pa, step_pa, num_patterns) +
m_glyph_padding_vertical * 2 +
line_width_anchor();
}
CustomGCode::Info info;
info.mode = CustomGCode::Mode::SingleExtruder;
info.gcodes = gcode_items;
double CalibPressureAdvancePattern::glyph_start_x(int num_patterns, double center_x)
{
return
center_x -
object_size_x(num_patterns) / 2 +
(((m_wall_count - 1) / 2) * line_spacing_angle() - 2)
;
}
double CalibPressureAdvancePattern::glyph_end_x(int num_patterns, double center_x)
{
return
center_x -
object_size_x(num_patterns) / 2 +
(num_patterns - 1) * (m_pattern_spacing + line_width()) +
(num_patterns - 1) * ((m_wall_count - 1) * line_spacing_angle()) +
4
;
}
double CalibPressureAdvancePattern::glyph_tab_max_x(int num_patterns, double center_x)
{
return
glyph_end_x(num_patterns, center_x) +
m_glyph_padding_horizontal +
line_width_anchor() / 2
;
}
double CalibPressureAdvancePattern::pattern_shift(int num_patterns, double center_x)
{
auto shift =
center_x -
object_size_x(num_patterns) / 2 -
glyph_start_x(num_patterns, center_x) +
m_glyph_padding_horizontal
;
if (shift > 0) {
return shift + line_width_anchor() / 2;
}
return 0;
return info;
}
std::string CalibPressureAdvancePattern::draw_line(double to_x, double to_y, DrawLineOptArgs opt_args)
{
std::stringstream gcode;
const auto& config = mp_gcodegen->config();
auto& writer = mp_gcodegen->writer();
const double e_per_mm = CalibPressureAdvance::e_per_mm(opt_args.line_width, opt_args.height);
const double e_per_mm = CalibPressureAdvance::e_per_mm(
opt_args.line_width,
opt_args.height,
mp_gcodegen->config().filament_diameter.get_at(0),
mp_gcodegen->config().filament_flow_ratio.get_at(0)
);
const Point last_pos = mp_gcodegen->last_pos();
const double length = get_distance(last_pos.x(), last_pos.y(), to_x, to_y);
auto dE = e_per_mm * length;
// TODO: set speed? save current and reset after line?
gcode << writer.extrude_to_xy(Vec2d(to_x, to_y), dE, opt_args.comment);
gcode << mp_gcodegen->writer().extrude_to_xy(Vec2d(to_x, to_y), dE, opt_args.comment);
return gcode.str();
}
@@ -516,7 +570,8 @@ std::string CalibPressureAdvancePattern::draw_box(double min_x, double min_y, do
gcode << move_to(Vec2d(min_x, min_y), "Move to box start");
DrawLineOptArgs line_opt_args;
PatternSettings ps(*this);
DrawLineOptArgs line_opt_args(ps);
line_opt_args.height = opt_args.height;
line_opt_args.line_width = opt_args.line_width;
line_opt_args.speed = opt_args.speed;
@@ -680,166 +735,127 @@ std::string CalibPressureAdvancePattern::draw_box(double min_x, double min_y, do
return gcode.str();
}
std::vector<std::string> CalibPressureAdvancePattern::print_pa_pattern(PatternCalc& calc)
{
auto& writer = mp_gcodegen->writer();
std::stringstream gcode;
std::vector<std::string> gcode_layers;
double CalibPressureAdvancePattern::get_distance(double cur_x, double cur_y, double to_x, double to_y)
{
return std::hypot((to_x - cur_x), (to_y - cur_y));
}
gcode << writer.travel_to_xyz(
Vec3d(calc.pattern_start_x, calc.pattern_start_y, m_height_first_layer),
"Move to start position"
);
Point CalibPressureAdvancePattern::bed_center()
{
BoundingBoxf bed_ext = get_extents(mp_gcodegen->config().printable_area.values);
if (is_delta()) {
delta_scale_bed_ext(bed_ext);
}
gcode << writer.set_pressure_advance(calc.start_pa);
double center_x = bed_ext.size().x() / 2;
double center_y = bed_ext.size().y() / 2;
const DrawBoxOptArgs draw_box_basic_settings;
DrawBoxOptArgs draw_box_opt_args;
return Point(center_x, center_y);
}
// create anchor frame
gcode << draw_box(
calc.pattern_start_x,
calc.pattern_start_y,
calc.print_size_x,
calc.frame_size_y,
draw_box_basic_settings
);
double CalibPressureAdvancePattern::object_size_x()
{
return get_num_patterns() * ((m_wall_count - 1) * line_spacing_angle()) +
(get_num_patterns() - 1) * (m_pattern_spacing + line_width()) +
std::cos(to_radians(m_corner_angle) / 2) * m_wall_side_length +
line_spacing_anchor() * m_anchor_perimeters
;
}
// create tab for numbers
draw_box_opt_args = draw_box_basic_settings;
draw_box_opt_args.is_filled = true;
draw_box_opt_args.num_perimeters = m_anchor_perimeters;
gcode << draw_box(
calc.pattern_start_x,
calc.pattern_start_y + calc.frame_size_y + line_spacing_anchor(),
glyph_tab_max_x(calc.num_patterns, calc.center_x) - calc.pattern_start_x,
max_numbering_height(calc.start_pa, calc.step_pa, calc.num_patterns) + line_spacing_anchor() + m_glyph_padding_vertical * 2,
draw_box_opt_args
);
double CalibPressureAdvancePattern::object_size_y()
{
return 2 * (std::sin(to_radians(m_corner_angle) / 2) * m_wall_side_length) +
max_numbering_height() +
m_glyph_padding_vertical * 2 +
line_width_anchor();
}
// draw pressure advance pattern
for (int i = 0; i < m_num_layers; ++i) {
if (i == 1) {
// TODO?
// set new fan speed after first layer
}
double CalibPressureAdvancePattern::glyph_start_x()
{
return
bed_center().x() -
object_size_x() / 2 +
(((m_wall_count - 1) / 2) * line_spacing_angle() - 2)
;
}
if (i > 0) {
gcode_layers.push_back(gcode.str());
gcode = std::stringstream(); // reset for next layer contents
double CalibPressureAdvancePattern::glyph_end_x()
{
return
bed_center().x() -
object_size_x() / 2 +
(get_num_patterns() - 1) * (m_pattern_spacing + line_width()) +
(get_num_patterns() - 1) * ((m_wall_count - 1) * line_spacing_angle()) +
4
;
}
Point last_pos = mp_gcodegen->last_pos();
std::stringstream comment;
comment << "move to next layer (" << i + 1 << ")";
gcode << writer.travel_to_xyz(
Vec3d(
last_pos.x(),
last_pos.y(),
m_height_first_layer + (i * m_layer_height)
),
comment.str()
);
}
double CalibPressureAdvancePattern::glyph_tab_max_x()
{
return
glyph_end_x() +
m_glyph_padding_horizontal +
line_width_anchor() / 2
;
}
// line numbering
if (i == 1) {
gcode << writer.set_pressure_advance(calc.start_pa);
double CalibPressureAdvancePattern::max_numbering_height()
{
std::string::size_type most_characters = 0;
const int num_patterns = get_num_patterns();
// glyph on every other line
for (int j = 0; j < calc.num_patterns; j += 2) {
double current_glyph_start_x =
calc.pattern_start_x +
(j * (m_pattern_spacing + line_width())) +
(j * ((m_wall_count - 1) * line_spacing_angle())) // this aligns glyph starts with first pattern perim
;
// shift glyph center to middle of pattern walls. m_digit_segment_len = half of x width of glyph
current_glyph_start_x +=
(((m_wall_count - 1) / 2) * line_spacing_angle()) - m_digit_segment_len
;
current_glyph_start_x += pattern_shift(calc.num_patterns, calc.center_x);
// note: only every other number is printed
for (std::string::size_type i = 0; i < num_patterns; i += 2) {
std::string sNumber = convert_number_to_string(m_start_pa + (i * m_step_pa));
gcode << draw_number(
current_glyph_start_x,
calc.pattern_start_y + calc.frame_size_y + m_glyph_padding_vertical + line_width(),
calc.start_pa + (j * calc.step_pa),
DrawDigitMode::Bottom_To_Top,
m_line_width,
m_layer_height
);
}
}
const DrawLineOptArgs draw_line_basic_settings;
DrawLineOptArgs draw_line_opt_args;
double to_x = calc.pattern_start_x + pattern_shift(calc.num_patterns, calc.center_x);
double to_y = calc.pattern_start_y;
double side_length = m_wall_side_length;
if (i == 0) {
// shrink first layer to fit inside frame
double shrink =
(
line_spacing_anchor() * (m_anchor_perimeters - 1) +
(line_width_anchor() * (1 - m_encroachment))
) / std::sin(to_radians(m_corner_angle) / 2)
;
side_length = m_wall_side_length - shrink;
to_x += shrink * std::sin(to_radians(90) - to_radians(m_corner_angle) / 2);
to_y +=
line_spacing_anchor() * (m_anchor_perimeters - 1) +
(line_width_anchor() * (1 - m_encroachment))
;
}
double initial_x = to_x;
double initial_y = to_y;
gcode << move_to(Vec2d(to_x, to_y), "Move to pattern start");
for (int j = 0; j < calc.num_patterns; ++j) {
// increment pressure advance
gcode << writer.set_pressure_advance(calc.start_pa + (j * calc.step_pa));
for (int k = 0; k < m_wall_count; ++k) {
to_x += std::cos(to_radians(m_corner_angle) / 2) * side_length;
to_y += std::sin(to_radians(m_corner_angle) / 2) * side_length;
draw_line_opt_args = draw_line_basic_settings;
draw_line_opt_args.height = i == 0 ? m_height_first_layer : m_layer_height;
draw_line_opt_args.speed = i == 0 ? m_speed_first_layer : m_speed_perimeter;
draw_line_opt_args.comment = "Print pattern wall";
gcode << draw_line(to_x, to_y, draw_line_opt_args);
to_x -= std::cos(to_radians(m_corner_angle) / 2) * side_length;
to_y += std::sin(to_radians(m_corner_angle) / 2) * side_length;
gcode << draw_line(to_x, to_y, draw_line_opt_args);
to_y = initial_y;
if (k != m_wall_count - 1) {
// perimeters not done yet. move to next perimeter
to_x += line_spacing_angle();
gcode << move_to(Vec2d(to_x, to_y), "Move to start next pattern wall");
} else if (j != calc.num_patterns - 1) {
// patterns not done yet. move to next pattern
to_x += m_pattern_spacing + line_width();
gcode << move_to(Vec2d(to_x, to_y), "Move to next pattern");
} else if (i != m_num_layers - 1) {
// layers not done yet. move back to start
to_x = initial_x;
gcode << move_to(Vec2d(to_x, to_y), "Move back to start position");
} else {
// everything done
}
}
if (sNumber.length() > most_characters) {
most_characters = sNumber.length();
}
}
// set pressure advance back to start value
gcode << writer.set_pressure_advance(calc.start_pa);
most_characters = std::min(most_characters, m_max_number_len);
gcode_layers.push_back(gcode.str());
return gcode_layers;
return (most_characters * m_digit_segment_len) + ((most_characters - 1) * m_digit_gap_len);
}
double CalibPressureAdvancePattern::pattern_shift()
{
auto shift =
bed_center().x() -
object_size_x() / 2 -
glyph_start_x() +
m_glyph_padding_horizontal
;
if (shift > 0) {
return shift + line_width_anchor() / 2;
}
return 0;
}
double CalibPressureAdvancePattern::pattern_start_x()
{
double pattern_start_x =
bed_center().x() -
(object_size_x() + pattern_shift()) / 2
;
if (is_delta()) {
pattern_start_x = -pattern_start_x;
}
return pattern_start_x;
};
double CalibPressureAdvancePattern::pattern_start_y()
{
double pattern_start_y = bed_center().y() - object_size_y() / 2;
if (is_delta()) {
pattern_start_y = -(frame_size_y() / 2);
}
return pattern_start_y;
};
} // namespace Slic3r

View File

@@ -2,6 +2,8 @@
#define calib_pressure_advance_dd
#include <string>
#include "CustomGCode.hpp"
#include "GCodeWriter.hpp"
#include "Point.hpp"
#include "PrintConfig.hpp"
namespace Slic3r {
@@ -19,8 +21,7 @@ enum class CalibMode : int {
Calib_Retraction_tower
};
struct Calib_Params
{
struct Calib_Params {
Calib_Params() : mode(CalibMode::Calib_None) { };
double start, end, step;
bool print_numbers;
@@ -29,12 +30,7 @@ struct Calib_Params
class CalibPressureAdvance {
protected:
CalibPressureAdvance() :
m_draw_digit_mode(DrawDigitMode::Left_To_Right),
m_digit_segment_len(2),
m_digit_gap_len(1),
m_max_number_len(5)
{ };
CalibPressureAdvance() : mp_gcodegen(nullptr) { };
CalibPressureAdvance(GCode* gcodegen);
~CalibPressureAdvance() { };
@@ -43,19 +39,27 @@ protected:
Bottom_To_Top
};
bool is_delta() const;
void delta_scale_bed_ext(BoundingBoxf& bed_ext) { bed_ext.scale(1.0f / 1.41421f); }
std::string move_to(Vec2d pt, std::string comment = std::string());
double e_per_mm(double line_width, double layer_height);
double speed_adjust(int speed) const { return speed * 60; };
double e_per_mm(
double line_width,
double layer_height,
float filament_diameter,
float print_flow_ratio
);
double speed_adjust(int speed) const { return speed * 60; };
std::string convert_number_to_string(double num);
double number_spacing() { return m_digit_segment_len + m_digit_gap_len; };
double number_spacing() { return m_digit_segment_len + m_digit_gap_len; };
std::string draw_digit(
double startx,
double starty,
char c,
CalibPressureAdvance::DrawDigitMode mode,
double line_width,
double layer_height
double e_per_mm
);
std::string draw_number(
double startx,
@@ -65,37 +69,22 @@ protected:
double line_width,
double layer_height
);
bool is_delta();
void delta_scale_bed_ext(BoundingBoxf& bed_ext);
GCode* mp_gcodegen;
DrawDigitMode m_draw_digit_mode;
double m_digit_segment_len;
double m_digit_gap_len;
std::string::size_type m_max_number_len;
DrawDigitMode m_draw_digit_mode {DrawDigitMode::Left_To_Right};
double m_digit_segment_len {2};
double m_digit_gap_len {1};
std::string::size_type m_max_number_len {5};
double m_nozzle_diameter;
double m_line_width;
double m_layer_height;
double m_height_layer;
};
class CalibPressureAdvanceLine : public CalibPressureAdvance {
public:
CalibPressureAdvanceLine(GCode* gcodegen) :
CalibPressureAdvance(gcodegen),
m_thin_line_width(0.44),
m_length_short(20.0),
m_length_long(40.0),
m_space_y(3.5),
m_draw_numbers(true)
{
this->m_line_width = 0.6;
this->m_number_line_width = 0.48;
this->m_layer_height = 0.2;
}
;
CalibPressureAdvanceLine(GCode* gcodegen);
~CalibPressureAdvanceLine() { };
std::string generate_test(double start_pa = 0, double step_pa = 0.002, int count = 50);
@@ -106,11 +95,12 @@ public:
}
double& line_width() { return m_line_width; };
bool& draw_numbers() { return m_draw_numbers; }
bool& draw_numbers() { return m_draw_numbers; }
private:
void delta_modify_start(double& startx, double& starty, int count);
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);
double m_thin_line_width;
double m_number_line_width;
@@ -120,212 +110,133 @@ private:
bool m_draw_numbers;
};
class CalibPressureAdvancePattern;
struct PatternSettings {
friend class CalibPressureAdvancePattern;
friend struct DrawLineOptArgs;
friend struct DrawBoxOptArgs;
private:
PatternSettings(const CalibPressureAdvancePattern& cpap);
double anchor_line_width;
int anchor_perimeters;
double encroachment;
double first_layer_height;
int first_layer_speed;
double layer_height;
double line_width;
int perim_speed;
};
struct DrawLineOptArgs {
friend class CalibPressureAdvancePattern;
private:
DrawLineOptArgs(const PatternSettings ps) {
height = ps.layer_height;
line_width = ps.line_width;
speed = ps.perim_speed;
};
double height;
double line_width;
int speed;
std::string comment {"Print line"};
};
struct DrawBoxOptArgs {
friend class CalibPressureAdvancePattern;
private:
DrawBoxOptArgs(const PatternSettings ps) {
num_perimeters = ps.anchor_perimeters;
height = ps.first_layer_height;
line_width = ps.anchor_line_width;
speed = ps.first_layer_speed;
};
bool is_filled {false};
int num_perimeters;
double height;
double line_width;
double speed;
};
class CalibPressureAdvancePattern : public CalibPressureAdvance {
friend struct PatternSettings;
public:
CalibPressureAdvancePattern(
DynamicPrintConfig* printer_config,
DynamicPrintConfig* print_config,
DynamicPrintConfig* filament_config
) :
m_printer_config(printer_config),
m_print_config(print_config),
m_filament_config(filament_config),
m_line_ratio(112.5),
m_num_layers(4),
m_height_first_layer(0.25),
m_speed_first_layer(30),
m_speed_perimeter(100),
m_anchor_perimeters(4),
m_anchor_layer_line_ratio(140),
m_prime_zone_buffer(10.0),
m_wall_count(3),
m_wall_side_length(30.0),
m_corner_angle(90),
m_pattern_spacing(2),
m_encroachment(1. / 3.),
m_glyph_padding_horizontal(1),
m_glyph_padding_vertical(1)
{
this->m_draw_digit_mode = DrawDigitMode::Bottom_To_Top;
this->m_line_width = line_width();
this->m_layer_height = 0.2;
this->m_max_layer_z = m_height_first_layer + ((m_num_layers - 1) * m_layer_height);
}
;
CalibPressureAdvancePattern(const Calib_Params& params);
CalibPressureAdvancePattern(const Calib_Params& params, GCode* gcodegen);
~CalibPressureAdvancePattern() { };
std::vector<std::string> generate_test(
double start_pa = 0,
double end_pa = 0.08,
double step_pa = 0.005
);
CustomGCode::Info generate_gcodes();
int num_layers() const { return m_num_layers; };
std::vector<double> layer_z();
double max_layer_z() const { return m_max_layer_z; }
double max_layer_z() { return m_height_first_layer + ((m_num_layers - 1) * m_height_layer); };
double first_layer_height() const { return m_height_first_layer; };
double layer_height() const { return m_layer_height; };
double height_first_layer() const { return m_height_first_layer; };
double height_layer() const { return m_height_layer; };
protected:
double line_width() const { return m_nozzle_diameter * m_line_ratio / 100; };
double line_width_anchor() const { return m_nozzle_diameter * m_anchor_layer_line_ratio / 100; };
double speed_first_layer() const { return m_speed_first_layer; };
double speed_perimeter() const { return m_speed_perimeter; };
int anchor_perimeters() const { return m_anchor_perimeters; };
double encroachment() const { return m_encroachment; };
private:
struct PatternCalc {
PatternCalc(
double start_pa,
double step_pa,
int num_patterns,
int get_num_patterns() const
{
return std::ceil((m_end_pa - m_start_pa) / m_step_pa + 1);
}
double center_x,
double center_y,
double pattern_start_x,
double pattern_start_y,
double print_size_x,
double frame_size_y,
double glyph_end_x,
double glyph_tab_max_x
) :
start_pa(start_pa),
step_pa(step_pa),
num_patterns(num_patterns),
center_x(center_x),
center_y(center_y),
pattern_start_x(pattern_start_x),
pattern_start_y(pattern_start_y),
print_size_x(print_size_x),
frame_size_y(frame_size_y),
glyph_end_x(glyph_end_x),
glyph_tab_max_x(glyph_tab_max_x)
{ };
double start_pa;
double step_pa;
int num_patterns;
double center_x;
double center_y;
double pattern_start_x;
double pattern_start_y;
double print_size_x;
double frame_size_y;
double glyph_end_x;
double glyph_tab_max_x;
};
struct PatternSettings {
PatternSettings();
double anchor_line_width;
int anchor_perimeters;
double encroachment;
double first_layer_height;
int first_layer_speed;
double layer_height;
double line_width;
int perim_speed;
};
struct DrawLineOptArgs {
public:
DrawLineOptArgs() {
height = _ps.layer_height;
line_width = _ps.line_width;
speed = _ps.perim_speed;
comment = "Print line";
};
double height;
double line_width;
int speed;
std::string comment;
private:
PatternSettings _ps = PatternSettings();
};
struct DrawBoxOptArgs {
public:
DrawBoxOptArgs() {
is_filled = false;
num_perimeters = _ps.anchor_perimeters;
height = _ps.first_layer_height;
line_width = _ps.anchor_line_width;
speed = _ps.first_layer_speed;
};
bool is_filled;
int num_perimeters;
double height;
double line_width;
double speed;
private:
PatternSettings _ps = PatternSettings();
};
void delta_modify_start(PatternCalc& pc);
std::string draw_line(double to_x, double to_y, 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(double cur_x, double cur_y, double to_x, double to_y);
double line_width() const { return m_nozzle_diameter * m_line_ratio / 100; };
double line_width_anchor() const { return m_nozzle_diameter * m_anchor_layer_line_ratio / 100; };
// from slic3r documentation: spacing = extrusion_width - layer_height * (1 - PI/4)
double line_spacing() { return line_width() - m_layer_height * (1 - M_PI / 4); };
double line_spacing() { return line_width() - m_height_layer * (1 - M_PI / 4); };
double line_spacing_anchor() { return line_width_anchor() - m_height_first_layer * (1 - M_PI / 4); };
double line_spacing_angle() { return line_spacing() / std::sin(to_radians(m_corner_angle) / 2); };
double max_numbering_height(double start_pa, double step_pa, int num_patterns);
double object_size_x(int num_patterns);
double object_size_y(double start_pa, double step_pa, int num_patterns);
Point bed_center();
double object_size_x();
double object_size_y();
double frame_size_y() { return std::sin(to_radians(double(m_corner_angle) / 2)) * m_wall_side_length * 2; };
double glyph_start_x(int num_patterns, double center_x);
double glyph_end_x(int num_patterns, double center_x);
double glyph_tab_max_x(int num_patterns, double center_x);
double glyph_start_x();
double glyph_end_x();
double glyph_tab_max_x();
double max_numbering_height();
double pattern_shift(int num_patterns, double center_x);
double print_size_x(int num_patterns, double center_x) { return object_size_x(num_patterns) + pattern_shift(num_patterns, center_x); };
double print_size_y(double start_pa, double step_pa, int num_patterns) { return object_size_y(start_pa, step_pa, num_patterns); };
double pattern_shift();
double print_size_x() { return object_size_x() + pattern_shift(); };
double print_size_y() { return object_size_y(); };
double pattern_start_x(int num_patterns, double center_x) { return center_x - (object_size_x(num_patterns) + pattern_shift(num_patterns, center_x)) / 2; };
double pattern_start_y(double start_pa, double step_pa, int num_patterns, double center_y) { return center_y - object_size_y(start_pa, step_pa, num_patterns) / 2; };
double pattern_start_x();
double pattern_start_y();
std::string draw_line(double to_x, double to_y, DrawLineOptArgs opt_args = DrawLineOptArgs());
std::string draw_box(double min_x, double min_y, double size_x, double size_y, DrawBoxOptArgs opt_args = DrawBoxOptArgs());
const double m_start_pa;
const double m_end_pa;
const double m_step_pa;
std::vector<std::string> print_pa_pattern(PatternCalc& calc);
DynamicPrintConfig* m_printer_config;
DynamicPrintConfig* m_print_config;
DynamicPrintConfig* m_filament_config;
double m_line_ratio;
int m_num_layers;
double m_height_first_layer;
double m_max_layer_z;
double m_speed_first_layer;
double m_speed_perimeter;
double m_line_ratio {112.5};
int m_num_layers {4};
double m_height_first_layer {0.25};
double m_speed_first_layer {30};
double m_speed_perimeter {100};
int m_anchor_perimeters;
int m_anchor_layer_line_ratio;
int m_anchor_perimeters {4};
int m_anchor_layer_line_ratio {140};
double m_prime_zone_buffer;
int m_wall_count;
double m_wall_side_length;
int m_corner_angle;
int m_pattern_spacing;
double m_encroachment;
double m_prime_zone_buffer {10};
int m_wall_count {3};
double m_wall_side_length {30.0};
int m_corner_angle {90};
int m_pattern_spacing {2};
double m_encroachment {1. / 3.};
double m_glyph_padding_horizontal;
double m_glyph_padding_vertical;
double m_glyph_padding_horizontal {1};
double m_glyph_padding_vertical {1};
};
} // namespace Slic3r