From 2b9f3c99128ba22f06a888949e17666dd02c2da6 Mon Sep 17 00:00:00 2001 From: "zhou.xu" Date: Wed, 19 Apr 2023 19:59:07 +0800 Subject: [PATCH] NEW: add plate name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit referenced OrcaSlicer code and support for Chinese textures,chinese xml,limit plate_name length,Code decoupling,wxColour use Local Variables Change-Id: I6434b90efb2f90235527c7dfb3a7ed516ac2cf4b (cherry picked from commit 0ecfefb0e1cfccbe73b0fcc530e04e6405ecf68a) --- src/libslic3r/BoundingBox.hpp | 11 ++ src/libslic3r/Format/bbs_3mf.cpp | 6 + src/libslic3r/Format/bbs_3mf.hpp | 1 + src/libslic3r/GCode.cpp | 6 + src/libslic3r/Print.cpp | 2 + src/libslic3r/PrintBase.hpp | 5 + src/slic3r/GUI/GLTexture.cpp | 2 +- src/slic3r/GUI/PartPlate.cpp | 213 ++++++++++++++++--------- src/slic3r/GUI/PartPlate.hpp | 23 ++- src/slic3r/GUI/PlateSettingsDialog.cpp | 14 ++ src/slic3r/GUI/PlateSettingsDialog.hpp | 4 + src/slic3r/GUI/Plater.cpp | 19 ++- src/slic3r/GUI/Widgets/Label.cpp | 5 +- src/slic3r/GUI/Widgets/Label.hpp | 2 + 14 files changed, 227 insertions(+), 86 deletions(-) diff --git a/src/libslic3r/BoundingBox.hpp b/src/libslic3r/BoundingBox.hpp index b90081b0d..283ba3de1 100644 --- a/src/libslic3r/BoundingBox.hpp +++ b/src/libslic3r/BoundingBox.hpp @@ -70,6 +70,17 @@ public: return ! (this->max(0) < other.min(0) || this->min(0) > other.max(0) || this->max(1) < other.min(1) || this->min(1) > other.max(1)); } + PointClass operator[](size_t idx) const + { + switch (idx) { + case 0: return min; break; + case 1: return PointClass(max(0), min(1)); break; + case 2: return max; break; + case 3: return PointClass(min(0), max(1)); break; + default: return PointClass(); break; + } + return PointClass(); + } bool operator==(const BoundingBoxBase &rhs) { return this->min == rhs.min && this->max == rhs.max; } bool operator!=(const BoundingBoxBase &rhs) { return ! (*this == rhs); } friend std::ostream &operator<<(std::ostream &os, const BoundingBoxBase &bbox) diff --git a/src/libslic3r/Format/bbs_3mf.cpp b/src/libslic3r/Format/bbs_3mf.cpp index b26165304..dee56aad2 100644 --- a/src/libslic3r/Format/bbs_3mf.cpp +++ b/src/libslic3r/Format/bbs_3mf.cpp @@ -277,6 +277,7 @@ static constexpr const char* OBJECT_ID_ATTR = "object_id"; static constexpr const char* INSTANCEID_ATTR = "instance_id"; static constexpr const char* IDENTIFYID_ATTR = "identify_id"; static constexpr const char* PLATERID_ATTR = "plater_id"; +static constexpr const char* PLATER_NAME_ATTR = "plater_name"; static constexpr const char* PLATE_IDX_ATTR = "index"; static constexpr const char* SLICE_PREDICTION_ATTR = "prediction"; static constexpr const char* SLICE_WEIGHT_ATTR = "weight"; @@ -2038,6 +2039,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) } plate_data_list[it->first-1]->locked = it->second->locked; plate_data_list[it->first-1]->plate_index = it->second->plate_index-1; + plate_data_list[it->first - 1]->plate_name = it->second->plate_name; plate_data_list[it->first-1]->obj_inst_map = it->second->obj_inst_map; plate_data_list[it->first-1]->gcode_file = (m_load_restore || it->second->gcode_file.empty()) ? it->second->gcode_file : m_backup_path + "/" + it->second->gcode_file; plate_data_list[it->first-1]->gcode_prediction = it->second->gcode_prediction; @@ -3814,6 +3816,9 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) if (key == PLATERID_ATTR) { m_curr_plater->plate_index = atoi(value.c_str()); + } + else if (key == PLATER_NAME_ATTR) { + m_curr_plater->plate_name = encode_path(value.c_str()); } else if (key == LOCK_ATTR) { @@ -6962,6 +6967,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) stream << " <" << PLATE_TAG << ">\n"; //plate index stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << PLATERID_ATTR << "\" " << VALUE_ATTR << "=\"" << plate_data->plate_index + 1 << "\"/>\n"; + stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << PLATER_NAME_ATTR << "\" " << VALUE_ATTR << "=\"" << decode_path(plate_data->plate_name.c_str()) << "\"/>\n"; stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << LOCK_ATTR << "\" " << VALUE_ATTR << "=\"" << std::boolalpha<< plate_data->locked<< "\"/>\n"; ConfigOption* bed_type_opt = plate_data->config.option("curr_bed_type"); t_config_enum_names bed_type_names = ConfigOptionEnum::get_enum_names(); diff --git a/src/libslic3r/Format/bbs_3mf.hpp b/src/libslic3r/Format/bbs_3mf.hpp index c0be9d97e..f28daba04 100644 --- a/src/libslic3r/Format/bbs_3mf.hpp +++ b/src/libslic3r/Format/bbs_3mf.hpp @@ -76,6 +76,7 @@ struct PlateData std::string pattern_bbox_file; std::string gcode_prediction; std::string gcode_weight; + std::string plate_name; std::vector slice_filaments_info; DynamicPrintConfig config; bool is_support_used {false}; diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 8d8d57e5e..a4d9f7ee9 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -1725,6 +1725,12 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato m_placeholder_parser.set("bed_temperature_initial_layer_single", new ConfigOptionInt(first_bed_temp_opt->get_at(initial_extruder_id))); m_placeholder_parser.set("bed_temperature_initial_layer_vector", new ConfigOptionString("")); + //support variables `first_layer_temperature` and `first_layer_bed_temperature` + m_placeholder_parser.set("first_layer_bed_temperature", new ConfigOptionInts(*first_bed_temp_opt)); + m_placeholder_parser.set("first_layer_temperature", new ConfigOptionInts(m_config.nozzle_temperature_initial_layer)); + m_placeholder_parser.set("max_print_height", new ConfigOptionInt(m_config.printable_height)); + m_placeholder_parser.set("z_offset", new ConfigOptionFloat(0.0f)); + m_placeholder_parser.set("plate_name", new ConfigOptionString(print.get_plate_name())); //BBS: calculate the volumetric speed of outer wall. Ignore pre-object setting and multi-filament, and just use the default setting { float filament_max_volumetric_speed = m_config.option("filament_max_volumetric_speed")->get_at(initial_non_support_extruder_id); diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index cb540c987..a5b99f67a 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -2167,6 +2167,8 @@ std::string Print::output_filename(const std::string &filename_base) const // These values will be just propagated into the output file name. DynamicConfig config = this->finished() ? this->print_statistics().config() : this->print_statistics().placeholders(); config.set_key_value("num_filaments", new ConfigOptionInt((int)m_config.nozzle_diameter.size())); + config.set_key_value("plate_name", new ConfigOptionString(get_plate_name())); + return this->PrintBase::output_filename(m_config.filename_format.value, ".gcode", filename_base, &config); } diff --git a/src/libslic3r/PrintBase.hpp b/src/libslic3r/PrintBase.hpp index 60087a396..db9ff4719 100644 --- a/src/libslic3r/PrintBase.hpp +++ b/src/libslic3r/PrintBase.hpp @@ -513,6 +513,9 @@ public: bool get_no_check_flag() const { return m_no_check; } void set_no_check_flag(bool no_check) { m_no_check = no_check; } + std::string get_plate_name() const { return m_plate_name; } + void set_plate_name(const std::string &name) { m_plate_name = name; } + protected: friend class PrintObjectBase; friend class BackgroundSlicingProcess; @@ -548,6 +551,8 @@ protected: int m_plate_index{ 0 }; bool m_no_check = false; + // current plate name + std::string m_plate_name; // Callback to be evoked regularly to update state of the UI thread. status_callback_type m_status_callback; diff --git a/src/slic3r/GUI/GLTexture.cpp b/src/slic3r/GUI/GLTexture.cpp index 74a755567..b0e28f3e6 100644 --- a/src/slic3r/GUI/GLTexture.cpp +++ b/src/slic3r/GUI/GLTexture.cpp @@ -483,7 +483,7 @@ bool GLTexture::generate_from_text(const std::string &text_str, wxFont &font, wx return false; } - wxString msg = _(text_str); + wxString msg = text_str; wxMemoryDC memDC; memDC.SetFont(font); diff --git a/src/slic3r/GUI/PartPlate.cpp b/src/slic3r/GUI/PartPlate.cpp index 0b737efb2..d7a8f823a 100644 --- a/src/slic3r/GUI/PartPlate.cpp +++ b/src/slic3r/GUI/PartPlate.cpp @@ -55,7 +55,7 @@ static const int PARTPLATE_ICON_GAP_Y = 5; static const int PARTPLATE_TEXT_OFFSET_X1 = 3; static const int PARTPLATE_TEXT_OFFSET_X2 = 1; static const int PARTPLATE_TEXT_OFFSET_Y = 1; - +std::array PlateTextureForeground = {0x0, 0xae, 0x42, 0xff}; namespace Slic3r { namespace GUI { @@ -413,6 +413,32 @@ void PartPlate::calc_vertex_for_number(int index, bool one_number, GeometryBuffe BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << "Unable to generate geometry buffers for icons\n"; } +void PartPlate::calc_vertex_for_plate_name(GLTexture &texture, GeometryBuffer &buffer) +{ + if (texture.get_width() > 0 && texture.get_height()) { + wxCoord w, h; + auto bed_ext = get_extents(m_shape); + auto factor = bed_ext.size()(1) / 200.0; + ExPolygon poly; + float offset_x = 1; + w = int(factor * (texture.get_width() * 16) / texture.get_height()); + h = int(factor * 16); + Vec2d p = bed_ext[3] + Vec2d(0, 1 + h * texture.m_original_height / texture.get_height()); + poly.contour.append({scale_(p(0) + PARTPLATE_ICON_GAP_LEFT + offset_x), scale_(p(1) - h + PARTPLATE_TEXT_OFFSET_Y)}); + poly.contour.append({scale_(p(0) + PARTPLATE_ICON_GAP_LEFT + w - offset_x), scale_(p(1) - h + PARTPLATE_TEXT_OFFSET_Y)}); + poly.contour.append({scale_(p(0) + PARTPLATE_ICON_GAP_LEFT + w - offset_x), scale_(p(1) - PARTPLATE_TEXT_OFFSET_Y)}); + poly.contour.append({scale_(p(0) + PARTPLATE_ICON_GAP_LEFT + offset_x), scale_(p(1) - PARTPLATE_TEXT_OFFSET_Y)}); + + auto triangles = triangulate_expolygon_2f(poly, NORMALS_UP); + if (!buffer.set_from_triangles(triangles, GROUND_Z)) BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << "Unable to generate geometry buffers for icons\n"; + + if (m_plate_name_vbo_id > 0) { + glsafe(::glDeleteBuffers(1, &m_plate_name_vbo_id)); + m_plate_name_vbo_id = 0; + } + } +} + void PartPlate::calc_vertex_for_icons(int index, GeometryBuffer &buffer) { ExPolygon poly; @@ -746,7 +772,37 @@ void PartPlate::render_icon_texture(int position_id, int tex_coords_id, const Ge glsafe(::glBindTexture(GL_TEXTURE_2D, 0)); } -void PartPlate::render_icons(bool bottom, int hover_id) const +void PartPlate::render_plate_name_texture(int position_id, int tex_coords_id) +{ + if (m_name.length() == 0) { + return; + } + if (m_name_texture.get_id() == 0 || m_name_change) { + m_name_change = false; + generate_plate_name_texture(); + calc_vertex_for_plate_name(m_name_texture, m_plate_name_icon); + } + + if (m_plate_name_vbo_id == 0 && m_plate_name_icon.get_vertices_data_size() > 0) { + glsafe(::glGenBuffers(1, &m_plate_name_vbo_id)); + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, m_plate_name_vbo_id)); + glsafe(::glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr) m_plate_name_icon.get_vertices_data_size(), (const GLvoid *) m_plate_name_icon.get_vertices_data(), GL_STATIC_DRAW)); + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); + } + + unsigned int stride = m_plate_name_icon.get_vertex_data_size(); + GLuint tex_id = (GLuint) m_name_texture.get_id(); + glsafe(::glBindTexture(GL_TEXTURE_2D, tex_id)); + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, m_plate_name_vbo_id)); + if (position_id != -1) glsafe(::glVertexAttribPointer(position_id, 3, GL_FLOAT, GL_FALSE, stride, (GLvoid *) (intptr_t) m_plate_name_icon.get_position_offset())); + if (tex_coords_id != -1) glsafe(::glVertexAttribPointer(tex_coords_id, 2, GL_FLOAT, GL_FALSE, stride, (GLvoid *) (intptr_t) m_plate_name_icon.get_tex_coords_offset())); + glsafe(::glDrawArrays(GL_TRIANGLES, 0, (GLsizei) m_plate_name_icon.get_vertices_count())); + + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); + glsafe(::glBindTexture(GL_TEXTURE_2D, 0)); +} + +void PartPlate::render_icons(bool bottom, bool only_body, int hover_id) { GLShaderProgram* shader = wxGetApp().get_shader("printbed"); if (shader != nullptr) { @@ -767,54 +823,54 @@ void PartPlate::render_icons(bool bottom, int hover_id) const if (tex_coords_id != -1) { glsafe(::glEnableVertexAttribArray(tex_coords_id)); } - - if (hover_id == 1) - render_icon_texture(position_id, tex_coords_id, m_del_icon, m_partplate_list->m_del_hovered_texture, m_del_vbo_id); - else - render_icon_texture(position_id, tex_coords_id, m_del_icon, m_partplate_list->m_del_texture, m_del_vbo_id); - - if (hover_id == 2) - render_icon_texture(position_id, tex_coords_id, m_orient_icon, m_partplate_list->m_orient_hovered_texture, m_orient_vbo_id); - else - render_icon_texture(position_id, tex_coords_id, m_orient_icon, m_partplate_list->m_orient_texture, m_orient_vbo_id); - - if (hover_id == 3) - render_icon_texture(position_id, tex_coords_id, m_arrange_icon, m_partplate_list->m_arrange_hovered_texture, m_arrange_vbo_id); - else - render_icon_texture(position_id, tex_coords_id, m_arrange_icon, m_partplate_list->m_arrange_texture, m_arrange_vbo_id); - - if (hover_id == 4) { - if (this->is_locked()) - render_icon_texture(position_id, tex_coords_id, m_lock_icon, m_partplate_list->m_locked_hovered_texture, m_lock_vbo_id); + if (!only_body) { + if (hover_id == 1) + render_icon_texture(position_id, tex_coords_id, m_del_icon, m_partplate_list->m_del_hovered_texture, m_del_vbo_id); else - render_icon_texture(position_id, tex_coords_id, m_lock_icon, m_partplate_list->m_lockopen_hovered_texture, m_lock_vbo_id); - } - else { - if (this->is_locked()) - render_icon_texture(position_id, tex_coords_id, m_lock_icon, m_partplate_list->m_locked_texture, m_lock_vbo_id); - else - render_icon_texture(position_id, tex_coords_id, m_lock_icon, m_partplate_list->m_lockopen_texture, m_lock_vbo_id); - } + render_icon_texture(position_id, tex_coords_id, m_del_icon, m_partplate_list->m_del_texture, m_del_vbo_id); - if (m_partplate_list->render_plate_settings) { - if (hover_id == 5) { - if (get_bed_type() == BedType::btDefault && get_print_seq() == PrintSequence::ByDefault) - render_icon_texture(position_id, tex_coords_id, m_plate_settings_icon, m_partplate_list->m_plate_settings_hovered_texture, m_plate_settings_vbo_id); + if (hover_id == 2) + render_icon_texture(position_id, tex_coords_id, m_orient_icon, m_partplate_list->m_orient_hovered_texture, m_orient_vbo_id); + else + render_icon_texture(position_id, tex_coords_id, m_orient_icon, m_partplate_list->m_orient_texture, m_orient_vbo_id); + + if (hover_id == 3) + render_icon_texture(position_id, tex_coords_id, m_arrange_icon, m_partplate_list->m_arrange_hovered_texture, m_arrange_vbo_id); + else + render_icon_texture(position_id, tex_coords_id, m_arrange_icon, m_partplate_list->m_arrange_texture, m_arrange_vbo_id); + + if (hover_id == 4) { + if (this->is_locked()) + render_icon_texture(position_id, tex_coords_id, m_lock_icon, m_partplate_list->m_locked_hovered_texture, m_lock_vbo_id); else - render_icon_texture(position_id, tex_coords_id, m_plate_settings_icon, m_partplate_list->m_plate_settings_changed_hovered_texture, m_plate_settings_vbo_id); + render_icon_texture(position_id, tex_coords_id, m_lock_icon, m_partplate_list->m_lockopen_hovered_texture, m_lock_vbo_id); + } else { + if (this->is_locked()) + render_icon_texture(position_id, tex_coords_id, m_lock_icon, m_partplate_list->m_locked_texture, m_lock_vbo_id); + else + render_icon_texture(position_id, tex_coords_id, m_lock_icon, m_partplate_list->m_lockopen_texture, m_lock_vbo_id); } - else { - if (get_bed_type() == BedType::btDefault && get_print_seq() == PrintSequence::ByDefault) - render_icon_texture(position_id, tex_coords_id, m_plate_settings_icon, m_partplate_list->m_plate_settings_texture, m_plate_settings_vbo_id); - else - render_icon_texture(position_id, tex_coords_id, m_plate_settings_icon, m_partplate_list->m_plate_settings_changed_texture, m_plate_settings_vbo_id); + + if (m_partplate_list->render_plate_settings) { + if (hover_id == 5) { + if (get_bed_type() == BedType::btDefault && get_print_seq() == PrintSequence::ByDefault) + render_icon_texture(position_id, tex_coords_id, m_plate_settings_icon, m_partplate_list->m_plate_settings_hovered_texture, m_plate_settings_vbo_id); + else + render_icon_texture(position_id, tex_coords_id, m_plate_settings_icon, m_partplate_list->m_plate_settings_changed_hovered_texture, + m_plate_settings_vbo_id); + } else { + if (get_bed_type() == BedType::btDefault && get_print_seq() == PrintSequence::ByDefault) + render_icon_texture(position_id, tex_coords_id, m_plate_settings_icon, m_partplate_list->m_plate_settings_texture, m_plate_settings_vbo_id); + else + render_icon_texture(position_id, tex_coords_id, m_plate_settings_icon, m_partplate_list->m_plate_settings_changed_texture, m_plate_settings_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); } } - - 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); - } - + render_plate_name_texture(position_id, tex_coords_id); if (tex_coords_id != -1) glsafe(::glDisableVertexAttribArray(tex_coords_id)); @@ -1191,6 +1247,10 @@ void PartPlate::release_opengl_resource() glsafe(::glDeleteBuffers(1, &m_plate_idx_vbo_id)); m_plate_idx_vbo_id = 0; } + if (m_plate_name_vbo_id > 0) { + glsafe(::glDeleteBuffers(1, &m_plate_name_vbo_id)); + m_plate_name_vbo_id = 0; + } } std::vector PartPlate::get_extruders(bool conside_custom_gcode) const @@ -1478,6 +1538,31 @@ Vec3d PartPlate::get_center_origin() return origin; } +bool PartPlate::generate_plate_name_texture() +{ + // generate m_name_texture texture from m_name with generate_from_text_string + m_name_texture.reset(); + auto *font = &Label::Head_32; + wxColour NumberForeground(PlateTextureForeground[0], PlateTextureForeground[1], PlateTextureForeground[2], PlateTextureForeground[3]); + if (!m_name_texture.generate_from_text_string(m_name, *font, *wxBLACK, NumberForeground)) { + BOOST_LOG_TRIVIAL(error) << "PartPlate::generate_plate_name_texture(): generate_from_text_string() failed"; + return false; + } + return true; +} + +void PartPlate::set_plate_name(const std::string &name) +{ + // compare if name equal to m_name, case sensitive + if (boost::equals(m_name, name)) return; + + m_name = name; + m_name_change = true; + if (m_print != nullptr) + m_print->set_plate_name(name); + +} + //get the print's object, result and index void PartPlate::get_print(PrintBase** print, GCodeResult** result, int* index) { @@ -2106,8 +2191,8 @@ bool PartPlate::set_shape(const Pointfs& shape, const Pointfs& exclude_areas, Ve calc_vertex_for_icons(4, m_plate_settings_icon); //calc_vertex_for_number(0, (m_plate_index < 9), m_plate_idx_icon); calc_vertex_for_number(0, false, m_plate_idx_icon); + calc_vertex_for_plate_name(m_name_texture, m_plate_name_icon);//if (generate_plate_name_texture()) } - calc_height_limit(); release_opengl_resource(); @@ -2178,35 +2263,8 @@ void PartPlate::render(bool bottom, bool only_body, bool force_background_color, render_height_limit(mode); - if (!only_body) { - /*float render_color[4]; - ::memcpy((void*)m_grabber_color, (const void*)DEFAULT_HIGHLIGHT_COLOR, 4 * sizeof(float)); - - render_color[0] = 1.0f - m_grabber_color[0]; - render_color[1] = 1.0f - m_grabber_color[1]; - render_color[2] = 1.0f - m_grabber_color[2]; - render_color[3] = m_grabber_color[3]; - - - if (m_hover_id == 0) - render_grabber(m_grabber_color, true); - else - render_grabber(render_color, true); - - if (m_selected) { - if (m_hover_id == 1) - render_left_arrow(m_grabber_color, true); - else - render_left_arrow(render_color, true); - - if (m_hover_id == 2) - render_right_arrow(m_grabber_color, true); - else - render_right_arrow(render_color, true); - }*/ - render_icons(bottom, hover_id); - } - else if (!force_background_color){ + render_icons(bottom, only_body, hover_id); + if (!force_background_color){ render_only_numbers(bottom); } glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); @@ -2711,9 +2769,8 @@ void PartPlateList::generate_icon_textures() file_name = std::string("0") + std::to_string(i+1); else file_name = std::to_string(i+1); - - wxColour foreground(0x0, 0xae, 0x42, 0xff); - if (!m_idx_textures[i].generate_from_text_string(file_name, *font, *wxBLACK, foreground)) { + wxColour NumberForeground(PlateTextureForeground[0], PlateTextureForeground[1], PlateTextureForeground[2], PlateTextureForeground[3]); + if (!m_idx_textures[i].generate_from_text_string(file_name, *font, *wxBLACK, NumberForeground)) { BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(":load file %1% failed") % file_name; } } @@ -4430,6 +4487,7 @@ int PartPlateList::store_to_3mf_structure(PlateDataPtrs& plate_data_list, bool w PlateData* plate_data_item = new PlateData(); plate_data_item->locked = m_plate_list[i]->m_locked; plate_data_item->plate_index = m_plate_list[i]->m_plate_index; + plate_data_item->plate_name = m_plate_list[i]->get_plate_name(); BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": plate %1% before load, width %2%, height %3%, size %4%!") %(i+1) %m_plate_list[i]->thumbnail_data.width %m_plate_list[i]->thumbnail_data.height %m_plate_list[i]->thumbnail_data.pixels.size(); plate_data_item->plate_thumbnail.load_from(m_plate_list[i]->thumbnail_data); @@ -4508,6 +4566,7 @@ int PartPlateList::load_from_3mf_structure(PlateDataPtrs& plate_data_list) int index = create_plate(false); m_plate_list[index]->m_locked = plate_data_list[i]->locked; m_plate_list[index]->config()->apply(plate_data_list[i]->config); + m_plate_list[index]->set_plate_name(plate_data_list[i]->plate_name); if (plate_data_list[i]->plate_index != index) { BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(":plate index %1% seems invalid, skip it")% plate_data_list[i]->plate_index; diff --git a/src/slic3r/GUI/PartPlate.hpp b/src/slic3r/GUI/PartPlate.hpp index 47c9cfd9f..46de2b62e 100644 --- a/src/slic3r/GUI/PartPlate.hpp +++ b/src/slic3r/GUI/PartPlate.hpp @@ -148,6 +148,13 @@ private: // BBS DynamicPrintConfig m_config; + // part plate name + std::string m_name; + bool m_name_change = false; + GeometryBuffer m_plate_name_icon; + mutable unsigned int m_plate_name_vbo_id{0}; + GLTexture m_name_texture; + void init(); bool valid_instance(int obj_id, int instance_id); void generate_print_polygon(ExPolygon &print_polygon); @@ -159,6 +166,7 @@ private: void calc_gridlines(const ExPolygon& poly, const BoundingBox& pp_bbox); void calc_height_limit(); void calc_vertex_for_number(int index, bool one_number, GeometryBuffer &buffer); + void calc_vertex_for_plate_name(GLTexture& texture, GeometryBuffer &buffer); void calc_vertex_for_icons(int index, GeometryBuffer &buffer); void calc_vertex_for_icons_background(int icon_count, GeometryBuffer &buffer); void render_background(bool force_default_color = false) const; @@ -175,7 +183,8 @@ private: void render_left_arrow(const float* render_color, bool use_lighting) const; void render_right_arrow(const float* render_color, bool use_lighting) const; void render_icon_texture(int position_id, int tex_coords_id, const GeometryBuffer &buffer, GLTexture &texture, unsigned int &vbo_id) const; - void render_icons(bool bottom, int hover_id = -1) const; + void render_plate_name_texture(int position_id, int tex_coords_id); + void render_icons(bool bottom, bool only_body = false, int hover_id = -1); void render_only_numbers(bool bottom) const; void render_rectangle_for_picking(const GeometryBuffer &buffer, const float* render_color) const; void on_render_for_picking() const; @@ -241,10 +250,17 @@ public: //set the plate's index void set_index(int index); - - //get the plate's index + // get the plate's index int get_index() { return m_plate_index; } + // get the plate's name + std::string get_plate_name() const { return m_name; } + bool generate_plate_name_texture(); + // set the plate's name + void set_plate_name(const std::string &name); + + + //get the print's object, result and index void get_print(PrintBase **print, GCodeResult **result, int *index); @@ -624,6 +640,7 @@ public: int get_curr_plate_index() const { return m_current_plate; } PartPlate* get_curr_plate() { return m_plate_list[m_current_plate]; } + const PartPlate *get_curr_plate() const { return m_plate_list[m_current_plate]; } std::vector& get_plate_list() { return m_plate_list; }; diff --git a/src/slic3r/GUI/PlateSettingsDialog.cpp b/src/slic3r/GUI/PlateSettingsDialog.cpp index 376714789..d0a155a02 100644 --- a/src/slic3r/GUI/PlateSettingsDialog.cpp +++ b/src/slic3r/GUI/PlateSettingsDialog.cpp @@ -43,6 +43,13 @@ PlateSettingsDialog::PlateSettingsDialog(wxWindow* parent, wxWindowID id, const top_sizer->Add(m_print_seq_txt, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT |wxALL, FromDIP(5)); top_sizer->Add(m_print_seq_choice, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT |wxALL, FromDIP(5)); + auto plate_name_txt = new wxStaticText(this, wxID_ANY, _L("Plate name")); + plate_name_txt->SetFont(Label::Body_14); + m_ti_plate_name = new TextInput(this, wxString::FromDouble(0.0), "", "", wxDefaultPosition, wxSize(FromDIP(240), -1), wxTE_PROCESS_ENTER); + top_sizer->Add(plate_name_txt, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT | wxALL, FromDIP(5)); + top_sizer->Add(m_ti_plate_name, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, FromDIP(5)); + m_ti_plate_name->GetTextCtrl()->SetMaxLength(14); + m_sizer_main->Add(top_sizer, 0, wxEXPAND | wxALL, FromDIP(30)); auto sizer_button = new wxBoxSizer(wxHORIZONTAL); @@ -155,4 +162,11 @@ void PlateSettingsDialog::on_dpi_changed(const wxRect& suggested_rect) m_button_cancel->Rescale(); } +wxString PlateSettingsDialog::get_plate_name() const { return m_ti_plate_name->GetTextCtrl()->GetValue(); +} + +void PlateSettingsDialog::set_plate_name(const wxString &name) { + m_ti_plate_name->GetTextCtrl()->SetValue(name); } + + }} // namespace Slic3r::GUI \ No newline at end of file diff --git a/src/slic3r/GUI/PlateSettingsDialog.hpp b/src/slic3r/GUI/PlateSettingsDialog.hpp index 6cb7b592f..2ba0721d3 100644 --- a/src/slic3r/GUI/PlateSettingsDialog.hpp +++ b/src/slic3r/GUI/PlateSettingsDialog.hpp @@ -49,11 +49,15 @@ public: return choice; }; + wxString get_plate_name() const; + void set_plate_name(const wxString &name); + protected: ComboBox* m_print_seq_choice { nullptr }; ComboBox* m_bed_type_choice { nullptr }; Button* m_button_ok; Button* m_button_cancel; + TextInput *m_ti_plate_name; }; }} // namespace Slic3r::GUI diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index e94b43514..7dcd70924 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -2131,7 +2131,7 @@ struct Plater::priv // returns the path to project file with the given extension (none if extension == wxEmptyString) // extension should contain the leading dot, i.e.: ".3mf" wxString get_project_filename(const wxString& extension = wxEmptyString) const; - wxString get_export_gcode_filename(const wxString& extension = wxEmptyString, bool only_filename = false, bool export_all = false) const; + wxString get_export_gcode_filename(const wxString& extension = wxEmptyString, bool only_filename = false, bool export_all = false) ; void set_project_filename(const wxString& filename); //BBS store bbs project name @@ -4656,7 +4656,7 @@ unsigned int Plater::priv::update_restart_background_process(bool force_update_s } void Plater::priv::update_fff_scene() -{ +{ if (this->preview != nullptr) this->preview->reload_print(); // In case this was MM print, wipe tower bounding box on 3D tab might need redrawing with exact depth: @@ -6569,9 +6569,16 @@ wxString Plater::priv::get_project_filename(const wxString& extension) const } } -wxString Plater::priv::get_export_gcode_filename(const wxString& extension, bool only_filename, bool export_all) const +wxString Plater::priv::get_export_gcode_filename(const wxString& extension, bool only_filename, bool export_all) { - std::string plate_index_str = (boost::format("_plate_%1%") % std::to_string(partplate_list.get_curr_plate_index() + 1)).str(); + std::string plate_index_str = ""; + + auto plate_name = partplate_list.get_curr_plate()->get_plate_name(); + if (!plate_name.empty()) + plate_index_str = (boost::format("_%1%") % plate_name).str(); + else if (partplate_list.get_plate_count() > 1) + plate_index_str = (boost::format("_plate_%1%") % std::to_string(partplate_list.get_curr_plate_index() + 1)).str(); + if (!m_project_folder.empty()) { if (!only_filename) { if (export_all) { @@ -11253,6 +11260,8 @@ int Plater::select_plate_by_hover_id(int hover_id, bool right_click) else dlg.sync_print_seq(0); + dlg.set_plate_name(curr_plate->get_plate_name()); + dlg.Bind(EVT_SET_BED_TYPE_CONFIRM, [this, plate_index, &dlg](wxCommandEvent& e) { PartPlate *curr_plate = p->partplate_list.get_curr_plate(); BedType old_bed_type = curr_plate->get_bed_type(); @@ -11278,6 +11287,8 @@ int Plater::select_plate_by_hover_id(int hover_id, bool right_click) }); dlg.ShowModal(); + curr_plate->set_plate_name(dlg.get_plate_name().ToStdString()); + this->schedule_background_process(); } else { diff --git a/src/slic3r/GUI/Widgets/Label.cpp b/src/slic3r/GUI/Widgets/Label.cpp index 8d23033bd..dbbf41a8d 100644 --- a/src/slic3r/GUI/Widgets/Label.cpp +++ b/src/slic3r/GUI/Widgets/Label.cpp @@ -21,6 +21,8 @@ wxFont Label::sysFont(int size, bool bold) } return font; } +wxFont Label::Head_48; +wxFont Label::Head_32; wxFont Label::Head_24; wxFont Label::Head_20; wxFont Label::Head_18; @@ -54,7 +56,8 @@ void Label::initSysFont() //BOOST_LOG_TRIVIAL(info) << boost::format("add font of HarmonyOS_Sans_SC_Regular returns %1%")%result; printf("add font of HarmonyOS_Sans_SC_Regular returns %d\n", result); #endif - + Head_48 = Label::sysFont(48, true); + Head_32 = Label::sysFont(32, true); Head_24 = Label::sysFont(24, true); Head_20 = Label::sysFont(20, true); Head_18 = Label::sysFont(18, true); diff --git a/src/slic3r/GUI/Widgets/Label.hpp b/src/slic3r/GUI/Widgets/Label.hpp index e13faf560..a56be4282 100644 --- a/src/slic3r/GUI/Widgets/Label.hpp +++ b/src/slic3r/GUI/Widgets/Label.hpp @@ -25,6 +25,8 @@ private: wxColour color; public: + static wxFont Head_48; + static wxFont Head_32; static wxFont Head_24; static wxFont Head_20; static wxFont Head_18;