| | |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | """ |
| | This is a preprocessor file for the Path workbench. Its aim is to |
| | parse the contents of a given OpenSBP file, and transform it to make it |
| | suitable for use in a Path object. This preprocessor, once placed in the |
| | appropriate PathScripts folder, can be used directly from inside FreeCAD, |
| | via the GUI importer or via python scripts with: |
| | |
| | import opensbp_pre |
| | opensbp_pre.insert("/path/to/myfile.ngc","DocumentName") |
| | |
| | |
| | DONE |
| | Correctly imports single axis and multi axis moves. |
| | Stores Jog and Feed speeds |
| | Appends Multiaxis Feed speed to G1 moves |
| | Jog rates don't append to G0 moves |
| | Make single axis feed rates work |
| | Imports CG (non-diameter) arcs. |
| | Handles CW and CCW spindle speeds |
| | if operations are preceded by a comment ('New Path ...) They are split into multiple paths |
| | |
| | TODO |
| | Many other OpenSBP commands not handled |
| | |
| | """ |
| |
|
| | import FreeCAD |
| | import Path |
| | import os |
| | import Path |
| | from builtins import open as pyopen |
| |
|
| | AXIS = ( |
| | "X", |
| | "Y", |
| | "Z", |
| | "A", |
| | "B", |
| | ) |
| | SPEEDS = "XY", "Z", "A", "B" |
| |
|
| |
|
| | def open(filename): |
| | "called when freecad opens a file." |
| | docname = os.path.splitext(os.path.basename(filename))[0] |
| | doc = FreeCAD.newDocument(docname) |
| | insert(filename, doc.Name) |
| |
|
| |
|
| | def insert(filename, docname): |
| | """called when freecad imports a file |
| | This insert expects parse to return a list of strings |
| | each string will become a separate path""" |
| | gfile = pyopen(filename) |
| | gcode = gfile.read() |
| | gfile.close() |
| | gcode = parse(gcode) |
| | doc = FreeCAD.getDocument(docname) |
| | for subpath in gcode: |
| | obj = doc.addObject("Path::Feature", "Path") |
| | path = Path.Path(subpath) |
| | obj.Path = path |
| |
|
| |
|
| | def parse(inputstring): |
| | "parse(inputstring): returns a list of parsed output string" |
| | print("preprocessing...") |
| | |
| | lines = inputstring.split("\n") |
| | return_output = [] |
| | output = "" |
| | last = {"X": None, "Y": None, "Z": None, "A": None, "B": None} |
| | lastrapidspeed = { |
| | "XY": "50", |
| | "Z": "50", |
| | "A": "50", |
| | "B": "50", |
| | } |
| | lastfeedspeed = { |
| | "XY": "50", |
| | "Z": "50", |
| | "A": "50", |
| | "B": "50", |
| | } |
| | movecommand = ["G1", "G0", "G02", "G03"] |
| |
|
| | for line in lines: |
| | |
| | line = line.strip() |
| | if not line: |
| | |
| | continue |
| | if line[0] in ["'", "&"]: |
| | |
| | if line[0:9] == "'New Path": |
| | |
| | if any( |
| | x in output for x in movecommand |
| | ): |
| | return_output.append(output) |
| | output = "" |
| | continue |
| |
|
| | words = [a.strip() for a in line.split(",")] |
| | words[0] = words[0].upper() |
| | if words[0] in [ |
| | "J2", |
| | "J3", |
| | "J4", |
| | "J5", |
| | "M2", |
| | "M3", |
| | "M4", |
| | "M5", |
| | ]: |
| | if words[0][0] == "J": |
| | s = "G0 " |
| | else: |
| | s = "G1 " |
| | speed = lastfeedspeed["XY"] |
| |
|
| | for i in range(1, len(words)): |
| | if words[i] == "": |
| | if last[AXIS[i - 1]] is None: |
| | continue |
| | else: |
| | s += AXIS[i - 1] + last[AXIS[i - 1]] |
| | else: |
| | s += AXIS[i - 1] + words[i] |
| | last[AXIS[i - 1]] = words[i] |
| | output += s + " F" + speed + "\n" |
| |
|
| | if words[0] in [ |
| | "JA", |
| | "JB", |
| | "JX", |
| | "JY", |
| | "JZ", |
| | "MA", |
| | "MB", |
| | "MX", |
| | "MY", |
| | "MZ", |
| | ]: |
| | if words[0][0] == "J": |
| | s = "G0 " |
| | if words[0][1] in ["X", "Y"]: |
| | speed = lastrapidspeed["XY"] |
| | else: |
| | speed = lastrapidspeed[words[0][1]] |
| |
|
| | else: |
| | s = "G1 " |
| | if words[0][1] in ["X", "Y"]: |
| | speed = lastfeedspeed["XY"] |
| | else: |
| | speed = lastfeedspeed[words[0][1]] |
| |
|
| | last[words[0][1]] = words[1] |
| | output += s |
| | for key, val in last.items(): |
| | if val is not None: |
| | output += key + str(val) + " F" + speed + "\n" |
| |
|
| | if words[0] in ["JS"]: |
| | for i in range(1, len(words)): |
| | if words[i] == "": |
| | continue |
| | else: |
| | lastrapidspeed[SPEEDS[i - 1]] = words[i] |
| |
|
| | if words[0] in ["MD"]: |
| | |
| | continue |
| | if words[0] in ["MH"]: |
| | |
| | continue |
| | if words[0] in ["MS"]: |
| | for i in range(1, len(words)): |
| | if words[i] == "": |
| | continue |
| | else: |
| | lastfeedspeed[SPEEDS[i - 1]] = words[i] |
| | if words[0] in ["MO"]: |
| | |
| | continue |
| |
|
| | if words[0] in ["TR"]: |
| | if float(words[1]) < 0: |
| | s = "M4 S" |
| | else: |
| | s = "M3 S" |
| | s += str(abs(float(words[1]))) |
| | output += s + "\n" |
| |
|
| | if words[0] in ["CG"]: |
| | if words[1] != "": |
| | print("diameter mode not supported") |
| | continue |
| |
|
| | else: |
| | if words[7] == "1": |
| | s = "G2" |
| | else: |
| | s = "G3" |
| |
|
| | s += ( |
| | " X" |
| | + words[2] |
| | + " Y" |
| | + words[3] |
| | + " I" |
| | + words[4] |
| | + " J" |
| | + words[5] |
| | + " F" |
| | + str(lastfeedspeed["XY"]) |
| | ) |
| | output += s + "\n" |
| |
|
| | last["X"] = words[2] |
| | last["Y"] = words[3] |
| |
|
| | |
| | if any(x in output for x in movecommand): |
| | return_output.append(output) |
| | print("done preprocessing.") |
| |
|
| | return return_output |
| |
|
| |
|
| | print(__name__ + " gcode preprocessor loaded.") |
| |
|