From b243bac28222a19aa1ee63499dc028c2cc990fe2 Mon Sep 17 00:00:00 2001 From: SoftFever Date: Wed, 29 Mar 2023 21:16:39 +0800 Subject: [PATCH 1/3] fix clang-format --- .clang-format | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.clang-format b/.clang-format index e8e14f5c0c..5412395cf8 100644 --- a/.clang-format +++ b/.clang-format @@ -153,7 +153,7 @@ Standard: Latest StatementMacros: - Q_UNUSED - QT_REQUIRE_VERSION -TabWidth: 8 +TabWidth: 4 UseCRLF: false UseTab: Never WhitespaceSensitiveMacros: From f5c4cc9a54bf511ce197ec0899ffec2d0ebb99ba Mon Sep 17 00:00:00 2001 From: SoftFever Date: Wed, 29 Mar 2023 21:36:14 +0800 Subject: [PATCH 2/3] New feature: plate name --- src/libslic3r/Format/bbs_3mf.cpp | 7 + src/libslic3r/Format/bbs_3mf.hpp | 1 + src/libslic3r/GCode.cpp | 1 + src/libslic3r/Print.cpp | 2 + src/libslic3r/PrintBase.hpp | 6 + src/slic3r/GUI/GLTexture.cpp | 8 +- src/slic3r/GUI/PartPlate.cpp | 278 ++++++++++++++++--------- src/slic3r/GUI/PartPlate.hpp | 21 +- src/slic3r/GUI/PlateSettingsDialog.cpp | 29 ++- src/slic3r/GUI/PlateSettingsDialog.hpp | 4 + src/slic3r/GUI/Plater.cpp | 3 + src/slic3r/GUI/Tab.cpp | 2 +- src/slic3r/GUI/Widgets/Label.cpp | 2 + src/slic3r/GUI/Widgets/Label.hpp | 1 + src/slic3r/GUI/Widgets/TabCtrl.cpp | 2 +- 15 files changed, 254 insertions(+), 113 deletions(-) diff --git a/src/libslic3r/Format/bbs_3mf.cpp b/src/libslic3r/Format/bbs_3mf.cpp index dce4862c87..4a4829d76b 100644 --- a/src/libslic3r/Format/bbs_3mf.cpp +++ b/src/libslic3r/Format/bbs_3mf.cpp @@ -249,6 +249,7 @@ static constexpr const char* OBJECT_ID_ATTR = "object_id"; static constexpr const char* INSTANCEID_ATTR = "instance_id"; static constexpr const char* ARRANGE_ORDER_ATTR = "arrange_order"; 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"; @@ -1765,6 +1766,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; @@ -3467,6 +3469,10 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) { m_curr_plater->plate_index = atoi(value.c_str()); } + else if(key == PLATER_NAME_ATTR) + { + m_curr_plater->plate_name = value; + } else if (key == LOCK_ATTR) { std::istringstream(value) >> std::boolalpha >> m_curr_plater->locked; @@ -6431,6 +6437,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 << "=\"" << plate_data->plate_name << "\"/>\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 e0914f6774..9a09877be5 100644 --- a/src/libslic3r/Format/bbs_3mf.hpp +++ b/src/libslic3r/Format/bbs_3mf.hpp @@ -70,6 +70,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 c4a77ae752..66ec6e0d78 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -1758,6 +1758,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato 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 { diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 492ad178d4..dc8017d76e 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -2152,6 +2152,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 0d8730b073..e4d4b5534e 100644 --- a/src/libslic3r/PrintBase.hpp +++ b/src/libslic3r/PrintBase.hpp @@ -511,6 +511,9 @@ public: int get_plate_index() const { return m_plate_index; } void set_plate_index(int index) { m_plate_index = index; } + //SoftFever plate name + 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; @@ -545,6 +548,9 @@ protected: //BBS: add plate id into print base int m_plate_index{ 0 }; + // SoftFever: 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 74a7555675..06b89a56bd 100644 --- a/src/slic3r/GUI/GLTexture.cpp +++ b/src/slic3r/GUI/GLTexture.cpp @@ -516,11 +516,9 @@ bool GLTexture::generate_from_text(const std::string &text_str, wxFont &font, wx // prepare buffer std::vector data(4 * m_width * m_height, 0); const unsigned char* src = image.GetData(); - /* for debug use - std::ofstream fout; - fout.open(text_str+std::to_string(m_width)+"_"+std::to_string(m_height)+".rgb", std::ios::out); - fout.write((const char*)src, 3 * m_width * m_height); - fout.close();*/ + //for debug use + //image.SaveFile(text_str+"_test.png", wxBITMAP_TYPE_PNG); + for (int h = 0; h < m_height; ++h) { unsigned char* dst = data.data() + 4 * h * m_width; for (int w = 0; w < m_width; ++w) { diff --git a/src/slic3r/GUI/PartPlate.cpp b/src/slic3r/GUI/PartPlate.cpp index 8784cec8e6..da331e37e1 100644 --- a/src/slic3r/GUI/PartPlate.cpp +++ b/src/slic3r/GUI/PartPlate.cpp @@ -74,7 +74,44 @@ std::array PartPlate::LINE_BOTTOM_COLOR = { 0.8f, 0.8f, 0.8f, 0.4f }; std::array PartPlate::HEIGHT_LIMIT_TOP_COLOR = { 0.6f, 0.6f, 1.0f, 1.0f }; std::array PartPlate::HEIGHT_LIMIT_BOTTOM_COLOR = { 0.4f, 0.4f, 1.0f, 1.0f }; +// get text extent with wxMemoryDC +void get_text_extent(const wxString &msg, wxCoord &w, wxCoord &h, wxFont *font) +{ + wxMemoryDC memDC; + if (font) + memDC.SetFont(*font); + memDC.GetTextExtent(msg, &w, &h); +} + +wxFont* find_font(const std::string& text_str, int max_size = 32) +{ + auto is_font_suitable = [](std::string str, wxFont &font, int max_size) { + wxString msg(str); + wxCoord w, h; + get_text_extent(msg, w, h, &font); + + if (w <= max_size) + return true; + else + return false; + }; + wxFont *font = nullptr; + if (is_font_suitable(text_str, Label::Head_24, max_size)) + font = &Label::Head_24; + else if (is_font_suitable(text_str, Label::Head_20, max_size)) + font = &Label::Head_20; + else if (is_font_suitable(text_str, Label::Head_18, max_size)) + font = &Label::Head_18; + else if (is_font_suitable(text_str, Label::Head_16, max_size)) + font = &Label::Head_16; + else if (is_font_suitable(text_str, Label::Head_14, max_size)) + font = &Label::Head_14; + else + font = &Label::Head_12; + + return font; +} void PartPlate::update_render_colors() { PartPlate::SELECT_COLOR = GLColor(RenderColor::colors[RenderCol_Plate_Selected]); @@ -131,6 +168,7 @@ void PartPlate::init() m_print_index = -1; m_print = nullptr; + m_plate_name_vbo_id = 0; } BedType PartPlate::get_bed_type() const @@ -744,8 +782,33 @@ void PartPlate::render_icon_texture(int position_id, int tex_coords_id, const Ge glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); glsafe(::glBindTexture(GL_TEXTURE_2D, 0)); } +void PartPlate::render_plate_name_texture(int position_id, int tex_coords_id) +{ + if (m_name_texture.get_id() == 0) + generate_plate_name_texture(); -void PartPlate::render_icons(bool bottom, int hover_id) const + 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_name, int hover_id) { GLShaderProgram* shader = wxGetApp().get_shader("printbed"); if (shader != nullptr) { @@ -766,54 +829,69 @@ 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_name) { + 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)); @@ -1190,6 +1268,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 @@ -1385,7 +1467,7 @@ void PartPlate::clear(bool clear_sliced_result) m_ready_for_slice = true; update_slice_result_valid_state(false); } - + m_name_texture.reset(); return; } @@ -1473,6 +1555,50 @@ Vec3d PartPlate::get_center_origin() return origin; } +void PartPlate::generate_plate_name_texture() +{ + // generate m_name_texture texture from m_name with generate_from_text_string + m_name_texture.reset(); + auto text = m_name.empty()? _L("Untitled") : m_name; + wxCoord w, h; + auto* font = &Label::Head_48; + wxColour foreground(0x0, 0x96, 0x88, 0xff); + if (!m_name_texture.generate_from_text_string(text.ToStdString(), *font, *wxBLACK, foreground)) + BOOST_LOG_TRIVIAL(error) << "PartPlate::generate_plate_name_texture(): generate_from_text_string() failed"; + auto bed_ext = get_extents(m_shape); + auto factor = bed_ext.size()(1) / 200.0; + ExPolygon poly; + float offset_x = 1; + w = int(factor * (m_name_texture.get_width() * 16) / m_name_texture.get_height()); + h = int(factor * 16); + Vec2d p = m_shape[3] + Vec2d(0, h*0.6); + 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 (!m_plate_name_icon.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::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; + if (m_print != nullptr) + m_print->set_plate_name(name); + + generate_plate_name_texture(); +} + //get the print's object, result and index void PartPlate::get_print(PrintBase** print, GCodeResult** result, int* index) { @@ -2100,6 +2226,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 + generate_plate_name_texture(); } calc_height_limit(); @@ -2172,35 +2300,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)); @@ -2666,32 +2767,9 @@ void PartPlateList::generate_icon_textures() } } - auto is_font_suitable = [](std::string text_str, wxFont& font, int max_size) { - wxMemoryDC memDC; - wxCoord w, h; - wxString msg(text_str); - memDC.SetFont(font); - memDC.GetMultiLineTextExtent(msg, &w, &h); - if (w <= max_size) - return true; - else - return false;; - }; - wxFont* font = nullptr; + std::string text_str = "01"; - int max_size = 32; - if (is_font_suitable(text_str, Label::Head_24, max_size)) - font = &Label::Head_24; - else if (is_font_suitable(text_str, Label::Head_20, max_size)) - font = &Label::Head_20; - else if (is_font_suitable(text_str, Label::Head_18, max_size)) - font = &Label::Head_18; - else if (is_font_suitable(text_str, Label::Head_16, max_size)) - font = &Label::Head_16; - else if (is_font_suitable(text_str, Label::Head_14, max_size)) - font = &Label::Head_14; - else - font = &Label::Head_12; + wxFont* font = find_font(text_str,32); for (int i = 0; i < MAX_PLATE_COUNT; i++) { if (m_idx_textures[i].get_id() == 0) { @@ -2701,7 +2779,7 @@ void PartPlateList::generate_icon_textures() else file_name = std::to_string(i+1); - wxColour foreground(0x0, 0xae, 0x42, 0xff); + wxColour foreground(0x0, 0x96, 0x88, 0xff); if (!m_idx_textures[i].generate_from_text_string(file_name, *font, *wxBLACK, foreground)) { BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(":load file %1% failed") % file_name; } @@ -4409,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); @@ -4482,6 +4561,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 edc876d9b5..422fd521ad 100644 --- a/src/slic3r/GUI/PartPlate.hpp +++ b/src/slic3r/GUI/PartPlate.hpp @@ -148,6 +148,15 @@ private: // BBS DynamicPrintConfig m_config; + // SoftFever + // part plate name + std::string m_name; + GeometryBuffer m_plate_name_icon; + mutable unsigned int m_plate_name_vbo_id{ 0 }; + GLTexture m_name_texture; + wxCoord m_name_texture_width; + wxCoord m_name_texture_height; + void init(); bool valid_instance(int obj_id, int instance_id); void generate_print_polygon(ExPolygon &print_polygon); @@ -161,6 +170,8 @@ private: void calc_vertex_for_number(int index, bool one_number, GeometryBuffer &buffer); void calc_vertex_for_icons(int index, GeometryBuffer &buffer); void calc_vertex_for_icons_background(int icon_count, GeometryBuffer &buffer); + //void calc_vertex_for_name_tex(GeometryBuffer &buffer); + void render_background(bool force_default_color = false) const; void render_logo(bool bottom) const; void render_logo_texture(GLTexture& logo_texture, const GeometryBuffer& logo_buffer, bool bottom, unsigned int vbo_id) const; @@ -175,8 +186,9 @@ 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_icons(bool bottom, bool only_name = false, int hover_id = -1); void render_only_numbers(bool bottom) const; + void render_plate_name_texture(int position_id, int tex_coords_id); void render_rectangle_for_picking(const GeometryBuffer &buffer, const float* render_color) const; void on_render_for_picking() const; std::array picking_color_component(int idx) const; @@ -242,6 +254,13 @@ public: //get the plate's index int get_index() { return m_plate_index; } + // SoftFever + //get the plate's name + std::string get_plate_name() { return m_name; } + void 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); diff --git a/src/slic3r/GUI/PlateSettingsDialog.cpp b/src/slic3r/GUI/PlateSettingsDialog.cpp index 723c67f6a0..eb44b19aca 100644 --- a/src/slic3r/GUI/PlateSettingsDialog.cpp +++ b/src/slic3r/GUI/PlateSettingsDialog.cpp @@ -23,14 +23,19 @@ PlateSettingsDialog::PlateSettingsDialog(wxWindow* parent, wxWindowID id, const top_sizer->SetFlexibleDirection(wxBOTH); top_sizer->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED); - m_bed_type_choice = new ComboBox( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(FromDIP(240),-1), 0, NULL, wxCB_READONLY ); - for (BedType i = btDefault; i < btCount; i = BedType(int(i) + 1)) { + bool is_bbl = wxGetApp().preset_bundle->printers.get_edited_preset().is_bbl_vendor_preset(wxGetApp().preset_bundle); + if (is_bbl) { + m_bed_type_choice = new ComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(FromDIP(240), -1), 0, + NULL, wxCB_READONLY); + for (BedType i = btDefault; i < btCount; i = BedType(int(i) + 1)) { m_bed_type_choice->Append(to_bed_type_name(i)); + } + wxStaticText *m_bed_type_txt = new wxStaticText(this, wxID_ANY, _L("Bed type")); + m_bed_type_txt->SetFont(Label::Body_14); + top_sizer->Add(m_bed_type_txt, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT | wxALL, FromDIP(5)); + top_sizer->Add(m_bed_type_choice, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, FromDIP(5)); } - wxStaticText* m_bed_type_txt = new wxStaticText(this, wxID_ANY, _L("Bed type")); - m_bed_type_txt->SetFont(Label::Body_14); - top_sizer->Add(m_bed_type_txt, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT | wxALL, FromDIP(5)); - top_sizer->Add(m_bed_type_choice, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT |wxALL, FromDIP(5)); + wxBoxSizer* m_sizer_selectbox = new wxBoxSizer(wxHORIZONTAL); m_print_seq_choice = new ComboBox( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(FromDIP(240),-1), 0, NULL, wxCB_READONLY ); @@ -43,6 +48,12 @@ 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_sizer_main->Add(top_sizer, 0, wxEXPAND | wxALL, FromDIP(30)); auto sizer_button = new wxBoxSizer(wxHORIZONTAL); @@ -155,4 +166,10 @@ 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 6cb7b592fd..404346b730 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 4a57fa09e0..eb523caa08 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -11508,6 +11508,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(); @@ -11531,6 +11533,7 @@ int Plater::select_plate_by_hover_id(int hover_id, bool right_click) wxGetApp().plater()->config_change_notification(plate_config, std::string("print_sequence")); }); dlg.ShowModal(); + curr_plate->set_plate_name(dlg.get_plate_name().ToStdString()); this->schedule_background_process(); } diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 0f70ba21a3..40ba091a9d 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -1647,7 +1647,7 @@ void Tab::on_presets_changed() 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); + wxGetApp().plater()->get_partplate_list().set_render_option(false, true); // Printer selected at the Printer tab, update "compatible" marks at the print and filament selectors. for (auto t: m_dependent_tabs) diff --git a/src/slic3r/GUI/Widgets/Label.cpp b/src/slic3r/GUI/Widgets/Label.cpp index 3d24d975f2..82ae281fcb 100644 --- a/src/slic3r/GUI/Widgets/Label.cpp +++ b/src/slic3r/GUI/Widgets/Label.cpp @@ -21,6 +21,7 @@ wxFont Label::sysFont(int size, bool bold) } return font; } +wxFont Label::Head_48; wxFont Label::Head_24; wxFont Label::Head_20; wxFont Label::Head_18; @@ -64,6 +65,7 @@ void Label::initSysFont() Head_12 = Label::sysFont(12, true); Head_10 = Label::sysFont(10, true); + Head_48 = Label::sysFont(48, true); Body_16 = Label::sysFont(16, false); Body_15 = Label::sysFont(15, false); Body_14 = Label::sysFont(14, false); diff --git a/src/slic3r/GUI/Widgets/Label.hpp b/src/slic3r/GUI/Widgets/Label.hpp index 950601b925..1330394964 100644 --- a/src/slic3r/GUI/Widgets/Label.hpp +++ b/src/slic3r/GUI/Widgets/Label.hpp @@ -35,6 +35,7 @@ public: static wxFont Head_12; static wxFont Head_10; + static wxFont Head_48; static wxFont Body_16; static wxFont Body_15; static wxFont Body_14; diff --git a/src/slic3r/GUI/Widgets/TabCtrl.cpp b/src/slic3r/GUI/Widgets/TabCtrl.cpp index c983a7e725..8928a24afb 100644 --- a/src/slic3r/GUI/Widgets/TabCtrl.cpp +++ b/src/slic3r/GUI/Widgets/TabCtrl.cpp @@ -302,7 +302,7 @@ void TabCtrl::doRender(wxDC& dc) #else dc.SetPen(wxPen(border_color.colorForStates(states), border_width)); dc.DrawLine(0, size.y - BS2, size.x, size.y - BS2); - wxColor c(0x42AE00); + wxColor c(0x968800); dc.SetPen(wxPen(c, 1)); dc.SetBrush(c); dc.DrawRoundedRectangle(x1 - radius, size.y - BS2 - border_width * 3, x2 + radius * 2 - x1, border_width * 3, radius); From ab73f0be6d1d7d614a22c6cdb23f00e2c1a94949 Mon Sep 17 00:00:00 2001 From: SoftFever Date: Wed, 29 Mar 2023 22:12:33 +0800 Subject: [PATCH 3/3] update locale --- bbl/i18n/de/OrcaSlicer_de.po | 172 +++++++++++++++++++++----------- resources/i18n/de/OrcaSlicer.mo | Bin 264233 -> 264137 bytes 2 files changed, 114 insertions(+), 58 deletions(-) diff --git a/bbl/i18n/de/OrcaSlicer_de.po b/bbl/i18n/de/OrcaSlicer_de.po index 1818d62c44..b8f0654276 100644 --- a/bbl/i18n/de/OrcaSlicer_de.po +++ b/bbl/i18n/de/OrcaSlicer_de.po @@ -458,7 +458,9 @@ msgid "" "OrcaSlicer will terminate because of running out of memory.It may be a bug. " "It will be appreciated if you report the issue to our team." msgstr "" -"OrcaSlicer wird aufgrund eines Speicherplatzmangels beendet. Es könnte sich um einen Fehler handeln. Wir würden es schätzen, wenn Sie das Problem unserem Team melden würden." +"OrcaSlicer wird aufgrund eines Speicherplatzmangels beendet. Es könnte sich " +"um einen Fehler handeln. Wir würden es schätzen, wenn Sie das Problem " +"unserem Team melden würden." msgid "Fatal error" msgstr "Fataler Fehler" @@ -467,7 +469,9 @@ msgid "" "OrcaSlicer will terminate because of a localization error. It will be " "appreciated if you report the specific scenario this issue happened." msgstr "" -"OrcaSlicer wird aufgrund eines Lokalisierungsfehlers beendet. Es wird geschätzt, wenn Sie das spezifische Szenario melden, in dem dieser Fehler aufgetreten ist." +"OrcaSlicer wird aufgrund eines Lokalisierungsfehlers beendet. Es wird " +"geschätzt, wenn Sie das spezifische Szenario melden, in dem dieser Fehler " +"aufgetreten ist." msgid "Critical error" msgstr "Kritischer Fehler" @@ -490,7 +494,9 @@ msgid "" "OrcaSlicer configuration file may be corrupted and is not abled to be parsed." "Please delete the file and try again." msgstr "" -"Die OrcaSlicer-Konfigurationsdatei ist möglicherweise beschädigt und kann nicht analysiert werden. Bitte löschen Sie die Datei und versuchen Sie es erneut." +"Die OrcaSlicer-Konfigurationsdatei ist möglicherweise beschädigt und kann " +"nicht analysiert werden. Bitte löschen Sie die Datei und versuchen Sie es " +"erneut." #, c-format, boost-format msgid "" @@ -1524,10 +1530,12 @@ msgid "" "The SLA archive doesn't contain any presets. Please activate some SLA " "printer preset first before importing that SLA archive." msgstr "" -"Die SLA-Archivdatei enthält keine Voreinstellungen. Bitte aktivieren Sie zuerst einige SLA-Druckervoreinstellungen, bevor Sie das SLA-Archiv importieren." +"Die SLA-Archivdatei enthält keine Voreinstellungen. Bitte aktivieren Sie " +"zuerst einige SLA-Druckervoreinstellungen, bevor Sie das SLA-Archiv " +"importieren." msgid "Importing canceled." -msgstr """Import abgebrochen." +msgstr "Import abgebrochen." msgid "Importing done." msgstr "Import erfolgreich." @@ -1536,13 +1544,17 @@ msgid "" "The imported SLA archive did not contain any presets. The current SLA " "presets were used as fallback." msgstr "" -"Die importierte SLA-Archivdatei enthält keine Voreinstellungen. Die aktuellen SLA-Voreinstellungen wurden als Fallback verwendet." +"Die importierte SLA-Archivdatei enthält keine Voreinstellungen. Die " +"aktuellen SLA-Voreinstellungen wurden als Fallback verwendet." msgid "You cannot load SLA project with a multi-part object on the bed" -msgstr "Du kannst kein SLA-Projekt mit einem mehrteiligen Objekt auf dem Druckbett laden." +msgstr "" +"Du kannst kein SLA-Projekt mit einem mehrteiligen Objekt auf dem Druckbett " +"laden." msgid "Please check your object list before preset changing." -msgstr "Bitte überprüfen Sie Ihre Objektliste vor der Änderung des Voreinstellungen." +msgstr "" +"Bitte überprüfen Sie Ihre Objektliste vor der Änderung des Voreinstellungen." msgid "Attention!" msgstr "Achtung!" @@ -1585,7 +1597,9 @@ msgid "" "by Prusa Research. PrusaSlicer is from Slic3r by Alessandro Ranellucci and " "the RepRap community" msgstr "" -"Orca Slicer basiert auf BambuStudio von Bambulab, welches von PrusaSlicer von Prusa Research stammt. PrusaSlicer wiederum basiert auf Slic3r von Alessandro Ranellucci und der RepRap-Community." +"Orca Slicer basiert auf BambuStudio von Bambulab, welches von PrusaSlicer " +"von Prusa Research stammt. PrusaSlicer wiederum basiert auf Slic3r von " +"Alessandro Ranellucci und der RepRap-Community." msgid "Libraries" msgstr "Bibliotheken" @@ -1668,7 +1682,9 @@ msgid "Factor N" msgstr "Faktor N" msgid "Setting Virtual slot information while printing is not supported" -msgstr "Das Einstellen von virtuellen Slot-Informationen während des Druckens wird nicht unterstützt." +msgstr "" +"Das Einstellen von virtuellen Slot-Informationen während des Druckens wird " +"nicht unterstützt." msgid "Please input a valid value (K in 0~0.5)" msgstr "Bitte geben Sie einen gültigen Wert ein (K im Bereich von 0 bis 0,5)" @@ -1784,7 +1800,9 @@ msgid "" "Green means that AMS humidity is normal, orange represent humidity is high, " "red represent humidity is too high.(Hygrometer: lower the better.)" msgstr "" -"Grün bedeutet, dass die Luftfeuchtigkeit der AMS normal ist, Orange bedeutet, dass die Luftfeuchtigkeit hoch ist und Rot bedeutet, dass die Luftfeuchtigkeit zu hoch ist. (Hygrometer: Je niedriger, desto besser.)" +"Grün bedeutet, dass die Luftfeuchtigkeit der AMS normal ist, Orange " +"bedeutet, dass die Luftfeuchtigkeit hoch ist und Rot bedeutet, dass die " +"Luftfeuchtigkeit zu hoch ist. (Hygrometer: Je niedriger, desto besser.)" msgid "Desiccant status" msgstr "Trockenmittelstatus" @@ -1793,7 +1811,9 @@ msgid "" "A desiccant status lower than two bars indicates that desiccant may be " "inactive. Please change the desiccant.(The bars: higher the better.)" msgstr "" -"Ein Desiccant-Status von weniger als zwei Balken zeigt an, dass der Desiccant möglicherweise inaktiv ist. Bitte wechseln Sie den Desiccant aus. (Die Balken: je höher, desto besser.)" +"Ein Desiccant-Status von weniger als zwei Balken zeigt an, dass der " +"Desiccant möglicherweise inaktiv ist. Bitte wechseln Sie den Desiccant aus. " +"(Die Balken: je höher, desto besser.)" msgid "" "Note: When the lid is open or the desiccant pack is changed, it can take " @@ -2217,7 +2237,9 @@ msgstr "" "Nein - Verzichten Sie dieses Mal auf den Spiralmodus" msgid "Arachne engine doesn't work with classic overhang speed mode.\n" -msgstr "Die Arachne-Engine funktioniert nicht im klassischen Überhanganpassungsmodus.\n" +msgstr "" +"Die Arachne-Engine funktioniert nicht im klassischen " +"Überhanganpassungsmodus.\n" msgid "" "Turn off classic mode automatically? \n" @@ -2282,7 +2304,8 @@ msgid "" "While printing by Object, the extruder may collide skirt.\n" "Thus, reset the skirt layer to 1 to avoid that." msgstr "" -"Während des Druckens mit einem Objekt kann der Extruder auf den Rand stoßen.\n" +"Während des Druckens mit einem Objekt kann der Extruder auf den Rand " +"stoßen.\n" "Daher sollten die Skirt-Ebenen zurückgesetzt werden." msgid "Auto bed leveling" @@ -2881,7 +2904,9 @@ msgid "No" msgstr "Nein" msgid "will be closed before creating a new model. Do you want to continue?" -msgstr "Bevor ein neues Modell erstellt wird, wird %1% geschlossen. Möchten Sie fortfahren?" +msgstr "" +"Bevor ein neues Modell erstellt wird, wird %1% geschlossen. Möchten Sie " +"fortfahren?" msgid "Slice plate" msgstr "Aktuelle Platte slicen" @@ -3213,11 +3238,15 @@ msgstr "&Hilfe" #, c-format, boost-format msgid "A file exists with the same name: %s, do you want to override it." -msgstr "Es existiert bereits eine Datei mit demselben Namen: %s. Möchten Sie sie überschreiben?" +msgstr "" +"Es existiert bereits eine Datei mit demselben Namen: %s. Möchten Sie sie " +"überschreiben?" #, c-format, boost-format msgid "A config exists with the same name: %s, do you want to override it." -msgstr "Eine Konfiguration mit dem gleichen Namen existiert bereits: %s. Möchten Sie sie überschreiben?" +msgstr "" +"Eine Konfiguration mit dem gleichen Namen existiert bereits: %s. Möchten Sie " +"sie überschreiben?" msgid "Overwrite file" msgstr "Datei überschreiben" @@ -3922,7 +3951,8 @@ msgid "" "Already did a synchronization, do you want to sync only changes or resync " "all?" msgstr "" -"Es wurde bereits eine Synchronisation durchgeführt. Möchtest du nur Änderungen synchronisieren oder alles neu synchronisieren?" +"Es wurde bereits eine Synchronisation durchgeführt. Möchtest du nur " +"Änderungen synchronisieren oder alles neu synchronisieren?" msgid "Sync" msgstr "Sync" @@ -4331,7 +4361,9 @@ msgid "" "still want to do this printing, please set this filament's bed temperature " "to non zero." msgstr "" -"Plate %d: %s wird nicht empfohlen, um Filament %s (%s) zu drucken. Wenn Sie dennoch diesen Druck durchführen möchten, stellen Sie bitte die Betttemperatur dieses Filaments auf einen Wert größer als Null." +"Plate %d: %s wird nicht empfohlen, um Filament %s (%s) zu drucken. Wenn Sie " +"dennoch diesen Druck durchführen möchten, stellen Sie bitte die " +"Betttemperatur dieses Filaments auf einen Wert größer als Null." msgid "Switching the language requires application restart.\n" msgstr "Der Wechsel der Sprache erfordert einen Neustart der Anwendung.\n" @@ -4928,7 +4960,9 @@ msgstr "" "wird" msgid "An SD card needs to be inserted before send to printer SD card." -msgstr "Bevor Sie die Datei an die SD-Karte des Druckers senden können, muss eine SD-Karte eingelegt werden." +msgstr "" +"Bevor Sie die Datei an die SD-Karte des Druckers senden können, muss eine SD-" +"Karte eingelegt werden." msgid "The printer is required to be in the same LAN as Orca Slicer." msgstr "Der Drucker muss sich im selben LAN wie OrcaSlicer befinden." @@ -5035,8 +5069,8 @@ 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\"." +"by right-click the empty position of build plate and choose \"Add Primitive" +"\"->\"Timelapse Wipe Tower\"." msgstr "" "Wenn Sie eine Zeitrafferaufnahme ohne Werkzeugkopf aufnehmen, wird " "empfohlen, einen „Timelapse Wipe Tower“ hinzuzufügen,\n" @@ -6414,7 +6448,9 @@ msgstr "Gerät" msgid "" "Specify the URL of your device user interface if it's not same as print_host" -msgstr "Bitte geben Sie die URL der Benutzeroberfläche Ihres Geräts an, falls sie nicht mit print_host identisch ist." +msgstr "" +"Bitte geben Sie die URL der Benutzeroberfläche Ihres Geräts an, falls sie " +"nicht mit print_host identisch ist." msgid "API Key / Password" msgstr "API Key / Passwort" @@ -6761,8 +6797,9 @@ msgid "" "This controls the generation of the brim at outer side of models. Auto means " "the brim width is analysed and calculated automatically." msgstr "" -"Dies steuert die Generierung des Brims auf der Außenseite von Modellen." -"Auto bedeutet, dass die Breite des Brims automatisch analysiert und berechnet wird." +"Dies steuert die Generierung des Brims auf der Außenseite von Modellen.Auto " +"bedeutet, dass die Breite des Brims automatisch analysiert und berechnet " +"wird." msgid "outer_only" msgstr "Nur Außen" @@ -6988,7 +7025,11 @@ msgid "" "example: 80%) it will be calculated on the outer wall speed setting above. " "Set to zero for auto." msgstr "" -"Diese separate Einstellung beeinflusst die Geschwindigkeit von Umfängen mit einem Radius <= small_perimeter_threshold (normalerweise Löcher). Wenn es als Prozentsatz ausgedrückt wird (z.B. 80%), wird es auf die oben genannte Einstellung der Geschwindigkeit der Außenwand berechnet. Setzen Sie es auf Null für automatisch." +"Diese separate Einstellung beeinflusst die Geschwindigkeit von Umfängen mit " +"einem Radius <= small_perimeter_threshold (normalerweise Löcher). Wenn es " +"als Prozentsatz ausgedrückt wird (z.B. 80%), wird es auf die oben genannte " +"Einstellung der Geschwindigkeit der Außenwand berechnet. Setzen Sie es auf " +"Null für automatisch." msgid "mm/s or %" msgstr "mm/s o. %" @@ -7205,7 +7246,6 @@ msgstr "" msgid "Shrinkage" msgstr "Schrumpfung" -#, c-format, boost-format msgid "" "Enter the shrinkage percentage that the filament will get after cooling " "(94% if you measure 94mm instead of 100mm). The part will be scaled in xy to " @@ -7213,11 +7253,12 @@ msgid "" "Be sure to allow enough space between objects, as this compensation is done " "after the checks." msgstr "" -"Gib das Schrumpfungsprozent ein, das der Filament nach dem Abkühlen haben wird" -"(94%, wenn du 94mm anstatt 100mm misst). Das Teil wird in der xy-Ebene skaliert, um zu" -"kompensieren. Nur das Filament, das für den Umfang verwendet wird, wird berücksichtigt." -"Stelle sicher, dass genügend Platz zwischen den Objekten vorhanden ist, da diese Kompensation " -"nach den Überprüfungen durchgeführt wird." +"Gib das Schrumpfungsprozent ein, das der Filament nach dem Abkühlen haben " +"wird(94%, wenn du 94mm anstatt 100mm misst). Das Teil wird in der xy-Ebene " +"skaliert, um zukompensieren. Nur das Filament, das für den Umfang verwendet " +"wird, wird berücksichtigt.Stelle sicher, dass genügend Platz zwischen den " +"Objekten vorhanden ist, da diese Kompensation nach den Überprüfungen " +"durchgeführt wird." msgid "Density" msgstr "Dichte" @@ -7363,8 +7404,9 @@ msgid "" "Acceleration of bridges. If the value is expressed as a percentage (e.g. " "50%), it will be calculated based on the outer wall acceleration." msgstr "" -"Beschleunigung der Brücken. Wenn der Wert als Prozentwert angegeben wird (z.B. " -"50%), wird er auf der Grundlage der Beschleunigung der Außenwand berechnet." +"Beschleunigung der Brücken. Wenn der Wert als Prozentwert angegeben wird (z." +"B. 50%), wird er auf der Grundlage der Beschleunigung der Außenwand " +"berechnet." msgid "mm/s² or %" msgstr "mm/s² or %" @@ -7373,15 +7415,18 @@ msgid "" "Acceleration of sparse infill. If the value is expressed as a percentage (e." "g. 100%), it will be calculated based on the default acceleration." msgstr "" -"Beschleunigung der spärlichen Innenfüllung. Wenn der Wert als Prozentwert angegeben wird (z.B. " -"100%), wird er auf der Grundlage der Standardbeschleunigung berechnet." +"Beschleunigung der spärlichen Innenfüllung. Wenn der Wert als Prozentwert " +"angegeben wird (z.B. 100%), wird er auf der Grundlage der " +"Standardbeschleunigung berechnet." msgid "" "Acceleration of internal solid infill. If the value is expressed as a " "percentage (e.g. 100%), it will be calculated based on the default " "acceleration." msgstr "" -"Beschleunigung des internen massiven Innenfülls. Wenn der Wert als Prozentwert angegeben wird (z.B. 100%), wird er auf der Grundlage der Standardbeschleunigung berechnet." +"Beschleunigung des internen massiven Innenfülls. Wenn der Wert als " +"Prozentwert angegeben wird (z.B. 100%), wird er auf der Grundlage der " +"Standardbeschleunigung berechnet." msgid "" "Acceleration of initial layer. Using a lower value can improve build plate " @@ -7604,7 +7649,11 @@ msgid "" "plugin. This settings is NOT compatible with Single Extruder Multi Material " "setup and Wipe into Object / Wipe into Infill." msgstr "" -"Aktivieren Sie diese Option, um Kommentare in den G-Code einzufügen, die die Druckbewegungen mit dem zugehörigen Objekt kennzeichnen. Dies ist nützlich für das Octoprint CancelObject-Plugin. Diese Einstellung ist NICHT kompatibel mit der Einzeldruckerdüsen-Mehrmaterial-Konfiguration und mit der Option zum Wischen in das Objekt / in den Innenfüllbereich." +"Aktivieren Sie diese Option, um Kommentare in den G-Code einzufügen, die die " +"Druckbewegungen mit dem zugehörigen Objekt kennzeichnen. Dies ist nützlich " +"für das Octoprint CancelObject-Plugin. Diese Einstellung ist NICHT " +"kompatibel mit der Einzeldruckerdüsen-Mehrmaterial-Konfiguration und mit der " +"Option zum Wischen in das Objekt / in den Innenfüllbereich." msgid "Verbose G-code" msgstr "ausführlicher G-Code" @@ -7614,7 +7663,10 @@ msgid "" "descriptive text. If you print from SD card, the additional weight of the " "file could make your firmware slow down." msgstr "" -"Aktivieren Sie diese Option, um eine kommentierte G-Code-Datei zu erhalten, in der jede Zeile durch einen beschreibenden Text erklärt wird. Wenn Sie von der SD-Karte drucken, kann das zusätzliche Gewicht der Datei dazu führen, dass Ihre Firmware langsamer wird." +"Aktivieren Sie diese Option, um eine kommentierte G-Code-Datei zu erhalten, " +"in der jede Zeile durch einen beschreibenden Text erklärt wird. Wenn Sie von " +"der SD-Karte drucken, kann das zusätzliche Gewicht der Datei dazu führen, " +"dass Ihre Firmware langsamer wird." msgid "Infill combination" msgstr "Füllungskombination" @@ -7913,8 +7965,7 @@ msgid "Start end points" msgstr "Start- und Endpunkte" msgid "The start and end points which is from cutter area to garbage can." -msgstr "" -"Die Start- und Endpunkte, die vom Schneidbereich zur Mülltonne führen." +msgstr "Die Start- und Endpunkte, die vom Schneidbereich zur Mülltonne führen." msgid "Reduce infill retraction" msgstr "Rückzug bei der Füllung verringern" @@ -7976,7 +8027,8 @@ msgid "Raft contact Z distance" msgstr "Z Abstand Objekt Druckbasis " msgid "Z gap between object and raft. Ignored for soluble interface" -msgstr "Z-Abstand zwischen Objekt und Druckbasis. Bei löslicher Oberfläche ignoriert" +msgstr "" +"Z-Abstand zwischen Objekt und Druckbasis. Bei löslicher Oberfläche ignoriert" msgid "Raft expansion" msgstr "Druckbasis Erweiterung" @@ -7995,8 +8047,8 @@ msgstr "Ausdehnung der ersten Schicht" msgid "Expand the first raft or support layer to improve bed plate adhesion" msgstr "" -"Ausdehnung der ersten Druckbasis oder Support-Schicht um die Druckplattenhaftung " -"zu verbessern" +"Ausdehnung der ersten Druckbasis oder Support-Schicht um die " +"Druckplattenhaftung zu verbessern" msgid "Raft layers" msgstr "Druckbasisschichten" @@ -8070,9 +8122,6 @@ msgstr "" msgid "Z Hop Type" msgstr "Z Hop Type" -msgid "select the type of Z Hop in the Slicer" -msgstr "Wähle den Typ des Z Hops im Slicer aus." - msgid "Z hop type" msgstr "Z-Hub Typ" @@ -8404,9 +8453,9 @@ msgid "" "Filament to print support base and raft. \"Default\" means no specific " "filament for support and current filament is used" msgstr "" -"Filament zum Drucken der Unterstützungsbasis und der Druckbasis. " -"„Standard“ bedeutet, dass kein bestimmtes Filament für die Unterstützung " -"verwendet wird und das aktuelle Filament verwendet wird" +"Filament zum Drucken der Unterstützungsbasis und der Druckbasis. „Standard“ " +"bedeutet, dass kein bestimmtes Filament für die Unterstützung verwendet wird " +"und das aktuelle Filament verwendet wird" msgid "Line width of support" msgstr "Linienbreite des Support" @@ -8575,7 +8624,8 @@ msgid "" "Enabling this option means the height of tree support layer except the " "first will be automatically calculated " msgstr "" -"Wenn Sie diese Option aktivieren, wird die Höhe der Baumstützschicht außer der ersten automatisch berechnet." +"Wenn Sie diese Option aktivieren, wird die Höhe der Baumstützschicht außer " +"der ersten automatisch berechnet." msgid "Auto brim width" msgstr "Automatische Randbreite" @@ -8960,7 +9010,7 @@ msgstr "Ungültiger Wert" #, c-format, boost-format msgid " doesn't work at 100%% density " -msgstr " doesn't work at 100%% density " +msgstr " doesn't work at 100%% density " msgid "Invalid value when spiral vase mode is enabled: " msgstr "Ungültiger Wert, wenn der Spiral-Vase-Modus aktiviert ist: " @@ -9062,7 +9112,9 @@ msgid "" "maintaining different profiles or including configurations from a network " "storage." msgstr "" -"Laden und Speichern von Einstellungen im angegebenen Verzeichnis. Dies ist nützlich, um verschiedene Profile beizubehalten oder Konfigurationen aus einem Netzwerkspeicher einzubeziehen." +"Laden und Speichern von Einstellungen im angegebenen Verzeichnis. Dies ist " +"nützlich, um verschiedene Profile beizubehalten oder Konfigurationen aus " +"einem Netzwerkspeicher einzubeziehen." msgid "Output directory" msgstr "Ausgabeverzeichnis" @@ -9134,14 +9186,17 @@ msgid "" "No layers were detected. You might want to repair your STL file(s) or check " "their size or thickness and retry.\n" msgstr "" -"Es wurden keine Schichten erkannt. Möglicherweise möchten Sie Ihre STL-Datei(en) reparieren oder ihre Größe oder Dicke überprüfen und es erneut versuchen.\n" +"Es wurden keine Schichten erkannt. Möglicherweise möchten Sie Ihre STL-" +"Datei(en) reparieren oder ihre Größe oder Dicke überprüfen und es erneut " +"versuchen.\n" msgid "" "An object's XY size compensation will not be used because it is also color-" "painted.\n" "XY Size compensation can not be combined with color-painting." msgstr "" -"Die XY-Größenkompensation eines Objekts wird nicht verwendet, da es auch farblich lackiert wurde.\n" +"Die XY-Größenkompensation eines Objekts wird nicht verwendet, da es auch " +"farblich lackiert wurde.\n" "Die XY-Größenkompensation kann nicht mit Farbmalerei kombiniert werden." #, c-format, boost-format @@ -9347,8 +9402,7 @@ msgid "" msgstr "" "Auto-Arrange\n" "Wussten Sie, dass Sie alle Objekte in Ihrem Projekt automatisch anordnen " -"können?" -"können?" +"können?können?" #: resources/data/hints.ini: [hint:Auto-Orient] msgid "" @@ -9574,10 +9628,12 @@ msgstr "" "Wussten Sie, dass Sie mehr Wandschlaufen und eine höhere spärliche " "Fülldichte verwenden können, um die Festigkeit des Modells zu verbessern?" +#~ msgid "select the type of Z Hop in the Slicer" +#~ msgstr "Wähle den Typ des Z Hops im Slicer aus." + #~ msgid "SoftFever Version" #~ msgstr "SoftFever Version" - #~ msgid "Loading user presets..." #~ msgstr "Nutzervoreinstellungen laden..." diff --git a/resources/i18n/de/OrcaSlicer.mo b/resources/i18n/de/OrcaSlicer.mo index b2ac4554d09186fe8a1870d46f92136b6aebbb9a..265542a6e7ae537d17ca0419f3387950bb91be89 100644 GIT binary patch delta 39731 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