mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-11-02 20:51:23 -07:00 
			
		
		
		
	Merge branch 'master' into lm_sla_supports_auto
This commit is contained in:
		
						commit
						75063410ad
					
				
					 45 changed files with 707 additions and 85 deletions
				
			
		| 
						 | 
				
			
			@ -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
									
								
							
							
						
						
									
										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
									
								
							
							
						
						
									
										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;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue