diff --git a/resources/images/bbl-3dp-EP-logo.svg b/resources/images/bbl-3dp-EP-logo.svg
new file mode 100644
index 000000000..11827f3e3
--- /dev/null
+++ b/resources/images/bbl-3dp-EP-logo.svg
@@ -0,0 +1,170 @@
+
diff --git a/resources/images/bbl-3dp-PC-logo.svg b/resources/images/bbl-3dp-PC-logo.svg
new file mode 100644
index 000000000..293a36315
--- /dev/null
+++ b/resources/images/bbl-3dp-PC-logo.svg
@@ -0,0 +1,134 @@
+
diff --git a/resources/images/bbl-3dp-PEI-logo.svg b/resources/images/bbl-3dp-PEI-logo.svg
new file mode 100644
index 000000000..5ef51ea4a
--- /dev/null
+++ b/resources/images/bbl-3dp-PEI-logo.svg
@@ -0,0 +1,146 @@
+
diff --git a/resources/images/bbl-3dp-PTE-logo.svg b/resources/images/bbl-3dp-PTE-logo.svg
new file mode 100644
index 000000000..d838f60a5
--- /dev/null
+++ b/resources/images/bbl-3dp-PTE-logo.svg
@@ -0,0 +1,100 @@
+
diff --git a/resources/images/bbl-3dp-logo.svg b/resources/images/bbl-3dp-logo.svg
new file mode 100644
index 000000000..d17daf639
--- /dev/null
+++ b/resources/images/bbl-3dp-logo.svg
@@ -0,0 +1,36 @@
+
diff --git a/resources/images/plate_set_bedtype.svg b/resources/images/plate_set_bedtype.svg
new file mode 100644
index 000000000..788682c48
--- /dev/null
+++ b/resources/images/plate_set_bedtype.svg
@@ -0,0 +1,10 @@
+
diff --git a/resources/images/plate_set_bedtype_hover.svg b/resources/images/plate_set_bedtype_hover.svg
new file mode 100644
index 000000000..cc95c312f
--- /dev/null
+++ b/resources/images/plate_set_bedtype_hover.svg
@@ -0,0 +1,10 @@
+
diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt
index eaf52b812..e4987d634 100644
--- a/src/slic3r/CMakeLists.txt
+++ b/src/slic3r/CMakeLists.txt
@@ -265,6 +265,8 @@ set(SLIC3R_GUI_SOURCES
GUI/RemovableDriveManager.hpp
GUI/SendSystemInfoDialog.cpp
GUI/SendSystemInfoDialog.hpp
+ GUI/SetBedTypeDialog.cpp
+ GUI/SetBedTypeDialog.hpp
GUI/ImGuiWrapper.hpp
GUI/ImGuiWrapper.cpp
GUI/DeviceManager.hpp
diff --git a/src/slic3r/GUI/PartPlate.cpp b/src/slic3r/GUI/PartPlate.cpp
index 8b613ee26..c07458b19 100644
--- a/src/slic3r/GUI/PartPlate.cpp
+++ b/src/slic3r/GUI/PartPlate.cpp
@@ -130,7 +130,7 @@ void PartPlate::init()
m_print = nullptr;
}
-BedType PartPlate::get_bed_type()
+BedType PartPlate::get_bed_type() const
{
std::string bed_type_key = "curr_bed_type";
@@ -384,71 +384,13 @@ void PartPlate::render_background(bool force_default_color) const {
glsafe(::glDepthMask(GL_TRUE));
}
-void PartPlate::render_logo(bool bottom) const
+void PartPlate::render_logo_texture(GLTexture &logo_texture, bool bottom) const
{
- //GLTexture* texture = const_cast(&m_logo_texture);
-
- if (m_partplate_list->m_logo_texture_filename.empty()) {
- m_partplate_list->m_logo_texture.reset();
- return;
- }
-
- //GLTexture* temp_texture = const_cast(&m_temp_texture);
-
- if (m_partplate_list->m_logo_texture.get_id() == 0 || m_partplate_list->m_logo_texture.get_source() != m_partplate_list->m_logo_texture_filename) {
- m_partplate_list->m_logo_texture.reset();
-
- if (boost::algorithm::iends_with(m_partplate_list->m_logo_texture_filename, ".svg")) {
- /*// use higher resolution images if graphic card and opengl version allow
- GLint max_tex_size = OpenGLManager::get_gl_info().get_max_tex_size();
- if (temp_texture->get_id() == 0 || temp_texture->get_source() != m_texture_filename) {
- // generate a temporary lower resolution texture to show while no main texture levels have been compressed
- if (!temp_texture->load_from_svg_file(m_texture_filename, false, false, false, max_tex_size / 8)) {
- render_default(bottom, false);
- return;
- }
- canvas.request_extra_frame();
- }*/
-
- // starts generating the main texture, compression will run asynchronously
- GLint max_tex_size = OpenGLManager::get_gl_info().get_max_tex_size();
- 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;
- }
- }
- else if (boost::algorithm::iends_with(m_partplate_list->m_logo_texture_filename, ".png")) {
- // generate a temporary lower resolution texture to show while no main texture levels have been compressed
- /* if (temp_texture->get_id() == 0 || temp_texture->get_source() != m_logo_texture_filename) {
- if (!temp_texture->load_from_file(m_logo_texture_filename, false, GLTexture::None, false)) {
- render_default(bottom, false);
- return;
- }
- canvas.request_extra_frame();
- }*/
-
- // starts generating the main texture, compression will run asynchronously
- if (!m_partplate_list->m_logo_texture.load_from_file(m_partplate_list->m_logo_texture_filename, true, GLTexture::MultiThreaded, true)) {
- BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(": load logo texture from %1% failed!")%m_partplate_list->m_logo_texture_filename;
- return;
- }
- }
- else {
- BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(": can not load logo texture from %1%, unsupported format")%m_partplate_list->m_logo_texture_filename;
- return;
- }
- }
- else if (m_partplate_list->m_logo_texture.unsent_compressed_data_available()) {
+ //check valid
+ if (logo_texture.unsent_compressed_data_available()) {
// sends to gpu the already available compressed levels of the main texture
- m_partplate_list->m_logo_texture.send_compressed_data_to_gpu();
-
- // the temporary texture is not needed anymore, reset it
- //if (temp_texture->get_id() != 0)
- // temp_texture->reset();
-
- //canvas.request_extra_frame();
- }
+ logo_texture.send_compressed_data_to_gpu();
+ }
if (m_logo_triangles.get_vertices_count() > 0) {
GLShaderProgram* shader = wxGetApp().get_shader("printbed");
@@ -476,7 +418,7 @@ void PartPlate::render_logo(bool bottom) const
}
// show the temporary texture while no compressed data is available
- GLuint tex_id = (GLuint)m_partplate_list->m_logo_texture.get_id();
+ GLuint tex_id = (GLuint)logo_texture.get_id();
unsigned int* vbo_id = const_cast(&m_vbo_id);
if (*vbo_id == 0) {
glsafe(::glGenBuffers(1, vbo_id));
@@ -513,6 +455,82 @@ void PartPlate::render_logo(bool bottom) const
}
}
+void PartPlate::render_logo(bool bottom) const
+{
+ if (!m_partplate_list->render_bedtype_logo) {
+ // render third-party printer texture logo
+ if (m_partplate_list->m_logo_texture_filename.empty()) {
+ m_partplate_list->m_logo_texture.reset();
+ return;
+ }
+
+ //GLTexture* temp_texture = const_cast(&m_temp_texture);
+
+ if (m_partplate_list->m_logo_texture.get_id() == 0 || m_partplate_list->m_logo_texture.get_source() != m_partplate_list->m_logo_texture_filename) {
+ m_partplate_list->m_logo_texture.reset();
+
+ if (boost::algorithm::iends_with(m_partplate_list->m_logo_texture_filename, ".svg")) {
+ /*// use higher resolution images if graphic card and opengl version allow
+ GLint max_tex_size = OpenGLManager::get_gl_info().get_max_tex_size();
+ if (temp_texture->get_id() == 0 || temp_texture->get_source() != m_texture_filename) {
+ // generate a temporary lower resolution texture to show while no main texture levels have been compressed
+ if (!temp_texture->load_from_svg_file(m_texture_filename, false, false, false, max_tex_size / 8)) {
+ render_default(bottom, false);
+ return;
+ }
+ canvas.request_extra_frame();
+ }*/
+
+ // starts generating the main texture, compression will run asynchronously
+ GLint max_tex_size = OpenGLManager::get_gl_info().get_max_tex_size();
+ 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;
+ }
+ }
+ else if (boost::algorithm::iends_with(m_partplate_list->m_logo_texture_filename, ".png")) {
+ // generate a temporary lower resolution texture to show while no main texture levels have been compressed
+ /* if (temp_texture->get_id() == 0 || temp_texture->get_source() != m_logo_texture_filename) {
+ if (!temp_texture->load_from_file(m_logo_texture_filename, false, GLTexture::None, false)) {
+ render_default(bottom, false);
+ return;
+ }
+ canvas.request_extra_frame();
+ }*/
+
+ // starts generating the main texture, compression will run asynchronously
+ if (!m_partplate_list->m_logo_texture.load_from_file(m_partplate_list->m_logo_texture_filename, true, GLTexture::MultiThreaded, true)) {
+ BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(": load logo texture from %1% failed!") % m_partplate_list->m_logo_texture_filename;
+ return;
+ }
+ }
+ else {
+ BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(": can not load logo texture from %1%, unsupported format") % m_partplate_list->m_logo_texture_filename;
+ return;
+ }
+ }
+ else if (m_partplate_list->m_logo_texture.unsent_compressed_data_available()) {
+ // sends to gpu the already available compressed levels of the main texture
+ m_partplate_list->m_logo_texture.send_compressed_data_to_gpu();
+
+ // the temporary texture is not needed anymore, reset it
+ //if (temp_texture->get_id() != 0)
+ // temp_texture->reset();
+
+ //canvas.request_extra_frame();
+ }
+
+ render_logo_texture(m_partplate_list->m_logo_texture, bottom);
+ return;
+ }
+
+ PartPlateList::load_bedtype_textures();
+
+ int bed_type_idx = (int)get_bed_type();
+ render_logo_texture(PartPlateList::bed_textures[bed_type_idx], bottom);
+}
+
void PartPlate::render_exclude_area(bool force_default_color) const {
if (force_default_color) //for thumbnail case
return;
@@ -672,6 +690,13 @@ void PartPlate::render_icons(bool bottom, int hover_id) const
render_icon_texture(position_id, tex_coords_id, m_lock_icon, m_partplate_list->m_lockopen_texture, m_lock_vbo_id);
}
+ if (m_partplate_list->render_bedtype_setting) {
+ if (hover_id == 5)
+ render_icon_texture(position_id, tex_coords_id, m_bedtype_icon, m_partplate_list->m_bedtype_hovered_texture, m_bedtype_vbo_id);
+ else
+ render_icon_texture(position_id, tex_coords_id, m_bedtype_icon, m_partplate_list->m_bedtype_texture, m_bedtype_vbo_id);
+ }
+
if (m_plate_index >=0 && m_plate_index < MAX_PLATE_COUNT) {
render_icon_texture(position_id, tex_coords_id, m_plate_idx_icon, m_partplate_list->m_idx_textures[m_plate_index], m_plate_idx_vbo_id);
}
@@ -1000,6 +1025,14 @@ void PartPlate::on_render_for_picking() const {
m_grabber_color[3] = color[3];
//render_right_arrow(m_grabber_color, false);
render_rectangle_for_picking(m_lock_icon, m_grabber_color);
+ hover_id = 5;
+ color = picking_color_component(hover_id);
+ m_grabber_color[0] = color[0];
+ m_grabber_color[1] = color[1];
+ m_grabber_color[2] = color[2];
+ m_grabber_color[3] = color[3];
+ if (m_partplate_list->render_bedtype_setting)
+ render_rectangle_for_picking(m_bedtype_icon, m_grabber_color);
}
std::array PartPlate::picking_color_component(int idx) const
@@ -1036,6 +1069,10 @@ void PartPlate::release_opengl_resource()
glsafe(::glDeleteBuffers(1, &m_lock_vbo_id));
m_lock_vbo_id = 0;
}
+ if (m_bedtype_vbo_id > 0) {
+ glsafe(::glDeleteBuffers(1, &m_bedtype_vbo_id));
+ m_bedtype_vbo_id = 0;
+ }
if (m_plate_idx_vbo_id > 0) {
glsafe(::glDeleteBuffers(1, &m_plate_idx_vbo_id));
m_plate_idx_vbo_id = 0;
@@ -1851,6 +1888,7 @@ bool PartPlate::set_shape(const Pointfs& shape, const Pointfs& exclude_areas, Ve
calc_vertex_for_icons(1, m_orient_icon);
calc_vertex_for_icons(2, m_arrange_icon);
calc_vertex_for_icons(3, m_lock_icon);
+ calc_vertex_for_icons(4, m_bedtype_icon);
//calc_vertex_for_number(0, (m_plate_index < 9), m_plate_idx_icon);
calc_vertex_for_number(0, false, m_plate_idx_icon);
}
@@ -1919,8 +1957,9 @@ void PartPlate::render(bool bottom, bool only_body, bool force_background_color,
render_grid(bottom);
- if (!bottom && m_selected && !force_background_color)
+ if (!bottom && m_selected && !force_background_color) {
render_logo(bottom);
+ }
render_height_limit(mode);
@@ -2364,6 +2403,22 @@ void PartPlateList::generate_icon_textures()
}
}
+ if (m_bedtype_texture.get_id() == 0)
+ {
+ file_name = path + "plate_set_bedtype.svg";
+ if (!m_bedtype_texture.load_from_svg_file(file_name, true, false, false, max_tex_size / 8)) {
+ BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(":load file %1% failed") % file_name;
+ }
+ }
+
+ if (m_bedtype_hovered_texture.get_id() == 0)
+ {
+ file_name = path + "plate_set_bedtype_hover.svg";
+ if (!m_bedtype_hovered_texture.load_from_svg_file(file_name, true, false, false, max_tex_size / 8)) {
+ BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(":load file %1% failed") % file_name;
+ }
+ }
+
auto is_font_suitable = [](std::string text_str, wxFont& font, int max_size) {
wxMemoryDC memDC;
wxCoord w, h;
@@ -2409,6 +2464,7 @@ void PartPlateList::generate_icon_textures()
void PartPlateList::release_icon_textures()
{
+ m_logo_texture.reset();
m_del_texture.reset();
m_del_hovered_texture.reset();
m_arrange_texture.reset();
@@ -2419,9 +2475,17 @@ void PartPlateList::release_icon_textures()
m_locked_hovered_texture.reset();
m_lockopen_texture.reset();
m_lockopen_hovered_texture.reset();
+ m_bedtype_texture.reset();
+ m_bedtype_hovered_texture.reset();
+
for (int i = 0;i < MAX_PLATE_COUNT; i++) {
m_idx_textures[i].reset();
}
+ //reset
+ PartPlateList::is_load_bedtype_textures = false;
+ for (int i = 0; i < btCount; i++) {
+ PartPlateList::bed_textures[i].reset();
+ }
}
//this may be happened after machine changed
@@ -3702,6 +3766,12 @@ void PartPlateList::render_for_picking_pass()
return 0;
}*/
+void PartPlateList::set_render_option(bool bedtype_texture, bool bedtype_setting)
+{
+ render_bedtype_logo = bedtype_texture;
+ render_bedtype_setting = bedtype_setting;
+}
+
int PartPlateList::select_plate_by_obj(int obj_index, int instance_index)
{
int ret = 0, index;
@@ -4207,5 +4277,33 @@ void PartPlateList::print() const
return;
}
+bool PartPlateList::is_load_bedtype_textures = false;
+
+static std::string bed_textures_filenames[btCount] = {
+ "bbl-3dp-PC-logo.svg",
+ "bbl-3dp-EP-logo.svg",
+ "bbl-3dp-PEI-logo.svg",
+ "bbl-3dp-PTE-logo.svg"
+};
+
+GLTexture PartPlateList::bed_textures[(unsigned int)btCount];
+
+void PartPlateList::load_bedtype_textures()
+{
+ if (PartPlateList::is_load_bedtype_textures) return;
+
+ GLint max_tex_size = OpenGLManager::get_gl_info().get_max_tex_size();
+ GLint logo_tex_size = (max_tex_size < 2048) ? max_tex_size : 2048;
+ for (int i = 0; i < (unsigned int)btCount; ++i) {
+ std::string filename = resources_dir() + "/images/" + bed_textures_filenames[i];
+ if (boost::filesystem::exists(filename)) {
+ if (!PartPlateList::bed_textures[i].load_from_svg_file(filename, true, true, true, logo_tex_size)) {
+ BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(": load logo texture from %1% failed!") % filename;
+ }
+ }
+ }
+ PartPlateList::is_load_bedtype_textures = true;
+}
+
}//end namespace GUI
}//end namespace slic3r
diff --git a/src/slic3r/GUI/PartPlate.hpp b/src/slic3r/GUI/PartPlate.hpp
index e2606e6db..9fddc85c6 100644
--- a/src/slic3r/GUI/PartPlate.hpp
+++ b/src/slic3r/GUI/PartPlate.hpp
@@ -132,6 +132,8 @@ private:
mutable unsigned int m_orient_vbo_id{ 0 };
GeometryBuffer m_lock_icon;
mutable unsigned int m_lock_vbo_id{ 0 };
+ GeometryBuffer m_bedtype_icon;
+ mutable unsigned int m_bedtype_vbo_id{ 0 };
GeometryBuffer m_plate_idx_icon;
mutable unsigned int m_plate_idx_vbo_id{ 0 };
GLTexture m_texture;
@@ -160,6 +162,7 @@ private:
void calc_vertex_for_icons_background(int icon_count, GeometryBuffer &buffer);
void render_background(bool force_default_color = false) const;
void render_logo(bool bottom) const;
+ void render_logo_texture(GLTexture& logo_texture, bool bottom) const;
void render_exclude_area(bool force_default_color) const;
//void render_background_for_picking(const float* render_color) const;
void render_grid(bool bottom) const;
@@ -180,7 +183,7 @@ private:
public:
static const unsigned int PLATE_BASE_ID = 255 * 255 * 253;
- static const unsigned int GRABBER_COUNT = 5;
+ static const unsigned int GRABBER_COUNT = 6;
static std::array SELECT_COLOR;
static std::array UNSELECT_COLOR;
@@ -203,7 +206,7 @@ public:
//clear alll the instances in plate
void clear(bool clear_sliced_result = true);
- BedType get_bed_type();
+ BedType get_bed_type() const;
void set_bed_type(BedType);
void reset_bed_type();
DynamicPrintConfig* config() { return &m_config; }
@@ -450,7 +453,12 @@ class PartPlateList : public ObjectBase
GLTexture m_locked_hovered_texture;
GLTexture m_lockopen_texture;
GLTexture m_lockopen_hovered_texture;
+ GLTexture m_bedtype_texture;
+ GLTexture m_bedtype_hovered_texture;
GLTexture m_idx_textures[MAX_PLATE_COUNT];
+ // set render option
+ bool render_bedtype_logo = true;
+ bool render_bedtype_setting = true;
void init();
//compute the origin for printable plate with index i
@@ -469,6 +477,8 @@ class PartPlateList : public ObjectBase
public:
static const unsigned int MAX_PLATES_COUNT = MAX_PLATE_COUNT;
+ static GLTexture bed_textures[(unsigned int)btCount];
+ static bool is_load_bedtype_textures;
PartPlateList(int width, int depth, int height, Plater* platerObj, Model* modelObj, PrinterTechnology tech = ptFFF);
PartPlateList(Plater* platerObj, Model* modelObj, PrinterTechnology tech = ptFFF);
@@ -596,6 +606,7 @@ public:
/*rendering related functions*/
void render(bool bottom, bool only_current = false, bool only_body = false, int hover_id = -1);
void render_for_picking_pass();
+ void set_render_option(bool bedtype_texture, bool bedtype_settings);
BoundingBoxf3& get_bounding_box() { return m_bounding_box; }
//int select_plate_by_hover_id(int hover_id);
int select_plate_by_obj(int obj_index, int instance_index);
@@ -649,6 +660,8 @@ public:
ar(m_shape, m_plate_width, m_plate_depth, m_plate_height, m_height_to_lid, m_height_to_rod, m_height_limit_mode, m_plate_count, m_current_plate, m_plate_list, unprintable_plate);
//ar(m_plate_width, m_plate_depth, m_plate_height, m_plate_count, m_current_plate);
}
+
+ static void load_bedtype_textures();
};
} // namespace GUI
diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp
index 48d2c165d..a6cc4d168 100644
--- a/src/slic3r/GUI/Plater.cpp
+++ b/src/slic3r/GUI/Plater.cpp
@@ -128,6 +128,7 @@
#include "PhysicalPrinterDialog.hpp"
#include "PrintHostDialogs.hpp"
+#include "SetBedTypeDialog.hpp"
using boost::optional;
namespace fs = boost::filesystem;
@@ -5209,6 +5210,10 @@ void Plater::priv::on_select_bed_type(wxCommandEvent &evt)
// update app_config
AppConfig *app_config = wxGetApp().app_config;
app_config->set("curr_bed_type", std::to_string(int(bed_type)));
+
+ // update render
+ view3D->get_canvas3d()->render();
+ preview->msw_rescale();
}
}
}
@@ -10571,6 +10576,25 @@ int Plater::select_plate_by_hover_id(int hover_id, bool right_click)
take_snapshot("lock partplate");
ret = p->partplate_list.lock_plate(plate_index, !p->partplate_list.is_locked(plate_index));
}
+ else if ((action == 5)&&(!right_click))
+ {
+ //set the plate type
+ ret = select_plate(plate_index);
+ if (!ret) {
+ SetBedTypeDialog dlg(this, wxID_ANY, _L("Select bed type"));
+ dlg.sync_bed_type(p->partplate_list.get_curr_plate()->get_bed_type());
+ dlg.Bind(EVT_SET_BED_TYPE_CONFIRM, [this, plate_index](wxCommandEvent& e) {
+ auto type = (BedType)(e.GetInt());
+ p->partplate_list.get_curr_plate()->set_bed_type(type);
+ BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format("select bed type %1% for plate %2% at plate side")%type %plate_index;
+ });
+ dlg.ShowModal();
+ }
+ else {
+ BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << "can not select plate %1%" << plate_index;
+ ret = -1;
+ }
+ }
else
{
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << "invalid action %1%, with right_click=%2%" << action << right_click;
diff --git a/src/slic3r/GUI/SetBedTypeDialog.cpp b/src/slic3r/GUI/SetBedTypeDialog.cpp
new file mode 100644
index 000000000..da90220b4
--- /dev/null
+++ b/src/slic3r/GUI/SetBedTypeDialog.cpp
@@ -0,0 +1,145 @@
+#include "SetBedTypeDialog.hpp"
+
+
+namespace Slic3r { namespace GUI {
+
+wxDEFINE_EVENT(EVT_SET_BED_TYPE_CONFIRM, wxCommandEvent);
+
+SetBedTypeDialog::SetBedTypeDialog(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style)
+:DPIDialog(parent, id, title, pos, size, style)
+{
+ std::string icon_path = (boost::format("%1%/images/BambuStudioTitle.ico") % resources_dir()).str();
+ SetIcon(wxIcon(encode_path(icon_path.c_str()), wxBITMAP_TYPE_ICO));
+
+ SetBackgroundColour(*wxWHITE);
+ wxBoxSizer* m_sizer_main = new wxBoxSizer(wxVERTICAL);
+ auto m_line_top = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(FromDIP(300), -1));
+ m_line_top->SetBackgroundColour(wxColour(166, 169, 170));
+ m_sizer_main->Add(m_line_top, 0, wxEXPAND, 0);
+ m_sizer_main->Add(0, 0, 0, wxTOP, FromDIP(5));
+
+ wxBoxSizer* m_sizer_radiobutton = new wxBoxSizer(wxVERTICAL);
+ m_cool_btn = create_item_radiobox(_L("Cool Plate"), this, wxEmptyString, FromDIP(5), 0, "btPC");
+ m_sizer_radiobutton->Add( m_cool_btn, 1, wxALL, FromDIP(5) );
+ m_engineering_btn = create_item_radiobox(_L("Engineering Plate"), this, wxEmptyString, FromDIP(5), 1, "btEP");
+ m_sizer_radiobutton->Add( m_engineering_btn, 1, wxALL, FromDIP(5) );
+ m_high_temp_btn = create_item_radiobox(_L("High Temp Plate"), this, wxEmptyString, FromDIP(5), 2, "btPEI");
+ m_sizer_radiobutton->Add( m_high_temp_btn, 1, wxALL, FromDIP(5) );
+ m_texture_pei_btn = create_item_radiobox(_L("Textured PEI Plate"), this, wxEmptyString, FromDIP(5), 3, "btPTE");
+ m_sizer_radiobutton->Add( m_texture_pei_btn, 1, wxALL, FromDIP(5) );
+
+ m_sizer_main->Add(m_sizer_radiobutton, 0, wxEXPAND | wxALL, FromDIP(10));
+
+ auto sizer_button = new wxBoxSizer(wxHORIZONTAL);
+ StateColor btn_bg_green(std::pair(wxColour(27, 136, 68), StateColor::Pressed), std::pair(wxColour(61, 203, 115), StateColor::Hovered),
+ std::pair(wxColour(0, 174, 66), StateColor::Normal));
+
+ StateColor btn_bg_white(std::pair(wxColour(206, 206, 206), StateColor::Pressed), std::pair(wxColour(238, 238, 238), StateColor::Hovered),
+ std::pair(*wxWHITE, StateColor::Normal));
+
+ m_button_ok = new Button(this, _L("OK"));
+ m_button_ok->SetBackgroundColor(btn_bg_green);
+ m_button_ok->SetBorderColor(*wxWHITE);
+ m_button_ok->SetTextColor(*wxWHITE);
+ m_button_ok->SetFont(Label::Body_12);
+ m_button_ok->SetSize(wxSize(FromDIP(58), FromDIP(24)));
+ m_button_ok->SetMinSize(wxSize(FromDIP(58), FromDIP(24)));
+ m_button_ok->SetCornerRadius(FromDIP(12));
+ m_button_ok->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent& e) {
+ int len = radio_buttons.size();
+ for (int i = 0; i < len; ++i) {
+ if (radio_buttons[i]->GetValue()) {
+ wxCommandEvent evt(EVT_SET_BED_TYPE_CONFIRM, GetId());
+ evt.SetInt(i);
+ e.SetEventObject(this);
+ GetEventHandler()->ProcessEvent(evt);
+ break;
+ }
+ }
+ if (this->IsModal())
+ EndModal(wxID_YES);
+ else
+ this->Close();
+ });
+
+ m_button_cancel = new Button(this, _L("Cancel"));
+ m_button_cancel->SetBackgroundColor(btn_bg_white);
+ m_button_cancel->SetBorderColor(wxColour(38, 46, 48));
+ m_button_cancel->SetFont(Label::Body_12);
+ m_button_cancel->SetSize(wxSize(FromDIP(58), FromDIP(24)));
+ m_button_cancel->SetMinSize(wxSize(FromDIP(58), FromDIP(24)));
+ m_button_cancel->SetCornerRadius(FromDIP(12));
+ m_button_cancel->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent& e) {
+ if (this->IsModal())
+ EndModal(wxID_NO);
+ else
+ this->Close();
+ });
+
+ sizer_button->AddStretchSpacer();
+ sizer_button->Add(m_button_ok, 0, wxALL, FromDIP(5));
+ sizer_button->Add(m_button_cancel, 0, wxALL, FromDIP(5));
+
+ m_sizer_main->Add(sizer_button, 0, wxEXPAND, FromDIP(20));
+
+ SetSizer(m_sizer_main);
+ Layout();
+ m_sizer_main->Fit(this);
+
+ CenterOnParent();
+}
+
+SetBedTypeDialog::~SetBedTypeDialog()
+{
+
+}
+
+wxWindow* SetBedTypeDialog::create_item_radiobox(wxString title, wxWindow* parent, wxString tooltip, int padding_left, int groupid, std::string param)
+{
+ wxWindow *item = new wxWindow(parent, wxID_ANY, wxDefaultPosition, wxSize(-1, FromDIP(28)));
+ item->SetBackgroundColour(*wxWHITE);
+
+ RadioBox *radiobox = new RadioBox(item);
+ radiobox->SetPosition(wxPoint(padding_left, (item->GetSize().GetHeight() - radiobox->GetSize().GetHeight()) / 2));
+ radiobox->Bind(wxEVT_LEFT_DOWN, &SetBedTypeDialog::select_curr_radiobox, this);
+ radio_buttons.push_back(radiobox);
+
+ wxStaticText *text = new wxStaticText(item, wxID_ANY, title, wxDefaultPosition, wxDefaultSize);
+ text->SetPosition(wxPoint(padding_left + radiobox->GetSize().GetWidth() + 10, (item->GetSize().GetHeight() - text->GetSize().GetHeight()) / 2));
+ text->SetFont(Label::Body_14);
+ text->SetForegroundColour(0x686868);
+
+ radiobox->SetToolTip(tooltip);
+ text->SetToolTip(tooltip);
+ return item;
+}
+
+void SetBedTypeDialog::select_curr_radiobox(wxMouseEvent &e)
+{
+ int len = radio_buttons.size();
+ for (auto rbtn:radio_buttons) {
+ if (rbtn->GetId() == e.GetId())
+ rbtn->SetValue(true);
+ else
+ rbtn->SetValue(false);
+ }
+}
+
+void SetBedTypeDialog::sync_bed_type(BedType type)
+{
+ int select_type = (int)(type);
+ int len = radio_buttons.size();
+ for (int i = 0; i < len; ++i) {
+ if (i == select_type)
+ radio_buttons[i]->SetValue(true);
+ else
+ radio_buttons[i]->SetValue(false);
+ }
+}
+
+void SetBedTypeDialog::on_dpi_changed(const wxRect& suggested_rect)
+{
+
+}
+
+}} // namespace Slic3r::GUI
\ No newline at end of file
diff --git a/src/slic3r/GUI/SetBedTypeDialog.hpp b/src/slic3r/GUI/SetBedTypeDialog.hpp
new file mode 100644
index 000000000..f877431e4
--- /dev/null
+++ b/src/slic3r/GUI/SetBedTypeDialog.hpp
@@ -0,0 +1,49 @@
+#ifndef slic3r_GUI_SetBedTypeDialog_hpp_
+#define slic3r_GUI_SetBedTypeDialog_hpp_
+
+#include "Plater.hpp"
+#include "PartPlate.hpp"
+#include "Widgets/Button.hpp"
+#include "Widgets/RadioBox.hpp"
+
+namespace Slic3r { namespace GUI {
+
+wxDECLARE_EVENT(EVT_SET_BED_TYPE_CONFIRM, wxCommandEvent);
+
+class SetBedTypeDialog : public DPIDialog
+{
+public:
+ enum ButtonStyle {
+ ONLY_CONFIRM = 0,
+ CONFIRM_AND_CANCEL = 1,
+ MAX_STYLE_NUM = 2
+ };
+ SetBedTypeDialog(
+ wxWindow* parent,
+ wxWindowID id = wxID_ANY,
+ const wxString& title = wxEmptyString,
+ const wxPoint& pos = wxDefaultPosition,
+ const wxSize& size = wxDefaultSize,
+ long style = wxCLOSE_BOX | wxCAPTION
+ );
+
+ ~SetBedTypeDialog();
+ void sync_bed_type(BedType type);
+ void on_dpi_changed(const wxRect& suggested_rect) override;
+
+protected:
+ wxWindow* m_cool_btn;
+ wxWindow* m_engineering_btn;
+ wxWindow* m_high_temp_btn;
+ wxWindow* m_texture_pei_btn;
+ Button* m_button_ok;
+ Button* m_button_cancel;
+ std::vector radio_buttons;
+
+ wxWindow * create_item_radiobox(wxString title, wxWindow *parent, wxString tooltip, int padding_left, int groupid, std::string param);
+ void select_curr_radiobox(wxMouseEvent &e);
+};
+
+}} // namespace Slic3r::GUI
+
+#endif
\ No newline at end of file
diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp
index 4a08c23af..718fc7583 100644
--- a/src/slic3r/GUI/Tab.cpp
+++ b/src/slic3r/GUI/Tab.cpp
@@ -1567,6 +1567,12 @@ void Tab::on_presets_changed()
// Instead of PostEvent (EVT_TAB_PRESETS_CHANGED) just call update_presets
wxGetApp().plater()->sidebar().update_presets(m_type);
+ bool is_bbl_vendor_preset = wxGetApp().preset_bundle->printers.get_edited_preset().is_bbl_vendor_preset(wxGetApp().preset_bundle);
+ if (is_bbl_vendor_preset)
+ wxGetApp().plater()->get_partplate_list().set_render_option(true, true);
+ else
+ wxGetApp().plater()->get_partplate_list().set_render_option(false, false);
+
// Printer selected at the Printer tab, update "compatible" marks at the print and filament selectors.
for (auto t: m_dependent_tabs)
{