Merge branch 'master' into et_world_coordinates

This commit is contained in:
Vojtech Bubnik 2022-03-23 14:05:33 +01:00
commit fe71e7c597
23 changed files with 638 additions and 227 deletions

View file

@ -1,3 +1,5 @@
min_slic3r_version = 2.4.1
0.1.4 Added Ender-3 Pro. Added M25 support for some printers.
min_slic3r_version = 2.4.0-rc
0.1.3 Ender-3 S1 improvements.
0.1.2 Added alpha Ender 3 S1 profiles.

View file

@ -5,7 +5,7 @@
name = Creality
# Configuration version of this file. Config file will only be installed, if the config_version differs.
# This means, the server may force the PrusaSlicer configuration to be downgraded.
config_version = 0.1.3
config_version = 0.1.4
# Where to get the updates from?
config_update_url = https://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/Creality/
# changelog_url = https://files.prusa3d.com/?latest=slicer-profiles&lng=%1%
@ -32,6 +32,15 @@ bed_model = ender3_bed.stl
bed_texture = ender3.svg
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Matt @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
[printer_model:ENDER3PRO]
name = Creality Ender-3 Pro
variants = 0.4
technology = FFF
family = ENDER
bed_model = ender3_bed.stl
bed_texture = ender3.svg
default_materials = Generic PLA @CREALITY; Generic PETG @CREALITY; Generic ABS @CREALITY; Creality PLA @CREALITY; Prusament PLA @CREALITY; Prusament PETG @CREALITY; AzureFilm PLA @CREALITY; Devil Design PLA @CREALITY; Devil Design PLA Matt @CREALITY; Devil Design PLA Galaxy @CREALITY; Extrudr PLA NX2 @CREALITY; Real Filament PLA @CREALITY; Velleman PLA @CREALITY; 3DJAKE ecoPLA @CREALITY; 3DJAKE ecoPLA Matt @CREALITY; 3DJAKE ecoPLA Tough @CREALITY; 123-3D Jupiter PLA @CREALITY
[printer_model:ENDER3V2]
name = Creality Ender-3 V2
variants = 0.4
@ -960,8 +969,16 @@ inherits = Creality Ender-3; *fastabl*
renamed_from = "Creality ENDER-3 BLTouch"
printer_model = ENDER3BLTOUCH
[printer:Creality Ender-3 Pro]
inherits = *common*; *pauseprint*
renamed_from = "Creality Ender-3 Pro"
bed_shape = 5x0,215x0,215x220,5x220
max_print_height = 250
printer_model = ENDER3PRO
printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_ENDER3PRO\nPRINTER_HAS_BOWDEN
[printer:Creality Ender-3 V2]
inherits = *common*
inherits = *common*; *pauseprint*
renamed_from = "Creality Ender-3V2"
bed_shape = 5x0,215x0,215x220,5x220
max_print_height = 250
@ -969,14 +986,14 @@ printer_model = ENDER3V2
printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_ENDER3V2\nPRINTER_HAS_BOWDEN
[printer:Creality Ender-3 S1]
inherits = *common*; *spriteextruder*
inherits = *common*; *pauseprint*; *spriteextruder*
bed_shape = 5x0,215x0,215x220,5x220
max_print_height = 270
printer_model = ENDER3S1
printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_ENDER3S1
[printer:Creality Ender-3 Max]
inherits = *common*
inherits = *common*; *pauseprint*
retract_length = 6
bed_shape = 5x5,295x5,295x295,5x295
max_print_height = 340

View file

@ -0,0 +1,11 @@
#version 110
uniform sampler2D Texture;
varying vec2 Frag_UV;
varying vec4 Frag_Color;
void main()
{
gl_FragColor = Frag_Color * texture2D(Texture, Frag_UV.st);
}

View file

@ -0,0 +1,17 @@
#version 110
uniform mat4 ProjMtx;
attribute vec2 Position;
attribute vec2 UV;
attribute vec4 Color;
varying vec2 Frag_UV;
varying vec4 Frag_Color;
void main()
{
Frag_UV = UV;
Frag_Color = Color;
gl_Position = ProjMtx * vec4(Position.xy, 0.0, 1.0);
}

View file

