diff --git a/src/slic3r/GUI/3DBed.cpp b/src/slic3r/GUI/3DBed.cpp index a41b39a7ee..3a8a669043 100644 --- a/src/slic3r/GUI/3DBed.cpp +++ b/src/slic3r/GUI/3DBed.cpp @@ -189,13 +189,14 @@ void Bed3D::Axes::render_axis(double length) const Bed3D::Bed3D() : m_type(Custom) , m_custom_texture("") + , m_custom_model("") , m_requires_canvas_update(false) , m_vbo_id(0) , m_scale_factor(1.0f) { } -bool Bed3D::set_shape(const Pointfs& shape, const std::string& custom_texture) +bool Bed3D::set_shape(const Pointfs& shape, const std::string& custom_texture, const std::string& custom_model) { EType new_type = detect_type(shape); @@ -207,12 +208,21 @@ bool Bed3D::set_shape(const Pointfs& shape, const std::string& custom_texture) cst_texture = ""; } - if ((m_shape == shape) && (m_type == new_type) && (m_custom_texture == cst_texture)) + // check that the passed custom texture filename is valid + std::string cst_model(custom_model); + if (!cst_model.empty()) + { + if (!boost::algorithm::iends_with(custom_model, ".stl") || !boost::filesystem::exists(custom_model)) + cst_model = ""; + } + + if ((m_shape == shape) && (m_type == new_type) && (m_custom_texture == cst_texture) && (m_custom_model == cst_model)) // No change, no need to update the UI. return false; m_shape = shape; m_custom_texture = cst_texture; + m_custom_model = cst_model; m_type = new_type; calc_bounding_boxes(); @@ -385,7 +395,7 @@ void Bed3D::render_prusa(GLCanvas3D& canvas, const std::string& key, bool bottom { if (!bottom) { - std::string filename = resources_dir() + "/models/" + key + "_bed.stl"; + std::string filename = m_custom_model.empty() ? resources_dir() + "/models/" + key + "_bed.stl" : m_custom_model; if ((m_model.get_filename() != filename) && m_model.init_from_file(filename)) { Vec3d offset = m_bounding_box.center() - Vec3d(0.0, 0.0, 0.5 * m_model.get_bounding_box().size()(2)); diff --git a/src/slic3r/GUI/3DBed.hpp b/src/slic3r/GUI/3DBed.hpp index 71b319b0ab..3571166daf 100644 --- a/src/slic3r/GUI/3DBed.hpp +++ b/src/slic3r/GUI/3DBed.hpp @@ -75,6 +75,7 @@ private: EType m_type; Pointfs m_shape; std::string m_custom_texture; + std::string m_custom_model; mutable BoundingBoxf3 m_bounding_box; mutable BoundingBoxf3 m_extended_bounding_box; Polygon m_polygon; @@ -103,7 +104,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, const std::string& custom_texture); + bool set_shape(const Pointfs& shape, const std::string& custom_texture, const std::string& custom_model); 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 2c9f41c566..de64e226e7 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1851,7 +1851,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, const std::string& custom_texture); + void set_bed_shape(const Pointfs& shape, const std::string& custom_texture, const std::string& custom_model); bool can_delete() const; bool can_delete_all() const; @@ -2010,7 +2010,8 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) view3D_canvas->Bind(EVT_GLCANVAS_UPDATE_BED_SHAPE, [this](SimpleEvent&) { set_bed_shape(config->option("bed_shape")->values, - config->option("bed_custom_texture")->value); + config->option("bed_custom_texture")->value, + config->option("bed_custom_model")->value); }); // Preview events: @@ -2018,7 +2019,8 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) 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); + config->option("bed_custom_texture")->value, + config->option("bed_custom_model")->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); }); @@ -3623,9 +3625,9 @@ bool Plater::priv::can_mirror() const return get_selection().is_from_single_instance(); } -void Plater::priv::set_bed_shape(const Pointfs& shape, const std::string& custom_texture) +void Plater::priv::set_bed_shape(const Pointfs& shape, const std::string& custom_texture, const std::string& custom_model) { - bool new_shape = bed.set_shape(shape, custom_texture); + bool new_shape = bed.set_shape(shape, custom_texture, custom_model); if (new_shape) { if (view3D) view3D->bed_shape_changed(); @@ -4502,7 +4504,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") || (opt_key == "bed_custom_texture")) { + else if ((opt_key == "bed_shape") || (opt_key == "bed_custom_texture") || (opt_key == "bed_custom_model")) { bed_shape_changed = true; update_scheduled = true; } @@ -4537,7 +4539,8 @@ void Plater::on_config_change(const DynamicPrintConfig &config) if (bed_shape_changed) p->set_bed_shape(p->config->option("bed_shape")->values, - p->config->option("bed_custom_texture")->value); + p->config->option("bed_custom_texture")->value, + p->config->option("bed_custom_model")->value); if (update_scheduled) update();