From 58193d1e2fbf7a7db3f2348406d03a5893a9197f Mon Sep 17 00:00:00 2001 From: LarryWoestman Date: Sat, 23 Jul 2022 16:23:27 -0700 Subject: [PATCH] Path: Refactored PostUtilsParse.parse a lot. --- src/Mod/Path/Path/Post/UtilsArguments.py | 4 +- src/Mod/Path/Path/Post/UtilsExport.py | 74 +--- src/Mod/Path/Path/Post/UtilsParse.py | 537 +++++++++++------------ 3 files changed, 279 insertions(+), 336 deletions(-) diff --git a/src/Mod/Path/Path/Post/UtilsArguments.py b/src/Mod/Path/Path/Post/UtilsArguments.py index 923de4b4dd..f458293550 100644 --- a/src/Mod/Path/Path/Post/UtilsArguments.py +++ b/src/Mod/Path/Path/Post/UtilsArguments.py @@ -413,8 +413,8 @@ def init_shared_values(values): # values["OUTPUT_COMMENTS"] = True # - # if False duplicate axis values are suppressed if they are the same - # as the previous line. + # if False duplicate axis values or feeds are suppressed + # if they are the same as the previous line. # values["OUTPUT_DOUBLES"] = True # diff --git a/src/Mod/Path/Path/Post/UtilsExport.py b/src/Mod/Path/Path/Post/UtilsExport.py index 3b76e7dd3f..125c5c19b8 100644 --- a/src/Mod/Path/Path/Post/UtilsExport.py +++ b/src/Mod/Path/Path/Post/UtilsExport.py @@ -82,25 +82,20 @@ def export_common(values, objectslist, filename): # write header if values["OUTPUT_HEADER"]: - comment = PostUtilsParse.create_comment( - "Exported by FreeCAD", values["COMMENT_SYMBOL"] - ) + comment = PostUtilsParse.create_comment(values, "Exported by FreeCAD") gcode += f"{PostUtilsParse.linenumber(values)}{comment}{nl}" comment = PostUtilsParse.create_comment( - f'Post Processor: {values["POSTPROCESSOR_FILE_NAME"]}', - values["COMMENT_SYMBOL"], + values, f'Post Processor: {values["POSTPROCESSOR_FILE_NAME"]}' ) gcode += f"{PostUtilsParse.linenumber(values)}{comment}{nl}" if FreeCAD.ActiveDocument: cam_file = os.path.basename(FreeCAD.ActiveDocument.FileName) else: cam_file = "" - comment = PostUtilsParse.create_comment( - f"Cam File: {cam_file}", values["COMMENT_SYMBOL"] - ) + comment = PostUtilsParse.create_comment(values, f"Cam File: {cam_file}") gcode += f"{PostUtilsParse.linenumber(values)}{comment}{nl}" comment = PostUtilsParse.create_comment( - f"Output Time: {str(datetime.datetime.now())}", values["COMMENT_SYMBOL"] + values, f"Output Time: {str(datetime.datetime.now())}" ) gcode += f"{PostUtilsParse.linenumber(values)}{comment}{nl}" @@ -122,13 +117,10 @@ def export_common(values, objectslist, filename): item.Proxy, PathToolController.ToolController ): comment = PostUtilsParse.create_comment( - f"T{item.ToolNumber}={item.Name}", - values["COMMENT_SYMBOL"], + values, f"T{item.ToolNumber}={item.Name}" ) gcode += f"{PostUtilsParse.linenumber(values)}{comment}{nl}" - comment = PostUtilsParse.create_comment( - "Begin preamble", values["COMMENT_SYMBOL"] - ) + comment = PostUtilsParse.create_comment(values, "Begin preamble") gcode += f"{PostUtilsParse.linenumber(values)}{comment}{nl}" for line in values["PREAMBLE"].splitlines(False): gcode += f"{PostUtilsParse.linenumber(values)}{line}{nl}" @@ -152,11 +144,6 @@ def export_common(values, objectslist, filename): for obj in objectslist: - # Debug... - # print("\n" + "*"*70) - # dump(obj) - # print("*"*70 + "\n") - # Skip inactive operations if hasattr(obj, "Active") and not obj.Active: continue @@ -165,38 +152,29 @@ def export_common(values, objectslist, filename): # do the pre_op if values["OUTPUT_BCNC"]: - comment = PostUtilsParse.create_comment( - f"Block-name: {obj.Label}", values["COMMENT_SYMBOL"] - ) + comment = PostUtilsParse.create_comment(values, f"Block-name: {obj.Label}") gcode += f"{PostUtilsParse.linenumber(values)}{comment}{nl}" - comment = PostUtilsParse.create_comment( - "Block-expand: 0", values["COMMENT_SYMBOL"] - ) + comment = PostUtilsParse.create_comment(values, "Block-expand: 0") gcode += f"{PostUtilsParse.linenumber(values)}{comment}{nl}" - comment = PostUtilsParse.create_comment( - "Block-enable: 1", values["COMMENT_SYMBOL"] - ) + comment = PostUtilsParse.create_comment(values, "Block-enable: 1") gcode += f"{PostUtilsParse.linenumber(values)}{comment}{nl}" if values["OUTPUT_COMMENTS"]: if values["SHOW_OPERATION_LABELS"]: comment = PostUtilsParse.create_comment( - f"Begin operation: {obj.Label}", values["COMMENT_SYMBOL"] + values, f"Begin operation: {obj.Label}" ) else: - comment = PostUtilsParse.create_comment( - "Begin operation", values["COMMENT_SYMBOL"] - ) + comment = PostUtilsParse.create_comment(values, "Begin operation") gcode += f"{PostUtilsParse.linenumber(values)}{comment}{nl}" if values["SHOW_MACHINE_UNITS"]: comment = PostUtilsParse.create_comment( - f'Machine units: {values["UNIT_SPEED_FORMAT"]}', - values["COMMENT_SYMBOL"], + values, f'Machine units: {values["UNIT_SPEED_FORMAT"]}' ) gcode += f"{PostUtilsParse.linenumber(values)}{comment}{nl}" if values["OUTPUT_MACHINE_NAME"]: comment = PostUtilsParse.create_comment( + values, f'Machine: {values["MACHINE_NAME"]}, {values["UNIT_SPEED_FORMAT"]}', - values["COMMENT_SYMBOL"], ) gcode += f"{PostUtilsParse.linenumber(values)}{comment}{nl}" for line in values["PRE_OPERATION"].splitlines(False): @@ -218,7 +196,7 @@ def export_common(values, objectslist, filename): if values["ENABLE_COOLANT"]: if values["OUTPUT_COMMENTS"] and coolantMode != "None": comment = PostUtilsParse.create_comment( - f"Coolant On: {coolantMode}", values["COMMENT_SYMBOL"] + values, f"Coolant On: {coolantMode}" ) gcode += f"{PostUtilsParse.linenumber(values)}{comment}{nl}" if coolantMode == "Flood": @@ -227,13 +205,11 @@ def export_common(values, objectslist, filename): gcode += f"{PostUtilsParse.linenumber(values)}M7{nl}" # process the operation gcode - gcode += PostUtilsParse.parse(values, obj) - + gcode += PostUtilsParse.parse_a_group(values, obj) # do the post_op if values["OUTPUT_COMMENTS"]: comment = PostUtilsParse.create_comment( - f'{values["FINISH_LABEL"]} operation: {obj.Label}', - values["COMMENT_SYMBOL"], + values, f'{values["FINISH_LABEL"]} operation: {obj.Label}' ) gcode += f"{PostUtilsParse.linenumber(values)}{comment}{nl}" for line in values["POST_OPERATION"].splitlines(False): @@ -243,7 +219,7 @@ def export_common(values, objectslist, filename): if values["ENABLE_COOLANT"] and coolantMode != "None": if values["OUTPUT_COMMENTS"]: comment = PostUtilsParse.create_comment( - f"Coolant Off: {coolantMode}", values["COMMENT_SYMBOL"] + values, f"Coolant Off: {coolantMode}" ) gcode += f"{PostUtilsParse.linenumber(values)}{comment}{nl}" gcode += f"{PostUtilsParse.linenumber(values)}M9{nl}" @@ -256,22 +232,14 @@ def export_common(values, objectslist, filename): # do the post_amble if values["OUTPUT_BCNC"]: - comment = PostUtilsParse.create_comment( - "Block-name: post_amble", values["COMMENT_SYMBOL"] - ) + comment = PostUtilsParse.create_comment(values, "Block-name: post_amble") gcode += f"{PostUtilsParse.linenumber(values)}{comment}{nl}" - comment = PostUtilsParse.create_comment( - "Block-expand: 0", values["COMMENT_SYMBOL"] - ) + comment = PostUtilsParse.create_comment(values, "Block-expand: 0") gcode += f"{PostUtilsParse.linenumber(values)}{comment}{nl}" - comment = PostUtilsParse.create_comment( - "Block-enable: 1", values["COMMENT_SYMBOL"] - ) + comment = PostUtilsParse.create_comment(values, "Block-enable: 1") gcode += f"{PostUtilsParse.linenumber(values)}{comment}{nl}" if values["OUTPUT_COMMENTS"]: - comment = PostUtilsParse.create_comment( - "Begin postamble", values["COMMENT_SYMBOL"] - ) + comment = PostUtilsParse.create_comment(values, "Begin postamble") gcode += f"{PostUtilsParse.linenumber(values)}{comment}{nl}" for line in values["TOOLRETURN"].splitlines(False): gcode += f"{PostUtilsParse.linenumber(values)}{line}{nl}" diff --git a/src/Mod/Path/Path/Post/UtilsParse.py b/src/Mod/Path/Path/Post/UtilsParse.py index 72919f66aa..635f266ae7 100644 --- a/src/Mod/Path/Path/Post/UtilsParse.py +++ b/src/Mod/Path/Path/Post/UtilsParse.py @@ -35,29 +35,90 @@ from FreeCAD import Units import Path import Path.Post.Utils as PostUtils +def add_parameters(values, outstring, command, params, currLocation): + """Add the parameters (sometimes called "words") to the outstring.""" + for param in values["PARAMETER_ORDER"]: + if param not in params: + continue + p_p = params[param] + if param == "F": + if currLocation[param] == p_p and not values["OUTPUT_DOUBLES"]: + continue + # Many posts don't use rapid speeds, but eventually + # there will be refactored posts that do, so this + # "if statement" is being kept separate to make it + # more obvious where to put that check. + if command in values["RAPID_MOVES"]: + continue + feed = Units.Quantity(p_p, Units.Velocity) + if feed.getValueAs(values["UNIT_SPEED_FORMAT"]) <= 0.0: + continue + param_num = format_for_feed(values, feed) + elif param in ("H", "L", "T"): + param_num = str(int(p_p)) + elif param == "D": + if command in ("G41", "G42"): + param_num = str(int(p_p)) + elif command in ("G41.1", "G42.1"): + pos = Units.Quantity(p_p, Units.Length) + param_num = format_for_axis(values, pos) + elif command in ("G96", "G97"): + param_num = format_for_spindle(values, p_p) + else: # anything else that is supported + param_num = str(float(p_p)) + elif param == "P": + if command in ( + "G2", + "G02", + "G3", + "G03", + "G5.2", + "G5.3", + "G10", + "G54.1", + "G59", + ): + param_num = str(int(p_p)) + elif command in ("G4", "G04", "G76", "G82", "G86", "G89"): + param_num = str(float(p_p)) + elif command in ("G5", "G05", "G64"): + pos = Units.Quantity(p_p, Units.Length) + param_num = format_for_axis(values, pos) + else: # anything else that is supported + param_num = str(p_p) + elif param == "Q": + if command == "G10": + param_num = str(int(p_p)) + elif command in ("G64", "G73", "G83"): + pos = Units.Quantity(p_p, Units.Length) + param_num = format_for_axis(values, pos) + elif param == "S": + param_num = format_for_spindle(values, p_p) + else: + if ( + not values["OUTPUT_DOUBLES"] + and param in currLocation + and currLocation[param] == p_p + ): + continue + pos = Units.Quantity(p_p, Units.Length) + param_num = format_for_axis(values, pos) + outstring.append(f"{param}{param_num}") -def create_comment(comment_string, comment_symbol): + +def create_comment(values, comment_string): """Create a comment from a string using the correct comment symbol.""" - if comment_symbol == "(": + if values["COMMENT_SYMBOL"] == "(": return f"({comment_string})" else: - return comment_symbol + comment_string + return values["COMMENT_SYMBOL"] + comment_string -def drill_translate(values, outstring, cmd, params): +def drill_translate(values, cmd, params): """Translate drill cycles.""" trBuff = "" nl = "\n" - if values["OUTPUT_COMMENTS"]: # Comment the original command - comment = create_comment( - values["COMMAND_SPACE"] - + format_outstring(values, outstring) - + values["COMMAND_SPACE"], - values["COMMENT_SYMBOL"], - ) - trBuff += f"{linenumber(values)}{comment}{nl}" - # cycle conversion # currently only cycles in XY are provided (G17) # other plains ZX (G18) and YZ (G19) are not dealt with : Z drilling only. @@ -67,9 +128,7 @@ def drill_translate(values, outstring, cmd, params): RETRACT_Z = Units.Quantity(params["R"], Units.Length) # R less than Z is error if RETRACT_Z < drill_Z: - comment = create_comment( - "Drill cycle error: R less than Z", values["COMMENT_SYMBOL"] - ) + comment = create_comment(values, "Drill cycle error: R less than Z") trBuff += f"{linenumber(values)}{comment}{nl}" return trBuff @@ -175,6 +234,11 @@ def format_for_feed(values, number): ) +def format_for_spindle(values, number): + """Format a number using the precision for a spindle speed.""" + return format(float(number), f'.{str(values["SPINDLE_DECIMALS"])}f') + + def format_outstring(values, strTable): """Construct the line for the final output.""" s = "" @@ -195,294 +259,205 @@ def linenumber(values, space=None): return "" -def parse(values, pathobj): - """Parse a Path.""" +def parse_a_group(values, pathobj): + """Parse a Group (compound, project, or simple path).""" nl = "\n" out = "" - lastcommand = None - - currLocation = {} # keep track for no doubles - firstmove = Path.Command("G0", {"X": -1, "Y": -1, "Z": -1, "F": 0.0}) - currLocation.update(firstmove.Parameters) # set First location Parameters if hasattr(pathobj, "Group"): # We have a compound or project. if values["OUTPUT_COMMENTS"]: - comment = create_comment( - "Compound: " + pathobj.Label, values["COMMENT_SYMBOL"] - ) + comment = create_comment(values, f"Compound: {pathobj.Label}") out += f"{linenumber(values)}{comment}{nl}" for p in pathobj.Group: - out += parse(values, p) - return out + out += parse_a_group(values, p) else: # parsing simple path - # groups might contain non-path things like stock. if not hasattr(pathobj, "Path"): return out - if values["OUTPUT_PATH_LABELS"] and values["OUTPUT_COMMENTS"]: - comment = create_comment("Path: " + pathobj.Label, values["COMMENT_SYMBOL"]) + comment = create_comment(values, f"Path: {pathobj.Label}") out += f"{linenumber(values)}{comment}{nl}" + out += parse_a_path(values, pathobj) + return out - if values["OUTPUT_ADAPTIVE"]: - adaptiveOp = False - opHorizRapid = 0 - opVertRapid = 0 - if "Adaptive" in pathobj.Name: - adaptiveOp = True - if hasattr(pathobj, "ToolController"): - if ( - hasattr(pathobj.ToolController, "HorizRapid") - and pathobj.ToolController.HorizRapid > 0 - ): - opHorizRapid = Units.Quantity( - pathobj.ToolController.HorizRapid, Units.Velocity - ) - else: - FreeCAD.Console.PrintWarning( - "Tool Controller Horizontal Rapid Values are unset\n" - ) - if ( - hasattr(pathobj.ToolController, "VertRapid") - and pathobj.ToolController.VertRapid > 0 - ): - opVertRapid = Units.Quantity( - pathobj.ToolController.VertRapid, Units.Velocity - ) - else: - FreeCAD.Console.PrintWarning( - "Tool Controller Vertical Rapid Values are unset\n" - ) - for c in pathobj.Path.Commands: +def parse_a_path(values, pathobj): + """Parse a simple Path.""" + nl = "\n" + out = "" - # List of elements in the command, code, and params. + adaptiveOp = False + opHorizRapid = 0 + opVertRapid = 0 + + lastcommand = None + firstmove = Path.Command("G0", {"X": -1, "Y": -1, "Z": -1, "F": 0.0}) + currLocation = {} # keep track for no doubles + currLocation.update(firstmove.Parameters) # set First location Parameters + + if values["OUTPUT_ADAPTIVE"] and "Adaptive" in pathobj.Name: + adaptiveOp = True + if hasattr(pathobj, "ToolController"): + tc = pathobj.ToolController + if hasattr(tc, "HorizRapid") and tc.HorizRapid > 0: + opHorizRapid = Units.Quantity(tc.HorizRapid, Units.Velocity) + else: + FreeCAD.Console.PrintWarning( + f"Tool Controller Horizontal Rapid Values are unset{nl}" + ) + if hasattr(tc, "VertRapid") and tc.VertRapid > 0: + opVertRapid = Units.Quantity(tc.VertRapid, Units.Velocity) + else: + FreeCAD.Console.PrintWarning( + f"Tool Controller Vertical Rapid Values are unset{nl}" + ) + + for c in pathobj.Path.Commands: + + # List of elements in the command, code, and params. + outstring = [] + # command may contain M code, G code, comment string, etc. + command = c.Name + if command[0] == "(": + if not values["OUTPUT_COMMENTS"]: + continue + if values["COMMENT_SYMBOL"] != "(" and len(command) > 2: + command = create_comment(values, command[1:-1]) + if ( + values["OUTPUT_ADAPTIVE"] + and adaptiveOp + and command in values["RAPID_MOVES"] + ): + if opHorizRapid and opVertRapid: + command = "G1" + else: + outstring.append(f"(Tool Controller Rapid Values are unset){nl}") + + outstring.append(command) + + # if modal: suppress the command if it is the same as the last one + if values["MODAL"] and command == lastcommand: + outstring.pop(0) + + # Now add the remaining parameters in order + add_parameters(values, outstring, command, c.Parameters, currLocation) + + if ( + values["OUTPUT_ADAPTIVE"] + and adaptiveOp + and command in values["RAPID_MOVES"] + and opHorizRapid + and opVertRapid + ): + if "Z" not in c.Parameters: + param_num = format_for_feed(values, opHorizRapid) + else: + param_num = format_for_feed(values, opVertRapid) + outstring.append(f"F{param_num}") + + # store the latest command + lastcommand = command + currLocation.update(c.Parameters) + # Memorizes the current position for calculating the related movements + # and the withdrawal plan + if command in values["MOTION_COMMANDS"]: + if "X" in c.Parameters: + values["CURRENT_X"] = Units.Quantity(c.Parameters["X"], Units.Length) + if "Y" in c.Parameters: + values["CURRENT_Y"] = Units.Quantity(c.Parameters["Y"], Units.Length) + if "Z" in c.Parameters: + values["CURRENT_Z"] = Units.Quantity(c.Parameters["Z"], Units.Length) + + if command in ("G98", "G99"): + values["DRILL_RETRACT_MODE"] = command + elif command in ("G90", "G91"): + values["MOTION_MODE"] = command + + if ( + values["TRANSLATE_DRILL_CYCLES"] + and command in values["DRILL_CYCLES_TO_TRANSLATE"] + ): + if values["OUTPUT_COMMENTS"]: # Comment the original command + comment = create_comment( + values, + values["COMMAND_SPACE"] + + format_outstring(values, outstring) + + values["COMMAND_SPACE"], + ) + out += f"{linenumber(values)}{comment}{nl}" + out += drill_translate(values, command, c.Parameters) + # Erase the line we just translated outstring = [] - # command M or G code or comment string - command = c.Name - if command[0] == "(": - if values["OUTPUT_COMMENTS"]: - if values["COMMENT_SYMBOL"] != "(": - command = PostUtils.fcoms(command, values["COMMENT_SYMBOL"]) - else: - continue - if ( - values["OUTPUT_ADAPTIVE"] - and adaptiveOp - and command in values["RAPID_MOVES"] - ): - if opHorizRapid and opVertRapid: - command = "G1" - else: - outstring.append("(Tool Controller Rapid Values are unset)\n") - outstring.append(command) + if values["SPINDLE_WAIT"] > 0 and command in ("M3", "M03", "M4", "M04"): + out += f"{linenumber(values)}{format_outstring(values, outstring)}{nl}" + num = format_outstring(values, ["G4", f'P{values["SPINDLE_WAIT"]}']) + out += f"{linenumber(values)}{num}{nl}" + outstring = [] - # if modal: suppress the command if it is the same as the last one - if values["MODAL"] and command == lastcommand: - outstring.pop(0) - - # Now add the remaining parameters in order - for param in values["PARAMETER_ORDER"]: - if param in c.Parameters: - if param == "F" and ( - currLocation[param] != c.Parameters[param] - or values["OUTPUT_DOUBLES"] - ): - # centroid and linuxcnc don't use rapid speeds - if command not in values["RAPID_MOVES"]: - speed = Units.Quantity(c.Parameters["F"], Units.Velocity) - if speed.getValueAs(values["UNIT_SPEED_FORMAT"]) > 0.0: - param_num = format_for_feed(values, speed) - outstring.append(f"{param}{param_num}") - else: - continue - elif param in ("H", "L", "T"): - outstring.append(f"{param}{str(int(c.Parameters[param]))}") - elif param == "D": - if command in ("G41", "G42"): - outstring.append(f"{param}{str(int(c.Parameters[param]))}") - elif command in ("G41.1", "G42.1"): - pos = Units.Quantity(c.Parameters[param], Units.Length) - param_num = format_for_axis(values, pos) - outstring.append(f"{param}{param_num}") - elif command in ("G96", "G97"): - param_num = PostUtils.fmt( - c.Parameters[param], - values["SPINDLE_DECIMALS"], - "G21", - ) - outstring.append(f"{param}{param_num}") - else: # anything else that is supported - outstring.append( - f"{param}{str(float(c.Parameters[param]))}" - ) - elif param == "P": - if command in ( - "G2", - "G02", - "G3", - "G03", - "G5.2", - "G5.3", - "G10", - "G54.1", - "G59", - ): - outstring.append(f"{param}{str(int(c.Parameters[param]))}") - elif command in ("G4", "G04", "G76", "G82", "G86", "G89"): - outstring.append( - f"{param}{str(float(c.Parameters[param]))}" - ) - elif command in ("G5", "G05", "G64"): - pos = Units.Quantity(c.Parameters[param], Units.Length) - param_num = format_for_axis(values, pos) - outstring.append(f"{param}{param_num}") - else: # anything else that is supported - outstring.append(f"{param}{str(c.Parameters[param])}") - elif param == "Q": - if command == "G10": - outstring.append(f"{param}{str(int(c.Parameters[param]))}") - elif command in ("G64", "G73", "G83"): - pos = Units.Quantity(c.Parameters[param], Units.Length) - param_num = format_for_axis(values, pos) - outstring.append(f"{param}{param_num}") - elif param == "S": - param_num = PostUtils.fmt( - c.Parameters[param], values["SPINDLE_DECIMALS"], "G21" - ) - outstring.append(f"{param}{param_num}") - else: - if ( - (not values["OUTPUT_DOUBLES"]) - and (param in currLocation) - and (currLocation[param] == c.Parameters[param]) - ): - continue - else: - pos = Units.Quantity(c.Parameters[param], Units.Length) - param_num = format_for_axis(values, pos) - outstring.append(f"{param}{param_num}") - - if ( - values["OUTPUT_ADAPTIVE"] - and adaptiveOp - and command in values["RAPID_MOVES"] - and opHorizRapid - and opVertRapid - ): - if "Z" not in c.Parameters: - param_num = format_for_axis(values, opHorizRapid) - outstring.append(f"F{param_num}") - else: - param_num = format_for_axis(values, opVertRapid) - outstring.append(f"F{param_num}") - - # store the latest command - lastcommand = command - - currLocation.update(c.Parameters) - # Memorizes the current position for calculating the related movements - # and the withdrawal plan - if command in values["MOTION_COMMANDS"]: - if "X" in c.Parameters: - values["CURRENT_X"] = Units.Quantity( - c.Parameters["X"], Units.Length - ) - if "Y" in c.Parameters: - values["CURRENT_Y"] = Units.Quantity( - c.Parameters["Y"], Units.Length - ) - if "Z" in c.Parameters: - values["CURRENT_Z"] = Units.Quantity( - c.Parameters["Z"], Units.Length - ) - - if command in ("G98", "G99"): - values["DRILL_RETRACT_MODE"] = command - elif command in ("G90", "G91"): - values["MOTION_MODE"] = command - - if ( - values["TRANSLATE_DRILL_CYCLES"] - and command in values["DRILL_CYCLES_TO_TRANSLATE"] - ): - out += drill_translate(values, outstring, command, c.Parameters) - # Erase the line we just translated + # Check for Tool Change: + if command in ("M6", "M06"): + if values["OUTPUT_COMMENTS"]: + comment = create_comment(values, "Begin toolchange") + out += f"{linenumber(values)}{comment}{nl}" + if values["OUTPUT_TOOL_CHANGE"]: + if values["STOP_SPINDLE_FOR_TOOL_CHANGE"]: + # stop the spindle + out += f"{linenumber(values)}M5{nl}" + for line in values["TOOL_CHANGE"].splitlines(False): + out += f"{linenumber(values)}{line}{nl}" + elif values["OUTPUT_COMMENTS"]: + # convert the tool change to a comment + comment = create_comment( + values, + values["COMMAND_SPACE"] + + format_outstring(values, outstring) + + values["COMMAND_SPACE"], + ) + out += f"{linenumber(values)}{comment}{nl}" outstring = [] - if values["SPINDLE_WAIT"] > 0 and command in ("M3", "M03", "M4", "M04"): - out += f"{linenumber(values)}{format_outstring(values, outstring)}{nl}" - num = format_outstring(values, ["G4", f'P{values["SPINDLE_WAIT"]}']) - out += f"{linenumber(values)}{num}{nl}" - outstring = [] + if command == "message" and values["REMOVE_MESSAGES"]: + if values["OUTPUT_COMMENTS"] is False: + out = [] + else: + outstring.pop(0) # remove the command - # Check for Tool Change: - if command in ("M6", "M06"): - if values["OUTPUT_COMMENTS"]: - comment = create_comment( - "Begin toolchange", values["COMMENT_SYMBOL"] - ) - out += f"{linenumber(values)}{comment}{nl}" - if values["OUTPUT_TOOL_CHANGE"]: - if values["STOP_SPINDLE_FOR_TOOL_CHANGE"]: - # stop the spindle - out += f"{linenumber(values)}M5{nl}" - for line in values["TOOL_CHANGE"].splitlines(False): - out += f"{linenumber(values)}{line}{nl}" - elif values["OUTPUT_COMMENTS"]: - # convert the tool change to a comment - comment = create_comment( - values["COMMAND_SPACE"] - + format_outstring(values, outstring) - + values["COMMAND_SPACE"], - values["COMMENT_SYMBOL"], - ) - out += f"{linenumber(values)}{comment}{nl}" - outstring = [] + if command in values["SUPPRESS_COMMANDS"]: + if values["OUTPUT_COMMENTS"]: + # convert the command to a comment + comment = create_comment( + values, + values["COMMAND_SPACE"] + + format_outstring(values, outstring) + + values["COMMAND_SPACE"], + ) + out += f"{linenumber(values)}{comment}{nl}" + # remove the command + outstring = [] - if command == "message" and values["REMOVE_MESSAGES"]: - if values["OUTPUT_COMMENTS"] is False: - out = [] - else: - outstring.pop(0) # remove the command + # prepend a line number and append a newline + if len(outstring) >= 1: + if values["OUTPUT_LINE_NUMBERS"]: + # In this case we don't want a space after the line number + # because the space is added in the join just below. + outstring.insert(0, (linenumber(values, ""))) - if command in values["SUPPRESS_COMMANDS"]: - if values["OUTPUT_COMMENTS"]: - # convert the command to a comment - comment = create_comment( - values["COMMAND_SPACE"] - + format_outstring(values, outstring) - + values["COMMAND_SPACE"], - values["COMMENT_SYMBOL"], - ) - out += f"{linenumber(values)}{comment}{nl}" - # remove the command - outstring = [] + # append the line to the final output + out += values["COMMAND_SPACE"].join(outstring) + # Note: Do *not* strip `out`, since that forces the allocation + # of a contiguous string & thus quadratic complexity. + out += f"{nl}" - # prepend a line number and append a newline - if len(outstring) >= 1: - if values["OUTPUT_LINE_NUMBERS"]: - # In this case we don't want a space after the line number - # because the space is added in the join just below. - outstring.insert(0, (linenumber(values, ""))) + # add height offset + if command in ("M6", "M06") and values["USE_TLO"]: + out += f'{linenumber(values)}G43 H{str(int(c.Parameters["T"]))}{nl}' - # append the line to the final output - out += values["COMMAND_SPACE"].join(outstring) - # Note: Do *not* strip `out`, since that forces the allocation - # of a contiguous string & thus quadratic complexity. - out += f"{nl}" - - # add height offset - if command in ("M6", "M06") and values["USE_TLO"]: - out += f'{linenumber(values)}G43 H{str(int(c.Parameters["T"]))}{nl}' - - # Check for comments containing machine-specific commands - # to pass literally to the controller - if values["ENABLE_MACHINE_SPECIFIC_COMMANDS"]: - m = re.match(r"^\(MC_RUN_COMMAND: ([^)]+)\)$", command) - if m: - raw_command = m.group(1) - out += f"{linenumber(values)}{raw_command}{nl}" - - return out + # Check for comments containing machine-specific commands + # to pass literally to the controller + if values["ENABLE_MACHINE_SPECIFIC_COMMANDS"]: + m = re.match(r"^\(MC_RUN_COMMAND: ([^)]+)\)$", command) + if m: + raw_command = m.group(1) + out += f"{linenumber(values)}{raw_command}{nl}" + return out