Merge branch 'master' into lm_sla_supports_auto
| Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.7 KiB | 
| Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.7 KiB | 
| Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 2.6 KiB | 
| Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2 KiB | 
| Before Width: | Height: | Size: 2 KiB After Width: | Height: | Size: 2 KiB | 
| Before Width: | Height: | Size: 2 KiB After Width: | Height: | Size: 2.5 KiB | 
| Before Width: | Height: | Size: 2 KiB After Width: | Height: | Size: 2 KiB | 
| Before Width: | Height: | Size: 2 KiB After Width: | Height: | Size: 1.9 KiB | 
| Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 2.4 KiB | 
| Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB | 
| Before Width: | Height: | Size: 2 KiB After Width: | Height: | Size: 2.1 KiB | 
| Before Width: | Height: | Size: 2 KiB After Width: | Height: | Size: 3.2 KiB | 
| Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 1.8 KiB | 
| Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 1.7 KiB | 
| Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.2 KiB | 
| Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 17 KiB | 
							
								
								
									
										
											BIN
										
									
								
								resources/icons/toolbar141.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 23 KiB | 
| Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 12 KiB | 
|  | @ -483,8 +483,9 @@ bool DynamicConfig::operator==(const DynamicConfig &rhs) const | |||
|     t_options_map::const_iterator it2     = rhs.options.begin(); | ||||
|     t_options_map::const_iterator it2_end = rhs.options.end(); | ||||
|     for (; it1 != it1_end && it2 != it2_end; ++ it1, ++ it2) | ||||
|         if (*it1->second != *it2->second) | ||||
|             return false; | ||||
| 		if (it1->first != it2->first || *it1->second != *it2->second) | ||||
| 			// key or value differ
 | ||||
| 			return false; | ||||
|     return it1 == it1_end && it2 == it2_end; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -668,6 +668,7 @@ void GCodeAnalyzer::_calc_gcode_preview_extrusion_layers(GCodePreviewData& previ | |||
|     { | ||||
|         static GCodePreviewData::Extrusion::Layer& get_layer_at_z(GCodePreviewData::Extrusion::LayersList& layers, float z) | ||||
|         { | ||||
|             //FIXME this has a terrible time complexity
 | ||||
|             for (GCodePreviewData::Extrusion::Layer& layer : layers) | ||||
|             { | ||||
|                 // if layer found, return it
 | ||||
|  | @ -863,20 +864,4 @@ size_t GCodeAnalyzer::memory_used() const | |||
|     return out; | ||||
| } | ||||
| 
 | ||||
| GCodePreviewData::Color operator + (const GCodePreviewData::Color& c1, const GCodePreviewData::Color& c2) | ||||
| { | ||||
|     return GCodePreviewData::Color(clamp(0.0f, 1.0f, c1.rgba[0] + c2.rgba[0]), | ||||
|         clamp(0.0f, 1.0f, c1.rgba[1] + c2.rgba[1]), | ||||
|         clamp(0.0f, 1.0f, c1.rgba[2] + c2.rgba[2]), | ||||
|         clamp(0.0f, 1.0f, c1.rgba[3] + c2.rgba[3])); | ||||
| } | ||||
| 
 | ||||
| GCodePreviewData::Color operator * (float f, const GCodePreviewData::Color& color) | ||||
| { | ||||
|     return GCodePreviewData::Color(clamp(0.0f, 1.0f, f * color.rgba[0]), | ||||
|         clamp(0.0f, 1.0f, f * color.rgba[1]), | ||||
|         clamp(0.0f, 1.0f, f * color.rgba[2]), | ||||
|         clamp(0.0f, 1.0f, f * color.rgba[3])); | ||||
| } | ||||
| 
 | ||||
| } // namespace Slic3r
 | ||||
|  |  | |||
|  | @ -521,4 +521,20 @@ size_t GCodePreviewData::memory_used() const | |||
|         sizeof(shell) + sizeof(ranges); | ||||
| } | ||||
| 
 | ||||
| GCodePreviewData::Color operator + (const GCodePreviewData::Color& c1, const GCodePreviewData::Color& c2) | ||||
| { | ||||
|     return GCodePreviewData::Color(clamp(0.0f, 1.0f, c1.rgba[0] + c2.rgba[0]), | ||||
|         clamp(0.0f, 1.0f, c1.rgba[1] + c2.rgba[1]), | ||||
|         clamp(0.0f, 1.0f, c1.rgba[2] + c2.rgba[2]), | ||||
|         clamp(0.0f, 1.0f, c1.rgba[3] + c2.rgba[3])); | ||||
| } | ||||
| 
 | ||||
| GCodePreviewData::Color operator * (float f, const GCodePreviewData::Color& color) | ||||
| { | ||||
|     return GCodePreviewData::Color(clamp(0.0f, 1.0f, f * color.rgba[0]), | ||||
|         clamp(0.0f, 1.0f, f * color.rgba[1]), | ||||
|         clamp(0.0f, 1.0f, f * color.rgba[2]), | ||||
|         clamp(0.0f, 1.0f, f * color.rgba[3])); | ||||
| } | ||||
| 
 | ||||
| } // namespace Slic3r
 | ||||
|  |  | |||
|  | @ -22,6 +22,7 @@ public: | |||
|         static const Color Dummy; | ||||
|     }; | ||||
| 
 | ||||
|     // Color mapping from a <min, max> range into a smooth rainbow of 10 colors.
 | ||||
