Add Ellis' pattern method for pressure advance calibration (#1547)

* Add pattern method to Pressure Advance dialog

* Convert calib_pressure_advance to more unique calib_pressure_advance_line

* Share move_to function with PA lines and patterns

* Add PA pattern to calib.hpp

* Implement move_to(Vec3d). Combine with Vec2d version

* Add call to PA pattern in GCode.cpp

* Add helper functions

* Add directionality to draw_digit

* Extract shared number drawing variables

* Extract convert_number_to_string function

* Use in-class initializers for pattern variables

* Add max_numbering_height function

* Add helper functions

* Extract shared delta helper functions

* Add pattern generate_test() and associated helpers

* Clarify use of math functions

* Remove unused move_to overload, accept move_to comments

* Add get_distance() and draw_line()

* Extract set_nozzle_diameter()

* Clean up and simplify

* Rearrange and clean up

* Start work on print_pa_pattern

* Complete basic draw_box function

* Add more helper functions

* Add struct for pattern config, more helpers

* Rearrange

* Add encroachment member variable

* Add structs to manage optional arguments

* Simplify optional arguments structs

* Update opt args usage. Finish draw_box function

* Complete print_pa_pattern function

* Reuse PA Line STL

* Fix forward declaration error

* Fix invalid comparison

* Fixing complier errors

* Make DrawDigitMode options more clear

* More compilation error fixes

* Yet more compile error fixes

* Fix incorrect default step value

* Handle top-level dialog changes, consolidate params definitions

* Add layer change G-code, set more print variables

* Simplify optArgs constructors

* Fix pattern drawing, minor misc. clean up

* Make draw_box() G-code comments more helpful

* Make more of draw_line() const

* Fix sequential number draw direction

* Extract shared e_per_mm function

* Fix misplaced decimal in PA Line

* Move short constructor into .hpp

* Fix inverted Y direction in pattern digit drawing

* Use placeholder STL to create needed layers

* Rearrange and clean up

* Proof of concept: Adding custom G-Code at layer

* Use new scaling method

* Reorganize Plater::calib_pa()

* Restructure calib

* New strategy for adding custom G-code

* Remove redundant invocation

* Use cube primitive as positioning handle

* Move logic to Plater

Modifications to model in GCode cancelled _do_export from within itself

* Consolidate m_starting_point and pattern_start functions

* Replace bed_center() with m_starting_point

* Fix and consolidate number tab creation

* Fix off by one layer bug

* Use correct bounding box

* Use Vec3d instead of Vec2d for m_starting_point and m_last_pos

* Add translate_starting_point function

* Vec3d fix

* Store CalibPressureAdvancePattern with model

* Formatting adjustments

* Move pattern when handle moves

* Improve const correctness

* Improve/fix pattern writer and config

* Fix speed setting bug

* Pass model into generate_gcodes to improve consistency

* Re-generate pattern on reslice

* Make pattern actually move with handle

* Fix overzealous m_last_pos initialization

* Use clearer function names

* Use correct model

* Remove unused member variable

* Don't hard-code print config settings

* Remove unused lines, formatting clean up

* Make sure set_key_value operates on existing keys

* Remove asserts which limited life of key/value set

* Update Calibration.md

* Update licensing info

* Actually use speed in draw_line

* Don't speed_adjust twice

* doc: Make width and speed settings used more clear

* Bugfix: Shouldn't need to move handle to see pattern

* Clean up

* Move mp_gcodegen into line method alone

* Fix wrong number thickness in PA Line

* Remove unnecessary middleman PatternSettings

* Give value of config to const m_initial_config, not ref

* Fix incorrect DrawBoxOptArg default

* Use line_width_anchor() for all of initial layer

* Use clearer function name

* Replace "anchor" with "first_layer" for better consistency

* Update Calibration.md

* Update Calibration.md

* Make number tab infill explanation more clear

* (Hopefully) fix missing origin

* Add GCodeProcessor tags

* Fully refresh config

