diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index e03be228d0..505a28335d 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -2582,8 +2582,12 @@ void GCodeProcessorResult::reset() { //BBS: add mutex for protection of gcode result lock(); - moves.clear(); - lines_ends.clear(); + // release rather than clear: these two are sized by the print - one entry per move and one + // per g-code line - and a reset is where the memory is expected to go back to the allocator + // (see BackgroundSlicingProcess::apply()). The capacity would not be reused anyway: the + // result is refilled by move-assigning the processor's own result. + moves = std::vector(); + lines_ends = std::vector(); printable_area = Pointfs(); //BBS: add bed exclude area bed_exclude_area = Pointfs(); diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp index 192a80a43d..a99a5188d6 100644 --- a/src/libslic3r/GCode/GCodeProcessor.hpp +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -369,6 +369,56 @@ class Print; initial_layer_time = other.initial_layer_time; #if ENABLE_GCODE_VIEWER_STATISTICS time = other.time; +#endif + return *this; + } + // Orca: the user-declared copy assignment above suppresses the implicit move assignment, so + // `*result = std::move(processor.extract_result())` used to deep copy 'moves' (one MoveVertex + // per move, gigabytes on a large print) while the source stayed alive. This moves exactly the + // same members as the copy above, with the same omissions, so the members the copy leaves + // untouched on the target are left untouched here too. + GCodeProcessorResult& operator=(GCodeProcessorResult &&other) + { + filename = std::move(other.filename); + id = other.id; + moves = std::move(other.moves); + lines_ends = std::move(other.lines_ends); + printable_area = std::move(other.printable_area); + bed_exclude_area = std::move(other.bed_exclude_area); + wrapping_exclude_area = std::move(other.wrapping_exclude_area); + toolpath_outside = other.toolpath_outside; + label_object_enabled = other.label_object_enabled; + long_retraction_when_cut = other.long_retraction_when_cut; + timelapse_warning_code = other.timelapse_warning_code; + printable_height = other.printable_height; + settings_ids = std::move(other.settings_ids); + filaments_count = other.filaments_count; + extruder_colors = std::move(other.extruder_colors); + filament_diameters = std::move(other.filament_diameters); + filament_densities = std::move(other.filament_densities); + filament_costs = std::move(other.filament_costs); + print_statistics = std::move(other.print_statistics); + custom_gcode_per_print_z = std::move(other.custom_gcode_per_print_z); + spiral_vase_mode = other.spiral_vase_mode; + warnings = std::move(other.warnings); + bed_type = other.bed_type; + gcode_check_result = std::move(other.gcode_check_result); + limit_filament_maps = std::move(other.limit_filament_maps); + filament_printable_reuslt = std::move(other.filament_printable_reuslt); + nozzle_group_result = std::move(other.nozzle_group_result); + extruder_types = std::move(other.extruder_types); + printer_extruder_variant = std::move(other.printer_extruder_variant); + printer_extruder_id = std::move(other.printer_extruder_id); + layer_filaments = std::move(other.layer_filaments); + filament_change_sequence = std::move(other.filament_change_sequence); + used_mixed_filaments = std::move(other.used_mixed_filaments); + nozzle_change_sequence = std::move(other.nozzle_change_sequence); + optimal_assignment = std::move(other.optimal_assignment); + filament_change_count_map = std::move(other.filament_change_count_map); + skippable_part_time = std::move(other.skippable_part_time); + initial_layer_time = other.initial_layer_time; +#if ENABLE_GCODE_VIEWER_STATISTICS + time = other.time; #endif return *this; } diff --git a/src/libvgcode/src/ViewerImpl.cpp b/src/libvgcode/src/ViewerImpl.cpp index 8212717931..e3e106bb59 100644 --- a/src/libvgcode/src/ViewerImpl.cpp +++ b/src/libvgcode/src/ViewerImpl.cpp @@ -883,15 +883,17 @@ void ViewerImpl::reset() m_used_extruders.clear(); m_total_time = { 0.0f, 0.0f }; m_travels_time = { 0.0f, 0.0f }; - m_vertices.clear(); - m_vertices_colors.clear(); // swap rather than clear: these are sized by the print, and a reset means the memory // should go back, not sit reserved until the next load + std::vector().swap(m_vertices); + std::vector().swap(m_vertices_colors); for (std::vector& times : m_layer_start_times) std::vector().swap(times); std::vector().swap(m_layer_first_vertex); std::vector().swap(m_colors_scratch); - m_valid_lines_bitset.clear(); + // BitSet::clear() only zeroes the bits, it keeps the blocks allocated; load() builds a new + // bitset anyway and it is never read while m_vertices is empty + m_valid_lines_bitset = BitSet<>(); #if VGCODE_ENABLE_COG_AND_TOOL_MARKERS m_cog_marker.reset(); #endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS @@ -1812,6 +1814,7 @@ size_t ViewerImpl::get_used_cpu_memory() const ret += sizeof(m_extrusion_roles_colors); ret += sizeof(m_options_colors); ret += STDVEC_MEMSIZE(m_vertices, PathVertex); + ret += STDVEC_MEMSIZE(m_vertices_colors, float); for (const std::vector& times : m_layer_start_times) ret += STDVEC_MEMSIZE(times, float); ret += STDVEC_MEMSIZE(m_layer_first_vertex, uint32_t);