NEW: add calibration

Change-Id: I03e5489a67042e7f76f5a42260a289d540b5a63a
(cherry picked from commit cbac2c639db830eb779b1979c8d6b4eb3decb7e6)
This commit is contained in:
liz.li
2023-07-07 17:25:51 +08:00
committed by Lane.Wei
parent ff3f78cfb5
commit 1f54aaf22b
35 changed files with 38647 additions and 54 deletions
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

+1
View File
@@ -37,6 +37,7 @@ set(lisbslic3r_sources
Brim.hpp
BuildVolume.cpp
BuildVolume.hpp
Calib.hpp
Circle.cpp
Circle.hpp
clipper.cpp
+26
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
+16 -1
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
+1
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;
+3 -1
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 {
+5
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);
+9
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.
+8
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");
+6
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,
+8
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)
+74
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);
}
}
}
}}
+36
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
+154
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
+148
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);
}
}}
+81
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
+22 -18
View File
@@ -37,7 +37,8 @@ PrintJob::PrintJob(std::shared_ptr<ProgressIndicator> pri, Plater* plater, std::
void PrintJob::prepare()
{
m_plater->get_print_job_data(&job_data);
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";
auto check_access_code_path = temp_file.c_str();
@@ -130,29 +131,32 @@ void PrintJob::process()
unsigned int http_code;
std::string http_body;
int total_plate_num = m_plater->get_partplate_list().get_plate_count();
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;
}
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;
}
/* check gcode is valid */
if (!plate->is_valid_gcode_file() && m_print_type == "from_normal") {
update_status(curr_percent, check_gcode_failed_str);
return;
}
/* check gcode is valid */
if (!plate->is_valid_gcode_file() && m_print_type == "from_normal") {
update_status(curr_percent, check_gcode_failed_str);
return;
}
if (was_canceled()) {
update_status(curr_percent, printjob_cancel_str);
return;
if (was_canceled()) {
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;
+14 -1
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;
+14
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();
+8 -2
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
+4
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);
+30 -2
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();
+2
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();
+59 -26
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,22 +232,25 @@ 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_play_loading) {
dc.DrawBitmap(m_selected ? m_bitmap_selected.bmp() : m_bitmap_normal.bmp(), pot);
} else {
/* m_bitmap_rotation = ScalableBitmap(this, "ams_refresh_normal", 30);
auto image = m_bitmap_rotation.bmp().ConvertToImage();
wxPoint offset;
auto loading_img = image.Rotate(m_rotation_angle, wxPoint(image.GetWidth() / 2, image.GetHeight() / 2), true, &offset);
ScalableBitmap loading_bitmap;
loading_bitmap.bmp() = wxBitmap(loading_img);
dc.DrawBitmap(loading_bitmap.bmp(), offset.x , offset.y);*/
m_rotation_angle++;
if (m_rotation_angle >= m_rfid_bitmap_list.size()) {
m_rotation_angle = 0;
if (!m_disable_mode) {
if (!m_play_loading) {
dc.DrawBitmap(m_selected ? m_bitmap_selected.bmp() : m_bitmap_normal.bmp(), pot);
}
else {
/* m_bitmap_rotation = ScalableBitmap(this, "ams_refresh_normal", 30);
auto image = m_bitmap_rotation.bmp().ConvertToImage();
wxPoint offset;
auto loading_img = image.Rotate(m_rotation_angle, wxPoint(image.GetWidth() / 2, image.GetHeight() / 2), true, &offset);
ScalableBitmap loading_bitmap;
loading_bitmap.bmp() = wxBitmap(loading_img);
dc.DrawBitmap(loading_bitmap.bmp(), offset.x , offset.y);*/
m_rotation_angle++;
if (m_rotation_angle >= m_rfid_bitmap_list.size()) {
m_rotation_angle = 0;
}
if (m_rfid_bitmap_list.size() <= 0)return;
dc.DrawBitmap(m_rfid_bitmap_list[m_rotation_angle].bmp(), pot);
}
if (m_rfid_bitmap_list.size() <= 0)return;
dc.DrawBitmap(m_rfid_bitmap_list[m_rotation_angle].bmp(), pot);
}
dc.SetPen(wxPen(colour));
@@ -964,14 +969,15 @@ void AMSLib::doRender(wxDC &dc)
dc.DrawRoundedRectangle(FromDIP(3), FromDIP(3), size.x - FromDIP(6), size.y - FromDIP(6), m_radius);
#endif
// edit icon
if (m_info.material_state != AMSCanType::AMS_CAN_TYPE_EMPTY && m_info.material_state != AMSCanType::AMS_CAN_TYPE_NONE)
{
if (m_info.material_state == AMSCanType::AMS_CAN_TYPE_THIRDBRAND || m_info.material_state == AMSCanType::AMS_CAN_TYPE_VIRTUAL)
dc.DrawBitmap(temp_bitmap_third.bmp(), (size.x - temp_bitmap_third.GetBmpSize().x) / 2, (size.y - FromDIP(10) - temp_bitmap_third.GetBmpSize().y));
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));
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)
{
if (m_info.material_state == AMSCanType::AMS_CAN_TYPE_THIRDBRAND || m_info.material_state == AMSCanType::AMS_CAN_TYPE_VIRTUAL)
dc.DrawBitmap(temp_bitmap_third.bmp(), (size.x - temp_bitmap_third.GetBmpSize().x) / 2, (size.y - FromDIP(10) - temp_bitmap_third.GetBmpSize().y));
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));
}
}
}
@@ -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)
+18 -3
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);
+473
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();
}
}
}
+25
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);
};
}
}