mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-11-02 20:51:23 -07:00 
			
		
		
		
	Merge branch 'master' of https://github.com/prusa3d/Slic3r into sidebar_fixes
This commit is contained in:
		
						commit
						5fa5d495bb
					
				
					 17 changed files with 417 additions and 221 deletions
				
			
		| 
						 | 
				
			
			@ -552,7 +552,7 @@ std::string Model::propose_export_file_name() const
 | 
			
		|||
    for (const ModelObject *model_object : this->objects)
 | 
			
		||||
        for (ModelInstance *model_instance : model_object->instances)
 | 
			
		||||
            if (model_instance->is_printable())
 | 
			
		||||
                return model_object->input_file;
 | 
			
		||||
                return model_object->name.empty() ? model_object->input_file : model_object->name;
 | 
			
		||||
    return std::string();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1686,7 +1686,7 @@ bool model_volume_list_changed(const ModelObject &model_object_old, const ModelO
 | 
			
		|||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef _DEBUG
 | 
			
		||||
#ifndef NDEBUG
 | 
			
		||||
// Verify whether the IDs of Model / ModelObject / ModelVolume / ModelInstance / ModelMaterial are valid and unique.
 | 
			
		||||
void check_model_ids_validity(const Model &model)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -1732,6 +1732,6 @@ void check_model_ids_equal(const Model &model1, const Model &model2)
 | 
			
		|||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
#endif /* _DEBUG */
 | 
			
		||||
#endif /* NDEBUG */
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -629,11 +629,11 @@ extern bool model_object_list_extended(const Model &model_old, const Model &mode
 | 
			
		|||
// than the old ModelObject.
 | 
			
		||||
extern bool model_volume_list_changed(const ModelObject &model_object_old, const ModelObject &model_object_new, const ModelVolume::Type type);
 | 
			
		||||
 | 
			
		||||
#ifdef _DEBUG
 | 
			
		||||
#ifndef NDEBUG
 | 
			
		||||
// Verify whether the IDs of Model / ModelObject / ModelVolume / ModelInstance / ModelMaterial are valid and unique.
 | 
			
		||||
void check_model_ids_validity(const Model &model);
 | 
			
		||||
void check_model_ids_equal(const Model &model1, const Model &model2);
 | 
			
		||||
#endif /* _DEBUG */
 | 
			
		||||
#endif /* NDEBUG */
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -54,3 +54,12 @@
 | 
			
		|||
#define ENABLE_ANISOTROPIC_FILTER_ON_BED_TEXTURES (1 && ENABLE_1_42_0_ALPHA4)
 | 
			
		||||
// Bunch of fixes related to volumes centering
 | 
			
		||||
#define ENABLE_VOLUMES_CENTERING_FIXES (1 && ENABLE_1_42_0_ALPHA4)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//====================
 | 
			
		||||
// 1.42.0.alpha5 techs
 | 
			
		||||
//====================
 | 
			
		||||
#define ENABLE_1_42_0_ALPHA5 1
 | 
			
		||||
 | 
			
		||||
// Toolbar items hidden/shown in dependence of the user mode
 | 
			
		||||
#define ENABLE_MODE_AWARE_TOOLBAR_ITEMS (1 && ENABLE_1_42_0_ALPHA5)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -35,6 +35,27 @@
 | 
			
		|||
 | 
			
		||||
#include "GUI.hpp"
 | 
			
		||||
 | 
			
		||||
#ifdef HAS_GLSAFE
 | 
			
		||||
void glAssertRecentCallImpl()
 | 
			
		||||
{
 | 
			
		||||
    GLenum err = glGetError();
 | 
			
		||||
    if (err == GL_NO_ERROR)
 | 
			
		||||
        return;
 | 
			
		||||
    const char *sErr = 0;
 | 
			
		||||
    switch (err) {
 | 
			
		||||
    case GL_INVALID_ENUM:       sErr = "Invalid Enum";      break;
 | 
			
		||||
    case GL_INVALID_VALUE:      sErr = "Invalid Value";     break;
 | 
			
		||||
    case GL_INVALID_OPERATION:  sErr = "Invalid Operation"; break;
 | 
			
		||||
    case GL_STACK_OVERFLOW:     sErr = "Stack Overflow";    break;
 | 
			
		||||
    case GL_STACK_UNDERFLOW:    sErr = "Stack Underflow";   break;
 | 
			
		||||
    case GL_OUT_OF_MEMORY:      sErr = "Out Of Memory";     break;
 | 
			
		||||
    default:                    sErr = "Unknown";           break;
 | 
			
		||||
    }
 | 
			
		||||
    BOOST_LOG_TRIVIAL(error) << "OpenGL error " << (int)err << ": " << sErr;
 | 
			
		||||
    assert(false);
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace Slic3r {
 | 
			
		||||
 | 
			
		||||
void GLIndexedVertexArray::load_mesh_flat_shading(const TriangleMesh &mesh)
 | 
			
		||||
| 
						 | 
				
			
			@ -81,25 +102,25 @@ void GLIndexedVertexArray::finalize_geometry(bool use_VBOs)
 | 
			
		|||
 | 
			
		||||
    if (use_VBOs) {
 | 
			
		||||
        if (! empty()) {
 | 
			
		||||
            glGenBuffers(1, &this->vertices_and_normals_interleaved_VBO_id);
 | 
			
		||||
            glBindBuffer(GL_ARRAY_BUFFER, this->vertices_and_normals_interleaved_VBO_id);
 | 
			
		||||
            glBufferData(GL_ARRAY_BUFFER, this->vertices_and_normals_interleaved.size() * 4, this->vertices_and_normals_interleaved.data(), GL_STATIC_DRAW);
 | 
			
		||||
            glBindBuffer(GL_ARRAY_BUFFER, 0);
 | 
			
		||||
            glsafe(glGenBuffers(1, &this->vertices_and_normals_interleaved_VBO_id));
 | 
			
		||||
            glsafe(glBindBuffer(GL_ARRAY_BUFFER, this->vertices_and_normals_interleaved_VBO_id));
 | 
			
		||||
            glsafe(glBufferData(GL_ARRAY_BUFFER, this->vertices_and_normals_interleaved.size() * 4, this->vertices_and_normals_interleaved.data(), GL_STATIC_DRAW));
 | 
			
		||||
            glsafe(glBindBuffer(GL_ARRAY_BUFFER, 0));
 | 
			
		||||
            this->vertices_and_normals_interleaved.clear();
 | 
			
		||||
        }
 | 
			
		||||
        if (! this->triangle_indices.empty()) {
 | 
			
		||||
            glGenBuffers(1, &this->triangle_indices_VBO_id);
 | 
			
		||||
            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->triangle_indices_VBO_id);
 | 
			
		||||
            glBufferData(GL_ELEMENT_ARRAY_BUFFER, this->triangle_indices.size() * 4, this->triangle_indices.data(), GL_STATIC_DRAW);
 | 
			
		||||
            glsafe(glGenBuffers(1, &this->triangle_indices_VBO_id));
 | 
			
		||||
            glsafe(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->triangle_indices_VBO_id));
 | 
			
		||||
            glsafe(glBufferData(GL_ELEMENT_ARRAY_BUFFER, this->triangle_indices.size() * 4, this->triangle_indices.data(), GL_STATIC_DRAW));
 | 
			
		||||
            this->triangle_indices.clear();
 | 
			
		||||
        }
 | 
			
		||||
        if (! this->quad_indices.empty()) {
 | 
			
		||||
            glGenBuffers(1, &this->quad_indices_VBO_id);
 | 
			
		||||
            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->quad_indices_VBO_id);
 | 
			
		||||
            glBufferData(GL_ELEMENT_ARRAY_BUFFER, this->quad_indices.size() * 4, this->quad_indices.data(), GL_STATIC_DRAW);
 | 
			
		||||
            glsafe(glGenBuffers(1, &this->quad_indices_VBO_id));
 | 
			
		||||
            glsafe(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->quad_indices_VBO_id));
 | 
			
		||||
            glsafe(glBufferData(GL_ELEMENT_ARRAY_BUFFER, this->quad_indices.size() * 4, this->quad_indices.data(), GL_STATIC_DRAW));
 | 
			
		||||
            this->quad_indices.clear();
 | 
			
		||||
        }
 | 
			
		||||
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
 | 
			
		||||
        glsafe(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
 | 
			
		||||
    }
 | 
			
		||||
    this->shrink_to_fit();
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -107,15 +128,15 @@ void GLIndexedVertexArray::finalize_geometry(bool use_VBOs)
 | 
			
		|||
void GLIndexedVertexArray::release_geometry()
 | 
			
		||||
{
 | 
			
		||||
    if (this->vertices_and_normals_interleaved_VBO_id) {
 | 
			
		||||
        glDeleteBuffers(1, &this->vertices_and_normals_interleaved_VBO_id);
 | 
			
		||||
        glsafe(glDeleteBuffers(1, &this->vertices_and_normals_interleaved_VBO_id));
 | 
			
		||||
        this->vertices_and_normals_interleaved_VBO_id = 0;
 | 
			
		||||
    }
 | 
			
		||||
    if (this->triangle_indices_VBO_id) {
 | 
			
		||||
        glDeleteBuffers(1, &this->triangle_indices_VBO_id);
 | 
			
		||||
        glsafe(glDeleteBuffers(1, &this->triangle_indices_VBO_id));
 | 
			
		||||
        this->triangle_indices_VBO_id = 0;
 | 
			
		||||
    }
 | 
			
		||||
    if (this->quad_indices_VBO_id) {
 | 
			
		||||
        glDeleteBuffers(1, &this->quad_indices_VBO_id);
 | 
			
		||||
        glsafe(glDeleteBuffers(1, &this->quad_indices_VBO_id));
 | 
			
		||||
        this->quad_indices_VBO_id = 0;
 | 
			
		||||
    }
 | 
			
		||||
    this->clear();
 | 
			
		||||
| 
						 | 
				
			
			@ -125,42 +146,42 @@ void GLIndexedVertexArray::release_geometry()
 | 
			
		|||
void GLIndexedVertexArray::render() const
 | 
			
		||||
{
 | 
			
		||||
    if (this->vertices_and_normals_interleaved_VBO_id) {
 | 
			
		||||
        glBindBuffer(GL_ARRAY_BUFFER, this->vertices_and_normals_interleaved_VBO_id);
 | 
			
		||||
        glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), (const void*)(3 * sizeof(float)));
 | 
			
		||||
        glNormalPointer(GL_FLOAT, 6 * sizeof(float), nullptr);
 | 
			
		||||
        glsafe(glBindBuffer(GL_ARRAY_BUFFER, this->vertices_and_normals_interleaved_VBO_id));
 | 
			
		||||
        glsafe(glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), (const void*)(3 * sizeof(float))));
 | 
			
		||||
        glsafe(glNormalPointer(GL_FLOAT, 6 * sizeof(float), nullptr));
 | 
			
		||||
    } else {
 | 
			
		||||
        glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), this->vertices_and_normals_interleaved.data() + 3);
 | 
			
		||||
        glNormalPointer(GL_FLOAT, 6 * sizeof(float), this->vertices_and_normals_interleaved.data());
 | 
			
		||||
        glsafe(glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), this->vertices_and_normals_interleaved.data() + 3));
 | 
			
		||||
        glsafe(glNormalPointer(GL_FLOAT, 6 * sizeof(float), this->vertices_and_normals_interleaved.data()));
 | 
			
		||||
    }
 | 
			
		||||
    glEnableClientState(GL_VERTEX_ARRAY);
 | 
			
		||||
    glEnableClientState(GL_NORMAL_ARRAY);
 | 
			
		||||
    glsafe(glEnableClientState(GL_VERTEX_ARRAY));
 | 
			
		||||
    glsafe(glEnableClientState(GL_NORMAL_ARRAY));
 | 
			
		||||
 | 
			
		||||
    if (this->indexed()) {
 | 
			
		||||
        if (this->vertices_and_normals_interleaved_VBO_id) {
 | 
			
		||||
            // Render using the Vertex Buffer Objects.
 | 
			
		||||
            if (this->triangle_indices_size > 0) {
 | 
			
		||||
                glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->triangle_indices_VBO_id);
 | 
			
		||||
                glDrawElements(GL_TRIANGLES, GLsizei(this->triangle_indices_size), GL_UNSIGNED_INT, nullptr);
 | 
			
		||||
                glsafe(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->triangle_indices_VBO_id));
 | 
			
		||||
                glsafe(glDrawElements(GL_TRIANGLES, GLsizei(this->triangle_indices_size), GL_UNSIGNED_INT, nullptr));
 | 
			
		||||
            }
 | 
			
		||||
            if (this->quad_indices_size > 0) {
 | 
			
		||||
                glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->quad_indices_VBO_id);
 | 
			
		||||
                glDrawElements(GL_QUADS, GLsizei(this->quad_indices_size), GL_UNSIGNED_INT, nullptr);
 | 
			
		||||
                glsafe(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->quad_indices_VBO_id));
 | 
			
		||||
                glsafe(glDrawElements(GL_QUADS, GLsizei(this->quad_indices_size), GL_UNSIGNED_INT, nullptr));
 | 
			
		||||
            }
 | 
			
		||||
            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
 | 
			
		||||
            glsafe(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
 | 
			
		||||
        } else {
 | 
			
		||||
            // Render in an immediate mode.
 | 
			
		||||
            if (! this->triangle_indices.empty())
 | 
			
		||||
                glDrawElements(GL_TRIANGLES, GLsizei(this->triangle_indices_size), GL_UNSIGNED_INT, this->triangle_indices.data());
 | 
			
		||||
                glsafe(glDrawElements(GL_TRIANGLES, GLsizei(this->triangle_indices_size), GL_UNSIGNED_INT, this->triangle_indices.data()));
 | 
			
		||||
            if (! this->quad_indices.empty())
 | 
			
		||||
                glDrawElements(GL_QUADS, GLsizei(this->quad_indices_size), GL_UNSIGNED_INT, this->quad_indices.data());
 | 
			
		||||
                glsafe(glDrawElements(GL_QUADS, GLsizei(this->quad_indices_size), GL_UNSIGNED_INT, this->quad_indices.data()));
 | 
			
		||||
        }
 | 
			
		||||
    } else
 | 
			
		||||
        glDrawArrays(GL_TRIANGLES, 0, GLsizei(this->vertices_and_normals_interleaved_size / 6));
 | 
			
		||||
        glsafe(glDrawArrays(GL_TRIANGLES, 0, GLsizei(this->vertices_and_normals_interleaved_size / 6)));
 | 
			
		||||
 | 
			
		||||
    if (this->vertices_and_normals_interleaved_VBO_id)
 | 
			
		||||
        glBindBuffer(GL_ARRAY_BUFFER, 0);
 | 
			
		||||
    glDisableClientState(GL_VERTEX_ARRAY);
 | 
			
		||||
    glDisableClientState(GL_NORMAL_ARRAY);
 | 
			
		||||
        glsafe(glBindBuffer(GL_ARRAY_BUFFER, 0));
 | 
			
		||||
    glsafe(glDisableClientState(GL_VERTEX_ARRAY));
 | 
			
		||||
    glsafe(glDisableClientState(GL_NORMAL_ARRAY));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GLIndexedVertexArray::render(
 | 
			
		||||
| 
						 | 
				
			
			@ -173,35 +194,35 @@ void GLIndexedVertexArray::render(
 | 
			
		|||
 | 
			
		||||
    if (this->vertices_and_normals_interleaved_VBO_id) {
 | 
			
		||||
        // Render using the Vertex Buffer Objects.
 | 
			
		||||
        glBindBuffer(GL_ARRAY_BUFFER, this->vertices_and_normals_interleaved_VBO_id);
 | 
			
		||||
        glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), (const void*)(3 * sizeof(float)));
 | 
			
		||||
        glNormalPointer(GL_FLOAT, 6 * sizeof(float), nullptr);
 | 
			
		||||
        glEnableClientState(GL_VERTEX_ARRAY);
 | 
			
		||||
        glEnableClientState(GL_NORMAL_ARRAY);
 | 
			
		||||
        glsafe(glBindBuffer(GL_ARRAY_BUFFER, this->vertices_and_normals_interleaved_VBO_id));
 | 
			
		||||
        glsafe(glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), (const void*)(3 * sizeof(float))));
 | 
			
		||||
        glsafe(glNormalPointer(GL_FLOAT, 6 * sizeof(float), nullptr));
 | 
			
		||||
        glsafe(glEnableClientState(GL_VERTEX_ARRAY));
 | 
			
		||||
        glsafe(glEnableClientState(GL_NORMAL_ARRAY));
 | 
			
		||||
        if (this->triangle_indices_size > 0) {
 | 
			
		||||
            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->triangle_indices_VBO_id);
 | 
			
		||||
            glDrawElements(GL_TRIANGLES, GLsizei(std::min(this->triangle_indices_size, tverts_range.second - tverts_range.first)), GL_UNSIGNED_INT, (const void*)(tverts_range.first * 4));
 | 
			
		||||
            glsafe(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->triangle_indices_VBO_id));
 | 
			
		||||
            glsafe(glDrawElements(GL_TRIANGLES, GLsizei(std::min(this->triangle_indices_size, tverts_range.second - tverts_range.first)), GL_UNSIGNED_INT, (const void*)(tverts_range.first * 4)));
 | 
			
		||||
        }
 | 
			
		||||
        if (this->quad_indices_size > 0) {
 | 
			
		||||
            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->quad_indices_VBO_id);
 | 
			
		||||
            glDrawElements(GL_QUADS, GLsizei(std::min(this->quad_indices_size, qverts_range.second - qverts_range.first)), GL_UNSIGNED_INT, (const void*)(qverts_range.first * 4));
 | 
			
		||||
            glsafe(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->quad_indices_VBO_id));
 | 
			
		||||
            glsafe(glDrawElements(GL_QUADS, GLsizei(std::min(this->quad_indices_size, qverts_range.second - qverts_range.first)), GL_UNSIGNED_INT, (const void*)(qverts_range.first * 4)));
 | 
			
		||||
        }
 | 
			
		||||
        glBindBuffer(GL_ARRAY_BUFFER, 0);
 | 
			
		||||
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
 | 
			
		||||
        glsafe(glBindBuffer(GL_ARRAY_BUFFER, 0));
 | 
			
		||||
        glsafe(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
 | 
			
		||||
    } else {
 | 
			
		||||
        // Render in an immediate mode.
 | 
			
		||||
        glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), this->vertices_and_normals_interleaved.data() + 3);
 | 
			
		||||
        glNormalPointer(GL_FLOAT, 6 * sizeof(float), this->vertices_and_normals_interleaved.data());
 | 
			
		||||
        glEnableClientState(GL_VERTEX_ARRAY);
 | 
			
		||||
        glEnableClientState(GL_NORMAL_ARRAY);
 | 
			
		||||
        glsafe(glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), this->vertices_and_normals_interleaved.data() + 3));
 | 
			
		||||
        glsafe(glNormalPointer(GL_FLOAT, 6 * sizeof(float), this->vertices_and_normals_interleaved.data()));
 | 
			
		||||
        glsafe(glEnableClientState(GL_VERTEX_ARRAY));
 | 
			
		||||
        glsafe(glEnableClientState(GL_NORMAL_ARRAY));
 | 
			
		||||
        if (! this->triangle_indices.empty())
 | 
			
		||||
            glDrawElements(GL_TRIANGLES, GLsizei(std::min(this->triangle_indices_size, tverts_range.second - tverts_range.first)), GL_UNSIGNED_INT, (const void*)(this->triangle_indices.data() + tverts_range.first));
 | 
			
		||||
            glsafe(glDrawElements(GL_TRIANGLES, GLsizei(std::min(this->triangle_indices_size, tverts_range.second - tverts_range.first)), GL_UNSIGNED_INT, (const void*)(this->triangle_indices.data() + tverts_range.first)));
 | 
			
		||||
        if (! this->quad_indices.empty())
 | 
			
		||||
            glDrawElements(GL_QUADS, GLsizei(std::min(this->quad_indices_size, qverts_range.second - qverts_range.first)), GL_UNSIGNED_INT, (const void*)(this->quad_indices.data() + qverts_range.first));
 | 
			
		||||
            glsafe(glDrawElements(GL_QUADS, GLsizei(std::min(this->quad_indices_size, qverts_range.second - qverts_range.first)), GL_UNSIGNED_INT, (const void*)(this->quad_indices.data() + qverts_range.first)));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    glDisableClientState(GL_VERTEX_ARRAY);
 | 
			
		||||
    glDisableClientState(GL_NORMAL_ARRAY);
 | 
			
		||||
    glsafe(glDisableClientState(GL_VERTEX_ARRAY));
 | 
			
		||||
    glsafe(glDisableClientState(GL_NORMAL_ARRAY));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const float GLVolume::SELECTED_COLOR[4] = { 0.0f, 1.0f, 0.0f, 1.0f };
 | 
			
		||||
