diff --git a/resources/models/mk2_bed.stl b/resources/models/mk2_bed.stl new file mode 100644 index 000000000..07b7655ea Binary files /dev/null and b/resources/models/mk2_bed.stl differ diff --git a/resources/models/mk3_bed.stl b/resources/models/mk3_bed.stl new file mode 100644 index 000000000..cfa6d8c6d Binary files /dev/null and b/resources/models/mk3_bed.stl differ diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index c32fe3e8d..dc6a2041c 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -42,8 +42,10 @@ //==================== #define ENABLE_1_42_0_ALPHA2 1 +// Improves navigation between sidebar fields #define ENABLE_IMPROVED_SIDEBAR_OBJECTS_MANIPULATION (1 && ENABLE_1_42_0_ALPHA2) - +// Adds print bed models to 3D scene +#define ENABLE_PRINT_BED_MODELS (1 && ENABLE_1_42_0_ALPHA2) #endif // _technologies_h_ diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index 42b025093..d44789b7a 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -11,6 +11,9 @@ #include "libslic3r/Slicing.hpp" #include "libslic3r/GCode/Analyzer.hpp" #include "slic3r/GUI/PresetBundle.hpp" +#if ENABLE_PRINT_BED_MODELS +#include "libslic3r/Format/STL.hpp" +#endif // ENABLE_PRINT_BED_MODELS #include #include @@ -20,6 +23,11 @@ #include +#if ENABLE_PRINT_BED_MODELS +#include +#include +#endif // ENABLE_PRINT_BED_MODELS + #include #include @@ -249,11 +257,7 @@ void GLVolume::set_render_color(float r, float g, float b, float a) void GLVolume::set_render_color(const float* rgba, unsigned int size) { - size = std::min((unsigned int)4, size); - for (unsigned int i = 0; i < size; ++i) - { - render_color[i] = rgba[i]; - } + ::memcpy((void*)render_color, (const void*)rgba, (size_t)(std::min((unsigned int)4, size) * sizeof(float))); } void GLVolume::set_render_color() @@ -1790,17 +1794,27 @@ GUI::GLCanvas3DManager _3DScene::s_canvas_mgr; #if ENABLE_SIDEBAR_VISUAL_HINTS GLModel::GLModel() : m_useVBOs(false) +#if ENABLE_PRINT_BED_MODELS + , m_filename("") +#endif // ENABLE_PRINT_BED_MODELS { m_volume.shader_outside_printer_detection_enabled = false; } GLModel::~GLModel() { +#if ENABLE_PRINT_BED_MODELS + reset(); +#else m_volume.release_geometry(); +#endif // ENABLE_PRINT_BED_MODELS } void GLModel::set_color(const float* color, unsigned int size) { +#if ENABLE_PRINT_BED_MODELS + ::memcpy((void*)m_volume.color, (const void*)color, (size_t)(std::min((unsigned int)4, size) * sizeof(float))); +#endif // ENABLE_PRINT_BED_MODELS m_volume.set_render_color(color, size); } @@ -1834,6 +1848,14 @@ void GLModel::set_scale(const Vec3d& scale) m_volume.set_volume_scaling_factor(scale); } +#if ENABLE_PRINT_BED_MODELS +void GLModel::reset() +{ + m_volume.release_geometry(); + m_filename = ""; +} +#endif // ENABLE_PRINT_BED_MODELS + void GLModel::render() const { if (m_useVBOs) @@ -1854,9 +1876,7 @@ void GLModel::render_VBOs() const GLint current_program_id; ::glGetIntegerv(GL_CURRENT_PROGRAM, ¤t_program_id); GLint color_id = (current_program_id > 0) ? glGetUniformLocation(current_program_id, "uniform_color") : -1; - GLint print_box_detection_id = (current_program_id > 0) ? glGetUniformLocation(current_program_id, "print_box.volume_detection") : -1; - - m_volume.render_VBOs(color_id, print_box_detection_id, -1); + m_volume.render_VBOs(color_id, -1, -1); ::glBindBuffer(GL_ARRAY_BUFFER, 0); ::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); @@ -2066,11 +2086,57 @@ bool GLCurvedArrow::on_init(bool useVBOs) else m_volume.indexed_vertex_array.load_mesh_flat_shading(TriangleMesh(vertices, triangles)); + m_volume.bounding_box = m_volume.indexed_vertex_array.bounding_box(); m_volume.finalize_geometry(m_useVBOs); return true; } #endif // ENABLE_SIDEBAR_VISUAL_HINTS +#if ENABLE_PRINT_BED_MODELS +bool GLBed::on_init_from_file(const std::string& filename, bool useVBOs) +{ + reset(); + + if (!boost::filesystem::exists(filename)) + return false; + + if (!boost::algorithm::iends_with(filename, ".stl")) + return false; + + Model model; + try + { + model = Model::read_from_file(filename); + } + catch (std::exception &e) + { + return false; + } + + m_filename = filename; + m_useVBOs = useVBOs; + + ModelObject* model_object = model.objects.front(); + model_object->center_around_origin(); + + TriangleMesh mesh = model.mesh(); + mesh.repair(); + + if (m_useVBOs) + m_volume.indexed_vertex_array.load_mesh_full_shading(mesh); + else + m_volume.indexed_vertex_array.load_mesh_flat_shading(mesh); + + float color[4] = { 0.235f, 0.235, 0.235f, 1.0f }; + set_color(color, 4); + + m_volume.bounding_box = m_volume.indexed_vertex_array.bounding_box(); + m_volume.finalize_geometry(m_useVBOs); + + return true; +} +#endif // ENABLE_PRINT_BED_MODELS + std::string _3DScene::get_gl_info(bool format_as_html, bool extensions) { return s_canvas_mgr.get_gl_info(format_as_html, extensions); diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp index 38996dc04..b7b1af73d 100644 --- a/src/slic3r/GUI/3DScene.hpp +++ b/src/slic3r/GUI/3DScene.hpp @@ -569,13 +569,20 @@ class GLModel protected: GLVolume m_volume; bool m_useVBOs; +#if ENABLE_PRINT_BED_MODELS + std::string m_filename; +#endif // ENABLE_PRINT_BED_MODELS public: GLModel(); virtual ~GLModel(); bool init(bool useVBOs) { return on_init(useVBOs); } +#if ENABLE_PRINT_BED_MODELS + bool init_from_file(const std::string& filename, bool useVBOs) { return on_init_from_file(filename, useVBOs); } + void center_around(const Vec3d& center) { m_volume.set_volume_offset(center - m_volume.bounding_box.center()); } +#endif // ENABLE_PRINT_BED_MODELS void set_color(const float* color, unsigned int size); const Vec3d& get_offset() const; @@ -585,10 +592,22 @@ public: const Vec3d& get_scale() const; void set_scale(const Vec3d& scale); +#if ENABLE_PRINT_BED_MODELS + const std::string& get_filename() const { return m_filename; } + const BoundingBoxf3& get_bounding_box() const { return m_volume.bounding_box; } + + void reset(); +#endif // ENABLE_PRINT_BED_MODELS + void render() const; protected: +#if ENABLE_PRINT_BED_MODELS + virtual bool on_init(bool useVBOs) { return false; } + virtual bool on_init_from_file(const std::string& filename, bool useVBOs) { return false; } +#else virtual bool on_init(bool useVBOs) = 0; +#endif // ENABLE_PRINT_BED_MODELS private: void render_VBOs() const; @@ -613,6 +632,14 @@ protected: }; #endif // ENABLE_SIDEBAR_VISUAL_HINTS +#if ENABLE_PRINT_BED_MODELS +class GLBed : public GLModel +{ +protected: + virtual bool on_init_from_file(const std::string& filename, bool useVBOs); +}; +#endif // ENABLE_PRINT_BED_MODELS + class _3DScene { static GUI::GLCanvas3DManager s_canvas_mgr; diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 5fa09d334..91b4a2855 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -386,6 +386,35 @@ Point GLCanvas3D::Bed::point_projection(const Point& point) const return m_polygon.point_projection(point); } +#if ENABLE_PRINT_BED_MODELS +void GLCanvas3D::Bed::render(float theta, bool useVBOs) const +{ + switch (m_type) + { + case MK2: + { + _render_prusa("mk2", theta, useVBOs); + break; + } + case MK3: + { + _render_prusa("mk3", theta, useVBOs); + break; + } + case SL1: + { + _render_prusa("sl1", theta, useVBOs); + break; + } + default: + case Custom: + { + _render_custom(); + break; + } + } +} +#else void GLCanvas3D::Bed::render(float theta) const { switch (m_type) @@ -413,6 +442,7 @@ void GLCanvas3D::Bed::render(float theta) const } } } +#endif // ENABLE_PRINT_BED_MODELS void GLCanvas3D::Bed::_calc_bounding_box() { @@ -504,9 +534,18 @@ GLCanvas3D::Bed::EType GLCanvas3D::Bed::_detect_type() const return type; } +#if ENABLE_PRINT_BED_MODELS +void GLCanvas3D::Bed::_render_prusa(const std::string &key, float theta, bool useVBOs) const +#else void GLCanvas3D::Bed::_render_prusa(const std::string &key, float theta) const +#endif // ENABLE_PRINT_BED_MODELS { - std::string filename = resources_dir() + "/icons/bed/" + key + "_top.png"; + std::string tex_path = resources_dir() + "/icons/bed/" + key; +#if ENABLE_PRINT_BED_MODELS + std::string model_path = resources_dir() + "/models/" + key; +#endif // ENABLE_PRINT_BED_MODELS + + std::string filename = tex_path + "_top.png"; if ((m_top_texture.get_id() == 0) || (m_top_texture.get_source() != filename)) { if (!m_top_texture.load_from_file(filename, true)) @@ -516,7 +555,7 @@ void GLCanvas3D::Bed::_render_prusa(const std::string &key, float theta) const } } - filename = resources_dir() + "/icons/bed/" + key + "_bottom.png"; + filename = tex_path + "_bottom.png"; if ((m_bottom_texture.get_id() == 0) || (m_bottom_texture.get_source() != filename)) { if (!m_bottom_texture.load_from_file(filename, true)) @@ -526,6 +565,22 @@ void GLCanvas3D::Bed::_render_prusa(const std::string &key, float theta) const } } +#if ENABLE_PRINT_BED_MODELS + if (theta <= 90.0f) + { + filename = model_path + "_bed.stl"; + if ((m_model.get_filename() != filename) && m_model.init_from_file(filename, useVBOs)) + m_model.center_around(m_bounding_box.center() - Vec3d(0.0, 0.0, 1.0 + 0.5 * m_model.get_bounding_box().size()(2))); + + if (!m_model.get_filename().empty()) + { + ::glEnable(GL_LIGHTING); + m_model.render(); + ::glDisable(GL_LIGHTING); + } + } +#endif // ENABLE_PRINT_BED_MODELS + unsigned int triangles_vcount = m_triangles.get_vertices_count(); if (triangles_vcount > 0) { @@ -6087,7 +6142,11 @@ void GLCanvas3D::_render_background() const void GLCanvas3D::_render_bed(float theta) const { +#if ENABLE_PRINT_BED_MODELS + m_bed.render(theta, m_use_VBOs); +#else m_bed.render(theta); +#endif // ENABLE_PRINT_BED_MODELS } void GLCanvas3D::_render_axes() const diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 73aa4bd02..c2f2074c1 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -201,6 +201,9 @@ class GLCanvas3D GeometryBuffer m_gridlines; mutable GLTexture m_top_texture; mutable GLTexture m_bottom_texture; +#if ENABLE_PRINT_BED_MODELS + mutable GLBed m_model; +#endif // ENABLE_PRINT_BED_MODELS public: Bed(); @@ -216,14 +219,22 @@ class GLCanvas3D bool contains(const Point& point) const; Point point_projection(const Point& point) const; +#if ENABLE_PRINT_BED_MODELS + void render(float theta, bool useVBOs) const; +#else void render(float theta) const; +#endif // ENABLE_PRINT_BED_MODELS private: void _calc_bounding_box(); void _calc_triangles(const ExPolygon& poly); void _calc_gridlines(const ExPolygon& poly, const BoundingBox& bed_bbox); EType _detect_type() const; +#if ENABLE_PRINT_BED_MODELS + void _render_prusa(const std::string &key, float theta, bool useVBOs) const; +#else void _render_prusa(const std::string &key, float theta) const; +#endif // ENABLE_PRINT_BED_MODELS void _render_custom() const; static bool _are_equal(const Pointfs& bed_1, const Pointfs& bed_2); };