From 979a32800d460e039a12a91923872cae4443f386 Mon Sep 17 00:00:00 2001 From: Gabriel Wicke Date: Sun, 17 May 2020 13:21:27 -0700 Subject: [PATCH] Path: LinuxCNC postprocessor scalability - Do not show editor when gcode size exceeds 100kb. The poor editor widget cannot handle that much output, and will hang FreeCAD. - Avoid quadratic behavior in output accumulator. While Python greater than 2.7 avoids quadratic behavior in string accumulators, this optimization is defeated when the string is forced to be materialized to contiguous memory, as was done by the `.trim()`. As a result, we got quadratic complexity, ensuring that large jobs would never successfully be post-processed. --- .../Path/PathScripts/post/linuxcnc_post.py | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/Mod/Path/PathScripts/post/linuxcnc_post.py b/src/Mod/Path/PathScripts/post/linuxcnc_post.py index 5bc9e5cca6..95ae5d289b 100644 --- a/src/Mod/Path/PathScripts/post/linuxcnc_post.py +++ b/src/Mod/Path/PathScripts/post/linuxcnc_post.py @@ -64,7 +64,7 @@ OUTPUT_HEADER = True OUTPUT_LINE_NUMBERS = False SHOW_EDITOR = True MODAL = False # if true commands are suppressed if the same as previous line. -USE_TLO = True # if true G43 will be output following tool changes +USE_TLO = True # if true G43 will be output following tool changes OUTPUT_DOUBLES = True # if false duplicate axis values are suppressed if the same as previous line. COMMAND_SPACE = " " LINENR = 100 # line number starting value @@ -185,7 +185,7 @@ def export(objectslist, filename, argstring): for obj in objectslist: # Skip inactive operations - if hasattr(obj, 'Active'): + if hasattr(obj, 'Active'): if not obj.Active: continue if hasattr(obj, 'Base') and hasattr(obj.Base, 'Active'): @@ -246,7 +246,7 @@ def export(objectslist, filename, argstring): # turn coolant off if required if not coolantMode == 'None': if OUTPUT_COMMENTS: - gcode += linenumber() + '(Coolant Off:' + coolantMode + ')\n' + gcode += linenumber() + '(Coolant Off:' + coolantMode + ')\n' gcode += linenumber() +'M9' + '\n' # do the post_amble @@ -256,13 +256,15 @@ def export(objectslist, filename, argstring): gcode += linenumber() + line if FreeCAD.GuiUp and SHOW_EDITOR: - dia = PostUtils.GCodeEditorDialog() - dia.editor.setText(gcode) - result = dia.exec_() - if result: - final = dia.editor.toPlainText() + final = gcode + if len(gcode) > 100000: + print("Skipping editor since output is greater than 100kb") else: - final = gcode + dia = PostUtils.GCodeEditorDialog() + dia.editor.setText(gcode) + result = dia.exec_() + if result: + final = dia.editor.toPlainText() else: final = gcode @@ -389,7 +391,9 @@ def parse(pathobj): # append the line to the final output for w in outstring: out += w + COMMAND_SPACE - out = out.strip() + "\n" + # Note: Do *not* strip `out`, since that forces the allocation + # of a contiguous string & thus quadratic complexity. + out += "\n" return out