| 
						 | 
				
			
			@ -375,15 +396,15 @@ void GLVolume::render() const
 | 
			
		|||
    if (!is_active)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    ::glCullFace(GL_BACK);
 | 
			
		||||
    ::glPushMatrix();
 | 
			
		||||
    glsafe(::glCullFace(GL_BACK));
 | 
			
		||||
    glsafe(::glPushMatrix());
 | 
			
		||||
 | 
			
		||||
    ::glMultMatrixd(world_matrix().data());
 | 
			
		||||
    glsafe(::glMultMatrixd(world_matrix().data()));
 | 
			
		||||
    if (this->indexed_vertex_array.indexed())
 | 
			
		||||
        this->indexed_vertex_array.render(this->tverts_range, this->qverts_range);
 | 
			
		||||
    else
 | 
			
		||||
        this->indexed_vertex_array.render();
 | 
			
		||||
    ::glPopMatrix();
 | 
			
		||||
    glsafe(::glPopMatrix());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GLVolume::render_VBOs(int color_id, int detection_id, int worldmatrix_id) const
 | 
			
		||||
| 
						 | 
				
			
			@ -398,63 +419,63 @@ void GLVolume::render_VBOs(int color_id, int detection_id, int worldmatrix_id) c
 | 
			
		|||
    GLsizei n_quads = GLsizei(std::min(indexed_vertex_array.quad_indices_size, qverts_range.second - qverts_range.first));
 | 
			
		||||
    if (n_triangles + n_quads == 0)
 | 
			
		||||
    {
 | 
			
		||||
        ::glDisableClientState(GL_VERTEX_ARRAY);
 | 
			
		||||
        ::glDisableClientState(GL_NORMAL_ARRAY);
 | 
			
		||||
        glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
 | 
			
		||||
        glsafe(::glDisableClientState(GL_NORMAL_ARRAY));
 | 
			
		||||
 | 
			
		||||
        if (color_id >= 0)
 | 
			
		||||
        {
 | 
			
		||||
            float color[4];
 | 
			
		||||
            ::memcpy((void*)color, (const void*)render_color, 4 * sizeof(float));
 | 
			
		||||
            ::glUniform4fv(color_id, 1, (const GLfloat*)color);
 | 
			
		||||
            glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)color));
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
            ::glColor4fv(render_color);
 | 
			
		||||
            glsafe(::glColor4fv(render_color));
 | 
			
		||||
 | 
			
		||||
        if (detection_id != -1)
 | 
			
		||||
            ::glUniform1i(detection_id, shader_outside_printer_detection_enabled ? 1 : 0);
 | 
			
		||||
            glsafe(::glUniform1i(detection_id, shader_outside_printer_detection_enabled ? 1 : 0));
 | 
			
		||||
 | 
			
		||||
        if (worldmatrix_id != -1)
 | 
			
		||||
            ::glUniformMatrix4fv(worldmatrix_id, 1, GL_FALSE, (const GLfloat*)world_matrix().cast<float>().data());
 | 
			
		||||
            glsafe(::glUniformMatrix4fv(worldmatrix_id, 1, GL_FALSE, (const GLfloat*)world_matrix().cast<float>().data()));
 | 
			
		||||
 | 
			
		||||
        render();
 | 
			
		||||
 | 
			
		||||
        ::glEnableClientState(GL_VERTEX_ARRAY);
 | 
			
		||||
        ::glEnableClientState(GL_NORMAL_ARRAY);
 | 
			
		||||
        glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
 | 
			
		||||
        glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
 | 
			
		||||
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (color_id >= 0)
 | 
			
		||||
        ::glUniform4fv(color_id, 1, (const GLfloat*)render_color);
 | 
			
		||||
        glsafe(::glUniform4fv(color_id, 1, (const GLfloat*)render_color));
 | 
			
		||||
    else
 | 
			
		||||
        ::glColor4fv(render_color);
 | 
			
		||||
        glsafe(::glColor4fv(render_color));
 | 
			
		||||
 | 
			
		||||
    if (detection_id != -1)
 | 
			
		||||
        ::glUniform1i(detection_id, shader_outside_printer_detection_enabled ? 1 : 0);
 | 
			
		||||
        glsafe(::glUniform1i(detection_id, shader_outside_printer_detection_enabled ? 1 : 0));
 | 
			
		||||
 | 
			
		||||
    if (worldmatrix_id != -1)
 | 
			
		||||
        ::glUniformMatrix4fv(worldmatrix_id, 1, GL_FALSE, (const GLfloat*)world_matrix().cast<float>().data());
 | 
			
		||||
        glsafe(::glUniformMatrix4fv(worldmatrix_id, 1, GL_FALSE, (const GLfloat*)world_matrix().cast<float>().data()));
 | 
			
		||||
 | 
			
		||||
    ::glBindBuffer(GL_ARRAY_BUFFER, indexed_vertex_array.vertices_and_normals_interleaved_VBO_id);
 | 
			
		||||
    ::glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), (const void*)(3 * sizeof(float)));
 | 
			
		||||
    ::glNormalPointer(GL_FLOAT, 6 * sizeof(float), nullptr);
 | 
			
		||||
    glsafe(::glBindBuffer(GL_ARRAY_BUFFER, indexed_vertex_array.vertices_and_normals_interleaved_VBO_id));
 | 
			
		||||
    glsafe(::glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), (const void*)(3 * sizeof(float))));
 | 
			
		||||
    glsafe(::glNormalPointer(GL_FLOAT, 6 * sizeof(float), nullptr));
 | 
			
		||||
 | 
			
		||||
    ::glPushMatrix();
 | 
			
		||||
    glsafe(::glPushMatrix());
 | 
			
		||||
 | 
			
		||||
    ::glMultMatrixd(world_matrix().data());
 | 
			
		||||
    glsafe(::glMultMatrixd(world_matrix().data()));
 | 
			
		||||
 | 
			
		||||
    if (n_triangles > 0)
 | 
			
		||||
    {
 | 
			
		||||
        ::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexed_vertex_array.triangle_indices_VBO_id);
 | 
			
		||||
        ::glDrawElements(GL_TRIANGLES, n_triangles, GL_UNSIGNED_INT, (const void*)(tverts_range.first * 4));
 | 
			
		||||
        glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexed_vertex_array.triangle_indices_VBO_id));
 | 
			
		||||
        glsafe(::glDrawElements(GL_TRIANGLES, n_triangles, GL_UNSIGNED_INT, (const void*)(tverts_range.first * 4)));
 | 
			
		||||
    }
 | 
			
		||||
    if (n_quads > 0)
 | 
			
		||||
    {
 | 
			
		||||
        ::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexed_vertex_array.quad_indices_VBO_id);
 | 
			
		||||
        ::glDrawElements(GL_QUADS, n_quads, GL_UNSIGNED_INT, (const void*)(qverts_range.first * 4));
 | 
			
		||||
        glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexed_vertex_array.quad_indices_VBO_id));
 | 
			
		||||
        glsafe(::glDrawElements(GL_QUADS, n_quads, GL_UNSIGNED_INT, (const void*)(qverts_range.first * 4)));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ::glPopMatrix();
 | 
			
		||||
    glsafe(::glPopMatrix());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GLVolume::render_legacy() const
 | 
			
		||||
