From ca8a42c8b12ab4d212497223778ea79228ff91da Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 10 May 2021 14:45:17 +0200 Subject: [PATCH] Tech ENABLE_SPLITTED_VERTEX_BUFFER set as default --- src/libslic3r/Technologies.hpp | 4 +- src/slic3r/GUI/GCodeViewer.cpp | 1364 +------------------------------- src/slic3r/GUI/GCodeViewer.hpp | 56 -- src/slic3r/GUI/GLCanvas3D.cpp | 4 - 4 files changed, 2 insertions(+), 1426 deletions(-) diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index 386728efb..f51241acc 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -41,10 +41,8 @@ //==================== #define ENABLE_2_4_0_ALPHA0 1 -// Enable splitting of vertex buffers used to render toolpaths -#define ENABLE_SPLITTED_VERTEX_BUFFER (1 && ENABLE_2_4_0_ALPHA0) // Enable rendering only starting and final caps for toolpaths -#define ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS (1 && ENABLE_SPLITTED_VERTEX_BUFFER) +#define ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS (1 && ENABLE_2_4_0_ALPHA0) // Enable reload from disk command for 3mf files #define ENABLE_RELOAD_FROM_DISK_FOR_3MF (1 && ENABLE_2_4_0_ALPHA0) // Removes obsolete warning texture code diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 233bdf1cd..7ccf10795 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -84,7 +84,6 @@ static float round_to_nearest(float value, unsigned int decimals) return res; } -#if ENABLE_SPLITTED_VERTEX_BUFFER void GCodeViewer::VBuffer::reset() { // release gpu memory @@ -95,38 +94,16 @@ void GCodeViewer::VBuffer::reset() sizes.clear(); count = 0; } -#else -void GCodeViewer::VBuffer::reset() -{ - // release gpu memory - if (id > 0) { - glsafe(::glDeleteBuffers(1, &id)); - id = 0; - } - - count = 0; -} -#endif // ENABLE_SPLITTED_VERTEX_BUFFER void GCodeViewer::IBuffer::reset() { -#if ENABLE_SPLITTED_VERTEX_BUFFER // release gpu memory if (ibo > 0) { glsafe(::glDeleteBuffers(1, &ibo)); ibo = 0; } -#else - // release gpu memory - if (id > 0) { - glsafe(::glDeleteBuffers(1, &id)); - id = 0; - } -#endif // ENABLE_SPLITTED_VERTEX_BUFFER -#if ENABLE_SPLITTED_VERTEX_BUFFER vbo = 0; -#endif // ENABLE_SPLITTED_VERTEX_BUFFER count = 0; } @@ -149,17 +126,10 @@ bool GCodeViewer::Path::matches(const GCodeProcessor::MoveVertex& move) const #endif // ENABLE_SEAMS_VISUALIZATION case EMoveType::Extrude: { // use rounding to reduce the number of generated paths -#if ENABLE_SPLITTED_VERTEX_BUFFER return type == move.type && extruder_id == move.extruder_id && cp_color_id == move.cp_color_id && role == move.extrusion_role && move.position[2] <= sub_paths.front().first.position[2] && feedrate == move.feedrate && fan_speed == move.fan_speed && height == round_to_nearest(move.height, 2) && width == round_to_nearest(move.width, 2) && matches_percent(volumetric_rate, move.volumetric_rate(), 0.05f); -#else - return type == move.type && extruder_id == move.extruder_id && cp_color_id == move.cp_color_id && role == move.extrusion_role && - move.position[2] <= first.position[2] && feedrate == move.feedrate && fan_speed == move.fan_speed && - height == round_to_nearest(move.height, 2) && width == round_to_nearest(move.width, 2) && - matches_percent(volumetric_rate, move.volumetric_rate(), 0.05f); -#endif // ENABLE_SPLITTED_VERTEX_BUFFER } case EMoveType::Travel: { return type == move.type && feedrate == move.feedrate && extruder_id == move.extruder_id && cp_color_id == move.cp_color_id; @@ -186,17 +156,10 @@ void GCodeViewer::TBuffer::add_path(const GCodeProcessor::MoveVertex& move, unsi { Path::Endpoint endpoint = { b_id, i_id, s_id, move.position }; // use rounding to reduce the number of generated paths -#if ENABLE_SPLITTED_VERTEX_BUFFER paths.push_back({ move.type, move.extrusion_role, move.delta_extruder, round_to_nearest(move.height, 2), round_to_nearest(move.width, 2), move.feedrate, move.fan_speed, move.temperature, move.volumetric_rate(), move.extruder_id, move.cp_color_id, { { endpoint, endpoint } } }); -#else - paths.push_back({ move.type, move.extrusion_role, endpoint, endpoint, move.delta_extruder, - round_to_nearest(move.height, 2), round_to_nearest(move.width, 2), - move.feedrate, move.fan_speed, move.temperature, - move.volumetric_rate(), move.extruder_id, move.cp_color_id }); -#endif // ENABLE_SPLITTED_VERTEX_BUFFER } GCodeViewer::Color GCodeViewer::Extrusions::Range::get_color_at(float value) const @@ -881,12 +844,10 @@ void GCodeViewer::render() const #endif // ENABLE_GCODE_VIEWER_STATISTICS } -#if ENABLE_SPLITTED_VERTEX_BUFFER bool GCodeViewer::can_export_toolpaths() const { return has_data() && m_buffers[buffer_id(EMoveType::Extrude)].render_primitive_type == TBuffer::ERenderPrimitiveType::Triangle; } -#endif // ENABLE_SPLITTED_VERTEX_BUFFER void GCodeViewer::update_sequential_view_current(unsigned int first, unsigned int last) { @@ -894,12 +855,8 @@ void GCodeViewer::update_sequential_view_current(unsigned int first, unsigned in for (const TBuffer& buffer : m_buffers) { if (buffer.visible) { for (const Path& path : buffer.paths) { -#if ENABLE_SPLITTED_VERTEX_BUFFER if (path.sub_paths.front().first.s_id <= id && id <= path.sub_paths.back().last.s_id) -#else - if (path.first.s_id <= id && id <= path.last.s_id) -#endif // ENABLE_SPLITTED_VERTEX_BUFFER - return true; + return true; } } } @@ -1021,20 +978,16 @@ void GCodeViewer::export_toolpaths_to_obj(const char* filename) const if (!t_buffer.has_data()) return; -#if ENABLE_SPLITTED_VERTEX_BUFFER if (t_buffer.render_primitive_type != TBuffer::ERenderPrimitiveType::Triangle) return; -#endif // ENABLE_SPLITTED_VERTEX_BUFFER // collect color information to generate materials std::vector colors; for (const RenderPath& path : t_buffer.render_paths) { colors.push_back(path.color); } -#if ENABLE_SPLITTED_VERTEX_BUFFER std::sort(colors.begin(), colors.end()); colors.erase(std::unique(colors.begin(), colors.end()), colors.end()); -#endif // ENABLE_SPLITTED_VERTEX_BUFFER // save materials file boost::filesystem::path mat_filename(filename); @@ -1069,7 +1022,6 @@ void GCodeViewer::export_toolpaths_to_obj(const char* filename) const fprintf(fp, "# Generated by %s-%s based on Slic3r\n", SLIC3R_APP_NAME, SLIC3R_VERSION); fprintf(fp, "\nmtllib ./%s\n", mat_filename.filename().string().c_str()); -#if ENABLE_SPLITTED_VERTEX_BUFFER const size_t floats_per_vertex = t_buffer.vertices.vertex_size_floats(); std::vector out_vertices; @@ -1155,253 +1107,10 @@ void GCodeViewer::export_toolpaths_to_obj(const char* filename) const } ++i; } -#else - // get vertices data from vertex buffer on gpu - size_t floats_per_vertex = t_buffer.vertices.vertex_size_floats(); - VertexBuffer vertices = VertexBuffer(t_buffer.vertices.count * floats_per_vertex); - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, t_buffer.vertices.id)); - glsafe(::glGetBufferSubData(GL_ARRAY_BUFFER, 0, t_buffer.vertices.data_size_bytes(), vertices.data())); - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); - - // get indices data from index buffer on gpu - MultiIndexBuffer indices; - for (size_t i = 0; i < t_buffer.indices.size(); ++i) { - indices.push_back(IndexBuffer(t_buffer.indices[i].count)); - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, t_buffer.indices[i].id)); - glsafe(::glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, static_cast(indices.back().size() * sizeof(unsigned int)), indices.back().data())); - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); - } - - auto get_vertex = [&vertices, floats_per_vertex](unsigned int id) { - // extract vertex from vector of floats - unsigned int base_id = id * floats_per_vertex; - return Vec3f(vertices[base_id + 0], vertices[base_id + 1], vertices[base_id + 2]); - }; - - struct Segment - { - Vec3f v1; - Vec3f v2; - Vec3f dir; - Vec3f right; - Vec3f up; - Vec3f rl_displacement; - Vec3f tb_displacement; - float length; - }; - - auto generate_segment = [get_vertex](unsigned int start_id, unsigned int end_id, float half_width, float half_height) { - auto local_basis = [](const Vec3f& dir) { - // calculate local basis (dir, right, up) on given segment - std::array ret; - ret[0] = dir.normalized(); - if (std::abs(ret[0][2]) < EPSILON) { - // segment parallel to XY plane - ret[1] = { ret[0][1], -ret[0][0], 0.0f }; - ret[2] = Vec3f::UnitZ(); - } - else if (std::abs(std::abs(ret[0].dot(Vec3f::UnitZ())) - 1.0f) < EPSILON) { - // segment parallel to Z axis - ret[1] = Vec3f::UnitX(); - ret[2] = Vec3f::UnitY(); - } - else { - ret[0] = dir.normalized(); - ret[1] = ret[0].cross(Vec3f::UnitZ()).normalized(); - ret[2] = ret[1].cross(ret[0]); - } - return ret; - }; - - Vec3f v1 = get_vertex(start_id) - half_height * Vec3f::UnitZ(); - Vec3f v2 = get_vertex(end_id) - half_height * Vec3f::UnitZ(); - float length = (v2 - v1).norm(); - const auto&& [dir, right, up] = local_basis(v2 - v1); - return Segment({ v1, v2, dir, right, up, half_width * right, half_height * up, length }); - }; - - size_t out_vertices_count = 0; - unsigned int indices_per_segment = t_buffer.indices_per_segment(); - unsigned int start_vertex_offset = t_buffer.start_segment_vertex_offset(); - unsigned int end_vertex_offset = t_buffer.end_segment_vertex_offset(); - - size_t i = 0; - for (const RenderPath& render_path : t_buffer.render_paths) { - // get paths segments from buffer paths - const IndexBuffer& ibuffer = indices[render_path.ibuffer_id]; - const Path& path = t_buffer.paths[render_path.path_id]; - - float half_width = 0.5f * path.width; - // clamp height to avoid artifacts due to z-fighting when importing the obj file into blender and similar - float half_height = std::max(0.5f * path.height, 0.005f); - - // generates vertices/normals/triangles - std::vector out_vertices; - std::vector out_normals; - using Triangle = std::array; - std::vector out_triangles; - for (size_t j = 0; j < render_path.offsets.size(); ++j) { - unsigned int start = static_cast(render_path.offsets[j] / sizeof(unsigned int)); - unsigned int end = start + render_path.sizes[j]; - - for (size_t k = start; k < end; k += static_cast(indices_per_segment)) { - Segment curr = generate_segment(ibuffer[k + start_vertex_offset], ibuffer[k + end_vertex_offset], half_width, half_height); - if (k == start) { - // starting endpoint vertices/normals - out_vertices.push_back(curr.v1 + curr.rl_displacement); out_normals.push_back(curr.right); // right - out_vertices.push_back(curr.v1 + curr.tb_displacement); out_normals.push_back(curr.up); // top - out_vertices.push_back(curr.v1 - curr.rl_displacement); out_normals.push_back(-curr.right); // left - out_vertices.push_back(curr.v1 - curr.tb_displacement); out_normals.push_back(-curr.up); // bottom - out_vertices_count += 4; - - // starting cap triangles - size_t base_id = out_vertices_count - 4 + 1; - out_triangles.push_back({ base_id + 0, base_id + 1, base_id + 2 }); - out_triangles.push_back({ base_id + 0, base_id + 2, base_id + 3 }); - } - else { - // for the endpoint shared by the current and the previous segments - // we keep the top and bottom vertices of the previous vertices - // and add new left/right vertices for the current segment - out_vertices.push_back(curr.v1 + curr.rl_displacement); out_normals.push_back(curr.right); // right - out_vertices.push_back(curr.v1 - curr.rl_displacement); out_normals.push_back(-curr.right); // left - out_vertices_count += 2; - - size_t first_vertex_id = k - static_cast(indices_per_segment); - Segment prev = generate_segment(ibuffer[first_vertex_id + start_vertex_offset], ibuffer[first_vertex_id + end_vertex_offset], half_width, half_height); - float disp = 0.0f; - float cos_dir = prev.dir.dot(curr.dir); - if (cos_dir > -0.9998477f) { - // if the angle between adjacent segments is smaller than 179 degrees - Vec3f med_dir = (prev.dir + curr.dir).normalized(); - disp = half_width * ::tan(::acos(std::clamp(curr.dir.dot(med_dir), -1.0f, 1.0f))); - } - - Vec3f disp_vec = disp * prev.dir; - - bool is_right_turn = prev.up.dot(prev.dir.cross(curr.dir)) <= 0.0f; - if (cos_dir < 0.7071068f) { - // if the angle between two consecutive segments is greater than 45 degrees - // we add a cap in the outside corner - // and displace the vertices in the inside corner to the same position, if possible - if (is_right_turn) { - // corner cap triangles (left) - size_t base_id = out_vertices_count - 6 + 1; - out_triangles.push_back({ base_id + 5, base_id + 2, base_id + 1 }); - out_triangles.push_back({ base_id + 5, base_id + 3, base_id + 2 }); - - // update right vertices - if (disp > 0.0f && disp < prev.length && disp < curr.length) { - base_id = out_vertices.size() - 6; - out_vertices[base_id + 0] -= disp_vec; - out_vertices[base_id + 4] = out_vertices[base_id + 0]; - } - } - else { - // corner cap triangles (right) - size_t base_id = out_vertices_count - 6 + 1; - out_triangles.push_back({ base_id + 0, base_id + 4, base_id + 1 }); - out_triangles.push_back({ base_id + 0, base_id + 3, base_id + 4 }); - - // update left vertices - if (disp > 0.0f && disp < prev.length && disp < curr.length) { - base_id = out_vertices.size() - 6; - out_vertices[base_id + 2] -= disp_vec; - out_vertices[base_id + 5] = out_vertices[base_id + 2]; - } - } - } - else { - // if the angle between two consecutive segments is lesser than 45 degrees - // displace the vertices to the same position - if (is_right_turn) { - size_t base_id = out_vertices.size() - 6; - // right - out_vertices[base_id + 0] -= disp_vec; - out_vertices[base_id + 4] = out_vertices[base_id + 0]; - // left - out_vertices[base_id + 2] += disp_vec; - out_vertices[base_id + 5] = out_vertices[base_id + 2]; - } - else { - size_t base_id = out_vertices.size() - 6; - // right - out_vertices[base_id + 0] += disp_vec; - out_vertices[base_id + 4] = out_vertices[base_id + 0]; - // left - out_vertices[base_id + 2] -= disp_vec; - out_vertices[base_id + 5] = out_vertices[base_id + 2]; - } - } - } - - // current second endpoint vertices/normals - out_vertices.push_back(curr.v2 + curr.rl_displacement); out_normals.push_back(curr.right); // right - out_vertices.push_back(curr.v2 + curr.tb_displacement); out_normals.push_back(curr.up); // top - out_vertices.push_back(curr.v2 - curr.rl_displacement); out_normals.push_back(-curr.right); // left - out_vertices.push_back(curr.v2 - curr.tb_displacement); out_normals.push_back(-curr.up); // bottom - out_vertices_count += 4; - - // sides triangles - if (k == start) { - size_t base_id = out_vertices_count - 8 + 1; - out_triangles.push_back({ base_id + 0, base_id + 4, base_id + 5 }); - out_triangles.push_back({ base_id + 0, base_id + 5, base_id + 1 }); - out_triangles.push_back({ base_id + 1, base_id + 5, base_id + 6 }); - out_triangles.push_back({ base_id + 1, base_id + 6, base_id + 2 }); - out_triangles.push_back({ base_id + 2, base_id + 6, base_id + 7 }); - out_triangles.push_back({ base_id + 2, base_id + 7, base_id + 3 }); - out_triangles.push_back({ base_id + 3, base_id + 7, base_id + 4 }); - out_triangles.push_back({ base_id + 3, base_id + 4, base_id + 0 }); - } - else { - size_t base_id = out_vertices_count - 10 + 1; - out_triangles.push_back({ base_id + 4, base_id + 6, base_id + 7 }); - out_triangles.push_back({ base_id + 4, base_id + 7, base_id + 1 }); - out_triangles.push_back({ base_id + 1, base_id + 7, base_id + 8 }); - out_triangles.push_back({ base_id + 1, base_id + 8, base_id + 5 }); - out_triangles.push_back({ base_id + 5, base_id + 8, base_id + 9 }); - out_triangles.push_back({ base_id + 5, base_id + 9, base_id + 3 }); - out_triangles.push_back({ base_id + 3, base_id + 9, base_id + 6 }); - out_triangles.push_back({ base_id + 3, base_id + 6, base_id + 4 }); - } - - if (k + 2 == end) { - // ending cap triangles - size_t base_id = out_vertices_count - 4 + 1; - out_triangles.push_back({ base_id + 0, base_id + 2, base_id + 1 }); - out_triangles.push_back({ base_id + 0, base_id + 3, base_id + 2 }); - } - } - } - - // save to file - fprintf(fp, "\n# vertices path %zu\n", i + 1); - for (const Vec3f& v : out_vertices) { - fprintf(fp, "v %g %g %g\n", v[0], v[1], v[2]); - } - - fprintf(fp, "\n# normals path %zu\n", i + 1); - for (const Vec3f& n : out_normals) { - fprintf(fp, "vn %g %g %g\n", n[0], n[1], n[2]); - } - - fprintf(fp, "\n# material path %zu\n", i + 1); - fprintf(fp, "usemtl material_%zu\n", i + 1); - - fprintf(fp, "\n# triangles path %zu\n", i + 1); - for (const Triangle& t : out_triangles) { - fprintf(fp, "f %zu//%zu %zu//%zu %zu//%zu\n", t[0], t[0], t[1], t[1], t[2], t[2]); - } - - ++ i; - } -#endif // ENABLE_SPLITTED_VERTEX_BUFFER fclose(fp); } -#if ENABLE_SPLITTED_VERTEX_BUFFER void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) { // max index buffer size, in bytes @@ -2265,667 +1974,6 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) if (progress_dialog != nullptr) progress_dialog->Destroy(); } -#else -void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) -{ -#if ENABLE_GCODE_VIEWER_STATISTICS - auto start_time = std::chrono::high_resolution_clock::now(); - m_statistics.results_size = SLIC3R_STDVEC_MEMSIZE(gcode_result.moves, GCodeProcessor::MoveVertex); - m_statistics.results_time = gcode_result.time; -#endif // ENABLE_GCODE_VIEWER_STATISTICS - - // vertices data - m_moves_count = gcode_result.moves.size(); - if (m_moves_count == 0) - return; - - unsigned int progress_count = 0; - static const unsigned int progress_threshold = 1000; - wxProgressDialog* progress_dialog = wxGetApp().is_gcode_viewer() ? - new wxProgressDialog(_L("Generating toolpaths"), "...", - 100, wxGetApp().plater(), wxPD_AUTO_HIDE | wxPD_APP_MODAL) : nullptr; - - m_extruders_count = gcode_result.extruders_count; - - for (size_t i = 0; i < m_moves_count; ++i) { - const GCodeProcessor::MoveVertex& move = gcode_result.moves[i]; - if (wxGetApp().is_gcode_viewer()) - // for the gcode viewer we need all moves to correctly size the printbed - m_paths_bounding_box.merge(move.position.cast()); - else { - if (move.type == EMoveType::Extrude && move.width != 0.0f && move.height != 0.0f) - m_paths_bounding_box.merge(move.position.cast()); - } - } - - // max bounding box (account for tool marker) - m_max_bounding_box = m_paths_bounding_box; - m_max_bounding_box.merge(m_paths_bounding_box.max + m_sequential_view.marker.get_bounding_box().size()[2] * Vec3d::UnitZ()); - - auto log_memory_usage = [this](const std::string& label, const std::vector& vertices, const std::vector& indices) { - int64_t vertices_size = 0; - for (size_t i = 0; i < vertices.size(); ++i) { - vertices_size += SLIC3R_STDVEC_MEMSIZE(vertices[i], float); - } - int64_t indices_size = 0; - for (size_t i = 0; i < indices.size(); ++i) { - for (size_t j = 0; j < indices[i].size(); ++j) { - indices_size += SLIC3R_STDVEC_MEMSIZE(indices[i][j], unsigned int); - } - } - log_memory_used(label, vertices_size + indices_size); - }; - - // format data into the buffers to be rendered as points - auto add_vertices_as_point = [](const GCodeProcessor::MoveVertex& curr, VertexBuffer& vertices) { - vertices.push_back(curr.position[0]); - vertices.push_back(curr.position[1]); - vertices.push_back(curr.position[2]); - }; - auto add_indices_as_point = [](const GCodeProcessor::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(indices.size())); - }; - - // format data into the buffers to be rendered as lines - auto add_vertices_as_line = [](const GCodeProcessor::MoveVertex& prev, const GCodeProcessor::MoveVertex& curr, - VertexBuffer& vertices) { - // x component of the normal to the current segment (the normal is parallel to the XY plane) - float normal_x = (curr.position - prev.position).normalized()[1]; - - auto add_vertex = [&vertices, normal_x](const GCodeProcessor::MoveVertex& vertex) { - // add position - vertices.push_back(vertex.position[0]); - vertices.push_back(vertex.position[1]); - vertices.push_back(vertex.position[2]); - // add normal x component - vertices.push_back(normal_x); - }; - - // add previous vertex - add_vertex(prev); - // add current vertex - add_vertex(curr); - }; - auto add_indices_as_line = [](const GCodeProcessor::MoveVertex& prev, const GCodeProcessor::MoveVertex& curr, TBuffer& buffer, - unsigned int ibuffer_id, IndexBuffer& indices, size_t move_id) { - if (prev.type != curr.type || !buffer.paths.back().matches(curr)) { - // add starting index - indices.push_back(static_cast(indices.size())); - buffer.add_path(curr, ibuffer_id, indices.size() - 1, move_id - 1); - buffer.paths.back().first.position = prev.position; - } - - Path& last_path = buffer.paths.back(); - if (last_path.first.i_id != last_path.last.i_id) { - // add previous index - indices.push_back(static_cast(indices.size())); - } - - // add current index - indices.push_back(static_cast(indices.size())); - last_path.last = { ibuffer_id, indices.size() - 1, move_id, curr.position }; - }; - - // format data into the buffers to be rendered as solid - auto add_vertices_as_solid = [](const GCodeProcessor::MoveVertex& prev, const GCodeProcessor::MoveVertex& curr, TBuffer& buffer, - VertexBuffer& vertices, size_t move_id) { - static Vec3f prev_dir; - static Vec3f prev_up; - static float prev_length; - auto store_vertex = [](VertexBuffer& vertices, const Vec3f& position, const Vec3f& normal) { - // append position - vertices.push_back(position[0]); - vertices.push_back(position[1]); - vertices.push_back(position[2]); - // append normal - vertices.push_back(normal[0]); - vertices.push_back(normal[1]); - vertices.push_back(normal[2]); - }; - auto extract_position_at = [](const VertexBuffer& vertices, size_t id) { - return Vec3f(vertices[id + 0], vertices[id + 1], vertices[id + 2]); - }; - auto update_position_at = [](VertexBuffer& vertices, size_t id, const Vec3f& position) { - vertices[id + 0] = position[0]; - vertices[id + 1] = position[1]; - vertices[id + 2] = position[2]; - }; - - if (prev.type != curr.type || !buffer.paths.back().matches(curr)) { - buffer.add_path(curr, 0, 0, move_id - 1); - buffer.paths.back().first.position = prev.position; - } - - unsigned int starting_vertices_size = static_cast(vertices.size() / buffer.vertices.vertex_size_floats()); - - Vec3f dir = (curr.position - prev.position).normalized(); - Vec3f right = (std::abs(std::abs(dir.dot(Vec3f::UnitZ())) - 1.0f) < EPSILON) ? -Vec3f::UnitY() : Vec3f(dir[1], -dir[0], 0.0f).normalized(); - Vec3f left = -right; - Vec3f up = right.cross(dir); - Vec3f down = -up; - - Path& last_path = buffer.paths.back(); - - float half_width = 0.5f * last_path.width; - float half_height = 0.5f * last_path.height; - - Vec3f prev_pos = prev.position - half_height * up; - Vec3f curr_pos = curr.position - half_height * up; - - float length = (curr_pos - prev_pos).norm(); - if (last_path.vertices_count() == 1) { - // 1st segment - - // vertices 1st endpoint - store_vertex(vertices, prev_pos + half_height * up, up); - store_vertex(vertices, prev_pos + half_width * right, right); - store_vertex(vertices, prev_pos + half_height * down, down); - store_vertex(vertices, prev_pos + half_width * left, left); - - // vertices 2nd endpoint - store_vertex(vertices, curr_pos + half_height * up, up); - store_vertex(vertices, curr_pos + half_width * right, right); - store_vertex(vertices, curr_pos + half_height * down, down); - store_vertex(vertices, curr_pos + half_width * left, left); - } - else { - // any other segment - float displacement = 0.0f; - float cos_dir = prev_dir.dot(dir); - if (cos_dir > -0.9998477f) { - // if the angle between adjacent segments is smaller than 179 degrees - Vec3f med_dir = (prev_dir + dir).normalized(); - displacement = half_width * ::tan(::acos(std::clamp(dir.dot(med_dir), -1.0f, 1.0f))); - } - - Vec3f displacement_vec = displacement * prev_dir; - bool can_displace = displacement > 0.0f && displacement < prev_length&& displacement < length; - - size_t prev_right_id = (starting_vertices_size - 3) * buffer.vertices.vertex_size_floats(); - size_t prev_left_id = (starting_vertices_size - 1) * buffer.vertices.vertex_size_floats(); - Vec3f prev_right_pos = extract_position_at(vertices, prev_right_id); - Vec3f prev_left_pos = extract_position_at(vertices, prev_left_id); - - bool is_right_turn = prev_up.dot(prev_dir.cross(dir)) <= 0.0f; - // whether the angle between adjacent segments is greater than 45 degrees - bool is_sharp = cos_dir < 0.7071068f; - - bool right_displaced = false; - bool left_displaced = false; - - // displace the vertex (inner with respect to the corner) of the previous segment 2nd enpoint, if possible - if (can_displace) { - if (is_right_turn) { - prev_right_pos -= displacement_vec; - update_position_at(vertices, prev_right_id, prev_right_pos); - right_displaced = true; - } - else { - prev_left_pos -= displacement_vec; - update_position_at(vertices, prev_left_id, prev_left_pos); - left_displaced = true; - } - } - - if (!is_sharp) { - // displace the vertex (outer with respect to the corner) of the previous segment 2nd enpoint, if possible - if (can_displace) { - if (is_right_turn) { - prev_left_pos += displacement_vec; - update_position_at(vertices, prev_left_id, prev_left_pos); - left_displaced = true; - } - else { - prev_right_pos += displacement_vec; - update_position_at(vertices, prev_right_id, prev_right_pos); - right_displaced = true; - } - } - - // vertices 1st endpoint (top and bottom are from previous segment 2nd endpoint) - // vertices position matches that of the previous segment 2nd endpoint, if displaced - store_vertex(vertices, right_displaced ? prev_right_pos : prev_pos + half_width * right, right); - store_vertex(vertices, left_displaced ? prev_left_pos : prev_pos + half_width * left, left); - } - else { - // vertices 1st endpoint (top and bottom are from previous segment 2nd endpoint) - // the inner corner vertex position matches that of the previous segment 2nd endpoint, if displaced - if (is_right_turn) { - store_vertex(vertices, right_displaced ? prev_right_pos : prev_pos + half_width * right, right); - store_vertex(vertices, prev_pos + half_width * left, left); - } - else { - store_vertex(vertices, prev_pos + half_width * right, right); - store_vertex(vertices, left_displaced ? prev_left_pos : prev_pos + half_width * left, left); - } - } - - // vertices 2nd endpoint - store_vertex(vertices, curr_pos + half_height * up, up); - store_vertex(vertices, curr_pos + half_width * right, right); - store_vertex(vertices, curr_pos + half_height * down, down); - store_vertex(vertices, curr_pos + half_width * left, left); - } - - last_path.last = { 0, 0, move_id, curr.position }; - prev_dir = dir; - prev_up = up; - prev_length = length; - }; - auto add_indices_as_solid = [](const GCodeProcessor::MoveVertex& prev, const GCodeProcessor::MoveVertex& curr, TBuffer& buffer, - size_t& buffer_vertices_size, unsigned int ibuffer_id, IndexBuffer& indices, size_t move_id) { - static Vec3f prev_dir; - static Vec3f prev_up; - static float prev_length; - auto store_triangle = [](IndexBuffer& indices, unsigned int i1, unsigned int i2, unsigned int i3) { - indices.push_back(i1); - indices.push_back(i2); - indices.push_back(i3); - }; - auto append_dummy_cap = [store_triangle](IndexBuffer& indices, unsigned int id) { - store_triangle(indices, id, id, id); - store_triangle(indices, id, id, id); - }; - - if (prev.type != curr.type || !buffer.paths.back().matches(curr)) { - buffer.add_path(curr, ibuffer_id, indices.size(), move_id - 1); - buffer.paths.back().first.position = prev.position; - } - - Vec3f dir = (curr.position - prev.position).normalized(); - Vec3f right = (std::abs(std::abs(dir.dot(Vec3f::UnitZ())) - 1.0f) < EPSILON) ? -Vec3f::UnitY() : Vec3f(dir[1], -dir[0], 0.0f).normalized(); - Vec3f up = right.cross(dir); - - Path& last_path = buffer.paths.back(); - - float half_width = 0.5f * last_path.width; - float half_height = 0.5f * last_path.height; - - Vec3f prev_pos = prev.position - half_height * up; - Vec3f curr_pos = curr.position - half_height * up; - - float length = (curr_pos - prev_pos).norm(); - if (last_path.vertices_count() == 1) { - // 1st segment - - // triangles starting cap - store_triangle(indices, buffer_vertices_size + 0, buffer_vertices_size + 2, buffer_vertices_size + 1); - store_triangle(indices, buffer_vertices_size + 0, buffer_vertices_size + 3, buffer_vertices_size + 2); - - // dummy triangles outer corner cap - append_dummy_cap(indices, buffer_vertices_size); - - // triangles sides - store_triangle(indices, buffer_vertices_size + 0, buffer_vertices_size + 1, buffer_vertices_size + 4); - store_triangle(indices, buffer_vertices_size + 1, buffer_vertices_size + 5, buffer_vertices_size + 4); - store_triangle(indices, buffer_vertices_size + 1, buffer_vertices_size + 2, buffer_vertices_size + 5); - store_triangle(indices, buffer_vertices_size + 2, buffer_vertices_size + 6, buffer_vertices_size + 5); - store_triangle(indices, buffer_vertices_size + 2, buffer_vertices_size + 3, buffer_vertices_size + 6); - store_triangle(indices, buffer_vertices_size + 3, buffer_vertices_size + 7, buffer_vertices_size + 6); - store_triangle(indices, buffer_vertices_size + 3, buffer_vertices_size + 0, buffer_vertices_size + 7); - store_triangle(indices, buffer_vertices_size + 0, buffer_vertices_size + 4, buffer_vertices_size + 7); - - // triangles ending cap - store_triangle(indices, buffer_vertices_size + 4, buffer_vertices_size + 6, buffer_vertices_size + 7); - store_triangle(indices, buffer_vertices_size + 4, buffer_vertices_size + 5, buffer_vertices_size + 6); - - buffer_vertices_size += 8; - } - else { - // any other segment - float displacement = 0.0f; - float cos_dir = prev_dir.dot(dir); - if (cos_dir > -0.9998477f) { - // if the angle between adjacent segments is smaller than 179 degrees - Vec3f med_dir = (prev_dir + dir).normalized(); - displacement = half_width * ::tan(::acos(std::clamp(dir.dot(med_dir), -1.0f, 1.0f))); - } - - Vec3f displacement_vec = displacement * prev_dir; - bool can_displace = displacement > 0.0f && displacement < prev_length && displacement < length; - - bool is_right_turn = prev_up.dot(prev_dir.cross(dir)) <= 0.0f; - // whether the angle between adjacent segments is greater than 45 degrees - bool is_sharp = cos_dir < 0.7071068f; - - bool right_displaced = false; - bool left_displaced = false; - - if (!is_sharp) { - if (can_displace) { - if (is_right_turn) - left_displaced = true; - else - right_displaced = true; - } - } - - // triangles starting cap - store_triangle(indices, buffer_vertices_size - 4, buffer_vertices_size - 2, buffer_vertices_size + 0); - store_triangle(indices, buffer_vertices_size - 4, buffer_vertices_size + 1, buffer_vertices_size - 2); - - // triangles outer corner cap - if (is_right_turn) { - if (left_displaced) - // dummy triangles - append_dummy_cap(indices, buffer_vertices_size); - else { - store_triangle(indices, buffer_vertices_size - 4, buffer_vertices_size + 1, buffer_vertices_size - 1); - store_triangle(indices, buffer_vertices_size + 1, buffer_vertices_size - 2, buffer_vertices_size - 1); - } - } - else { - if (right_displaced) - // dummy triangles - append_dummy_cap(indices, buffer_vertices_size); - else { - store_triangle(indices, buffer_vertices_size - 4, buffer_vertices_size - 3, buffer_vertices_size + 0); - store_triangle(indices, buffer_vertices_size - 3, buffer_vertices_size - 2, buffer_vertices_size + 0); - } - } - - // triangles sides - store_triangle(indices, buffer_vertices_size - 4, buffer_vertices_size + 0, buffer_vertices_size + 2); - store_triangle(indices, buffer_vertices_size + 0, buffer_vertices_size + 3, buffer_vertices_size + 2); - store_triangle(indices, buffer_vertices_size + 0, buffer_vertices_size - 2, buffer_vertices_size + 3); - store_triangle(indices, buffer_vertices_size - 2, buffer_vertices_size + 4, buffer_vertices_size + 3); - store_triangle(indices, buffer_vertices_size - 2, buffer_vertices_size + 1, buffer_vertices_size + 4); - store_triangle(indices, buffer_vertices_size + 1, buffer_vertices_size + 5, buffer_vertices_size + 4); - store_triangle(indices, buffer_vertices_size + 1, buffer_vertices_size - 4, buffer_vertices_size + 5); - store_triangle(indices, buffer_vertices_size - 4, buffer_vertices_size + 2, buffer_vertices_size + 5); - - // triangles ending cap - store_triangle(indices, buffer_vertices_size + 2, buffer_vertices_size + 4, buffer_vertices_size + 5); - store_triangle(indices, buffer_vertices_size + 2, buffer_vertices_size + 3, buffer_vertices_size + 4); - - buffer_vertices_size += 6; - } - - last_path.last = { ibuffer_id, indices.size() - 1, move_id, curr.position }; - prev_dir = dir; - prev_up = up; - prev_length = length; - }; - - wxBusyCursor busy; - - // to reduce the peak in memory usage, we split the generation of the vertex and index buffers in two steps. - // the data are deleted as soon as they are sent to the gpu. - std::vector vertices(m_buffers.size()); - std::vector indices(m_buffers.size()); - std::vector options_zs; - - // toolpaths data -> extract vertices from result - for (size_t i = 0; i < m_moves_count; ++i) { - // skip first vertex - if (i == 0) - continue; - - ++progress_count; - if (progress_dialog != nullptr && progress_count % progress_threshold == 0) { - progress_dialog->Update(int(100.0f * float(i) / (2.0f * float(m_moves_count))), - _L("Generating vertex buffer") + ": " + wxNumberFormatter::ToString(100.0 * double(i) / double(m_moves_count), 0, wxNumberFormatter::Style_None) + "%"); - progress_dialog->Fit(); - progress_count = 0; - } - - const GCodeProcessor::MoveVertex& prev = gcode_result.moves[i - 1]; - const GCodeProcessor::MoveVertex& curr = gcode_result.moves[i]; - - unsigned char id = buffer_id(curr.type); - TBuffer& buffer = m_buffers[id]; - VertexBuffer& buffer_vertices = vertices[id]; - - switch (buffer.render_primitive_type) - { - case TBuffer::ERenderPrimitiveType::Point: { - add_vertices_as_point(curr, buffer_vertices); - break; - } - case TBuffer::ERenderPrimitiveType::Line: { - add_vertices_as_line(prev, curr, buffer_vertices); - break; - } - case TBuffer::ERenderPrimitiveType::Triangle: { - add_vertices_as_solid(prev, curr, buffer, buffer_vertices, i); - break; - } - } - - if (curr.type == EMoveType::Pause_Print || curr.type == EMoveType::Custom_GCode) { - const float* const last_z = options_zs.empty() ? nullptr : &options_zs.back(); - if (last_z == nullptr || curr.position[2] < *last_z - EPSILON || *last_z + EPSILON < curr.position[2]) - options_zs.emplace_back(curr.position[2]); - } - } - - // move the wipe toolpaths half height up to render them on proper position - VertexBuffer& wipe_vertices = vertices[buffer_id(EMoveType::Wipe)]; - for (size_t i = 2; i < wipe_vertices.size(); i += 3) { - wipe_vertices[i] += 0.5f * GCodeProcessor::Wipe_Height; - } - - log_memory_usage("Loaded G-code generated vertex buffers, ", vertices, indices); - - // toolpaths data -> send vertices data to gpu - for (size_t i = 0; i < m_buffers.size(); ++i) { - TBuffer& buffer = m_buffers[i]; - - const VertexBuffer& buffer_vertices = vertices[i]; - buffer.vertices.count = buffer_vertices.size() / buffer.vertices.vertex_size_floats(); -#if ENABLE_GCODE_VIEWER_STATISTICS - m_statistics.total_vertices_gpu_size += buffer_vertices.size() * sizeof(float); - m_statistics.max_vbuffer_gpu_size = std::max(m_statistics.max_vbuffer_gpu_size, static_cast(buffer_vertices.size() * sizeof(float))); -#endif // ENABLE_GCODE_VIEWER_STATISTICS - - if (buffer.vertices.count > 0) { -#if ENABLE_GCODE_VIEWER_STATISTICS - ++m_statistics.vbuffers_count; -#endif // ENABLE_GCODE_VIEWER_STATISTICS - glsafe(::glGenBuffers(1, &buffer.vertices.id)); - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, buffer.vertices.id)); - glsafe(::glBufferData(GL_ARRAY_BUFFER, buffer_vertices.size() * sizeof(float), buffer_vertices.data(), GL_STATIC_DRAW)); - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); - } - } - - // dismiss vertices data, no more needed - std::vector().swap(vertices); - - // toolpaths data -> extract indices from result - // paths may have been filled while extracting vertices, - // so reset them, they will be filled again while extracting indices - for (TBuffer& buffer : m_buffers) { - buffer.paths.clear(); - } - - // max index buffer size - const size_t IBUFFER_THRESHOLD = 1024 * 1024 * 32; - - // variable used to keep track of the current size (in vertices) of the vertex buffer - std::vector curr_buffer_vertices_size(m_buffers.size(), 0); - for (size_t i = 0; i < m_moves_count; ++i) { - // skip first vertex - if (i == 0) - continue; - - ++progress_count; - if (progress_dialog != nullptr && progress_count % progress_threshold == 0) { - progress_dialog->Update(int(100.0f * float(m_moves_count + i) / (2.0f * float(m_moves_count))), - _L("Generating index buffers") + ": " + wxNumberFormatter::ToString(100.0 * double(i) / double(m_moves_count), 0, wxNumberFormatter::Style_None) + "%"); - progress_dialog->Fit(); - progress_count = 0; - } - - const GCodeProcessor::MoveVertex& prev = gcode_result.moves[i - 1]; - const GCodeProcessor::MoveVertex& curr = gcode_result.moves[i]; - - unsigned char id = buffer_id(curr.type); - TBuffer& buffer = m_buffers[id]; - MultiIndexBuffer& buffer_indices = indices[id]; - if (buffer_indices.empty()) - buffer_indices.push_back(IndexBuffer()); - - // if adding the indices for the current segment exceeds the threshold size of the current index buffer - // create another index buffer, and move the current path indices into it - if (buffer_indices.back().size() >= IBUFFER_THRESHOLD - static_cast(buffer.indices_per_segment())) { - buffer_indices.push_back(IndexBuffer()); - if (buffer.render_primitive_type != TBuffer::ERenderPrimitiveType::Point) { - if (!(prev.type != curr.type || !buffer.paths.back().matches(curr))) { - Path& last_path = buffer.paths.back(); - size_t delta_id = last_path.last.i_id - last_path.first.i_id; - - // move indices of the last path from the previous into the new index buffer - IndexBuffer& src_buffer = buffer_indices[buffer_indices.size() - 2]; - IndexBuffer& dst_buffer = buffer_indices[buffer_indices.size() - 1]; - std::move(src_buffer.begin() + last_path.first.i_id, src_buffer.end(), std::back_inserter(dst_buffer)); - src_buffer.erase(src_buffer.begin() + last_path.first.i_id, src_buffer.end()); - - // updates path indices - last_path.first.b_id = buffer_indices.size() - 1; - last_path.first.i_id = 0; - last_path.last.b_id = buffer_indices.size() - 1; - last_path.last.i_id = delta_id; - } - } - } - - switch (buffer.render_primitive_type) - { - case TBuffer::ERenderPrimitiveType::Point: { - add_indices_as_point(curr, buffer, static_cast(buffer_indices.size()) - 1, buffer_indices.back(), i); - break; - } - case TBuffer::ERenderPrimitiveType::Line: { - add_indices_as_line(prev, curr, buffer, static_cast(buffer_indices.size()) - 1, buffer_indices.back(), i); - break; - } - case TBuffer::ERenderPrimitiveType::Triangle: { - add_indices_as_solid(prev, curr, buffer, curr_buffer_vertices_size[id], static_cast(buffer_indices.size()) - 1, buffer_indices.back(), i); - break; - } - } - } - - if (progress_dialog != nullptr) { - progress_dialog->Update(100, ""); - progress_dialog->Fit(); - } - - log_memory_usage("Loaded G-code generated indices buffers, ", vertices, indices); - - // toolpaths data -> send indices data to gpu - for (size_t i = 0; i < m_buffers.size(); ++i) { - TBuffer& buffer = m_buffers[i]; - - for (size_t j = 0; j < indices[i].size(); ++j) { - const IndexBuffer& buffer_indices = indices[i][j]; - buffer.indices.push_back(IBuffer()); - IBuffer& ibuffer = buffer.indices.back(); - ibuffer.count = buffer_indices.size(); -#if ENABLE_GCODE_VIEWER_STATISTICS - m_statistics.total_indices_gpu_size += ibuffer.count * sizeof(unsigned int); - m_statistics.max_ibuffer_gpu_size = std::max(m_statistics.max_ibuffer_gpu_size, static_cast(ibuffer.count * sizeof(unsigned int))); -#endif // ENABLE_GCODE_VIEWER_STATISTICS - - if (ibuffer.count > 0) { -#if ENABLE_GCODE_VIEWER_STATISTICS - ++m_statistics.ibuffers_count; -#endif // ENABLE_GCODE_VIEWER_STATISTICS - glsafe(::glGenBuffers(1, &ibuffer.id)); - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibuffer.id)); - glsafe(::glBufferData(GL_ELEMENT_ARRAY_BUFFER, buffer_indices.size() * sizeof(unsigned int), buffer_indices.data(), GL_STATIC_DRAW)); - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); - } - } - } - -#if ENABLE_GCODE_VIEWER_STATISTICS - for (const TBuffer& buffer : m_buffers) { - m_statistics.paths_size += SLIC3R_STDVEC_MEMSIZE(buffer.paths, Path); - } - unsigned int travel_buffer_id = buffer_id(EMoveType::Travel); - const MultiIndexBuffer& travel_buffer_indices = indices[travel_buffer_id]; - for (size_t i = 0; i < travel_buffer_indices.size(); ++i) { - m_statistics.travel_segments_count += travel_buffer_indices[i].size() / m_buffers[travel_buffer_id].indices_per_segment(); - } - unsigned int wipe_buffer_id = buffer_id(EMoveType::Wipe); - const MultiIndexBuffer& wipe_buffer_indices = indices[wipe_buffer_id]; - for (size_t i = 0; i < wipe_buffer_indices.size(); ++i) { - m_statistics.wipe_segments_count += wipe_buffer_indices[i].size() / m_buffers[wipe_buffer_id].indices_per_segment(); - } - unsigned int extrude_buffer_id = buffer_id(EMoveType::Extrude); - const MultiIndexBuffer& extrude_buffer_indices = indices[extrude_buffer_id]; - for (size_t i = 0; i < extrude_buffer_indices.size(); ++i) { - m_statistics.extrude_segments_count += extrude_buffer_indices[i].size() / m_buffers[extrude_buffer_id].indices_per_segment(); - } -#endif // ENABLE_GCODE_VIEWER_STATISTICS - - // dismiss indices data, no more needed - std::vector().swap(indices); - - // layers zs / roles / extruder ids / cp color ids -> extract from result - size_t last_travel_s_id = 0; - for (size_t i = 0; i < m_moves_count; ++i) { - const GCodeProcessor::MoveVertex& move = gcode_result.moves[i]; - if (move.type == EMoveType::Extrude) { - // layers zs - const double* const last_z = m_layers.empty() ? nullptr : &m_layers.get_zs().back(); - double z = static_cast(move.position[2]); - if (last_z == nullptr || z < *last_z - EPSILON || *last_z + EPSILON < z) - m_layers.append(z, { last_travel_s_id, i }); - else - m_layers.get_endpoints().back().last = i; - // extruder ids - m_extruder_ids.emplace_back(move.extruder_id); - // roles - if (i > 0) - m_roles.emplace_back(move.extrusion_role); - } - else if (move.type == EMoveType::Travel) { - if (i - last_travel_s_id > 1 && !m_layers.empty()) - m_layers.get_endpoints().back().last = i; - - last_travel_s_id = i; - } - } - - // set layers z range - if (!m_layers.empty()) - m_layers_z_range = { 0, static_cast(m_layers.size() - 1) }; - - // change color of paths whose layer contains option points - if (!options_zs.empty()) { - TBuffer& extrude_buffer = m_buffers[buffer_id(EMoveType::Extrude)]; - for (Path& path : extrude_buffer.paths) { - float z = path.first.position[2]; - if (std::find_if(options_zs.begin(), options_zs.end(), [z](float f) { return f - EPSILON <= z && z <= f + EPSILON; }) != options_zs.end()) - path.cp_color_id = 255 - path.cp_color_id; - } - } - - // roles -> remove duplicates - std::sort(m_roles.begin(), m_roles.end()); - m_roles.erase(std::unique(m_roles.begin(), m_roles.end()), m_roles.end()); - m_roles.shrink_to_fit(); - - // extruder ids -> remove duplicates - std::sort(m_extruder_ids.begin(), m_extruder_ids.end()); - m_extruder_ids.erase(std::unique(m_extruder_ids.begin(), m_extruder_ids.end()), m_extruder_ids.end()); - m_extruder_ids.shrink_to_fit(); - - log_memory_usage("Loaded G-code generated extrusion paths, ", vertices, indices); - -#if ENABLE_GCODE_VIEWER_STATISTICS - m_statistics.load_time = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - start_time).count(); -#endif // ENABLE_GCODE_VIEWER_STATISTICS - - if (progress_dialog != nullptr) - progress_dialog->Destroy(); -} -#endif // ENABLE_SPLITTED_VERTEX_BUFFER void GCodeViewer::load_shells(const Print& print, bool initialized) { @@ -2981,7 +2029,6 @@ void GCodeViewer::load_shells(const Print& print, bool initialized) } } -#if ENABLE_SPLITTED_VERTEX_BUFFER void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool keep_sequential_current_last) const { #if ENABLE_GCODE_VIEWER_STATISTICS @@ -3444,261 +2491,7 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool statistics->refresh_paths_time = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - start_time).count(); #endif // ENABLE_GCODE_VIEWER_STATISTICS } -#else -void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool keep_sequential_current_last) const -{ -#if ENABLE_GCODE_VIEWER_STATISTICS - auto start_time = std::chrono::high_resolution_clock::now(); -#endif // ENABLE_GCODE_VIEWER_STATISTICS - auto extrusion_color = [this](const Path& path) { - Color color; - switch (m_view_type) - { - case EViewType::FeatureType: { color = Extrusion_Role_Colors[static_cast(path.role)]; break; } - case EViewType::Height: { color = m_extrusions.ranges.height.get_color_at(path.height); break; } - case EViewType::Width: { color = m_extrusions.ranges.width.get_color_at(path.width); break; } - case EViewType::Feedrate: { color = m_extrusions.ranges.feedrate.get_color_at(path.feedrate); break; } - case EViewType::FanSpeed: { color = m_extrusions.ranges.fan_speed.get_color_at(path.fan_speed); break; } - case EViewType::Temperature: { color = m_extrusions.ranges.temperature.get_color_at(path.temperature); break; } - case EViewType::VolumetricRate: { color = m_extrusions.ranges.volumetric_rate.get_color_at(path.volumetric_rate); break; } - case EViewType::Tool: { color = m_tool_colors[path.extruder_id]; break; } - case EViewType::ColorPrint: { - if (path.cp_color_id >= static_cast(m_tool_colors.size())) { - color = { 0.5f, 0.5f, 0.5f }; -// // complementary color -// color = m_tool_colors[255 - path.cp_color_id]; -// color = { 1.0f - color[0], 1.0f - color[1], 1.0f - color[2] }; - } - else - color = m_tool_colors[path.cp_color_id]; - - break; - } - default: { color = { 1.0f, 1.0f, 1.0f }; break; } - } - - return color; - }; - - auto travel_color = [this](const Path& path) { - return (path.delta_extruder < 0.0f) ? Travel_Colors[2] /* Retract */ : - ((path.delta_extruder > 0.0f) ? Travel_Colors[1] /* Extrude */ : - Travel_Colors[0] /* Move */); - }; - - auto is_in_layers_range = [this](const Path& path, size_t min_id, size_t max_id) { - auto in_layers_range = [this, min_id, max_id](size_t id) { - return m_layers.get_endpoints_at(min_id).first <= id && id <= m_layers.get_endpoints_at(max_id).last; - }; - - return in_layers_range(path.first.s_id) || in_layers_range(path.last.s_id); - }; - - auto is_travel_in_layers_range = [this](size_t path_id, size_t min_id, size_t max_id) { - auto is_in_z_range = [](const Path& path, double min_z, double max_z) { - auto in_z_range = [min_z, max_z](double z) { - return min_z - EPSILON < z&& z < max_z + EPSILON; - }; - - return in_z_range(path.first.position[2]) || in_z_range(path.last.position[2]); - }; - - const TBuffer& buffer = m_buffers[buffer_id(EMoveType::Travel)]; - if (path_id >= buffer.paths.size()) - return false; - - Path path = buffer.paths[path_id]; - size_t first = path_id; - size_t last = path_id; - - // check adjacent paths - while (first > 0 && path.first.position.isApprox(buffer.paths[first - 1].last.position)) { - --first; - path.first = buffer.paths[first].first; - } - while (last < buffer.paths.size() - 1 && path.last.position.isApprox(buffer.paths[last + 1].first.position)) { - ++last; - path.last = buffer.paths[last].last; - } - - size_t min_s_id = m_layers.get_endpoints_at(min_id).first; - size_t max_s_id = m_layers.get_endpoints_at(max_id).last; - - return (min_s_id <= path.first.s_id && path.first.s_id <= max_s_id) || - (min_s_id <= path.last.s_id && path.last.s_id <= max_s_id); - }; - -#if ENABLE_GCODE_VIEWER_STATISTICS - Statistics* statistics = const_cast(&m_statistics); - statistics->render_paths_size = 0; -#endif // ENABLE_GCODE_VIEWER_STATISTICS - - bool top_layer_only = get_app_config()->get("seq_top_layer_only") == "1"; - - SequentialView::Endpoints global_endpoints = { m_moves_count , 0 }; - SequentialView::Endpoints top_layer_endpoints = global_endpoints; - SequentialView* sequential_view = const_cast(&m_sequential_view); - if (top_layer_only || !keep_sequential_current_first) sequential_view->current.first = 0; - if (!keep_sequential_current_last) sequential_view->current.last = m_moves_count; - - // first pass: collect visible paths and update sequential view data - std::vector> paths; - for (size_t b = 0; b < m_buffers.size(); ++b) { - TBuffer& buffer = const_cast(m_buffers[b]); - // reset render paths - buffer.render_paths.clear(); - - if (!buffer.visible) - continue; - - for (size_t i = 0; i < buffer.paths.size(); ++i) { - const Path& path = buffer.paths[i]; - if (path.type == EMoveType::Travel) { - if (!is_travel_in_layers_range(i, m_layers_z_range[0], m_layers_z_range[1])) - continue; - } - else if (!is_in_layers_range(path, m_layers_z_range[0], m_layers_z_range[1])) - continue; - - if (path.type == EMoveType::Extrude && !is_visible(path)) - continue; - - // store valid path - paths.push_back({ &buffer, path.first.b_id, static_cast(i) }); - - global_endpoints.first = std::min(global_endpoints.first, path.first.s_id); - global_endpoints.last = std::max(global_endpoints.last, path.last.s_id); - - if (top_layer_only) { - if (path.type == EMoveType::Travel) { - if (is_travel_in_layers_range(i, m_layers_z_range[1], m_layers_z_range[1])) { - top_layer_endpoints.first = std::min(top_layer_endpoints.first, path.first.s_id); - top_layer_endpoints.last = std::max(top_layer_endpoints.last, path.last.s_id); - } - } - else if (is_in_layers_range(path, m_layers_z_range[1], m_layers_z_range[1])) { - top_layer_endpoints.first = std::min(top_layer_endpoints.first, path.first.s_id); - top_layer_endpoints.last = std::max(top_layer_endpoints.last, path.last.s_id); - } - } - } - } - - // update current sequential position - sequential_view->current.first = !top_layer_only && keep_sequential_current_first ? std::clamp(sequential_view->current.first, global_endpoints.first, global_endpoints.last) : global_endpoints.first; - sequential_view->current.last = keep_sequential_current_last ? std::clamp(sequential_view->current.last, global_endpoints.first, global_endpoints.last) : global_endpoints.last; - - // get the world position from gpu - bool found = false; - for (const TBuffer& buffer : m_buffers) { - // searches the path containing the current position - for (const Path& path : buffer.paths) { - if (path.contains(m_sequential_view.current.last)) { - unsigned int offset = static_cast(m_sequential_view.current.last - path.first.s_id); - if (offset > 0) { - if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::Line) - offset = 2 * offset - 1; - else if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::Triangle) { - unsigned int indices_count = buffer.indices_per_segment(); - offset = indices_count * (offset - 1) + (indices_count - 6); - } - } - offset += static_cast(path.first.i_id); - - // gets the index from the index buffer on gpu - unsigned int index = 0; - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer.indices[path.first.b_id].id)); - glsafe(::glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, static_cast(offset * sizeof(unsigned int)), static_cast(sizeof(unsigned int)), static_cast(&index))); - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); - - // gets the position from the vertices buffer on gpu - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, buffer.vertices.id)); - glsafe(::glGetBufferSubData(GL_ARRAY_BUFFER, static_cast(index * buffer.vertices.vertex_size_bytes()), static_cast(3 * sizeof(float)), static_cast(sequential_view->current_position.data()))); - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); - found = true; - break; - } - } - if (found) - break; - } - - // second pass: filter paths by sequential data and collect them by color - RenderPath *render_path = nullptr; - for (const auto& [buffer, ibuffer_id, path_id] : paths) { - const Path& path = buffer->paths[path_id]; - if (m_sequential_view.current.last <= path.first.s_id || path.last.s_id <= m_sequential_view.current.first) - continue; - - Color color; - switch (path.type) - { - case EMoveType::Extrude: { - if (!top_layer_only || - m_sequential_view.current.last == global_endpoints.last || - is_in_layers_range(path, m_layers_z_range[1], m_layers_z_range[1])) - color = extrusion_color(path); - else - color = { 0.25f, 0.25f, 0.25f }; - - break; - } - case EMoveType::Travel: { - if (!top_layer_only || m_sequential_view.current.last == global_endpoints.last || is_travel_in_layers_range(path_id, m_layers_z_range[1], m_layers_z_range[1])) - color = (m_view_type == EViewType::Feedrate || m_view_type == EViewType::Tool || m_view_type == EViewType::ColorPrint) ? extrusion_color(path) : travel_color(path); - else - color = { 0.25f, 0.25f, 0.25f }; - - break; - } - case EMoveType::Wipe: { color = Wipe_Color; break; } - default: { color = { 0.0f, 0.0f, 0.0f }; break; } - } - - RenderPath key{ color, static_cast(ibuffer_id), path_id }; - if (render_path == nullptr || ! RenderPathPropertyEqual()(*render_path, key)) - render_path = const_cast(&(*buffer->render_paths.emplace(key).first)); - unsigned int segments_count = std::min(m_sequential_view.current.last, path.last.s_id) - std::max(m_sequential_view.current.first, path.first.s_id) + 1; - unsigned int size_in_indices = 0; - switch (buffer->render_primitive_type) - { - case TBuffer::ERenderPrimitiveType::Point: { size_in_indices = segments_count; break; } - case TBuffer::ERenderPrimitiveType::Line: - case TBuffer::ERenderPrimitiveType::Triangle: { size_in_indices = buffer->indices_per_segment() * (segments_count - 1); break; } - } - render_path->sizes.push_back(size_in_indices); - - unsigned int delta_1st = 0; - if (path.first.s_id < m_sequential_view.current.first && m_sequential_view.current.first <= path.last.s_id) - delta_1st = m_sequential_view.current.first - path.first.s_id; - - if (buffer->render_primitive_type == TBuffer::ERenderPrimitiveType::Triangle) - delta_1st *= buffer->indices_per_segment(); - - render_path->offsets.push_back(static_cast((path.first.i_id + delta_1st) * sizeof(unsigned int))); - } - - // set sequential data to their final value - sequential_view->endpoints = top_layer_only ? top_layer_endpoints : global_endpoints; - sequential_view->current.first = !top_layer_only && keep_sequential_current_first ? std::clamp(sequential_view->current.first, sequential_view->endpoints.first, sequential_view->endpoints.last) : sequential_view->endpoints.first; - - wxGetApp().plater()->enable_preview_moves_slider(!paths.empty()); - -#if ENABLE_GCODE_VIEWER_STATISTICS - for (const TBuffer& buffer : m_buffers) { - statistics->render_paths_size += SLIC3R_STDUNORDEREDSET_MEMSIZE(buffer.render_paths, RenderPath); - for (const RenderPath& path : buffer.render_paths) { - statistics->render_paths_size += SLIC3R_STDVEC_MEMSIZE(path.sizes, unsigned int); - statistics->render_paths_size += SLIC3R_STDVEC_MEMSIZE(path.offsets, size_t); - } - } - statistics->refresh_paths_time = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - start_time).count(); -#endif // ENABLE_GCODE_VIEWER_STATISTICS -} -#endif // ENABLE_SPLITTED_VERTEX_BUFFER - -#if ENABLE_SPLITTED_VERTEX_BUFFER void GCodeViewer::render_toolpaths() const { #if ENABLE_FIXED_SCREEN_SIZE_POINT_MARKERS @@ -3875,155 +2668,6 @@ void GCodeViewer::render_toolpaths() const } #endif // ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS } -#else -void GCodeViewer::render_toolpaths() const -{ -#if ENABLE_FIXED_SCREEN_SIZE_POINT_MARKERS - float point_size = 20.0f; -#else - float point_size = 0.8f; -#endif // ENABLE_FIXED_SCREEN_SIZE_POINT_MARKERS - std::array light_intensity = { 0.25f, 0.70f, 0.75f, 0.75f }; - const Camera& camera = wxGetApp().plater()->get_camera(); - double zoom = camera.get_zoom(); - const std::array& viewport = camera.get_viewport(); - float near_plane_height = camera.get_type() == Camera::Perspective ? static_cast(viewport[3]) / (2.0f * static_cast(2.0 * std::tan(0.5 * Geometry::deg2rad(camera.get_fov())))) : - static_cast(viewport[3]) * 0.0005; - - auto set_uniform_color = [](const std::array& color, GLShaderProgram& shader) { - std::array color4 = { color[0], color[1], color[2], 1.0f }; - shader.set_uniform("uniform_color", color4); - }; - - auto render_as_points = [this, zoom, point_size, near_plane_height, set_uniform_color] - (const TBuffer& buffer, unsigned int ibuffer_id, EOptionsColors color_id, GLShaderProgram& shader) { - set_uniform_color(Options_Colors[static_cast(color_id)], 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); - - glsafe(::glEnable(GL_VERTEX_PROGRAM_POINT_SIZE)); - glsafe(::glEnable(GL_POINT_SPRITE)); - - for (const RenderPath& path : buffer.render_paths) { - if (path.ibuffer_id == ibuffer_id) { - glsafe(::glMultiDrawElements(GL_POINTS, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); -#if ENABLE_GCODE_VIEWER_STATISTICS - ++const_cast(&m_statistics)->gl_multi_points_calls_count; -#endif // ENABLE_GCODE_VIEWER_STATISTICS - } - } - - glsafe(::glDisable(GL_POINT_SPRITE)); - glsafe(::glDisable(GL_VERTEX_PROGRAM_POINT_SIZE)); - }; - - auto render_as_lines = [this, light_intensity, set_uniform_color](const TBuffer& buffer, unsigned int ibuffer_id, GLShaderProgram& shader) { - shader.set_uniform("light_intensity", light_intensity); - for (const RenderPath& path : buffer.render_paths) { - if (path.ibuffer_id == ibuffer_id) { - set_uniform_color(path.color, shader); - glsafe(::glMultiDrawElements(GL_LINES, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); -#if ENABLE_GCODE_VIEWER_STATISTICS - ++const_cast(&m_statistics)->gl_multi_lines_calls_count; -#endif // ENABLE_GCODE_VIEWER_STATISTICS - } - } - }; - - auto render_as_triangles = [this, set_uniform_color](const TBuffer& buffer, unsigned int ibuffer_id, GLShaderProgram& shader) { - for (const RenderPath& path : buffer.render_paths) { - if (path.ibuffer_id == ibuffer_id) { - set_uniform_color(path.color, shader); - glsafe(::glMultiDrawElements(GL_TRIANGLES, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_INT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size())); -#if ENABLE_GCODE_VIEWER_STATISTICS - ++const_cast(&m_statistics)->gl_multi_triangles_calls_count; -#endif // ENABLE_GCODE_VIEWER_STATISTICS - } - } - }; - - auto line_width = [](double zoom) { - return (zoom < 5.0) ? 1.0 : (1.0 + 5.0 * (zoom - 5.0) / (100.0 - 5.0)); - }; - - glsafe(::glLineWidth(static_cast(line_width(zoom)))); - - unsigned char begin_id = buffer_id(EMoveType::Retract); - unsigned char end_id = buffer_id(EMoveType::Count); - - for (unsigned char i = begin_id; i < end_id; ++i) { - const TBuffer& buffer = m_buffers[i]; - if (!buffer.visible || !buffer.has_data()) - continue; - - GLShaderProgram* shader = wxGetApp().get_shader(buffer.shader.c_str()); - if (shader != nullptr) { - shader->start_using(); - - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, buffer.vertices.id)); - glsafe(::glVertexPointer(buffer.vertices.position_size_floats(), GL_FLOAT, buffer.vertices.vertex_size_bytes(), (const void*)buffer.vertices.position_offset_size())); - glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); - bool has_normals = buffer.vertices.normal_size_floats() > 0; - if (has_normals) { - glsafe(::glNormalPointer(GL_FLOAT, buffer.vertices.vertex_size_bytes(), (const void*)buffer.vertices.normal_offset_size())); - glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); - } - - for (size_t j = 0; j < buffer.indices.size(); ++j) { - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer.indices[j].id)); - - switch (buffer.render_primitive_type) - { - case TBuffer::ERenderPrimitiveType::Point: - { - EOptionsColors color = EOptionsColors(0); - switch (buffer_type(i)) - { - case EMoveType::Tool_change: { color = EOptionsColors::ToolChanges; break; } - case EMoveType::Color_change: { color = EOptionsColors::ColorChanges; break; } - case EMoveType::Pause_Print: { color = EOptionsColors::PausePrints; break; } - case EMoveType::Custom_GCode: { color = EOptionsColors::CustomGCodes; break; } - case EMoveType::Retract: { color = EOptionsColors::Retractions; break; } - case EMoveType::Unretract: { color = EOptionsColors::Unretractions; break; } - default: { assert(false); break; } - } - render_as_points(buffer, static_cast(j), color, *shader); - break; - } - case TBuffer::ERenderPrimitiveType::Line: - { - render_as_lines(buffer, static_cast(j), *shader); - break; - } - case TBuffer::ERenderPrimitiveType::Triangle: - { - render_as_triangles(buffer, static_cast(j), *shader); - break; - } - } - - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); - } - - if (has_normals) - glsafe(::glDisableClientState(GL_NORMAL_ARRAY)); - - glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); - - shader->stop_using(); - } - } -} -#endif // ENABLE_SPLITTED_VERTEX_BUFFER void GCodeViewer::render_shells() const { @@ -5047,15 +3691,9 @@ void GCodeViewer::log_memory_used(const std::string& label, int64_t additional) } int64_t layers_size = SLIC3R_STDVEC_MEMSIZE(m_layers.get_zs(), double); layers_size += SLIC3R_STDVEC_MEMSIZE(m_layers.get_endpoints(), Layers::Endpoints); -#if ENABLE_SPLITTED_VERTEX_BUFFER BOOST_LOG_TRIVIAL(trace) << label << "(" << format_memsize_MB(additional + paths_size + render_paths_size + layers_size) << ");" << log_memory_info(); -#else - BOOST_LOG_TRIVIAL(trace) << label - << format_memsize_MB(additional + paths_size + render_paths_size + layers_size) - << log_memory_info(); -#endif // ENABLE_SPLITTED_VERTEX_BUFFER } } diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 112c681d4..3386e314e 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -23,17 +23,11 @@ namespace GUI { class GCodeViewer { -#if ENABLE_SPLITTED_VERTEX_BUFFER using IBufferType = unsigned short; -#endif // ENABLE_SPLITTED_VERTEX_BUFFER using Color = std::array; using VertexBuffer = std::vector; -#if ENABLE_SPLITTED_VERTEX_BUFFER using MultiVertexBuffer = std::vector; using IndexBuffer = std::vector; -#else - using IndexBuffer = std::vector; -#endif // ENABLE_SPLITTED_VERTEX_BUFFER using MultiIndexBuffer = std::vector; static const std::vector Extrusion_Role_Colors; @@ -69,24 +63,17 @@ class GCodeViewer }; EFormat format{ EFormat::Position }; -#if ENABLE_SPLITTED_VERTEX_BUFFER // vbos id std::vector vbos; // sizes of the buffers, in bytes, used in export to obj std::vector sizes; -#else - // vbo id - unsigned int id{ 0 }; -#endif // ENABLE_SPLITTED_VERTEX_BUFFER // count of vertices, updated after data are sent to gpu size_t count{ 0 }; size_t data_size_bytes() const { return count * vertex_size_bytes(); } -#if ENABLE_SPLITTED_VERTEX_BUFFER // We set 65536 as max count of vertices inside a vertex buffer to allow // to use unsigned short in place of unsigned int for indices in the index buffer, to save memory size_t max_size_bytes() const { return 65536 * vertex_size_bytes(); } -#endif // ENABLE_SPLITTED_VERTEX_BUFFER size_t vertex_size_floats() const { return position_size_floats() + normal_size_floats(); } size_t vertex_size_bytes() const { return vertex_size_floats() * sizeof(float); } @@ -116,15 +103,10 @@ class GCodeViewer // ibo buffer containing indices data (for lines/triangles) used to render a specific toolpath type struct IBuffer { -#if ENABLE_SPLITTED_VERTEX_BUFFER // id of the associated vertex buffer unsigned int vbo{ 0 }; // ibo id unsigned int ibo{ 0 }; -#else - // ibo id - unsigned int id{ 0 }; -#endif // ENABLE_SPLITTED_VERTEX_BUFFER // count of indices, updated after data are sent to gpu size_t count{ 0 }; @@ -148,7 +130,6 @@ class GCodeViewer Vec3f position{ Vec3f::Zero() }; }; -#if ENABLE_SPLITTED_VERTEX_BUFFER struct Sub_Path { Endpoint first; @@ -158,14 +139,9 @@ class GCodeViewer return first.s_id <= s_id && s_id <= last.s_id; } }; -#endif // ENABLE_SPLITTED_VERTEX_BUFFER EMoveType type{ EMoveType::Noop }; ExtrusionRole role{ erNone }; -#if !ENABLE_SPLITTED_VERTEX_BUFFER - Endpoint first; - Endpoint last; -#endif // !ENABLE_SPLITTED_VERTEX_BUFFER float delta_extruder{ 0.0f }; float height{ 0.0f }; float width{ 0.0f }; @@ -175,12 +151,9 @@ class GCodeViewer float volumetric_rate{ 0.0f }; unsigned char extruder_id{ 0 }; unsigned char cp_color_id{ 0 }; -#if ENABLE_SPLITTED_VERTEX_BUFFER std::vector sub_paths; -#endif // ENABLE_SPLITTED_VERTEX_BUFFER bool matches(const GCodeProcessor::MoveVertex& move) const; -#if ENABLE_SPLITTED_VERTEX_BUFFER size_t vertices_count() const { return sub_paths.empty() ? 0 : sub_paths.back().last.s_id - sub_paths.front().first.s_id + 1; } @@ -202,10 +175,6 @@ class GCodeViewer Endpoint endpoint = { b_id, i_id, s_id, move.position }; sub_paths.push_back({ endpoint , endpoint }); } -#else - size_t vertices_count() const { return last.s_id - first.s_id + 1; } - bool contains(size_t id) const { return first.s_id <= id && id <= last.s_id; } -#endif // ENABLE_SPLITTED_VERTEX_BUFFER }; // Used to batch the indices needed to render the paths @@ -295,7 +264,6 @@ class GCodeViewer // s_id index of first vertex contained in this->vertices void add_path(const GCodeProcessor::MoveVertex& move, unsigned int b_id, size_t i_id, size_t s_id); -#if ENABLE_SPLITTED_VERTEX_BUFFER unsigned int max_vertices_per_segment() const { switch (render_primitive_type) { @@ -308,7 +276,6 @@ class GCodeViewer size_t max_vertices_per_segment_size_floats() const { return vertices.vertex_size_floats() * static_cast(max_vertices_per_segment()); } size_t max_vertices_per_segment_size_bytes() const { return max_vertices_per_segment_size_floats() * sizeof(float); } -#endif // ENABLE_SPLITTED_VERTEX_BUFFER unsigned int indices_per_segment() const { switch (render_primitive_type) { @@ -322,9 +289,7 @@ class GCodeViewer default: { return 0; } } } -#if ENABLE_SPLITTED_VERTEX_BUFFER size_t indices_per_segment_size_bytes() const { return static_cast(indices_per_segment() * sizeof(IBufferType)); } -#endif // ENABLE_SPLITTED_VERTEX_BUFFER #if ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS unsigned int max_indices_per_segment() const { switch (render_primitive_type) @@ -338,24 +303,9 @@ class GCodeViewer size_t max_indices_per_segment_size_bytes() const { return max_indices_per_segment() * sizeof(IBufferType); } #endif // ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS -#if ENABLE_SPLITTED_VERTEX_BUFFER bool has_data() const { return !vertices.vbos.empty() && vertices.vbos.front() != 0 && !indices.empty() && indices.front().ibo != 0; } -#else - unsigned int start_segment_vertex_offset() const { return 0; } - unsigned int end_segment_vertex_offset() const { - switch (render_primitive_type) - { - case ERenderPrimitiveType::Point: { return 0; } - case ERenderPrimitiveType::Line: { return 1; } - case ERenderPrimitiveType::Triangle: { return 36; } // 1st vertex of 13th triangle - default: { return 0; } - } - } - - bool has_data() const { return vertices.id != 0 && !indices.empty() && indices.front().id != 0; } -#endif // ENABLE_SPLITTED_VERTEX_BUFFER }; // helper to render shells @@ -434,11 +384,9 @@ class GCodeViewer size_t first{ 0 }; size_t last{ 0 }; -#if ENABLE_SPLITTED_VERTEX_BUFFER bool operator == (const Endpoints& other) const { return first == other.first && last == other.last; } -#endif // ENABLE_SPLITTED_VERTEX_BUFFER }; private: @@ -464,7 +412,6 @@ class GCodeViewer double get_z_at(unsigned int id) const { return (id < m_zs.size()) ? m_zs[id] : 0.0; } Endpoints get_endpoints_at(unsigned int id) const { return (id < m_endpoints.size()) ? m_endpoints[id] : Endpoints(); } -#if ENABLE_SPLITTED_VERTEX_BUFFER bool operator != (const Layers& other) const { if (m_zs != other.m_zs) return true; @@ -473,7 +420,6 @@ class GCodeViewer return false; } -#endif // ENABLE_SPLITTED_VERTEX_BUFFER }; #if ENABLE_REDUCED_TOOLPATHS_SEGMENT_CAPS @@ -722,9 +668,7 @@ public: void render() const; bool has_data() const { return !m_roles.empty(); } -#if ENABLE_SPLITTED_VERTEX_BUFFER bool can_export_toolpaths() const; -#endif // ENABLE_SPLITTED_VERTEX_BUFFER const BoundingBoxf3& get_paths_bounding_box() const { return m_paths_bounding_box; } const BoundingBoxf3& get_max_bounding_box() const { return m_max_bounding_box; } diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 8873af245..064924c41 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3933,11 +3933,7 @@ void GLCanvas3D::update_tooltip_for_settings_item_in_main_toolbar() bool GLCanvas3D::has_toolpaths_to_export() const { -#if ENABLE_SPLITTED_VERTEX_BUFFER return m_gcode_viewer.can_export_toolpaths(); -#else - return m_gcode_viewer.has_data(); -#endif // ENABLE_SPLITTED_VERTEX_BUFFER } void GLCanvas3D::export_toolpaths_to_obj(const char* filename) const