mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-10-03 05:41:10 +00:00
Move the G-code processing result instead of copying it
GCodeProcessorResult declares a copy assignment, which suppresses the implicit move assignment, so `*result = std::move(processor.extract_result())` binds to the copy and duplicates the whole moves array: 96 bytes per move, measured at 147.7 MiB in one allocation for a 597k facet model at 0.08 mm, with the source staying alive until the export returns. Add the move assignment. It assigns exactly the same 39 members in the same order as the copy, including the ones the copy deliberately leaves alone, so a target that carries its own filament maps and nozzle type keeps them. A move constructor is intentionally not added: the type holds a std::mutex, so it is neither copy nor move constructible today and a partial one would leave ten members uninitialised. reset() now releases the two print sized vectors rather than clearing them. Its callers are the paths that discard a result, so the memory went back only at the next slice. ViewerImpl::reset() does the same for the two vectors sized by the print, which is what keeps a discarded preview resident, and counts m_vertices_colors in the reported CPU memory, where it was missing.
This commit is contained in:
@@ -2582,8 +2582,12 @@ void GCodeProcessorResult::reset() {
|
|||||||
//BBS: add mutex for protection of gcode result
|
//BBS: add mutex for protection of gcode result
|
||||||
lock();
|
lock();
|
||||||
|
|
||||||
moves.clear();
|
// release rather than clear: these two are sized by the print - one entry per move and one
|
||||||
lines_ends.clear();
|
// 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<MoveVertex>();
|
||||||
|
lines_ends = std::vector<size_t>();
|
||||||
printable_area = Pointfs();
|
printable_area = Pointfs();
|
||||||
//BBS: add bed exclude area
|
//BBS: add bed exclude area
|
||||||
bed_exclude_area = Pointfs();
|
bed_exclude_area = Pointfs();
|
||||||
|
|||||||
@@ -369,6 +369,56 @@ class Print;
|
|||||||
initial_layer_time = other.initial_layer_time;
|
initial_layer_time = other.initial_layer_time;
|
||||||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
#if ENABLE_GCODE_VIEWER_STATISTICS
|
||||||
time = other.time;
|
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
|
#endif
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -883,15 +883,17 @@ void ViewerImpl::reset()
|
|||||||
m_used_extruders.clear();
|
m_used_extruders.clear();
|
||||||
m_total_time = { 0.0f, 0.0f };
|
m_total_time = { 0.0f, 0.0f };
|
||||||
m_travels_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
|
// 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
|
// should go back, not sit reserved until the next load
|
||||||
|
std::vector<PathVertex>().swap(m_vertices);
|
||||||
|
std::vector<float>().swap(m_vertices_colors);
|
||||||
for (std::vector<float>& times : m_layer_start_times)
|
for (std::vector<float>& times : m_layer_start_times)
|
||||||
std::vector<float>().swap(times);
|
std::vector<float>().swap(times);
|
||||||
std::vector<uint32_t>().swap(m_layer_first_vertex);
|
std::vector<uint32_t>().swap(m_layer_first_vertex);
|
||||||
std::vector<float>().swap(m_colors_scratch);
|
std::vector<float>().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
|
#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||||
m_cog_marker.reset();
|
m_cog_marker.reset();
|
||||||
#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
#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_extrusion_roles_colors);
|
||||||
ret += sizeof(m_options_colors);
|
ret += sizeof(m_options_colors);
|
||||||
ret += STDVEC_MEMSIZE(m_vertices, PathVertex);
|
ret += STDVEC_MEMSIZE(m_vertices, PathVertex);
|
||||||
|
ret += STDVEC_MEMSIZE(m_vertices_colors, float);
|
||||||
for (const std::vector<float>& times : m_layer_start_times)
|
for (const std::vector<float>& times : m_layer_start_times)
|
||||||
ret += STDVEC_MEMSIZE(times, float);
|
ret += STDVEC_MEMSIZE(times, float);
|
||||||
ret += STDVEC_MEMSIZE(m_layer_first_vertex, uint32_t);
|
ret += STDVEC_MEMSIZE(m_layer_first_vertex, uint32_t);
|
||||||
|
|||||||
Reference in New Issue
Block a user