diff --git a/lib/python/rs274/glcanon.py b/lib/python/rs274/glcanon.py index 2d329f92567..c20a6cbf51e 100644 --- a/lib/python/rs274/glcanon.py +++ b/lib/python/rs274/glcanon.py @@ -132,6 +132,8 @@ def __init__(self, colors, geometry, is_foam=0, foam_w=1.5, foam_z=0.0): self.min_extents_notool_zero_rxy = [9e99,9e99,9e99] self.max_extents_notool_zero_rxy = [-9e99,-9e99,-9e99] self.colors = colors + # Set if the parse was aborted, so the extents above are only partial. + self.preview_incomplete = False self.in_arc = 0 self.xo = self.yo = self.zo = self.ao = self.bo = self.co = self.uo = self.vo = self.wo = 0 self.dwell_time = 0 @@ -706,9 +708,10 @@ def __init__(self, s=None, lp=None, g=None): # the cap is left as it behaves rather than as it was described. self.max_file_size = min(system_memory_gb, 20) * 1024 * 1024 - #: Name of the file the size limit last refused, so that the refusal is - #: reported once instead of on every frame. See _resolve_show_program. - self._refused_file = None + #: Set once per load in load_preview() when the file exceeds the size + #: limit; _resolve_show_program() reads it instead of re-stat'ing the + #: file on every frame. + self.preview_too_large = False try: if os.environ["INI_FILE_NAME"]: @@ -1274,26 +1277,12 @@ def redraw(self): def _resolve_show_program(self): """get_show_program(), refused for a file too large to preview. - Called from frame_context(), so this runs once per frame - which is why - the refusal is latched on the file it refused rather than logged where - it is decided. Unlatched, a single over-size file produces a warning per - redraw for as long as it stays loaded. Latching on the name and not on a - bool means a different over-size file still reports. + The size decision is made once per load in load_preview(); this only + reads the flag, so no file is stat'ed per frame. """ - show_program = self.get_show_program() - s = self.stat - if (os.path.exists(s.file) - and 0 < self.max_file_size < os.stat(s.file).st_size): - if self._refused_file != s.file: - self._refused_file = s.file - log.warning("%s is larger than the %.0f MB preview limit; " - "preview disabled for it", - s.file, self.max_file_size / (1024 * 1024)) + if self.preview_too_large: return False - # Cleared rather than left set, so that loading a small file and then - # coming back to the big one reports it again. - self._refused_file = None - return show_program + return self.get_show_program() def lathe_historical_config(self,trajcoordinates): # detect historical lathe config with dummy joint 1 @@ -1464,7 +1453,16 @@ def extents_info(self): def load_preview(self, f, canon, *args): self.set_canon(canon) - result, seq = gcode.parse(f, canon, *args) + self.preview_too_large = False + canon.preview_incomplete = False + try: + result, seq = gcode.parse(f, canon, *args) + except KeyboardInterrupt: + # Aborted parse: extents cover only the parsed portion. Flag it so + # callers do not treat the partial check as complete. + canon.preview_incomplete = True + canon.calc_extents() + raise if result <= gcode.MIN_ERROR: self.canon.progress.nextphase(1) @@ -1472,6 +1470,16 @@ def load_preview(self, f, canon, *args): self.stale_dlist('program_rapids') self.stale_dlist('program_norapids') + # Parsed fully (extents and the run-time limit check stay valid); only + # drawing is suppressed. + if 0 < self.max_file_size and os.path.exists(f) \ + and self.max_file_size < os.stat(f).st_size: + self.preview_too_large = True + log.warning("%s is larger than the %.0f MB preview limit; " + "preview disabled for it. The program still runs, " + "but without a graphical extents check.", + f, self.max_file_size / (1024 * 1024)) + return result, seq def from_internal_units(self, pos, unit=None): diff --git a/src/emc/usr_intf/axis/scripts/axis.py b/src/emc/usr_intf/axis/scripts/axis.py index 8ccf6b1e73f..f9f04cc72a5 100755 --- a/src/emc/usr_intf/axis/scripts/axis.py +++ b/src/emc/usr_intf/axis/scripts/axis.py @@ -1893,6 +1893,11 @@ def run_warn(): if o.canon.max_extents_notool[i] > machine_limit_max[i]: warnings.append(_("Program exceeds machine maximum on axis %s") % "XYZABCUVW"[i]) + # A truncated preview only checked part of the program; warn rather + # than imply a clean all-clear. + if getattr(o.canon, "preview_incomplete", False): + warnings.append(_("G-code preview was truncated before completion; " + "machine limits could not be fully checked.")) if warnings: text = "\n".join(warnings) return int(root_window.tk.call("nf_dialog", ".error",