From db862ae84258023af015e0fc75de581f453f7ad4 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 18 Jan 2021 13:55:45 +0100 Subject: ENABLE_SPLITTED_VERTEX_BUFFER - slightly faster indices buffers generation in GCodeViewer::load_toolpaths() --- src/slic3r/GUI/GCodeViewer.cpp | 124 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 123 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 006572235..61c34d25c 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -1282,6 +1282,128 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) last_path.sub_paths.back().last = { vbuffer_id, vertices.size(), move_id, curr.position }; }; + auto add_indices_as_solid = [](const GCodeProcessor::MoveVertex& prev, const GCodeProcessor::MoveVertex& curr, TBuffer& buffer, + size_t& vbuffer_size, unsigned int ibuffer_id, IndexBuffer& indices, size_t move_id) { + static Vec3f prev_dir; + static Vec3f prev_up; + static float sq_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); + }; + auto store_main_triangles = [&](IndexBuffer& indices, size_t vbuffer_size, const std::array& v_offsets) { + std::array v_ids; + for (size_t i = 0; i < v_ids.size(); ++i) { + v_ids[i] = static_cast(static_cast(vbuffer_size) + v_offsets[i]); + } + + // triangles starting cap + store_triangle(indices, v_ids[0], v_ids[2], v_ids[1]); + store_triangle(indices, v_ids[0], v_ids[3], v_ids[2]); + + // triangles sides + store_triangle(indices, v_ids[0], v_ids[1], v_ids[4]); + store_triangle(indices, v_ids[1], v_ids[5], v_ids[4]); + store_triangle(indices, v_ids[1], v_ids[2], v_ids[5]); + store_triangle(indices, v_ids[2], v_ids[6], v_ids[5]); + store_triangle(indices, v_ids[2], v_ids[3], v_ids[6]); + store_triangle(indices, v_ids[3], v_ids[7], v_ids[6]); + store_triangle(indices, v_ids[3], v_ids[0], v_ids[7]); + store_triangle(indices, v_ids[0], v_ids[4], v_ids[7]); + + // triangles ending cap + store_triangle(indices, v_ids[4], v_ids[6], v_ids[7]); + store_triangle(indices, v_ids[4], v_ids[5], v_ids[6]); + }; + + if (prev.type != curr.type || !buffer.paths.back().matches(curr)) { + buffer.add_path(curr, ibuffer_id, indices.size(), move_id - 1); + buffer.paths.back().sub_paths.back().first.position = prev.position; + } + + Path& last_path = buffer.paths.back(); + + Vec3f dir = (curr.position - prev.position).normalized(); + Vec3f right = Vec3f(dir[1], -dir[0], 0.0f).normalized(); + Vec3f up = right.cross(dir); + float sq_length = (curr.position - prev.position).squaredNorm(); + + if (last_path.vertices_count() == 1 || vbuffer_size == 0) { + // 1st segment or restart into a new vertex buffer + // =============================================== + // dummy triangles outer corner cap + append_dummy_cap(indices, vbuffer_size); + + // stem triangles + store_main_triangles(indices, vbuffer_size, { 0, 1, 2, 3, 4, 5, 6, 7 }); + + vbuffer_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(); + float half_width = 0.5f * last_path.width; + displacement = half_width * ::tan(::acos(std::clamp(dir.dot(med_dir), -1.0f, 1.0f))); + } + + float sq_displacement = sqr(displacement); + bool can_displace = displacement > 0.0f && sq_displacement < sq_prev_length && sq_displacement < sq_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 && can_displace) { + if (is_right_turn) + left_displaced = true; + else + right_displaced = true; + } + + // triangles outer corner cap + if (is_right_turn) { + if (left_displaced) + // dummy triangles + append_dummy_cap(indices, vbuffer_size); + else { + store_triangle(indices, vbuffer_size - 4, vbuffer_size + 1, vbuffer_size - 1); + store_triangle(indices, vbuffer_size + 1, vbuffer_size - 2, vbuffer_size - 1); + } + } + else { + if (right_displaced) + // dummy triangles + append_dummy_cap(indices, vbuffer_size); + else { + store_triangle(indices, vbuffer_size - 4, vbuffer_size - 3, vbuffer_size + 0); + store_triangle(indices, vbuffer_size - 3, vbuffer_size - 2, vbuffer_size + 0); + } + } + + // stem triangles + store_main_triangles(indices, vbuffer_size, { -4, 0, -2, 1, 2, 3, 4, 5 }); + + vbuffer_size += 6; + } + + last_path.sub_paths.back().last = { ibuffer_id, indices.size() - 1, move_id, curr.position }; + prev_dir = dir; + prev_up = up; + sq_prev_length = sq_length; + }; #else 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; @@ -1430,7 +1552,6 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) prev_up = up; prev_length = length; }; -#endif // ENABLE_TOOLPATHS_ALTERNATE_SMOOTHING auto add_indices_as_solid = [](const GCodeProcessor::MoveVertex& prev, const GCodeProcessor::MoveVertex& curr, TBuffer& buffer, size_t& vbuffer_size, unsigned int ibuffer_id, IndexBuffer& indices, size_t move_id) { static Vec3f prev_dir; @@ -1568,6 +1689,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) prev_up = up; prev_length = length; }; +#endif // ENABLE_TOOLPATHS_ALTERNATE_SMOOTHING #if ENABLE_GCODE_VIEWER_STATISTICS auto start_time = std::chrono::high_resolution_clock::now(); -- cgit v1.2.3