mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-08-04 16:52:29 +00:00
* fix: constrain PA_Line calibration bounding box to model geometry - PA_Line bounding box now uses actual model convex hull for X constraint instead of full printable area - Skip EXCLUDE_OBJECT_DEFINE for PA_Line mode (single object, no exclusion needed) - Add tool config files to .gitignore * modified: .gitignore * fix: add gcode type annotations and fix box height in PA line calibration - Label calibration segments with appropriate TYPE comments (Outer wall, Bottom surface, Top surface, Custom) for proper gcode processing - Fix bounding box height calculation to account for z_offset - Add LAYER_CHANGE and HEIGHT comments for multi-layer numbering display * fix: lock PA_Line bounding box X to bed centre instead of model hull * Added extra TYPE to ensure text/numbers/glyphs are labelled correctly ` gcode << ";TYPE:Outer wall\n"; ` * Remove hardcoded Perl path in OpenSSL.cmake Remove hardcoded Perl path for Windows configuration. * Add cross compilation support for Windows in OpenSSL.cmake * Remove unnecessary blank line in OpenSSL.cmake * Set perl config command back to variable Accidentally uploaded version with hardcoded path for my local environment * whitespace adjustment in previous * removed personal .gitignore config Remove specific files and directories from .gitignore. * Fix box height parameter in DrawBoxOptArgs Update DrawBoxOptArgs to use `m_height_layer` instead of `m_height_layer*2+z_offset`. This isn't a Z coordinate, it's a layer height * Replace hardcoded extrusion type with call to `GCodeProcessor::reserved_tag` Etags * Get pa_line bounding box from actual calibration variables Updated calibration line bounding box calculation to use actual geometry for X bounds, using a fake call to generate the calibration pattern. This will accurately get the size of the calibration pattern, massively reducing wasted time from bed mesh probing. * Implement print_extents method in CalibPressureAdvanceLine Add print_extents method to calculate bounding box extents based on bed dimensions. * Declare print_extents method in CalibPressureAdvanceLine Added print_extents method to return X-bounds of the pattern. * Fixed whitespace issues * Adjust print_extents to account for delta printers Check if the printer is delta layout and adjust bed dimensions if so. Used code from `CalibPressureAdvanceLine::generate_test` * Added semicolons to reserved tags Didn't realise etags wouldn't add semicolon - added these * only include number list in bounding box if number list is used Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * avoid bounding box overflowing bed * Tabs to spaces --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Co-authored-by: Ian Bassi <ian.bassi@outlook.com>
385 lines
14 KiB
C++
385 lines
14 KiB
C++
#pragma once
|
||
#include <string>
|
||
#define calib_pressure_advance_dd
|
||
|
||
#include "GCodeWriter.hpp"
|
||
#include "PrintConfig.hpp"
|
||
#include "BoundingBox.hpp"
|
||
#include "CustomGCode.hpp"
|
||
|
||
namespace Slic3r {
|
||
|
||
class GCode;
|
||
class Model;
|
||
class ModelObject;
|
||
|
||
enum class CalibMode : int {
|
||
Calib_None = 0,
|
||
Calib_PA_Line,
|
||
Calib_PA_Pattern,
|
||
Calib_PA_Tower,
|
||
Calib_Auto_PA_Line,
|
||
Calib_Flow_Rate,
|
||
Calib_Temp_Tower,
|
||
Calib_Vol_speed_Tower,
|
||
Calib_VFA_Tower,
|
||
Calib_Retraction_tower,
|
||
Calib_Input_shaping_freq,
|
||
Calib_Input_shaping_damp,
|
||
Calib_Cornering
|
||
};
|
||
|
||
enum class CalibState { Start = 0, Preset, Calibration, CoarseSave, FineCalibration, Save, Finish };
|
||
|
||
struct Calib_Params
|
||
{
|
||
Calib_Params() : mode(CalibMode::Calib_None){};
|
||
int extruder_id = 0;
|
||
double start, end, step;
|
||
bool print_numbers;
|
||
double freqStartX, freqEndX, freqStartY, freqEndY;
|
||
int test_model;
|
||
std::string shaper_type;
|
||
std::vector<double> accelerations;
|
||
std::vector<double> speeds;
|
||
|
||
CalibMode mode;
|
||
};
|
||
|
||
enum FlowRatioCalibrationType {
|
||
COMPLETE_CALIBRATION = 0,
|
||
FINE_CALIBRATION,
|
||
};
|
||
|
||
class X1CCalibInfos
|
||
{
|
||
public:
|
||
struct X1CCalibInfo
|
||
{
|
||
int extruder_id = 0;
|
||
int tray_id;
|
||
int ams_id = 0;
|
||
int slot_id = 0;
|
||
int bed_temp;
|
||
ExtruderType extruder_type{ExtruderType::etDirectDrive};
|
||
NozzleVolumeType nozzle_volume_type = NozzleVolumeType::nvtStandard;
|
||
int nozzle_temp;
|
||
float nozzle_diameter;
|
||
std::string filament_id;
|
||
std::string setting_id;
|
||
float max_volumetric_speed;
|
||
float flow_rate = 0.98f; // for flow ratio
|
||
};
|
||
|
||
std::vector<X1CCalibInfo> calib_datas;
|
||
CalibMode cali_mode{ CalibMode::Calib_None };
|
||
};
|
||
|
||
class CaliPresetInfo
|
||
{
|
||
public:
|
||
int tray_id;
|
||
int extruder_id;
|
||
NozzleVolumeType nozzle_volume_type;
|
||
BedType bed_type;
|
||
float nozzle_diameter;
|
||
int nozzle_pos_id{-1};
|
||
std::string nozzle_sn;
|
||
std::string filament_id;
|
||
std::string setting_id;
|
||
std::string name;
|
||
|
||
CaliPresetInfo &operator=(const CaliPresetInfo &other)
|
||
{
|
||
this->tray_id = other.tray_id;
|
||
this->extruder_id = other.extruder_id;
|
||
this->nozzle_volume_type = other.nozzle_volume_type;
|
||
this->nozzle_diameter = other.nozzle_diameter;
|
||
this->nozzle_pos_id = other.nozzle_pos_id;
|
||
this->nozzle_sn = other.nozzle_sn;
|
||
this->filament_id = other.filament_id;
|
||
this->setting_id = other.setting_id;
|
||
this->name = other.name;
|
||
return *this;
|
||
}
|
||
};
|
||
|
||
struct PrinterCaliInfo
|
||
{
|
||
std::string dev_id;
|
||
bool cali_finished = true;
|
||
float cache_flow_ratio;
|
||
std::vector<CaliPresetInfo> selected_presets;
|
||
FlowRatioCalibrationType cache_flow_rate_calibration_type = FlowRatioCalibrationType::COMPLETE_CALIBRATION;
|
||
};
|
||
|
||
class PACalibResult
|
||
{
|
||
public:
|
||
enum CalibResult {
|
||
CALI_RESULT_SUCCESS = 0,
|
||
CALI_RESULT_PROBLEM = 1,
|
||
CALI_RESULT_FAILED = 2,
|
||
};
|
||
int extruder_id = 0;
|
||
NozzleVolumeType nozzle_volume_type;
|
||
int tray_id = 0;
|
||
int ams_id = 0;
|
||
int slot_id = 0;
|
||
int cali_idx = -1;
|
||
int nozzle_pos_id = -1; //-1 means no nozzle pos
|
||
float nozzle_diameter;
|
||
std::string nozzle_sn;
|
||
std::string filament_id;
|
||
std::string setting_id;
|
||
std::string name;
|
||
float k_value = 0.0;
|
||
float n_coef = 0.0;
|
||
int confidence = -1; // 0: success 1: uncertain 2: failed
|
||
};
|
||
|
||
struct PACalibIndexInfo
|
||
{
|
||
int extruder_id = 0;
|
||
NozzleVolumeType nozzle_volume_type;
|
||
int tray_id = 0;
|
||
int ams_id = 0;
|
||
int slot_id = 0;
|
||
int cali_idx = -1; // -1 means default
|
||
int nozzle_pos_id = -1; //-1 means no nozzle pos
|
||
float nozzle_diameter;
|
||
std::string nozzle_sn;
|
||
std::string filament_id;
|
||
};
|
||
|
||
struct PACalibExtruderInfo
|
||
{
|
||
int extruder_id = 0;
|
||
NozzleVolumeType nozzle_volume_type;
|
||
int nozzle_pos_id = -1; //-1 means no nozzle pos
|
||
float nozzle_diameter;
|
||
std::string nozzle_sn;
|
||
std::string filament_id = "";
|
||
bool use_extruder_id{true};
|
||
bool use_nozzle_volume_type{true};
|
||
};
|
||
|
||
struct PACalibTabInfo
|
||
{
|
||
float pa_calib_tab_nozzle_dia;
|
||
int extruder_id;
|
||
NozzleVolumeType nozzle_volume_type;
|
||
};
|
||
|
||
class FlowRatioCalibResult
|
||
{
|
||
public:
|
||
int tray_id;
|
||
float nozzle_diameter;
|
||
std::string filament_id;
|
||
std::string setting_id;
|
||
float flow_ratio;
|
||
int confidence; // 0: success 1: uncertain 2: failed
|
||
};
|
||
|
||
struct DrawBoxOptArgs
|
||
{
|
||
DrawBoxOptArgs(int num_perimeters, double height, double line_width, double speed)
|
||
: num_perimeters{num_perimeters}, height{height}, line_width{line_width}, speed{speed} {};
|
||
DrawBoxOptArgs() = default;
|
||
|
||
bool is_filled{false};
|
||
int num_perimeters;
|
||
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 extruder_id = 0, int filament_idx = 0);
|
||
|
||
protected:
|
||
CalibPressureAdvance() = default;
|
||
CalibPressureAdvance(const DynamicPrintConfig& config) : m_config(config){};
|
||
CalibPressureAdvance(const FullPrintConfig &config) { m_config.apply(config); };
|
||
~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 z = 0, double layer_height = -1);
|
||
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, unsigned precision = 0) 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);
|
||
|
||
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;
|
||
DynamicPrintConfig m_config;
|
||
|
||
const double m_encroachment{1. / 3.};
|
||
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};
|
||
std::string::size_type m_number_len{m_max_number_len}; /* Current length of number labels */
|
||
};
|
||
|
||
class CalibPressureAdvanceLine : public CalibPressureAdvance
|
||
{
|
||
public:
|
||
CalibPressureAdvanceLine(GCode* gcodegen);
|
||
~CalibPressureAdvanceLine(){};
|
||
// Return the X‑bounds of the pattern on the given bed.
|
||
BoundingBoxf print_extents(const BoundingBoxf &bed_ext) const;
|
||
|
||
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)
|
||
{
|
||
m_slow_speed = slow;
|
||
m_fast_speed = fast;
|
||
}
|
||
|
||
const double &line_width() { return m_line_width; };
|
||
const double &height_layer() { return m_height_layer; };
|
||
bool is_delta() const;
|
||
bool &draw_numbers() { return m_draw_numbers; }
|
||
|
||
private:
|
||
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);
|
||
|
||
GCode *mp_gcodegen;
|
||
|
||
double m_nozzle_diameter;
|
||
double m_slow_speed, m_fast_speed;
|
||
|
||
double m_height_layer{0.2};
|
||
double m_line_width{0.6};
|
||
double m_thin_line_width{0.44};
|
||
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 SuggestedConfigCalibPAPattern
|
||
{
|
||
const std::vector<std::pair<std::string, std::vector<double>>> floats_pairs{{"initial_layer_speed", {30}}};
|
||
|
||
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{{"skirt_loops", 0}, {"wall_loops", 3}};
|
||
|
||
const std::pair<std::string, BrimType> brim_pair{"brim_type", BrimType::btNoBrim};
|
||
};
|
||
|
||
class CalibPressureAdvancePattern : public CalibPressureAdvance
|
||
{
|
||
friend struct DrawBoxOptArgs;
|
||
|
||
public:
|
||
CalibPressureAdvancePattern(
|
||
const Calib_Params ¶ms, const DynamicPrintConfig &config, bool is_bbl_machine, const ModelObject &object, const Vec3d &origin);
|
||
|
||
double handle_xy_size() const { return m_handle_xy_size; };
|
||
double handle_spacing() const { return m_handle_spacing; };
|
||
Vec3d handle_pos_offset() const;
|
||
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()); };
|
||
double flow_val() const;
|
||
|
||
CustomGCode::Info generate_custom_gcodes(const DynamicPrintConfig &config, bool is_bbl_machine, const ModelObject &object, const Vec3d &origin);
|
||
|
||
void set_start_offset(const Vec3d &offset);
|
||
Vec3d get_start_offset();
|
||
|
||
protected:
|
||
// todo multi_extruders:
|
||
double speed_first_layer() const { return m_config.get_abs_value_at("initial_layer_speed", m_params.extruder_id); };
|
||
double speed_perimeter() const { return m_config.get_abs_value_at("outer_wall_speed", m_params.extruder_id); };
|
||
double accel_perimeter() const { return m_config.get_abs_value_at("outer_wall_acceleration", m_params.extruder_id); }
|
||
double line_width_first_layer() const;
|
||
double line_width() const;
|
||
int wall_count() const { return m_config.option<ConfigOptionInt>("wall_loops")->value; };
|
||
|
||
private:
|
||
void refresh_setup(const DynamicPrintConfig &config, bool is_bbl_machine, const ModelObject &object, const Vec3d &origin);
|
||
void _refresh_starting_point(const ModelObject &object);
|
||
void _refresh_writer(bool is_bbl_machine, const ModelObject &object, const Vec3d &origin);
|
||
|
||
double height_first_layer() const { return m_config.option<ConfigOptionFloat>("initial_layer_print_height")->value; };
|
||
double height_z_offset() const { return m_config.option<ConfigOptionFloat>("z_offset")->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); }
|
||
|
||
/*
|
||
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;
|
||
size_t max_numbering_length() const;
|
||
|
||
double pattern_shift() const;
|
||
|
||
const Calib_Params &m_params;
|
||
|
||
GCodeWriter m_writer;
|
||
Vec3d m_starting_point;
|
||
bool m_is_start_point_fixed = false;
|
||
|
||
const double m_handle_xy_size{5};
|
||
const double m_handle_spacing{1.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_glyph_padding_horizontal{1};
|
||
const double m_glyph_padding_vertical{1};
|
||
};
|
||
|
||
} // namespace Slic3r
|