diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index 6b4274b11..8e7fba126 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -76,6 +76,8 @@ #define ENABLE_RELOAD_FROM_DISK_REWORK (1 && ENABLE_2_5_0_ALPHA1) // Enable showing toolpaths center of gravity #define ENABLE_SHOW_TOOLPATHS_COG (1 && ENABLE_2_5_0_ALPHA1) +// Enable recalculating toolpaths when switching to/from volumetric rate visualization +#define ENABLE_VOLUMETRIC_RATE_TOOLPATHS_RECALC (1 && ENABLE_2_5_0_ALPHA1) #endif // _prusaslicer_technologies_h_ diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index a4808a0cf..d54c28293 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -103,7 +103,11 @@ void GCodeViewer::IBuffer::reset() count = 0; } +#if ENABLE_VOLUMETRIC_RATE_TOOLPATHS_RECALC +bool GCodeViewer::Path::matches(const GCodeProcessorResult::MoveVertex& move, bool account_for_volumetric_rate) const +#else bool GCodeViewer::Path::matches(const GCodeProcessorResult::MoveVertex& move) const +#endif // ENABLE_VOLUMETRIC_RATE_TOOLPATHS_RECALC { auto matches_percent = [](float value1, float value2, float max_percent) { return std::abs(value2 - value1) / value1 <= max_percent; @@ -120,10 +124,22 @@ bool GCodeViewer::Path::matches(const GCodeProcessorResult::MoveVertex& move) co case EMoveType::Seam: case EMoveType::Extrude: { // use rounding to reduce the number of generated paths +#if ENABLE_VOLUMETRIC_RATE_TOOLPATHS_RECALC + if (account_for_volumetric_rate) + return type == move.type && extruder_id == move.extruder_id && cp_color_id == move.cp_color_id && role == move.extrusion_role && + move.position.z() <= sub_paths.front().first.position.z() && feedrate == move.feedrate && fan_speed == move.fan_speed && + height == round_to_bin(move.height) && width == round_to_bin(move.width) && + matches_percent(volumetric_rate, move.volumetric_rate(), 0.001f); + else + return type == move.type && extruder_id == move.extruder_id && cp_color_id == move.cp_color_id && role == move.extrusion_role && + move.position.z() <= sub_paths.front().first.position.z() && feedrate == move.feedrate && fan_speed == move.fan_speed && + height == round_to_bin(move.height) && width == round_to_bin(move.width); +#else return type == move.type && extruder_id == move.extruder_id && cp_color_id == move.cp_color_id && role == move.extrusion_role && move.position.z() <= sub_paths.front().first.position.z() && feedrate == move.feedrate && fan_speed == move.fan_speed && height == round_to_bin(move.height) && width == round_to_bin(move.width) && matches_percent(volumetric_rate, move.volumetric_rate(), 0.05f); +#endif // ENABLE_VOLUMETRIC_RATE_TOOLPATHS_RECALC } case EMoveType::Travel: { return type == move.type && feedrate == move.feedrate && extruder_id == move.extruder_id && cp_color_id == move.cp_color_id; @@ -698,10 +714,19 @@ void GCodeViewer::init() void GCodeViewer::load(const GCodeProcessorResult& gcode_result, const Print& print, bool initialized) { // avoid processing if called with the same gcode_result +#if ENABLE_VOLUMETRIC_RATE_TOOLPATHS_RECALC + if (m_last_result_id == gcode_result.id && + (m_last_view_type == m_view_type || (m_last_view_type != EViewType::VolumetricRate && m_view_type != EViewType::VolumetricRate))) + return; +#else if (m_last_result_id == gcode_result.id) return; +#endif // ENABLE_VOLUMETRIC_RATE_TOOLPATHS_RECALC m_last_result_id = gcode_result.id; +#if ENABLE_VOLUMETRIC_RATE_TOOLPATHS_RECALC + m_last_view_type = m_view_type; +#endif // ENABLE_VOLUMETRIC_RATE_TOOLPATHS_RECALC // release gpu memory, if used reset(); @@ -1266,9 +1291,15 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result) // add current vertex add_vertex(curr); }; +#if ENABLE_VOLUMETRIC_RATE_TOOLPATHS_RECALC + auto add_indices_as_line = [](const GCodeProcessorResult::MoveVertex& prev, const GCodeProcessorResult::MoveVertex& curr, TBuffer& buffer, + unsigned int ibuffer_id, IndexBuffer& indices, size_t move_id, bool account_for_volumetric_rate) { + if (buffer.paths.empty() || prev.type != curr.type || !buffer.paths.back().matches(curr, account_for_volumetric_rate)) { +#else auto add_indices_as_line = [](const GCodeProcessorResult::MoveVertex& prev, const GCodeProcessorResult::MoveVertex& curr, TBuffer& buffer, unsigned int ibuffer_id, IndexBuffer& indices, size_t move_id) { if (buffer.paths.empty() || prev.type != curr.type || !buffer.paths.back().matches(curr)) { +#endif // ENABLE_VOLUMETRIC_RATE_TOOLPATHS_RECALC // add starting index indices.push_back(static_cast(indices.size())); buffer.add_path(curr, ibuffer_id, indices.size() - 1, move_id - 1); @@ -1287,7 +1318,13 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result) }; // format data into the buffers to be rendered as solid - auto add_vertices_as_solid = [](const GCodeProcessorResult::MoveVertex& prev, const GCodeProcessorResult::MoveVertex& curr, TBuffer& buffer, unsigned int vbuffer_id, VertexBuffer& vertices, size_t move_id) { +#if ENABLE_VOLUMETRIC_RATE_TOOLPATHS_RECALC + auto add_vertices_as_solid = [](const GCodeProcessorResult::MoveVertex& prev, const GCodeProcessorResult::MoveVertex& curr, TBuffer& buffer, + unsigned int vbuffer_id, VertexBuffer& vertices, size_t move_id, bool account_for_volumetric_rate) { +#else + auto add_vertices_as_solid = [](const GCodeProcessorResult::MoveVertex& prev, const GCodeProcessorResult::MoveVertex& curr, TBuffer& buffer, + unsigned int vbuffer_id, VertexBuffer& vertices, size_t move_id) { +#endif // ENABLE_VOLUMETRIC_RATE_TOOLPATHS_RECALC auto store_vertex = [](VertexBuffer& vertices, const Vec3f& position, const Vec3f& normal) { // append position vertices.push_back(position.x()); @@ -1299,7 +1336,11 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result) vertices.push_back(normal.z()); }; +#if ENABLE_VOLUMETRIC_RATE_TOOLPATHS_RECALC + if (buffer.paths.empty() || prev.type != curr.type || !buffer.paths.back().matches(curr, account_for_volumetric_rate)) { +#else if (buffer.paths.empty() || prev.type != curr.type || !buffer.paths.back().matches(curr)) { +#endif // ENABLE_VOLUMETRIC_RATE_TOOLPATHS_RECALC buffer.add_path(curr, vbuffer_id, vertices.size(), move_id - 1); buffer.paths.back().sub_paths.back().first.position = prev.position; } @@ -1344,8 +1385,15 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result) last_path.sub_paths.back().last = { vbuffer_id, vertices.size(), move_id, curr.position }; }; - auto add_indices_as_solid = [&](const GCodeProcessorResult::MoveVertex& prev, const GCodeProcessorResult::MoveVertex& curr, const GCodeProcessorResult::MoveVertex* next, - TBuffer& buffer, size_t& vbuffer_size, unsigned int ibuffer_id, IndexBuffer& indices, size_t move_id) { +#if ENABLE_VOLUMETRIC_RATE_TOOLPATHS_RECALC + auto add_indices_as_solid = [&](const GCodeProcessorResult::MoveVertex& prev, const GCodeProcessorResult::MoveVertex& curr, + const GCodeProcessorResult::MoveVertex* next, TBuffer& buffer, size_t& vbuffer_size, unsigned int ibuffer_id, + IndexBuffer& indices, size_t move_id, bool account_for_volumetric_rate) { +#else + auto add_indices_as_solid = [&](const GCodeProcessorResult::MoveVertex& prev, const GCodeProcessorResult::MoveVertex& curr, + const GCodeProcessorResult::MoveVertex* next, TBuffer& buffer, size_t& vbuffer_size, unsigned int ibuffer_id, + IndexBuffer& indices, size_t move_id) { +#endif // ENABLE_VOLUMETRIC_RATE_TOOLPATHS_RECALC static Vec3f prev_dir; static Vec3f prev_up; static float sq_prev_length; @@ -1390,7 +1438,11 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result) store_triangle(indices, v_offsets[4], v_offsets[5], v_offsets[6]); }; +#if ENABLE_VOLUMETRIC_RATE_TOOLPATHS_RECALC + if (buffer.paths.empty() || prev.type != curr.type || !buffer.paths.back().matches(curr, account_for_volumetric_rate)) { +#else if (buffer.paths.empty() || prev.type != curr.type || !buffer.paths.back().matches(curr)) { +#endif // ENABLE_VOLUMETRIC_RATE_TOOLPATHS_RECALC buffer.add_path(curr, ibuffer_id, indices.size(), move_id - 1); buffer.paths.back().sub_paths.back().first.position = prev.position; } @@ -1474,7 +1526,11 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result) vbuffer_size += 6; } +#if ENABLE_VOLUMETRIC_RATE_TOOLPATHS_RECALC + if (next != nullptr && (curr.type != next->type || !last_path.matches(*next, account_for_volumetric_rate))) +#else if (next != nullptr && (curr.type != next->type || !last_path.matches(*next))) +#endif // ENABLE_VOLUMETRIC_RATE_TOOLPATHS_RECALC // ending cap triangles append_ending_cap_triangles(indices, is_first_segment ? first_seg_v_offsets : non_first_seg_v_offsets); @@ -1614,6 +1670,10 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result) m_sequential_view.gcode_ids.push_back(move.gcode_id); } +#if ENABLE_VOLUMETRIC_RATE_TOOLPATHS_RECALC + bool account_for_volumetric_rate = m_view_type == EViewType::VolumetricRate; +#endif // ENABLE_VOLUMETRIC_RATE_TOOLPATHS_RECALC + std::vector vertices(m_buffers.size()); std::vector indices(m_buffers.size()); std::vector instances(m_buffers.size()); @@ -1678,7 +1738,11 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result) v_multibuffer.push_back(VertexBuffer()); if (t_buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::Triangle) { Path& last_path = t_buffer.paths.back(); +#if ENABLE_VOLUMETRIC_RATE_TOOLPATHS_RECALC + if (prev.type == curr.type && last_path.matches(curr, account_for_volumetric_rate)) +#else if (prev.type == curr.type && last_path.matches(curr)) +#endif // ENABLE_VOLUMETRIC_RATE_TOOLPATHS_RECALC last_path.add_sub_path(prev, static_cast(v_multibuffer.size()) - 1, 0, move_id - 1); } } @@ -1689,7 +1753,11 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result) { 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(v_multibuffer.size()) - 1, v_buffer, move_id, account_for_volumetric_rate); break; } +#else case TBuffer::ERenderPrimitiveType::Triangle: { add_vertices_as_solid(prev, curr, t_buffer, static_cast(v_multibuffer.size()) - 1, v_buffer, move_id); break; } +#endif // ENABLE_VOLUMETRIC_RATE_TOOLPATHS_RECALC case TBuffer::ERenderPrimitiveType::InstancedModel: { add_model_instance(curr, inst_buffer, inst_id_buffer, move_id); @@ -2053,12 +2121,20 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result) break; } case TBuffer::ERenderPrimitiveType::Line: { +#if ENABLE_VOLUMETRIC_RATE_TOOLPATHS_RECALC + add_indices_as_line(prev, curr, t_buffer, static_cast(i_multibuffer.size()) - 1, i_buffer, move_id, account_for_volumetric_rate); +#else add_indices_as_line(prev, curr, t_buffer, static_cast(i_multibuffer.size()) - 1, i_buffer, move_id); +#endif // ENABLE_VOLUMETRIC_RATE_TOOLPATHS_RECALC curr_vertex_buffer.second += t_buffer.max_vertices_per_segment(); break; } case TBuffer::ERenderPrimitiveType::Triangle: { +#if ENABLE_VOLUMETRIC_RATE_TOOLPATHS_RECALC + add_indices_as_solid(prev, curr, next, t_buffer, curr_vertex_buffer.second, static_cast(i_multibuffer.size()) - 1, i_buffer, move_id, account_for_volumetric_rate); +#else add_indices_as_solid(prev, curr, next, t_buffer, curr_vertex_buffer.second, static_cast(i_multibuffer.size()) - 1, i_buffer, move_id); +#endif // ENABLE_VOLUMETRIC_RATE_TOOLPATHS_RECALC break; } case TBuffer::ERenderPrimitiveType::BatchedModel: { diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 22e866fe6..b2b0626d5 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -212,7 +212,11 @@ class GCodeViewer unsigned char cp_color_id{ 0 }; std::vector sub_paths; +#if ENABLE_VOLUMETRIC_RATE_TOOLPATHS_RECALC + bool matches(const GCodeProcessorResult::MoveVertex& move, bool account_for_volumetric_rate) const; +#else bool matches(const GCodeProcessorResult::MoveVertex& move) const; +#endif // ENABLE_VOLUMETRIC_RATE_TOOLPATHS_RECALC size_t vertices_count() const { return sub_paths.empty() ? 0 : sub_paths.back().last.s_id - sub_paths.front().first.s_id + 1; } @@ -762,6 +766,9 @@ public: private: bool m_gl_data_initialized{ false }; unsigned int m_last_result_id{ 0 }; +#if ENABLE_VOLUMETRIC_RATE_TOOLPATHS_RECALC + EViewType m_last_view_type{ EViewType::Count }; +#endif // ENABLE_VOLUMETRIC_RATE_TOOLPATHS_RECALC size_t m_moves_count{ 0 }; std::vector m_buffers{ static_cast(EMoveType::Extrude) }; // bounding box of toolpaths