From f61d43de07ae973e701a5c516be344b251d44bfb Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 18 Jul 2019 14:39:19 +0200 Subject: [PATCH] Render custom bed textures in svg format on prusa beds --- src/slic3r/GUI/3DBed.cpp | 46 ++++++++++++++++++++++++++++++--------- src/slic3r/GUI/3DBed.hpp | 3 ++- src/slic3r/GUI/Plater.cpp | 25 ++++++++++++++------- src/slic3r/GUI/Preset.cpp | 1 + 4 files changed, 56 insertions(+), 19 deletions(-) diff --git a/src/slic3r/GUI/3DBed.cpp b/src/slic3r/GUI/3DBed.cpp index 482cd58ad..873da7116 100644 --- a/src/slic3r/GUI/3DBed.cpp +++ b/src/slic3r/GUI/3DBed.cpp @@ -14,6 +14,7 @@ #include #include +#include static const float GROUND_Z = -0.02f; @@ -274,6 +275,7 @@ void Bed3D::Axes::render_axis(double length) const Bed3D::Bed3D() : m_type(Custom) + , m_custom_texture("") #if ENABLE_TEXTURES_FROM_SVG , m_requires_canvas_update(false) , m_vbo_id(0) @@ -282,14 +284,25 @@ Bed3D::Bed3D() { } -bool Bed3D::set_shape(const Pointfs& shape) +bool Bed3D::set_shape(const Pointfs& shape, const std::string& custom_texture) { EType new_type = detect_type(shape); - if (m_shape == shape && m_type == new_type) + + // check that the passed custom texture filename is valid + std::string cst_texture(custom_texture); + if (!cst_texture.empty()) + { + std::string ext = boost::filesystem::path(cst_texture).extension().string(); + if ((!boost::iequals(ext.c_str(), ".png") && !boost::iequals(ext.c_str(), ".svg")) || !boost::filesystem::exists(custom_texture)) + cst_texture = ""; + } + + if ((m_shape == shape) && (m_type == new_type) && (m_custom_texture == cst_texture)) // No change, no need to update the UI. return false; m_shape = shape; + m_custom_texture = cst_texture; m_type = new_type; calc_bounding_boxes(); @@ -498,26 +511,39 @@ Bed3D::EType Bed3D::detect_type(const Pointfs& shape) const #if ENABLE_TEXTURES_FROM_SVG void Bed3D::render_prusa(GLCanvas3D* canvas, const std::string &key, bool bottom) const { - std::string tex_path = resources_dir() + "/icons/bed/" + key; + std::string filename = !m_custom_texture.empty() ? m_custom_texture : resources_dir() + "/icons/bed/" + key + ".svg"; std::string model_path = resources_dir() + "/models/" + key; // use higher resolution images if graphic card and opengl version allow GLint max_tex_size = GLCanvas3DManager::get_gl_info().get_max_tex_size(); - std::string filename = tex_path + ".svg"; - if ((m_texture.get_id() == 0) || (m_texture.get_source() != filename)) { - // generate a temporary lower resolution texture to show while no main texture levels have been compressed - if (!m_temp_texture.load_from_svg_file(filename, false, false, false, max_tex_size / 8)) + std::string ext = boost::filesystem::path(filename).extension().string(); + if (boost::iequals(ext.c_str(), ".svg")) { + // generate a temporary lower resolution texture to show while no main texture levels have been compressed + if (!m_temp_texture.load_from_svg_file(filename, false, false, false, max_tex_size / 8)) + { + render_custom(); + return; + } + + // starts generating the main texture, compression will run asynchronously + if (!m_texture.load_from_svg_file(filename, true, true, true, max_tex_size)) + { + render_custom(); + return; + } + } + else if (boost::iequals(ext.c_str(), ".png")) + { + std::cout << "texture: " << filename << std::endl; render_custom(); return; } - - // starts generating the main texture, compression will run asynchronously - if (!m_texture.load_from_svg_file(filename, true, true, true, max_tex_size)) + else { render_custom(); return; diff --git a/src/slic3r/GUI/3DBed.hpp b/src/slic3r/GUI/3DBed.hpp index 6c8913a9b..186282997 100644 --- a/src/slic3r/GUI/3DBed.hpp +++ b/src/slic3r/GUI/3DBed.hpp @@ -87,6 +87,7 @@ public: private: EType m_type; Pointfs m_shape; + std::string m_custom_texture; mutable BoundingBoxf3 m_bounding_box; mutable BoundingBoxf3 m_extended_bounding_box; Polygon m_polygon; @@ -122,7 +123,7 @@ public: const Pointfs& get_shape() const { return m_shape; } // Return true if the bed shape changed, so the calee will update the UI. - bool set_shape(const Pointfs& shape); + bool set_shape(const Pointfs& shape, const std::string& custom_texture); const BoundingBoxf3& get_bounding_box(bool extended) const { return extended ? m_extended_bounding_box : m_bounding_box; } bool contains(const Point& point) const; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 8fefca00c..ef3cbb965 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1700,7 +1700,7 @@ struct Plater::priv // triangulate the bed and store the triangles into m_bed.m_triangles, // fills the m_bed.m_grid_lines and sets m_bed.m_origin. // Sets m_bed.m_polygon to limit the object placement. - void set_bed_shape(const Pointfs& shape); + void set_bed_shape(const Pointfs& shape, const std::string& custom_texture); bool can_delete() const; bool can_delete_all() const; @@ -1750,7 +1750,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) : q(q) , main_frame(main_frame) , config(Slic3r::DynamicPrintConfig::new_from_defaults_keys({ - "bed_shape", "complete_objects", "duplicate_distance", "extruder_clearance_radius", "skirts", "skirt_distance", + "bed_shape", "bed_custom_texture", "bed_custom_model", "complete_objects", "duplicate_distance", "extruder_clearance_radius", "skirts", "skirt_distance", "brim_width", "variable_layer_height", "serial_port", "serial_speed", "host_type", "print_host", "printhost_apikey", "printhost_cafile", "nozzle_diameter", "single_extruder_multi_material", "wipe_tower", "wipe_tower_x", "wipe_tower_y", "wipe_tower_width", "wipe_tower_rotation_angle", @@ -1853,11 +1853,19 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) view3D_canvas->Bind(EVT_GLTOOLBAR_SPLIT_VOLUMES, &priv::on_action_split_volumes, this); view3D_canvas->Bind(EVT_GLTOOLBAR_LAYERSEDITING, &priv::on_action_layersediting, this); view3D_canvas->Bind(EVT_GLCANVAS_INIT, [this](SimpleEvent&) { init_view_toolbar(); }); - view3D_canvas->Bind(EVT_GLCANVAS_UPDATE_BED_SHAPE, [this](SimpleEvent&) { set_bed_shape(config->option("bed_shape")->values); }); + view3D_canvas->Bind(EVT_GLCANVAS_UPDATE_BED_SHAPE, [this](SimpleEvent&) + { + set_bed_shape(config->option("bed_shape")->values, + config->option("bed_custom_texture")->value); + }); // Preview events: preview->get_wxglcanvas()->Bind(EVT_GLCANVAS_QUESTION_MARK, [this](SimpleEvent&) { wxGetApp().keyboard_shortcuts(); }); - preview->get_wxglcanvas()->Bind(EVT_GLCANVAS_UPDATE_BED_SHAPE, [this](SimpleEvent&) { set_bed_shape(config->option("bed_shape")->values); }); + preview->get_wxglcanvas()->Bind(EVT_GLCANVAS_UPDATE_BED_SHAPE, [this](SimpleEvent&) + { + set_bed_shape(config->option("bed_shape")->values, + config->option("bed_custom_texture")->value); + }); preview->get_wxglcanvas()->Bind(EVT_GLCANVAS_TAB, [this](SimpleEvent&) { select_next_view_3D(); }); preview->get_wxglcanvas()->Bind(EVT_GLCANVAS_MOVE_DOUBLE_SLIDER, [this](wxKeyEvent& evt) { preview->move_double_slider(evt); }); preview->get_wxglcanvas()->Bind(EVT_GLCANVAS_EDIT_COLOR_CHANGE, [this](wxKeyEvent& evt) { preview->edit_double_slider(evt); }); @@ -3504,9 +3512,9 @@ bool Plater::priv::can_mirror() const return get_selection().is_from_single_instance(); } -void Plater::priv::set_bed_shape(const Pointfs& shape) +void Plater::priv::set_bed_shape(const Pointfs& shape, const std::string& custom_texture) { - bool new_shape = bed.set_shape(shape); + bool new_shape = bed.set_shape(shape, custom_texture); if (new_shape) { if (view3D) view3D->bed_shape_changed(); @@ -4251,7 +4259,7 @@ void Plater::on_config_change(const DynamicPrintConfig &config) p->config->set_key_value(opt_key, config.option(opt_key)->clone()); if (opt_key == "printer_technology") this->set_printer_technology(config.opt_enum(opt_key)); - else if (opt_key == "bed_shape") { + else if ((opt_key == "bed_shape") || (opt_key == "bed_custom_texture")) { bed_shape_changed = true; update_scheduled = true; } @@ -4285,7 +4293,8 @@ void Plater::on_config_change(const DynamicPrintConfig &config) } if (bed_shape_changed) - p->set_bed_shape(p->config->option("bed_shape")->values); + p->set_bed_shape(p->config->option("bed_shape")->values, + p->config->option("bed_custom_texture")->value); if (update_scheduled) update(); diff --git a/src/slic3r/GUI/Preset.cpp b/src/slic3r/GUI/Preset.cpp index 635b21ba9..e34c9be28 100644 --- a/src/slic3r/GUI/Preset.cpp +++ b/src/slic3r/GUI/Preset.cpp @@ -512,6 +512,7 @@ const std::vector& Preset::sla_printer_options() if (s_opts.empty()) { s_opts = { "printer_technology", + "bed_shape", "bed_custom_texture", "bed_custom_model", "max_print_height", "bed_shape", "max_print_height", "display_width", "display_height", "display_pixels_x", "display_pixels_y", "display_mirror_x", "display_mirror_y",