Skip to content

fix: post-process re-parse only updates moves, preserves slicer state (fixes #10528)#10529

Open
adele-with-a-b wants to merge 1 commit intobambulab:masterfrom
adele-with-a-b:pr/post-process-preserve-gcode-result
Open

fix: post-process re-parse only updates moves, preserves slicer state (fixes #10528)#10529
adele-with-a-b wants to merge 1 commit intobambulab:masterfrom
adele-with-a-b:pr/post-process-preserve-gcode-result

Conversation

@adele-with-a-b
Copy link
Copy Markdown
Contributor

@adele-with-a-b adele-with-a-b commented May 3, 2026

Fixes #10528.

PR #9920 (my own, merged as 3722c98a3) introduced a regression: after running post-processing scripts, finalize_gcode() was replacing the entire GCodeProcessorResult with a fresh parse of the G-code text. That clobbers slicer-computed config-derived state (filament_maps, nozzle_group_result, filament_change_sequence, required_nozzle_HRC, nozzle_type, extruder_colors, print_statistics, etc.) — none of which can be reconstructed from G-code text alone.

On H2C/H2D, this broke the send-to-printer flow: SelectMachineDialog::CheckStatusAndShow() reads the now-empty nozzle_group_result and calls ctrl_get_auto_nozzle_mapping() with malformed filament info, which the printer rejects with result="fail", errno=1. Users see:

The printer failed to build the nozzle auto-mapping table { code: 1 }. Please refreash nozzle information.

Single-extruder printers aren't visibly affected because CheckStatusAndShow short-circuits before the mapping query when no right-extruder nozzles are used. State is still being clobbered there too, just not exercised.

Change

Only update the fields that reflect G-code text content (moves, lines_ends). Preserve everything else from the original slicing result:

GCodeProcessorResult&& reparsed = processor.extract_result();
m_gcode_result->moves      = std::move(reparsed.moves);
m_gcode_result->lines_ends = std::move(reparsed.lines_ends);

Rvalue-reference binding rather than value is required — GCodeProcessorResult's copy constructor is implicitly deleted due to a mutable std::mutex member.

This preserves #9920's original goal (preview reflects post-processed toolpaths) while fixing the regression.

Tradeoff worth flagging

This assumes moves and lines_ends are sufficient to make the preview reflect any change a post-process script could make. That's true for scripts that reorder or rewrite extrusion moves within the existing tool-change structure — e.g. BrickLayers. I have not audited the general case.

If a post-process script adds or removes tool changes, fields like filament_change_sequence, print_statistics, and extruder_colors will now stay tied to the pre-post-process sequence rather than the executed G-code. Consequences I can think of: time estimates, flush-weight calculations (GetFlushWeight() reads filament_change_sequence), and any per-extruder visualization in the preview would be stale for the post-processed output.

My view is this is still the right tradeoff relative to the current bug (which makes the send flow completely non-functional on H2C/H2D with any post_process entry), but it's a narrower correctness property than the original #9920 was aiming for. If there's a known use case where post-process scripts alter tool-change structure and the existing time/flush outputs need to reflect that, happy to rework — would likely mean selectively updating more fields rather than the all-or-nothing approach #9920 originally took.

Testing

  • ❌ Before the fix, 2.6.x: any post_process entry on an H2C plate (even a no-op like cat) causes the mapping error.
  • ❌ Before the fix, 2.6.x: same plate without post_process entry works fine.
  • ✅ After the fix: BrickLayers post-process entry on multi-filament H2C plate slices, preview shows post-processed toolpath, Send to Printer succeeds, print runs.
  • ✅ Rolling back to 2.5.3 (cut pre-feat: Re-parse G-code after post-processing scripts for live preview #9920) also works — confirming this is a regression, not a pre-existing issue.

Why this was missed in review

My own #9920 was tested on a single-extruder printer where the clobbered state isn't exercised. The bug only surfaces during the send flow on multi-nozzle (H2C/H2D). I should have verified against an H2C before submitting — won't repeat that.

The previous patch replaced the entire GCodeProcessorResult after running
post-processing scripts, clobbering slicer-computed fields (filament_maps,
nozzle_group_result, filament_change_sequence, required_nozzle_HRC,
nozzle_type, extruder_colors, print_statistics, etc.) that cannot be
reconstructed from G-code text alone.

On H2C/H2D, this caused the send-to-printer flow to send a malformed
get_auto_nozzle_mapping request, which the printer rejected with
result="fail", errno=1, surfacing as:

  'The printer failed to build the nozzle auto-mapping table
   { code: 1 }. Please refreash nozzle information.'

The bug reproduces with ANY post_process entry — even a no-op like
'cat' — because the trigger is the re-parse path, not the script output.

Fix: only copy 'moves' and 'lines_ends' from the re-parsed result into
the existing m_gcode_result. Everything else is preserved. Preview still
reflects the post-processed toolpath; send-to-printer keeps the
slicer-computed nozzle/filament mapping state intact.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Regression in #9920: post-process re-parse clobbers GCodeProcessorResult state, breaks H2C/H2D nozzle auto-mapping

1 participant