| 
						 | 
				
			
			@ -467,33 +488,33 @@ void GLVolume::render_legacy() const
 | 
			
		|||
    GLsizei n_quads = GLsizei(std::min(indexed_vertex_array.quad_indices_size, qverts_range.second - qverts_range.first));
 | 
			
		||||
    if (n_triangles + n_quads == 0)
 | 
			
		||||
    {
 | 
			
		||||
        ::glDisableClientState(GL_VERTEX_ARRAY);
 | 
			
		||||
        ::glDisableClientState(GL_NORMAL_ARRAY);
 | 
			
		||||
        glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
 | 
			
		||||
        glsafe(::glDisableClientState(GL_NORMAL_ARRAY));
 | 
			
		||||
 | 
			
		||||
        ::glColor4fv(render_color);
 | 
			
		||||
        glsafe(::glColor4fv(render_color));
 | 
			
		||||
        render();
 | 
			
		||||
 | 
			
		||||
        ::glEnableClientState(GL_VERTEX_ARRAY);
 | 
			
		||||
        ::glEnableClientState(GL_NORMAL_ARRAY);
 | 
			
		||||
        glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
 | 
			
		||||
        glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
 | 
			
		||||
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ::glColor4fv(render_color);
 | 
			
		||||
    ::glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), indexed_vertex_array.vertices_and_normals_interleaved.data() + 3);
 | 
			
		||||
    ::glNormalPointer(GL_FLOAT, 6 * sizeof(float), indexed_vertex_array.vertices_and_normals_interleaved.data());
 | 
			
		||||
    glsafe(::glColor4fv(render_color));
 | 
			
		||||
    glsafe(::glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), indexed_vertex_array.vertices_and_normals_interleaved.data() + 3));
 | 
			
		||||
    glsafe(::glNormalPointer(GL_FLOAT, 6 * sizeof(float), indexed_vertex_array.vertices_and_normals_interleaved.data()));
 | 
			
		||||
 | 
			
		||||
    ::glPushMatrix();
 | 
			
		||||
    glsafe(::glPushMatrix());
 | 
			
		||||
 | 
			
		||||
    ::glMultMatrixd(world_matrix().data());
 | 
			
		||||
    glsafe(::glMultMatrixd(world_matrix().data()));
 | 
			
		||||
 | 
			
		||||
    if (n_triangles > 0)
 | 
			
		||||
        ::glDrawElements(GL_TRIANGLES, n_triangles, GL_UNSIGNED_INT, indexed_vertex_array.triangle_indices.data() + tverts_range.first);
 | 
			
		||||
        glsafe(::glDrawElements(GL_TRIANGLES, n_triangles, GL_UNSIGNED_INT, indexed_vertex_array.triangle_indices.data() + tverts_range.first));
 | 
			
		||||
 | 
			
		||||
    if (n_quads > 0)
 | 
			
		||||
        ::glDrawElements(GL_QUADS, n_quads, GL_UNSIGNED_INT, indexed_vertex_array.quad_indices.data() + qverts_range.first);
 | 
			
		||||
        glsafe(::glDrawElements(GL_QUADS, n_quads, GL_UNSIGNED_INT, indexed_vertex_array.quad_indices.data() + qverts_range.first));
 | 
			
		||||
 | 
			
		||||
    ::glPopMatrix();
 | 
			
		||||
    glsafe(::glPopMatrix());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::vector<int> GLVolumeCollection::load_object(
 | 
			
		||||
| 
						 | 
				
			
			@ -705,7 +726,7 @@ static GLVolumesWithZList volumes_to_render(const GLVolumePtrs& volumes, GLVolum
 | 
			
		|||
    if ((type == GLVolumeCollection::Transparent) && (list.size() > 1))
 | 
			
		||||
    {
 | 
			
		||||
        Transform3d modelview_matrix;
 | 
			
		||||
        ::glGetDoublev(GL_MODELVIEW_MATRIX, modelview_matrix.data());
 | 
			
		||||
        glsafe(::glGetDoublev(GL_MODELVIEW_MATRIX, modelview_matrix.data()));
 | 
			
		||||
 | 
			
		||||
        for (GLVolumeWithZ& volume : list)
 | 
			
		||||
        {
 | 
			
		||||
| 
						 | 
				
			
			@ -722,18 +743,18 @@ static GLVolumesWithZList volumes_to_render(const GLVolumePtrs& volumes, GLVolum
 | 
			
		|||
 | 
			
		||||
void GLVolumeCollection::render_VBOs(GLVolumeCollection::ERenderType type, bool disable_cullface, std::function<bool(const GLVolume&)> filter_func) const
 | 
			
		||||
{
 | 
			
		||||
    ::glEnable(GL_BLEND);
 | 
			
		||||
    ::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 | 
			
		||||
    glsafe(::glEnable(GL_BLEND));
 | 
			
		||||
    glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
 | 
			
		||||
 | 
			
		||||
    ::glCullFace(GL_BACK);
 | 
			
		||||
    glsafe(::glCullFace(GL_BACK));
 | 
			
		||||
    if (disable_cullface)
 | 
			
		||||
        ::glDisable(GL_CULL_FACE);
 | 
			
		||||
        glsafe(::glDisable(GL_CULL_FACE));
 | 
			
		||||
 | 
			
		||||
    ::glEnableClientState(GL_VERTEX_ARRAY);
 | 
			
		||||
    ::glEnableClientState(GL_NORMAL_ARRAY);
 | 
			
		||||
    glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
 | 
			
		||||
    glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
 | 
			
		||||
 
 | 
			
		||||
    GLint current_program_id;
 | 
			
		||||
    ::glGetIntegerv(GL_CURRENT_PROGRAM, ¤t_program_id);
 | 
			
		||||
    glsafe(::glGetIntegerv(GL_CURRENT_PROGRAM, ¤t_program_id));
 | 
			
		||||
    GLint color_id = (current_program_id > 0) ? glGetUniformLocation(current_program_id, "uniform_color") : -1;
 | 
			
		||||
    GLint z_range_id = (current_program_id > 0) ? glGetUniformLocation(current_program_id, "z_range") : -1;
 | 
			
		||||
    GLint print_box_min_id = (current_program_id > 0) ? glGetUniformLocation(current_program_id, "print_box.min") : -1;
 | 
			
		||||
| 
						 | 
				
			
			@ -742,13 +763,13 @@ void GLVolumeCollection::render_VBOs(GLVolumeCollection::ERenderType type, bool
 | 
			
		|||
    GLint print_box_worldmatrix_id = (current_program_id > 0) ? glGetUniformLocation(current_program_id, "print_box.volume_world_matrix") : -1;
 | 
			
		||||
 | 
			
		||||
    if (print_box_min_id != -1)
 | 
			
		||||
        ::glUniform3fv(print_box_min_id, 1, (const GLfloat*)print_box_min);
 | 
			
		||||
        glsafe(::glUniform3fv(print_box_min_id, 1, (const GLfloat*)print_box_min));
 | 
			
		||||
 | 
			
		||||
    if (print_box_max_id != -1)
 | 
			
		||||
        ::glUniform3fv(print_box_max_id, 1, (const GLfloat*)print_box_max);
 | 
			
		||||
        glsafe(::glUniform3fv(print_box_max_id, 1, (const GLfloat*)print_box_max));
 | 
			
		||||
 | 
			
		||||
    if (z_range_id != -1)
 | 
			
		||||
        ::glUniform2fv(z_range_id, 1, (const GLfloat*)z_range);
 | 
			
		||||
        glsafe(::glUniform2fv(z_range_id, 1, (const GLfloat*)z_range));
 | 
			
		||||
 | 
			
		||||
    GLVolumesWithZList to_render = volumes_to_render(this->volumes, type, filter_func);
 | 
			
		||||
    for (GLVolumeWithZ& volume : to_render) {
 | 
			
		||||
| 
						 | 
				
			
			@ -756,29 +777,29 @@ void GLVolumeCollection::render_VBOs(GLVolumeCollection::ERenderType type, bool
 | 
			
		|||
        volume.first->render_VBOs(color_id, print_box_detection_id, print_box_worldmatrix_id);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ::glBindBuffer(GL_ARRAY_BUFFER, 0);
 | 
			
		||||
    ::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
 | 
			
		||||
    glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
 | 
			
		||||
    glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
 | 
			
		||||
 | 
			
		||||
    ::glDisableClientState(GL_VERTEX_ARRAY);
 | 
			
		||||
    ::glDisableClientState(GL_NORMAL_ARRAY);
 | 
			
		||||
    glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
 | 
			
		||||
    glsafe(::glDisableClientState(GL_NORMAL_ARRAY));
 | 
			
		||||
 | 
			
		||||
    if (disable_cullface)
 | 
			
		||||
        ::glEnable(GL_CULL_FACE);
 | 
			
		||||
        glsafe(::glEnable(GL_CULL_FACE));
 | 
			
		||||
 | 
			
		||||
    ::glDisable(GL_BLEND);
 | 
			
		||||
    glsafe(::glDisable(GL_BLEND));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GLVolumeCollection::render_legacy(ERenderType type, bool disable_cullface) const
 | 
			
		||||
{
 | 
			
		||||
    glEnable(GL_BLEND);
 | 
			
		||||
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 | 
			
		||||
    glsafe(glEnable(GL_BLEND));
 | 
			
		||||
    glsafe(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
 | 
			
		||||
 | 
			
		||||
    glCullFace(GL_BACK);
 | 
			
		||||
    glsafe(glCullFace(GL_BACK));
 | 
			
		||||
    if (disable_cullface)
 | 
			
		||||
        ::glDisable(GL_CULL_FACE);
 | 
			
		||||
        glsafe(::glDisable(GL_CULL_FACE));
 | 
			
		||||
 | 
			
		||||
    glEnableClientState(GL_VERTEX_ARRAY);
 | 
			
		||||
    glEnableClientState(GL_NORMAL_ARRAY);
 | 
			
		||||
    glsafe(glEnableClientState(GL_VERTEX_ARRAY));
 | 
			
		||||
    glsafe(glEnableClientState(GL_NORMAL_ARRAY));
 | 
			
		||||
 
 | 
			
		||||
	GLVolumesWithZList to_render = volumes_to_render(this->volumes, type, std::function<bool(const GLVolume&)>());
 | 
			
		||||
    for (GLVolumeWithZ& volume : to_render)
 | 
			
		||||
| 
						 | 
				
			
			@ -787,13 +808,13 @@ void GLVolumeCollection::render_legacy(ERenderType type, bool disable_cullface)
 | 
			
		|||
        volume.first->render_legacy();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    glDisableClientState(GL_VERTEX_ARRAY);
 | 
			
		||||
    glDisableClientState(GL_NORMAL_ARRAY);
 | 
			
		||||
    glsafe(glDisableClientState(GL_VERTEX_ARRAY));
 | 
			
		||||
    glsafe(glDisableClientState(GL_NORMAL_ARRAY));
 | 
			
		||||
 | 
			
		||||
    if (disable_cullface)
 | 
			
		||||
        ::glEnable(GL_CULL_FACE);
 | 
			
		||||
        glsafe(::glEnable(GL_CULL_FACE));
 | 
			
		||||
 | 
			
		||||
    glDisable(GL_BLEND);
 | 
			
		||||
    glsafe(glDisable(GL_BLEND));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool GLVolumeCollection::check_outside_state(const DynamicPrintConfig* config, ModelInstance::EPrintVolumeState* out_state)
 | 
			
		||||
| 
						 | 
				
			
			@ -1718,44 +1739,44 @@ void GLModel::render() const
 | 
			
		|||
 | 
			
		||||
void GLModel::render_VBOs() const
 | 
			
		||||
{
 | 
			
		||||
    ::glEnable(GL_BLEND);
 | 
			
		||||
    ::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 | 
			
		||||
    glsafe(::glEnable(GL_BLEND));
 | 
			
		||||
    glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
 | 
			
		||||
 | 
			
		||||
    ::glCullFace(GL_BACK);
 | 
			
		||||
    ::glEnableClientState(GL_VERTEX_ARRAY);
 | 
			
		||||
    ::glEnableClientState(GL_NORMAL_ARRAY);
 | 
			
		||||
    glsafe(::glCullFace(GL_BACK));
 | 
			
		||||
    glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
 | 
			
		||||
    glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
 | 
			
		||||
 | 
			
		||||
    GLint current_program_id;
 | 
			
		||||
    ::glGetIntegerv(GL_CURRENT_PROGRAM, ¤t_program_id);
 | 
			
		||||
    glsafe(::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);
 | 
			
		||||
    glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
 | 
			
		||||
    glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
 | 
			
		||||
 | 
			
		||||
    ::glDisableClientState(GL_VERTEX_ARRAY);
 | 
			
		||||
    ::glDisableClientState(GL_NORMAL_ARRAY);
 | 
			
		||||
    glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
 | 
			
		||||
    glsafe(::glDisableClientState(GL_NORMAL_ARRAY));
 | 
			
		||||
 | 
			
		||||
    ::glDisable(GL_BLEND);
 | 
			
		||||
    glsafe(::glDisable(GL_BLEND));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GLModel::render_legacy() const
 | 
			
		||||
{
 | 
			
		||||
    ::glEnable(GL_LIGHTING);
 | 
			
		||||
    ::glEnable(GL_BLEND);
 | 
			
		||||
    ::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 | 
			
		||||
    glsafe(::glEnable(GL_LIGHTING));
 | 
			
		||||
    glsafe(::glEnable(GL_BLEND));
 | 
			
		||||
    glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
 | 
			
		||||
 | 
			
		||||
    ::glCullFace(GL_BACK);
 | 
			
		||||
    ::glEnableClientState(GL_VERTEX_ARRAY);
 | 
			
		||||
    ::glEnableClientState(GL_NORMAL_ARRAY);
 | 
			
		||||
    glsafe(::glCullFace(GL_BACK));
 | 
			
		||||
    glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
 | 
			
		||||
    glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
 | 
			
		||||
 | 
			
		||||
    m_volume.render_legacy();
 | 
			
		||||
 | 
			
		||||
    ::glDisableClientState(GL_VERTEX_ARRAY);
 | 
			
		||||
    ::glDisableClientState(GL_NORMAL_ARRAY);
 | 
			
		||||
    glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
 | 
			
		||||
    glsafe(::glDisableClientState(GL_NORMAL_ARRAY));
 | 
			
		||||
 | 
			
		||||
    ::glDisable(GL_BLEND);
 | 
			
		||||
    ::glDisable(GL_LIGHTING);
 | 
			
		||||
    glsafe(::glDisable(GL_BLEND));
 | 
			
		||||
    glsafe(::glDisable(GL_LIGHTING));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool GLArrow::on_init(bool useVBOs)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,6 +11,19 @@
 | 
			
		|||
 | 
			
		||||
#include <functional>
 | 
			
		||||
 | 
			
		||||
#ifndef NDEBUG
 | 
			
		||||
#define HAS_GLSAFE
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef HAS_GLSAFE
 | 
			
		||||
extern void glAssertRecentCallImpl();
 | 
			
		||||
inline void glAssertRecentCall() { glAssertRecentCallImpl(); }
 | 
			
		||||
#define glsafe(cmd) do { cmd; glAssertRecentCallImpl(); } while (false)
 | 
			
		||||
#else
 | 
			
		||||
inline void glAssertRecentCall() { }
 | 
			
		||||
#define glsafe(cmd) cmd
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace Slic3r {
 | 
			
		||||
 | 
			
		||||
class Print;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4174,6 +4174,8 @@ unsigned int GLCanvas3D::get_volumes_count() const
 | 
			
		|||
 | 
			
		||||
void GLCanvas3D::reset_volumes()
 | 
			
		||||
{
 | 
			
		||||
    _set_current();
 | 
			
		||||
 | 
			
		||||
    if (!m_volumes.empty())
 | 
			
		||||
    {
 | 
			
		||||
        m_selection.clear();
 | 
			
		||||
| 
						 | 
				
			
			@ -4413,6 +4415,16 @@ void GLCanvas3D::update_volumes_colors_by_extruder()
 | 
			
		|||
        m_volumes.update_colors_by_extruder(m_config);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS
 | 
			
		||||
void GLCanvas3D::update_toolbar_items_visibility()
 | 
			
		||||
{
 | 
			
		||||
    ConfigOptionMode mode = wxGetApp().get_mode();
 | 
			
		||||
    m_toolbar.set_item_visible("more", mode != comSimple);
 | 
			
		||||
    m_toolbar.set_item_visible("fewer", mode != comSimple);
 | 
			
		||||
    m_dirty = true;
 | 
			
		||||
}
 | 
			
		||||
#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS
 | 
			
		||||
 | 
			
		||||
// Returns a Rect object denoting size and position of the Reset button used by a gizmo.
 | 
			
		||||
// Returns in either screen or viewport coords.
 | 
			
		||||
#if !ENABLE_IMGUI
 | 
			
		||||
| 
						 | 
				
			
			@ -4628,6 +4640,8 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
 | 
			
		|||
    if ((m_canvas == nullptr) || (m_config == nullptr) || (m_model == nullptr))
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    _set_current();
 | 
			
		||||
 | 
			
		||||
    struct ModelVolumeState {
 | 
			
		||||
        ModelVolumeState(const GLVolume *volume) : 
 | 
			
		||||
			model_volume(nullptr), geometry_id(volume->geometry_id), volume_idx(-1) {}
 | 
			
		||||
| 
						 | 
				
			
			@ -4934,6 +4948,8 @@ void GLCanvas3D::load_gcode_preview(const GCodePreviewData& preview_data, const
 | 
			
		|||
    const Print *print = this->fff_print();
 | 
			
		||||
    if ((m_canvas != nullptr) && (print != nullptr))
 | 
			
		||||
    {
 | 
			
		||||
        _set_current();
 | 
			
		||||
 | 
			
		||||
        std::vector<float> tool_colors = _parse_colors(str_tool_colors);
 | 
			
		||||
 | 
			
		||||
        if (m_volumes.empty())
 | 
			
		||||
| 
						 | 
				
			
			@ -4971,6 +4987,7 @@ void GLCanvas3D::load_sla_preview()
 | 
			
		|||
    const SLAPrint* print = this->sla_print();
 | 
			
		||||
    if ((m_canvas != nullptr) && (print != nullptr))
 | 
			
		||||
    {
 | 
			
		||||
        _set_current();
 | 
			
		||||
        _load_shells_sla();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -4981,6 +4998,8 @@ void GLCanvas3D::load_preview(const std::vector<std::string>& str_tool_colors, c
 | 
			
		|||
    if (print == nullptr)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    _set_current();
 | 
			
		||||
 | 
			
		||||
    _load_print_toolpaths();
 | 
			
		||||
    _load_wipe_tower_toolpaths(str_tool_colors);
 | 
			
		||||
    for (const PrintObject* object : print->objects())
 | 
			
		||||
| 
						 | 
				
			
			@ -5198,6 +5217,9 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
 | 
			
		|||
 | 
			
		||||
    Point pos(evt.GetX(), evt.GetY());
 | 
			
		||||
 | 
			
		||||
    if (m_picking_enabled)
 | 
			
		||||
        _set_current();
 | 
			
		||||
 | 
			
		||||
    int selected_object_idx = m_selection.get_object_idx();
 | 
			
		||||
    int layer_editing_object_idx = is_layers_editing_enabled() ? selected_object_idx : -1;
 | 
			
		||||
    m_layers_editing.select_object(*m_model, layer_editing_object_idx);
 | 
			
		||||
| 
						 | 
				
			
			@ -5642,7 +5664,11 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
 | 
			
		|||
 | 
			
		||||
void GLCanvas3D::on_paint(wxPaintEvent& evt)
 | 
			
		||||
{
 | 
			
		||||
    render();
 | 
			
		||||
    if (m_initialized)
 | 
			
		||||
        m_dirty = true;
 | 
			
		||||
    else
 | 
			
		||||
        // Call render directly, so it gets initialized immediately, not from On Idle handler.
 | 
			
		||||
        this->render();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GLCanvas3D::on_key_down(wxKeyEvent& evt)
 | 
			
		||||
| 
						 | 
				
			
			@ -5693,6 +5719,7 @@ Point GLCanvas3D::get_local_mouse_position() const
 | 
			
		|||
 | 
			
		||||
void GLCanvas3D::reset_legend_texture()
 | 
			
		||||
{
 | 
			
		||||
    _set_current();
 | 
			
		||||
    m_legend_texture.reset();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -6121,6 +6148,10 @@ bool GLCanvas3D::_init_toolbar()
 | 
			
		|||
 | 
			
		||||
    enable_toolbar_item("add", true);
 | 
			
		||||
 | 
			
		||||
#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS
 | 
			
		||||
    update_toolbar_items_visibility();
 | 
			
		||||
#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS
 | 
			
		||||
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -8292,6 +8323,8 @@ void GLCanvas3D::_update_toolpath_volumes_outside_state()
 | 
			
		|||
 | 
			
		||||
void GLCanvas3D::_show_warning_texture_if_needed()
 | 
			
		||||
{
 | 
			
		||||
    _set_current();
 | 
			
		||||
 | 
			
		||||
    if (_is_any_volume_outside())
 | 
			
		||||
    {
 | 
			
		||||
        enable_warning_texture(true);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1002,6 +1002,10 @@ public:
 | 
			
		|||
 | 
			
		||||
    void update_volumes_colors_by_extruder();
 | 
			
		||||
 | 
			
		||||
#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS
 | 
			
		||||
    void update_toolbar_items_visibility();
 | 
			
		||||
#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS
 | 
			
		||||
 | 
			
		||||
#if !ENABLE_IMGUI
 | 
			
		||||
    Rect get_gizmo_reset_rect(const GLCanvas3D& canvas, bool viewport) const;
 | 
			
		||||
    bool gizmo_reset_rect_contains(const GLCanvas3D& canvas, float x, float y) const;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -35,6 +35,9 @@ GLToolbarItem::Data::Data()
 | 
			
		|||
    , tooltip("")
 | 
			
		||||
    , sprite_id(-1)
 | 
			
		||||
    , is_toggable(false)
 | 
			
		||||
#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS
 | 
			
		||||
    , visible(true)
 | 
			
		||||
#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -45,61 +48,11 @@ GLToolbarItem::GLToolbarItem(GLToolbarItem::EType type, const GLToolbarItem::Dat
 | 
			
		|||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GLToolbarItem::EState GLToolbarItem::get_state() const
 | 
			
		||||
{
 | 
			
		||||
    return m_state;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GLToolbarItem::set_state(GLToolbarItem::EState state)
 | 
			
		||||
{
 | 
			
		||||
    m_state = state;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const std::string& GLToolbarItem::get_name() const
 | 
			
		||||
{
 | 
			
		||||
    return m_data.name;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const std::string& GLToolbarItem::get_tooltip() const
 | 
			
		||||
{
 | 
			
		||||
    return m_data.tooltip;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GLToolbarItem::do_action(wxEvtHandler *target)
 | 
			
		||||
{
 | 
			
		||||
    wxPostEvent(target, SimpleEvent(m_data.action_event));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool GLToolbarItem::is_enabled() const
 | 
			
		||||
{
 | 
			
		||||
    return m_state != Disabled;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool GLToolbarItem::is_disabled() const
 | 
			
		||||
{
 | 
			
		||||
    return m_state == Disabled;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool GLToolbarItem::is_hovered() const
 | 
			
		||||
{
 | 
			
		||||
    return (m_state == Hover) || (m_state == HoverPressed);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool GLToolbarItem::is_pressed() const
 | 
			
		||||
{
 | 
			
		||||
    return (m_state == Pressed) || (m_state == HoverPressed);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool GLToolbarItem::is_toggable() const
 | 
			
		||||
{
 | 
			
		||||
    return m_data.is_toggable;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool GLToolbarItem::is_separator() const
 | 
			
		||||
{
 | 
			
		||||
    return m_type == Separator;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GLToolbarItem::render(unsigned int tex_id, float left, float right, float bottom, float top, unsigned int texture_size, unsigned int border_size, unsigned int icon_size, unsigned int gap_size) const
 | 
			
		||||
{
 | 
			
		||||
    GLTexture::render_sub_texture(tex_id, left, right, bottom, top, get_uvs(texture_size, border_size, icon_size, gap_size));
 | 
			
		||||
| 
						 | 
				
			
			@ -355,6 +308,46 @@ bool GLToolbar::is_item_disabled(const std::string& name) const
 | 
			
		|||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS
 | 
			
		||||
bool GLToolbar::is_item_visible(const std::string& name) const
 | 
			
		||||
{
 | 
			
		||||
    for (GLToolbarItem* item : m_items)
 | 
			
		||||
    {
 | 
			
		||||
        if (item->get_name() == name)
 | 
			
		||||
            return item->is_visible();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GLToolbar::set_item_visible(const std::string& name, bool visible)
 | 
			
		||||
{
 | 
			
		||||
    for (GLToolbarItem* item : m_items)
 | 
			
		||||
    {
 | 
			
		||||
        if ((item->get_name() == name) && (item->is_visible() != visible))
 | 
			
		||||
        {
 | 
			
		||||
            item->set_visible(visible);
 | 
			
		||||
            m_layout.dirty = true;
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // updates separators visibility to avoid having two consecutive
 | 
			
		||||
    bool any_item_visible = false;
 | 
			
		||||
    for (GLToolbarItem* item : m_items)
 | 
			
		||||
    {
 | 
			
		||||
        if (!item->is_separator())
 | 
			
		||||
            any_item_visible |= item->is_visible();
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            item->set_visible(any_item_visible);
 | 
			
		||||
            any_item_visible = false;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS
 | 
			
		||||
 | 
			
		||||
std::string GLToolbar::update_hover_state(const Vec2d& mouse_pos, GLCanvas3D& parent)
 | 
			
		||||
{
 | 
			
		||||
    if (!m_enabled)
 | 
			
		||||
| 
						 | 
				
			
			@ -486,6 +479,11 @@ float GLToolbar::get_main_size() const
 | 
			
		|||
    float size = 2.0f * m_layout.border * m_layout.icons_scale;
 | 
			
		||||
    for (unsigned int i = 0; i < (unsigned int)m_items.size(); ++i)
 | 
			
		||||
    {
 | 
			
		||||
#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS
 | 
			
		||||
        if (!m_items[i]->is_visible())
 | 
			
		||||
            continue;
 | 
			
		||||
#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS
 | 
			
		||||
 | 
			
		||||
        if (m_items[i]->is_separator())
 | 
			
		||||
            size += m_layout.separator_size * m_layout.icons_scale;
 | 
			
		||||
        else
 | 
			
		||||
| 
						 | 
				
			
			@ -524,6 +522,11 @@ std::string GLToolbar::update_hover_state_horizontal(const Vec2d& mouse_pos, GLC
 | 
			
		|||
        
 | 
			
		||||
    for (GLToolbarItem* item : m_items)
 | 
			
		||||
    {
 | 
			
		||||
#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS
 | 
			
		||||
        if (!item->is_visible())
 | 
			
		||||
            continue;
 | 
			
		||||
#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS
 | 
			
		||||
 | 
			
		||||
        if (item->is_separator())
 | 
			
		||||
            left += separator_stride;
 | 
			
		||||
        else
 | 
			
		||||
| 
						 | 
				
			
			@ -618,6 +621,11 @@ std::string GLToolbar::update_hover_state_vertical(const Vec2d& mouse_pos, GLCan
 | 
			
		|||
 | 
			
		||||
    for (GLToolbarItem* item : m_items)
 | 
			
		||||
    {
 | 
			
		||||
#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS
 | 
			
		||||
        if (!item->is_visible())
 | 
			
		||||
            continue;
 | 
			
		||||
#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS
 | 
			
		||||
 | 
			
		||||
        if (item->is_separator())
 | 
			
		||||
            top -= separator_stride;
 | 
			
		||||
        else
 | 
			
		||||
| 
						 | 
				
			
			@ -714,6 +722,11 @@ int GLToolbar::contains_mouse_horizontal(const Vec2d& mouse_pos, const GLCanvas3
 | 
			
		|||
    {
 | 
			
		||||
        ++id;
 | 
			
		||||
        
 | 
			
		||||
#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS
 | 
			
		||||
        if (!item->is_visible())
 | 
			
		||||
            continue;
 | 
			
		||||
#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS
 | 
			
		||||
 | 
			
		||||
        if (item->is_separator())
 | 
			
		||||
            left += separator_stride;
 | 
			
		||||
        else
 | 
			
		||||
| 
						 | 
				
			
			@ -759,6 +772,11 @@ int GLToolbar::contains_mouse_vertical(const Vec2d& mouse_pos, const GLCanvas3D&
 | 
			
		|||
    {
 | 
			
		||||
        ++id;
 | 
			
		||||
 | 
			
		||||
#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS
 | 
			
		||||
        if (!item->is_visible())
 | 
			
		||||
            continue;
 | 
			
		||||
#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS
 | 
			
		||||
 | 
			
		||||
        if (item->is_separator())
 | 
			
		||||
            top -= separator_stride;
 | 
			
		||||
        else
 | 
			
		||||
| 
						 | 
				
			
			@ -892,6 +910,11 @@ void GLToolbar::render_horizontal(const GLCanvas3D& parent) const
 | 
			
		|||
    // renders icons
 | 
			
		||||
    for (const GLToolbarItem* item : m_items)
 | 
			
		||||
    {
 | 
			
		||||
#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS
 | 
			
		||||
        if (!item->is_visible())
 | 
			
		||||
            continue;
 | 
			
		||||
#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS
 | 
			
		||||
 | 
			
		||||
        if (item->is_separator())
 | 
			
		||||
            left += separator_stride;
 | 
			
		||||
        else
 | 
			
		||||
| 
						 | 
				
			
			@ -1018,6 +1041,11 @@ void GLToolbar::render_vertical(const GLCanvas3D& parent) const
 | 
			
		|||
    // renders icons
 | 
			
		||||
    for (const GLToolbarItem* item : m_items)
 | 
			
		||||
    {
 | 
			
		||||
#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS
 | 
			
		||||
        if (!item->is_visible())
 | 
			
		||||
            continue;
 | 
			
		||||
#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS
 | 
			
		||||
 | 
			
		||||
        if (item->is_separator())
 | 
			
		||||
            top -= separator_stride;
 | 
			
		||||
        else
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,7 +8,6 @@
 | 
			
		|||
#include "GLTexture.hpp"
 | 
			
		||||
#include "Event.hpp"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class wxEvtHandler;
 | 
			
		||||
 | 
			
		||||
namespace Slic3r {
 | 
			
		||||
| 
						 | 
				
			
			@ -56,6 +55,9 @@ public:
 | 
			
		|||
        unsigned int sprite_id;
 | 
			
		||||
        bool is_toggable;
 | 
			
		||||
        wxEventType action_event;
 | 
			
		||||
#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS
 | 
			
		||||
        bool visible;
 | 
			
		||||
#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS
 | 
			
		||||
 | 
			
		||||
        Data();
 | 
			
		||||
    };
 | 
			
		||||
| 
						 | 
				
			
			@ -68,21 +70,25 @@ private:
 | 
			
		|||
public:
 | 
			
		||||
    GLToolbarItem(EType type, const Data& data);
 | 
			
		||||
 | 
			
		||||
    EState get_state() const;
 | 
			
		||||
    void set_state(EState state);
 | 
			
		||||
    EState get_state() const { return m_state; }
 | 
			
		||||
    void set_state(EState state) { m_state = state; }
 | 
			
		||||
 | 
			
		||||
    const std::string& get_name() const;
 | 
			
		||||
    const std::string& get_tooltip() const;
 | 
			
		||||
    const std::string& get_name() const { return m_data.name; }
 | 
			
		||||
    const std::string& get_tooltip() const { return m_data.tooltip; }
 | 
			
		||||
 | 
			
		||||
    void do_action(wxEvtHandler *target);
 | 
			
		||||
 | 
			
		||||
    bool is_enabled() const;
 | 
			
		||||
    bool is_disabled() const;
 | 
			
		||||
    bool is_hovered() const;
 | 
			
		||||
    bool is_pressed() const;
 | 
			
		||||
    bool is_enabled() const { return m_state != Disabled; }
 | 
			
		||||
    bool is_disabled() const { return m_state == Disabled; }
 | 
			
		||||
    bool is_hovered() const { return (m_state == Hover) || (m_state == HoverPressed); }
 | 
			
		||||
    bool is_pressed() const { return (m_state == Pressed) || (m_state == HoverPressed); }
 | 
			
		||||
 | 
			
		||||
    bool is_toggable() const;
 | 
			
		||||
    bool is_separator() const;
 | 
			
		||||
    bool is_toggable() const { return m_data.is_toggable; }
 | 
			
		||||
#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS
 | 
			
		||||
    bool is_visible() const { return m_data.visible; }
 | 
			
		||||
    void set_visible(bool visible) { m_data.visible = visible; }
 | 
			
		||||
#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS
 | 
			
		||||
    bool is_separator() const { return m_type == Separator; }
 | 
			
		||||
 | 
			
		||||
    void render(unsigned int tex_id, float left, float right, float bottom, float top, unsigned int texture_size, unsigned int border_size, unsigned int icon_size, unsigned int gap_size) const;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -223,6 +229,10 @@ public:
 | 
			
		|||
 | 
			
		||||
    bool is_item_pressed(const std::string& name) const;
 | 
			
		||||
    bool is_item_disabled(const std::string& name) const;
 | 
			
		||||
#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS
 | 
			
		||||
    bool is_item_visible(const std::string& name) const;
 | 
			
		||||
    void set_item_visible(const std::string& name, bool visible);
 | 
			
		||||
#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS
 | 
			
		||||
 | 
			
		||||
    std::string update_hover_state(const Vec2d& mouse_pos, GLCanvas3D& parent);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -955,10 +955,20 @@ wxMenuItem* ObjectList::append_menu_item_instance_to_object(wxMenu* menu)
 | 
			
		|||
        [this](wxCommandEvent&) { split_instances(); }, "", menu);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
wxMenuItem* ObjectList::append_menu_item_rename(wxMenu* menu)
 | 
			
		||||
void ObjectList::append_menu_item_rename(wxMenu* menu)
 | 
			
		||||
{
 | 
			
		||||
    return append_menu_item(menu, wxID_ANY, _(L("Rename")), "",
 | 
			
		||||
    append_menu_item(menu, wxID_ANY, _(L("Rename")), "",
 | 
			
		||||
        [this](wxCommandEvent&) { rename_item(); }, "", menu);
 | 
			
		||||
    menu->AppendSeparator();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ObjectList::append_menu_item_fix_through_netfabb(wxMenu* menu)
 | 
			
		||||
{
 | 
			
		||||
    if (!is_windows10())
 | 
			
		||||
        return;
 | 
			
		||||
    append_menu_item(menu, wxID_ANY, _(L("Fix through the Netfabb")), "",
 | 
			
		||||
        [this](wxCommandEvent&) { fix_through_netfabb(); }, "", menu);
 | 
			
		||||
    menu->AppendSeparator();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ObjectList::create_object_popupmenu(wxMenu *menu)
 | 
			
		||||
| 
						 | 
				
			
			@ -967,6 +977,8 @@ void ObjectList::create_object_popupmenu(wxMenu *menu)
 | 
			
		|||
    append_menu_item_rename(menu);
 | 
			
		||||
#endif // __WXOSX__
 | 
			
		||||
 | 
			
		||||
    append_menu_item_fix_through_netfabb(menu);
 | 
			
		||||
 | 
			
		||||
    // Split object to parts
 | 
			
		||||
    m_menu_item_split = append_menu_item_split(menu);
 | 
			
		||||
    menu->AppendSeparator();
 | 
			
		||||
| 
						 | 
				
			
			@ -984,6 +996,8 @@ void ObjectList::create_sla_object_popupmenu(wxMenu *menu)
 | 
			
		|||
#ifdef __WXOSX__  
 | 
			
		||||
    append_menu_item_rename(menu);
 | 
			
		||||
#endif // __WXOSX__
 | 
			
		||||
    
 | 
			
		||||
    append_menu_item_fix_through_netfabb(menu);
 | 
			
		||||
    // rest of a object_sla_menu will be added later in:
 | 
			
		||||
    // - append_menu_item_settings() -> for "Add (settings)"
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -994,6 +1008,8 @@ void ObjectList::create_part_popupmenu(wxMenu *menu)
 | 
			
		|||
    append_menu_item_rename(menu);
 | 
			
		||||
#endif // __WXOSX__
 | 
			
		||||
 | 
			
		||||
    append_menu_item_fix_through_netfabb(menu);
 | 
			
		||||
 | 
			
		||||
    m_menu_item_split_part = append_menu_item_split(menu);
 | 
			
		||||
 | 
			
		||||
    // Append change part type
 | 
			
		||||
| 
						 | 
				
			
			@ -2114,6 +2130,21 @@ void ObjectList::rename_item()
 | 
			
		|||
    update_name_in_model(item);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ObjectList::fix_through_netfabb() const 
 | 
			
		||||
{
 | 
			
		||||
    const wxDataViewItem item = GetSelection();
 | 
			
		||||
    if (!item)
 | 
			
		||||
        return;
 | 
			
		||||
    
 | 
			
		||||
    ItemType type = m_objects_model->GetItemType(item);
 | 
			
		||||
    
 | 
			
		||||
    if (type & itObject)
 | 
			
		||||
        wxGetApp().plater()->fix_through_netfabb(m_objects_model->GetIdByItem(item));
 | 
			
		||||
    else if (type & itVolume) 
 | 
			
		||||
        wxGetApp().plater()->fix_through_netfabb(m_objects_model->GetIdByItem(m_objects_model->GetTopParent(item)),
 | 
			
		||||
                                                 m_objects_model->GetVolumeIdByItem(item));    
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ObjectList::ItemValueChanged(wxDataViewEvent &event)
 | 
			
		||||
{
 | 
			
		||||
    if (event.GetColumn() == 0)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -179,7 +179,8 @@ public:
 | 
			
		|||
    wxMenuItem*         append_menu_item_settings(wxMenu* menu);
 | 
			
		||||
    wxMenuItem*         append_menu_item_change_type(wxMenu* menu);
 | 
			
		||||
    wxMenuItem*         append_menu_item_instance_to_object(wxMenu* menu);
 | 
			
		||||
    wxMenuItem*         append_menu_item_rename(wxMenu* menu);
 | 
			
		||||
    void                append_menu_item_rename(wxMenu* menu);
 | 
			
		||||
    void                append_menu_item_fix_through_netfabb(wxMenu* menu);
 | 
			
		||||
    void                create_object_popupmenu(wxMenu *menu);
 | 
			
		||||
    void                create_sla_object_popupmenu(wxMenu*menu);
 | 
			
		||||
    void                create_part_popupmenu(wxMenu*menu);
 | 
			
		||||
| 
						 | 
				
			
			@ -262,7 +263,7 @@ public:
 | 
			
		|||
    void instances_to_separated_object(const int obj_idx, const std::set<int>& inst_idx);
 | 
			
		||||
    void split_instances();
 | 
			
		||||
    void rename_item();
 | 
			
		||||
 | 
			
		||||
    void fix_through_netfabb() const;
 | 
			
		||||
private:
 | 
			
		||||
    void OnChar(wxKeyEvent& event);
 | 
			
		||||
    void OnContextMenu(wxDataViewEvent &event);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -139,6 +139,14 @@ void View3D::mirror_selection(Axis axis)
 | 
			
		|||
        m_canvas->mirror_selection(axis);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS
 | 
			
		||||
void View3D::update_toolbar_items_visibility()
 | 
			
		||||
{
 | 
			
		||||
    if (m_canvas != nullptr)
 | 
			
		||||
        m_canvas->update_toolbar_items_visibility();
 | 
			
		||||
}
 | 
			
		||||
#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS
 | 
			
		||||
 | 
			
		||||
void View3D::enable_toolbar_item(const std::string& name, bool enable)
 | 
			
		||||
{
 | 
			
		||||
    if (m_canvas != nullptr)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -58,6 +58,9 @@ public:
 | 
			
		|||
    void delete_selected();
 | 
			
		||||
    void mirror_selection(Axis axis);
 | 
			
		||||
 | 
			
		||||
#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS
 | 
			
		||||
    void update_toolbar_items_visibility();
 | 
			
		||||
#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS
 | 
			
		||||
    void enable_toolbar_item(const std::string& name, bool enable);
 | 
			
		||||
    int check_volumes_outside_state() const;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -44,7 +44,8 @@ KBShortcutsDialog::KBShortcutsDialog()
 | 
			
		|||
 | 
			
		||||
    for (auto& sc : m_full_shortcuts)
 | 
			
		||||
    {
 | 
			
		||||
        auto sizer = sc.first == _(L("Main Shortcuts")) ? l_sizer : r_sizer;
 | 
			
		||||
//         auto sizer = sc.first == _(L("Main Shortcuts")) ? l_sizer : r_sizer;
 | 
			
		||||
        auto sizer = sc.second.second == 0 ? l_sizer : r_sizer;
 | 
			
		||||
        wxBoxSizer* hsizer = new wxBoxSizer(wxHORIZONTAL);
 | 
			
		||||
        sizer->Add(hsizer, 0, wxEXPAND | wxTOP | wxBOTTOM, 10);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -61,7 +62,7 @@ KBShortcutsDialog::KBShortcutsDialog()
 | 
			
		|||
        auto grid_sizer = new wxFlexGridSizer(2, 5, 15);
 | 
			
		||||
        sizer->Add(grid_sizer, 0, wxEXPAND | wxLEFT| wxRIGHT, 15);
 | 
			
		||||
 | 
			
		||||
        for (auto pair : sc.second)
 | 
			
		||||
        for (auto pair : sc.second.first)
 | 
			
		||||
        {
 | 
			
		||||
            auto shortcut = new wxStaticText(panel, wxID_ANY, _(pair.first));
 | 
			
		||||
            shortcut->SetFont(bold_font);
 | 
			
		||||
| 
						 | 
				
			
			@ -95,6 +96,8 @@ void KBShortcutsDialog::fill_shortcuts()
 | 
			
		|||
    const std::string alt = "Alt+";
 | 
			
		||||
#endif // __WXOSX__
 | 
			
		||||
 | 
			
		||||
    m_full_shortcuts.reserve(4);
 | 
			
		||||
 | 
			
		||||
    Shortcuts main_shortcuts;
 | 
			
		||||
    main_shortcuts.reserve(25);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -122,7 +125,7 @@ void KBShortcutsDialog::fill_shortcuts()
 | 
			
		|||
    main_shortcuts.push_back(Shortcut("?"               ,L("Show keyboard shortcuts list")));
 | 
			
		||||
    main_shortcuts.push_back(Shortcut("Shift+LeftMouse", L("Select multiple object/Move multiple object")));
 | 
			
		||||
 | 
			
		||||
    m_full_shortcuts.emplace(_(L("Main Shortcuts")),    main_shortcuts);
 | 
			
		||||
    m_full_shortcuts.push_back(std::make_pair( _(L("Main Shortcuts")), std::make_pair(main_shortcuts, 0) ));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    Shortcuts plater_shortcuts;
 | 
			
		||||
| 
						 | 
				
			
			@ -138,6 +141,8 @@ void KBShortcutsDialog::fill_shortcuts()
 | 
			
		|||
    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("Shift+",   L("Press to snap by 5% in Gizmo scale\nor by 1mm in Gizmo move")));
 | 
			
		||||
    plater_shortcuts.push_back(Shortcut(alt,        L("Press to scale or rotate selected objects\naround their own center")));
 | 
			
		||||
    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")));
 | 
			
		||||
| 
						 | 
				
			
			@ -145,16 +150,40 @@ void KBShortcutsDialog::fill_shortcuts()
 | 
			
		|||
    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);
 | 
			
		||||
    m_full_shortcuts.push_back(std::make_pair(_(L("Plater Shortcuts")), std::make_pair(plater_shortcuts, 1)));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//     Shortcuts gizmo_shortcuts;
 | 
			
		||||
//     gizmo_shortcuts.reserve(2);
 | 
			
		||||
// 
 | 
			
		||||
//     gizmo_shortcuts.push_back(Shortcut("Shift+",    L("Press to snap by 5% in Gizmo Scale\n or by 1mm in Gizmo Move")));
 | 
			
		||||
//     gizmo_shortcuts.push_back(Shortcut(alt,         L("Press to scale or rotate selected objects around their own center")));
 | 
			
		||||
// 
 | 
			
		||||
//     m_full_shortcuts.push_back(std::make_pair(_(L("Gizmo Shortcuts")), std::make_pair(gizmo_shortcuts, 1)));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    Shortcuts preview_shortcuts;
 | 
			
		||||
    preview_shortcuts.reserve(2);
 | 
			
		||||
    preview_shortcuts.reserve(4);
 | 
			
		||||
 | 
			
		||||
    preview_shortcuts.push_back(Shortcut(L("Arrow Up"),     L("Upper Layer")));
 | 
			
		||||
    preview_shortcuts.push_back(Shortcut(L("Arrow Down"),   L("Lower Layer")));
 | 
			
		||||
    preview_shortcuts.push_back(Shortcut("U",               L("Upper Layer")));
 | 
			
		||||
    preview_shortcuts.push_back(Shortcut("D",               L("Lower Layer")));
 | 
			
		||||
 | 
			
		||||
    m_full_shortcuts.emplace(_(L("Preview Shortcuts")), preview_shortcuts);
 | 
			
		||||
    m_full_shortcuts.push_back(std::make_pair( _(L("Preview Shortcuts")), std::make_pair(preview_shortcuts, 0) ));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    Shortcuts layers_slider_shortcuts;
 | 
			
		||||
    layers_slider_shortcuts.reserve(6);
 | 
			
		||||
 | 
			
		||||
    layers_slider_shortcuts.push_back(Shortcut(L("Arrow Up"),   L("Move current slider thump Up")));
 | 
			
		||||
    layers_slider_shortcuts.push_back(Shortcut(L("Arrow Down"), L("Move current slider thump Down")));
 | 
			
		||||
    layers_slider_shortcuts.push_back(Shortcut(L("Arrow Left"), L("Set upper thumb to current slider thumb")));
 | 
			
		||||
    layers_slider_shortcuts.push_back(Shortcut(L("Arrow Right"),L("Set lower thumb to current slider thumb")));
 | 
			
		||||
    layers_slider_shortcuts.push_back(Shortcut("+",             L("Add color change marker for current layer")));
 | 
			
		||||
    layers_slider_shortcuts.push_back(Shortcut("-",             L("Delete color change marker for current layer")));
 | 
			
		||||
 | 
			
		||||
    m_full_shortcuts.push_back(std::make_pair( _(L("Layers Slider Shortcuts")), std::make_pair(layers_slider_shortcuts, 1) ));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void KBShortcutsDialog::onCloseDialog(wxEvent &)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,11 +11,11 @@ class KBShortcutsDialog : public wxDialog
 | 
			
		|||
{
 | 
			
		||||
    typedef std::pair<std::string, std::string> Shortcut;
 | 
			
		||||
    typedef std::vector< Shortcut >             Shortcuts;
 | 
			
		||||
    typedef std::map<wxString, Shortcuts>       ShortcutsMap;
 | 
			
		||||
    typedef std::vector< std::pair<wxString, std::pair<Shortcuts, int>> >   ShortcutsVec;
 | 
			
		||||
 | 
			
		||||
    wxString text_info {wxEmptyString};
 | 
			
		||||
 | 
			
		||||
    ShortcutsMap m_full_shortcuts;
 | 
			
		||||
    ShortcutsVec m_full_shortcuts;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    KBShortcutsDialog();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1031,7 +1031,7 @@ struct Plater::priv
 | 
			
		|||
    void update_restart_background_process(bool force_scene_update, bool force_preview_update);
 | 
			
		||||
    void export_gcode(fs::path output_path, PrintHostJob upload_job);
 | 
			
		||||
    void reload_from_disk();
 | 
			
		||||
    void fix_through_netfabb(const int obj_idx);
 | 
			
		||||
    void fix_through_netfabb(const int obj_idx, const int vol_idx = -1);
 | 
			
		||||
 | 
			
		||||
    void set_current_panel(wxPanel* panel);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2104,7 +2104,7 @@ void Plater::priv::reload_from_disk()
 | 
			
		|||
    remove(obj_orig_idx);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Plater::priv::fix_through_netfabb(const int obj_idx)
 | 
			
		||||
void Plater::priv::fix_through_netfabb(const int obj_idx, const int vol_idx/* = -1*/)
 | 
			
		||||
{
 | 
			
		||||
    if (obj_idx < 0)
 | 
			
		||||
        return;
 | 
			
		||||
| 
						 | 
				
			
			@ -2438,6 +2438,8 @@ bool Plater::priv::init_common_menu(wxMenu* menu, const bool is_part/* = false*/
 | 
			
		|||
    }
 | 
			
		||||
    menu->AppendSeparator();
 | 
			
		||||
 | 
			
		||||
    sidebar->obj_list()->append_menu_item_fix_through_netfabb(menu);
 | 
			
		||||
 | 
			
		||||
    wxMenu* mirror_menu = new wxMenu();
 | 
			
		||||
    if (mirror_menu == nullptr)
 | 
			
		||||
        return false;
 | 
			
		||||
| 
						 | 
				
			
			@ -2644,6 +2646,10 @@ bool Plater::priv::can_mirror() const
 | 
			
		|||
void Plater::priv::update_object_menu()
 | 
			
		||||
{
 | 
			
		||||
    sidebar->obj_list()->append_menu_items_add_volume(&object_menu);
 | 
			
		||||
#if ENABLE_MODE_AWARE_TOOLBAR_ITEMS
 | 
			
		||||
    if (view3D != nullptr)
 | 
			
		||||
        view3D->update_toolbar_items_visibility();
 | 
			
		||||
#endif // ENABLE_MODE_AWARE_TOOLBAR_ITEMS
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Plater / Public
 | 
			
		||||
| 
						 | 
				
			
			@ -3148,7 +3154,7 @@ void Plater::changed_object(int obj_idx)
 | 
			
		|||
    this->p->schedule_background_process();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Plater::fix_through_netfabb(const int obj_idx) { p->fix_through_netfabb(obj_idx); }
 | 
			
		||||
void Plater::fix_through_netfabb(const int obj_idx, const int vol_idx/* = -1*/) { p->fix_through_netfabb(obj_idx, vol_idx); }
 | 
			
		||||
 | 
			
		||||
void Plater::update_object_menu() { p->update_object_menu(); }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -147,7 +147,7 @@ public:
 | 
			
		|||
    void export_3mf(const boost::filesystem::path& output_path = boost::filesystem::path());
 | 
			
		||||
    void reslice();
 | 
			
		||||
    void changed_object(int obj_idx);
 | 
			
		||||
    void fix_through_netfabb(const int obj_idx);
 | 
			
		||||
    void fix_through_netfabb(const int obj_idx, const int vol_idx = -1);
 | 
			
		||||
    void send_gcode();
 | 
			
		||||
 | 
			
		||||
    void on_extruders_change(int extruders_count);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue