Loading a large G-code file in AXIS spams the terminal every frame with File too large to load, disabling preview. Digging in turned up bigger problems with the GRAPHICAL_MAX_FILE_SIZE gate. I would like agreement on direction before a PR.
The bug
The check is in GlCanonDraw.redraw() (glcanon.py:1321), which runs every frame:
- Prints on every repaint (spam) and re-stats the file on disk each frame.
- Only suppresses drawing.
load_preview parses the whole file regardless, so it saves nothing on load; it pays the full parse, then refuses to draw.
- Shrinking the file on disk flips the gate back on and draws stale geometry until reload.
Original design in PR #2896 checked size once at load, logged once, and had a disable_preview magic comment. The centralization into glcanon dropped both.
Two things that make this more than a cosmetic fix
1. File size is a weak proxy. A few-KB program with while loops or subroutine calls can emit millions of segments; a 30 MB linear file is cheap. The shared canon GLCanon already sees every segment via its feed/traverse callbacks, so a segment-count limit there would be accurate and shared by all GUIs.
2. The preview parse feeds the run-time limit check. AXIS's run_warn() (axis.py:1892) compares program extents to soft limits before every run. Those extents come from calc_extents() during the preview parse. So:
- The current byte gate parses fully, so
run_warn still works.
- Any parse abort (to save load time or stop a runaway
while) skips calc_extents => stale extents => run_warn silently gives a false "all clear." Real safety regression.
Fundamental tension: saving parse time means not knowing the extents of the skipped code, which means no run_warn.
Decisions to discuss
- Move the gate out of
redraw() into the shared load/canon path (kills spam + per-frame stat). Small, safe, backportable. Any objection?
- Segment count vs file size as the metric. Worth the change?
- Soft cap vs hard abort. Soft (parse fully, just stop drawing/keeping GL lists) preserves
run_warn; hard (abort parse) saves time and stops runaway loops but voids run_warn unless we also make run_warn treat truncated extents as "unknown." Which do we want as default?
- Auto-skip vs ask. Instead of silently disabling, prompt the operator ("large file: load full preview / skip"). AXIS can do this live (and "skip" can abort a runaway
while); other UIs can only do post-parse or a logged message. Acceptable to have per-UI behavior?
- Restore the
disable_preview magic comment as the explicit in-file opt-out, plus an INI off-switch?
My lean: 1 + 2 + soft cap default + magic comment, with the ask-dialog where the toolkit allows. Happy to PR once there's rough consensus.
cc @satiowadahc @c-morley (original PR #2896)
Loading a large G-code file in AXIS spams the terminal every frame with
File too large to load, disabling preview.Digging in turned up bigger problems with theGRAPHICAL_MAX_FILE_SIZEgate. I would like agreement on direction before a PR.The bug
The check is in
GlCanonDraw.redraw()(glcanon.py:1321), which runs every frame:load_previewparses the whole file regardless, so it saves nothing on load; it pays the full parse, then refuses to draw.Original design in PR #2896 checked size once at load, logged once, and had a
disable_previewmagic comment. The centralization into glcanon dropped both.Two things that make this more than a cosmetic fix
1. File size is a weak proxy. A few-KB program with
whileloops or subroutine calls can emit millions of segments; a 30 MB linear file is cheap. The shared canonGLCanonalready sees every segment via its feed/traverse callbacks, so a segment-count limit there would be accurate and shared by all GUIs.2. The preview parse feeds the run-time limit check. AXIS's
run_warn()(axis.py:1892) compares program extents to soft limits before every run. Those extents come fromcalc_extents()during the preview parse. So:run_warnstill works.while) skipscalc_extents=> stale extents =>run_warnsilently gives a false "all clear." Real safety regression.Fundamental tension: saving parse time means not knowing the extents of the skipped code, which means no
run_warn.Decisions to discuss
redraw()into the shared load/canon path (kills spam + per-frame stat). Small, safe, backportable. Any objection?run_warn; hard (abort parse) saves time and stops runaway loops but voidsrun_warnunless we also makerun_warntreat truncated extents as "unknown." Which do we want as default?while); other UIs can only do post-parse or a logged message. Acceptable to have per-UI behavior?disable_previewmagic comment as the explicit in-file opt-out, plus an INI off-switch?My lean: 1 + 2 + soft cap default + magic comment, with the ask-dialog where the toolkit allows. Happy to PR once there's rough consensus.
cc @satiowadahc @c-morley (original PR #2896)