* Don't store is_bbl_printer

* Move set_starting_point to private

* Don't constantly recreate GCodeWriter

* Use different step value for pattern test

* Remove redundant processor tags

* Label glyph G-code

* Fix comparison typo

* Set number print speed

* Fix mixed up draw_number parameter

* Don't use line_width_first_layer for pattern

* (Hopefully) fix temp tower generating PA pattern

* Start with pattern centered on plate

* Add gap between pattern and handle

* Fix overly persistent pattern

* Revert "(Hopefully) fix temp tower generating PA pattern"

This reverts commit 0aa1206886.

---------

Co-authored-by: SoftFever <softfeverever@gmail.com>
This commit is contained in:
thewildmage 2023-07-22 06:48:56 -06:00 committed by GitHub
parent 87f6c43784
commit 777c7c68f9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 1396 additions and 296 deletions

View file

@ -1,55 +1,274 @@
#pragma once
#define calib_pressure_advance_dd
#include <string>
#include "Point.hpp"
namespace Slic3r {
#include "GCode.hpp"
#include "GCodeWriter.hpp"
#include "PrintConfig.hpp"
class GCode;
namespace Slic3r {
enum class CalibMode : int {
Calib_None = 0,
Calib_PA_Line,
Calib_PA_Pattern,
Calib_PA_Tower,
Calib_Temp_Tower,
Calib_Vol_speed_Tower,
Calib_VFA_Tower,
Calib_Retraction_tower
};
struct Calib_Params
{
Calib_Params();
struct Calib_Params {
Calib_Params() : mode(CalibMode::Calib_None) { };
double start, end, step;
bool print_numbers;
CalibMode mode;
};
class calib_pressure_advance
{
class CalibPressureAdvance {
protected:
CalibPressureAdvance() =default;
~CalibPressureAdvance() =default;
enum class DrawDigitMode {
Left_To_Right,
Bottom_To_Top
};
void delta_scale_bed_ext(BoundingBoxf& bed_ext) const { bed_ext.scale(1.0f / 1.41421f); }
std::string move_to(Vec2d pt, GCodeWriter& writer, std::string comment = std::string());
double e_per_mm(
double line_width,
double layer_height,
float nozzle_diameter,
float filament_diameter,
float print_flow_ratio
) const;
double speed_adjust(int speed) const { return speed * 60; };
std::string convert_number_to_string(double num) const;
double number_spacing() const { 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 e_per_mm,
GCodeWriter& writer
);
std::string draw_number(
double startx,
double starty,
double value,
CalibPressureAdvance::DrawDigitMode mode,
double line_width,
double e_per_mm,
double speed,
GCodeWriter& writer
);
Vec3d m_last_pos;
DrawDigitMode m_draw_digit_mode {DrawDigitMode::Left_To_Right};
const double m_digit_segment_len {2};
const double m_digit_gap_len {1};
const std::string::size_type m_max_number_len {5};
};
class CalibPressureAdvanceLine : public CalibPressureAdvance {
public:
calib_pressure_advance(GCode* gcodegen);
~calib_pressure_advance() {}
CalibPressureAdvanceLine(GCode* gcodegen) :
mp_gcodegen(gcodegen),
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);
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_fast_speed = fast;
}
double& line_width() { return m_line_width; };
bool& draw_numbers() { return m_draw_numbers; }
const double& line_width() { return m_line_width; };
bool is_delta() const;
bool& draw_numbers() { return m_draw_numbers; }
private:
std::string move_to(Vec2d pt);
std::string print_pa_lines(double start_x, double start_y, double start_pa, double step_pa, int num);
std::string draw_digit(double startx, double starty, char c);
std::string draw_number(double startx, double starty, double value);
private:
void delta_modify_start(double& startx, double& starty, int count);
GCode* mp_gcodegen;
double m_length_short, m_length_long;
double m_space_y;
double m_nozzle_diameter;
double m_slow_speed, m_fast_speed;
double m_line_width;
bool m_draw_numbers;
const double m_height_layer {0.2};
const double m_line_width {0.6};
const double m_thin_line_width {0.44};
const double m_number_line_width {0.48};
const double m_space_y {3.5};
double m_length_short {20.0}, m_length_long {40.0};
bool m_draw_numbers {true};
};
struct SuggestedCalibPressureAdvancePatternConfig {
const std::vector<std::pair<std::string, double>> float_pairs {
{"initial_layer_print_height", 0.25},
{"layer_height", 0.2},
{"initial_layer_speed", 30},
{"outer_wall_speed", 100}
};
const std::vector<std::pair<std::string, double>> nozzle_ratio_pairs {
{"line_width", 112.5},
{"initial_layer_line_width", 140}
};
const std::vector<std::pair<std::string, int>> int_pairs {
{"wall_loops", 3}
};
};
class CalibPressureAdvancePattern : public CalibPressureAdvance {
friend struct DrawLineOptArgs;
friend struct DrawBoxOptArgs;
public:
CalibPressureAdvancePattern(
const Calib_Params& params,
const DynamicPrintConfig& config,
bool is_bbl_machine,
Model& model,
const Vec3d& origin
);
double handle_xy_size() const { return m_handle_xy_size; };
double handle_spacing() const { return m_handle_spacing; };
double print_size_x() const { return object_size_x() + pattern_shift(); };
double print_size_y() const { return object_size_y(); };
double max_layer_z() const { return height_first_layer() + ((m_num_layers - 1) * height_layer()); };
void generate_custom_gcodes(
const DynamicPrintConfig& config,
bool is_bbl_machine,
Model& model,
const Vec3d& origin
);
protected:
double speed_first_layer() const { return m_config.option<ConfigOptionFloat>("initial_layer_speed")->value; };
double speed_perimeter() const { return m_config.option<ConfigOptionFloat>("outer_wall_speed")->value; };
double line_width_first_layer() const { return m_config.option<ConfigOptionFloat>("initial_layer_line_width")->value; };
double line_width() const { return m_config.option<ConfigOptionFloat>("line_width")->value; };
int wall_count() const { return m_config.option<ConfigOptionInt>("wall_loops")->value; };
private:
struct DrawLineOptArgs {
DrawLineOptArgs(const CalibPressureAdvancePattern& p) :
height {p.height_layer()},
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_layer() const { return m_config.option<ConfigOptionFloat>("layer_height")->value; };
const int get_num_patterns() const
{
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)
"spacing" = center-to-center distance of adjacent extrusions, which partially overlap
https://manual.slic3r.org/advanced/flow-math
https://ellis3dp.com/Print-Tuning-Guide/articles/misconceptions.html#two-04mm-perimeters--08mm
*/
double line_spacing() const { return line_width() - height_layer() * (1 - M_PI / 4); };
double line_spacing_first_layer() const { return line_width_first_layer() - height_first_layer() * (1 - M_PI / 4); };
double line_spacing_angle() const { return line_spacing() / std::sin(to_radians(m_corner_angle) / 2); };
double object_size_x() const;
double object_size_y() const;
double frame_size_y() const { return std::sin(to_radians(double(m_corner_angle) / 2)) * m_wall_side_length * 2; };
double glyph_start_x(int pattern_i = 0) const;
double glyph_length_x() const;
double glyph_tab_max_x() const;
double max_numbering_height() const;
double pattern_shift() const;
const Calib_Params& m_params;
DynamicPrintConfig m_config;
GCodeWriter m_writer;
bool m_is_delta;
Vec3d m_starting_point;
const double m_handle_xy_size {5};
const double m_handle_spacing {2};
const int m_num_layers {4};
const double m_wall_side_length {30.0};
const int m_corner_angle {90};
const int m_pattern_spacing {2};
const double m_encroachment {1. / 3.};
const double m_glyph_padding_horizontal {1};
const double m_glyph_padding_vertical {1};
};
} // namespace Slic3r