diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index 86bd0d03bc..a88bdd9910 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -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 */ } diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index 0ae238510e..ba109246a5 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -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 */ } diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index 8bf5409741..5f02653c65 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -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) diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index d10d9e0eb7..fd1645c9e2 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -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().data()); + glsafe(::glUniformMatrix4fv(worldmatrix_id, 1, GL_FALSE, (const GLfloat*)world_matrix().cast().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().data()); + glsafe(::glUniformMatrix4fv(worldmatrix_id, 1, GL_FALSE, (const GLfloat*)world_matrix().cast().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 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 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()); 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) diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp index e9340bd6e2..7430ff4aa0 100644 --- a/src/slic3r/GUI/3DScene.hpp +++ b/src/slic3r/GUI/3DScene.hpp @@ -11,6 +11,19 @@ #include +#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; diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 6570b8d4b2..b5e979bc48 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -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 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& 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); diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index e65ace238b..ec980dd926 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -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; diff --git a/src/slic3r/GUI/GLToolbar.cpp b/src/slic3r/GUI/GLToolbar.cpp index b15048ec61..8d04868f80 100644 --- a/src/slic3r/GUI/GLToolbar.cpp +++ b/src/slic3r/GUI/GLToolbar.cpp @@ -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 diff --git a/src/slic3r/GUI/GLToolbar.hpp b/src/slic3r/GUI/GLToolbar.hpp index 37eef5708b..951d5e0725 100644 --- a/src/slic3r/GUI/GLToolbar.hpp +++ b/src/slic3r/GUI/GLToolbar.hpp @@ -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); diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index f4c5789515..eb34e12514 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -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) diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index 66e1423941..e572bec827 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -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& inst_idx); void split_instances(); void rename_item(); - + void fix_through_netfabb() const; private: void OnChar(wxKeyEvent& event); void OnContextMenu(wxDataViewEvent &event); diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index b594d0fef4..0ad6c35625 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -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) diff --git a/src/slic3r/GUI/GUI_Preview.hpp b/src/slic3r/GUI/GUI_Preview.hpp index d4410c5891..49dbed44d9 100644 --- a/src/slic3r/GUI/GUI_Preview.hpp +++ b/src/slic3r/GUI/GUI_Preview.hpp @@ -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; diff --git a/src/slic3r/GUI/KBShortcutsDialog.cpp b/src/slic3r/GUI/KBShortcutsDialog.cpp index 23169dde19..3aeda03482 100644 --- a/src/slic3r/GUI/KBShortcutsDialog.cpp +++ b/src/slic3r/GUI/KBShortcutsDialog.cpp @@ -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 &) diff --git a/src/slic3r/GUI/KBShortcutsDialog.hpp b/src/slic3r/GUI/KBShortcutsDialog.hpp index 8517544b57..c5f60f0b8f 100644 --- a/src/slic3r/GUI/KBShortcutsDialog.hpp +++ b/src/slic3r/GUI/KBShortcutsDialog.hpp @@ -11,11 +11,11 @@ class KBShortcutsDialog : public wxDialog { typedef std::pair Shortcut; typedef std::vector< Shortcut > Shortcuts; - typedef std::map ShortcutsMap; + typedef std::vector< std::pair> > ShortcutsVec; wxString text_info {wxEmptyString}; - ShortcutsMap m_full_shortcuts; + ShortcutsVec m_full_shortcuts; public: KBShortcutsDialog(); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index f69d260f32..efcc02a562 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -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(); } diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 7b19d6f313..09b7348d5d 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -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);