From ba83769030c3fe98c0b564106967dec4fbc32efb Mon Sep 17 00:00:00 2001 From: gerrit Date: Sat, 23 Jul 2022 22:41:50 +0800 Subject: [PATCH 001/180] FIX: fix the hang issue after change language under macos Change-Id: I9286173303225330b3052d8b7a5119b046c44754 --- src/slic3r/GUI/GUI_App.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 18f9af9a896..1bade7562c1 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -2523,7 +2523,7 @@ void GUI_App::recreate_GUI(const wxString& msg_name) dlg.Update(80, _L("Loading current presets") + dots); load_current_presets(); mainframe->Show(true); - mainframe->refresh_plugin_tips(); + //mainframe->refresh_plugin_tips(); dlg.Update(90, _L("Loading a mode view") + dots); @@ -2540,6 +2540,10 @@ void GUI_App::recreate_GUI(const wxString& msg_name) // }); m_is_recreating_gui = false; + + CallAfter([this]() { + mainframe->refresh_plugin_tips(); + }); } void GUI_App::system_info() From c1ac1d8cfce611a61cc70c636295140f50617d75 Mon Sep 17 00:00:00 2001 From: "yifan.wu" Date: Sat, 23 Jul 2022 16:46:17 +0800 Subject: [PATCH 002/180] ENH: rename Fragment Filter to Gap Fill Signed-off-by: yifan.wu Change-Id: If9b417c0bb80d2a9f331c1878507df427690f348 --- .../{fragment_filter.svg => gap_fill.svg} | 0 src/imgui/imconfig.h | 2 +- src/libslic3r/TriangleSelector.hpp | 2 +- src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp | 36 ++++++++--------- .../GUI/Gizmos/GLGizmoMmuSegmentation.cpp | 40 +++++++++---------- src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp | 6 +-- src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp | 10 ++--- src/slic3r/GUI/ImGuiWrapper.cpp | 2 +- 8 files changed, 49 insertions(+), 49 deletions(-) rename resources/images/{fragment_filter.svg => gap_fill.svg} (100%) diff --git a/resources/images/fragment_filter.svg b/resources/images/gap_fill.svg similarity index 100% rename from resources/images/fragment_filter.svg rename to resources/images/gap_fill.svg diff --git a/src/imgui/imconfig.h b/src/imgui/imconfig.h index b9de0a96789..56e90af952b 100644 --- a/src/imgui/imconfig.h +++ b/src/imgui/imconfig.h @@ -165,7 +165,7 @@ namespace ImGui const wchar_t FoldButtonIcon = 0x0814; const wchar_t UnfoldButtonIcon = 0x0815; const wchar_t SphereButtonIcon = 0x0816; - const wchar_t FragmentFilterIcon = 0x0817; + const wchar_t GapFillIcon = 0x0817; // void MyFunction(const char* name, const MyMatrix44& v); } diff --git a/src/libslic3r/TriangleSelector.hpp b/src/libslic3r/TriangleSelector.hpp index 0060ee4529f..645a63aefef 100644 --- a/src/libslic3r/TriangleSelector.hpp +++ b/src/libslic3r/TriangleSelector.hpp @@ -28,7 +28,7 @@ class TriangleSelector POINTER, // BBS HEIGHT_RANGE, - FRAGMENT_FILTER, + GAP_FILL, }; struct ClippingPlane diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp index 92331c80962..170673cd408 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp @@ -88,9 +88,9 @@ bool GLGizmoFdmSupports::on_init() m_desc["remove"] = _L("Erase painting"); m_desc["remove_all"] = _L("Erase all painting"); m_desc["highlight_by_angle"] = _L("Highlight overhang areas") + ": "; - m_desc["fragment_filter"] = _L("Gap fill"); - m_desc["perform_filter"] = _L("Perform"); - m_desc["fragment_area"] = _L("Fragment area"); + m_desc["gap_fill"] = _L("Gap fill"); + m_desc["perform"] = _L("Perform"); + m_desc["gap_area"] = _L("Gap area"); m_desc["brush_size"] = _L("Set pen size"); m_desc["brush_size_caption"] = _L("Ctrl + Mouse wheel") + ": "; m_desc["tool_type"] = _L("Tool type"); @@ -212,10 +212,10 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l // First calculate width of all the texts that are could possibly be shown. We will decide set the dialog width based on that: const float clipping_slider_left = m_imgui->calc_text_size(m_desc.at("clipping_of_view")).x + m_imgui->scaled(1.5f); const float cursor_slider_left = m_imgui->calc_text_size(m_desc.at("cursor_size")).x + m_imgui->scaled(1.5f); - const float fragment_filter_slider_left = m_imgui->calc_text_size(m_desc.at("fragment_filter")).x + m_imgui->scaled(1.5f); + const float gap_fill_slider_left = m_imgui->calc_text_size(m_desc.at("gap_fill")).x + m_imgui->scaled(1.5f); const float highlight_slider_left = m_imgui->calc_text_size(m_desc.at("highlight_by_angle")).x + m_imgui->scaled(1.5f); const float remove_btn_width = m_imgui->calc_text_size(m_desc.at("remove_all")).x + m_imgui->scaled(1.5f); - const float filter_btn_width = m_imgui->calc_text_size(m_desc.at("perform_filter")).x + m_imgui->scaled(1.5f); + const float filter_btn_width = m_imgui->calc_text_size(m_desc.at("perform")).x + m_imgui->scaled(1.5f); const float buttons_width = remove_btn_width + filter_btn_width + m_imgui->scaled(1.5f); const float empty_button_width = m_imgui->calc_button_size("").x; @@ -232,7 +232,7 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l total_text_max += caption_max + m_imgui->scaled(1.f); caption_max += m_imgui->scaled(1.f); - const float sliders_left_width = std::max(std::max(cursor_slider_left, clipping_slider_left), std::max(highlight_slider_left, fragment_filter_slider_left)); + const float sliders_left_width = std::max(std::max(cursor_slider_left, clipping_slider_left), std::max(highlight_slider_left, gap_fill_slider_left)); const float slider_icon_width = m_imgui->get_slider_icon_size().x; float window_width = minimal_slider_width + sliders_left_width + slider_icon_width; const float max_tooltip_width = ImGui::GetFontSize() * 20.0f; @@ -245,7 +245,7 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l ImGui::AlignTextToFramePadding(); m_imgui->text(m_desc.at("tool_type")); - std::array tool_icons = { ImGui::CircleButtonIcon, ImGui::SphereButtonIcon, ImGui::FillButtonIcon, ImGui::FragmentFilterIcon }; + std::array tool_icons = { ImGui::CircleButtonIcon, ImGui::SphereButtonIcon, ImGui::FillButtonIcon, ImGui::GapFillIcon }; std::array tool_tips = { _L("Circle"), _L("Sphere"), _L("Fill"), _L("Gap Fill") }; for (int i = 0; i < tool_icons.size(); i++) { std::string str_label = std::string("##"); @@ -322,19 +322,19 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l ImGui::SameLine(window_width - drag_pos_times * slider_icon_width); ImGui::PushItemWidth(1.5 * slider_icon_width); ImGui::BBLDragFloat("##smart_fill_angle_input", &m_smart_fill_angle, 0.05f, 0.0f, 0.0f, "%.2f"); - } else if (m_current_tool == ImGui::FragmentFilterIcon) { - m_tool_type = ToolType::FRAGMENT_FILTER; + } else if (m_current_tool == ImGui::GapFillIcon) { + m_tool_type = ToolType::GAP_FILL; m_cursor_type = TriangleSelector::CursorType::POINTER; ImGui::AlignTextToFramePadding(); - m_imgui->text(m_desc["fragment_area"] + ":"); + m_imgui->text(m_desc["gap_area"] + ":"); ImGui::SameLine(sliders_left_width); ImGui::PushItemWidth(window_width - sliders_left_width - slider_icon_width); std::string format_str = std::string("%.2f") + I18N::translate_utf8("", "Triangle patch area threshold,""triangle patch will be merged to neighbor if its area is less than threshold"); - m_imgui->bbl_slider_float_style("##fragment_area", &TriangleSelectorPatch::fragment_area, TriangleSelectorPatch::FragmentAreaMin, TriangleSelectorPatch::FragmentAreaMax, format_str.data(), 1.0f, true); + m_imgui->bbl_slider_float_style("##gap_area", &TriangleSelectorPatch::gap_area, TriangleSelectorPatch::GapAreaMin, TriangleSelectorPatch::GapAreaMax, format_str.data(), 1.0f, true); ImGui::SameLine(window_width - drag_pos_times * slider_icon_width); ImGui::PushItemWidth(1.5 * slider_icon_width); - ImGui::BBLDragFloat("##fragment_area_input", &TriangleSelectorPatch::fragment_area, 0.05f, 0.0f, 0.0f, "%.2f"); + ImGui::BBLDragFloat("##gap_area_input", &TriangleSelectorPatch::gap_area, 0.05f, 0.0f, 0.0f, "%.2f"); } float position_before_text_y = ImGui::GetCursorPos().y; @@ -374,7 +374,7 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l ImGui::PushItemWidth(1.5 * slider_icon_width); ImGui::BBLDragFloat("##angle_threshold_deg_input", &m_highlight_by_angle_threshold_deg, 0.05f, 0.0f, 0.0f, "%.2f"); - if (m_current_tool != ImGui::FragmentFilterIcon) { + if (m_current_tool != ImGui::GapFillIcon) { ImGui::Separator(); ImGui::AlignTextToFramePadding(); m_imgui->text(m_desc.at("clipping_of_view")); @@ -399,8 +399,8 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l ImGui::SameLine(); // Perform button is for gap fill - if (m_current_tool == ImGui::FragmentFilterIcon) { - if (m_imgui->button(m_desc.at("perform_filter"))) { + if (m_current_tool == ImGui::GapFillIcon) { + if (m_imgui->button(m_desc.at("perform"))) { Plater::TakeSnapshot snapshot(wxGetApp().plater(), "Reset selection", UndoRedo::SnapshotType::GizmoAction); for (int i = 0; i < m_triangle_selectors.size(); i++) { @@ -439,13 +439,13 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l void GLGizmoFdmSupports::tool_changed(wchar_t old_tool, wchar_t new_tool) { - if ((old_tool == ImGui::FragmentFilterIcon && new_tool == ImGui::FragmentFilterIcon) || - (old_tool != ImGui::FragmentFilterIcon && new_tool != ImGui::FragmentFilterIcon)) + if ((old_tool == ImGui::GapFillIcon && new_tool == ImGui::GapFillIcon) || + (old_tool != ImGui::GapFillIcon && new_tool != ImGui::GapFillIcon)) return; for (auto& selector_ptr : m_triangle_selectors) { TriangleSelectorPatch* tsp = dynamic_cast(selector_ptr.get()); - tsp->set_filter_state(new_tool == ImGui::FragmentFilterIcon); + tsp->set_filter_state(new_tool == ImGui::GapFillIcon); } } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp index 0464ceb09cb..30f7e2a02b7 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp @@ -108,10 +108,10 @@ bool GLGizmoMmuSegmentation::on_init() m_desc["shortcut_key_caption"] = _L("Key 1~9") + ": "; m_desc["shortcut_key"] = _L("Choose filament"); m_desc["edge_detection"] = _L("Edge detection"); - m_desc["fragment_area"] = _L("Fragment area"); - m_desc["perform_filter"] = _L("Perform"); + m_desc["gap_area"] = _L("Gap area"); + m_desc["perform"] = _L("Perform"); - m_desc["remove_all"] = _L("Clear all"); + m_desc["remove_all"] = _L("Erase all painting"); m_desc["circle"] = _L("Circle"); m_desc["sphere"] = _L("Sphere"); m_desc["pointer"] = _L("Triangles"); @@ -341,11 +341,11 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott const float cursor_slider_left = m_imgui->calc_text_size(m_desc.at("cursor_size")).x + m_imgui->scaled(1.f); const float smart_fill_slider_left = m_imgui->calc_text_size(m_desc.at("smart_fill_angle")).x + m_imgui->scaled(1.5f); const float edge_detect_slider_left = m_imgui->calc_text_size(m_desc.at("edge_detection")).x + m_imgui->scaled(1.f); - const float fragment_area_slider_left = m_imgui->calc_text_size(m_desc.at("fragment_area")).x + m_imgui->scaled(1.5f); + const float gap_area_slider_left = m_imgui->calc_text_size(m_desc.at("gap_area")).x + m_imgui->scaled(1.5f); const float height_range_slider_left = m_imgui->calc_text_size(m_desc.at("height_range")).x + m_imgui->scaled(1.5f); const float remove_btn_width = m_imgui->calc_text_size(m_desc.at("remove_all")).x + m_imgui->scaled(1.f); - const float filter_btn_width = m_imgui->calc_text_size(m_desc.at("perform_filter")).x + m_imgui->scaled(1.f); + const float filter_btn_width = m_imgui->calc_text_size(m_desc.at("perform")).x + m_imgui->scaled(1.f); const float buttons_width = remove_btn_width + filter_btn_width + m_imgui->scaled(1.f); const float minimal_slider_width = m_imgui->scaled(4.f); const float color_button_width = m_imgui->calc_text_size("").x + m_imgui->scaled(1.75f); @@ -362,7 +362,7 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott const float circle_max_width = std::max(clipping_slider_left,cursor_slider_left); const float height_max_width = std::max(clipping_slider_left,height_range_slider_left); const float sliders_left_width = std::max(smart_fill_slider_left, - std::max(cursor_slider_left, std::max(edge_detect_slider_left, std::max(fragment_area_slider_left, std::max(height_range_slider_left, + std::max(cursor_slider_left, std::max(edge_detect_slider_left, std::max(gap_area_slider_left, std::max(height_range_slider_left, clipping_slider_left))))); const float slider_icon_width = m_imgui->get_slider_icon_size().x; float window_width = minimal_slider_width + sliders_left_width + slider_icon_width; @@ -434,7 +434,7 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott m_imgui->text(m_desc.at("tool_type")); - std::array tool_icons = { ImGui::CircleButtonIcon,ImGui::SphereButtonIcon, ImGui::TriangleButtonIcon, ImGui::HeightRangeIcon, ImGui::FillButtonIcon, ImGui::FragmentFilterIcon }; + std::array tool_icons = { ImGui::CircleButtonIcon,ImGui::SphereButtonIcon, ImGui::TriangleButtonIcon, ImGui::HeightRangeIcon, ImGui::FillButtonIcon, ImGui::GapFillIcon }; std::array tool_tips = { _L("Circle"), _L("Sphere"), _L("Triangle"), _L("Height Range"), _L("Fill"), _L("Gap Fill") }; for (int i = 0; i < tool_icons.size(); i++) { std::string str_label = std::string("##"); @@ -585,18 +585,18 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott if (slider_clp_dist || b_clp_dist_input) { m_c->object_clipper()->set_position(clp_dist, true); } } - else if (m_current_tool == ImGui::FragmentFilterIcon) { - m_tool_type = ToolType::FRAGMENT_FILTER; + else if (m_current_tool == ImGui::GapFillIcon) { + m_tool_type = ToolType::GAP_FILL; m_cursor_type = TriangleSelector::CursorType::POINTER; ImGui::AlignTextToFramePadding(); - m_imgui->text(m_desc["fragment_area"] + ":"); - ImGui::SameLine(fragment_area_slider_left); - ImGui::PushItemWidth(window_width - fragment_area_slider_left - slider_width_times * slider_icon_width); + m_imgui->text(m_desc["gap_area"] + ":"); + ImGui::SameLine(gap_area_slider_left); + ImGui::PushItemWidth(window_width - gap_area_slider_left - slider_width_times * slider_icon_width); std::string format_str = std::string("%.2f") + I18N::translate_utf8("", "Triangle patch area threshold,""triangle patch will be merged to neighbor if its area is less than threshold"); - m_imgui->bbl_slider_float_style("##fragment_area", &TriangleSelectorPatch::fragment_area, TriangleSelectorPatch::FragmentAreaMin, TriangleSelectorPatch::FragmentAreaMax, format_str.data(), 1.0f, true); + m_imgui->bbl_slider_float_style("##gap_area", &TriangleSelectorPatch::gap_area, TriangleSelectorPatch::GapAreaMin, TriangleSelectorPatch::GapAreaMax, format_str.data(), 1.0f, true); ImGui::SameLine(window_width - slider_icon_width); ImGui::PushItemWidth(1.5 * slider_icon_width); - ImGui::BBLDragFloat("##fragment_area_input", &TriangleSelectorPatch::fragment_area, 0.05f, 0.0f, 0.0f, "%.2f"); + ImGui::BBLDragFloat("##gap_area_input", &TriangleSelectorPatch::gap_area, 0.05f, 0.0f, 0.0f, "%.2f"); } ImGui::Separator(); @@ -607,9 +607,9 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott show_tooltip_information(caption_max, x, get_cur_y); ImGui::SameLine(); - if (m_current_tool == ImGui::FragmentFilterIcon) { - if (m_imgui->button(m_desc.at("perform_filter"))) { - Plater::TakeSnapshot snapshot(wxGetApp().plater(), "Filter fragment", UndoRedo::SnapshotType::GizmoAction); + if (m_current_tool == ImGui::GapFillIcon) { + if (m_imgui->button(m_desc.at("perform"))) { + Plater::TakeSnapshot snapshot(wxGetApp().plater(), "Gap fill", UndoRedo::SnapshotType::GizmoAction); for (int i = 0; i < m_triangle_selectors.size(); i++) { TriangleSelectorPatch* ts_mm = dynamic_cast(m_triangle_selectors[i].get()); @@ -730,13 +730,13 @@ void GLGizmoMmuSegmentation::update_from_model_object(bool first_update) void GLGizmoMmuSegmentation::tool_changed(wchar_t old_tool, wchar_t new_tool) { - if ((old_tool == ImGui::FragmentFilterIcon && new_tool == ImGui::FragmentFilterIcon) || - (old_tool != ImGui::FragmentFilterIcon && new_tool != ImGui::FragmentFilterIcon)) + if ((old_tool == ImGui::GapFillIcon && new_tool == ImGui::GapFillIcon) || + (old_tool != ImGui::GapFillIcon && new_tool != ImGui::GapFillIcon)) return; for (auto& selector_ptr : m_triangle_selectors) { TriangleSelectorPatch* tsp = dynamic_cast(selector_ptr.get()); - tsp->set_filter_state(new_tool == ImGui::FragmentFilterIcon); + tsp->set_filter_state(new_tool == ImGui::GapFillIcon); } } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp index ae4197154f2..189db6236b9 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp @@ -1036,10 +1036,10 @@ void TriangleSelectorGUI::update_render_data() // BBS bool TrianglePatch::is_fragment() const { - return this->area < TriangleSelectorPatch::fragment_area; + return this->area < TriangleSelectorPatch::gap_area; } -float TriangleSelectorPatch::fragment_area = TriangleSelectorPatch::FragmentAreaMin; +float TriangleSelectorPatch::gap_area = TriangleSelectorPatch::GapAreaMin; void TriangleSelectorPatch::render(ImGuiWrapper* imgui) { @@ -1198,7 +1198,7 @@ void TriangleSelectorPatch::update_triangles_per_patch() visited[current_facet] = true; } - patch.area = calc_fragment_area(patch, FragmentAreaMax); + patch.area = calc_fragment_area(patch, GapAreaMax); patch.type = start_facet_state; m_triangle_patches.emplace_back(std::move(patch)); } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp index 5e15961e565..19ad9c3599b 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp @@ -116,7 +116,7 @@ struct TrianglePatch { std::vector facet_indices; EnforcerBlockerType type = EnforcerBlockerType::NONE; std::set neighbor_types; - // if area is larger than FragmentAreaMax, stop accumulate left triangle areas to improve performance + // if area is larger than GapAreaMax, stop accumulate left triangle areas to improve performance float area = 0.f; bool is_fragment() const; @@ -140,11 +140,11 @@ class TriangleSelectorPatch : public TriangleSelectorGUI { void set_ebt_colors(const std::vector> ebt_colors) { m_ebt_colors = ebt_colors; } void set_filter_state(bool is_filter_state); - constexpr static float FragmentAreaMin = 0.f; - constexpr static float FragmentAreaMax = 5.f; + constexpr static float GapAreaMin = 0.f; + constexpr static float GapAreaMax = 5.f; // BBS: fix me - static float fragment_area; + static float gap_area; protected: // Release the geometry data, release OpenGL VBOs. @@ -265,7 +265,7 @@ class GLGizmoPainterBase : public GLGizmoBase BUCKET_FILL, SMART_FILL, // BBS - FRAGMENT_FILTER, + GAP_FILL, }; struct ProjectedMousePosition diff --git a/src/slic3r/GUI/ImGuiWrapper.cpp b/src/slic3r/GUI/ImGuiWrapper.cpp index 18a784b938d..a00a5aa3f65 100644 --- a/src/slic3r/GUI/ImGuiWrapper.cpp +++ b/src/slic3r/GUI/ImGuiWrapper.cpp @@ -61,7 +61,7 @@ static const std::map font_icons = { {ImGui::TriangleButtonIcon , "Triangle_paint" }, {ImGui::FillButtonIcon , "fill_paint" }, {ImGui::HeightRangeIcon , "height_range" }, - {ImGui::FragmentFilterIcon , "fragment_filter" }, + {ImGui::GapFillIcon , "gap_fill" }, {ImGui::FoldButtonIcon , "im_fold" }, {ImGui::UnfoldButtonIcon , "im_unfold" }, {ImGui::SphereButtonIcon , "toolbar_modifier_sphere" }, From ace3c2a231080b9a37696ffa35a3935376f3fa31 Mon Sep 17 00:00:00 2001 From: Arthur Date: Fri, 22 Jul 2022 18:32:10 +0800 Subject: [PATCH 003/180] FIX: auto arranging has stauts report Jira: STUDIO-305 Change-Id: Ib13ccf4037cd1144177935c1184eaf203aa0eb7f --- src/slic3r/GUI/Jobs/ArrangeJob.cpp | 10 ++++------ src/slic3r/GUI/Jobs/ArrangeJob.hpp | 3 ++- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/slic3r/GUI/Jobs/ArrangeJob.cpp b/src/slic3r/GUI/Jobs/ArrangeJob.cpp index ba1a3e2415b..25aaa5f80f0 100644 --- a/src/slic3r/GUI/Jobs/ArrangeJob.cpp +++ b/src/slic3r/GUI/Jobs/ArrangeJob.cpp @@ -412,7 +412,7 @@ void ArrangeJob::prepare() //add the virtual object into unselect list if has m_plater->get_partplate_list().preprocess_exclude_areas(m_unselected, MAX_NUM_PLATES); - + #if SAVE_ARRANGE_POLY if (1) { // subtract excluded region and get a polygon bed @@ -558,10 +558,8 @@ void ArrangeJob::process() params.stopcondition = [this]() { return was_canceled(); }; - auto count = unsigned(m_selected.size());// + m_unprintable.size()); - params.progressind = [this, count](unsigned num_finished, std::string str="") { - // if (num_finished >= 0 && num_finished <= count) - // update_status(int(float(num_finished) / count * 100), _L("Arranging") + " "+str); + params.progressind = [this](unsigned num_finished, std::string str="") { + update_status(num_finished, _L("Arranging") + " " + str); }; if(!params.is_seq_print) @@ -610,7 +608,7 @@ void ArrangeJob::process() } // finalize just here. - update_status(100, + update_status(status_range(), was_canceled() ? _(L("Arranging canceled.")) : we_have_unpackable_items ? _(L("Arranging is done but there are unpacked items. Reduce spacing and try again.")) : _(L("Arranging done."))); } diff --git a/src/slic3r/GUI/Jobs/ArrangeJob.hpp b/src/slic3r/GUI/Jobs/ArrangeJob.hpp index be6205bae90..340d867a903 100644 --- a/src/slic3r/GUI/Jobs/ArrangeJob.hpp +++ b/src/slic3r/GUI/Jobs/ArrangeJob.hpp @@ -59,7 +59,8 @@ class ArrangeJob : public PlaterJob int status_range() const override { - return int(m_selected.size() + m_unprintable.size()); + // ensure finalize() is called after all operations in process() is finished. + return int(m_selected.size() + m_unprintable.size() + 1); } void finalize() override; From e0c4453c46fec4e4ec9e9d69a20f23807d57cb13 Mon Sep 17 00:00:00 2001 From: "salt.wei" Date: Mon, 25 Jul 2022 09:58:06 +0800 Subject: [PATCH 004/180] ENH: some preset change 1 change bambu PC and TPU temperature by pineapple Signed-off-by: salt.wei Change-Id: Id2bc603893ce9e2c33f15de420c79b94cd6dd89a --- resources/profiles/BBL.json | 2 +- .../profiles/BBL/filament/Bambu PC @BBL X1C 0.8 nozzle.json | 2 +- resources/profiles/BBL/filament/Bambu TPU 95A @base.json | 3 +++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/resources/profiles/BBL.json b/resources/profiles/BBL.json index af3c7730706..f73da522ab5 100644 --- a/resources/profiles/BBL.json +++ b/resources/profiles/BBL.json @@ -1,7 +1,7 @@ { "name": "Bambulab", "url": "http://www.bambulab.com/Parameters/vendor/BBL.json", - "version": "01.01.00.10", + "version": "01.01.00.11", "force_update": "0", "description": "the initial version of BBL configurations", "machine_model_list": [ diff --git a/resources/profiles/BBL/filament/Bambu PC @BBL X1C 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PC @BBL X1C 0.8 nozzle.json index 56256f60902..f10699dd069 100644 --- a/resources/profiles/BBL/filament/Bambu PC @BBL X1C 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC @BBL X1C 0.8 nozzle.json @@ -6,7 +6,7 @@ "instantiation": "true", "inherits": "Bambu PC @base", "nozzle_temperature": [ - "270" + "260" ], "compatible_printers": [ "Bambu Lab X1 Carbon 0.8 nozzle" diff --git a/resources/profiles/BBL/filament/Bambu TPU 95A @base.json b/resources/profiles/BBL/filament/Bambu TPU 95A @base.json index 2c67fb7b6fd..84fe7cba33a 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 95A @base.json +++ b/resources/profiles/BBL/filament/Bambu TPU 95A @base.json @@ -13,5 +13,8 @@ ], "nozzle_temperature_initial_layer": [ "230" + ], + "nozzle_temperature": [ + "230" ] } From a9fd7c762ef48994b2820f060bcfd405b55884b7 Mon Sep 17 00:00:00 2001 From: Stone Li Date: Mon, 25 Jul 2022 18:10:52 +0800 Subject: [PATCH 005/180] FIX: shutdown GUI_App after confirm dialog Change-Id: Ie379e9e764f43be1592a74b929bfbfc1d2d41a49 Signed-off-by: Stone Li --- src/slic3r/GUI/GUI_App.cpp | 31 +++++++++++++++++-------------- src/slic3r/GUI/GUI_App.hpp | 1 + src/slic3r/GUI/MainFrame.cpp | 1 + 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 1bade7562c1..35023163b5b 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -1105,6 +1105,23 @@ GUI_App::GUI_App() reset_to_active(); } +void GUI_App::shutdown() +{ + m_is_closing = true; + stop_sync_user_preset(); + + if (m_device_manager) { + delete m_device_manager; + m_device_manager = nullptr; + } + + if (m_agent) { + m_agent->start_discovery(false, false); + delete m_agent; + m_agent = nullptr; + } +} + std::string GUI_App::get_http_url(std::string country_code) { @@ -2703,21 +2720,7 @@ void GUI_App::persist_window_geometry(wxTopLevelWindow *window, bool default_max const std::string name = into_u8(window->GetName()); window->Bind(wxEVT_CLOSE_WINDOW, [=](wxCloseEvent &event) { - m_is_closing = true; window_pos_save(window, "mainframe"); - // - stop_sync_user_preset(); - - if (m_device_manager) { - delete m_device_manager; - m_device_manager = nullptr; - } - - if (m_agent) { - m_agent->start_discovery(false, false); - delete m_agent; - m_agent = nullptr; - } event.Skip(); }); diff --git a/src/slic3r/GUI/GUI_App.hpp b/src/slic3r/GUI/GUI_App.hpp index 4aeea2e0c69..af2b4e13472 100644 --- a/src/slic3r/GUI/GUI_App.hpp +++ b/src/slic3r/GUI/GUI_App.hpp @@ -280,6 +280,7 @@ class GUI_App : public wxApp // Process command line parameters cached in this->init_params, // load configs, STLs etc. void post_init(); + void shutdown(); // If formatted for github, plaintext with OpenGL extensions enclosed into
. // Otherwise HTML formatted for the system info dialog. static std::string get_gl_info(bool for_github); diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 2daa1734589..b469230935b 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -700,6 +700,7 @@ void MainFrame::shutdown() // to avoid any manipulations with them from App->wxEVT_IDLE after of the mainframe closing wxGetApp().tabs_list.clear(); wxGetApp().model_tabs_list.clear(); + wxGetApp().shutdown(); // BBS: why clear ? //wxGetApp().plater_ = nullptr; } From 7986b302dea202fceb686f06a717a709467fa43b Mon Sep 17 00:00:00 2001 From: Stone Li Date: Mon, 25 Jul 2022 16:03:23 +0800 Subject: [PATCH 006/180] FIX: display wrong password when connect failed Change-Id: Iebdf6ca78e4e98a60b60793a259dcfb4615894cc --- src/slic3r/GUI/GUI_App.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 35023163b5b..70c6eefcb01 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -1519,10 +1519,13 @@ void GUI_App::init_networking_callbacks() obj->command_get_version(); } else if (state == ConnectStatus::ConnectStatusFailed || ConnectStatus::ConnectStatusLost) { obj->set_access_code(""); - wxString text = wxString::Format(_L("Connect %s[SN:%s] failed!"), from_u8(obj->dev_name), obj->dev_id); - MessageDialog msg_dlg(nullptr, text, "", wxAPPLY | wxOK); - if (msg_dlg.ShowModal() == wxOK) { - return; + wxString text; + if (msg == "5") { + text = wxString::Format(_L("Incorrect password")); + wxGetApp().show_dialog(text); + } else { + text = wxString::Format(_L("Connect %s failed! [SN:%s, code=%s]"), from_u8(obj->dev_name), obj->dev_id, msg); + wxGetApp().show_dialog(text); } } else { BOOST_LOG_TRIVIAL(info) << "set_on_local_connect_fn: state = " << state; @@ -1960,13 +1963,13 @@ bool GUI_App::on_init_inner() }); Bind(EVT_SHOW_DIALOG, [this](const wxCommandEvent& evt) { - /*wxString msg = evt.GetString(); + wxString msg = evt.GetString(); InfoDialog dlg(this->mainframe, _L("Info"), msg); - dlg.ShowModal();*/ + dlg.ShowModal(); - wxString text = evt.GetString(); + /*wxString text = evt.GetString(); Slic3r::GUI::MessageDialog msg_dlg(this->mainframe, text, "", wxAPPLY | wxOK); - msg_dlg.ShowModal(); + msg_dlg.ShowModal();*/ }); } else { From f908ccd7b382ad5cd59c1919c42bf42ed142d774 Mon Sep 17 00:00:00 2001 From: "chunmao.guo" Date: Mon, 25 Jul 2022 09:39:59 +0800 Subject: [PATCH 007/180] FIX: modify NvOptimusEnablement earlier in contructor of wxMediaCtrl2 Change-Id: I0562c393245726887c2d507f41269d09cf7a8800 --- src/slic3r/GUI/wxMediaCtrl2.cpp | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/slic3r/GUI/wxMediaCtrl2.cpp b/src/slic3r/GUI/wxMediaCtrl2.cpp index c8897851427..133163bb28e 100644 --- a/src/slic3r/GUI/wxMediaCtrl2.cpp +++ b/src/slic3r/GUI/wxMediaCtrl2.cpp @@ -2,8 +2,22 @@ #include "I18N.hpp" wxMediaCtrl2::wxMediaCtrl2(wxWindow *parent) - : wxMediaCtrl(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxMEDIACTRLPLAYERCONTROLS_NONE) { +#ifdef __WIN32__ + auto hModExe = GetModuleHandle(NULL); + // BOOST_LOG_TRIVIAL(info) << "wxMediaCtrl2: GetModuleHandle " << hModExe; + auto NvOptimusEnablement = (DWORD *) GetProcAddress(hModExe, "NvOptimusEnablement"); + auto AmdPowerXpressRequestHighPerformance = (int *) GetProcAddress(hModExe, "AmdPowerXpressRequestHighPerformance"); + if (NvOptimusEnablement) { + // BOOST_LOG_TRIVIAL(info) << "wxMediaCtrl2: NvOptimusEnablement " << *NvOptimusEnablement; + *NvOptimusEnablement = 0; + } + if (AmdPowerXpressRequestHighPerformance) { + // BOOST_LOG_TRIVIAL(info) << "wxMediaCtrl2: AmdPowerXpressRequestHighPerformance " << *AmdPowerXpressRequestHighPerformance; + *AmdPowerXpressRequestHighPerformance = 0; + } +#endif + wxMediaCtrl::Create(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxMEDIACTRLPLAYERCONTROLS_NONE); } void wxMediaCtrl2::Load(wxURI url) @@ -22,13 +36,6 @@ void wxMediaCtrl2::Load(wxURI url) wxPostEvent(this, event); return; } - - auto hModExe = LoadLibrary(NULL); - auto NvOptimusEnablement = (DWORD *) GetProcAddress(hModExe, "NvOptimusEnablement"); - auto AmdPowerXpressRequestHighPerformance = (int *) GetProcAddress(hModExe, "AmdPowerXpressRequestHighPerformance"); - if (NvOptimusEnablement) *NvOptimusEnablement = 0; - if (AmdPowerXpressRequestHighPerformance) *AmdPowerXpressRequestHighPerformance = 0; - url = wxURI(url.BuildURI().append("&hwnd=").append( boost::lexical_cast(GetHandle()))); #endif From 63c3ea26345325134a9e7db0ad6bc73cb5a95852 Mon Sep 17 00:00:00 2001 From: tao wang Date: Mon, 25 Jul 2022 20:12:22 +0800 Subject: [PATCH 008/180] FIX:fixed taskbar icons being too large on MacOS Change-Id: I696a877bb62106cd3b6530fd78810eafdaec79c9 --- resources/images/BambuStudio-mac_256px.ico | Bin 0 -> 3063 bytes src/slic3r/GUI/MainFrame.cpp | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 resources/images/BambuStudio-mac_256px.ico diff --git a/resources/images/BambuStudio-mac_256px.ico b/resources/images/BambuStudio-mac_256px.ico new file mode 100644 index 0000000000000000000000000000000000000000..fa9c43cdea4336acd7365e76351682a230d8f2ca GIT binary patch literal 3063 zcmeHJdpML^7k_6M)iCHQLNXI4w+08tH4GvY(G`JV5e^Z(iJv!A`z+P}5;+H0-7*9!n3@h52@ zKn3_93joSuIvs;{fkD-vViM-&>f|YzmGt#8;=%94O|pcG^mK6qDqGb@#f&t?!NUOn z7paA>8#)Bml_2kaSRe*v$X{kUi<<TYt_R`;K+#Ek~^_NzF_al%DhpD8Rz)1CX~F4Lre6YqPeJ5>Dh`y0r}T zV0VU5b3*DJ#{FK~q29=;W|*(GO$J#-u_kO5P{nHpe@5g#! z;wi0lr8%55A_5G)!l`MeEf}I7V&(4bp%cO#E~x`R!5qdO4L1;b2Obh^kSg? z*GytTi{rkk7YgOfUBkshL5|_9%=X8=LT86oA%k3AqY>Vj-)JGjP#%mRV(Z?*BSLMs zrPjDbt=23CMyYv)7FBV){AVVLe|RvNpcE&Sv%K*>_BL2D2)e-h9;{cmQ-07X7sO;t z*&CXrMfLeN=eX0?z*_vn21YU`rWGP=#p6uKGul{Slv?c!Ji@dBErnar3MFT%Zk?|{ zv0)+T#Wte-u1B5QHy$|7)H^1)epM5pS=q_At{qvIW}+@8kNOaL+r2(0M%-5xg1U!s zsk_-79Il&!P_z+F>4|Tn|C{YqB^5r$FX?%KTCzDK3`1R1t$Wr)|5&J6@??uqfXvRG z;m2_2^jiaSqCskNT?5LHl=|h{)aB*YMLI+C4-~-Q_ zuK|q*ok6EZ4-`wt-Jk%6GbZQ3x(bl95T!8$%mzX-TnT%4JYfah{6RdhR72zW{S@2@rSM3#maf(tF_(WPyI{a6q zwRGwm`7FFc-Xh=8&rDaSfUYj?2`Dft*6e~3Y*YP|PJb5hay2A5NiY?&+`RAfz_g!8 z7{u)9>|cHIJ{NgV+C&=xa727`q~dH6tP6v+rjcg|n{@0ZnYZIz?Z)fjb>a z8qSeLkUIy%T05^Cs`mt%ylV7aC1Mq^Sja8g>KoEgbI6JV#$hJP5Vqn-5%s7ZfmQm|+6Ee{Dia!W10cjZ=!=01>gN51kkmop|`t)Sv1qOGUS?mG%4oGulMm;oSm za7{%@Ay}nYVrK725RxpsVK_}>wv;9924%kaCU$FRIgol~V$h7wA2`a)TFgEB1Fe1+ zNX?%ZG$$;9TTM3Go3xiW<}SPg(;QIC0(y%2yJ@uy9^L`;lc~f^x&bxXdeWQ{2Z5Yz z{=TXwU~GyaF3ovcNxwmJ@CN*4U+hL=Kj}E4)GDkvS;V2 zj)|!}2l)e}4Z&!vCf;WIn6>ozSp5A)xPdODeZP$VfJp!Af_vg(K$a8(eP~fZ@3#_N zW$$vR(GJq$+xDq-0ygu_gqF%vTqVC zrQ5t~`IB)`2%6;T6kj`h4Q?xw?|~mXOS@?s-$B=qV#!lkx$P;>629fUG50ai)$Hpy zx^CbUSAohZMK_5c`7(&g8}DZlK{r6O^7~woNO2tMv_wrqO}J#}g}f+5IFT}8aV!Q^F@)L` z&4XXB!Vce%j{l&W%_cXV6Il_=sILRnrF?%@#_I<=MLf#3yvA&DJs_p=w|;H`K!!pYsbK{< U6~qR#*hqBUoY78|j)dg@0Ga_7NdN!< literal 0 HcmV?d00001 diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index b469230935b..cf19e139ed9 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -206,7 +206,7 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, BORDERLESS_FRAME_ default: case GUI_App::EAppMode::Editor: m_taskbar_icon = std::make_unique(wxTBI_DOCK); - m_taskbar_icon->SetIcon(wxIcon(Slic3r::var("BambuStudio-mac_128px.png"), wxBITMAP_TYPE_PNG), "BambuStudio"); + m_taskbar_icon->SetIcon(wxIcon(Slic3r::var("BambuStudio-mac_256px.ico"), wxBITMAP_TYPE_PNG), "BambuStudio"); break; case GUI_App::EAppMode::GCodeViewer: break; From 79dd525793d41f703a8a6fa174be53948e38d093 Mon Sep 17 00:00:00 2001 From: Stone Li Date: Tue, 26 Jul 2022 10:42:04 +0800 Subject: [PATCH 009/180] FIX: fix crash when cancel a print job Change-Id: Ic4678ef0d963ae4447506de7aa3cf208173edf72 --- src/slic3r/GUI/SelectMachine.cpp | 36 ++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/src/slic3r/GUI/SelectMachine.cpp b/src/slic3r/GUI/SelectMachine.cpp index e1776abcdcf..69ac1f28405 100644 --- a/src/slic3r/GUI/SelectMachine.cpp +++ b/src/slic3r/GUI/SelectMachine.cpp @@ -1406,11 +1406,26 @@ void SelectMachineDialog::on_ok(wxCommandEvent &event) return; } - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << "for send task, current printer id = " << m_printer_last_select << std::endl; + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", print_job: for send task, current printer id = " << m_printer_last_select << std::endl; show_status(PrintDialogStatus::PrintStatusSending); m_status_bar->reset(); m_status_bar->set_prog_block(); + m_status_bar->set_cancel_callback_fina([this]() { + BOOST_LOG_TRIVIAL(info) << "print_job: enter canceled"; + if (m_print_job) { + if (m_print_job->is_running()) { + BOOST_LOG_TRIVIAL(info) << "print_job: canceled"; + m_print_job->cancel(); + } + m_print_job->join(); + } + wxCommandEvent* event = new wxCommandEvent(EVT_PRINT_JOB_CANCEL); + wxQueueEvent(this, event); + }); + + // enter sending mode + sending_mode(); // get ams_mapping_result std::string ams_mapping_array; @@ -1423,14 +1438,14 @@ void SelectMachineDialog::on_ok(wxCommandEvent &event) m_export_3mf_cancel = cancel = cancelled; }); - if (result < 0) { - wxString msg = _L("Abnormal print file data. Please slice again"); - m_status_bar->set_status_text(msg); + if (m_export_3mf_cancel) { + m_status_bar->set_status_text(task_canceled_text); return; } - if (m_export_3mf_cancel) { - m_status_bar->set_status_text(task_canceled_text); + if (result < 0) { + wxString msg = _L("Abnormal print file data. Please slice again"); + m_status_bar->set_status_text(msg); return; } @@ -1468,12 +1483,6 @@ void SelectMachineDialog::on_ok(wxCommandEvent &event) m_print_job->on_success([this]() { finish_mode(); }); - m_status_bar->set_cancel_callback_fina([this]() { - m_print_job->cancel(); - wxCommandEvent *event = new wxCommandEvent(EVT_PRINT_JOB_CANCEL); - wxQueueEvent(this, event); - }); - wxCommandEvent evt(m_plater->get_print_finished_event()); m_print_job->start(); } @@ -1542,8 +1551,9 @@ void SelectMachineDialog::on_set_finish_mapping(wxCommandEvent &evt) void SelectMachineDialog::on_print_job_cancel(wxCommandEvent &evt) { - if (m_print_job->is_running()) { m_print_job->join(5 * 1000); } show_status(PrintDialogStatus::PrintStatusSendingCanceled); + // enter prepare mode + prepare_mode(); } std::vector SelectMachineDialog::sort_string(std::vector strArray) From f9dce93a52b455be396d8066ca9c128d3787ddb9 Mon Sep 17 00:00:00 2001 From: tao wang Date: Mon, 25 Jul 2022 15:29:55 +0800 Subject: [PATCH 010/180] FIX:fixed AMSLib caused by switching pages will not keep fixed size Change-Id: Id7a66dd1c705670c20c75546c02c864a98b4cf2e --- src/slic3r/GUI/Widgets/AMSControl.cpp | 8 ++++++-- src/slic3r/GUI/Widgets/AMSControl.hpp | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/slic3r/GUI/Widgets/AMSControl.cpp b/src/slic3r/GUI/Widgets/AMSControl.cpp index c359eba4404..bc7e41f683c 100644 --- a/src/slic3r/GUI/Widgets/AMSControl.cpp +++ b/src/slic3r/GUI/Widgets/AMSControl.cpp @@ -396,6 +396,10 @@ void AMSLib::create(wxWindow *parent, wxWindowID id, const wxPoint &pos, const w { wxWindow::Create(parent, id, pos, size); + SetSize(AMS_CAN_LIB_SIZE); + SetMinSize(AMS_CAN_LIB_SIZE); + SetMaxSize(AMS_CAN_LIB_SIZE); + auto m_sizer_body = new wxBoxSizer(wxVERTICAL); wxBoxSizer *m_sizer_edit = new wxBoxSizer(wxHORIZONTAL); @@ -1074,7 +1078,7 @@ void AmsCans::AddCan(Caninfo caninfo, int canindex, int maxcan) auto m_panel_refresh = new AMSrefresh(amscan, wxID_ANY, m_can_count + 1, caninfo); m_sizer_ams->Add(m_panel_refresh, 0, wxALIGN_CENTER_HORIZONTAL, 0); m_sizer_ams->Add(0, 0, 0, wxEXPAND | wxTOP, FromDIP(2)); - auto m_panel_lib = new AMSLib(amscan, wxID_ANY, caninfo, wxDefaultPosition, AMS_CAN_LIB_SIZE); + auto m_panel_lib = new AMSLib(amscan, wxID_ANY, caninfo); m_panel_lib->Bind(wxEVT_LEFT_DOWN, [this, canindex](wxMouseEvent &ev) { m_canlib_selection = canindex; // m_canlib_id = caninfo.can_id; @@ -1098,7 +1102,7 @@ void AmsCans::AddCan(Caninfo caninfo, int canindex, int maxcan) amscan->SetSizer(m_sizer_ams); amscan->Layout(); - m_sizer_ams->Fit(amscan); + amscan->Fit(); sizer_can->Add(amscan, 0, wxALL, 0); Canrefreshs *canrefresh = new Canrefreshs; diff --git a/src/slic3r/GUI/Widgets/AMSControl.hpp b/src/slic3r/GUI/Widgets/AMSControl.hpp index 52e3690b4f2..063dd853994 100644 --- a/src/slic3r/GUI/Widgets/AMSControl.hpp +++ b/src/slic3r/GUI/Widgets/AMSControl.hpp @@ -95,7 +95,7 @@ enum FilamentStep { #define AMS_ITEM_CUBE_SIZE wxSize(FromDIP(14), FromDIP(14)) #define AMS_ITEM_SIZE wxSize(FromDIP(82), FromDIP(27)) #define AMS_ITEM_HUMIDITY_SIZE wxSize(FromDIP(150), FromDIP(27)) -#define AMS_CAN_LIB_SIZE wxSize(FromDIP(58), FromDIP(84)) +#define AMS_CAN_LIB_SIZE wxSize(FromDIP(58), FromDIP(80)) #define AMS_CAN_ROAD_SIZE wxSize(FromDIP(66), FromDIP(60)) #define AMS_CAN_ITEM_HEIGHT_SIZE FromDIP(27) #define AMS_CANS_SIZE wxSize(FromDIP(284), FromDIP(186)) From 5a2669dcc2aaf5d2bb548b031b73e72058c78b51 Mon Sep 17 00:00:00 2001 From: "salt.wei" Date: Mon, 25 Jul 2022 18:32:05 +0800 Subject: [PATCH 011/180] ENH: privide setting option of exclude_area As title. User can delete the value to enable 256x256 printable size Signed-off-by: salt.wei Change-Id: Ia10454b7a7a1b28c04d8d41df9f3251875f6e74e --- src/libslic3r/PrintConfig.cpp | 8 +++++--- src/slic3r/GUI/Field.cpp | 14 +++++++++++--- src/slic3r/GUI/GUI.cpp | 2 +- src/slic3r/GUI/OptionsGroup.cpp | 4 ++++ src/slic3r/GUI/PartPlate.hpp | 1 + src/slic3r/GUI/Plater.cpp | 4 +++- src/slic3r/GUI/Tab.cpp | 8 +++++--- 7 files changed, 30 insertions(+), 11 deletions(-) diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 9fdd1b37541..905d33295a3 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -264,8 +264,11 @@ void PrintConfigDef::init_common_params() //BBS: add "bed_exclude_area" def = this->add("bed_exclude_area", coPoints); def->label = L("Bed exclude area"); - def->mode = comDevelop; - def->set_default_value(new ConfigOptionPoints{}); + def->tooltip = L("Bed exclude area that can't used as printable area in X-Y plane. For example, the bottom left area which is used to cut filament in X1 when printing multi colors with AMS. " + "The area is expressed as polygon by points in following format: \"XxY, XxY, ...\""); + def->mode = comAdvanced; + def->gui_type = ConfigOptionDef::GUIType::one_string; + def->set_default_value(new ConfigOptionPoints{ Vec2d(0, 0) }); def = this->add("elefant_foot_compensation", coFloat); def->label = L("Elephant foot compensation"); @@ -290,7 +293,6 @@ void PrintConfigDef::init_common_params() def->sidetext = L("mm"); def->min = 0; def->max = 1000; - def->readonly = true; def->mode = comSimple; def->set_default_value(new ConfigOptionFloat(100.0)); diff --git a/src/slic3r/GUI/Field.cpp b/src/slic3r/GUI/Field.cpp index de94173dd21..75720dda098 100644 --- a/src/slic3r/GUI/Field.cpp +++ b/src/slic3r/GUI/Field.cpp @@ -374,9 +374,17 @@ void Field::get_value_by_opt_type(wxString& str, const bool check_value/* = true if (x_str.ToDouble(&x) && thumbnail.HasMoreTokens()) { wxString y_str = thumbnail.GetNextToken(); if (y_str.ToDouble(&y) && !thumbnail.HasMoreTokens()) { - if (0 < x && x < 1000 && 0 < y && y < 1000) { - out_values.push_back(Vec2d(x, y)); - continue; + if (m_opt_id == "bed_exclude_area") { + if (0 <= x && x <= 256 && 0 <= y && y <= 256) { + out_values.push_back(Vec2d(x, y)); + continue; + } + } + else { + if (0 < x && x < 1000 && 0 < y && y < 1000) { + out_values.push_back(Vec2d(x, y)); + continue; + } } out_of_range_val = true; break; diff --git a/src/slic3r/GUI/GUI.cpp b/src/slic3r/GUI/GUI.cpp index 7add7481988..4c302392b2e 100644 --- a/src/slic3r/GUI/GUI.cpp +++ b/src/slic3r/GUI/GUI.cpp @@ -197,7 +197,7 @@ void change_opt_value(DynamicPrintConfig& config, const t_config_option_key& opt } break; case coPoints:{ - if (opt_key == "printable_area") { + if (opt_key == "printable_area" || opt_key == "bed_exclude_area") { config.option(opt_key)->values = boost::any_cast>(value); break; } diff --git a/src/slic3r/GUI/OptionsGroup.cpp b/src/slic3r/GUI/OptionsGroup.cpp index fe16aac3c1b..53af5474515 100644 --- a/src/slic3r/GUI/OptionsGroup.cpp +++ b/src/slic3r/GUI/OptionsGroup.cpp @@ -1022,6 +1022,8 @@ boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config case coPoints: if (opt_key == "printable_area") ret = config.option(opt_key)->values; + else if (opt_key == "bed_exclude_area") + ret = get_thumbnails_string(config.option(opt_key)->values); else ret = config.option(opt_key)->get_at(idx); break; @@ -1130,6 +1132,8 @@ boost::any ConfigOptionsGroup::get_config_value2(const DynamicPrintConfig& confi case coPoints: if (opt_key == "printable_area") ret = config.option(opt_key)->values; + else if (opt_key == "bed_exclude_area") + ret = get_thumbnails_string(config.option(opt_key)->values); else ret = config.option(opt_key)->get_at(idx); break; diff --git a/src/slic3r/GUI/PartPlate.hpp b/src/slic3r/GUI/PartPlate.hpp index 7bcaa067596..b0a29125c45 100644 --- a/src/slic3r/GUI/PartPlate.hpp +++ b/src/slic3r/GUI/PartPlate.hpp @@ -520,6 +520,7 @@ class PartPlateList : public ObjectBase Vec3d get_current_plate_origin() { return compute_origin(m_current_plate, m_plate_cols); } Vec2d get_current_shape_position() { return compute_shape_position(m_current_plate, m_plate_cols); } + Pointfs get_exclude_area() { return m_exclude_areas; } //select plate int select_plate(int index); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 5e0e1d0b82a..107be515da8 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -5879,7 +5879,9 @@ void Plater::priv::set_bed_shape(const Pointfs& shape, const Pointfs& exclude_ar partplate_list.get_height_limits(prev_height_lid, prev_height_rod); double height_to_lid = config->opt_float("extruder_clearance_height_to_lid"); double height_to_rod = config->opt_float("extruder_clearance_height_to_rod"); - new_shape |= (height_to_lid != prev_height_lid) || (height_to_rod != prev_height_rod); + + Pointfs prev_exclude_areas = partplate_list.get_exclude_area(); + new_shape |= (height_to_lid != prev_height_lid) || (height_to_rod != prev_height_rod) || (prev_exclude_areas != exclude_areas); if (new_shape) { if (view3D) view3D->bed_shape_changed(); if (preview) preview->bed_shape_changed(); diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 1b591d16e2b..82ba27a8757 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -851,7 +851,7 @@ void TabPrinter::init_options_list() for (const std::string& opt_key : m_config->keys()) { - if (opt_key == "printable_area") { + if (opt_key == "printable_area" || opt_key == "bed_exclude_area") { m_options_list.emplace(opt_key, m_opt_status_value); continue; } @@ -2677,7 +2677,9 @@ void TabPrinter::build_fff() //create_line_with_widget(optgroup.get(), "printable_area", "custom-svg-and-png-bed-textures_124612", [this](wxWindow* parent) { // return create_bed_shape_widget(parent); //}); - + Option option = optgroup->get_option("bed_exclude_area"); + option.opt.full_width = true; + optgroup->append_single_option_line(option); optgroup->append_single_option_line("printable_height"); optgroup->append_single_option_line("nozzle_volume"); // BBS @@ -2793,7 +2795,7 @@ void TabPrinter::build_fff() optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) { validate_custom_gcode_cb(this, optgroup, opt_key, value); }; - Option option = optgroup->get_option("machine_start_gcode"); + option = optgroup->get_option("machine_start_gcode"); option.opt.full_width = true; option.opt.is_code = true; option.opt.height = gcode_field_height;//150; From 3d3cda5e45e7e42243646797ab2b863f67790a05 Mon Sep 17 00:00:00 2001 From: Stone Li Date: Tue, 26 Jul 2022 12:15:30 +0800 Subject: [PATCH 012/180] FIX: fix destroy BBLNetworkAgent when changing language Change-Id: I95942abffbab3445775fa1598738249256e0e31d --- src/slic3r/GUI/GUI_App.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 70c6eefcb01..719bf88fad8 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -1107,6 +1107,9 @@ GUI_App::GUI_App() void GUI_App::shutdown() { + BOOST_LOG_TRIVIAL(info) << "shutdown"; + + if (m_is_recreating_gui) return; m_is_closing = true; stop_sync_user_preset(); From 7a5771419a9b6e6696d9dd98c8ce0451c7982da0 Mon Sep 17 00:00:00 2001 From: "salt.wei" Date: Tue, 26 Jul 2022 12:41:56 +0800 Subject: [PATCH 013/180] ENH: don't show extruder index when only has one As title Signed-off-by: salt.wei Change-Id: I752a43ccda1711a13f2fd152e9b7341195450cb0 --- src/slic3r/GUI/Tab.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 82ba27a8757..8e65ddea00d 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -3096,7 +3096,7 @@ void TabPrinter::build_unregular_pages(bool from_initial_build/* = false*/) // Build missed extruder pages //for (auto extruder_idx = m_extruders_count_old; extruder_idx < m_extruders_count; ++extruder_idx) auto extruder_idx = 0; - const wxString& page_name = wxString::Format("Extruder %d", int(extruder_idx + 1)); + const wxString& page_name = (m_extruders_count > 1) ? wxString::Format("Extruder %d", int(extruder_idx + 1)) : wxString::Format("Extruder"); bool page_exist = false; for (auto page_temp : m_pages) { if (page_temp->title() == page_name) { From 9a640be43ce3ea4612c667f30667a9b43834f02d Mon Sep 17 00:00:00 2001 From: Stone Li Date: Tue, 26 Jul 2022 12:46:29 +0800 Subject: [PATCH 014/180] FIX: fix bug that thumbnail is not display Change-Id: Ic974e378fbcaea096f5e2aa8b40092d2ef3e8e54 --- src/slic3r/GUI/DeviceManager.cpp | 2 ++ src/slic3r/GUI/GLCanvas3D.cpp | 11 ++--------- src/slic3r/GUI/GLCanvas3D.hpp | 1 - 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/src/slic3r/GUI/DeviceManager.cpp b/src/slic3r/GUI/DeviceManager.cpp index 34590047700..31cbc875c69 100644 --- a/src/slic3r/GUI/DeviceManager.cpp +++ b/src/slic3r/GUI/DeviceManager.cpp @@ -2360,6 +2360,8 @@ void MachineObject::update_slice_info(std::string project_id, std::string profil if (plate_idx >= 0) { plate_index = plate_idx; } else { + if (subtask_id.compare("0") == 0) + return; m_agent->get_task_plate_index(subtask_id, &plate_index); } diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 4391c8d9685..788969b2bc1 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2133,7 +2133,6 @@ void GLCanvas3D::bind_event_handlers() m_canvas->Bind(wxEVT_RIGHT_DCLICK, &GLCanvas3D::on_mouse, this); m_canvas->Bind(wxEVT_PAINT, &GLCanvas3D::on_paint, this); m_canvas->Bind(wxEVT_SET_FOCUS, &GLCanvas3D::on_set_focus, this); - m_canvas->Bind(wxEVT_KILL_FOCUS, &GLCanvas3D::on_kill_focus, this); m_event_handlers_bound = true; } } @@ -2163,7 +2162,6 @@ void GLCanvas3D::unbind_event_handlers() m_canvas->Unbind(wxEVT_RIGHT_DCLICK, &GLCanvas3D::on_mouse, this); m_canvas->Unbind(wxEVT_PAINT, &GLCanvas3D::on_paint, this); m_canvas->Unbind(wxEVT_SET_FOCUS, &GLCanvas3D::on_set_focus, this); - m_canvas->Unbind(wxEVT_KILL_FOCUS, &GLCanvas3D::on_kill_focus, this); m_event_handlers_bound = false; } @@ -3484,19 +3482,14 @@ void GLCanvas3D::on_set_focus(wxFocusEvent& evt) { m_tooltip_enabled = false; if (m_canvas_type == ECanvasType::CanvasPreview) { + // update thumbnails and update plate toolbar + wxGetApp().plater()->update_platplate_thumbnails(); _update_imgui_select_plate_toolbar(); } _refresh_if_shown_on_screen(); m_tooltip_enabled = true; } -void GLCanvas3D::on_kill_focus(wxFocusEvent& evt) -{ - if (m_canvas_type == ECanvasType::CanvasView3D) { - wxGetApp().plater()->update_platplate_thumbnails(); - } -} - Size GLCanvas3D::get_canvas_size() const { int w = 0; diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 1d37e85ff75..50280ff7474 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -767,7 +767,6 @@ class GLCanvas3D void on_mouse(wxMouseEvent& evt); void on_paint(wxPaintEvent& evt); void on_set_focus(wxFocusEvent& evt); - void on_kill_focus(wxFocusEvent& evt); Size get_canvas_size() const; Vec2d get_local_mouse_position() const; From 252aa91ae7c501b561dede5a631ccb432f084072 Mon Sep 17 00:00:00 2001 From: Tao Wang Date: Tue, 26 Jul 2022 11:20:49 +0800 Subject: [PATCH 015/180] FIX:fixed multiple monitors not being maximized correctly Change-Id: Idcaddcd5bbd483e14d290e9658da0283d33028fc --- src/slic3r/GUI/BBLTopbar.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/slic3r/GUI/BBLTopbar.cpp b/src/slic3r/GUI/BBLTopbar.cpp index b5d142154ae..da8fdc96fb5 100644 --- a/src/slic3r/GUI/BBLTopbar.cpp +++ b/src/slic3r/GUI/BBLTopbar.cpp @@ -493,6 +493,9 @@ void BBLTopbar::OnFullScreen(wxAuiToolBarEvent& event) m_frame->Restore(); } else { + wxDisplay display(wxDisplay::GetFromWindow(this)); + auto size = display.GetClientArea().GetSize(); + m_frame->SetMaxSize(size + wxSize{16, 16}); m_normalRect = m_frame->GetRect(); m_frame->Maximize(); } @@ -516,6 +519,9 @@ void BBLTopbar::OnMouseLeftDClock(wxMouseEvent& mouse) m_frame->Restore(); } else { + wxDisplay display(wxDisplay::GetFromWindow(this)); + auto size = display.GetClientArea().GetSize(); + m_frame->SetMaxSize(size + wxSize{16, 16}); m_normalRect = m_frame->GetRect(); m_frame->Maximize(); } From ae45af16885fbf0a3ab3cd1db4ff99cdd25b1ee2 Mon Sep 17 00:00:00 2001 From: Tao Wang Date: Tue, 26 Jul 2022 15:46:01 +0800 Subject: [PATCH 016/180] FIX:show msgdialog when user selected timelapse_no_toolhead first time Change-Id: I08307aae17ccc93ae4448016504f68ab9e67558b (cherry picked from commit 41a9cd933b6c98b7b2fbeea3b3863e3bce56e27a) --- src/slic3r/GUI/ConfigManipulation.cpp | 11 ----------- src/slic3r/GUI/ConfigManipulation.hpp | 1 - src/slic3r/GUI/Tab.cpp | 17 ++++++++++++++++- src/slic3r/GUI/Tab.hpp | 3 +++ 4 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/slic3r/GUI/ConfigManipulation.cpp b/src/slic3r/GUI/ConfigManipulation.cpp index f88d514661d..ce16875f198 100644 --- a/src/slic3r/GUI/ConfigManipulation.cpp +++ b/src/slic3r/GUI/ConfigManipulation.cpp @@ -291,17 +291,6 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con is_msg_dlg_already_exist = false; } - //BBS - if (config->opt_bool("timelapse_no_toolhead") && !is_timelapse_wipe_tower_already_prompted) { - wxString msg_text = _(L("When recording timelapse without toolhead, it is recommended to add a \"Timelapse Wipe Tower\" \n" - "by right-click the empty position of build plate and choose \"Add Primitive\"->\"Timelapse Wipe Tower\".\n")); - MessageDialog dialog(m_msg_dlg_parent, msg_text, "", wxICON_WARNING | wxOK); - is_msg_dlg_already_exist = true; - dialog.ShowModal(); - is_msg_dlg_already_exist = false; - is_timelapse_wipe_tower_already_prompted = true; - } - // BBS int filament_cnt = wxGetApp().preset_bundle->filament_presets.size(); #if 0 diff --git a/src/slic3r/GUI/ConfigManipulation.hpp b/src/slic3r/GUI/ConfigManipulation.hpp index e57c848dd56..c7300639d8e 100644 --- a/src/slic3r/GUI/ConfigManipulation.hpp +++ b/src/slic3r/GUI/ConfigManipulation.hpp @@ -21,7 +21,6 @@ namespace GUI { class ConfigManipulation { bool is_msg_dlg_already_exist{ false }; - bool is_timelapse_wipe_tower_already_prompted{false}; // BBS bool m_is_initialized_support_material_overhangs_queried{ false }; bool m_support_material_overhangs_queried{ false }; diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 8e65ddea00d..9d91c2c1ff6 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -1374,6 +1374,12 @@ void Tab::on_value_change(const std::string& opt_key, const boost::any& value) if (opt_key == "enable_prime_tower" || opt_key == "single_extruder_multi_material" || opt_key == "extruders_count" ) update_wiping_button_visibility(); + //popup message dialog when first selected + if (opt_key == "timelapse_no_toolhead" && boost::any_cast(value)) + show_timelapse_warning_dialog(); + + + // BBS #if 0 if (opt_key == "extruders_count") @@ -1391,6 +1397,16 @@ void Tab::on_value_change(const std::string& opt_key, const boost::any& value) m_page_view->GetParent()->Layout(); } +void Tab::show_timelapse_warning_dialog() { + if (!m_is_timelapse_wipe_tower_already_prompted) { + wxString msg_text = _(L("When recording timelapse without toolhead, it is recommended to add a \"Timelapse Wipe Tower\" \n" + "by right-click the empty position of build plate and choose \"Add Primitive\"->\"Timelapse Wipe Tower\".\n")); + MessageDialog dialog(nullptr, msg_text, "", wxICON_WARNING | wxOK); + dialog.ShowModal(); + m_is_timelapse_wipe_tower_already_prompted = true; + } +} + // Show/hide the 'purging volumes' button void Tab::update_wiping_button_visibility() { if (m_preset_bundle->printers.get_selected_preset().printer_technology() == ptSLA) @@ -1503,7 +1519,6 @@ void Tab::apply_config_from_cache() BOOST_LOG_TRIVIAL(info) << __FUNCTION__<& selected_options); void apply_config_from_cache(); + void show_timelapse_warning_dialog(); const std::map& get_category_icon_map() { return m_category_icon; } //BBS: GUI refactor From 18901127ec079a936e018ecfe947613d614777ec Mon Sep 17 00:00:00 2001 From: Tao Wang Date: Tue, 26 Jul 2022 13:35:56 +0800 Subject: [PATCH 017/180] FIX:fixed can not load task bar dock icon Change-Id: I6b52498eda04cacea147a2f098219eb16da24301 --- src/slic3r/GUI/MainFrame.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index cf19e139ed9..c689064643c 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -206,7 +206,7 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, BORDERLESS_FRAME_ default: case GUI_App::EAppMode::Editor: m_taskbar_icon = std::make_unique(wxTBI_DOCK); - m_taskbar_icon->SetIcon(wxIcon(Slic3r::var("BambuStudio-mac_256px.ico"), wxBITMAP_TYPE_PNG), "BambuStudio"); + m_taskbar_icon->SetIcon(wxIcon(Slic3r::var("BambuStudio-mac_256px.ico"), wxBITMAP_TYPE_ICO), "BambuStudio"); break; case GUI_App::EAppMode::GCodeViewer: break; From 835f9837b1182681d0cb15cef3cbc45b713d02e8 Mon Sep 17 00:00:00 2001 From: "chunmao.guo" Date: Mon, 25 Jul 2022 15:37:22 +0800 Subject: [PATCH 018/180] FIX: load url in guide web dialog Change-Id: Ie723d8994dddcaeb21299837a0e34d8c15b698ed (cherry picked from commit 05d3a1c20a6f4a817dd098c2b121539863257a66) --- src/slic3r/GUI/WebGuideDialog.cpp | 2 +- src/slic3r/GUI/Widgets/WebView.cpp | 10 ++++++++++ src/slic3r/GUI/Widgets/WebView.hpp | 2 ++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/WebGuideDialog.cpp b/src/slic3r/GUI/WebGuideDialog.cpp index 05de4938eab..65a57cce41f 100644 --- a/src/slic3r/GUI/WebGuideDialog.cpp +++ b/src/slic3r/GUI/WebGuideDialog.cpp @@ -111,7 +111,7 @@ void GuideFrame::load_url(wxString &url) { BOOST_LOG_TRIVIAL(trace) << "app_start: GuideFrame url=" << url.ToStdString(); this->Show(); - m_browser->LoadURL(url); + WebView::LoadUrl(m_browser, url); m_browser->SetFocus(); UpdateState(); } diff --git a/src/slic3r/GUI/Widgets/WebView.cpp b/src/slic3r/GUI/Widgets/WebView.cpp index 31378b7139f..6bd59c27e58 100644 --- a/src/slic3r/GUI/Widgets/WebView.cpp +++ b/src/slic3r/GUI/Widgets/WebView.cpp @@ -98,6 +98,16 @@ wxWebView* WebView::CreateWebView(wxWindow * parent, wxString const & url) return webView; } +void WebView::LoadUrl(wxWebView * webView, wxString const &url) +{ + auto url2 = url; +#ifdef __WIN32__ + url2.Replace("\\", "/"); +#endif + if (!url2.empty()) { url2 = wxURI(url2).BuildURI(); } + webView->LoadURL(url2); +} + bool WebView::RunScript(wxWebView *webView, wxString const &javascript) { if (Slic3r::GUI::wxGetApp().get_mode() == Slic3r::comDevelop) diff --git a/src/slic3r/GUI/Widgets/WebView.hpp b/src/slic3r/GUI/Widgets/WebView.hpp index 9ca12ccf686..ce142913f0c 100644 --- a/src/slic3r/GUI/Widgets/WebView.hpp +++ b/src/slic3r/GUI/Widgets/WebView.hpp @@ -7,6 +7,8 @@ class WebView { public: static wxWebView *CreateWebView(wxWindow *parent, wxString const &url); + + static void LoadUrl(wxWebView * webView, wxString const &url); static bool RunScript(wxWebView * webView, wxString const & msg); }; From 157fae556f0eff90df7485de04820ab6b9609d48 Mon Sep 17 00:00:00 2001 From: "chunmao.guo" Date: Mon, 25 Jul 2022 18:07:57 +0800 Subject: [PATCH 019/180] FIX: send WM_NCLBUTTON(xxx) to use default window features Change-Id: Ib5caa249857b416fc814ad1ccdea549bd15be3b1 --- src/slic3r/GUI/BBLTopbar.cpp | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/slic3r/GUI/BBLTopbar.cpp b/src/slic3r/GUI/BBLTopbar.cpp index da8fdc96fb5..d80fc478ec7 100644 --- a/src/slic3r/GUI/BBLTopbar.cpp +++ b/src/slic3r/GUI/BBLTopbar.cpp @@ -508,12 +508,17 @@ void BBLTopbar::OnCloseFrame(wxAuiToolBarEvent& event) void BBLTopbar::OnMouseLeftDClock(wxMouseEvent& mouse) { + wxPoint mouse_pos = ::wxGetMousePosition(); // check whether mouse is not on any tool item if (this->FindToolByCurrentPosition() != NULL && this->FindToolByCurrentPosition() != m_title_item) { mouse.Skip(); return; } +#ifdef __W1XMSW__ + ::PostMessage((HWND) m_frame->GetHandle(), WM_NCLBUTTONDBLCLK, HTCAPTION, MAKELPARAM(mouse_pos.x, mouse_pos.y)); + return; +#endif // __WXMSW__ if (m_frame->IsMaximized()) { m_frame->Restore(); @@ -567,16 +572,23 @@ void BBLTopbar::OnMouseLeftDown(wxMouseEvent& event) wxPoint frame_pos = m_frame->GetScreenPosition(); m_delta = mouse_pos - frame_pos; - if (FindToolByCurrentPosition() == NULL) + if (FindToolByCurrentPosition() == NULL + || this->FindToolByCurrentPosition() == m_title_item) { CaptureMouse(); +#ifdef __WXMSW__ + ReleaseMouse(); + ::PostMessage((HWND) m_frame->GetHandle(), WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(mouse_pos.x, mouse_pos.y)); + return; +#endif // __WXMSW__ } - + event.Skip(); } void BBLTopbar::OnMouseLeftUp(wxMouseEvent& event) { + wxPoint mouse_pos = ::wxGetMousePosition(); if (HasCapture()) { ReleaseMouse(); @@ -587,7 +599,8 @@ void BBLTopbar::OnMouseLeftUp(wxMouseEvent& event) void BBLTopbar::OnMouseMotion(wxMouseEvent& event) { - wxPoint mouse_pos = event.GetPosition(); + wxPoint mouse_pos = ::wxGetMousePosition(); + if (!HasCapture()) { //m_frame->OnMouseMotion(event); @@ -597,7 +610,6 @@ void BBLTopbar::OnMouseMotion(wxMouseEvent& event) if (event.Dragging() && event.LeftIsDown()) { - wxPoint mouse_pos = ::wxGetMousePosition(); // leave max state and adjust position if (m_frame->IsMaximized()) { wxRect rect = m_frame->GetRect(); From 3e5d660a3778095c76264218d382b81c7a1a4490 Mon Sep 17 00:00:00 2001 From: "chunmao.guo" Date: Fri, 22 Jul 2022 17:03:26 +0800 Subject: [PATCH 020/180] FIX: toggle line for Model Tabs. Change-Id: Ia3964d6509a97ae098ac79be06396fe1c39396d6 (cherry picked from commit 597fb201f3c19756cfd91808447beaf3a6227434) --- src/slic3r/GUI/Tab.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 9d91c2c1ff6..6fd2a3fa027 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -2107,6 +2107,9 @@ void TabPrintModel::update_model_config() m_config->apply_only(local_config, local_keys); m_config_manipulation.apply_null_fff_config(m_config, m_null_keys, m_object_configs); } + toggle_options(); + if (m_active_page) + m_active_page->update_visibility(m_mode, true); // for taggle line update_dirty(); TabPrint::reload_config(); //update(); From 13bd9ca44566243388fa6a67116853b76ea642ce Mon Sep 17 00:00:00 2001 From: "zhimin.zeng" Date: Tue, 26 Jul 2022 16:24:36 +0800 Subject: [PATCH 021/180] FIX: fix issue STUDIO-480 associate files problem Change-Id: I348778349c0786c1b9388305c9290c62a24c30f1 (cherry picked from commit dd35e2a5bfdb107f973eb11a40b72b7e9a494e73) --- src/slic3r/GUI/GUI_App.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 719bf88fad8..e65a6b239c3 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -4820,8 +4820,15 @@ void GUI_App::disassociate_files(std::wstring extend) bool is_new = false; is_new |= del_win_registry(HKEY_CURRENT_USER, reg_extension.c_str(), prog_id.c_str()); - is_new |= del_win_registry(HKEY_CURRENT_USER, reg_prog_id.c_str(), prog_desc.c_str()); - is_new |= del_win_registry(HKEY_CURRENT_USER, reg_prog_id_command.c_str(), prog_command.c_str()); + + bool is_associate_3mf = app_config->get("associate_3mf") == "true"; + bool is_associate_stl = app_config->get("associate_stl") == "true"; + bool is_associate_step = app_config->get("associate_step") == "true"; + if (!is_associate_3mf && !is_associate_stl && !is_associate_step) + { + is_new |= del_win_registry(HKEY_CURRENT_USER, reg_prog_id.c_str(), prog_desc.c_str()); + is_new |= del_win_registry(HKEY_CURRENT_USER, reg_prog_id_command.c_str(), prog_command.c_str()); + } if (is_new) ::SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, nullptr, nullptr); From 405444f042a05da294e4d4093402decc4ea2f2ab Mon Sep 17 00:00:00 2001 From: "chunmao.guo" Date: Tue, 26 Jul 2022 15:19:28 +0800 Subject: [PATCH 022/180] FIX: crash when no WMP Change-Id: I9bab2e73da05125ee2ca24ac13456fbb82e91714 --- src/slic3r/GUI/MediaPlayCtrl.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/MediaPlayCtrl.cpp b/src/slic3r/GUI/MediaPlayCtrl.cpp index 7f0625fc2df..110c37c5e75 100644 --- a/src/slic3r/GUI/MediaPlayCtrl.cpp +++ b/src/slic3r/GUI/MediaPlayCtrl.cpp @@ -233,8 +233,10 @@ void wxMediaCtrl2::DoSetSize(int x, int y, int width, int height, int sizeFlags) BOOST_LOG_TRIVIAL(info) << "wxMediaCtrl2::DoSetSize: width: " << width << ", height: " << height << ", maxHeight: " << maxHeight; SetMaxSize({-1, maxHeight}); Slic3r::GUI::wxGetApp().CallAfter([this] { - GetParent()->Layout(); - GetParent()->Refresh(); + if (auto p = GetParent()) { + p->Layout(); + p->Refresh(); + } }); } } From 54c5113b797326043f199ddc4cfd683750866df5 Mon Sep 17 00:00:00 2001 From: "chunmao.guo" Date: Tue, 26 Jul 2022 18:47:36 +0800 Subject: [PATCH 023/180] FIX: recalc textsize after set font Change-Id: Ic4717ffd5b418fa7030659e3e684b0868cca2c61 --- src/slic3r/GUI/Widgets/SpinInput.cpp | 8 +++----- src/slic3r/GUI/Widgets/TextInput.cpp | 21 +++++++++------------ 2 files changed, 12 insertions(+), 17 deletions(-) diff --git a/src/slic3r/GUI/Widgets/SpinInput.cpp b/src/slic3r/GUI/Widgets/SpinInput.cpp index 9fa0727b827..52a1eeb522b 100644 --- a/src/slic3r/GUI/Widgets/SpinInput.cpp +++ b/src/slic3r/GUI/Widgets/SpinInput.cpp @@ -48,9 +48,10 @@ SpinInput::SpinInput(wxWindow * parent, wxWindow::SetLabel(label); state_handler.attach({&border_color, &text_color, &background_color}); state_handler.update_binds(); - text_ctrl = new wxTextCtrl(this, wxID_ANY, text, {20, 5}, wxDefaultSize, + text_ctrl = new wxTextCtrl(this, wxID_ANY, text, {20, 4}, wxDefaultSize, style | wxBORDER_NONE | wxTE_PROCESS_ENTER, wxTextValidator(wxFILTER_DIGITS)); text_ctrl->SetFont(Label::Body_14); + text_ctrl->SetInitialSize(text_ctrl->GetBestSize()); text_ctrl->Bind(wxEVT_SET_FOCUS, [this](auto &e) { e.SetId(GetId()); ProcessEventLocally(e); @@ -199,10 +200,7 @@ void SpinInput::messureSize() { wxSize size = GetSize(); wxSize textSize = text_ctrl->GetSize(); -#ifdef __WXOSX__ - textSize.y -= 3; // TODO: -#endif - int h = textSize.y * 24 / 14; + int h = textSize.y + 8; if (size.y < h) { size.y = h; SetSize(size); diff --git a/src/slic3r/GUI/Widgets/TextInput.cpp b/src/slic3r/GUI/Widgets/TextInput.cpp index 43e822f9800..82c90b171f4 100644 --- a/src/slic3r/GUI/Widgets/TextInput.cpp +++ b/src/slic3r/GUI/Widgets/TextInput.cpp @@ -61,13 +61,14 @@ void TextInput::Create(wxWindow * parent, { text_ctrl = nullptr; wxWindow::Create(parent, wxID_ANY, pos, size, style); - + wxWindow::SetLabel(label); style &= ~wxRIGHT; state_handler.attach({&border_color, &text_color, &background_color}); state_handler.update_binds(); - text_ctrl = new wxTextCtrl(this, wxID_ANY, text, {5, 5}, wxDefaultSize, - style | wxBORDER_NONE); + text_ctrl = new wxTextCtrl(this, wxID_ANY, text, {4, 4}, wxDefaultSize, style | wxBORDER_NONE); + text_ctrl->SetFont(Label::Body_14); + text_ctrl->SetInitialSize(text_ctrl->GetBestSize()); text_ctrl->Bind(wxEVT_SET_FOCUS, [this](auto &e) { e.SetId(GetId()); ProcessEventLocally(e); @@ -91,7 +92,6 @@ void TextInput::Create(wxWindow * parent, ProcessEventLocally(e); }); text_ctrl->Bind(wxEVT_RIGHT_DOWN, [this](auto &e) {}); // disable context menu - text_ctrl->SetFont(Label::Body_14); if (!icon.IsEmpty()) { this->icon = ScalableBitmap(this, icon.ToStdString(), 16); } @@ -180,10 +180,10 @@ void TextInput::DoSetSize(int x, int y, int width, int height, int sizeFlags) if (align_right) textPos.x += labelSize.x; if (text_ctrl) { - wxSize textSize = text_ctrl->GetSize(); - textSize.x = size.x - textPos.x - labelSize.x - 10; - text_ctrl->SetSize(textSize); - text_ctrl->SetPosition({textPos.x, (size.y - textSize.y) / 2}); + wxSize textSize = text_ctrl->GetSize(); + textSize.x = size.x - textPos.x - labelSize.x - 10; + text_ctrl->SetSize(textSize); + text_ctrl->SetPosition({textPos.x, (size.y - textSize.y) / 2}); } } @@ -245,10 +245,7 @@ void TextInput::messureSize() wxClientDC dc(this); labelSize = dc.GetTextExtent(wxWindow::GetLabel()); wxSize textSize = text_ctrl->GetSize(); -#ifdef __WXOSX__ - textSize.y -= 3; // TODO: -#endif - int h = textSize.y * 24 / 14; + int h = textSize.y + 8; if (size.y < h) { size.y = h; } From d61ec596e95b8f9a8516d4287d1fd199ee809d44 Mon Sep 17 00:00:00 2001 From: "chunmao.guo" Date: Tue, 26 Jul 2022 17:54:55 +0800 Subject: [PATCH 024/180] FIX: add load_ams_list call after switch language Change-Id: Ibc6a994b4e5101439fe947008a7329e5c42b2339 --- src/slic3r/GUI/Monitor.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/slic3r/GUI/Monitor.cpp b/src/slic3r/GUI/Monitor.cpp index bf6a44d230f..ba8fd6f99ab 100644 --- a/src/slic3r/GUI/Monitor.cpp +++ b/src/slic3r/GUI/Monitor.cpp @@ -148,6 +148,12 @@ MonitorPanel::~MonitorPanel() m_refresh_timer->SetOwner(this); m_refresh_timer->Start(REFRESH_INTERVAL); wxPostEvent(this, wxTimerEvent()); + + Slic3r::DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager(); + if (!dev) return; + MachineObject *obj_ = dev->get_selected_machine(); + if (obj_) + GUI::wxGetApp().sidebar().load_ams_list(obj_->amsList); } void MonitorPanel::init_tabpanel() From 0d94bc619e61fd9d46c3ac4c02aafbd998b66a26 Mon Sep 17 00:00:00 2001 From: "chunmao.guo" Date: Tue, 26 Jul 2022 14:34:56 +0800 Subject: [PATCH 025/180] FIX: handle gesture event in GLCanvas Change-Id: I2e0af39d30693e997bf0c0bb68edb6c40c484864 --- src/slic3r/GUI/GLCanvas3D.cpp | 41 ++++++++++++++++++++++++++++++++++- src/slic3r/GUI/GLCanvas3D.hpp | 1 + 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 788969b2bc1..050084b56ba 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2134,6 +2134,11 @@ void GLCanvas3D::bind_event_handlers() m_canvas->Bind(wxEVT_PAINT, &GLCanvas3D::on_paint, this); m_canvas->Bind(wxEVT_SET_FOCUS, &GLCanvas3D::on_set_focus, this); m_event_handlers_bound = true; + + m_canvas->Bind(wxEVT_GESTURE_PAN, &GLCanvas3D::on_gesture, this); + m_canvas->Bind(wxEVT_GESTURE_ZOOM, &GLCanvas3D::on_gesture, this); + m_canvas->Bind(wxEVT_GESTURE_ROTATE, &GLCanvas3D::on_gesture, this); + m_canvas->EnableTouchEvents(wxTOUCH_ZOOM_GESTURE | wxTOUCH_ROTATE_GESTURE); } } @@ -2162,8 +2167,11 @@ void GLCanvas3D::unbind_event_handlers() m_canvas->Unbind(wxEVT_RIGHT_DCLICK, &GLCanvas3D::on_mouse, this); m_canvas->Unbind(wxEVT_PAINT, &GLCanvas3D::on_paint, this); m_canvas->Unbind(wxEVT_SET_FOCUS, &GLCanvas3D::on_set_focus, this); - m_event_handlers_bound = false; + + m_canvas->Unbind(wxEVT_GESTURE_PAN, &GLCanvas3D::on_gesture, this); + m_canvas->Unbind(wxEVT_GESTURE_ZOOM, &GLCanvas3D::on_gesture, this); + m_canvas->Unbind(wxEVT_GESTURE_ROTATE, &GLCanvas3D::on_gesture, this); } } @@ -2933,6 +2941,37 @@ std::string format_mouse_event_debug_message(const wxMouseEvent &evt) } #endif /* SLIC3R_DEBUG_MOUSE_EVENTS */ +void GLCanvas3D::on_gesture(wxGestureEvent &evt) +{ + if (!m_initialized || !_set_current()) + return; + + auto & camera = wxGetApp().plater()->get_camera(); + if (evt.GetEventType() == wxEVT_GESTURE_PAN) { + auto d = static_cast(evt).GetDelta(); + Vec3d delta{(double) d.x, (double) d.y, 0}; + camera.set_target(camera.get_target() + delta); + } else if (evt.GetEventType() == wxEVT_GESTURE_ZOOM) { + static float zoom_start = 1; + if (evt.IsGestureStart()) + zoom_start = camera.get_zoom(); + camera.set_zoom(zoom_start * static_cast(evt).GetZoomFactor()); + } else if (evt.GetEventType() == wxEVT_GESTURE_ROTATE) { + PartPlate* plate = wxGetApp().plater()->get_partplate_list().get_curr_plate(); + bool rotate_limit = current_printer_technology() != ptSLA; + static double last_rotate = 0; + if (evt.IsGestureStart()) + last_rotate = 0; + auto rotate = static_cast(evt).GetRotationAngle() - last_rotate; + last_rotate += rotate; + if (plate) + camera.rotate_on_sphere_with_target(-rotate, 0, rotate_limit, plate->get_bounding_box().center()); + else + camera.rotate_on_sphere(-rotate, 0, rotate_limit); + } + m_dirty = true; +} + void GLCanvas3D::on_mouse(wxMouseEvent& evt) { if (!m_initialized || !_set_current()) diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 50280ff7474..21de36f8c5f 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -765,6 +765,7 @@ class GLCanvas3D void on_timer(wxTimerEvent& evt); void on_render_timer(wxTimerEvent& evt); void on_mouse(wxMouseEvent& evt); + void on_gesture(wxGestureEvent& evt); void on_paint(wxPaintEvent& evt); void on_set_focus(wxFocusEvent& evt); From 1705f3d5b78c83ef3413c01762cb25a748db48f2 Mon Sep 17 00:00:00 2001 From: "chunmao.guo" Date: Tue, 26 Jul 2022 14:45:09 +0800 Subject: [PATCH 026/180] FIX: transfer touch wheel event to pan gesture Change-Id: Ic74662849a3728017a557417ec8cb1bf49826f15 (cherry picked from commit ccd1aa95de4abecbddecc0fb43ae7ce2296c6ede) --- src/slic3r/GUI/GLCanvas3D.cpp | 4 ++ src/slic3r/Utils/MacDarkMode.hpp | 5 ++ src/slic3r/Utils/MacDarkMode.mm | 95 ++++++++++++++++++++++++++++++++ 3 files changed, 104 insertions(+) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 050084b56ba..2a28b633cf9 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -27,6 +27,7 @@ #include "slic3r/Utils/UndoRedo.hpp" #include "slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp" #include "slic3r/GUI/BitmapCache.hpp" +#include "slic3r/Utils/MacDarkMode.hpp" #include "GUI_App.hpp" #include "GUI_ObjectList.hpp" @@ -2139,6 +2140,9 @@ void GLCanvas3D::bind_event_handlers() m_canvas->Bind(wxEVT_GESTURE_ZOOM, &GLCanvas3D::on_gesture, this); m_canvas->Bind(wxEVT_GESTURE_ROTATE, &GLCanvas3D::on_gesture, this); m_canvas->EnableTouchEvents(wxTOUCH_ZOOM_GESTURE | wxTOUCH_ROTATE_GESTURE); +#if __WXOSX__ + initGestures(m_canvas->GetHandle(), m_canvas); // for UIPanGestureRecognizer allowedScrollTypesMask +#endif } } diff --git a/src/slic3r/Utils/MacDarkMode.hpp b/src/slic3r/Utils/MacDarkMode.hpp index b3574035e52..8a5dd30afee 100644 --- a/src/slic3r/Utils/MacDarkMode.hpp +++ b/src/slic3r/Utils/MacDarkMode.hpp @@ -1,6 +1,8 @@ #ifndef slic3r_MacDarkMode_hpp_ #define slic3r_MacDarkMode_hpp_ +#include + namespace Slic3r { namespace GUI { @@ -8,6 +10,9 @@ namespace GUI { extern bool mac_dark_mode(); extern double mac_max_scaling_factor(); extern void set_miniaturizable(void * window); + +void initGestures(void * view, wxEvtHandler * handler); + #endif diff --git a/src/slic3r/Utils/MacDarkMode.mm b/src/slic3r/Utils/MacDarkMode.mm index 8a85322e9cf..040bebc2fd3 100644 --- a/src/slic3r/Utils/MacDarkMode.mm +++ b/src/slic3r/Utils/MacDarkMode.mm @@ -6,6 +6,8 @@ #import #import +#include + @interface MacDarkMode : NSObject {} @end @@ -76,6 +78,8 @@ - (void)setTextColor:(NSColor *)textColor @end +/* edit column for wxTableView */ + #include #include #include @@ -98,6 +102,7 @@ - (BOOL)outlineView: (NSOutlineView*) view shouldEditTableColumn:(nullable NSTab @end +/* remove focused border for wxTextCtrl */ @implementation NSTextField (FocusRing) @@ -107,3 +112,93 @@ - (NSFocusRingType) focusRingType } @end + +/* gesture handle for Canvas3D */ + +@interface wxNSCustomOpenGLView : NSOpenGLView +{ +} +@end + + +@implementation wxNSCustomOpenGLView (Gesture) + +wxEvtHandler * _gestureHandler = nullptr; + +- (void) onGestureMove: (NSPanGestureRecognizer*) gesture +{ + wxPanGestureEvent evt; + NSPoint tr = [gesture translationInView: self]; + evt.SetDelta({(int) tr.x, (int) tr.y}); + [self postEvent:evt withGesture:gesture]; +} + +- (void) onGestureScale: (NSMagnificationGestureRecognizer*) gesture +{ + wxZoomGestureEvent evt; + evt.SetZoomFactor(gesture.magnification + 1.0); + [self postEvent:evt withGesture:gesture]; +} + +- (void) onGestureRotate: (NSRotationGestureRecognizer*) gesture +{ + wxRotateGestureEvent evt; + evt.SetRotationAngle(-gesture.rotation); + [self postEvent:evt withGesture:gesture]; +} + +- (void) postEvent: (wxGestureEvent &) evt withGesture: (NSGestureRecognizer* ) gesture +{ + NSPoint pos = [gesture locationInView: self]; + evt.SetPosition({(int) pos.x, (int) pos.y}); + if (gesture.state == NSGestureRecognizerStateBegan) + evt.SetGestureStart(); + else if (gesture.state == NSGestureRecognizerStateEnded) + evt.SetGestureEnd(); + _gestureHandler->ProcessEvent(evt); +} + +- (void) scrollWheel2:(NSEvent *)event +{ + if (_gestureHandler && event.hasPreciseScrollingDeltas) { + wxPanGestureEvent evt; + evt.SetDelta({(int)[event scrollingDeltaX], -(int)[event scrollingDeltaY]}); + _gestureHandler->ProcessEvent(evt); + } else { + [self scrollWheel2: event]; + } +} + ++ (void) load +{ + Method scrollWheel = class_getInstanceMethod([wxNSCustomOpenGLView class], @selector(scrollWheel:)); + Method scrollWheel2 = class_getInstanceMethod([wxNSCustomOpenGLView class], @selector(scrollWheel2:)); + method_exchangeImplementations(scrollWheel, scrollWheel2); +} + +- (void) initGesturesWithHandler: (wxEvtHandler*) handler +{ +// NSPanGestureRecognizer * pan = [[NSPanGestureRecognizer alloc] initWithTarget: self action: @selector(onGestureMove:)]; +// pan.numberOfTouchesRequired = 2; +// pan.allowedTouchTypes = 0; +// NSMagnificationGestureRecognizer * magnification = [[NSMagnificationGestureRecognizer alloc] initWithTarget: self action: @selector(onGestureScale:)]; +// NSRotationGestureRecognizer * rotation = [[NSRotationGestureRecognizer alloc] initWithTarget: self action: @selector(onGestureRotate:)]; +// [self addGestureRecognizer:pan]; +// [self addGestureRecognizer:magnification]; +// [self addGestureRecognizer:rotation]; + _gestureHandler = handler; +} + +@end + +namespace Slic3r { +namespace GUI { + +void initGestures(void * view, wxEvtHandler * handler) +{ + NSOpenGLView * glView = (NSOpenGLView *) view; + [glView initGesturesWithHandler: handler]; +} + +} +} From 18920df354f81c741bc438c136202fa8df5b0882 Mon Sep 17 00:00:00 2001 From: "chunmao.guo" Date: Tue, 26 Jul 2022 18:11:34 +0800 Subject: [PATCH 027/180] FIX: temp disable markdown tooltip on release to public Change-Id: I6f37b9176aaec6f0d7d3ccc6aa60c5a829729fd5 --- src/slic3r/GUI/MarkdownTip.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/slic3r/GUI/MarkdownTip.cpp b/src/slic3r/GUI/MarkdownTip.cpp index 7c387cc78e5..dd3e6151ce2 100644 --- a/src/slic3r/GUI/MarkdownTip.cpp +++ b/src/slic3r/GUI/MarkdownTip.cpp @@ -293,6 +293,9 @@ MarkdownTip* MarkdownTip::markdownTip(bool create) bool MarkdownTip::ShowTip(std::string const& tip, std::string const & tooltip, wxPoint pos) { +#if BBL_RELEASE_TO_PUBLIC + return false; +#endif return markdownTip()->ShowTip(pos, tip, tooltip); } From 45e7443bb38d50c4d7fcebe5c18b1141cd8ba2e3 Mon Sep 17 00:00:00 2001 From: "chunmao.guo" Date: Mon, 25 Jul 2022 20:07:06 +0800 Subject: [PATCH 028/180] FIX: windows position after Maximize on Win32 Change-Id: I02d491e819369009ae188a1dd4cfe98900e52c6b --- src/slic3r/GUI/MainFrame.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index c689064643c..a5afdd9dc22 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -352,6 +352,12 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, BORDERLESS_FRAME_ e.Skip(); }); setMaxSize(); + this->Bind(wxEVT_MAXIMIZE, [this](auto &e) { + wxDisplay display(wxDisplay::GetFromWindow(this)); + auto pos = display.GetClientArea().GetPosition(); + Move(pos - wxPoint{8, 8}); + e.Skip(); + }); #endif // WIN32 // BBS Fit(); From 57c6c3d79753ac6aa189aedf1886bfaecd42c65c Mon Sep 17 00:00:00 2001 From: "liz.li" Date: Fri, 22 Jul 2022 12:35:33 +0800 Subject: [PATCH 029/180] ENH:add character checking when connect printer by LAN Change-Id: Iacaeb26736f00b7b00f42c16a7b0c28a2d8dfe02 --- src/slic3r/GUI/ConnectPrinter.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/slic3r/GUI/ConnectPrinter.cpp b/src/slic3r/GUI/ConnectPrinter.cpp index 0e06b6ed359..fcd8df8220e 100644 --- a/src/slic3r/GUI/ConnectPrinter.cpp +++ b/src/slic3r/GUI/ConnectPrinter.cpp @@ -33,6 +33,7 @@ ConnectPrinterDialog::ConnectPrinterDialog(wxWindow *parent, wxWindowID id, cons sizer_connect = new wxBoxSizer(wxHORIZONTAL); m_textCtrl_code = new TextInput(this, wxEmptyString); + m_textCtrl_code->GetTextCtrl()->SetMaxLength(10); m_textCtrl_code->SetFont(Label::Body_14); m_textCtrl_code->SetCornerRadius(FromDIP(5)); m_textCtrl_code->SetSize(wxSize(FromDIP(330), FromDIP(40))); @@ -132,6 +133,12 @@ void ConnectPrinterDialog::on_input_enter(wxCommandEvent& evt) void ConnectPrinterDialog::on_button_confirm(wxCommandEvent &event) { wxString code = m_textCtrl_code->GetTextCtrl()->GetValue(); + for (char c : code) { + if (!('0' <= c && c <= '9' || 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z')) { + show_error(this, _L("Invalid input.")); + return; + } + } if (m_obj) { m_obj->set_access_code(code.ToStdString()); } From ffc86d15cf39810f1fa4b04367df65aa1823e61d Mon Sep 17 00:00:00 2001 From: "liz.li" Date: Fri, 22 Jul 2022 14:32:54 +0800 Subject: [PATCH 030/180] FIX:(mac) print button display issues Change-Id: I3a5471b509d601b45722a5174ddb4dd132ca4350 --- src/slic3r/GUI/Widgets/SideButton.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/Widgets/SideButton.cpp b/src/slic3r/GUI/Widgets/SideButton.cpp index 885abd7e5df..4252a991346 100644 --- a/src/slic3r/GUI/Widgets/SideButton.cpp +++ b/src/slic3r/GUI/Widgets/SideButton.cpp @@ -214,9 +214,9 @@ void SideButton::render(wxDC& dc) dc.SetPen(wxNullPen); } else { dc.DrawRoundedRectangle(0, 0, size.x, size.y, radius); - dc.DrawRectangle(0, 0, size.x - radius, size.y); + dc.DrawRectangle(0, 0, radius, size.y); dc.SetPen(wxNullPen); - dc.DrawRectangle(size.x - radius - pen_width, pen_width, 2 * pen_width, size.y - 2 * pen_width); + dc.DrawRectangle(pen_width, pen_width, size.x - radius, size.y - 2 * pen_width); } } else { dc.DrawRectangle(0, 0, size.x, size.y); From eaf71e4d2f332789a915b0b5206f3a99bd6ceea8 Mon Sep 17 00:00:00 2001 From: "zhimin.zeng" Date: Tue, 19 Jul 2022 19:30:03 +0800 Subject: [PATCH 031/180] FIX: fix issue STUDIO-395 cannot save project Change-Id: I977402535dee8ea7b84fec4bb721a4e146a5e49e (cherry picked from commit d1e483dca2903128cde028dfec77692c74fe7ba0) --- src/slic3r/GUI/Plater.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 107be515da8..c3c166fcaa2 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -6572,6 +6572,8 @@ int Plater::save_project(bool saveAs) up_to_date(true, false); up_to_date(true, true); + + wxGetApp().update_saved_preset_from_current_preset(); p->dirty_state.reset_after_save(); return wxID_YES; } From 3d80bb52dc84eeb2d2f1c78666c728043bc4ba94 Mon Sep 17 00:00:00 2001 From: "zhimin.zeng" Date: Tue, 26 Jul 2022 15:43:30 +0800 Subject: [PATCH 032/180] FIX: fix issue STUDIO-452 wrong transformation when sub model is rotated Change-Id: I40e7ad0f808dd4d3445f4556ae517f5284e1a65c (cherry picked from commit 6d1328a4eb630a08a9c635f0efea2a057283329e) --- src/slic3r/GUI/GUI_ObjectList.cpp | 24 +++++++++++++++++++ .../GUI/Gizmos/GizmoObjectManipulation.cpp | 2 +- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 15367a2fbd2..09935315759 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -1977,6 +1977,30 @@ void ObjectList::load_generic_subobject(const std::string& type_name, const Mode // update printable state on canvas wxGetApp().plater()->canvas3D()->update_instance_printable_state_for_object((size_t)obj_idx); + // apply the instance transform to all volumes and reset instance transform except the offset + { + const Geometry::Transformation &instance_transformation = model_object.instances[0]->get_transformation(); + Vec3d original_instance_center = instance_transformation.get_offset(); + + const Transform3d &transformation_matrix = instance_transformation.get_matrix(); + for (ModelVolume *volume : model_object.volumes) { + const Transform3d &volume_matrix = volume->get_matrix(); + Transform3d new_matrix = transformation_matrix * volume_matrix; + volume->set_transformation(new_matrix); + } + model_object.instances[0]->set_transformation(Geometry::Transformation()); + + model_object.ensure_on_bed(); + // keep new instance center the same as the original center + model_object.translate(-original_instance_center); + model_object.origin_translation += original_instance_center; + model_object.translate_instances(model_object.origin_translation); + model_object.origin_translation = Vec3d::Zero(); + + // update the cache data in selection to keep the data of ModelVolume and GLVolume are consistent + wxGetApp().plater()->update(); + } + selection_changed(); //BBS: notify partplate the modify diff --git a/src/slic3r/GUI/Gizmos/GizmoObjectManipulation.cpp b/src/slic3r/GUI/Gizmos/GizmoObjectManipulation.cpp index 5b7dbe2f494..b8653f5d672 100644 --- a/src/slic3r/GUI/Gizmos/GizmoObjectManipulation.cpp +++ b/src/slic3r/GUI/Gizmos/GizmoObjectManipulation.cpp @@ -98,7 +98,7 @@ void GizmoObjectManipulation::update_settings_value(const Selection& selection) if (m_world_coordinates) { m_new_rotate_label_string = L("Rotate"); - m_new_rotation = Vec3d::Zero(); + m_new_rotation = volume->get_instance_rotation() * (180. / M_PI); m_new_size = selection.get_scaled_instance_bounding_box().size(); m_new_scale = m_new_size.cwiseProduct(selection.get_unscaled_instance_bounding_box().size().cwiseInverse()) * 100.; } From 21d41bbbec7fc90c0dbb8cd3fb97b0b933d7d7ec Mon Sep 17 00:00:00 2001 From: "yifan.wu" Date: Wed, 27 Jul 2022 11:51:22 +0800 Subject: [PATCH 033/180] ENH: optimize object list display 1. add filament title 2. adjust the layout propotion of object list and per-object parameter setting panel 3. replace wxScrollWindow with wxPanel for the Sidebar to avoid ugly double scrollbars 4. remove the auto height logic in object list to avoid it occupies too much height, causing no enough space for per-object setting panel Signed-off-by: yifan.wu Change-Id: I2201b61e5a654e86427ce7f377d0e4c4ef593748 (cherry picked from commit dd0413d6c22a20059e9042b88a15391518fb54c7) --- src/slic3r/GUI/GUI_ObjectList.cpp | 6 +++++- src/slic3r/GUI/Plater.cpp | 12 ++++++------ src/slic3r/GUI/Plater.hpp | 2 +- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 09935315759..ed55b8ad042 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -289,10 +289,14 @@ void ObjectList::update_min_height() wxDataViewItemArray all_items; m_objects_model->GetAllChildren(wxDataViewItem(nullptr), all_items); size_t items_cnt = all_items.Count(); +#if 0 if (items_cnt < 7) items_cnt = 7; else if (items_cnt >= 15) items_cnt = 15; +#else + items_cnt = 8; +#endif if (m_items_count == items_cnt) return; @@ -356,7 +360,7 @@ void ObjectList::create_objects_ctrl() bmp_choice_renderer->set_default_extruder_idx([this]() { return m_objects_model->GetDefaultExtruderIdx(GetSelection()); }); - AppendColumn(new wxDataViewColumn(_L(""), bmp_choice_renderer, + AppendColumn(new wxDataViewColumn(_L("Fila."), bmp_choice_renderer, colFilament, m_columns_width[colFilament] * em, wxALIGN_CENTER_HORIZONTAL, 0)); // BBS diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index c3c166fcaa2..1d7f30743ca 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -268,7 +268,7 @@ struct Sidebar::priv { Plater *plater; - wxScrolledWindow *scrolled; + wxPanel *scrolled; PlaterPresetComboBox *combo_print; std::vector combos_filament; int editing_filament = -1; @@ -407,12 +407,12 @@ void Sidebar::priv::hide_rich_tip(wxButton* btn) Sidebar::Sidebar(Plater *parent) : wxPanel(parent, wxID_ANY, wxDefaultPosition, wxSize(42 * wxGetApp().em_unit(), -1)), p(new priv(parent)) { - p->scrolled = new wxScrolledWindow(this); + p->scrolled = new wxPanel(this); // p->scrolled->SetScrollbars(0, 100, 1, 2); // ys_DELETE_after_testing. pixelsPerUnitY = 100 // but this cause the bad layout of the sidebar, when all infoboxes appear. // As a result we can see the empty block at the bottom of the sidebar // But if we set this value to 5, layout will be better - p->scrolled->SetScrollRate(0, 5); + //p->scrolled->SetScrollRate(0, 5); p->scrolled->SetBackgroundColour(*wxWHITE); @@ -724,7 +724,7 @@ Sidebar::Sidebar(Plater *parent) p->sizer_params = new wxBoxSizer(wxVERTICAL); p->m_object_list = new ObjectList(p->scrolled); p->sizer_params->Add(p->m_object_list, 1, wxEXPAND | wxTOP, 0); - scrolled_sizer->Add(p->sizer_params, 3, wxEXPAND | wxLEFT, 0); + scrolled_sizer->Add(p->sizer_params, 2, wxEXPAND | wxLEFT, 0); p->m_object_list->Hide(); p->m_auxiliary_dialog = new AuxiliaryDialog(this); @@ -737,7 +737,7 @@ Sidebar::Sidebar(Plater *parent) #else if (params_panel) { params_panel->Reparent(p->scrolled); - scrolled_sizer->Add(params_panel, 2, wxEXPAND); + scrolled_sizer->Add(params_panel, 3, wxEXPAND); } #endif @@ -1202,7 +1202,7 @@ ObjectSettings* Sidebar::obj_settings() return p->object_settings; } -wxScrolledWindow* Sidebar::scrolled_panel() +wxPanel* Sidebar::scrolled_panel() { return p->scrolled; } diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 95d3f635b46..a8f0b812c4e 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -122,7 +122,7 @@ class Sidebar : public wxPanel ObjectList* obj_list(); ObjectSettings* obj_settings(); - wxScrolledWindow* scrolled_panel(); + wxPanel* scrolled_panel(); wxPanel* print_panel(); wxPanel* filament_panel(); From 04bdbb4a2883b924748a3731a90527885df8d768 Mon Sep 17 00:00:00 2001 From: "yifan.wu" Date: Wed, 27 Jul 2022 15:06:14 +0800 Subject: [PATCH 034/180] ENH: add cn translations for newly added phrases Signed-off-by: yifan.wu Change-Id: I17323af5f6cee8839aa99e4957b9abcf22662f4a --- bbl/i18n/BambuStudio.pot | 41 ++++++++++++------ bbl/i18n/de/BambuStudio_de.po | 52 +++++++++++++++-------- bbl/i18n/en/BambuStudio_en.po | 49 +++++++++++++++------- bbl/i18n/es/BambuStudio_es.po | 52 +++++++++++++++-------- bbl/i18n/fr/BambuStudio_fr.po | 49 +++++++++++++++------- bbl/i18n/nl/BambuStudio_nl.po | 49 +++++++++++++++------- bbl/i18n/sv/BambuStudio_sv.po | 49 +++++++++++++++------- bbl/i18n/zh_cn/BambuStudio_zh_CN.po | 63 ++++++++++++++++++++-------- resources/i18n/de/BambuStudio.mo | Bin 162067 -> 161985 bytes resources/i18n/en/BambuStudio.mo | Bin 150300 -> 150220 bytes resources/i18n/es/BambuStudio.mo | Bin 162751 -> 162707 bytes resources/i18n/fr/BambuStudio.mo | Bin 164614 -> 164531 bytes resources/i18n/nl/BambuStudio.mo | Bin 161846 -> 161747 bytes resources/i18n/sv/BambuStudio.mo | Bin 152755 -> 152674 bytes resources/i18n/zh_cn/BambuStudio.mo | Bin 145921 -> 146223 bytes src/libslic3r/PrintConfig.cpp | 4 +- 16 files changed, 285 insertions(+), 123 deletions(-) diff --git a/bbl/i18n/BambuStudio.pot b/bbl/i18n/BambuStudio.pot index e508e3646dc..df2f9510dec 100644 --- a/bbl/i18n/BambuStudio.pot +++ b/bbl/i18n/BambuStudio.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-07-23 18:15+0800\n" +"POT-Creation-Date: 2022-07-27 15:03+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -57,7 +57,7 @@ msgstr "" msgid "Perform" msgstr "" -msgid "Fragment area" +msgid "Gap area" msgstr "" msgid "Set pen size" @@ -126,9 +126,6 @@ msgstr "" msgid "Edge detection" msgstr "" -msgid "Clear all" -msgstr "" - msgid "Triangles" msgstr "" @@ -419,8 +416,11 @@ msgstr "" msgid "Downloading Bambu Network plug-in" msgstr "" +msgid "Incorrect password" +msgstr "" + #, possible-c-format, possible-boost-format -msgid "Connect %s[SN:%s] failed!" +msgid "Connect %s failed! [SN:%s, code=%s]" msgstr "" msgid "" @@ -790,6 +790,9 @@ msgstr "" msgid "Name" msgstr "" +msgid "Fila." +msgstr "" + #, possible-c-format, possible-boost-format msgid "%1$d error repaired" msgid_plural "%1$d errors repaired" @@ -1053,6 +1056,9 @@ msgid "" "Arrange failed. Found some exceptions when processing object geometries." msgstr "" +msgid "Arranging" +msgstr "" + msgid "Arranging canceled." msgstr "" @@ -1495,13 +1501,6 @@ msgid "" "No - Give up using spiral mode this time" msgstr "" -msgid "" -"When recording timelapse without toolhead, it is recommended to add a " -"\"Timelapse Wipe Tower\" \n" -"by right-click the empty position of build plate and choose \"Add Primitive" -"\"->\"Timelapse Wipe Tower\".\n" -msgstr "" - msgid "" "Prime tower does not work when Adaptive Layer Height or Independent Support " "Layer Height is on.\n" @@ -1972,6 +1971,9 @@ msgid "" "on the printer, as shown in the figure:" msgstr "" +msgid "Invalid input." +msgstr "" + msgid "Application is closing" msgstr "" @@ -3283,6 +3285,13 @@ msgstr "" msgid "Delete this preset" msgstr "" +msgid "" +"When recording timelapse without toolhead, it is recommended to add a " +"\"Timelapse Wipe Tower\" \n" +"by right-click the empty position of build plate and choose \"Add Primitive" +"\"->\"Timelapse Wipe Tower\".\n" +msgstr "" + msgid "Line width" msgstr "" @@ -4263,6 +4272,12 @@ msgstr "" msgid "Bed exclude area" msgstr "" +msgid "" +"Unprintable area in XY plane. For example, X1 Series printers use the front " +"left corner to cut filament during filament change. The area is expressed as " +"polygon by points in following format: \"XxY, XxY, ...\"" +msgstr "" + msgid "Elephant foot compensation" msgstr "" diff --git a/bbl/i18n/de/BambuStudio_de.po b/bbl/i18n/de/BambuStudio_de.po index 0abaa1cb636..4051026e988 100644 --- a/bbl/i18n/de/BambuStudio_de.po +++ b/bbl/i18n/de/BambuStudio_de.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: Bambu Studio\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-07-23 18:15+0800\n" +"POT-Creation-Date: 2022-07-27 15:03+0800\n" "PO-Revision-Date: \n" "Last-Translator: \n" "Language-Team: \n" @@ -52,8 +52,8 @@ msgstr "" msgid "Perform" msgstr "Ausführen" -msgid "Fragment area" -msgstr "Fragment area" +msgid "Gap area" +msgstr "" msgid "Set pen size" msgstr "Pinselgröße festlegen" @@ -124,9 +124,6 @@ msgstr "Wähle Material" msgid "Edge detection" msgstr "Kantenerkennung" -msgid "Clear all" -msgstr "Alles löschen" - msgid "Triangles" msgstr "Dreiecke" @@ -430,8 +427,11 @@ msgstr "BambuStudio hat eine unbehandelte Ausnahme erhalten: %1%" msgid "Downloading Bambu Network plug-in" msgstr "" +msgid "Incorrect password" +msgstr "" + #, c-format, boost-format -msgid "Connect %s[SN:%s] failed!" +msgid "Connect %s failed! [SN:%s, code=%s]" msgstr "" msgid "" @@ -811,6 +811,9 @@ msgstr "Schließen" msgid "Name" msgstr "Name" +msgid "Fila." +msgstr "" + #, c-format, boost-format msgid "%1$d error repaired" msgid_plural "%1$d errors repaired" @@ -1102,6 +1105,9 @@ msgstr "" "Anordnen fehlgeschlagen. Bei der Verarbeitung von Objektgeometrien wurden " "einige Ausnahmen gefunden." +msgid "Arranging" +msgstr "Anordnen" + msgid "Arranging canceled." msgstr "Anordnen abgebrochen." @@ -1631,13 +1637,6 @@ msgstr "" "Ja - Diese Einstellungen ändern und den Spiralmodus automatisch aktivieren\n" "Nein - Verzichten Sie dieses Mal auf den Spiralmodus" -msgid "" -"When recording timelapse without toolhead, it is recommended to add a " -"\"Timelapse Wipe Tower\" \n" -"by right-click the empty position of build plate and choose \"Add Primitive" -"\"->\"Timelapse Wipe Tower\".\n" -msgstr "" - msgid "" "Prime tower does not work when Adaptive Layer Height or Independent Support " "Layer Height is on.\n" @@ -2134,6 +2133,9 @@ msgstr "" "You can find it in \"Settings > Network > Connection code\"\n" "on the printer, as shown in the figure:" +msgid "Invalid input." +msgstr "" + msgid "Application is closing" msgstr "Anwendung schließt" @@ -3496,6 +3498,13 @@ msgstr "Speichere aktuelle %s" msgid "Delete this preset" msgstr "Lösche diese Voreinstellung" +msgid "" +"When recording timelapse without toolhead, it is recommended to add a " +"\"Timelapse Wipe Tower\" \n" +"by right-click the empty position of build plate and choose \"Add Primitive" +"\"->\"Timelapse Wipe Tower\".\n" +msgstr "" + msgid "Line width" msgstr "Breite der Linie" @@ -4574,6 +4583,12 @@ msgstr "Druckbarer Bereich" msgid "Bed exclude area" msgstr "ausgenommene Druckbettfläche" +msgid "" +"Unprintable area in XY plane. For example, X1 Series printers use the front " +"left corner to cut filament during filament change. The area is expressed as " +"polygon by points in following format: \"XxY, XxY, ...\"" +msgstr "" + msgid "Elephant foot compensation" msgstr "Elefantenfußkompensation" @@ -6460,6 +6475,12 @@ msgstr "Support: fix holes at layer %d" msgid "Support: propagate branches at layer %d" msgstr "Support: propagate branches at layer %d" +#~ msgid "Fragment area" +#~ msgstr "Fragment area" + +#~ msgid "Clear all" +#~ msgstr "Alles löschen" + #~ msgid "Creating" #~ msgstr "Creating" @@ -6510,9 +6531,6 @@ msgstr "Support: propagate branches at layer %d" #~ "Lösen Sie das Problem, indem Sie es vollständig innerhalb oder außerhalb " #~ "der Druckplatte verschieben." -#~ msgid "Arranging" -#~ msgstr "Anordnen" - #~ msgid "Ctrl + Any arrow" #~ msgstr "Strg + beliebiger Pfeil" diff --git a/bbl/i18n/en/BambuStudio_en.po b/bbl/i18n/en/BambuStudio_en.po index 3a313e16bd3..9b477114984 100644 --- a/bbl/i18n/en/BambuStudio_en.po +++ b/bbl/i18n/en/BambuStudio_en.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: Bambu Studio\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-07-23 18:15+0800\n" +"POT-Creation-Date: 2022-07-27 15:03+0800\n" "PO-Revision-Date: \n" "Last-Translator: \n" "Language-Team: \n" @@ -52,8 +52,8 @@ msgstr "" msgid "Perform" msgstr "Perform" -msgid "Fragment area" -msgstr "Fragment area" +msgid "Gap area" +msgstr "" msgid "Set pen size" msgstr "Set pen size" @@ -123,9 +123,6 @@ msgstr "Choose filament" msgid "Edge detection" msgstr "Edge detection" -msgid "Clear all" -msgstr "Clear all" - msgid "Triangles" msgstr "Triangles" @@ -424,8 +421,11 @@ msgstr "BambuStudio got an unhandled exception: %1%" msgid "Downloading Bambu Network plug-in" msgstr "" +msgid "Incorrect password" +msgstr "" + #, c-format, boost-format -msgid "Connect %s[SN:%s] failed!" +msgid "Connect %s failed! [SN:%s, code=%s]" msgstr "" msgid "" @@ -801,6 +801,9 @@ msgstr "Lock" msgid "Name" msgstr "Name" +msgid "Fila." +msgstr "" + #, c-format, boost-format msgid "%1$d error repaired" msgid_plural "%1$d errors repaired" @@ -1076,6 +1079,9 @@ msgid "" msgstr "" "Arrange failed. Found some exceptions when processing object geometries." +msgid "Arranging" +msgstr "" + msgid "Arranging canceled." msgstr "Arranging canceled." @@ -1593,13 +1599,6 @@ msgstr "" "Yes - Change these settings and enable spiral mode automatically\n" "No - Give up using spiral mode this time" -msgid "" -"When recording timelapse without toolhead, it is recommended to add a " -"\"Timelapse Wipe Tower\" \n" -"by right-click the empty position of build plate and choose \"Add Primitive" -"\"->\"Timelapse Wipe Tower\".\n" -msgstr "" - msgid "" "Prime tower does not work when Adaptive Layer Height or Independent Support " "Layer Height is on.\n" @@ -2094,6 +2093,9 @@ msgstr "" "You can find it in \"Settings > Network > Connection code\"\n" "on the printer, as shown in the figure:" +msgid "Invalid input." +msgstr "" + msgid "Application is closing" msgstr "Closing application" @@ -3433,6 +3435,13 @@ msgstr "Save current %s" msgid "Delete this preset" msgstr "Delete this preset" +msgid "" +"When recording timelapse without toolhead, it is recommended to add a " +"\"Timelapse Wipe Tower\" \n" +"by right-click the empty position of build plate and choose \"Add Primitive" +"\"->\"Timelapse Wipe Tower\".\n" +msgstr "" + msgid "Line width" msgstr "Line width" @@ -4482,6 +4491,12 @@ msgstr "Printable area" msgid "Bed exclude area" msgstr "Excluded bed area" +msgid "" +"Unprintable area in XY plane. For example, X1 Series printers use the front " +"left corner to cut filament during filament change. The area is expressed as " +"polygon by points in following format: \"XxY, XxY, ...\"" +msgstr "" + msgid "Elephant foot compensation" msgstr "Elephant foot compensation" @@ -6324,6 +6339,12 @@ msgstr "Support: fix holes at layer %d" msgid "Support: propagate branches at layer %d" msgstr "Support: propagate branches at layer %d" +#~ msgid "Fragment area" +#~ msgstr "Fragment area" + +#~ msgid "Clear all" +#~ msgstr "Clear all" + #~ msgid "Creating" #~ msgstr "Creating" diff --git a/bbl/i18n/es/BambuStudio_es.po b/bbl/i18n/es/BambuStudio_es.po index 9a444fdd010..55903a89b62 100644 --- a/bbl/i18n/es/BambuStudio_es.po +++ b/bbl/i18n/es/BambuStudio_es.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: Bambu Studio\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-07-23 18:15+0800\n" +"POT-Creation-Date: 2022-07-27 15:03+0800\n" "PO-Revision-Date: \n" "Last-Translator: \n" "Language-Team: \n" @@ -52,8 +52,8 @@ msgstr "" msgid "Perform" msgstr "Realizar" -msgid "Fragment area" -msgstr "Fragment area" +msgid "Gap area" +msgstr "" msgid "Set pen size" msgstr "Ajustar el tamaño del lápiz" @@ -124,9 +124,6 @@ msgstr "Elegir filamento" msgid "Edge detection" msgstr "Detección de bordes" -msgid "Clear all" -msgstr "Borrar todo" - msgid "Triangles" msgstr "Triángulos" @@ -433,8 +430,11 @@ msgstr "BambuStudio recibió una notificación de excepción no controlada: %1%. msgid "Downloading Bambu Network plug-in" msgstr "" +msgid "Incorrect password" +msgstr "" + #, c-format, boost-format -msgid "Connect %s[SN:%s] failed!" +msgid "Connect %s failed! [SN:%s, code=%s]" msgstr "" msgid "" @@ -812,6 +812,9 @@ msgstr "Bloquear" msgid "Name" msgstr "Nombre" +msgid "Fila." +msgstr "" + #, c-format, boost-format msgid "%1$d error repaired" msgid_plural "%1$d errors repaired" @@ -1097,6 +1100,9 @@ msgstr "" "El posicionamiento ha fallado. Se han encontrado algunas excepciones al " "procesar las geometrías de los objetos." +msgid "Arranging" +msgstr "Organizando" + msgid "Arranging canceled." msgstr "Ordenamiento cancelado." @@ -1621,13 +1627,6 @@ msgstr "" "Sí - Cambiar estos ajustes y activar el modo espiral automáticamente\n" "No - Dejar de usar el modo espiral esta vez" -msgid "" -"When recording timelapse without toolhead, it is recommended to add a " -"\"Timelapse Wipe Tower\" \n" -"by right-click the empty position of build plate and choose \"Add Primitive" -"\"->\"Timelapse Wipe Tower\".\n" -msgstr "" - msgid "" "Prime tower does not work when Adaptive Layer Height or Independent Support " "Layer Height is on.\n" @@ -2126,6 +2125,9 @@ msgstr "" "You can find it in \"Settings > Network > Connection code\"\n" "on the printer, as shown in the figure:" +msgid "Invalid input." +msgstr "" + msgid "Application is closing" msgstr "La aplicación se está cerrando" @@ -3484,6 +3486,13 @@ msgstr "Guardar %s actuales" msgid "Delete this preset" msgstr "Borra este ajuste" +msgid "" +"When recording timelapse without toolhead, it is recommended to add a " +"\"Timelapse Wipe Tower\" \n" +"by right-click the empty position of build plate and choose \"Add Primitive" +"\"->\"Timelapse Wipe Tower\".\n" +msgstr "" + msgid "Line width" msgstr "Ancho de línea" @@ -4556,6 +4565,12 @@ msgstr "Área imprimible" msgid "Bed exclude area" msgstr "La cama excluye el área" +msgid "" +"Unprintable area in XY plane. For example, X1 Series printers use the front " +"left corner to cut filament during filament change. The area is expressed as " +"polygon by points in following format: \"XxY, XxY, ...\"" +msgstr "" + msgid "Elephant foot compensation" msgstr "Compensación del pie de elefante" @@ -6439,6 +6454,12 @@ msgstr "Soporte: arreglar huecos en la capa %d" msgid "Support: propagate branches at layer %d" msgstr "Soporte: propagar ramas en la capa %d" +#~ msgid "Fragment area" +#~ msgstr "Fragment area" + +#~ msgid "Clear all" +#~ msgstr "Borrar todo" + #~ msgid "Creating" #~ msgstr "Creando" @@ -6489,9 +6510,6 @@ msgstr "Soporte: propagar ramas en la capa %d" #~ "Por favor, resuelva el problema moviéndolo totalmente dentro o fuera de " #~ "la placa." -#~ msgid "Arranging" -#~ msgstr "Organizando" - #~ msgid "Ctrl + Any arrow" #~ msgstr "Ctrl + Cualquier tecla" diff --git a/bbl/i18n/fr/BambuStudio_fr.po b/bbl/i18n/fr/BambuStudio_fr.po index b3ae6e11320..138403fcb33 100644 --- a/bbl/i18n/fr/BambuStudio_fr.po +++ b/bbl/i18n/fr/BambuStudio_fr.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: Bambu Studio\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-07-23 18:15+0800\n" +"POT-Creation-Date: 2022-07-27 15:03+0800\n" "PO-Revision-Date: \n" "Last-Translator: \n" "Language-Team: \n" @@ -52,8 +52,8 @@ msgstr "" msgid "Perform" msgstr "Exécuter" -msgid "Fragment area" -msgstr "Fragment area" +msgid "Gap area" +msgstr "" msgid "Set pen size" msgstr "Définir la taille du stylo" @@ -124,9 +124,6 @@ msgstr "Choisissez le filament" msgid "Edge detection" msgstr "Détection des contours" -msgid "Clear all" -msgstr "Tout effacer" - msgid "Triangles" msgstr "Triangles" @@ -433,8 +430,11 @@ msgstr "BambuStudio a reçu une exception non gérée : %1%" msgid "Downloading Bambu Network plug-in" msgstr "" +msgid "Incorrect password" +msgstr "" + #, c-format, boost-format -msgid "Connect %s[SN:%s] failed!" +msgid "Connect %s failed! [SN:%s, code=%s]" msgstr "" msgid "" @@ -814,6 +814,9 @@ msgstr "Bloquer" msgid "Name" msgstr "Nom" +msgid "Fila." +msgstr "" + #, c-format, boost-format msgid "%1$d error repaired" msgid_plural "%1$d errors repaired" @@ -1098,6 +1101,9 @@ msgstr "" "Échec de l'arrangement. Trouvé quelques exceptions lors du traitement des " "géométries d'objets." +msgid "Arranging" +msgstr "" + msgid "Arranging canceled." msgstr "Agencement annulé." @@ -1609,13 +1615,6 @@ msgstr "" "support est désactivé, les couches de coque supérieures sont à 0 et la " "densité de remplissage clairsemée est à 0" -msgid "" -"When recording timelapse without toolhead, it is recommended to add a " -"\"Timelapse Wipe Tower\" \n" -"by right-click the empty position of build plate and choose \"Add Primitive" -"\"->\"Timelapse Wipe Tower\".\n" -msgstr "" - msgid "" "Prime tower does not work when Adaptive Layer Height or Independent Support " "Layer Height is on.\n" @@ -2108,6 +2107,9 @@ msgstr "" "You can find it in \"Settings > Network > Connection code\"\n" "on the printer, as shown in the figure:" +msgid "Invalid input." +msgstr "" + msgid "Application is closing" msgstr "L'application se ferme" @@ -3468,6 +3470,13 @@ msgstr "Enregistrer l'état actuel %s" msgid "Delete this preset" msgstr "Supprimer ce préréglage" +msgid "" +"When recording timelapse without toolhead, it is recommended to add a " +"\"Timelapse Wipe Tower\" \n" +"by right-click the empty position of build plate and choose \"Add Primitive" +"\"->\"Timelapse Wipe Tower\".\n" +msgstr "" + msgid "Line width" msgstr "Largeur de ligne" @@ -4548,6 +4557,12 @@ msgstr "Zone imprimable" msgid "Bed exclude area" msgstr "Zone d'exclusion de lit" +msgid "" +"Unprintable area in XY plane. For example, X1 Series printers use the front " +"left corner to cut filament during filament change. The area is expressed as " +"polygon by points in following format: \"XxY, XxY, ...\"" +msgstr "" + msgid "Elephant foot compensation" msgstr "Compensation de l'effet patte d'éléphant" @@ -6442,6 +6457,12 @@ msgstr "Support: fix holes at layer %d" msgid "Support: propagate branches at layer %d" msgstr "Support: propagate branches at layer %d" +#~ msgid "Fragment area" +#~ msgstr "Fragment area" + +#~ msgid "Clear all" +#~ msgstr "Tout effacer" + #~ msgid "Creating" #~ msgstr "Creating" diff --git a/bbl/i18n/nl/BambuStudio_nl.po b/bbl/i18n/nl/BambuStudio_nl.po index fce24136802..e30b75f792f 100644 --- a/bbl/i18n/nl/BambuStudio_nl.po +++ b/bbl/i18n/nl/BambuStudio_nl.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: Bambu Studio\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-07-23 18:15+0800\n" +"POT-Creation-Date: 2022-07-27 15:03+0800\n" "PO-Revision-Date: \n" "Last-Translator: \n" "Language-Team: \n" @@ -52,8 +52,8 @@ msgstr "" msgid "Perform" msgstr "Perform" -msgid "Fragment area" -msgstr "Fragment area" +msgid "Gap area" +msgstr "" msgid "Set pen size" msgstr "Selecteer pen formaat" @@ -124,9 +124,6 @@ msgstr "Kies filament" msgid "Edge detection" msgstr "Rand detectie" -msgid "Clear all" -msgstr "Alles wissen" - msgid "Triangles" msgstr "Driehoeken" @@ -428,8 +425,11 @@ msgstr "Er is een onbekende uitzondering opgetreden in BambuStudio : %1%" msgid "Downloading Bambu Network plug-in" msgstr "" +msgid "Incorrect password" +msgstr "" + #, c-format, boost-format -msgid "Connect %s[SN:%s] failed!" +msgid "Connect %s failed! [SN:%s, code=%s]" msgstr "" msgid "" @@ -810,6 +810,9 @@ msgstr "Vergrendelen" msgid "Name" msgstr "Naam" +msgid "Fila." +msgstr "" + #, c-format, boost-format msgid "%1$d error repaired" msgid_plural "%1$d errors repaired" @@ -1104,6 +1107,9 @@ msgstr "" "Het rangschikken is mislukt. Er zijn enkele uitzonderingen gevonden tijdens " "het verwerken van het object." +msgid "Arranging" +msgstr "" + msgid "Arranging canceled." msgstr "Rangschikken geannuleerd." @@ -1627,13 +1633,6 @@ msgstr "" "Ja - Pas de instellingen aan en zet de vaas modus automatisch aan\n" "Nee - Pas de vaas modus deze keer niet toe" -msgid "" -"When recording timelapse without toolhead, it is recommended to add a " -"\"Timelapse Wipe Tower\" \n" -"by right-click the empty position of build plate and choose \"Add Primitive" -"\"->\"Timelapse Wipe Tower\".\n" -msgstr "" - msgid "" "Prime tower does not work when Adaptive Layer Height or Independent Support " "Layer Height is on.\n" @@ -2129,6 +2128,9 @@ msgstr "" "You can find it in \"Settings > Network > Connection code\"\n" "on the printer, as shown in the figure:" +msgid "Invalid input." +msgstr "" + msgid "Application is closing" msgstr "De toepassing wordt afgesloten" @@ -3502,6 +3504,13 @@ msgstr "Bewaar huidige %s" msgid "Delete this preset" msgstr "Verwijder deze voorinstelling" +msgid "" +"When recording timelapse without toolhead, it is recommended to add a " +"\"Timelapse Wipe Tower\" \n" +"by right-click the empty position of build plate and choose \"Add Primitive" +"\"->\"Timelapse Wipe Tower\".\n" +msgstr "" + msgid "Line width" msgstr "Lijn dikte" @@ -4581,6 +4590,12 @@ msgstr "Gebeid waarbinnen geprint kan worden" msgid "Bed exclude area" msgstr "Uitgesloten printbed gebied" +msgid "" +"Unprintable area in XY plane. For example, X1 Series printers use the front " +"left corner to cut filament during filament change. The area is expressed as " +"polygon by points in following format: \"XxY, XxY, ...\"" +msgstr "" + msgid "Elephant foot compensation" msgstr "\"Elephant foot\" compensatie" @@ -6488,6 +6503,12 @@ msgstr "Support: fix holes at layer %d" msgid "Support: propagate branches at layer %d" msgstr "Support: propagate branches at layer %d" +#~ msgid "Fragment area" +#~ msgstr "Fragment area" + +#~ msgid "Clear all" +#~ msgstr "Alles wissen" + #~ msgid "Creating" #~ msgstr "Creating" diff --git a/bbl/i18n/sv/BambuStudio_sv.po b/bbl/i18n/sv/BambuStudio_sv.po index 46ff2a97bac..064d4e3d458 100644 --- a/bbl/i18n/sv/BambuStudio_sv.po +++ b/bbl/i18n/sv/BambuStudio_sv.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: Bambu Studio\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-07-23 18:15+0800\n" +"POT-Creation-Date: 2022-07-27 15:03+0800\n" "PO-Revision-Date: \n" "Last-Translator: \n" "Language-Team: \n" @@ -52,8 +52,8 @@ msgstr "" msgid "Perform" msgstr "Perform" -msgid "Fragment area" -msgstr "Fragment area" +msgid "Gap area" +msgstr "" msgid "Set pen size" msgstr "Välj penn storlek" @@ -124,9 +124,6 @@ msgstr "Välj filament" msgid "Edge detection" msgstr "Kant detektering" -msgid "Clear all" -msgstr "Rensa allt" - msgid "Triangles" msgstr "Trianglar" @@ -425,8 +422,11 @@ msgstr "Bambu Studio har ett ohanterat undantag: %1%" msgid "Downloading Bambu Network plug-in" msgstr "" +msgid "Incorrect password" +msgstr "" + #, c-format, boost-format -msgid "Connect %s[SN:%s] failed!" +msgid "Connect %s failed! [SN:%s, code=%s]" msgstr "" msgid "" @@ -802,6 +802,9 @@ msgstr "Lås" msgid "Name" msgstr "Namn" +msgid "Fila." +msgstr "" + #, c-format, boost-format msgid "%1$d error repaired" msgid_plural "%1$d errors repaired" @@ -1084,6 +1087,9 @@ msgstr "" "Placering misslyckades. Avvikelser hittades när objektets geometri " "bearbetades." +msgid "Arranging" +msgstr "" + msgid "Arranging canceled." msgstr "Placering avbruten." @@ -1598,13 +1604,6 @@ msgstr "" "JA -Ändra dessa inställningar och möjliggör Spiral läge automatiskt\n" "NEJ -Avbryt Spiral läge denna gång" -msgid "" -"When recording timelapse without toolhead, it is recommended to add a " -"\"Timelapse Wipe Tower\" \n" -"by right-click the empty position of build plate and choose \"Add Primitive" -"\"->\"Timelapse Wipe Tower\".\n" -msgstr "" - msgid "" "Prime tower does not work when Adaptive Layer Height or Independent Support " "Layer Height is on.\n" @@ -2099,6 +2098,9 @@ msgstr "" "You can find it in \"Settings > Network > Connection code\"\n" "on the printer, as shown in the figure:" +msgid "Invalid input." +msgstr "" + msgid "Application is closing" msgstr "Begäran avslutas" @@ -3431,6 +3433,13 @@ msgstr "Spara nuvarande %s" msgid "Delete this preset" msgstr "Radera denna förinställning" +msgid "" +"When recording timelapse without toolhead, it is recommended to add a " +"\"Timelapse Wipe Tower\" \n" +"by right-click the empty position of build plate and choose \"Add Primitive" +"\"->\"Timelapse Wipe Tower\".\n" +msgstr "" + msgid "Line width" msgstr "Linjebredd" @@ -4484,6 +4493,12 @@ msgstr "Utskriftsbar yta" msgid "Bed exclude area" msgstr "Utesluten yta av byggplattan" +msgid "" +"Unprintable area in XY plane. For example, X1 Series printers use the front " +"left corner to cut filament during filament change. The area is expressed as " +"polygon by points in following format: \"XxY, XxY, ...\"" +msgstr "" + msgid "Elephant foot compensation" msgstr "Elefant fots kompensation" @@ -6323,6 +6338,12 @@ msgstr "Support: fix holes at layer %d" msgid "Support: propagate branches at layer %d" msgstr "Support: propagate branches at layer %d" +#~ msgid "Fragment area" +#~ msgstr "Fragment area" + +#~ msgid "Clear all" +#~ msgstr "Rensa allt" + #~ msgid "Creating" #~ msgstr "Creating" diff --git a/bbl/i18n/zh_cn/BambuStudio_zh_CN.po b/bbl/i18n/zh_cn/BambuStudio_zh_CN.po index f83ab5c5783..ff8885fd0cf 100644 --- a/bbl/i18n/zh_cn/BambuStudio_zh_CN.po +++ b/bbl/i18n/zh_cn/BambuStudio_zh_CN.po @@ -6,8 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: Slic3rPE\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-07-23 18:15+0800\n" -"PO-Revision-Date: 2022-07-22 13:28+0800\n" +"POT-Creation-Date: 2022-07-27 15:03+0800\n" +"PO-Revision-Date: 2022-07-27 15:05+0800\n" "Last-Translator: Jiang Yue \n" "Language-Team: \n" "Language: zh_CN\n" @@ -56,8 +56,8 @@ msgstr "缝隙填充" msgid "Perform" msgstr "执行" -msgid "Fragment area" -msgstr "碎片面积阈值" +msgid "Gap area" +msgstr "" msgid "Set pen size" msgstr "设置画笔大小" @@ -126,9 +126,6 @@ msgstr "选择耗材丝" msgid "Edge detection" msgstr "边沿检测" -msgid "Clear all" -msgstr "清除所有" - msgid "Triangles" msgstr "三角形" @@ -423,9 +420,12 @@ msgstr "Bambu Studio捕捉到一个未处理的异常:%1%" msgid "Downloading Bambu Network plug-in" msgstr "正在下载Bambu网络插件" +msgid "Incorrect password" +msgstr "" + #, c-format, boost-format -msgid "Connect %s[SN:%s] failed!" -msgstr "连接 %s[SN:%s]失败." +msgid "Connect %s failed! [SN:%s, code=%s]" +msgstr "" msgid "" "BambuStudio configuration file may be corrupted and is not abled to be " @@ -795,6 +795,9 @@ msgstr "锁定" msgid "Name" msgstr "名称" +msgid "Fila." +msgstr "耗材丝" + #, c-format, boost-format msgid "%1$d error repaired" msgid_plural "%1$d errors repaired" @@ -1055,6 +1058,9 @@ msgid "" "Arrange failed. Found some exceptions when processing object geometries." msgstr "自动摆放失败,处理对象几何数据时遇到异常。" +msgid "Arranging" +msgstr "" + msgid "Arranging canceled." msgstr "已取消自动摆放。" @@ -1543,15 +1549,6 @@ msgstr "" "是 - 自动调整这些设置并开启旋转模式\n" "否 - 暂不使用旋转模式" -msgid "" -"When recording timelapse without toolhead, it is recommended to add a " -"\"Timelapse Wipe Tower\" \n" -"by right-click the empty position of build plate and choose \"Add Primitive" -"\"->\"Timelapse Wipe Tower\".\n" -msgstr "" -"在录制无工具头延时摄影视频时,建议添加“延时摄影擦料塔”\n" -"右键单击构建板的空白位置,选择“添加标准模型”->“延时摄影擦料塔”。\n" - msgid "" "Prime tower does not work when Adaptive Layer Height or Independent Support " "Layer Height is on.\n" @@ -2047,6 +2044,9 @@ msgstr "" "你可以在打印机“设置->网络->连接->访问码\"\n" "查看,如下图所示:" +msgid "Invalid input." +msgstr "" + msgid "Application is closing" msgstr "正在关闭应用程序" @@ -3371,6 +3371,15 @@ msgstr "保存当前 %s" msgid "Delete this preset" msgstr "删除此预设" +msgid "" +"When recording timelapse without toolhead, it is recommended to add a " +"\"Timelapse Wipe Tower\" \n" +"by right-click the empty position of build plate and choose \"Add Primitive" +"\"->\"Timelapse Wipe Tower\".\n" +msgstr "" +"在录制无工具头延时摄影视频时,建议添加“延时摄影擦料塔”\n" +"右键单击构建板的空白位置,选择“添加标准模型”->“延时摄影擦料塔”。\n" + msgid "Line width" msgstr "线宽" @@ -4372,6 +4381,14 @@ msgstr "可打印区域" msgid "Bed exclude area" msgstr "不可打印区域" +msgid "" +"Unprintable area in XY plane. For example, X1 Series printers use the front " +"left corner to cut filament during filament change. The area is expressed as " +"polygon by points in following format: \"XxY, XxY, ...\"" +msgstr "" +"XY平面上的不可打印区域。例如,X1系列打印机在换料过程中,会使用左前角区域来切" +"断耗材丝。这个多边形区域由以下格式的点表示:“XxY,XxY,…”" + msgid "Elephant foot compensation" msgstr "象脚补偿" @@ -6057,6 +6074,16 @@ msgstr "支撑:正在修补层%d的空洞" msgid "Support: propagate branches at layer %d" msgstr "支撑:正在生长层%d的树枝" +#~ msgid "Fragment area" +#~ msgstr "碎片面积阈值" + +#~ msgid "Clear all" +#~ msgstr "清除所有" + +#, c-format, boost-format +#~ msgid "Connect %s[SN:%s] failed!" +#~ msgstr "连接 %s[SN:%s]失败." + #~ msgid "Printer firmware does not support material = >ams slot mapping." #~ msgstr "打印机固件不支持材料=>AMS槽位映射" diff --git a/resources/i18n/de/BambuStudio.mo b/resources/i18n/de/BambuStudio.mo index e43445e10874bfc638c32245c9f33107ce6109ea..108de07389b2d62bf036cc051f80d724b8885cfb 100644 GIT binary patch delta 36700 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 delta 36792 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

)*?)EALjr~!4t_}B+E@G&-h3Tlbxp$57L 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𝔛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 diff --git a/resources/i18n/en/BambuStudio.mo b/resources/i18n/en/BambuStudio.mo index 6d236e2dbc0ede545600182e61bd21ace5ee626c..1f3b317e0bea8a8ba7b4313d3c0dd2df8814b38e 100644 GIT binary patch delta 36401 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 I3|8# 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�+IbY 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 delta 36451 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 diff --git a/resources/i18n/fr/BambuStudio.mo b/resources/i18n/fr/BambuStudio.mo index 2b7d74b33a68f41d4b5f4d7db40286fe715775f5..9b8961369c2b354c9e443b395de0fca0a1110897 100644 GIT binary patch delta 36591 zcmZA91#}h1!-wHb2<}dh5CXvhK|+Aw7Tlq@ySqbK+}+*XA$W0@0>vp#af-VX_}<^0 z$#*#aJ!kuj?fC4y3D6NEVnqy(<=#%@Gu`1@8O?E0W6e;7TQw$lcSVOK1NTQDE~hs80^M8}DZz0eDXpwfq7Nj!#`9mjQIO>&%I5<)NvHp5uh z3Ugsstbj`~3}0am%re<=e6cRZ!S0v}2cbGT50l{vREPIs0z8H)cNL@4zVnViJQBX4 z8jdx^RFD*-5>IOlL^Tv-4Kc$^(}5wVa^p|~h_D{8 zo|(z~tAgt!XcIoe8t6OAG}sZ75g&)z3rkUJy&5y)HdM!Nqw0Bt8tF$Yi?L=qP5{y)ezehkle}mdwu@;#QWJYbCFdT?YFfHD}?)Vdf zu=`@i8H)>X6b3CZBj1YJ?FUgab_F#9_fVVq9mb)3=Mw>q#Am5llX$4}nHse;*)b&+ z#=ckw2jK-&$7(EdoZl742&}r?aXO&S3e(Z9*p>K0?18mc@;b&p(H%~p$||!tE@J@k z+o%S;R+}EDMs1p4jE05L4@;poZ*$a=^v2{k6g8uBZT?o&DLR3w=Z=lPT+RIJSVdi9 zDvph+C=qI{{4ge_$5@yhH6!^^&y_`$uZ${R4`X0s)N^f6GuaLG+)z~csi+sw!Zpml zdc1{%q<9K7^1Ie=s0Wg*H5CP*MjV0~VHxzrCaAUUXPt9- zyUtAcI@HvjL-p(m7Qm+%2QzRqG=f~#;;1RDhLf-j#>OwGO&oQDX)rzJARdaEiI%AR zUZ{b((+FrPH)05G!)Evtvth-J#=fWytUz^WJE{YRF$-SDoanR3G!%*&P-)bXR6@-} zE$oEtkoH{XZvvqt#NF&Txv?aMVJ{5AO_&#NVjfJ)%R=$8s3~_bHBQ4qxEVE|m#7iG z$9Nb&!le7*Na7hVkIw%(0=Y@Jhp8~hR#Px1>cPCIsSQVsyqdL<&2NtyX+P^=j8A+N zCc;^$4z5Mje*y#X0mjz(kG0M0?qsN4oDQ`{8L=FeLXBjCO<#@ah#$w&_!N_1&h2K? zg`+-{>SJPTj>_+i&vBg1@4JK9(})HWNQe_qJzj)rFal%YS?k}ZiXYhg=ho;uO@{+e z11N?XX*jChrl?)t9W&xQ)bTvLllj*JXGqYRUBHTX4U=KuF0%xMP#vpas#X!TXpM1NNHdDxn74#Oih=kd%aesB=2WI@=alf~s&M zrpFzq&2$3?<7?DXblbRIf=W@?k5c5i0X(iA{76pq?-HBoz^E@r`&s3n?++Kg+kIBr7Cz+2Q(enHg}lisGJ zeJ2HhLKuS0u?uPnFQK;=d*CP^G{pUmnJd5vS3CmiqWu@&F_e5i4U>qOHi9| zH3s1mRKrP5ndj12kd*{&jyxEEg|HMhMorl=R6|=)$LbG^g_lqj-a(!Bm#7i{ zhk7pVX)~}i=u12&s$6;0Qq?)l{Kq2Dodmsb2HK42s2SOW+Kh)$9lU|6=sv2U@2IJb z_ou1H-x`D(SYC{Q#ZVnBhw4}z)N^fI0xH1VLp87rHHF(y9eIzrG0qvsDS<`N zABUi(ekq3HVbn4Gf|)ShSu>!#SebY^EQ;y{>bDfTrRKYI8lY1%BX2;_?47=XfUS zbnHcK%5>+=h(b{fmqpdn0aedH%!1Rf9qz*(nB{_*nFSbA=RbmgD%^`Ia2|cI^hGlx z6|D79>FrTV)&;c}`q}hpsFBS^jeHGilWjxI@L#BzdyXm>MGtiWn zka*B_=07!o!X)@%J=8Ali@rD;Q(^?FV`otnK0?jd7gWWuZkWxO2=$&wfyz&di7_W? z=}Ou3a;S3kZZQ8*2s9-@BWa0hpofi*#5lxfV0&DO12O(hlRg186LYPrQ61WWYH+{x z2*xLV5;a4AV+xGs-eNQa(xNBfwkenvwaIc|Rt&=+Y=P>~ButI-aT@N%(pcq=`K*|M zir+@j(5F9_zlTCQDpBj$JVy zE=28_tEdJaq1OHr>balRI1hOX68A;bvk^4|M=%%dI~NF4M4v}yB-KzAHARiItxX?= zn&MeDz7|sw|HHu9L-_^4NQ0D8`UFah;A4{9cgqo$~aO>d3b zggtEfLex}8U^Lu^8qrakei7C1ZPX^dkE-_ts{Buz9_16aRvT?0od%Rd44$R`H85_J;%Bob;>Sadi?h(^Pho0{AVU34{Gfz zp+?jkwQ0KA^iimpT7VkSS`5Lx7>aLfex`rTb9pd~^a`kf4!4d+4Q#qgKvTUO)$lIV z$j+e}dW_m!?@>LE`rMTFLzT;ov9LU9%74R{SP!*1TcFmwJF3AEsP<-{I^?b)pbEBN zRNRYk@UZnS3?_aHqhOpDrhx>g=Tf3K2BIp=jA}3^#>JATj#NYK{wAmn_C)rA>$n7( zkT3$(z+=?Z{)-yncZ|TKFU@X0iK^%UYD8bGF<+UuuQdy5>B6j4t*xyCF+k^kI)NYx z?nG^h2bc|Gyfz<3p_rNYZ>UW+(7M=q#QGS!kRR)f8F7E>80&27D%7#vAwB2cCcLo5 zcx!%eNRRO;*wWh5I@~%Peflh+o*9jaaoT(4KL&wS zBg)uHI0%yCSJ>UaPuJqR_$p{S08VFE0INw5m$!xpGh zG7pR5GM7MH0uN9w3gXX9ms=fpctxSRZ$f;!jjk)hv9nEbGg47!!Qx?VyNe9;81LC z(;s69@vm3{gTHw`)?KG70W~}Y)!+iu$k$;Q?n8YFezqq6&&)_(R0qOP<%?kglWE;%@>Zbb^hxT(3-SFZI+JKe&|npq|IN2TAEF$-MbsLcg|un{D$gK zqaWs!w8T8bhuZi~%t-tSR>tq>Py0^ApJoIdQ5|q?e4LFhK#gQAYKr%uI&cm()%P(k zzC&%ctd5uGI2T2gYm6FTchsisj~Q?ny6W+20%~9rssjg6>1R>r_OeaCVSR$?$Olxp z82ogiJrWqa#V zv_(yAXH>;5s=;YCe+jCARhSyLVH&)E!T1`pVcKY3o;_0$HR4*RdK;r=qO)rQy-_1o zT&H0w>Vbu*5wF4^+<=<$>!>NehsE$Y=ELmKy*z&c+7bhaA4Uz}DJuU5=E1x%ygXlK z-Sz}(lQ0`q@C_!%Xfe%F_@UOiEUH8GQ6p%9It@Kg9Uh39>M^L1%|*@7Qq;gUVK^Q^ z%~-5ho{qRqCIUL24Xnpe73Pj@8Y+USure0LTBsSBhAKD5x&kK<--1`McpNWh8T!UG z9odI^?le}#^H@>mKOmkNNoUMVMqkv2&Jqm8&6pb>+w_$2%?Prfc6({mOw>U=*9;(*Rzp{7+kwD+ba4naPh@)j2-6Y&h^in(VspIwQSm_3 zX3UP-GkH)mP!Y8>^|3d$Mos-4)W{#Aj_IewoPSN-elfGw|G|zenvQ*C&PTF{(gn)aJ;58evgX z1$9wt*8=rmFVrh}B&q{zP~|pZar^`G;dj)j3iUNJ+6Xm(u1JSnrw;+WSVp4u!X)&@ zIjFUqkE(bHY6;e(mh2E}gy(Gf9ZW|2y-kmu(#%jQ)C(sBb-Jpe*1i!2>HN1Npb^hN zP4#Bfh%RF$yn$*kN-A?25}=MzZq!VaMRlw$s>7X74RuG=GZ;1Ek*InmpawKoah?Aa z1XN*!%{YnLe3wvb{1~-4f1*a5Dz$l~2BE$o6}9%Y=@HiBs1DsgjrcBV37@0t`GKDA z|MAk88OVwnaX4y8I->SOFN}f%Q7@z+s0x;#MzjSr;{B*4JY(~(qB{Nyd}inOjdHfKqwOu{YHT4nS1^8ArY2&x19QO9c-YLiVxP3;=Yf*VmC`x|v??pVK| z$|X)`o=<^VicF~TAua(;Ss3a&TuB@6hblM>wZ@Zd{1j?QuAnyGZPdtL+4xUvL_9%& znbFRu4iCT}oQm3f`%%xkrwDj9399FJZN^tDOFVXZFVEk0sfjuzConhOM~xs^2K(MX zy_z$iKBh~c1~dq@Bs;Jn9z|{T^no5-CyapBz6z?s1~%Rds}b*v>ghpTh!-#$cFXAH z)W?Mwg5OYIG;(C}^8ATON%U-1)Q8X#)GhLh9c-2`De9E8M$OD*)Qlet=KO2Z z-6TP~^dstXKW+{$&yQZ&FeC9ws0Vu3_(ar;WjpE|UqE&ED{777xXGZ62Id2kN$esG<01OiEjR)n8q zs5l!kNT*{_^K-!x67?d9TilDET=_E`)W{BCT|HOAY_cY(^etEsKVvftFKPDBDpdM8 zoP()L>EoXBw}XJb$=pD#)eqFBN)Ybl`Rh0NQJZiG*1*-MrTC7;Fjr|aW8JVj@r|fA zWco5@DQaOg;=NG=IfSEKesgK{Q)D{8mD!^;?-`9Fyd@c?eD z;N>jEE)`8YNhPz1FQe*BTG@=eCMv!d&*5EkUlQ0<#q@AtRWHxqN_m57D0?-t=25Df z-9G^JVi|`eaWZPkFJnwhRl^*=KvcN`=s6Xr51kUI7g8lu2Wr*e{A*KWtZ5#sfSURy zsPs`beLbqeL#T$1ThF6jI5$wo={f3)%6rs|eYW{YelraRqTaBNwM@f_umtf`SP&bb1~SJb zpazzq-rbu}Z^Rv_hR)mgZPW|ovo&dL^W88v>L;A?sCt^Crnobzfj+1X4nfV}6jVoN zqTZ5PF z2Xhf0jA|zWZ(~S9^X5#{h;%*Jfq+KP4b{_;s3{tUnt?f}9c4L#C z8?{$Tp~^Qz)z=+!U?0@+T!l?>U1QFFDFX4Dm~X8$up{v;m;wEpnm1WE>O*NbYEK+O zt@<h_f^^4dp_0I4^2oB~g2-9IE40t<6v!?9t3M$88J=I=9PE4QxYId;(R`U#JSM zpl0fc&Hs+t3sIY!CCY*-Uk3fLl8tvlJ>LUW{|MA(ob3`&!>g>jtf#CuPz9f(D)@$) z(zq?m$P%GO?2CGFWkemv0;pGSc~paytWD6fBsT8$A)p4vqB=4MwaM0^8a$5rlKD4k zDt%fSW24qGku@2r!IY>5(xA!**mxFeuuTs^HnHmzAfUA_X*1fOM${R{-~d!dqPH^V z+ZQ#Wrl@45!FsJ^ql`T1hm=up(+}J zDmWH3rHfHhy$sdhDpW_dV<1C6hV_X*Z)@_)wlf2$g~dp3i26RU0Q2ETtboDoIscmK zegrgyBT-W~8nfYg)JU$QK9t^|Iug5s*(>p}9C3fFhwV@=vZJW;{uA{xVUCVwNh_h= zfb~!V=-H9;uLg&cpjYr})W{=j!IP*Nd4SpjFHoEGC#r%3oy=7FTQi~tl+DJ&tVL0u zj^U_*RzuBfjZU0@t#K_9^yaFM$+3qmI1V+U3D_M^pni%i)Y*)D4r%}ourkKzVrHl| zs)O}WOV%DWqkU0(ZH0B4OF+l%2#&zJsI_X{)ohymsLgi)H3PR$o9`8B&&26w@{^!C zo)$HO`B3#%vgvJ6&kaUx#s#PsnY)>Q9yo@6coQ|EZ`QQk&CdrVQKzCKs^K2i0jL=q zhI&to#yq$cgYhY9%~SL+U*AKp7x9hAfLteIPxEy-KdNW#tplx-QA@K7RpDOLXT)>V z($wo^Ht96f9$Jf<;%%50kDxmI4Yir0^fvXS#AZ7GAq4b-n1Py-Q>d@Wcd!xq^|3D& zRQ_aafh$m(Ep}hCxl*7S&R`8e<(IHlL3OYJmcmw8QlHCf31}p*Y=JEO%uIx!j!$XS zo2`Yl4`v}g&br-t7c-C^tH0?`4%E^VM4g&qm=3F<2GSi}P3x1eU|FlvS_TVJ5w{ZWT`ITJB6&cK~G4XX?{ zKh8hEd&EbKFdc5=j`VVdlkgaaV#iVDQ|}GVB0gZWmopcWjxlSx8TBIBi(1QPs7)4U ztm(Kfs^h^Jgn3ctz8PwBy6BG+Fi`Q0HsLaA1RqhG&3Bx6A7n=@Nk!CVs)1^-4yvJ+ zs5f0l)J*-3nxUySf4R+Hk9vMDYH1H4d&70k5YU=kMNR!D)Vn&)cr(Q*tT|B)ltpc# zMyRFhiz+`I_5N6lTAHoskAI@-e__+(PB0w|L|>i%e4YTu0zEGv)G-=}`*0~1#by)D zh?k%`vIYy_0o303hMKuJlZ^hTC!5Ck*V={<(3%uL zjUXK7U|lSQ@2z3e&F_K+Vj0qpqh4I`XPESISe^J3tcwp(Gg)+|*^Dhv`IAuX-k-_& z_b2d-1ob%fER*4nH;HG$O6W7&d`48qOvHzyHs5;G)NeyQe+;#RH&9FT(&qcjG4&?3 zrbg|d^m91>Dp-UBKdg!V*d4RuG}LZCWIcykikp}R|G^fRe6Fc*0Hz~86ZMMTh58J+ zkN#L^kcSXo?P@dX{dnsW3BY1o^EkP~Qb7VL_aY+FX}W zOY{}haP%c+h5}I^LSZ-ttD-t^12wSw=%@4ljzDP=5-l}fi|eAMYB`p{qo}otyUe^o zlUp;Q_CP4=h0_l8+z`~rmst1M^eb3`^pB{4ge~XT(!NuIKn@&-s%Q_YhnG;B^8xzf zSJZ>4R+tWDK)q^%QR&4{^^`*`XqB7%0ZsjK)Ecit zjd%yDfrHo(FQTR}*J|^z8-`7YH$ipaAm+nUsNL_q#{6C}8>*gx_!%dmmS*%?&VNw? zi`IHM4e%~%mls}V&UIDPIc@j?I$lFj$8jd=+weMUi+|x#EU?kb^N-eUV*`$B$R_h6*rd(o z51XFjbjr2Z!p{Tbe?@itM}+w-iL=%GXjaiBpa#dI8eDAMjvC2n)JX25Hr2nV@=>>$ z5%{9g{jCL1pX)VIA5Q&H&u_E&du{$zo9=!mpb?WW!yo4F?Evf?FohF_eRZ(3` zhpkYXYZU6aEvT9L3)Rsl=&1*FdVF`8nazQ!rxa?FS3}Rg|7qX}P%&y(c0qMuq;(PM zfnBJP9I;+Qjr=**!0+gf)pnbY+iqB!_)=7dzM+;T;1Bcb__FBv`#;kOXm_qb?e@E< z7t1%SgE{w@^E(=~%a@}%xDD0ev#94D+PJgV%usUF5*9}-X<5`8wHE5Q4nbEV8%sc6 zp=O}sOHd80M?H89HIpeAbtS@uJuT0e4)sDkHx^az0`$@6|4IVt(K^%! zwqhwfi<;`hXPE((rWk4sTbwh;a15$LbFd<=vVK5ysKj69W4H<)CEfw`A(#8S`81t~ z4QStaL7*v?zhE-fq1HCmMYAOSs3ppZnyIo_6+5F&$pO?z@1r*Hd(@staLG)45!_3> zJnB6W2>4@l)bZ(#deQVjH8=`Y@kUIGr%@ICi|H`h74xy08I@iGwd*^f z@|U7E<5AR-T}9RN=nCgw8PTqq5u`wEx-6)QilLUIKB`<#)EjK1&5uB>=~>ha-9v58 zpI8)gT{HD|MGbTaYN=Nhy`a{izLXxZ@u#R6^txf5%Zz%%7DsiwqDw%>qA^CpmZ*w4pk`v2O`nT8$4hMb z4%D0NENTERFdToPzWasWG$U+=8gVyN{rzlwu#LN;38+VtP*Xk^bv(AC-Us__{3NQQ z7f`$Y8fw!$LT%Phm>c8XGM|RUP)j!r&*KKnhl6gL=XWB{yUsBJda+zZO;z+eW(k5Z zn0Pf*#e-~m1Zp#0L2cHzs29{Ho1f~gnc5<#O;!!7VOP{KJ&c;M1ozaA%jYqH(jYmeHjE^5ZsqLyM8Y7ZSmKiYS$ z6VL-+P*WE7zG*lU>bMj^b*vIcv~ETd~9AY)iE3Kk*H(374^b-W{va2#DlF>aWeVc zP>E!#dl#&w3xVXJR}vBdcOSjw^+s!nnQ*9eEow7f#6WzF1u)rjFV8Ey8fGEh4OQeMW?>AO+K_#~=B zpHaup`=yt2UFSau0rl_|7Qra5j3uxz@xj*ps1bih?TPfSO}rv%&AXv?`!rMs7NQ#5 zjvBxL)C=qkdcIGf=l6eC31~{+U`>qo#*C;rHYMH-^`^UI(;uSN?mcQIeBPQ0eNiv6 zG^qM2S=*szU?i%Z?HGo~rOvUjrLk9(nx;Q-XJ9Ev(t6HzagC8!Z@ z!pgW8hhd!eW{D=FmSzs>xrL~XZ$Wn^f#U@9q0{(-`2}HbY)E`7X2V1uO#?+y4OT?0 zVLdE?9WX0yL=E6N>V@+aHGuD^&z2~k%PP;buGpE&=TlHW-fiW5*%nCP=9Py#jL zI;a_Ff!b{CQP1^5y|Bij)_wzOX?CIZ%1P9odWGFE_=}m5#i-AWHD5UYc?g^(LAyQ5 zSM${=9o8pa1xw;u)QDf9Hka2oGoloz83{pks5okhtD{~pEm5atFc!zTsF}Wn+Qc7R z0{#U2{xefm6t(u@sHv}lp0!7vlA)*>nTdK|EJaQ6TGY&JwjQvaL(R->8-I%a#6P2! z!1euZMw|mRB@IziI2g65CZpc<3s9S82j;{-F$;c2jWp8_^GocKsE+kRt@#kt49rK> zvja7tzmVr#=PH4WB)r3`nDVFjvzxa#%!`h&mEvMFZ*R}kC5htgsURC_Dnn2oHWg4a z&<-^teNhd&sN*;rwZz*o7%yQqef~%BF%RZMjl3vojjN!RqLsA^Y6<$G)_4MHY8RtM zv<~xP1ZoDJp=R(cYA^l7Dp)_Nx94=N#Xz0^n9;mF@Aw>8hInn%JAEM*#Ov4tlSTLT zyy?bT*Q4^!p*kEphPUUH9Do`~5UPU(QJb_hro)=3f%QUHn_v(Djcf+iz%{53p&wWo z)5rAo{0g<3^*d@xN5wKzy&N^-wOAG-P%oVSP#y7#ZA^$4h^NDREb05$-mde8gluum z68Ob4Bgl@LnY`E%x1&aoI=;8(*knbGxCW|&?XVE;vgsdDrzdU#vj+;GW}+slLyb{O z*g1jg?K#&&Y=LQ5jEse--Fp|cIlm#h)d@&w9xQ^2S3|w=I-+J^JZhIuM{TkVI0kQ_ z-VbdOnZ42%b^Zsr1oQ@5jjG^JRE3vN9e9uGY5c_A&K(Ruy(ztumUk6NOciQ#_C-zUMAVe8LRECc zre8rl_sZsfLcJFfr!XA}LJg!cszbGHyeTHpE^9|XQ|+P}oP%X?6Y5R(1#@9mUvJNc zQv+1`I8?{>Vs^ZOS~{PUrojxT7gKhOhZRvvP#@J^UrbB;&NKpgr*B2|@Br#Ko_iVN5PZ=tL6ULdu%=Qkb` zP!(K6P3a5N=KFx^K#Vk|g9*`_cq&xGey9#-MKxFi)$w+ykq*L4I2ZL9a~L%fkJE7e zwTYtone&nk7V_C&4@~nped?|+U+$^BX430c1Lw|tW95!>gWN~_lMi4O`JHLNiTqEpbl2T zE?5rtp^jgS08=ilOF&ay7`3azQOBn?s)Bx~nV5o_$_=QgJc-&XZ%|9~&BlGwn;D3Q zYN#}7-uokK#6R;nyL3KDV&~zjps)NN* zFPsLbjx|GnY>)cP7>DY}YUDGo>ybUjfW8H-xd6_^#*qh|UVYH!@d)H?q^38-M|%;tEdM}0`-LQQdTn_dB{5U-2c ze5+AYyVIthK{cEviy3)-)G;iMnyGrIJ=Fn+p^Hg%{(Z8VsZWW8iRVF$xEuQ87*x;K zqK;1ls=}+-7@y)wEEi;!?hO_vo+6tWSUuDXHAO9L2dsfp(Jf8jF#&Cs;OyR>ugT%4 zDcXtJ^;c0Zo-e45L=QGI5Fc9*_d`wnP<)BAF%(DTFrR+=P%~F9r&;RRs1EGP$@$lt zEN(7u&%b=ghnliySPY}&Hk+mt1`=1n;Q{h>>hsxiS z#~izzn2Y$8Je>dB1Y(4mgo3DeN7VUVgj%zGs9k*?wdPk*A5zcJ(*e|yMayf_{jeDE z99Rmwpia*=^wfjeb5~sg+GMwF#uMvH)YQL6^*mWVb8P%j4dq7df%4cM8`%64sHMD# znY{Q`jp|^kF!Q070X2Y*sB-QQ0`&>ZMosAl)K{sX0%lXTu?|5!Fb}miBG4Z%pf=Sz z)b3AN(8NPgBW{41u#b%|LcMSHAbZAj?wEk{!5X`ex92aDrbE4u2H-NBfqJlDVQ z^`;Sq6W@yJ&{x#4^(|sLmIbx9%A-2o1HEx9YBNv3I6D9H2xyI0qt<*6s^ROXseg}6 z@IM@g4U2kv{)yI2Tui)gG4uJKs<=76<#09WBe5CgD&g(J3UK!J2iFw zrxMU{c!IOBP$~1R_X>7UJlu?AHR@aKMbr{GrOnI~MjgX{a0Qkrq9$|BwSk-LKci5VE<7#HWoX{vMnHATIvn})7qMdHzFczgcBU=8#q9>1n} z^W{XnA8KNL?1*)61*(HTZ9KqR?Pew5O&~YM$57OpEnMj|Pz&=AuiM(p z)C3G8z801K(59zsW8Q4}P%oIm7zeAP-UE$MpPK#A2ghJqo&Sjhv;-SbJ^T}OUazA+ zzQI6D)YcrE{1`yI7V5dam>6fEHt!nb#p0Yq4d@PP&%8ptdSkRRZ_aoaSLffKKx{IC zu@M$PZK~O*SLa*Q$LBZHh@!POBT9^V1?ND0EEh+8(P)X8aT2D(UFeTDP|yE|syAi_ zUi~`%i3n)QQ=@vA9rfW5f_k+Uu<1=v9c_)Os5@#62ca4sg=#RureC(+Le0cO)DJEn zYm9t~Pxr>Qiza>O*D)*2aUVSG8{!(_jdC5wC(; zf@-Mzel~v^YQ{EU8Qj^0^Iw*L)0N`{ zoB^o4Pz<$HEl^Y61-0gbP%}Lmbs8qQ1o9JDh}sL+FgZi0)7{(i&uY8$Fg<>O`q21* zswiLu{;h!?Tyo@4u3=qC`KFv|J+Llb z!5Nsdx3}kSI3Guy|Jr@bhsik9Ox{FwG_bFELzYBM`A$?j2T)6S)X2a8C7@mZH)=E8 zL2a&&sPi4apBX_m)Cg*$^4p>+9)hZH3}(P-sONUs{41zke;fTVet)wBInnd`zkD{K z1*W4wd(>2pN4;3qp+6o#ReaCJe_&qXX$P3EWVKKu?}U1zjzg{WMATZ(Kz(&vj@mPO z(MN0k7XdYV+4@Nt#C?A^>3*mRilKIM6;wlQQKx4lYIDv<&B#^j9n?}jw*HIi*eg{1 zZ_#u9KiPyI)+hr_&tssbHa=>T`r3GPREHYiT5ON%SaMEN9n6Iq&=}MVtV1u1K%K5_ zsJ(OB<@~Fn#DmPoXaJTY-o?5b)nlK*<_#GgwO3N0M(Std8Bs5$Y^Ws*Lw!b6LhYF@ zsAD?>gK#`*uk9L4PqZd~kszO-)}H@!nCFTxKB}E3DTCKH_tRAO()2SO8d`j z2NeI80;?$4g+lkKY@e;XJn=T9dz0UfupZ%$3!U=hXXdU=XYY`Ag>W&-@oM0IPR9wM zTz1NBB9A|D@%#_UvfK9Nk~f6?=lLlm1)2J4{lRAb&I3bWOGX>XOrotruXZ9RN=I&NhO#w2i@Lg~pUMu8z%0<)4n znDA)sb>!D2K8Et)i?ojd~uacBcOI|4D{v;el zfB&i$mFxP8#Oox!r@%qd^kGxclS40w=Otg)AC%Dt&0G6i72+caU%~Zyo{s6#*YNv< zE8roXokiMH$}OQo`d817X~(nwPEz2St^74f18l{YDZp1gCk79^#E+yG^*qE2iwZ{D zh6?k%uJM%HgRv>|k-Ysj{XgOjc{T%e%(3mL{6Rgh^IwPpH_6z+J&8MxtvE5^8{DO+ z_#E;_h0bv9^OV;|vaT#t>`z`^%FHL7zxd$%ZX4cDJ)cR_MG?<;$@B#D0^3h|HFPr& zI76TXx2{|~oQnqs5Z0@+D*3Z*hxQV#PX0U9X0JLle3VYCAnh1=MF{Jos~ZtcH;h0?k=6X&OML(xs-27>0Xr4)ytMk;`#UYBn+Uj=-ida z$V1^6_?Cxo^lA@QM2j;Sr=Y=59fF59R*hj=Yl7&|;p;kGe!o;(?wR zKepLf`Ij_Z_qnf8Zw~Gn+;OSvy65j-lF?3?B%CGVD`8!md9b5>_!)WeXyFX`-lP>G zT%1m=C!Pf(%p*=^((@4isxqXNr4yTZwk_dyq<0~_3jMjS^Xv(||IgT-+B%$n3CyP8 zEYh=6NLLl^nN-@!cIYtqeF=wPc?{O@?KOz!rjj0ct)sEpMBY)C7iAZ6FOSTpeTP5z zb~4&dRJ9Ebw*~aIOV>T(>A7Q)uP+wAUK4q~o9zI9r^J~|nfx>oc^#zgXg2>J@`~Gx zW0Y}&e<>LGz;4n$5}C){&vqmu6&K;wb)I_w>C33>C1uA_c@M(60!UwDpD`)C=WXNF zZJEe)be%Fb^Ar{Bp}-^_u1iCy2p=NN%QiX%Gm)pCj#Ai)u8|*ww1@xGU>(vI+A?YE z^J+8^>E(#$Q_HkF+4KG-l7YgRxnEF`w|!6#>>&Q9t$ZpEj^UvrR5FHeQ>OJSWk!)U z)eb_>WVcKCjCz6y$ENI5!qX_@&$E%&bUmZ>&qLxU+h}eYE6MFkT4x^2M*3MQxk0%R zJdoQ~zJ>hBlq+m&Yf9b{(zf$V- z;$61uQhmlt{2C$J%rXkHY8to?|P>{mw zDDjSa3%ywcaW%>1?=bB;bX+x|Z z;oGFg#yEQaUnB7(l|){pY+x~IhbdTrigk_Tf$z4_x3)rkt}eFW*n|TKm%?+npXVm> z+_uQFgop5acH2Qe%AMCYo8=@{wTVS3w2HLa+|O;N_|=_Lk#H=Gytb0hZ(H~u3iJ9# ze!1nuqM-opw6?)U6s|z{2W3~{4O?F)o_R?8Anm&S34~H$35JlNpU)=XH{#JqkG%LR zT+UO{W>U#Q^2^X*Gcr?>rYjoxPsqDOd@N2RUsr144asX|8xJS#GxfG0ek!UH;QU3T z7Zo<*fl-8CBR{G;HMv(&_|nw#y%XzyaqG0Ds<_-uD7{p5bM^eCixHIhNq$A1tWEXh zxtCDp8tD&gxzg4zo~QYQpsw$PmvfhV42@fUQ zgo<@lCM_3tODZ@{-ruBWHCfJLTjs5ekD^R`$}Fd1U3rKn;vUHJx;Aq^rxU?E*Mx8! z!hZTS!9^l1Z12C?!s$rsO+|iG@DJh0D~NJGXyh^XW^P?~NsCFj$ZI?eEU@teHZdw? zmXel=`uB5BqD&3aT$jKE0@KK>Vtd}4icj(2G5c^5+bKosaS!5|Qk1WQxFj?6xyFpVh|56qq0B@QRTmk z_&+M&NjxF>-N^GHKA*6zJft_L!tR9m)u%I?^eL1XK|QZXpN{b;|B$>&+`1+apGjUL z%6Z0L+h!akdV<7mWcH%aXexV39>1S+;@dKx@sOV5%0=aMC>Kik$ZI5lzp0}=&LV#i z%EP-ulEKly>9!h*G`4_o;Y`GZJ zl$i8(+^KnH(=X$FM4qnJJUfp3449bKezH(WacFtN?PRAnT9sff%dks6~tfJk?*o;{65-q zm9}w3&T&_vTmUvAJp;a@Q{AcGk2-W^@63N9AR`CydBk-cBCcyZdCPgA1mT?IJs_T$M*gJYTZDCe z=DtnZ@1!NQ9jHKBQtG%vn%*n-a1Ckg37@1s&uT5AKvV7%Q@^{(-F$=^kaZtZQ*5HG zev(Sts}*|DjR>mKHPurUuPM^b(ezxNjl3F@R*(2M$_%5f7vzs4^D=22i3gA$c?IZ~ z6zNDfLd9_@P#oVx=He9|-o-LLr(zTSjc0!n_N+$@Dw$28ljb?+0B$Gk6$R>|=a<%`bs@glR<5Ee2zRy>ucN~I zlub>eVch$O>$*+aA?_rUy-C_G>gY~6-J;scSX{5)wOxID4RI)mlP{$N4D0ByP zEu?|PwnH@ur)D;i{Zer-<;K}*+(3Fpo;}T-pD=&Y=ehduT;w&MvMqmkUg>4@ONv%B z(u+t9?oU(@z@3|dTd3p<;q9cy$AVNafO`vZT^Go&z}=XP!VTObY+kvkn};TLCzJB)m5eH~P~s-(G3}Fg zZGpK|U7!4l)ViEIn7bThzLI{OGRb+aAXc=`H6>ryWz54}!lo-NA@Sb&s2k5iJ!q_} zQvc_=Zo8V&J~*6mg}GxBkB8N$B#7I`mK#A@al()6e00PO-0P`#Cgt+c(ZM+5|2x7$ zJtT8C87XZg$tlo|yFTgdsW21i1-R#vwwkm`n2JiL+eS!oGV{Ey*_87oy*mv|qg+D5 zQMn7+x>cqu>5*4g{WSUORg264ws&(0Z?F%pC0xfA{F}zs{8HgO8t6(q8TSdo^=$(m zh(}QNHEs0aE=2lw{7F5PD7S*J=S+?xP?bB59mP?MPbcP6!9WV?T1vh@>Cs7VjLo>` zlJ*ysHpOPP(+f;-CpFLRBHWtvFO=CsJO_6X;%RZBDepQ(9Lr>w3Oq`l&cFX2{r?PF_3vH#DsB|`EUJy^D2DrEVQjeZ5$@8~qP}gwsXVBR#+#k7H z67Qn*?`bP+z{9n;2a@?O*0dvigg2?61m)Ti9!ogCeWp2;6rgN%%*Y+xrUz4pu0^D! zB0R^|Wm5TyK-wZAZZrEp5)#(hLQ`y77YfWHEfEd;N4OIfz?>L)y(IjeGRa8z&8ANw zoQP59AicWn$X((;s5d%k<+w*tHl5D@3EP+|tfl{OO|}(vz}DRNdEhA(JtJ=q;a{%_ zq@SjazkjKxAdRiHb+on}xWsd}N&AC`E80BI{(n#8ZywN9p6OalMNduCnMphj@rA@o zQ6?JU7nHw@JE?FwX(8OLNc%*Y!juoQbv?mGG~SMKdAYrKCbMn0G~sdN7j|vovSb8N z!4Tq8xEB-NXL~-La2nF~P-YShB;eux*poZ*s!rNz8}TQ-qYWS7nZe}!L0u_rT0Y`O z2>Vf|=U)?N<$+oBa5xD)xgU@j4VO^x7U5v-AGR}Zun_6G+EDpGo?F9Bai&b;|XuX_V$6uil0+{8tE-5cZED38a_>$u9(&Wq?aSU zmAqfC={%=v2zO7d|5Pd&#zW0`;1h*^kkOB{L8xmH;q;7nBaX5UKPSCBcL~a0AiXr< z1an(sGa&#J!!gOqAV5dWh|?%03{k_b<=ppaZ)}_q5-_797Td zJ1MwAPuOcZY2Fl`@JnT@DN~cQC^juAjTW($|4UjW@=|es`=voucZ%myaz|eOcsmg} hCNv3%n7!$rOcA56#n`iB!8ETNAv}_e`<=aW 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≠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 delta 36699 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 To8na}*Y9Pvojm9jWApz5%R6hM diff --git a/resources/i18n/sv/BambuStudio.mo b/resources/i18n/sv/BambuStudio.mo index 10b9685dc0478f1eaf6284e94c83cb3e1daf1bc5..bc064bcfb9764dfb7c7cecb451c1d5fe34e406b5 100644 GIT binary patch delta 36339 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 PbUg{$RXozweg6Ld4RTQ- delta 36421 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 delta 36857 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 mTQ#~adptj}uXr;*p6 z2#3-pDe0WY_{Y~{6p0r!yhf}j>F-I$#OPM1869;SU%h{5l)0p8GE|fC?fR$ipHi=l zO`?nq_O(y_c78jto-AZ4ExsN{iB;$9^EH4Gtd9ZI`<*^R8MlSC38noIE00UO8}(Ze zyP~f;hv=vuXACM2qf&S(ETTdu&hO~xgDoHjc^xS@e6kc=zE)E2KJ~KsYQR>^rNQ?Urse#4tRZoV@&*=L zNe8v5t0NP3we+uaq~kmDA?e1PLpfj3ehu{ol3qhU2^c(_)oVb^?@b^P1yAU_J_Ye< z@ZY1q4blt;Q8$dbx2U&{N~y>%C4YpotF5#uv0y?M z&-LF&pdf*@3~-F#ALQ5KZ5os!mXvfK(nUD`;nb0t&XY07_ozQl=$K4C5&5c||B(Nc zKC=+}fpkyW&9OnhkgiPZ??9es_*W_wAlQU~<8eNrgO}vHQ(+NhL#X_OypA@u8~M$< z)~U*p6I)IFy_{iIzXyqWYDjLVtR8V+W#6`aM19p)UzS&6d8bf%*h`LD+c z()FmTz^BfU@XJeg(IStAO2Gnq%$2}RzwRLoAj>D2k> zKkp{`H8*7&`8w{%FoIK2qlx{xj-zqD_1Pu{bBOqJGpF$+^MW48&8EouR+M z)W1ue*tF5n12baRK#p}-ygF^}kRD3?3pkqcJ+u!|edcP1hSk49$eW3ZM<_f(r8?tN z4iC-RmSJ?{wPhS6e}h^%seJ)c3Gj%>T>2L_6PZ` zobgC+R3S$q+AX78M?~5tq+JHm?@33dY#yWBwOQ=4K0D$R>XaltmGYgz{2Q<>X)u^T zWxPtTClxkhVJw34a3$v&>P(`8SEwV!_?*9n`q3<>NIIscBMKJaY|VLuUUO3CI`J&z zn{#fo>AWR&hb0_TBaW&TZ)+-+h4OTke@8wSedXrN!+Boc+uy4e$6i%rFdYLKM8`O$ zzr-5HwV2`!Xk3~4Q7MnbS&DY|tZfm>_EV=j=Vi_ml-DHIkovheb8bGvUXN4K7F;Jd^cxq z$~xn}^ygXmRborYuHr0NnaXJ?m`sJ@4A_zU6w>=_uma?>Q1R>0hQ>M?Q8zy6hy3&( z>Sv>tj-*6}&~h8+Bl0!KN2DwlJ#Hp8iu|9L6PsEawL9{4YNTr`U`Kk}g0K0H)cc9P z+S5m5oJ>BycJX&II_?u#N5`?K5W*lj%97TR$_7cJhU6bw{txQcBR0bFK{l}@xRAE5 zaX1s1WO4Nsp1Ko>%_sI+pWLr)kYDL24h6Nzf1vO?i+^G=!Q^w`TM8pL%Bwb*Uy>!?B>#VIS#d6ax{CfgCq5)Y=IJe*f3>r1SFwfz_UNBpB2=O-$R zq_YT|S#A4wlRjw!($2e2ooeLub)yS)=28A5b|9XHw2q&wtTq0{;$uw^Vd9Bw;bLhjEUb$|HKhcoBiU$pAslwo)KZ`=6orl6*sHg?V&ye-!M00?#uMF0Q* diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 905d33295a3..17dec6b1921 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -264,8 +264,8 @@ void PrintConfigDef::init_common_params() //BBS: add "bed_exclude_area" def = this->add("bed_exclude_area", coPoints); def->label = L("Bed exclude area"); - def->tooltip = L("Bed exclude area that can't used as printable area in X-Y plane. For example, the bottom left area which is used to cut filament in X1 when printing multi colors with AMS. " - "The area is expressed as polygon by points in following format: \"XxY, XxY, ...\""); + def->tooltip = L("Unprintable area in XY plane. For example, X1 Series printers use the front left corner to cut filament during filament change. " + "The area is expressed as polygon by points in following format: \"XxY, XxY, ...\""); def->mode = comAdvanced; def->gui_type = ConfigOptionDef::GUIType::one_string; def->set_default_value(new ConfigOptionPoints{ Vec2d(0, 0) }); From 89959400daf62faef972c07f5eb8e85361767e4a Mon Sep 17 00:00:00 2001 From: "salt.wei" Date: Wed, 27 Jul 2022 16:01:28 +0800 Subject: [PATCH 035/180] ENH: separate PA and PA-CF filament type Filament type of Bambu PA-CF in RFID is PA-CF. Change it to PA-CF as well in preset to avoid failure of AMS mapping. Signed-off-by: salt.wei Change-Id: Ic6b6269123d59863fea2b7d262a124468c95b8af --- resources/profiles/BBL.json | 2 +- resources/profiles/BBL/filament/Bambu PA-CF @base.json | 3 +++ resources/profiles/BBL/filament/Generic PA-CF.json | 3 +++ .../profiles/BBL/machine/Bambu Lab X1 0.4 nozzle.json | 2 +- .../BBL/machine/Bambu Lab X1 Carbon 0.2 nozzle.json | 2 +- .../BBL/machine/Bambu Lab X1 Carbon 0.4 nozzle.json | 2 +- .../BBL/machine/Bambu Lab X1 Carbon 0.6 nozzle.json | 2 +- .../BBL/machine/Bambu Lab X1 Carbon 0.8 nozzle.json | 2 +- src/libslic3r/Print.cpp | 1 + src/libslic3r/PrintConfig.cpp | 7 ++++--- 10 files changed, 17 insertions(+), 9 deletions(-) diff --git a/resources/profiles/BBL.json b/resources/profiles/BBL.json index f73da522ab5..736e4c08fad 100644 --- a/resources/profiles/BBL.json +++ b/resources/profiles/BBL.json @@ -1,7 +1,7 @@ { "name": "Bambulab", "url": "http://www.bambulab.com/Parameters/vendor/BBL.json", - "version": "01.01.00.11", + "version": "01.01.00.13", "force_update": "0", "description": "the initial version of BBL configurations", "machine_model_list": [ diff --git a/resources/profiles/BBL/filament/Bambu PA-CF @base.json b/resources/profiles/BBL/filament/Bambu PA-CF @base.json index 99f8c876519..34c84203cbf 100644 --- a/resources/profiles/BBL/filament/Bambu PA-CF @base.json +++ b/resources/profiles/BBL/filament/Bambu PA-CF @base.json @@ -17,6 +17,9 @@ "nozzle_temperature_initial_layer": [ "280" ], + "filament_type": [ + "PA-CF" + ], "nozzle_temperature": [ "280" ] diff --git a/resources/profiles/BBL/filament/Generic PA-CF.json b/resources/profiles/BBL/filament/Generic PA-CF.json index 887e63a44d7..aaaa07bfff0 100644 --- a/resources/profiles/BBL/filament/Generic PA-CF.json +++ b/resources/profiles/BBL/filament/Generic PA-CF.json @@ -6,6 +6,9 @@ "from": "system", "instantiation": "true", "inherits": "fdm_filament_pa", + "filament_type": [ + "PA-CF" + ], "nozzle_temperature_initial_layer": [ "280" ], diff --git a/resources/profiles/BBL/machine/Bambu Lab X1 0.4 nozzle.json b/resources/profiles/BBL/machine/Bambu Lab X1 0.4 nozzle.json index 5db555c6259..b82ede4af8b 100644 --- a/resources/profiles/BBL/machine/Bambu Lab X1 0.4 nozzle.json +++ b/resources/profiles/BBL/machine/Bambu Lab X1 0.4 nozzle.json @@ -19,7 +19,7 @@ "18x28", "0x28" ], - "machine_start_gcode": "\n;===== date: 202200714 =====================\n;===== reset machine status =================\nM17 X1.2 Y1.2 Z0.75 ; reset motor current to default\nM960 S5 P1 ; turn on logo lamp\nG90\nM220 S100 ;Reset Feedrate\nM221 S100 ;Reset Flowrate\nM73.2 R1.0 ;Reset left time magnitude\nM1002 set_gcode_claim_speed_level : 5\n\n;===== heatbed preheat ====================\nM1002 gcode_claim_action : 2\n{if bbl_bed_temperature_gcode}\nM1002 set_heatbed_surface_temp:[bed_temperature_initial_layer_vector] ;config bed temps\nM140 A S[bed_temperature_initial_layer_single] ;set bed temp\nM190 A S[bed_temperature_initial_layer_single] ;wait for bed temp\n{else}\nM140 S[bed_temperature_initial_layer_single] ;set bed temp\nM190 S[bed_temperature_initial_layer_single] ;wait for bed temp\n{endif}\n\n{if scan_first_layer}\n;=========register first layer scan=====\nM977 S1 P60\n{endif}\n\n=============turn on fans to prevent PLA jamming=================\n{if filament_type[initial_tool]==\"PLA\"}\n {if (bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}\n M106 P3 S180\n {elsif (bed_temperature[current_extruder] >50)||(bed_temperature_initial_layer[current_extruder] >50)}\n M106 P3 S255\n {endif};Prevent PLA from jamming\n{endif}\nM106 P2 S100 ; turn on big fan ,to cool down toolhead\n\n;===== prepare print temperature and material ==========\nM104 S[nozzle_temperature_initial_layer] ;set extruder temp\nG91\nG0 Z2 F1200\nG90\nG28 X\nM975 S1 ; turn on \nG1 X60 F12000\nG1 Y245\nG1 Y265 F3000\nM620 M\nM620 S[initial_tool]A ; switch material if AMS exist\n M109 S[nozzle_temperature_initial_layer]\n G1 X120 F12000\n\n G1 X20 Y50 F12000\n G1 Y-3\n T[initial_tool]\n G1 X54 F12000\n G1 Y265\n M400\nM621 S[initial_tool]A\n\nM412 S1 ; ===turn on filament runout detection===\n\nM109 S250 ;set nozzle to common flush temp\nM106 P1 S0\nG92 E0\nG1 E50 F200\nM400\nM104 S[nozzle_temperature_initial_layer]\nG92 E0\nG1 E50 F200\nM400\nM106 P1 S255\nG92 E0\nG1 E5 F300\nM109 S{nozzle_temperature_initial_layer[initial_extruder]-20} ; drop nozzle temp, make filament shink a bit\nG92 E0\nG1 E-0.5 F300\n\nG1 X70 F9000\nG1 X76 F15000\nG1 X65 F15000\nG1 X76 F15000\nG1 X65 F15000; shake to put down garbage\nG1 X80 F6000\nG1 X95 F15000\nG1 X80 F15000\nG1 X165 F15000; wipe and shake\nM400\nM106 P1 S0\nM975 S1\n;===== prepare print temperature and material end =====\n\n\n;===== wipe mouth ===============================\nM1002 gcode_claim_action : 14\nM975 S1\nM106 S255\nG1 X65 Y230 F18000\nG1 Y264 F6000\nM109 S{nozzle_temperature_initial_layer[initial_extruder]-20}\nG1 X100 F18000 ; first wipe mouth\n\nG0 X135 Y253 F20000 ; move to exposed steel surface edge\nG28 Z P0 T300; home z with low precision,permit 300deg temperature\nG29.2 S0 ; turn off ABL\nG0 Z2 F20000\n\nG1 X60 Y265\nG92 E0\nG1 E-0.5 F300 ; retrack more\nG1 X100 F5000; second wipe mouth\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X90 F5000\nG0 X128 Y261 Z-1.5 F20000 ; move to exposed steel surface and stop the nozzle\nM104 S140 ; set temp down to heatbed acceptable\nM106 S255 ; turn on fan (G28 has turn off fan)\n\nG0 X126 F120\nG0 X130\nG0 X126\nG0 X130\nG0 X128\nM109 S140 ; wait nozzle temp down to heatbed acceptable\nG1 Z10 F1200\nG1 F30000\nG1 X230 Y15\nG29.2 S1 ; turn on ABL\n;G28 ; home again after hard wipe mouth\nM106 S0 ; turn off fan , too noisy\n;===== wipe mouth end ================================\n\n\n;===== bed leveling ==================================\nM1002 judge_flag g29_before_print_flag\nM622 J1\n\n M1002 gcode_claim_action : 1\n G29 A X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]}\n M400\n M500 ; save cali data\n\nM623\n;===== bed leveling end ================================\n\n;===== home after wipe mouth============================\nM1002 judge_flag g29_before_print_flag\nM622 J0\n\n M1002 gcode_claim_action : 13\n G28\n\nM623\n;===== home after wipe mouth end =======================\n\nM975 S1 ; turn on vibration supression\n\n;===== check scanner clarity ===========================\nM972 S5 P0 \nM400 S1\n;===== check scanner clarity end =======================\n\n=============turn on fans to prevent PLA jamming=================\n{if filament_type[initial_tool]==\"PLA\"}\n {if (bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}\n M106 P3 S180\n {elsif (bed_temperature[current_extruder] >50)||(bed_temperature_initial_layer[current_extruder] >50)}\n M106 P3 S255\n {endif};Prevent PLA from jamming\n{endif}\nM106 P2 S100 ; turn on big fan ,to cool down toolhead\n\n{if scan_first_layer}\n;start heatbed scan====================================\nM976 S2 P1 \n{endif}\n\nM104 S{nozzle_temperature_initial_layer[initial_extruder]} ; set extrude temp earlier, to reduce wait time\n\n;===== mech mode fast check============================\nG1 X128 Y128 Z5 F20000\nM400 P200\nM970.3 Q1 A7 B30 C80 H15 K0\nM974 Q1 S2 P0\n\nG1 X128 Y128 Z5 F20000\nM400 P200\nM970.3 Q0 A7 B30 C90 Q0 H15 K0\nM974 Q0 S2 P0\n;===== fmech mode fast check============================\n\n\n;===== noozle load line ===============================\nM975 S1\nG90 \nM83\nT1000\nG1 X18.0 Y5.0 Z0.3 F18000;Move to start position\nM109 S{nozzle_temperature[initial_extruder]}\nG0 E3 F300\nG0 X240 E15 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \nG0 Y5.5 \nG0 X18 E15\nM400\n\n;===== draw extrinsic para cali paint =================\nM1002 judge_flag extrude_cali_flag\nM622 J1\n\n M1002 gcode_claim_action : 8\n\n T1000 \n G0 F3000 X28.000 Y19.500 Z0.200\n G1 F1200.0 X28.000 Y45.000 Z0.200 E0.933 \n G1 F1200.0 X28.500 Y45.000 Z0.200 E0.018 \n G1 F1200.0 X28.500 Y19.500 Z0.200 E0.933 \n G1 F1200.0 X31.000 Y19.500 Z0.200 E0.091 \n G1 F1200.0 X31.000 Y49.000 Z0.200 E1.080 \n G1 F1200.0 X37.500 Y49.000 Z0.200 E0.238 \n G1 F1200.0 X37.500 Y60.000 Z0.200 E0.403 \n G1 F1200.0 X42.500 Y60.000 Z0.200 E0.183 \n G1 F1200.0 X42.500 Y49.000 Z0.200 E0.403 \n G1 F1200.0 X48.000 Y49.000 Z0.200 E0.201 \n G1 F1200.0 X48.000 Y20.000 Z0.200 E1.061 \n G1 F1200.0 X30.000 Y20.000 Z0.200 E0.659 \n G1 F1200.0 X30.000 Y41.000 Z0.200 E0.769 \n G1 F1200.0 X50.000 Y41.000 Z0.200 E0.732 \n G1 F1200.0 X50.000 Y34.000 Z0.200 E0.256 \n G1 F1200.0 X30.000 Y34.000 Z0.200 E0.732 \n G1 F1500.000 E-0.800 \n\n ;=========== extruder cali extrusion ================== \n T1000 \n M83 \n\n ;G0 X18 Y28 F20000\n ;G0 Y0\n ;G0 Z0.3\n ;G0 X250 E18 F{outer_wall_volumetric_speed/(0.3*0.5) * 60}\n ;G0 Y0.5\n ;G0 X18 E18 F{outer_wall_volumetric_speed/(0.3*0.5) * 60}\n\n G0 X35.000 Y18.000 Z0.300 F30000 E0\n G1 F1500.000 E0.800 \n M106 S0 ; turn off fan\n G0 X185.000 E9.35441 F{outer_wall_volumetric_speed/(0.3*0.5) * 60}\n G0 X187 Z0\n G1 F1500.000 E-0.800 \n G0 Z1\n G0 X180 Z0.3 F18000\n \n M900 L1000.0 M1.0\n M900 K0.040 \n G0 X45.000 F30000 \n G0 Y20.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E1.24726 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60}\n G1 X70.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X75.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X80.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X85.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X90.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X95.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X100.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X105.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X110.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X115.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X120.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X125.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X130.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X135.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X140.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X145.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X150.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X155.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X160.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X165.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X170.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X175.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X180.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 F1500.000 E-0.800 \n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n M400\n\n G0 X45.000 F30000 \n M900 K0.020 \n G0 X45.000 F30000 \n G0 Y22.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E1.24726 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60}\n G1 X70.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X75.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X80.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X85.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X90.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X95.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X100.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X105.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X110.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X115.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X120.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X125.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X130.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X135.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X140.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X145.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X150.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X155.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X160.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X165.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X170.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X175.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X180.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 F1500.000 E-0.800 \n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n M400\n\n G0 X45.000 F30000 \n M900 K0.000 \n G0 X45.000 F30000 \n G0 Y24.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E1.24726 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60}\n G1 X70.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X75.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X80.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X85.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X90.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X95.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X100.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X105.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X110.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X115.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X120.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X125.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X130.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X135.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X140.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X145.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X150.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X155.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X160.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X165.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X170.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X175.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X180.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 F1500.000 E-0.800\n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n\n G0 X45.000 F30000 ; move to start point\n\nM623 ; end of \"draw extrinsic para cali paint\"\n\nM104 S140\n\n\n;=========== laser and rgb calibration =========== \nM400\nM18 E\nM500 R\n\nM973 S3 P14\n\nG1 X120 Y5.0 Z0.3 F18000.0;Move to first extrude line pos\nT1100\nG1 X143.0 Y5.0 Z0.3 F18000.0;Move to first extrude line pos\n\nM400 P100\n\nM960 S1 P1\nM400 P100\nM973 S6 ; use auto exposure by xcam\nM960 S0 P0\n\n;=========== handeye calibration ======================\nM1002 judge_flag extrude_cali_flag\nM622 J1\n\n M973 S3 P1 ; camera start stream\n M400 P500\n M973 S1 \n G0 F6000 X40.000 Y54.500 Z0.000 \n M960 S0 P1\n M973 S1\n M400 P800\n M971 S6 P0\n M973 S2 P16000\n M400 P500 \n G0 Z0.000 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P1 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P200 \n M971 S5 P3 \n G0 Z0.500 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P2 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P500 \n M971 S5 P4 \n M963 S1 \n M400 P1500 \n M964 \n T1100 \n G0 F6000 X40.000 Y54.500 Z0.000 \n M960 S0 P1\n M973 S1\n M400 P800\n M971 S6 P0\n M973 S2 P16000\n M400 P500 \n G0 Z0.000 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P1 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P200 \n M971 S5 P3 \n G0 Z0.500 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P2 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P500 \n M971 S5 P4 \n M963 S1 \n M400 P1500 \n M964 \n T1100 \n G1 Z3 F3000 \n\n M400\n M500 ; save cali data\n\n M104 S{nozzle_temperature[initial_extruder]} ; rise nozzle temp now ,to reduce temp waiting time.\n\n T1100 \n M400 P400 \n M960 S0 P0\n G0 F30000.000 Y22.000 X65.000 Z0.000\n M400 P400 \n M960 S1 P1 \n M400 P50 \n\n M969 S1 N3 A2000 \n G0 F360.000 X181.000 Z0.000\n M980.3 A70.000 B{outer_wall_volumetric_speed/(1.75*1.75/4*3.14)*60/4} C5.000 D{outer_wall_volumetric_speed/(1.75*1.75/4*3.14)*60} E5.000 F175.000 H1.000 I0.000 J0.020 K0.040\n M400 P100 \n G0 F20000\n G0 Z1 ; rise nozzle up\n T1000 ; change to nozzle space\n G0 X45.000 Y16.000 F30000 ; move to test line pos\n M969 S0 ; turn off scanning\n M960 S0 P0\n\n\n G1 Z2 F20000 \n T1000 \n G0 X45.000 Y16.000 F30000 E0\n M109 S{nozzle_temperature[initial_extruder]}\n G0 Z0.3\n G1 F1500.000 E3.600 \n G1 X65.000 E1.24726 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60}\n G1 X70.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X75.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X80.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X85.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X90.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X95.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X100.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X105.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X110.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X115.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X120.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X125.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X130.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X135.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60}\n\n ; see if extrude cali success, if not ,use default value\n M1002 judge_last_extrude_cali_success\n M622 J0\n M400\n M900 K0.02 M{outer_wall_volumetric_speed/(1.75*1.75/4*3.14)*0.02}\n M623 \n\n G1 X140.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X145.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X150.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X155.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X160.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X165.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X170.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X175.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X180.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X185.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X190.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X195.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X200.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X205.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X210.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X215.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X220.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X225.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n M973 S4 \n\nM623\n\n;========turn off light and wait extrude temperature =============\nM1002 gcode_claim_action : 0\nM973 S4 ; turn off scanner\nM400 ; wait all motion done before implement the emprical L parameters\n;M900 L500.0 ; Empirical parameters\nM109 S[nozzle_temperature_initial_layer]\nM960 S1 P0 ; turn off laser\nM960 S2 P0 ; turn off laser\nM106 S0 ; turn off fan\nM106 P2 S0 ; turn off big fan \nM106 P3 S0 ; turn off chamber fan\n\nM975 S1 ; turn on mech mode supression\nG90 \nM83\nT1000\nG1 X128.0 Y253.0 Z0.2 F6000.0;Move to start position\nM109 S{nozzle_temperature_initial_layer[initial_extruder]}\nG0 X253 E6.4 F{outer_wall_volumetric_speed/(0.3*0.6) * 60} \nG0 Y128 E6.4\nG0 X252.5\nG0 Y252.5 E6.4\nG0 X128 E6.4", + "machine_start_gcode": "\n;===== date: 202200726 =====================\n;===== reset machine status =================\nG91\nM17 Z0.3 ; lower the z-motor current\nG0 Z7 F300 ; lower the hotbed , to prevent the nozzle is below the hotbed\nG90\nM17 X1.2 Y1.2 Z0.75 ; reset motor current to default\nM960 S5 P1 ; turn on logo lamp\nG90\nM220 S100 ;Reset Feedrate\nM221 S100 ;Reset Flowrate\nM73.2 R1.0 ;Reset left time magnitude\nM1002 set_gcode_claim_speed_level : 5\n\n;===== heatbed preheat ====================\nM1002 gcode_claim_action : 2\n{if bbl_bed_temperature_gcode}\nM1002 set_heatbed_surface_temp:[bed_temperature_initial_layer_vector] ;config bed temps\nM140 A S[bed_temperature_initial_layer_single] ;set bed temp\nM190 A S[bed_temperature_initial_layer_single] ;wait for bed temp\n{else}\nM140 S[bed_temperature_initial_layer_single] ;set bed temp\nM190 S[bed_temperature_initial_layer_single] ;wait for bed temp\n{endif}\n\n{if scan_first_layer}\n;=========register first layer scan=====\nM977 S1 P60\n{endif}\n\n=============turn on fans to prevent PLA jamming=================\n{if filament_type[initial_tool]==\"PLA\"}\n {if (bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}\n M106 P3 S180\n {elsif (bed_temperature[current_extruder] >50)||(bed_temperature_initial_layer[current_extruder] >50)}\n M106 P3 S255\n {endif};Prevent PLA from jamming\n{endif}\nM106 P2 S100 ; turn on big fan ,to cool down toolhead\n\n;===== prepare print temperature and material ==========\nM104 S[nozzle_temperature_initial_layer] ;set extruder temp\nG91\nG0 Z2 F1200\nG90\nG28 X\nM975 S1 ; turn on \nG1 X60 F12000\nG1 Y245\nG1 Y265 F3000\nM620 M\nM620 S[initial_tool]A ; switch material if AMS exist\n M109 S[nozzle_temperature_initial_layer]\n G1 X120 F12000\n\n G1 X20 Y50 F12000\n G1 Y-3\n T[initial_tool]\n G1 X54 F12000\n G1 Y265\n M400\nM621 S[initial_tool]A\n\nM412 S1 ; ===turn on filament runout detection===\n\nM109 S250 ;set nozzle to common flush temp\nM106 P1 S0\nG92 E0\nG1 E50 F200\nM400\nM104 S[nozzle_temperature_initial_layer]\nG92 E0\nG1 E50 F200\nM400\nM106 P1 S255\nG92 E0\nG1 E5 F300\nM109 S{nozzle_temperature_initial_layer[initial_extruder]-20} ; drop nozzle temp, make filament shink a bit\nG92 E0\nG1 E-0.5 F300\n\nG1 X70 F9000\nG1 X76 F15000\nG1 X65 F15000\nG1 X76 F15000\nG1 X65 F15000; shake to put down garbage\nG1 X80 F6000\nG1 X95 F15000\nG1 X80 F15000\nG1 X165 F15000; wipe and shake\nM400\nM106 P1 S0\nM975 S1\n;===== prepare print temperature and material end =====\n\n\n;===== wipe mouth ===============================\nM1002 gcode_claim_action : 14\nM975 S1\nM106 S255\nG1 X65 Y230 F18000\nG1 Y264 F6000\nM109 S{nozzle_temperature_initial_layer[initial_extruder]-20}\nG1 X100 F18000 ; first wipe mouth\n\nG0 X135 Y253 F20000 ; move to exposed steel surface edge\nG28 Z P0 T300; home z with low precision,permit 300deg temperature\nG29.2 S0 ; turn off ABL\nG0 Z2 F20000\n\nG1 X60 Y265\nG92 E0\nG1 E-0.5 F300 ; retrack more\nG1 X100 F5000; second wipe mouth\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X90 F5000\nG0 X128 Y261 Z-1.5 F20000 ; move to exposed steel surface and stop the nozzle\nM104 S140 ; set temp down to heatbed acceptable\nM106 S255 ; turn on fan (G28 has turn off fan)\n\nG0 X126 F120\nG0 X130\nG0 X126\nG0 X130\nG0 X128\nM109 S140 ; wait nozzle temp down to heatbed acceptable\nG1 Z10 F1200\nG1 F30000\nG1 X230 Y15\nG29.2 S1 ; turn on ABL\n;G28 ; home again after hard wipe mouth\nM106 S0 ; turn off fan , too noisy\n;===== wipe mouth end ================================\n\n\n;===== bed leveling ==================================\nM1002 judge_flag g29_before_print_flag\nM622 J1\n\n M1002 gcode_claim_action : 1\n G29 A X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]}\n M400\n M500 ; save cali data\n\nM623\n;===== bed leveling end ================================\n\n;===== home after wipe mouth============================\nM1002 judge_flag g29_before_print_flag\nM622 J0\n\n M1002 gcode_claim_action : 13\n G28\n\nM623\n;===== home after wipe mouth end =======================\n\nM975 S1 ; turn on vibration supression\n\n;===== check scanner clarity ===========================\nM972 S5 P0 \nM400 S1\n;===== check scanner clarity end =======================\n\n=============turn on fans to prevent PLA jamming=================\n{if filament_type[initial_tool]==\"PLA\"}\n {if (bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}\n M106 P3 S180\n {elsif (bed_temperature[current_extruder] >50)||(bed_temperature_initial_layer[current_extruder] >50)}\n M106 P3 S255\n {endif};Prevent PLA from jamming\n{endif}\nM106 P2 S100 ; turn on big fan ,to cool down toolhead\n\n{if scan_first_layer}\n;start heatbed scan====================================\nM976 S2 P1 \n{endif}\n\nM104 S{nozzle_temperature_initial_layer[initial_extruder]} ; set extrude temp earlier, to reduce wait time\n\n;===== mech mode fast check============================\nG1 X128 Y128 Z5 F20000\nM400 P200\nM970.3 Q1 A7 B30 C80 H15 K0\nM974 Q1 S2 P0\n\nG1 X128 Y128 Z5 F20000\nM400 P200\nM970.3 Q0 A7 B30 C90 Q0 H15 K0\nM974 Q0 S2 P0\n\nG1 F30000\nG1 X230 Y15\nG28 X ; re-home XY \n;===== fmech mode fast check============================\n\n\n;===== noozle load line ===============================\nM975 S1\nG90 \nM83\nT1000\nG1 X18.0 Y5.0 Z0.3 F18000;Move to start position\nM109 S{nozzle_temperature[initial_extruder]}\nG0 E3 F300\nG0 X240 E15 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \nG0 Y5.5 \nG0 X18 E15\nM400\n\n;===== draw extrinsic para cali paint =================\nM1002 judge_flag extrude_cali_flag\nM622 J1\n\n M1002 gcode_claim_action : 8\n\n T1000 \n G0 F3000 X28.000 Y19.500 Z0.200\n G1 F1200.0 X28.000 Y45.000 Z0.200 E0.933 \n G1 F1200.0 X28.500 Y45.000 Z0.200 E0.018 \n G1 F1200.0 X28.500 Y19.500 Z0.200 E0.933 \n G1 F1200.0 X31.000 Y19.500 Z0.200 E0.091 \n G1 F1200.0 X31.000 Y49.000 Z0.200 E1.080 \n G1 F1200.0 X37.500 Y49.000 Z0.200 E0.238 \n G1 F1200.0 X37.500 Y60.000 Z0.200 E0.403 \n G1 F1200.0 X42.500 Y60.000 Z0.200 E0.183 \n G1 F1200.0 X42.500 Y49.000 Z0.200 E0.403 \n G1 F1200.0 X48.000 Y49.000 Z0.200 E0.201 \n G1 F1200.0 X48.000 Y20.000 Z0.200 E1.061 \n G1 F1200.0 X30.000 Y20.000 Z0.200 E0.659 \n G1 F1200.0 X30.000 Y41.000 Z0.200 E0.769 \n G1 F1200.0 X50.000 Y41.000 Z0.200 E0.732 \n G1 F1200.0 X50.000 Y34.000 Z0.200 E0.256 \n G1 F1200.0 X30.000 Y34.000 Z0.200 E0.732 \n G1 F1500.000 E-0.800 \n\n ;=========== extruder cali extrusion ================== \n T1000 \n M83 \n\n ;G0 X18 Y28 F20000\n ;G0 Y0\n ;G0 Z0.3\n ;G0 X250 E18 F{outer_wall_volumetric_speed/(0.3*0.5) * 60}\n ;G0 Y0.5\n ;G0 X18 E18 F{outer_wall_volumetric_speed/(0.3*0.5) * 60}\n\n G0 X35.000 Y18.000 Z0.300 F30000 E0\n G1 F1500.000 E0.800 \n M106 S0 ; turn off fan\n G0 X185.000 E9.35441 F{outer_wall_volumetric_speed/(0.3*0.5) * 60}\n G0 X187 Z0\n G1 F1500.000 E-0.800 \n G0 Z1\n G0 X180 Z0.3 F18000\n \n M900 L1000.0 M1.0\n M900 K0.040 \n G0 X45.000 F30000 \n G0 Y20.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E1.24726 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60}\n G1 X70.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X75.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X80.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X85.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X90.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X95.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X100.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X105.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X110.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X115.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X120.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X125.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X130.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X135.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X140.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X145.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X150.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X155.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X160.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X165.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X170.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X175.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X180.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 F1500.000 E-0.800 \n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n M400\n\n G0 X45.000 F30000 \n M900 K0.020 \n G0 X45.000 F30000 \n G0 Y22.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E1.24726 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60}\n G1 X70.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X75.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X80.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X85.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X90.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X95.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X100.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X105.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X110.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X115.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X120.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X125.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X130.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X135.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X140.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X145.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X150.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X155.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X160.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X165.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X170.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X175.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X180.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 F1500.000 E-0.800 \n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n M400\n\n G0 X45.000 F30000 \n M900 K0.000 \n G0 X45.000 F30000 \n G0 Y24.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E1.24726 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60}\n G1 X70.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X75.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X80.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X85.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X90.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X95.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X100.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X105.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X110.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X115.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X120.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X125.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X130.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X135.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X140.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X145.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X150.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X155.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X160.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X165.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X170.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X175.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X180.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 F1500.000 E-0.800\n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n\n G0 X45.000 F30000 ; move to start point\n\nM623 ; end of \"draw extrinsic para cali paint\"\n\nM104 S140\n\n\n;=========== laser and rgb calibration =========== \nM400\nM18 E\nM500 R\n\nM973 S3 P14\n\nG1 X120 Y5.0 Z0.3 F18000.0;Move to first extrude line pos\nT1100\nG1 X143.0 Y5.0 Z0.3 F18000.0;Move to first extrude line pos\n\nM400 P100\n\nM960 S1 P1\nM400 P100\nM973 S6 ; use auto exposure by xcam\nM960 S0 P0\n\n;=========== handeye calibration ======================\nM1002 judge_flag extrude_cali_flag\nM622 J1\n\n M973 S3 P1 ; camera start stream\n M400 P500\n M973 S1 \n G0 F6000 X40.000 Y54.500 Z0.000 \n M960 S0 P1\n M973 S1\n M400 P800\n M971 S6 P0\n M973 S2 P16000\n M400 P500 \n G0 Z0.000 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P1 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P200 \n M971 S5 P3 \n G0 Z0.500 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P2 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P500 \n M971 S5 P4 \n M963 S1 \n M400 P1500 \n M964 \n T1100 \n G0 F6000 X40.000 Y54.500 Z0.000 \n M960 S0 P1\n M973 S1\n M400 P800\n M971 S6 P0\n M973 S2 P16000\n M400 P500 \n G0 Z0.000 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P1 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P200 \n M971 S5 P3 \n G0 Z0.500 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P2 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P500 \n M971 S5 P4 \n M963 S1 \n M400 P1500 \n M964 \n T1100 \n G1 Z3 F3000 \n\n M400\n M500 ; save cali data\n\n M104 S{nozzle_temperature[initial_extruder]} ; rise nozzle temp now ,to reduce temp waiting time.\n\n T1100 \n M400 P400 \n M960 S0 P0\n G0 F30000.000 Y22.000 X65.000 Z0.000\n M400 P400 \n M960 S1 P1 \n M400 P50 \n\n M969 S1 N3 A2000 \n G0 F360.000 X181.000 Z0.000\n M980.3 A70.000 B{outer_wall_volumetric_speed/(1.75*1.75/4*3.14)*60/4} C5.000 D{outer_wall_volumetric_speed/(1.75*1.75/4*3.14)*60} E5.000 F175.000 H1.000 I0.000 J0.020 K0.040\n M400 P100 \n G0 F20000\n G0 Z1 ; rise nozzle up\n T1000 ; change to nozzle space\n G0 X45.000 Y16.000 F30000 ; move to test line pos\n M969 S0 ; turn off scanning\n M960 S0 P0\n\n\n G1 Z2 F20000 \n T1000 \n G0 X45.000 Y16.000 F30000 E0\n M109 S{nozzle_temperature[initial_extruder]}\n G0 Z0.3\n G1 F1500.000 E3.600 \n G1 X65.000 E1.24726 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60}\n G1 X70.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X75.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X80.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X85.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X90.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X95.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X100.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X105.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X110.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X115.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X120.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X125.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X130.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X135.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60}\n\n ; see if extrude cali success, if not ,use default value\n M1002 judge_last_extrude_cali_success\n M622 J0\n M400\n M900 K0.02 M{outer_wall_volumetric_speed/(1.75*1.75/4*3.14)*0.02}\n M623 \n\n G1 X140.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X145.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X150.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X155.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X160.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X165.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X170.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X175.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X180.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X185.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X190.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X195.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X200.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X205.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X210.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X215.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X220.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X225.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n M973 S4 \n\nM623\n\n;========turn off light and wait extrude temperature =============\nM1002 gcode_claim_action : 0\nM973 S4 ; turn off scanner\nM400 ; wait all motion done before implement the emprical L parameters\n;M900 L500.0 ; Empirical parameters\nM109 S[nozzle_temperature_initial_layer]\nM960 S1 P0 ; turn off laser\nM960 S2 P0 ; turn off laser\nM106 S0 ; turn off fan\nM106 P2 S0 ; turn off big fan \nM106 P3 S0 ; turn off chamber fan\n\nM975 S1 ; turn on mech mode supression\nG90 \nM83\nT1000\nG1 X128.0 Y253.0 Z0.2 F6000.0;Move to start position\nM109 S{nozzle_temperature_initial_layer[initial_extruder]}\nG0 X253 E6.4 F{outer_wall_volumetric_speed/(0.3*0.6) * 60} \nG0 Y128 E6.4\nG0 X252.5\nG0 Y252.5 E6.4\nG0 X128 E6.4", "machine_end_gcode": "M400 ; wait for buffer to clear\nG92 E0 ; zero the extruder\nG1 E-0.8 F1800 ; retract\nG1 Z{max_layer_z + 1.0} F900 ; lower z a little\nG1 X65 Y245 F12000 ; move to safe pos \nG1 Y265 F3000\n\nM17 S\nM17 Z0.5 ; lower z motor current to reduce impact if there is something in the bottom\n{if (max_layer_z + 100.0) < 250}\n G1 Z{max_layer_z + 100.0} F900\n{else}\n G1 Z250 F900\n{endif}\nM400 P100\nM17 R ; restore z current\n\nG1 X65 Y245 F12000\nG1 Y265 F3000\nM140 S0 ; turn off bed\nM106 S0 ; turn off fan\nM106 P2 S0 ; turn off remote part cooling fan\nM106 P3 S0 ; turn off chamber cooling fan\n\nG1 X100 F12000 ; wipe\n; pull back filament to AMS\nM620 S255\nG1 X20 Y50 F12000\nG1 Y-3\nT255\nG1 X65 F12000\nG1 Y265\nG1 X100 F12000 ; wipe\nM621 S255\nM104 S0 ; turn off hotend\n\nG90\nG1 X128 Y250 F3600\n\nM220 S100 ; Reset feedrate magnitude\nM201.2 K1.0 ; Reset acc magnitude\nM73.2 R1.0 ;Reset left time magnitude\nM1002 set_gcode_claim_speed_level : 0", "scan_first_layer": "1", "machine_load_filament_time": "17", diff --git a/resources/profiles/BBL/machine/Bambu Lab X1 Carbon 0.2 nozzle.json b/resources/profiles/BBL/machine/Bambu Lab X1 Carbon 0.2 nozzle.json index 7252de98fc3..b192c1f23e3 100644 --- a/resources/profiles/BBL/machine/Bambu Lab X1 Carbon 0.2 nozzle.json +++ b/resources/profiles/BBL/machine/Bambu Lab X1 Carbon 0.2 nozzle.json @@ -26,6 +26,6 @@ "retraction_minimum_travel": [ "5" ], - "machine_start_gcode": "\n;===== date: 202200710 =====================\n;===== reset machine status =================\nM17 X1.2 Y1.2 Z0.75 ; reset motor current to default\nM960 S5 P1 ; turn on logo lamp\nG90\nM220 S100 ;Reset Feedrate\nM221 S100 ;Reset Flowrate\nM73.2 R1.0 ;Reset left time magnitude\nM1002 set_gcode_claim_speed_level : 5\n\n;===== heatbed preheat ====================\nM1002 gcode_claim_action : 2\n{if bbl_bed_temperature_gcode}\nM1002 set_heatbed_surface_temp:[bed_temperature_initial_layer_vector] ;config bed temps\nM140 A S[bed_temperature_initial_layer_single] ;set bed temp\nM190 A S[bed_temperature_initial_layer_single] ;wait for bed temp\n{else}\nM140 S[bed_temperature_initial_layer_single] ;set bed temp\nM190 S[bed_temperature_initial_layer_single] ;wait for bed temp\n{endif}\n\n{if scan_first_layer}\n;=========register first layer scan=====\nM977 S1 P60\n{endif}\n\n=============turn on fans to prevent PLA jamming=================\n{if filament_type[initial_tool]==\"PLA\"}\n {if (bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}\n M106 P3 S180\n {elsif (bed_temperature[current_extruder] >50)||(bed_temperature_initial_layer[current_extruder] >50)}\n M106 P3 S255\n {endif};Prevent PLA from jamming\n{endif}\nM106 P2 S100 ; turn on big fan ,to cool down toolhead\n\n;===== prepare print temperature and material ==========\nM104 S[nozzle_temperature_initial_layer] ;set extruder temp\nG91\nG0 Z2 F1200\nG90\nG28 X\nM975 S1 ; turn on \nG1 X60 F12000\nG1 Y245\nG1 Y265 F3000\nM620 M\nM620 S[initial_tool]A ; switch material if AMS exist\n M109 S[nozzle_temperature_initial_layer]\n G1 X120 F12000\n\n G1 X20 Y50 F12000\n G1 Y-3\n T[initial_tool]\n G1 X54 F12000\n G1 Y265\n M400\nM621 S[initial_tool]A\n\nM412 S1 ; ===turn on filament runout detection===\n\nM109 S250 ;set nozzle to common flush temp\nM106 P1 S0\nG92 E0\nG1 E50 F200\nM400\nM104 S[nozzle_temperature_initial_layer]\nG92 E0\nG1 E50 F200\nM400\nM106 P1 S255\nG92 E0\nG1 E5 F300\nM109 S{nozzle_temperature_initial_layer[initial_extruder]-20} ; drop nozzle temp, make filament shink a bit\nG92 E0\nG1 E-0.5 F300\n\nG1 X70 F9000\nG1 X76 F15000\nG1 X65 F15000\nG1 X76 F15000\nG1 X65 F15000; shake to put down garbage\nG1 X80 F6000\nG1 X95 F15000\nG1 X80 F15000\nG1 X165 F15000; wipe and shake\nM400\nM106 P1 S0\nM975 S1\n;===== prepare print temperature and material end =====\n\n\n;===== wipe mouth ===============================\nM1002 gcode_claim_action : 14\nM975 S1\nM106 S255\nG1 X65 Y230 F18000\nG1 Y264 F6000\nM109 S{nozzle_temperature_initial_layer[initial_extruder]-20}\nG1 X100 F18000 ; first wipe mouth\n\nG0 X135 Y253 F20000 ; move to exposed steel surface edge\nG28 Z P0 T300; home z with low precision,permit 300deg temperature\nG29.2 S0 ; turn off ABL\nG0 Z2 F20000\n\nG1 X60 Y265\nG92 E0\nG1 E-0.5 F300 ; retrack more\nG1 X100 F5000; second wipe mouth\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X90 F5000\nG0 X128 Y261 Z-1.5 F20000 ; move to exposed steel surface and stop the nozzle\nM104 S140 ; set temp down to heatbed acceptable\nM106 S255 ; turn on fan (G28 has turn off fan)\n\nG0 X126 F120\nG0 X130\nG0 X126\nG0 X130\nG0 X128\nM109 S140 ; wait nozzle temp down to heatbed acceptable\nG1 Z10 F1200\nG1 F30000\nG1 X230 Y15\nG29.2 S1 ; turn on ABL\n;G28 ; home again after hard wipe mouth\nM106 S0 ; turn off fan , too noisy\n;===== wipe mouth end ================================\n\n\n;===== bed leveling ==================================\nM1002 judge_flag g29_before_print_flag\nM622 J1\n\n M1002 gcode_claim_action : 1\n G29 A X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]}\n M400\n M500 ; save cali data\n\nM623\n;===== bed leveling end ================================\n\n;===== home after wipe mouth============================\nM1002 judge_flag g29_before_print_flag\nM622 J0\n\n M1002 gcode_claim_action : 13\n G28\n\nM623\n;===== home after wipe mouth end =======================\n\nM975 S1 ; turn on vibration supression\n\n;===== check scanner clarity ===========================\nM972 S5 P0 \nM400 P500\n;===== check scanner clarity end =======================\n\n=============turn on fans to prevent PLA jamming=================\n{if filament_type[initial_tool]==\"PLA\"}\n {if (bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}\n M106 P3 S180\n {elsif (bed_temperature[current_extruder] >50)||(bed_temperature_initial_layer[current_extruder] >50)}\n M106 P3 S255\n {endif};Prevent PLA from jamming\n{endif}\nM106 P2 S100 ; turn on big fan ,to cool down toolhead\n\n{if scan_first_layer}\n;start heatbed scan====================================\nM976 S2 P1 \nM400 S3\n{endif}\n\nM104 S{nozzle_temperature_initial_layer[initial_extruder]} ; set extrude temp earlier, to reduce wait time\n\n;===== mech mode fast check============================\nG1 X128 Y128 Z5 F20000\nM400 P200\nM970.3 Q1 A7 B30 C80 H15 K0\nM974 Q1 S2 P0\n\nG1 X128 Y128 Z5 F20000\nM400 P200\nM970.3 Q0 A7 B30 C90 Q0 H15 K0\nM974 Q0 S2 P0\n;===== fmech mode fast check============================\n\n\n;===== noozle load line ===============================\nM975 S1\nG90 \nM83\nT1000\nG1 X18.0 Y5.0 Z0.3 F18000;Move to start position\nM109 S{nozzle_temperature_initial_layer[initial_extruder]}\nG0 E3 F300\nG0 X240 E15 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \nG0 Y5.5 \nG0 X18 E15\nM400\n\n;===== draw extrinsic para cali paint =================\nM1002 judge_flag extrude_cali_flag\nM622 J1\n\n M1002 gcode_claim_action : 8\n\n T1000 \n G0 F3000 X28.000 Y19.500 Z0.200\n G1 F1200.0 X28.000 Y45.000 Z0.200 E0.933 \n G1 F1200.0 X28.500 Y45.000 Z0.200 E0.018 \n G1 F1200.0 X28.500 Y19.500 Z0.200 E0.933 \n G1 F1200.0 X31.000 Y19.500 Z0.200 E0.091 \n G1 F1200.0 X31.000 Y49.000 Z0.200 E1.080 \n G1 F1200.0 X37.500 Y49.000 Z0.200 E0.238 \n G1 F1200.0 X37.500 Y60.000 Z0.200 E0.403 \n G1 F1200.0 X42.500 Y60.000 Z0.200 E0.183 \n G1 F1200.0 X42.500 Y49.000 Z0.200 E0.403 \n G1 F1200.0 X48.000 Y49.000 Z0.200 E0.201 \n G1 F1200.0 X48.000 Y20.000 Z0.200 E1.061 \n G1 F1200.0 X30.000 Y20.000 Z0.200 E0.659 \n G1 F1200.0 X30.000 Y41.000 Z0.200 E0.769 \n G1 F1200.0 X50.000 Y41.000 Z0.200 E0.732 \n G1 F1200.0 X50.000 Y34.000 Z0.200 E0.256 \n G1 F1200.0 X30.000 Y34.000 Z0.200 E0.732 \n G1 F1500.000 E-0.800 \n\n ;=========== extruder cali extrusion ================== \n T1000 \n M83 \n G0 X35.000 Y18.000 Z0.300 F30000 E0\n G1 F1500.000 E0.800 \n M106 S0 ; turn off fan\n G0 X185.000 E9.35441 F4800 \n G0 X187 Z0\n G1 F1500.000 E-0.800 \n G0 Z1\n G0 X180 Z0.3 F18000\n \n M900 L1000.0 M1.0\n M900 K0.160 \n G0 X45.000 F30000 \n G0 Y20.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E1.24726 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60}\n G1 X70.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X75.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X80.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X85.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X90.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X95.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X100.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X105.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X110.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X115.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X120.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X125.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X130.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X135.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X140.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X145.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X150.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X155.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X160.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X165.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X170.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X175.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X180.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 F1500.000 E-0.800 \n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n M400\n\n G0 X45.000 F30000 \n M900 K0.080 \n G0 X45.000 F30000 \n G0 Y22.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E1.24726 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60}\n G1 X70.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X75.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X80.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X85.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X90.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X95.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X100.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X105.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X110.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X115.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X120.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X125.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X130.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X135.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X140.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X145.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X150.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X155.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X160.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X165.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X170.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X175.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X180.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 F1500.000 E-0.800 \n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n M400\n\n G0 X45.000 F30000 \n M900 K0.000 \n G0 X45.000 F30000 \n G0 Y24.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E1.24726 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60}\n G1 X70.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X75.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X80.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X85.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X90.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X95.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X100.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X105.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X110.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X115.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X120.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X125.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X130.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X135.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X140.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X145.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X150.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X155.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X160.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X165.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X170.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X175.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X180.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 F1500.000 E-0.800\n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n\n G0 X45.000 F30000 ; move to start point\n\nM623 ; end of \"draw extrinsic para cali paint\"\n\nM104 S140\n\n\n;=========== laser and rgb calibration =========== \nM400\nM18 E\nM500 R\n\nM973 S3 P14\n\nG1 X120 Y5.0 Z0.3 F18000.0;Move to first extrude line pos\nT1100\nG1 X143.0 Y5.0 Z0.3 F18000.0;Move to first extrude line pos\n\nM400 P100\n\nM960 S1 P1\nM400 P100\nM973 S6 ; use auto exposure by xcam\nM960 S0 P0\n\n;=========== handeye calibration ======================\nM1002 judge_flag extrude_cali_flag\nM622 J1\n\n M973 S3 P1 ; camera start stream\n M400 P500\n M973 S1 \n G0 F6000 X40.000 Y54.500 Z0.000 \n M960 S0 P1\n M973 S1\n M400 P800\n M971 S6 P0\n M973 S2 P16000\n M400 P500 \n G0 Z0.000 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P1 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P200 \n M971 S5 P3 \n G0 Z0.500 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P2 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P500 \n M971 S5 P4 \n M963 S1 \n M400 P1500 \n M964 \n T1100 \n G0 F6000 X40.000 Y54.500 Z0.000 \n M960 S0 P1\n M973 S1\n M400 P800\n M971 S6 P0\n M973 S2 P16000\n M400 P500 \n G0 Z0.000 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P1 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P200 \n M971 S5 P3 \n G0 Z0.500 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P2 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P500 \n M971 S5 P4 \n M963 S1 \n M400 P1500 \n M964 \n T1100 \n G1 Z3 F3000 \n\n M400\n M500 ; save cali data\n\n M104 S{nozzle_temperature_initial_layer[initial_extruder]} ; rise nozzle temp now ,to reduce temp waiting time.\n\n T1100 \n M400 P400 \n M960 S0 P0\n G0 F30000.000 Y22.000 X65.000 Z0.000\n M400 P400 \n M960 S1 P1 \n M400 P50 \n\n M969 S1 N3 A2000 \n G0 F360.000 X181.000 Z0.000\n M980.3 A70.000 B{outer_wall_volumetric_speed/(1.75*1.75/4*3.14)*60/4} C5.000 D{outer_wall_volumetric_speed/(1.75*1.75/4*3.14)*60} E5.000 F175.000 H1.000 I0.000 J0.080 K0.160\n M400 P100 \n G0 F20000\n G0 Z1 ; rise nozzle up\n T1000 ; change to nozzle space\n G0 X45.000 Y16.000 F30000 ; move to test line pos\n M969 S0 ; turn off scanning\n M960 S0 P0\n\n\n G1 Z2 F20000 \n T1000 \n G0 X45.000 Y16.000 F30000 E0\n M109 S{nozzle_temperature_initial_layer[initial_extruder]} \n G0 Z0.3\n G1 F1500.000 E3.600 \n G1 X65.000 E1.24726 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60}\n G1 X70.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X75.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X80.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X85.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X90.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X95.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X100.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X105.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X110.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X115.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X120.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X125.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X130.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X135.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60}\n\n ; see if extrude cali success, if not ,use default value\n M1002 judge_last_extrude_cali_success\n M622 J0\n M400\n M900 K0.08 M{outer_wall_volumetric_speed/(1.75*1.75/4*3.14)*0.08}\n M623 \n\n G1 X140.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X145.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X150.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X155.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X160.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X165.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X170.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X175.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X180.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X185.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X190.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X195.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X200.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X205.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X210.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X215.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X220.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X225.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n M973 S4 \n\nM623\n\n;========turn off light and wait extrude temperature =============\nM1002 gcode_claim_action : 0\nM973 S4 ; turn off scanner\nM400 ; wait all motion done before implement the emprical L parameters\n;M900 L500.0 ; Empirical parameters\nM109 S[nozzle_temperature_initial_layer]\nM960 S1 P0 ; turn off laser\nM960 S2 P0 ; turn off laser\nM106 S0 ; turn off fan\nM106 P2 S0 ; turn off big fan \nM106 P3 S0 ; turn off chamber fan\n\nM975 S1 ; turn on mech mode supression\nG90 \nM83\nT1000\nG1 X128.0 Y253.0 Z0.2 F6000.0;Move to start position\nM109 S{nozzle_temperature_initial_layer[initial_extruder]}\nG0 X253 E6.4 F{outer_wall_volumetric_speed/(0.3*0.6) * 60} \nG0 Y128 E6.4\nG0 X252.5\nG0 Y252.5 E6.4\nG0 X128 E6.4", + "machine_start_gcode": "\n;===== date: 202200726 =====================\n;===== reset machine status =================\nG91\nM17 Z0.3 ; lower the z-motor current\nG0 Z7 F300 ; lower the hotbed , to prevent the nozzle is below the hotbed\nG90\nM17 X1.2 Y1.2 Z0.75 ; reset motor current to default\nM960 S5 P1 ; turn on logo lamp\nG90\nM220 S100 ;Reset Feedrate\nM221 S100 ;Reset Flowrate\nM73.2 R1.0 ;Reset left time magnitude\nM1002 set_gcode_claim_speed_level : 5\n\n;===== heatbed preheat ====================\nM1002 gcode_claim_action : 2\n{if bbl_bed_temperature_gcode}\nM1002 set_heatbed_surface_temp:[bed_temperature_initial_layer_vector] ;config bed temps\nM140 A S[bed_temperature_initial_layer_single] ;set bed temp\nM190 A S[bed_temperature_initial_layer_single] ;wait for bed temp\n{else}\nM140 S[bed_temperature_initial_layer_single] ;set bed temp\nM190 S[bed_temperature_initial_layer_single] ;wait for bed temp\n{endif}\n\n{if scan_first_layer}\n;=========register first layer scan=====\nM977 S1 P60\n{endif}\n\n=============turn on fans to prevent PLA jamming=================\n{if filament_type[initial_tool]==\"PLA\"}\n {if (bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}\n M106 P3 S180\n {elsif (bed_temperature[current_extruder] >50)||(bed_temperature_initial_layer[current_extruder] >50)}\n M106 P3 S255\n {endif};Prevent PLA from jamming\n{endif}\nM106 P2 S100 ; turn on big fan ,to cool down toolhead\n\n;===== prepare print temperature and material ==========\nM104 S[nozzle_temperature_initial_layer] ;set extruder temp\nG91\nG0 Z2 F1200\nG90\nG28 X\nM975 S1 ; turn on \nG1 X60 F12000\nG1 Y245\nG1 Y265 F3000\nM620 M\nM620 S[initial_tool]A ; switch material if AMS exist\n M109 S[nozzle_temperature_initial_layer]\n G1 X120 F12000\n\n G1 X20 Y50 F12000\n G1 Y-3\n T[initial_tool]\n G1 X54 F12000\n G1 Y265\n M400\nM621 S[initial_tool]A\n\nM412 S1 ; ===turn on filament runout detection===\n\nM109 S250 ;set nozzle to common flush temp\nM106 P1 S0\nG92 E0\nG1 E50 F200\nM400\nM104 S[nozzle_temperature_initial_layer]\nG92 E0\nG1 E50 F200\nM400\nM106 P1 S255\nG92 E0\nG1 E5 F300\nM109 S{nozzle_temperature_initial_layer[initial_extruder]-20} ; drop nozzle temp, make filament shink a bit\nG92 E0\nG1 E-0.5 F300\n\nG1 X70 F9000\nG1 X76 F15000\nG1 X65 F15000\nG1 X76 F15000\nG1 X65 F15000; shake to put down garbage\nG1 X80 F6000\nG1 X95 F15000\nG1 X80 F15000\nG1 X165 F15000; wipe and shake\nM400\nM106 P1 S0\nM975 S1\n;===== prepare print temperature and material end =====\n\n\n;===== wipe mouth ===============================\nM1002 gcode_claim_action : 14\nM975 S1\nM106 S255\nG1 X65 Y230 F18000\nG1 Y264 F6000\nM109 S{nozzle_temperature_initial_layer[initial_extruder]-20}\nG1 X100 F18000 ; first wipe mouth\n\nG0 X135 Y253 F20000 ; move to exposed steel surface edge\nG28 Z P0 T300; home z with low precision,permit 300deg temperature\nG29.2 S0 ; turn off ABL\nG0 Z2 F20000\n\nG1 X60 Y265\nG92 E0\nG1 E-0.5 F300 ; retrack more\nG1 X100 F5000; second wipe mouth\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X90 F5000\nG0 X128 Y261 Z-1.5 F20000 ; move to exposed steel surface and stop the nozzle\nM104 S140 ; set temp down to heatbed acceptable\nM106 S255 ; turn on fan (G28 has turn off fan)\n\nG0 X126 F120\nG0 X130\nG0 X126\nG0 X130\nG0 X128\nM109 S140 ; wait nozzle temp down to heatbed acceptable\nG1 Z10 F1200\nG1 F30000\nG1 X230 Y15\nG29.2 S1 ; turn on ABL\n;G28 ; home again after hard wipe mouth\nM106 S0 ; turn off fan , too noisy\n;===== wipe mouth end ================================\n\n\n;===== bed leveling ==================================\nM1002 judge_flag g29_before_print_flag\nM622 J1\n\n M1002 gcode_claim_action : 1\n G29 A X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]}\n M400\n M500 ; save cali data\n\nM623\n;===== bed leveling end ================================\n\n;===== home after wipe mouth============================\nM1002 judge_flag g29_before_print_flag\nM622 J0\n\n M1002 gcode_claim_action : 13\n G28\n\nM623\n;===== home after wipe mouth end =======================\n\nM975 S1 ; turn on vibration supression\n\n;===== check scanner clarity ===========================\nM972 S5 P0 \nM400 P500\n;===== check scanner clarity end =======================\n\n=============turn on fans to prevent PLA jamming=================\n{if filament_type[initial_tool]==\"PLA\"}\n {if (bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}\n M106 P3 S180\n {elsif (bed_temperature[current_extruder] >50)||(bed_temperature_initial_layer[current_extruder] >50)}\n M106 P3 S255\n {endif};Prevent PLA from jamming\n{endif}\nM106 P2 S100 ; turn on big fan ,to cool down toolhead\n\n{if scan_first_layer}\n;start heatbed scan====================================\nM976 S2 P1 \nM400 S3\n{endif}\n\nM104 S{nozzle_temperature_initial_layer[initial_extruder]} ; set extrude temp earlier, to reduce wait time\n\n;===== mech mode fast check============================\nG1 X128 Y128 Z5 F20000\nM400 P200\nM970.3 Q1 A7 B30 C80 H15 K0\nM974 Q1 S2 P0\n\nG1 X128 Y128 Z5 F20000\nM400 P200\nM970.3 Q0 A7 B30 C90 Q0 H15 K0\nM974 Q0 S2 P0\n\nG1 F30000\nG1 X230 Y15\nG28 X ; re-home XY \n;===== fmech mode fast check============================\n\n\n;===== noozle load line ===============================\nM975 S1\nG90 \nM83\nT1000\nG1 X18.0 Y5.0 Z0.3 F18000;Move to start position\nM109 S{nozzle_temperature_initial_layer[initial_extruder]}\nG0 E3 F300\nG0 X240 E15 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \nG0 Y5.5 \nG0 X18 E15\nM400\n\n;===== draw extrinsic para cali paint =================\nM1002 judge_flag extrude_cali_flag\nM622 J1\n\n M1002 gcode_claim_action : 8\n\n T1000 \n G0 F3000 X28.000 Y19.500 Z0.200\n G1 F1200.0 X28.000 Y45.000 Z0.200 E0.933 \n G1 F1200.0 X28.500 Y45.000 Z0.200 E0.018 \n G1 F1200.0 X28.500 Y19.500 Z0.200 E0.933 \n G1 F1200.0 X31.000 Y19.500 Z0.200 E0.091 \n G1 F1200.0 X31.000 Y49.000 Z0.200 E1.080 \n G1 F1200.0 X37.500 Y49.000 Z0.200 E0.238 \n G1 F1200.0 X37.500 Y60.000 Z0.200 E0.403 \n G1 F1200.0 X42.500 Y60.000 Z0.200 E0.183 \n G1 F1200.0 X42.500 Y49.000 Z0.200 E0.403 \n G1 F1200.0 X48.000 Y49.000 Z0.200 E0.201 \n G1 F1200.0 X48.000 Y20.000 Z0.200 E1.061 \n G1 F1200.0 X30.000 Y20.000 Z0.200 E0.659 \n G1 F1200.0 X30.000 Y41.000 Z0.200 E0.769 \n G1 F1200.0 X50.000 Y41.000 Z0.200 E0.732 \n G1 F1200.0 X50.000 Y34.000 Z0.200 E0.256 \n G1 F1200.0 X30.000 Y34.000 Z0.200 E0.732 \n G1 F1500.000 E-0.800 \n\n ;=========== extruder cali extrusion ================== \n T1000 \n M83 \n G0 X35.000 Y18.000 Z0.300 F30000 E0\n G1 F1500.000 E0.800 \n M106 S0 ; turn off fan\n G0 X185.000 E9.35441 F4800 \n G0 X187 Z0\n G1 F1500.000 E-0.800 \n G0 Z1\n G0 X180 Z0.3 F18000\n \n M900 L1000.0 M1.0\n M900 K0.160 \n G0 X45.000 F30000 \n G0 Y20.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E1.24726 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60}\n G1 X70.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X75.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X80.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X85.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X90.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X95.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X100.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X105.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X110.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X115.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X120.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X125.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X130.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X135.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X140.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X145.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X150.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X155.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X160.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X165.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X170.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X175.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X180.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 F1500.000 E-0.800 \n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n M400\n\n G0 X45.000 F30000 \n M900 K0.080 \n G0 X45.000 F30000 \n G0 Y22.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E1.24726 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60}\n G1 X70.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X75.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X80.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X85.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X90.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X95.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X100.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X105.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X110.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X115.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X120.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X125.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X130.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X135.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X140.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X145.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X150.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X155.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X160.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X165.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X170.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X175.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X180.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 F1500.000 E-0.800 \n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n M400\n\n G0 X45.000 F30000 \n M900 K0.000 \n G0 X45.000 F30000 \n G0 Y24.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E1.24726 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60}\n G1 X70.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X75.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X80.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X85.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X90.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X95.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X100.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X105.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X110.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X115.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X120.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X125.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X130.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X135.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X140.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X145.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X150.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X155.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X160.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X165.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X170.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X175.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X180.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 F1500.000 E-0.800\n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n\n G0 X45.000 F30000 ; move to start point\n\nM623 ; end of \"draw extrinsic para cali paint\"\n\nM104 S140\n\n\n;=========== laser and rgb calibration =========== \nM400\nM18 E\nM500 R\n\nM973 S3 P14\n\nG1 X120 Y5.0 Z0.3 F18000.0;Move to first extrude line pos\nT1100\nG1 X143.0 Y5.0 Z0.3 F18000.0;Move to first extrude line pos\n\nM400 P100\n\nM960 S1 P1\nM400 P100\nM973 S6 ; use auto exposure by xcam\nM960 S0 P0\n\n;=========== handeye calibration ======================\nM1002 judge_flag extrude_cali_flag\nM622 J1\n\n M973 S3 P1 ; camera start stream\n M400 P500\n M973 S1 \n G0 F6000 X40.000 Y54.500 Z0.000 \n M960 S0 P1\n M973 S1\n M400 P800\n M971 S6 P0\n M973 S2 P16000\n M400 P500 \n G0 Z0.000 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P1 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P200 \n M971 S5 P3 \n G0 Z0.500 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P2 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P500 \n M971 S5 P4 \n M963 S1 \n M400 P1500 \n M964 \n T1100 \n G0 F6000 X40.000 Y54.500 Z0.000 \n M960 S0 P1\n M973 S1\n M400 P800\n M971 S6 P0\n M973 S2 P16000\n M400 P500 \n G0 Z0.000 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P1 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P200 \n M971 S5 P3 \n G0 Z0.500 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P2 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P500 \n M971 S5 P4 \n M963 S1 \n M400 P1500 \n M964 \n T1100 \n G1 Z3 F3000 \n\n M400\n M500 ; save cali data\n\n M104 S{nozzle_temperature_initial_layer[initial_extruder]} ; rise nozzle temp now ,to reduce temp waiting time.\n\n T1100 \n M400 P400 \n M960 S0 P0\n G0 F30000.000 Y22.000 X65.000 Z0.000\n M400 P400 \n M960 S1 P1 \n M400 P50 \n\n M969 S1 N3 A2000 \n G0 F360.000 X181.000 Z0.000\n M980.3 A70.000 B{outer_wall_volumetric_speed/(1.75*1.75/4*3.14)*60/4} C5.000 D{outer_wall_volumetric_speed/(1.75*1.75/4*3.14)*60} E5.000 F175.000 H1.000 I0.000 J0.080 K0.160\n M400 P100 \n G0 F20000\n G0 Z1 ; rise nozzle up\n T1000 ; change to nozzle space\n G0 X45.000 Y16.000 F30000 ; move to test line pos\n M969 S0 ; turn off scanning\n M960 S0 P0\n\n\n G1 Z2 F20000 \n T1000 \n G0 X45.000 Y16.000 F30000 E0\n M109 S{nozzle_temperature_initial_layer[initial_extruder]} \n G0 Z0.3\n G1 F1500.000 E3.600 \n G1 X65.000 E1.24726 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60}\n G1 X70.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X75.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X80.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X85.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X90.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X95.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X100.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X105.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X110.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X115.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X120.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X125.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X130.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X135.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60}\n\n ; see if extrude cali success, if not ,use default value\n M1002 judge_last_extrude_cali_success\n M622 J0\n M400\n M900 K0.08 M{outer_wall_volumetric_speed/(1.75*1.75/4*3.14)*0.08}\n M623 \n\n G1 X140.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X145.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X150.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X155.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X160.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X165.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X170.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X175.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X180.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X185.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X190.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X195.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X200.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X205.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X210.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X215.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X220.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X225.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n M973 S4 \n\nM623\n\n;========turn off light and wait extrude temperature =============\nM1002 gcode_claim_action : 0\nM973 S4 ; turn off scanner\nM400 ; wait all motion done before implement the emprical L parameters\n;M900 L500.0 ; Empirical parameters\nM109 S[nozzle_temperature_initial_layer]\nM960 S1 P0 ; turn off laser\nM960 S2 P0 ; turn off laser\nM106 S0 ; turn off fan\nM106 P2 S0 ; turn off big fan \nM106 P3 S0 ; turn off chamber fan\n\nM975 S1 ; turn on mech mode supression\nG90 \nM83\nT1000\nG1 X128.0 Y253.0 Z0.2 F6000.0;Move to start position\nM109 S{nozzle_temperature_initial_layer[initial_extruder]}\nG0 X253 E6.4 F{outer_wall_volumetric_speed/(0.3*0.6) * 60} \nG0 Y128 E6.4\nG0 X252.5\nG0 Y252.5 E6.4\nG0 X128 E6.4", "nozzle_type": "stainless_steel" } diff --git a/resources/profiles/BBL/machine/Bambu Lab X1 Carbon 0.4 nozzle.json b/resources/profiles/BBL/machine/Bambu Lab X1 Carbon 0.4 nozzle.json index a545ce70773..12540a4416e 100644 --- a/resources/profiles/BBL/machine/Bambu Lab X1 Carbon 0.4 nozzle.json +++ b/resources/profiles/BBL/machine/Bambu Lab X1 Carbon 0.4 nozzle.json @@ -19,7 +19,7 @@ "18x28", "0x28" ], - "machine_start_gcode": "\n;===== date: 202200714 =====================\n;===== reset machine status =================\nM17 X1.2 Y1.2 Z0.75 ; reset motor current to default\nM960 S5 P1 ; turn on logo lamp\nG90\nM220 S100 ;Reset Feedrate\nM221 S100 ;Reset Flowrate\nM73.2 R1.0 ;Reset left time magnitude\nM1002 set_gcode_claim_speed_level : 5\n\n;===== heatbed preheat ====================\nM1002 gcode_claim_action : 2\n{if bbl_bed_temperature_gcode}\nM1002 set_heatbed_surface_temp:[bed_temperature_initial_layer_vector] ;config bed temps\nM140 A S[bed_temperature_initial_layer_single] ;set bed temp\nM190 A S[bed_temperature_initial_layer_single] ;wait for bed temp\n{else}\nM140 S[bed_temperature_initial_layer_single] ;set bed temp\nM190 S[bed_temperature_initial_layer_single] ;wait for bed temp\n{endif}\n\n{if scan_first_layer}\n;=========register first layer scan=====\nM977 S1 P60\n{endif}\n\n=============turn on fans to prevent PLA jamming=================\n{if filament_type[initial_tool]==\"PLA\"}\n {if (bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}\n M106 P3 S180\n {elsif (bed_temperature[current_extruder] >50)||(bed_temperature_initial_layer[current_extruder] >50)}\n M106 P3 S255\n {endif};Prevent PLA from jamming\n{endif}\nM106 P2 S100 ; turn on big fan ,to cool down toolhead\n\n;===== prepare print temperature and material ==========\nM104 S[nozzle_temperature_initial_layer] ;set extruder temp\nG91\nG0 Z2 F1200\nG90\nG28 X\nM975 S1 ; turn on \nG1 X60 F12000\nG1 Y245\nG1 Y265 F3000\nM620 M\nM620 S[initial_tool]A ; switch material if AMS exist\n M109 S[nozzle_temperature_initial_layer]\n G1 X120 F12000\n\n G1 X20 Y50 F12000\n G1 Y-3\n T[initial_tool]\n G1 X54 F12000\n G1 Y265\n M400\nM621 S[initial_tool]A\n\nM412 S1 ; ===turn on filament runout detection===\n\nM109 S250 ;set nozzle to common flush temp\nM106 P1 S0\nG92 E0\nG1 E50 F200\nM400\nM104 S[nozzle_temperature_initial_layer]\nG92 E0\nG1 E50 F200\nM400\nM106 P1 S255\nG92 E0\nG1 E5 F300\nM109 S{nozzle_temperature_initial_layer[initial_extruder]-20} ; drop nozzle temp, make filament shink a bit\nG92 E0\nG1 E-0.5 F300\n\nG1 X70 F9000\nG1 X76 F15000\nG1 X65 F15000\nG1 X76 F15000\nG1 X65 F15000; shake to put down garbage\nG1 X80 F6000\nG1 X95 F15000\nG1 X80 F15000\nG1 X165 F15000; wipe and shake\nM400\nM106 P1 S0\nM975 S1\n;===== prepare print temperature and material end =====\n\n\n;===== wipe mouth ===============================\nM1002 gcode_claim_action : 14\nM975 S1\nM106 S255\nG1 X65 Y230 F18000\nG1 Y264 F6000\nM109 S{nozzle_temperature_initial_layer[initial_extruder]-20}\nG1 X100 F18000 ; first wipe mouth\n\nG0 X135 Y253 F20000 ; move to exposed steel surface edge\nG28 Z P0 T300; home z with low precision,permit 300deg temperature\nG29.2 S0 ; turn off ABL\nG0 Z2 F20000\n\nG1 X60 Y265\nG92 E0\nG1 E-0.5 F300 ; retrack more\nG1 X100 F5000; second wipe mouth\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X90 F5000\nG0 X128 Y261 Z-1.5 F20000 ; move to exposed steel surface and stop the nozzle\nM104 S140 ; set temp down to heatbed acceptable\nM106 S255 ; turn on fan (G28 has turn off fan)\n\nG0 X126 F120\nG0 X130\nG0 X126\nG0 X130\nG0 X128\nM109 S140 ; wait nozzle temp down to heatbed acceptable\nG1 Z10 F1200\nG1 F30000\nG1 X230 Y15\nG29.2 S1 ; turn on ABL\n;G28 ; home again after hard wipe mouth\nM106 S0 ; turn off fan , too noisy\n;===== wipe mouth end ================================\n\n\n;===== bed leveling ==================================\nM1002 judge_flag g29_before_print_flag\nM622 J1\n\n M1002 gcode_claim_action : 1\n G29 A X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]}\n M400\n M500 ; save cali data\n\nM623\n;===== bed leveling end ================================\n\n;===== home after wipe mouth============================\nM1002 judge_flag g29_before_print_flag\nM622 J0\n\n M1002 gcode_claim_action : 13\n G28\n\nM623\n;===== home after wipe mouth end =======================\n\nM975 S1 ; turn on vibration supression\n\n;===== check scanner clarity ===========================\nM972 S5 P0 \nM400 S1\n;===== check scanner clarity end =======================\n\n=============turn on fans to prevent PLA jamming=================\n{if filament_type[initial_tool]==\"PLA\"}\n {if (bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}\n M106 P3 S180\n {elsif (bed_temperature[current_extruder] >50)||(bed_temperature_initial_layer[current_extruder] >50)}\n M106 P3 S255\n {endif};Prevent PLA from jamming\n{endif}\nM106 P2 S100 ; turn on big fan ,to cool down toolhead\n\n{if scan_first_layer}\n;start heatbed scan====================================\nM976 S2 P1 \n{endif}\n\nM104 S{nozzle_temperature_initial_layer[initial_extruder]} ; set extrude temp earlier, to reduce wait time\n\n;===== mech mode fast check============================\nG1 X128 Y128 Z5 F20000\nM400 P200\nM970.3 Q1 A7 B30 C80 H15 K0\nM974 Q1 S2 P0\n\nG1 X128 Y128 Z5 F20000\nM400 P200\nM970.3 Q0 A7 B30 C90 Q0 H15 K0\nM974 Q0 S2 P0\n;===== fmech mode fast check============================\n\n\n;===== noozle load line ===============================\nM975 S1\nG90 \nM83\nT1000\nG1 X18.0 Y5.0 Z0.3 F18000;Move to start position\nM109 S{nozzle_temperature[initial_extruder]}\nG0 E3 F300\nG0 X240 E15 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \nG0 Y5.5 \nG0 X18 E15\nM400\n\n;===== draw extrinsic para cali paint =================\nM1002 judge_flag extrude_cali_flag\nM622 J1\n\n M1002 gcode_claim_action : 8\n\n T1000 \n G0 F3000 X28.000 Y19.500 Z0.200\n G1 F1200.0 X28.000 Y45.000 Z0.200 E0.933 \n G1 F1200.0 X28.500 Y45.000 Z0.200 E0.018 \n G1 F1200.0 X28.500 Y19.500 Z0.200 E0.933 \n G1 F1200.0 X31.000 Y19.500 Z0.200 E0.091 \n G1 F1200.0 X31.000 Y49.000 Z0.200 E1.080 \n G1 F1200.0 X37.500 Y49.000 Z0.200 E0.238 \n G1 F1200.0 X37.500 Y60.000 Z0.200 E0.403 \n G1 F1200.0 X42.500 Y60.000 Z0.200 E0.183 \n G1 F1200.0 X42.500 Y49.000 Z0.200 E0.403 \n G1 F1200.0 X48.000 Y49.000 Z0.200 E0.201 \n G1 F1200.0 X48.000 Y20.000 Z0.200 E1.061 \n G1 F1200.0 X30.000 Y20.000 Z0.200 E0.659 \n G1 F1200.0 X30.000 Y41.000 Z0.200 E0.769 \n G1 F1200.0 X50.000 Y41.000 Z0.200 E0.732 \n G1 F1200.0 X50.000 Y34.000 Z0.200 E0.256 \n G1 F1200.0 X30.000 Y34.000 Z0.200 E0.732 \n G1 F1500.000 E-0.800 \n\n ;=========== extruder cali extrusion ================== \n T1000 \n M83 \n\n ;G0 X18 Y28 F20000\n ;G0 Y0\n ;G0 Z0.3\n ;G0 X250 E18 F{outer_wall_volumetric_speed/(0.3*0.5) * 60}\n ;G0 Y0.5\n ;G0 X18 E18 F{outer_wall_volumetric_speed/(0.3*0.5) * 60}\n\n G0 X35.000 Y18.000 Z0.300 F30000 E0\n G1 F1500.000 E0.800 \n M106 S0 ; turn off fan\n G0 X185.000 E9.35441 F{outer_wall_volumetric_speed/(0.3*0.5) * 60}\n G0 X187 Z0\n G1 F1500.000 E-0.800 \n G0 Z1\n G0 X180 Z0.3 F18000\n \n M900 L1000.0 M1.0\n M900 K0.040 \n G0 X45.000 F30000 \n G0 Y20.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E1.24726 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60}\n G1 X70.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X75.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X80.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X85.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X90.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X95.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X100.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X105.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X110.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X115.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X120.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X125.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X130.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X135.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X140.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X145.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X150.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X155.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X160.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X165.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X170.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X175.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X180.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 F1500.000 E-0.800 \n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n M400\n\n G0 X45.000 F30000 \n M900 K0.020 \n G0 X45.000 F30000 \n G0 Y22.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E1.24726 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60}\n G1 X70.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X75.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X80.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X85.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X90.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X95.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X100.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X105.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X110.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X115.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X120.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X125.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X130.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X135.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X140.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X145.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X150.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X155.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X160.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X165.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X170.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X175.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X180.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 F1500.000 E-0.800 \n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n M400\n\n G0 X45.000 F30000 \n M900 K0.000 \n G0 X45.000 F30000 \n G0 Y24.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E1.24726 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60}\n G1 X70.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X75.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X80.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X85.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X90.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X95.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X100.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X105.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X110.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X115.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X120.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X125.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X130.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X135.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X140.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X145.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X150.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X155.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X160.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X165.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X170.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X175.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X180.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 F1500.000 E-0.800\n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n\n G0 X45.000 F30000 ; move to start point\n\nM623 ; end of \"draw extrinsic para cali paint\"\n\nM104 S140\n\n\n;=========== laser and rgb calibration =========== \nM400\nM18 E\nM500 R\n\nM973 S3 P14\n\nG1 X120 Y5.0 Z0.3 F18000.0;Move to first extrude line pos\nT1100\nG1 X143.0 Y5.0 Z0.3 F18000.0;Move to first extrude line pos\n\nM400 P100\n\nM960 S1 P1\nM400 P100\nM973 S6 ; use auto exposure by xcam\nM960 S0 P0\n\n;=========== handeye calibration ======================\nM1002 judge_flag extrude_cali_flag\nM622 J1\n\n M973 S3 P1 ; camera start stream\n M400 P500\n M973 S1 \n G0 F6000 X40.000 Y54.500 Z0.000 \n M960 S0 P1\n M973 S1\n M400 P800\n M971 S6 P0\n M973 S2 P16000\n M400 P500 \n G0 Z0.000 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P1 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P200 \n M971 S5 P3 \n G0 Z0.500 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P2 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P500 \n M971 S5 P4 \n M963 S1 \n M400 P1500 \n M964 \n T1100 \n G0 F6000 X40.000 Y54.500 Z0.000 \n M960 S0 P1\n M973 S1\n M400 P800\n M971 S6 P0\n M973 S2 P16000\n M400 P500 \n G0 Z0.000 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P1 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P200 \n M971 S5 P3 \n G0 Z0.500 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P2 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P500 \n M971 S5 P4 \n M963 S1 \n M400 P1500 \n M964 \n T1100 \n G1 Z3 F3000 \n\n M400\n M500 ; save cali data\n\n M104 S{nozzle_temperature[initial_extruder]} ; rise nozzle temp now ,to reduce temp waiting time.\n\n T1100 \n M400 P400 \n M960 S0 P0\n G0 F30000.000 Y22.000 X65.000 Z0.000\n M400 P400 \n M960 S1 P1 \n M400 P50 \n\n M969 S1 N3 A2000 \n G0 F360.000 X181.000 Z0.000\n M980.3 A70.000 B{outer_wall_volumetric_speed/(1.75*1.75/4*3.14)*60/4} C5.000 D{outer_wall_volumetric_speed/(1.75*1.75/4*3.14)*60} E5.000 F175.000 H1.000 I0.000 J0.020 K0.040\n M400 P100 \n G0 F20000\n G0 Z1 ; rise nozzle up\n T1000 ; change to nozzle space\n G0 X45.000 Y16.000 F30000 ; move to test line pos\n M969 S0 ; turn off scanning\n M960 S0 P0\n\n\n G1 Z2 F20000 \n T1000 \n G0 X45.000 Y16.000 F30000 E0\n M109 S{nozzle_temperature[initial_extruder]}\n G0 Z0.3\n G1 F1500.000 E3.600 \n G1 X65.000 E1.24726 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60}\n G1 X70.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X75.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X80.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X85.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X90.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X95.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X100.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X105.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X110.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X115.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X120.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X125.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X130.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X135.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60}\n\n ; see if extrude cali success, if not ,use default value\n M1002 judge_last_extrude_cali_success\n M622 J0\n M400\n M900 K0.02 M{outer_wall_volumetric_speed/(1.75*1.75/4*3.14)*0.02}\n M623 \n\n G1 X140.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X145.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X150.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X155.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X160.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X165.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X170.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X175.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X180.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X185.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X190.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X195.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X200.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X205.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X210.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X215.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X220.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X225.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n M973 S4 \n\nM623\n\n;========turn off light and wait extrude temperature =============\nM1002 gcode_claim_action : 0\nM973 S4 ; turn off scanner\nM400 ; wait all motion done before implement the emprical L parameters\n;M900 L500.0 ; Empirical parameters\nM109 S[nozzle_temperature_initial_layer]\nM960 S1 P0 ; turn off laser\nM960 S2 P0 ; turn off laser\nM106 S0 ; turn off fan\nM106 P2 S0 ; turn off big fan \nM106 P3 S0 ; turn off chamber fan\n\nM975 S1 ; turn on mech mode supression\nG90 \nM83\nT1000\nG1 X128.0 Y253.0 Z0.2 F6000.0;Move to start position\nM109 S{nozzle_temperature_initial_layer[initial_extruder]}\nG0 X253 E6.4 F{outer_wall_volumetric_speed/(0.3*0.6) * 60} \nG0 Y128 E6.4\nG0 X252.5\nG0 Y252.5 E6.4\nG0 X128 E6.4", + "machine_start_gcode": "\n;===== date: 202200726 =====================\n;===== reset machine status =================\nG91\nM17 Z0.3 ; lower the z-motor current\nG0 Z7 F300 ; lower the hotbed , to prevent the nozzle is below the hotbed\nG90\nM17 X1.2 Y1.2 Z0.75 ; reset motor current to default\nM960 S5 P1 ; turn on logo lamp\nG90\nM220 S100 ;Reset Feedrate\nM221 S100 ;Reset Flowrate\nM73.2 R1.0 ;Reset left time magnitude\nM1002 set_gcode_claim_speed_level : 5\n\n;===== heatbed preheat ====================\nM1002 gcode_claim_action : 2\n{if bbl_bed_temperature_gcode}\nM1002 set_heatbed_surface_temp:[bed_temperature_initial_layer_vector] ;config bed temps\nM140 A S[bed_temperature_initial_layer_single] ;set bed temp\nM190 A S[bed_temperature_initial_layer_single] ;wait for bed temp\n{else}\nM140 S[bed_temperature_initial_layer_single] ;set bed temp\nM190 S[bed_temperature_initial_layer_single] ;wait for bed temp\n{endif}\n\n{if scan_first_layer}\n;=========register first layer scan=====\nM977 S1 P60\n{endif}\n\n=============turn on fans to prevent PLA jamming=================\n{if filament_type[initial_tool]==\"PLA\"}\n {if (bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}\n M106 P3 S180\n {elsif (bed_temperature[current_extruder] >50)||(bed_temperature_initial_layer[current_extruder] >50)}\n M106 P3 S255\n {endif};Prevent PLA from jamming\n{endif}\nM106 P2 S100 ; turn on big fan ,to cool down toolhead\n\n;===== prepare print temperature and material ==========\nM104 S[nozzle_temperature_initial_layer] ;set extruder temp\nG91\nG0 Z2 F1200\nG90\nG28 X\nM975 S1 ; turn on \nG1 X60 F12000\nG1 Y245\nG1 Y265 F3000\nM620 M\nM620 S[initial_tool]A ; switch material if AMS exist\n M109 S[nozzle_temperature_initial_layer]\n G1 X120 F12000\n\n G1 X20 Y50 F12000\n G1 Y-3\n T[initial_tool]\n G1 X54 F12000\n G1 Y265\n M400\nM621 S[initial_tool]A\n\nM412 S1 ; ===turn on filament runout detection===\n\nM109 S250 ;set nozzle to common flush temp\nM106 P1 S0\nG92 E0\nG1 E50 F200\nM400\nM104 S[nozzle_temperature_initial_layer]\nG92 E0\nG1 E50 F200\nM400\nM106 P1 S255\nG92 E0\nG1 E5 F300\nM109 S{nozzle_temperature_initial_layer[initial_extruder]-20} ; drop nozzle temp, make filament shink a bit\nG92 E0\nG1 E-0.5 F300\n\nG1 X70 F9000\nG1 X76 F15000\nG1 X65 F15000\nG1 X76 F15000\nG1 X65 F15000; shake to put down garbage\nG1 X80 F6000\nG1 X95 F15000\nG1 X80 F15000\nG1 X165 F15000; wipe and shake\nM400\nM106 P1 S0\nM975 S1\n;===== prepare print temperature and material end =====\n\n\n;===== wipe mouth ===============================\nM1002 gcode_claim_action : 14\nM975 S1\nM106 S255\nG1 X65 Y230 F18000\nG1 Y264 F6000\nM109 S{nozzle_temperature_initial_layer[initial_extruder]-20}\nG1 X100 F18000 ; first wipe mouth\n\nG0 X135 Y253 F20000 ; move to exposed steel surface edge\nG28 Z P0 T300; home z with low precision,permit 300deg temperature\nG29.2 S0 ; turn off ABL\nG0 Z2 F20000\n\nG1 X60 Y265\nG92 E0\nG1 E-0.5 F300 ; retrack more\nG1 X100 F5000; second wipe mouth\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X90 F5000\nG0 X128 Y261 Z-1.5 F20000 ; move to exposed steel surface and stop the nozzle\nM104 S140 ; set temp down to heatbed acceptable\nM106 S255 ; turn on fan (G28 has turn off fan)\n\nG0 X126 F120\nG0 X130\nG0 X126\nG0 X130\nG0 X128\nM109 S140 ; wait nozzle temp down to heatbed acceptable\nG1 Z10 F1200\nG1 F30000\nG1 X230 Y15\nG29.2 S1 ; turn on ABL\n;G28 ; home again after hard wipe mouth\nM106 S0 ; turn off fan , too noisy\n;===== wipe mouth end ================================\n\n\n;===== bed leveling ==================================\nM1002 judge_flag g29_before_print_flag\nM622 J1\n\n M1002 gcode_claim_action : 1\n G29 A X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]}\n M400\n M500 ; save cali data\n\nM623\n;===== bed leveling end ================================\n\n;===== home after wipe mouth============================\nM1002 judge_flag g29_before_print_flag\nM622 J0\n\n M1002 gcode_claim_action : 13\n G28\n\nM623\n;===== home after wipe mouth end =======================\n\nM975 S1 ; turn on vibration supression\n\n;===== check scanner clarity ===========================\nM972 S5 P0 \nM400 S1\n;===== check scanner clarity end =======================\n\n=============turn on fans to prevent PLA jamming=================\n{if filament_type[initial_tool]==\"PLA\"}\n {if (bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}\n M106 P3 S180\n {elsif (bed_temperature[current_extruder] >50)||(bed_temperature_initial_layer[current_extruder] >50)}\n M106 P3 S255\n {endif};Prevent PLA from jamming\n{endif}\nM106 P2 S100 ; turn on big fan ,to cool down toolhead\n\n{if scan_first_layer}\n;start heatbed scan====================================\nM976 S2 P1 \n{endif}\n\nM104 S{nozzle_temperature_initial_layer[initial_extruder]} ; set extrude temp earlier, to reduce wait time\n\n;===== mech mode fast check============================\nG1 X128 Y128 Z5 F20000\nM400 P200\nM970.3 Q1 A7 B30 C80 H15 K0\nM974 Q1 S2 P0\n\nG1 X128 Y128 Z5 F20000\nM400 P200\nM970.3 Q0 A7 B30 C90 Q0 H15 K0\nM974 Q0 S2 P0\n\nG1 F30000\nG1 X230 Y15\nG28 X ; re-home XY \n;===== fmech mode fast check============================\n\n\n;===== noozle load line ===============================\nM975 S1\nG90 \nM83\nT1000\nG1 X18.0 Y5.0 Z0.3 F18000;Move to start position\nM109 S{nozzle_temperature[initial_extruder]}\nG0 E3 F300\nG0 X240 E15 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \nG0 Y5.5 \nG0 X18 E15\nM400\n\n;===== draw extrinsic para cali paint =================\nM1002 judge_flag extrude_cali_flag\nM622 J1\n\n M1002 gcode_claim_action : 8\n\n T1000 \n G0 F3000 X28.000 Y19.500 Z0.200\n G1 F1200.0 X28.000 Y45.000 Z0.200 E0.933 \n G1 F1200.0 X28.500 Y45.000 Z0.200 E0.018 \n G1 F1200.0 X28.500 Y19.500 Z0.200 E0.933 \n G1 F1200.0 X31.000 Y19.500 Z0.200 E0.091 \n G1 F1200.0 X31.000 Y49.000 Z0.200 E1.080 \n G1 F1200.0 X37.500 Y49.000 Z0.200 E0.238 \n G1 F1200.0 X37.500 Y60.000 Z0.200 E0.403 \n G1 F1200.0 X42.500 Y60.000 Z0.200 E0.183 \n G1 F1200.0 X42.500 Y49.000 Z0.200 E0.403 \n G1 F1200.0 X48.000 Y49.000 Z0.200 E0.201 \n G1 F1200.0 X48.000 Y20.000 Z0.200 E1.061 \n G1 F1200.0 X30.000 Y20.000 Z0.200 E0.659 \n G1 F1200.0 X30.000 Y41.000 Z0.200 E0.769 \n G1 F1200.0 X50.000 Y41.000 Z0.200 E0.732 \n G1 F1200.0 X50.000 Y34.000 Z0.200 E0.256 \n G1 F1200.0 X30.000 Y34.000 Z0.200 E0.732 \n G1 F1500.000 E-0.800 \n\n ;=========== extruder cali extrusion ================== \n T1000 \n M83 \n\n ;G0 X18 Y28 F20000\n ;G0 Y0\n ;G0 Z0.3\n ;G0 X250 E18 F{outer_wall_volumetric_speed/(0.3*0.5) * 60}\n ;G0 Y0.5\n ;G0 X18 E18 F{outer_wall_volumetric_speed/(0.3*0.5) * 60}\n\n G0 X35.000 Y18.000 Z0.300 F30000 E0\n G1 F1500.000 E0.800 \n M106 S0 ; turn off fan\n G0 X185.000 E9.35441 F{outer_wall_volumetric_speed/(0.3*0.5) * 60}\n G0 X187 Z0\n G1 F1500.000 E-0.800 \n G0 Z1\n G0 X180 Z0.3 F18000\n \n M900 L1000.0 M1.0\n M900 K0.040 \n G0 X45.000 F30000 \n G0 Y20.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E1.24726 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60}\n G1 X70.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X75.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X80.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X85.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X90.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X95.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X100.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X105.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X110.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X115.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X120.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X125.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X130.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X135.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X140.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X145.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X150.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X155.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X160.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X165.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X170.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X175.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X180.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 F1500.000 E-0.800 \n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n M400\n\n G0 X45.000 F30000 \n M900 K0.020 \n G0 X45.000 F30000 \n G0 Y22.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E1.24726 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60}\n G1 X70.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X75.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X80.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X85.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X90.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X95.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X100.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X105.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X110.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X115.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X120.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X125.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X130.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X135.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X140.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X145.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X150.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X155.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X160.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X165.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X170.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X175.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X180.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 F1500.000 E-0.800 \n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n M400\n\n G0 X45.000 F30000 \n M900 K0.000 \n G0 X45.000 F30000 \n G0 Y24.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E1.24726 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60}\n G1 X70.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X75.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X80.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X85.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X90.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X95.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X100.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X105.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X110.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X115.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X120.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X125.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X130.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X135.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X140.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X145.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X150.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X155.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X160.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X165.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X170.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X175.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X180.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 F1500.000 E-0.800\n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n\n G0 X45.000 F30000 ; move to start point\n\nM623 ; end of \"draw extrinsic para cali paint\"\n\nM104 S140\n\n\n;=========== laser and rgb calibration =========== \nM400\nM18 E\nM500 R\n\nM973 S3 P14\n\nG1 X120 Y5.0 Z0.3 F18000.0;Move to first extrude line pos\nT1100\nG1 X143.0 Y5.0 Z0.3 F18000.0;Move to first extrude line pos\n\nM400 P100\n\nM960 S1 P1\nM400 P100\nM973 S6 ; use auto exposure by xcam\nM960 S0 P0\n\n;=========== handeye calibration ======================\nM1002 judge_flag extrude_cali_flag\nM622 J1\n\n M973 S3 P1 ; camera start stream\n M400 P500\n M973 S1 \n G0 F6000 X40.000 Y54.500 Z0.000 \n M960 S0 P1\n M973 S1\n M400 P800\n M971 S6 P0\n M973 S2 P16000\n M400 P500 \n G0 Z0.000 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P1 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P200 \n M971 S5 P3 \n G0 Z0.500 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P2 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P500 \n M971 S5 P4 \n M963 S1 \n M400 P1500 \n M964 \n T1100 \n G0 F6000 X40.000 Y54.500 Z0.000 \n M960 S0 P1\n M973 S1\n M400 P800\n M971 S6 P0\n M973 S2 P16000\n M400 P500 \n G0 Z0.000 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P1 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P200 \n M971 S5 P3 \n G0 Z0.500 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P2 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P500 \n M971 S5 P4 \n M963 S1 \n M400 P1500 \n M964 \n T1100 \n G1 Z3 F3000 \n\n M400\n M500 ; save cali data\n\n M104 S{nozzle_temperature[initial_extruder]} ; rise nozzle temp now ,to reduce temp waiting time.\n\n T1100 \n M400 P400 \n M960 S0 P0\n G0 F30000.000 Y22.000 X65.000 Z0.000\n M400 P400 \n M960 S1 P1 \n M400 P50 \n\n M969 S1 N3 A2000 \n G0 F360.000 X181.000 Z0.000\n M980.3 A70.000 B{outer_wall_volumetric_speed/(1.75*1.75/4*3.14)*60/4} C5.000 D{outer_wall_volumetric_speed/(1.75*1.75/4*3.14)*60} E5.000 F175.000 H1.000 I0.000 J0.020 K0.040\n M400 P100 \n G0 F20000\n G0 Z1 ; rise nozzle up\n T1000 ; change to nozzle space\n G0 X45.000 Y16.000 F30000 ; move to test line pos\n M969 S0 ; turn off scanning\n M960 S0 P0\n\n\n G1 Z2 F20000 \n T1000 \n G0 X45.000 Y16.000 F30000 E0\n M109 S{nozzle_temperature[initial_extruder]}\n G0 Z0.3\n G1 F1500.000 E3.600 \n G1 X65.000 E1.24726 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60}\n G1 X70.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X75.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X80.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X85.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X90.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X95.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X100.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X105.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X110.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X115.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X120.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X125.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X130.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X135.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60}\n\n ; see if extrude cali success, if not ,use default value\n M1002 judge_last_extrude_cali_success\n M622 J0\n M400\n M900 K0.02 M{outer_wall_volumetric_speed/(1.75*1.75/4*3.14)*0.02}\n M623 \n\n G1 X140.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X145.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X150.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X155.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X160.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X165.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X170.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X175.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X180.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X185.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X190.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X195.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X200.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X205.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X210.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X215.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X220.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X225.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n M973 S4 \n\nM623\n\n;========turn off light and wait extrude temperature =============\nM1002 gcode_claim_action : 0\nM973 S4 ; turn off scanner\nM400 ; wait all motion done before implement the emprical L parameters\n;M900 L500.0 ; Empirical parameters\nM109 S[nozzle_temperature_initial_layer]\nM960 S1 P0 ; turn off laser\nM960 S2 P0 ; turn off laser\nM106 S0 ; turn off fan\nM106 P2 S0 ; turn off big fan \nM106 P3 S0 ; turn off chamber fan\n\nM975 S1 ; turn on mech mode supression\nG90 \nM83\nT1000\nG1 X128.0 Y253.0 Z0.2 F6000.0;Move to start position\nM109 S{nozzle_temperature_initial_layer[initial_extruder]}\nG0 X253 E6.4 F{outer_wall_volumetric_speed/(0.3*0.6) * 60} \nG0 Y128 E6.4\nG0 X252.5\nG0 Y252.5 E6.4\nG0 X128 E6.4", "machine_end_gcode": "M400 ; wait for buffer to clear\nG92 E0 ; zero the extruder\nG1 E-0.8 F1800 ; retract\nG1 Z{max_layer_z + 1.0} F900 ; lower z a little\nG1 X65 Y245 F12000 ; move to safe pos \nG1 Y265 F3000\n\nM17 S\nM17 Z0.5 ; lower z motor current to reduce impact if there is something in the bottom\n{if (max_layer_z + 100.0) < 250}\n G1 Z{max_layer_z + 100.0} F900\n{else}\n G1 Z250 F900\n{endif}\nM400 P100\nM17 R ; restore z current\n\nG1 X65 Y245 F12000\nG1 Y265 F3000\nM140 S0 ; turn off bed\nM106 S0 ; turn off fan\nM106 P2 S0 ; turn off remote part cooling fan\nM106 P3 S0 ; turn off chamber cooling fan\n\nG1 X100 F12000 ; wipe\n; pull back filament to AMS\nM620 S255\nG1 X20 Y50 F12000\nG1 Y-3\nT255\nG1 X65 F12000\nG1 Y265\nG1 X100 F12000 ; wipe\nM621 S255\nM104 S0 ; turn off hotend\n\nG90\nG1 X128 Y250 F3600\n\nM220 S100 ; Reset feedrate magnitude\nM201.2 K1.0 ; Reset acc magnitude\nM73.2 R1.0 ;Reset left time magnitude\nM1002 set_gcode_claim_speed_level : 0", "scan_first_layer": "1", "machine_load_filament_time": "17", diff --git a/resources/profiles/BBL/machine/Bambu Lab X1 Carbon 0.6 nozzle.json b/resources/profiles/BBL/machine/Bambu Lab X1 Carbon 0.6 nozzle.json index ada196c74ed..37d4f86cc15 100644 --- a/resources/profiles/BBL/machine/Bambu Lab X1 Carbon 0.6 nozzle.json +++ b/resources/profiles/BBL/machine/Bambu Lab X1 Carbon 0.6 nozzle.json @@ -26,5 +26,5 @@ "retraction_minimum_travel": [ "3" ], - "machine_start_gcode": "\n;===== date: 202200710 =====================\n;===== reset machine status =================\nM17 X1.2 Y1.2 Z0.75 ; reset motor current to default\nM960 S5 P1 ; turn on logo lamp\nG90\nM220 S100 ;Reset Feedrate\nM221 S100 ;Reset Flowrate\nM73.2 R1.0 ;Reset left time magnitude\nM1002 set_gcode_claim_speed_level : 5\n\n;===== heatbed preheat ====================\nM1002 gcode_claim_action : 2\n{if bbl_bed_temperature_gcode}\nM1002 set_heatbed_surface_temp:[bed_temperature_initial_layer_vector] ;config bed temps\nM140 A S[bed_temperature_initial_layer_single] ;set bed temp\nM190 A S[bed_temperature_initial_layer_single] ;wait for bed temp\n{else}\nM140 S[bed_temperature_initial_layer_single] ;set bed temp\nM190 S[bed_temperature_initial_layer_single] ;wait for bed temp\n{endif}\n\n{if scan_first_layer}\n;=========register first layer scan=====\nM977 S1 P60\n{endif}\n\n=============turn on fans to prevent PLA jamming=================\n{if filament_type[initial_tool]==\"PLA\"}\n {if (bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}\n M106 P3 S180\n {elsif (bed_temperature[current_extruder] >50)||(bed_temperature_initial_layer[current_extruder] >50)}\n M106 P3 S255\n {endif};Prevent PLA from jamming\n{endif}\nM106 P2 S100 ; turn on big fan ,to cool down toolhead\n\n;===== prepare print temperature and material ==========\nM104 S[nozzle_temperature_initial_layer] ;set extruder temp\nG91\nG0 Z2 F1200\nG90\nG28 X\nM975 S1 ; turn on \nG1 X60 F12000\nG1 Y245\nG1 Y265 F3000\nM620 M\nM620 S[initial_tool]A ; switch material if AMS exist\n M109 S[nozzle_temperature_initial_layer]\n G1 X120 F12000\n\n G1 X20 Y50 F12000\n G1 Y-3\n T[initial_tool]\n G1 X54 F12000\n G1 Y265\n M400\nM621 S[initial_tool]A\n\nM412 S1 ; ===turn on filament runout detection===\n\nM109 S250 ;set nozzle to common flush temp\nM106 P1 S0\nG92 E0\nG1 E50 F200\nM400\nM104 S[nozzle_temperature_initial_layer]\nG92 E0\nG1 E50 F200\nM400\nM106 P1 S255\nG92 E0\nG1 E5 F300\nM109 S{nozzle_temperature_initial_layer[initial_extruder]-20} ; drop nozzle temp, make filament shink a bit\nG92 E0\nG1 E-0.5 F300\n\nG1 X70 F9000\nG1 X76 F15000\nG1 X65 F15000\nG1 X76 F15000\nG1 X65 F15000; shake to put down garbage\nG1 X80 F6000\nG1 X95 F15000\nG1 X80 F15000\nG1 X165 F15000; wipe and shake\nM400\nM106 P1 S0\nM975 S1\n;===== prepare print temperature and material end =====\n\n\n;===== wipe mouth ===============================\nM1002 gcode_claim_action : 14\nM975 S1\nM106 S255\nG1 X65 Y230 F18000\nG1 Y264 F6000\nM109 S{nozzle_temperature_initial_layer[initial_extruder]-20}\nG1 X100 F18000 ; first wipe mouth\n\nG0 X135 Y253 F20000 ; move to exposed steel surface edge\nG28 Z P0 T300; home z with low precision,permit 300deg temperature\nG29.2 S0 ; turn off ABL\nG0 Z2 F20000\n\nG1 X60 Y265\nG92 E0\nG1 E-0.5 F300 ; retrack more\nG1 X100 F5000; second wipe mouth\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X90 F5000\nG0 X128 Y261 Z-1.5 F20000 ; move to exposed steel surface and stop the nozzle\nM104 S140 ; set temp down to heatbed acceptable\nM106 S255 ; turn on fan (G28 has turn off fan)\n\nG0 X126 F120\nG0 X130\nG0 X126\nG0 X130\nG0 X128\nM109 S140 ; wait nozzle temp down to heatbed acceptable\nG1 Z10 F1200\nG1 F30000\nG1 X230 Y15\nG29.2 S1 ; turn on ABL\n;G28 ; home again after hard wipe mouth\nM106 S0 ; turn off fan , too noisy\n;===== wipe mouth end ================================\n\n\n;===== bed leveling ==================================\nM1002 judge_flag g29_before_print_flag\nM622 J1\n\n M1002 gcode_claim_action : 1\n G29 A X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]}\n M400\n M500 ; save cali data\n\nM623\n;===== bed leveling end ================================\n\n;===== home after wipe mouth============================\nM1002 judge_flag g29_before_print_flag\nM622 J0\n\n M1002 gcode_claim_action : 13\n G28\n\nM623\n;===== home after wipe mouth end =======================\n\nM975 S1 ; turn on vibration supression\n\n;===== check scanner clarity ===========================\nM972 S5 P0 \nM400 P500\n;===== check scanner clarity end =======================\n\n=============turn on fans to prevent PLA jamming=================\n{if filament_type[initial_tool]==\"PLA\"}\n {if (bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}\n M106 P3 S180\n {elsif (bed_temperature[current_extruder] >50)||(bed_temperature_initial_layer[current_extruder] >50)}\n M106 P3 S255\n {endif};Prevent PLA from jamming\n{endif}\nM106 P2 S100 ; turn on big fan ,to cool down toolhead\n\n{if scan_first_layer}\n;start heatbed scan====================================\nM976 S2 P1 \n{endif}\n\nM104 S{nozzle_temperature_initial_layer[initial_extruder]} ; set extrude temp earlier, to reduce wait time\n\n;===== mech mode fast check============================\nG1 X128 Y128 Z5 F20000\nM400 P200\nM970.3 Q1 A7 B30 C80 H15 K0\nM974 Q1 S2 P0\n\nG1 X128 Y128 Z5 F20000\nM400 P200\nM970.3 Q0 A7 B30 C90 Q0 H15 K0\nM974 Q0 S2 P0\n;===== fmech mode fast check============================\n\n\n;===== noozle load line ===============================\nM975 S1\nG90 \nM83\nT1000\nG1 X18.0 Y5.0 Z0.3 F18000;Move to start position\nM109 S{nozzle_temperature[initial_extruder]}\nG0 E3 F300\nG0 X240 E25 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \nG0 Y5.5 \nG0 X18 E25\nM400\n\n;===== draw extrinsic para cali paint =================\nM1002 judge_flag extrude_cali_flag\nM622 J1\n\n M1002 gcode_claim_action : 8\n\n T1000 \n G0 F3000 X28.000 Y19.500 Z0.200\n G1 F1200.0 X28.000 Y45.000 Z0.200 E1.679 \n G1 F1200.0 X28.500 Y45.000 Z0.200 E0.032 \n G1 F1200.0 X28.500 Y19.500 Z0.200 E1.679 \n G1 F1200.0 X31.000 Y19.500 Z0.200 E0.164 \n G1 F1200.0 X31.000 Y49.000 Z0.200 E1.944 \n G1 F1200.0 X37.500 Y49.000 Z0.200 E0.428 \n G1 F1200.0 X37.500 Y60.000 Z0.200 E0.725 \n G1 F1200.0 X42.500 Y60.000 Z0.200 E0.329 \n G1 F1200.0 X42.500 Y49.000 Z0.200 E0.725 \n G1 F1200.0 X48.000 Y49.000 Z0.200 E0.362 \n G1 F1200.0 X48.000 Y20.000 Z0.200 E1.910 \n G1 F1200.0 X30.000 Y20.000 Z0.200 E1.186 \n G1 F1200.0 X30.000 Y41.000 Z0.200 E1.384 \n G1 F1200.0 X50.000 Y41.000 Z0.200 E1.318 \n G1 F1200.0 X50.000 Y34.000 Z0.200 E0.461 \n G1 F1200.0 X30.000 Y34.000 Z0.200 E1.318 \n G1 F1500.000 E-0.800 \n\n ;=========== extruder cali extrusion ================== \n T1000 \n M83 \n\n ;G0 X18 Y28 F20000\n ;G0 Y0\n ;G0 Z0.3\n ;G0 X250 E25 F{outer_wall_volumetric_speed/(0.3*0.9) * 60}\n ;G0 Y0.9\n ;G0 X18 E25 F{outer_wall_volumetric_speed/(0.3*0.9) * 60}\n\n G0 X35.000 Y18.000 Z0.300 F30000 E0\n G1 F1500.000 E0.800 \n M106 S0 ; turn off fan\n G0 X185.000 E16.9 F{outer_wall_volumetric_speed/(0.3*0.9) * 60}\n G0 X187 Z0\n G1 F1500.000 E-0.800 \n G0 Z1\n G0 X180 Z0.3 F18000\n \n M900 L1000.0 M1.0\n M900 K0.030 \n G0 X45.000 F30000 \n G0 Y20.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E2.25000 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60}\n G1 X70.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X75.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X80.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X85.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X90.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X95.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X100.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X105.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X110.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X115.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X120.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X125.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X130.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X135.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X140.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X145.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X150.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X155.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X160.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X165.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X170.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X175.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X180.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 F1500.000 E-0.800 \n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n M400\n\n G0 X45.000 F30000 \n M900 K0.015 \n G0 X45.000 F30000 \n G0 Y22.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E2.25000 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60}\n G1 X70.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X75.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X80.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X85.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X90.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X95.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X100.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X105.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X110.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X115.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X120.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X125.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X130.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X135.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X140.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X145.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X150.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X155.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X160.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X165.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X170.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X175.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X180.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 F1500.000 E-0.800 \n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n M400\n\n G0 X45.000 F30000 \n M900 K0.000 \n G0 X45.000 F30000 \n G0 Y24.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E2.25000 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60}\n G1 X70.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X75.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X80.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X85.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X90.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X95.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X100.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X105.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X110.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X115.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X120.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X125.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X130.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X135.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X140.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X145.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X150.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X155.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X160.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X165.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X170.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X175.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X180.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 F1500.000 E-0.800\n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n\n G0 X45.000 F30000 ; move to start point\n\nM623 ; end of \"draw extrinsic para cali paint\"\n\nM104 S140\n\n\n;=========== laser and rgb calibration =========== \nM400\nM18 E\nM500 R\n\nM973 S3 P14\n\nG1 X120 Y5.0 Z0.3 F18000.0;Move to first extrude line pos\nT1100\nG1 X143.0 Y5.0 Z0.3 F18000.0;Move to first extrude line pos\n\nM400 P100\n\nM960 S1 P1\nM400 P100\nM973 S6 ; use auto exposure by xcam\nM960 S0 P0\n\n;=========== handeye calibration ======================\nM1002 judge_flag extrude_cali_flag\nM622 J1\n\n M973 S3 P1 ; camera start stream\n M400 P500\n M973 S1 \n G0 F6000 X40.000 Y54.500 Z0.000 \n M960 S0 P1\n M973 S1\n M400 P800\n M971 S6 P0\n M973 S2 P16000\n M400 P500 \n G0 Z0.000 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P1 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P200 \n M971 S5 P3 \n G0 Z0.500 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P2 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P500 \n M971 S5 P4 \n M963 S1 \n M400 P1500 \n M964 \n T1100 \n G0 F6000 X40.000 Y54.500 Z0.000 \n M960 S0 P1\n M973 S1\n M400 P800\n M971 S6 P0\n M973 S2 P16000\n M400 P500 \n G0 Z0.000 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P1 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P200 \n M971 S5 P3 \n G0 Z0.500 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P2 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P500 \n M971 S5 P4 \n M963 S1 \n M400 P1500 \n M964 \n T1100 \n G1 Z3 F3000 \n\n M400\n M500 ; save cali data\n\n M104 S{nozzle_temperature[initial_extruder]} ; rise nozzle temp now ,to reduce temp waiting time.\n\n T1100 \n M400 P400 \n M960 S0 P0\n G0 F30000.000 Y22.000 X65.000 Z0.000\n M400 P400 \n M960 S1 P1 \n M400 P50 \n\n M969 S1 N3 A2000 \n G0 F360.000 X181.000 Z0.000\n M980.3 A70.000 B{outer_wall_volumetric_speed/(1.75*1.75/4*3.14)*60/4} C5.000 D{outer_wall_volumetric_speed/(1.75*1.75/4*3.14)*60} E5.000 F175.000 H1.000 I0.000 J0.015 K0.030\n M400 P100 \n G0 F20000\n G0 Z1 ; rise nozzle up\n T1000 ; change to nozzle space\n G0 X45.000 Y16.000 F30000 ; move to test line pos\n M969 S0 ; turn off scanning\n M960 S0 P0\n\n\n G1 Z2 F20000 \n T1000 \n G0 X45.000 Y16.000 F30000 E0\n M109 S{nozzle_temperature[initial_extruder]}\n G0 Z0.3\n G1 F1500.000 E3.600 \n G1 X65.000 E2.25000 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60}\n G1 X70.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X75.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X80.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X85.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X90.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X95.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X100.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X105.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X110.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X115.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X120.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X125.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X130.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X135.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60}\n\n ; see if extrude cali success, if not ,use default value\n M1002 judge_last_extrude_cali_success\n M622 J0\n M400\n M900 K0.015 M{outer_wall_volumetric_speed/(1.75*1.75/4*3.14)*0.015}\n M623 \n\n G1 X140.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X145.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X150.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X155.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X160.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X165.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X170.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X175.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X180.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X185.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X190.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X195.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X200.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X205.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X210.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X215.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X220.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X225.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n M973 S4 \n\nM623\n\n;========turn off light and wait extrude temperature =============\nM1002 gcode_claim_action : 0\nM973 S4 ; turn off scanner\nM400 ; wait all motion done before implement the emprical L parameters\n;M900 L500.0 ; Empirical parameters\nM109 S[nozzle_temperature_initial_layer]\nM960 S1 P0 ; turn off laser\nM960 S2 P0 ; turn off laser\nM106 S0 ; turn off fan\nM106 P2 S0 ; turn off big fan \nM106 P3 S0 ; turn off chamber fan\n\nM975 S1 ; turn on mech mode supression\nG90 \nM83\nT1000\nG1 X128.0 Y253.0 Z0.2 F6000.0;Move to start position\nM109 S{nozzle_temperature_initial_layer[initial_extruder]}\nG0 X253 E6.4 F{outer_wall_volumetric_speed/(0.3*0.6) * 60} \nG0 Y128 E6.4\nG0 X252.5\nG0 Y252.5 E6.4\nG0 X128 E6.4" + "machine_start_gcode": "\n;===== date: 202200726 =====================\n;===== reset machine status =================\nG91\nM17 Z0.3 ; lower the z-motor current\nG0 Z7 F300 ; lower the hotbed , to prevent the nozzle is below the hotbed\nG90\nM17 X1.2 Y1.2 Z0.75 ; reset motor current to default\nM960 S5 P1 ; turn on logo lamp\nG90\nM220 S100 ;Reset Feedrate\nM221 S100 ;Reset Flowrate\nM73.2 R1.0 ;Reset left time magnitude\nM1002 set_gcode_claim_speed_level : 5\n\n;===== heatbed preheat ====================\nM1002 gcode_claim_action : 2\n{if bbl_bed_temperature_gcode}\nM1002 set_heatbed_surface_temp:[bed_temperature_initial_layer_vector] ;config bed temps\nM140 A S[bed_temperature_initial_layer_single] ;set bed temp\nM190 A S[bed_temperature_initial_layer_single] ;wait for bed temp\n{else}\nM140 S[bed_temperature_initial_layer_single] ;set bed temp\nM190 S[bed_temperature_initial_layer_single] ;wait for bed temp\n{endif}\n\n{if scan_first_layer}\n;=========register first layer scan=====\nM977 S1 P60\n{endif}\n\n=============turn on fans to prevent PLA jamming=================\n{if filament_type[initial_tool]==\"PLA\"}\n {if (bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}\n M106 P3 S180\n {elsif (bed_temperature[current_extruder] >50)||(bed_temperature_initial_layer[current_extruder] >50)}\n M106 P3 S255\n {endif};Prevent PLA from jamming\n{endif}\nM106 P2 S100 ; turn on big fan ,to cool down toolhead\n\n;===== prepare print temperature and material ==========\nM104 S[nozzle_temperature_initial_layer] ;set extruder temp\nG91\nG0 Z2 F1200\nG90\nG28 X\nM975 S1 ; turn on \nG1 X60 F12000\nG1 Y245\nG1 Y265 F3000\nM620 M\nM620 S[initial_tool]A ; switch material if AMS exist\n M109 S[nozzle_temperature_initial_layer]\n G1 X120 F12000\n\n G1 X20 Y50 F12000\n G1 Y-3\n T[initial_tool]\n G1 X54 F12000\n G1 Y265\n M400\nM621 S[initial_tool]A\n\nM412 S1 ; ===turn on filament runout detection===\n\nM109 S250 ;set nozzle to common flush temp\nM106 P1 S0\nG92 E0\nG1 E50 F200\nM400\nM104 S[nozzle_temperature_initial_layer]\nG92 E0\nG1 E50 F200\nM400\nM106 P1 S255\nG92 E0\nG1 E5 F300\nM109 S{nozzle_temperature_initial_layer[initial_extruder]-20} ; drop nozzle temp, make filament shink a bit\nG92 E0\nG1 E-0.5 F300\n\nG1 X70 F9000\nG1 X76 F15000\nG1 X65 F15000\nG1 X76 F15000\nG1 X65 F15000; shake to put down garbage\nG1 X80 F6000\nG1 X95 F15000\nG1 X80 F15000\nG1 X165 F15000; wipe and shake\nM400\nM106 P1 S0\nM975 S1\n;===== prepare print temperature and material end =====\n\n\n;===== wipe mouth ===============================\nM1002 gcode_claim_action : 14\nM975 S1\nM106 S255\nG1 X65 Y230 F18000\nG1 Y264 F6000\nM109 S{nozzle_temperature_initial_layer[initial_extruder]-20}\nG1 X100 F18000 ; first wipe mouth\n\nG0 X135 Y253 F20000 ; move to exposed steel surface edge\nG28 Z P0 T300; home z with low precision,permit 300deg temperature\nG29.2 S0 ; turn off ABL\nG0 Z2 F20000\n\nG1 X60 Y265\nG92 E0\nG1 E-0.5 F300 ; retrack more\nG1 X100 F5000; second wipe mouth\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X90 F5000\nG0 X128 Y261 Z-1.5 F20000 ; move to exposed steel surface and stop the nozzle\nM104 S140 ; set temp down to heatbed acceptable\nM106 S255 ; turn on fan (G28 has turn off fan)\n\nG0 X126 F120\nG0 X130\nG0 X126\nG0 X130\nG0 X128\nM109 S140 ; wait nozzle temp down to heatbed acceptable\nG1 Z10 F1200\nG1 F30000\nG1 X230 Y15\nG29.2 S1 ; turn on ABL\n;G28 ; home again after hard wipe mouth\nM106 S0 ; turn off fan , too noisy\n;===== wipe mouth end ================================\n\n\n;===== bed leveling ==================================\nM1002 judge_flag g29_before_print_flag\nM622 J1\n\n M1002 gcode_claim_action : 1\n G29 A X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]}\n M400\n M500 ; save cali data\n\nM623\n;===== bed leveling end ================================\n\n;===== home after wipe mouth============================\nM1002 judge_flag g29_before_print_flag\nM622 J0\n\n M1002 gcode_claim_action : 13\n G28\n\nM623\n;===== home after wipe mouth end =======================\n\nM975 S1 ; turn on vibration supression\n\n;===== check scanner clarity ===========================\nM972 S5 P0 \nM400 P500\n;===== check scanner clarity end =======================\n\n=============turn on fans to prevent PLA jamming=================\n{if filament_type[initial_tool]==\"PLA\"}\n {if (bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}\n M106 P3 S180\n {elsif (bed_temperature[current_extruder] >50)||(bed_temperature_initial_layer[current_extruder] >50)}\n M106 P3 S255\n {endif};Prevent PLA from jamming\n{endif}\nM106 P2 S100 ; turn on big fan ,to cool down toolhead\n\n{if scan_first_layer}\n;start heatbed scan====================================\nM976 S2 P1 \n{endif}\n\nM104 S{nozzle_temperature_initial_layer[initial_extruder]} ; set extrude temp earlier, to reduce wait time\n\n;===== mech mode fast check============================\nG1 X128 Y128 Z5 F20000\nM400 P200\nM970.3 Q1 A7 B30 C80 H15 K0\nM974 Q1 S2 P0\n\nG1 X128 Y128 Z5 F20000\nM400 P200\nM970.3 Q0 A7 B30 C90 Q0 H15 K0\nM974 Q0 S2 P0\n\nG1 F30000\nG1 X230 Y15\nG28 X ; re-home XY \n;===== fmech mode fast check============================\n\n\n;===== noozle load line ===============================\nM975 S1\nG90 \nM83\nT1000\nG1 X18.0 Y5.0 Z0.3 F18000;Move to start position\nM109 S{nozzle_temperature[initial_extruder]}\nG0 E3 F300\nG0 X240 E25 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \nG0 Y5.5 \nG0 X18 E25\nM400\n\n;===== draw extrinsic para cali paint =================\nM1002 judge_flag extrude_cali_flag\nM622 J1\n\n M1002 gcode_claim_action : 8\n\n T1000 \n G0 F3000 X28.000 Y19.500 Z0.200\n G1 F1200.0 X28.000 Y45.000 Z0.200 E1.679 \n G1 F1200.0 X28.500 Y45.000 Z0.200 E0.032 \n G1 F1200.0 X28.500 Y19.500 Z0.200 E1.679 \n G1 F1200.0 X31.000 Y19.500 Z0.200 E0.164 \n G1 F1200.0 X31.000 Y49.000 Z0.200 E1.944 \n G1 F1200.0 X37.500 Y49.000 Z0.200 E0.428 \n G1 F1200.0 X37.500 Y60.000 Z0.200 E0.725 \n G1 F1200.0 X42.500 Y60.000 Z0.200 E0.329 \n G1 F1200.0 X42.500 Y49.000 Z0.200 E0.725 \n G1 F1200.0 X48.000 Y49.000 Z0.200 E0.362 \n G1 F1200.0 X48.000 Y20.000 Z0.200 E1.910 \n G1 F1200.0 X30.000 Y20.000 Z0.200 E1.186 \n G1 F1200.0 X30.000 Y41.000 Z0.200 E1.384 \n G1 F1200.0 X50.000 Y41.000 Z0.200 E1.318 \n G1 F1200.0 X50.000 Y34.000 Z0.200 E0.461 \n G1 F1200.0 X30.000 Y34.000 Z0.200 E1.318 \n G1 F1500.000 E-0.800 \n\n ;=========== extruder cali extrusion ================== \n T1000 \n M83 \n\n ;G0 X18 Y28 F20000\n ;G0 Y0\n ;G0 Z0.3\n ;G0 X250 E25 F{outer_wall_volumetric_speed/(0.3*0.9) * 60}\n ;G0 Y0.9\n ;G0 X18 E25 F{outer_wall_volumetric_speed/(0.3*0.9) * 60}\n\n G0 X35.000 Y18.000 Z0.300 F30000 E0\n G1 F1500.000 E0.800 \n M106 S0 ; turn off fan\n G0 X185.000 E16.9 F{outer_wall_volumetric_speed/(0.3*0.9) * 60}\n G0 X187 Z0\n G1 F1500.000 E-0.800 \n G0 Z1\n G0 X180 Z0.3 F18000\n \n M900 L1000.0 M1.0\n M900 K0.030 \n G0 X45.000 F30000 \n G0 Y20.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E2.25000 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60}\n G1 X70.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X75.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X80.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X85.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X90.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X95.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X100.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X105.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X110.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X115.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X120.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X125.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X130.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X135.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X140.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X145.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X150.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X155.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X160.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X165.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X170.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X175.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X180.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 F1500.000 E-0.800 \n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n M400\n\n G0 X45.000 F30000 \n M900 K0.015 \n G0 X45.000 F30000 \n G0 Y22.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E2.25000 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60}\n G1 X70.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X75.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X80.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X85.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X90.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X95.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X100.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X105.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X110.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X115.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X120.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X125.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X130.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X135.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X140.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X145.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X150.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X155.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X160.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X165.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X170.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X175.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X180.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 F1500.000 E-0.800 \n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n M400\n\n G0 X45.000 F30000 \n M900 K0.000 \n G0 X45.000 F30000 \n G0 Y24.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E2.25000 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60}\n G1 X70.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X75.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X80.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X85.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X90.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X95.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X100.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X105.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X110.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X115.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X120.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X125.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X130.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X135.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X140.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X145.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X150.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X155.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X160.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X165.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X170.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X175.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X180.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 F1500.000 E-0.800\n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n\n G0 X45.000 F30000 ; move to start point\n\nM623 ; end of \"draw extrinsic para cali paint\"\n\nM104 S140\n\n\n;=========== laser and rgb calibration =========== \nM400\nM18 E\nM500 R\n\nM973 S3 P14\n\nG1 X120 Y5.0 Z0.3 F18000.0;Move to first extrude line pos\nT1100\nG1 X143.0 Y5.0 Z0.3 F18000.0;Move to first extrude line pos\n\nM400 P100\n\nM960 S1 P1\nM400 P100\nM973 S6 ; use auto exposure by xcam\nM960 S0 P0\n\n;=========== handeye calibration ======================\nM1002 judge_flag extrude_cali_flag\nM622 J1\n\n M973 S3 P1 ; camera start stream\n M400 P500\n M973 S1 \n G0 F6000 X40.000 Y54.500 Z0.000 \n M960 S0 P1\n M973 S1\n M400 P800\n M971 S6 P0\n M973 S2 P16000\n M400 P500 \n G0 Z0.000 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P1 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P200 \n M971 S5 P3 \n G0 Z0.500 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P2 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P500 \n M971 S5 P4 \n M963 S1 \n M400 P1500 \n M964 \n T1100 \n G0 F6000 X40.000 Y54.500 Z0.000 \n M960 S0 P1\n M973 S1\n M400 P800\n M971 S6 P0\n M973 S2 P16000\n M400 P500 \n G0 Z0.000 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P1 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P200 \n M971 S5 P3 \n G0 Z0.500 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P2 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P500 \n M971 S5 P4 \n M963 S1 \n M400 P1500 \n M964 \n T1100 \n G1 Z3 F3000 \n\n M400\n M500 ; save cali data\n\n M104 S{nozzle_temperature[initial_extruder]} ; rise nozzle temp now ,to reduce temp waiting time.\n\n T1100 \n M400 P400 \n M960 S0 P0\n G0 F30000.000 Y22.000 X65.000 Z0.000\n M400 P400 \n M960 S1 P1 \n M400 P50 \n\n M969 S1 N3 A2000 \n G0 F360.000 X181.000 Z0.000\n M980.3 A70.000 B{outer_wall_volumetric_speed/(1.75*1.75/4*3.14)*60/4} C5.000 D{outer_wall_volumetric_speed/(1.75*1.75/4*3.14)*60} E5.000 F175.000 H1.000 I0.000 J0.015 K0.030\n M400 P100 \n G0 F20000\n G0 Z1 ; rise nozzle up\n T1000 ; change to nozzle space\n G0 X45.000 Y16.000 F30000 ; move to test line pos\n M969 S0 ; turn off scanning\n M960 S0 P0\n\n\n G1 Z2 F20000 \n T1000 \n G0 X45.000 Y16.000 F30000 E0\n M109 S{nozzle_temperature[initial_extruder]}\n G0 Z0.3\n G1 F1500.000 E3.600 \n G1 X65.000 E2.25000 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60}\n G1 X70.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X75.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X80.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X85.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X90.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X95.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X100.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X105.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X110.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X115.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X120.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X125.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X130.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X135.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60}\n\n ; see if extrude cali success, if not ,use default value\n M1002 judge_last_extrude_cali_success\n M622 J0\n M400\n M900 K0.015 M{outer_wall_volumetric_speed/(1.75*1.75/4*3.14)*0.015}\n M623 \n\n G1 X140.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X145.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X150.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X155.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X160.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X165.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X170.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X175.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X180.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X185.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X190.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X195.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X200.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X205.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X210.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X215.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X220.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X225.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n M973 S4 \n\nM623\n\n;========turn off light and wait extrude temperature =============\nM1002 gcode_claim_action : 0\nM973 S4 ; turn off scanner\nM400 ; wait all motion done before implement the emprical L parameters\n;M900 L500.0 ; Empirical parameters\nM109 S[nozzle_temperature_initial_layer]\nM960 S1 P0 ; turn off laser\nM960 S2 P0 ; turn off laser\nM106 S0 ; turn off fan\nM106 P2 S0 ; turn off big fan \nM106 P3 S0 ; turn off chamber fan\n\nM975 S1 ; turn on mech mode supression\nG90 \nM83\nT1000\nG1 X128.0 Y253.0 Z0.2 F6000.0;Move to start position\nM109 S{nozzle_temperature_initial_layer[initial_extruder]}\nG0 X253 E6.4 F{outer_wall_volumetric_speed/(0.3*0.6) * 60} \nG0 Y128 E6.4\nG0 X252.5\nG0 Y252.5 E6.4\nG0 X128 E6.4" } diff --git a/resources/profiles/BBL/machine/Bambu Lab X1 Carbon 0.8 nozzle.json b/resources/profiles/BBL/machine/Bambu Lab X1 Carbon 0.8 nozzle.json index f8d7c5f77ad..859eeae86bf 100644 --- a/resources/profiles/BBL/machine/Bambu Lab X1 Carbon 0.8 nozzle.json +++ b/resources/profiles/BBL/machine/Bambu Lab X1 Carbon 0.8 nozzle.json @@ -26,5 +26,5 @@ "retraction_minimum_travel": [ "1" ], - "machine_start_gcode": "\n;===== date: 202200710 =====================\n;===== reset machine status =================\nM17 X1.2 Y1.2 Z0.75 ; reset motor current to default\nM960 S5 P1 ; turn on logo lamp\nG90\nM220 S100 ;Reset Feedrate\nM221 S100 ;Reset Flowrate\nM73.2 R1.0 ;Reset left time magnitude\nM1002 set_gcode_claim_speed_level : 5\n\n;===== heatbed preheat ====================\nM1002 gcode_claim_action : 2\n{if bbl_bed_temperature_gcode}\nM1002 set_heatbed_surface_temp:[bed_temperature_initial_layer_vector] ;config bed temps\nM140 A S[bed_temperature_initial_layer_single] ;set bed temp\nM190 A S[bed_temperature_initial_layer_single] ;wait for bed temp\n{else}\nM140 S[bed_temperature_initial_layer_single] ;set bed temp\nM190 S[bed_temperature_initial_layer_single] ;wait for bed temp\n{endif}\n\n{if scan_first_layer}\n;=========register first layer scan=====\nM977 S1 P60\n{endif}\n\n=============turn on fans to prevent PLA jamming=================\n{if filament_type[initial_tool]==\"PLA\"}\n {if (bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}\n M106 P3 S180\n {elsif (bed_temperature[current_extruder] >50)||(bed_temperature_initial_layer[current_extruder] >50)}\n M106 P3 S255\n {endif};Prevent PLA from jamming\n{endif}\nM106 P2 S100 ; turn on big fan ,to cool down toolhead\n\n;===== prepare print temperature and material ==========\nM104 S[nozzle_temperature_initial_layer] ;set extruder temp\nG91\nG0 Z2 F1200\nG90\nG28 X\nM975 S1 ; turn on \nG1 X60 F12000\nG1 Y245\nG1 Y265 F3000\nM620 M\nM620 S[initial_tool]A ; switch material if AMS exist\n M109 S[nozzle_temperature_initial_layer]\n G1 X120 F12000\n\n G1 X20 Y50 F12000\n G1 Y-3\n T[initial_tool]\n G1 X54 F12000\n G1 Y265\n M400\nM621 S[initial_tool]A\n\nM412 S1 ; ===turn on filament runout detection===\n\nM109 S250 ;set nozzle to common flush temp\nM106 P1 S0\nG92 E0\nG1 E50 F200\nM400\nM104 S[nozzle_temperature_initial_layer]\nG92 E0\nG1 E50 F200\nM400\nM106 P1 S255\nG92 E0\nG1 E5 F300\nM109 S{nozzle_temperature_initial_layer[initial_extruder]-20} ; drop nozzle temp, make filament shink a bit\nG92 E0\nG1 E-0.5 F300\n\nG1 X70 F9000\nG1 X76 F15000\nG1 X65 F15000\nG1 X76 F15000\nG1 X65 F15000; shake to put down garbage\nG1 X80 F6000\nG1 X95 F15000\nG1 X80 F15000\nG1 X165 F15000; wipe and shake\nM400\nM106 P1 S0\nM975 S1\n;===== prepare print temperature and material end =====\n\n\n;===== wipe mouth ===============================\nM1002 gcode_claim_action : 14\nM975 S1\nM106 S255\nG1 X65 Y230 F18000\nG1 Y264 F6000\nM109 S{nozzle_temperature_initial_layer[initial_extruder]-20}\nG1 X100 F18000 ; first wipe mouth\n\nG0 X135 Y253 F20000 ; move to exposed steel surface edge\nG28 Z P0 T300; home z with low precision,permit 300deg temperature\nG29.2 S0 ; turn off ABL\nG0 Z2 F20000\n\nG1 X60 Y265\nG92 E0\nG1 E-0.5 F300 ; retrack more\nG1 X100 F5000; second wipe mouth\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X90 F5000\nG0 X128 Y261 Z-1.5 F20000 ; move to exposed steel surface and stop the nozzle\nM104 S140 ; set temp down to heatbed acceptable\nM106 S255 ; turn on fan (G28 has turn off fan)\n\nG0 X126 F120\nG0 X130\nG0 X126\nG0 X130\nG0 X128\nM109 S140 ; wait nozzle temp down to heatbed acceptable\nG1 Z10 F1200\nG1 F30000\nG1 X230 Y15\nG29.2 S1 ; turn on ABL\n;G28 ; home again after hard wipe mouth\nM106 S0 ; turn off fan , too noisy\n;===== wipe mouth end ================================\n\n\n;===== bed leveling ==================================\nM1002 judge_flag g29_before_print_flag\nM622 J1\n\n M1002 gcode_claim_action : 1\n G29 A X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]}\n M400\n M500 ; save cali data\n\nM623\n;===== bed leveling end ================================\n\n;===== home after wipe mouth============================\nM1002 judge_flag g29_before_print_flag\nM622 J0\n\n M1002 gcode_claim_action : 13\n G28\n\nM623\n;===== home after wipe mouth end =======================\n\nM975 S1 ; turn on vibration supression\n\n;===== check scanner clarity ===========================\nM972 S5 P0 \nM400 P500\n;===== check scanner clarity end =======================\n\n=============turn on fans to prevent PLA jamming=================\n{if filament_type[initial_tool]==\"PLA\"}\n {if (bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}\n M106 P3 S180\n {elsif (bed_temperature[current_extruder] >50)||(bed_temperature_initial_layer[current_extruder] >50)}\n M106 P3 S255\n {endif};Prevent PLA from jamming\n{endif}\nM106 P2 S100 ; turn on big fan ,to cool down toolhead\n\n{if scan_first_layer}\n;start heatbed scan====================================\nM976 S2 P1 \nM400 S3\n{endif}\n\nM104 S{nozzle_temperature_initial_layer[initial_extruder]} ; set extrude temp earlier, to reduce wait time\n\n;===== mech mode fast check============================\nG1 X128 Y128 Z5 F20000\nM400 P200\nM970.3 Q1 A7 B30 C80 H15 K0\nM974 Q1 S2 P0\n\nG1 X128 Y128 Z5 F20000\nM400 P200\nM970.3 Q0 A7 B30 C90 Q0 H15 K0\nM974 Q0 S2 P0\n;===== fmech mode fast check============================\n\n\n;===== noozle load line ===============================\nM975 S1\nG90 \nM83\nT1000\nG1 X18.0 Y4.5 Z0.3 F18000;Move to start position\nM109 S{nozzle_temperature_initial_layer[initial_extruder]}\nG0 E3 F300\nG0 X129 E15 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \nG0 X240 E15 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \nG0 Y5.5 \nG0 X129 E15\nG0 X18 E15\nM400\n\n;===== draw extrinsic para cali paint =================\nM1002 judge_flag extrude_cali_flag\nM622 J1\n\n M1002 gcode_claim_action : 8\n\n T1000 \n G0 F3000 X28.000 Y19.500 Z0.200\n G1 F1200.0 X28.000 Y45.000 Z0.200 E1.8660 \n G1 F1200.0 X28.500 Y45.000 Z0.200 E0.0360 \n G1 F1200.0 X28.500 Y19.500 Z0.200 E1.8660 \n G1 F1200.0 X31.000 Y19.500 Z0.200 E0.1820 \n G1 F1200.0 X31.000 Y49.000 Z0.200 E2.1600 \n G1 F1200.0 X37.500 Y49.000 Z0.200 E0.4760 \n G1 F1200.0 X37.500 Y60.000 Z0.200 E0.8060 \n G1 F1200.0 X42.500 Y60.000 Z0.200 E0.3660 \n G1 F1200.0 X42.500 Y49.000 Z0.200 E0.8060 \n G1 F1200.0 X48.000 Y49.000 Z0.200 E0.4020 \n G1 F1200.0 X48.000 Y20.000 Z0.200 E2.1220 \n G1 F1200.0 X30.000 Y20.000 Z0.200 E1.3180 \n G1 F1200.0 X30.000 Y41.000 Z0.200 E1.5380 \n G1 F1200.0 X50.000 Y41.000 Z0.200 E1.4640 \n G1 F1200.0 X50.000 Y34.000 Z0.200 E0.5120 \n G1 F1200.0 X30.000 Y34.000 Z0.200 E1.4640 \n G1 F1500.000 E-0.800 \n\n ;=========== extruder cali extrusion ================== \n\n T1000 \n M83 \n G0 X35.000 Y18.000 Z0.300 F30000 E0\n G1 F1500.000 E0.800 \n M106 S0 ; turn off fan\n G0 X110.000 E9.35441 F4800 \n G0 X185.000 E9.35441 F4800 \n G0 X187 Z0\n G1 F1500.000 E-0.800 \n G0 Z1\n G0 X180 Z0.3 F18000\n \n M900 L1000.0 M1.0\n M900 K0.020 \n G0 X45.000 F30000 \n G0 Y20.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E2.4945 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60}\n G1 X70.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X75.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X80.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X85.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X90.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X95.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X100.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X105.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X110.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X115.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X120.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X125.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X130.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X135.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X140.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X145.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X150.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X155.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X160.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X165.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X170.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X175.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X180.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 F1500.000 E-0.800 \n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n M400\n\n G0 X45.000 F30000 \n M900 K0.010 \n G0 X45.000 F30000 \n G0 Y22.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E2.4945 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60}\n G1 X70.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X75.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X80.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X85.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X90.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X95.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X100.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X105.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X110.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X115.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X120.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X125.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X130.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X135.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X140.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X145.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X150.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X155.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X160.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X165.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X170.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X175.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X180.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 F1500.000 E-0.800 \n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n M400\n\n G0 X45.000 F30000 \n M900 K0.000 \n G0 X45.000 F30000 \n G0 Y24.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E2.4945 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60}\n G1 X70.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X75.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X80.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X85.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X90.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X95.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X100.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X105.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X110.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X115.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X120.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X125.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X130.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X135.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X140.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X145.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X150.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X155.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X160.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X165.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X170.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X175.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X180.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 F1500.000 E-0.800\n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n\n G0 X45.000 F30000 ; move to start point\n\nM623 ; end of \"draw extrinsic para cali paint\"\n\nM104 S140\n\n\n;=========== laser and rgb calibration =========== \nM400\nM18 E\nM500 R\n\nM973 S3 P14\n\nG1 X120 Y5.0 Z0.3 F18000.0;Move to first extrude line pos\nT1100\nG1 X143.0 Y5.0 Z0.3 F18000.0;Move to first extrude line pos\n\nM400 P100\n\nM960 S1 P1\nM400 P100\nM973 S6 ; use auto exposure by xcam\nM960 S0 P0\n\n;=========== handeye calibration ======================\nM1002 judge_flag extrude_cali_flag\nM622 J1\n\n M973 S3 P1 ; camera start stream\n M400 P500\n M973 S1 \n G0 F6000 X40.000 Y54.500 Z0.000 \n M960 S0 P1\n M973 S1\n M400 P800\n M971 S6 P0\n M973 S2 P16000\n M400 P500 \n G0 Z0.000 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P1 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P200 \n M971 S5 P3 \n G0 Z0.500 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P2 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P500 \n M971 S5 P4 \n M963 S1 \n M400 P1500 \n M964 \n T1100 \n G0 F6000 X40.000 Y54.500 Z0.000 \n M960 S0 P1\n M973 S1\n M400 P800\n M971 S6 P0\n M973 S2 P16000\n M400 P500 \n G0 Z0.000 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P1 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P200 \n M971 S5 P3 \n G0 Z0.500 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P2 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P500 \n M971 S5 P4 \n M963 S1 \n M400 P1500 \n M964 \n T1100 \n G1 Z3 F3000 \n\n M400\n M500 ; save cali data\n\n M104 S{nozzle_temperature_initial_layer[initial_extruder]} ; rise nozzle temp now ,to reduce temp waiting time.\n\n T1100 \n M400 P400 \n M960 S0 P0\n G0 F30000.000 Y22.000 X65.000 Z0.000\n M400 P400 \n M960 S1 P1 \n M400 P50 \n\n M969 S1 N3 A2000 \n G0 F360.000 X181.000 Z0.000\n M980.3 A70.000 B{outer_wall_volumetric_speed/(1.75*1.75/4*3.14)*60/4} C5.000 D{outer_wall_volumetric_speed/(1.75*1.75/4*3.14)*60} E5.000 F175.000 H1.000 I0.000 J0.010 K0.020\n M400 P100 \n G0 F20000\n G0 Z1 ; rise nozzle up\n T1000 ; change to nozzle space\n G0 X45.000 Y16.000 F30000 ; move to test line pos\n M969 S0 ; turn off scanning\n M960 S0 P0\n\n\n G1 Z2 F20000 \n T1000 \n G0 X45.000 Y16.000 F30000 E0\n M109 S{nozzle_temperature_initial_layer[initial_extruder]} \n G0 Z0.3\n G1 F1500.000 E3.600 \n G1 X65.000 E2.4945 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60}\n G1 X70.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X75.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X80.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X85.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X90.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X95.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X100.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X105.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X110.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X115.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X120.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X125.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X130.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X135.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60}\n\n ; see if extrude cali success, if not ,use default value\n M1002 judge_last_extrude_cali_success\n M622 J0\n M400\n M900 K0.01 M{outer_wall_volumetric_speed/(1.75*1.75/4*3.14) *0.01}\n M623 \n\n G1 X140.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X145.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X150.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X155.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X160.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X165.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X170.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X175.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X180.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X185.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X190.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X195.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X200.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X205.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X210.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X215.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X220.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X225.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n M973 S4 \n\nM623\n\n;========turn off light and wait extrude temperature =============\nM1002 gcode_claim_action : 0\nM973 S4 ; turn off scanner\nM400 ; wait all motion done before implement the emprical L parameters\n;M900 L500.0 ; Empirical parameters\nM109 S[nozzle_temperature_initial_layer]\nM960 S1 P0 ; turn off laser\nM960 S2 P0 ; turn off laser\nM106 S0 ; turn off fan\nM106 P2 S0 ; turn off big fan \nM106 P3 S0 ; turn off chamber fan\n\nM975 S1 ; turn on mech mode supression\nG90 \nM83\nT1000\nG1 X128.0 Y253.0 Z0.2 F6000.0;Move to start position\nM109 S{nozzle_temperature_initial_layer[initial_extruder]}\nG0 X253 E6.4 F{outer_wall_volumetric_speed/(0.3*0.6) * 60} \nG0 Y128 E6.4\nG0 X252.5\nG0 Y252.5 E6.4\nG0 X128 E6.4" + "machine_start_gcode": "\n;===== date: 202200726 =====================\n;===== reset machine status =================\nG91\nM17 Z0.3 ; lower the z-motor current\nG0 Z7 F300 ; lower the hotbed , to prevent the nozzle is below the hotbed\nG90\nM17 X1.2 Y1.2 Z0.75 ; reset motor current to default\nM960 S5 P1 ; turn on logo lamp\nG90\nM220 S100 ;Reset Feedrate\nM221 S100 ;Reset Flowrate\nM73.2 R1.0 ;Reset left time magnitude\nM1002 set_gcode_claim_speed_level : 5\n\n;===== heatbed preheat ====================\nM1002 gcode_claim_action : 2\n{if bbl_bed_temperature_gcode}\nM1002 set_heatbed_surface_temp:[bed_temperature_initial_layer_vector] ;config bed temps\nM140 A S[bed_temperature_initial_layer_single] ;set bed temp\nM190 A S[bed_temperature_initial_layer_single] ;wait for bed temp\n{else}\nM140 S[bed_temperature_initial_layer_single] ;set bed temp\nM190 S[bed_temperature_initial_layer_single] ;wait for bed temp\n{endif}\n\n{if scan_first_layer}\n;=========register first layer scan=====\nM977 S1 P60\n{endif}\n\n=============turn on fans to prevent PLA jamming=================\n{if filament_type[initial_tool]==\"PLA\"}\n {if (bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}\n M106 P3 S180\n {elsif (bed_temperature[current_extruder] >50)||(bed_temperature_initial_layer[current_extruder] >50)}\n M106 P3 S255\n {endif};Prevent PLA from jamming\n{endif}\nM106 P2 S100 ; turn on big fan ,to cool down toolhead\n\n;===== prepare print temperature and material ==========\nM104 S[nozzle_temperature_initial_layer] ;set extruder temp\nG91\nG0 Z2 F1200\nG90\nG28 X\nM975 S1 ; turn on \nG1 X60 F12000\nG1 Y245\nG1 Y265 F3000\nM620 M\nM620 S[initial_tool]A ; switch material if AMS exist\n M109 S[nozzle_temperature_initial_layer]\n G1 X120 F12000\n\n G1 X20 Y50 F12000\n G1 Y-3\n T[initial_tool]\n G1 X54 F12000\n G1 Y265\n M400\nM621 S[initial_tool]A\n\nM412 S1 ; ===turn on filament runout detection===\n\nM109 S250 ;set nozzle to common flush temp\nM106 P1 S0\nG92 E0\nG1 E50 F200\nM400\nM104 S[nozzle_temperature_initial_layer]\nG92 E0\nG1 E50 F200\nM400\nM106 P1 S255\nG92 E0\nG1 E5 F300\nM109 S{nozzle_temperature_initial_layer[initial_extruder]-20} ; drop nozzle temp, make filament shink a bit\nG92 E0\nG1 E-0.5 F300\n\nG1 X70 F9000\nG1 X76 F15000\nG1 X65 F15000\nG1 X76 F15000\nG1 X65 F15000; shake to put down garbage\nG1 X80 F6000\nG1 X95 F15000\nG1 X80 F15000\nG1 X165 F15000; wipe and shake\nM400\nM106 P1 S0\nM975 S1\n;===== prepare print temperature and material end =====\n\n\n;===== wipe mouth ===============================\nM1002 gcode_claim_action : 14\nM975 S1\nM106 S255\nG1 X65 Y230 F18000\nG1 Y264 F6000\nM109 S{nozzle_temperature_initial_layer[initial_extruder]-20}\nG1 X100 F18000 ; first wipe mouth\n\nG0 X135 Y253 F20000 ; move to exposed steel surface edge\nG28 Z P0 T300; home z with low precision,permit 300deg temperature\nG29.2 S0 ; turn off ABL\nG0 Z2 F20000\n\nG1 X60 Y265\nG92 E0\nG1 E-0.5 F300 ; retrack more\nG1 X100 F5000; second wipe mouth\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X90 F5000\nG0 X128 Y261 Z-1.5 F20000 ; move to exposed steel surface and stop the nozzle\nM104 S140 ; set temp down to heatbed acceptable\nM106 S255 ; turn on fan (G28 has turn off fan)\n\nG0 X126 F120\nG0 X130\nG0 X126\nG0 X130\nG0 X128\nM109 S140 ; wait nozzle temp down to heatbed acceptable\nG1 Z10 F1200\nG1 F30000\nG1 X230 Y15\nG29.2 S1 ; turn on ABL\n;G28 ; home again after hard wipe mouth\nM106 S0 ; turn off fan , too noisy\n;===== wipe mouth end ================================\n\n\n;===== bed leveling ==================================\nM1002 judge_flag g29_before_print_flag\nM622 J1\n\n M1002 gcode_claim_action : 1\n G29 A X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]}\n M400\n M500 ; save cali data\n\nM623\n;===== bed leveling end ================================\n\n;===== home after wipe mouth============================\nM1002 judge_flag g29_before_print_flag\nM622 J0\n\n M1002 gcode_claim_action : 13\n G28\n\nM623\n;===== home after wipe mouth end =======================\n\nM975 S1 ; turn on vibration supression\n\n;===== check scanner clarity ===========================\nM972 S5 P0 \nM400 P500\n;===== check scanner clarity end =======================\n\n=============turn on fans to prevent PLA jamming=================\n{if filament_type[initial_tool]==\"PLA\"}\n {if (bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}\n M106 P3 S180\n {elsif (bed_temperature[current_extruder] >50)||(bed_temperature_initial_layer[current_extruder] >50)}\n M106 P3 S255\n {endif};Prevent PLA from jamming\n{endif}\nM106 P2 S100 ; turn on big fan ,to cool down toolhead\n\n{if scan_first_layer}\n;start heatbed scan====================================\nM976 S2 P1 \nM400 S3\n{endif}\n\nM104 S{nozzle_temperature_initial_layer[initial_extruder]} ; set extrude temp earlier, to reduce wait time\n\n;===== mech mode fast check============================\nG1 X128 Y128 Z5 F20000\nM400 P200\nM970.3 Q1 A7 B30 C80 H15 K0\nM974 Q1 S2 P0\n\nG1 X128 Y128 Z5 F20000\nM400 P200\nM970.3 Q0 A7 B30 C90 Q0 H15 K0\nM974 Q0 S2 P0\n\nG1 F30000\nG1 X230 Y15\nG28 X ; re-home XY \n;===== fmech mode fast check============================\n\n\n;===== noozle load line ===============================\nM975 S1\nG90 \nM83\nT1000\nG1 X18.0 Y4.5 Z0.3 F18000;Move to start position\nM109 S{nozzle_temperature_initial_layer[initial_extruder]}\nG0 E3 F300\nG0 X129 E15 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \nG0 X240 E15 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \nG0 Y5.5 \nG0 X129 E15\nG0 X18 E15\nM400\n\n;===== draw extrinsic para cali paint =================\nM1002 judge_flag extrude_cali_flag\nM622 J1\n\n M1002 gcode_claim_action : 8\n\n T1000 \n G0 F3000 X28.000 Y19.500 Z0.200\n G1 F1200.0 X28.000 Y45.000 Z0.200 E1.8660 \n G1 F1200.0 X28.500 Y45.000 Z0.200 E0.0360 \n G1 F1200.0 X28.500 Y19.500 Z0.200 E1.8660 \n G1 F1200.0 X31.000 Y19.500 Z0.200 E0.1820 \n G1 F1200.0 X31.000 Y49.000 Z0.200 E2.1600 \n G1 F1200.0 X37.500 Y49.000 Z0.200 E0.4760 \n G1 F1200.0 X37.500 Y60.000 Z0.200 E0.8060 \n G1 F1200.0 X42.500 Y60.000 Z0.200 E0.3660 \n G1 F1200.0 X42.500 Y49.000 Z0.200 E0.8060 \n G1 F1200.0 X48.000 Y49.000 Z0.200 E0.4020 \n G1 F1200.0 X48.000 Y20.000 Z0.200 E2.1220 \n G1 F1200.0 X30.000 Y20.000 Z0.200 E1.3180 \n G1 F1200.0 X30.000 Y41.000 Z0.200 E1.5380 \n G1 F1200.0 X50.000 Y41.000 Z0.200 E1.4640 \n G1 F1200.0 X50.000 Y34.000 Z0.200 E0.5120 \n G1 F1200.0 X30.000 Y34.000 Z0.200 E1.4640 \n G1 F1500.000 E-0.800 \n\n ;=========== extruder cali extrusion ================== \n\n T1000 \n M83 \n G0 X35.000 Y18.000 Z0.300 F30000 E0\n G1 F1500.000 E0.800 \n M106 S0 ; turn off fan\n G0 X110.000 E9.35441 F4800 \n G0 X185.000 E9.35441 F4800 \n G0 X187 Z0\n G1 F1500.000 E-0.800 \n G0 Z1\n G0 X180 Z0.3 F18000\n \n M900 L1000.0 M1.0\n M900 K0.020 \n G0 X45.000 F30000 \n G0 Y20.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E2.4945 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60}\n G1 X70.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X75.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X80.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X85.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X90.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X95.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X100.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X105.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X110.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X115.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X120.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X125.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X130.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X135.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X140.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X145.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X150.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X155.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X160.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X165.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X170.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X175.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X180.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 F1500.000 E-0.800 \n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n M400\n\n G0 X45.000 F30000 \n M900 K0.010 \n G0 X45.000 F30000 \n G0 Y22.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E2.4945 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60}\n G1 X70.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X75.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X80.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X85.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X90.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X95.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X100.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X105.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X110.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X115.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X120.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X125.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X130.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X135.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X140.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X145.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X150.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X155.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X160.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X165.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X170.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X175.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X180.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 F1500.000 E-0.800 \n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n M400\n\n G0 X45.000 F30000 \n M900 K0.000 \n G0 X45.000 F30000 \n G0 Y24.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E2.4945 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60}\n G1 X70.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X75.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X80.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X85.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X90.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X95.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X100.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X105.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X110.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X115.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X120.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X125.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X130.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X135.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X140.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X145.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X150.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X155.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X160.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X165.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X170.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X175.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X180.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 F1500.000 E-0.800\n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n\n G0 X45.000 F30000 ; move to start point\n\nM623 ; end of \"draw extrinsic para cali paint\"\n\nM104 S140\n\n\n;=========== laser and rgb calibration =========== \nM400\nM18 E\nM500 R\n\nM973 S3 P14\n\nG1 X120 Y5.0 Z0.3 F18000.0;Move to first extrude line pos\nT1100\nG1 X143.0 Y5.0 Z0.3 F18000.0;Move to first extrude line pos\n\nM400 P100\n\nM960 S1 P1\nM400 P100\nM973 S6 ; use auto exposure by xcam\nM960 S0 P0\n\n;=========== handeye calibration ======================\nM1002 judge_flag extrude_cali_flag\nM622 J1\n\n M973 S3 P1 ; camera start stream\n M400 P500\n M973 S1 \n G0 F6000 X40.000 Y54.500 Z0.000 \n M960 S0 P1\n M973 S1\n M400 P800\n M971 S6 P0\n M973 S2 P16000\n M400 P500 \n G0 Z0.000 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P1 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P200 \n M971 S5 P3 \n G0 Z0.500 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P2 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P500 \n M971 S5 P4 \n M963 S1 \n M400 P1500 \n M964 \n T1100 \n G0 F6000 X40.000 Y54.500 Z0.000 \n M960 S0 P1\n M973 S1\n M400 P800\n M971 S6 P0\n M973 S2 P16000\n M400 P500 \n G0 Z0.000 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P1 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P200 \n M971 S5 P3 \n G0 Z0.500 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P2 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P500 \n M971 S5 P4 \n M963 S1 \n M400 P1500 \n M964 \n T1100 \n G1 Z3 F3000 \n\n M400\n M500 ; save cali data\n\n M104 S{nozzle_temperature_initial_layer[initial_extruder]} ; rise nozzle temp now ,to reduce temp waiting time.\n\n T1100 \n M400 P400 \n M960 S0 P0\n G0 F30000.000 Y22.000 X65.000 Z0.000\n M400 P400 \n M960 S1 P1 \n M400 P50 \n\n M969 S1 N3 A2000 \n G0 F360.000 X181.000 Z0.000\n M980.3 A70.000 B{outer_wall_volumetric_speed/(1.75*1.75/4*3.14)*60/4} C5.000 D{outer_wall_volumetric_speed/(1.75*1.75/4*3.14)*60} E5.000 F175.000 H1.000 I0.000 J0.010 K0.020\n M400 P100 \n G0 F20000\n G0 Z1 ; rise nozzle up\n T1000 ; change to nozzle space\n G0 X45.000 Y16.000 F30000 ; move to test line pos\n M969 S0 ; turn off scanning\n M960 S0 P0\n\n\n G1 Z2 F20000 \n T1000 \n G0 X45.000 Y16.000 F30000 E0\n M109 S{nozzle_temperature_initial_layer[initial_extruder]} \n G0 Z0.3\n G1 F1500.000 E3.600 \n G1 X65.000 E2.4945 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60}\n G1 X70.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X75.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X80.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X85.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X90.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X95.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X100.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X105.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X110.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X115.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X120.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X125.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X130.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X135.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60}\n\n ; see if extrude cali success, if not ,use default value\n M1002 judge_last_extrude_cali_success\n M622 J0\n M400\n M900 K0.01 M{outer_wall_volumetric_speed/(1.75*1.75/4*3.14) *0.01}\n M623 \n\n G1 X140.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X145.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X150.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X155.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X160.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X165.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X170.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X175.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X180.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X185.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X190.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X195.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X200.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X205.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X210.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X215.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X220.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X225.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n M973 S4 \n\nM623\n\n;========turn off light and wait extrude temperature =============\nM1002 gcode_claim_action : 0\nM973 S4 ; turn off scanner\nM400 ; wait all motion done before implement the emprical L parameters\n;M900 L500.0 ; Empirical parameters\nM109 S[nozzle_temperature_initial_layer]\nM960 S1 P0 ; turn off laser\nM960 S2 P0 ; turn off laser\nM106 S0 ; turn off fan\nM106 P2 S0 ; turn off big fan \nM106 P3 S0 ; turn off chamber fan\n\nM975 S1 ; turn on mech mode supression\nG90 \nM83\nT1000\nG1 X128.0 Y253.0 Z0.2 F6000.0;Move to start position\nM109 S{nozzle_temperature_initial_layer[initial_extruder]}\nG0 X253 E6.4 F{outer_wall_volumetric_speed/(0.3*0.6) * 60} \nG0 Y128 E6.4\nG0 X252.5\nG0 Y252.5 E6.4\nG0 X128 E6.4" } diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index a4ba79b662c..f11989634cf 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -696,6 +696,7 @@ static std::map filament_is_high_temp { {"ABS", true}, {"TPU", false}, {"PA", true}, + {"PA-CF", true}, {"PET-CF", true}, {"PC", true}, {"ASA", true}, diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 17dec6b1921..efda105b61a 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -953,13 +953,14 @@ void PrintConfigDef::init_fff_params() def->gui_type = ConfigOptionDef::GUIType::f_enum_open; def->gui_flags = "show_value"; def->enum_values.push_back("PLA"); - def->enum_values.push_back("PET"); def->enum_values.push_back("ABS"); + def->enum_values.push_back("ASA"); + def->enum_values.push_back("PET"); def->enum_values.push_back("TPU"); + def->enum_values.push_back("PC"); def->enum_values.push_back("PA"); + def->enum_values.push_back("PA-CF"); def->enum_values.push_back("PET-CF"); - def->enum_values.push_back("PC"); - def->enum_values.push_back("ASA"); def->enum_values.push_back("PVA"); def->mode = comSimple; def->set_default_value(new ConfigOptionStrings { "PLA" }); From 042e17952cd5a22be5e4fc0c8ab67f127e1f43fc Mon Sep 17 00:00:00 2001 From: "liz.li" Date: Mon, 25 Jul 2022 15:06:30 +0800 Subject: [PATCH 036/180] FIX:GUI cannot response when closing Calibration dialog Change-Id: I576ac47f022bef0d59df168db96be1ef746ce3bb (cherry picked from commit 393d623a8a4a634add6946f3ed7f1c86e962e844) --- src/slic3r/GUI/Calibration.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/slic3r/GUI/Calibration.cpp b/src/slic3r/GUI/Calibration.cpp index 0be5afc22fb..5994566be1b 100644 --- a/src/slic3r/GUI/Calibration.cpp +++ b/src/slic3r/GUI/Calibration.cpp @@ -148,8 +148,6 @@ CalibrationDialog::CalibrationDialog(Plater *plater) Layout(); Fit(); - Bind(wxEVT_CLOSE_WINDOW, [this](wxCloseEvent &evt) { Hide(); }); - m_calibration_btn->Bind(wxEVT_LEFT_DOWN, &CalibrationDialog::on_start_calibration, this); } From 1a8e5295b2a79aea616c8b02abfabeaaf1248891 Mon Sep 17 00:00:00 2001 From: "liz.li" Date: Tue, 26 Jul 2022 16:14:42 +0800 Subject: [PATCH 037/180] ENH:keyboard shortcut in macos 1.fix:global shortcut cannot use in webview panel 2.fix:ban original web-shortcut in webview 3.add cmd+q & cmd+h shortcut in macos 4.move some global shortcut to prepare panel Change-Id: I17ba3c86069dab92df754a319d0c0c3d77b34d74 --- resources/web/homepage/index.html | 29 ++++++ resources/web/homepage/js/home.js | 12 +++ src/slic3r/GUI/GUI_App.cpp | 20 +++++ src/slic3r/GUI/MainFrame.cpp | 145 ++++++++++++++++++------------ 4 files changed, 148 insertions(+), 58 deletions(-) diff --git a/resources/web/homepage/index.html b/resources/web/homepage/index.html index 2d0a4679508..b2f6a246e3b 100644 --- a/resources/web/homepage/index.html +++ b/resources/web/homepage/index.html @@ -142,6 +142,35 @@ diff --git a/resources/web/homepage/js/home.js b/resources/web/homepage/js/home.js index d77a36c00cd..e1bcdd8e8bd 100644 --- a/resources/web/homepage/js/home.js +++ b/resources/web/homepage/js/home.js @@ -215,4 +215,16 @@ function BeginDownloadNetworkPlugin() SendWXMessage( JSON.stringify(tSend) ); } +function OutputKey(keyCode, isCtrlDown, isShiftDown, isCmdDown) { + var tSend = {}; + tSend['sequence_id'] = Math.round(new Date() / 1000); + tSend['command'] = "get_web_shortcut"; + tSend['key_event'] = {}; + tSend['key_event']['key'] = keyCode; + tSend['key_event']['ctrl'] = isCtrlDown; + tSend['key_event']['shift'] = isShiftDown; + tSend['key_event']['cmd'] = isCmdDown; + + SendWXMessage(JSON.stringify(tSend)); +} window.postMessage = HandleStudio; diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index e65a6b239c3..96dbbabf0fa 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -2948,6 +2948,26 @@ std::string GUI_App::handle_web_request(std::string cmd) } else if (command_str.compare("begin_network_plugin_download") == 0) { CallAfter([this] { wxGetApp().ShowDownNetPluginDlg(); }); + } + else if (command_str.compare("get_web_shortcut") == 0) { + if (root.get_child_optional("key_event") != boost::none) { + pt::ptree key_event_node = root.get_child("key_event"); + auto keyCode = key_event_node.get("key"); + auto ctrlKey = key_event_node.get("ctrl"); + auto shiftKey = key_event_node.get("shift"); + auto cmdKey = key_event_node.get("cmd"); + + wxKeyEvent e(wxEVT_CHAR_HOOK); +#ifdef __APPLE__ + e.SetControlDown(cmdKey); +#else + e.SetControlDown(ctrlKey); +#endif + e.SetShiftDown(shiftKey); + e.m_keyCode = keyCode; + e.SetEventObject(mainframe); + wxPostEvent(mainframe, e); + } } } } diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index a5afdd9dc22..4d5181158d7 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -238,52 +238,52 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, BORDERLESS_FRAME_ #endif // _WIN32 // BBS - wxAcceleratorEntry entries[13]; - int index = 0; - entries[index++].Set(wxACCEL_CTRL, (int)'N', wxID_HIGHEST + wxID_NEW); - entries[index++].Set(wxACCEL_CTRL, (int)'O', wxID_HIGHEST + wxID_OPEN); - entries[index++].Set(wxACCEL_CTRL, (int)'S', wxID_HIGHEST + wxID_SAVE); - entries[index++].Set(wxACCEL_CTRL | wxACCEL_SHIFT, (int)'S', wxID_HIGHEST + wxID_SAVEAS); - entries[index++].Set(wxACCEL_CTRL, (int)'X', wxID_HIGHEST + wxID_CUT); - //entries[index++].Set(wxACCEL_CTRL, (int)'I', wxID_HIGHEST + wxID_ADD); - entries[index++].Set(wxACCEL_CTRL, (int)'A', wxID_HIGHEST + wxID_SELECTALL); - entries[index++].Set(wxACCEL_NORMAL, (int)27 /* escape */, wxID_HIGHEST + wxID_CANCEL); - entries[index++].Set(wxACCEL_CTRL, (int)'Z', wxID_HIGHEST + wxID_UNDO); - entries[index++].Set(wxACCEL_CTRL, (int)'Y', wxID_HIGHEST + wxID_REDO); - entries[index++].Set(wxACCEL_CTRL, (int)'C', wxID_HIGHEST + wxID_COPY); - entries[index++].Set(wxACCEL_CTRL, (int)'V', wxID_HIGHEST + wxID_PASTE); - entries[index++].Set(wxACCEL_CTRL, (int)'P', wxID_HIGHEST + wxID_PREFERENCES); - entries[index++].Set(wxACCEL_CTRL, (int)'I', wxID_HIGHEST + wxID_FILE6); - wxAcceleratorTable accel(sizeof(entries) / sizeof(entries[0]), entries); - SetAcceleratorTable(accel); - - Bind(wxEVT_MENU, [this](wxCommandEvent&) { m_plater->new_project(); }, wxID_HIGHEST + wxID_NEW); - Bind(wxEVT_MENU, [this](wxCommandEvent&) { m_plater->load_project(); }, wxID_HIGHEST + wxID_OPEN); - // BBS: close save project - Bind(wxEVT_MENU, [this](wxCommandEvent&) { if (m_plater) m_plater->save_project(); }, wxID_HIGHEST + wxID_SAVE); - Bind(wxEVT_MENU, [this](wxCommandEvent&) { if (m_plater) m_plater->save_project(true); }, wxID_HIGHEST + wxID_SAVEAS); - //Bind(wxEVT_MENU, [this](wxCommandEvent&) { if (m_plater) m_plater->add_model(); }, wxID_HIGHEST + wxID_ADD); - //Bind(wxEVT_MENU, [this](wxCommandEvent&) { m_plater->remove_selected(); }, wxID_HIGHEST + wxID_DELETE); - Bind(wxEVT_MENU, [this](wxCommandEvent&) { - if (!can_add_models()) - return; - if (m_plater) { - m_plater->add_model(); - } - }, wxID_HIGHEST + wxID_FILE6); - Bind(wxEVT_MENU, [this](wxCommandEvent&) { m_plater->select_all(); }, wxID_HIGHEST + wxID_SELECTALL); - Bind(wxEVT_MENU, [this](wxCommandEvent&) { m_plater->deselect_all(); }, wxID_HIGHEST + wxID_CANCEL); - Bind(wxEVT_MENU, [this](wxCommandEvent&) { - if (m_plater->is_view3D_shown()) - m_plater->undo(); - }, wxID_HIGHEST + wxID_UNDO); - Bind(wxEVT_MENU, [this](wxCommandEvent&) { - if (m_plater->is_view3D_shown()) - m_plater->redo(); - }, wxID_HIGHEST + wxID_REDO); - Bind(wxEVT_MENU, [this](wxCommandEvent&) { m_plater->copy_selection_to_clipboard(); }, wxID_HIGHEST + wxID_COPY); - Bind(wxEVT_MENU, [this](wxCommandEvent&) { m_plater->paste_from_clipboard(); }, wxID_HIGHEST + wxID_PASTE); - Bind(wxEVT_MENU, [this](wxCommandEvent&) { m_plater->cut_selection_to_clipboard(); }, wxID_HIGHEST + wxID_CUT); + //wxAcceleratorEntry entries[13]; + //int index = 0; + //entries[index++].Set(wxACCEL_CTRL, (int)'N', wxID_HIGHEST + wxID_NEW); + //entries[index++].Set(wxACCEL_CTRL, (int)'O', wxID_HIGHEST + wxID_OPEN); + //entries[index++].Set(wxACCEL_CTRL, (int)'S', wxID_HIGHEST + wxID_SAVE); + //entries[index++].Set(wxACCEL_CTRL | wxACCEL_SHIFT, (int)'S', wxID_HIGHEST + wxID_SAVEAS); + //entries[index++].Set(wxACCEL_CTRL, (int)'X', wxID_HIGHEST + wxID_CUT); + ////entries[index++].Set(wxACCEL_CTRL, (int)'I', wxID_HIGHEST + wxID_ADD); + //entries[index++].Set(wxACCEL_CTRL, (int)'A', wxID_HIGHEST + wxID_SELECTALL); + //entries[index++].Set(wxACCEL_NORMAL, (int)27 /* escape */, wxID_HIGHEST + wxID_CANCEL); + //entries[index++].Set(wxACCEL_CTRL, (int)'Z', wxID_HIGHEST + wxID_UNDO); + //entries[index++].Set(wxACCEL_CTRL, (int)'Y', wxID_HIGHEST + wxID_REDO); + //entries[index++].Set(wxACCEL_CTRL, (int)'C', wxID_HIGHEST + wxID_COPY); + //entries[index++].Set(wxACCEL_CTRL, (int)'V', wxID_HIGHEST + wxID_PASTE); + //entries[index++].Set(wxACCEL_CTRL, (int)'P', wxID_HIGHEST + wxID_PREFERENCES); + //entries[index++].Set(wxACCEL_CTRL, (int)'I', wxID_HIGHEST + wxID_FILE6); + //wxAcceleratorTable accel(sizeof(entries) / sizeof(entries[0]), entries); + //SetAcceleratorTable(accel); + + //Bind(wxEVT_MENU, [this](wxCommandEvent&) { m_plater->new_project(); }, wxID_HIGHEST + wxID_NEW); + //Bind(wxEVT_MENU, [this](wxCommandEvent&) { m_plater->load_project(); }, wxID_HIGHEST + wxID_OPEN); + //// BBS: close save project + //Bind(wxEVT_MENU, [this](wxCommandEvent&) { if (m_plater) m_plater->save_project(); }, wxID_HIGHEST + wxID_SAVE); + //Bind(wxEVT_MENU, [this](wxCommandEvent&) { if (m_plater) m_plater->save_project(true); }, wxID_HIGHEST + wxID_SAVEAS); + ////Bind(wxEVT_MENU, [this](wxCommandEvent&) { if (m_plater) m_plater->add_model(); }, wxID_HIGHEST + wxID_ADD); + ////Bind(wxEVT_MENU, [this](wxCommandEvent&) { m_plater->remove_selected(); }, wxID_HIGHEST + wxID_DELETE); + //Bind(wxEVT_MENU, [this](wxCommandEvent&) { + // if (!can_add_models()) + // return; + // if (m_plater) { + // m_plater->add_model(); + // } + // }, wxID_HIGHEST + wxID_FILE6); + //Bind(wxEVT_MENU, [this](wxCommandEvent&) { m_plater->select_all(); }, wxID_HIGHEST + wxID_SELECTALL); + //Bind(wxEVT_MENU, [this](wxCommandEvent&) { m_plater->deselect_all(); }, wxID_HIGHEST + wxID_CANCEL); + //Bind(wxEVT_MENU, [this](wxCommandEvent&) { + // if (m_plater->is_view3D_shown()) + // m_plater->undo(); + // }, wxID_HIGHEST + wxID_UNDO); + //Bind(wxEVT_MENU, [this](wxCommandEvent&) { + // if (m_plater->is_view3D_shown()) + // m_plater->redo(); + // }, wxID_HIGHEST + wxID_REDO); + //Bind(wxEVT_MENU, [this](wxCommandEvent&) { m_plater->copy_selection_to_clipboard(); }, wxID_HIGHEST + wxID_COPY); + //Bind(wxEVT_MENU, [this](wxCommandEvent&) { m_plater->paste_from_clipboard(); }, wxID_HIGHEST + wxID_PASTE); + //Bind(wxEVT_MENU, [this](wxCommandEvent&) { m_plater->cut_selection_to_clipboard(); }, wxID_HIGHEST + wxID_CUT); Bind(wxEVT_SIZE, [this](wxSizeEvent&) { BOOST_LOG_TRIVIAL(trace) << "mainframe: size changed, is maximized = " << this->IsMaximized(); if (this->IsMaximized()) { @@ -302,18 +302,18 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, BORDERLESS_FRAME_ }); Bind(EVT_SYNC_CLOUD_PRESET, &MainFrame::on_select_default_preset, this); - Bind(wxEVT_MENU, - [this](wxCommandEvent&) - { - PreferencesDialog dlg(this); - dlg.ShowModal(); -#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER - if (dlg.seq_top_layer_only_changed() || dlg.seq_seq_top_gcode_indices_changed()) -#else - if (dlg.seq_top_layer_only_changed()) -#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER - plater()->refresh_print(); - }, wxID_HIGHEST + wxID_PREFERENCES); +// Bind(wxEVT_MENU, +// [this](wxCommandEvent&) +// { +// PreferencesDialog dlg(this); +// dlg.ShowModal(); +//#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER +// if (dlg.seq_top_layer_only_changed() || dlg.seq_seq_top_gcode_indices_changed()) +//#else +// if (dlg.seq_top_layer_only_changed()) +//#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER +// plater()->refresh_print(); +// }, wxID_HIGHEST + wxID_PREFERENCES); // set default tooltip timer in msec @@ -474,6 +474,35 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, BORDERLESS_FRAME_ Slic3r::run_backup_ui_tasks(); }); ; } + + this->Bind(wxEVT_CHAR_HOOK, [this](wxKeyEvent &evt) { +#ifdef __APPLE__ + if (evt.CmdDown() && evt.GetKeyCode() == 'H') { this->Iconize(); return;} + if (evt.CmdDown() && evt.GetKeyCode() == 'Q') { wxPostEvent(this, wxCloseEvent(wxEVT_CLOSE_WINDOW)); return;} +#endif + if (evt.CmdDown() && evt.GetKeyCode() == 'N') { m_plater->new_project(); return;} + if (evt.CmdDown() && evt.GetKeyCode() == 'O') { m_plater->load_project(); return;} + if (evt.CmdDown() && evt.ShiftDown() && evt.GetKeyCode() == 'S') { if (m_plater) m_plater->save_project(true); return;} + else if (evt.CmdDown() && evt.GetKeyCode() == 'S') { if (m_plater) m_plater->save_project(); return;} + + if (evt.CmdDown() && evt.GetKeyCode() == 'P') { + PreferencesDialog dlg(this); + dlg.ShowModal(); +#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER + if (dlg.seq_top_layer_only_changed() || dlg.seq_seq_top_gcode_indices_changed()) +#else + if (dlg.seq_top_layer_only_changed()) +#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER + plater()->refresh_print(); + return; + } + if (evt.CmdDown() && evt.GetKeyCode() == 'I') { + if (!can_add_models()) return; + if (m_plater) { m_plater->add_model(); } + return; + } + evt.Skip(); + }); } #ifdef __WIN32__ From cc1fb36a22f496201023bc2ced35d96541401c62 Mon Sep 17 00:00:00 2001 From: "chunmao.guo" Date: Wed, 27 Jul 2022 16:55:55 +0800 Subject: [PATCH 038/180] FIX: web view log Change-Id: I8e28d7b8f5cfbc95428a3768b32f312a591e41c1 (cherry picked from commit fe623cb52a449ff7dffb10c9de8d7af9c7651f1e) --- src/slic3r/GUI/MediaPlayCtrl.cpp | 2 +- src/slic3r/GUI/WebGuideDialog.cpp | 2 +- src/slic3r/GUI/Widgets/WebView.cpp | 3 +++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/MediaPlayCtrl.cpp b/src/slic3r/GUI/MediaPlayCtrl.cpp index 110c37c5e75..7218dcb0ec9 100644 --- a/src/slic3r/GUI/MediaPlayCtrl.cpp +++ b/src/slic3r/GUI/MediaPlayCtrl.cpp @@ -230,7 +230,7 @@ void wxMediaCtrl2::DoSetSize(int x, int y, int width, int height, int sizeFlags) size = wxSize{16, 9}; int maxHeight = (width * size.GetHeight() + size.GetHeight() - 1) / size.GetWidth(); if (maxHeight != GetMaxHeight()) { - BOOST_LOG_TRIVIAL(info) << "wxMediaCtrl2::DoSetSize: width: " << width << ", height: " << height << ", maxHeight: " << maxHeight; + // BOOST_LOG_TRIVIAL(info) << "wxMediaCtrl2::DoSetSize: width: " << width << ", height: " << height << ", maxHeight: " << maxHeight; SetMaxSize({-1, maxHeight}); Slic3r::GUI::wxGetApp().CallAfter([this] { if (auto p = GetParent()) { diff --git a/src/slic3r/GUI/WebGuideDialog.cpp b/src/slic3r/GUI/WebGuideDialog.cpp index 65a57cce41f..ab66b63d96a 100644 --- a/src/slic3r/GUI/WebGuideDialog.cpp +++ b/src/slic3r/GUI/WebGuideDialog.cpp @@ -48,7 +48,7 @@ GuideFrame::GuideFrame(GUI_App *pGUI, long style) wxBoxSizer *topsizer = new wxBoxSizer(wxVERTICAL); wxString TargetUrl = SetStartPage(BBL_WELCOME, false); - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", set start page to welcome ") << TargetUrl; + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", set start page to welcome "); // Create the webview m_browser = WebView::CreateWebView(this, TargetUrl); diff --git a/src/slic3r/GUI/Widgets/WebView.cpp b/src/slic3r/GUI/Widgets/WebView.cpp index 6bd59c27e58..c0fadad0f7e 100644 --- a/src/slic3r/GUI/Widgets/WebView.cpp +++ b/src/slic3r/GUI/Widgets/WebView.cpp @@ -65,6 +65,7 @@ wxWebView* WebView::CreateWebView(wxWindow * parent, wxString const & url) url2.Replace("\\", "/"); #endif if (!url2.empty()) { url2 = wxURI(url2).BuildURI(); } + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << url2.ToUTF8(); auto webView = wxWebView::New(); if (webView) { @@ -93,6 +94,7 @@ wxWebView* WebView::CreateWebView(wxWindow * parent, wxString const & url) #endif webView->EnableContextMenu(false); } else { + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": failed. Use fake web view."; webView = new FakeWebView; } return webView; @@ -105,6 +107,7 @@ void WebView::LoadUrl(wxWebView * webView, wxString const &url) url2.Replace("\\", "/"); #endif if (!url2.empty()) { url2 = wxURI(url2).BuildURI(); } + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << url2.ToUTF8(); webView->LoadURL(url2); } From 46a9df509c559e2cfd580dad533584c4f53160c2 Mon Sep 17 00:00:00 2001 From: "chunmao.guo" Date: Wed, 27 Jul 2022 14:11:22 +0800 Subject: [PATCH 039/180] FIX: temp disable markdown tooltip on release build Change-Id: Idde9a5127a064c1b6593607bca122eda21cdeee6 --- src/slic3r/GUI/MarkdownTip.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/slic3r/GUI/MarkdownTip.cpp b/src/slic3r/GUI/MarkdownTip.cpp index dd3e6151ce2..c0c25f51089 100644 --- a/src/slic3r/GUI/MarkdownTip.cpp +++ b/src/slic3r/GUI/MarkdownTip.cpp @@ -293,7 +293,7 @@ MarkdownTip* MarkdownTip::markdownTip(bool create) bool MarkdownTip::ShowTip(std::string const& tip, std::string const & tooltip, wxPoint pos) { -#if BBL_RELEASE_TO_PUBLIC +#ifdef NDEBUG return false; #endif return markdownTip()->ShowTip(pos, tip, tooltip); From 2c61072ec917430f516292bf5523bd63508baf2e Mon Sep 17 00:00:00 2001 From: "yifan.wu" Date: Wed, 27 Jul 2022 17:37:50 +0800 Subject: [PATCH 040/180] FIX: fix incorrect selection after moving an object to new plate Signed-off-by: yifan.wu Change-Id: Ic47a23ca64888f0805c559fff52a50a0812b88b1 (cherry picked from commit d209293fe1409f039c4ec3065a990ce47c9003e8) --- src/slic3r/GUI/GUI_ObjectList.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index ed55b8ad042..162d9fd7523 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -646,6 +646,9 @@ void ObjectList::update_plate_values_for_items() if (plate_idx == old_plate_idx) continue; + // hotfix for wxDataViewCtrl selection not updated after wxDataViewModel::ItemDeleted() + Unselect(item); + bool is_old_parent_expanded = IsExpanded(old_parent); bool is_expanded = IsExpanded(item); m_objects_model->OnPlateChange(plate_idx, item); From 77afdc6467b3ad873bc70bd87054c98e2932f57d Mon Sep 17 00:00:00 2001 From: "lane.wei" Date: Wed, 27 Jul 2022 21:01:19 +0800 Subject: [PATCH 041/180] Fix the preset incorrect issue caused by logout when logout, if the preset selected is still there we should not select it by force, which will cause the edited preset cleaned Change-Id: I930cfcb04eae7473f6bc5f037d26b852013b6f42 --- src/libslic3r/PresetBundle.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libslic3r/PresetBundle.cpp b/src/libslic3r/PresetBundle.cpp index 91c47da20c2..145535eb0cf 100644 --- a/src/libslic3r/PresetBundle.cpp +++ b/src/libslic3r/PresetBundle.cpp @@ -729,7 +729,7 @@ void PresetBundle::remove_users_preset(AppConfig& config) } printers.select_preset_by_name(default_printer_name, true); } else { - printers.select_preset_by_name(printer_selected_preset_name, true); + printers.select_preset_by_name(printer_selected_preset_name, false); } std::string selected_print_name = prints.get_selected_preset().name; @@ -750,7 +750,7 @@ void PresetBundle::remove_users_preset(AppConfig& config) std::string default_print_profile_name = printers.get_selected_preset().config.opt_string("default_print_profile"); prints.select_preset_by_name(default_print_profile_name, true); } else { - prints.select_preset_by_name(selected_print_name, true); + prints.select_preset_by_name(selected_print_name, false); } std::string selected_filament_name = filaments.get_selected_preset().name; @@ -771,7 +771,7 @@ void PresetBundle::remove_users_preset(AppConfig& config) if (prefered_filament_profiles.size() > 0) filaments.select_preset_by_name(prefered_filament_profiles[0], true); } else { - filaments.select_preset_by_name(selected_filament_name, true); + filaments.select_preset_by_name(selected_filament_name, false); } /* set selected preset */ From 461eaa13aa4668cefa67f0a00b312ee85b534047 Mon Sep 17 00:00:00 2001 From: "lane.wei" Date: Wed, 27 Jul 2022 19:45:05 +0800 Subject: [PATCH 042/180] FIX: fix some rendering issues 1. increase the logo's resolution 2. set the logo's height to 0.02 3. fix a clip issue when shell preview Change-Id: Ibd2491c2d4cc38ab10a2627f0024712d0a6a09b2 --- src/slic3r/GUI/GCodeViewer.cpp | 1 - src/slic3r/GUI/PartPlate.cpp | 5 +++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 3a2ec4531ea..5b739dd3db4 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -1070,7 +1070,6 @@ void GCodeViewer::reset() } m_paths_bounding_box = BoundingBoxf3(); m_max_bounding_box = BoundingBoxf3(); - m_shell_bounding_box = BoundingBoxf3(); m_max_print_height = 0.0f; m_tools.m_tool_colors = std::vector(); m_tools.m_tool_visibles = std::vector(); diff --git a/src/slic3r/GUI/PartPlate.cpp b/src/slic3r/GUI/PartPlate.cpp index f90b07ca473..9a63a5cfe82 100644 --- a/src/slic3r/GUI/PartPlate.cpp +++ b/src/slic3r/GUI/PartPlate.cpp @@ -385,7 +385,8 @@ void PartPlate::render_logo(bool bottom) const // starts generating the main texture, compression will run asynchronously GLint max_tex_size = OpenGLManager::get_gl_info().get_max_tex_size(); - if (!m_partplate_list->m_logo_texture.load_from_svg_file(m_partplate_list->m_logo_texture_filename, true, true, true, max_tex_size/8)) { + GLint logo_tex_size = (max_tex_size < 2048)?max_tex_size: 2048; + if (!m_partplate_list->m_logo_texture.load_from_svg_file(m_partplate_list->m_logo_texture_filename, true, true, true, logo_tex_size)) { BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(": load logo texture from %1% failed!")%m_partplate_list->m_logo_texture_filename; return; } @@ -1838,7 +1839,7 @@ bool PartPlate::set_shape(const Pointfs& shape, const Pointfs& exclude_areas, Ve ExPolygon logo_poly; generate_logo_polygon(logo_poly); - if (!m_logo_triangles.set_from_triangles(triangulate_expolygon_2f(logo_poly, NORMALS_UP), GROUND_Z+0.28f)) + if (!m_logo_triangles.set_from_triangles(triangulate_expolygon_2f(logo_poly, NORMALS_UP), GROUND_Z+0.02f)) BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ":Unable to create plate triangles\n"; ExPolygon poly; From a713573544236b81bdc8865ef1d786ee9a462cf4 Mon Sep 17 00:00:00 2001 From: "salt.wei" Date: Wed, 27 Jul 2022 18:19:11 +0800 Subject: [PATCH 043/180] ENH: add extruder offset for X1 and X1 carbon The extruder offset of X1 and X1C is (0,2). All generated gcode should minus this value. Also change the min speed of cooling buffer for better cooling for small area(from pineapple) Signed-off-by: salt.wei Change-Id: I06e58a26f8736ae24fa9da02477a9d19114daeca --- resources/profiles/BBL.json | 2 +- resources/profiles/BBL/filament/Bambu PLA Basic @base.json | 2 +- resources/profiles/BBL/filament/Bambu PLA Matte @base.json | 2 +- resources/profiles/BBL/filament/Generic PETG.json | 2 +- resources/profiles/BBL/filament/Generic PLA.json | 2 +- resources/profiles/BBL/filament/PolyTerra PLA @base.json | 2 +- resources/profiles/BBL/filament/fdm_filament_pla.json | 2 +- resources/profiles/BBL/machine/Bambu Lab X1 0.4 nozzle.json | 3 +++ .../BBL/machine/Bambu Lab X1 Carbon 0.4 nozzle.json | 3 +++ src/slic3r/GUI/Tab.cpp | 6 ++---- 10 files changed, 15 insertions(+), 11 deletions(-) diff --git a/resources/profiles/BBL.json b/resources/profiles/BBL.json index 736e4c08fad..7d9eb5a7e8f 100644 --- a/resources/profiles/BBL.json +++ b/resources/profiles/BBL.json @@ -1,7 +1,7 @@ { "name": "Bambulab", "url": "http://www.bambulab.com/Parameters/vendor/BBL.json", - "version": "01.01.00.13", + "version": "01.01.00.14", "force_update": "0", "description": "the initial version of BBL configurations", "machine_model_list": [ diff --git a/resources/profiles/BBL/filament/Bambu PLA Basic @base.json b/resources/profiles/BBL/filament/Bambu PLA Basic @base.json index 9bb4ae56eb7..d450ad4320a 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Basic @base.json +++ b/resources/profiles/BBL/filament/Bambu PLA Basic @base.json @@ -12,7 +12,7 @@ "25.4" ], "filament_flow_ratio": [ - "0.96" + "0.98" ], "filament_density": [ "1.26" diff --git a/resources/profiles/BBL/filament/Bambu PLA Matte @base.json b/resources/profiles/BBL/filament/Bambu PLA Matte @base.json index f49165d168e..b6001992d9b 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Matte @base.json +++ b/resources/profiles/BBL/filament/Bambu PLA Matte @base.json @@ -15,6 +15,6 @@ "1.32" ], "filament_flow_ratio": [ - "0.95" + "0.98" ] } diff --git a/resources/profiles/BBL/filament/Generic PETG.json b/resources/profiles/BBL/filament/Generic PETG.json index 576fe15b05d..6bc8c202593 100644 --- a/resources/profiles/BBL/filament/Generic PETG.json +++ b/resources/profiles/BBL/filament/Generic PETG.json @@ -28,7 +28,7 @@ "40" ], "slow_down_min_speed": [ - "40" + "20" ], "slow_down_layer_time": [ "8" diff --git a/resources/profiles/BBL/filament/Generic PLA.json b/resources/profiles/BBL/filament/Generic PLA.json index f416abbe76f..cf52396cf4c 100644 --- a/resources/profiles/BBL/filament/Generic PLA.json +++ b/resources/profiles/BBL/filament/Generic PLA.json @@ -7,7 +7,7 @@ "instantiation": "true", "inherits": "fdm_filament_pla", "filament_flow_ratio": [ - "0.95" + "0.98" ], "filament_max_volumetric_speed": [ "12" diff --git a/resources/profiles/BBL/filament/PolyTerra PLA @base.json b/resources/profiles/BBL/filament/PolyTerra PLA @base.json index 96b5f1672b0..40e3785d07d 100644 --- a/resources/profiles/BBL/filament/PolyTerra PLA @base.json +++ b/resources/profiles/BBL/filament/PolyTerra PLA @base.json @@ -15,6 +15,6 @@ "1.24" ], "filament_flow_ratio": [ - "0.95" + "0.98" ] } diff --git a/resources/profiles/BBL/filament/fdm_filament_pla.json b/resources/profiles/BBL/filament/fdm_filament_pla.json index 388268d37ae..a3b8a8f8892 100644 --- a/resources/profiles/BBL/filament/fdm_filament_pla.json +++ b/resources/profiles/BBL/filament/fdm_filament_pla.json @@ -74,7 +74,7 @@ "230" ], "slow_down_min_speed": [ - "50" + "20" ], "slow_down_layer_time": [ "4" diff --git a/resources/profiles/BBL/machine/Bambu Lab X1 0.4 nozzle.json b/resources/profiles/BBL/machine/Bambu Lab X1 0.4 nozzle.json index b82ede4af8b..ea7a12b487f 100644 --- a/resources/profiles/BBL/machine/Bambu Lab X1 0.4 nozzle.json +++ b/resources/profiles/BBL/machine/Bambu Lab X1 0.4 nozzle.json @@ -13,6 +13,9 @@ "nozzle_diameter": [ "0.4" ], + "extruder_offset": [ + "0x2" + ], "bed_exclude_area": [ "0x0", "18x0", diff --git a/resources/profiles/BBL/machine/Bambu Lab X1 Carbon 0.4 nozzle.json b/resources/profiles/BBL/machine/Bambu Lab X1 Carbon 0.4 nozzle.json index 12540a4416e..ce65957dd96 100644 --- a/resources/profiles/BBL/machine/Bambu Lab X1 Carbon 0.4 nozzle.json +++ b/resources/profiles/BBL/machine/Bambu Lab X1 Carbon 0.4 nozzle.json @@ -13,6 +13,9 @@ "nozzle_diameter": [ "0.4" ], + "extruder_offset": [ + "0x2" + ], "bed_exclude_area": [ "0x0", "18x0", diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 6fd2a3fa027..638c7f18d7f 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -3173,10 +3173,8 @@ void TabPrinter::build_unregular_pages(bool from_initial_build/* = false*/) optgroup->append_single_option_line("min_layer_height", "", extruder_idx); optgroup->append_single_option_line("max_layer_height", "", extruder_idx); -#if 0 - //optgroup = page->new_optgroup(L("Position (for multi-extruder printers)"), -1, true); - //optgroup->append_single_option_line("extruder_offset", "", extruder_idx); -#endif + optgroup = page->new_optgroup(L("Position"), -1, true); + optgroup->append_single_option_line("extruder_offset", "", extruder_idx); //BBS: don't show retract related config menu in machine page optgroup = page->new_optgroup(L("Retraction")); From a0e2e1e62de28f57d59df2190f1ab03966f590e1 Mon Sep 17 00:00:00 2001 From: "xiangdong.yang" Date: Mon, 25 Jul 2022 09:50:52 +0800 Subject: [PATCH 044/180] FIX:fix keypad ICONS not being centered Change-Id: I2b20a2f9b95a1970802b51c7dc51d96ece91fce6 (cherry picked from commit bf348670711467f9092f29ddccc8d5eb03dcc18e) --- src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp | 5 ++++- src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp | 6 ++++-- src/slic3r/GUI/Gizmos/GLGizmosManager.cpp | 5 +++++ src/slic3r/GUI/Gizmos/GLGizmosManager.hpp | 2 ++ 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp index 170673cd408..421ef618fb9 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp @@ -395,7 +395,10 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(6.0f, 10.0f)); float get_cur_y = ImGui::GetContentRegionMax().y + ImGui::GetFrameHeight() + y; show_tooltip_information(caption_max, x, get_cur_y); - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(6.0f, 5.0f)); + + float f_scale =m_parent.get_gizmos_manager().get_layout_scale(); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(6.0f, 4.0f * f_scale)); + ImGui::SameLine(); // Perform button is for gap fill diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp index 30f7e2a02b7..be7a28e2fde 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp @@ -601,10 +601,12 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott ImGui::Separator(); ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(6.0f, 10.0f)); - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(6.0f, 5.0f)); - float get_cur_y = ImGui::GetContentRegionMax().y + ImGui::GetFrameHeight() + y; show_tooltip_information(caption_max, x, get_cur_y); + + float f_scale =m_parent.get_gizmos_manager().get_layout_scale(); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(6.0f, 4.0f * f_scale)); + ImGui::SameLine(); if (m_current_tool == ImGui::GapFillIcon) { diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp index 7f33b1dece2..1ef16b53bfe 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp @@ -199,6 +199,11 @@ bool GLGizmosManager::init_icon_textures() return true; } +float GLGizmosManager::get_layout_scale() +{ + return m_layout.scale; +} + bool GLGizmosManager::init_arrow(const BackgroundTexture::Metadata& arrow_texture) { if (m_arrow_texture.texture.get_id() != 0) diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp index 5b7bbfd8459..11c0ff07571 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp @@ -159,6 +159,8 @@ class GLGizmosManager : public Slic3r::ObjectBase bool init_icon_textures(); + float get_layout_scale(); + bool init_arrow(const BackgroundTexture::Metadata& arrow_texture); template From 45d2081a0880a4db8ed386b0b8b5abc88afc6520 Mon Sep 17 00:00:00 2001 From: Stone Li Date: Wed, 27 Jul 2022 17:27:36 +0800 Subject: [PATCH 045/180] FIX: fix crash when return HTTP 401 cause: we call wx widget before GUI_App Created set_on_http_error_fn in post_init() Change-Id: I1fcec76bc9472288315b3cc29c651a929fcc749d Signed-off-by: Stone Li --- src/slic3r/GUI/GUI_App.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 96dbbabf0fa..4a49333556c 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -1066,6 +1066,9 @@ void GUI_App::post_init() }); } ); + m_agent->set_on_http_error_fn([this](unsigned int status, std::string body) { + this->handle_http_error(status, body); + }); m_agent->start_discovery(true, false); } @@ -1421,6 +1424,9 @@ void GUI_App::restart_networking() }); } ); + m_agent->set_on_http_error_fn([this](unsigned int status, std::string body) { + this->handle_http_error(status, body); + }); m_agent->start_discovery(true, false); if (mainframe) mainframe->refresh_plugin_tips(); @@ -1539,10 +1545,6 @@ void GUI_App::init_networking_callbacks() } ); - m_agent->set_on_http_error_fn([this](unsigned int status, std::string body) { - this->handle_http_error(status, body); - }); - auto message_arrive_fn = [this](std::string dev_id, std::string msg) { CallAfter([this, dev_id, msg] { if (m_is_closing) { From 654dd34652aa271e38f16cfdef8300f8bf98ca30 Mon Sep 17 00:00:00 2001 From: Stone Li Date: Thu, 28 Jul 2022 11:53:23 +0800 Subject: [PATCH 046/180] ENH: disable buttons when printing job is finished Change-Id: Ic3ead6c1204ca30e4478db63cff12ca070790db2 Signed-off-by: Stone Li --- src/slic3r/GUI/StatusPanel.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/StatusPanel.cpp b/src/slic3r/GUI/StatusPanel.cpp index 69f2a35836b..78fe307fbda 100644 --- a/src/slic3r/GUI/StatusPanel.cpp +++ b/src/slic3r/GUI/StatusPanel.cpp @@ -1556,8 +1556,13 @@ void StatusPanel::update_subtask(MachineObject *obj) m_button_pause_resume->SetLabel(_L("Resume")); else m_button_pause_resume->SetLabel(_L("Pause")); - m_button_abort->Enable(true); - m_button_pause_resume->Enable(true); + if (obj->print_status == "FINISH") { + m_button_abort->Enable(false); + m_button_pause_resume->Enable(false); + } else { + m_button_abort->Enable(true); + m_button_pause_resume->Enable(true); + } // update printing stage m_printing_stage_value->SetLabelText(obj->get_curr_stage()); update_left_time(obj->mc_left_time); From 396918f21f2a60208a7d25e7af3f9642de962835 Mon Sep 17 00:00:00 2001 From: "chunmao.guo" Date: Wed, 27 Jul 2022 10:36:34 +0800 Subject: [PATCH 047/180] FIX: background color of text ctrl when disabled Change-Id: I904a6ea78a692e2f511857d908c98ffa8f8b1bc8 --- src/slic3r/GUI/Widgets/SpinInput.cpp | 1 + src/slic3r/GUI/Widgets/TextInput.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/src/slic3r/GUI/Widgets/SpinInput.cpp b/src/slic3r/GUI/Widgets/SpinInput.cpp index 52a1eeb522b..e68806040cf 100644 --- a/src/slic3r/GUI/Widgets/SpinInput.cpp +++ b/src/slic3r/GUI/Widgets/SpinInput.cpp @@ -157,6 +157,7 @@ bool SpinInput::Enable(bool enable) wxCommandEvent e(EVT_ENABLE_CHANGED); e.SetEventObject(this); GetEventHandler()->ProcessEvent(e); + text_ctrl->SetBackgroundColour(background_color.colorForStates(state_handler.states())); } return result; } diff --git a/src/slic3r/GUI/Widgets/TextInput.cpp b/src/slic3r/GUI/Widgets/TextInput.cpp index 82c90b171f4..473e02c3d6c 100644 --- a/src/slic3r/GUI/Widgets/TextInput.cpp +++ b/src/slic3r/GUI/Widgets/TextInput.cpp @@ -150,6 +150,7 @@ bool TextInput::Enable(bool enable) wxCommandEvent e(EVT_ENABLE_CHANGED); e.SetEventObject(this); GetEventHandler()->ProcessEvent(e); + text_ctrl->SetBackgroundColour(background_color.colorForStates(state_handler.states())); } return result; } From 0ac982b8c26b192a6a238e55b0251ffcb44906be Mon Sep 17 00:00:00 2001 From: "chunmao.guo" Date: Wed, 27 Jul 2022 16:16:43 +0800 Subject: [PATCH 048/180] FIX: invert touchpad move direction Change-Id: Ic6be977828a1c82a56205c06d4ab63c05241a090 --- src/slic3r/Utils/MacDarkMode.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/slic3r/Utils/MacDarkMode.mm b/src/slic3r/Utils/MacDarkMode.mm index 040bebc2fd3..b5572a4e03f 100644 --- a/src/slic3r/Utils/MacDarkMode.mm +++ b/src/slic3r/Utils/MacDarkMode.mm @@ -162,7 +162,7 @@ - (void) scrollWheel2:(NSEvent *)event { if (_gestureHandler && event.hasPreciseScrollingDeltas) { wxPanGestureEvent evt; - evt.SetDelta({(int)[event scrollingDeltaX], -(int)[event scrollingDeltaY]}); + evt.SetDelta({-(int)[event scrollingDeltaX], (int)[event scrollingDeltaY]}); _gestureHandler->ProcessEvent(evt); } else { [self scrollWheel2: event]; From e7f379f4dee53bc40533d369c0af660f2598fbbf Mon Sep 17 00:00:00 2001 From: "salt.wei" Date: Thu, 28 Jul 2022 14:04:04 +0800 Subject: [PATCH 049/180] ENH: change spiral mode to be spiral vase Signed-off-by: salt.wei Change-Id: I3df7e0534c6b8e899c145a1b9ee199eeeaad54d0 --- src/libslic3r/PrintConfig.cpp | 2 +- src/slic3r/GUI/GCodeViewer.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index efda105b61a..6033d3fd08f 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -1973,7 +1973,7 @@ void PrintConfigDef::init_fff_params() def->set_default_value(new ConfigOptionFloat(100)); def = this->add("spiral_mode", coBool); - def->label = L("Spiral mode"); + def->label = L("Spiral vase"); def->tooltip = L("Spiralize smooths out the z moves of the outer contour. " "And turns a solid model into a single walled print with solid bottom layers. " "The final generated model has no seam"); diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 5b739dd3db4..184e328a449 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -4422,7 +4422,7 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv }; const bool visible = m_buffers[buffer_id(type)].visible; if (type == EMoveType::Travel) { - //TODO display travel time, salt.wei + //TODO display travel time append_option_item_with_type(type, Travel_Colors[0], _u8L("Travel"), visible); } else if (type == EMoveType::Seam) From 8c39e3f6f561ec550da384340a6af428c7d571b9 Mon Sep 17 00:00:00 2001 From: tao wang Date: Thu, 28 Jul 2022 10:57:55 +0800 Subject: [PATCH 050/180] FIX:fixed scrolling too slow of parameter search scroll bar Change-Id: I9999df7329545ef8ca8337c16db1d1ec722c728d --- src/slic3r/GUI/Widgets/Scrollbar.cpp | 9 ++++++--- src/slic3r/GUI/Widgets/Scrollbar.hpp | 1 + 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/slic3r/GUI/Widgets/Scrollbar.cpp b/src/slic3r/GUI/Widgets/Scrollbar.cpp index 2eac9f1bf8e..b71390b833c 100644 --- a/src/slic3r/GUI/Widgets/Scrollbar.cpp +++ b/src/slic3r/GUI/Widgets/Scrollbar.cpp @@ -270,10 +270,13 @@ void MyScrollbar::OnMouseWheel(wxMouseEvent &event) { int dMotion, actualDim; if (event.GetWheelRotation() > 0) - dMotion = -m_pixelsPerUnit; + //dMotion = -m_pixelsPerUnit; + dMotion = -SCROLL_D_MOTION; else - dMotion = m_pixelsPerUnit; - m_previousMouse += dMotion; + // dMotion = m_pixelsPerUnit; + dMotion = SCROLL_D_MOTION; + + //m_previousMouse += dMotion; actualDim = m_actualDim; if (m_direction == wxVSCROLL) diff --git a/src/slic3r/GUI/Widgets/Scrollbar.hpp b/src/slic3r/GUI/Widgets/Scrollbar.hpp index eab7aaa77ee..9b00eaedca4 100644 --- a/src/slic3r/GUI/Widgets/Scrollbar.hpp +++ b/src/slic3r/GUI/Widgets/Scrollbar.hpp @@ -9,6 +9,7 @@ #endif enum {BEFORE_SCROLLBAR, ON_SCROLLBAR, AFTER_SCROLLBAR, NOWHERE}; +#define SCROLL_D_MOTION 4 class ScrolledWindow; From ddee1dacafc39d3ee6948067d307ef79f86dc478 Mon Sep 17 00:00:00 2001 From: "chunmao.guo" Date: Wed, 27 Jul 2022 16:16:43 +0800 Subject: [PATCH 051/180] FIX: modify touchpad translate in Canvas3D 1. invert touchpad move direction 2. fix canvas 3d move with rotation 3. press shift for move Change-Id: I9c7f39eba45a168c92d4459cd88896d26ec6e8db --- src/slic3r/GUI/GLCanvas3D.cpp | 7 +++++-- src/slic3r/Utils/MacDarkMode.mm | 5 +++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 2a28b633cf9..8b38dabbec3 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2952,9 +2952,12 @@ void GLCanvas3D::on_gesture(wxGestureEvent &evt) auto & camera = wxGetApp().plater()->get_camera(); if (evt.GetEventType() == wxEVT_GESTURE_PAN) { + auto p = evt.GetPosition(); auto d = static_cast(evt).GetDelta(); - Vec3d delta{(double) d.x, (double) d.y, 0}; - camera.set_target(camera.get_target() + delta); + float z = 0; + const Vec3d &p2 = _mouse_to_3d({p.x, p.y}, &z); + const Vec3d &p1 = _mouse_to_3d({p.x - d.x, p.y - d.y}, &z); + camera.set_target(camera.get_target() + p2 - p1); } else if (evt.GetEventType() == wxEVT_GESTURE_ZOOM) { static float zoom_start = 1; if (evt.IsGestureStart()) diff --git a/src/slic3r/Utils/MacDarkMode.mm b/src/slic3r/Utils/MacDarkMode.mm index b5572a4e03f..de6808328c4 100644 --- a/src/slic3r/Utils/MacDarkMode.mm +++ b/src/slic3r/Utils/MacDarkMode.mm @@ -160,9 +160,10 @@ - (void) postEvent: (wxGestureEvent &) evt withGesture: (NSGestureRecognizer* ) - (void) scrollWheel2:(NSEvent *)event { - if (_gestureHandler && event.hasPreciseScrollingDeltas) { + bool shiftDown = [event modifierFlags] & NSShiftKeyMask; + if (_gestureHandler && shiftDown && event.hasPreciseScrollingDeltas) { wxPanGestureEvent evt; - evt.SetDelta({-(int)[event scrollingDeltaX], (int)[event scrollingDeltaY]}); + evt.SetDelta({-(int)[event scrollingDeltaX], - (int)[event scrollingDeltaY]}); _gestureHandler->ProcessEvent(evt); } else { [self scrollWheel2: event]; From 9f062905b274c20e3f46be36f28a9849476a45b1 Mon Sep 17 00:00:00 2001 From: Stone Li Date: Thu, 28 Jul 2022 16:51:24 +0800 Subject: [PATCH 052/180] FIX: fix unparsable character when saving 3mf MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit bbl cloud can not parse character '&’ use xml_escape to convert to xml format Change-Id: I9a2c0abb3c80c26be6f3add507c133f72b2bf7d1 Signed-off-by: Stone Li --- src/libslic3r/Format/bbs_3mf.cpp | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src/libslic3r/Format/bbs_3mf.cpp b/src/libslic3r/Format/bbs_3mf.cpp index 95f9b87f2c1..be32d061554 100644 --- a/src/libslic3r/Format/bbs_3mf.cpp +++ b/src/libslic3r/Format/bbs_3mf.cpp @@ -3755,7 +3755,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) bool _add_project_config_file_to_archive(mz_zip_archive& archive, const DynamicPrintConfig &config, Model& model); //BBS: add project embedded preset files bool _add_project_embedded_presets_to_archive(mz_zip_archive& archive, Model& model, std::vector project_presets); - bool _add_model_config_file_to_archive(mz_zip_archive& archive, const Model& model, PlateDataPtrs& plate_data_list, const IdToObjectDataMap &objects_data, int export_plate_idx = -1); + bool _add_model_config_file_to_archive(mz_zip_archive& archive, const Model& model, PlateDataPtrs& plate_data_list, const IdToObjectDataMap &objects_data, int export_plate_idx = -1, bool save_gcode = true); bool _add_slice_info_config_file_to_archive(mz_zip_archive& archive, const Model& model, PlateDataPtrs& plate_data_list); bool _add_gcode_file_to_archive(mz_zip_archive& archive, const Model& model, PlateDataPtrs& plate_data_list, Export3mfProgressFn proFn = nullptr); bool _add_custom_gcode_per_print_z_file_to_archive(mz_zip_archive& archive, Model& model, const DynamicPrintConfig* config); @@ -4093,7 +4093,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) // This file contains all the attributes of all ModelObjects and their ModelVolumes (names, parameter overrides). // As there is just a single Indexed Triangle Set data stored per ModelObject, offsets of volumes into their respective Indexed Triangle Set data // is stored here as well. - if (!_add_model_config_file_to_archive(archive, model, plate_data_list, objects_data, export_plate_idx)) { + if (!_add_model_config_file_to_archive(archive, model, plate_data_list, objects_data, export_plate_idx, m_save_gcode)) { BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ":" << __LINE__ << boost::format(", _add_model_config_file_to_archive failed\n"); return false; } @@ -4414,13 +4414,13 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) region_code = project->project_country_code; } - stream << " <" << METADATA_TAG << " name=\"" << BBL_MODEL_NAME_TAG << "\">" << name << "\n"; - stream << " <" << METADATA_TAG << " name=\"" << BBL_DESIGNER_TAG << "\">" << user_name << "\n"; - stream << " <" << METADATA_TAG << " name=\"" << BBL_DESIGNER_USER_ID_TAG << "\">" << user_id << "\n"; - stream << " <" << METADATA_TAG << " name=\"" << BBL_DESIGNER_COVER_FILE_TAG << "\">" << design_cover << "\n"; - stream << " <" << METADATA_TAG << " name=\"" << BBL_DESCRIPTION_TAG << "\">" << description << "\n"; - stream << " <" << METADATA_TAG << " name=\"" << BBL_COPYRIGHT_TAG << "\">" << copyright << "\n"; - stream << " <" << METADATA_TAG << " name=\"" << BBL_LICENSE_TAG << "\">" << license << "\n"; + stream << " <" << METADATA_TAG << " name=\"" << BBL_MODEL_NAME_TAG << "\">" << xml_escape(name) << "\n"; + stream << " <" << METADATA_TAG << " name=\"" << BBL_DESIGNER_TAG << "\">" << xml_escape(user_name) << "\n"; + stream << " <" << METADATA_TAG << " name=\"" << BBL_DESIGNER_USER_ID_TAG << "\">" << user_id << "\n"; + stream << " <" << METADATA_TAG << " name=\"" << BBL_DESIGNER_COVER_FILE_TAG << "\">" << xml_escape(design_cover) << "\n"; + stream << " <" << METADATA_TAG << " name=\"" << BBL_DESCRIPTION_TAG << "\">" << xml_escape(description) << "\n"; + stream << " <" << METADATA_TAG << " name=\"" << BBL_COPYRIGHT_TAG << "\">" << xml_escape(copyright) << "\n"; + stream << " <" << METADATA_TAG << " name=\"" << BBL_LICENSE_TAG << "\">" << xml_escape(license) << "\n"; /* save model info */ if (!model_id.empty()) { @@ -5199,7 +5199,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) return true; } - bool _BBS_3MF_Exporter::_add_model_config_file_to_archive(mz_zip_archive& archive, const Model& model, PlateDataPtrs& plate_data_list, const IdToObjectDataMap &objects_data, int export_plate_idx) + bool _BBS_3MF_Exporter::_add_model_config_file_to_archive(mz_zip_archive& archive, const Model& model, PlateDataPtrs& plate_data_list, const IdToObjectDataMap &objects_data, int export_plate_idx, bool save_gcode) { std::stringstream stream; // Store mesh transformation in full precision, as the volumes are stored transformed and they need to be transformed back @@ -5324,7 +5324,8 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) //plate index stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << PLATERID_ATTR << "\" " << VALUE_ATTR << "=\"" << plate_data->plate_index + 1 << "\"/>\n"; stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << LOCK_ATTR << "\" " << VALUE_ATTR << "=\"" << std::boolalpha<< plate_data->locked<< "\"/>\n"; - stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << GCODE_FILE_ATTR << "\" " << VALUE_ATTR << "=\"" << std::boolalpha << plate_data->gcode_file << "\"/>\n"; + if (save_gcode) + stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << GCODE_FILE_ATTR << "\" " << VALUE_ATTR << "=\"" << std::boolalpha << xml_escape(plate_data->gcode_file) << "\"/>\n"; if (!plate_data->gcode_file.empty()) { gcode_paths.push_back(plate_data->gcode_file); } @@ -5363,8 +5364,10 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) stream << " \n"; } } + // write model rels - _add_relationships_file_to_archive(archive, BBS_MODEL_CONFIG_RELS_FILE, gcode_paths, {"http://schemas.bambulab.com/package/2021/gcode"}, Slic3r::PackingTemporaryData(), export_plate_idx); + if (save_gcode) + _add_relationships_file_to_archive(archive, BBS_MODEL_CONFIG_RELS_FILE, gcode_paths, {"http://schemas.bambulab.com/package/2021/gcode"}, Slic3r::PackingTemporaryData(), export_plate_idx); //BBS: store assemble related info stream << " <" << ASSEMBLE_TAG << ">\n"; From 00ba5157833e805cebe4a25922e8837ca7df7296 Mon Sep 17 00:00:00 2001 From: "chunmao.guo" Date: Tue, 26 Jul 2022 17:28:49 +0800 Subject: [PATCH 053/180] FIX: use scaled icon in MacOS Change-Id: Ic7e89a3ff1dd92818adfcec410cc0bdcacfc0398 --- src/slic3r/GUI/Widgets/Button.cpp | 6 +++--- src/slic3r/GUI/Widgets/DropDown.cpp | 2 +- src/slic3r/GUI/Widgets/SideButton.cpp | 4 ++-- src/slic3r/GUI/Widgets/TextInput.cpp | 2 +- src/slic3r/Utils/MacDarkMode.mm | 12 ++++++------ 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/slic3r/GUI/Widgets/Button.cpp b/src/slic3r/GUI/Widgets/Button.cpp index 0a21b74f024..b7abb2412bc 100644 --- a/src/slic3r/GUI/Widgets/Button.cpp +++ b/src/slic3r/GUI/Widgets/Button.cpp @@ -162,7 +162,7 @@ void Button::render(wxDC& dc) //BBS norrow size between text and icon szContent.x += padding; } - szIcon = icon.bmp().GetSize(); + szIcon = icon.GetBmpSize(); szContent.x += szIcon.x; if (szIcon.y > szContent.y) szContent.y = szIcon.y; @@ -211,7 +211,7 @@ void Button::messureSize() //BBS norrow size between text and icon szContent.x += 5; } - wxSize szIcon = this->active_icon.bmp().GetSize(); + wxSize szIcon = this->active_icon.GetBmpSize(); szContent.x += szIcon.x; if (szIcon.y > szContent.y) szContent.y = szIcon.y; @@ -246,4 +246,4 @@ void Button::sendButtonEvent() wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, GetId()); event.SetEventObject(this); GetEventHandler()->ProcessEvent(event); -} \ No newline at end of file +} diff --git a/src/slic3r/GUI/Widgets/DropDown.cpp b/src/slic3r/GUI/Widgets/DropDown.cpp index 9e15c77e31e..a0cdc6338a1 100644 --- a/src/slic3r/GUI/Widgets/DropDown.cpp +++ b/src/slic3r/GUI/Widgets/DropDown.cpp @@ -233,7 +233,7 @@ void DropDown::render(wxDC &dc) rcContent.x += 5; rcContent.width -= 5; if (check_bitmap.bmp().IsOk()) { - auto szBmp = check_bitmap.bmp().GetSize(); + auto szBmp = check_bitmap.GetBmpSize(); if (selection >= 0) { wxPoint pt = rcContent.GetLeftTop(); pt.y += (rcContent.height - szBmp.y) / 2; diff --git a/src/slic3r/GUI/Widgets/SideButton.cpp b/src/slic3r/GUI/Widgets/SideButton.cpp index 4252a991346..3d85ae18470 100644 --- a/src/slic3r/GUI/Widgets/SideButton.cpp +++ b/src/slic3r/GUI/Widgets/SideButton.cpp @@ -232,7 +232,7 @@ void SideButton::render(wxDC& dc) //BBS norrow size between text and icon szContent.x += 5; } - szIcon = icon.bmp().GetSize(); + szIcon = icon.GetBmpSize(); szContent.x += szIcon.x; if (szIcon.y > szContent.y) szContent.y = szIcon.y; @@ -284,7 +284,7 @@ void SideButton::messureSize() if (szContent.y > 0) { szContent.x += 5; } - wxSize szIcon = this->icon.bmp().GetSize(); + wxSize szIcon = this->icon.GetBmpSize(); szContent.x += szIcon.x; if (szIcon.y > szContent.y) szContent.y = szIcon.y; diff --git a/src/slic3r/GUI/Widgets/TextInput.cpp b/src/slic3r/GUI/Widgets/TextInput.cpp index 473e02c3d6c..a54fe984dda 100644 --- a/src/slic3r/GUI/Widgets/TextInput.cpp +++ b/src/slic3r/GUI/Widgets/TextInput.cpp @@ -174,7 +174,7 @@ void TextInput::DoSetSize(int x, int y, int width, int height, int sizeFlags) wxSize size = GetSize(); wxPoint textPos = {5, 0}; if (this->icon.bmp().IsOk()) { - wxSize szIcon = this->icon.bmp().GetSize(); + wxSize szIcon = this->icon.GetBmpSize(); textPos.x += szIcon.x; } bool align_right = GetWindowStyle() & wxRIGHT; diff --git a/src/slic3r/Utils/MacDarkMode.mm b/src/slic3r/Utils/MacDarkMode.mm index de6808328c4..7e704221601 100644 --- a/src/slic3r/Utils/MacDarkMode.mm +++ b/src/slic3r/Utils/MacDarkMode.mm @@ -26,12 +26,12 @@ bool mac_dark_mode() double mac_max_scaling_factor() { double scaling = 1.; -// if ([NSScreen screens] == nil) { -// scaling = [[NSScreen mainScreen] backingScaleFactor]; -// } else { -// for (int i = 0; i < [[NSScreen screens] count]; ++ i) -// scaling = std::max(scaling, [[[NSScreen screens] objectAtIndex:0] backingScaleFactor]); -// } + if ([NSScreen screens] == nil) { + scaling = [[NSScreen mainScreen] backingScaleFactor]; + } else { + for (int i = 0; i < [[NSScreen screens] count]; ++ i) + scaling = std::max(scaling, [[[NSScreen screens] objectAtIndex:0] backingScaleFactor]); + } return scaling; } From 9fc010512c621b8a239aa89cff28e1ca3a2d3910 Mon Sep 17 00:00:00 2001 From: tao wang Date: Wed, 27 Jul 2022 17:40:07 +0800 Subject: [PATCH 054/180] FIX:use scalablebitmap replace wxbitmap Change-Id: I4ca885051f309be4a7d9a6e08de097fe75847257 --- src/slic3r/GUI/AboutDialog.cpp | 10 ++-- src/slic3r/GUI/AboutDialog.hpp | 2 +- src/slic3r/GUI/Auxiliary.cpp | 32 ++++++------- src/slic3r/GUI/Auxiliary.hpp | 6 +-- src/slic3r/GUI/CameraPopup.cpp | 16 +++---- src/slic3r/GUI/CameraPopup.hpp | 8 ++-- src/slic3r/GUI/SelectMachine.cpp | 47 +++++++++--------- src/slic3r/GUI/SelectMachine.hpp | 17 ++++--- src/slic3r/GUI/StatusPanel.cpp | 14 +++--- src/slic3r/GUI/StatusPanel.hpp | 14 +++--- src/slic3r/GUI/TabButton.cpp | 26 +++++----- src/slic3r/GUI/TabButton.hpp | 8 ++-- src/slic3r/GUI/Tabbook.cpp | 4 +- src/slic3r/GUI/Tabbook.hpp | 5 +- src/slic3r/GUI/Widgets/AMSControl.cpp | 35 +++++++------- src/slic3r/GUI/Widgets/AMSControl.hpp | 14 +++--- src/slic3r/GUI/Widgets/AxisCtrlButton.cpp | 12 ++--- src/slic3r/GUI/Widgets/AxisCtrlButton.hpp | 6 +-- src/slic3r/GUI/Widgets/ImageSwitchButton.cpp | 20 ++++---- src/slic3r/GUI/Widgets/ImageSwitchButton.hpp | 8 ++-- src/slic3r/GUI/Widgets/SideTools.cpp | 50 ++++++++++---------- src/slic3r/GUI/Widgets/SideTools.hpp | 19 ++++---- 22 files changed, 187 insertions(+), 186 deletions(-) diff --git a/src/slic3r/GUI/AboutDialog.cpp b/src/slic3r/GUI/AboutDialog.cpp index 74b2d74ae7b..fa99b15f78d 100644 --- a/src/slic3r/GUI/AboutDialog.cpp +++ b/src/slic3r/GUI/AboutDialog.cpp @@ -17,8 +17,8 @@ AboutDialogLogo::AboutDialogLogo(wxWindow* parent) : wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize) { this->SetBackgroundColour(*wxWHITE); - this->logo = wxBitmap(from_u8(Slic3r::var("BambuStudio_192px.png")), wxBITMAP_TYPE_PNG); - this->SetMinSize(this->logo.GetSize()); + this->logo = ScalableBitmap(this, Slic3r::var("BambuStudio_192px.png"), wxBITMAP_TYPE_PNG); + this->SetMinSize(this->logo.GetBmpSize()); this->Bind(wxEVT_PAINT, &AboutDialogLogo::onRepaint, this); } @@ -29,9 +29,9 @@ void AboutDialogLogo::onRepaint(wxEvent &event) dc.SetBackgroundMode(wxTRANSPARENT); wxSize size = this->GetSize(); - int logo_w = this->logo.GetWidth(); - int logo_h = this->logo.GetHeight(); - dc.DrawBitmap(this->logo, (size.GetWidth() - logo_w)/2, (size.GetHeight() - logo_h)/2, true); + int logo_w = this->logo.GetBmpWidth(); + int logo_h = this->logo.GetBmpHeight(); + dc.DrawBitmap(this->logo.bmp(), (size.GetWidth() - logo_w)/2, (size.GetHeight() - logo_h)/2, true); event.Skip(); } diff --git a/src/slic3r/GUI/AboutDialog.hpp b/src/slic3r/GUI/AboutDialog.hpp index 8774d8ce8b5..8dc72d15a3a 100644 --- a/src/slic3r/GUI/AboutDialog.hpp +++ b/src/slic3r/GUI/AboutDialog.hpp @@ -17,7 +17,7 @@ class AboutDialogLogo : public wxPanel AboutDialogLogo(wxWindow* parent); private: - wxBitmap logo; + ScalableBitmap logo; void onRepaint(wxEvent &event); }; diff --git a/src/slic3r/GUI/Auxiliary.cpp b/src/slic3r/GUI/Auxiliary.cpp index 2a31af74b5d..fb49f4a9897 100644 --- a/src/slic3r/GUI/Auxiliary.cpp +++ b/src/slic3r/GUI/Auxiliary.cpp @@ -94,9 +94,9 @@ AuFile::AuFile(wxWindow *parent, fs::path file_path, wxString file_name, Auxilia cover_text_right = _L("Rename"); cover_text_cover = _L("Cover"); - m_file_cover = create_scaled_bitmap("auxiliary_cover", this, 50); - m_file_edit_mask = create_scaled_bitmap("auxiliary_edit_mask", this, 43); - m_file_delete = create_scaled_bitmap("auxiliary_delete", this, 28); + m_file_cover = ScalableBitmap(this, "auxiliary_cover", 50); + m_file_edit_mask = ScalableBitmap(this, "auxiliary_edit_mask", 43); + m_file_delete = ScalableBitmap(this, "auxiliary_delete", 28); auto m_text_panel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(FromDIP(300), FromDIP(40)), wxTAB_TRAVERSAL); m_text_panel->SetBackgroundColour(AUFILE_GREY300); @@ -183,7 +183,7 @@ void AuFile::PaintForeground(wxDC &dc) wxSize size = wxSize(FromDIP(300), FromDIP(300)); if (m_hover) { - dc.DrawBitmap(m_file_edit_mask, 0, size.y - m_file_edit_mask.GetSize().y); + dc.DrawBitmap(m_file_edit_mask.bmp(), 0, size.y - m_file_edit_mask.GetBmpSize().y); dc.SetFont(Label::Body_14); dc.SetTextForeground(*wxWHITE); if (m_type == MODEL_PICTURE) { @@ -191,14 +191,14 @@ void AuFile::PaintForeground(wxDC &dc) auto sizet = dc.GetTextExtent(cover_text_left); auto pos = wxPoint(0, 0); pos.x = (size.x / 2 - sizet.x) / 2; - pos.y = (size.y - (m_file_edit_mask.GetSize().y + sizet.y) / 2); + pos.y = (size.y - (m_file_edit_mask.GetBmpSize().y + sizet.y) / 2); dc.DrawText(cover_text_left, pos); // right text sizet = dc.GetTextExtent(cover_text_right); pos = wxPoint(0, 0); pos.x = size.x / 2 + (size.x / 2 - sizet.x) / 2; - pos.y = (size.y - (m_file_edit_mask.GetSize().y + sizet.y) / 2); + pos.y = (size.y - (m_file_edit_mask.GetBmpSize().y + sizet.y) / 2); dc.DrawText(cover_text_right, pos); // Split @@ -206,21 +206,21 @@ void AuFile::PaintForeground(wxDC &dc) dc.SetBrush(AUFILE_GREY700); pos = wxPoint(0, 0); pos.x = size.x / 2 - 1; - pos.y = size.y - FromDIP(30) - (m_file_edit_mask.GetSize().y - FromDIP(30)) / 2; + pos.y = size.y - FromDIP(30) - (m_file_edit_mask.GetBmpSize().y - FromDIP(30)) / 2; dc.DrawRectangle(pos.x, pos.y, 2, FromDIP(30)); } else { // right text auto sizet = dc.GetTextExtent(cover_text_right); auto pos = wxPoint(0, 0); pos.x = (size.x - sizet.x) / 2; - pos.y = (size.y - (m_file_edit_mask.GetSize().y + sizet.y) / 2); + pos.y = (size.y - (m_file_edit_mask.GetBmpSize().y + sizet.y) / 2); dc.DrawText(cover_text_right, pos); } } if (m_cover) { dc.SetTextForeground(*wxWHITE); - dc.DrawBitmap(m_file_cover, size.x - m_file_cover.GetSize().x, 0); + dc.DrawBitmap(m_file_cover.bmp(), size.x - m_file_cover.GetBmpSize().x, 0); dc.SetFont(Label::Body_12); auto sizet = dc.GetTextExtent(cover_text_cover); auto pos = wxPoint(0, 0); @@ -229,7 +229,7 @@ void AuFile::PaintForeground(wxDC &dc) dc.DrawText(cover_text_cover, pos); } - if (m_hover) { dc.DrawBitmap(m_file_delete, size.x - m_file_delete.GetSize().x - FromDIP(15), FromDIP(15)); } + if (m_hover) { dc.DrawBitmap(m_file_delete.bmp(), size.x - m_file_delete.GetBmpSize().x - FromDIP(15), FromDIP(15)); } } void AuFile::on_mouse_enter(wxMouseEvent &evt) @@ -337,7 +337,7 @@ void AuFile::on_mouse_left_up(wxMouseEvent &evt) auto pos = evt.GetPosition(); // set cover - auto mask_size = m_file_edit_mask.GetSize(); + auto mask_size = m_file_edit_mask.GetBmpSize(); auto cover_left = 0; auto cover_top = size.y - mask_size.y; auto cover_right = mask_size.x / 2; @@ -353,10 +353,10 @@ void AuFile::on_mouse_left_up(wxMouseEvent &evt) if (pos.x > rename_left && pos.x < rename_right && pos.y > rename_top && pos.y < rename_bottom) { on_set_rename(); } // close - auto close_left = size.x - m_file_delete.GetSize().x - FromDIP(15); + auto close_left = size.x - m_file_delete.GetBmpSize().x - FromDIP(15); auto close_top = FromDIP(15); auto close_right = size.x - FromDIP(15); - auto close_bottom = m_file_delete.GetSize().y + FromDIP(15); + auto close_bottom = m_file_delete.GetBmpSize().y + FromDIP(15); if (pos.x > close_left && pos.x < close_right && pos.y > close_top && pos.y < close_bottom) { on_set_delete(); } } @@ -449,9 +449,9 @@ AuFile::~AuFile() {} void AuFile::msw_rescale() { - m_file_cover = create_scaled_bitmap("auxiliary_cover", this, 50); - m_file_edit_mask = create_scaled_bitmap("auxiliary_edit_mask", this, 43); - m_file_delete = create_scaled_bitmap("auxiliary_delete", this, 28); + m_file_cover = ScalableBitmap(this, "auxiliary_cover", 50); + m_file_edit_mask = ScalableBitmap(this, "auxiliary_edit_mask", 43); + m_file_delete = ScalableBitmap(this, "auxiliary_delete", 28); if (m_type == MODEL_PICTURE) { if (m_file_path.empty()) { return;} diff --git a/src/slic3r/GUI/Auxiliary.hpp b/src/slic3r/GUI/Auxiliary.hpp index d4b93c03844..fd61637e440 100644 --- a/src/slic3r/GUI/Auxiliary.hpp +++ b/src/slic3r/GUI/Auxiliary.hpp @@ -81,9 +81,9 @@ class AuFile : public wxPanel wxString cover_text_right; wxString cover_text_cover; wxBitmap m_file_bitmap; - wxBitmap m_file_cover; - wxBitmap m_file_edit_mask; - wxBitmap m_file_delete; + ScalableBitmap m_file_cover; + ScalableBitmap m_file_edit_mask; + ScalableBitmap m_file_delete; wxBitmap m_bitmap_excel; wxBitmap m_bitmap_pdf; diff --git a/src/slic3r/GUI/CameraPopup.cpp b/src/slic3r/GUI/CameraPopup.cpp index 954b1492354..42dfcda6297 100644 --- a/src/slic3r/GUI/CameraPopup.cpp +++ b/src/slic3r/GUI/CameraPopup.cpp @@ -139,10 +139,10 @@ CameraItem::CameraItem(wxWindow *parent,std::string off_normal, std::string on_n SetDoubleBuffered(true); #endif //__WINDOWS__ - m_bitmap_on_normal = create_scaled_bitmap(on_normal, nullptr, 20); - m_bitmap_off_normal = create_scaled_bitmap(off_normal, nullptr, 20); - m_bitmap_on_hover = create_scaled_bitmap(on_hover, nullptr, 20); - m_bitmap_off_hover = create_scaled_bitmap(off_hover, nullptr, 20); + m_bitmap_on_normal = ScalableBitmap(this, on_normal, 20); + m_bitmap_off_normal = ScalableBitmap(this, off_normal, 20); + m_bitmap_on_hover = ScalableBitmap(this, on_hover, 20); + m_bitmap_off_hover = ScalableBitmap(this, off_hover, 20); SetSize(wxSize(FromDIP(20), FromDIP(20))); SetMinSize(wxSize(FromDIP(20), FromDIP(20))); @@ -208,16 +208,16 @@ void CameraItem::doRender(wxDC &dc) { if (m_on) { if (m_hover) { - dc.DrawBitmap(m_bitmap_on_hover, wxPoint((GetSize().x - m_bitmap_on_hover.GetSize().x) / 2, (GetSize().y - m_bitmap_on_hover.GetSize().y) / 2)); + dc.DrawBitmap(m_bitmap_on_hover.bmp(), wxPoint((GetSize().x - m_bitmap_on_hover.GetBmpSize().x) / 2, (GetSize().y - m_bitmap_on_hover.GetBmpSize().y) / 2)); } else { - dc.DrawBitmap(m_bitmap_on_normal, wxPoint((GetSize().x - m_bitmap_on_normal.GetSize().x) / 2, (GetSize().y - m_bitmap_on_normal.GetSize().y) / 2)); + dc.DrawBitmap(m_bitmap_on_normal.bmp(), wxPoint((GetSize().x - m_bitmap_on_normal.GetBmpSize().x) / 2, (GetSize().y - m_bitmap_on_normal.GetBmpSize().y) / 2)); } } else { if (m_hover) { - dc.DrawBitmap(m_bitmap_off_hover, wxPoint((GetSize().x - m_bitmap_off_hover.GetSize().x) / 2, (GetSize().y - m_bitmap_off_hover.GetSize().y) / 2)); + dc.DrawBitmap(m_bitmap_off_hover.bmp(), wxPoint((GetSize().x - m_bitmap_off_hover.GetBmpSize().x) / 2, (GetSize().y - m_bitmap_off_hover.GetBmpSize().y) / 2)); } else { - dc.DrawBitmap(m_bitmap_off_normal, wxPoint((GetSize().x - m_bitmap_off_normal.GetSize().x) / 2, (GetSize().y - m_bitmap_off_normal.GetSize().y) / 2)); + dc.DrawBitmap(m_bitmap_off_normal.bmp(), wxPoint((GetSize().x - m_bitmap_off_normal.GetBmpSize().x) / 2, (GetSize().y - m_bitmap_off_normal.GetBmpSize().y) / 2)); } } } diff --git a/src/slic3r/GUI/CameraPopup.hpp b/src/slic3r/GUI/CameraPopup.hpp index b2adc7a0aa0..6be91177917 100644 --- a/src/slic3r/GUI/CameraPopup.hpp +++ b/src/slic3r/GUI/CameraPopup.hpp @@ -59,10 +59,10 @@ class CameraItem : public wxPanel MachineObject *m_obj{nullptr}; bool m_on{false}; bool m_hover{false}; - wxBitmap m_bitmap_on_normal; - wxBitmap m_bitmap_on_hover; - wxBitmap m_bitmap_off_normal; - wxBitmap m_bitmap_off_hover; + ScalableBitmap m_bitmap_on_normal; + ScalableBitmap m_bitmap_on_hover; + ScalableBitmap m_bitmap_off_normal; + ScalableBitmap m_bitmap_off_hover; void msw_rescale(); void set_switch(bool is_on); diff --git a/src/slic3r/GUI/SelectMachine.cpp b/src/slic3r/GUI/SelectMachine.cpp index 69ac1f28405..56d4cc7f825 100644 --- a/src/slic3r/GUI/SelectMachine.cpp +++ b/src/slic3r/GUI/SelectMachine.cpp @@ -102,15 +102,15 @@ MachineObjectPanel::MachineObjectPanel(wxWindow *parent, wxWindowID id, const wx SetBackgroundColour(*wxWHITE); - m_unbind_img = create_scaled_bitmap("unbind", nullptr, 18); - m_edit_name_img = create_scaled_bitmap("edit_button", nullptr, 18); - m_select_unbind_img = create_scaled_bitmap("unbind_selected", nullptr, 18); + m_unbind_img = ScalableBitmap(this, "unbind", 18); + m_edit_name_img = ScalableBitmap(this, "edit_button", 18); + m_select_unbind_img = ScalableBitmap(this, "unbind_selected", 18); - m_printer_status_offline = create_scaled_bitmap("printer_status_offline", nullptr, 12); - m_printer_status_busy = create_scaled_bitmap("printer_status_busy", nullptr, 12); - m_printer_status_idle = create_scaled_bitmap("printer_status_idle", nullptr, 12); - m_printer_status_lock = create_scaled_bitmap("printer_status_lock", nullptr, 16); - m_printer_in_lan = create_scaled_bitmap("printer_in_lan", nullptr, 16); + m_printer_status_offline = ScalableBitmap(this, "printer_status_offline", 12); + m_printer_status_busy = ScalableBitmap(this, "printer_status_busy", 12); + m_printer_status_idle = ScalableBitmap(this, "printer_status_idle", 12); + m_printer_status_lock = ScalableBitmap(this, "printer_status_lock", 16); + m_printer_in_lan = ScalableBitmap(this, "printer_in_lan", 16); this->Bind(wxEVT_ENTER_WINDOW, &MachineObjectPanel::on_mouse_enter, this); this->Bind(wxEVT_LEAVE_WINDOW, &MachineObjectPanel::on_mouse_leave, this); @@ -188,9 +188,9 @@ void MachineObjectPanel::doRender(wxDC &dc) if (m_state == PrinterState::IN_LAN) { dwbitmap = m_printer_in_lan; } // dc.DrawCircle(left, size.y / 2, 3); - dc.DrawBitmap(dwbitmap, wxPoint(left, (size.y - dwbitmap.GetSize().y) / 2)); + dc.DrawBitmap(dwbitmap.bmp(), wxPoint(left, (size.y - dwbitmap.GetBmpSize().y) / 2)); - left += dwbitmap.GetSize().x + 8; + left += dwbitmap.GetBmpSize().x + 8; dc.SetFont(Label::Body_13); dc.SetBackgroundMode(wxTRANSPARENT); dc.SetTextForeground(SELECT_MACHINE_GREY900); @@ -199,7 +199,7 @@ void MachineObjectPanel::doRender(wxDC &dc) dev_name = from_u8(m_info->dev_name); } auto sizet = dc.GetTextExtent(dev_name); - auto text_end = size.x - m_unbind_img.GetSize().x - 30; + auto text_end = size.x - m_unbind_img.GetBmpSize().x - 30; wxString finally_name = dev_name; if (sizet.x > (text_end - left)) { auto limit_width = text_end - left - dc.GetTextExtent("...").x - 15; @@ -221,13 +221,14 @@ void MachineObjectPanel::doRender(wxDC &dc) if (m_show_bind) { if (m_bind_state == ALLOW_UNBIND) { - left = size.x - m_unbind_img.GetSize().x - 6; - dc.DrawBitmap(m_select_unbind_img, left, (size.y - m_unbind_img.GetSize().y) / 2); } + left = size.x - m_unbind_img.GetBmpSize().x - 6; + dc.DrawBitmap(m_select_unbind_img.bmp(), left, (size.y - m_unbind_img.GetBmpSize().y) / 2); + } } if (m_show_edit) { - left = size.x - m_unbind_img.GetSize().x - 6 - m_edit_name_img.GetSize().x - 6; - dc.DrawBitmap(m_edit_name_img, left, (size.y - m_edit_name_img.GetSize().y) / 2); + left = size.x - m_unbind_img.GetBmpSize().x - 6 - m_edit_name_img.GetBmpSize().x - 6; + dc.DrawBitmap(m_edit_name_img.bmp(), left, (size.y - m_edit_name_img.GetBmpSize().y) / 2); } } } @@ -256,10 +257,10 @@ void MachineObjectPanel::on_mouse_left_up(wxMouseEvent &evt) if (m_is_my_devices) { // show edit if (m_show_edit) { - auto edit_left = GetSize().x - m_unbind_img.GetSize().x - 6 - m_edit_name_img.GetSize().x - 6; - auto edit_right = edit_left + m_edit_name_img.GetSize().x; - auto edit_top = (GetSize().y - m_edit_name_img.GetSize().y) / 2; - auto edit_bottom = (GetSize().y - m_edit_name_img.GetSize().y) / 2 + m_edit_name_img.GetSize().y; + auto edit_left = GetSize().x - m_unbind_img.GetBmpSize().x - 6 - m_edit_name_img.GetBmpSize().x - 6; + auto edit_right = edit_left + m_edit_name_img.GetBmpSize().x; + auto edit_top = (GetSize().y - m_edit_name_img.GetBmpSize().y) / 2; + auto edit_bottom = (GetSize().y - m_edit_name_img.GetBmpSize().y) / 2 + m_edit_name_img.GetBmpSize().y; if ((evt.GetPosition().x >= edit_left && evt.GetPosition().x <= edit_right) && evt.GetPosition().y >= edit_top && evt.GetPosition().y <= edit_bottom) { wxCommandEvent event(EVT_EDIT_PRINT_NAME); event.SetEventObject(this); @@ -268,10 +269,10 @@ void MachineObjectPanel::on_mouse_left_up(wxMouseEvent &evt) } } if (m_show_bind) { - auto left = GetSize().x - m_unbind_img.GetSize().x - 6; - auto right = left + m_unbind_img.GetSize().x; - auto top = (GetSize().y - m_unbind_img.GetSize().y) / 2; - auto bottom = (GetSize().y - m_unbind_img.GetSize().y) / 2 + m_unbind_img.GetSize().y; + auto left = GetSize().x - m_unbind_img.GetBmpSize().x - 6; + auto right = left + m_unbind_img.GetBmpSize().x; + auto top = (GetSize().y - m_unbind_img.GetBmpSize().y) / 2; + auto bottom = (GetSize().y - m_unbind_img.GetBmpSize().y) / 2 + m_unbind_img.GetBmpSize().y; if ((evt.GetPosition().x >= left && evt.GetPosition().x <= right) && evt.GetPosition().y >= top && evt.GetPosition().y <= bottom) { wxCommandEvent event(EVT_UNBIND_MACHINE, GetId()); diff --git a/src/slic3r/GUI/SelectMachine.hpp b/src/slic3r/GUI/SelectMachine.hpp index a026b50f06e..37a3e9fc23c 100644 --- a/src/slic3r/GUI/SelectMachine.hpp +++ b/src/slic3r/GUI/SelectMachine.hpp @@ -114,20 +114,19 @@ class MachineObjectPanel : public wxPanel PrinterBindState m_bind_state; PrinterState m_state; - wxBitmap m_unbind_img; - wxBitmap m_edit_name_img; - wxBitmap m_select_unbind_img; + ScalableBitmap m_unbind_img; + ScalableBitmap m_edit_name_img; + ScalableBitmap m_select_unbind_img; - wxBitmap m_printer_status_offline; - wxBitmap m_printer_status_busy; - wxBitmap m_printer_status_idle; - wxBitmap m_printer_status_lock; - wxBitmap m_printer_in_lan; + ScalableBitmap m_printer_status_offline; + ScalableBitmap m_printer_status_busy; + ScalableBitmap m_printer_status_idle; + ScalableBitmap m_printer_status_lock; + ScalableBitmap m_printer_in_lan; MachineObject *m_info; protected: - wxBitmap m_bitmap_type; wxStaticBitmap *m_bitmap_info; wxStaticBitmap *m_bitmap_bind; diff --git a/src/slic3r/GUI/StatusPanel.cpp b/src/slic3r/GUI/StatusPanel.cpp index 78fe307fbda..8b4f5e74eb7 100644 --- a/src/slic3r/GUI/StatusPanel.cpp +++ b/src/slic3r/GUI/StatusPanel.cpp @@ -159,13 +159,13 @@ void StatusBasePanel::init_bitmaps() m_bitmap_item_prediction = create_scaled_bitmap("monitor_item_prediction", nullptr, 16); m_bitmap_item_cost = create_scaled_bitmap("monitor_item_cost", nullptr, 16); m_bitmap_item_print = create_scaled_bitmap("monitor_item_print", nullptr, 18); - m_bitmap_axis_home = create_scaled_bitmap("monitor_axis_home", nullptr, 32); - m_bitmap_lamp_on = create_scaled_bitmap("monitor_lamp_on", nullptr, 24); - m_bitmap_lamp_off = create_scaled_bitmap("monitor_lamp_off", nullptr, 24); - m_bitmap_fan_on = create_scaled_bitmap("monitor_fan_on", nullptr, 24); - m_bitmap_fan_off = create_scaled_bitmap("monitor_fan_off", nullptr, 24); - m_bitmap_speed = create_scaled_bitmap("monitor_speed", nullptr, 24); - m_bitmap_speed_active = create_scaled_bitmap("monitor_speed_active", nullptr, 24); + m_bitmap_axis_home = ScalableBitmap(this, "monitor_axis_home", 32); + m_bitmap_lamp_on = ScalableBitmap(this, "monitor_lamp_on", 24); + m_bitmap_lamp_off = ScalableBitmap(this, "monitor_lamp_off", 24); + m_bitmap_fan_on = ScalableBitmap(this, "monitor_fan_on", 24); + m_bitmap_fan_off = ScalableBitmap(this, "monitor_fan_off", 24); + m_bitmap_speed = ScalableBitmap(this, "monitor_speed", 24); + m_bitmap_speed_active = ScalableBitmap(this, "monitor_speed_active", 24); m_thumbnail_placeholder = create_scaled_bitmap("monitor_placeholder", nullptr, 120); m_thumbnail_sdcard = create_scaled_bitmap("monitor_sdcard_thumbnail", nullptr, 120); //m_bitmap_camera = create_scaled_bitmap("monitor_camera", nullptr, 18); diff --git a/src/slic3r/GUI/StatusPanel.hpp b/src/slic3r/GUI/StatusPanel.hpp index 046d9c8fcfe..91250610959 100644 --- a/src/slic3r/GUI/StatusPanel.hpp +++ b/src/slic3r/GUI/StatusPanel.hpp @@ -70,13 +70,13 @@ class StatusBasePanel : public wxScrolledWindow wxBitmap m_bitmap_item_prediction; wxBitmap m_bitmap_item_cost; wxBitmap m_bitmap_item_print; - wxBitmap m_bitmap_speed; - wxBitmap m_bitmap_speed_active; - wxBitmap m_bitmap_axis_home; - wxBitmap m_bitmap_lamp_on; - wxBitmap m_bitmap_lamp_off; - wxBitmap m_bitmap_fan_on; - wxBitmap m_bitmap_fan_off; + ScalableBitmap m_bitmap_speed; + ScalableBitmap m_bitmap_speed_active; + ScalableBitmap m_bitmap_axis_home; + ScalableBitmap m_bitmap_lamp_on; + ScalableBitmap m_bitmap_lamp_off; + ScalableBitmap m_bitmap_fan_on; + ScalableBitmap m_bitmap_fan_off; wxBitmap m_bitmap_extruder; CameraRecordingStatus m_state_recording{CameraRecordingStatus::RECORDING_NONE}; diff --git a/src/slic3r/GUI/TabButton.cpp b/src/slic3r/GUI/TabButton.cpp index effb679da29..3243a2f1d74 100644 --- a/src/slic3r/GUI/TabButton.cpp +++ b/src/slic3r/GUI/TabButton.cpp @@ -33,13 +33,13 @@ TabButton::TabButton() std::make_pair(*wxWHITE, (int) StateColor::Normal)); } -TabButton::TabButton(wxWindow *parent, wxString text, wxBitmap &bmp, long style, int iconSize) +TabButton::TabButton(wxWindow *parent, wxString text, ScalableBitmap &bmp, long style, int iconSize) : TabButton() { Create(parent, text, bmp, style, iconSize); } -bool TabButton::Create(wxWindow *parent, wxString text, wxBitmap &bmp, long style, int iconSize) +bool TabButton::Create(wxWindow *parent, wxString text, ScalableBitmap &bmp, long style, int iconSize) { StaticBox::Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, style); state_handler.attach({&text_color, &border_color}); @@ -47,7 +47,7 @@ bool TabButton::Create(wxWindow *parent, wxString text, wxBitmap &bmp, long styl //BBS set default font SetFont(Label::Body_14); wxWindow::SetLabel(text); - this->icon = bmp.GetSubBitmap(wxRect(0, 0, bmp.GetWidth(), bmp.GetHeight())); + this->icon = bmp; messureSize(); return true; } @@ -92,9 +92,9 @@ void TabButton::SetBGColor(StateColor const &color) Refresh(); } -void TabButton::SetBitmap(wxBitmap &bitmap) +void TabButton::SetBitmap(ScalableBitmap &bitmap) { - this->icon = bitmap.GetSubBitmap(wxRect(0, 0, bitmap.GetWidth(), bitmap.GetHeight())); + this->icon = bitmap; } bool TabButton::Enable(bool enable) @@ -138,12 +138,12 @@ void TabButton::render(wxDC &dc) // calc content size wxSize szIcon; wxSize szContent = textSize; - if (icon.IsOk()) { + if (icon.bmp().IsOk()) { if (szContent.y > 0) { // BBS norrow size between text and icon szContent.x += 5; } - szIcon = icon.GetSize(); + szIcon = icon.GetBmpSize(); szContent.x += szIcon.x; if (szIcon.y > szContent.y) szContent.y = szIcon.y; } @@ -163,10 +163,10 @@ void TabButton::render(wxDC &dc) dc.DrawText(text, pt); } - if (icon.IsOk()) { - pt.x = size.x - icon.GetWidth() - paddingSize.y; - pt.y = (size.y - icon.GetHeight()) / 2; - dc.DrawBitmap(icon, pt); + if (icon.bmp().IsOk()) { + pt.x = size.x - icon.GetBmpWidth() - paddingSize.y; + pt.y = (size.y - icon.GetBmpHeight()) / 2; + dc.DrawBitmap(icon.bmp(), pt); } } @@ -179,12 +179,12 @@ void TabButton::messureSize() return; } wxSize szContent = textSize; - if (this->icon.IsOk()) { + if (this->icon.bmp().IsOk()) { if (szContent.y > 0) { // BBS norrow size between text and icon szContent.x += 5; } - wxSize szIcon = this->icon.GetSize(); + wxSize szIcon = this->icon.GetBmpSize(); szContent.x += szIcon.x; if (szIcon.y > szContent.y) szContent.y = szIcon.y; } diff --git a/src/slic3r/GUI/TabButton.hpp b/src/slic3r/GUI/TabButton.hpp index ca82a67b405..e64722d637c 100644 --- a/src/slic3r/GUI/TabButton.hpp +++ b/src/slic3r/GUI/TabButton.hpp @@ -9,7 +9,7 @@ class TabButton : public StaticBox wxSize textSize; wxSize minSize; wxSize paddingSize; - wxBitmap icon; + ScalableBitmap icon; StateColor text_color; StateColor border_color; @@ -18,9 +18,9 @@ class TabButton : public StaticBox public: TabButton(); - TabButton(wxWindow *parent, wxString text, wxBitmap &icon, long style = 0, int iconSize = 0); + TabButton(wxWindow *parent, wxString text, ScalableBitmap &icon, long style = 0, int iconSize = 0); - bool Create(wxWindow *parent, wxString text, wxBitmap &icon, long style = 0, int iconSize = 0); + bool Create(wxWindow *parent, wxString text, ScalableBitmap &icon, long style = 0, int iconSize = 0); void SetLabel(const wxString& label) override; @@ -34,7 +34,7 @@ class TabButton : public StaticBox void SetBGColor(StateColor const &color); - void SetBitmap(wxBitmap &bitmap); + void SetBitmap(ScalableBitmap &bitmap); bool Enable(bool enable = true); diff --git a/src/slic3r/GUI/Tabbook.cpp b/src/slic3r/GUI/Tabbook.cpp index fb02ceaac63..cce19da250e 100644 --- a/src/slic3r/GUI/Tabbook.cpp +++ b/src/slic3r/GUI/Tabbook.cpp @@ -38,7 +38,7 @@ TabButtonsListCtrl::TabButtonsListCtrl(wxWindow *parent, wxBoxSizer *side_tools) m_btn_margin = 0; m_line_margin = std::lround(0.1 * em); - m_arrow_img = create_scaled_bitmap("monitor_arrow", nullptr, 14); + m_arrow_img = ScalableBitmap(this, "monitor_arrow", 14); m_sizer = new wxBoxSizer(wxVERTICAL); this->SetSizer(m_sizer); @@ -87,7 +87,7 @@ void TabButtonsListCtrl::OnPaint(wxPaintEvent &) void TabButtonsListCtrl::Rescale() { - m_arrow_img = create_scaled_bitmap("monitor_arrow", nullptr, 14); + m_arrow_img = ScalableBitmap(this, "monitor_arrow", 14); int em = em_unit(this); for (TabButton *btn : m_pageButtons) { diff --git a/src/slic3r/GUI/Tabbook.hpp b/src/slic3r/GUI/Tabbook.hpp index 6adafb54047..b57fb907ab6 100644 --- a/src/slic3r/GUI/Tabbook.hpp +++ b/src/slic3r/GUI/Tabbook.hpp @@ -5,6 +5,7 @@ #include #include +#include "wxExtensions.hpp" class ScalableButton; @@ -33,8 +34,8 @@ class TabButtonsListCtrl : public wxControl wxWindow* m_parent; wxFlexGridSizer* m_buttons_sizer; wxBoxSizer* m_sizer; - wxBitmap m_arrow_img; - std::vector m_pageButtons; + ScalableBitmap m_arrow_img; + std::vector m_pageButtons; int m_selection {-1}; int m_btn_margin; int m_line_margin; diff --git a/src/slic3r/GUI/Widgets/AMSControl.cpp b/src/slic3r/GUI/Widgets/AMSControl.cpp index bc7e41f683c..e9879aa3365 100644 --- a/src/slic3r/GUI/Widgets/AMSControl.cpp +++ b/src/slic3r/GUI/Widgets/AMSControl.cpp @@ -133,8 +133,8 @@ void AMSrefresh::create(wxWindow *parent, wxWindowID id, const wxPoint &pos, con Bind(wxEVT_LEAVE_WINDOW, &AMSrefresh::OnLeaveWindow, this); Bind(wxEVT_LEFT_DOWN, &AMSrefresh::OnClick, this); - m_bitmap_normal = create_scaled_bitmap("ams_refresh_normal", this, 26); - m_bitmap_selected = create_scaled_bitmap("ams_refresh_selected", this, 26); + m_bitmap_normal = ScalableBitmap(this, "ams_refresh_normal", 26); + m_bitmap_selected = ScalableBitmap(this, "ams_refresh_selected", 26); /* m_animationCtrl = new wxAnimationCtrl(this, wxID_ANY, wxNullAnimation, wxDefaultPosition, AMS_REFRESH_SIZE); auto path = (boost::format("%1%/images/refresh.gif") % resources_dir()).str(); @@ -213,17 +213,18 @@ void AMSrefresh::paintEvent(wxPaintEvent &evt) auto colour = AMS_CONTROL_GRAY700; if (!wxWindow::IsEnabled()) { colour = AMS_CONTROL_GRAY500; } - auto pot = wxPoint((size.x - m_bitmap_selected.GetSize().x) / 2, (size.y - m_bitmap_selected.GetSize().y) / 2); + 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 : m_bitmap_normal, pot); + dc.DrawBitmap(m_selected ? m_bitmap_selected.bmp() : m_bitmap_normal.bmp(), pot); } else { - m_bitmap_rotation = create_scaled_bitmap("ams_refresh_normal", this, 26); - auto image = m_bitmap_rotation.ConvertToImage(); + m_bitmap_rotation = ScalableBitmap(this, "ams_refresh_normal", 26); + 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); - auto loading_bitmap = wxBitmap(loading_img); - dc.DrawBitmap( loading_bitmap, offset.x , offset.y); + ScalableBitmap loading_bitmap; + loading_bitmap.bmp() = wxBitmap(loading_img); + dc.DrawBitmap(loading_bitmap.bmp(), offset.x , offset.y); } dc.SetPen(wxPen(colour)); @@ -246,8 +247,8 @@ void AMSrefresh::msw_rescale() { } void AMSrefresh::DoSetSize(int x, int y, int width, int height, int sizeFlags) { wxWindow::DoSetSize(x, y, width, height, sizeFlags); - m_bitmap_normal = create_scaled_bitmap("ams_refresh_normal", this, 26); - m_bitmap_selected = create_scaled_bitmap("ams_refresh_selected", this, 26); + m_bitmap_normal = ScalableBitmap(this, "ams_refresh_normal", 26); + m_bitmap_selected = ScalableBitmap(this, "ams_refresh_selected", 26); } /************************************************* @@ -269,7 +270,7 @@ void AMSextruderImage::msw_rescale() { //m_ams_extruder.SetSize(AMS_EXTRUDER_BITMAP_SIZE); //auto image = m_ams_extruder.ConvertToImage(); - m_ams_extruder = create_scaled_bitmap("monitor_ams_extruder", nullptr, 55); + m_ams_extruder = ScalableBitmap(this, "monitor_ams_extruder", 55); Refresh(); } @@ -306,7 +307,7 @@ void AMSextruderImage::doRender(wxDC &dc) dc.SetPen(*wxTRANSPARENT_PEN); dc.SetBrush(m_colour); dc.DrawRectangle(0, 0, size.x, size.y - FromDIP(5)); - dc.DrawBitmap(m_ams_extruder, wxPoint( (size.x - m_ams_extruder.GetSize().x) / 2, (size.y - m_ams_extruder.GetSize().y) / 2 )); + dc.DrawBitmap(m_ams_extruder.bmp(), wxPoint((size.x - m_ams_extruder.GetBmpSize().x) / 2, (size.y - m_ams_extruder.GetBmpSize().y) / 2)); } @@ -315,7 +316,7 @@ AMSextruderImage::AMSextruderImage(wxWindow *parent, wxWindowID id, const wxPoin wxWindow::Create(parent, id, pos, AMS_EXTRUDER_BITMAP_SIZE); SetBackgroundColour(*wxWHITE); - m_ams_extruder = create_scaled_bitmap("monitor_ams_extruder", nullptr,55); + m_ams_extruder = ScalableBitmap(this, "monitor_ams_extruder",55); SetSize(AMS_EXTRUDER_BITMAP_SIZE); SetMinSize(AMS_EXTRUDER_BITMAP_SIZE); @@ -404,8 +405,8 @@ void AMSLib::create(wxWindow *parent, wxWindowID id, const wxPoint &pos, const w wxBoxSizer *m_sizer_edit = new wxBoxSizer(wxHORIZONTAL); - m_bitmap_editable = create_scaled_bitmap("ams_editable", this, 14); - m_bitmap_editable_lifht = create_scaled_bitmap("ams_editable_light", this, 14); + m_bitmap_editable = ScalableBitmap(this, "ams_editable", 14); + m_bitmap_editable_lifht = ScalableBitmap(this, "ams_editable_light", 14); m_sizer_body->Add(0, 0, 1, wxEXPAND, 0); m_sizer_body->Add(m_sizer_edit, 0, wxALIGN_CENTER, 0); @@ -434,7 +435,7 @@ void AMSLib::on_left_down(wxMouseEvent &evt) auto size = GetSize(); auto pos = evt.GetPosition(); auto left = FromDIP(20); - auto top = (size.y - FromDIP(10) - m_bitmap_editable_lifht.GetSize().y); + auto top = (size.y - FromDIP(10) - m_bitmap_editable_lifht.GetBmpSize().y); auto right = size.x - FromDIP(20); auto bottom = size.y - FromDIP(10); @@ -590,7 +591,7 @@ void AMSLib::doRender(wxDC &dc) // edit icon if (m_info.material_state != AMSCanType::AMS_CAN_TYPE_EMPTY && m_info.material_state != AMSCanType::AMS_CAN_TYPE_NONE && m_info.material_state == AMSCanType::AMS_CAN_TYPE_THIRDBRAND ) { - dc.DrawBitmap(temp_bitmap, (size.x - m_bitmap_editable.GetSize().x) / 2, ( size.y - FromDIP(10) - temp_bitmap.GetSize().y) ); + dc.DrawBitmap(temp_bitmap.bmp(), (size.x - m_bitmap_editable.GetBmpSize().x) / 2, (size.y - FromDIP(10) - temp_bitmap.GetBmpSize().y)); } } diff --git a/src/slic3r/GUI/Widgets/AMSControl.hpp b/src/slic3r/GUI/Widgets/AMSControl.hpp index 063dd853994..bc3d638110e 100644 --- a/src/slic3r/GUI/Widgets/AMSControl.hpp +++ b/src/slic3r/GUI/Widgets/AMSControl.hpp @@ -160,9 +160,9 @@ class AMSrefresh : public wxWindow bool m_play_loading = {false}; bool m_selected = {false}; - wxBitmap m_bitmap_rotation; - wxBitmap m_bitmap_normal; - wxBitmap m_bitmap_selected; + ScalableBitmap m_bitmap_rotation; + ScalableBitmap m_bitmap_normal; + ScalableBitmap m_bitmap_selected; wxString m_text; wxBoxSizer * m_size_body; virtual void DoSetSize(int x, int y, int width, int height, int sizeFlags = wxSIZE_AUTO); @@ -182,7 +182,7 @@ class AMSextruderImage: public wxWindow void render(wxDC &dc); bool m_turn_on = {false}; wxColour m_colour; - wxBitmap m_ams_extruder; + ScalableBitmap m_ams_extruder; void doRender(wxDC &dc); AMSextruderImage(wxWindow *parent, wxWindowID id, const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize); ~AMSextruderImage(); @@ -200,7 +200,7 @@ class AMSextruder : public wxWindow wxBoxSizer * m_bitmap_sizer{nullptr}; wxPanel * m_bitmap_panel{nullptr}; AMSextruderImage *m_amsSextruder{nullptr}; - wxBitmap monitor_ams_extruder; + ScalableBitmap monitor_ams_extruder; AMSextruder(wxWindow *parent, wxWindowID id, const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize); ~AMSextruder(); }; @@ -228,8 +228,8 @@ class AMSLib : public wxWindow protected: wxStaticBitmap *m_edit_bitmp = {nullptr}; wxStaticBitmap *m_edit_bitmp_light = {nullptr}; - wxBitmap m_bitmap_editable; - wxBitmap m_bitmap_editable_lifht; + ScalableBitmap m_bitmap_editable; + ScalableBitmap m_bitmap_editable_lifht; bool m_unable_selected = {false}; bool m_enable = {false}; bool m_selected = {false}; diff --git a/src/slic3r/GUI/Widgets/AxisCtrlButton.cpp b/src/slic3r/GUI/Widgets/AxisCtrlButton.cpp index 6e96c491779..58fbe736f73 100644 --- a/src/slic3r/GUI/Widgets/AxisCtrlButton.cpp +++ b/src/slic3r/GUI/Widgets/AxisCtrlButton.cpp @@ -24,7 +24,7 @@ END_EVENT_TABLE() #define BLANK_SIZE FromDIP(23) #define GAP_SIZE FromDIP(4) -AxisCtrlButton::AxisCtrlButton(wxWindow *parent, wxBitmap &icon, long stlye) +AxisCtrlButton::AxisCtrlButton(wxWindow *parent, ScalableBitmap &icon, long stlye) : wxWindow(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, stlye) , r_outer(OUTER_SIZE) , r_inner(INNER_SIZE) @@ -36,7 +36,7 @@ AxisCtrlButton::AxisCtrlButton(wxWindow *parent, wxBitmap &icon, long stlye) , text_color(std::make_pair(0x6B6B6B, (int) StateColor::Disabled), std::make_pair(*wxBLACK, (int) StateColor::Normal)) , state_handler(this) { - m_icon = icon.GetSubBitmap(wxRect(0, 0, icon.GetWidth(), icon.GetHeight())); + m_icon = icon; wxWindow::SetBackgroundColour(parent->GetBackgroundColour()); border_color.append(bd, StateColor::Hovered); @@ -119,9 +119,9 @@ void AxisCtrlButton::SetInnerBackgroundColor(StateColor const& color) Refresh(); } -void AxisCtrlButton::SetBitmap(wxBitmap &bmp) +void AxisCtrlButton::SetBitmap(ScalableBitmap &bmp) { - m_icon = bmp.GetSubBitmap(wxRect(0, 0, bmp.GetWidth(), bmp.GetHeight())); + m_icon = bmp; } void AxisCtrlButton::Rescale() { @@ -210,8 +210,8 @@ void AxisCtrlButton::render(wxDC& dc) } gc->DrawPath(home_path); - if (m_icon.IsOk()) { - gc->DrawBitmap(m_icon, -1 * m_icon.GetWidth() / 2, -1 * m_icon.GetHeight() / 2, m_icon.GetWidth(), m_icon.GetHeight()); + if (m_icon.bmp().IsOk()) { + gc->DrawBitmap(m_icon.bmp(), -1 * m_icon.GetBmpWidth() / 2, -1 * m_icon.GetBmpHeight() / 2, m_icon.GetBmpWidth(), m_icon.GetBmpHeight()); } gc->PopState(); diff --git a/src/slic3r/GUI/Widgets/AxisCtrlButton.hpp b/src/slic3r/GUI/Widgets/AxisCtrlButton.hpp index a0ddb1adcda..739861bf0d2 100644 --- a/src/slic3r/GUI/Widgets/AxisCtrlButton.hpp +++ b/src/slic3r/GUI/Widgets/AxisCtrlButton.hpp @@ -25,7 +25,7 @@ class AxisCtrlButton : public wxWindow StateColor background_color; StateColor inner_background_color; - wxBitmap m_icon; + ScalableBitmap m_icon; bool pressedDown = false; @@ -45,7 +45,7 @@ class AxisCtrlButton : public wxWindow }; public: - AxisCtrlButton(wxWindow *parent, wxBitmap &icon, long style = 0); + AxisCtrlButton(wxWindow *parent, ScalableBitmap &icon, long style = 0); void SetMinSize(const wxSize& size) override; @@ -57,7 +57,7 @@ class AxisCtrlButton : public wxWindow void SetInnerBackgroundColor(StateColor const& color); - void SetBitmap(wxBitmap &bmp); + void SetBitmap(ScalableBitmap &bmp); void Rescale(); diff --git a/src/slic3r/GUI/Widgets/ImageSwitchButton.cpp b/src/slic3r/GUI/Widgets/ImageSwitchButton.cpp index 618046b47d7..2b9e03173a2 100644 --- a/src/slic3r/GUI/Widgets/ImageSwitchButton.cpp +++ b/src/slic3r/GUI/Widgets/ImageSwitchButton.cpp @@ -18,13 +18,13 @@ END_EVENT_TABLE() static const wxColour DEFAULT_HOVER_COL = wxColour(0, 174, 66); static const wxColour DEFAULT_PRESS_COL = wxColour(238, 238, 238); -ImageSwitchButton::ImageSwitchButton(wxWindow *parent, wxBitmap &img_on, wxBitmap &img_off, long style) +ImageSwitchButton::ImageSwitchButton(wxWindow *parent, ScalableBitmap &img_on, ScalableBitmap &img_off, long style) : text_color(std::make_pair(0x6B6B6B, (int) StateColor::Disabled), std::make_pair(*wxBLACK, (int) StateColor::Normal)) , state_handler(this) { m_padding = 0; - m_on = img_on.GetSubBitmap(wxRect(0, 0, img_on.GetWidth(), img_on.GetHeight())); - m_off = img_off.GetSubBitmap(wxRect(0, 0, img_off.GetWidth(), img_off.GetHeight())); + m_on = img_on; + m_off = img_off; bg_color = StateColor(std::make_pair(DEFAULT_PRESS_COL, (int) StateColor::Pressed), std::make_pair(*wxWHITE, (int) StateColor::Normal)); border_color = StateColor(std::make_pair(DEFAULT_HOVER_COL, (int) StateColor::Hovered)); @@ -46,7 +46,7 @@ void ImageSwitchButton::SetLabels(wxString const &lbl_on, wxString const &lbl_of Refresh(); } -void ImageSwitchButton::SetImages(wxBitmap &img_on, wxBitmap &img_off) +void ImageSwitchButton::SetImages(ScalableBitmap &img_on, ScalableBitmap &img_off) { m_on = img_on; m_off = img_off; @@ -120,14 +120,14 @@ void ImageSwitchButton::render(wxDC& dc) wxSize szIcon; wxSize szContent = textSize; - wxBitmap &icon = GetValue() ? m_on: m_off; + ScalableBitmap &icon = GetValue() ? m_on : m_off; - int content_height = icon.GetHeight() + textSize.y + m_padding; + int content_height = icon.GetBmpHeight() + textSize.y + m_padding; - wxPoint pt = wxPoint((size.x - icon.GetWidth()) / 2, (size.y - content_height) / 2); - if (icon.IsOk()) { - dc.DrawBitmap(icon, pt); - pt.y += m_padding + icon.GetHeight(); + wxPoint pt = wxPoint((size.x - icon.GetBmpWidth()) / 2, (size.y - content_height) / 2); + if (icon.bmp().IsOk()) { + dc.DrawBitmap(icon.bmp(), pt); + pt.y += m_padding + icon.GetBmpHeight(); } pt.x = (size.x - textSize.x) / 2; dc.SetFont(GetFont()); diff --git a/src/slic3r/GUI/Widgets/ImageSwitchButton.hpp b/src/slic3r/GUI/Widgets/ImageSwitchButton.hpp index 01abb2c5083..e28f13e138a 100644 --- a/src/slic3r/GUI/Widgets/ImageSwitchButton.hpp +++ b/src/slic3r/GUI/Widgets/ImageSwitchButton.hpp @@ -12,10 +12,10 @@ class ImageSwitchButton : public StaticBox { public: - ImageSwitchButton(wxWindow *parent, wxBitmap &img_on, wxBitmap &img_off, long style = 0); + ImageSwitchButton(wxWindow *parent, ScalableBitmap &img_on, ScalableBitmap &img_off, long style = 0); void SetLabels(wxString const & lbl_on, wxString const & lbl_off); - void SetImages(wxBitmap &img_on, wxBitmap &img_off); + void SetImages(ScalableBitmap &img_on, ScalableBitmap &img_off); void SetTextColor(StateColor const &color); void SetBorderColor(StateColor const &color); void SetBgColor(StateColor const &color); @@ -38,8 +38,8 @@ class ImageSwitchButton : public StaticBox DECLARE_EVENT_TABLE() private: - wxBitmap m_on; - wxBitmap m_off; + ScalableBitmap m_on; + ScalableBitmap m_off; bool m_on_off; int m_padding; // size between icon and text bool pressedDown = false; diff --git a/src/slic3r/GUI/Widgets/SideTools.cpp b/src/slic3r/GUI/Widgets/SideTools.cpp index 9bd6d40cf3f..f614b4e32f8 100644 --- a/src/slic3r/GUI/Widgets/SideTools.cpp +++ b/src/slic3r/GUI/Widgets/SideTools.cpp @@ -14,17 +14,17 @@ namespace Slic3r { namespace GUI { SetBackgroundColour(*wxWHITE); - m_printing_img = create_scaled_bitmap("printer", nullptr, 16); - m_arrow_img = create_scaled_bitmap("monitor_arrow", nullptr, 14); + m_printing_img = ScalableBitmap(this, "printer", 16); + m_arrow_img = ScalableBitmap(this, "monitor_arrow", 14); - m_none_printing_img = create_scaled_bitmap("tab_monitor_active", nullptr, 24); - m_none_arrow_img = create_scaled_bitmap("monitor_none_arrow", nullptr, 14); - m_none_add_img = create_scaled_bitmap("monitor_none_add", nullptr, 14); + m_none_printing_img = ScalableBitmap(this, "tab_monitor_active", 24); + m_none_arrow_img = ScalableBitmap(this, "monitor_none_arrow", 14); + m_none_add_img = ScalableBitmap(this, "monitor_none_add", 14); - m_wifi_none_img = create_scaled_bitmap("monitor_signal_no", nullptr, 18); - m_wifi_weak_img = create_scaled_bitmap("monitor_signal_weak", nullptr, 18); - m_wifi_middle_img = create_scaled_bitmap("monitor_signal_middle", nullptr, 18); - m_wifi_strong_img = create_scaled_bitmap("monitor_signal_strong", nullptr, 18); + m_wifi_none_img = ScalableBitmap(this, "monitor_signal_no", 18); + m_wifi_weak_img = ScalableBitmap(this, "monitor_signal_weak", 18); + m_wifi_middle_img = ScalableBitmap(this, "monitor_signal_middle", 18); + m_wifi_strong_img = ScalableBitmap(this, "monitor_signal_strong", 18); m_intetval_timer = new wxTimer(); m_intetval_timer->SetOwner(this); @@ -131,12 +131,12 @@ void SideTools::doRender(wxDC &dc) dc.SetBrush(SIDE_TOOLS_BRAND); dc.DrawRectangle(0, 0, size.x, size.y); - dc.DrawBitmap(m_none_printing_img, left, (size.y - m_none_printing_img.GetSize().y) / 2); + dc.DrawBitmap(m_none_printing_img.bmp(), left, (size.y - m_none_printing_img.GetBmpSize().y) / 2); - left += (m_none_printing_img.GetSize().x + FromDIP(15)); - dc.DrawBitmap(m_none_arrow_img, left, (size.y - m_none_arrow_img.GetSize().y) / 2); + left += (m_none_printing_img.GetBmpSize().x + FromDIP(15)); + dc.DrawBitmap(m_none_arrow_img.bmp(), left, (size.y - m_none_arrow_img.GetBmpSize().y) / 2); - left += (m_none_arrow_img.GetSize().x + FromDIP(6)); + left += (m_none_arrow_img.GetBmpSize().x + FromDIP(6)); dc.SetFont(::Label::Body_14); dc.SetBackgroundMode(wxTRANSPARENT); dc.SetTextForeground(*wxWHITE); @@ -144,21 +144,21 @@ void SideTools::doRender(wxDC &dc) auto sizet = dc.GetTextExtent(_L("No printer")); dc.DrawText(_L("No printer"), wxPoint(left, (size.y - sizet.y) / 2)); - left = size.x - FromDIP(30) - m_wifi_none_img.GetSize().x; - dc.DrawBitmap(m_none_add_img, left, (size.y - m_none_add_img.GetSize().y) / 2); + left = size.x - FromDIP(30) - m_wifi_none_img.GetBmpSize().x; + dc.DrawBitmap(m_none_add_img.bmp(), left, (size.y - m_none_add_img.GetBmpSize().y) / 2); } else { - dc.DrawBitmap(m_printing_img, left, (size.y - m_printing_img.GetSize().y) / 2); + dc.DrawBitmap(m_printing_img.bmp(), left, (size.y - m_printing_img.GetBmpSize().y) / 2); - left += (m_printing_img.GetSize().x + FromDIP(5)); - dc.DrawBitmap(m_arrow_img, left, (size.y - m_arrow_img.GetSize().y) / 2); + left += (m_printing_img.GetBmpSize().x + FromDIP(5)); + dc.DrawBitmap(m_arrow_img.bmp(), left, (size.y - m_arrow_img.GetBmpSize().y) / 2); - left += (m_arrow_img.GetSize().x + FromDIP(6)); + left += (m_arrow_img.GetBmpSize().x + FromDIP(6)); dc.SetFont(::Label::Body_14); dc.SetBackgroundMode(wxTRANSPARENT); dc.SetTextForeground(SIDE_TOOLS_GREY900); auto sizet = dc.GetTextExtent(m_dev_name); - auto text_end = size.x - m_wifi_none_img.GetSize().x - 20; + auto text_end = size.x - m_wifi_none_img.GetBmpSize().x - 20; std::string finally_name = m_dev_name.ToStdString(); if (sizet.x > (text_end - left)) { @@ -175,11 +175,11 @@ void SideTools::doRender(wxDC &dc) dc.DrawText(finally_name, wxPoint(left, (size.y - sizet.y) / 2)); - left = size.x - FromDIP(18) - m_wifi_none_img.GetSize().x; - if (m_wifi_type == WifiSignal::NONE) dc.DrawBitmap(m_wifi_none_img, left, (size.y - m_wifi_none_img.GetSize().y) / 2); - if (m_wifi_type == WifiSignal::WEAK) dc.DrawBitmap(m_wifi_weak_img, left, (size.y - m_wifi_weak_img.GetSize().y) / 2); - if (m_wifi_type == WifiSignal::MIDDLE) dc.DrawBitmap(m_wifi_middle_img, left, (size.y - m_wifi_middle_img.GetSize().y) / 2); - if (m_wifi_type == WifiSignal::STRONG) dc.DrawBitmap(m_wifi_strong_img, left, (size.y - m_wifi_strong_img.GetSize().y) / 2); + left = size.x - FromDIP(18) - m_wifi_none_img.GetBmpSize().x; + if (m_wifi_type == WifiSignal::NONE) dc.DrawBitmap(m_wifi_none_img.bmp(), left, (size.y - m_wifi_none_img.GetBmpSize().y) / 2); + if (m_wifi_type == WifiSignal::WEAK) dc.DrawBitmap(m_wifi_weak_img.bmp(), left, (size.y - m_wifi_weak_img.GetBmpSize().y) / 2); + if (m_wifi_type == WifiSignal::MIDDLE) dc.DrawBitmap(m_wifi_middle_img.bmp(), left, (size.y - m_wifi_middle_img.GetBmpSize().y) / 2); + if (m_wifi_type == WifiSignal::STRONG) dc.DrawBitmap(m_wifi_strong_img.bmp(), left, (size.y - m_wifi_strong_img.GetBmpSize().y) / 2); } if (m_hover) { diff --git a/src/slic3r/GUI/Widgets/SideTools.hpp b/src/slic3r/GUI/Widgets/SideTools.hpp index a4c608878b8..09c086f1cae 100644 --- a/src/slic3r/GUI/Widgets/SideTools.hpp +++ b/src/slic3r/GUI/Widgets/SideTools.hpp @@ -33,20 +33,19 @@ class SideTools : public wxPanel bool m_none_printer{true}; int last_printer_signal = 0; - wxBitmap m_printing_img; - wxBitmap m_arrow_img; + ScalableBitmap m_printing_img; + ScalableBitmap m_arrow_img; - wxBitmap m_none_printing_img; - wxBitmap m_none_arrow_img; - wxBitmap m_none_add_img; + ScalableBitmap m_none_printing_img; + ScalableBitmap m_none_arrow_img; + ScalableBitmap m_none_add_img; - wxBitmap m_wifi_none_img; - wxBitmap m_wifi_weak_img; - wxBitmap m_wifi_middle_img; - wxBitmap m_wifi_strong_img; + ScalableBitmap m_wifi_none_img; + ScalableBitmap m_wifi_weak_img; + ScalableBitmap m_wifi_middle_img; + ScalableBitmap m_wifi_strong_img; protected: - wxBitmap m_bitmap_type; wxStaticBitmap *m_bitmap_info; wxStaticBitmap *m_bitmap_bind; wxTimer * m_intetval_timer{nullptr}; From 444ab790871aded1237119c6d2b7a4233dc60097 Mon Sep 17 00:00:00 2001 From: "chunmao.guo" Date: Wed, 27 Jul 2022 10:18:02 +0800 Subject: [PATCH 055/180] FIX: scale bitmap of SwitchButton in MacOS Change-Id: I5c2329d5b8fd409f87276851068e6594bbae5b3d --- src/slic3r/GUI/Widgets/SwitchButton.cpp | 29 +++++++++++++++++++------ 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/src/slic3r/GUI/Widgets/SwitchButton.cpp b/src/slic3r/GUI/Widgets/SwitchButton.cpp index 22258af38f0..9770ef5b7e5 100644 --- a/src/slic3r/GUI/Widgets/SwitchButton.cpp +++ b/src/slic3r/GUI/Widgets/SwitchButton.cpp @@ -3,6 +3,7 @@ #include "StaticBox.hpp" #include "../wxExtensions.hpp" +#include "../Utils/MacDarkMode.hpp" #include @@ -56,11 +57,19 @@ void SwitchButton::Rescale() m_off.msw_rescale(); } else { - constexpr int BS = 1; +#ifdef __WXOSX__ + auto scale = Slic3r::GUI::mac_max_scaling_factor(); + int BS = (int) scale; +#else + constexpr int BS = 1; +#endif wxSize thumbSize; wxSize trackSize; wxClientDC dc(this); - wxSize textSize[2]; +#ifdef __WXOSX__ + dc.SetFont(dc.GetFont().Scaled(scale)); +#endif + wxSize textSize[2]; { textSize[0] = dc.GetTextExtent(labels[0]); textSize[1] = dc.GetTextExtent(labels[1]); @@ -70,11 +79,14 @@ void SwitchButton::Rescale() auto size = textSize[1]; if (size.x > thumbSize.x) thumbSize.x = size.x; else size.x = thumbSize.x; - thumbSize.x += 12; - thumbSize.y += 2; - trackSize.x = thumbSize.x + size.x + 10; + thumbSize.x += BS * 12; + thumbSize.y += BS * 2; + trackSize.x = thumbSize.x + size.x + BS * 10; trackSize.y = thumbSize.y + BS * 2; auto maxWidth = GetMaxWidth(); +#ifdef __WXOSX__ + maxWidth *= scale; +#endif if (trackSize.x > maxWidth) { thumbSize.x -= (trackSize.x - maxWidth) / 2; trackSize.x = maxWidth; @@ -86,7 +98,7 @@ void SwitchButton::Rescale() memdc.SelectObject(bmp); memdc.SetBackground(wxBrush(GetBackgroundColour())); memdc.Clear(); - memdc.SetFont(GetFont()); + memdc.SetFont(dc.GetFont()); auto state = i == 0 ? StateColor::Enabled : (StateColor::Checked | StateColor::Enabled); { #ifdef __WXMSW__ @@ -106,6 +118,9 @@ void SwitchButton::Rescale() memdc.SetTextForeground(text_color.colorForStates(state)); memdc.DrawText(labels[1], {trackSize.x - thumbSize.x - BS + (thumbSize.x - textSize[1].x) / 2, BS + (thumbSize.y - textSize[1].y) / 2}); memdc.SelectObject(wxNullBitmap); +#ifdef __WXOSX__ + bmp = wxBitmap(bmp.ConvertToImage(), -1, scale); +#endif (i == 0 ? m_off : m_on).bmp() = bmp; } } @@ -116,4 +131,4 @@ void SwitchButton::Rescale() void SwitchButton::update() { SetBitmap((GetValue() ? m_on : m_off).bmp()); -} \ No newline at end of file +} From 099e72b885d1515c610ee79bb516db9a181f36ee Mon Sep 17 00:00:00 2001 From: "salt.wei" Date: Thu, 28 Jul 2022 17:44:15 +0800 Subject: [PATCH 056/180] ENH: fix overflow which is caused by wrong spacing Disable the spacing adjustment by bounding box before fixing, to avoid overflow in some cases. Signed-off-by: salt.wei Change-Id: I13c751c8d46040156d79c1fdfc513f22f5e40fe2 --- src/libslic3r/Fill/FillRectilinear.cpp | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/src/libslic3r/Fill/FillRectilinear.cpp b/src/libslic3r/Fill/FillRectilinear.cpp index 0bf27609efb..91c7efc0899 100644 --- a/src/libslic3r/Fill/FillRectilinear.cpp +++ b/src/libslic3r/Fill/FillRectilinear.cpp @@ -3099,6 +3099,8 @@ void FillMonotonicLineWGapFill::fill_surface_extrusion(const Surface* surface, c FillParams params2 = params; params2.monotonic = true; params2.anchor_length_max = 0.0f; + //BBS: always don't adjust the spacing of top surface infill + params2.dont_adjust = true; //BBS: always use no overlap expolygons to avoid overflow in top surface for (const ExPolygon &rectilinear_area : this->no_overlap_expolygons) { @@ -3188,14 +3190,14 @@ void FillMonotonicLineWGapFill::fill_surface_by_lines(const Surface* surface, co std::pair rotate_vector = this->_infill_direction(surface); assert(params.full_infill()); - coord_t line_spacing = coord_t(scale_(this->spacing)); + coord_t line_spacing = params.flow.scaled_spacing(); // On the polygons of poly_with_offset, the infill lines will be connected. ExPolygonWithOffset poly_with_offset( surface->expolygon, - rotate_vector.first, - float(scale_(0 - (0.5 - INFILL_OVERLAP_OVER_SPACING) * this->spacing)), - float(scale_(0 - 0.5f * this->spacing))); + float(scale_(0 - (0.5 - INFILL_OVERLAP_OVER_SPACING) * params.flow.spacing())), + float(scale_(0 - 0.5f * params.flow.spacing()))); if (poly_with_offset.n_contours_inner == 0) { // Not a single infill line fits. //FIXME maybe one shall trigger the gap fill here? @@ -3205,9 +3207,18 @@ void FillMonotonicLineWGapFill::fill_surface_by_lines(const Surface* surface, co BoundingBox bounding_box = poly_with_offset.bounding_box_src(); // define flow spacing according to requested density - assert(!params.dont_adjust); - line_spacing = this->_adjust_solid_spacing(bounding_box.size()(0), line_spacing); - this->spacing = unscale(line_spacing); + if (params.full_infill() && !params.dont_adjust) { + line_spacing = this->_adjust_solid_spacing(bounding_box.size()(0), line_spacing); + this->spacing = unscale(line_spacing); + } else { + // extend bounding box so that our pattern will be aligned with other layers + // Transform the reference point to the rotated coordinate system. + Point refpt = rotate_vector.second.rotated(-rotate_vector.first); + bounding_box.merge(align_to_grid( + bounding_box.min, + Point(line_spacing, line_spacing), + refpt)); + } // Intersect a set of euqally spaced vertical lines wiht expolygon. size_t n_vlines = (bounding_box.max(0) - bounding_box.min(0) + line_spacing - 1) / line_spacing; From 39f9c23b89a3933e1fec1b0d1021575c8c6c4279 Mon Sep 17 00:00:00 2001 From: "chunmao.guo" Date: Wed, 27 Jul 2022 16:24:45 +0800 Subject: [PATCH 057/180] ENH: use system menu on mac platform Change-Id: Ia0e0bf42232d51cd08216811fdc6633527b3eb97 Signed-off-by: chunmao.guo --- src/slic3r/GUI/GUI_App.cpp | 2 + src/slic3r/GUI/GUI_App.hpp | 5 ++ src/slic3r/GUI/MainFrame.cpp | 90 ++++++++++++++++++++++++++++++------ src/slic3r/GUI/Plater.cpp | 4 ++ 4 files changed, 88 insertions(+), 13 deletions(-) diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 4a49333556c..666e6ce467f 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -2057,7 +2057,9 @@ bool GUI_App::on_init_inner() } // BBS: +#ifdef __WINDOWS__ mainframe->topbar()->SaveNormalRect(); +#endif mainframe->Show(true); BOOST_LOG_TRIVIAL(info) << "main frame firstly shown"; diff --git a/src/slic3r/GUI/GUI_App.hpp b/src/slic3r/GUI/GUI_App.hpp index af2b4e13472..cba3d947fad 100644 --- a/src/slic3r/GUI/GUI_App.hpp +++ b/src/slic3r/GUI/GUI_App.hpp @@ -100,6 +100,11 @@ enum ConfigMenuIDs { ConfigMenuCnt, }; +enum BambuStudioMenuIDs { + BambuStudioMenuAbout, + BambuStudioMenuPreferences, +}; + enum CameraMenuIDs { wxID_CAMERA_PERSPECTIVE, wxID_CAMERA_ORTHOGONAL, diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 4d5181158d7..0700811527b 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -142,7 +142,7 @@ static wxIcon main_frame_icon(GUI_App::EAppMode app_mode) #ifdef __WINDOWS__ #define BORDERLESS_FRAME_STYLE (wxRESIZE_BORDER | wxMINIMIZE_BOX | wxMAXIMIZE_BOX | wxCLOSE_BOX) #else -#define BORDERLESS_FRAME_STYLE (wxRESIZE_BORDER) +#define BORDERLESS_FRAME_STYLE (wxMINIMIZE_BOX | wxMAXIMIZE_BOX | wxCLOSE_BOX) #endif wxDEFINE_EVENT(EVT_SYNC_CLOUD_PRESET, SimpleEvent); @@ -184,8 +184,6 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, BORDERLESS_FRAME_ auto panel_topbar = new wxPanel(this, wxID_ANY); panel_topbar->SetBackgroundColour(wxColour(38, 46, 48)); auto sizer_tobar = new wxBoxSizer(wxVERTICAL); - m_topbar = new BBLTopbar(this); - sizer_tobar->Add(m_topbar, 0, wxEXPAND); panel_topbar->SetSizer(sizer_tobar); panel_topbar->Layout(); #endif @@ -286,13 +284,15 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, BORDERLESS_FRAME_ //Bind(wxEVT_MENU, [this](wxCommandEvent&) { m_plater->cut_selection_to_clipboard(); }, wxID_HIGHEST + wxID_CUT); Bind(wxEVT_SIZE, [this](wxSizeEvent&) { BOOST_LOG_TRIVIAL(trace) << "mainframe: size changed, is maximized = " << this->IsMaximized(); +#ifdef __WINDOWS__ if (this->IsMaximized()) { m_topbar->SetWindowSize(); } else { m_topbar->SetMaximizedSize(); } - Refresh(); - Layout(); +#endif + Refresh(); + Layout(); }); //BBS @@ -828,13 +828,14 @@ void MainFrame::init_tabpanel() //monitor } +#ifdef __WINDOWS__ if (sel == tp3DEditor) { m_topbar->EnableUndoRedoItems(); } else { m_topbar->DisableUndoRedoItems(); } - +#endif /*switch (sel) { case TabPosition::tpHome: @@ -1475,8 +1476,10 @@ void MainFrame::on_dpi_changed(const wxRect& suggested_rect) dynamic_cast(m_tabpanel)->Rescale(); #endif +#ifdef __WINDOWS__ // BBS m_topbar->Rescale(); +#endif m_tabpanel->Rescale(); @@ -1596,9 +1599,11 @@ static wxMenu* generate_help_menu() return true; }); // About +#ifdef __WINDOWS__ wxString about_title = wxString::Format(_L("&About %s"), SLIC3R_APP_FULL_NAME); append_menu_item(helpMenu, wxID_ANY, about_title, about_title, [](wxCommandEvent&) { Slic3r::GUI::about(); }); +#endif return helpMenu; } @@ -1628,6 +1633,7 @@ void MainFrame::init_menubar_as_editor() { #ifdef __APPLE__ wxMenuBar::SetAutoWindowMenu(false); + m_menubar = new wxMenuBar(); #endif // File menu @@ -1890,10 +1896,18 @@ void MainFrame::init_menubar_as_editor() //auto config_wizard_name = _(ConfigWizard::name(true) + "(Debug)"); //const auto config_wizard_tooltip = from_u8((boost::format(_utf8(L("Run %s"))) % config_wizard_name).str()); //auto config_item = new wxMenuItem(m_topbar->GetTopMenu(), ConfigMenuWizard + config_id_base, config_wizard_name, config_wizard_tooltip); - auto preference_item = new wxMenuItem(m_topbar->GetTopMenu(), ConfigMenuPreferences + config_id_base, _L("Preferences") + "\tCtrl+P", ""); - //auto printer_item = new wxMenuItem(m_topbar->GetTopMenu(), ConfigMenuPrinter + config_id_base, _L("Printer"), ""); - //auto language_item = new wxMenuItem(m_topbar->GetTopMenu(), ConfigMenuLanguage + config_id_base, _L("Switch Language"), ""); - m_topbar->GetTopMenu()->Bind(wxEVT_MENU, [this, config_id_base](wxEvent& event) { +#ifdef __APPLE__ + wxWindowID bambu_studio_id_base = wxWindow::NewControlId(int(2)); + wxMenu* parent_menu = m_menubar->OSXGetAppleMenu(); + auto preference_item = new wxMenuItem(parent_menu, BambuStudioMenuPreferences + bambu_studio_id_base, _L("Preferences") + "\tCtrl+P", ""); +#else + wxMenu* parent_menu = m_topbar->GetTopMenu(); + auto preference_item = new wxMenuItem(parent_menu, ConfigMenuPreferences + config_id_base, _L("Preferences") + "\tCtrl+P", ""); +#endif + + //auto printer_item = new wxMenuItem(parent_menu, ConfigMenuPrinter + config_id_base, _L("Printer"), ""); + //auto language_item = new wxMenuItem(parent_menu, ConfigMenuLanguage + config_id_base, _L("Switch Language"), ""); + parent_menu->Bind(wxEVT_MENU, [this, config_id_base](wxEvent& event) { switch (event.GetId() - config_id_base) { //case ConfigMenuLanguage: //{ @@ -1958,10 +1972,50 @@ void MainFrame::init_menubar_as_editor() } }); - +#ifdef __APPLE__ + wxString about_title = wxString::Format(_L("&About %s"), SLIC3R_APP_FULL_NAME); + auto about_item = new wxMenuItem(parent_menu, BambuStudioMenuAbout + bambu_studio_id_base, about_title, ""); + parent_menu->Bind(wxEVT_MENU, [this, bambu_studio_id_base](wxEvent& event) { + switch (event.GetId() - bambu_studio_id_base) { + case BambuStudioMenuAbout: + Slic3r::GUI::about(); + break; + case BambuStudioMenuPreferences: + wxGetApp().CallAfter([this] { + PreferencesDialog dlg(this); + dlg.ShowModal(); + #if ENABLE_GCODE_LINES_ID_IN_H_SLIDER + if (dlg.seq_top_layer_only_changed() || dlg.seq_seq_top_gcode_indices_changed()) + #else + if (dlg.seq_top_layer_only_changed()) + #endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER + plater()->refresh_print(); + #if ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN + #ifdef _WIN32 + /* + if (wxGetApp().app_config()->get("associate_3mf") == "true") + wxGetApp().associate_3mf_files(); + if (wxGetApp().app_config()->get("associate_stl") == "true") + wxGetApp().associate_stl_files(); + /*if (wxGetApp().app_config()->get("associate_step") == "true") + wxGetApp().associate_step_files();*/ + #endif // _WIN32 + #endif + }); + break; + default: + break; + } + + }); + parent_menu->Insert(0, about_item); + parent_menu->Insert(1, preference_item); +#endif // Help menu auto helpMenu = generate_help_menu(); + +#ifdef __WINDOWS__ m_topbar->SetFileMenu(fileMenu); if (editMenu) m_topbar->AddDropDownSubMenu(editMenu, _L("Edit")); @@ -1973,6 +2027,16 @@ void MainFrame::init_menubar_as_editor() //m_topbar->AddDropDownMenuItem(language_item); //m_topbar->AddDropDownMenuItem(config_item); m_topbar->AddDropDownSubMenu(helpMenu, _L("Help")); +#else + m_menubar->Append(fileMenu, _L("&File")); + if (editMenu) + m_menubar->Append(editMenu, _L("&Edit")); + if (viewMenu) + m_menubar->Append(viewMenu, _L("&View")); + if (helpMenu) + m_menubar->Append(helpMenu, _L("&Help")); + SetMenuBar(m_menubar); +#endif #ifdef _MSW_DARK_MODE if (wxGetApp().tabs_as_menu()) @@ -1982,12 +2046,12 @@ void MainFrame::init_menubar_as_editor() #ifdef __APPLE__ // This fixes a bug on Mac OS where the quit command doesn't emit window close events // wx bug: https://trac.wxwidgets.org/ticket/18328 - /* wxMenu* apple_menu = m_menubar->OSXGetAppleMenu(); + wxMenu* apple_menu = m_menubar->OSXGetAppleMenu(); if (apple_menu != nullptr) { apple_menu->Bind(wxEVT_MENU, [this](wxCommandEvent &) { Close(); }, wxID_EXIT); - }*/ + } #endif // __APPLE__ } diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 1d7f30743ca..d957a3f8832 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -5557,7 +5557,11 @@ void Plater::priv::set_project_name(const wxString& project_name) { m_project_name = project_name; //update topbar title +#ifdef __WINDOWS__ wxGetApp().mainframe->topbar()->SetTitle(m_project_name); +#else + wxGetApp().mainframe->SetTitle(m_project_name); +#endif } void Plater::priv::set_project_filename(const wxString& filename) From a302a58c9e731bf906dd5ff97a5cdcb9c006626a Mon Sep 17 00:00:00 2001 From: "chunmao.guo" Date: Thu, 28 Jul 2022 13:17:03 +0800 Subject: [PATCH 058/180] FIX: support key event in SpinInput Change-Id: Ie25404c8dec25b0b4012cae51a1f57c95d9fca66 --- src/slic3r/GUI/Widgets/SpinInput.cpp | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/Widgets/SpinInput.cpp b/src/slic3r/GUI/Widgets/SpinInput.cpp index e68806040cf..5cb556bbdde 100644 --- a/src/slic3r/GUI/Widgets/SpinInput.cpp +++ b/src/slic3r/GUI/Widgets/SpinInput.cpp @@ -66,6 +66,7 @@ SpinInput::SpinInput(wxWindow * parent, }); text_ctrl->Bind(wxEVT_KILL_FOCUS, &SpinInput::onTextLostFocus, this); text_ctrl->Bind(wxEVT_TEXT_ENTER, &SpinInput::onTextEnter, this); + text_ctrl->Bind(wxEVT_KEY_DOWN, &SpinInput::keyPressed, this); text_ctrl->Bind(wxEVT_RIGHT_DOWN, [this](auto &e) {}); // disable context menu button_inc = createButton(true); button_dec = createButton(false); @@ -313,7 +314,27 @@ void SpinInput::mouseWheelMoved(wxMouseEvent &event) // currently unused events void SpinInput::mouseMoved(wxMouseEvent& event) {} -void SpinInput::keyPressed(wxKeyEvent& event) {} + +void SpinInput::keyPressed(wxKeyEvent &event) +{ + switch (event.GetKeyCode()) { + case WXK_UP: + case WXK_DOWN: + long value; + if (!text_ctrl->GetValue().ToLong(&value)) { value = val; } + if (event.GetKeyCode() == WXK_DOWN && value > min) { + --value; + } else if (event.GetKeyCode() == WXK_UP && value + 1 < max) { + ++value; + } + if (value != val) { + SetValue(value); + sendSpinEvent(); + } + break; + default: event.Skip(); break; + } +} void SpinInput::keyReleased(wxKeyEvent &event) {} void SpinInput::sendSpinEvent() From 7a5bca3c301773e646fa18098a12cca0a1b4d818 Mon Sep 17 00:00:00 2001 From: "chunmao.guo" Date: Wed, 27 Jul 2022 19:33:30 +0800 Subject: [PATCH 059/180] FIX: enable focus navigation in SpinInput/TextInput Change-Id: I32671cb8aa23f85b868284c41a66c583161e1b89 --- src/slic3r/GUI/Widgets/SpinInput.cpp | 47 ++++++++++++++++++---------- src/slic3r/GUI/Widgets/SpinInput.hpp | 14 ++++++++- src/slic3r/GUI/Widgets/TextInput.cpp | 4 ++- src/slic3r/GUI/Widgets/TextInput.hpp | 2 +- 4 files changed, 47 insertions(+), 20 deletions(-) diff --git a/src/slic3r/GUI/Widgets/SpinInput.cpp b/src/slic3r/GUI/Widgets/SpinInput.cpp index 5cb556bbdde..4d96d849e33 100644 --- a/src/slic3r/GUI/Widgets/SpinInput.cpp +++ b/src/slic3r/GUI/Widgets/SpinInput.cpp @@ -24,32 +24,46 @@ END_EVENT_TABLE() * calling Refresh()/Update(). */ -SpinInput::SpinInput(wxWindow * parent, +SpinInput::SpinInput() + : state_handler(this) + , border_color(std::make_pair(0xDBDBDB, (int) StateColor::Disabled), + std::make_pair(0x00AE42, (int) StateColor::Focused), + std::make_pair(0x00AE42, (int) StateColor::Hovered), + std::make_pair(0xDBDBDB, (int) StateColor::Normal)) + , text_color(std::make_pair(0xACACAC, (int) StateColor::Disabled), std::make_pair(*wxBLACK, (int) StateColor::Normal)) + , background_color(std::make_pair(0xF0F0F0, (int) StateColor::Disabled), std::make_pair(*wxWHITE, (int) StateColor::Normal)) +{ + hover = false; + radius = 0; +} + + +SpinInput::SpinInput(wxWindow *parent, wxString text, wxString label, const wxPoint &pos, const wxSize & size, long style, int min, int max, int initial) - : wxWindow(parent, wxID_ANY, pos, size) - , state_handler(this) - , border_color(std::make_pair(0xDBDBDB, (int) StateColor::Disabled), - std::make_pair(0x00AE42, (int) StateColor::Focused), - std::make_pair(0x00AE42, (int) StateColor::Hovered), - std::make_pair(0xDBDBDB, (int) StateColor::Normal)) - , text_color(std::make_pair(0xACACAC, (int) StateColor::Disabled), - std::make_pair(*wxBLACK, (int) StateColor::Normal)) - , background_color(std::make_pair(0xF0F0F0, (int) StateColor::Disabled), - std::make_pair(*wxWHITE, (int) StateColor::Normal)) + : SpinInput() { - hover = false; - radius = 0; + Create(parent, text, label, pos, size, style, min, max, initial); +} + +void SpinInput::Create(wxWindow *parent, + wxString text, + wxString label, + const wxPoint &pos, + const wxSize & size, + long style, + int min, int max, int initial) +{ + wxWindow::Create(parent, wxID_ANY, pos, size); SetFont(Label::Body_12); wxWindow::SetLabel(label); state_handler.attach({&border_color, &text_color, &background_color}); state_handler.update_binds(); - text_ctrl = new wxTextCtrl(this, wxID_ANY, text, {20, 4}, wxDefaultSize, - style | wxBORDER_NONE | wxTE_PROCESS_ENTER, wxTextValidator(wxFILTER_DIGITS)); + text_ctrl = new wxTextCtrl(this, wxID_ANY, text, {20, 4}, wxDefaultSize, style | wxBORDER_NONE | wxTE_PROCESS_ENTER, wxTextValidator(wxFILTER_DIGITS)); text_ctrl->SetFont(Label::Body_14); text_ctrl->SetInitialSize(text_ctrl->GetBestSize()); text_ctrl->Bind(wxEVT_SET_FOCUS, [this](auto &e) { @@ -74,8 +88,7 @@ SpinInput::SpinInput(wxWindow * parent, timer.Bind(wxEVT_TIMER, &SpinInput::onTimer, this); long initialFromText; - if ( text.ToLong(&initialFromText) ) - initial = initialFromText; + if (text.ToLong(&initialFromText)) initial = initialFromText; SetRange(min, max); SetValue(initial); messureSize(); diff --git a/src/slic3r/GUI/Widgets/SpinInput.hpp b/src/slic3r/GUI/Widgets/SpinInput.hpp index 2986a8eaa8b..aded55bfbe3 100644 --- a/src/slic3r/GUI/Widgets/SpinInput.hpp +++ b/src/slic3r/GUI/Widgets/SpinInput.hpp @@ -7,7 +7,7 @@ class Button; -class SpinInput : public wxWindow +class SpinInput : public wxNavigationEnabled { bool hover; @@ -31,6 +31,8 @@ class SpinInput : public wxWindow static const int SpinInputHeight = 50; public: + SpinInput(); + SpinInput(wxWindow * parent, wxString text, wxString label = "", @@ -39,6 +41,16 @@ class SpinInput : public wxWindow long style = 0, int min = 0, int max = 100, int initial = 0); + void Create(wxWindow * parent, + wxString text, + wxString label = "", + const wxPoint &pos = wxDefaultPosition, + const wxSize & size = wxDefaultSize, + long style = 0, + int min = 0, + int max = 100, + int initial = 0); + void SetCornerRadius(double radius); void SetLabel(const wxString &label) wxOVERRIDE; diff --git a/src/slic3r/GUI/Widgets/TextInput.cpp b/src/slic3r/GUI/Widgets/TextInput.cpp index a54fe984dda..1b962a27813 100644 --- a/src/slic3r/GUI/Widgets/TextInput.cpp +++ b/src/slic3r/GUI/Widgets/TextInput.cpp @@ -61,7 +61,6 @@ void TextInput::Create(wxWindow * parent, { text_ctrl = nullptr; wxWindow::Create(parent, wxID_ANY, pos, size, style); - wxWindow::SetLabel(label); style &= ~wxRIGHT; state_handler.attach({&border_color, &text_color, &background_color}); @@ -246,6 +245,9 @@ void TextInput::messureSize() wxClientDC dc(this); labelSize = dc.GetTextExtent(wxWindow::GetLabel()); wxSize textSize = text_ctrl->GetSize(); +#ifdef __WXOSX__ + textSize.y -= 3; // TODO: +#endif int h = textSize.y + 8; if (size.y < h) { size.y = h; diff --git a/src/slic3r/GUI/Widgets/TextInput.hpp b/src/slic3r/GUI/Widgets/TextInput.hpp index e38de481d1f..92f5e8827c3 100644 --- a/src/slic3r/GUI/Widgets/TextInput.hpp +++ b/src/slic3r/GUI/Widgets/TextInput.hpp @@ -5,7 +5,7 @@ #include "../wxExtensions.hpp" #include "StateHandler.hpp" -class TextInput : public wxWindow +class TextInput : public wxNavigationEnabled { bool hover; From d14e5c9d594c958d1727c7494b761134330c432e Mon Sep 17 00:00:00 2001 From: "yifan.wu" Date: Thu, 28 Jul 2022 23:05:46 +0800 Subject: [PATCH 060/180] ENH: change alt behavior for part selection 1. Alt is no long for object/part delection 2. Alt is defined to select part in View3D Signed-off-by: yifan.wu Change-Id: If0f14f79a321be2d0320a841e15dc973715364ea (cherry picked from commit 9c092f2d20b89470202df037180425b2ecb8ef82) --- src/slic3r/GUI/GLCanvas3D.cpp | 4 +++- src/slic3r/GUI/GUI_Preview.cpp | 1 + src/slic3r/GUI/Selection.hpp | 6 +++++- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 8b38dabbec3..a5b6866ab78 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3180,7 +3180,9 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) return; } - if (evt.LeftDown() && (evt.ShiftDown() || evt.AltDown()) && m_picking_enabled) { + // BBS: define Alt key to enable volume selection mode + m_selection.set_volume_selection_mode(evt.AltDown() ? Selection::Volume : Selection::Instance); + if (evt.LeftDown() && evt.ShiftDown() && m_picking_enabled) { if (m_gizmos.get_current_type() != GLGizmosManager::SlaSupports && m_gizmos.get_current_type() != GLGizmosManager::FdmSupports && m_gizmos.get_current_type() != GLGizmosManager::Seam diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 374894a50db..d9db9e0f31c 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -766,6 +766,7 @@ bool AssembleView::init(wxWindow* parent, Bed3D& bed, Model* model, DynamicPrint // BBS: set volume_selection_mode to Volume m_canvas->get_selection().set_volume_selection_mode(Selection::Volume); + m_canvas->get_selection().lock_volume_selection_mode(); wxBoxSizer* main_sizer = new wxBoxSizer(wxVERTICAL); main_sizer->Add(m_canvas_widget, 1, wxALL | wxEXPAND, 0); diff --git a/src/slic3r/GUI/Selection.hpp b/src/slic3r/GUI/Selection.hpp index 5c24160f9a5..96a98e5ab5b 100644 --- a/src/slic3r/GUI/Selection.hpp +++ b/src/slic3r/GUI/Selection.hpp @@ -226,6 +226,7 @@ class Selection // BBS EMode m_volume_selection_mode{ Instance }; + bool m_volume_selection_locked { false }; public: Selection(); @@ -343,7 +344,10 @@ class Selection void translate(unsigned int object_idx, unsigned int instance_idx, const Vec3d& displacement); //BBS: add partplate related logic void notify_instance_update(int object_idx, int instance_idx); - void set_volume_selection_mode(EMode mode) { m_volume_selection_mode = mode; } + // BBS + void set_volume_selection_mode(EMode mode) { if (!m_volume_selection_locked) m_volume_selection_mode = mode; } + void lock_volume_selection_mode() { m_volume_selection_locked = true; } + void unlock_volume_selection_mode() { m_volume_selection_locked = false; } void erase(); From 0d1242d9c66b8de36f5cc2484268c513cb4592d9 Mon Sep 17 00:00:00 2001 From: tao wang Date: Thu, 28 Jul 2022 21:20:06 +0800 Subject: [PATCH 061/180] FIX:change title background colour on macos Change-Id: I387bd8c1b6d74f4db92417c3459959b3212af9f5 --- src/slic3r/Utils/MacDarkMode.mm | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/slic3r/Utils/MacDarkMode.mm b/src/slic3r/Utils/MacDarkMode.mm index 7e704221601..1730d4a8852 100644 --- a/src/slic3r/Utils/MacDarkMode.mm +++ b/src/slic3r/Utils/MacDarkMode.mm @@ -37,6 +37,11 @@ bool mac_dark_mode() void set_miniaturizable(void * window) { + CGFloat rFloat = 38/255.0; + CGFloat gFloat = 46/255.0; + CGFloat bFloat = 48/255.0; + [(NSView*) window window].titlebarAppearsTransparent = true; + [(NSView*) window window].backgroundColor = [NSColor colorWithCalibratedRed:rFloat green:gFloat blue:bFloat alpha:1.0]; [(NSView*) window window].styleMask |= NSMiniaturizableWindowMask; } From 4d52b8a44a0bff0d2ae786ddc636daf0c11989f9 Mon Sep 17 00:00:00 2001 From: "lane.wei" Date: Tue, 26 Jul 2022 12:23:21 +0800 Subject: [PATCH 062/180] add more logs for debugging Change-Id: I420e6e60901a32cc378c09ed57fba2ee1ac688df --- src/slic3r/GUI/WebGuideDialog.cpp | 15 ++++++++++----- src/slic3r/Utils/NetworkAgent.cpp | 8 +++++--- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/slic3r/GUI/WebGuideDialog.cpp b/src/slic3r/GUI/WebGuideDialog.cpp index ab66b63d96a..4b83a48b3ef 100644 --- a/src/slic3r/GUI/WebGuideDialog.cpp +++ b/src/slic3r/GUI/WebGuideDialog.cpp @@ -109,15 +109,18 @@ GuideFrame::~GuideFrame() void GuideFrame::load_url(wxString &url) { - BOOST_LOG_TRIVIAL(trace) << "app_start: GuideFrame url=" << url.ToStdString(); + BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< " enter, url=" << url.ToStdString(); this->Show(); WebView::LoadUrl(m_browser, url); m_browser->SetFocus(); UpdateState(); + + BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< " exit"; } wxString GuideFrame::SetStartPage(GuidePage startpage, bool load) { + BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< boost::format(" enter, load=%1%, start_page=%2%")%load%int(startpage); //wxLogMessage("GUIDE: webpage_1 %s", (boost::filesystem::path(resources_dir()) / "web\\guide\\1\\index.html").make_preferred().string().c_str() ); wxString TargetUrl = from_u8( (boost::filesystem::path(resources_dir()) / "web/guide/1/index.html").make_preferred().string() ); //wxLogMessage("GUIDE: webpage_2 %s", TargetUrl.mb_str()); @@ -153,6 +156,7 @@ wxString GuideFrame::SetStartPage(GuidePage startpage, bool load) } std::string strlang = wxGetApp().app_config->get("language"); + BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< boost::format(", strlang=%1%")%strlang; if (strlang != "") TargetUrl = wxString::Format("%s?lang=%s", w2s(TargetUrl), strlang); @@ -160,6 +164,7 @@ wxString GuideFrame::SetStartPage(GuidePage startpage, bool load) if (load) load_url(TargetUrl); + BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< " exit"; return TargetUrl; } @@ -353,8 +358,8 @@ void GuideFrame::OnScriptMessage(wxWebViewEvent &evt) } this->EndModal(wxID_OK); - - if (InstallNetplugin) + + if (InstallNetplugin) GUI::wxGetApp().CallAfter([this] { GUI::wxGetApp().ShowDownNetPluginDlg(); }); if (bLogin) @@ -365,7 +370,7 @@ void GuideFrame::OnScriptMessage(wxWebViewEvent &evt) this->Close(); } else if (strCmd == "save_region") { m_Region = j["region"]; - } + } else if (strCmd == "network_plugin_install") { std::string sAction = j["data"]["action"]; @@ -925,7 +930,7 @@ int GuideFrame::LoadProfile() //----region m_Region = wxGetApp().app_config->get("region"); m_ProfileJson["region"] = m_Region; - + m_ProfileJson["network_plugin_install"] = wxGetApp().app_config->get("app","installed_networking"); m_ProfileJson["network_plugin_compability"] = wxGetApp().is_compatibility_version() ? "1" : "0"; } diff --git a/src/slic3r/Utils/NetworkAgent.cpp b/src/slic3r/Utils/NetworkAgent.cpp index 6d9f0b4c457..f53dd98b86d 100644 --- a/src/slic3r/Utils/NetworkAgent.cpp +++ b/src/slic3r/Utils/NetworkAgent.cpp @@ -141,7 +141,9 @@ int NetworkAgent::initialize_network_module() library = std::string("lib") + BAMBU_NETWORK_LIBRARY + ".so"; #endif*/ //netwoking_module = dlopen( library.c_str(), RTLD_LAZY); - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", error, dlerror is %1%")%dlerror(); + char* dll_error = dlerror(); + printf("error, dlerror is %s\n", dll_error); + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", error, dlerror is %1%")%dll_error; } printf("after dlopen, network_module is %p\n", netwoking_module); #endif @@ -383,13 +385,13 @@ std::string NetworkAgent::get_version() #endif } if (!consistent) { - BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(", inconsistent library,return 00.00.00.00!"); + BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(", inconsistent library,return 00.00.00.00!"); return "00.00.00.00"; } if (get_version_ptr) { return get_version_ptr(); } - BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(", get_version not supported,return 00.00.00.00!"); + BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(", get_version not supported,return 00.00.00.00!"); return "00.00.00.00"; } From e6131fc5f70fff4058c6b010544e473fe67b0bd6 Mon Sep 17 00:00:00 2001 From: "lane.wei" Date: Thu, 28 Jul 2022 17:02:30 +0800 Subject: [PATCH 063/180] ENH: render: adjust the logo background color to bed's color use the color of bed's stl Change-Id: I56f1e184a27271b8bea5704f823ae7b28b656a46 --- resources/profiles/BBL/bbl-3dp-logo.svg | 77 +++++++++++-------------- src/slic3r/GUI/PartPlate.cpp | 6 +- 2 files changed, 38 insertions(+), 45 deletions(-) diff --git a/resources/profiles/BBL/bbl-3dp-logo.svg b/resources/profiles/BBL/bbl-3dp-logo.svg index f0062e3cf6b..d17daf639a4 100644 --- a/resources/profiles/BBL/bbl-3dp-logo.svg +++ b/resources/profiles/BBL/bbl-3dp-logo.svg @@ -1,43 +1,36 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/slic3r/GUI/PartPlate.cpp b/src/slic3r/GUI/PartPlate.cpp index 9a63a5cfe82..f764c74b536 100644 --- a/src/slic3r/GUI/PartPlate.cpp +++ b/src/slic3r/GUI/PartPlate.cpp @@ -62,7 +62,7 @@ namespace GUI { class Bed3D; -std::array PartPlate::SELECT_COLOR = { 0.4196f, 0.4235f, 0.4235f, 1.0f }; +std::array PartPlate::SELECT_COLOR = { 0.2666f, 0.2784f, 0.2784f, 1.0f }; //{ 0.4196f, 0.4235f, 0.4235f, 1.0f }; std::array PartPlate::UNSELECT_COLOR = { 0.82f, 0.82f, 0.82f, 1.0f }; std::array PartPlate::DEFAULT_COLOR = { 0.5f, 0.5f, 0.5f, 1.0f }; std::array PartPlate::LINE_TOP_COLOR = { 0.89f, 0.89f, 0.89f, 1.0f }; @@ -199,11 +199,11 @@ void PartPlate::calc_gridlines(const ExPolygon& poly, const BoundingBox& pp_bbox line.append(Point(x, pp_bbox.min(1))); line.append(Point(x, pp_bbox.max(1))); - count ++; if ( (count % 5) == 0 ) axes_lines_bolder.push_back(line); else axes_lines.push_back(line); + count ++; } count = 0; for (coord_t y = pp_bbox.min(1); y <= pp_bbox.max(1); y += scale_(10.0)) { @@ -212,11 +212,11 @@ void PartPlate::calc_gridlines(const ExPolygon& poly, const BoundingBox& pp_bbox line.append(Point(pp_bbox.max(0), y)); axes_lines.push_back(line); - count ++; if ( (count % 5) == 0 ) axes_lines_bolder.push_back(line); else axes_lines.push_back(line); + count ++; } // clip with a slightly grown expolygon because our lines lay on the contours and may get erroneously clipped From 92ad7ff1d0e05d06de20cc9d81cdfd182db17827 Mon Sep 17 00:00:00 2001 From: "lane.wei" Date: Fri, 29 Jul 2022 15:04:32 +0800 Subject: [PATCH 064/180] Fix the app can not launch issue under case-sensitive APFS on macos Change-Id: I849bd8023c0973b0603e1cbaadbd7035c276a745 (cherry picked from commit 5d08ccd146eb818c83825e28337834a6abdf4fbe) --- src/slic3r/GUI/ImGuiWrapper.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/slic3r/GUI/ImGuiWrapper.cpp b/src/slic3r/GUI/ImGuiWrapper.cpp index a00a5aa3f65..c34551534ec 100644 --- a/src/slic3r/GUI/ImGuiWrapper.cpp +++ b/src/slic3r/GUI/ImGuiWrapper.cpp @@ -58,7 +58,7 @@ static const std::map font_icons = { {ImGui::SliderFloatEditBtnIcon, "edit_button" }, #endif // ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT {ImGui::CircleButtonIcon , "circle_paint" }, - {ImGui::TriangleButtonIcon , "Triangle_paint" }, + {ImGui::TriangleButtonIcon , "triangle_paint" }, {ImGui::FillButtonIcon , "fill_paint" }, {ImGui::HeightRangeIcon , "height_range" }, {ImGui::GapFillIcon , "gap_fill" }, @@ -196,7 +196,7 @@ bool slider_behavior(ImGuiID id, const ImRect& region, const ImS32 v_min, const mouse_wheel_responsive_region = ImRect(region.Min - ImVec2(0, handle_sz.y), region.Max + ImVec2(0, handle_sz.y)); if (ImGui::ItemHoverable(mouse_wheel_responsive_region, id)) { #ifdef __APPLE__ - if (io.KeyShift) + if (io.KeyShift) v_new = ImClamp(*out_value - 5 * (ImS32) (context.IO.MouseWheel), v_min, v_max); else if (io.KeyCtrl) v_new = ImClamp(*out_value + 5 * (ImS32) (context.IO.MouseWheel), v_min, v_max); @@ -236,7 +236,7 @@ bool slider_behavior(ImGuiID id, const ImRect& region, const ImS32 v_min, const { v_new = fixed_value; } - + // apply result, output value if (*out_value != v_new) { @@ -606,7 +606,7 @@ bool ImGuiWrapper::bbl_slider_float_style(const std::string &label, float *v, fl bool ImGuiWrapper::bbl_slider_float(const std::string& label, float* v, float v_min, float v_max, const char* format, float power, bool clamp, const wxString& tooltip) { - + const float max_tooltip_width = ImGui::GetFontSize() * 20.0f; // let the label string start with "##" to hide the automatic label from ImGui::SliderFloat() @@ -969,7 +969,7 @@ bool ImGuiWrapper::combo(const wxString& label, const std::vector& return res; } -// Scroll up for one item +// Scroll up for one item static void scroll_up() { ImGuiContext& g = *GImGui; @@ -981,7 +981,7 @@ static void scroll_up() ImGui::SetScrollY(win_top - item_size_y); } -// Scroll down for one item +// Scroll down for one item static void scroll_down() { ImGuiContext& g = *GImGui; @@ -1229,7 +1229,7 @@ void ImGuiWrapper::search_list(const ImVec2& size_, bool (*items_getter)(int, co { int& hovered_id = view_params.hovered_id; // ImGui::ListBoxHeader("", size); - { + { // rewrote part of function to add a TextInput instead of label Text ImGuiContext& g = *GImGui; ImGuiWindow* window = ImGui::GetCurrentWindow(); From 6a08c2d50926c46a400479dec1e3b0d30b5605c9 Mon Sep 17 00:00:00 2001 From: "lane.wei" Date: Thu, 28 Jul 2022 19:58:06 +0800 Subject: [PATCH 065/180] ENH: preview: refine the logic to switch camera view when switch between preview and view3D, if the screen center is on the plate don't change to the plate view Change-Id: I16b8815ad9b10a7cea174faa6a16bb9e582a77c3 --- src/slic3r/GUI/GLCanvas3D.hpp | 8 ++++---- src/slic3r/GUI/PartPlate.cpp | 11 +++-------- src/slic3r/GUI/PartPlate.hpp | 4 +--- src/slic3r/GUI/Plater.cpp | 9 ++++++++- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 21de36f8c5f..d11f0508bff 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -909,6 +909,10 @@ class GLCanvas3D bool is_object_sinking(int object_idx) const; + // Convert the screen space coordinate to an object space coordinate. + // If the Z screen space coordinate is not provided, a depth buffer value is substituted. + Vec3d _mouse_to_3d(const Point& mouse_pos, float* z = nullptr); + private: bool _is_shown_on_screen() const; @@ -981,10 +985,6 @@ class GLCanvas3D void _update_volumes_hover_state(); - // Convert the screen space coordinate to an object space coordinate. - // If the Z screen space coordinate is not provided, a depth buffer value is substituted. - Vec3d _mouse_to_3d(const Point& mouse_pos, float* z = nullptr); - // Convert the screen space coordinate to world coordinate on the bed. Vec3d _mouse_to_bed_3d(const Point& mouse_pos); diff --git a/src/slic3r/GUI/PartPlate.cpp b/src/slic3r/GUI/PartPlate.cpp index f764c74b536..8e240b04e25 100644 --- a/src/slic3r/GUI/PartPlate.cpp +++ b/src/slic3r/GUI/PartPlate.cpp @@ -1840,7 +1840,7 @@ bool PartPlate::set_shape(const Pointfs& shape, const Pointfs& exclude_areas, Ve ExPolygon logo_poly; generate_logo_polygon(logo_poly); if (!m_logo_triangles.set_from_triangles(triangulate_expolygon_2f(logo_poly, NORMALS_UP), GROUND_Z+0.02f)) - BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ":Unable to create plate triangles\n"; + BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ":Unable to create logo triangles\n"; ExPolygon poly; /*for (const Vec2d& p : m_shape) { @@ -1883,9 +1883,9 @@ const BoundingBox PartPlate::get_bounding_box_crd() return plate_shape.bounding_box(); } -bool PartPlate::contains(const Point& point) const +bool PartPlate::contains(const Vec3d& point) const { - return m_polygon.contains(point); + return m_bounding_box.contains(point); } bool PartPlate::contains(const GLVolume& v) const @@ -1917,11 +1917,6 @@ bool PartPlate::intersects(const BoundingBoxf3& bb) const return print_volume.intersects(bb); } -Point PartPlate::point_projection(const Point& point) const -{ - return m_polygon.point_projection(point); -} - void PartPlate::render(bool bottom, bool only_body, bool force_background_color, HeightLimitMode mode, int hover_id) { glsafe(::glEnable(GL_DEPTH_TEST)); diff --git a/src/slic3r/GUI/PartPlate.hpp b/src/slic3r/GUI/PartPlate.hpp index b0a29125c45..8dbff320a9d 100644 --- a/src/slic3r/GUI/PartPlate.hpp +++ b/src/slic3r/GUI/PartPlate.hpp @@ -114,7 +114,6 @@ class PartPlate : public ObjectBase Transform3d m_grabber_trans_matrix; Slic3r::Geometry::Transformation position; std::vector positions; - Polygon m_polygon; unsigned int m_vbo_id{ 0 }; GeometryBuffer m_triangles; GeometryBuffer m_exclude_triangles; @@ -285,12 +284,11 @@ class PartPlate : public ObjectBase /*rendering related functions*/ const Pointfs& get_shape() const { return m_shape; } bool set_shape(const Pointfs& shape, const Pointfs& exclude_areas, Vec2d position, float height_to_lid, float height_to_rod); - bool contains(const Point& point) const; + bool contains(const Vec3d& point) const; bool contains(const GLVolume& v) const; bool contains(const BoundingBoxf3& bb) const; bool intersects(const BoundingBoxf3& bb) const; - Point point_projection(const Point& point) const; void render(bool bottom, bool only_body = false, bool force_background_color = false, HeightLimitMode mode = HEIGHT_LIMIT_NONE, int hover_id = -1); void render_for_picking() const { on_render_for_picking(); } void set_selected(); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index d957a3f8832..834a1a26620 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -4482,7 +4482,14 @@ void Plater::priv::set_current_panel(wxPanel* panel, bool no_slice) preview->get_canvas3d()->render(true); } } - this->partplate_list.select_plate_view(); + //TODO: turn off this switch currently + /*auto canvas_w = float(preview->get_canvas3d()->get_canvas_size().get_width()); + auto canvas_h = float(preview->get_canvas3d()->get_canvas_size().get_height()); + Point screen_center(canvas_w/2, canvas_h/2); + auto center_point = preview->get_canvas3d()->_mouse_to_3d(screen_center); + center_point(2) = 0.f; + if (!current_plate->contains(center_point)) + this->partplate_list.select_plate_view();*/ // keeps current gcode preview, if any if (this->m_slice_all) { From 93cbd5173f722a4f919898fb8d343c33709ad9fd Mon Sep 17 00:00:00 2001 From: "chunmao.guo" Date: Thu, 28 Jul 2022 11:08:59 +0800 Subject: [PATCH 066/180] FIX: support key event in ComboBox Change-Id: Iac5f114ff45123f0a6b1bc24ef289a6112475183 --- src/slic3r/GUI/Widgets/ComboBox.cpp | 62 ++++++++++++++++++++++++++--- src/slic3r/GUI/Widgets/ComboBox.hpp | 5 +++ src/slic3r/GUI/Widgets/DropDown.cpp | 2 + 3 files changed, 63 insertions(+), 6 deletions(-) diff --git a/src/slic3r/GUI/Widgets/ComboBox.cpp b/src/slic3r/GUI/Widgets/ComboBox.cpp index bdbdc82da4d..d4d4e28c598 100644 --- a/src/slic3r/GUI/Widgets/ComboBox.cpp +++ b/src/slic3r/GUI/Widgets/ComboBox.cpp @@ -7,6 +7,7 @@ BEGIN_EVENT_TABLE(ComboBox, TextInput) EVT_LEFT_DOWN(ComboBox::mouseDown) //EVT_MOUSEWHEEL(ComboBox::mouseWheelMoved) +EVT_KEY_DOWN(ComboBox::keyDown) // catch paint events END_EVENT_TABLE() @@ -33,8 +34,7 @@ ComboBox::ComboBox(wxWindow * parent, TextInput::Create(parent, "", value, (style & CB_NO_DROP_ICON) ? "" : "drop_down", pos, size, style | wxTE_PROCESS_ENTER); - if (style & wxCB_READONLY) - { + if (style & wxCB_READONLY) { GetTextCtrl()->Hide(); TextInput::SetFont(Label::Body_14); TextInput::SetBorderColor(StateColor(std::make_pair(0xDBDBDB, (int) StateColor::Disabled), @@ -44,6 +44,8 @@ ComboBox::ComboBox(wxWindow * parent, TextInput::SetBackgroundColor(StateColor(std::make_pair(0xF0F0F0, (int) StateColor::Disabled), std::make_pair(0xEDFAF2, (int) StateColor::Focused), std::make_pair(*wxWHITE, (int) StateColor::Normal))); + } else { + GetTextCtrl()->Bind(wxEVT_KEY_DOWN, &ComboBox::keyDown, this); } drop.Bind(wxEVT_COMBOBOX, [this](wxCommandEvent &e) { SetSelection(e.GetInt()); @@ -56,7 +58,7 @@ ComboBox::ComboBox(wxWindow * parent, drop.Bind(wxEVT_SHOW, [this](auto &e) { if (!e.IsShown()) { drop_down = false; - wxCommandEvent e(wxEVT_COMBOBOX_DROPDOWN); + wxCommandEvent e(wxEVT_COMBOBOX_CLOSEUP); GetEventHandler()->ProcessEvent(e); } }); @@ -212,9 +214,8 @@ void ComboBox::mouseDown(wxMouseEvent &event) } else if (drop.HasDismissLongTime()) { drop.autoPosition(); drop_down = true; - drop.Show(); - drop.Raise(); - wxCommandEvent e(wxEVT_COMBOBOX_CLOSEUP); + drop.Popup(this); + wxCommandEvent e(wxEVT_COMBOBOX_DROPDOWN); GetEventHandler()->ProcessEvent(e); } } @@ -231,12 +232,61 @@ void ComboBox::mouseWheelMoved(wxMouseEvent &event) } } +void ComboBox::keyDown(wxKeyEvent& event) { + switch (event.GetKeyCode()) { + case WXK_RETURN: + case WXK_SPACE: + if (drop_down) { + drop.Hide(); + } else if (drop.HasDismissLongTime()) { + drop.autoPosition(); + drop_down = true; + drop.Popup(this); + wxCommandEvent e(wxEVT_COMBOBOX_DROPDOWN); + GetEventHandler()->ProcessEvent(e); + } + break; + case WXK_UP: + case WXK_DOWN: + if (event.GetKeyCode() == WXK_UP && GetSelection() > 0) { + SetSelection(GetSelection() - 1); + } else if (event.GetKeyCode() == WXK_DOWN && GetSelection() + 1 < texts.size()) { + SetSelection(GetSelection() + 1); + } else { + break; + } + { + wxCommandEvent e(wxEVT_COMBOBOX); + e.SetEventObject(this); + e.SetId(GetId()); + e.SetInt(GetSelection()); + GetEventHandler()->ProcessEvent(e); + } + break; + default: + event.Skip(); + break; + } +} + void ComboBox::OnEdit() { auto value = GetTextCtrl()->GetValue(); SetValue(value); } +#ifdef __WIN32__ + +WXLRESULT ComboBox::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) +{ + if (nMsg == WM_GETDLGCODE) { + return DLGC_WANTALLKEYS; + } + return TextInput::MSWWindowProc(nMsg, wParam, lParam); +} + +#endif + void ComboBox::sendComboBoxEvent() { wxCommandEvent event(wxEVT_COMBOBOX, GetId()); diff --git a/src/slic3r/GUI/Widgets/ComboBox.hpp b/src/slic3r/GUI/Widgets/ComboBox.hpp index ec35bcb5483..a15cd9ae14b 100644 --- a/src/slic3r/GUI/Widgets/ComboBox.hpp +++ b/src/slic3r/GUI/Widgets/ComboBox.hpp @@ -73,11 +73,16 @@ class ComboBox : public wxWindowWithItems void OnEdit() override; +#ifdef __WIN32__ + WXLRESULT MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) override; +#endif + private: // some useful events void mouseDown(wxMouseEvent &event); void mouseWheelMoved(wxMouseEvent &event); + void keyDown(wxKeyEvent &event); void sendComboBoxEvent(); diff --git a/src/slic3r/GUI/Widgets/DropDown.cpp b/src/slic3r/GUI/Widgets/DropDown.cpp index a0cdc6338a1..b0b609e46a0 100644 --- a/src/slic3r/GUI/Widgets/DropDown.cpp +++ b/src/slic3r/GUI/Widgets/DropDown.cpp @@ -71,7 +71,9 @@ void DropDown::SetSelection(int n) assert(n < (int) texts.size()); if (n >= (int) texts.size()) n = -1; + if (selection == n) return; selection = n; + paintNow(); } wxString DropDown::GetValue() const From ab16d4c73ef3c8d5da21c966f06e6d4717c0cc5f Mon Sep 17 00:00:00 2001 From: "chunmao.guo" Date: Thu, 28 Jul 2022 18:05:44 +0800 Subject: [PATCH 067/180] FIX: add log for exiting of WebViewPanel Change-Id: Ia0b971acec22f35653cf231d1022c873bb532296 --- src/slic3r/GUI/WebViewDialog.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/WebViewDialog.cpp b/src/slic3r/GUI/WebViewDialog.cpp index bfc84553eec..8b3fe8bb297 100644 --- a/src/slic3r/GUI/WebViewDialog.cpp +++ b/src/slic3r/GUI/WebViewDialog.cpp @@ -213,6 +213,9 @@ WebViewPanel::WebViewPanel(wxWindow *parent) WebViewPanel::~WebViewPanel() { + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " Start"; + SetEvtHandlerEnabled(false); + delete m_tools_menu; if (m_LoginUpdateTimer != nullptr) { @@ -220,7 +223,7 @@ WebViewPanel::~WebViewPanel() delete m_LoginUpdateTimer; m_LoginUpdateTimer = NULL; } - + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " End"; } @@ -542,6 +545,7 @@ void WebViewPanel::OnScriptMessage(wxWebViewEvent& evt) { // update login status if (m_LoginUpdateTimer == nullptr) { + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " Create Timer"; m_LoginUpdateTimer = new wxTimer(this, LOGIN_INFO_UPDATE_TIMER_ID); m_LoginUpdateTimer->Start(2000); } From fc659fcf2c72fd976b38557a452c4a229b818bbf Mon Sep 17 00:00:00 2001 From: "lane.wei" Date: Fri, 29 Jul 2022 17:28:13 +0800 Subject: [PATCH 068/180] FIX: presetupdater: fix the crash issue when exit app at the early stage Change-Id: Ia6e6e56e09c5d3ebbdd7b9a8d0bb1b898d05935c --- src/slic3r/GUI/GUI_App.cpp | 9 ++-- src/slic3r/Utils/PresetUpdater.cpp | 85 ++++++++++++++++++------------ src/slic3r/Utils/PresetUpdater.hpp | 2 +- 3 files changed, 57 insertions(+), 39 deletions(-) diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 666e6ce467f..c484bd9320f 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -1046,7 +1046,8 @@ void GUI_App::post_init() bool cw_showed = this->config_wizard_startup(); std::string http_url = get_http_url(app_config->get_country_code()); - this->preset_updater->sync(http_url, preset_bundle); + std::string language = GUI::into_u8(current_language_code()); + this->preset_updater->sync(http_url, language, preset_bundle); //BBS: check new version this->check_new_version(); @@ -1541,7 +1542,7 @@ void GUI_App::init_networking_callbacks() } } } - }); + }); } ); @@ -2567,7 +2568,7 @@ void GUI_App::recreate_GUI(const wxString& msg_name) // }); m_is_recreating_gui = false; - + CallAfter([this]() { mainframe->refresh_plugin_tips(); }); @@ -2952,7 +2953,7 @@ std::string GUI_App::handle_web_request(std::string cmd) } else if (command_str.compare("begin_network_plugin_download") == 0) { CallAfter([this] { wxGetApp().ShowDownNetPluginDlg(); }); - } + } else if (command_str.compare("get_web_shortcut") == 0) { if (root.get_child_optional("key_event") != boost::none) { pt::ptree key_event_node = root.get_child("key_event"); diff --git a/src/slic3r/Utils/PresetUpdater.cpp b/src/slic3r/Utils/PresetUpdater.cpp index 8e12dfc1bbe..683785a4e31 100644 --- a/src/slic3r/Utils/PresetUpdater.cpp +++ b/src/slic3r/Utils/PresetUpdater.cpp @@ -227,7 +227,7 @@ struct PresetUpdater::priv void parse_version_string(const std::string& body) const; void sync_resources(std::string http_url, std::map &resources); void sync_config(std::string http_url, const VendorMap vendors); - void sync_tooltip(std::string http_url); + void sync_tooltip(std::string http_url, std::string language); //BBS: refine preset update logic bool install_bundles_rsrc(std::vector bundles, bool snapshot) const; @@ -268,36 +268,38 @@ void PresetUpdater::priv::set_download_prefs(AppConfig *app_config) // Downloads a file (http get operation). Cancels if the Updater is being destroyed. bool PresetUpdater::priv::get_file(const std::string &url, const fs::path &target_path) const { - bool res = false; - fs::path tmp_path = target_path; - tmp_path += format(".%1%%2%", get_current_pid(), TMP_EXTENSION); + bool res = false; + fs::path tmp_path = target_path; + tmp_path += format(".%1%%2%", get_current_pid(), TMP_EXTENSION); - BOOST_LOG_TRIVIAL(info) << format("[BBS Updater]download file `%1%`, stored to `%2%`, tmp path `%3%`", - url, - target_path.string(), - tmp_path.string()); + BOOST_LOG_TRIVIAL(info) << format("[BBS Updater]download file `%1%`, stored to `%2%`, tmp path `%3%`", + url, + target_path.string(), + tmp_path.string()); Slic3r::Http::get(url) - .on_progress([](Slic3r::Http::Progress, bool &cancel) { - if (cancel) { cancel = true; } - }) - .on_error([&](std::string body, std::string error, unsigned http_status) { - (void)body; - BOOST_LOG_TRIVIAL(error) << format("[BBS Updater]getting: `%1%`: http status %2%, %3%", - url, - http_status, - error); - }) - .on_complete([&](std::string body, unsigned /* http_status */) { - fs::fstream file(tmp_path, std::ios::out | std::ios::binary | std::ios::trunc); - file.write(body.c_str(), body.size()); - file.close(); - fs::rename(tmp_path, target_path); - res = true; - }) - .perform_sync(); + .on_progress([this](Slic3r::Http::Progress, bool &cancel_http) { + if (cancel) { + cancel_http = true; + } + }) + .on_error([&](std::string body, std::string error, unsigned http_status) { + (void)body; + BOOST_LOG_TRIVIAL(error) << format("[BBS Updater]getting: `%1%`: http status %2%, %3%", + url, + http_status, + error); + }) + .on_complete([&](std::string body, unsigned /* http_status */) { + fs::fstream file(tmp_path, std::ios::out | std::ios::binary | std::ios::trunc); + file.write(body.c_str(), body.size()); + file.close(); + fs::rename(tmp_path, target_path); + res = true; + }) + .perform_sync(); - return res; + return res; } //BBS: refine preset update logic @@ -494,7 +496,12 @@ void PresetUpdater::priv::sync_resources(std::string http_url, std::mapset_download_prefs(GUI::wxGetApp().app_config); if (!p->enabled_version_check && !p->enabled_config_update) { return; } @@ -1064,11 +1075,17 @@ void PresetUpdater::sync(std::string http_url, PresetBundle *preset_bundle) // into the closure (but perhaps the compiler can elide this). VendorMap vendors = preset_bundle->vendors; - p->thread = std::thread([this, vendors, http_url]() { + p->thread = std::thread([this, vendors, http_url, language]() { this->p->prune_tmps(); + if (p->cancel) + return; this->p->sync_version(); + if (p->cancel) + return; this->p->sync_config(http_url, std::move(vendors)); - this->p->sync_tooltip(http_url); + if (p->cancel) + return; + this->p->sync_tooltip(http_url, language); }); } diff --git a/src/slic3r/Utils/PresetUpdater.hpp b/src/slic3r/Utils/PresetUpdater.hpp index 8e949efbc53..4db67728495 100644 --- a/src/slic3r/Utils/PresetUpdater.hpp +++ b/src/slic3r/Utils/PresetUpdater.hpp @@ -26,7 +26,7 @@ class PresetUpdater ~PresetUpdater(); // If either version check or config updating is enabled, get the appropriate data in the background and cache it. - void sync(std::string http_url, PresetBundle *preset_bundle); + void sync(std::string http_url, std::string language, PresetBundle *preset_bundle); // If version check is enabled, check if chaced online slic3r version is newer, notify if so. void slic3r_update_notify(); From 8992cab6fe17a79448335756a82391fcbf2ddd9e Mon Sep 17 00:00:00 2001 From: tao wang Date: Fri, 29 Jul 2022 15:52:11 +0800 Subject: [PATCH 069/180] FIX:set the MacOS mainframe title color to white Change-Id: I3e16000f3d93f95509d6e16cec95d4d6ad0ac85b --- src/slic3r/Utils/MacDarkMode.mm | 34 +++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/slic3r/Utils/MacDarkMode.mm b/src/slic3r/Utils/MacDarkMode.mm index 1730d4a8852..d09247cd4ce 100644 --- a/src/slic3r/Utils/MacDarkMode.mm +++ b/src/slic3r/Utils/MacDarkMode.mm @@ -16,6 +16,8 @@ @implementation MacDarkMode namespace Slic3r { namespace GUI { +NSTextField* mainframe_text_field; + bool mac_dark_mode() { NSString *style = [[NSUserDefaults standardUserDefaults] stringForKey:@"AppleInterfaceStyle"]; @@ -43,6 +45,16 @@ void set_miniaturizable(void * window) [(NSView*) window window].titlebarAppearsTransparent = true; [(NSView*) window window].backgroundColor = [NSColor colorWithCalibratedRed:rFloat green:gFloat blue:bFloat alpha:1.0]; [(NSView*) window window].styleMask |= NSMiniaturizableWindowMask; + + NSEnumerator *viewEnum = [[[[[[[(NSView*) window window] contentView] superview] titlebarViewController] view] subviews] objectEnumerator]; + NSView *viewObject; + + while(viewObject = (NSView *)[viewEnum nextObject]) { + if([viewObject class] == [NSTextField self]) { + //[(NSTextField*)viewObject setTextColor : NSColor.whiteColor]; + mainframe_text_field = viewObject; + } + } } } @@ -50,6 +62,28 @@ void set_miniaturizable(void * window) @end +/* textColor for NSTextField */ +@implementation NSTextField (NSTextField_Extended) + +- (void)setTextColor2:(NSColor *)textColor +{ + if (Slic3r::GUI::mainframe_text_field != self){ + [self setTextColor2: textColor]; + }else{ + [self setTextColor2 : NSColor.whiteColor]; + } +} + + ++ (void) load +{ + Method setTextColor = class_getInstanceMethod([NSTextField class], @selector(setTextColor:)); + Method setTextColor2 = class_getInstanceMethod([NSTextField class], @selector(setTextColor2:)); + method_exchangeImplementations(setTextColor, setTextColor2); +} + +@end + /* textColor for NSButton */ @implementation NSButton (NSButton_Extended) From 6c4b1f79da106a5485104f5a5d52934601e79ae1 Mon Sep 17 00:00:00 2001 From: "liz.li" Date: Fri, 29 Jul 2022 11:07:08 +0800 Subject: [PATCH 070/180] FIX:preferences dialog location problem in high scaling ratio Change-Id: I109c8563ff946d6ed8aca647b17d4c4b1491a65b --- src/slic3r/GUI/Preferences.cpp | 45 ++++++++++++++++++++++------------ src/slic3r/GUI/Preferences.hpp | 1 + 2 files changed, 31 insertions(+), 15 deletions(-) diff --git a/src/slic3r/GUI/Preferences.cpp b/src/slic3r/GUI/Preferences.cpp index cf426cb6f78..224454f3838 100644 --- a/src/slic3r/GUI/Preferences.cpp +++ b/src/slic3r/GUI/Preferences.cpp @@ -561,9 +561,14 @@ void PreferencesDialog::create() SetIcon(wxIcon(encode_path(icon_path.c_str()), wxBITMAP_TYPE_ICO)); SetSizeHints(wxDefaultSize, wxDefaultSize); + auto main_sizer = new wxBoxSizer(wxVERTICAL); + + m_scrolledWindow = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxVSCROLL); + m_scrolledWindow->SetScrollRate(5, 5); + m_sizer_body = new wxBoxSizer(wxVERTICAL); - auto m_top_line = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(DESIGN_RESOUTION_PREFERENCES.x, 1), wxTAB_TRAVERSAL); + auto m_top_line = new wxPanel(m_scrolledWindow, wxID_ANY, wxDefaultPosition, wxSize(DESIGN_RESOUTION_PREFERENCES.x, 1), wxTAB_TRAVERSAL); m_top_line->SetBackgroundColour(DESIGN_GRAY400_COLOR); m_sizer_body->Add(m_top_line, 0, wxEXPAND, 0); @@ -576,16 +581,26 @@ void PreferencesDialog::create() create_sync_page(); create_shortcuts_page();*/ - m_sizer_body->Add(0, 0, 0, wxTOP, FromDIP(28)); + m_sizer_body->Add(0, 0, 0, wxTOP, FromDIP(28)); m_sizer_body->Add(general_page, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(38)); #if !BBL_RELEASE_TO_PUBLIC m_sizer_body->Add(debug_page, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(38)); #endif m_sizer_body->Add(0, 0, 0, wxBOTTOM, FromDIP(28)); - SetSizer(m_sizer_body); + m_scrolledWindow->SetSizerAndFit(m_sizer_body); + + main_sizer->Add(m_scrolledWindow, 1, wxEXPAND); + + SetSizer(main_sizer); Layout(); Fit(); + int screen_height = wxGetDisplaySize().GetY(); + if (this->GetSize().GetY() > screen_height) + this->SetSize(this->GetSize().GetX() + FromDIP(40), screen_height * 4 / 5); + CenterOnParent(); + wxPoint start_pos = this->GetPosition(); + if (start_pos.y < 0) { this->SetPosition(wxPoint(start_pos.x, 0)); } //select first auto event = wxCommandEvent(EVT_PREFERENCES_SELECT_TAB); @@ -625,7 +640,7 @@ void PreferencesDialog::Split(const std::string &src, const std::string &separat wxWindow* PreferencesDialog::create_general_page() { - auto page = new wxWindow(this, wxID_ANY); + auto page = new wxWindow(m_scrolledWindow, wxID_ANY); page->SetBackgroundColour(*wxWHITE); wxBoxSizer *sizer_page = new wxBoxSizer(wxVERTICAL); @@ -782,19 +797,19 @@ wxBoxSizer* PreferencesDialog::create_debug_page() wxBoxSizer *bSizer = new wxBoxSizer(wxVERTICAL); - auto title_develop_mode = create_item_title(_L("Develop mode"), this, _L("Develop mode")); - auto item_develop_mode = create_item_checkbox(_L("Develop mode"), this, _L("Develop mode"), 50, "developer_mode"); - auto item_dump_video = create_item_checkbox(_L("Dump video"), this, _L("Dump video"), 50, "dump_video"); + auto title_develop_mode = create_item_title(_L("Develop mode"), m_scrolledWindow, _L("Develop mode")); + auto item_develop_mode = create_item_checkbox(_L("Develop mode"), m_scrolledWindow, _L("Develop mode"), 50, "developer_mode"); + auto item_dump_video = create_item_checkbox(_L("Dump video"), m_scrolledWindow, _L("Dump video"), 50, "dump_video"); - auto title_log_level = create_item_title(_L("Log Level"), this, _L("Log Level")); + auto title_log_level = create_item_title(_L("Log Level"), m_scrolledWindow, _L("Log Level")); auto log_level_list = std::vector{_L("fatal"), _L("error"), _L("warning"), _L("info"), _L("debug"), _L("trace")}; - auto loglevel_combox = create_item_loglevel_combobox(_L("Log Level"), this, _L("Log Level"), log_level_list); + auto loglevel_combox = create_item_loglevel_combobox(_L("Log Level"), m_scrolledWindow, _L("Log Level"), log_level_list); - auto title_host = create_item_title(_L("Host Setting"), this, _L("Host Setting")); - auto radio1 = create_item_radiobox(_L("DEV host: api-dev.bambu-lab.com/v1"), this, wxEmptyString, 50, 1, "dev_host"); - auto radio2 = create_item_radiobox(_L("QA host: api-qa.bambu-lab.com/v1"), this, wxEmptyString, 50, 1, "qa_host"); - auto radio3 = create_item_radiobox(_L("PRE host: api-pre.bambu-lab.com/v1"), this, wxEmptyString, 50, 1, "pre_host"); - auto radio4 = create_item_radiobox(_L("Product host"), this, wxEmptyString, 50, 1, "product_host"); + auto title_host = create_item_title(_L("Host Setting"), m_scrolledWindow, _L("Host Setting")); + auto radio1 = create_item_radiobox(_L("DEV host: api-dev.bambu-lab.com/v1"), m_scrolledWindow, wxEmptyString, 50, 1, "dev_host"); + auto radio2 = create_item_radiobox(_L("QA host: api-qa.bambu-lab.com/v1"), m_scrolledWindow, wxEmptyString, 50, 1, "qa_host"); + auto radio3 = create_item_radiobox(_L("PRE host: api-pre.bambu-lab.com/v1"), m_scrolledWindow, wxEmptyString, 50, 1, "pre_host"); + auto radio4 = create_item_radiobox(_L("Product host"), m_scrolledWindow, wxEmptyString, 50, 1, "product_host"); if (m_iot_environment_def == ENV_DEV_HOST) { on_select_radio("dev_host"); @@ -806,7 +821,7 @@ wxBoxSizer* PreferencesDialog::create_debug_page() on_select_radio("product_host"); } - wxButton *debug_button = new wxButton(this, wxID_ANY, _L("debug save button"), wxDefaultPosition, wxDefaultSize, 0); + wxButton *debug_button = new wxButton(m_scrolledWindow, wxID_ANY, _L("debug save button"), wxDefaultPosition, wxDefaultSize, 0); debug_button->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent &e) { // success message box MessageDialog dialog(this, _L("save debug settings"), _L("DEBUG settings have saved successfully!"), wxNO_DEFAULT | wxYES_NO | wxICON_INFORMATION); diff --git a/src/slic3r/GUI/Preferences.hpp b/src/slic3r/GUI/Preferences.hpp index 1bcca1b004a..4457cf6e9c2 100644 --- a/src/slic3r/GUI/Preferences.hpp +++ b/src/slic3r/GUI/Preferences.hpp @@ -60,6 +60,7 @@ class PreferencesDialog : public DPIDialog protected: wxBoxSizer * m_sizer_body; + wxScrolledWindow *m_scrolledWindow; // bool m_settings_layout_changed {false}; bool m_seq_top_layer_only_changed{false}; From a74fb146131de6eb4994649316f58998dce39a9f Mon Sep 17 00:00:00 2001 From: "chunmao.guo" Date: Fri, 29 Jul 2022 11:18:33 +0800 Subject: [PATCH 071/180] FIX: button handle key event Change-Id: If3ecd2356e516105c2054c9b85a122f3ccc72d91 --- src/slic3r/GUI/SavePresetDialog.cpp | 8 ++--- src/slic3r/GUI/SavePresetDialog.hpp | 4 +-- src/slic3r/GUI/UnsavedChangesDialog.cpp | 2 +- src/slic3r/GUI/Widgets/Button.cpp | 39 +++++++++++++++++++++++++ src/slic3r/GUI/Widgets/Button.hpp | 6 ++++ src/slic3r/GUI/Widgets/ComboBox.cpp | 9 ++++-- 6 files changed, 59 insertions(+), 9 deletions(-) diff --git a/src/slic3r/GUI/SavePresetDialog.cpp b/src/slic3r/GUI/SavePresetDialog.cpp index fd148cb6b70..3f5822c7ee7 100644 --- a/src/slic3r/GUI/SavePresetDialog.cpp +++ b/src/slic3r/GUI/SavePresetDialog.cpp @@ -340,7 +340,7 @@ void SavePresetDialog::build(std::vector types, std::string suffix m_confirm->SetTextColor(wxColour(255, 255, 255)); m_confirm->SetMinSize(SAVE_PRESET_DIALOG_BUTTON_SIZE); m_confirm->SetCornerRadius(12); - m_confirm->Bind(wxEVT_LEFT_DOWN, &SavePresetDialog::accept, this); + m_confirm->Bind(wxEVT_BUTTON, &SavePresetDialog::accept, this); btns->Add(m_confirm, 0, wxEXPAND, 0); auto block_middle = new wxWindow(this, -1); @@ -351,7 +351,7 @@ void SavePresetDialog::build(std::vector types, std::string suffix m_cancel->SetMinSize(SAVE_PRESET_DIALOG_BUTTON_SIZE); m_cancel->SetTextColor(wxColour(107, 107, 107)); m_cancel->SetCornerRadius(12); - m_cancel->Bind(wxEVT_LEFT_DOWN, &SavePresetDialog::on_select_cancel, this); + m_cancel->Bind(wxEVT_BUTTON, &SavePresetDialog::on_select_cancel, this); btns->Add(m_cancel, 0, wxEXPAND, 0); auto block_right = new wxWindow(this, -1); @@ -372,7 +372,7 @@ void SavePresetDialog::build(std::vector types, std::string suffix this->Centre(wxBOTH); } -void SavePresetDialog::on_select_cancel(wxMouseEvent &event) +void SavePresetDialog::on_select_cancel(wxCommandEvent &event) { EndModal(wxID_CANCEL); } @@ -511,7 +511,7 @@ void SavePresetDialog::update_physical_printers(const std::string &preset_name) } } -void SavePresetDialog::accept(wxMouseEvent &event) +void SavePresetDialog::accept(wxCommandEvent &event) { for (Item *item : m_items) { item->accept(); diff --git a/src/slic3r/GUI/SavePresetDialog.hpp b/src/slic3r/GUI/SavePresetDialog.hpp index 2449c08b7b0..1b2089f8986 100644 --- a/src/slic3r/GUI/SavePresetDialog.hpp +++ b/src/slic3r/GUI/SavePresetDialog.hpp @@ -111,9 +111,9 @@ class SavePresetDialog : public DPIDialog private: void build(std::vector types, std::string suffix = ""); - void on_select_cancel(wxMouseEvent &event); + void on_select_cancel(wxCommandEvent &event); void update_physical_printers(const std::string &preset_name); - void accept(wxMouseEvent &event); + void accept(wxCommandEvent &event); }; } // namespace GUI diff --git a/src/slic3r/GUI/UnsavedChangesDialog.cpp b/src/slic3r/GUI/UnsavedChangesDialog.cpp index c62377b39a8..a54810e7c19 100644 --- a/src/slic3r/GUI/UnsavedChangesDialog.cpp +++ b/src/slic3r/GUI/UnsavedChangesDialog.cpp @@ -955,7 +955,7 @@ void UnsavedChangesDialog::build(Preset::Type type, PresetCollection *dependent_ (*btn)->SetMinSize(UNSAVE_CHANGE_DIALOG_BUTTON_SIZE); (*btn)->SetCornerRadius(12); - (*btn)->Bind(wxEVT_LEFT_DOWN, [this, close_act, dependent_presets](wxEvent &) { + (*btn)->Bind(wxEVT_BUTTON, [this, close_act, dependent_presets](wxEvent &) { bool save_names_and_types = close_act == Action::Save || (close_act == Action::Transfer && ActionButtons::KEEP & m_buttons); if (save_names_and_types && !save(dependent_presets, close_act == Action::Save)) return; close(close_act); diff --git a/src/slic3r/GUI/Widgets/Button.cpp b/src/slic3r/GUI/Widgets/Button.cpp index b7abb2412bc..54b10c4b1d3 100644 --- a/src/slic3r/GUI/Widgets/Button.cpp +++ b/src/slic3r/GUI/Widgets/Button.cpp @@ -7,6 +7,8 @@ BEGIN_EVENT_TABLE(Button, StaticBox) EVT_LEFT_DOWN(Button::mouseDown) EVT_LEFT_UP(Button::mouseReleased) +EVT_KEY_DOWN(Button::keyDownUp) +EVT_KEY_UP(Button::keyDownUp) // catch paint events EVT_PAINT(Button::paintEvent) @@ -241,9 +243,46 @@ void Button::mouseReleased(wxMouseEvent& event) } } +void Button::keyDownUp(wxKeyEvent &event) +{ + if (event.GetKeyCode() == WXK_SPACE || event.GetKeyCode() == WXK_RETURN) { + wxMouseEvent evt(event.GetEventType() == wxEVT_KEY_UP ? wxEVT_LEFT_UP : wxEVT_LEFT_DOWN); + event.SetEventObject(this); + GetEventHandler()->ProcessEvent(evt); + return; + } + event.Skip(); +} + void Button::sendButtonEvent() { wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, GetId()); event.SetEventObject(this); GetEventHandler()->ProcessEvent(event); } + +#ifdef __WIN32__ + +WXLRESULT Button::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) +{ + if (nMsg == WM_GETDLGCODE) { return DLGC_WANTMESSAGE; } + if (nMsg == WM_KEYDOWN) { + wxKeyEvent event(CreateKeyEvent(wxEVT_KEY_DOWN, wParam, lParam)); + switch (wParam) { + case WXK_RETURN: { + GetEventHandler()->ProcessEvent(event); + return 0; + } + case WXK_TAB: + case WXK_LEFT: + case WXK_RIGHT: + case WXK_UP: + case WXK_DOWN: + if (HandleAsNavigationKey(event)) + return 0; + } + } + return wxWindow::MSWWindowProc(nMsg, wParam, lParam); +} + +#endif diff --git a/src/slic3r/GUI/Widgets/Button.hpp b/src/slic3r/GUI/Widgets/Button.hpp index 16967856897..3b3233e5a38 100644 --- a/src/slic3r/GUI/Widgets/Button.hpp +++ b/src/slic3r/GUI/Widgets/Button.hpp @@ -47,6 +47,11 @@ class Button : public StaticBox void Rescale(); +protected: +#ifdef __WIN32__ + WXLRESULT MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) override; +#endif + private: void paintEvent(wxPaintEvent& evt); @@ -57,6 +62,7 @@ class Button : public StaticBox // some useful events void mouseDown(wxMouseEvent& event); void mouseReleased(wxMouseEvent& event); + void keyDownUp(wxKeyEvent &event); void sendButtonEvent(); diff --git a/src/slic3r/GUI/Widgets/ComboBox.cpp b/src/slic3r/GUI/Widgets/ComboBox.cpp index d4d4e28c598..e6fd9c2bee2 100644 --- a/src/slic3r/GUI/Widgets/ComboBox.cpp +++ b/src/slic3r/GUI/Widgets/ComboBox.cpp @@ -248,9 +248,11 @@ void ComboBox::keyDown(wxKeyEvent& event) { break; case WXK_UP: case WXK_DOWN: - if (event.GetKeyCode() == WXK_UP && GetSelection() > 0) { + case WXK_LEFT: + case WXK_RIGHT: + if ((event.GetKeyCode() == WXK_UP || event.GetKeyCode() == WXK_LEFT) && GetSelection() > 0) { SetSelection(GetSelection() - 1); - } else if (event.GetKeyCode() == WXK_DOWN && GetSelection() + 1 < texts.size()) { + } else if ((event.GetKeyCode() == WXK_DOWN || event.GetKeyCode() == WXK_RIGHT) && GetSelection() + 1 < texts.size()) { SetSelection(GetSelection() + 1); } else { break; @@ -263,6 +265,9 @@ void ComboBox::keyDown(wxKeyEvent& event) { GetEventHandler()->ProcessEvent(e); } break; + case WXK_TAB: + HandleAsNavigationKey(event); + break; default: event.Skip(); break; From da732ac3961bc68ad799f69dd48da7b324aaf71d Mon Sep 17 00:00:00 2001 From: tao wang Date: Thu, 28 Jul 2022 16:24:18 +0800 Subject: [PATCH 072/180] FIX:optimize RDIF animation Change-Id: I45e45b92efa43f290151e39715ca057da4d862c1 --- resources/images/ams_refresh_normal.svg | 18 +++-- resources/images/ams_refresh_selected.svg | 22 +++--- resources/images/ams_rfid_0.svg | 14 ++++ resources/images/ams_rfid_1.svg | 14 ++++ resources/images/ams_rfid_2.svg | 14 ++++ resources/images/ams_rfid_3.svg | 14 ++++ resources/images/ams_rfid_4.svg | 14 ++++ resources/images/ams_rfid_5.svg | 14 ++++ resources/images/ams_rfid_6.svg | 14 ++++ resources/images/ams_rfid_7.svg | 14 ++++ src/slic3r/GUI/Widgets/AMSControl.cpp | 90 ++++++++++++++++------- src/slic3r/GUI/Widgets/AMSControl.hpp | 21 ++++-- 12 files changed, 210 insertions(+), 53 deletions(-) create mode 100644 resources/images/ams_rfid_0.svg create mode 100644 resources/images/ams_rfid_1.svg create mode 100644 resources/images/ams_rfid_2.svg create mode 100644 resources/images/ams_rfid_3.svg create mode 100644 resources/images/ams_rfid_4.svg create mode 100644 resources/images/ams_rfid_5.svg create mode 100644 resources/images/ams_rfid_6.svg create mode 100644 resources/images/ams_rfid_7.svg diff --git a/resources/images/ams_refresh_normal.svg b/resources/images/ams_refresh_normal.svg index e12c80ad310..99ea1107a47 100644 --- a/resources/images/ams_refresh_normal.svg +++ b/resources/images/ams_refresh_normal.svg @@ -1,12 +1,14 @@ - - - background - - - + + + + + + Layer 1 - - + + + + \ No newline at end of file diff --git a/resources/images/ams_refresh_selected.svg b/resources/images/ams_refresh_selected.svg index 36dda61d7b6..653d0edc1ec 100644 --- a/resources/images/ams_refresh_selected.svg +++ b/resources/images/ams_refresh_selected.svg @@ -1,12 +1,14 @@ - - - background - - - - - Layer 1 - - + + + + + + + + Layer 1 + + + + \ No newline at end of file diff --git a/resources/images/ams_rfid_0.svg b/resources/images/ams_rfid_0.svg new file mode 100644 index 00000000000..653d0edc1ec --- /dev/null +++ b/resources/images/ams_rfid_0.svg @@ -0,0 +1,14 @@ + + + + + + + + Layer 1 + + + + + + \ No newline at end of file diff --git a/resources/images/ams_rfid_1.svg b/resources/images/ams_rfid_1.svg new file mode 100644 index 00000000000..001274d2087 --- /dev/null +++ b/resources/images/ams_rfid_1.svg @@ -0,0 +1,14 @@ + + + + + + + + Layer 1 + + + + + + \ No newline at end of file diff --git a/resources/images/ams_rfid_2.svg b/resources/images/ams_rfid_2.svg new file mode 100644 index 00000000000..12076b79bfe --- /dev/null +++ b/resources/images/ams_rfid_2.svg @@ -0,0 +1,14 @@ + + + + + + + + Layer 1 + + + + + + \ No newline at end of file diff --git a/resources/images/ams_rfid_3.svg b/resources/images/ams_rfid_3.svg new file mode 100644 index 00000000000..fb7eedd02f9 --- /dev/null +++ b/resources/images/ams_rfid_3.svg @@ -0,0 +1,14 @@ + + + + + + + + Layer 1 + + + + + + \ No newline at end of file diff --git a/resources/images/ams_rfid_4.svg b/resources/images/ams_rfid_4.svg new file mode 100644 index 00000000000..cf4e1baeb4c --- /dev/null +++ b/resources/images/ams_rfid_4.svg @@ -0,0 +1,14 @@ + + + + + + + + Layer 1 + + + + + + \ No newline at end of file diff --git a/resources/images/ams_rfid_5.svg b/resources/images/ams_rfid_5.svg new file mode 100644 index 00000000000..8cf963c6e23 --- /dev/null +++ b/resources/images/ams_rfid_5.svg @@ -0,0 +1,14 @@ + + + + + + + + Layer 1 + + + + + + \ No newline at end of file diff --git a/resources/images/ams_rfid_6.svg b/resources/images/ams_rfid_6.svg new file mode 100644 index 00000000000..422fc623a55 --- /dev/null +++ b/resources/images/ams_rfid_6.svg @@ -0,0 +1,14 @@ + + + + + + + + Layer 1 + + + + + + \ No newline at end of file diff --git a/resources/images/ams_rfid_7.svg b/resources/images/ams_rfid_7.svg new file mode 100644 index 00000000000..16a872c890e --- /dev/null +++ b/resources/images/ams_rfid_7.svg @@ -0,0 +1,14 @@ + + + + + + + + Layer 1 + + + + + + \ No newline at end of file diff --git a/src/slic3r/GUI/Widgets/AMSControl.cpp b/src/slic3r/GUI/Widgets/AMSControl.cpp index e9879aa3365..27cee631fa5 100644 --- a/src/slic3r/GUI/Widgets/AMSControl.cpp +++ b/src/slic3r/GUI/Widgets/AMSControl.cpp @@ -133,13 +133,26 @@ void AMSrefresh::create(wxWindow *parent, wxWindowID id, const wxPoint &pos, con Bind(wxEVT_LEAVE_WINDOW, &AMSrefresh::OnLeaveWindow, this); Bind(wxEVT_LEFT_DOWN, &AMSrefresh::OnClick, this); - m_bitmap_normal = ScalableBitmap(this, "ams_refresh_normal", 26); - m_bitmap_selected = ScalableBitmap(this, "ams_refresh_selected", 26); - - /* m_animationCtrl = new wxAnimationCtrl(this, wxID_ANY, wxNullAnimation, wxDefaultPosition, AMS_REFRESH_SIZE); - auto path = (boost::format("%1%/images/refresh.gif") % resources_dir()).str(); - path = encode_path(path.c_str()); - if (m_animationCtrl->LoadFile(path)) m_animationCtrl->Hide();*/ + m_bitmap_normal = ScalableBitmap(this, "ams_refresh_normal", 30); + m_bitmap_selected = ScalableBitmap(this, "ams_refresh_selected", 30); + + m_bitmap_ams_rfid_0 = ScalableBitmap(this, "ams_rfid_0", 30); + m_bitmap_ams_rfid_1 = ScalableBitmap(this, "ams_rfid_1", 30); + m_bitmap_ams_rfid_2 = ScalableBitmap(this, "ams_rfid_2", 30); + m_bitmap_ams_rfid_3 = ScalableBitmap(this, "ams_rfid_3", 30); + m_bitmap_ams_rfid_4 = ScalableBitmap(this, "ams_rfid_4", 30); + m_bitmap_ams_rfid_5 = ScalableBitmap(this, "ams_rfid_5", 30); + m_bitmap_ams_rfid_6 = ScalableBitmap(this, "ams_rfid_6", 30); + m_bitmap_ams_rfid_7 = ScalableBitmap(this, "ams_rfid_7", 30); + + m_rfid_bitmap_list.push_back(m_bitmap_ams_rfid_0); + m_rfid_bitmap_list.push_back(m_bitmap_ams_rfid_1); + m_rfid_bitmap_list.push_back(m_bitmap_ams_rfid_2); + m_rfid_bitmap_list.push_back(m_bitmap_ams_rfid_3); + m_rfid_bitmap_list.push_back(m_bitmap_ams_rfid_4); + m_rfid_bitmap_list.push_back(m_bitmap_ams_rfid_5); + m_rfid_bitmap_list.push_back(m_bitmap_ams_rfid_6); + m_rfid_bitmap_list.push_back(m_bitmap_ams_rfid_7); m_playing_timer = new wxTimer(); m_playing_timer->SetOwner(this); @@ -147,35 +160,31 @@ void AMSrefresh::create(wxWindow *parent, wxWindowID id, const wxPoint &pos, con SetSize(AMS_REFRESH_SIZE); SetMinSize(AMS_REFRESH_SIZE); + SetMaxSize(AMS_REFRESH_SIZE); } void AMSrefresh::on_timer(wxTimerEvent &event) { - if (m_rotation_angle == 0) { - m_rotation_angle = 360; - } else { - m_rotation_angle--; - } + //if (m_rotation_angle >= m_rfid_bitmap_list.size()) { + // m_rotation_angle = 0; + //} else { + // m_rotation_angle++; + //} Refresh(); } void AMSrefresh::PlayLoading() { if (m_play_loading) return; - //this->m_animationCtrl->Show(); - //this->m_animationCtrl->Play(); m_play_loading = true; - m_rotation_angle = 360; + //m_rotation_angle = 0; m_playing_timer->Start(AMS_REFRESH_PLAY_LOADING_TIMER); Refresh(); } void AMSrefresh::StopLoading() { - if (!m_play_loading) return; - //this->m_animationCtrl->Stop(); - //this->m_animationCtrl->Hide(); m_playing_timer->Stop(); m_play_loading = false; Refresh(); @@ -218,13 +227,19 @@ void AMSrefresh::paintEvent(wxPaintEvent &evt) 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", 26); - 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_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); } dc.SetPen(wxPen(colour)); @@ -242,13 +257,32 @@ void AMSrefresh::Update(Caninfo info) StopLoading(); } -void AMSrefresh::msw_rescale() { } +void AMSrefresh::msw_rescale() { + m_bitmap_normal = ScalableBitmap(this, "ams_refresh_normal", 30); + m_bitmap_selected = ScalableBitmap(this, "ams_refresh_selected", 30); + m_bitmap_ams_rfid_0 = ScalableBitmap(this, "ams_rfid_0", 30); + m_bitmap_ams_rfid_1 = ScalableBitmap(this, "ams_rfid_1", 30); + m_bitmap_ams_rfid_2 = ScalableBitmap(this, "ams_rfid_2", 30); + m_bitmap_ams_rfid_3 = ScalableBitmap(this, "ams_rfid_3", 30); + m_bitmap_ams_rfid_4 = ScalableBitmap(this, "ams_rfid_4", 30); + m_bitmap_ams_rfid_5 = ScalableBitmap(this, "ams_rfid_5", 30); + m_bitmap_ams_rfid_6 = ScalableBitmap(this, "ams_rfid_6", 30); + m_bitmap_ams_rfid_7 = ScalableBitmap(this, "ams_rfid_7", 30); + + m_rfid_bitmap_list.clear(); + m_rfid_bitmap_list.push_back(m_bitmap_ams_rfid_0); + m_rfid_bitmap_list.push_back(m_bitmap_ams_rfid_1); + m_rfid_bitmap_list.push_back(m_bitmap_ams_rfid_2); + m_rfid_bitmap_list.push_back(m_bitmap_ams_rfid_3); + m_rfid_bitmap_list.push_back(m_bitmap_ams_rfid_4); + m_rfid_bitmap_list.push_back(m_bitmap_ams_rfid_5); + m_rfid_bitmap_list.push_back(m_bitmap_ams_rfid_6); + m_rfid_bitmap_list.push_back(m_bitmap_ams_rfid_7); +} void AMSrefresh::DoSetSize(int x, int y, int width, int height, int sizeFlags) { wxWindow::DoSetSize(x, y, width, height, sizeFlags); - m_bitmap_normal = ScalableBitmap(this, "ams_refresh_normal", 26); - m_bitmap_selected = ScalableBitmap(this, "ams_refresh_selected", 26); } /************************************************* diff --git a/src/slic3r/GUI/Widgets/AMSControl.hpp b/src/slic3r/GUI/Widgets/AMSControl.hpp index bc3d638110e..506b72eb77c 100644 --- a/src/slic3r/GUI/Widgets/AMSControl.hpp +++ b/src/slic3r/GUI/Widgets/AMSControl.hpp @@ -101,7 +101,7 @@ enum FilamentStep { #define AMS_CANS_SIZE wxSize(FromDIP(284), FromDIP(186)) #define AMS_CANS_WINDOW_SIZE wxSize(FromDIP(264), FromDIP(186)) #define AMS_STEP_SIZE wxSize(FromDIP(172), FromDIP(180)) -#define AMS_REFRESH_SIZE wxSize(FromDIP(26), FromDIP(26)) +#define AMS_REFRESH_SIZE wxSize(FromDIP(30), FromDIP(30)) #define AMS_EXTRUDER_SIZE wxSize(FromDIP(66), FromDIP(55)) #define AMS_EXTRUDER_BITMAP_SIZE wxSize(FromDIP(36), FromDIP(55)) @@ -130,7 +130,7 @@ struct AMSinfo /************************************************* Description:AMSrefresh **************************************************/ -#define AMS_REFRESH_PLAY_LOADING_TIMER 200 +#define AMS_REFRESH_PLAY_LOADING_TIMER 100 class AMSrefresh : public wxWindow { public: @@ -153,16 +153,23 @@ class AMSrefresh : public wxWindow protected: wxTimer *m_playing_timer= {nullptr}; - int m_rotation_angle = {360}; - - wxAnimationCtrl *m_animationCtrl = {nullptr}; - + int m_rotation_angle = 0; bool m_play_loading = {false}; bool m_selected = {false}; - ScalableBitmap m_bitmap_rotation; + ScalableBitmap m_bitmap_normal; ScalableBitmap m_bitmap_selected; + ScalableBitmap m_bitmap_ams_rfid_0; + ScalableBitmap m_bitmap_ams_rfid_1; + ScalableBitmap m_bitmap_ams_rfid_2; + ScalableBitmap m_bitmap_ams_rfid_3; + ScalableBitmap m_bitmap_ams_rfid_4; + ScalableBitmap m_bitmap_ams_rfid_5; + ScalableBitmap m_bitmap_ams_rfid_6; + ScalableBitmap m_bitmap_ams_rfid_7; + std::vector m_rfid_bitmap_list; + wxString m_text; wxBoxSizer * m_size_body; virtual void DoSetSize(int x, int y, int width, int height, int sizeFlags = wxSIZE_AUTO); From acc6d70db946c21606fb6e4e5fe8880832d93a54 Mon Sep 17 00:00:00 2001 From: Stone Li Date: Mon, 25 Jul 2022 16:55:18 +0800 Subject: [PATCH 073/180] ENH: do not show dialog if no bambu network lib Change-Id: I9dbdb89b7161515ec7995969106764f66a5dd6e3 --- src/slic3r/GUI/Preferences.cpp | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/slic3r/GUI/Preferences.cpp b/src/slic3r/GUI/Preferences.cpp index 224454f3838..1f22c4e913b 100644 --- a/src/slic3r/GUI/Preferences.cpp +++ b/src/slic3r/GUI/Preferences.cpp @@ -237,20 +237,24 @@ wxBoxSizer *PreferencesDialog::create_item_region_combobox(wxString title, wxWin else area = "Others"; - MessageDialog msg_wingow(nullptr, _L("Changing the region will log out your account.\n") + "\n" + _L("Do you want to continue?"), L("Region selection"), - wxICON_QUESTION | wxOK | wxCANCEL); - if (msg_wingow.ShowModal() == wxID_CANCEL) { - combobox->SetSelection(current_region); - return; - } else { - NetworkAgent *agent = wxGetApp().getAgent(); - wxGetApp().request_user_logout(); - AppConfig * config = GUI::wxGetApp().app_config; - if (agent) { - agent->set_country_code(area); + NetworkAgent* agent = wxGetApp().getAgent(); + AppConfig* config = GUI::wxGetApp().app_config; + if (agent) { + MessageDialog msg_wingow(this, _L("Changing the region will log out your account.\n") + "\n" + _L("Do you want to continue?"), L("Region selection"), + wxICON_QUESTION | wxOK | wxCANCEL); + if (msg_wingow.ShowModal() == wxID_CANCEL) { + combobox->SetSelection(current_region); + return; + } else { + wxGetApp().request_user_logout(); + if (agent) { + agent->set_country_code(area); + } + config->set("region", region.ToStdString()); + EndModal(wxID_CANCEL); } + } else { config->set("region", region.ToStdString()); - EndModal(wxID_CANCEL); } e.Skip(); From 09d5651c39d6c061497396da0565fce1a9d08e74 Mon Sep 17 00:00:00 2001 From: "zhimin.zeng" Date: Fri, 29 Jul 2022 15:28:56 +0800 Subject: [PATCH 074/180] FIX: issue 551: support to import prusa 3mf file Change-Id: I6d00fab62304893cc5f1aba0d0a74e4c6194bce9 --- src/libslic3r/Format/3mf.cpp | 127 ++++++++++++++++++++++++++++++++++- src/libslic3r/Format/3mf.hpp | 23 +++++++ src/libslic3r/Model.cpp | 26 +++++-- src/libslic3r/Model.hpp | 10 ++- src/slic3r/GUI/Plater.cpp | 37 ++++++++-- 5 files changed, 209 insertions(+), 14 deletions(-) diff --git a/src/libslic3r/Format/3mf.cpp b/src/libslic3r/Format/3mf.cpp index ca177e6c56b..f74545e9821 100644 --- a/src/libslic3r/Format/3mf.cpp +++ b/src/libslic3r/Format/3mf.cpp @@ -271,6 +271,105 @@ namespace Slic3r { //! return same string #define L(s) (s) #define _(s) Slic3r::I18N::translate(s) +void XMLCALL PrusaFileParser::start_element_handler(void *userData, const char *name, const char **attributes) +{ + PrusaFileParser *prusa_parser = (PrusaFileParser *) userData; + if (prusa_parser != nullptr) { prusa_parser->_start_element_handler(name, attributes); } +} + +void XMLCALL PrusaFileParser::characters_handler(void *userData, const XML_Char *s, int len) +{ + PrusaFileParser *prusa_parser = (PrusaFileParser *) userData; + if (prusa_parser != nullptr) { prusa_parser->_characters_handler(s, len); } +} + +bool PrusaFileParser::check_3mf_from_prusa(const std::string filename) +{ + mz_zip_archive archive; + mz_zip_zero_struct(&archive); + if (!open_zip_reader(&archive, filename)) { + // throw Slic3r::RuntimeError("Loading 3mf file failed."); + return false; + } + + const std::string sub_relationship_file = "3D/_rels/3dmodel.model.rels"; + int sub_index = mz_zip_reader_locate_file(&archive, sub_relationship_file.c_str(), nullptr, 0); + if (sub_index == -1) { + const std::string model_file = "3D/3dmodel.model"; + int model_file_index = mz_zip_reader_locate_file(&archive, model_file.c_str(), nullptr, 0); + if (model_file_index != -1) { + int depth = 0; + m_parser = XML_ParserCreate(nullptr); + XML_SetUserData(m_parser, (void *) this); + XML_SetElementHandler(m_parser, start_element_handler, nullptr); + XML_SetCharacterDataHandler(m_parser, characters_handler); + + mz_zip_archive_file_stat stat; + if (!mz_zip_reader_file_stat(&archive, model_file_index, &stat)) goto EXIT; + + void *parser_buffer = XML_GetBuffer(m_parser, (int) stat.m_uncomp_size); + if (parser_buffer == nullptr) goto EXIT; + + mz_bool res = mz_zip_reader_extract_file_to_mem(&archive, stat.m_filename, parser_buffer, (size_t) stat.m_uncomp_size, 0); + if (res == 0) goto EXIT; + + XML_ParseBuffer(m_parser, (int) stat.m_uncomp_size, 1); + } + } + +EXIT: + close_zip_reader(&archive); + return m_from_prusa; +} + +void PrusaFileParser::_characters_handler(const XML_Char *s, int len) +{ + if (m_is_application_key) { + std::string str(s, len); + if (!str.empty() && str.find("PrusaSlicer") != std::string::npos) m_from_prusa = true; + } +} + +void PrusaFileParser::_start_element_handler(const char *name, const char **attributes) +{ + if (::strcmp(name, "metadata") == 0) { + unsigned int num_attributes = (unsigned int) XML_GetSpecifiedAttributeCount(m_parser); + + std::string str_name = get_attribute_value_string(attributes, num_attributes, "name"); + if (!str_name.empty() && str_name.find("Application") != std::string::npos) { m_is_application_key = true; } + } +} + +const char *PrusaFileParser::get_attribute_value_charptr(const char **attributes, unsigned int attributes_size, const char *attribute_key) +{ + if ((attributes == nullptr) || (attributes_size == 0) || (attributes_size % 2 != 0) || (attribute_key == nullptr)) return nullptr; + + for (unsigned int a = 0; a < attributes_size; a += 2) { + if (::strcmp(attributes[a], attribute_key) == 0) return attributes[a + 1]; + } + + return nullptr; +} + +std::string PrusaFileParser::get_attribute_value_string(const char **attributes, unsigned int attributes_size, const char *attribute_key) +{ + const char *text = get_attribute_value_charptr(attributes, attributes_size, attribute_key); + return (text != nullptr) ? text : ""; +} + +ModelVolumeType type_from_string(const std::string &s) +{ + // Legacy support + if (s == "1") return ModelVolumeType::PARAMETER_MODIFIER; + // New type (supporting the support enforcers & blockers) + if (s == "ModelPart") return ModelVolumeType::MODEL_PART; + if (s == "NegativeVolume") return ModelVolumeType::NEGATIVE_VOLUME; + if (s == "ParameterModifier") return ModelVolumeType::PARAMETER_MODIFIER; + if (s == "SupportEnforcer") return ModelVolumeType::SUPPORT_ENFORCER; + if (s == "SupportBlocker") return ModelVolumeType::SUPPORT_BLOCKER; + // Default value if invalud type string received. + return ModelVolumeType::MODEL_PART; +} // Base class with error messages management class _3MF_Base @@ -668,6 +767,7 @@ namespace Slic3r { std::string name(stat.m_filename); std::replace(name.begin(), name.end(), '\\', '/'); + /* if (boost::algorithm::iequals(name, LAYER_HEIGHTS_PROFILE_FILE)) { // extract slic3r layer heights profile file _extract_layer_heights_profile_config_from_archive(archive, stat); @@ -692,7 +792,9 @@ namespace Slic3r { // extract slic3r layer config ranges file _extract_custom_gcode_per_print_z_from_archive(archive, stat); } - else if (boost::algorithm::iequals(name, MODEL_CONFIG_FILE)) { + */ + // only read the model config for Prusa 3mf + if (boost::algorithm::iequals(name, MODEL_CONFIG_FILE)) { // extract slic3r model config file if (!_extract_model_config_from_archive(archive, stat, model)) { close_zip_reader(&archive); @@ -1913,6 +2015,27 @@ namespace Slic3r { std::string key = get_attribute_value_string(attributes, num_attributes, KEY_ATTR); std::string value = get_attribute_value_string(attributes, num_attributes, VALUE_ATTR); + // filter the prusa model config keys + std::vector valid_keys = { + "name", + "volume_type", + "matrix", + "source_file", + "source_object_id", + "source_volume_id", + "source_offset_x", + "source_offset_y", + "source_offset_z", + "extruder", + "modifier" + }; + + auto itor = std::find(valid_keys.begin(), valid_keys.end(), key); + if (itor == valid_keys.end()) { + // do nothing if not valid keys + return true; + } + if (type == OBJECT_TYPE) object->second.metadata.emplace_back(key, value); else if (type == VOLUME_TYPE) { @@ -2044,7 +2167,7 @@ namespace Slic3r { else if ((metadata.key == MODIFIER_KEY) && (metadata.value == "1")) volume->set_type(ModelVolumeType::PARAMETER_MODIFIER); else if (metadata.key == VOLUME_TYPE_KEY) - volume->set_type(ModelVolume::type_from_string(metadata.value)); + volume->set_type(type_from_string(metadata.value)); else if (metadata.key == SOURCE_FILE_KEY) volume->source.input_file = metadata.value; else if (metadata.key == SOURCE_OBJECT_ID_KEY) diff --git a/src/libslic3r/Format/3mf.hpp b/src/libslic3r/Format/3mf.hpp index b91e90da745..9509b2c7042 100644 --- a/src/libslic3r/Format/3mf.hpp +++ b/src/libslic3r/Format/3mf.hpp @@ -1,7 +1,30 @@ #ifndef slic3r_Format_3mf_hpp_ #define slic3r_Format_3mf_hpp_ +#include "../expat.h" namespace Slic3r { +// PrusaFileParser is used to check 3mf file is from Prusa +class PrusaFileParser +{ +public: + PrusaFileParser() {} + ~PrusaFileParser() {} + + bool check_3mf_from_prusa(const std::string filename); + void _start_element_handler(const char *name, const char **attributes); + void _characters_handler(const XML_Char *s, int len); + +private: + const char *get_attribute_value_charptr(const char **attributes, unsigned int attributes_size, const char *attribute_key); + std::string get_attribute_value_string(const char **attributes, unsigned int attributes_size, const char *attribute_key); + + static void XMLCALL start_element_handler(void *userData, const char *name, const char **attributes); + static void XMLCALL characters_handler(void *userData, const XML_Char *s, int len); +private: + bool m_from_prusa = false; + bool m_is_application_key = false; + XML_Parser m_parser; +}; /* The format for saving the SLA points was changing in the past. This enum holds the latest version that is being currently used. * Examples of the Slic3r_PE_sla_support_points.txt for historically used versions: diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index 2160ff6276a..34a97cf9c67 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -33,6 +33,7 @@ // BBS: for segment #include "MeshBoolean.hpp" +#include "Format/3mf.hpp" namespace Slic3r { // BBS initialization of static variables @@ -202,7 +203,7 @@ Model Model::read_from_file(const std::string& input_file, DynamicPrintConfig* c //BBS: add part plate related logic // BBS: backup & restore // Loading model from a file (3MF or AMF), not from a simple geometry file (STL or OBJ). -Model Model::read_from_archive(const std::string& input_file, DynamicPrintConfig* config, ConfigSubstitutionContext* config_substitutions, LoadStrategy options, PlateDataPtrs* plate_data, std::vector* project_presets, bool *is_bbl_3mf, Semver* file_version, Import3mfProgressFn proFn, BBLProject *project) +Model Model::read_from_archive(const std::string& input_file, DynamicPrintConfig* config, ConfigSubstitutionContext* config_substitutions, En3mfType& out_file_type, LoadStrategy options, PlateDataPtrs* plate_data, std::vector* project_presets, Semver* file_version, Import3mfProgressFn proFn, BBLProject *project) { assert(config != nullptr); assert(config_substitutions != nullptr); @@ -210,15 +211,28 @@ Model Model::read_from_archive(const std::string& input_file, DynamicPrintConfig Model model; bool result = false; - if (boost::algorithm::iends_with(input_file, ".3mf")) - //BBS: add part plate related logic - // BBS: backup & restore - result = load_bbs_3mf(input_file.c_str(), config, config_substitutions, &model, plate_data, project_presets, is_bbl_3mf, file_version, proFn, options, project); + bool is_bbl_3mf; + if (boost::algorithm::iends_with(input_file, ".3mf")) { + PrusaFileParser prusa_file_parser; + if (prusa_file_parser.check_3mf_from_prusa(input_file)) { + // for Prusa 3mf + result = load_3mf(input_file.c_str(), *config, *config_substitutions, &model, true); + out_file_type = En3mfType::From_Prusa; + } else { + // BBS: add part plate related logic + // BBS: backup & restore + result = load_bbs_3mf(input_file.c_str(), config, config_substitutions, &model, plate_data, project_presets, &is_bbl_3mf, file_version, proFn, options, project); + } + } else if (boost::algorithm::iends_with(input_file, ".zip.amf")) - result = load_amf(input_file.c_str(), config, config_substitutions, &model, is_bbl_3mf); + result = load_amf(input_file.c_str(), config, config_substitutions, &model, &is_bbl_3mf); else throw Slic3r::RuntimeError("Unknown file format. Input file must have .3mf or .zip.amf extension."); + if (out_file_type != En3mfType::From_Prusa) { + out_file_type = is_bbl_3mf ? En3mfType::From_BBS : En3mfType::From_Other; + } + if (!result) throw Slic3r::RuntimeError("Loading of a model file failed."); diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index 3a5b7e7f6d2..ed277491382 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -577,6 +577,12 @@ enum class ConversionType : int { CONV_FROM_METER, }; +enum class En3mfType : int { + From_BBS, + From_Prusa, + From_Other +}; + class FacetsAnnotation final : public ObjectWithTimestamp { public: // Assign the content if the timestamp differs, don't assign an ObjectID. @@ -1280,8 +1286,8 @@ class Model final : public ObjectBase // BBS: backup static Model read_from_archive( const std::string& input_file, - DynamicPrintConfig* config, ConfigSubstitutionContext* config_substitutions, - LoadStrategy options = LoadStrategy::AddDefaultInstances, PlateDataPtrs* plate_data = nullptr, std::vector* project_presets = nullptr, bool* is_bbl_3mf = nullptr, Semver* file_version = nullptr, Import3mfProgressFn proFn = nullptr, BBLProject* project = nullptr); + DynamicPrintConfig* config, ConfigSubstitutionContext* config_substitutions, En3mfType& out_file_type, + LoadStrategy options = LoadStrategy::AddDefaultInstances, PlateDataPtrs* plate_data = nullptr, std::vector* project_presets = nullptr, Semver* file_version = nullptr, Import3mfProgressFn proFn = nullptr, BBLProject* project = nullptr); // Add a new ModelObject to this Model, generate a new ID for this ModelObject. ModelObject* add_object(); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 834a1a26620..f7b7508b3be 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -2642,11 +2642,11 @@ std::vector Plater::priv::load_files(const std::vector& input_ // BBS: add part plate related logic PlateDataPtrs plate_data; - bool is_bbs_3mf; + En3mfType en_3mf_file_type = En3mfType::From_BBS; ConfigSubstitutionContext config_substitutions{ForwardCompatibilitySubstitutionRule::Enable}; std::vector project_presets; // BBS: backup & restore - model = Slic3r::Model::read_from_archive(path.string(), &config_loaded, &config_substitutions, strategy, &plate_data, &project_presets, &is_bbs_3mf, + model = Slic3r::Model::read_from_archive(path.string(), &config_loaded, &config_substitutions, en_3mf_file_type, strategy, &plate_data, &project_presets, &file_version, [this, &dlg, real_filename, progress_percent](int import_stage, int current, int total, bool &cancel) { bool cont = true; @@ -2657,11 +2657,40 @@ std::vector Plater::priv::load_files(const std::vector& input_ BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ << boost::format(", plate_data.size %1%, project_preset.size %2%, is_bbs_3mf %3%, file_version %4% \n") % plate_data.size() % - project_presets.size() % is_bbs_3mf % file_version.to_string(); + project_presets.size() % (en_3mf_file_type == En3mfType::From_BBS) % file_version.to_string(); + + // add extruder for prusa model if the number of existing extruders is not enough + if (en_3mf_file_type == En3mfType::From_Prusa) { + std::set extruderIds; + for (ModelObject *o : model.objects) { + if (o->config.option("extruder")) extruderIds.insert(o->config.extruder()); + for (auto volume : o->volumes) { + if (volume->config.option("extruder")) extruderIds.insert(volume->config.extruder()); + for (int extruder : volume->get_extruders()) { extruderIds.insert(extruder); } + } + } + int size = extruderIds.size() == 0 ? 0 : *(extruderIds.rbegin()); + + int filament_size = sidebar->combos_filament().size(); + while (filament_size < 16 && filament_size < size) { + int filament_count = filament_size + 1; + wxColour new_col = Plater::get_next_color_for_filament(); + std::string new_color = new_col.GetAsString(wxC2S_HTML_SYNTAX).ToStdString(); + wxGetApp().preset_bundle->set_num_filaments(filament_count, new_color); + wxGetApp().plater()->on_filaments_change(filament_count); + ++filament_size; + } + wxGetApp().get_tab(Preset::TYPE_PRINT)->update(); + } // BBS: version check Semver app_version = *(Semver::parse(SLIC3R_VERSION)); - if (load_config && (file_version.maj() != app_version.maj())) { + if (en_3mf_file_type == En3mfType::From_Prusa) { + // do not reset the model config + load_config = false; + show_info(q, _L("the 3mf is not compatible, load geometry data only!"), _L("Incompatible 3mf")); + } + else if (load_config && (file_version.maj() != app_version.maj())) { // version mismatch, only load geometries load_config = false; if (!load_model) { From ec59446e448d73d1d144c55974c1622e19e3efc7 Mon Sep 17 00:00:00 2001 From: "chunmao.guo" Date: Fri, 29 Jul 2022 15:10:41 +0800 Subject: [PATCH 075/180] FIX: button focused state Change-Id: Ieab02661c8f2e406b5bf5f156d9142efbe76d1cf --- src/slic3r/GUI/Widgets/Button.cpp | 5 +++-- src/slic3r/GUI/Widgets/SpinInput.cpp | 1 - src/slic3r/GUI/Widgets/StateColor.cpp | 13 +++++++++++++ src/slic3r/GUI/Widgets/StateColor.hpp | 3 +++ src/slic3r/GUI/Widgets/TextInput.cpp | 1 - 5 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/slic3r/GUI/Widgets/Button.cpp b/src/slic3r/GUI/Widgets/Button.cpp index 54b10c4b1d3..7972d51e6c9 100644 --- a/src/slic3r/GUI/Widgets/Button.cpp +++ b/src/slic3r/GUI/Widgets/Button.cpp @@ -26,8 +26,9 @@ Button::Button() , text_color(*wxBLACK) { background_color = StateColor( - std::make_pair(*wxLIGHT_GREY, (int) StateColor::Checked), - std::make_pair(*wxLIGHT_GREY, (int) StateColor::Hovered), + std::make_pair(0x00AE42, (int) StateColor::Checked), + std::make_pair(*wxLIGHT_GREY, (int) StateColor::Hovered), + std::make_pair(0x37EE7C, (int) StateColor::Hovered | StateColor::Checked), std::make_pair(*wxWHITE, (int) StateColor::Normal)); } diff --git a/src/slic3r/GUI/Widgets/SpinInput.cpp b/src/slic3r/GUI/Widgets/SpinInput.cpp index 4d96d849e33..f970a6a9649 100644 --- a/src/slic3r/GUI/Widgets/SpinInput.cpp +++ b/src/slic3r/GUI/Widgets/SpinInput.cpp @@ -27,7 +27,6 @@ END_EVENT_TABLE() SpinInput::SpinInput() : state_handler(this) , border_color(std::make_pair(0xDBDBDB, (int) StateColor::Disabled), - std::make_pair(0x00AE42, (int) StateColor::Focused), std::make_pair(0x00AE42, (int) StateColor::Hovered), std::make_pair(0xDBDBDB, (int) StateColor::Normal)) , text_color(std::make_pair(0xACACAC, (int) StateColor::Disabled), std::make_pair(*wxBLACK, (int) StateColor::Normal)) diff --git a/src/slic3r/GUI/Widgets/StateColor.cpp b/src/slic3r/GUI/Widgets/StateColor.cpp index b513eeae2c5..a3419b08d37 100644 --- a/src/slic3r/GUI/Widgets/StateColor.cpp +++ b/src/slic3r/GUI/Widgets/StateColor.cpp @@ -36,6 +36,9 @@ int StateColor::states() const { int states = 0; for (auto s : statesList_) states |= s; + states = (states & 0xffff) | (states >> 16); + if (takeFocusedAsHovered_ && (states & Hovered)) + states |= Focused; return states; } @@ -45,6 +48,7 @@ wxColour StateColor::defaultColor() { wxColour StateColor::colorForStates(int states) { + bool focused = takeFocusedAsHovered_ && (states & Focused); for (int i = 0; i < statesList_.size(); ++i) { int s = statesList_[i]; int on = s & 0xffff; @@ -52,6 +56,13 @@ wxColour StateColor::colorForStates(int states) if ((on & states) == on && (off & ~states) == off) { return colors_[i]; } + if (focused && (on & Hovered)) { + on |= Focused; + on &= ~Hovered; + if ((on & states) == on && (off & ~states) == off) { + return colors_[i]; + } + } } return wxColour(0, 0, 0, 0); } @@ -78,3 +89,5 @@ bool StateColor::setColorForStates(wxColour const &color, int states) return false; } +void StateColor::setTakeFocusedAsHovered(bool set) { takeFocusedAsHovered_ = set; } + diff --git a/src/slic3r/GUI/Widgets/StateColor.hpp b/src/slic3r/GUI/Widgets/StateColor.hpp index 2b7643a0d79..0855e64db4f 100644 --- a/src/slic3r/GUI/Widgets/StateColor.hpp +++ b/src/slic3r/GUI/Widgets/StateColor.hpp @@ -58,6 +58,8 @@ class StateColor bool setColorForStates(wxColour const & color, int states); + void setTakeFocusedAsHovered(bool set); + private: template void fill(std::pair color, std::pair... colors) { @@ -76,6 +78,7 @@ class StateColor private: std::vector statesList_; std::vector colors_; + bool takeFocusedAsHovered_ = true; }; #endif // !slic3r_GUI_StateColor_hpp_ diff --git a/src/slic3r/GUI/Widgets/TextInput.cpp b/src/slic3r/GUI/Widgets/TextInput.cpp index 1b962a27813..605e2e12bb4 100644 --- a/src/slic3r/GUI/Widgets/TextInput.cpp +++ b/src/slic3r/GUI/Widgets/TextInput.cpp @@ -26,7 +26,6 @@ END_EVENT_TABLE() TextInput::TextInput() : state_handler(this) , border_color(std::make_pair(0xDBDBDB, (int) StateColor::Disabled), - std::make_pair(0x00AE42, (int) StateColor::Focused), std::make_pair(0x00AE42, (int) StateColor::Hovered), std::make_pair(0xDBDBDB, (int) StateColor::Normal)) , text_color(std::make_pair(0xACACAC, (int) StateColor::Disabled), From 807cc2236dd9c0a69e26e753fb642833a13c4a45 Mon Sep 17 00:00:00 2001 From: "chunmao.guo" Date: Fri, 29 Jul 2022 13:29:09 +0800 Subject: [PATCH 076/180] FIX: focus state of CheckBox Change-Id: Iceac4b9877a07e4517250255203c2e0ecdbc34ac --- resources/images/check_half_focused.svg | 4 ++++ resources/images/check_off.svg | 7 +++---- resources/images/check_off_focused.svg | 3 +++ resources/images/check_on.svg | 9 ++++----- resources/images/check_on_focused.svg | 4 ++++ src/slic3r/GUI/Widgets/CheckBox.cpp | 21 ++++++++++++++------- src/slic3r/GUI/Widgets/CheckBox.hpp | 6 ++++++ 7 files changed, 38 insertions(+), 16 deletions(-) create mode 100644 resources/images/check_half_focused.svg create mode 100644 resources/images/check_off_focused.svg create mode 100644 resources/images/check_on_focused.svg diff --git a/resources/images/check_half_focused.svg b/resources/images/check_half_focused.svg new file mode 100644 index 00000000000..ad3f4c10136 --- /dev/null +++ b/resources/images/check_half_focused.svg @@ -0,0 +1,4 @@ + + + + diff --git a/resources/images/check_off.svg b/resources/images/check_off.svg index 601a44277c0..cf58fbc94c5 100644 --- a/resources/images/check_off.svg +++ b/resources/images/check_off.svg @@ -1,4 +1,3 @@ - - - - \ No newline at end of file + + + diff --git a/resources/images/check_off_focused.svg b/resources/images/check_off_focused.svg new file mode 100644 index 00000000000..df78824780d --- /dev/null +++ b/resources/images/check_off_focused.svg @@ -0,0 +1,3 @@ + + + diff --git a/resources/images/check_on.svg b/resources/images/check_on.svg index 4ecbf27056c..83a78da28ab 100644 --- a/resources/images/check_on.svg +++ b/resources/images/check_on.svg @@ -1,5 +1,4 @@ - - - - - \ No newline at end of file + + + + diff --git a/resources/images/check_on_focused.svg b/resources/images/check_on_focused.svg new file mode 100644 index 00000000000..379f61b650b --- /dev/null +++ b/resources/images/check_on_focused.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/slic3r/GUI/Widgets/CheckBox.cpp b/src/slic3r/GUI/Widgets/CheckBox.cpp index aec46c3376e..92878209912 100644 --- a/src/slic3r/GUI/Widgets/CheckBox.cpp +++ b/src/slic3r/GUI/Widgets/CheckBox.cpp @@ -4,12 +4,15 @@ CheckBox::CheckBox(wxWindow* parent) : wxBitmapToggleButton(parent, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE) - , m_on(this, "check_on", 16) - , m_half(this, "check_half", 16) - , m_off(this, "check_off", 16) - , m_on_disabled(this, "check_on_disabled", 16) - , m_half_disabled(this, "check_half_disabled", 16) - , m_off_disabled(this, "check_off_disabled", 16) + , m_on(this, "check_on", 18) + , m_half(this, "check_half", 18) + , m_off(this, "check_off", 18) + , m_on_disabled(this, "check_on_disabled", 18) + , m_half_disabled(this, "check_half_disabled", 18) + , m_off_disabled(this, "check_off_disabled", 18) + , m_on_focused(this, "check_on_focused", 18) + , m_half_focused(this, "check_half_focused", 18) + , m_off_focused(this, "check_off_focused", 18) { //SetBackgroundStyle(wxBG_STYLE_TRANSPARENT); if (parent) @@ -42,6 +45,10 @@ void CheckBox::Rescale() void CheckBox::update() { - SetBitmap((m_half_checked ? m_half : GetValue() ? m_on : m_off).bmp()); + SetBitmapLabel((m_half_checked ? m_half : GetValue() ? m_on : m_off).bmp()); SetBitmapDisabled((m_half_checked ? m_half_disabled : GetValue() ? m_on_disabled : m_off_disabled).bmp()); + SetBitmapFocus((m_half_checked ? m_half_focused : GetValue() ? m_on_focused : m_off_focused).bmp()); + SetBitmapCurrent((m_half_checked ? m_half_focused : GetValue() ? m_on_focused : m_off_focused).bmp()); } + +CheckBox::State CheckBox::GetNormalState() const { return State_Normal; } diff --git a/src/slic3r/GUI/Widgets/CheckBox.hpp b/src/slic3r/GUI/Widgets/CheckBox.hpp index 69d0e0e7d73..6d6451a71e5 100644 --- a/src/slic3r/GUI/Widgets/CheckBox.hpp +++ b/src/slic3r/GUI/Widgets/CheckBox.hpp @@ -17,6 +17,9 @@ class CheckBox : public wxBitmapToggleButton void Rescale(); +protected: + virtual State GetNormalState() const wxOVERRIDE; + private: void update(); @@ -27,6 +30,9 @@ class CheckBox : public wxBitmapToggleButton ScalableBitmap m_on_disabled; ScalableBitmap m_half_disabled; ScalableBitmap m_off_disabled; + ScalableBitmap m_on_focused; + ScalableBitmap m_half_focused; + ScalableBitmap m_off_focused; bool m_half_checked = false; }; From 173b43d2bdc09f764d6bdeec874cac19ec5b4cb9 Mon Sep 17 00:00:00 2001 From: "chunmao.guo" Date: Thu, 28 Jul 2022 09:46:30 +0800 Subject: [PATCH 077/180] FIX: stop keyboard tab navigation in StaticLine/SpinInput Change-Id: Id0287418acc36bf9f74a62df79ecf99354f01cc9 --- src/slic3r/GUI/Widgets/SpinInput.cpp | 2 +- src/slic3r/GUI/Widgets/StaticLine.cpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/Widgets/SpinInput.cpp b/src/slic3r/GUI/Widgets/SpinInput.cpp index f970a6a9649..0e534465ae2 100644 --- a/src/slic3r/GUI/Widgets/SpinInput.cpp +++ b/src/slic3r/GUI/Widgets/SpinInput.cpp @@ -239,7 +239,7 @@ Button *SpinInput::createButton(bool inc) { auto btn = new Button(this, "", inc ? "spin_inc" : "spin_dec", wxBORDER_NONE, 6); btn->SetCornerRadius(0); - btn->SetCanFocus(false); + btn->DisableFocusFromKeyboard(); btn->Bind(wxEVT_LEFT_DOWN, [=](auto &e) { delta = inc ? 1 : -1; SetValue(val + delta); diff --git a/src/slic3r/GUI/Widgets/StaticLine.cpp b/src/slic3r/GUI/Widgets/StaticLine.cpp index 69892ebcbdd..16f89ec9ce7 100644 --- a/src/slic3r/GUI/Widgets/StaticLine.cpp +++ b/src/slic3r/GUI/Widgets/StaticLine.cpp @@ -16,6 +16,7 @@ StaticLine::StaticLine(wxWindow* parent, bool vertical, const wxString& label) { wxWindow::SetBackgroundColour(parent->GetBackgroundColour()); this->pen = wxPen(wxColour("#C4C4C4")); + DisableFocusFromKeyboard(); SetFont(Label::Body_14); SetLabel(label); } From e43f80e875d9388e038768b04c856aa8d19487a6 Mon Sep 17 00:00:00 2001 From: "zorro.zhang" Date: Tue, 26 Jul 2022 10:14:43 +0800 Subject: [PATCH 078/180] ENH: support 3rd printer model Change-Id: Ib8c2c846f73a6ac14339e1d0222204d7440de014 --- resources/web/guide/21/21.js | 6 ++- resources/web/guide/24/24.js | 6 ++- resources/web/guide/6/6.css | 1 + resources/web/guide/css/common.css | 1 + resources/web/homepage/css/home.css | 1 + src/slic3r/GUI/WebDownPluginDlg.cpp | 7 +++- src/slic3r/GUI/WebGuideDialog.cpp | 61 +++++++++++++++++++++++------ 7 files changed, 69 insertions(+), 14 deletions(-) diff --git a/resources/web/guide/21/21.js b/resources/web/guide/21/21.js index 6dd7218e259..5a37c4c32e7 100644 --- a/resources/web/guide/21/21.js +++ b/resources/web/guide/21/21.js @@ -59,13 +59,17 @@ function HandleModelList( pVal ) //Add Vendor Html Node if($(".OneVendorBlock[vendor='"+strVendor+"']").length==0) { + let sVV=strVendor; + if( sVV=="BBL" ) + sVV="Bambu Lab"; + let HtmlNewVendor='
'+ ''+ '
'+ '
'+ diff --git a/resources/web/guide/24/24.js b/resources/web/guide/24/24.js index ccfdd6164bc..43dffda1304 100644 --- a/resources/web/guide/24/24.js +++ b/resources/web/guide/24/24.js @@ -59,13 +59,17 @@ function HandleModelList( pVal ) //Add Vendor Html Node if($(".OneVendorBlock[vendor='"+strVendor+"']").length==0) { + let sVV=strVendor; + if( sVV=="BBL" ) + sVV="Bambu Lab"; + let HtmlNewVendor='
'+ '
'+ '
'+ '
all
'+ '
none
'+ '
'+ -' Bambu Lab'+ +' '+sVV+''+ '
'+ '
'+ '
'+ diff --git a/resources/web/guide/6/6.css b/resources/web/guide/6/6.css index ca27c8eaa03..b60480520ea 100644 --- a/resources/web/guide/6/6.css +++ b/resources/web/guide/6/6.css @@ -3,6 +3,7 @@ padding: 0; border: 0; margin: 0; + font-family: "system-ui", "Segoe UI", Roboto, Oxygen, Ubuntu, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-sans; } html,body diff --git a/resources/web/guide/css/common.css b/resources/web/guide/css/common.css index c7e2cc0b626..4f0a2ae7954 100644 --- a/resources/web/guide/css/common.css +++ b/resources/web/guide/css/common.css @@ -3,6 +3,7 @@ padding: 0; border: 0; margin: 0; + font-family: "system-ui", "Segoe UI", Roboto, Oxygen, Ubuntu, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-sans; } html diff --git a/resources/web/homepage/css/home.css b/resources/web/homepage/css/home.css index e287a76cbd0..c03c76f4e53 100644 --- a/resources/web/homepage/css/home.css +++ b/resources/web/homepage/css/home.css @@ -4,6 +4,7 @@ border: 0px; margin: 0px; font-size: 16px; + font-family: "system-ui", "Segoe UI", Roboto, Oxygen, Ubuntu, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-sans; } html, body { diff --git a/src/slic3r/GUI/WebDownPluginDlg.cpp b/src/slic3r/GUI/WebDownPluginDlg.cpp index ee5ce10577f..b651323df51 100644 --- a/src/slic3r/GUI/WebDownPluginDlg.cpp +++ b/src/slic3r/GUI/WebDownPluginDlg.cpp @@ -319,7 +319,12 @@ int DownPluginFrame::InstallPlugin() int DownPluginFrame::ShowPluginStatus(int status, int percent, bool &cancel) { - // TODO + static int nPercent = 0; + if (nPercent == percent) + return 0; + + nPercent = percent; + json m_Data = json::object(); m_Data["status"] = status; m_Data["percent"] = percent; diff --git a/src/slic3r/GUI/WebGuideDialog.cpp b/src/slic3r/GUI/WebGuideDialog.cpp index 4b83a48b3ef..1095a7b50a7 100644 --- a/src/slic3r/GUI/WebGuideDialog.cpp +++ b/src/slic3r/GUI/WebGuideDialog.cpp @@ -19,6 +19,7 @@ #include #include +#include #include "MainFrame.hpp" #include @@ -850,25 +851,63 @@ int GuideFrame::LoadProfile() //} while (_findnext(handle, &findData) == 0); // 查找目录中的下一个文件 // BBS: change directories by design - vendor_dir = (boost::filesystem::path(Slic3r::data_dir()) / PRESET_SYSTEM_DIR).make_preferred(); + //BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", will load config from %1%.") % bbl_bundle_path; + m_ProfileJson = json::parse("{}"); + m_ProfileJson["model"] = json::array(); + m_ProfileJson["machine"] = json::array(); + m_ProfileJson["filament"] = json::object(); + m_ProfileJson["process"] = json::array(); + + vendor_dir = (boost::filesystem::path(Slic3r::data_dir()) / PRESET_SYSTEM_DIR ).make_preferred(); rsrc_vendor_dir = (boost::filesystem::path(resources_dir()) / "profiles").make_preferred(); // BBS: add BBL as default // BBS: add json logic for vendor bundle - auto bbl_bundle_path = (vendor_dir / PresetBundle::BBL_BUNDLE).replace_extension(".json"); + auto bbl_bundle_path = vendor_dir; bbl_bundle_rsrc = false; - if (!boost::filesystem::exists(bbl_bundle_path)) { - bbl_bundle_path = (rsrc_vendor_dir / PresetBundle::BBL_BUNDLE).replace_extension(".json"); + if (!boost::filesystem::exists((vendor_dir / PresetBundle::BBL_BUNDLE).replace_extension(".json"))) { + bbl_bundle_path = rsrc_vendor_dir; bbl_bundle_rsrc = true; } - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", will load config from %1%.")% bbl_bundle_path; - m_ProfileJson = json::parse("{}"); - m_ProfileJson["model"] = json::array(); - m_ProfileJson["machine"] = json::array(); - m_ProfileJson["filament"] = json::object(); - m_ProfileJson["process"] = json::array(); - LoadProfileFamily(PresetBundle::BBL_BUNDLE, bbl_bundle_path.string()); + // intptr_t handle; + //_finddata_t findData; + + //handle = _findfirst((bbl_bundle_path / "*.json").make_preferred().string().c_str(), &findData); // 查找目录中的第一个文件 + // if (handle == -1) { return -1; } + + // do { + // if (findData.attrib & _A_SUBDIR && strcmp(findData.name, ".") == 0 && strcmp(findData.name, "..") == 0) // 是否是子目录并且不为"."或".." + // { + // // cout << findData.name << "\t\n"; + // } else { + // wxString strVendor = wxString(findData.name).BeforeLast('.'); + // LoadProfileFamily(w2s(strVendor), vendor_dir.make_preferred().string() + "\\"+ findData.name); + // } + + //} while (_findnext(handle, &findData) == 0); // 查找目录中的下一个文件 + + + string targetPath = bbl_bundle_path.make_preferred().string(); + boost::filesystem::path myPath(targetPath); + boost::filesystem::directory_iterator endIter; + for (boost::filesystem::directory_iterator iter(myPath); iter != endIter; iter++) { + if (boost::filesystem::is_directory(*iter)) { + //cout << "is dir" << endl; + //cout << iter->path().string() << endl; + } else { + //cout << "is a file" << endl; + //cout << iter->path().string() << endl; + wxString strVendor = wxString(iter->path().string()).BeforeLast('.'); + strVendor = strVendor.AfterLast( '\\'); + strVendor = strVendor.AfterLast('\/'); + + LoadProfileFamily(w2s(strVendor), iter->path().string()); + } + } + + + //LoadProfileFamily(PresetBundle::BBL_BUNDLE, bbl_bundle_path.string()); const auto enabled_filaments = wxGetApp().app_config->has_section(AppConfig::SECTION_FILAMENTS) ? wxGetApp().app_config->get_section(AppConfig::SECTION_FILAMENTS) : std::map(); m_appconfig_new.set_vendors(*wxGetApp().app_config); From 6eb4d671b57fcae21d233e265bd6512efe84bf00 Mon Sep 17 00:00:00 2001 From: "zorro.zhang" Date: Fri, 29 Jul 2022 16:30:40 +0800 Subject: [PATCH 079/180] ENH: Login button add Largen UI-Action Change-Id: I40f668364730205c6cc1b916ef486fce836c08d8 --- resources/web/homepage/css/home.css | 10 ++++++++-- src/slic3r/GUI/WebGuideDialog.cpp | 4 ++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/resources/web/homepage/css/home.css b/resources/web/homepage/css/home.css index c03c76f4e53..2da4e566eb6 100644 --- a/resources/web/homepage/css/home.css +++ b/resources/web/homepage/css/home.css @@ -3,7 +3,6 @@ padding:0px; border: 0px; margin: 0px; - font-size: 16px; font-family: "system-ui", "Segoe UI", Roboto, Oxygen, Ubuntu, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-sans; } @@ -13,6 +12,7 @@ html, body { margin: 0px; padding: 0px; line-height: 20px; + font-size: 16px; } .RedFont @@ -72,6 +72,12 @@ body cursor:pointer; } +#LoginBtn:hover +{ + font-size:17px; +} + + #NoPluginTip { position: absolute; @@ -80,7 +86,7 @@ body bottom: 0px; right: 0px; z-index: 1; - display: flex; + display: none; flex-direction: column; justify-content: flex-end; padding: 5px; diff --git a/src/slic3r/GUI/WebGuideDialog.cpp b/src/slic3r/GUI/WebGuideDialog.cpp index 1095a7b50a7..0f9f55a8f15 100644 --- a/src/slic3r/GUI/WebGuideDialog.cpp +++ b/src/slic3r/GUI/WebGuideDialog.cpp @@ -145,10 +145,10 @@ wxString GuideFrame::SetStartPage(GuidePage startpage, bool load) else TargetUrl = from_u8((boost::filesystem::path(resources_dir()) / "web/guide/21/index.html").make_preferred().string()); } else if (startpage == BBL_FILAMENT_ONLY) { - SetTitle(_L("Filaments Selection")); + SetTitle(_L("")); TargetUrl = from_u8((boost::filesystem::path(resources_dir()) / "web/guide/23/index.html").make_preferred().string()); } else if (startpage == BBL_MODELS_ONLY) { - SetTitle(_L("Printer Selection")); + SetTitle(_L("")); TargetUrl = from_u8((boost::filesystem::path(resources_dir()) / "web/guide/24/index.html").make_preferred().string()); } else { From 7a041ac2a004a1dd6c0a7a37a719b2eadaaeacef Mon Sep 17 00:00:00 2001 From: "xiangdong.yang" Date: Fri, 22 Jul 2022 16:43:08 +0800 Subject: [PATCH 080/180] ENH:Show ErrorCode to the Device screen Change-Id: I481b08a439d07a99f6c06c558e0a7fb3467a7d51 --- src/libslic3r/AppConfig.cpp | 35 ++++++++ src/libslic3r/AppConfig.hpp | 3 + src/slic3r/CMakeLists.txt | 4 + src/slic3r/GUI/DeviceManager.cpp | 10 ++- src/slic3r/GUI/DeviceManager.hpp | 1 + src/slic3r/GUI/StatusPanel.cpp | 105 +++++++++++++++++++++-- src/slic3r/GUI/StatusPanel.hpp | 18 ++-- src/slic3r/GUI/UpdateErrorMessage.cpp | 60 +++++++++++++ src/slic3r/GUI/UpdateErrorMessage.hpp | 26 ++++++ src/slic3r/GUI/Widgets/wxStaticText2.cpp | 54 ++++++++++++ src/slic3r/GUI/Widgets/wxStaticText2.hpp | 22 +++++ 11 files changed, 322 insertions(+), 16 deletions(-) create mode 100644 src/slic3r/GUI/UpdateErrorMessage.cpp create mode 100644 src/slic3r/GUI/UpdateErrorMessage.hpp create mode 100644 src/slic3r/GUI/Widgets/wxStaticText2.cpp create mode 100644 src/slic3r/GUI/Widgets/wxStaticText2.hpp diff --git a/src/libslic3r/AppConfig.cpp b/src/libslic3r/AppConfig.cpp index c7f64c5a2ce..8eac50bd548 100644 --- a/src/libslic3r/AppConfig.cpp +++ b/src/libslic3r/AppConfig.cpp @@ -44,6 +44,41 @@ static const std::string MODELS_STR = "models"; const std::string AppConfig::SECTION_FILAMENTS = "filaments"; const std::string AppConfig::SECTION_MATERIALS = "sla_materials"; +std::string AppConfig::get_langauge_code() +{ + std::string get_lang = get("language"); + if (get_lang.empty()) return ""; + + if (get_lang == "zh_CN") + { + get_lang = "zh-cn"; + } + else + { + if (get_lang.length() >= 2) { get_lang = get_lang.substr(0, 2); } + } + + return get_lang; +} + +std::string AppConfig::get_hms_host() +{ + std::string sel = get("iot_environment"); + std::string host = ""; +#if !BBL_RELEASE_TO_PUBLIC + if (sel == ENV_DEV_HOST) + host = "e-dev.bambu-lab.com"; + else if (sel == ENV_QAT_HOST) + host = "e-qa.bambu-lab.com"; + else if (sel == ENV_PRE_HOST) + host = "e-pre.bambu-lab.com"; + else if (sel == ENV_PRODUCT_HOST) + host = "e.bambulab.com"; + return host; +#else + return "e.bambulab.com"; +#endif +} void AppConfig::reset() { diff --git a/src/libslic3r/AppConfig.hpp b/src/libslic3r/AppConfig.hpp index a324b364dfa..69f46cdeaf4 100644 --- a/src/libslic3r/AppConfig.hpp +++ b/src/libslic3r/AppConfig.hpp @@ -39,6 +39,9 @@ class AppConfig this->reset(); } + std::string get_langauge_code(); + std::string get_hms_host(); + // Clear and reset to defaults. void reset(); // Override missing or keys with their defaults. diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index 358557ccb6a..d9db4d6a777 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -68,6 +68,8 @@ set(SLIC3R_GUI_SOURCES GUI/Widgets/SideTools.hpp GUI/Widgets/WebView.cpp GUI/Widgets/WebView.hpp + GUI/Widgets/wxStaticText2.cpp + GUI/Widgets/wxStaticText2.hpp GUI/AboutDialog.cpp GUI/AboutDialog.hpp GUI/AuxiliaryDialog.cpp @@ -213,6 +215,8 @@ set(SLIC3R_GUI_SOURCES GUI/MonitorPage.hpp GUI/StatusPanel.cpp GUI/StatusPanel.hpp + GUI/UpdateErrorMessage.cpp + GUI/UpdateErrorMessage.hpp GUI/SliceInfoPanel.cpp GUI/SliceInfoPanel.hpp GUI/CameraPopup.cpp diff --git a/src/slic3r/GUI/DeviceManager.cpp b/src/slic3r/GUI/DeviceManager.cpp index 31cbc875c69..a6357496660 100644 --- a/src/slic3r/GUI/DeviceManager.cpp +++ b/src/slic3r/GUI/DeviceManager.cpp @@ -336,6 +336,7 @@ MachineObject::MachineObject(NetworkAgent* agent, std::string name, std::string /* printing */ mc_print_stage = 0; mc_print_error_code = 0; + print_error = 0; mc_print_line_number = 0; mc_print_percent = 0; mc_print_sub_stage = 0; @@ -1680,8 +1681,6 @@ int MachineObject::parse_json(std::string payload) mc_print_stage = jj["mc_print_stage"].get(); } if (jj.contains("mc_print_error_code")) { - if (jj["mc_print_error_code"].is_string()) - mc_print_error_code = atoi(jj["mc_print_error_code"].get().c_str()); if (jj["mc_print_error_code"].is_number()) mc_print_error_code = jj["mc_print_error_code"].get(); @@ -1690,6 +1689,11 @@ int MachineObject::parse_json(std::string payload) if (jj["mc_print_line_number"].is_string() && !jj["mc_print_line_number"].is_null()) mc_print_line_number = atoi(jj["mc_print_line_number"].get().c_str()); } + if (jj.contains("print_error")) { + if (jj["print_error"].is_number()) + print_error = jj["print_error"].get(); + } + #pragma endregion #pragma region print_task @@ -1750,6 +1754,8 @@ int MachineObject::parse_json(std::string payload) } } + + #pragma endregion #pragma region status diff --git a/src/slic3r/GUI/DeviceManager.hpp b/src/slic3r/GUI/DeviceManager.hpp index 8e9dcb0c59a..7c2472d7b9c 100644 --- a/src/slic3r/GUI/DeviceManager.hpp +++ b/src/slic3r/GUI/DeviceManager.hpp @@ -426,6 +426,7 @@ class MachineObject int mc_left_time; /* left time in seconds */ int last_mc_print_stage; bool is_system_printing(); + int print_error; std::vector stage_list_info; int stage_curr = 0; diff --git a/src/slic3r/GUI/StatusPanel.cpp b/src/slic3r/GUI/StatusPanel.cpp index 8b4f5e74eb7..ef9513dc965 100644 --- a/src/slic3r/GUI/StatusPanel.cpp +++ b/src/slic3r/GUI/StatusPanel.cpp @@ -7,6 +7,10 @@ #include "BitmapCache.hpp" #include "GUI_App.hpp" +#include "slic3r/Utils/Http.hpp" +#include "libslic3r/Thread.hpp" + + namespace Slic3r { namespace GUI { #define TEMP_THRESHOLD_VAL 2 @@ -105,6 +109,7 @@ StatusBasePanel::StatusBasePanel(wxWindow *parent, wxWindowID id, const wxPoint m_project_task_panel = new wxPanel(this); m_project_task_panel->SetBackgroundColour(*wxWHITE); + auto m_project_task_sizer = create_project_task_page(m_project_task_panel); m_project_task_panel->SetSizer(m_project_task_sizer); m_project_task_panel->Layout(); @@ -145,7 +150,6 @@ StatusBasePanel::StatusBasePanel(wxWindow *parent, wxWindowID id, const wxPoint m_panel_separotor_bottom->SetBackgroundColour(STATUS_PANEL_BG); bSizer_status->Add(m_panel_separotor_bottom, 0, wxEXPAND | wxALL, 0); - this->SetSizerAndFit(bSizer_status); this->Layout(); } @@ -392,14 +396,11 @@ wxBoxSizer *StatusBasePanel::create_project_task_page(wxWindow *parent) m_staticText_progress_percent->SetFont(::Label::Head_13); m_staticText_progress_percent->SetForegroundColour(wxColour(0, 174, 66)); - m_staticText_progress_left = new wxStaticText(penel_text, wxID_ANY, _L("N/A"), wxDefaultPosition, wxDefaultSize, 0); m_staticText_progress_left->Wrap(-1); m_staticText_progress_left->SetFont(wxFont(10, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxT("HarmonyOS Sans SC"))); m_staticText_progress_left->SetForegroundColour(wxColour(146, 146, 146)); - - //fgSizer_task->Add(bSizer_buttons, 0, wxEXPAND, 0); //fgSizer_task->Add(0, 0, 0, wxEXPAND, FromDIP(5)); @@ -417,7 +418,6 @@ wxBoxSizer *StatusBasePanel::create_project_task_page(wxWindow *parent) penel_text->SetSizer(bSizer_text); penel_text->Layout(); - bSizer_buttons->Add(penel_text, 1, wxEXPAND | wxALL, 0); bSizer_buttons->Add(panel_button_block, 0, wxALIGN_CENTER | wxALL, 0); @@ -431,6 +431,37 @@ wxBoxSizer *StatusBasePanel::create_project_task_page(wxWindow *parent) sizer->Add(m_printing_sizer, 0, wxEXPAND | wxALL, 0); + m_staticline = new wxPanel( parent, wxID_ANY); + m_staticline->SetBackgroundColour(wxColour(238,238,238)); + m_staticline->Layout(); + m_staticline->Hide(); + + sizer->Add(0, 0, 0, wxTOP, FromDIP(15)); + sizer->Add(m_staticline, 0, wxEXPAND|wxALL, FromDIP(10)); + + m_panel_error_txt = new wxPanel(parent, wxID_ANY); + m_panel_error_txt->SetBackgroundColour(*wxWHITE); + + wxBoxSizer *static_text_sizer = new wxBoxSizer(wxHORIZONTAL); + wxBoxSizer *text_sizer = new wxBoxSizer(wxHORIZONTAL); + + m_error_text = new wxStaticText2(m_panel_error_txt); + m_error_text->SetForegroundColour(PAGE_TITLE_FONT_COL); + text_sizer->Add(m_error_text, 1, wxEXPAND|wxLEFT, FromDIP(17)); + m_button_clean = new Button(m_panel_error_txt, _L("Clean")); + m_button_clean->SetBackgroundColor(abort_bg); + m_button_clean->SetBorderColor(abort_bd); + m_button_clean->SetTextColor(abort_text); + m_button_clean->SetFont(Label::Body_10); + m_button_clean->SetMinSize(TASK_BUTTON_SIZE2); + + static_text_sizer->Add(text_sizer, 1, wxEXPAND|wxTOP, FromDIP(7)); + static_text_sizer->Add( FromDIP(10), 0, 0, 0, 0 ); + static_text_sizer->Add(m_button_clean, 0, wxALIGN_CENTRE_VERTICAL|wxRIGHT,FromDIP(5)); + + m_panel_error_txt->SetSizer(static_text_sizer); + m_panel_error_txt->Hide(); + sizer->Add(m_panel_error_txt, 0, wxEXPAND | wxALL,0); sizer->Add(0, FromDIP(12), 0); m_tasklist_sizer = new wxBoxSizer(wxVERTICAL); @@ -563,7 +594,6 @@ wxBoxSizer *StatusBasePanel::create_temp_control(wxWindow *parent) m_tempCtrl_frame->SetBorderColor(StateColor(std::make_pair(*wxWHITE, (int) StateColor::Disabled), std::make_pair(BUTTON_HOVER_COL, (int) StateColor::Focused), std::make_pair(BUTTON_HOVER_COL, (int) StateColor::Hovered), std::make_pair(*wxWHITE, (int) StateColor::Normal))); sizer->Add(m_tempCtrl_frame, 0, wxEXPAND | wxALL, 1); - line = new StaticLine(parent); line->SetLineColour(STATIC_BOX_LINE_COL); sizer->Add(line, 0, wxEXPAND | wxLEFT | wxRIGHT, 12); @@ -916,6 +946,7 @@ StatusPanel::StatusPanel(wxWindow *parent, wxWindowID id, const wxPoint &pos, co m_buttons.push_back(m_button_pause_resume); m_buttons.push_back(m_button_abort); m_buttons.push_back(m_button_unload); + m_buttons.push_back(m_button_clean); m_buttons.push_back(m_bpButton_z_10); m_buttons.push_back(m_bpButton_z_1); m_buttons.push_back(m_bpButton_z_down_1); @@ -924,7 +955,6 @@ StatusPanel::StatusPanel(wxWindow *parent, wxWindowID id, const wxPoint &pos, co m_buttons.push_back(m_bpButton_e_down_10); obj = nullptr; - /* set default values */ m_switch_lamp->SetValue(false); m_switch_printing_fan->SetValue(false); @@ -953,6 +983,7 @@ StatusPanel::StatusPanel(wxWindow *parent, wxWindowID id, const wxPoint &pos, co m_button_pause_resume->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_subtask_pause_resume), NULL, this); m_button_abort->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_subtask_abort), NULL, this); + m_button_clean->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_subtask_clean), NULL, this); m_tempCtrl_bed->Connect(wxEVT_KILL_FOCUS, wxFocusEventHandler(StatusPanel::on_bed_temp_kill_focus), NULL, this); m_tempCtrl_bed->Connect(wxEVT_SET_FOCUS, wxFocusEventHandler(StatusPanel::on_bed_temp_set_focus), NULL, this); m_tempCtrl_nozzle->Connect(wxEVT_KILL_FOCUS, wxFocusEventHandler(StatusPanel::on_nozzle_temp_kill_focus), NULL, this); @@ -974,6 +1005,7 @@ StatusPanel::StatusPanel(wxWindow *parent, wxWindowID id, const wxPoint &pos, co Bind(EVT_AMS_REFRESH_RFID, &StatusPanel::on_ams_refresh_rfid, this); Bind(EVT_AMS_ON_SELECTED, &StatusPanel::on_ams_selected, this); Bind(EVT_AMS_ON_FILAMENT_EDIT, &StatusPanel::on_filament_edit, this); + Bind(EVT_UPDATE_ERROR_MESSAGE, &StatusPanel::on_update_error_message, this); m_switch_speed->Connect(wxEVT_LEFT_DOWN, wxCommandEventHandler(StatusPanel::on_switch_speed), NULL, this); m_calibration_btn->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_start_calibration), NULL, this); @@ -987,6 +1019,7 @@ StatusPanel::~StatusPanel() m_recording_button->Disconnect(wxEVT_LEFT_DOWN, wxMouseEventHandler(StatusPanel::on_switch_recording), NULL, this); m_button_pause_resume->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_subtask_pause_resume), NULL, this); m_button_abort->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_subtask_abort), NULL, this); + m_button_clean->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(StatusPanel::on_subtask_clean), NULL, this); m_tempCtrl_bed->Disconnect(wxEVT_KILL_FOCUS, wxFocusEventHandler(StatusPanel::on_bed_temp_kill_focus), NULL, this); m_tempCtrl_bed->Disconnect(wxEVT_SET_FOCUS, wxFocusEventHandler(StatusPanel::on_bed_temp_set_focus), NULL, this); m_tempCtrl_nozzle->Disconnect(wxEVT_KILL_FOCUS, wxFocusEventHandler(StatusPanel::on_nozzle_temp_kill_focus), NULL, this); @@ -1014,6 +1047,8 @@ void StatusPanel::init_scaled_buttons() m_button_pause_resume->SetCornerRadius(FromDIP(12)); m_button_abort->SetMinSize(wxSize(FromDIP(48), FromDIP(24))); m_button_abort->SetCornerRadius(FromDIP(12)); + m_button_clean->SetMinSize(wxSize(FromDIP(48), FromDIP(24))); + m_button_clean->SetCornerRadius(FromDIP(12)); m_button_unload->SetMinSize(wxSize(-1, FromDIP(24))); m_button_unload->SetCornerRadius(FromDIP(10)); m_bpButton_z_10->SetMinSize(Z_BUTTON_SIZE); @@ -1066,6 +1101,7 @@ void StatusPanel::show_task_list_info(bool show) m_tasklist_sizer->Hide(m_tasklist_caption_sizer); } Layout(); + } void StatusPanel::update_tasklist_info() @@ -1091,6 +1127,20 @@ void StatusPanel::on_subtask_abort(wxCommandEvent &event) if (obj) obj->command_task_abort(); } +void StatusPanel::error_info_reset() +{ + m_error_text->SetLabel(""); + before_error_code = 0; +} + +void StatusPanel::on_subtask_clean(wxCommandEvent &event) +{ + m_staticline->Hide(); + m_panel_error_txt->Hide(); + m_panel_error_txt->GetParent()->Layout(); + error_info_reset(); +} + void StatusPanel::on_webrequest_state(wxWebRequestEvent &evt) { BOOST_LOG_TRIVIAL(trace) << "monitor: monitor_panel web request state = " << evt.GetState(); @@ -1163,13 +1213,49 @@ void StatusPanel::update(MachineObject *obj) calibration_dlg->update_machine_obj(obj); } calibration_dlg->update_cali(obj); + + if (print_options_dlg == nullptr) { + print_options_dlg = new PrintOptionsDialog(this); + print_options_dlg->update_machine_obj(obj); + } else { + print_options_dlg->update_machine_obj(obj); + } + print_options_dlg->update_options(obj); + update_error_message(); } - upodate_camera_state(obj->has_recording(), obj->has_timelapse(), obj->has_sdcard()); m_machine_ctrl_panel->Thaw(); } +void StatusPanel::on_update_error_message(wxCommandEvent &event) +{ + m_error_text->SetLabel(event.GetString()); + m_staticline->Show(); + m_panel_error_txt->Show(); +} + +void StatusPanel::update_error_message() +{ + if (obj->print_error <= 0) { + before_error_code = obj->print_error; + return; + } + + if (before_error_code != obj->print_error) { + if (!get_error_message_thread) { + get_error_message_thread = new boost::thread(Slic3r::create_thread([&] { + std::string message = show_error_message(obj->print_error); + wxCommandEvent event(EVT_UPDATE_ERROR_MESSAGE); + event.SetString(wxString(message)); + event.SetEventObject(this); + wxPostEvent(this, event); + })); + } + before_error_code = obj->print_error; + } +} + void StatusPanel::show_printing_status(bool ctrl_area, bool temp_area) { if (!ctrl_area) { @@ -2113,6 +2199,9 @@ void StatusPanel::set_default() m_ams_control->Hide(); m_ams_control->Reset(); clean_tasklist_info(); + m_staticline->Hide(); + m_panel_error_txt->Hide(); + error_info_reset(); } void StatusPanel::show_status(int status) diff --git a/src/slic3r/GUI/StatusPanel.hpp b/src/slic3r/GUI/StatusPanel.hpp index 91250610959..6ee29890a6f 100644 --- a/src/slic3r/GUI/StatusPanel.hpp +++ b/src/slic3r/GUI/StatusPanel.hpp @@ -26,8 +26,8 @@ #include "Widgets/ProgressBar.hpp" #include "Widgets/ImageSwitchButton.hpp" #include "Widgets/AMSControl.hpp" - - +#include "UpdateErrorMessage.hpp" +#include "Widgets/wxStaticText2.hpp" class StepIndicator; #define COMMAND_TIMEOUT_U0 15 @@ -119,6 +119,7 @@ class StatusBasePanel : public wxScrolledWindow Button * m_button_report; Button * m_button_pause_resume; Button * m_button_abort; + Button * m_button_clean; wxStaticText * m_text_tasklist_caption; @@ -165,6 +166,9 @@ class StatusBasePanel : public wxScrolledWindow wxBoxSizer * m_printing_sizer; wxBoxSizer * m_tasklist_sizer; wxBoxSizer * m_tasklist_caption_sizer; + wxPanel* m_panel_error_txt; + wxPanel* m_staticline; + wxStaticText2 * m_error_text; wxStaticText* m_staticText_calibration_caption; wxStaticText* m_staticText_calibration_caption_top; wxStaticText* m_calibration_text; @@ -214,7 +218,7 @@ class StatusBasePanel : public wxScrolledWindow wxBoxSizer *create_extruder_control(wxWindow *parent); void reset_temp_misc_control(); - + int before_error_code = 0; wxBoxSizer *create_ams_group(wxWindow *parent); void show_ams_group(bool show = true); @@ -240,7 +244,6 @@ class StatusPanel : public StatusBasePanel bool m_start_loading_thumbnail = false; bool m_load_sdcard_thumbnail = false; wxWebRequest web_request; - bool bed_temp_input = false; bool nozzle_temp_input = false; int speed_lvl = 1; // 0 - 3 @@ -250,9 +253,8 @@ class StatusPanel : public StatusBasePanel std::map img_list; // key: url, value: wxBitmap png Image std::vector