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 18f9af9a89..1bade7562c 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 b9de0a9678..56e90af952 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 0060ee4529..645a63aefe 100644 --- a/src/libslic3r/TriangleSelector.hpp +++ b/src/libslic3r/TriangleSelector.hpp @@ -28,7 +28,7 @@ public: 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 92331c8096..170673cd40 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 0464ceb09c..30f7e2a02b 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 ae4197154f..189db6236b 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 5e15961e56..19ad9c3599 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 @@ public: 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 @@ protected: 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 18a784b938..a00a5aa3f6 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 ba1a3e2415..25aaa5f80f 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 be6205bae9..340d867a90 100644 --- a/src/slic3r/GUI/Jobs/ArrangeJob.hpp +++ b/src/slic3r/GUI/Jobs/ArrangeJob.hpp @@ -59,7 +59,8 @@ public: 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 af3c773070..f73da522ab 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 56256f6090..f10699dd06 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 2c67fb7b6f..84fe7cba33 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 1bade7562c..35023163b5 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 4aeea2e0c6..af2b4e1347 100644 --- a/src/slic3r/GUI/GUI_App.hpp +++ b/src/slic3r/GUI/GUI_App.hpp @@ -280,6 +280,7 @@ public: // 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 2daa173458..b469230935 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 35023163b5..70c6eefcb0 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 c889785142..133163bb28 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 b469230935..cf19e139ed 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 e1776abcdc..69ac1f2840 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 c359eba440..bc7e41f683 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 52e3690b4f..063dd85399 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 9fdd1b3754..905d33295a 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 de94173dd2..75720dda09 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 7add748198..4c302392b2 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 fe16aac3c1..53af547451 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 7bcaa06759..b0a29125c4 100644 --- a/src/slic3r/GUI/PartPlate.hpp +++ b/src/slic3r/GUI/PartPlate.hpp @@ -520,6 +520,7 @@ public: 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 5e0e1d0b82..107be515da 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 1b591d16e2..82ba27a875 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 70c6eefcb0..719bf88fad 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 82ba27a875..8e65ddea00 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 3459004770..31cbc875c6 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 4391c8d968..788969b2bc 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 1d37e85ff7..50280ff747 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -767,7 +767,6 @@ public: 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 b5d142154a..da8fdc96fb 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 f88d514661..ce16875f19 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 e57c848dd5..c7300639d8 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 8e65ddea00..9d91c2c1ff 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 cf19e139ed..c689064643 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 05de4938ea..65a57cce41 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 31378b7139..6bd59c27e5 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 9ca12ccf68..ce142913f0 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 da8fdc96fb..d80fc478ec 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 9d91c2c1ff..6fd2a3fa02 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 719bf88fad..e65a6b239c 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 7f0625fc2d..110c37c5e7 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 9fa0727b82..52a1eeb522 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 43e822f980..82c90b171f 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 bf6a44d230..ba8fd6f99a 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 788969b2bc..050084b56b 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 50280ff747..21de36f8c5 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -765,6 +765,7 @@ public: 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 050084b56b..2a28b633cf 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 b3574035e5..8a5dd30afe 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 8a85322e9c..040bebc2fd 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 set_miniaturizable(void * window) @end +/* edit column for wxTableView */ + #include #include #include @@ -98,6 +102,7 @@ void set_miniaturizable(void * window) @end +/* remove focused border for wxTextCtrl */ @implementation NSTextField (FocusRing) @@ -107,3 +112,93 @@ void set_miniaturizable(void * window) } @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 7c387cc78e..dd3e6151ce 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 c689064643..a5afdd9dc2 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 0e06b6ed35..fcd8df8220 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 885abd7e5d..4252a99134 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 107be515da..c3c166fcaa 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 15367a2fbd..0993531575 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 5b7dbe2f49..b8653f5d67 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 0993531575..ed55b8ad04 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 c3c166fcaa..1d7f30743c 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 95d3f635b4..a8f0b812c4 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -122,7 +122,7 @@ public: 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 e508e3646d..df2f9510de 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 0abaa1cb63..4051026e98 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 3a313e16bd..9b47711498 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 9a444fdd01..55903a89b6 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 b3ae6e1132..138403fcb3 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 fce2413680..e30b75f792 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 46ff2a97ba..064d4e3d45 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 f83ab5c578..ff8885fd0c 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 zcmZwQ1#}eI!nW;72Mz8H36c;9!5sp@CAdp)m*6gqyAJN|gS)%S;4XsS!z z;5N*O2eBf)$AVaFvg2gOK9~YmVQf5%sqj2%pf52genJg6&L55wACscW1z>dgcS;h7 zOF~6d$MsPSw8W^`$=U&q1~L!R;v!6g2hbnyq6QLmhT}BCBp8m}Q4_m}Dt8+- z5bv4B_|`NtS${QQf2cz1_hni^_EQj?m zJub2N$1o@Ht5^kNxM!ORbx{p;z)IL3HR4mKEx2ZVfEvIn)JlCtm2=H8@pu?QJUJG| zIv9jgP~{Jxw)!M$E8W)#sN=^r;S**c9%ZiM1Y%}XygF({dZGq24RyK~qLz9YCdc)t z0iHk&?6UPf>WoC%d}kh~U(bJR0-MMvifi!=>U7SZZ=TcjsE$t~6`bd&4pJ>J9S7iO z;yF?2yD=pm$8`7rwFRz)X26+{cb$_3YHvKzg31|sxqV}W_Y5*NjTQdMP zqw&}WSK=T{ztjwD2@X(vnd5B6h1daWE;j=`h+T;1UBQ!qD{u&=Udj3oC$NBk4o9X{ zW~qWv9ack)xC83Y3`8y6c+{3mMVMZ6WNp{}SI4@J#z2ByFbs5jdw>pe_D`~#}I&!1)`(_&`g zIgn%G)N>Qi>HL9Ofpk0q8ks*9!h#qZyQ5|>*g6^YVp@cga0kZ1^6ShYu7%pVZkQd1 zqb9J`<{v{%)cuHnmhwN$jZxRL{8$i!aIWr|MQrgnMoN1$;^TF}hXY(snbWTbO|OQ`CsRp*oDS!wf95H8-kW z2r9pfwJB=A{ZSK`jatbCsCIXwPXAf-$4@(0e;tN2J57ZE)RG5b80NyH=tgb9bkx9> z+4v5OPy9Hl!|SN}cTijL5aZx;48jw06S)?2mdpm!bxG z9JNIkP+N8zHL$1H7C)m_rs;0eL0e2tyeH~VPQ?6p29seF_a5^(ofH)% zTOj0sS)wvnf%HbGimNafH)1CI8>?fqgJvu0;Su6(P)ncfkSSLN3lZ;tTHzHKU(f$0 z0-E_@9E&$lE70<=S=tEH=^cWqI2E<$3s8q{9qKG>#z5SU+M;Ku!x)9pgrW~>1;S8U zSp(zJztfz6Ds;snI3AnhDbx}MALRqei!*>_iT6HczC0elj>O|1=k<*PQ3D)!!o1K% zqXx7OwKY#s6ZvY5b&~bhOwth0NP|#Ykqebx+NRe;9kTkUJ&!=G*iiJxSr`ou*!<&| zj`(ex{sTjZd!I6|@)D@_BTljYsyKjzm^ciz#}hC;PRCNX6SZVNQRU;FHhY@{eTWC6 z8Z3x<-piq8TpLxdHELqLFa?f5m0Nn6_1DsGB0&wEMZIvYqtaiaD*Bu;hcOLmfO%03 z6-9Ma2eq_qQ0?@!4o6LF62`#UsDUm)4Q!K}fGQqB6})US?ph;J9sEQsVZ5_uAeAu} z@m5#@XQ40NMlJonm>1KWGh0>z1BkalO=uEUM)wi|#R$B^RG8~8GqTF4$EOi$V7)L7 z4z}@$sFj+9Iy)OM7H-1~cnCG)$EX!~ZS%j`c(n7LiMgEw1k`YP)Jo()9j+3lfKwMo z5^sx{@Ga`;NOr*-%6_OBO+cV6kLe$aG7S?;RIpN4*U)#**Nlgdpgo&{sc{*m#Y3pmd>>Pw*DbS@sZayUhib4gs-32&hP$FB(iio< z7-aKDVj|)*Q4{|27VEEy8*RZu=uP}2Y9?n<9o)9@*BG1lPi&8|Zu7duUa0g>sFm=( zV@!Y=P&!nH0oEYYnab%Vpd|{$afkgEVu}>;u%!OUr;L-^&THk zm>$dEb}WlOZM@9i=Io5e3Z%R56VQ?b-8au`aZE+LJSN4Ks253p)Shobt=MrJzmC4d zU!j&d?gR7VcoNjgEkJGUCRDv6sQ#`XE8=#Z5zvxFVjBE`dTvubG<%!_)p0p%IQkOr zifU*Iro|PgGjR;Hw0BX5I1<(ISJXg!9+`M*OseNU8v!*`3N`b(sDj-wC5}K1Xc20u zx1$Dh1he4{%#YFkF=wV2s>8~ty>E=F*V@`0rx72FiRs@-#)fMJf-ol*!Z7TBn#oR7 zLnl!)yt2FskD+s6$*4)o!h)tiLL>wiyu^op^6l zg+VrbIBG8^qE=)!2HYz8O<00t6@u>DDp*oz2ac~W4AUlz# z$nBgUpa$-s&cYLHf{~~WszjQlt$~_hOWceDP^UfTYx6jUp=Q+7+QmB9IvKSEi>y05 zvj2bCgvY2u^Dkya-#6w=gkccz&X^A8VP@QmD*xCT^R0;oS*u`Y^1EVOd}w`V^?FCT zp8xm+G?R4JLe^T=&KOGmSd52ft#_=itp8#y^5eWWTh|=5qHR$t+}XzaqE>b=y0xUk z38>+DsK;Y1YNjV`{2A)0i2A|IFbnDpSPAvYZieb;5XQlgsCK7W*IJL-{5z<#_2L8j zuS4^eghcoQV_^J`=JP%UCMKR6HG^`frL2xR-A!%06~-do1O0HY&0k{ESK>6%x1bJl zg->Qn>wIGUwYS4;!ba;|OhS6B&t_}

)*?)EALjr~!4t_}B+E@G&-h3Tlbxp$57L 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𝔛b4prO*MmOc~ee}Co_A)t{yK`s4z)QFQzHXow_s1<00+S@J|gcDJFx(6HJAsm5e z|M2qsJ)mV+gZOvUXGE1Lrk%#9cDkZl&*dZn1@R!N;CEERv8I|CBtV_!w5Yw#h4V2K z^`iP4D`Vzq=JUQ6RwsTG^_V4}Zqln^81V(z9A8f7`41#eb%uFS^u=)E^HGQ72Wl_9 zXPS|xL!FUaxE70|8hnAdu)r)+zCCIJBT-v09(5>Zqv|h3t@!#`JpT&pCP5t@w*}9k z&cJol%s<+A%-QDf_@mxz#Ze8nKy?&>>bM`~#KBk+{}_RC1a$b~E%$N`Vn!T*k5OCEVucw{PgFw# zP=|9ks^iJn3Rj|@hIlK@)}+81#EYZqO~oLbi#hS+N}m5p1iq7?JuJV9$A{A$j(X)b zUu_EZN4-$ip=R#2#*~kTT9FL63yY&x;5%xDQT{X&OOL9TAGKnoQ7csIPq%rVn~<&d)Yk5^@f#RG{0+MGX_b7BnOR!Y2(zJPR0p*ZO;CH+ z-o|^OIvRp{to}f4*+T0!n|}sZkbWEeaoAq-URi^hSl~XMf9-k5KJyEOs;Ck7M>RMF z3*jo9jgN3Wy7!v~vL7%5D~0;7sfyjP4QgU{Z2m)3yRT7?b+m)#ti?LW^RL5^h6Gh8 zifX7NY5)yTOV zrg9%KGaQTBlVg|#Bk?n)IBMbvj+sA_DT3-S>v8kg7DR92p{NOzMt#gyL|?3r+QNRQ ziH$(LxaMOCbZ@i;KA;-@5AS1~6Lu!3y-t17G!TR_iI+mHKxJ!V^d;UI^|3n{b(puH zR_=!NBW5F>;FM<|Zl@Rl9fsN%c-n(;|2 z!XCdweb);-XI8EpYQS}|I5x*nT#BBb{~r_3o9jL9!uWrg7shF9OgzhZ6CZ;uh(E(7 zSowlkx%H@(JAyjQ=P)xyVsT7%(G0jQYNB0Hp8-SB?MGk{0nPLnhKGVFIg3 z(4l#33x2`q#A9BwhX!?s(&9CuFwC*1hgaz@i^|n9602*X<##|;$GBKat?LMU!Y#ivF@0a^T(XTYoHF>aMTtp zLLJs!sPg+!kLOMF{QEy&ZAQ$yW)CxBNeVPZE%6f6mTW{lx5rSQjxp|;h7+K+AStTD z%%~SnC~BZJQD>k#>d?AT6P}KV+ypid(1?zp8h(hX@Dg_E@I|8;K75cP3e-rCgK$L3E)4R8_a%&bJ6 zkx;WF(+NQ~))y5~#z}7iyDuX5>Z9ye{go8;zRrLR5dpFrhyG&l6CG4^bn1fm-6vsF8k0t%&o= z>~(T1MKnKZYx-jw9F7`rBl zP1N;~=U?AY;(RoF;)hz1I;f?*jT!MFmcSUF%vM!IJ!WmOEdGI6@g}OhXrIkWq(nU( zfv5?DpzTH}tt*rYF0nH@R7D)EhRP;rCj0U5&qyp;I8je9Y5!K-yR0k(eGrEZC z;05NvZ>Y18{hOJ2b=20iLJqClnM6P@j_IfdmY@#Z9@OJ<3AJ?BQRSZEBK(NWaK?9j z8up?id`G;+zh=qn{4@jWfO@a=v`#^-%m(!Q?|=5$gd?`VMbzW?8g*#m{AXrd1a)ZI zq8jLq+S?(hLpQ_bFF@__YShZ@L!G4ys1>`8x$u$Vdj6B~45;A@*cXGbGOogK{DOLO z)%J2Ze%K$CKOc2gUZDFx5o$SR@ELQ8aOX(I?|00U8b zIU3c#6x4_}pdO<=sF|HZ{YK*f24H9um*>~;ZE-m9ZPp@DU7qLs5URrm))!cZ_=l)2 z^Y8zKMKc4aZVkuv6ljCrF?n>C=O?4YF3#lMS^ZEl?}g z8};~2L#^l<)S=ymdgC2N)qjXOJ1^V>G*TzF%k#Hd0#Qr71y%4E>bv1NR0FS2Gl~<( z<@pAa7JZ4AK+UK*-ou_a6l=#d?cGG3otLOBjvLRk?@mrYBlJa`(rlMuGd0y24sIyWTqtn0B z-ez<|bvzsO23%>~k80p5YJicbnSVtM%qNM-_eJFwKy777)Sg#Bb=bkCk4E(~2|a)Q zKi?MEY71OME#(bthcB@q)=6rf+byU8#7<^9N`oq&5w-XEQA=GMU0A`!E1~MuL4CHg zNyhW9y&Fb?W-=Xh%Kt=d$r+pe!lrvAH)p^P_4t%QeXVYQdIR=Ey(xF1zB%1P4J1Vh zm*-P71M1M$M15*@Ou_T72Bwmr0jx(gd=#~mH&IW=Kd2>rhdO*;Q3Ll%X-;_})M3kj zIwSc}Gp&Z&x@M?;`l2Q{4b{(9HvuihDXfN%u?`kUWg3`-YG4s+06S3wI)FMOXHiT4 z2-VJKR7Z(Yn^$u%>M5#?dSf<2wbKT5NZp+XXymg{&+A(2UepZFTJNDgOx~iFFkTuH z&y0D9m%$+HhZ^uoY>5X@?f9oPhpqr>rOO~6?{23d0gb3Bs$v_|-VZ_*T!0$bR@4BF zqGtXOeeoNn$5iQzA*iKoiaNACQ8T}UweSXN1+)9w=f4O6HCz?7w-J~Xd!kPBV$|ca z#(Dzv`22(F=sju+V)&VkQlXaI4+~&6)FEtzD%Tln;866@^M8$iR^S2Z@H|7!&^x_Z zft1*ucn;K3&P5G)9TveesFjMD!PHNOnn*#^Pr0F}EpCZTun#W7o9Nad7?jcF`I`)@ zQA_n4)xaCnEB6bQ$26H-p5KhLMm4wwyWoD*sm|$dtcF_RE~u>=h?>v@?19Trhcs0H z&;M}(`2x&0nV&d{c&W@LeipU2i2_}ozgCwIa}pndYjF!|Yno*-6L6!-??+AS0jhlL ztR_DM^;ix>O>|;bw^_PrBzA>P&S;tzaKF0WH;dRD-io4PHboQH<H?H;Is4MUxs8Q2Y1p$6tolf$e)HuUl0LjzT@a!!}$f8P_1iZ4esuoc7c zIBJPA{Z?GX4fb&ru9z*T% zbyR~NQKvn29#cL&wj>^cdVeg%g}4W`#Nl~eo*z=XU~%HdP)|?veA+6Wzf1&tNyvwq zQ5{rAgVBXEQP2Av)Mvsf)FIk}8pu&pN4HRq@oQ{_pKu_C=XZJjmru8G5%E3+%u1yy z$RXGBA3|U~4#Vb{r;y8OiZfA9!#B)^Lkqh+KSpoF62x6aT+U)FjScZBs($IB=2g7P zdKLAa@D6c#{@PA)tVH}Cx)&12R*aE(@g)y^?j&mYg#Dr>%mpDN4qKaGMh%b7#909z3M7aL)- z@@Aw5u@3Qg6j$FpTaQwgnE2SRy1enC+f|YDa>q5dDH;Iu{BOWJe1X z$Xdze`E!5~Sep1DEQv8Ho5v*#wd4oT7rm>vJbwh65la!DfSUOw)WD-xb$R|;Pb>UD zd?R+p<<(rC-v_3uZr+sb-2@`Z7>jSQZw(jUD)_Ee)8+Z!Zgs51;Uk`)w)rZSu8zy| zZ@Z7drj-AT8bH0eF6Sc7#}LYQsps>Ul1R8ennMfU2S1;Z0Cyr!CgNBdC=~-pstx z)1zL|*)culN4+QNqb3l6nf3e+BcPG5MLkZZQ8Rsx8mV`4(_s>8TGT)S&>QoiR;Uo_ z%~=e!RjpAg+7UIdKBxf<#Sol40jmn{@zc z;3H8pU2fA)qRL-Ft?W(I0N$dWvZyWX_y3A5%?gC09~u2nOF9p=#BWhs6xPZ#)EKpd zJyGf7tP4McUe@F*6<8>p2_)YfceYSe&((HBGA1Tqt7hAKD~^*`3+>JVXcTs!y2DRkTJDS6m2K5R}k9r@}!KPRr8{-}vjHx4Bp1-g>9|MW!?_~DA zDOS+)zk+~H`#Wrpu{xW*>xDYigHey)2-K;bVV#G1Pb@)AU@z(^I*aP)g-uV=#k>zP zp;od4>Zz!Jp1=QBn}AMl1Zt_qV{V*|es~JC6)!O(zDISKysN2~8TG;`i+WSGKws>G z8sKcy7n?1pH{*HKTp$0g}#z$Jm+4RY%$8IL- zY%I3v*H9C>i>vV+YJl^4@cdUNu(pSpsngSRkQBX0PlMXibf{Bb6t%?NurQ9ol6VBm zV~k#A0@YDxrZ#G?TcftN8)_o`QHOhQFP?urk5fp{sb7wYpF}+-w=p|DN9}#e-e#|h zq4u;PYJj~_D>L2Z&qE!yU8of~ggRqqP%HWZwbGGp0-Dh~)JUWEF*8rW^gk)iyByZhM8y&4YJ3ENpD4g5t~ zZ7TI7UEc+s5I=%zDU*Qo0K&Jpe_gpr%S>KbJWb*gZk_Z%+FD3@Q#+u(q>ZBA;@&*} z?Z{kVJHJVxATk@0xq(K0UC}60nabJ7Z}uw@pV>0r)K@Sj|7k>cG~qPJ%g{MN-B0+A zyp*(ikg%@ur0f0Txr+1O!zA#H*mIS)tD;DADhATnc=8k4^sI!taX+B^OUf)Doj(L~ z-V*9lQ0nKUOiaQR@i>+uj}J-DRhYK< zb1D9<0rvl-O)O#ZoL$8A1Aw%Wwv}6joh$h4{(kr5i za!a@y+j@5hucTaD;={-fpxt54TLqoQ&K_8T4lI*AR|QnLXSIxu?Ee=j86sy_z(B)^z4$UJ5p&LJh*}F%wRpo)_xMLt1(UkPo*} zCm!L6V3Zj8pwttplxYbkjZ zsH3YdWou|wzg-y^l&<8Y|Bd?C)-|0vd^>VG7j0(;C@_!)29voEH&byGc_j%q;MSFh zO82?b63LIT#!=`h z1qRuQ6PST7`B`j*-lVtU-p8Gk^km%0xmQuIj;)iKw)CY#S0h_*w6z&!N0Wbp@`KUs z&wpN-vd#@MJJ=<&NltnyMkD>ZO_)k~T~&T7*O-ng*z~OA<)iUS++#c?`Qscru=%7N zpxis|F{D-3^M91cIwI+C4vlUjT$m1Z-R90nn7=Rb|GNqj&rA8gDEo+e9`RB%uInE0 zuY~JUuM}l;l_V`IH-D4IX~`WxUKGkq(*9SXP*hv+1ch{+$Epmb6NQtKcZ9;}2k{Sea_j0$nfE66fBzlw+hFFCe~+AKb_Ko>UQXIwTRM^X8P>$AQSmtq zZ?~C=ZKX`id?|z2MBX9NCfEV>CY+hZN|C;rx_gPIv8$zT)X|9#b(v*(+L>Snv6psxl9q&< z-`cYNT>p`{gaZ7|&~p_bT;2qob5yR&eVn@uogAm(e&p?-Oc%;$vE_0S-bUI;oJP4b zl=CKBlyEiDQ&C^n2-0*FBz{%6(Maqb@{u>&HzkAdR)>o6V}zuZ37Q~Yp4%}buFiGJ;I$RGl)?) zBEAo6nQUh|c~R-$9%){Lhf^*+@x!#0jd%mfr66q~P9m*7d8 z`U@1!L&0Krl(dg_sg@Gg^%Z9^h+kJ#oBk_)gu0n%SXXb#^~d74h;o&Yzp>>M{H=Zw z_3uT6`eaO{vuZRjlv~#%(sT{86{_ND8Y)M61hyouUnOSns}to@Qf9($A8OEbTN5D=^!-?#2`;sW9}@Z|4Y0sb@p)UN{AouGkHy^bB%WDa3^O%^|;6C`R_%7 z+CN9(eK-Q&p|1E8DoCT#3HPRfBE*Af?7r>b8kQkmgEH&vVB*->52MlOL3Gy^;K-lzU8ibMCH`n?`zP?mx&&YiC=Q zGH??zT4tL*ks0uJN}WnH`2V`5(cuj01<>dnTc;;sKik%? zI!~$Jk~Hf_<*v-FD*@@=+!wfuGJsJu za*B$5i4Vl1+#BtTcaRs`&MH6kJ99tfu1Pz~C^MM6qQvtP-a^_P+Q_Tte-#yV^{259 zgzsZH+t5SOQy<~J3{$?$&Y2*Q2qnrQ?Wn!f6z_` z?5H+9M;`KWH?|e@``mmK&^6jNT!y?C#3z#8lJFEyWls@jmo2-AvNH&$A^!`5_=D_J zrigQhy!eF6kY9$nRc!s@djBV+@SkM1qGCF3UFlVTN?B~dUZmfp>~&`Hk+irt#8cAz zrzH7Z2#zCN*FfA#{XE>dDp2RA2|5{QXF2f@>XfcUq$Y)zV|~2OJ)HXsg~Ld@O;}e5 z6*h7&V6bjG$b$GUY5k^L=#|L5iBJQZ^N~_*sr{9je%ONa{0!wF>A$Wgq_3v+)THkv z@iBR?Nb6#I97B2uJN&4${gL!q+<~NhBJO3|>VW||NiA*5DJZmx0=mvpxH|>X(6FwO z*w%JXnD9r^#*u%R@I}&N+j^-O@F~(8Q2!}qnsWP)|HuxAs56)Re#Gmc=OhJFsV>2X zBwWD!o(yI3dZUA5+;{1q8R-#rrA#hA666kx57(F{NHN;9n7XoZ!$WO|Aq#t5+1_9N|CpY+acV7GGW{U$&W(X zeUfk4w#QgWa_ZP{Pug;~qTmJY+1%M}MiDZ~sieIY;B@j^(r`!0{3L$`9gas`>j~G# zx7@y@%_si*70xO}p>7-67(w{8?dL-j_TS4kl8pl1w&F?(Y$UxZ_X5ION&kazc^de2 z?X+b#Q*S(pGs)XRc(*N(mU=0%_y_Wo$wl9CeXGqJXZxTHi(R&hpUBw7wrSS)( z^`yZ+QGe9Ah{k?hGYIsh%qH$xG&+SgbiJTVIF{soMfzRhQOKJ`J9S74IM z(?6Z%G$3<}9obIXNo;E^(v{VOa^tD^m`G*@v>DIiZqjwtA#Xcr6$uZa?o2G846fRw z59O{*Ke{5wciDRGr$pKiDNSZ`8rh2_@G@!7sPyZaN4O1lpso1ATEaH^AA?D3!#$`J z%Z7*j*2XsaYGE79hmE4K|GBByokGn~S2|m9KONMyX_-i$K{y!=#Ak5rxvNkoA7$f^ zR)#woX}VfaZx_b1b(OY(us`LiQ|2N0gD7t<_FvZv3e2RjB@`%vZ;1bA3w`^oA(f3q zx(|&__`gQ@B2S&)ueL-o{FbnVvPbCnt8Hs8{VXQ!tDb*d*=eAW33~pjLM`I^sIZWN z!Bo0VJUfn}Oo**hh5R|HLz&9l-$)OmTyh5Y(3Vm5Gs?xn=iHUKr%yzLjt<8oTZ(#aGMt%~)eJPWVI~n!=BEE%t1$nLX{I@2M)^;F9Q*a#VgGoP21%K|c zqy^hDO=vhC@q-NR6yfcZ{hM1?2xXIS>s&SQr0_{+C$yIIWTYja>`3nPwC|b!P%;vc zP{~&KMMu(gHNhB|kA`wl>2Km)QP)}Oo#GB9FD8R(#;q$pWd>-V+$#we!jF{Gm4vV^ zfBu(@&Sw%!bLS?ZG>BlJ__BiBWhzaPS8+68qjr!3QMWn2FsF`6Lq~(I#$FW z>W#PQIVk&-Th}(*#(eVT5>Ln7i*O~%CsJQp|4bzO$pF@12^_$PBdEBZykFN(@_xU< z>7WB;+mhbQb{3m@t?dM2+FAdqlf$MfzLT~?a3OU)`+to{b{fe_#$wx8bL(tuNP0cW z_z-UYKLdG7e3@-L;I~c+Pnd(L%0@Ub;X>S(ZNuxSv%t>&)^Dq@mGmI$x1%3jqi}~ll=o2R zx@|Zkh5jMl&lc)uI|?H026;!R_yB)hk(9gmD}t|xKcVb+zFQ~O7w!t&R~XrM+kr2I zu2JAB1>ci)8jI85CEG{>;=00Y$2Tam&!$bqZq%J@iZ~Mq>uOJ#%eKsL>W#5=J$qZ7 z#xGJ}FM~Kv;l9K}iI=k#9@<9KP#?8RDQ;iH=J;_YX9YJ_16_es6;;U?f`&F1L1M&N$>zYjX3H5i= z`55Z7!p-EJB&_Q@b*^$>q|9vY@7#sF?DwA*6fQ)ePPSoB4gS-V1}@M*Zrky{q}3)| z!fSKz1n=0J3(szpG>UK24jnd6+3++VR@2rUTSj#EZQ8YE)6KoF_glFAM{h4zsyH1w lwCv{F;qbO@&D*q$*#2XR*Na?n%5?p$@b<^Yyl!p${{WZLh5i5l 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 zH|gvGx2|cn@Oi>Laet2Osp^4e1G8{uHeq}GQle~rW$!~N^^ zg@$)fSl2$nlgS@MgEz*JdNiKRRz6N=IVf|LS_QBhWun^-)X-PT9rmck*k0n?CwN6)`5k^jA-+RDS}>@oRGY+U8C+psrzYw0`@cX`S@ z;f`YmSDP~5xx3ni3;i<47NnJ=+z^})alK!{GA9^bASJ3Yw5!z0Ylo}K>$#&*`WR{V zxepN!!wr<{$UTEPx)Ma>?4Q#0VhlyNw~`ZiWgt+H7DkaCd7UFLi?}zv>i27-$)7+x zC#IoAKho>bOEc2y+O{HWPt8e>yz&ybO#TqccZ=pwn`>Icd4_U{8Qp( zi+0lEMM}*etg9$x^iAPU;`~E2C$nk9@x|)oXQlpO^2geAPbL1iPui~+f7S5+FaEls z>y)BmSv%GQWL6_ylUr9G(vxwwq{F(ljM5JhUrNL8ZDZ4Ir^~1}jP!YwDS@k1m@6Ck zNo|{pY}qrOx@@djWc1-)&OMxlBd;37_fV(_H-FpD$!2HLmULY;NsCKky@<~tK9KyP zxPf$C`tAH^Tc?#xyMpVupON>3dZS(bSi#+hhBn#4cNoMg?o4*ZH>?M!)S5DdZMhlL zIZ9n08hp;(p0KU}>TaM;R~*mXn)Dmw7bhH>@G0Bg5W)q^@<&vgum~s9Xh+g=+BE$d zwikB;(u$DQfQAOqP-sNjfeGEG428cO>ika10BY*`LYTig>-3MqXhgCb1PG)9R2GMx|m@`oO)CyB2pYZe8v1Uk2h&_#;MMKGaDN z8Ns|ZFD9m?kI&TGg=6(Q=nw*p7`?8S++`{BpRKTqcnu1_bMljN5W2wLBV8pX{yKf%;=f*L8yQw&YhPoQbru9jFwGKqK4XH8Lxbd5-ua z^0G#z6HY>dJuyAy7ZILJ*$2djM~w&@noy7O2Dh$K)GA5t5=vH~#1FzvaVmF1h8%`b z@HXjpD4(2i{kW6Z-qgln!f!~cK-n(n!#$t!y0(z^n|%(QiMJr^*-DkEw4BUko?`q+ zNxTIW-;kD%viJVvS6|9cv*BIjZ6;4wM#^5* zR$f4X>Ley2;UpPd>8KsyeWdFePvyPp)K*MK+P{Pg*m!!%H>A8TH~;UsrvEay7`F4$ zlpjNZShmn#o-)jT9|=QjVl!(u3SXtb9NWnr!YR4$Fp$AEZH?`$CFw=EuTXcV?W`Di zT`7BtvQ0>jO@2S(j|r#ZZo{BYkhfXuKaz}vBt%}Z2q&XLRPIT(vsE-);+Hbni6qdef|#9l{^Zv6gS1j~bdg)vNbZf~mA3hp$=Bt+p`xw?6g+OjjfpR@9V@Rc_iQTW z#QwHSJlpUkTtxa}?&0KhCtiesUZea&+L&VpUBZ@cOS~8ND>DF|Kb3BAFQvjy5_@xR z;qLOw0BGBpP1-Ta2WLf-<0cum8m<&<_)9VHp1C) zH~HsjZ#MZ+D5opEeTzARY{D@Tt5V<$1-oNZ(wmZY);8FjhKAU%8u-k;lK4cNNe7YF zYQi0;dz^NH30I=bV!|D5fw81D@w8)i(R4CLa2dG0#40cB($V+GbDEv80K z_@-^N7i9|&Pslx%aBdtyC-c-X@lMq7B3yxVT?=hJg}akCioDg7Z=eJ&_ZELdrBHI5 zO6DsXX-;?&cS$NF)lK>c2DO250k*-1l+*PWjlIV#l=+Xct+;qyfzlRJp|l_=kk zw1V6Tsh5xVO40|}@+#Yo_WvU-fvp>pa*_K_AtxW1Zz-fJ@^I&-AzeSn+mE+x<#5Wi zr16KOC&wP1QuYt>LTNk`b>EP$>oxH#q$i`k7iq6ZD?t7Xy^;cm{K8?w$mZx2Xbd1E%N%4GLct50`4IS z=b+GKTd8(rE>5N56)Jop@04vM2OZBLej0VHAiW#m%-nmpyA$8dU;?nXEwh&RLfUyn zJe<18=&vmC3i|g!@{-V-hJKRi!+nR0l&TnOdWrU4mA8Fw<5e}vrr#%R@}GWqtXIm2 jyEm(C8neD`(5AOnPi)>sQrXNAZ?6{KR%@%*u_^xtewK#B 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 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 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 905d33295a..17dec6b192 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 +- .../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 | 11 ++++++----- 10 files changed, 19 insertions(+), 11 deletions(-) diff --git a/resources/profiles/BBL.json b/resources/profiles/BBL.json index f73da522ab..736e4c08fa 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 99f8c87651..34c84203cb 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 887e63a44d..aaaa07bfff 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 5db555c625..b82ede4af8 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 7252de98fc..b192c1f23e 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 a545ce7077..12540a4416 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 ada196c74e..37d4f86cc1 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 f8d7c5f77a..859eeae86b 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 a4ba79b662..f11989634c 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 17dec6b192..efda105b61 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("TPU"); - def->enum_values.push_back("PA"); - def->enum_values.push_back("PET-CF"); - def->enum_values.push_back("PC"); 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("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 0be5afc22f..5994566be1 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 | 143 ++++++++++++++++++------------ 4 files changed, 147 insertions(+), 57 deletions(-) diff --git a/resources/web/homepage/index.html b/resources/web/homepage/index.html index 2d0a467950..b2f6a246e3 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 d77a36c00c..e1bcdd8e8b 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 e65a6b239c..96dbbabf0f 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 a5afdd9dc2..4d5181158d 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); + //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_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 110c37c5e7..7218dcb0ec 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 65a57cce41..ab66b63d96 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 6bd59c27e5..c0fadad0f7 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 dd3e6151ce..c0c25f5108 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 ed55b8ad04..162d9fd752 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 91c47da20c..145535eb0c 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 3a2ec4531e..5b739dd3db 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 f90b07ca47..9a63a5cfe8 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 736e4c08fa..7d9eb5a7e8 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 9bb4ae56eb..d450ad4320 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 f49165d168..b6001992d9 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 576fe15b05..6bc8c20259 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 f416abbe76..cf52396cf4 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 96b5f1672b..40e3785d07 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 388268d37a..a3b8a8f889 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 b82ede4af8..ea7a12b487 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 12540a4416..ce65957dd9 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 6fd2a3fa02..638c7f18d7 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 170673cd40..421ef618fb 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 30f7e2a02b..be7a28e2fd 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 7f33b1dece..1ef16b53bf 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 5b7bbfd845..11c0ff0757 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp @@ -159,6 +159,8 @@ public: 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 96dbbabf0f..4a49333556 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 69f2a35836..78fe307fbd 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 52a1eeb522..e68806040c 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 82c90b171f..473e02c3d6 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 040bebc2fd..b5572a4e03 100644 --- a/src/slic3r/Utils/MacDarkMode.mm +++ b/src/slic3r/Utils/MacDarkMode.mm @@ -162,7 +162,7 @@ wxEvtHandler * _gestureHandler = nullptr; { 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 efda105b61..6033d3fd08 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 5b739dd3db..184e328a44 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 2eac9f1bf8..b71390b833 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 eab7aaa77e..9b00eaedca 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 2a28b633cf..8b38dabbec 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 b5572a4e03..de6808328c 100644 --- a/src/slic3r/Utils/MacDarkMode.mm +++ b/src/slic3r/Utils/MacDarkMode.mm @@ -160,9 +160,10 @@ wxEvtHandler * _gestureHandler = nullptr; - (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 95f9b87f2c..be32d06155 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 0a21b74f02..b7abb2412b 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 9e15c77e31..a0cdc6338a 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 4252a99134..3d85ae1847 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 473e02c3d6..a54fe984dd 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 de6808328c..7e70422160 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 74b2d74ae7..fa99b15f78 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 8774d8ce8b..8dc72d15a3 100644 --- a/src/slic3r/GUI/AboutDialog.hpp +++ b/src/slic3r/GUI/AboutDialog.hpp @@ -17,7 +17,7 @@ public: 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 2a31af74b5..fb49f4a989 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 d4b93c0384..fd61637e44 100644 --- a/src/slic3r/GUI/Auxiliary.hpp +++ b/src/slic3r/GUI/Auxiliary.hpp @@ -81,9 +81,9 @@ public: 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 954b149235..42dfcda629 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 b2adc7a0aa..6be9117791 100644 --- a/src/slic3r/GUI/CameraPopup.hpp +++ b/src/slic3r/GUI/CameraPopup.hpp @@ -59,10 +59,10 @@ public: 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 69ac1f2840..56d4cc7f82 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 a026b50f06..37a3e9fc23 100644 --- a/src/slic3r/GUI/SelectMachine.hpp +++ b/src/slic3r/GUI/SelectMachine.hpp @@ -114,20 +114,19 @@ private: 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 78fe307fbd..8b4f5e74eb 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 046d9c8fcf..9125061095 100644 --- a/src/slic3r/GUI/StatusPanel.hpp +++ b/src/slic3r/GUI/StatusPanel.hpp @@ -70,13 +70,13 @@ protected: 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 effb679da2..3243a2f1d7 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 ca82a67b40..e64722d637 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 @@ public: 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 fb02ceaac6..cce19da250 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 6adafb5404..b57fb907ab 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 @@ private: 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 bc7e41f683..e9879aa336 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 063dd85399..bc3d638110 100644 --- a/src/slic3r/GUI/Widgets/AMSControl.hpp +++ b/src/slic3r/GUI/Widgets/AMSControl.hpp @@ -160,9 +160,9 @@ protected: 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 @@ public: 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 @@ public: 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 @@ public: 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 6e96c49177..58fbe736f7 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 a0ddb1adcd..739861bf0d 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 @@ public: 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 618046b47d..2b9e03173a 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 01abb2c508..e28f13e138 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 @@ private: 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 9bd6d40cf3..f614b4e32f 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 a4c608878b..09c086f1ca 100644 --- a/src/slic3r/GUI/Widgets/SideTools.hpp +++ b/src/slic3r/GUI/Widgets/SideTools.hpp @@ -33,20 +33,19 @@ private: 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 22258af38f..9770ef5b7e 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 0bf27609ef..91c7efc089 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 4a49333556..666e6ce467 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 af2b4e1347..cba3d947fa 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 4d5181158d..0700811527 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 1d7f30743c..d957a3f883 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 e68806040c..5cb556bbdd 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 5cb556bbdd..4d96d849e3 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 2986a8eaa8..aded55bfbe 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 @@ public: 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 a54fe984dd..1b962a2781 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 e38de481d1..92f5e8827c 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 8b38dabbec..a5b6866ab7 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 374894a50d..d9db9e0f31 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 5c24160f9a..96a98e5ab5 100644 --- a/src/slic3r/GUI/Selection.hpp +++ b/src/slic3r/GUI/Selection.hpp @@ -226,6 +226,7 @@ private: // BBS EMode m_volume_selection_mode{ Instance }; + bool m_volume_selection_locked { false }; public: Selection(); @@ -343,7 +344,10 @@ public: 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 7e70422160..1730d4a885 100644 --- a/src/slic3r/Utils/MacDarkMode.mm +++ b/src/slic3r/Utils/MacDarkMode.mm @@ -37,6 +37,11 @@ double mac_max_scaling_factor() 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 ab66b63d96..4b83a48b3e 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 6d9f0b4c45..f53dd98b86 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 f0062e3cf6..d17daf639a 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 9a63a5cfe8..f764c74b53 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 a00a5aa3f6..c34551534e 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 21de36f8c5..d11f0508bf 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -909,6 +909,10 @@ public: 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 @@ private: 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 f764c74b53..8e240b04e2 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 b0a29125c4..8dbff320a9 100644 --- a/src/slic3r/GUI/PartPlate.hpp +++ b/src/slic3r/GUI/PartPlate.hpp @@ -114,7 +114,6 @@ private: 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 @@ public: /*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 d957a3f883..834a1a2662 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 bdbdc82da4..d4d4e28c59 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 ec35bcb548..a15cd9ae14 100644 --- a/src/slic3r/GUI/Widgets/ComboBox.hpp +++ b/src/slic3r/GUI/Widgets/ComboBox.hpp @@ -73,11 +73,16 @@ protected: 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 a0cdc6338a..b0b609e46a 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 bfc84553ee..8b3fe8bb29 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 666e6ce467..c484bd9320 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 8e12dfc1bb..683785a4e3 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 8e949efbc5..4db6772849 100644 --- a/src/slic3r/Utils/PresetUpdater.hpp +++ b/src/slic3r/Utils/PresetUpdater.hpp @@ -26,7 +26,7 @@ public: ~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 1730d4a885..d09247cd4c 100644 --- a/src/slic3r/Utils/MacDarkMode.mm +++ b/src/slic3r/Utils/MacDarkMode.mm @@ -16,6 +16,8 @@ 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 cf426cb6f7..224454f383 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 1bcca1b004..4457cf6e9c 100644 --- a/src/slic3r/GUI/Preferences.hpp +++ b/src/slic3r/GUI/Preferences.hpp @@ -60,6 +60,7 @@ private: 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 fd148cb6b7..3f5822c7ee 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 2449c08b7b..1b2089f898 100644 --- a/src/slic3r/GUI/SavePresetDialog.hpp +++ b/src/slic3r/GUI/SavePresetDialog.hpp @@ -111,9 +111,9 @@ protected: 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 c62377b39a..a54810e7c1 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 b7abb2412b..54b10c4b1d 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 1696785689..3b3233e5a3 100644 --- a/src/slic3r/GUI/Widgets/Button.hpp +++ b/src/slic3r/GUI/Widgets/Button.hpp @@ -47,6 +47,11 @@ public: void Rescale(); +protected: +#ifdef __WIN32__ + WXLRESULT MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) override; +#endif + private: void paintEvent(wxPaintEvent& evt); @@ -57,6 +62,7 @@ private: // 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 d4d4e28c59..e6fd9c2bee 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 | 88 ++++++++++++++++------- src/slic3r/GUI/Widgets/AMSControl.hpp | 21 ++++-- 12 files changed, 209 insertions(+), 52 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 e12c80ad31..99ea1107a4 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 36dda61d7b..653d0edc1e 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 0000000000..653d0edc1e --- /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 0000000000..001274d208 --- /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 0000000000..12076b79bf --- /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 0000000000..fb7eedd02f --- /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 0000000000..cf4e1baeb4 --- /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 0000000000..8cf963c6e2 --- /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 0000000000..422fc623a5 --- /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 0000000000..16a872c890 --- /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 e9879aa336..27cee631fa 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_bitmap_normal = ScalableBitmap(this, "ams_refresh_normal", 30); + m_bitmap_selected = ScalableBitmap(this, "ams_refresh_selected", 30); - /* 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_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 bc3d638110..506b72eb77 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 @@ public: /************************************************* 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 @@ public: 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 224454f383..1f22c4e913 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 ca177e6c56..f74545e982 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 b91e90da74..9509b2c704 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 2160ff6276..34a97cf9c6 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 3a5b7e7f6d..ed27749138 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 @@ public: // 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 834a1a2662..f7b7508b3b 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 54b10c4b1d..7972d51e6c 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 4d96d849e3..f970a6a964 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 b513eeae2c..a3419b08d3 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 2b7643a0d7..0855e64db4 100644 --- a/src/slic3r/GUI/Widgets/StateColor.hpp +++ b/src/slic3r/GUI/Widgets/StateColor.hpp @@ -58,6 +58,8 @@ public: 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 @@ private: 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 1b962a2781..605e2e12bb 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 0000000000..ad3f4c1013 --- /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 601a44277c..cf58fbc94c 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 0000000000..df78824780 --- /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 4ecbf27056..83a78da28a 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 0000000000..379f61b650 --- /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 aec46c3376..9287820991 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 69d0e0e7d7..6d6451a71e 100644 --- a/src/slic3r/GUI/Widgets/CheckBox.hpp +++ b/src/slic3r/GUI/Widgets/CheckBox.hpp @@ -17,6 +17,9 @@ public: void Rescale(); +protected: + virtual State GetNormalState() const wxOVERRIDE; + private: void update(); @@ -27,6 +30,9 @@ private: 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 f970a6a964..0e534465ae 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 69892ebcbd..16f89ec9ce 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 | 65 +++++++++++++++++++++++------ 7 files changed, 71 insertions(+), 16 deletions(-) diff --git a/resources/web/guide/21/21.js b/resources/web/guide/21/21.js index 6dd7218e25..5a37c4c32e 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 ccfdd6164b..43dffda130 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 ca27c8eaa0..b60480520e 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 c7e2cc0b62..4f0a2ae795 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 e287a76cbd..c03c76f4e5 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 ee5ce10577..b651323df5 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 4b83a48b3e..1095a7b50a 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(); - 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"); - bbl_bundle_rsrc = false; - if (!boost::filesystem::exists(bbl_bundle_path)) { - bbl_bundle_path = (rsrc_vendor_dir / PresetBundle::BBL_BUNDLE).replace_extension(".json"); - bbl_bundle_rsrc = true; - } - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", will load config from %1%.")% bbl_bundle_path; + //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()); + 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; + bbl_bundle_rsrc = false; + if (!boost::filesystem::exists((vendor_dir / PresetBundle::BBL_BUNDLE).replace_extension(".json"))) { + bbl_bundle_path = rsrc_vendor_dir; + bbl_bundle_rsrc = true; + } + + // 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 c03c76f4e5..2da4e566eb 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 1095a7b50a..0f9f55a8f1 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 c7f64c5a2c..8eac50bd54 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 a324b364df..69f46cdeaf 100644 --- a/src/libslic3r/AppConfig.hpp +++ b/src/libslic3r/AppConfig.hpp @@ -39,6 +39,9 @@ public: 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 358557ccb6..d9db4d6a77 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 31cbc875c6..a635749666 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 8e9dcb0c59..7c2472d7b9 100644 --- a/src/slic3r/GUI/DeviceManager.hpp +++ b/src/slic3r/GUI/DeviceManager.hpp @@ -426,6 +426,7 @@ public: 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 8b4f5e74eb..ef9513dc96 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 9125061095..6ee29890a6 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 @@ protected: 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 @@ protected: 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 @@ public: 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 @@ protected: 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 @@ protected: std::map img_list; // key: url, value: wxBitmap png Image std::vector