|     struct Range | ||||
|     { | ||||
|         static const unsigned int Colors_Count = 10; | ||||
|  | @ -45,9 +46,13 @@ public: | |||
| 
 | ||||
|     struct Ranges | ||||
|     { | ||||
|         // Color mapping by layer height.
 | ||||
|         Range height; | ||||
|         // Color mapping by extrusion width.
 | ||||
|         Range width; | ||||
|         // Color mapping by feedrate.
 | ||||
|         Range feedrate; | ||||
|         // Color mapping by volumetric extrusion rate.
 | ||||
|         Range volumetric_rate; | ||||
|     }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -42,6 +42,8 @@ | |||
| #define ENABLE_TOOLBAR_BACKGROUND_TEXTURE (1 && ENABLE_1_42_0) | ||||
| // Renders a small sphere in the center of the bounding box of the current selection when no gizmo is active
 | ||||
| #define ENABLE_RENDER_SELECTION_CENTER (0 && ENABLE_1_42_0) | ||||
| // Show visual hints in the 3D scene when sidebar matrix fields have focus
 | ||||
| #define ENABLE_SIDEBAR_VISUAL_HINTS (0 && ENABLE_1_42_0) | ||||
| 
 | ||||
| #endif // _technologies_h_
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -10,6 +10,8 @@ add_library(libslic3r_gui STATIC | |||
|     GUI/AboutDialog.hpp | ||||
|     GUI/SysInfoDialog.cpp | ||||
|     GUI/SysInfoDialog.hpp | ||||
|     GUI/KBShortcutsDialog.cpp | ||||
|     GUI/KBShortcutsDialog.hpp | ||||
|     GUI/AppConfig.cpp | ||||
|     GUI/AppConfig.hpp | ||||
|     GUI/BackgroundSlicingProcess.cpp | ||||
|  |  | |||
|  | @ -1868,6 +1868,130 @@ void _3DScene::point3_to_verts(const Vec3crd& point, double width, double height | |||
| 
 | ||||
| GUI::GLCanvas3DManager _3DScene::s_canvas_mgr; | ||||
| 
 | ||||
| #if ENABLE_SIDEBAR_VISUAL_HINTS | ||||
| GLModel::GLModel() | ||||
|     : m_useVBOs(false) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| GLModel::~GLModel() | ||||
| { | ||||
|     m_volume.release_geometry(); | ||||
| } | ||||
| 
 | ||||
| void GLModel::set_color(float* color, unsigned int size) | ||||
| { | ||||
|     m_volume.set_render_color(color, size); | ||||
| } | ||||
| 
 | ||||
| void GLModel::set_scale(const Vec3d& scale) | ||||
| { | ||||
|     m_volume.set_volume_scaling_factor(scale); | ||||
| } | ||||
| 
 | ||||
| void GLModel::render() const | ||||
| { | ||||
|     if (m_useVBOs) | ||||
|         render_VBOs(); | ||||
|     else | ||||
|     { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void GLModel::render_VBOs() const | ||||
| { | ||||
|     ::glEnable(GL_BLEND); | ||||
|     ::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | ||||
| 
 | ||||
|     ::glCullFace(GL_BACK); | ||||
|     ::glEnableClientState(GL_VERTEX_ARRAY); | ||||
|     ::glEnableClientState(GL_NORMAL_ARRAY); | ||||
| 
 | ||||
|     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; | ||||
| 
 | ||||
|     m_volume.render_VBOs(color_id, -1, -1); | ||||
| 
 | ||||
|     ::glBindBuffer(GL_ARRAY_BUFFER, 0); | ||||
|     ::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); | ||||
| 
 | ||||
|     ::glDisableClientState(GL_VERTEX_ARRAY); | ||||
|     ::glDisableClientState(GL_NORMAL_ARRAY); | ||||
| 
 | ||||
|     ::glDisable(GL_BLEND); | ||||
| } | ||||
| 
 | ||||
| GLArrow::GLArrow() | ||||
|     : GLModel() | ||||
| { | ||||
| } | ||||
| 
 | ||||
| bool GLArrow::on_init(bool useVBOs) | ||||
| { | ||||
|     Pointf3s vertices; | ||||
|     std::vector<Vec3crd> triangles; | ||||
| 
 | ||||
|     // top face
 | ||||
|     vertices.emplace_back(0.5, 0.0, -0.1); | ||||
|     vertices.emplace_back(0.5, 2.0, -0.1); | ||||
|     vertices.emplace_back(1.0, 2.0, -0.1); | ||||
|     vertices.emplace_back(0.0, 3.0, -0.1); | ||||
|     vertices.emplace_back(-1.0, 2.0, -0.1); | ||||
|     vertices.emplace_back(-0.5, 2.0, -0.1); | ||||
|     vertices.emplace_back(-0.5, 0.0, -0.1); | ||||
| 
 | ||||
|     // bottom face
 | ||||
|     vertices.emplace_back(0.5, 0.0, 0.1); | ||||
|     vertices.emplace_back(0.5, 2.0, 0.1); | ||||
|     vertices.emplace_back(1.0, 2.0, 0.1); | ||||
|     vertices.emplace_back(0.0, 3.0, 0.1); | ||||
|     vertices.emplace_back(-1.0, 2.0, 0.1); | ||||
|     vertices.emplace_back(-0.5, 2.0, 0.1); | ||||
|     vertices.emplace_back(-0.5, 0.0, 0.1); | ||||
| 
 | ||||
|     // bottom face
 | ||||
|     triangles.emplace_back(0, 6, 1); | ||||
|     triangles.emplace_back(6, 5, 1); | ||||
|     triangles.emplace_back(5, 4, 3); | ||||
|     triangles.emplace_back(5, 3, 1); | ||||
|     triangles.emplace_back(1, 3, 2); | ||||
| 
 | ||||
|     // top face
 | ||||
|     triangles.emplace_back(7, 8, 13); | ||||
|     triangles.emplace_back(13, 8, 12); | ||||
|     triangles.emplace_back(12, 10, 11); | ||||
|     triangles.emplace_back(8, 10, 12); | ||||
|     triangles.emplace_back(8, 9, 10); | ||||
| 
 | ||||
|     // side face
 | ||||
|     triangles.emplace_back(0, 1, 8); | ||||
|     triangles.emplace_back(8, 7, 0); | ||||
|     triangles.emplace_back(1, 2, 9); | ||||
|     triangles.emplace_back(9, 8, 1); | ||||
|     triangles.emplace_back(2, 3, 10); | ||||
|     triangles.emplace_back(10, 9, 2); | ||||
|     triangles.emplace_back(3, 4, 11); | ||||
|     triangles.emplace_back(11, 10, 3); | ||||
|     triangles.emplace_back(4, 5, 12); | ||||
|     triangles.emplace_back(12, 11, 4); | ||||
|     triangles.emplace_back(5, 6, 13); | ||||
|     triangles.emplace_back(13, 12, 5); | ||||
|     triangles.emplace_back(6, 0, 7); | ||||
|     triangles.emplace_back(7, 13, 6); | ||||
| 
 | ||||
|     m_useVBOs = useVBOs; | ||||
| 
 | ||||
|     if (m_useVBOs) | ||||
|         m_volume.indexed_vertex_array.load_mesh_full_shading(TriangleMesh(vertices, triangles)); | ||||
|     else | ||||
|         m_volume.indexed_vertex_array.load_mesh_flat_shading(TriangleMesh(vertices, triangles)); | ||||
| 
 | ||||
|     m_volume.finalize_geometry(m_useVBOs); | ||||
|     return true; | ||||
| } | ||||
| #endif // ENABLE_SIDEBAR_VISUAL_HINTS
 | ||||
| 
 | ||||
| std::string _3DScene::get_gl_info(bool format_as_html, bool extensions) | ||||
| { | ||||
|     return s_canvas_mgr.get_gl_info(format_as_html, extensions); | ||||
|  |  | |||
|  | @ -18,7 +18,6 @@ class SLAPrintObject; | |||
| enum  SLAPrintObjectStep : unsigned int; | ||||
| class Model; | ||||
| class ModelObject; | ||||
| class GCodePreviewData; | ||||
| class DynamicPrintConfig; | ||||
| class ExtrusionPath; | ||||
| class ExtrusionMultiPath; | ||||
|  | @ -583,6 +582,41 @@ private: | |||
|     GLVolumeCollection& operator=(const GLVolumeCollection &); | ||||
| }; | ||||
| 
 | ||||
| #if ENABLE_SIDEBAR_VISUAL_HINTS | ||||
| class GLModel | ||||
| { | ||||
| protected: | ||||
|     GLVolume m_volume; | ||||
|     bool m_useVBOs; | ||||
| 
 | ||||
| public: | ||||
|     GLModel(); | ||||
|     virtual ~GLModel(); | ||||
| 
 | ||||
|     bool init(bool useVBOs) { return on_init(useVBOs); } | ||||
| 
 | ||||
|     void set_color(float* color, unsigned int size); | ||||
|     void set_scale(const Vec3d& scale); | ||||
| 
 | ||||
|     void render() const;  | ||||
| 
 | ||||
| protected: | ||||
|     virtual bool on_init(bool useVBOs) = 0; | ||||
| 
 | ||||
| private: | ||||
|     void render_VBOs() const; | ||||
| }; | ||||
| 
 | ||||
| class GLArrow : public GLModel | ||||
| { | ||||
| public: | ||||
|     GLArrow(); | ||||
| 
 | ||||
| protected: | ||||
|     virtual bool on_init(bool useVBOs); | ||||
| }; | ||||
| #endif // ENABLE_SIDEBAR_VISUAL_HINTS
 | ||||
| 
 | ||||
| class _3DScene | ||||
| { | ||||
|     static GUI::GLCanvas3DManager s_canvas_mgr; | ||||
|  |  | |||
|  | @ -15,8 +15,8 @@ | |||
| #include "libslic3r/SLAPrint.hpp" | ||||
| #include "libslic3r/Utils.hpp" | ||||
| #include "libslic3r/GCode/PostProcessor.hpp" | ||||
| #include "libslic3r/GCode/PreviewData.hpp" | ||||
| 
 | ||||
| //#undef NDEBUG
 | ||||
| #include <cassert> | ||||
| #include <stdexcept> | ||||
| #include <cctype> | ||||
|  | @ -367,6 +367,13 @@ Print::ApplyStatus BackgroundSlicingProcess::apply(const Model &model, const Dyn | |||
| 	assert(m_print != nullptr); | ||||
| 	assert(config.opt_enum<PrinterTechnology>("printer_technology") == m_print->technology()); | ||||
| 	Print::ApplyStatus invalidated = m_print->apply(model, config); | ||||
| 	if ((invalidated & PrintBase::APPLY_STATUS_INVALIDATED) != 0 && m_print->technology() == ptFFF && | ||||
| 		m_gcode_preview_data != nullptr && ! this->m_fff_print->is_step_done(psGCodeExport)) { | ||||
| 		// Some FFF status was invalidated, and the G-code was not exported yet.
 | ||||
| 		// Let the G-code preview UI know that the final G-code preview is not valid.
 | ||||
| 		// In addition, this early memory deallocation reduces memory footprint.
 | ||||
| 		m_gcode_preview_data->reset(); | ||||
| 	} | ||||
| 	return invalidated; | ||||
| } | ||||
| 
 | ||||
|  | @ -392,7 +399,7 @@ void BackgroundSlicingProcess::schedule_upload(Slic3r::PrintHostJob upload_job) | |||
| 	// Guard against entering the export step before changing the export path.
 | ||||
| 	tbb::mutex::scoped_lock lock(m_print->state_mutex()); | ||||
| 	this->invalidate_step(bspsGCodeFinalize); | ||||
| 	m_export_path = std::string(); | ||||
| 	m_export_path.clear(); | ||||
| 	m_upload_job = std::move(upload_job); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -1154,6 +1154,12 @@ GLCanvas3D::Selection::VolumeCache::VolumeCache(const Vec3d& position, const Vec | |||
| } | ||||
| #endif // ENABLE_MODELVOLUME_TRANSFORM
 | ||||
| 
 | ||||
| #if ENABLE_SIDEBAR_VISUAL_HINTS | ||||
| const float GLCanvas3D::Selection::RED[3] = { 1.0f, 0.0f, 0.0f }; | ||||
| const float GLCanvas3D::Selection::GREEN[3] = { 0.0f, 1.0f, 0.0f }; | ||||
| const float GLCanvas3D::Selection::BLUE[3] = { 0.0f, 0.0f, 1.0f }; | ||||
| #endif // ENABLE_SIDEBAR_VISUAL_HINTS
 | ||||
| 
 | ||||
| GLCanvas3D::Selection::Selection() | ||||
|     : m_volumes(nullptr) | ||||
|     , m_model(nullptr) | ||||
|  | @ -1183,6 +1189,19 @@ void GLCanvas3D::Selection::set_volumes(GLVolumePtrs* volumes) | |||
|     _update_valid(); | ||||
| } | ||||
| 
 | ||||
| #if ENABLE_SIDEBAR_VISUAL_HINTS | ||||
| bool GLCanvas3D::Selection::init(bool useVBOs) | ||||
| { | ||||
|     if (m_arrow.init(useVBOs)) | ||||
|     { | ||||
|         m_arrow.set_scale(5.0 * Vec3d::Ones()); | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|     return false; | ||||
| } | ||||
| #endif // ENABLE_SIDEBAR_VISUAL_HINTS
 | ||||
| 
 | ||||
| void GLCanvas3D::Selection::set_model(Model* model) | ||||
| { | ||||
|     m_model = model; | ||||
|  | @ -1530,7 +1549,7 @@ void GLCanvas3D::Selection::start_dragging() | |||
|     _set_caches(); | ||||
| } | ||||
| 
 | ||||
| void GLCanvas3D::Selection::translate(const Vec3d& displacement) | ||||
| void GLCanvas3D::Selection::translate(const Vec3d& displacement, bool local) | ||||
| { | ||||
|     if (!m_valid) | ||||
|         return; | ||||
|  | @ -1540,7 +1559,7 @@ void GLCanvas3D::Selection::translate(const Vec3d& displacement) | |||
| #if ENABLE_MODELVOLUME_TRANSFORM | ||||
|     if ((m_mode == Volume) || (*m_volumes)[i]->is_wipe_tower) | ||||
|     { | ||||
|         if (_requires_local_axes()) | ||||
|         if (local) | ||||
|             (*m_volumes)[i]->set_volume_offset(m_cache.volumes_data[i].get_volume_position() + displacement); | ||||
|         else | ||||
|         { | ||||
|  | @ -1595,7 +1614,7 @@ void GLCanvas3D::Selection::rotate(const Vec3d& rotation, bool local) | |||
|         else if (is_single_volume() || is_single_modifier()) | ||||
| #if ENABLE_WORLD_ROTATIONS | ||||
|         { | ||||
|             if (_requires_local_axes()) | ||||
|             if (requires_local_axes()) | ||||
|                 (*m_volumes)[i]->set_volume_rotation(rotation); | ||||
|             else | ||||
|             { | ||||
|  | @ -2055,6 +2074,55 @@ void GLCanvas3D::Selection::render_center() const | |||
| } | ||||
| #endif // ENABLE_RENDER_SELECTION_CENTER
 | ||||
| 
 | ||||
| #if ENABLE_SIDEBAR_VISUAL_HINTS | ||||
| void GLCanvas3D::Selection::render_sidebar_hints(const std::string& sidebar_field) const | ||||
| { | ||||
|     if (sidebar_field.empty()) | ||||
|         return; | ||||
| 
 | ||||
|     ::glClear(GL_DEPTH_BUFFER_BIT); | ||||
|     ::glEnable(GL_DEPTH_TEST); | ||||
| 
 | ||||
|     ::glEnable(GL_LIGHTING); | ||||
| 
 | ||||
|     ::glPushMatrix(); | ||||
| 
 | ||||
|     const Vec3d& center = get_bounding_box().center(); | ||||
| 
 | ||||
|     if (is_single_full_instance()) | ||||
|         ::glTranslated(center(0), center(1), center(2)); | ||||
|     else if (is_single_volume() || is_single_modifier()) | ||||
|     { | ||||
|         const GLVolume* volume = (*m_volumes)[*m_list.begin()]; | ||||
|         Transform3d orient_matrix = volume->get_instance_transformation().get_matrix(true, false, true, true) * volume->get_volume_transformation().get_matrix(true, false, true, true); | ||||
|         const Vec3d& offset = get_bounding_box().center(); | ||||
| 
 | ||||
|         ::glTranslated(offset(0), offset(1), offset(2)); | ||||
|         ::glMultMatrixd(orient_matrix.data()); | ||||
|     } | ||||
|     else | ||||
|         ::glTranslated(center(0), center(1), center(2)); | ||||
| 
 | ||||
|     if (boost::starts_with(sidebar_field, "position")) | ||||
|         _render_sidebar_position_hints(sidebar_field); | ||||
|     else if (boost::starts_with(sidebar_field, "rotation")) | ||||
|         _render_sidebar_rotation_hints(sidebar_field); | ||||
|     else if (boost::starts_with(sidebar_field, "scale")) | ||||
|         _render_sidebar_scale_hints(sidebar_field); | ||||
|     else if (boost::starts_with(sidebar_field, "size")) | ||||
|         _render_sidebar_size_hints(sidebar_field); | ||||
| 
 | ||||
|     ::glPopMatrix(); | ||||
| 
 | ||||
|     ::glDisable(GL_LIGHTING); | ||||
| } | ||||
| #endif // ENABLE_SIDEBAR_VISUAL_HINTS
 | ||||
| 
 | ||||
| bool GLCanvas3D::Selection::requires_local_axes() const | ||||
| { | ||||
|     return (m_mode == Volume) && is_from_single_instance(); | ||||
| } | ||||
| 
 | ||||
| void GLCanvas3D::Selection::_update_valid() | ||||
| { | ||||
|     m_valid = (m_volumes != nullptr) && (m_model != nullptr); | ||||
|  | @ -2457,6 +2525,101 @@ void GLCanvas3D::Selection::_render_bounding_box(const BoundingBoxf3& box, float | |||
|     ::glEnd(); | ||||
| } | ||||
| 
 | ||||
| #if ENABLE_SIDEBAR_VISUAL_HINTS | ||||
| void GLCanvas3D::Selection::_render_sidebar_position_hints(const std::string& sidebar_field) const | ||||
| { | ||||
|     if (boost::ends_with(sidebar_field, "x")) | ||||
|     { | ||||
|         ::glRotated(-90.0, 0.0, 0.0, 1.0); | ||||
|         _render_sidebar_position_hint(X); | ||||
|     } | ||||
|     else if (boost::ends_with(sidebar_field, "y")) | ||||
|         _render_sidebar_position_hint(Y); | ||||
|     else if (boost::ends_with(sidebar_field, "z")) | ||||
|     { | ||||
|         ::glRotated(90.0, 1.0, 0.0, 0.0); | ||||
|         _render_sidebar_position_hint(Z); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void GLCanvas3D::Selection::_render_sidebar_rotation_hints(const std::string& sidebar_field) const | ||||
| { | ||||
| } | ||||
| 
 | ||||
| void GLCanvas3D::Selection::_render_sidebar_scale_hints(const std::string& sidebar_field) const | ||||
| { | ||||
|     if (boost::ends_with(sidebar_field, "x") || requires_uniform_scale()) | ||||
|     { | ||||
|         ::glPushMatrix(); | ||||
|         ::glRotated(-90.0, 0.0, 0.0, 1.0); | ||||
|         _render_sidebar_scale_hint(X); | ||||
|         ::glPopMatrix(); | ||||
|     } | ||||
| 
 | ||||
|     if (boost::ends_with(sidebar_field, "y") || requires_uniform_scale()) | ||||
|     { | ||||
|         ::glPushMatrix(); | ||||
|         _render_sidebar_scale_hint(Y); | ||||
|         ::glPopMatrix(); | ||||
|     } | ||||
| 
 | ||||
|     if (boost::ends_with(sidebar_field, "z") || requires_uniform_scale()) | ||||
|     { | ||||
|         ::glPushMatrix(); | ||||
|         ::glRotated(90.0, 1.0, 0.0, 0.0); | ||||
|         _render_sidebar_scale_hint(Z); | ||||
|         ::glPopMatrix(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void GLCanvas3D::Selection::_render_sidebar_size_hints(const std::string& sidebar_field) const | ||||
| { | ||||
|     _render_sidebar_scale_hints(sidebar_field); | ||||
| } | ||||
| 
 | ||||
| void GLCanvas3D::Selection::_render_sidebar_position_hint(Axis axis) const | ||||
| { | ||||
|     float color[3]; | ||||
|     switch (axis) | ||||
|     { | ||||
|     case X: { ::memcpy((void*)color, (const void*)RED, 3 * sizeof(float)); break; } | ||||
|     case Y: { ::memcpy((void*)color, (const void*)GREEN, 3 * sizeof(float)); break; } | ||||
|     case Z: { ::memcpy((void*)color, (const void*)BLUE, 3 * sizeof(float)); break; } | ||||
|     } | ||||
| 
 | ||||
|     m_arrow.set_color(color, 3); | ||||
|     m_arrow.render(); | ||||
| } | ||||
| 
 | ||||
| void GLCanvas3D::Selection::_render_sidebar_rotation_hint(Axis axis, double length) const | ||||
| { | ||||
| } | ||||
| 
 | ||||
| void GLCanvas3D::Selection::_render_sidebar_scale_hint(Axis axis) const | ||||
| { | ||||
|     float color[3]; | ||||
|     switch (axis) | ||||
|     { | ||||
|     case X: { ::memcpy((void*)color, (const void*)RED, 3 * sizeof(float)); break; } | ||||
|     case Y: { ::memcpy((void*)color, (const void*)GREEN, 3 * sizeof(float)); break; } | ||||
|     case Z: { ::memcpy((void*)color, (const void*)BLUE, 3 * sizeof(float)); break; } | ||||
|     } | ||||
| 
 | ||||
|     m_arrow.set_color(color, 3); | ||||
| 
 | ||||
|     ::glTranslated(0.0, 5.0, 0.0); | ||||
|     m_arrow.render(); | ||||
| 
 | ||||
|     ::glTranslated(0.0, -10.0, 0.0); | ||||
|     ::glRotated(180.0, 0.0, 0.0, 1.0); | ||||
|     m_arrow.render(); | ||||
| } | ||||
| 
 | ||||
| void GLCanvas3D::Selection::_render_sidebar_size_hint(Axis axis, double length) const | ||||
| { | ||||
| } | ||||
| #endif // ENABLE_SIDEBAR_VISUAL_HINTS
 | ||||
| 
 | ||||
| void GLCanvas3D::Selection::_synchronize_unselected_instances() | ||||
| { | ||||
|     std::set<unsigned int> done;  // prevent processing volumes twice
 | ||||
|  | @ -2588,11 +2751,6 @@ void GLCanvas3D::Selection::_ensure_on_bed() | |||
| } | ||||
| #endif // ENABLE_ENSURE_ON_BED_WHILE_SCALING
 | ||||
| 
 | ||||
| bool GLCanvas3D::Selection::_requires_local_axes() const | ||||
| { | ||||
|     return (m_mode == Volume) && is_from_single_instance(); | ||||
| } | ||||
| 
 | ||||
| const float GLCanvas3D::Gizmos::OverlayIconsScale = 1.0f; | ||||
| const float GLCanvas3D::Gizmos::OverlayBorder = 5.0f; | ||||
| const float GLCanvas3D::Gizmos::OverlayGapY = 5.0f * OverlayIconsScale; | ||||
|  | @ -3624,6 +3782,7 @@ wxDEFINE_EVENT(EVT_GLCANVAS_RIGHT_CLICK, Vec2dEvent); | |||
| wxDEFINE_EVENT(EVT_GLCANVAS_MODEL_UPDATE, SimpleEvent); | ||||
| wxDEFINE_EVENT(EVT_GLCANVAS_REMOVE_OBJECT, SimpleEvent); | ||||
| wxDEFINE_EVENT(EVT_GLCANVAS_ARRANGE, SimpleEvent); | ||||
| wxDEFINE_EVENT(EVT_GLCANVAS_QUESTION_MARK, SimpleEvent); | ||||
| wxDEFINE_EVENT(EVT_GLCANVAS_INCREASE_INSTANCES, Event<int>); | ||||
| wxDEFINE_EVENT(EVT_GLCANVAS_INSTANCE_MOVED, SimpleEvent); | ||||
| wxDEFINE_EVENT(EVT_GLCANVAS_WIPETOWER_MOVED, Vec3dEvent); | ||||
|  | @ -3787,6 +3946,11 @@ bool GLCanvas3D::init(bool useVBOs, bool use_legacy_opengl) | |||
|     if (!_init_toolbar()) | ||||
|         return false; | ||||
| 
 | ||||
| #if ENABLE_SIDEBAR_VISUAL_HINTS | ||||
|     if (!m_selection.init(m_use_VBOs)) | ||||
|         return false; | ||||
| #endif // ENABLE_SIDEBAR_VISUAL_HINTS
 | ||||
| 
 | ||||
| #if ENABLE_REMOVE_TABS_FROM_PLATER | ||||
|     post_event(SimpleEvent(EVT_GLCANVAS_INIT)); | ||||
| #endif // ENABLE_REMOVE_TABS_FROM_PLATER
 | ||||
|  | @ -4164,6 +4328,10 @@ void GLCanvas3D::render() | |||
|     // this position is used later into on_mouse() to drag the objects
 | ||||
|     m_mouse.scene_position = _mouse_to_3d(m_mouse.position.cast<int>()); | ||||
| 
 | ||||
| #if ENABLE_SIDEBAR_VISUAL_HINTS | ||||
|     _render_selection_sidebar_hints(); | ||||
| #endif // ENABLE_SIDEBAR_VISUAL_HINTS
 | ||||
| 
 | ||||
|     _render_current_gizmo(); | ||||
| #if ENABLE_SHOW_CAMERA_TARGET | ||||
|     _render_camera_target(); | ||||
|  | @ -4777,6 +4945,8 @@ void GLCanvas3D::on_char(wxKeyEvent& evt) | |||
|                 case 43: { post_event(Event<int>(EVT_GLCANVAS_INCREASE_INSTANCES, +1)); break; } | ||||
|                 // key -
 | ||||
|                 case 45: { post_event(Event<int>(EVT_GLCANVAS_INCREASE_INSTANCES, -1)); break; } | ||||
|                 // key ?
 | ||||
|                 case 63: { post_event(SimpleEvent(EVT_GLCANVAS_QUESTION_MARK)); break; } | ||||
|                 // key A/a
 | ||||
|                 case 65: | ||||
|                 case 97: { post_event(SimpleEvent(EVT_GLCANVAS_ARRANGE)); break; } | ||||
|  | @ -5668,6 +5838,11 @@ bool GLCanvas3D::_init_toolbar() | |||
|     icons_data.icon_border_size = 1; | ||||
|     icons_data.icon_gap_size = 1; | ||||
| 
 | ||||
| //    icons_data.filename = "toolbar141.png";
 | ||||
| //    icons_data.icon_size = 52;
 | ||||
| //    icons_data.icon_border_size = 0;
 | ||||
| //    icons_data.icon_gap_size = 0;
 | ||||
| 
 | ||||
|     BackgroundTexture::Metadata background_data; | ||||
|     background_data.filename = "toolbar_background.png"; | ||||
|     background_data.left = 16; | ||||
|  | @ -6574,6 +6749,19 @@ void GLCanvas3D::_render_sla_slices() const | |||
|     } | ||||
| } | ||||
| 
 | ||||
| #if ENABLE_SIDEBAR_VISUAL_HINTS | ||||
| void GLCanvas3D::_render_selection_sidebar_hints() const | ||||
| { | ||||
|     if (m_use_VBOs) | ||||
|         m_shader.start_using(); | ||||
| 
 | ||||
|     m_selection.render_sidebar_hints(m_sidebar_field); | ||||
| 
 | ||||
|     if (m_use_VBOs) | ||||
|         m_shader.stop_using(); | ||||
| } | ||||
| #endif // ENABLE_SIDEBAR_VISUAL_HINTS
 | ||||
| 
 | ||||
| void GLCanvas3D::_update_volumes_hover_state() const | ||||
| { | ||||
|     for (GLVolume* v : m_volumes.volumes) | ||||
|  |  | |||
|  | @ -28,6 +28,7 @@ namespace Slic3r { | |||
| class GLShader; | ||||
| class ExPolygon; | ||||
| class BackgroundSlicingProcess; | ||||
| class GCodePreviewData; | ||||
| 
 | ||||
| namespace GUI { | ||||
| 
 | ||||
|  | @ -105,6 +106,7 @@ wxDECLARE_EVENT(EVT_GLCANVAS_RIGHT_CLICK, Vec2dEvent); | |||
| wxDECLARE_EVENT(EVT_GLCANVAS_MODEL_UPDATE, SimpleEvent); | ||||
| wxDECLARE_EVENT(EVT_GLCANVAS_REMOVE_OBJECT, SimpleEvent); | ||||
| wxDECLARE_EVENT(EVT_GLCANVAS_ARRANGE, SimpleEvent); | ||||
| wxDECLARE_EVENT(EVT_GLCANVAS_QUESTION_MARK, SimpleEvent); | ||||
| wxDECLARE_EVENT(EVT_GLCANVAS_INCREASE_INSTANCES, Event<int>); // data: +1 => increase, -1 => decrease
 | ||||
| wxDECLARE_EVENT(EVT_GLCANVAS_INSTANCE_MOVED, SimpleEvent); | ||||
| wxDECLARE_EVENT(EVT_GLCANVAS_WIPETOWER_MOVED, Vec3dEvent); | ||||
|  | @ -367,6 +369,12 @@ class GLCanvas3D | |||
| public: | ||||
|     class Selection | ||||
|     { | ||||
| #if ENABLE_SIDEBAR_VISUAL_HINTS | ||||
|         static const float RED[3]; | ||||
|         static const float GREEN[3]; | ||||
|         static const float BLUE[3]; | ||||
| #endif // ENABLE_SIDEBAR_VISUAL_HINTS
 | ||||
| 
 | ||||
|     public: | ||||
|         typedef std::set<unsigned int> IndicesList; | ||||
| 
 | ||||
|  | @ -494,6 +502,9 @@ public: | |||
| #if ENABLE_RENDER_SELECTION_CENTER | ||||
|         GLUquadricObj* m_quadric; | ||||
| #endif // ENABLE_RENDER_SELECTION_CENTER
 | ||||
| #if ENABLE_SIDEBAR_VISUAL_HINTS | ||||
|         mutable GLArrow m_arrow; | ||||
| #endif // ENABLE_SIDEBAR_VISUAL_HINTS
 | ||||
| 
 | ||||
|     public: | ||||
|         Selection(); | ||||
|  | @ -502,6 +513,9 @@ public: | |||
| #endif // ENABLE_RENDER_SELECTION_CENTER
 | ||||
| 
 | ||||
|         void set_volumes(GLVolumePtrs* volumes); | ||||
| #if ENABLE_SIDEBAR_VISUAL_HINTS | ||||
|         bool init(bool useVBOs); | ||||
| #endif // ENABLE_SIDEBAR_VISUAL_HINTS
 | ||||
| 
 | ||||
|         Model* get_model() const { return m_model; } | ||||
|         void set_model(Model* model); | ||||
|  | @ -564,7 +578,7 @@ public: | |||
| 
 | ||||
|         void start_dragging(); | ||||
| 
 | ||||
|         void translate(const Vec3d& displacement); | ||||
|         void translate(const Vec3d& displacement, bool local = false); | ||||
|         void rotate(const Vec3d& rotation, bool local); | ||||
|         void flattening_rotate(const Vec3d& normal); | ||||
|         void scale(const Vec3d& scale, bool local); | ||||
|  | @ -579,6 +593,11 @@ public: | |||
| #if ENABLE_RENDER_SELECTION_CENTER | ||||
|         void render_center() const; | ||||
| #endif // ENABLE_RENDER_SELECTION_CENTER
 | ||||
| #if ENABLE_SIDEBAR_VISUAL_HINTS | ||||
|         void render_sidebar_hints(const std::string& sidebar_field) const; | ||||
| #endif // ENABLE_SIDEBAR_VISUAL_HINTS
 | ||||
| 
 | ||||
|         bool requires_local_axes() const; | ||||
| 
 | ||||
|     private: | ||||
|         void _update_valid(); | ||||
|  | @ -594,12 +613,21 @@ public: | |||
|         void _render_selected_volumes() const; | ||||
|         void _render_synchronized_volumes() const; | ||||
|         void _render_bounding_box(const BoundingBoxf3& box, float* color) const; | ||||
| #if ENABLE_SIDEBAR_VISUAL_HINTS | ||||
|         void _render_sidebar_position_hints(const std::string& sidebar_field) const; | ||||
|         void _render_sidebar_rotation_hints(const std::string& sidebar_field) const; | ||||
|         void _render_sidebar_scale_hints(const std::string& sidebar_field) const; | ||||
|         void _render_sidebar_size_hints(const std::string& sidebar_field) const; | ||||
|         void _render_sidebar_position_hint(Axis axis) const; | ||||
|         void _render_sidebar_rotation_hint(Axis axis, double length) const; | ||||
|         void _render_sidebar_scale_hint(Axis axis) const; | ||||
|         void _render_sidebar_size_hint(Axis axis, double length) const; | ||||
| #endif // ENABLE_SIDEBAR_VISUAL_HINTS
 | ||||
|         void _synchronize_unselected_instances(); | ||||
|         void _synchronize_unselected_volumes(); | ||||
| #if ENABLE_ENSURE_ON_BED_WHILE_SCALING | ||||
|         void _ensure_on_bed(); | ||||
| #endif // ENABLE_ENSURE_ON_BED_WHILE_SCALING
 | ||||
|         bool _requires_local_axes() const; | ||||
|     }; | ||||
| 
 | ||||
|     class ClippingPlane | ||||
|  | @ -1054,6 +1082,9 @@ private: | |||
|     void _render_camera_target() const; | ||||
| #endif // ENABLE_SHOW_CAMERA_TARGET
 | ||||
|     void _render_sla_slices() const; | ||||
| #if ENABLE_SIDEBAR_VISUAL_HINTS | ||||
|     void _render_selection_sidebar_hints() const; | ||||
| #endif // ENABLE_SIDEBAR_VISUAL_HINTS
 | ||||
| 
 | ||||
|     void _update_volumes_hover_state() const; | ||||
|     void _update_gizmos_data(); | ||||
|  |  | |||
|  | @ -19,7 +19,6 @@ class ExPolygon; | |||
| typedef std::vector<ExPolygon> ExPolygons; | ||||
| class ModelObject; | ||||
| class PrintObject; | ||||
| class GCodePreviewData; | ||||
| 
 | ||||
| namespace GUI { | ||||
| 
 | ||||
|  |  | |||
|  | @ -16,7 +16,6 @@ namespace Slic3r { | |||
| class AppConfig; | ||||
| class DynamicPrintConfig; | ||||
| class Print; | ||||
| class GCodePreviewData; | ||||
| 
 | ||||
| namespace GUI { | ||||
| 
 | ||||
|  |  | |||
|  | @ -35,6 +35,7 @@ | |||
| #include "Preferences.hpp" | ||||
| #include "Tab.hpp" | ||||
| #include "SysInfoDialog.hpp" | ||||
| #include "KBShortcutsDialog.hpp" | ||||
| 
 | ||||
| namespace Slic3r { | ||||
| namespace GUI { | ||||
|  | @ -301,6 +302,13 @@ void GUI_App::system_info() | |||
|     dlg.Destroy(); | ||||
| } | ||||
| 
 | ||||
| void GUI_App::keyboard_shortcuts() | ||||
| { | ||||
|     KBShortcutsDialog dlg; | ||||
|     dlg.ShowModal(); | ||||
|     dlg.Destroy(); | ||||
| } | ||||
| 
 | ||||
| // static method accepting a wxWindow object as first parameter
 | ||||
| bool GUI_App::catch_error(std::function<void()> cb, | ||||
|     //                       wxMessageDialog* message_dialog,
 | ||||
|  | @ -426,7 +434,7 @@ bool GUI_App::select_language(  wxArrayString & names, | |||
|         m_wxLocale = new wxLocale; | ||||
|         m_wxLocale->Init(identifiers[index]); | ||||
|         m_wxLocale->AddCatalogLookupPathPrefix(localization_dir()); | ||||
|         m_wxLocale->AddCatalog(GetAppName()); | ||||
|         m_wxLocale->AddCatalog(/*GetAppName()*/"Slic3rPE"); | ||||
|         wxSetlocale(LC_NUMERIC, "C"); | ||||
|         Preset::update_suffix_modified(); | ||||
|         return true; | ||||
|  | @ -453,7 +461,7 @@ bool GUI_App::load_language() | |||
|             m_wxLocale = new wxLocale; | ||||
|             m_wxLocale->Init(identifiers[i]); | ||||
|             m_wxLocale->AddCatalogLookupPathPrefix(localization_dir()); | ||||
|             m_wxLocale->AddCatalog(GetAppName()); | ||||
|             m_wxLocale->AddCatalog(/*GetAppName()*/"Slic3rPE"); | ||||
|             wxSetlocale(LC_NUMERIC, "C"); | ||||
|             Preset::update_suffix_modified(); | ||||
|             return true; | ||||
|  | @ -496,7 +504,8 @@ void GUI_App::get_installed_languages(wxArrayString & names, wxArrayLong & ident | |||
|         { | ||||
|             auto full_file_name = dir.GetName() + wxFileName::GetPathSeparator() + | ||||
|                 filename + wxFileName::GetPathSeparator() + | ||||
|                 GetAppName() + wxT(".mo"); | ||||
|                 /*GetAppName()*/"Slic3rPE" +  | ||||
|                 wxT(".mo"); | ||||
|             if (wxFileExists(full_file_name)) | ||||
|             { | ||||
|                 names.Add(langinfo->Description); | ||||
|  |  | |||
|  | @ -115,6 +115,7 @@ public: | |||
| 
 | ||||
|     void            recreate_GUI(); | ||||
|     void            system_info(); | ||||
|     void            keyboard_shortcuts(); | ||||
|     void            load_project(wxWindow *parent, wxString& input_file); | ||||
|     void            import_model(wxWindow *parent, wxArrayString& input_files); | ||||
|     static bool     catch_error(std::function<void()> cb, | ||||
|  |  | |||
|  | @ -361,8 +361,9 @@ void ObjectManipulation::update_rotation_value(const Vec3d& rotation) | |||
| void ObjectManipulation::change_position_value(const Vec3d& position) | ||||
| { | ||||
|     auto canvas = wxGetApp().plater()->canvas3D(); | ||||
|     canvas->get_selection().start_dragging(); | ||||
|     canvas->get_selection().translate(position - cache_position); | ||||
|     GLCanvas3D::Selection& selection = canvas->get_selection(); | ||||
|     selection.start_dragging(); | ||||
|     selection.translate(position - cache_position, selection.requires_local_axes()); | ||||
|     canvas->do_move(); | ||||
| 
 | ||||
|     cache_position = position; | ||||
|  |  | |||
|  | @ -395,12 +395,6 @@ void Preview::set_number_extruders(unsigned int number_extruders) | |||
|     } | ||||
| } | ||||
| 
 | ||||
| void Preview::reset_gcode_preview_data() | ||||
| { | ||||
|     m_gcode_preview_data->reset(); | ||||
|     m_canvas->reset_legend_texture(); | ||||
| } | ||||
| 
 | ||||
| void Preview::set_canvas_as_dirty() | ||||
| { | ||||
|     m_canvas->set_as_dirty(); | ||||
|  | @ -451,6 +445,7 @@ void Preview::load_print() | |||
| void Preview::reload_print(bool force) | ||||
| { | ||||
|     m_canvas->reset_volumes(); | ||||
|     m_canvas->reset_legend_texture(); | ||||
|     m_loaded = false; | ||||
| 
 | ||||
|     if (!IsShown() && !force) | ||||
|  | @ -759,7 +754,8 @@ void Preview::load_print_as_fff() | |||
| 
 | ||||
|     // Collect colors per extruder.
 | ||||
|     std::vector<std::string> colors; | ||||
|     if (!m_gcode_preview_data->empty() || (m_gcode_preview_data->extrusion.view_type == GCodePreviewData::Extrusion::Tool)) | ||||
|     bool gcode_preview_data_valid = print->is_step_done(psGCodeExport) && ! m_gcode_preview_data->empty(); | ||||
|     if (gcode_preview_data_valid || (m_gcode_preview_data->extrusion.view_type == GCodePreviewData::Extrusion::Tool)) | ||||
|     { | ||||
|         const ConfigOptionStrings* extruders_opt = dynamic_cast<const ConfigOptionStrings*>(m_config->option("extruder_colour")); | ||||
|         const ConfigOptionStrings* filamemts_opt = dynamic_cast<const ConfigOptionStrings*>(m_config->option("filament_colour")); | ||||
|  | @ -785,13 +781,7 @@ void Preview::load_print_as_fff() | |||
|         // used to set the sliders to the extremes of the current zs range
 | ||||
|         m_force_sliders_full_range = false; | ||||
| 
 | ||||
|         if (m_gcode_preview_data->empty()) | ||||
|         { | ||||
|             // load skirt and brim
 | ||||
|             m_canvas->load_preview(colors); | ||||
|             show_hide_ui_elements("simple"); | ||||
|         } | ||||
|         else | ||||
|         if (gcode_preview_data_valid) | ||||
|         { | ||||
|             m_force_sliders_full_range = (m_canvas->get_volumes_count() == 0); | ||||
|             m_canvas->load_gcode_preview(*m_gcode_preview_data, colors); | ||||
|  | @ -805,8 +795,15 @@ void Preview::load_print_as_fff() | |||
|                 reset_sliders(); | ||||
|                 m_canvas_widget->Refresh(); | ||||
|             } | ||||
|         }  | ||||
|         else | ||||
|         { | ||||
|             // load skirt and brim
 | ||||
|             m_canvas->load_preview(colors); | ||||
|             show_hide_ui_elements("simple"); | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         if (n_layers > 0) | ||||
|             update_sliders(m_canvas->get_current_print_zs(true)); | ||||
| 
 | ||||
|  |  | |||
|  | @ -140,7 +140,6 @@ public: | |||
| #endif // ENABLE_REMOVE_TABS_FROM_PLATER
 | ||||
| 
 | ||||
|     void set_number_extruders(unsigned int number_extruders); | ||||
|     void reset_gcode_preview_data(); | ||||
|     void set_canvas_as_dirty(); | ||||
|     void set_enabled(bool enabled); | ||||
|     void set_bed_shape(const Pointfs& shape); | ||||
|  |  | |||
							
								
								
									
										153
									
								
								src/slic3r/GUI/KBShortcutsDialog.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						|  | @ -0,0 +1,153 @@ | |||
| #include "KBShortcutsDialog.hpp" | ||||
| #include "I18N.hpp" | ||||
| #include "libslic3r/Utils.hpp" | ||||
| #include "GUI.hpp" | ||||
| #include <wx/scrolwin.h> | ||||
| 
 | ||||
| namespace Slic3r {  | ||||
| namespace GUI { | ||||
| 
 | ||||
| KBShortcutsDialog::KBShortcutsDialog() | ||||
|     : wxDialog(NULL, wxID_ANY, _(L("Slic3r Prusa Edition - Keyboard Shortcuts")), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER) | ||||
| { | ||||
| 	SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));     | ||||
| 
 | ||||
| 	auto main_sizer = new wxBoxSizer(wxVERTICAL); | ||||
| 
 | ||||
|     // logo
 | ||||
| 	wxBitmap logo_bmp = wxBitmap(from_u8(Slic3r::var("Slic3r_32px.png")), wxBITMAP_TYPE_PNG); | ||||
| 
 | ||||
|     // fonts
 | ||||
|     wxFont head_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Bold(); | ||||
|     head_font.SetPointSize(19); | ||||
| 
 | ||||
|     wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); | ||||
|     font.SetPointSize(10); | ||||
|     wxFont bold_font = font.Bold(); | ||||
| #ifdef __WXOSX__ | ||||
|     font.SetPointSize(12); | ||||
|     bold_font.SetPointSize(14); | ||||
| #endif /*__WXOSX__*/ | ||||
| 
 | ||||
|     fill_shortcuts(); | ||||
| 
 | ||||
|     auto panel = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxSize(500, 600)); | ||||
|     panel->SetScrollbars(0, 20, 1, 2); | ||||
|     auto  sizer = new wxBoxSizer(wxVERTICAL); | ||||
|     panel->SetSizer(sizer); | ||||
|     main_sizer->Add(panel, 1, wxEXPAND | wxALL, 0); | ||||
| 
 | ||||
|     for (auto& sc : m_full_shortcuts) | ||||
|     { | ||||
|         wxBoxSizer* hsizer = new wxBoxSizer(wxHORIZONTAL); | ||||
|         sizer->Add(hsizer, 0, wxEXPAND | wxTOP, 25); | ||||
| 
 | ||||
|         // logo
 | ||||
|         auto *logo = new wxStaticBitmap(panel, wxID_ANY, logo_bmp); | ||||
|         hsizer->Add(logo, 0, wxEXPAND | wxLEFT | wxRIGHT, 15); | ||||
| 
 | ||||
|         // head
 | ||||
|         wxStaticText* head = new wxStaticText(panel, wxID_ANY, sc.first, wxDefaultPosition, wxSize(400,-1)); | ||||
|         head->SetFont(head_font); | ||||
|         hsizer->Add(head, 0, wxALIGN_CENTER_VERTICAL); | ||||
| 
 | ||||
|         // Shortcuts list
 | ||||
|         auto grid_sizer = new wxFlexGridSizer(2, 10, 25); | ||||
|         sizer->Add(grid_sizer, 0, wxEXPAND | wxLEFT | wxTOP, 10); | ||||
| 
 | ||||
|         for (auto pair : sc.second) | ||||
|         { | ||||
|             auto shortcut = new wxStaticText(panel, wxID_ANY, _(pair.first)); | ||||
|             shortcut->SetFont(bold_font); | ||||
|             grid_sizer->Add(shortcut, -1, wxALIGN_CENTRE_VERTICAL); | ||||
| 
 | ||||
|             auto description = new wxStaticText(panel, wxID_ANY, _(pair.second)); | ||||
|             description->SetFont(font); | ||||
|             grid_sizer->Add(description, -1, wxALIGN_CENTRE_VERTICAL); | ||||
|         } | ||||
|     } | ||||
|    | ||||
|     wxStdDialogButtonSizer* buttons = this->CreateStdDialogButtonSizer(wxOK); | ||||
| 
 | ||||
|     this->SetEscapeId(wxID_CLOSE); | ||||
|     this->Bind(wxEVT_BUTTON, &KBShortcutsDialog::onCloseDialog, this, wxID_OK); | ||||
|     main_sizer->Add(buttons, 0, wxEXPAND | wxALL, 15); | ||||
|      | ||||
|     this->Bind(wxEVT_LEFT_DOWN, &KBShortcutsDialog::onCloseDialog, this); | ||||
| 
 | ||||
| 	SetSizer(main_sizer); | ||||
| 	main_sizer->SetSizeHints(this); | ||||
| } | ||||
| 
 | ||||
| void KBShortcutsDialog::fill_shortcuts() | ||||
| { | ||||
|     Shortcuts main_shortcuts; | ||||
|     main_shortcuts.reserve(25); | ||||
| 
 | ||||
|     main_shortcuts.push_back(Shortcut("Ctrl+O",         L("Open project STL/OBJ/AMF/3MF with config, delete bed"))); | ||||
|     main_shortcuts.push_back(Shortcut("Ctrl+I",         L("Import STL//OBJ/AMF/3MF without config, keep bed"))); | ||||
|     main_shortcuts.push_back(Shortcut("Ctrl+L",         L("Load Config from .ini/amf/3mf/gcode"))); | ||||
|     main_shortcuts.push_back(Shortcut("Ctrl+Alt+L",     L("Load Config from .ini/amf/3mf/gcode and merge"))); | ||||
|     main_shortcuts.push_back(Shortcut("Ctrl+G",         L("Export Gcode"))); | ||||
|     main_shortcuts.push_back(Shortcut("Ctrl+S",         L("Save project (3MF)"))); | ||||
|     main_shortcuts.push_back(Shortcut("Ctrl+R",         L("(Re)slice"))); | ||||
|     main_shortcuts.push_back(Shortcut("Ctrl+U",         L("Quick slice"))); | ||||
|     main_shortcuts.push_back(Shortcut("Ctrl+Alt+U",     L("Quick slice and Save as"))); | ||||
|     main_shortcuts.push_back(Shortcut("Ctrl+Shift+U",   L("Repeat last quick slice"))); | ||||
|     main_shortcuts.push_back(Shortcut("Ctrl+1",         L("Select Plater Tab"))); | ||||
|     main_shortcuts.push_back(Shortcut("Ctrl+2",         L("Select Print Settings Tab"))); | ||||
|     main_shortcuts.push_back(Shortcut("Ctrl+3",         L("Select Filament Setting Tab"))); | ||||
|     main_shortcuts.push_back(Shortcut("Ctrl+4",         L("Select Printer Setting Tab"))); | ||||
|     main_shortcuts.push_back(Shortcut("Ctrl+5",         L("Switch to 3D"))); | ||||
|     main_shortcuts.push_back(Shortcut("Ctrl+6",         L("Switch to Preview"))); | ||||
|     main_shortcuts.push_back(Shortcut("Ctrl+P",         L("Preferences"))); | ||||
|     main_shortcuts.push_back(Shortcut("0-6",            L("Camera view "))); | ||||
|     main_shortcuts.push_back(Shortcut("+",              L("Add Instance to selected object "))); | ||||
|     main_shortcuts.push_back(Shortcut("-",              L("Remove Instance from selected object"))); | ||||
|     main_shortcuts.push_back(Shortcut("?",              L("Show keyboard shortcuts list"))); | ||||
|     main_shortcuts.push_back(Shortcut("PgUp/PgDn",      L("Switch between 3D and Preview"))); | ||||
|     main_shortcuts.push_back(Shortcut("Shift+LeftMouse",L("Select multiple object/Move multiple object"))); | ||||
| 
 | ||||
|     m_full_shortcuts.emplace(_(L("Main Shortcuts")),    main_shortcuts); | ||||
| 
 | ||||
| 
 | ||||
|     Shortcuts plater_shortcuts; | ||||
|     plater_shortcuts.reserve(20); | ||||
| 
 | ||||
|     plater_shortcuts.push_back(Shortcut("A",        L("Arrange"))); | ||||
|     plater_shortcuts.push_back(Shortcut("Ctrl+A",   L("Select All objects"))); | ||||
|     plater_shortcuts.push_back(Shortcut("Del",      L("Delete selected"))); | ||||
|     plater_shortcuts.push_back(Shortcut("Ctrl+Del", L("Delete all"))); | ||||
|     plater_shortcuts.push_back(Shortcut("M",        L("Gizmo move"))); | ||||
|     plater_shortcuts.push_back(Shortcut("S",        L("Gizmo scale"))); | ||||
|     plater_shortcuts.push_back(Shortcut("R",        L("Gizmo rotate"))); | ||||
|     plater_shortcuts.push_back(Shortcut("C",        L("Gizmo cut"))); | ||||
|     plater_shortcuts.push_back(Shortcut("F",        L("Gizmo Place face on bed"))); | ||||
|     plater_shortcuts.push_back(Shortcut("L",        L("Gizmo SLA support points"))); | ||||
|     plater_shortcuts.push_back(Shortcut("B",        L("Zoom to Bed"))); | ||||
|     plater_shortcuts.push_back(Shortcut("Z",        L("Zoom to all objects in scene, if none selected"))); | ||||
|     plater_shortcuts.push_back(Shortcut("Z",        L("Zoom to selected object"))); | ||||
|     plater_shortcuts.push_back(Shortcut("I",        L("Zoom in"))); | ||||
|     plater_shortcuts.push_back(Shortcut("O",        L("Zoom out"))); | ||||
|     plater_shortcuts.push_back(Shortcut("ESC",      L("Unselect gizmo, keep object selection"))); | ||||
| 
 | ||||
|     m_full_shortcuts.emplace(_(L("Plater Shortcuts")),  plater_shortcuts); | ||||
| 
 | ||||
| 
 | ||||
|     Shortcuts preview_shortcuts; | ||||
|     preview_shortcuts.reserve(2); | ||||
| 
 | ||||
|     preview_shortcuts.push_back(Shortcut(L("Arrow Up"),     L("Upper Layer"))); | ||||
|     preview_shortcuts.push_back(Shortcut(L("Arrow Down"),   L("Lower Layer"))); | ||||
| 
 | ||||
|     m_full_shortcuts.emplace(_(L("Preview Shortcuts")), preview_shortcuts); | ||||
| } | ||||
| 
 | ||||
| void KBShortcutsDialog::onCloseDialog(wxEvent &) | ||||
| { | ||||
|     this->EndModal(wxID_CLOSE); | ||||
|     this->Close(); | ||||
| } | ||||
| 
 | ||||
| } // namespace GUI
 | ||||
| } // namespace Slic3r
 | ||||
							
								
								
									
										32
									
								
								src/slic3r/GUI/KBShortcutsDialog.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						|  | @ -0,0 +1,32 @@ | |||
| #ifndef slic3r_GUI_KBShortcutsDialog_hpp_ | ||||
| #define slic3r_GUI_KBShortcutsDialog_hpp_ | ||||
| 
 | ||||
| #include <wx/wx.h> | ||||
| #include <map> | ||||
| 
 | ||||
| namespace Slic3r {  | ||||
| namespace GUI { | ||||
| 
 | ||||
| class KBShortcutsDialog : public wxDialog | ||||
| { | ||||
|     typedef std::pair<std::string, std::string> Shortcut; | ||||
|     typedef std::vector< Shortcut >             Shortcuts; | ||||
|     typedef std::map<wxString, Shortcuts>       ShortcutsMap; | ||||
| 
 | ||||
|     wxString text_info {wxEmptyString}; | ||||
| 
 | ||||
|     ShortcutsMap m_full_shortcuts; | ||||
| 
 | ||||
| public: | ||||
|     KBShortcutsDialog(); | ||||
|      | ||||
|     void fill_shortcuts(); | ||||
| 
 | ||||
| private: | ||||
|     void onCloseDialog(wxEvent &); | ||||
| }; | ||||
| 
 | ||||
| } // namespace GUI
 | ||||
| } // namespace Slic3r
 | ||||
| 
 | ||||
| #endif | ||||
|  | @ -432,6 +432,9 @@ void MainFrame::init_menubar() | |||
|             [this](wxCommandEvent&) { wxLaunchDefaultBrowser("http://github.com/prusa3d/slic3r/issues/new"); }); | ||||
|         append_menu_item(helpMenu, wxID_ANY, _(L("About Slic3r")), _(L("Show about dialog")), | ||||
|             [this](wxCommandEvent&) { Slic3r::GUI::about(); }); | ||||
|         helpMenu->AppendSeparator(); | ||||
|         append_menu_item(helpMenu, wxID_ANY, _(L("Keyboard Shortcuts")) + "\t?", _(L("Show the list of the keyboard shortcuts")), | ||||
|             [this](wxCommandEvent&) { wxGetApp().keyboard_shortcuts(); }); | ||||
|     } | ||||
| 
 | ||||
|     // menubar
 | ||||
|  |  | |||
|  | @ -1186,6 +1186,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) | |||
|     view3D_canvas->Bind(EVT_GLCANVAS_MODEL_UPDATE, [this](SimpleEvent&) { this->schedule_background_process(); }); | ||||
|     view3D_canvas->Bind(EVT_GLCANVAS_REMOVE_OBJECT, [q](SimpleEvent&) { q->remove_selected(); }); | ||||
|     view3D_canvas->Bind(EVT_GLCANVAS_ARRANGE, [this](SimpleEvent&) { arrange(); }); | ||||
|     view3D_canvas->Bind(EVT_GLCANVAS_QUESTION_MARK, [this](SimpleEvent&) { wxGetApp().keyboard_shortcuts(); }); | ||||
|     view3D_canvas->Bind(EVT_GLCANVAS_INCREASE_INSTANCES, [this](Event<int> &evt)  | ||||
|         { if (evt.data == 1) this->q->increase_instances(); else if (this->can_decrease_instances()) this->q->decrease_instances(); }); | ||||
|     view3D_canvas->Bind(EVT_GLCANVAS_INSTANCE_MOVED, [this](SimpleEvent&) { update(); }); | ||||
|  | @ -1273,7 +1274,6 @@ void Plater::priv::update(bool force_full_scene_refresh) | |||
| #else | ||||
|     this->canvas3D->reload_scene(false, force_full_scene_refresh); | ||||
| #endif // ENABLE_REMOVE_TABS_FROM_PLATER
 | ||||
|     preview->reset_gcode_preview_data(); | ||||
|     preview->reload_print(); | ||||
| 
 | ||||
|     this->schedule_background_process(); | ||||
|  | @ -2010,7 +2010,6 @@ unsigned int Plater::priv::update_background_process() | |||
|         this->sidebar->show_sliced_info_sizer(false); | ||||
|         // Reset preview canvases. If the print has been invalidated, the preview canvases will be cleared.
 | ||||
|         // Otherwise they will be just refreshed.
 | ||||
|         this->gcode_preview_data.reset(); | ||||
|         switch (this->printer_technology) { | ||||
|         case ptFFF: | ||||
|             if (this->preview != nullptr) | ||||
|  |  | |||
|  | @ -1551,7 +1551,7 @@ void TabPrinter::build_printhost(ConfigOptionsGroup *optgroup) | |||
| 
 | ||||
| 	auto printhost_browse = [this, optgroup] (wxWindow* parent) { | ||||
| 
 | ||||
| 		// TODO: SLA
 | ||||
| 		// TODO: SLA Bonjour
 | ||||
| 
 | ||||
| 		auto btn = m_printhost_browse_btn = new wxButton(parent, wxID_ANY, _(L(" Browse "))+dots, wxDefaultPosition, wxDefaultSize, wxBU_LEFT); | ||||
| 		btn->SetBitmap(wxBitmap(from_u8(Slic3r::var("zoom.png")), wxBITMAP_TYPE_PNG)); | ||||
|  | @ -1562,6 +1562,7 @@ void TabPrinter::build_printhost(ConfigOptionsGroup *optgroup) | |||
| 			BonjourDialog dialog(parent); | ||||
| 			if (dialog.show_and_lookup()) { | ||||
| 				optgroup->set_value("print_host", std::move(dialog.get_selected()), true); | ||||
| 				// FIXME: emit killfocus on the edit widget
 | ||||
| 			} | ||||
| 		}); | ||||
| 
 | ||||
|  |  | |||
|  | @ -19,12 +19,12 @@ public: | |||
| 	Duet(DynamicPrintConfig *config); | ||||
| 	virtual ~Duet(); | ||||
| 
 | ||||
| 	bool test(wxString &curl_msg) const; | ||||
| 	wxString get_test_ok_msg () const; | ||||
| 	wxString get_test_failed_msg (wxString &msg) const; | ||||
| 	bool upload(PrintHostUpload upload_data, Http::ProgressFn prorgess_fn, Http::ErrorFn error_fn) const; | ||||
| 	bool has_auto_discovery() const; | ||||
| 	bool can_test() const; | ||||
| 	virtual bool test(wxString &curl_msg) const; | ||||
| 	virtual wxString get_test_ok_msg () const; | ||||
| 	virtual wxString get_test_failed_msg (wxString &msg) const; | ||||
| 	virtual bool upload(PrintHostUpload upload_data, Http::ProgressFn prorgess_fn, Http::ErrorFn error_fn) const; | ||||
| 	virtual bool has_auto_discovery() const; | ||||
| 	virtual bool can_test() const; | ||||
| 	virtual std::string get_host() const { return host; } | ||||
| private: | ||||
| 	std::string host; | ||||
|  |  | |||
|  | @ -1,8 +1,12 @@ | |||
| #include "OctoPrint.hpp" | ||||
| 
 | ||||
| #include <algorithm> | ||||
| #include <sstream> | ||||
| #include <boost/format.hpp> | ||||
| #include <boost/log/trivial.hpp> | ||||
| #include <boost/property_tree/ptree.hpp> | ||||
| #include <boost/property_tree/json_parser.hpp> | ||||
| #include <boost/algorithm/string/predicate.hpp> | ||||
| 
 | ||||
| #include <wx/progdlg.h> | ||||
| 
 | ||||
|  | @ -12,6 +16,7 @@ | |||
| 
 | ||||
| 
 | ||||
| namespace fs = boost::filesystem; | ||||
| namespace pt = boost::property_tree; | ||||
| 
 | ||||
| 
 | ||||
| namespace Slic3r { | ||||
|  | @ -41,11 +46,29 @@ bool OctoPrint::test(wxString &msg) const | |||
|             res = false; | ||||
|             msg = format_error(body, error, status); | ||||
|         }) | ||||
|         .on_complete([&](std::string body, unsigned) { | ||||
|         .on_complete([&, this](std::string body, unsigned) { | ||||
|             BOOST_LOG_TRIVIAL(debug) << boost::format("Octoprint: Got version: %1%") % body; | ||||
| 
 | ||||
|             // TODO: parse body, call validate_version_text
 | ||||
|             try { | ||||
|                 std::stringstream ss(body); | ||||
|                 pt::ptree ptree; | ||||
|                 pt::read_json(ss, ptree); | ||||
| 
 | ||||
|                 if (! ptree.get_optional<std::string>("api")) { | ||||
|                     res = false; | ||||
|                     return; | ||||
|                 } | ||||
| 
 | ||||
|                 const auto text = ptree.get_optional<std::string>("text"); | ||||
|                 res = validate_version_text(text); | ||||
|                 if (! res) { | ||||
|                     msg = wxString::Format("Mismatched type of print host: %s", text ? *text : "OctoPrint"); | ||||
|                 } | ||||
|             } | ||||
|             catch (...) { | ||||
|                 res = false; | ||||
|                 msg = "Could not parse server response"; | ||||
|             } | ||||
|         }) | ||||
|         .perform_sync(); | ||||
| 
 | ||||
|  | @ -71,7 +94,7 @@ bool OctoPrint::upload(PrintHostUpload upload_data, Http::ProgressFn prorgess_fn | |||
|     wxString test_msg; | ||||
|     if (! test(test_msg)) { | ||||
| 
 | ||||
|         // TODO:
 | ||||
|         // FIXME:
 | ||||
| 
 | ||||
|         // auto errormsg = wxString::Format("%s: %s", errortitle, test_msg);
 | ||||
|         // GUI::show_error(&progress_dialog, std::move(errormsg));
 | ||||
|  | @ -125,10 +148,9 @@ bool OctoPrint::can_test() const | |||
|     return true; | ||||
| } | ||||
| 
 | ||||
| bool OctoPrint::validate_version_text(const std::string &version_text) | ||||
| bool OctoPrint::validate_version_text(const boost::optional<std::string> &version_text) const | ||||
| { | ||||
|     // FIXME
 | ||||
|     return true; | ||||
|     return version_text ? boost::starts_with(*version_text, "OctoPrint") : true; | ||||
| } | ||||
| 
 | ||||
| void OctoPrint::set_auth(Http &http) const | ||||
|  | @ -164,14 +186,23 @@ wxString OctoPrint::format_error(const std::string &body, const std::string &err | |||
| } | ||||
| 
 | ||||
| 
 | ||||
| // SL1
 | ||||
| // SLAHost
 | ||||
| 
 | ||||
| SL1Host::~SL1Host() {} | ||||
| SLAHost::~SLAHost() {} | ||||
| 
 | ||||
| bool SL1Host::validate_version_text(const std::string &version_text) | ||||
| wxString SLAHost::get_test_ok_msg () const | ||||
| { | ||||
|     // FIXME
 | ||||
|     return true; | ||||
|     return wxString::Format("%s", _(L("Connection to Prusa SLA works correctly."))); | ||||
| } | ||||
| 
 | ||||
| wxString SLAHost::get_test_failed_msg (wxString &msg) const | ||||
| { | ||||
|     return wxString::Format("%s: %s", _(L("Could not connect to Prusa SLA")), msg); | ||||
| } | ||||
| 
 | ||||
| bool SLAHost::validate_version_text(const boost::optional<std::string> &version_text) const | ||||
| { | ||||
|     return version_text ? boost::starts_with(*version_text, "Prusa SLA") : false; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -3,6 +3,7 @@ | |||
| 
 | ||||
| #include <string> | ||||
| #include <wx/string.h> | ||||
| #include <boost/optional.hpp> | ||||
| 
 | ||||
| #include "PrintHost.hpp" | ||||
| 
 | ||||
|  | @ -19,16 +20,16 @@ public: | |||
|     OctoPrint(DynamicPrintConfig *config); | ||||
|     virtual ~OctoPrint(); | ||||
| 
 | ||||
|     bool test(wxString &curl_msg) const; | ||||
|     wxString get_test_ok_msg () const; | ||||
|     wxString get_test_failed_msg (wxString &msg) const; | ||||
|     bool upload(PrintHostUpload upload_data, Http::ProgressFn prorgess_fn, Http::ErrorFn error_fn) const; | ||||
|     bool has_auto_discovery() const; | ||||
|     bool can_test() const; | ||||
|     virtual bool test(wxString &curl_msg) const; | ||||
|     virtual wxString get_test_ok_msg () const; | ||||
|     virtual wxString get_test_failed_msg (wxString &msg) const; | ||||
|     virtual bool upload(PrintHostUpload upload_data, Http::ProgressFn prorgess_fn, Http::ErrorFn error_fn) const; | ||||
|     virtual bool has_auto_discovery() const; | ||||
|     virtual bool can_test() const; | ||||
|     virtual std::string get_host() const { return host; } | ||||
| 
 | ||||
| protected: | ||||
|     virtual bool validate_version_text(const std::string &version_text); | ||||
|     virtual bool validate_version_text(const boost::optional<std::string> &version_text) const; | ||||
| 
 | ||||
| private: | ||||
|     std::string host; | ||||
|  | @ -41,14 +42,16 @@ private: | |||
| }; | ||||
| 
 | ||||
| 
 | ||||
| class SL1Host: public OctoPrint | ||||
| class SLAHost: public OctoPrint | ||||
| { | ||||
| public: | ||||
|     SL1Host(DynamicPrintConfig *config) : OctoPrint(config) {} | ||||
|     virtual ~SL1Host(); | ||||
|     SLAHost(DynamicPrintConfig *config) : OctoPrint(config) {} | ||||
|     virtual ~SLAHost(); | ||||
| 
 | ||||
|     virtual wxString get_test_ok_msg () const; | ||||
|     virtual wxString get_test_failed_msg (wxString &msg) const; | ||||
| protected: | ||||
|     virtual bool validate_version_text(const std::string &version_text); | ||||
|     virtual bool validate_version_text(const boost::optional<std::string> &version_text) const; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -30,8 +30,8 @@ PrintHost* PrintHost::get_print_host(DynamicPrintConfig *config) | |||
| 
 | ||||
|     switch (opt->value) { | ||||
|         case htOctoPrint: return new OctoPrint(config); | ||||
|         case htSL1:       return new SL1Host(config); | ||||
|         case htDuet:      return new Duet(config); | ||||
|         case htSL1:       return new SLAHost(config); | ||||
|         default: return nullptr; | ||||
|     } | ||||
| } | ||||
|  |  | |||
 Lukas Matena
						Lukas Matena