Render custom bed textures in svg format on prusa beds

This commit is contained in:
Enrico Turri 2019-07-18 14:39:19 +02:00
parent af3cb890d1
commit f61d43de07
4 changed files with 56 additions and 19 deletions

View File

@ -14,6 +14,7 @@
#include <GL/glew.h>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/filesystem/operations.hpp>
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;

View File

@ -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;

View File

@ -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<ConfigOptionPoints>("bed_shape")->values); });
view3D_canvas->Bind(EVT_GLCANVAS_UPDATE_BED_SHAPE, [this](SimpleEvent&)
{
set_bed_shape(config->option<ConfigOptionPoints>("bed_shape")->values,
config->option<ConfigOptionString>("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<ConfigOptionPoints>("bed_shape")->values); });
preview->get_wxglcanvas()->Bind(EVT_GLCANVAS_UPDATE_BED_SHAPE, [this](SimpleEvent&)
{
set_bed_shape(config->option<ConfigOptionPoints>("bed_shape")->values,
config->option<ConfigOptionString>("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<PrinterTechnology>(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<ConfigOptionPoints>("bed_shape")->values);
p->set_bed_shape(p->config->option<ConfigOptionPoints>("bed_shape")->values,
p->config->option<ConfigOptionString>("bed_custom_texture")->value);
if (update_scheduled)
update();

View File

@ -512,6 +512,7 @@ const std::vector<std::string>& 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",