| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | import os |
| | import FreeCAD |
| | from FreeCAD import Units |
| | import Path.Post.Utils as PostUtils |
| | from PathScripts import PathUtils |
| | import datetime |
| | import Path |
| | from builtins import open as pyopen |
| |
|
| | TOOLTIP = """ |
| | This is a postprocessor file for the Path workbench. It is used to |
| | take a pseudo-G-code fragment outputted by a Path object, and output |
| | real G-code suitable for a centroid 3 axis mill. This postprocessor, once placed |
| | in the appropriate Path/Tool folder, can be used directly from inside |
| | FreeCAD, via the GUI importer or via python scripts with: |
| | |
| | import centroid_legacy_post |
| | centroid_legacy_post.export(object,"/path/to/file.ncc","") |
| | """ |
| |
|
| | TOOLTIP_ARGS = """ |
| | Arguments for centroid: |
| | --header,--no-header ... output headers (--header) |
| | --comments,--no-comments ... output comments (--comments) |
| | --line-numbers,--no-line-numbers ... prefix with line numbers (--no-lin-numbers) |
| | --show-editor, --no-show-editor ... pop up editor before writing output(--show-editor) |
| | --feed-precision=1 ... number of digits of precision for feed rate. Default=1 |
| | --axis-precision=4 ... number of digits of precision for axis moves. Default=4 |
| | --inches ... Convert output for US imperial mode (G20) |
| | --no-tlo ... Suppress tool length offset (G43) following tool changes |
| | """ |
| |
|
| | |
| | OUTPUT_COMMENTS = True |
| | OUTPUT_HEADER = True |
| | OUTPUT_LINE_NUMBERS = False |
| | if FreeCAD.GuiUp: |
| | SHOW_EDITOR = True |
| | else: |
| | SHOW_EDITOR = False |
| | MODAL = False |
| | USE_TLO = True |
| |
|
| | COMMAND_SPACE = " " |
| | LINENR = 100 |
| |
|
| | |
| | UNITS = "G21" |
| | UNIT_FORMAT = "mm" |
| | UNIT_SPEED_FORMAT = "mm/min" |
| | MACHINE_NAME = "Centroid" |
| | CORNER_MIN = {"x": -609.6, "y": -152.4, "z": 0} |
| | CORNER_MAX = {"x": 609.6, "y": 152.4, "z": 304.8} |
| | AXIS_PRECISION = 4 |
| | FEED_PRECISION = 1 |
| | SPINDLE_DECIMALS = 0 |
| |
|
| | COMMENT = ";" |
| |
|
| | |
| | |
| | if FreeCAD.ActiveDocument: |
| | cam_file = os.path.basename(FreeCAD.ActiveDocument.FileName) |
| | else: |
| | cam_file = "<None>" |
| |
|
| | HEADER = """;Exported by FreeCAD |
| | ;Post Processor: {} |
| | ;CAM file: {} |
| | ;Output Time: {} |
| | """.format( |
| | __name__, cam_file, str(datetime.datetime.now()) |
| | ) |
| |
|
| | |
| | PREAMBLE = """G53 G00 G17 |
| | """ |
| |
|
| | |
| | POSTAMBLE = """M99 |
| | """ |
| |
|
| | TOOLRETURN = """M5 |
| | M25 |
| | G49 H0 |
| | """ |
| |
|
| | ZAXISRETURN = """G91 G28 X0 Z0 |
| | G90 |
| | """ |
| |
|
| | SAFETYBLOCK = """G90 G80 G40 G49 |
| | """ |
| |
|
| | |
| | PRE_OPERATION = """""" |
| |
|
| | |
| | POST_OPERATION = """""" |
| |
|
| | |
| | TOOL_CHANGE = """""" |
| |
|
| |
|
| | def processArguments(argstring): |
| | global OUTPUT_HEADER |
| | global OUTPUT_COMMENTS |
| | global OUTPUT_LINE_NUMBERS |
| | global SHOW_EDITOR |
| | global AXIS_PRECISION |
| | global FEED_PRECISION |
| | global UNIT_SPEED_FORMAT |
| | global UNIT_FORMAT |
| | global UNITS |
| | global USE_TLO |
| |
|
| | for arg in argstring.split(): |
| | if arg == "--header": |
| | OUTPUT_HEADER = True |
| | elif arg == "--no-header": |
| | OUTPUT_HEADER = False |
| | elif arg == "--comments": |
| | OUTPUT_COMMENTS = True |
| | elif arg == "--no-comments": |
| | OUTPUT_COMMENTS = False |
| | elif arg == "--line-numbers": |
| | OUTPUT_LINE_NUMBERS = True |
| | elif arg == "--no-line-numbers": |
| | OUTPUT_LINE_NUMBERS = False |
| | elif arg == "--show-editor": |
| | SHOW_EDITOR = True |
| | elif arg == "--no-show-editor": |
| | SHOW_EDITOR = False |
| | elif arg.split("=")[0] == "--axis-precision": |
| | AXIS_PRECISION = arg.split("=")[1] |
| | elif arg.split("=")[0] == "--feed-precision": |
| | FEED_PRECISION = arg.split("=")[1] |
| | elif arg == "--inches": |
| | UNITS = "G20" |
| | UNIT_SPEED_FORMAT = "in/min" |
| | UNIT_FORMAT = "in" |
| | elif arg == "--no-tlo": |
| | USE_TLO = False |
| |
|
| |
|
| | def export(objectslist, filename, argstring): |
| | processArguments(argstring) |
| | for i in objectslist: |
| | print(i.Name) |
| | global UNITS |
| | global UNIT_FORMAT |
| | global UNIT_SPEED_FORMAT |
| |
|
| | print("postprocessing...") |
| | gcode = "" |
| |
|
| | |
| | if OUTPUT_HEADER: |
| | gcode += HEADER |
| |
|
| | gcode += SAFETYBLOCK |
| |
|
| | |
| | if OUTPUT_COMMENTS: |
| | for item in objectslist: |
| | if hasattr(item, "Proxy") and isinstance( |
| | item.Proxy, Path.Tool.Controller.ToolController |
| | ): |
| | gcode += ";T{}={}\n".format(item.ToolNumber, item.Name) |
| | gcode += linenumber() + ";begin preamble\n" |
| | for line in PREAMBLE.splitlines(): |
| | gcode += linenumber() + line + "\n" |
| |
|
| | gcode += linenumber() + UNITS + "\n" |
| |
|
| | for obj in objectslist: |
| | |
| | if OUTPUT_COMMENTS: |
| | gcode += linenumber() + ";begin operation\n" |
| | for line in PRE_OPERATION.splitlines(True): |
| | gcode += linenumber() + line |
| |
|
| | gcode += parse(obj) |
| |
|
| | |
| | if OUTPUT_COMMENTS: |
| | gcode += linenumber() + ";end operation: %s\n" % obj.Label |
| | for line in POST_OPERATION.splitlines(True): |
| | gcode += linenumber() + line |
| |
|
| | |
| |
|
| | if OUTPUT_COMMENTS: |
| | gcode += ";begin postamble\n" |
| | for line in TOOLRETURN.splitlines(True): |
| | gcode += linenumber() + line |
| | for line in SAFETYBLOCK.splitlines(True): |
| | gcode += linenumber() + line |
| | for line in POSTAMBLE.splitlines(): |
| | gcode += linenumber() + line + "\n" |
| |
|
| | if SHOW_EDITOR: |
| | dia = PostUtils.GCodeEditorDialog() |
| | dia.editor.setPlainText(gcode) |
| | result = dia.exec_() |
| | if result: |
| | final = dia.editor.toPlainText() |
| | else: |
| | final = gcode |
| | else: |
| | final = gcode |
| |
|
| | print("done postprocessing.") |
| |
|
| | if not filename == "-": |
| | gfile = pyopen(filename, "w") |
| | gfile.write(final) |
| | gfile.close() |
| |
|
| | return final |
| |
|
| |
|
| | def linenumber(): |
| | global LINENR |
| | if OUTPUT_LINE_NUMBERS is True: |
| | LINENR += 10 |
| | return "N" + str(LINENR) + " " |
| | return "" |
| |
|
| |
|
| | def parse(pathobj): |
| | out = "" |
| | lastcommand = None |
| | axis_precision_string = "." + str(AXIS_PRECISION) + "f" |
| | feed_precision_string = "." + str(FEED_PRECISION) + "f" |
| | |
| | |
| | params = ["X", "Y", "Z", "A", "B", "I", "J", "F", "S", "T", "Q", "R", "L", "H"] |
| |
|
| | if hasattr(pathobj, "Group"): |
| | |
| | |
| | for p in pathobj.Group: |
| | out += parse(p) |
| | return out |
| | else: |
| |
|
| | |
| | if not hasattr(pathobj, "Path"): |
| | return out |
| |
|
| | for c in PathUtils.getPathWithPlacement(pathobj).Commands: |
| | commandlist = [] |
| | command = c.Name |
| |
|
| | if command.startswith("("): |
| | command = PostUtils.fcoms(command, COMMENT) |
| |
|
| | commandlist.append(command) |
| | if MODAL is True: |
| | if command == lastcommand: |
| | commandlist.pop(0) |
| |
|
| | |
| | for param in params: |
| | if param in c.Parameters: |
| | if param == "F": |
| | if c.Name not in [ |
| | "G0", |
| | "G00", |
| | ]: |
| | speed = Units.Quantity(c.Parameters["F"], FreeCAD.Units.Velocity) |
| | commandlist.append( |
| | param |
| | + format( |
| | float(speed.getValueAs(UNIT_SPEED_FORMAT)), |
| | feed_precision_string, |
| | ) |
| | ) |
| | elif param == "H": |
| | commandlist.append(param + str(int(c.Parameters["H"]))) |
| | elif param == "S": |
| | commandlist.append( |
| | param + PostUtils.fmt(c.Parameters["S"], SPINDLE_DECIMALS, "G21") |
| | ) |
| | elif param == "T": |
| | commandlist.append(param + str(int(c.Parameters["T"]))) |
| | else: |
| | pos = Units.Quantity(c.Parameters[param], FreeCAD.Units.Length) |
| | commandlist.append( |
| | param |
| | + format( |
| | float(pos.getValueAs(UNIT_FORMAT)), |
| | axis_precision_string, |
| | ) |
| | ) |
| | outstr = str(commandlist) |
| | outstr = outstr.replace("[", "") |
| | outstr = outstr.replace("]", "") |
| | outstr = outstr.replace("'", "") |
| | outstr = outstr.replace(",", "") |
| |
|
| | |
| | lastcommand = command |
| |
|
| | |
| | if command == "M6": |
| | for line in TOOL_CHANGE.splitlines(True): |
| | out += linenumber() + line |
| | if USE_TLO: |
| | out += linenumber() + "G43 H" + str(int(c.Parameters["T"])) + "\n" |
| |
|
| | |
| | if len(commandlist) >= 1: |
| | if OUTPUT_LINE_NUMBERS: |
| | commandlist.insert(0, (linenumber())) |
| |
|
| | |
| | for w in commandlist: |
| | out += w + COMMAND_SPACE |
| | out = out.strip() + "\n" |
| |
|
| | return out |
| |
|