NEW: add calibration

Change-Id: I03e5489a67042e7f76f5a42260a289d540b5a63a
(cherry picked from commit cbac2c639db830eb779b1979c8d6b4eb3decb7e6)
This commit is contained in:
liz.li 2023-04-23 09:04:55 +08:00 committed by Lane.Wei
parent ff3f78cfb5
commit 1f54aaf22b
35 changed files with 38647 additions and 54 deletions

Binary file not shown.

Binary file not shown.

BIN
resources/calib/vfa/VFA.stl Normal file

Binary file not shown.

File diff suppressed because it is too large Load diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 194 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 536 KiB

View file

@ -37,6 +37,7 @@ set(lisbslic3r_sources
Brim.hpp
BuildVolume.cpp
BuildVolume.hpp
Calib.hpp
Circle.cpp
Circle.hpp
clipper.cpp

26
src/libslic3r/Calib.hpp Normal file
View file

@ -0,0 +1,26 @@
#pragma once
#include <string>
#include "Point.hpp"
namespace Slic3r {
class GCode;
enum class CalibMode : int {
Calib_None = 0,
Calib_PA_Line,
Calib_PA_Tower,
Calib_Flow_Rate,
Calib_Temp_Tower,
Calib_Vol_speed_Tower,
Calib_VFA_Tower
};
struct Calib_Params
{
Calib_Params() : mode(CalibMode::Calib_None){}
double start, end, step;
bool print_numbers;
CalibMode mode;
};
} // namespace Slic3r

View file

@ -2703,6 +2703,19 @@ GCode::LayerResult GCode::process_layer(
config.set_key_value("max_layer_z", new ConfigOptionFloat(m_max_layer_z));
}
if (print.calib_mode() == CalibMode::Calib_Temp_Tower) {
auto offset = static_cast<unsigned int>(print_z / 10.001) * 5;
gcode += writer().set_temperature(print.calib_params().start - offset);
}
else if (print.calib_mode() == CalibMode::Calib_Vol_speed_Tower) {
auto _speed = print.calib_params().start + print_z * print.calib_params().step;
m_calib_config.set_key_value("outer_wall_speed", new ConfigOptionFloat(std::round(_speed)));
}
else if (print.calib_mode() == CalibMode::Calib_VFA_Tower) {
auto _speed = print.calib_params().start + std::floor(print_z / 5.0) * print.calib_params().step;
m_calib_config.set_key_value("outer_wall_speed", new ConfigOptionFloat(std::round(_speed)));
}
//BBS
if (first_layer) {
//BBS: set first layer global acceleration
@ -3654,6 +3667,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
// compensate retraction
gcode += this->unretract();
m_config.apply(m_calib_config);
// adjust acceleration
if (m_config.default_acceleration.value > 0) {
@ -3680,7 +3694,8 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
}
// calculate extrusion length per distance unit
double e_per_mm = m_writer.extruder()->e_per_mm3() * path.mm3_per_mm;
auto _mm3_per_mm = path.mm3_per_mm * (m_curr_print->calib_mode() == CalibMode::Calib_Flow_Rate ? this->config().print_flow_ratio : 1);
double e_per_mm = m_writer.extruder()->e_per_mm3() * _mm3_per_mm;
double min_speed = double(m_config.slow_down_min_speed.get_at(m_writer.extruder()->id()));
// set speed

View file

@ -413,6 +413,7 @@ private:
methods. */
Vec2d m_origin;
FullPrintConfig m_config;
DynamicConfig m_calib_config;
// scaled G-code resolution
double m_scaled_resolution;
GCodeWriter m_writer;

View file

@ -747,7 +747,9 @@ static std::vector<std::string> s_Preset_print_options {
"initial_layer_infill_speed", "only_one_wall_top", "only_one_wall_first_layer",
"timelapse_type", "internal_bridge_support_thickness",
"wall_generator", "wall_transition_length", "wall_transition_filter_deviation", "wall_transition_angle",
"wall_distribution_count", "min_feature_size", "min_bead_width", "post_process"
"wall_distribution_count", "min_feature_size", "min_bead_width", "post_process",
// calib
"print_flow_ratio"
};
static std::vector<std::string> s_Preset_filament_options {

View file

@ -253,6 +253,11 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n
return invalidated;
}
void Print::set_calib_params(const Calib_Params &params)
{
m_calib_params = params;
}
bool Print::invalidate_step(PrintStep step)
{
bool invalidated = Inherited::invalidate_step(step);

View file

@ -21,6 +21,7 @@
#include <functional>
#include <set>
#include "Calib.hpp"
namespace Slic3r {
@ -788,6 +789,11 @@ public:
// Return 4 wipe tower corners in the world coordinates (shifted and rotated), including the wipe tower brim.
std::vector<Point> first_layer_wipe_tower_corners(bool check_wipe_tower_existance=true) const;
CalibMode & calib_mode() { return m_calib_params.mode; }
const CalibMode& calib_mode() const { return m_calib_params.mode; }
void set_calib_params(const Calib_Params &params);
const Calib_Params& calib_params() const { return m_calib_params; }
protected:
// Invalidates the step, and its depending steps in Print.
bool invalidate_step(PrintStep step);
@ -841,6 +847,9 @@ private:
ConflictResultOpt m_conflict_result;
FakeWipeTower m_fake_wipe_tower;
// SoftFever: calibration
Calib_Params m_calib_params;
// To allow GCode to set the Print's GCodeExport step status.
friend class GCode;
// Allow PrintObject to access m_mutex and m_cancel_callback.

View file

@ -1119,6 +1119,14 @@ void PrintConfigDef::init_fff_params()
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloats { 1. });
def = this->add("print_flow_ratio", coFloat);
def->label = L("Object flow ratio");
def->tooltip = L("The flow ratio set by object, the meaning is the same as flow ratio.");
def->mode = comDevelop;
def->max = 2;
def->min = 0.01;
def->set_default_value(new ConfigOptionFloat(1));
def = this->add("line_width", coFloat);
def->label = L("Default");
def->category = L("Quality");

View file

@ -756,8 +756,14 @@ PRINT_CONFIG_CLASS_DEFINE(
((ConfigOptionFloat, overhang_1_4_speed))
((ConfigOptionFloat, overhang_2_4_speed))
((ConfigOptionFloat, overhang_3_4_speed))
<<<<<<< HEAD (88f268 FIX: wipe tower is not generated with different filament lay)
((ConfigOptionFloatOrPercent, sparse_infill_anchor))
((ConfigOptionFloatOrPercent, sparse_infill_anchor_max))
=======
((ConfigOptionFloat, overhang_4_4_speed))
//calib
((ConfigOptionFloat, print_flow_ratio)))
>>>>>>> CHANGE (cbac2c NEW: add calibration)
PRINT_CONFIG_CLASS_DEFINE(
MachineEnvelopeConfig,

View file

@ -388,6 +388,12 @@ set(SLIC3R_GUI_SOURCES
GUI/ReleaseNote.cpp
GUI/SingleChoiceDialog.hpp
GUI/SingleChoiceDialog.cpp
GUI/CalibrationPanel.hpp
GUI/CalibrationPanel.cpp
GUI/CalibrationWizard.hpp
GUI/CalibrationWizard.cpp
GUI/CalibrationWizardPage.cpp
GUI/CalibrationWizardPage.hpp
GUI/Calibration.hpp
GUI/Calibration.cpp
GUI/PrintOptionsDialog.hpp
@ -423,6 +429,8 @@ set(SLIC3R_GUI_SOURCES
Utils/PrintHost.cpp
Utils/NetworkAgent.cpp
Utils/NetworkAgent.hpp
Utils/CalibUtils.cpp
Utils/CalibUtils.hpp
)
if (WIN32)

View file

@ -0,0 +1,74 @@
#include "CalibrationPanel.hpp"
#include "I18N.hpp"
namespace Slic3r { namespace GUI {
CalibrationPanel::CalibrationPanel(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style)
: wxPanel(parent, id, pos, size, style)
{
SetBackgroundColour(*wxWHITE);
//init_bitmaps();
init_tabpanel();
wxBoxSizer* sizer_main = new wxBoxSizer(wxVERTICAL);
sizer_main->Add(m_tabpanel, 1, wxEXPAND, 0);
SetSizerAndFit(sizer_main);
Layout();
}
void CalibrationPanel::init_tabpanel() {
//m_side_tools = new SideTools(this, wxID_ANY);
wxBoxSizer* sizer_side_tools = new wxBoxSizer(wxVERTICAL);
//sizer_side_tools->Add(m_side_tools, 1, wxEXPAND, 0);
m_tabpanel = new Tabbook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, sizer_side_tools, wxNB_LEFT | wxTAB_TRAVERSAL | wxNB_NOPAGETHEME);
m_tabpanel->SetBackgroundColour(*wxWHITE);
//m_pa_panel = new CalibrationWizard(m_tabpanel);
//m_tabpanel->AddPage(m_pa_panel, _L("Pressure Adavance"), "", true);
m_flow_panel = new FlowRateWizard(m_tabpanel);
m_tabpanel->AddPage(m_flow_panel, _L("Flow Rate"), "", false);
m_volumetric_panel = new MaxVolumetricSpeedWizard(m_tabpanel);
m_tabpanel->AddPage(m_volumetric_panel, _L("Max Volumetric Speed"), "", false);
m_temp_panel = new TemperatureWizard(m_tabpanel);
m_tabpanel->AddPage(m_temp_panel, _L("Temperature"), "", true);
//m_vfa_panel = new CalibrationWizard(m_tabpanel);
//m_tabpanel->AddPage(m_vfa_panel, _L("VFA"), "", false);
//m_tabpanel->Bind(wxEVT_BOOKCTRL_PAGE_CHANGED, [this](wxBookCtrlEvent& e) {
// CalibrationWizard* page = static_cast<CalibrationWizard*>(m_tabpanel->GetCurrentPage());
// if (page->get_frist_page()) {
// page->update_comboboxes();
// }
// }, m_tabpanel->GetId());
}
void CalibrationPanel::update_obj(MachineObject* obj) {
if (obj) {
if (m_pa_panel)
m_pa_panel->update_obj(obj);
if (m_flow_panel) {
m_flow_panel->update_obj(obj);
m_flow_panel->update_ams(obj);
}
if (m_volumetric_panel) {
m_volumetric_panel->update_obj(obj);
m_volumetric_panel->update_ams(obj);
}
if (m_temp_panel) {
m_temp_panel->update_obj(obj);
m_temp_panel->update_ams(obj);
m_temp_panel->update_progress();
}
if (m_vfa_panel) {
m_vfa_panel->update_obj(obj);
}
}
}
}}

View file

@ -0,0 +1,36 @@
#ifndef slic3r_GUI_CalibrationPanel_hpp_
#define slic3r_GUI_CalibrationPanel_hpp_
#include "CalibrationWizard.hpp"
#include "Tabbook.hpp"
//#include "Widgets/SideTools.hpp"
namespace Slic3r { namespace GUI {
class CalibrationPanel : public wxPanel
{
public:
CalibrationPanel(wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxTAB_TRAVERSAL);
~CalibrationPanel() {};
Tabbook* get_tabpanel() { return m_tabpanel; };
void update_obj(MachineObject* obj);
protected:
void init_bitmaps();
void init_tabpanel();
//void show_wizard();
//CalibrationWizard* get_current_wizard();
private:
Tabbook* m_tabpanel{ nullptr };
//SideTools* m_side_tools{ nullptr };
CalibrationWizard* m_pa_panel{ nullptr };
CalibrationWizard* m_flow_panel{ nullptr };
CalibrationWizard* m_volumetric_panel{ nullptr };
TemperatureWizard* m_temp_panel{ nullptr };
CalibrationWizard* m_vfa_panel{ nullptr };
};
}} // namespace Slic3r::GUI
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,154 @@
#ifndef slic3r_GUI_CalibrationWizard_hpp_
#define slic3r_GUI_CalibrationWizard_hpp_
#include "GUI_Utils.hpp"
#include "DeviceManager.hpp"
#include "CalibrationWizardPage.hpp"
#include "Widgets/ComboBox.hpp"
#include "Widgets/TextInput.hpp"
#include "Widgets/AMSControl.hpp"
#include "SavePresetDialog.hpp"
#include "../slic3r/Utils/CalibUtils.hpp"
namespace Slic3r { namespace GUI {
class CalibrationWizard : public wxPanel {
public:
CalibrationWizard(wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxTAB_TRAVERSAL);
~CalibrationWizard() {};
CalibrationWizardPage* get_curr_page() { return m_curr_page; }
CalibrationWizardPage* get_frist_page() { return m_first_page; }
void show_page(CalibrationWizardPage* page);
void update_obj(MachineObject* rhs_obj) { obj = rhs_obj; }
void update_ams(MachineObject* obj);
void update_progress();
protected:
virtual void create_pages() = 0;
virtual bool start_calibration(std::string tray_id) = 0;
virtual void save_calibration_result() {};
virtual void update_calibration_value() = 0;
protected:
wxPanel* m_background_panel;
wxPanel* m_presets_panel;
AMSControl* m_ams_control;
ComboBox* m_comboBox_printer;
ComboBox* m_comboBox_filament;
ComboBox* m_comboBox_bed_type;
ComboBox* m_comboBox_process;
wxStaticText* m_from_text;
wxStaticText* m_to_text;
wxStaticText* m_step_text;
TextInput* m_from_value;
TextInput* m_to_value;
TextInput* m_step;
BBLStatusBarSend* m_progress_bar;
MachineObject* obj{ nullptr };
CalibrationWizardPage* m_curr_page{ nullptr };
CalibrationWizardPage* m_first_page{ nullptr };
void add_presets_panel_to_page(CalibrationWizardPage* page, wxBoxSizer* sizer);
void add_progress_bar_to_page(CalibrationWizardPage* page, wxBoxSizer* sizer);
void show_progress_bar(bool show);
wxString get_presets_incompatible() { return wxString(); }
void on_select_printer(wxCommandEvent& evt);
void on_select_filament(wxCommandEvent& evt);
void on_select_bed_type(wxCommandEvent& evt);
void on_select_process(wxCommandEvent& evt);
void on_click_btn_prev(IntEvent& event);
void on_click_btn_next(IntEvent& event);
private:
void create_presets_panel();
void create_progress_bar();
void init_printer_selections();
void init_filaments_selections();
void init_bed_type_selections();
void init_process_selections();
void init_presets_selections();
};
class PressureAdvanceWizard : public CalibrationWizard{};
class FlowRateWizard : public CalibrationWizard {
public:
FlowRateWizard(wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxTAB_TRAVERSAL);
~FlowRateWizard() {};
protected:
virtual void create_pages() override;
virtual bool start_calibration(std::string tray_id) override;
virtual void update_calibration_value() override;
private:
// page 1
CalibrationWizardPage* m_page1;
// page 2
CalibrationWizardPage* m_page2;
// page 3
CalibrationWizardPage* m_page3;
ComboBox* m_optimal_block_coarse;
// page 4
CalibrationWizardPage* m_page4;
AMSControl* m_readonly_ams_control;
TextInput* m_readonly_printer;
TextInput* m_readonly_filament;
TextInput* m_readonly_bed_type;
TextInput* m_readonly_process;
// page 5
CalibrationWizardPage* m_page5;
ComboBox* m_optimal_block_fine;
void create_readonly_presets_panel();
};
class MaxVolumetricSpeedWizard : public CalibrationWizard {
public:
MaxVolumetricSpeedWizard(wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxTAB_TRAVERSAL);
~MaxVolumetricSpeedWizard() {};
protected:
virtual void create_pages() override;
virtual bool start_calibration(std::string tray_id) override;
virtual void update_calibration_value() override;
private:
// page 1
CalibrationWizardPage* m_page1;
// page 2
CalibrationWizardPage* m_page2;
// page 3
CalibrationWizardPage* m_page3;
TextInput* m_optimal_max_speed;
};
class TemperatureWizard : public CalibrationWizard {
public:
TemperatureWizard(wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxTAB_TRAVERSAL);
~TemperatureWizard() {};
protected:
virtual void create_pages() override;
virtual bool start_calibration(std::string tray_id) override;
virtual void save_calibration_result();
virtual void update_calibration_value() override;
private:
// page 1
CalibrationWizardPage* m_page1;
// page 2
CalibrationWizardPage* m_page2;
TextInput* m_optimal_temp;
};
class VFAWizard : public CalibrationWizard {};
}} // namespace Slic3r::GUI
#endif

View file

@ -0,0 +1,148 @@
#include "CalibrationWizardPage.hpp"
#include "CalibrationWizard.hpp"
#include "I18N.hpp"
namespace Slic3r { namespace GUI {
wxDEFINE_EVENT(EVT_CALIBRATIONPAGE_PREV, IntEvent);
wxDEFINE_EVENT(EVT_CALIBRATIONPAGE_NEXT, IntEvent);
PageButton::PageButton(wxWindow* parent, wxString text, ButtonType type)
: m_type(type),
Button(parent, text)
{
StateColor btn_bg_green(std::pair<wxColour, int>(AMS_CONTROL_DISABLE_COLOUR, StateColor::Disabled),
std::pair<wxColour, int>(wxColour(27, 136, 68), StateColor::Pressed),
std::pair<wxColour, int>(wxColour(61, 203, 115), StateColor::Hovered),
std::pair<wxColour, int>(wxColour(0, 174, 66), StateColor::Normal));
StateColor btn_bg_white(std::pair<wxColour, int>(AMS_CONTROL_DISABLE_COLOUR, StateColor::Disabled),
std::pair<wxColour, int>(wxColour(206, 206, 206), StateColor::Pressed),
std::pair<wxColour, int>(wxColour(238, 238, 238), StateColor::Hovered),
std::pair<wxColour, int>(wxColour(255, 255, 255), StateColor::Normal));
StateColor btn_bd_green(std::pair<wxColour, int>(wxColour(255, 255, 254), StateColor::Disabled),
std::pair<wxColour, int>(wxColour(0, 174, 66), StateColor::Enabled));
StateColor btn_bd_white(std::pair<wxColour, int>(wxColour(255, 255, 254), StateColor::Disabled),
std::pair<wxColour, int>(wxColour(38, 46, 48), StateColor::Enabled));
StateColor btn_text_green(std::pair<wxColour, int>(wxColour(255, 255, 254), StateColor::Disabled),
std::pair<wxColour, int>(wxColour(255, 255, 254), StateColor::Enabled));
StateColor btn_text_white(std::pair<wxColour, int>(wxColour(255, 255, 254), StateColor::Disabled),
std::pair<wxColour, int>(wxColour(38, 46, 48), StateColor::Enabled));
switch (m_type)
{
case Slic3r::GUI::Back:
case Slic3r::GUI::Recalibrate:
SetBackgroundColor(btn_bg_white);
SetBorderColor(btn_bd_white);
SetTextColor(btn_text_white);
break;
case Slic3r::GUI::Start:
case Slic3r::GUI::Next:
case Slic3r::GUI::Calibrate:
case Slic3r::GUI::Save:
SetBackgroundColor(btn_bg_green);
SetBorderColor(btn_bd_green);
SetTextColor(btn_text_green);
break;
default:
break;
}
SetBackgroundColour(*wxWHITE);
SetFont(Label::Body_13);
SetMinSize(wxSize(-1, FromDIP(24)));
SetCornerRadius(FromDIP(12));
}
CalibrationWizardPage::CalibrationWizardPage(wxWindow* parent, bool has_split_line, wxWindowID id, const wxPoint& pos, const wxSize& size, long style)
: m_has_middle_line(has_split_line),
wxPanel(parent, id, pos, size, style)
{
SetBackgroundColour(*wxWHITE);
wxBoxSizer* page_sizer;
page_sizer = new wxBoxSizer(wxVERTICAL);
wxBoxSizer* title_sizer;
title_sizer = new wxBoxSizer(wxHORIZONTAL);
m_title = new wxStaticText(this, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, 0);
m_title->Wrap(-1);
m_title->SetFont(Label::Head_16);
title_sizer->Add(m_title, 0, wxALL | wxEXPAND, 0);
title_sizer->Add(0, 0, 1, wxEXPAND, 0);
m_index = new wxStaticText(this, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, 0);
m_index->Wrap(-1);
m_index->SetFont(Label::Head_16);
title_sizer->Add(m_index, 0, wxALL, 0);
page_sizer->Add(title_sizer, 0, wxEXPAND, 0);
page_sizer->Add(0, FromDIP(20), 0, wxEXPAND, 0);
m_top_sizer = new wxBoxSizer(wxVERTICAL);
page_sizer->Add(m_top_sizer, 0, wxEXPAND, 0);
wxBoxSizer* horiz_sizer;
horiz_sizer = new wxBoxSizer(wxHORIZONTAL);
m_left_sizer = new wxBoxSizer(wxVERTICAL);
horiz_sizer->Add(m_left_sizer, 1, wxEXPAND, 0);
auto middle_line = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(1, -1), wxTAB_TRAVERSAL);
middle_line->SetBackgroundColour(wxColour(0, 0, 0));
horiz_sizer->Add(middle_line, 0, wxEXPAND | wxRIGHT | wxLEFT, FromDIP(20));
if (!has_split_line) {
middle_line->Hide();
}
auto right_sizer = new wxBoxSizer(wxVERTICAL);
m_right_content_sizer = new wxBoxSizer(wxVERTICAL);
right_sizer->Add(m_right_content_sizer, 0, wxEXPAND, 0);
m_right_btn_sizer = new wxBoxSizer(wxHORIZONTAL);
m_right_btn_sizer->Add(0, 0, 1, wxEXPAND, 0);
m_btn_prev = new PageButton(this, "Back", Back);
m_right_btn_sizer->Add(m_btn_prev, 0);
m_right_btn_sizer->AddSpacer(FromDIP(10));
m_btn_next = new PageButton(this, "Next", Next);
m_right_btn_sizer->Add(m_btn_next, 0);
right_sizer->Add(m_right_btn_sizer, 0, wxEXPAND, 0);
horiz_sizer->Add(right_sizer, 1, wxEXPAND, 0);
page_sizer->Add(horiz_sizer, 1, wxEXPAND, 0);
this->SetSizer(page_sizer);
this->Layout();
page_sizer->Fit(this);
m_btn_prev->Bind(wxEVT_BUTTON, &CalibrationWizardPage::on_click_prev, this);
m_btn_next->Bind(wxEVT_BUTTON, &CalibrationWizardPage::on_click_next, this);
}
void CalibrationWizardPage::on_click_prev(wxCommandEvent&)
{
IntEvent e(EVT_CALIBRATIONPAGE_PREV, static_cast<int>(m_btn_prev->GetButtonType()), m_parent);
m_parent->GetEventHandler()->ProcessEvent(e);
}
void CalibrationWizardPage::on_click_next(wxCommandEvent&)
{
IntEvent e(EVT_CALIBRATIONPAGE_NEXT, static_cast<int>(m_btn_next->GetButtonType()), m_parent);
m_parent->GetEventHandler()->ProcessEvent(e);
}
}}

View file

@ -0,0 +1,81 @@
#ifndef slic3r_GUI_CalibrationWizardPage_hpp_
#define slic3r_GUI_CalibrationWizardPage_hpp_
#include "Widgets/Button.hpp"
#include "Event.hpp"
namespace Slic3r { namespace GUI {
wxDECLARE_EVENT(EVT_CALIBRATIONPAGE_PREV, IntEvent);
wxDECLARE_EVENT(EVT_CALIBRATIONPAGE_NEXT, IntEvent);
class CalibrationWizard;
enum ButtonType
{
Start,
Back,
Next,
Calibrate,
Recalibrate,
Save,
};
class PageButton : public Button
{
public:
PageButton(wxWindow* parent, wxString text, ButtonType type);
void SetButtonType(ButtonType rhs_type) { m_type = rhs_type; }
ButtonType GetButtonType() { return m_type; }
~PageButton() {};
private:
ButtonType m_type;
};
class CalibrationWizardPage : public wxPanel
{
public:
CalibrationWizardPage(wxWindow* parent, bool has_split_line, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxTAB_TRAVERSAL);
~CalibrationWizardPage() {};
CalibrationWizardPage* get_prev_page() { return m_prev_page; }
CalibrationWizardPage* get_next_page() { return m_next_page; }
void set_prev_page(CalibrationWizardPage* prev) { m_prev_page = prev; }
void set_next_page(CalibrationWizardPage* next) { m_next_page = next; }
CalibrationWizardPage* chain(CalibrationWizardPage* next)
{
set_next_page(next);
next->set_prev_page(this);
return next;
}
wxBoxSizer* get_top_vsizer() { return m_top_sizer; }
wxBoxSizer* get_left_vsizer() { return m_left_sizer; }
wxBoxSizer* get_right_content_vsizer() { return m_right_content_sizer; }
PageButton* get_prev_btn() { return m_btn_prev; }
PageButton* get_next_btn() { return m_btn_next; }
void set_page_title(wxString title) { m_title->SetLabel(title); }
void set_page_index(wxString index) { m_index->SetLabel(index); }
private:
bool m_has_middle_line;
wxStaticText* m_title;
wxStaticText* m_index;
wxBoxSizer* m_top_sizer;
wxBoxSizer* m_left_sizer;
wxBoxSizer* m_right_content_sizer;
wxBoxSizer* m_right_btn_sizer;
PageButton* m_btn_prev;
PageButton* m_btn_next;
CalibrationWizardPage* m_prev_page{nullptr};
CalibrationWizardPage* m_next_page{nullptr};
void on_click_prev(wxCommandEvent&);
void on_click_next(wxCommandEvent&);
};
}} // namespace Slic3r::GUI
#endif

View file

@ -37,6 +37,7 @@ PrintJob::PrintJob(std::shared_ptr<ProgressIndicator> pri, Plater* plater, std::
void PrintJob::prepare()
{
if (job_data.is_from_plater)
m_plater->get_print_job_data(&job_data);
if (&job_data) {
std::string temp_file = Slic3r::resources_dir() + "/check_access_code.txt";
@ -130,13 +131,13 @@ void PrintJob::process()
unsigned int http_code;
std::string http_body;
int total_plate_num = m_plater->get_partplate_list().get_plate_count();
PartPlate* plate = m_plater->get_partplate_list().get_plate(job_data.plate_idx);
int total_plate_num = plate_data.plate_count;
if (!plate_data.is_valid) {
total_plate_num = m_plater->get_partplate_list().get_plate_count();
PartPlate *plate = m_plater->get_partplate_list().get_plate(job_data.plate_idx);
if (plate == nullptr) {
plate = m_plater->get_partplate_list().get_curr_plate();
if (plate == nullptr)
return;
if (plate == nullptr) return;
}
/* check gcode is valid */
@ -149,10 +150,13 @@ void PrintJob::process()
update_status(curr_percent, printjob_cancel_str);
return;
}
}
// task name
std::string project_name = wxGetApp().plater()->get_project_name().ToUTF8().data();
int curr_plate_idx = 0;
if (plate_data.is_valid)
curr_plate_idx = plate_data.cur_plate_index;
if (job_data.plate_idx >= 0)
curr_plate_idx = job_data.plate_idx + 1;
else if (job_data.plate_idx == PLATE_CURRENT_IDX)
@ -164,7 +168,7 @@ void PrintJob::process()
PartPlate* curr_plate = m_plater->get_partplate_list().get_curr_plate();
if (curr_plate) {
this->task_bed_type = bed_type_to_gcode_string(curr_plate->get_bed_type(true));
this->task_bed_type = bed_type_to_gcode_string(plate_data.is_valid ? plate_data.bed_type : curr_plate->get_bed_type(true));
}
BBL::PrintParams params;

View file

@ -13,6 +13,7 @@ namespace GUI {
class PrintPrepareData
{
public:
bool is_from_plater = true;
int plate_idx;
fs::path _3mf_path;
fs::path _3mf_config_path;
@ -22,16 +23,28 @@ public:
}
};
class PlateListData
{
public:
bool is_valid = false;
int plate_count = 0;
int cur_plate_index = 0;
BedType bed_type = BedType::btDefault;
};
class PrintJob : public PlaterJob
{
std::function<void()> m_success_fun{nullptr};
PrintPrepareData job_data;
std::string m_dev_id;
bool m_job_finished{ false };
int m_print_job_completed_id = 0;
std::function<void()> m_enter_ip_address_fun_fail{ nullptr };
std::function<void()> m_enter_ip_address_fun_success{ nullptr };
public:
PrintPrepareData job_data;
PlateListData plate_data;
protected:
void prepare() override;
void on_exception(const std::exception_ptr &) override;

View file

@ -1021,6 +1021,20 @@ void MainFrame::init_tabpanel()
m_project->SetBackgroundColour(*wxWHITE);
m_tabpanel->AddPage(m_project, _L("Project"), std::string("tab_auxiliary_avtice"), std::string("tab_auxiliary_avtice"));
<<<<<<< HEAD (88f268 FIX: wipe tower is not generated with different filament lay)
=======
m_calibration = new CalibrationPanel(m_tabpanel, wxID_ANY, wxDefaultPosition, wxDefaultSize);
m_calibration->SetBackgroundColour(*wxWHITE);
m_tabpanel->AddPage(m_calibration, _L("Calibration"), std::string("tab_monitor_active"), std::string("tab_monitor_active"));
#if !BBL_RELEASE_TO_PUBLIC
m_debug_tool_dlg = new DebugToolDialog(m_tabpanel, wxID_ANY, wxDefaultPosition, wxDefaultSize);
m_debug_tool_dlg->SetBackgroundColour(*wxWHITE);
m_debug_tool_dlg->Hide();
m_tabpanel->AddPage(m_debug_tool_dlg, _L("Debug"), "debugtool", "debugtool");
#endif
>>>>>>> CHANGE (cbac2c NEW: add calibration)
if (m_plater) {
// load initial config
auto full_config = wxGetApp().preset_bundle->full_config();

View file

@ -21,6 +21,7 @@
#include "Monitor.hpp"
#include "Auxiliary.hpp"
#include "Project.hpp"
#include "CalibrationPanel.hpp"
#include "UnsavedChangesDialog.hpp"
#include "Widgets/SideButton.hpp"
#include "Widgets/SideMenuPopup.hpp"
@ -28,7 +29,6 @@
// BBS
#include "BBLTopbar.hpp"
#define ENABEL_PRINT_ALL 0
class Notebook;
@ -220,7 +220,8 @@ public:
tpPreview = 2,
tpMonitor = 3,
tpProject = 4,
toDebugTool = 5,
tpCalibration = 5,
toDebugTool = 6,
};
//BBS: add slice&&print status update logic
@ -338,7 +339,12 @@ public:
//AuxiliaryPanel* m_auxiliary{ nullptr };
ProjectPanel* m_project{ nullptr };
<<<<<<< HEAD (88f268 FIX: wipe tower is not generated with different filament lay)
=======
CalibrationPanel* m_calibration{ nullptr };
DebugToolDialog* m_debug_tool_dlg{ nullptr };
>>>>>>> CHANGE (cbac2c NEW: add calibration)
WebViewPanel* m_webview { nullptr };
wxLogWindow* m_log_window { nullptr };
// BBS

View file

@ -458,6 +458,10 @@ void MonitorPanel::update_all()
if (m_hms_panel->IsShown()) {
m_hms_panel->update(obj);
}
auto cali_panel = static_cast<CalibrationPanel*>(wxGetApp().mainframe->m_calibration);
if(cali_panel)
cali_panel->update_obj(obj);
#if !BBL_RELEASE_TO_PUBLIC
if (m_upgrade_panel->IsShown()) {
m_upgrade_panel->update(obj);

View file

@ -158,6 +158,7 @@ wxDEFINE_EVENT(EVT_PUBLISH, wxCommandEvent);
// BBS: backup & restore
wxDEFINE_EVENT(EVT_RESTORE_PROJECT, wxCommandEvent);
wxDEFINE_EVENT(EVT_PRINT_FINISHED, wxCommandEvent);
wxDEFINE_EVENT(EVT_SEND_CALIBRATION_FINISHED, wxCommandEvent);
wxDEFINE_EVENT(EVT_SEND_FINISHED, wxCommandEvent);
wxDEFINE_EVENT(EVT_PUBLISH_FINISHED, wxCommandEvent);
//BBS: repair model
@ -1903,7 +1904,11 @@ struct Plater::priv
bool init_collapse_toolbar();
// BBS
void hide_select_machine_dlg() { m_select_machine_dlg->EndModal(wxID_OK); }
void hide_select_machine_dlg()
{
if (m_select_machine_dlg)
m_select_machine_dlg->EndModal(wxID_OK);
}
void hide_send_to_printer_dlg() { m_send_to_sdcard_dlg->EndModal(wxID_OK); }
void update_preview_bottom_toolbar();
@ -2513,6 +2518,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
q->Bind(EVT_DOWNLOAD_PROJECT, &priv::on_action_download_project, this);
q->Bind(EVT_IMPORT_MODEL_ID, &priv::on_action_request_model_id, this);
q->Bind(EVT_PRINT_FINISHED, [q](wxCommandEvent &evt) { q->print_job_finished(evt); });
q->Bind(EVT_SEND_CALIBRATION_FINISHED, [q](wxCommandEvent &evt) { q->send_calibration_job_finished(evt); });
q->Bind(EVT_SEND_FINISHED, [q](wxCommandEvent &evt) { q->send_job_finished(evt); });
q->Bind(EVT_PUBLISH_FINISHED, [q](wxCommandEvent &evt) { q->publish_job_finished(evt);});
//q->Bind(EVT_GLVIEWTOOLBAR_ASSEMBLE, [q](SimpleEvent&) { q->select_view_3D("Assemble"); });
@ -6744,6 +6750,11 @@ void Plater::get_print_job_data(PrintPrepareData* data)
}
}
int Plater::get_send_calibration_finished_event()
{
return EVT_SEND_CALIBRATION_FINISHED;
}
int Plater::get_print_finished_event()
{
return EVT_PRINT_FINISHED;
@ -8074,7 +8085,7 @@ void Plater::add_model(bool imperial_units/* = false*/)
return;
std::vector<fs::path> paths;
for (const auto &file : input_files)
for (const auto& file : input_files)
paths.emplace_back(into_path(file));
std::string snapshot_label;
@ -10281,6 +10292,23 @@ int Plater::export_config_3mf(int plate_idx, Export3mfProgressFn proFn)
}
//BBS
void Plater::send_calibration_job_finished(wxCommandEvent & evt)
{
Slic3r::DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager();
if (!dev) return;
dev->set_selected_machine(evt.GetString().ToStdString());
p->hide_select_machine_dlg();
p->main_frame->request_select_tab(MainFrame::TabPosition::tpCalibration);
//jump to monitor and select device status panel
auto curr_calibration = p->main_frame->m_calibration;
if (curr_calibration) {
// todo select current tab
auto calibration_wizard = static_cast<CalibrationWizard*>(curr_calibration->get_tabpanel()->GetPage(curr_calibration->get_tabpanel()->GetSelection()));
calibration_wizard->show_page(calibration_wizard->get_curr_page()->get_next_page());
}
}
void Plater::print_job_finished(wxCommandEvent &evt)
{
Slic3r::DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager();

View file

@ -357,6 +357,7 @@ public:
void send_gcode_legacy(int plate_idx = -1, Export3mfProgressFn proFn = nullptr);
int export_config_3mf(int plate_idx = -1, Export3mfProgressFn proFn = nullptr);
//BBS jump to nonitor after print job finished
void send_calibration_job_finished(wxCommandEvent &evt);
void print_job_finished(wxCommandEvent &evt);
void send_job_finished(wxCommandEvent& evt);
void publish_job_finished(wxCommandEvent& evt);
@ -426,6 +427,7 @@ public:
int get_prepare_state();
//BBS: add print job releated functions
void get_print_job_data(PrintPrepareData* data);
int get_send_calibration_finished_event();
int get_print_finished_event();
int get_send_finished_event();
int get_publish_finished_event();

View file

@ -181,7 +181,7 @@ void AMSrefresh::on_timer(wxTimerEvent &event)
void AMSrefresh::PlayLoading()
{
if (m_play_loading) return;
if (m_play_loading | m_disable_mode) return;
m_play_loading = true;
//m_rotation_angle = 0;
m_playing_timer->Start(AMS_REFRESH_PLAY_LOADING_TIMER);
@ -190,7 +190,7 @@ void AMSrefresh::PlayLoading()
void AMSrefresh::StopLoading()
{
if (!m_play_loading) return;
if (!m_play_loading | m_disable_mode) return;
m_playing_timer->Stop();
m_play_loading = false;
Refresh();
@ -214,6 +214,8 @@ void AMSrefresh::OnClick(wxMouseEvent &evt) {
void AMSrefresh::post_event(wxCommandEvent &&event)
{
if (m_disable_mode)
return;
event.SetString(m_info.can_id);
event.SetEventObject(m_parent);
wxPostEvent(m_parent, event);
@ -230,9 +232,11 @@ void AMSrefresh::paintEvent(wxPaintEvent &evt)
auto pot = wxPoint((size.x - m_bitmap_selected.GetBmpSize().x) / 2, (size.y - m_bitmap_selected.GetBmpSize().y) / 2);
if (!m_disable_mode) {
if (!m_play_loading) {
dc.DrawBitmap(m_selected ? m_bitmap_selected.bmp() : m_bitmap_normal.bmp(), pot);
} else {
}
else {
/* m_bitmap_rotation = ScalableBitmap(this, "ams_refresh_normal", 30);
auto image = m_bitmap_rotation.bmp().ConvertToImage();
wxPoint offset;
@ -247,6 +251,7 @@ void AMSrefresh::paintEvent(wxPaintEvent &evt)
if (m_rfid_bitmap_list.size() <= 0)return;
dc.DrawBitmap(m_rfid_bitmap_list[m_rotation_angle].bmp(), pot);
}
}
dc.SetPen(wxPen(colour));
dc.SetBrush(wxBrush(colour));
@ -964,7 +969,7 @@ void AMSLib::doRender(wxDC &dc)
dc.DrawRoundedRectangle(FromDIP(3), FromDIP(3), size.x - FromDIP(6), size.y - FromDIP(6), m_radius);
#endif
if (!m_disable_mode) {
// edit icon
if (m_info.material_state != AMSCanType::AMS_CAN_TYPE_EMPTY && m_info.material_state != AMSCanType::AMS_CAN_TYPE_NONE)
{
@ -973,6 +978,7 @@ void AMSLib::doRender(wxDC &dc)
if (m_info.material_state == AMSCanType::AMS_CAN_TYPE_BRAND)
dc.DrawBitmap(temp_bitmap_brand.bmp(), (size.x - temp_bitmap_brand.GetBmpSize().x) / 2, (size.y - FromDIP(10) - temp_bitmap_brand.GetBmpSize().y));
}
}
}
void AMSLib::Update(Caninfo info, bool refresh)
@ -2416,6 +2422,31 @@ void AMSControl::ExitNoneAMSMode()
m_is_none_ams_mode = false;
}
void AMSControl::EnterSimpleMode()
{
// hide AmsLib edit button
// hide AmsRefresh bmp
for (auto ams_cans_window : m_ams_cans_list) {
ams_cans_window->set_disable_mode(true);
}
m_vams_lib->set_disable_mode(true);
// hide buttons
m_button_ams_setting->Hide();
m_button_extruder_feed->Hide();
m_button_extruder_back->Hide();
m_button_extrusion_cali->Hide();
m_button_guide->Hide();
m_button_retry->Hide();
// hide tips
ShowFilamentTip(false);
m_amswin->Layout();
m_amswin->Fit();
Layout();
}
void AMSControl::EnterCalibrationMode(bool read_to_calibration)
{
SetSelection(1);
@ -2580,7 +2611,7 @@ void AMSControl::Reset()
m_current_senect = "";
}
void AMSControl::show_noams_mode(bool show, bool support_virtual_tray, bool support_extrustion_cali, bool support_vt_load)
void AMSControl::show_noams_mode(bool show, bool support_virtual_tray, bool support_extrustion_cali, bool support_vt_load, bool simple_mode)
{
show_vams(support_virtual_tray);
m_sizer_ams_tips->Show(support_virtual_tray);
@ -2592,6 +2623,8 @@ void AMSControl::show_noams_mode(bool show, bool support_virtual_tray, bool supp
}
show?ExitNoneAMSMode() : EnterNoneAMSMode(support_vt_load);
if (simple_mode)
EnterSimpleMode();
}
void AMSControl::show_vams(bool show)

View file

@ -176,6 +176,7 @@ public:
void paintEvent(wxPaintEvent &evt);
void Update(std::string ams_id, Caninfo info);
void msw_rescale();
void set_disable_mode(bool disable) { m_disable_mode = disable; }
Caninfo m_info;
@ -203,6 +204,8 @@ protected:
wxString m_refresh_id;
wxBoxSizer * m_size_body;
virtual void DoSetSize(int x, int y, int width, int height, int sizeFlags = wxSIZE_AUTO);
bool m_disable_mode{ false };
};
/*************************************************
@ -299,7 +302,7 @@ public:
void show_kn_value(bool show) { m_show_kn = show; };
void support_cali(bool sup) { m_support_cali = sup; Refresh(); };
virtual bool Enable(bool enable = true);
void set_disable_mode(bool disable) { m_disable_mode = disable; }
protected:
wxStaticBitmap *m_edit_bitmp = {nullptr};
@ -321,6 +324,7 @@ protected:
wxColour m_border_color;
wxColour m_road_def_color;
wxColour m_lib_color;
bool m_disable_mode{ false };
void on_enter_window(wxMouseEvent &evt);
void on_leave_window(wxMouseEvent &evt);
@ -463,7 +467,6 @@ public:
void StopRridLoading(wxString canid);
void msw_rescale();
void show_sn_value(bool show);
std::string GetCurrentCan();
public:
@ -487,6 +490,17 @@ class AmsCansWindow
public:
wxString amsIndex;
AmsCans *amsCans;
bool m_disable_mode{ false };
void set_disable_mode(bool disable) {
m_disable_mode = disable;
for (auto can_lib : amsCans->m_can_lib_list) {
can_lib->canLib->set_disable_mode(disable);
}
for (auto can_refresh : amsCans->m_can_refresh_list) {
can_refresh->canrefresh->set_disable_mode(disable);
}
}
};
class AmsItems
@ -589,6 +603,7 @@ public:
void SetActionState(bool button_status[]);
void EnterNoneAMSMode(bool support_vt_load = false);
void ExitNoneAMSMode();
void EnterSimpleMode();
void EnterCalibrationMode(bool read_to_calibration);
void ExitcClibrationMode();
@ -621,7 +636,7 @@ public:
void on_clibration_cancel_click(wxMouseEvent &event);
void Reset();
void show_noams_mode(bool show, bool support_virtual_tray, bool support_extrustion_cali, bool support_vt_load = false);
void show_noams_mode(bool show, bool support_virtual_tray, bool support_extrustion_cali, bool support_vt_load = false, bool simple_mode = false);
void show_vams(bool show);
void show_vams_kn_value(bool show);
void update_vams_kn_value(AmsTray tray, MachineObject* obj);

View file

@ -0,0 +1,473 @@
#include "CalibUtils.hpp"
#include "../GUI/GUI_App.hpp"
#include "../GUI/DeviceManager.hpp"
#include "../GUI/Jobs/PrintJob.hpp"
#include "../GUI/Jobs/ProgressIndicator.hpp"
#include "../GUI/PartPlate.hpp"
#include "libslic3r/Model.hpp"
// todo test
#include "../GUI/BBLStatusBar.hpp"
namespace Slic3r {
namespace GUI {
std::shared_ptr<PrintJob> print_job;
static const std::string temp_dir = "D:/temp/";
static const std::string temp_gcode_path = temp_dir + "temp.gcode";
static const std::string path = temp_dir + "test.3mf";
static const std::string config_3mf_path = temp_dir + "test_config.3mf";
static void cut_model(Model &model, std::array<Vec3d, 4> plane_points, ModelObjectCutAttributes attributes)
{
size_t obj_idx = 0;
size_t instance_idx = 0;
if (!attributes.has(ModelObjectCutAttribute::KeepUpper) && !attributes.has(ModelObjectCutAttribute::KeepLower))
return;
auto* object = model.objects[0];
const auto new_objects = object->cut(instance_idx, plane_points, attributes);
model.delete_object(obj_idx);
for (ModelObject *model_object : new_objects) {
auto *object = model.add_object(*model_object);
object->sort_volumes(true);
std::string object_name = object->name.empty() ? fs::path(object->input_file).filename().string() : object->name;
object->ensure_on_bed();
}
}
static void read_model_from_file(const std::string& input_file, Model& model)
{
LoadStrategy strategy = LoadStrategy::LoadModel;
ConfigSubstitutionContext config_substitutions{ForwardCompatibilitySubstitutionRule::Enable};
int plate_to_slice = 0;
bool is_bbl_3mf;
Semver file_version;
DynamicPrintConfig config;
PlateDataPtrs plate_data_src;
std::vector<Preset *> project_presets;
model = Model::read_from_file(input_file, &config, &config_substitutions, strategy, &plate_data_src, &project_presets,
&is_bbl_3mf, &file_version, nullptr, nullptr, nullptr, nullptr, nullptr, plate_to_slice);
model.add_default_instances();
for (auto object : model.objects)
object->ensure_on_bed();
}
void CalibUtils::calib_flowrate(int pass, std::string dev_id, std::string select_ams, std::shared_ptr<ProgressIndicator> process_bar)
{
if (pass != 1 && pass != 2)
return;
Model model;
std::string input_file;
if (pass == 1)
input_file = Slic3r::resources_dir() + "/calib/filament_flow/flowrate-test-pass1.3mf";
else
input_file = Slic3r::resources_dir() + "/calib/filament_flow/flowrate-test-pass2.3mf";
read_model_from_file(input_file, model);
DynamicConfig print_config = wxGetApp().preset_bundle->prints.get_edited_preset().config;
DynamicConfig printer_config = wxGetApp().preset_bundle->printers.get_edited_preset().config;
DynamicConfig filament_config = wxGetApp().preset_bundle->filaments.get_edited_preset().config;
/// --- scale ---
// model is created for a 0.4 nozzle, scale z with nozzle size.
const ConfigOptionFloats *nozzle_diameter_config = printer_config.option<ConfigOptionFloats>("nozzle_diameter");
assert(nozzle_diameter_config->values.size() > 0);
float nozzle_diameter = nozzle_diameter_config->values[0];
float xyScale = nozzle_diameter / 0.6;
// scale z to have 7 layers
double first_layer_height = print_config.option<ConfigOptionFloat>("initial_layer_print_height")->value;
double layer_height = nozzle_diameter / 2.0; // prefer 0.2 layer height for 0.4 nozzle
first_layer_height = std::max(first_layer_height, layer_height);
float zscale = (first_layer_height + 6 * layer_height) / 1.4;
// only enlarge
if (xyScale > 1.2) {
for (auto _obj : model.objects) _obj->scale(xyScale, xyScale, zscale);
} else {
for (auto _obj : model.objects) _obj->scale(1, 1, zscale);
}
Flow infill_flow = Flow(nozzle_diameter * 1.2f, layer_height, nozzle_diameter);
double filament_max_volumetric_speed = filament_config.option<ConfigOptionFloats>("filament_max_volumetric_speed")->get_at(0);
double max_infill_speed = filament_max_volumetric_speed / (infill_flow.mm3_per_mm() * (pass == 1 ? 1.2 : 1));
double internal_solid_speed = std::floor(std::min(print_config.opt_float("internal_solid_infill_speed"), max_infill_speed));
double top_surface_speed = std::floor(std::min(print_config.opt_float("top_surface_speed"), max_infill_speed));
// adjust parameters
for (auto _obj : model.objects) {
_obj->ensure_on_bed();
_obj->config.set_key_value("wall_loops", new ConfigOptionInt(3));
_obj->config.set_key_value("only_one_wall_top", new ConfigOptionBool(true));
_obj->config.set_key_value("sparse_infill_density", new ConfigOptionPercent(35));
_obj->config.set_key_value("bottom_shell_layers", new ConfigOptionInt(1));
_obj->config.set_key_value("top_shell_layers", new ConfigOptionInt(5));
_obj->config.set_key_value("detect_thin_wall", new ConfigOptionBool(true));
//_obj->config.set_key_value("filter_out_gap_fill", new ConfigOptionFloat(0)); // SoftFever parameter
_obj->config.set_key_value("sparse_infill_pattern", new ConfigOptionEnum<InfillPattern>(ipRectilinear));
_obj->config.set_key_value("top_surface_line_width", new ConfigOptionFloat(nozzle_diameter * 1.2f));
_obj->config.set_key_value("internal_solid_infill_line_width", new ConfigOptionFloat(nozzle_diameter * 1.2f));
_obj->config.set_key_value("top_surface_pattern", new ConfigOptionEnum<InfillPattern>(ipMonotonic));
// _obj->config.set_key_value("top_solid_infill_flow_ratio", new ConfigOptionFloat(1.0f)); // not need
_obj->config.set_key_value("infill_direction", new ConfigOptionFloat(45));
_obj->config.set_key_value("ironing_type", new ConfigOptionEnum<IroningType>(IroningType::NoIroning));
_obj->config.set_key_value("internal_solid_infill_speed", new ConfigOptionFloat(internal_solid_speed));
_obj->config.set_key_value("top_surface_speed", new ConfigOptionFloat(top_surface_speed));
// extract flowrate from name, filename format: flowrate_xxx
std::string obj_name = _obj->name;
assert(obj_name.length() > 9);
obj_name = obj_name.substr(9);
if (obj_name[0] == 'm') obj_name[0] = '-';
auto modifier = stof(obj_name);
_obj->config.set_key_value("print_flow_ratio", new ConfigOptionFloat(1.0f + modifier / 100.f));
}
print_config.set_key_value("layer_height", new ConfigOptionFloat(layer_height));
print_config.set_key_value("initial_layer_print_height", new ConfigOptionFloat(first_layer_height));
print_config.set_key_value("reduce_crossing_wall", new ConfigOptionBool(true));
// apply preset
DynamicPrintConfig full_config;
full_config.apply(FullPrintConfig::defaults());
full_config.apply(print_config);
full_config.apply(filament_config);
full_config.apply(printer_config);
Calib_Params params;
params.mode = CalibMode::Calib_None;
process_and_store_3mf(&model, full_config, params);
send_to_print(dev_id, select_ams, process_bar);
}
void CalibUtils::calib_temptue(const Calib_Params& params, std::string dev_id, std::string select_ams, std::shared_ptr<ProgressIndicator> process_bar) {
if (params.mode != CalibMode::Calib_Temp_Tower)
return;
Model model;
std::string input_file = Slic3r::resources_dir() + "/calib/temperature_tower/temperature_tower.stl";
read_model_from_file(input_file, model);
// cut upper
auto obj_bb = model.objects[0]->bounding_box();
auto block_count = lround((350 - params.start) / 5 + 1);
if (block_count > 0) {
// add EPSILON offset to avoid cutting at the exact location where the flat surface is
auto new_height = block_count * 10.0 + EPSILON;
if (new_height < obj_bb.size().z()) {
std::array<Vec3d, 4> plane_pts;
plane_pts[0] = Vec3d(obj_bb.min(0), obj_bb.min(1), new_height);
plane_pts[1] = Vec3d(obj_bb.max(0), obj_bb.min(1), new_height);
plane_pts[2] = Vec3d(obj_bb.max(0), obj_bb.max(1), new_height);
plane_pts[3] = Vec3d(obj_bb.min(0), obj_bb.max(1), new_height);
cut_model(model, plane_pts, ModelObjectCutAttribute::KeepLower);
}
}
// cut bottom
obj_bb = model.objects[0]->bounding_box();
block_count = lround((350 - params.end) / 5);
if (block_count > 0) {
auto new_height = block_count * 10.0 + EPSILON;
if (new_height < obj_bb.size().z()) {
std::array<Vec3d, 4> plane_pts;
plane_pts[0] = Vec3d(obj_bb.min(0), obj_bb.min(1), new_height);
plane_pts[1] = Vec3d(obj_bb.max(0), obj_bb.min(1), new_height);
plane_pts[2] = Vec3d(obj_bb.max(0), obj_bb.max(1), new_height);
plane_pts[3] = Vec3d(obj_bb.min(0), obj_bb.max(1), new_height);
cut_model(model, plane_pts, ModelObjectCutAttribute::KeepUpper);
}
}
// edit preset
PresetBundle * preset_bundle = wxGetApp().preset_bundle;
DynamicPrintConfig print_config = preset_bundle->prints.get_edited_preset().config;
DynamicPrintConfig filament_config = preset_bundle->filaments.get_edited_preset().config;
DynamicPrintConfig printer_config = preset_bundle->printers.get_edited_preset().config;
auto start_temp = lround(params.start);
filament_config.set_key_value("nozzle_temperature_initial_layer", new ConfigOptionInts(1, (int) start_temp));
filament_config.set_key_value("nozzle_temperature", new ConfigOptionInts(1, (int) start_temp));
model.objects[0]->config.set_key_value("brim_type", new ConfigOptionEnum<BrimType>(btOuterOnly));
model.objects[0]->config.set_key_value("brim_width", new ConfigOptionFloat(5.0));
model.objects[0]->config.set_key_value("brim_object_gap", new ConfigOptionFloat(0.0));
// apply preset
DynamicPrintConfig full_config;
full_config.apply(FullPrintConfig::defaults());
full_config.apply(print_config);
full_config.apply(filament_config);
full_config.apply(printer_config);
process_and_store_3mf(&model, full_config, params);
send_to_print(dev_id, select_ams, process_bar);
}
void CalibUtils::calib_max_vol_speed(const Calib_Params &params, std::string dev_id, std::string select_ams, std::shared_ptr<ProgressIndicator> process_bar)
{
if (params.mode != CalibMode::Calib_Vol_speed_Tower)
return;
Model model;
std::string input_file = Slic3r::resources_dir() + "/calib/volumetric_speed/SpeedTestStructure.step";
read_model_from_file(input_file, model);
PresetBundle * preset_bundle = wxGetApp().preset_bundle;
DynamicPrintConfig print_config = preset_bundle->prints.get_edited_preset().config;
DynamicPrintConfig filament_config = preset_bundle->filaments.get_edited_preset().config;
DynamicPrintConfig printer_config = preset_bundle->printers.get_edited_preset().config;
auto obj = model.objects[0];
auto bed_shape = printer_config.option<ConfigOptionPoints>("printable_area")->values;
BoundingBoxf bed_ext = get_extents(bed_shape);
auto scale_obj = (bed_ext.size().x() - 10) / obj->bounding_box().size().x();
if (scale_obj < 1.0)
obj->scale(scale_obj, 1, 1);
const ConfigOptionFloats *nozzle_diameter_config = printer_config.option<ConfigOptionFloats>("nozzle_diameter");
assert(nozzle_diameter_config->values.size() > 0);
double nozzle_diameter = nozzle_diameter_config->values[0];
double line_width = nozzle_diameter * 1.75;
double layer_height = nozzle_diameter * 0.8;
auto max_lh = printer_config.option<ConfigOptionFloats>("max_layer_height");
if (max_lh->values[0] < layer_height) max_lh->values[0] = {layer_height};
filament_config.set_key_value("filament_max_volumetric_speed", new ConfigOptionFloats{200});
filament_config.set_key_value("slow_down_layer_time", new ConfigOptionInts{0});
print_config.set_key_value("enable_overhang_speed", new ConfigOptionBool{false});
print_config.set_key_value("timelapse_type", new ConfigOptionEnum<TimelapseType>(tlTraditional));
print_config.set_key_value("wall_loops", new ConfigOptionInt(1));
print_config.set_key_value("top_shell_layers", new ConfigOptionInt(0));
print_config.set_key_value("bottom_shell_layers", new ConfigOptionInt(1));
print_config.set_key_value("sparse_infill_density", new ConfigOptionPercent(0));
print_config.set_key_value("spiral_mode", new ConfigOptionBool(true));
print_config.set_key_value("outer_wall_line_width", new ConfigOptionFloat(line_width));
print_config.set_key_value("initial_layer_print_height", new ConfigOptionFloat(layer_height));
print_config.set_key_value("layer_height", new ConfigOptionFloat(layer_height));
obj->config.set_key_value("brim_type", new ConfigOptionEnum<BrimType>(btOuterAndInner));
obj->config.set_key_value("brim_width", new ConfigOptionFloat(3.0));
obj->config.set_key_value("brim_object_gap", new ConfigOptionFloat(0.0));
// cut upper
auto obj_bb = obj->bounding_box();
auto height = (params.end - params.start + 1) / params.step;
if (height < obj_bb.size().z()) {
std::array<Vec3d, 4> plane_pts;
plane_pts[0] = Vec3d(obj_bb.min(0), obj_bb.min(1), height);
plane_pts[1] = Vec3d(obj_bb.max(0), obj_bb.min(1), height);
plane_pts[2] = Vec3d(obj_bb.max(0), obj_bb.max(1), height);
plane_pts[3] = Vec3d(obj_bb.min(0), obj_bb.max(1), height);
cut_model(model, plane_pts, ModelObjectCutAttribute::KeepLower);
}
auto new_params = params;
auto mm3_per_mm = Flow(line_width, layer_height, nozzle_diameter).mm3_per_mm() * filament_config.option<ConfigOptionFloats>("filament_flow_ratio")->get_at(0);
new_params.end = params.end / mm3_per_mm;
new_params.start = params.start / mm3_per_mm;
new_params.step = params.step / mm3_per_mm;
DynamicPrintConfig full_config;
full_config.apply(FullPrintConfig::defaults());
full_config.apply(print_config);
full_config.apply(filament_config);
full_config.apply(printer_config);
process_and_store_3mf(&model, full_config, new_params);
send_to_print(dev_id, select_ams, process_bar);
}
void CalibUtils::calib_VFA(const Calib_Params& params)
{
if (params.mode != CalibMode::Calib_VFA_Tower)
return;
Model model;
std::string input_file = Slic3r::resources_dir() + "/calib/vfa/VFA.stl";
read_model_from_file(input_file, model);
PresetBundle * preset_bundle = wxGetApp().preset_bundle;
DynamicPrintConfig print_config = preset_bundle->prints.get_edited_preset().config;
DynamicPrintConfig filament_config = preset_bundle->filaments.get_edited_preset().config;
DynamicPrintConfig printer_config = preset_bundle->printers.get_edited_preset().config;
filament_config.set_key_value("slow_down_layer_time", new ConfigOptionInts{0});
filament_config.set_key_value("filament_max_volumetric_speed", new ConfigOptionFloats{200});
print_config.set_key_value("enable_overhang_speed", new ConfigOptionBool{false});
print_config.set_key_value("timelapse_type", new ConfigOptionEnum<TimelapseType>(tlTraditional));
print_config.set_key_value("wall_loops", new ConfigOptionInt(1));
print_config.set_key_value("top_shell_layers", new ConfigOptionInt(0));
print_config.set_key_value("bottom_shell_layers", new ConfigOptionInt(1));
print_config.set_key_value("sparse_infill_density", new ConfigOptionPercent(0));
print_config.set_key_value("spiral_mode", new ConfigOptionBool(true));
model.objects[0]->config.set_key_value("brim_type", new ConfigOptionEnum<BrimType>(btOuterOnly));
model.objects[0]->config.set_key_value("brim_width", new ConfigOptionFloat(3.0));
model.objects[0]->config.set_key_value("brim_object_gap", new ConfigOptionFloat(0.0));
// cut upper
auto obj_bb = model.objects[0]->bounding_box();
auto height = 5 * ((params.end - params.start) / params.step + 1);
if (height < obj_bb.size().z()) {
std::array<Vec3d, 4> plane_pts;
plane_pts[0] = Vec3d(obj_bb.min(0), obj_bb.min(1), height);
plane_pts[1] = Vec3d(obj_bb.max(0), obj_bb.min(1), height);
plane_pts[2] = Vec3d(obj_bb.max(0), obj_bb.max(1), height);
plane_pts[3] = Vec3d(obj_bb.min(0), obj_bb.max(1), height);
cut_model(model, plane_pts, ModelObjectCutAttribute::KeepLower);
}
DynamicPrintConfig full_config;
full_config.apply(FullPrintConfig::defaults());
full_config.apply(print_config);
full_config.apply(filament_config);
full_config.apply(printer_config);
process_and_store_3mf(&model, full_config, params);
std::string dev_id = "00M00A252000001"; // to do: hard code test
std::string select_ams = "[0]";
std::shared_ptr<ProgressIndicator> process_bar(new BBLStatusBar(wxGetApp().plater()));
send_to_print(dev_id, select_ams, process_bar);
}
void CalibUtils::process_and_store_3mf(Model *model, const DynamicPrintConfig &full_config, const Calib_Params &params)
{
Pointfs bedfs = full_config.opt<ConfigOptionPoints>("printable_area")->values;
double print_height = full_config.opt_float("printable_height");
double current_width = bedfs[2].x() - bedfs[0].x();
double current_depth = bedfs[2].y() - bedfs[0].y();
Vec3i plate_size;
plate_size[0] = bedfs[2].x() - bedfs[0].x();
plate_size[1] = bedfs[2].y() - bedfs[0].y();
plate_size[2] = print_height;
// todo: adjust the objects position
if (model->objects.size() == 1) {
ModelInstance *instance = model->objects[0]->instances[0];
instance->set_offset(instance->get_offset() + Vec3d(current_width / 2, current_depth / 2, 0));
}
else {
for (auto object : model->objects) {
ModelInstance *instance = object->instances[0];
instance->set_offset(instance->get_offset() + Vec3d(100, 100, 0));
}
}
Slic3r::GUI::PartPlateList partplate_list(nullptr, model, PrinterTechnology::ptFFF);
partplate_list.reset_size(plate_size.x(), plate_size.y(), plate_size.z(), false);
Slic3r::GUI::PartPlate *part_plate = partplate_list.get_plate(0);
PrintBase * print = NULL;
Slic3r::GUI::GCodeResult *gcode_result = NULL;
int print_index;
part_plate->get_print(&print, &gcode_result, &print_index);
// apply the new print config
DynamicPrintConfig new_print_config = std::move(full_config);
print->apply(*model, new_print_config);
Print *fff_print = dynamic_cast<Print *>(print);
fff_print->set_calib_params(params);
fff_print->process();
part_plate->update_slice_result_valid_state(true);
gcode_result->reset();
fff_print->export_gcode(temp_gcode_path, gcode_result, nullptr);
PlateDataPtrs plate_data_list;
partplate_list.store_to_3mf_structure(plate_data_list, true, 0);
for (auto plate_data : plate_data_list) {
plate_data->gcode_file = temp_gcode_path;
plate_data->is_sliced_valid = true;
plate_data->slice_filaments_info;
}
StoreParams store_params;
store_params.path = path.c_str();
store_params.model = model;
store_params.plate_data_list = plate_data_list;
store_params.config = &new_print_config;
store_params.strategy = SaveStrategy::Silence | SaveStrategy::WithGcode | SaveStrategy::SplitModel | SaveStrategy::SkipModel;
bool success = Slic3r::store_bbs_3mf(store_params);
store_params.strategy = SaveStrategy::Silence | SaveStrategy::SplitModel | SaveStrategy::WithSliceInfo | SaveStrategy::SkipAuxiliary;
store_params.path = config_3mf_path.c_str();
success = Slic3r::store_bbs_3mf(store_params);
}
void CalibUtils::send_to_print(const std::string &dev_id, const std::string &select_ams, std::shared_ptr<ProgressIndicator> process_bar)
{
DeviceManager *dev = Slic3r::GUI::wxGetApp().getDeviceManager();
if (!dev)
return;
MachineObject *obj_ = dev->get_selected_machine();
if (obj_ == nullptr)
return;
print_job = std::make_shared<PrintJob>(std::move(process_bar), wxGetApp().plater(), dev_id);
print_job->m_dev_ip = obj_->dev_ip;
print_job->m_ftp_folder = obj_->get_ftp_folder();
print_job->m_access_code = obj_->get_access_code();
print_job->m_local_use_ssl_for_ftp = obj_->local_use_ssl_for_ftp;
print_job->m_local_use_ssl_for_mqtt = obj_->local_use_ssl_for_mqtt;
print_job->connection_type = obj_->connection_type();
print_job->cloud_print_only = obj_->is_cloud_print_only;
print_job->set_print_job_finished_event(wxGetApp().plater()->get_send_calibration_finished_event());
PrintPrepareData job_data;
job_data.is_from_plater = false;
job_data.plate_idx = 0;
job_data._3mf_config_path = config_3mf_path;
job_data._3mf_path = path;
job_data._temp_path = temp_dir;
PlateListData plate_data;
plate_data.is_valid = true;
plate_data.plate_count = 1;
plate_data.cur_plate_index = 0;
plate_data.bed_type = BedType::btPC;
print_job->job_data = job_data;
print_job->plate_data = plate_data;
if (!obj_->is_support_ams_mapping())
return;
if (!obj_->has_ams())
return;
print_job->task_ams_mapping = select_ams;
print_job->task_ams_mapping_info = "";
print_job->task_use_ams = true;
print_job->has_sdcard = obj_->has_sdcard();
print_job->set_print_config("pc", true, false, false, false, true);
print_job->start();
}
}
}

View file

@ -0,0 +1,25 @@
#pragma once
#include "libslic3r/Calib.hpp"
namespace Slic3r {
class ProgressIndicator;
namespace GUI {
class CalibUtils
{
public:
CalibUtils(){};
static void calib_flowrate(int pass, std::string dev_id, std::string select_ams, std::shared_ptr<ProgressIndicator> process_bar);
static void calib_temptue(const Calib_Params &params, std::string dev_id, std::string select_ams, std::shared_ptr<ProgressIndicator> process_bar);
static void calib_max_vol_speed(const Calib_Params &params, std::string dev_id, std::string select_ams, std::shared_ptr<ProgressIndicator> process_bar);
static void calib_VFA(const Calib_Params &params);
private:
static void process_and_store_3mf(Model *model, const DynamicPrintConfig &full_config, const Calib_Params &params);
static void send_to_print(const std::string &dev_id, const std::string &select_ams, std::shared_ptr<ProgressIndicator> process_bar);
};
}
}