diff --git a/resources/images/filament_green.svg b/resources/images/filament_green.svg
new file mode 100644
index 000000000..1a417fbb9
--- /dev/null
+++ b/resources/images/filament_green.svg
@@ -0,0 +1,8 @@
+
diff --git a/src/imgui/imconfig.h b/src/imgui/imconfig.h
index 358912148..13f542bbe 100644
--- a/src/imgui/imconfig.h
+++ b/src/imgui/imconfig.h
@@ -215,5 +215,7 @@ namespace ImGui
const wchar_t ClipboardBtnIcon = 0x0848;
const wchar_t ClipboardBtnDarkIcon = 0x0849;
// void MyFunction(const char* name, const MyMatrix44& v);
+
+ const wchar_t FilamentGreen = 0x0850;
}
diff --git a/src/slic3r/GUI/BitmapCache.cpp b/src/slic3r/GUI/BitmapCache.cpp
index 8e5990c89..5582ece23 100644
--- a/src/slic3r/GUI/BitmapCache.cpp
+++ b/src/slic3r/GUI/BitmapCache.cpp
@@ -13,11 +13,12 @@
#include
#include
#endif /* __WXGTK2__ */
-
+#include
#define NANOSVG_IMPLEMENTATION
#include "nanosvg/nanosvg.h"
#define NANOSVGRAST_IMPLEMENTATION
#include "nanosvg/nanosvgrast.h"
+#include "3DScene.hpp"
namespace Slic3r { namespace GUI {
@@ -541,6 +542,65 @@ bool BitmapCache::parse_color4(const std::string& scolor, unsigned char* rgba_ou
}
return true;
}
+//BBS Replace svg green with the specified colour
+bool BitmapCache::load_from_svg_file_change_color(const std::string &filename, unsigned width, unsigned height, ImTextureID &texture_id, const char *hexColor)
+{
+ NSVGimage* image = nsvgParseFromFile(filename.c_str(), "px", 96.0f);
+ if (image == nullptr) {
+ return false;
+ }
+
+ unsigned int change_color = nsvg__parseColorHex(hexColor);
+ change_color |= (unsigned int) (1.0f * 255) << 24; // opacity
+ unsigned int green_color = 4282560000;
+ for (NSVGshape* shape = image->shapes; shape != nullptr; shape = shape->next) {
+ // find green color
+ if (shape->fill.color == green_color) {
+ shape->fill.color = change_color;
+ }
+ }
+
+ float scale = (float)width / image->width;
+
+ int n_pixels = width * height;
+
+ if (n_pixels <= 0) {
+ nsvgDelete(image);
+ return false;
+ }
+
+ NSVGrasterizer* rast = nsvgCreateRasterizer();
+ if (rast == nullptr) {
+ nsvgDelete(image);
+ return false;
+ }
+ std::vector data(n_pixels * 4, 0);
+ nsvgRasterize(rast, image, 0, 0, scale, data.data(), width, height, width * 4);
+
+ bool compress = false;
+ GLint last_texture;
+ unsigned m_image_texture{ 0 };
+ unsigned char* pixels = (unsigned char*)(&data[0]);
+
+ glsafe(::glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture));
+ glsafe(::glGenTextures(1, &m_image_texture));
+ glsafe(::glBindTexture(GL_TEXTURE_2D, m_image_texture));
+ glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
+ glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
+ glsafe(::glPixelStorei(GL_UNPACK_ROW_LENGTH, 0));
+ glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels));
+
+ // Store our identifier
+ texture_id = (ImTextureID)(intptr_t)m_image_texture;
+
+ // Restore state
+ glsafe(::glBindTexture(GL_TEXTURE_2D, last_texture));
+
+ nsvgDeleteRasterizer(rast);
+ nsvgDelete(image);
+
+ return true;
+}
} // namespace GUI
} // namespace Slic3r
diff --git a/src/slic3r/GUI/BitmapCache.hpp b/src/slic3r/GUI/BitmapCache.hpp
index bbfecd715..e321d3e56 100644
--- a/src/slic3r/GUI/BitmapCache.hpp
+++ b/src/slic3r/GUI/BitmapCache.hpp
@@ -8,6 +8,7 @@
#ifndef WX_PRECOMP
#include
#endif
+#include
struct NSVGimage;
@@ -52,6 +53,9 @@ public:
static bool parse_color(const std::string& scolor, unsigned char* rgb_out);
static bool parse_color4(const std::string& scolor, unsigned char* rgba_out);
+ static bool load_from_svg_file_change_color(const std::string &filename, unsigned width, unsigned height, ImTextureID &texture_id, const char *hexColor);
+
+
private:
std::map m_map;
double m_gs = 0.2; // value, used for image.ConvertToGreyscale(m_gs, m_gs, m_gs)
@@ -61,4 +65,4 @@ private:
} // GUI
} // Slic3r
-#endif /* SLIC3R_GUI_BITMAP_CACHE_HPP */
+#endif // SLIC3R_GUI_BITMAP_CACHE_HPP
diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp
index 389b7d7e2..6bcae6e08 100644
--- a/src/slic3r/GUI/GCodeViewer.cpp
+++ b/src/slic3r/GUI/GCodeViewer.cpp
@@ -1012,6 +1012,16 @@ void GCodeViewer::load(const GCodeProcessorResult& gcode_result, const Print& pr
m_gcode_result = &gcode_result;
m_only_gcode_in_preview = only_gcode;
+ std::vector filament_maps = print.get_filament_maps();
+ std::vector color_opt = print.config().option("filament_colour")->values;
+ std::vector type_opt = print.config().option("filament_type")->values;
+ for (int i = 0; i < filament_maps.size(); ++i) {
+ if (filament_maps[i] == 1) {
+ m_left_extruder_filament.emplace_back(type_opt[i], color_opt[i]);
+ } else {
+ m_right_extruder_filament.emplace_back(type_opt[i], color_opt[i]);
+ }
+ }
m_sequential_view.gcode_window.load_gcode(gcode_result.filename, gcode_result.lines_ends);
//BBS: add only gcode mode
@@ -4576,6 +4586,91 @@ void GCodeViewer::render_all_plates_stats(const std::vectorAddLine(lineStart, lineEnd, HyperColor);
+
+ if (ImGui::IsMouseClicked(ImGuiMouseButton_Left));
+ }
+ };
+
+ ////BBS Color Arrangement Recommendation
+ ImGui::Dummy({ window_padding, window_padding });
+ ImGui::Dummy({ window_padding, window_padding });
+ ImGui::SameLine();
+ imgui.title(_u8L("Color Arrangement Recommendation"));
+ //BBS AMS containers
+ ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(window_padding * 3, 0));
+ ImGui::BeginChild("#AMS", ImVec2(0, 230.0f), false, ImGuiWindowFlags_AlwaysUseWindowPadding);
+ {
+ // BBS save time;
+ imgui.text(_u8L("Since you set 1 AMS"));
+ ImGui::SameLine();
+ // BBS change button
+ link_text(_u8L("(change)"));
+ ImGui::SameLine();
+ imgui.text(_u8L(",this arrangement would be optimal."));
+ imgui.text(_u8L("It will save 738g filament and 23 minutes"));
+
+ float available_width = ImGui::GetContentRegionAvail().x;
+ float available_height = ImGui::GetContentRegionAvail().y;
+ float half_width = available_width * 0.5f;
+ float spacing = 12.0f * m_scale;
+ ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(0.00f, 0.00f, 0.00f, 0.3f));
+ ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(window_padding * 2, window_padding));
+ ImDrawList *child_begin_draw_list = ImGui::GetWindowDrawList();
+ ImVec2 cursor_pos = ImGui::GetCursorScreenPos();
+ child_begin_draw_list->AddRectFilled(cursor_pos, ImVec2(cursor_pos.x + half_width, cursor_pos.y + 24.0f * m_scale), IM_COL32(0, 0, 0, 64));
+ ImGui::BeginChild("#LeftAMS", ImVec2(half_width, available_height - 20 * m_scale), false, ImGuiWindowFlags_AlwaysUseWindowPadding);
+ {
+ imgui.bold_text(_u8L("Left"));
+ ImGui::Dummy({window_padding, window_padding});
+ int index = 1;
+ for (const auto &extruder_filament : m_left_extruder_filament) {
+ imgui.filament_group(extruder_filament.first, extruder_filament.second.c_str());
+ if (index % 4 != 0) { ImGui::SameLine(0, spacing); }
+ }
+ ImGui::EndChild();
+ }
+ ImGui::SameLine();
+ cursor_pos = ImGui::GetCursorScreenPos();
+ child_begin_draw_list->AddRectFilled(cursor_pos, ImVec2(cursor_pos.x + half_width, cursor_pos.y + 24.0f * m_scale), IM_COL32(0, 0, 0, 64));
+ ImGui::BeginChild("#RightAMS", ImVec2(half_width, available_height - 20 * m_scale), false, ImGuiWindowFlags_AlwaysUseWindowPadding);
+ {
+ imgui.bold_text(_u8L("Right"));
+ ImGui::Dummy({window_padding, window_padding});
+ int index = 1;
+ for (const auto &extruder_filament : m_right_extruder_filament) {
+ imgui.filament_group(extruder_filament.first, extruder_filament.second.c_str());
+ if (index % 4 != 0) { ImGui::SameLine(0, spacing); }
+ }
+ ImGui::EndChild();
+ }
+ ImGui::PopStyleColor(1);
+ ImGui::PopStyleVar(1);
+ link_text(_u8L("Customize Arrangement"));
+ ImGui::EndChild();
+ }
+ ImGui::PopStyleVar(1);
+}
+
void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canvas_height, int right_margin)
{
if (!m_legend_enabled)
@@ -4868,10 +4963,15 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv
return ret;
};
- //BBS display Color Scheme
+ //BBS Slicing Result title
ImGui::Dummy({ window_padding, window_padding });
ImGui::Dummy({ window_padding, window_padding });
ImGui::SameLine();
+ std::string title = _u8L("Slicing Result");
+ imgui.bold_text(title);
+ ImVec2 longest_text_size = imgui.calc_text_size(_u8L("Since you set 1 AMS (change) ,this arrangement would be optimal."));
+ ImVec2 title_text_size = imgui.calc_text_size(title);
+ ImGui::SameLine(0, longest_text_size.x - title_text_size.x);
std::wstring btn_name;
if (m_fold)
btn_name = ImGui::UnfoldButtonIcon + boost::nowide::widen(std::string(""));
@@ -4881,13 +4981,25 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.0f, 0.68f, 0.26f, 1.00f));
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.0f, 0.68f, 0.26f, 0.78f));
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 0.0f));
- //ImGui::PushItemWidth(
float button_width = ImGui::CalcTextSize(into_u8(btn_name).c_str()).x;
if (ImGui::Button(into_u8(btn_name).c_str(), ImVec2(button_width, 0))) {
m_fold = !m_fold;
}
ImGui::PopStyleColor(3);
ImGui::PopStyleVar(1);
+
+ if (m_fold) {
+ legend_height = ImGui::GetStyle().WindowPadding.y + ImGui::GetFrameHeight() + window_padding * 2.5;
+ imgui.end();
+ ImGui::PopStyleColor(6);
+ ImGui::PopStyleVar(2);
+ return;
+ }
+
+ render_legend_color_arr_recommen(window_padding);
+
+ //BBS display Color Scheme
+ ImGui::Dummy({ window_padding, window_padding });
ImGui::SameLine();
imgui.bold_text(_u8L("Color Scheme"));
push_combo_style();
@@ -4920,14 +5032,6 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv
ImGui::SameLine();
ImGui::Dummy({ window_padding, window_padding });
- if (m_fold) {
- legend_height = ImGui::GetStyle().WindowPadding.y + ImGui::GetFrameHeight() + window_padding * 2.5;
- imgui.end();
- ImGui::PopStyleColor(6);
- ImGui::PopStyleVar(2);
- return;
- }
-
// data used to properly align items in columns when showing time
std::vector offsets;
std::vector labels;
diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp
index ae0c1ca38..2887c4961 100644
--- a/src/slic3r/GUI/GCodeViewer.hpp
+++ b/src/slic3r/GUI/GCodeViewer.hpp
@@ -751,6 +751,11 @@ private:
bool m_only_gcode_in_preview {false};
std::vector m_ssid_to_moveid_map;
+ //BBS: extruder dispensing filament
+ //std::pair
+ std::vector> m_left_extruder_filament;
+ std::vector> m_right_extruder_filament;
+
std::vector m_buffers{ static_cast(EMoveType::Extrude) };
// bounding box of toolpaths
BoundingBoxf3 m_paths_bounding_box;
@@ -911,6 +916,7 @@ private:
//BBS: GUI refactor: add canvas size
void render_legend(float &legend_height, int canvas_width, int canvas_height, int right_margin);
+ void render_legend_color_arr_recommen(float window_padding);
void render_slider(int canvas_width, int canvas_height);
#if ENABLE_GCODE_VIEWER_STATISTICS
diff --git a/src/slic3r/GUI/ImGuiWrapper.cpp b/src/slic3r/GUI/ImGuiWrapper.cpp
index ec50a49fc..79a92cb16 100644
--- a/src/slic3r/GUI/ImGuiWrapper.cpp
+++ b/src/slic3r/GUI/ImGuiWrapper.cpp
@@ -133,6 +133,7 @@ static const std::map font_icons_large = {
{ImGui::PrevArrowBtnIcon, "notification_arrow_left" },
{ImGui::NextArrowBtnIcon, "notification_arrow_right" },
{ImGui::CompleteIcon, "notification_slicing_complete" },
+ {ImGui::FilamentGreen, "filament_green" }
};
static const std::map font_icons_extra_large = {
@@ -2840,6 +2841,39 @@ void ImGuiWrapper::clipboard_set(void* /* user_data */, const char* text)
}
}
+void ImGuiWrapper::filament_group(const std::string &filament_type, const char *hex_color)
+{
+ //ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0));
+ ImDrawList *draw_list = ImGui::GetWindowDrawList();
+ static ImTextureID transparent;
+ ImVec2 img_size = {30.0f, 45.0f};
+ ImVec2 text_size = ImGui::CalcTextSize(filament_type.c_str());
+ BitmapCache::load_from_svg_file_change_color(Slic3r::resources_dir() + "/images/filament_green.svg", img_size.x, img_size.y, transparent, hex_color);
+ ImGui::BeginGroup();
+ {
+ ImVec2 cursor_pos = ImGui::GetCursorScreenPos();
+ draw_list->AddImage(transparent, cursor_pos, {cursor_pos.x + img_size.x, cursor_pos.y + img_size.y}, {0, 0}, {1, 1}, ImGui::GetColorU32(ImVec4(1.f, 1.f, 1.f, 1.f)));
+ // image border test
+ // draw_list->AddRect(cursor_pos, {cursor_pos.x + img_size.x, cursor_pos.y + img_size.y}, IM_COL32(0, 0, 0, 255));
+ ImVec2 current_cursor = ImGui::GetCursorPos();
+ ImGui::SetCursorPos({current_cursor.x + (img_size.x - text_size.x) * 0.5f, current_cursor.y + 40});
+ this->text(filament_type);
+ ImGui::EndGroup();
+ }
+ //ImGui::PopStyleVar(1);
+}
+
+void ImGuiWrapper::sub_title(const std::string &label)
+{
+ ImDrawList *draw_list = ImGui::GetWindowDrawList();
+ text_colored(ImVec4(1.0f, 1.0f, 1.0f, 0.5f), label);
+ ImGui::SameLine();
+ ImVec2 cursor_pos = ImGui::GetCursorScreenPos();
+ float available_width = ImGui::GetContentRegionAvail().x;
+ draw_list->AddLine(ImVec2(cursor_pos.x, cursor_pos.y + 8.0f), ImVec2(cursor_pos.x + available_width, cursor_pos.y + 8.0f), IM_COL32(255, 255, 255, 100));
+ ImGui::NewLine();
+}
+
bool IMTexture::load_from_svg_file(const std::string& filename, unsigned width, unsigned height, ImTextureID& texture_id)
{
NSVGimage* image = nsvgParseFromFile(filename.c_str(), "px", 96.0f);
diff --git a/src/slic3r/GUI/ImGuiWrapper.hpp b/src/slic3r/GUI/ImGuiWrapper.hpp
index ca4259714..f5d89f8a7 100644
--- a/src/slic3r/GUI/ImGuiWrapper.hpp
+++ b/src/slic3r/GUI/ImGuiWrapper.hpp
@@ -153,6 +153,8 @@ public:
void text_wrapped(const wxString &label, float wrap_width);
void tooltip(const char *label, float wrap_width);
void tooltip(const wxString &label, float wrap_width);
+ void filament_group(const std::string &filament_type, const char *hex_color);
+ void sub_title(const std::string &label);
// Float sliders: Manually inserted values aren't clamped by ImGui.Using this wrapper function does (when clamp==true).
@@ -335,7 +337,6 @@ class IMTexture
public:
// load svg file to thumbnail data, specific width, height is thumbnailData width, height
static bool load_from_svg_file(const std::string& filename, unsigned width, unsigned height, ImTextureID &texture_id);
-
};