From ba445bf6303e2a458ae42cb60f936c03c2fd8644 Mon Sep 17 00:00:00 2001 From: "hu.wang" Date: Fri, 29 Dec 2023 11:00:24 +0800 Subject: [PATCH] NEW:Adaptation of semi transparent materials JIRA: XXXX Change-Id: Ie32d8ce67c37b85eb6d7d6594cb514a696307e68 --- resources/images/transparent_ams_lib.svg | 2 +- resources/images/transparent_color_picker.svg | 2 +- src/slic3r/GUI/AMSMaterialsSetting.cpp | 22 +++++- src/slic3r/GUI/AMSMaterialsSetting.hpp | 2 + src/slic3r/GUI/BitmapCache.cpp | 72 +++++++++++++++++++ src/slic3r/GUI/BitmapCache.hpp | 2 + src/slic3r/GUI/StatusPanel.cpp | 1 + src/slic3r/GUI/Widgets/AMSControl.cpp | 31 ++++++-- src/slic3r/GUI/Widgets/AMSControl.hpp | 1 + src/slic3r/GUI/wxExtensions.cpp | 34 +++++++-- src/slic3r/GUI/wxExtensions.hpp | 14 +++- 11 files changed, 168 insertions(+), 15 deletions(-) diff --git a/resources/images/transparent_ams_lib.svg b/resources/images/transparent_ams_lib.svg index fa2a0b65f..404028e07 100644 --- a/resources/images/transparent_ams_lib.svg +++ b/resources/images/transparent_ams_lib.svg @@ -1,4 +1,4 @@ - + diff --git a/resources/images/transparent_color_picker.svg b/resources/images/transparent_color_picker.svg index 5a41befa3..e0918cda1 100644 --- a/resources/images/transparent_color_picker.svg +++ b/resources/images/transparent_color_picker.svg @@ -1,4 +1,4 @@ - + diff --git a/src/slic3r/GUI/AMSMaterialsSetting.cpp b/src/slic3r/GUI/AMSMaterialsSetting.cpp index a02e5a21a..db9b0fe30 100644 --- a/src/slic3r/GUI/AMSMaterialsSetting.cpp +++ b/src/slic3r/GUI/AMSMaterialsSetting.cpp @@ -1136,6 +1136,9 @@ void ColorPicker::msw_rescale() void ColorPicker::set_color(wxColour col) { + if (m_colour != col&&col.Alpha()!=0&&col.Alpha()!=255) { + transparent_changed = true; + } m_colour = col; Refresh(); } @@ -1177,13 +1180,29 @@ void ColorPicker::doRender(wxDC& dc) { wxSize size = GetSize(); auto alpha = m_colour.Alpha(); - auto radius = m_show_full ? size.x / 2 - FromDIP(1) : size.x / 2; if (m_selected) radius -= FromDIP(1); if (alpha == 0) { dc.DrawBitmap(m_bitmap_transparent, 0, 0); } + else if (alpha != 0 && alpha != 255) { + if (transparent_changed) { + std::string rgb = (m_colour.GetAsString(wxC2S_HTML_SYNTAX)).ToStdString(); + if (rgb.size() == 8) { + //delete alpha value + rgb = rgb.substr(0, rgb.size() - 2); + } + float alpha_f = 0.3 * m_colour.Alpha() / 255.0; + std::vector replace; + replace.push_back(rgb); + std::string fill_replace = "fill-opacity=\"" + std::to_string(alpha_f); + replace.push_back(fill_replace); + m_bitmap_transparent = ScalableBitmap(this, "transparent_color_picker", 25, false, false, true, replace).bmp(); + transparent_changed = false; + } + dc.DrawBitmap(m_bitmap_transparent, 0, 0); + } else { dc.SetPen(wxPen(m_colour)); dc.SetBrush(wxBrush(m_colour)); @@ -1237,6 +1256,7 @@ void ColorPicker::doRender(wxDC& dc) startAngle += ev_angle; startAngle = startAngle > 360.0 ? startAngle - 360.0 : startAngle; } + dc.DrawBitmap(m_bitmap_border, wxPoint(0, 0)); } } } diff --git a/src/slic3r/GUI/AMSMaterialsSetting.hpp b/src/slic3r/GUI/AMSMaterialsSetting.hpp index 49d861fb5..5cdb03a66 100644 --- a/src/slic3r/GUI/AMSMaterialsSetting.hpp +++ b/src/slic3r/GUI/AMSMaterialsSetting.hpp @@ -43,6 +43,8 @@ public: bool m_is_empty{false}; int ctype; + bool transparent_changed{false}; + ColorPicker(wxWindow* parent, wxWindowID id, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize); ~ColorPicker(); diff --git a/src/slic3r/GUI/BitmapCache.cpp b/src/slic3r/GUI/BitmapCache.cpp index 1c683ec9c..788681a3a 100644 --- a/src/slic3r/GUI/BitmapCache.cpp +++ b/src/slic3r/GUI/BitmapCache.cpp @@ -384,6 +384,78 @@ wxBitmap* BitmapCache::load_svg(const std::string &bitmap_name, unsigned target_ return this->insert_raw_rgba(bitmap_key, width, height, data.data(), grayscale); } +wxBitmap* BitmapCache::load_svg2(const std::string& bitmap_name, unsigned target_width, unsigned target_height, + const bool grayscale/* = false*/, const bool dark_mode/* = false*/, const std::vector& array_new_color /*= vector()*/, const float scale_in_center/* = 0*/) +{ + + std::map replaces; + if (array_new_color.size() == 2) { + replaces["#D9D9D9"] = array_new_color[0]; + replaces["fill-opacity=\"1.0"] = array_new_color[1]; + } + + + NSVGimage* image = nullptr; + image = nsvgParseFromFileWithReplace(Slic3r::var(bitmap_name + ".svg").c_str(), "px", 96.0f, replaces); + + if (image == nullptr) + return nullptr; + + if (target_height == 0 && target_width == 0) + target_height = image->height; + + target_height != 0 ? target_height *= m_scale : target_width *= m_scale; + + float svg_scale = target_height != 0 ? + (float)target_height / image->height : target_width != 0 ? + (float)target_width / image->width : 1; + + int width = (int)(svg_scale * image->width + 0.5f); + int height = (int)(svg_scale * image->height + 0.5f); + int n_pixels = width * height; + if (n_pixels <= 0) { + ::nsvgDelete(image); + return nullptr; + } + + NSVGrasterizer* rast = ::nsvgCreateRasterizer(); + if (rast == nullptr) { + ::nsvgDelete(image); + return nullptr; + } + + std::vector data(n_pixels * 4, 0); + // BBS: support resize by fill border + if (scale_in_center > 0 && scale_in_center < svg_scale) { + int w = (int)(image->width * scale_in_center); + int h = (int)(image->height * scale_in_center); + ::nsvgRasterize(rast, image, 0, 0, scale_in_center, data.data() + int(height - h) / 2 * width * 4 + int(width - w) / 2 * 4, w, h, width * 4); + } + else + ::nsvgRasterize(rast, image, 0, 0, svg_scale, data.data(), width, height, width * 4); + ::nsvgDeleteRasterizer(rast); + ::nsvgDelete(image); + + const unsigned char * raw_data = data.data(); + wxImage wx_image(width, height); + wx_image.InitAlpha(); + unsigned char* rgb = wx_image.GetData(); + unsigned char* alpha = wx_image.GetAlpha(); + unsigned int pixels = width * height; + for (unsigned int i = 0; i < pixels; ++i) { + *rgb++ = *raw_data++; + *rgb++ = *raw_data++; + *rgb++ = *raw_data++; + *alpha++ = *raw_data++; + } + + if (grayscale) + wx_image = wx_image.ConvertToGreyscale(m_gs, m_gs, m_gs); + auto result = new wxBitmap(wxImage_to_wxBitmap_with_alpha(std::move(wx_image), m_scale)); + return result; + +} + //we make scaled solid bitmaps only for the cases, when its will be used with scaled SVG icon in one output bitmap wxBitmap BitmapCache::mksolid(size_t width, size_t height, unsigned char r, unsigned char g, unsigned char b, unsigned char transparency, bool suppress_scaling/* = false*/, size_t border_width /*= 0*/, bool dark_mode/* = false*/) { diff --git a/src/slic3r/GUI/BitmapCache.hpp b/src/slic3r/GUI/BitmapCache.hpp index 4803fa961..bbfecd715 100644 --- a/src/slic3r/GUI/BitmapCache.hpp +++ b/src/slic3r/GUI/BitmapCache.hpp @@ -42,6 +42,8 @@ public: static NSVGimage* nsvgParseFromFileWithReplace(const char* filename, const char* units, float dpi, const std::map& replaces); // Load svg from resources/icons. bitmap_key is given without the .svg suffix. SVG will be rasterized to provided height/width. wxBitmap* load_svg(const std::string &bitmap_key, unsigned width = 0, unsigned height = 0, const bool grayscale = false, const bool dark_mode = false, const std::string& new_color = "", const float scale_in_center = 0.f); + //Load background image of semi transparent material with color, + wxBitmap* load_svg2(const std::string &bitmap_key, unsigned width = 0, unsigned height = 0, const bool grayscale = false, const bool dark_mode = false, const std::vector& array_new_color = std::vector(), const float scale_in_center = 0.0f); wxBitmap mksolid(size_t width, size_t height, unsigned char r, unsigned char g, unsigned char b, unsigned char transparency, bool suppress_scaling = false, size_t border_width = 0, bool dark_mode = false); wxBitmap mksolid(size_t width, size_t height, const unsigned char rgb[3], bool suppress_scaling = false, size_t border_width = 0, bool dark_mode = false) { return mksolid(width, height, rgb[0], rgb[1], rgb[2], wxALPHA_OPAQUE, suppress_scaling, border_width, dark_mode); } diff --git a/src/slic3r/GUI/StatusPanel.cpp b/src/slic3r/GUI/StatusPanel.cpp index 7c8e1bd91..e6e3ee895 100644 --- a/src/slic3r/GUI/StatusPanel.cpp +++ b/src/slic3r/GUI/StatusPanel.cpp @@ -3512,6 +3512,7 @@ void StatusPanel::on_filament_edit(wxCommandEvent &event) } else { m_filament_setting_dlg->set_color(color); + m_filament_setting_dlg->set_colors(cols); } m_filament_setting_dlg->m_is_third = !MachineObject::is_bbl_filament(tray_it->second->tag_uid); diff --git a/src/slic3r/GUI/Widgets/AMSControl.cpp b/src/slic3r/GUI/Widgets/AMSControl.cpp index bef0d34b0..826ab24ca 100644 --- a/src/slic3r/GUI/Widgets/AMSControl.cpp +++ b/src/slic3r/GUI/Widgets/AMSControl.cpp @@ -862,6 +862,10 @@ void AMSLib::render_generic_text(wxDC &dc) dc.SetFont(::Label::Body_13); dc.SetTextForeground(temp_text_colour); + auto alpha = m_info.material_colour.Alpha(); + if (alpha != 0 && alpha != 255) { + dc.SetTextForeground(*wxBLACK); + } auto libsize = GetSize(); if (m_info.material_state == AMSCanType::AMS_CAN_TYPE_THIRDBRAND @@ -908,6 +912,7 @@ void AMSLib::render_generic_text(wxDC &dc) auto pot_top = wxPoint((libsize.x - line_top_tsize.x) / 2, (libsize.y - line_top_tsize.y) / 2 - line_top_tsize.y + FromDIP(6)); dc.DrawText(line_top, pot_top); + auto pot_bottom = wxPoint((libsize.x - line_bottom_tsize.x) / 2, (libsize.y - line_bottom_tsize.y) / 2 + FromDIP(4)); dc.DrawText(line_bottom, pot_bottom); } @@ -1135,7 +1140,7 @@ void AMSLib::render_generic_lib(wxDC &dc) //draw remain int height = size.y - FromDIP(8); - int curr_height = height * float(m_info.material_remain * 1.0 / 100.0); + int curr_height = height * float(m_info.material_remain * 1.0 / 100.0); dc.SetFont(::Label::Body_13); int top = height - curr_height; @@ -1146,8 +1151,7 @@ void AMSLib::render_generic_lib(wxDC &dc) if (alpha == 0) { dc.DrawBitmap(m_bitmap_transparent.bmp(), FromDIP(4), FromDIP(4)); } - - + //gradient if (m_info.material_cols.size() > 1) { int left = FromDIP(4); float total_width = size.x - FromDIP(8); @@ -1206,6 +1210,23 @@ void AMSLib::render_generic_lib(wxDC &dc) dc.DrawRoundedRectangle(FromDIP(4), FromDIP(4) + top, size.x - FromDIP(8), curr_height, m_radius); #else dc.DrawRoundedRectangle(FromDIP(4), FromDIP(4) + top, size.x - FromDIP(8), curr_height, m_radius - 1); + if (alpha != 0 && alpha != 255) { + if (transparent_changed) { + std::string rgb = (tmp_lib_colour.GetAsString(wxC2S_HTML_SYNTAX)).ToStdString(); + if (rgb.size() == 8) { + //delete alpha value + rgb= rgb.substr(0, rgb.size() - 2); + } + float alpha_f = 0.3 * tmp_lib_colour.Alpha() / 255.0; + std::vector replace; + replace.push_back(rgb); + std::string fill_replace = "fill-opacity=\"" + std::to_string(alpha_f); + replace.push_back(fill_replace); + m_bitmap_transparent = ScalableBitmap(this, "transparent_ams_lib", 68, false, false, true, replace); + transparent_changed = false; + } + dc.DrawBitmap(m_bitmap_transparent.bmp(), FromDIP(4), FromDIP(4)); + } #endif } } @@ -1274,7 +1295,9 @@ void AMSLib::Update(Caninfo info, bool refresh) if (dev->get_selected_machine() && dev->get_selected_machine() != m_obj) { m_obj = dev->get_selected_machine(); } - + if (info.material_colour.Alpha() != 0 && info.material_colour.Alpha() != 255 && m_info.material_colour != info.material_colour) { + transparent_changed = true; + } m_info = info; Layout(); if (refresh) Refresh(); diff --git a/src/slic3r/GUI/Widgets/AMSControl.hpp b/src/slic3r/GUI/Widgets/AMSControl.hpp index 7a9243366..711cde26a 100644 --- a/src/slic3r/GUI/Widgets/AMSControl.hpp +++ b/src/slic3r/GUI/Widgets/AMSControl.hpp @@ -339,6 +339,7 @@ protected: bool m_hover = {false}; bool m_show_kn = {false}; bool m_support_cali = {false}; + bool transparent_changed = {false}; double m_radius = {4}; wxColour m_border_color; diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 092c7a582..b53573d01 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -7,7 +7,6 @@ #include -#include "BitmapCache.hpp" #include "GUI.hpp" #include "GUI_App.hpp" #include "GUI_ObjectList.hpp" @@ -432,10 +431,14 @@ wxBitmap create_scaled_bitmap( const std::string& bmp_name_in, const bool grayscale/* = false*/, const std::string& new_color/* = std::string()*/, // color witch will used instead of orange const bool menu_bitmap/* = false*/, - const bool resize/* = false*/) + const bool resize/* = false*/, + const bool bitmap2/* = false*/, + const vector& array_new_color/* = vector*/)//used for semi transparent material) { static Slic3r::GUI::BitmapCache cache; - + if (bitmap2) { + return create_scaled_bitmap2(bmp_name_in, cache, win, px_cnt, grayscale, resize, array_new_color); + } unsigned int width = 0; unsigned int height = (unsigned int) (win->FromDIP(px_cnt) + 0.5f); @@ -462,6 +465,25 @@ wxBitmap create_scaled_bitmap( const std::string& bmp_name_in, return *bmp; } +wxBitmap create_scaled_bitmap2(const std::string& bmp_name_in, Slic3r::GUI::BitmapCache& cache, wxWindow* win/* = nullptr*/ , + const int px_cnt/* = 16*/, const bool grayscale/* = false*/ , const bool resize/* = false*/ , + const vector& array_new_color/* = vector()*/) // color witch will used instead of orange +{ + unsigned int width = 0; + unsigned int height = (unsigned int)(win->FromDIP(px_cnt) + 0.5f); + + std::string bmp_name = bmp_name_in; + boost::replace_last(bmp_name, ".png", ""); + + wxBitmap* bmp = cache.load_svg2(bmp_name, width, height, grayscale, false, array_new_color, resize ? em_unit(win) * 0.1f : 0.f); + if (bmp == nullptr) { + // No SVG found + throw Slic3r::RuntimeError("Could not load bitmap: " + bmp_name); + } + return *bmp; +} + + wxBitmap* get_default_extruder_color_icon(bool thin_icon/* = false*/) { static Slic3r::GUI::BitmapCache bmp_cache; @@ -858,11 +880,13 @@ ScalableBitmap::ScalableBitmap( wxWindow *parent, const std::string& icon_name/* = ""*/, const int px_cnt/* = 16*/, const bool grayscale/* = false*/, - const bool resize/* = false*/): + const bool resize/* = false*/, + const bool bitmap2/* = false*/, + const std::vector& new_color/* = vector*/) : m_parent(parent), m_icon_name(icon_name), m_px_cnt(px_cnt), m_grayscale(grayscale), m_resize(resize) // BBS: support resize by fill border { - m_bmp = create_scaled_bitmap(icon_name, parent, px_cnt, m_grayscale, std::string(), false, resize); + m_bmp = create_scaled_bitmap(icon_name, parent, px_cnt, m_grayscale, std::string(), false, resize, bitmap2, new_color); if (px_cnt == 0) { m_px_cnt = m_bmp.GetHeight(); // scale unsigned int height = (unsigned int) (parent->FromDIP(m_px_cnt) + 0.5f); diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index 6ed6f2bab..e7e992e4b 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -16,7 +16,7 @@ #include #include - +#include "BitmapCache.hpp" #include "Widgets/PopupWindow.hpp" #ifdef __WXMSW__ @@ -60,7 +60,13 @@ wxBitmap create_menu_bitmap(const std::string& bmp_name); wxBitmap create_scaled_bitmap(const std::string& bmp_name, wxWindow *win = nullptr, const int px_cnt = 16, const bool grayscale = false, const std::string& new_color = std::string(), // color witch will used instead of orange - const bool menu_bitmap = false, const bool resize = false); + const bool menu_bitmap = false, const bool resize = false, + const bool bitmap2 = false,// for create_scaled_bitmap2 + const std::vector& array_new_color = std::vector()); +//used for semi transparent material +wxBitmap create_scaled_bitmap2(const std::string& bmp_name_in, Slic3r::GUI::BitmapCache& cache, wxWindow* win = nullptr, + const int px_cnt = 16, const bool grayscale = false, const bool resize = false, + const std::vector& array_new_color = std::vector()); // color witch will used instead of orange #else wxBitmap create_scaled_bitmap(const std::string& bmp_name, wxWindow *win = nullptr, const int px_cnt = 16, const bool grayscale = false, const bool resize = false); @@ -154,7 +160,9 @@ public: const std::string& icon_name = "", const int px_cnt = 16, const bool grayscale = false, - const bool resize = false); // BBS: support resize by fill border + const bool resize = false, + const bool bitmap2 = false, + const std::vector& new_color = std::vector());// BBS: support resize by fill border ~ScalableBitmap() {}