Consistent black formatting of all Path python files

This commit is contained in:
Markus Lampert
2022-02-28 21:06:16 -08:00
parent 8583894284
commit 934b0aaa07
93 changed files with 5216 additions and 3118 deletions

View File

@@ -1,28 +1,28 @@
#***************************************************************************
#* Copyright (c) 2015 Jon Nordby <jononor@gmail.com> *
#* *
#* 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 *
#* *
#***************************************************************************
# ***************************************************************************
# * Copyright (c) 2015 Jon Nordby <jononor@gmail.com> *
# * *
# * 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 *
# * *
# ***************************************************************************
TOOLTIP='''
TOOLTIP = """
FreeCAD Path post-processor to output code for the Roland Modela MDX-## machines.
The machine speaks RML-1, specified in 'Roland RML-1 Programming Guidelines'
@@ -32,14 +32,14 @@ http://altlab.org/d/content/m/pangelo/ideas/rml_command_guide_en_v100.pdf
The format has some overlap with HPGL:
https://en.wikipedia.org/wiki/HPGL
http://paulbourke.net/dataformats/hpgl/
'''
"""
import FreeCAD
import Part
import PathScripts.PostUtils as PostUtils
# to distinguish python built-in open function from the one declared below
if open.__module__ in ['__builtin__','io']:
if open.__module__ in ["__builtin__", "io"]:
pythonopen = open
@@ -51,34 +51,46 @@ def export(objectslist, filename, argstring):
for obj in objectslist:
code += convertobject(obj)
gfile = pythonopen(filename,"w")
gfile = pythonopen(filename, "w")
gfile.write(code)
gfile.close()
def convertobject(obj):
gcode = obj.Path.toGCode()
gcode = parse(gcode)
return gcode
def motoron():
return [ "!MC1;" ]
return ["!MC1;"]
def motoroff():
return [ "!MC0;" ]
return ["!MC0;"]
def home():
return [ "H;" ]
return ["H;"]
def setjog():
# "!PZ%d,%d;",iz_down,iz_up); // set z down, jog
return ""
def addheader():
return [ "PA;PA;" ] # absolute positioning
return ["PA;PA;"] # absolute positioning
def addfooter():
return []
def mm2cord(mm):
mm = float(mm)
return int(40.0*mm)
return int(40.0 * mm)
def feed(x=None, y=None, z=None, state=None):
c = []
@@ -87,13 +99,13 @@ def feed(x=None, y=None, z=None, state=None):
if x is not None:
x = float(x)
state['X'] = x
state["X"] = x
if y is not None:
y = float(y)
state['Y'] = y
state["Y"] = y
if z is not None:
z = float(z)
state['Z'] = z
state["Z"] = z
if x is not None and y is not None and z is not None:
# 3d motion
@@ -105,6 +117,7 @@ def feed(x=None, y=None, z=None, state=None):
pass
return c
def jog(x=None, y=None, z=None, state=None):
c = []
if state is None:
@@ -112,22 +125,23 @@ def jog(x=None, y=None, z=None, state=None):
if x is not None and y is not None:
x, y = float(x), float(y)
c.append("PU%d,%d;" % (mm2cord(x), mm2cord(y)))
state['X'] = x
state['Y'] = y
state["X"] = x
state["Y"] = y
if z is not None:
z = float(z)
c.append("PU;")
state['Z'] = z
state["Z"] = z
return c
def xyarc(args, state):
# no native support in RML/Modela, convert to linear line segments
c = []
lastPoint = FreeCAD.Vector(state['X'], state['Y'])
newPoint = FreeCAD.Vector(float(args['X']), float(args['Y']))
centerOffset = FreeCAD.Vector(float(args['I']), float(args['J']))
lastPoint = FreeCAD.Vector(state["X"], state["Y"])
newPoint = FreeCAD.Vector(float(args["X"]), float(args["Y"]))
centerOffset = FreeCAD.Vector(float(args["I"]), float(args["J"]))
center = lastPoint + centerOffset
radius = (center - lastPoint).Length
xyNormal = FreeCAD.Vector(0, 0, 1)
@@ -135,14 +149,15 @@ def xyarc(args, state):
p0 = circle.parameter(lastPoint)
p1 = circle.parameter(newPoint)
arc = Part.ArcOfCircle(circle, p0, p1)
steps = 64 # specify max error instead?
steps = 64 # specify max error instead?
points = arc.discretize(steps)
# consider direction?
#print('p = Part.ArcOfCircle(Part.Circle(FreeCAD.Vector(%f, %f), FreeCAD.Vector(0, 0, 1), %f), %f, %f)' % (center.x, center.y, radius, p0, p1))
# print('p = Part.ArcOfCircle(Part.Circle(FreeCAD.Vector(%f, %f), FreeCAD.Vector(0, 0, 1), %f), %f, %f)' % (center.x, center.y, radius, p0, p1))
for p in points:
c += feed(p.x, p.y, state['Z'], state)
c += feed(p.x, p.y, state["Z"], state)
return c
def speed(xy=None, z=None, state=None):
c = []
if state is None:
@@ -150,66 +165,67 @@ def speed(xy=None, z=None, state=None):
print(xy, z, state)
if xy is not None:
xy = float(xy)
if xy > 0.0 and xy != state['XYspeed']:
if xy > 0.0 and xy != state["XYspeed"]:
c.append("VS%.1f;" % xy)
state['XYspeed'] = xy
state["XYspeed"] = xy
if z is not None:
z = float(z)
if z > 0.0 and z != state['Zspeed']:
if z > 0.0 and z != state["Zspeed"]:
c.append("!VZ%.1f;" % z)
state['Zspeed'] = z
state["Zspeed"] = z
return c
def convertgcode(cmd, args, state):
"""Convert a single gcode command to equivalent Roland code"""
if cmd == 'G0':
if cmd == "G0":
# jog
return jog(args['X'], args['Y'], args['Z'], state)
elif cmd == 'G1':
return jog(args["X"], args["Y"], args["Z"], state)
elif cmd == "G1":
# linear feed
c = []
# feedrate
c += speed(xy=args['F'], z=args['F'], state=state)
c += speed(xy=args["F"], z=args["F"], state=state)
# motion
c += feed(args['X'], args['Y'], args['Z'], state)
c += feed(args["X"], args["Y"], args["Z"], state)
return c
elif cmd == 'G2' or cmd == 'G3':
elif cmd == "G2" or cmd == "G3":
# arc feed
c = []
# feedrate
c += speed(xy=args['F'], state=state)
c += speed(xy=args["F"], state=state)
# motion
if args['X'] and args['Y'] and args['Z']:
if args["X"] and args["Y"] and args["Z"]:
# helical motion
pass
elif args['X'] and args['Y']:
elif args["X"] and args["Y"]:
# arc in plane
c += xyarc(args, state)
return c
elif cmd == 'G20':
elif cmd == "G20":
# inches mode
raise ValueError("rml_post: Inches mode not supported")
elif cmd == 'G21':
elif cmd == "G21":
# millimeter mode
return ""
elif cmd == 'G40':
elif cmd == "G40":
# tool compensation off
return ""
elif cmd == 'G80':
elif cmd == "G80":
# cancel all cycles (drill normally)
return "PU;"
elif cmd == 'G81':
elif cmd == "G81":
c = []
# feedrate
c += speed(z=args['F'], state=state)
c += speed(z=args["F"], state=state)
# motion
c += jog(args['X'], args['Y'], state=state)
c += feed(args['X'], args['Y'], args['Z'], state)
c += jog(args["X"], args["Y"], state=state)
c += feed(args["X"], args["Y"], args["Z"], state)
return c
elif cmd == 'G90':
elif cmd == "G90":
# absolute mode?
return ""
elif cmd == 'G98':
elif cmd == "G98":
# feedrate
return ""
else:
@@ -219,14 +235,14 @@ def convertgcode(cmd, args, state):
def parse(inputstring):
"parse(inputstring): returns a parsed output string"
state = { 'X': 0.0, 'Y': 0.0, 'Z': 0.0, 'XYspeed': -1.0, 'Zspeed': -1.0 }
state = {"X": 0.0, "Y": 0.0, "Z": 0.0, "XYspeed": -1.0, "Zspeed": -1.0}
output = []
# header
output += addheader()
output += motoron()
output += speed(2.0, 1.0, state) # defaults
output += speed(2.0, 1.0, state) # defaults
# respect clearance height?
@@ -236,13 +252,13 @@ def parse(inputstring):
if not line:
continue
parsed = PostUtils.stringsplit(line)
command = parsed['command']
print('cmd', line)
command = parsed["command"]
print("cmd", line)
try:
if command:
code = convertgcode(command, parsed, state)
if not isinstance(code, list):
code = [ code ]
code = [code]
if len(code) and code[0]:
output += code
except NotImplementedError as e:
@@ -253,7 +269,7 @@ def parse(inputstring):
output += home()
output += addfooter()
return '\n'.join(output)
return "\n".join(output)
# print (__name__ + " gcode postprocessor loaded.")