@ -1952,12 +1952,15 @@ void GCodeProcessor::process_tags(const std::string_view comment, bool producers
++m_layer_id;
#if ENABLE_SPIRAL_VASE_LAYERS
if (m_spiral_vase_active) {
assert(!m_result.moves.empty());
size_t move_id = m_result.moves.size() - 1;
if (!m_result.spiral_vase_layers.empty() && m_end_position[Z] == m_result.spiral_vase_layers.back().first)
m_result.spiral_vase_layers.back().second.second = move_id;
else
m_result.spiral_vase_layers.push_back({ static_cast<float>(m_end_position[Z]), { move_id, move_id } });
if (m_result.moves.empty())
m_result.spiral_vase_layers.push_back({ m_first_layer_height, { 0, 0 } });
else {
const size_t move_id = m_result.moves.size() - 1;
if (!m_result.spiral_vase_layers.empty() && m_end_position[Z] == m_result.spiral_vase_layers.back().first)
m_result.spiral_vase_layers.back().second.second = move_id;
else
m_result.spiral_vase_layers.push_back({ static_cast<float>(m_end_position[Z]), { move_id, move_id } });
}
}
#endif // ENABLE_SPIRAL_VASE_LAYERS
return;

View file

@ -34,8 +34,6 @@
#define ENABLE_ENVIRONMENT_MAP 0
// Enable smoothing of objects normals
#define ENABLE_SMOOTH_NORMALS 0
// Enable rendering markers for options in preview as fixed screen size points
#define ENABLE_FIXED_SCREEN_SIZE_POINT_MARKERS 1
//================
@ -70,6 +68,10 @@
#define ENABLE_LEGACY_OPENGL_REMOVAL (1 && ENABLE_2_5_0_ALPHA1)
// Enable using vertex attributes and matrices in shaders
#define ENABLE_GL_SHADERS_ATTRIBUTES (1 && ENABLE_LEGACY_OPENGL_REMOVAL)
// Enable rendering imgui using shaders
#define ENABLE_GL_IMGUI_SHADERS (1 && ENABLE_GL_SHADERS_ATTRIBUTES)
// Shows an imgui dialog with GLModel statistics data
#define ENABLE_GLMODEL_STATISTICS (0 && ENABLE_LEGACY_OPENGL_REMOVAL)
// Enable show non-manifold edges
#define ENABLE_SHOW_NON_MANIFOLD_EDGES (1 && ENABLE_2_5_0_ALPHA1)
// Enable rework of Reload from disk command
@ -88,6 +90,9 @@
#define ENABLE_WORLD_COORDINATE_SHOW_AXES (1 && ENABLE_WORLD_COORDINATE)
// Enable alternate implementation of manipulating scale for instances and volumes
#define ENABLE_WORLD_COORDINATE_SCALE_REVISITED (1 && ENABLE_WORLD_COORDINATE)
// Enable modified camera control using mouse
#define ENABLE_NEW_CAMERA_MOVEMENTS (1 && ENABLE_2_5_0_ALPHA1)
// Enable modified rectangle selection
#define ENABLE_NEW_RECTANGLE_SELECTION (1 && ENABLE_2_5_0_ALPHA1)
#endif // _prusaslicer_technologies_h_

View file

@ -529,7 +529,7 @@ void Bed3D::render_system(GLCanvas3D& canvas, const Transform3d& view_matrix, co
render_model(view_matrix, projection_matrix);
if (show_texture)
render_texture(bottom, canvas);
render_texture(bottom, canvas, view_matrix, projection_matrix);
}
#else
void Bed3D::render_system(GLCanvas3D& canvas, bool bottom, bool show_texture)
@ -542,11 +542,19 @@ void Bed3D::render_system(GLCanvas3D& canvas, bool bottom, bool show_texture)
}
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
#if ENABLE_GL_SHADERS_ATTRIBUTES
void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix)
#else
void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas)
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
{
if (m_texture_filename.empty()) {
m_texture.reset();
#if ENABLE_GL_SHADERS_ATTRIBUTES
render_default(bottom, false, view_matrix, projection_matrix);
#else
render_default(bottom, false);
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
return;
}
@ -559,7 +567,11 @@ void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas)
if (m_temp_texture.get_id() == 0 || m_temp_texture.get_source() != m_texture_filename) {
// generate a temporary lower resolution texture to show while no main texture levels have been compressed
if (!m_temp_texture.load_from_svg_file(m_texture_filename, false, false, false, max_tex_size / 8)) {
#if ENABLE_GL_SHADERS_ATTRIBUTES
render_default(bottom, false, view_matrix, projection_matrix);
#else
render_default(bottom, false);
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
return;
}
canvas.request_extra_frame();
@ -567,7 +579,11 @@ void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas)
// starts generating the main texture, compression will run asynchronously
if (!m_texture.load_from_svg_file(m_texture_filename, true, true, true, max_tex_size)) {
#if ENABLE_GL_SHADERS_ATTRIBUTES
render_default(bottom, false, view_matrix, projection_matrix);
#else
render_default(bottom, false);
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
return;
}
}
@ -575,7 +591,11 @@ void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas)
// generate a temporary lower resolution texture to show while no main texture levels have been compressed
if (m_temp_texture.get_id() == 0 || m_temp_texture.get_source() != m_texture_filename) {
if (!m_temp_texture.load_from_file(m_texture_filename, false, GLTexture::None, false)) {
#if ENABLE_GL_SHADERS_ATTRIBUTES
render_default(bottom, false, view_matrix, projection_matrix);
#else
render_default(bottom, false);
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
return;
}
canvas.request_extra_frame();
@ -583,12 +603,20 @@ void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas)
// starts generating the main texture, compression will run asynchronously
if (!m_texture.load_from_file(m_texture_filename, true, GLTexture::MultiThreaded, true)) {
#if ENABLE_GL_SHADERS_ATTRIBUTES
render_default(bottom, false, view_matrix, projection_matrix);
#else
render_default(bottom, false);
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
return;
}
}
else {
#if ENABLE_GL_SHADERS_ATTRIBUTES
render_default(bottom, false, view_matrix, projection_matrix);
#else
render_default(bottom, false);
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
return;
}
}
@ -614,9 +642,8 @@ void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas)
if (shader != nullptr) {
shader->start_using();
#if ENABLE_GL_SHADERS_ATTRIBUTES
const Camera& camera = wxGetApp().plater()->get_camera();
shader->set_uniform("view_model_matrix", camera.get_view_matrix());
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
shader->set_uniform("view_model_matrix", view_matrix);
shader->set_uniform("projection_matrix", projection_matrix);
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
shader->set_uniform("transparent_background", bottom);
shader->set_uniform("svg_source", boost::algorithm::iends_with(m_texture.get_source(), ".svg"));
@ -768,7 +795,11 @@ void Bed3D::render_custom(GLCanvas3D& canvas, bool bottom, bool show_texture, bo
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
{
if (m_texture_filename.empty() && m_model_filename.empty()) {
#if ENABLE_GL_SHADERS_ATTRIBUTES
render_default(bottom, picking, view_matrix, projection_matrix);
#else
render_default(bottom, picking);
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
return;
}
@ -780,10 +811,18 @@ void Bed3D::render_custom(GLCanvas3D& canvas, bool bottom, bool show_texture, bo
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (show_texture)
#if ENABLE_GL_SHADERS_ATTRIBUTES
render_texture(bottom, canvas, view_matrix, projection_matrix);
#else
render_texture(bottom, canvas);
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
}
#if ENABLE_GL_SHADERS_ATTRIBUTES
void Bed3D::render_default(bool bottom, bool picking, const Transform3d& view_matrix, const Transform3d& projection_matrix)
#else
void Bed3D::render_default(bool bottom, bool picking)
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
{
m_texture.reset();
@ -800,9 +839,8 @@ void Bed3D::render_default(bool bottom, bool picking)
shader->start_using();
#if ENABLE_GL_SHADERS_ATTRIBUTES
const Camera& camera = wxGetApp().plater()->get_camera();
shader->set_uniform("view_model_matrix", camera.get_view_matrix());
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
shader->set_uniform("view_model_matrix", view_matrix);
shader->set_uniform("projection_matrix", projection_matrix);
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
glsafe(::glEnable(GL_DEPTH_TEST));

View file

@ -178,18 +178,18 @@ private:
void render_axes();
#if ENABLE_GL_SHADERS_ATTRIBUTES
void render_system(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, bool show_texture);
#else
void render_system(GLCanvas3D& canvas, bool bottom, bool show_texture);
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
void render_texture(bool bottom, GLCanvas3D& canvas);
#if ENABLE_GL_SHADERS_ATTRIBUTES
void render_texture(bool bottom, GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix);
void render_model(const Transform3d& view_matrix, const Transform3d& projection_matrix);
void render_custom(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, bool show_texture, bool picking);
void render_default(bool bottom, bool picking, const Transform3d& view_matrix, const Transform3d& projection_matrix);
#else
void render_system(GLCanvas3D& canvas, bool bottom, bool show_texture);
void render_texture(bool bottom, GLCanvas3D& canvas);
void render_model();
void render_custom(GLCanvas3D& canvas, bool bottom, bool show_texture, bool picking);
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
void render_default(bool bottom, bool picking);
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
#if !ENABLE_LEGACY_OPENGL_REMOVAL
void release_VBOs();
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL

View file

@ -459,6 +459,7 @@ void GCodeViewer::SequentialView::GCodeWindow::render(float top, float bottom, u
static const ImVec4 COMMAND_COLOR = { 0.8f, 0.8f, 0.0f, 1.0f };
static const ImVec4 PARAMETERS_COLOR = { 1.0f, 1.0f, 1.0f, 1.0f };
static const ImVec4 COMMENT_COLOR = { 0.7f, 0.7f, 0.7f, 1.0f };
static const ImVec4 ELLIPSIS_COLOR = { 0.0f, 0.7f, 0.0f, 1.0f };
if (!m_visible || m_filename.empty() || m_lines_ends.empty() || curr_line_id == 0)
return;
@ -503,6 +504,35 @@ void GCodeViewer::SequentialView::GCodeWindow::render(float top, float bottom, u
ImGuiWrapper& imgui = *wxGetApp().imgui();
auto add_item_to_line = [&imgui](const std::string& txt, const ImVec4& color, float spacing, size_t& current_length) {
static const size_t LENGTH_THRESHOLD = 60;
if (txt.empty())
return false;
std::string out_text = txt;
bool reduced = false;
if (current_length + out_text.length() > LENGTH_THRESHOLD) {
out_text = out_text.substr(0, LENGTH_THRESHOLD - current_length);
reduced = true;
}
current_length += out_text.length();
ImGui::SameLine(0.0f, spacing);
ImGui::PushStyleColor(ImGuiCol_Text, color);
imgui.text(out_text);
ImGui::PopStyleColor();
if (reduced) {
ImGui::SameLine(0.0f, 0.0f);
ImGui::PushStyleColor(ImGuiCol_Text, ELLIPSIS_COLOR);
imgui.text("...");
ImGui::PopStyleColor();
}
return reduced;
};
imgui.set_next_window_pos(0.0f, top, ImGuiCond_Always, 0.0f, 0.0f);
imgui.set_next_window_size(0.0f, wnd_height, ImGuiCond_Always);
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
@ -527,41 +557,22 @@ void GCodeViewer::SequentialView::GCodeWindow::render(float top, float bottom, u
ImGui::GetColorU32(SELECTION_RECT_COLOR));
}
// render line number
const std::string id_str = std::to_string(id);
// spacer to right align text
ImGui::Dummy({ id_width - ImGui::CalcTextSize(id_str.c_str()).x, text_height });
ImGui::SameLine(0.0f, 0.0f);
ImGui::PushStyleColor(ImGuiCol_Text, LINE_NUMBER_COLOR);
imgui.text(id_str);
ImGui::PopStyleColor();
if (!line.command.empty() || !line.comment.empty())
ImGui::SameLine();
// render command
if (!line.command.empty()) {
ImGui::PushStyleColor(ImGuiCol_Text, COMMAND_COLOR);
imgui.text(line.command);
ImGui::PopStyleColor();
}
// render parameters
if (!line.parameters.empty()) {
ImGui::SameLine(0.0f, 0.0f);
ImGui::PushStyleColor(ImGuiCol_Text, PARAMETERS_COLOR);
imgui.text(line.parameters);
ImGui::PopStyleColor();
}
// render comment
if (!line.comment.empty()) {
if (!line.command.empty())
ImGui::SameLine(0.0f, 0.0f);
ImGui::PushStyleColor(ImGuiCol_Text, COMMENT_COLOR);
imgui.text(line.comment);
ImGui::PopStyleColor();
}
size_t line_length = 0;
// render line number
bool stop_adding = add_item_to_line(id_str, LINE_NUMBER_COLOR, 0.0f, line_length);
if (!stop_adding && !line.command.empty())
// render command
stop_adding = add_item_to_line(line.command, COMMAND_COLOR, -1.0f, line_length);
if (!stop_adding && !line.parameters.empty())
// render parameters
stop_adding = add_item_to_line(line.parameters, PARAMETERS_COLOR, 0.0f, line_length);
if (!stop_adding && !line.comment.empty())
// render comment
stop_adding = add_item_to_line(line.comment, COMMENT_COLOR, line.command.empty() ? -1.0f : 0.0f, line_length);
}
imgui.end();
@ -1310,18 +1321,6 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result)
log_memory_used(label, vertices_size + indices_size);
};
// format data into the buffers to be rendered as points
auto add_vertices_as_point = [](const GCodeProcessorResult::MoveVertex& curr, VertexBuffer& vertices) {
vertices.push_back(curr.position.x());
vertices.push_back(curr.position.y());
vertices.push_back(curr.position.z());
};
auto add_indices_as_point = [](const GCodeProcessorResult::MoveVertex& curr, TBuffer& buffer,
unsigned int ibuffer_id, IndexBuffer& indices, size_t move_id) {
buffer.add_path(curr, ibuffer_id, indices.size(), move_id);
indices.push_back(static_cast<IBufferType>(indices.size()));
};
// format data into the buffers to be rendered as lines
auto add_vertices_as_line = [](const GCodeProcessorResult::MoveVertex& prev, const GCodeProcessorResult::MoveVertex& curr, VertexBuffer& vertices) {
#if !ENABLE_GL_SHADERS_ATTRIBUTES
@ -1816,7 +1815,6 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result)
switch (t_buffer.render_primitive_type)
{
case TBuffer::ERenderPrimitiveType::Point: { add_vertices_as_point(curr, v_buffer); break; }
case TBuffer::ERenderPrimitiveType::Line: { add_vertices_as_line(prev, curr, v_buffer); break; }
#if ENABLE_VOLUMETRIC_RATE_TOOLPATHS_RECALC
case TBuffer::ERenderPrimitiveType::Triangle: { add_vertices_as_solid(prev, curr, t_buffer, static_cast<unsigned int>(v_multibuffer.size()) - 1, v_buffer, move_id, account_for_volumetric_rate); break; }
@ -2152,8 +2150,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result)
if (i_multibuffer.back().size() * sizeof(IBufferType) >= IBUFFER_THRESHOLD_BYTES - indiced_size_to_add) {
i_multibuffer.push_back(IndexBuffer());
vbo_index_list.push_back(t_buffer.vertices.vbos[curr_vertex_buffer.first]);
if (t_buffer.render_primitive_type != TBuffer::ERenderPrimitiveType::Point &&
t_buffer.render_primitive_type != TBuffer::ERenderPrimitiveType::BatchedModel) {
if (t_buffer.render_primitive_type != TBuffer::ERenderPrimitiveType::BatchedModel) {
Path& last_path = t_buffer.paths.back();
last_path.add_sub_path(prev, static_cast<unsigned int>(i_multibuffer.size()) - 1, 0, move_id - 1);
}
@ -2169,8 +2166,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result)
curr_vertex_buffer.second = 0;
vbo_index_list.push_back(t_buffer.vertices.vbos[curr_vertex_buffer.first]);
if (t_buffer.render_primitive_type != TBuffer::ERenderPrimitiveType::Point &&
t_buffer.render_primitive_type != TBuffer::ERenderPrimitiveType::BatchedModel) {
if (t_buffer.render_primitive_type != TBuffer::ERenderPrimitiveType::BatchedModel) {
Path& last_path = t_buffer.paths.back();
last_path.add_sub_path(prev, static_cast<unsigned int>(i_multibuffer.size()) - 1, 0, move_id - 1);
}
@ -2180,11 +2176,6 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result)
switch (t_buffer.render_primitive_type)
{
case TBuffer::ERenderPrimitiveType::Point: {
add_indices_as_point(curr, t_buffer, static_cast<unsigned int>(i_multibuffer.size()) - 1, i_buffer, move_id);
curr_vertex_buffer.second += t_buffer.max_vertices_per_segment();
break;
}
case TBuffer::ERenderPrimitiveType::Line: {
#if ENABLE_VOLUMETRIC_RATE_TOOLPATHS_RECALC
add_indices_as_line(prev, curr, t_buffer, static_cast<unsigned int>(i_multibuffer.size()) - 1, i_buffer, move_id, account_for_volumetric_rate);
@ -2732,10 +2723,6 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool
unsigned int size_in_indices = 0;
switch (buffer.render_primitive_type)
{
case TBuffer::ERenderPrimitiveType::Point: {
size_in_indices = buffer.indices_per_segment();
break;
}
case TBuffer::ERenderPrimitiveType::Line:
case TBuffer::ERenderPrimitiveType::Triangle: {
unsigned int segments_count = std::min(m_sequential_view.current.last, sub_path.last.s_id) - std::max(m_sequential_view.current.first, sub_path.first.s_id);
@ -2968,56 +2955,11 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool
void GCodeViewer::render_toolpaths()
{
#if ENABLE_FIXED_SCREEN_SIZE_POINT_MARKERS
const float point_size = 20.0f;
#else
const float point_size = 0.8f;
#endif // ENABLE_FIXED_SCREEN_SIZE_POINT_MARKERS
#if !ENABLE_GL_SHADERS_ATTRIBUTES
const std::array<float, 4> light_intensity = { 0.25f, 0.70f, 0.75f, 0.75f };
#endif // !ENABLE_GL_SHADERS_ATTRIBUTES
const Camera& camera = wxGetApp().plater()->get_camera();
const double zoom = camera.get_zoom();
const std::array<int, 4>& viewport = camera.get_viewport();
const float near_plane_height = camera.get_type() == Camera::EType::Perspective ? static_cast<float>(viewport[3]) / (2.0f * static_cast<float>(2.0 * std::tan(0.5 * Geometry::deg2rad(camera.get_fov())))) :
static_cast<float>(viewport[3]) * 0.0005;
auto shader_init_as_points = [zoom, point_size, near_plane_height](GLShaderProgram& shader) {
#if ENABLE_FIXED_SCREEN_SIZE_POINT_MARKERS
shader.set_uniform("use_fixed_screen_size", 1);
#else
shader.set_uniform("use_fixed_screen_size", 0);
#endif // ENABLE_FIXED_SCREEN_SIZE_POINT_MARKERS
shader.set_uniform("zoom", zoom);
shader.set_uniform("percent_outline_radius", 0.0f);
shader.set_uniform("percent_center_radius", 0.33f);
shader.set_uniform("point_size", point_size);
shader.set_uniform("near_plane_height", near_plane_height);
};
auto render_as_points = [
#if ENABLE_GCODE_VIEWER_STATISTICS
this
#endif // ENABLE_GCODE_VIEWER_STATISTICS
](std::vector<RenderPath>::iterator it_path, std::vector<RenderPath>::iterator it_end, GLShaderProgram& shader, int uniform_color) {
glsafe(::glEnable(GL_VERTEX_PROGRAM_POINT_SIZE));
glsafe(::glEnable(GL_POINT_SPRITE));
for (auto it = it_path; it != it_end && it_path->ibuffer_id == it->ibuffer_id; ++it) {
const RenderPath& path = *it;
// Some OpenGL drivers crash on empty glMultiDrawElements, see GH #7415.
assert(! path.sizes.empty());
assert(! path.offsets.empty());
shader.set_uniform(uniform_color, path.color);
glsafe(::glMultiDrawElements(GL_POINTS, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_SHORT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size()));
#if ENABLE_GCODE_VIEWER_STATISTICS
++m_statistics.gl_multi_points_calls_count;
#endif // ENABLE_GCODE_VIEWER_STATISTICS
}
glsafe(::glDisable(GL_POINT_SPRITE));
glsafe(::glDisable(GL_VERTEX_PROGRAM_POINT_SIZE));
};
#if !ENABLE_GL_SHADERS_ATTRIBUTES
auto shader_init_as_lines = [light_intensity](GLShaderProgram &shader) {
@ -3194,15 +3136,10 @@ void GCodeViewer::render_toolpaths()
shader->start_using();
#if ENABLE_GL_SHADERS_ATTRIBUTES
int position_id = -1;
int normal_id = -1;
const Transform3d& view_matrix = camera.get_view_matrix();
shader->set_uniform("view_model_matrix", view_matrix);
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
shader->set_uniform("normal_matrix", (Matrix3d)view_matrix.matrix().block(0, 0, 3, 3).inverse().transpose());
position_id = shader->get_attrib_location("v_position");
normal_id = shader->get_attrib_location("v_normal");
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::InstancedModel) {
@ -3213,6 +3150,8 @@ void GCodeViewer::render_toolpaths()
else if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::BatchedModel) {
shader->set_uniform("emission_factor", 0.25f);
#if ENABLE_GL_SHADERS_ATTRIBUTES
const int position_id = shader->get_attrib_location("v_position");
const int normal_id = shader->get_attrib_location("v_normal");
render_as_batched_model(buffer, *shader, position_id, normal_id);
#else
render_as_batched_model(buffer, *shader);
@ -3221,8 +3160,8 @@ void GCodeViewer::render_toolpaths()
}
else {
#if ENABLE_GL_SHADERS_ATTRIBUTES
if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::Point)
shader_init_as_points(*shader);
const int position_id = shader->get_attrib_location("v_position");
const int normal_id = shader->get_attrib_location("v_normal");
#else
switch (buffer.render_primitive_type) {
case TBuffer::ERenderPrimitiveType::Point: shader_init_as_points(*shader); break;
@ -3269,10 +3208,6 @@ void GCodeViewer::render_toolpaths()
// Render all elements with it_path->ibuffer_id == ibuffer_id, possible with varying colors.
switch (buffer.render_primitive_type)
{
case TBuffer::ERenderPrimitiveType::Point: {
render_as_points(it_path, buffer.render_paths.end(), *shader, uniform_color);
break;
}
case TBuffer::ERenderPrimitiveType::Line: {
glsafe(::glLineWidth(static_cast<GLfloat>(line_width(zoom))));
render_as_lines(it_path, buffer.render_paths.end(), *shader, uniform_color);
@ -3306,9 +3241,9 @@ void GCodeViewer::render_toolpaths()
}
#if ENABLE_GCODE_VIEWER_STATISTICS
auto render_sequential_range_cap = [this]
auto render_sequential_range_cap = [this, &camera]
#else
auto render_sequential_range_cap = []
auto render_sequential_range_cap = [&camera]
#endif // ENABLE_GCODE_VIEWER_STATISTICS
(const SequentialRangeCap& cap) {
const TBuffer* buffer = cap.buffer;
@ -3319,16 +3254,13 @@ void GCodeViewer::render_toolpaths()
shader->start_using();
#if ENABLE_GL_SHADERS_ATTRIBUTES
int position_id = -1;
int normal_id = -1;
const Camera& camera = wxGetApp().plater()->get_camera();
const Transform3d& view_matrix = camera.get_view_matrix();
shader->set_uniform("view_model_matrix", view_matrix);
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
shader->set_uniform("normal_matrix", (Matrix3d)view_matrix.matrix().block(0, 0, 3, 3).inverse().transpose());
position_id = shader->get_attrib_location("v_position");
normal_id = shader->get_attrib_location("v_normal");
const int position_id = shader->get_attrib_location("v_position");
const int normal_id = shader->get_attrib_location("v_normal");
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, cap.vbo));
@ -4682,7 +4614,6 @@ void GCodeViewer::render_statistics()
}
if (ImGui::CollapsingHeader("OpenGL calls")) {
add_counter(std::string("Multi GL_POINTS:"), m_statistics.gl_multi_points_calls_count);
add_counter(std::string("Multi GL_LINES:"), m_statistics.gl_multi_lines_calls_count);
add_counter(std::string("Multi GL_TRIANGLES:"), m_statistics.gl_multi_triangles_calls_count);
add_counter(std::string("GL_TRIANGLES:"), m_statistics.gl_triangles_calls_count);

View file

@ -284,7 +284,6 @@ class GCodeViewer
{
enum class ERenderPrimitiveType : unsigned char
{
Point,
Line,
Triangle,
InstancedModel,
@ -325,7 +324,6 @@ class GCodeViewer
unsigned int max_vertices_per_segment() const {
switch (render_primitive_type)
{
case ERenderPrimitiveType::Point: { return 1; }
case ERenderPrimitiveType::Line: { return 2; }
case ERenderPrimitiveType::Triangle: { return 8; }
default: { return 0; }
@ -337,7 +335,6 @@ class GCodeViewer
unsigned int indices_per_segment() const {
switch (render_primitive_type)
{
case ERenderPrimitiveType::Point: { return 1; }
case ERenderPrimitiveType::Line: { return 2; }
case ERenderPrimitiveType::Triangle: { return 30; } // 3 indices x 10 triangles
default: { return 0; }
@ -347,7 +344,6 @@ class GCodeViewer
unsigned int max_indices_per_segment() const {
switch (render_primitive_type)
{
case ERenderPrimitiveType::Point: { return 1; }
case ERenderPrimitiveType::Line: { return 2; }
case ERenderPrimitiveType::Triangle: { return 36; } // 3 indices x 12 triangles
default: { return 0; }
@ -358,7 +354,6 @@ class GCodeViewer
bool has_data() const {
switch (render_primitive_type)
{
case ERenderPrimitiveType::Point:
case ERenderPrimitiveType::Line:
case ERenderPrimitiveType::Triangle: {
return !vertices.vbos.empty() && vertices.vbos.front() != 0 && !indices.empty() && indices.front().ibo != 0;
@ -585,7 +580,6 @@ class GCodeViewer
int64_t refresh_time{ 0 };
int64_t refresh_paths_time{ 0 };
// opengl calls
int64_t gl_multi_points_calls_count{ 0 };
int64_t gl_multi_lines_calls_count{ 0 };
int64_t gl_multi_triangles_calls_count{ 0 };
int64_t gl_triangles_calls_count{ 0 };
@ -628,7 +622,6 @@ class GCodeViewer
}
void reset_opengl() {
gl_multi_points_calls_count = 0;
gl_multi_lines_calls_count = 0;
gl_multi_triangles_calls_count = 0;
gl_triangles_calls_count = 0;

View file

@ -1667,6 +1667,10 @@ void GLCanvas3D::render()
wxGetApp().plater()->init_environment_texture();
#endif // ENABLE_ENVIRONMENT_MAP
#if ENABLE_GLMODEL_STATISTICS
GLModel::reset_statistics_counters();
#endif // ENABLE_GLMODEL_STATISTICS
const Size& cnv_size = get_canvas_size();
// Probably due to different order of events on Linux/GTK2, when one switched from 3D scene
// to preview, this was called before canvas had its final size. It reported zero width
@ -1692,13 +1696,17 @@ void GLCanvas3D::render()
wxGetApp().imgui()->new_frame();
if (m_picking_enabled) {
if (m_rectangle_selection.is_dragging())
// picking pass using rectangle selection
_rectangular_selection_picking_pass();
else if (!m_volumes.empty())
// regular picking pass
_picking_pass();
}
#if ENABLE_NEW_RECTANGLE_SELECTION
if (m_rectangle_selection.is_dragging() && !m_rectangle_selection.is_empty())
#else
if (m_rectangle_selection.is_dragging())
#endif // ENABLE_NEW_RECTANGLE_SELECTION
// picking pass using rectangle selection
_rectangular_selection_picking_pass();
else if (!m_volumes.empty())
// regular picking pass
_picking_pass();
}
#if ENABLE_RENDER_PICKING_PASS
if (!m_picking_enabled || !m_show_picking_texture) {
@ -1776,6 +1784,9 @@ void GLCanvas3D::render()
#if ENABLE_CAMERA_STATISTICS
camera.debug_render();
#endif // ENABLE_CAMERA_STATISTICS
#if ENABLE_GLMODEL_STATISTICS
GLModel::render_statistics();
#endif // ENABLE_GLMODEL_STATISTICS
std::string tooltip;
@ -2917,8 +2928,7 @@ void GLCanvas3D::on_key(wxKeyEvent& evt)
if (imgui->update_key_data(evt)) {
render();
}
else
{
else {
if (!m_gizmos.on_key(evt)) {
if (evt.GetEventType() == wxEVT_KEY_UP) {
if (evt.ShiftDown() && evt.ControlDown() && keyCode == WXK_SPACE) {
@ -2941,8 +2951,13 @@ void GLCanvas3D::on_key(wxKeyEvent& evt)
_update_selection_from_hover();
m_rectangle_selection.stop_dragging();
m_mouse.ignore_left_up = true;
#if !ENABLE_NEW_RECTANGLE_SELECTION
m_dirty = true;
#endif // !ENABLE_NEW_RECTANGLE_SELECTION
}
#if ENABLE_NEW_RECTANGLE_SELECTION
m_dirty = true;
#endif // ENABLE_NEW_RECTANGLE_SELECTION
// set_cursor(Standard);
}
else if (keyCode == WXK_ALT) {
@ -2954,8 +2969,17 @@ void GLCanvas3D::on_key(wxKeyEvent& evt)
}
// set_cursor(Standard);
}
else if (keyCode == WXK_CONTROL)
else if (keyCode == WXK_CONTROL) {
#if ENABLE_NEW_CAMERA_MOVEMENTS
if (m_mouse.dragging) {
// if the user releases CTRL while rotating the 3D scene
// prevent from moving the selected volume
m_mouse.drag.move_volume_idx = -1;
m_mouse.set_start_position_3D_as_invalid();
}
#endif // ENABLE_NEW_CAMERA_MOVEMENTS
m_dirty = true;
}
else if (m_gizmos.is_enabled() && !m_selection.is_empty()) {
translationProcessor.process(evt);
@ -2986,15 +3010,16 @@ void GLCanvas3D::on_key(wxKeyEvent& evt)
if (keyCode == WXK_SHIFT) {
translationProcessor.process(evt);
if (m_picking_enabled && (m_gizmos.get_current_type() != GLGizmosManager::SlaSupports))
{
if (m_picking_enabled && (m_gizmos.get_current_type() != GLGizmosManager::SlaSupports)) {
m_mouse.ignore_left_up = false;
// set_cursor(Cross);
}
#if ENABLE_NEW_RECTANGLE_SELECTION
m_dirty = true;
#endif // ENABLE_NEW_RECTANGLE_SELECTION
}
else if (keyCode == WXK_ALT) {
if (m_picking_enabled && (m_gizmos.get_current_type() != GLGizmosManager::SlaSupports))
{
if (m_picking_enabled && (m_gizmos.get_current_type() != GLGizmosManager::SlaSupports)) {
m_mouse.ignore_left_up = false;
// set_cursor(Cross);
}
@ -3413,6 +3438,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
m_layers_editing.state = LayersEditing::Editing;
_perform_layer_editing_action(&evt);
}
#if !ENABLE_NEW_RECTANGLE_SELECTION
else if (evt.LeftDown() && (evt.ShiftDown() || evt.AltDown()) && m_picking_enabled) {
if (m_gizmos.get_current_type() != GLGizmosManager::SlaSupports
&& m_gizmos.get_current_type() != GLGizmosManager::FdmSupports
@ -3422,23 +3448,52 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
m_dirty = true;
}
}
#endif // !ENABLE_NEW_RECTANGLE_SELECTION
else {
#if ENABLE_NEW_RECTANGLE_SELECTION
if (evt.LeftDown() && (evt.ShiftDown() || evt.AltDown()) && m_picking_enabled) {
if (m_gizmos.get_current_type() != GLGizmosManager::SlaSupports &&
m_gizmos.get_current_type() != GLGizmosManager::FdmSupports &&
m_gizmos.get_current_type() != GLGizmosManager::Seam &&
m_gizmos.get_current_type() != GLGizmosManager::MmuSegmentation) {
m_rectangle_selection.start_dragging(m_mouse.position, evt.ShiftDown() ? GLSelectionRectangle::EState::Select : GLSelectionRectangle::EState::Deselect);
m_dirty = true;
}
}
#endif // ENABLE_NEW_RECTANGLE_SELECTION
// Select volume in this 3D canvas.
// Don't deselect a volume if layer editing is enabled or any gizmo is active. We want the object to stay selected
// during the scene manipulation.
#if ENABLE_NEW_RECTANGLE_SELECTION
if (m_picking_enabled && (!any_gizmo_active || !evt.ShiftDown()) && (!m_hover_volume_idxs.empty() || !is_layers_editing_enabled()) &&
!m_rectangle_selection.is_dragging()) {
#else
if (m_picking_enabled && (!any_gizmo_active || !evt.CmdDown()) && (!m_hover_volume_idxs.empty() || !is_layers_editing_enabled())) {
#endif // ENABLE_NEW_RECTANGLE_SELECTION
if (evt.LeftDown() && !m_hover_volume_idxs.empty()) {
int volume_idx = get_first_hover_volume_idx();
bool already_selected = m_selection.contains_volume(volume_idx);
#if ENABLE_NEW_RECTANGLE_SELECTION
bool shift_down = evt.ShiftDown();
#else
bool ctrl_down = evt.CmdDown();
#endif // ENABLE_NEW_RECTANGLE_SELECTION
Selection::IndicesList curr_idxs = m_selection.get_volume_idxs();
#if ENABLE_NEW_RECTANGLE_SELECTION
if (already_selected && shift_down)
m_selection.remove(volume_idx);
else {
m_selection.add(volume_idx, !shift_down, true);
#else
if (already_selected && ctrl_down)
m_selection.remove(volume_idx);
else {
m_selection.add(volume_idx, !ctrl_down, true);
#endif // ENABLE_NEW_RECTANGLE_SELECTION
m_mouse.drag.move_requires_threshold = !already_selected;
if (already_selected)
m_mouse.set_move_start_threshold_position_2D_as_invalid();
@ -3460,18 +3515,25 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
}
}
#if ENABLE_NEW_RECTANGLE_SELECTION
if (!m_hover_volume_idxs.empty() && !m_rectangle_selection.is_dragging()) {
#else
if (!m_hover_volume_idxs.empty()) {
#endif // ENABLE_NEW_RECTANGLE_SELECTION
if (evt.LeftDown() && m_moving_enabled && m_mouse.drag.move_volume_idx == -1) {
// Only accept the initial position, if it is inside the volume bounding box.
int volume_idx = get_first_hover_volume_idx();
const int volume_idx = get_first_hover_volume_idx();
BoundingBoxf3 volume_bbox = m_volumes.volumes[volume_idx]->transformed_bounding_box();
volume_bbox.offset(1.0);
if ((!any_gizmo_active || !evt.CmdDown()) && volume_bbox.contains(m_mouse.scene_position)) {
m_volumes.volumes[volume_idx]->hover = GLVolume::HS_None;
// The dragging operation is initiated.
m_mouse.drag.move_volume_idx = volume_idx;
#if ENABLE_NEW_CAMERA_MOVEMENTS
m_selection.setup_cache();
m_mouse.drag.start_position_3D = m_mouse.scene_position;
if (!evt.CmdDown())
#endif // ENABLE_NEW_CAMERA_MOVEMENTS
m_mouse.drag.start_position_3D = m_mouse.scene_position;
m_sequential_print_clearance_first_displacement = true;
m_moving = true;
}
@ -3479,31 +3541,36 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
}
}
}
#if ENABLE_NEW_CAMERA_MOVEMENTS
else if (evt.Dragging() && evt.LeftIsDown() && !evt.CmdDown() && m_layers_editing.state == LayersEditing::Unknown &&
m_mouse.drag.move_volume_idx != -1 && m_mouse.is_start_position_3D_defined()) {
#else
else if (evt.Dragging() && evt.LeftIsDown() && m_layers_editing.state == LayersEditing::Unknown && m_mouse.drag.move_volume_idx != -1) {
if (!m_mouse.drag.move_requires_threshold) {
#endif // ENABLE_NEW_CAMERA_MOVEMENTS
if (!m_mouse.drag.move_requires_threshold) {
m_mouse.dragging = true;
Vec3d cur_pos = m_mouse.drag.start_position_3D;
// we do not want to translate objects if the user just clicked on an object while pressing shift to remove it from the selection and then drag
if (m_selection.contains_volume(get_first_hover_volume_idx())) {
const Camera& camera = wxGetApp().plater()->get_camera();
if (std::abs(camera.get_dir_forward()(2)) < EPSILON) {
if (std::abs(camera.get_dir_forward().z()) < EPSILON) {
// side view -> move selected volumes orthogonally to camera view direction
Linef3 ray = mouse_ray(pos);
Vec3d dir = ray.unit_vector();
const Linef3 ray = mouse_ray(pos);
const Vec3d dir = ray.unit_vector();
// finds the intersection of the mouse ray with the plane parallel to the camera viewport and passing throught the starting position
// use ray-plane intersection see i.e. https://en.wikipedia.org/wiki/Line%E2%80%93plane_intersection algebric form
// in our case plane normal and ray direction are the same (orthogonal view)
// when moving to perspective camera the negative z unit axis of the camera needs to be transformed in world space and used as plane normal
Vec3d inters = ray.a + (m_mouse.drag.start_position_3D - ray.a).dot(dir) / dir.squaredNorm() * dir;
const Vec3d inters = ray.a + (m_mouse.drag.start_position_3D - ray.a).dot(dir) / dir.squaredNorm() * dir;
// vector from the starting position to the found intersection
Vec3d inters_vec = inters - m_mouse.drag.start_position_3D;
const Vec3d inters_vec = inters - m_mouse.drag.start_position_3D;
Vec3d camera_right = camera.get_dir_right();
Vec3d camera_up = camera.get_dir_up();
const Vec3d camera_right = camera.get_dir_right();
const Vec3d camera_up = camera.get_dir_up();
// finds projection of the vector along the camera axes
double projection_x = inters_vec.dot(camera_right);
double projection_z = inters_vec.dot(camera_up);
const double projection_x = inters_vec.dot(camera_right);
const double projection_z = inters_vec.dot(camera_up);
// apply offset
cur_pos = m_mouse.drag.start_position_3D + projection_x * camera_right + projection_z * camera_up;
@ -3513,7 +3580,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
// Get new position at the same Z of the initial click point.
float z0 = 0.0f;
float z1 = 1.0f;
cur_pos = Linef3(_mouse_to_3d(pos, &z0), _mouse_to_3d(pos, &z1)).intersect_plane(m_mouse.drag.start_position_3D(2));
cur_pos = Linef3(_mouse_to_3d(pos, &z0), _mouse_to_3d(pos, &z1)).intersect_plane(m_mouse.drag.start_position_3D.z());
}
}
@ -3525,7 +3592,13 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
}
}
else if (evt.Dragging() && evt.LeftIsDown() && m_picking_enabled && m_rectangle_selection.is_dragging()) {
#if ENABLE_NEW_RECTANGLE_SELECTION
// keeps the mouse position updated while dragging the selection rectangle
m_mouse.position = pos.cast<double>();
m_rectangle_selection.dragging(m_mouse.position);
#else
m_rectangle_selection.dragging(pos.cast<double>());
#endif // ENABLE_NEW_RECTANGLE_SELECTION
m_dirty = true;
}
else if (evt.Dragging()) {
@ -3538,13 +3611,19 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
}
}
// do not process the dragging if the left mouse was set down in another canvas
else if (evt.LeftIsDown()) {
#if ENABLE_NEW_CAMERA_MOVEMENTS
else if (evt.LeftIsDown() || evt.MiddleIsDown()) {
// if dragging over blank area with left button, rotate
if ((any_gizmo_active || evt.CmdDown() || evt.MiddleIsDown() || m_hover_volume_idxs.empty()) && m_mouse.is_start_position_3D_defined()) {
#else
// if dragging over blank area with left button, rotate
else if (evt.LeftIsDown()) {
if ((any_gizmo_active || m_hover_volume_idxs.empty()) && m_mouse.is_start_position_3D_defined()) {
const Vec3d rot = (Vec3d(pos.x(), pos.y(), 0.) - m_mouse.drag.start_position_3D) * (PI * TRACKBALLSIZE / 180.);
#endif // ENABLE_NEW_CAMERA_MOVEMENTS
const Vec3d rot = (Vec3d(pos.x(), pos.y(), 0.0) - m_mouse.drag.start_position_3D) * (PI * TRACKBALLSIZE / 180.0);
if (wxGetApp().app_config->get("use_free_camera") == "1")
// Virtual track ball (similar to the 3DConnexion mouse).
wxGetApp().plater()->get_camera().rotate_local_around_target(Vec3d(rot.y(), rot.x(), 0.));
wxGetApp().plater()->get_camera().rotate_local_around_target(Vec3d(rot.y(), rot.x(), 0.0));
else {
// Forces camera right vector to be parallel to XY plane in case it has been misaligned using the 3D mouse free rotation.
// It is cheaper to call this function right away instead of testing wxGetApp().plater()->get_mouse3d_controller().connected(),
@ -3557,15 +3636,20 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
m_dirty = true;
}
m_mouse.drag.start_position_3D = Vec3d((double)pos(0), (double)pos(1), 0.0);
m_mouse.drag.start_position_3D = Vec3d((double)pos.x(), (double)pos.y(), 0.0);
}
#if ENABLE_NEW_CAMERA_MOVEMENTS
else if (evt.RightIsDown()) {
// If dragging with right button, pan.
#else
else if (evt.MiddleIsDown() || evt.RightIsDown()) {
// If dragging over blank area with right button, pan.
#endif // ENABLE_NEW_CAMERA_MOVEMENTS
if (m_mouse.is_start_position_2D_defined()) {
// get point in model space at Z = 0
float z = 0.0f;
const Vec3d& cur_pos = _mouse_to_3d(pos, &z);
Vec3d orig = _mouse_to_3d(m_mouse.drag.start_position_2D, &z);
const Vec3d orig = _mouse_to_3d(m_mouse.drag.start_position_2D, &z);
Camera& camera = wxGetApp().plater()->get_camera();
if (wxGetApp().app_config->get("use_free_camera") != "1")
// Forces camera right vector to be parallel to XY plane in case it has been misaligned using the 3D mouse free rotation.
@ -3638,7 +3722,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
if (!m_mouse.dragging) {
// do not post the event if the user is panning the scene
// or if right click was done over the wipe tower
bool post_right_click_event = m_hover_volume_idxs.empty() || !m_volumes.volumes[get_first_hover_volume_idx()]->is_wipe_tower;
const bool post_right_click_event = m_hover_volume_idxs.empty() || !m_volumes.volumes[get_first_hover_volume_idx()]->is_wipe_tower;
if (post_right_click_event)
post_event(RBtnEvent(EVT_GLCANVAS_RIGHT_CLICK, { logical_pos, m_hover_volume_idxs.empty() }));
}
@ -6331,7 +6415,9 @@ void GLCanvas3D::_update_volumes_hover_state()
return;
}
#if !ENABLE_NEW_RECTANGLE_SELECTION
bool selection_modifiers_only = m_selection.is_empty() || m_selection.is_any_modifier();
#endif // !ENABLE_NEW_RECTANGLE_SELECTION
bool hover_modifiers_only = true;
for (int i : m_hover_volume_idxs) {
@ -6360,9 +6446,14 @@ void GLCanvas3D::_update_volumes_hover_state()
if (volume.hover != GLVolume::HS_None)
continue;
#if ENABLE_NEW_RECTANGLE_SELECTION
bool deselect = volume.selected && ((shift_pressed && m_rectangle_selection.is_empty()) || (alt_pressed && !m_rectangle_selection.is_empty()));
bool select = !volume.selected && (m_rectangle_selection.is_empty() || (shift_pressed && !m_rectangle_selection.is_empty()));
#else
bool deselect = volume.selected && ((ctrl_pressed && !shift_pressed) || alt_pressed);
// (volume->is_modifier && !selection_modifiers_only && !is_ctrl_pressed) -> allows hovering on selected modifiers belonging to selection of type Instance
bool select = (!volume.selected || (volume.is_modifier && !selection_modifiers_only && !ctrl_pressed)) && !alt_pressed;
#endif // ENABLE_NEW_RECTANGLE_SELECTION
if (select || deselect) {
bool as_volume =
@ -7280,7 +7371,7 @@ void GLCanvas3D::_update_selection_from_hover()
bool ctrl_pressed = wxGetKeyState(WXK_CONTROL);
if (m_hover_volume_idxs.empty()) {
if (!ctrl_pressed && (m_rectangle_selection.get_state() == GLSelectionRectangle::Select))
if (!ctrl_pressed && m_rectangle_selection.get_state() == GLSelectionRectangle::EState::Select)
m_selection.remove_all();
return;
@ -7297,7 +7388,10 @@ void GLCanvas3D::_update_selection_from_hover()
}
bool selection_changed = false;
if (state == GLSelectionRectangle::Select) {
#if ENABLE_NEW_RECTANGLE_SELECTION
if (!m_rectangle_selection.is_empty()) {
#endif // ENABLE_NEW_RECTANGLE_SELECTION
if (state == GLSelectionRectangle::EState::Select) {
bool contains_all = true;
for (int i : m_hover_volume_idxs) {
if (!m_selection.contains_volume((unsigned int)i)) {
@ -7308,7 +7402,7 @@ void GLCanvas3D::_update_selection_from_hover()
// the selection is going to be modified (Add)
if (!contains_all) {
wxGetApp().plater()->take_snapshot(_(L("Selection-Add from rectangle")), UndoRedo::SnapshotType::Selection);
wxGetApp().plater()->take_snapshot(_L("Selection-Add from rectangle"), UndoRedo::SnapshotType::Selection);
selection_changed = true;
}
}
@ -7323,21 +7417,24 @@ void GLCanvas3D::_update_selection_from_hover()
// the selection is going to be modified (Remove)
if (contains_any) {
wxGetApp().plater()->take_snapshot(_(L("Selection-Remove from rectangle")), UndoRedo::SnapshotType::Selection);
wxGetApp().plater()->take_snapshot(_L("Selection-Remove from rectangle"), UndoRedo::SnapshotType::Selection);
selection_changed = true;
}
}
#if ENABLE_NEW_RECTANGLE_SELECTION
}
#endif // ENABLE_NEW_RECTANGLE_SELECTION
if (!selection_changed)
return;
Plater::SuppressSnapshots suppress(wxGetApp().plater());
if ((state == GLSelectionRectangle::Select) && !ctrl_pressed)
if (state == GLSelectionRectangle::EState::Select && !ctrl_pressed)
m_selection.clear();
for (int i : m_hover_volume_idxs) {
if (state == GLSelectionRectangle::Select) {
if (state == GLSelectionRectangle::EState::Select) {
if (hover_modifiers_only) {
const GLVolume& v = *m_volumes.volumes[i];
m_selection.add_volume(v.object_idx(), v.volume_idx(), v.instance_idx(), false);

View file

@ -4,6 +4,10 @@
#include "3DScene.hpp"
#include "GUI_App.hpp"
#include "GLShader.hpp"
#if ENABLE_GLMODEL_STATISTICS
#include "Plater.hpp"
#include "GLCanvas3D.hpp"
#endif // ENABLE_GLMODEL_STATISTICS
#include "libslic3r/TriangleMesh.hpp"
#include "libslic3r/Model.hpp"
@ -13,6 +17,10 @@
#include "libslic3r/Geometry/ConvexHull.hpp"
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_GLMODEL_STATISTICS
#include <imgui/imgui_internal.h>
#endif // ENABLE_GLMODEL_STATISTICS
#include <boost/filesystem/operations.hpp>
#include <boost/algorithm/string/predicate.hpp>
@ -380,6 +388,10 @@ size_t GLModel::Geometry::indices_count() const
}
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_GLMODEL_STATISTICS
GLModel::Statistics GLModel::s_statistics;
#endif // ENABLE_GLMODEL_STATISTICS
#if ENABLE_LEGACY_OPENGL_REMOVAL
void GLModel::init_from(Geometry&& data)
#else
@ -702,10 +714,16 @@ void GLModel::reset()
if (m_render_data.ibo_id > 0) {
glsafe(::glDeleteBuffers(1, &m_render_data.ibo_id));
m_render_data.ibo_id = 0;
#if ENABLE_GLMODEL_STATISTICS
s_statistics.gpu_memory.indices.current -= indices_size_bytes();
#endif // ENABLE_GLMODEL_STATISTICS
}
if (m_render_data.vbo_id > 0) {
glsafe(::glDeleteBuffers(1, &m_render_data.vbo_id));
m_render_data.vbo_id = 0;
#if ENABLE_GLMODEL_STATISTICS
s_statistics.gpu_memory.vertices.current -= vertices_size_bytes();
#endif // ENABLE_GLMODEL_STATISTICS
}
m_render_data.vertices_count = 0;
@ -899,6 +917,10 @@ void GLModel::render(const std::pair<size_t, size_t>& range)
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
#if ENABLE_GLMODEL_STATISTICS
++s_statistics.render_calls;
#endif // ENABLE_GLMODEL_STATISTICS
}
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
@ -1054,6 +1076,10 @@ void GLModel::render_instanced(unsigned int instances_vbo, unsigned int instance
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
#if ENABLE_GLMODEL_STATISTICS
++s_statistics.render_instanced_calls;
#endif // ENABLE_GLMODEL_STATISTICS
}
#if ENABLE_LEGACY_OPENGL_REMOVAL
@ -1076,6 +1102,10 @@ bool GLModel::send_to_gpu()
glsafe(::glBufferData(GL_ARRAY_BUFFER, data.vertices_size_bytes(), data.vertices.data(), GL_STATIC_DRAW));
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
m_render_data.vertices_count = vertices_count();
#if ENABLE_GLMODEL_STATISTICS
s_statistics.gpu_memory.vertices.current += data.vertices_size_bytes();
s_statistics.gpu_memory.vertices.max = std::max(s_statistics.gpu_memory.vertices.current, s_statistics.gpu_memory.vertices.max);
#endif // ENABLE_GLMODEL_STATISTICS
data.vertices = std::vector<float>();
// indices
@ -1107,10 +1137,75 @@ bool GLModel::send_to_gpu()
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
}
m_render_data.indices_count = indices_count;
#if ENABLE_GLMODEL_STATISTICS
s_statistics.gpu_memory.indices.current += data.indices_size_bytes();
s_statistics.gpu_memory.indices.max = std::max(s_statistics.gpu_memory.indices.current, s_statistics.gpu_memory.indices.max);
#endif // ENABLE_GLMODEL_STATISTICS
data.indices = std::vector<unsigned int>();
return true;
}
#if ENABLE_GLMODEL_STATISTICS
void GLModel::render_statistics()
{
static const float offset = 175.0f;
ImGuiWrapper& imgui = *wxGetApp().imgui();
auto add_memory = [&imgui](const std::string& label, int64_t memory) {
auto format_string = [memory](const std::string& units, float value) {
return std::to_string(memory) + " bytes (" +
Slic3r::float_to_string_decimal_point(float(memory) * value, 3)
+ " " + units + ")";
};
static const float kb = 1024.0f;
static const float inv_kb = 1.0f / kb;
static const float mb = 1024.0f * kb;
static const float inv_mb = 1.0f / mb;
static const float gb = 1024.0f * mb;
static const float inv_gb = 1.0f / gb;
imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, label);
ImGui::SameLine(offset);
if (static_cast<float>(memory) < mb)
imgui.text(format_string("KB", inv_kb));
else if (static_cast<float>(memory) < gb)
imgui.text(format_string("MB", inv_mb));
else
imgui.text(format_string("GB", inv_gb));
};
auto add_counter = [&imgui](const std::string& label, int64_t counter) {
imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, label);
ImGui::SameLine(offset);
imgui.text(std::to_string(counter));
};
imgui.set_next_window_pos(0.5f * wxGetApp().plater()->get_current_canvas3D()->get_canvas_size().get_width(), 0.0f, ImGuiCond_Once, 0.5f, 0.0f);
ImGui::SetNextWindowSizeConstraints({ 300.0f, 100.0f }, { 600.0f, 900.0f });
imgui.begin(std::string("GLModel Statistics"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize);
ImGui::BringWindowToDisplayFront(ImGui::GetCurrentWindow());
add_counter(std::string("Render calls:"), s_statistics.render_calls);
add_counter(std::string("Render instanced calls:"), s_statistics.render_instanced_calls);
if (ImGui::CollapsingHeader("GPU memory")) {
ImGui::Indent(10.0f);
if (ImGui::CollapsingHeader("Vertices")) {
add_memory(std::string("Current:"), s_statistics.gpu_memory.vertices.current);
add_memory(std::string("Max:"), s_statistics.gpu_memory.vertices.max);
}
if (ImGui::CollapsingHeader("Indices")) {
add_memory(std::string("Current:"), s_statistics.gpu_memory.indices.current);
add_memory(std::string("Max:"), s_statistics.gpu_memory.indices.max);
}
ImGui::Unindent(10.0f);
}
imgui.end();
}
#endif // ENABLE_GLMODEL_STATISTICS
#else
void GLModel::send_to_gpu(RenderData& data, const std::vector<float>& vertices, const std::vector<unsigned int>& indices)
{

View file

@ -177,6 +177,29 @@ namespace GUI {
private:
#if ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_GLMODEL_STATISTICS
struct Statistics
{
struct Buffers
{
struct Data
{
size_t current{ 0 };
size_t max{ 0 };
};
Data indices;
Data vertices;
};
Buffers gpu_memory;
int64_t render_calls{ 0 };
int64_t render_instanced_calls{ 0 };
};
static Statistics s_statistics;
#endif // ENABLE_GLMODEL_STATISTICS
RenderData m_render_data;
// By default the vertex and index buffers data are sent to gpu at the first call to render() method.
@ -272,6 +295,14 @@ namespace GUI {
ret += indices_size_bytes();
return ret;
}
#if ENABLE_GLMODEL_STATISTICS
static void render_statistics();
static void reset_statistics_counters() {
s_statistics.render_calls = 0;
s_statistics.render_instanced_calls = 0;
}
#endif // ENABLE_GLMODEL_STATISTICS
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
private:

View file

@ -13,12 +13,12 @@ namespace GUI {
void GLSelectionRectangle::start_dragging(const Vec2d& mouse_position, EState state)
{
if (is_dragging() || (state == Off))
if (is_dragging() || state == EState::Off)
return;
m_state = state;
m_start_corner = mouse_position;
m_end_corner = mouse_position;
m_end_corner = mouse_position;
}
void GLSelectionRectangle::dragging(const Vec2d& mouse_position)
@ -36,7 +36,7 @@ namespace GUI {
if (!is_dragging())
return out;
m_state = Off;
m_state = EState::Off;
const Camera& camera = wxGetApp().plater()->get_camera();
Matrix4d modelview = camera.get_view_matrix().matrix();
@ -66,7 +66,7 @@ namespace GUI {
void GLSelectionRectangle::stop_dragging()
{
if (is_dragging())
m_state = Off;
m_state = EState::Off;
}
void GLSelectionRectangle::render(const GLCanvas3D& canvas)
@ -108,8 +108,8 @@ namespace GUI {
glsafe(::glLineWidth(1.5f));
#if !ENABLE_LEGACY_OPENGL_REMOVAL
float color[3];
color[0] = (m_state == Select) ? 0.3f : 1.0f;
color[1] = (m_state == Select) ? 1.0f : 0.3f;
color[0] = (m_state == EState::Select) ? 0.3f : 1.0f;
color[1] = (m_state == EState::Select) ? 1.0f : 0.3f;
color[2] = 0.3f;
glsafe(::glColor3fv(color));
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
@ -169,7 +169,7 @@ namespace GUI {
shader->set_uniform("projection_matrix", Transform3d::Identity());
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
m_rectangle.set_color(ColorRGBA((m_state == Select) ? 0.3f : 1.0f, (m_state == Select) ? 1.0f : 0.3f, 0.3f, 1.0f));
m_rectangle.set_color(ColorRGBA((m_state == EState::Select) ? 0.3f : 1.0f, (m_state == EState::Select) ? 1.0f : 0.3f, 0.3f, 1.0f));
m_rectangle.render();
shader->stop_using();
}

View file

@ -14,7 +14,7 @@ class GLCanvas3D;
class GLSelectionRectangle {
public:
enum EState {
enum class EState {
Off,
Select,
Deselect
@ -35,7 +35,11 @@ public:
void render(const GLCanvas3D& canvas);
bool is_dragging() const { return m_state != Off; }
bool is_dragging() const { return m_state != EState::Off; }
#if ENABLE_NEW_RECTANGLE_SELECTION
bool is_empty() const { return m_state == EState::Off || m_start_corner.isApprox(m_end_corner); }
#endif // ENABLE_NEW_RECTANGLE_SELECTION
EState get_state() const { return m_state; }
float get_width() const { return std::abs(m_start_corner.x() - m_end_corner.x()); }
@ -46,7 +50,7 @@ public:
float get_bottom() const { return std::min(m_start_corner.y(), m_end_corner.y()); }
private:
EState m_state{ Off };
EState m_state{ EState::Off };
Vec2d m_start_corner{ Vec2d::Zero() };
Vec2d m_end_corner{ Vec2d::Zero() };
#if ENABLE_LEGACY_OPENGL_REMOVAL

View file

@ -122,8 +122,7 @@ bool GLShaderProgram::init_from_texts(const std::string& name, const ShaderSourc
for (size_t i = 0; i < static_cast<size_t>(EShaderType::Count); ++i) {
const std::string& source = sources[i];
if (!source.empty())
{
if (!source.empty()) {
EShaderType type = static_cast<EShaderType>(i);
auto [result, id] = create_shader(type);
if (result)
@ -303,6 +302,19 @@ void GLShaderProgram::set_uniform(int id, const Matrix3d& value) const
}
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
#if ENABLE_GL_IMGUI_SHADERS
void GLShaderProgram::set_uniform(int id, const Matrix4f& value) const
{
if (id >= 0)
glsafe(::glUniformMatrix4fv(id, 1, GL_FALSE, static_cast<const GLfloat*>(value.data())));
}
void GLShaderProgram::set_uniform(int id, const Matrix4d& value) const
{
set_uniform(id, (Matrix4f)value.cast<float>());
}
#endif // ENABLE_GL_IMGUI_SHADERS
void GLShaderProgram::set_uniform(int id, const Vec3f& value) const
{
if (id >= 0)

View file

@ -64,6 +64,10 @@ public:
#if ENABLE_GL_SHADERS_ATTRIBUTES
void set_uniform(const char* name, const Matrix3d& value) const { set_uniform(get_uniform_location(name), value); }
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
#if ENABLE_GL_IMGUI_SHADERS
void set_uniform(const char* name, const Matrix4f& value) const { set_uniform(get_uniform_location(name), value); }
void set_uniform(const char* name, const Matrix4d& value) const { set_uniform(get_uniform_location(name), value); }
#endif // ENABLE_GL_IMGUI_SHADERS
void set_uniform(const char* name, const Vec3f& value) const { set_uniform(get_uniform_location(name), value); }
void set_uniform(const char* name, const Vec3d& value) const { set_uniform(get_uniform_location(name), value); }
void set_uniform(const char* name, const ColorRGB& value) const { set_uniform(get_uniform_location(name), value); }
@ -86,6 +90,10 @@ public:
#if ENABLE_GL_SHADERS_ATTRIBUTES
void set_uniform(int id, const Matrix3d& value) const;
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
#if ENABLE_GL_IMGUI_SHADERS
void set_uniform(int id, const Matrix4f& value) const;
void set_uniform(int id, const Matrix4d& value) const;
#endif // ENABLE_GL_IMGUI_SHADERS
void set_uniform(int id, const Vec3f& value) const;
void set_uniform(int id, const Vec3d& value) const;
void set_uniform(int id, const ColorRGB& value) const;

View file

@ -35,6 +35,8 @@ std::pair<bool, std::string> GLShadersManager::init()
#if ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_GL_SHADERS_ATTRIBUTES
// imgui shader
valid &= append_shader("imgui", { "imgui.vs", "imgui.fs" });
// basic shader, used to render all what was previously rendered using the immediate mode
valid &= append_shader("flat_attr", { "flat_attr.vs", "flat.fs" });
// basic shader for textures, used to render textures

View file

@ -293,7 +293,7 @@ bool GLGizmoHollow::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_pos
if (action == SLAGizmoEventType::LeftDown && (shift_down || alt_down || control_down)) {
if (m_hover_id == -1) {
if (shift_down || alt_down) {
m_selection_rectangle.start_dragging(mouse_position, shift_down ? GLSelectionRectangle::Select : GLSelectionRectangle::Deselect);
m_selection_rectangle.start_dragging(mouse_position, shift_down ? GLSelectionRectangle::EState::Select : GLSelectionRectangle::EState::Deselect);
}
}
else {
@ -359,7 +359,7 @@ bool GLGizmoHollow::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_pos
trafo, wxGetApp().plater()->get_camera(), points_inside,
m_c->object_clipper()->get_clipping_plane()))
{
if (rectangle_status == GLSelectionRectangle::Deselect)
if (rectangle_status == GLSelectionRectangle::EState::Deselect)
unselect_point(points_idxs[idx]);
else
select_point(points_idxs[idx]);

View file

@ -600,11 +600,17 @@ void TriangleSelectorMmGui::render(ImGuiWrapper *imgui)
return;
#if ENABLE_GL_SHADERS_ATTRIBUTES
assert(shader->get_name() == "mm_gouraud_attr");
const Camera& camera = wxGetApp().plater()->get_camera();
const Transform3d view_model_matrix = camera.get_view_matrix() * matrix;
shader->set_uniform("view_model_matrix", view_model_matrix);
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
shader->set_uniform("normal_matrix", (Matrix3d)view_model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose());
#else
assert(shader->get_name() == "mm_gouraud");
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
for (size_t color_idx = 0; color_idx < m_gizmo_scene.triangle_indices.size(); ++color_idx)
for (size_t color_idx = 0; color_idx < m_gizmo_scene.triangle_indices.size(); ++color_idx) {
if (m_gizmo_scene.has_VBOs(color_idx)) {
if (color_idx > m_colors.size()) // Seed fill VBO
shader->set_uniform("uniform_color", TriangleSelectorGUI::get_seed_fill_color(color_idx == (m_colors.size() + 1) ? m_default_volume_color : m_colors[color_idx - (m_colors.size() + 1) - 1]));
@ -613,6 +619,7 @@ void TriangleSelectorMmGui::render(ImGuiWrapper *imgui)
m_gizmo_scene.render(color_idx);
}
}
#if ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_GL_SHADERS_ATTRIBUTES
@ -724,19 +731,41 @@ void GLMmSegmentationGizmo3DScene::render(size_t triangle_indices_idx) const
assert(this->vertices_VBO_id != 0);
assert(this->triangle_indices_VBO_ids[triangle_indices_idx] != 0);
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, this->vertices_VBO_id));
glsafe(::glVertexPointer(3, GL_FLOAT, 3 * sizeof(float), (const void*)(0 * sizeof(float))));
#if ENABLE_GL_SHADERS_ATTRIBUTES
GLShaderProgram* shader = wxGetApp().get_current_shader();
if (shader == nullptr)
return;
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, this->vertices_VBO_id));
#if ENABLE_GL_SHADERS_ATTRIBUTES
const GLint position_id = shader->get_attrib_location("v_position");
if (position_id != -1) {
glsafe(::glVertexAttribPointer(position_id, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (GLvoid*)0));
glsafe(::glEnableVertexAttribArray(position_id));
}
// Render using the Vertex Buffer Objects.
if (this->triangle_indices_VBO_ids[triangle_indices_idx] != 0 &&
this->triangle_indices_sizes[triangle_indices_idx] > 0) {
#else
glsafe(::glVertexPointer(3, GL_FLOAT, 3 * sizeof(float), (const void*)(0 * sizeof(float))));
glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
// Render using the Vertex Buffer Objects.
if (this->triangle_indices_sizes[triangle_indices_idx] > 0) {
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->triangle_indices_VBO_ids[triangle_indices_idx]));
glsafe(::glDrawElements(GL_TRIANGLES, GLsizei(this->triangle_indices_sizes[triangle_indices_idx]), GL_UNSIGNED_INT, nullptr));
glsafe(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
}
#if ENABLE_GL_SHADERS_ATTRIBUTES
if (position_id != -1)
glsafe(::glDisableVertexAttribArray(position_id));
#else
glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
}

View file

@ -195,8 +195,7 @@ void GLGizmoRotate::on_render()
#if ENABLE_GL_SHADERS_ATTRIBUTES
const Camera& camera = wxGetApp().plater()->get_camera();
Transform3d view_model_matrix = camera.get_view_matrix() * m_grabbers.front().matrix;
const Transform3d view_model_matrix = camera.get_view_matrix() * m_grabbers.front().matrix;
shader->set_uniform("view_model_matrix", view_model_matrix);
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
#endif // ENABLE_GL_SHADERS_ATTRIBUTES

View file

@ -419,7 +419,7 @@ bool GLGizmoSlaSupports::gizmo_event(SLAGizmoEventType action, const Vec2d& mous
if (action == SLAGizmoEventType::LeftDown && (shift_down || alt_down || control_down)) {
if (m_hover_id == -1) {
if (shift_down || alt_down) {
m_selection_rectangle.start_dragging(mouse_position, shift_down ? GLSelectionRectangle::Select : GLSelectionRectangle::Deselect);
m_selection_rectangle.start_dragging(mouse_position, shift_down ? GLSelectionRectangle::EState::Select : GLSelectionRectangle::EState::Deselect);
}
}
else {
@ -490,7 +490,7 @@ bool GLGizmoSlaSupports::gizmo_event(SLAGizmoEventType action, const Vec2d& mous
{
if (idx >= orig_pts_num) // this is a cone-base, get index of point it belongs to
idx -= orig_pts_num;
if (rectangle_status == GLSelectionRectangle::Deselect)
if (rectangle_status == GLSelectionRectangle::EState::Deselect)
unselect_point(points_idxs[idx]);
else
select_point(points_idxs[idx]);

View file

@ -26,13 +26,18 @@
#include "libslic3r/libslic3r.h"
#include "libslic3r/Utils.hpp"
#include "libslic3r/Color.hpp"
#include "3DScene.hpp"
#include "GUI.hpp"
#include "I18N.hpp"
#include "Search.hpp"
#include "BitmapCache.hpp"
#if ENABLE_GL_IMGUI_SHADERS
#include "GUI_App.hpp"
#endif // ENABLE_GL_IMGUI_SHADERS
#include "../Utils/MacDarkMode.hpp"
#include "nanosvg/nanosvg.h"
#include "nanosvg/nanosvgrast.h"
@ -1442,13 +1447,31 @@ void ImGuiWrapper::init_style()
void ImGuiWrapper::render_draw_data(ImDrawData *draw_data)
{
if (draw_data == nullptr || draw_data->CmdListsCount == 0)
return;
#if ENABLE_GL_IMGUI_SHADERS
GLShaderProgram* shader = wxGetApp().get_shader("imgui");
if (shader == nullptr)
return;
#endif // ENABLE_GL_IMGUI_SHADERS
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
ImGuiIO& io = ImGui::GetIO();
const int fb_width = (int)(draw_data->DisplaySize.x * io.DisplayFramebufferScale.x);
const int fb_width = (int)(draw_data->DisplaySize.x * io.DisplayFramebufferScale.x);
const int fb_height = (int)(draw_data->DisplaySize.y * io.DisplayFramebufferScale.y);
if (fb_width == 0 || fb_height == 0)
return;
#if ENABLE_GL_IMGUI_SHADERS
GLShaderProgram* curr_shader = wxGetApp().get_current_shader();
if (curr_shader != nullptr)
curr_shader->stop_using();
shader->start_using();
#else
draw_data->ScaleClipRects(io.DisplayFramebufferScale);
#endif // ENABLE_GL_IMGUI_SHADERS
// We are using the OpenGL fixed pipeline to make the example code simpler to read!
// Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers, polygon fill.
@ -1456,25 +1479,43 @@ void ImGuiWrapper::render_draw_data(ImDrawData *draw_data)
GLint last_polygon_mode[2]; glsafe(::glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode));
GLint last_viewport[4]; glsafe(::glGetIntegerv(GL_VIEWPORT, last_viewport));
GLint last_scissor_box[4]; glsafe(::glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box));
GLint last_texture_env_mode; glsafe(::glGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &last_texture_env_mode));
glsafe(::glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT));
glsafe(::glEnable(GL_BLEND));
glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
glsafe(::glDisable(GL_CULL_FACE));
glsafe(::glDisable(GL_DEPTH_TEST));
glsafe(::glEnable(GL_SCISSOR_TEST));
#if !ENABLE_GL_IMGUI_SHADERS
glsafe(::glDisable(GL_LIGHTING));
glsafe(::glDisable(GL_COLOR_MATERIAL));
glsafe(::glEnable(GL_SCISSOR_TEST));
glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
glsafe(::glEnableClientState(GL_TEXTURE_COORD_ARRAY));
glsafe(::glEnableClientState(GL_COLOR_ARRAY));
#endif // !ENABLE_GL_IMGUI_SHADERS
glsafe(::glEnable(GL_TEXTURE_2D));
glsafe(::glPolygonMode(GL_FRONT_AND_BACK, GL_FILL));
glsafe(::glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE));
GLint texture_env_mode = GL_MODULATE;
glsafe(::glGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &texture_env_mode));
glsafe(::glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE));
//glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context where shaders may be bound
#if ENABLE_GL_IMGUI_SHADERS
// Setup viewport, orthographic projection matrix
// Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps.
glsafe(::glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height));
const float L = draw_data->DisplayPos.x;
const float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x;
const float T = draw_data->DisplayPos.y;
const float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y;
Matrix4f ortho_projection;
ortho_projection <<
2.0f / (R - L), 0.0f, 0.0f, (R + L) / (L - R),
0.0f, 2.0f / (T - B), 0.0f, (T + B) / (B - T),
0.0f, 0.0f, -1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f;
shader->set_uniform("Texture", 0);
shader->set_uniform("ProjMtx", ortho_projection);
#else
// Setup viewport, orthographic projection matrix
// Our visible imgui space lies from draw_data->DisplayPps (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayMin is typically (0,0) for single viewport apps.
glsafe(::glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height));
@ -1485,16 +1526,55 @@ void ImGuiWrapper::render_draw_data(ImDrawData *draw_data)
glsafe(::glMatrixMode(GL_MODELVIEW));
glsafe(::glPushMatrix());
glsafe(::glLoadIdentity());
#endif // ENABLE_GL_IMGUI_SHADERS
#if ENABLE_GL_IMGUI_SHADERS
// Will project scissor/clipping rectangles into framebuffer space
const ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports
const ImVec2 clip_scale = draw_data->FramebufferScale; // (1,1) unless using retina display which are often (2,2)
#else
const ImVec2 pos = draw_data->DisplayPos;
#endif // ENABLE_GL_IMGUI_SHADERS
// Render command lists
ImVec2 pos = draw_data->DisplayPos;
for (int n = 0; n < draw_data->CmdListsCount; ++n) {
const ImDrawList* cmd_list = draw_data->CmdLists[n];
const ImDrawVert* vtx_buffer = cmd_list->VtxBuffer.Data;
const ImDrawIdx* idx_buffer = cmd_list->IdxBuffer.Data;
#if ENABLE_GL_IMGUI_SHADERS
const GLsizeiptr vtx_buffer_size = (GLsizeiptr)cmd_list->VtxBuffer.Size * (int)sizeof(ImDrawVert);
const GLsizeiptr idx_buffer_size = (GLsizeiptr)cmd_list->IdxBuffer.Size * (int)sizeof(ImDrawIdx);
GLuint vbo_id;
glsafe(::glGenBuffers(1, &vbo_id));
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, vbo_id));
glsafe(::glBufferData(GL_ARRAY_BUFFER, vtx_buffer_size, vtx_buffer, GL_STATIC_DRAW));
GLuint ibo_id;
glsafe(::glGenBuffers(1, &ibo_id));
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_id));
glsafe(::glBufferData(GL_ELEMENT_ARRAY_BUFFER, idx_buffer_size, idx_buffer, GL_STATIC_DRAW));
const int position_id = shader->get_attrib_location("Position");
if (position_id != -1) {
glsafe(::glVertexAttribPointer(position_id, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, pos)));
glsafe(::glEnableVertexAttribArray(position_id));
}
const int uv_id = shader->get_attrib_location("UV");
if (uv_id != -1) {
glsafe(::glVertexAttribPointer(uv_id, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, uv)));
glsafe(::glEnableVertexAttribArray(uv_id));
}
const int color_id = shader->get_attrib_location("Color");
if (color_id != -1) {
glsafe(::glVertexAttribPointer(color_id, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, col)));
glsafe(::glEnableVertexAttribArray(color_id));
}
#else
glsafe(::glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + IM_OFFSETOF(ImDrawVert, pos))));
glsafe(::glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + IM_OFFSETOF(ImDrawVert, uv))));
glsafe(::glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + IM_OFFSETOF(ImDrawVert, col))));
#endif // ENABLE_GL_IMGUI_SHADERS
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; ++cmd_i) {
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
@ -1502,34 +1582,71 @@ void ImGuiWrapper::render_draw_data(ImDrawData *draw_data)
// User callback (registered via ImDrawList::AddCallback)
pcmd->UserCallback(cmd_list, pcmd);
else {
ImVec4 clip_rect = ImVec4(pcmd->ClipRect.x - pos.x, pcmd->ClipRect.y - pos.y, pcmd->ClipRect.z - pos.x, pcmd->ClipRect.w - pos.y);
#if ENABLE_GL_IMGUI_SHADERS
// Project scissor/clipping rectangles into framebuffer space
const ImVec2 clip_min((pcmd->ClipRect.x - clip_off.x) * clip_scale.x, (pcmd->ClipRect.y - clip_off.y) * clip_scale.y);
const ImVec2 clip_max((pcmd->ClipRect.z - clip_off.x) * clip_scale.x, (pcmd->ClipRect.w - clip_off.y) * clip_scale.y);
if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y)
continue;
// Apply scissor/clipping rectangle (Y is inverted in OpenGL)
glsafe(::glScissor((int)clip_min.x, (int)(fb_height - clip_max.y), (int)(clip_max.x - clip_min.x), (int)(clip_max.y - clip_min.y)));
// Bind texture, Draw
glsafe(::glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->GetTexID()));
glsafe(::glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, (void*)(intptr_t)(pcmd->IdxOffset * sizeof(ImDrawIdx))));
#else
const ImVec4 clip_rect = ImVec4(pcmd->ClipRect.x - pos.x, pcmd->ClipRect.y - pos.y, pcmd->ClipRect.z - pos.x, pcmd->ClipRect.w - pos.y);
if (clip_rect.x < fb_width && clip_rect.y < fb_height && clip_rect.z >= 0.0f && clip_rect.w >= 0.0f) {
// Apply scissor/clipping rectangle
glsafe(::glScissor((int)clip_rect.x, (int)(fb_height - clip_rect.w), (int)(clip_rect.z - clip_rect.x), (int)(clip_rect.w - clip_rect.y)));
// Bind texture, Draw
glsafe(::glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId));
glsafe(::glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer));
glsafe(::glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->GetTexID()));
glsafe(::glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, (void*)(intptr_t)(pcmd->IdxOffset * sizeof(ImDrawIdx))));
}
#endif // ENABLE_GL_IMGUI_SHADERS
}
idx_buffer += pcmd->ElemCount;
}
#if ENABLE_GL_IMGUI_SHADERS
if (position_id != -1)
glsafe(::glDisableVertexAttribArray(position_id));
if (uv_id != -1)
glsafe(::glDisableVertexAttribArray(uv_id));
if (color_id != -1)
glsafe(::glDisableVertexAttribArray(color_id));
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
glsafe(::glDeleteBuffers(1, &ibo_id));
glsafe(::glDeleteBuffers(1, &vbo_id));
#endif // ENABLE_GL_IMGUI_SHADERS
}
// Restore modified state
glsafe(::glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, texture_env_mode));
glsafe(::glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, last_texture_env_mode));
glsafe(::glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture));
#if !ENABLE_GL_IMGUI_SHADERS
glsafe(::glDisableClientState(GL_COLOR_ARRAY));
glsafe(::glDisableClientState(GL_TEXTURE_COORD_ARRAY));
glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
glsafe(::glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture));
glsafe(::glMatrixMode(GL_MODELVIEW));
glsafe(::glPopMatrix());
glsafe(::glMatrixMode(GL_PROJECTION));
glsafe(::glPopMatrix());
#endif // !ENABLE_GL_IMGUI_SHADERS
glsafe(::glPopAttrib());
glsafe(::glPolygonMode(GL_FRONT, (GLenum)last_polygon_mode[0]); glPolygonMode(GL_BACK, (GLenum)last_polygon_mode[1]));
glsafe(::glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]));
glsafe(::glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], (GLsizei)last_scissor_box[3]));
#if ENABLE_GL_IMGUI_SHADERS
if (curr_shader != nullptr)
curr_shader->start_using();
#endif // ENABLE_GL_IMGUI_SHADERS
}
bool ImGuiWrapper::display_initialized() const