diff --git a/src/Mod/Path/PathScripts/PathCustom.py b/src/Mod/Path/PathScripts/PathCustom.py index 74cb93ba1a..a07343731c 100644 --- a/src/Mod/Path/PathScripts/PathCustom.py +++ b/src/Mod/Path/PathScripts/PathCustom.py @@ -25,9 +25,11 @@ import FreeCAD import FreeCADGui import Path from PySide import QtCore +from copy import copy __doc__ = """Path Custom object and FreeCAD command""" +movecommands = ['G0', 'G00', 'G1', 'G01', 'G2', 'G02', 'G3', 'G03'] # Qt translation handling def translate(context, text, disambig=None): @@ -39,6 +41,8 @@ class ObjectCustom: def __init__(self,obj): obj.addProperty("App::PropertyStringList", "Gcode", "Path", QtCore.QT_TRANSLATE_NOOP("PathCustom", "The gcode to be inserted")) obj.addProperty("App::PropertyLink", "ToolController", "Path", QtCore.QT_TRANSLATE_NOOP("PathCustom", "The tool controller that will be used to calculate the path")) + obj.addProperty("App::PropertyBool", "OperationPlacement", "Path", "Use operation placement") + obj.OperationPlacement = False obj.Proxy = self def __getstate__(self): @@ -54,6 +58,20 @@ class ObjectCustom: s += str(l) if s: path = Path.Path(s) + if obj.OperationPlacement: + for x in range(len(path.Commands)): + if path.Commands[x].Name in movecommands: + base = copy(obj.Placement.Base) + new = path.Commands[x] + if 'X' not in path.Commands[x].Parameters: + base[0] = 0.0 + if 'Y' not in path.Commands[x].Parameters: + base[1] = 0.0 + if 'Z' not in path.Commands[x].Parameters: + base[2] = 0.0 + new.Placement.translate(base) + path.deleteCommand(x) + path.insertCommand(new, x) obj.Path = path diff --git a/src/Mod/Path/PathScripts/post/gcode_pre.py b/src/Mod/Path/PathScripts/post/gcode_pre.py new file mode 100644 index 0000000000..1ec9aaa702 --- /dev/null +++ b/src/Mod/Path/PathScripts/post/gcode_pre.py @@ -0,0 +1,124 @@ +# *************************************************************************** +# * (c) Yorik van Havre (yorik@uncreated.net) 2014 * +# * * +# * This file is part of the FreeCAD CAx development system. * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * FreeCAD is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Lesser General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with FreeCAD; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# ***************************************************************************/ + + +''' +This is an example preprocessor file for the Path workbench. Its aim is to +open a gcode file, parse its contents, and create the appropriate objects +in FreeCAD. + +Read the Path Workbench documentation to know how to create Path objects +from GCode. +''' + +import os +import Path +import FreeCAD +import PathScripts.PathUtils +import PathScripts.PathLog as PathLog + +# LEVEL = PathLog.Level.DEBUG +LEVEL = PathLog.Level.INFO +PathLog.setLevel(LEVEL, PathLog.thisModule()) + +if LEVEL == PathLog.Level.DEBUG: + PathLog.trackModule(PathLog.thisModule()) + + +# to distinguish python built-in open function from the one declared below +if open.__module__ in ['__builtin__', 'io']: + pythonopen = open + + +def open(filename): + "called when freecad opens a file." + PathLog.track(filename) + 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" + PathLog.track(filename) + gfile = pythonopen(filename) + gcode = gfile.read() + gfile.close() + gcode = parse(gcode) + doc = FreeCAD.getDocument(docname) + obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", "Custom") + PathScripts.PathCustom.ObjectCustom(obj) + obj.ViewObject.Proxy = 0 + obj.Gcode = gcode + PathScripts.PathUtils.addToJob(obj) + obj.ToolController = PathScripts.PathUtils.findToolController(obj) + FreeCAD.ActiveDocument.recompute() + + +def parse(inputstring): + "parse(inputstring): returns a parsed output string" + print("preprocessing...") + print(inputstring) + PathLog.track(inputstring) + # split the input by line + lines = inputstring.split("\n") + output = "" + lastcommand = None + print(lines) + + for lin in lines: + # remove any leftover trailing and preceding spaces + lin = lin.strip() + if not lin: + # discard empty lines + continue + if lin[0].upper() in ["N"]: + # remove line numbers + lin = lin.split(" ", 1) + if len(lin) >= 1: + lin = lin[1] + else: + continue + + if lin[0] in ["(", "%", "#", ";"]: + # discard comment and other non strictly gcode lines + continue + if lin[0].upper() in ["G", "M"]: + # found a G or M command: we store it + output += lin + "\n" + last = lin[0].upper() + for c in lin[1:]: + if not c.isdigit(): + break + else: + last += c + lastcommand = last + elif lastcommand: + # no G or M command: we repeat the last one + output += lastcommand + " " + lin + "\n" + + print("done preprocessing.") + return output + + +print(__name__ + " gcode preprocessor loaded.")