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,4 +1,5 @@
#include "Plater.hpp"
#include <cstddef>
#include <algorithm>
#include <numeric>
@ -100,6 +101,7 @@
#include "MsgDialog.hpp"
#include "ProjectDirtyStateManager.hpp"
#include "Gizmos/GLGizmoSimplify.hpp" // create suggestion notification
#include "Gizmos/GizmoObjectManipulation.hpp"
// BBS
#include "Widgets/ProgressDialog.hpp"
@ -8100,60 +8102,165 @@ std::array<Vec3d, 4> get_cut_plane(const BoundingBoxf3& bbox, const double& cut_
return plane_pts;
}
void Plater::calib_pa(const Calib_Params& params) {
void Plater::calib_pa(const Calib_Params& params)
{
const auto calib_pa_name = wxString::Format(L"Pressure Advance Test");
new_project(false, false, calib_pa_name);
wxGetApp().mainframe->select_tab(size_t(MainFrame::tp3DEditor));
if (params.mode == CalibMode::Calib_PA_Line) {
add_model(false, Slic3r::resources_dir() + "/calib/PressureAdvance/pressure_advance_test.stl");
switch (params.mode) {
case CalibMode::Calib_PA_Line:
add_model(false, Slic3r::resources_dir() + "/calib/PressureAdvance/pressure_advance_test.stl");
break;
case CalibMode::Calib_PA_Pattern:
_calib_pa_pattern(params);
break;
case CalibMode::Calib_PA_Tower:
_calib_pa_tower(params);
break;
default: break;
}
else {
add_model(false, Slic3r::resources_dir() + "/calib/PressureAdvance/tower_with_seam.stl");
auto print_config = &wxGetApp().preset_bundle->prints.get_edited_preset().config;
auto printer_config = &wxGetApp().preset_bundle->printers.get_edited_preset().config;
auto filament_config = &wxGetApp().preset_bundle->filaments.get_edited_preset().config;
filament_config->set_key_value("slow_down_layer_time", new ConfigOptionFloats{ 1.0f });
print_config->set_key_value("default_jerk", new ConfigOptionFloat(1.0f));
print_config->set_key_value("outer_wall_jerk", new ConfigOptionFloat(1.0f));
print_config->set_key_value("inner_wall_jerk", new ConfigOptionFloat(1.0f));
if(print_config->option<ConfigOptionEnum<PerimeterGeneratorType>>("wall_generator")->value == PerimeterGeneratorType::Arachne)
print_config->set_key_value("wall_transition_angle", new ConfigOptionFloat(25));
model().objects[0]->config.set_key_value("seam_position", new ConfigOptionEnum<SeamPosition>(spRear));
changed_objects({ 0 });
wxGetApp().get_tab(Preset::TYPE_PRINT)->update_dirty();
wxGetApp().get_tab(Preset::TYPE_FILAMENT)->update_dirty();
wxGetApp().get_tab(Preset::TYPE_PRINTER)->update_dirty();
wxGetApp().get_tab(Preset::TYPE_PRINT)->reload_config();
wxGetApp().get_tab(Preset::TYPE_FILAMENT)->reload_config();
wxGetApp().get_tab(Preset::TYPE_PRINTER)->reload_config();
auto new_height = std::ceil((params.end - params.start) / params.step) + 1;
auto obj_bb = model().objects[0]->bounding_box();
if (new_height < obj_bb.size().z()) {
std::array<Vec3d, 4> plane_pts = get_cut_plane(obj_bb, new_height);
cut(0, 0, plane_pts, ModelObjectCutAttribute::KeepLower);
}
// automatic selection of added objects
// update printable state for new volumes on canvas3D
wxGetApp().plater()->canvas3D()->update_instance_printable_state_for_objects({0});
Selection& selection = p->view3D->get_canvas3d()->get_selection();
selection.clear();
selection.add_object(0, false);
// BBS: update object list selection
p->sidebar->obj_list()->update_selections();
selection.notify_instance_update(-1, -1);
if (p->view3D->get_canvas3d()->get_gizmos_manager().is_enabled())
// this is required because the selected object changed and the flatten on face an sla support gizmos need to be updated accordingly
p->view3D->get_canvas3d()->update_gizmos_on_off_state();
}
p->background_process.fff_print()->set_calib_params(params);
}
void Plater::_calib_pa_pattern(const Calib_Params& params)
{
// add "handle" cube
sidebar().obj_list()->load_generic_subobject("Cube", ModelVolumeType::INVALID);
orient();
changed_objects({ 0 });
_calib_pa_select_added_objects();
const DynamicPrintConfig& printer_config = wxGetApp().preset_bundle->printers.get_edited_preset().config;
DynamicPrintConfig& print_config = wxGetApp().preset_bundle->prints.get_edited_preset().config;
for (const auto opt : SuggestedCalibPressureAdvancePatternConfig().float_pairs) {
print_config.set_key_value(
opt.first,
new ConfigOptionFloat(opt.second)
);
}
for (const auto opt : SuggestedCalibPressureAdvancePatternConfig().nozzle_ratio_pairs) {
double nozzle_diameter = printer_config.option<ConfigOptionFloats>("nozzle_diameter")->get_at(0);
print_config.set_key_value(
opt.first,
new ConfigOptionFloat(nozzle_diameter * opt.second / 100)
);
}
for (const auto opt : SuggestedCalibPressureAdvancePatternConfig().int_pairs) {
print_config.set_key_value(
opt.first,
new ConfigOptionInt(opt.second)
);
}
wxGetApp().get_tab(Preset::TYPE_PRINT)->update_dirty();
wxGetApp().get_tab(Preset::TYPE_PRINT)->reload_config();
const DynamicPrintConfig full_config = wxGetApp().preset_bundle->full_config();
PresetBundle* preset_bundle = wxGetApp().preset_bundle;
const bool is_bbl_machine = preset_bundle->printers.get_edited_preset().is_bbl_vendor_preset(preset_bundle);
const Vec3d plate_origin = get_partplate_list().get_current_plate_origin();
CalibPressureAdvancePattern pa_pattern(
params,
full_config,
is_bbl_machine,
model(),
plate_origin
);
// scale cube to suit test
GizmoObjectManipulation& giz_obj_manip = p->view3D->get_canvas3d()->
get_gizmos_manager().get_object_manipulation();
giz_obj_manip.set_uniform_scaling(true);
giz_obj_manip.on_change(
"size",
0,
pa_pattern.handle_xy_size()
);
giz_obj_manip.set_uniform_scaling(false);
giz_obj_manip.on_change(
"size",
2,
pa_pattern.max_layer_z()
);
// start with pattern centered on plate
center_selection();
const Vec3d plate_center = get_partplate_list().get_curr_plate()->get_center_origin();
giz_obj_manip.on_change(
"position",
0,
plate_center.x() - (pa_pattern.print_size_x() / 2)
);
giz_obj_manip.on_change(
"position",
1,
plate_center.y() -
(pa_pattern.print_size_y() / 2) -
pa_pattern.handle_spacing()
);
pa_pattern.generate_custom_gcodes(
full_config,
is_bbl_machine,
model(),
plate_origin
);
model().calib_pa_pattern = std::make_unique<CalibPressureAdvancePattern>(pa_pattern);
changed_objects({ 0 });
}
void Plater::_calib_pa_tower(const Calib_Params& params) {
add_model(false, Slic3r::resources_dir() + "/calib/PressureAdvance/tower_with_seam.stl");
auto print_config = &wxGetApp().preset_bundle->prints.get_edited_preset().config;
auto printer_config = &wxGetApp().preset_bundle->printers.get_edited_preset().config;
auto filament_config = &wxGetApp().preset_bundle->filaments.get_edited_preset().config;
filament_config->set_key_value("slow_down_layer_time", new ConfigOptionFloats{ 1.0f });
print_config->set_key_value("default_jerk", new ConfigOptionFloat(1.0f));
print_config->set_key_value("outer_wall_jerk", new ConfigOptionFloat(1.0f));
print_config->set_key_value("inner_wall_jerk", new ConfigOptionFloat(1.0f));
if(print_config->option<ConfigOptionEnum<PerimeterGeneratorType>>("wall_generator")->value == PerimeterGeneratorType::Arachne)
print_config->set_key_value("wall_transition_angle", new ConfigOptionFloat(25));
model().objects[0]->config.set_key_value("seam_position", new ConfigOptionEnum<SeamPosition>(spRear));
changed_objects({ 0 });
wxGetApp().get_tab(Preset::TYPE_PRINT)->update_dirty();
wxGetApp().get_tab(Preset::TYPE_FILAMENT)->update_dirty();
wxGetApp().get_tab(Preset::TYPE_PRINTER)->update_dirty();
wxGetApp().get_tab(Preset::TYPE_PRINT)->reload_config();
wxGetApp().get_tab(Preset::TYPE_FILAMENT)->reload_config();
wxGetApp().get_tab(Preset::TYPE_PRINTER)->reload_config();
auto new_height = std::ceil((params.end - params.start) / params.step) + 1;
auto obj_bb = model().objects[0]->bounding_box();
if (new_height < obj_bb.size().z()) {
std::array<Vec3d, 4> plane_pts = get_cut_plane(obj_bb, new_height);
cut(0, 0, plane_pts, ModelObjectCutAttribute::KeepLower);
}
_calib_pa_select_added_objects();
}
void Plater::_calib_pa_select_added_objects() {
// update printable state for new volumes on canvas3D
wxGetApp().plater()->canvas3D()->update_instance_printable_state_for_objects({0});
Selection& selection = p->view3D->get_canvas3d()->get_selection();
selection.clear();
selection.add_object(0, false);
// BBS: update object list selection
p->sidebar->obj_list()->update_selections();
selection.notify_instance_update(-1, -1);
if (p->view3D->get_canvas3d()->get_gizmos_manager().is_enabled()) {
// this is required because the selected object changed and the flatten on face an sla support gizmos need to be updated accordingly
p->view3D->get_canvas3d()->update_gizmos_on_off_state();
}
}
void Plater::calib_flowrate(int pass) {
@ -8243,7 +8350,6 @@ void Plater::calib_flowrate(int pass) {
wxGetApp().get_tab(Preset::TYPE_PRINT)->reload_config();
wxGetApp().get_tab(Preset::TYPE_FILAMENT)->reload_config();
wxGetApp().get_tab(Preset::TYPE_PRINTER)->reload_config();
}
void Plater::calib_temp(const Calib_Params& params) {
@ -10260,6 +10366,18 @@ void Plater::reslice()
// Stop arrange and (or) optimize rotation tasks.
this->stop_jobs();
// regenerate CalibPressureAdvancePattern custom G-code to apply changes
if (model().calib_pa_pattern) {
PresetBundle* preset_bundle = wxGetApp().preset_bundle;
model().calib_pa_pattern->generate_custom_gcodes(
wxGetApp().preset_bundle->full_config(),
preset_bundle->printers.get_edited_preset().is_bbl_vendor_preset(preset_bundle),
model(),
get_partplate_list().get_current_plate_origin()
);
}
if (printer_technology() == ptSLA) {
for (auto& object : model().objects)
if (object->sla_points_status == sla::PointsStatus::NoPoints)