Extensive Path Workbench improvements.

Implement libarea improvements for profile
Implement libarea pocketing.
consolidate occ and libarea pocketing operation into one with algorithm
switch
consolidate occ aand libarea profile op into one with algorithm switch
add basic engraving operation.
Add rough UI for profile holding tags
implement holding tags for libarea profile.
implement basic defaults for depth settings.
First move in Drilling is rapid to clearance height.

UI needs lots of work but is usable.
This commit is contained in:
sliptonic
2016-02-24 09:02:25 -06:00
committed by Yorik van Havre
parent a55f676134
commit b67f6f1886
71 changed files with 11954 additions and 727 deletions

View File

@@ -0,0 +1,30 @@
import nc
import iso
import math
import datetime
import time
from format import Format
now = datetime.datetime.now()
class Creator(iso.Creator):
def __init__(self):
iso.Creator.__init__(self)
self.output_tool_definitions = False
self.fmt = Format(dp_wanted = False, add_trailing_zeros = True, add_plus = True)
def SPACE_STR(self): return ' '
def PROGRAM(self): return None
def PROGRAM_END(self): return( 'T0' + self.SPACE() + 'M06' + self.SPACE() + 'M02')
############################################################################
## Begin Program
def program_begin(self, id, comment):
self.write( ('(Created with Deckel FP4Ma post processor ' + str(now.strftime("%Y/%m/%d %H:%M")) + ')' + '\n') )
iso.Creator.program_begin(self, id, comment)
nc.creator = Creator()

View File

@@ -0,0 +1,6 @@
################################################################################
# __init__.py
#
# This is here to make python see NC folder
#
# Hirutso Enni, 2009-01-13

View File

@@ -0,0 +1,111 @@
# Preliminary postprocessor support for Anilam Crusader M CNC controller
# This code modified from iso.py and emc2.py distriuted with HeeksCAD as of Sep 2010
# Kurt Jensen 6 Sep 2010
# Use at your own risk.
import nc
import iso
class Creator(iso.Creator):
def init(self):
iso.Creator.init(self)
self.arc_centre_absolute = True
def SPACE(self): return(' ')
# This version of COMMENT removes comments from the resultant GCode
# Note: The Anilam hates comments when importing code.
def COMMENT(self,comment): return('')
def program_begin(self, id, comment):
self.write('%\n'); # Start of file token that Anilam Crusader M likes
# No Comments for the Anilam crusaher M, please......
#self.write( ('(' + comment + ')' + '\n') )
def program_end(self):
self.write_blocknum()
self.write('G29E\n') # End of code signal for Anilam Crusader M
self.write('%\n') # EOF signal for Anilam Crusader M
############################################################################
## Settings
def imperial(self):
self.write_blocknum()
self.write( self.IMPERIAL() + '\n')
self.fmt.number_of_decimal_places = 4
def metric(self):
self.write_blocknum()
self.write( self.METRIC() + '\n' )
self.fmt.number_of_decimal_places = 3
def absolute(self):
self.write_blocknum()
self.write( self.ABSOLUTE() + '\n')
def incremental(self):
self.write_blocknum()
self.write( self.INCREMENTAL() + '\n' )
def polar(self, on=True):
if (on) :
self.write_blocknum()
self.write(self.POLAR_ON() + '\n' )
else :
self.write_blocknum()
self.write(self.POLAR_OFF() + '\n' )
def set_plane(self, plane):
if (plane == 0) :
self.write_blocknum()
self.write('G17\n')
elif (plane == 1) :
self.write_blocknum()
self.write('G18\n')
elif (plane == 2) :
self.write_blocknum()
self.write('G19\n')
def comment(self, text):
self.write_blocknum()
############################################################################
## Tools
def tool_change(self, id):
self.write_blocknum()
self.write(('T%i' % id) + '\n')
self.t = id
def tool_defn(self, id, name='', params=None):
self.write_blocknum()
self.write(('T10%.2d' % id) + ' ')
if (radius != None):
self.write(('X%.3f' % radius) + ' ')
if (length != None):
self.write('Z%.3f' % length)
self.write('\n')
# This is the coordinate system we're using. G54->G59, G59.1, G59.2, G59.3
# These are selected by values from 1 to 9 inclusive.
def workplane(self, id):
if ((id >= 1) and (id <= 6)):
self.write_blocknum()
self.write( (self.WORKPLANE() % (id + self.WORKPLANE_BASE())) + '\n')
if ((id >= 7) and (id <= 9)):
self.write_blocknum()
self.write( ((self.WORKPLANE() % (6 + self.WORKPLANE_BASE())) + ('.%i' % (id - 6))) + '\n')
# inhibit N codes being generated for line numbers:
def write_blocknum(self):
pass
def drill(self, x=None, y=None, dwell=None, depthparams = None, retract_mode=None, spindle_mode=None, internal_coolant_on=None, rapid_to_clearance = None):
self.write('(Canned drill cycle ops are not yet supported here on this Anilam Crusader M postprocessor)')
nc.creator = Creator()

View File

@@ -0,0 +1,13 @@
# Preliminary backplot support for Anilam Crusader M CNC controller
# This code modified from iso_read.py and emc2_read.py distriuted with HeeksCAD as of Sep 2010
# Kurt Jensen 6 Sep 2010
# Use at your own risk.
import iso_read as iso
import sys
# Override some iso parser methods to interpret arc centers as relative to origin, not relative to start of arc.
class Parser(iso.Parser):
def __init__(self, writer):
iso.Parser.__init__(self, writer)
self.arc_centre_absolute = True

View File

@@ -0,0 +1,134 @@
################################################################################
# attach.py
#
# NC code creator for attaching Z coordinates to a surface
#
import recreator
import ocl
import ocl_funcs
import nc
attached = False
units = 1.0
################################################################################
class Creator(recreator.Redirector):
def __init__(self, original):
recreator.Redirector.__init__(self, original)
self.stl = None
self.cutter = None
self.minz = None
self.path = None
self.pdcf = None
self.material_allowance = 0.0
############################################################################
## Shift in Z
def setPdcfIfNotSet(self):
if self.pdcf == None:
self.pdcf = ocl.PathDropCutter()
self.pdcf.setSTL(self.stl)
self.pdcf.setCutter(self.cutter)
self.pdcf.setSampling(0.1)
self.pdcf.setZ(self.minz/units)
def z2(self, z):
path = ocl.Path()
# use a line with no length
path.append(ocl.Line(ocl.Point(self.x, self.y, self.z), ocl.Point(self.x, self.y, self.z)))
self.setPdcfIfNotSet()
if (self.z>self.minz):
self.pdcf.setZ(self.z) # Adjust Z if we have gotten a higher limit (Fix pocketing loosing steps when using attach?)
else:
self.pdcf.setZ(self.minz/units) # Else use minz
self.pdcf.setPath(path)
self.pdcf.run()
plist = self.pdcf.getCLPoints()
p = plist[0]
return p.z + self.material_allowance/units
def cut_path(self):
if self.path == None: return
self.setPdcfIfNotSet()
if (self.z>self.minz):
self.pdcf.setZ(self.z) # Adjust Z if we have gotten a higher limit (Fix pocketing loosing steps when using attach?)
else:
self.pdcf.setZ(self.minz/units) # Else use minz
# get the points on the surface
self.pdcf.setPath(self.path)
self.pdcf.run()
plist = self.pdcf.getCLPoints()
#refine the points
f = ocl.LineCLFilter()
f.setTolerance(0.005)
for p in plist:
f.addCLPoint(p)
f.run()
plist = f.getCLPoints()
i = 0
for p in plist:
if i > 0:
self.original.feed(p.x/units, p.y/units, p.z/units + self.material_allowance/units)
i = i + 1
self.path = ocl.Path()
def rapid(self, x=None, y=None, z=None, a=None, b=None, c=None ):
if z != None:
if z < self.z:
return
recreator.Redirector.rapid(self, x, y, z, a, b, c)
def feed(self, x=None, y=None, z=None, a=None, b=None, c=None):
px = self.x
py = self.y
pz = self.z
recreator.Redirector.feed(self, x, y, z, a, b, c)
if self.x == None or self.y == None or self.z == None:
return
if px == self.x and py == self.y:
return
# add a line to the path
if self.path == None: self.path = ocl.Path()
self.path.append(ocl.Line(ocl.Point(px, py, pz), ocl.Point(self.x, self.y, self.z)))
def arc(self, x=None, y=None, z=None, i=None, j=None, k=None, r=None, ccw = True):
px = self.x
py = self.y
pz = self.z
recreator.Redirector.arc(self, x, y, z, i, j, k, r, ccw)
# add an arc to the path
if self.path == None: self.path = ocl.Path()
self.path.append(ocl.Arc(ocl.Point(px, py, pz), ocl.Point(self.x, self.y, self.z), ocl.Point(i, j, pz), ccw))
def set_ocl_cutter(self, cutter):
self.cutter = cutter
################################################################################
def attach_begin():
global attached
if attached == True:
attach_end()
nc.creator = Creator(nc.creator)
recreator.units = units
attached = True
nc.creator.pdcf = None
nc.creator.path = None
def attach_end():
global attached
nc.creator.cut_path()
nc.creator = nc.creator.original
attached = False

View File

@@ -0,0 +1,229 @@
################################################################################
# iso_read.py
#
# Simple ISO NC code parsing
#
# Hirutso Enni, 2009-01-13
""" use this script to backplot nc files to *.scr file for autocad,bricscad,
draftsight,progecad,ares commander, etc....
usage: python cad_iso_read.py temp.nc temp.scr
"""
import cad_nc_read as nc
import re
import sys
################################################################################
class Parser(nc.Parser):
def __init__(self, writer):
nc.Parser.__init__(self, writer)
self.pattern_main = re.compile('([(!;].*|\s+|[a-zA-Z0-9_:](?:[+-])?\d*(?:\.\d*)?|\w\#\d+|\(.*?\)|\#\d+\=(?:[+-])?\d*(?:\.\d*)?)')
#if ( or ! or ; at least one space or a letter followed by some character or not followed by a +/- followed by decimal, with a possible decimal point
# followed by a possible deimcal, or a letter followed by # with a decimal . deimcal
# add your character here > [(!;] for comments char
# then look for the 'comment' function towards the end of the file and add another elif
def ParseWord(self, word):
if (word[0] == 'A' or word[0] == 'a'):
self.col = "axis"
self.a = eval(word[1:])
self.move = True
elif (word[0] == 'B' or word[0] == 'b'):
self.col = "axis"
self.b = eval(word[1:])
self.move = True
elif (word[0] == 'C' or word[0] == 'c'):
self.col = "axis"
self.c = eval(word[1:])
self.move = True
elif (word[0] == 'F' or word[0] == 'f'):
self.col = "axis"
self.f = eval(word[1:])
self.move = True
elif (word == 'G0' or word == 'G00' or word == 'g0' or word == 'g00'):
self.path_col = "rapid"
self.col = "rapid"
self.arc = 0
elif (word == 'G1' or word == 'G01' or word == 'g1' or word == 'g01'):
self.path_col = "feed"
self.col = "feed"
self.arc = 0
elif (word == 'G2' or word == 'G02' or word == 'g2' or word == 'g02' or word == 'G12' or word == 'g12'):
self.path_col = "feed"
self.col = "feed"
self.arc = -1
elif (word == 'G3' or word == 'G03' or word == 'g3' or word == 'g03' or word == 'G13' or word == 'g13'):
self.path_col = "feed"
self.col = "feed"
self.arc = +1
elif (word == 'G10' or word == 'g10'):
self.no_move = True
elif (word == 'L1' or word == 'l1'):
self.no_move = True
elif (word == 'G61.1' or word == 'g61.1' or word == 'G61' or word == 'g61' or word == 'G64' or word == 'g64'):
self.no_move = True
elif (word == 'G20' or word == 'G70'):
self.col = "prep"
self.set_mode(units=25.4)
elif (word == 'G21' or word == 'G71'):
self.col = "prep"
self.set_mode(units=1.0)
elif (word == 'G81' or word == 'g81'):
self.drill = True
self.no_move = True
self.path_col = "feed"
self.col = "feed"
elif (word == 'G82' or word == 'g82'):
self.drill = True;
self.no_move = True
self.path_col = "feed"
self.col = "feed"
elif (word == 'G83' or word == 'g83'):
self.drill = True
self.no_move = True
self.path_col = "feed"
self.col = "feed"
elif (word == 'G90' or word == 'g90'):
self.absolute()
elif (word == 'G91' or word == 'g91'):
self.incremental()
elif (word[0] == 'G') : col = "prep"
elif (word[0] == 'I' or word[0] == 'i'):
self.col = "axis"
self.i = eval(word[1:])
self.move = True
elif (word[0] == 'J' or word[0] == 'j'):
self.col = "axis"
self.j = eval(word[1:])
self.move = True
elif (word[0] == 'K' or word[0] == 'k'):
self.col = "axis"
self.k = eval(word[1:])
self.move = True
elif (word[0] == 'M') : self.col = "misc"
elif (word[0] == 'N') : self.col = "blocknum"
elif (word[0] == 'O') : self.col = "program"
elif (word[0] == 'P' or word[0] == 'p'):
if (self.no_move != True):
self.col = "axis"
self.p = eval(word[1:])
self.move = True
elif (word[0] == 'Q' or word[0] == 'q'):
if (self.no_move != True):
self.col = "axis"
self.q = eval(word[1:])
self.move = True
elif (word[0] == 'R' or word[0] == 'r'):
self.col = "axis"
self.r = eval(word[1:])
self.move = True
elif (word[0] == 'S' or word[0] == 's'):
self.col = "axis"
self.s = eval(word[1:])
self.move = True
elif (word[0] == 'T') :
self.col = "tool"
self.set_tool( eval(word[1:]) )
elif (word[0] == 'X' or word[0] == 'x'):
self.col = "axis"
self.x = eval(word[1:])
self.move = True
elif (word[0] == 'Y' or word[0] == 'y'):
self.col = "axis"
self.y = eval(word[1:])
self.move = True
elif (word[0] == 'Z' or word[0] == 'z'):
self.col = "axis"
self.z = eval(word[1:])
self.move = True
elif (word[0] == '(') : (self.col, self.cdata) = ("comment", True)
elif (word[0] == '!') : (self.col, self.cdata) = ("comment", True)
elif (word[0] == ';') : (self.col, self.cdata) = ("comment", True)
elif (word[0] == '#') : self.col = "variable"
elif (word[0] == ':') : self.col = "blocknum"
elif (ord(word[0]) <= 32) : self.cdata = True
def Parse(self, name, oname=None):
self.files_open(name,oname)
#self.begin_ncblock()
#self.begin_path(None)
#self.add_line(z=500)
#self.end_path()
#self.end_ncblock()
self.path_col = None
self.f = None
self.arc = 0
while (self.readline()):
self.a = None
self.b = None
self.c = None
self.i = None
self.j = None
self.k = None
self.p = None
self.q = None
self.r = None
self.s = None
self.x = None
self.y = None
self.z = None
#self.begin_ncblock()
self.move = False
self.drill = False
self.no_move = False
words = self.pattern_main.findall(self.line)
for word in words:
self.col = None
self.cdata = False
self.ParseWord(word)
self.add_text(word, self.col, self.cdata)
if (self.drill):
self.begin_path("rapid")
self.add_line(self.x, self.y, self.r)
self.end_path()
self.begin_path("feed")
self.add_line(self.x, self.y, self.z)
self.end_path()
self.begin_path("feed")
self.add_line(self.x, self.y, self.r)
self.end_path()
else:
if (self.move and not self.no_move):
self.begin_path(self.path_col)
if (self.arc==-1):
self.add_arc(self.x, self.y, self.z, self.i, self.j, self.k, self.r, self.arc)
elif (self.arc==1):
#self.add_arc(x, y, z, i, j, k, -r, arc) #if you want to use arcs with R values uncomment the first part of this line and comment the next one
self.add_arc(self.x, self.y, self.z, self.i, self.j, self.k, self.r, self.arc)
else : self.add_line(self.x, self.y, self.z, self.a, self.b, self.c)
self.end_path()
self.end_ncblock()
self.files_close()
################################################################################
if __name__ == '__main__':
parser = ParserIso()
if len(sys.argv)>2:
parser.Parse(sys.argv[1],sys.argv[2])
else:
parser.Parse(sys.argv[1])

View File

@@ -0,0 +1,113 @@
################################################################################
# cad_nc_read.py
#
# Base class for NC code parsing and backplotting
#
# Dan Falck 2011/01/06
################################################################################
class Parser:
def __init__(self):
self.currentx = -1.0
self.currenty = 0.0
self.currentz = 0.0
x,y,z = 0.0,0.0,0.0
self.absolute_flag = True
############################################################################
## Internals
def files_open(self, name, oname=None):
if (oname == None ):
oname = (name+'.scr')
self.file_in = open(name, 'r')
self.file_out = open(oname, 'w')
def files_close(self):
self.file_in.close()
self.file_out.write('-linetype set continuous\n')
self.file_out.write('\n')
self.file_out.close()
def readline(self):
self.line = self.file_in.readline().rstrip()
if (len(self.line)):
return True
else:
return False
def write(self, s):
self.file_out.write(s)
############################################################################
def end_ncblock(self):
self.file_out.write('Delay 0\n')
def add_text(self, s, col=None, cdata=False):
return
def set_mode(self, units=None):
#self.file_out.write(' units="'+str(units)+'"')
return
def set_tool(self, number=None):
if (number != None):
self.file_out.write('-LAYER New T'+str(number)+'\n')
self.file_out.write('-LAYER Set T'+str(number)+'\n')
def begin_path(self, col=None):
if (col != None):
if col == 'rapid':
self.file_out.write('-color Red\n')
#self.file_out.write('')
self.file_out.write('-linetype set dashed\n')
self.file_out.write('\n')
else:
self.file_out.write('-color Green\n')
#self.file_out.write('')
self.file_out.write('-linetype set continuous\n')
self.file_out.write('\n')
else : self.file_out.write('\n')
def end_path(self):
self.file_out.write('\n')
def add_line(self, x=None, y=None, z=None, a=None, b=None, c=None):
if (x == None and y == None and z == None and a == None and b == None and c == None) : return
#self.file_out.write('line %s,%s %s,%s' %(self.currentx,self.currenty,x,y))
if (x == None) : x = self.currentx
if (y == None) : y = self.currenty
if (z == None) : z = self.currentz
self.file_out.write('line %s,%s,%s %s,%s,%s\n' %(self.currentx,self.currenty,self.currentz,x,y,z))
self.currentx = x
self.currenty = y
self.currentz = z
def add_arc(self, x=None, y=None, z=None, i=None, j=None, k=None, r=None, d=None):
if (x == None and y == None and z == None and i == None and j == None and k == None and r == None and d == None) : return
z = self.currentz
if (x == None) : x = self.currentx
if (y == None) : y = self.currenty
if (z == None) : z = self.currentz
if (d == 1):
self.file_out.write('arc %s,%s,%s\n' %(self.currentx,self.currenty,self.currentz))
self.file_out.write('c\n')
self.file_out.write('%s,%s,%s\n' %(self.currentx+i,self.currenty+j,self.currentz))
self.file_out.write('%s,%s,%s' %(x,y,z))
else:
self.file_out.write('arc %s,%s,%s\n' %(x,y,z))
self.file_out.write('c\n')
self.file_out.write('%s,%s,%s\n' %(self.currentx+i,self.currenty+j,self.currentz))
self.file_out.write('%s,%s,%s' %(self.currentx,self.currenty,self.currentz))
self.currentx = x
self.currenty = y
self.currentz = z
def incremental(self):
self.absolute_flag = False
def absolute(self):
self.absolute_flag = True

View File

@@ -0,0 +1,275 @@
# Preliminary backplot support for autocad clone applications
# This code modified from iso_read.py and emc2_read.py distriuted with HeeksCAD as of Sep 2010
# Dan Falck 2011/01/06
#
""" use this script to backplot nc files to *.scr file for autocad,bricscad,
draftsight,progecad,ares commander, etc....
usage: python cad_read.py temp.nc temp.scr
"""
import cad_iso_read as iso
import sys
# Override some iso parser methods to interpret arc centers as relative to origin, not relative to start of arc.
#def write_layer(name,number):
#FILE.write('-LAYER New %s%s \n' %(name,number))
#FILE.write('-LAYER Set %s%s \n' %(name,number))
class CAD_backplot(iso.Parser):
def __init__(self):
iso.Parser.__init__(self)
def Parse(self, name, oname=None):
self.files_open(name,oname)
#self.begin_ncblock()
#self.begin_path(None)
#self.add_line(z=500)
#self.end_path()
#self.end_ncblock()
path_col = None
f = None
arc = 0
# Storage for tool position history of last block processed to properly convert absolute arc centers
oldx = -1.0
oldy = 0.0
oldz = 0.0
movelist = []
while (self.readline()):
# self.readline returns false if the line is empty - the parsing stops if the line is empty.
a = None
b = None
c = None
#f = None
i = None
j = None
k = None
p = None
q = None
r = None
s = None
x = None
y = None
z = None
iout = None
jout = None
kout = None
tool = 0
#self.begin_ncblock()
move = False
#arc = 0
#path_col = None
drill = False
no_move = False
words = self.pattern_main.findall(self.line)
for word in words:
col = None
cdata = False
if (word[0] == 'A' or word[0] == 'a'):
col = "axis"
a = eval(word[1:])
move = True
elif (word[0] == 'B' or word[0] == 'b'):
col = "axis"
b = eval(word[1:])
move = True
elif (word[0] == 'C' or word[0] == 'c'):
col = "axis"
c = eval(word[1:])
move = True
elif (word[0] == 'F' or word[0] == 'f'):
col = "axis"
f = eval(word[1:])
move = True
elif (word == 'G0' or word == 'G00' or word == 'g0' or word == 'g00'):
##FILE.write('-color Magenta\n')
path_col = "rapid"
col = "rapid"
arc = 0
elif (word == 'G1' or word == 'G01' or word == 'g1' or word == 'g01'):
##FILE.write('-color Green\n')
path_col = "feed"
col = "feed"
arc = 0
elif (word == 'G2' or word == 'G02' or word == 'g2' or word == 'g02' or word == 'G12' or word == 'g12'):
##FILE.write('-color Green\n')
path_col = "feed"
col = "feed"
arc = -1
elif (word == 'G3' or word == 'G03' or word == 'g3' or word == 'g03' or word == 'G13' or word == 'g13'):
##FILE.write('-color Green\n')
path_col = "feed"
col = "feed"
arc = +1
elif (word == 'G10' or word == 'g10'):
no_move = True
elif (word == 'L1' or word == 'l1'):
no_move = True
elif (word == 'G20' or word == 'G70'):
col = "prep"
self.set_mode(units=25.4)
elif (word == 'G21' or word == 'G71'):
col = "prep"
self.set_mode(units=1.0)
# Note: Anilam has very non standard params for drill cycles. Not Yet implemented!
elif (word == 'G81' or word == 'g81'):
drill = True
no_move = True
path_col = "feed"
col = "feed"
elif (word == 'G82' or word == 'g82'):
drill = True;
no_move = True
path_col = "feed"
col = "feed"
elif (word == 'G83' or word == 'g83'):
drill = True
no_move = True
path_col = "feed"
col = "feed"
elif (word[0] == 'G') : col = "prep"
elif (word[0] == 'I' or word[0] == 'i'):
col = "axis"
i = eval(word[1:])
move = True
elif (word[0] == 'J' or word[0] == 'j'):
col = "axis"
j = eval(word[1:])
move = True
elif (word[0] == 'K' or word[0] == 'k'):
col = "axis"
k = eval(word[1:])
move = True
elif (word[0] == 'M') : col = "misc"
elif (word[0] == 'N') : col = "blocknum"
elif (word[0] == 'O') : col = "program"
elif (word[0] == 'P' or word[0] == 'p'):
col = "axis"
p = eval(word[1:])
move = True
elif (word[0] == 'Q' or word[0] == 'q'):
col = "axis"
q = eval(word[1:])
move = True
elif (word[0] == 'R' or word[0] == 'r'):
col = "axis"
r = eval(word[1:])
move = True
elif (word[0] == 'S' or word[0] == 's'):
col = "axis"
s = eval(word[1:])
move = True
elif (word[0] == 'T') :
col = "tool"
self.set_tool( eval(word[1:]) )
tool = eval(word[1:])
elif (word[0] == 'X' or word[0] == 'x'):
col = "axis"
x = eval(word[1:])
move = True
elif (word[0] == 'Y' or word[0] == 'y'):
col = "axis"
y = eval(word[1:])
move = True
elif (word[0] == 'Z' or word[0] == 'z'):
col = "axis"
z = eval(word[1:])
move = True
elif (word[0] == '(') : (col, cdata) = ("comment", True)
elif (word[0] == '!') : (col, cdata) = ("comment", True)
elif (word[0] == ';') : (col, cdata) = ("comment", True)
elif (word[0] == '#') : col = "variable"
elif (word[0] == ':') : col = "blocknum"
elif (ord(word[0]) <= 32) : cdata = True
#self.add_text(word, col, cdata)
if (drill):
self.begin_path("rapid")
self.add_line(x, y, r)
self.end_path()
self.begin_path("feed")
self.add_line(x, y, z)
self.end_path()
self.begin_path("feed")
self.add_line(x, y, r)
self.end_path()
#elif (tool):
#write_layer('T',tool)
else:
if (move and not no_move):
self.begin_path(path_col)
#use absolute arc centers for IJK params.
# Subtract old XYZ off to get relative centers as expected:
#if path_col == 'rapid':
#FILE.write('-color Red\n')
#else:
#FILE.write('-color Green\n')
if (arc) :
z = oldz
if (x != None) and (oldx != None) and (i != None): iout = i
if (y != None) and (oldy != None) and (j != None): jout = j
if (z != None) and (oldz != None) and (k != None): kout = k
self.add_arc(x, y, z, iout, jout, kout, r, arc)
#if (arc == -1):
##FILE.write('arc %s,%s,%s\n' %(x,y,z))
##FILE.write('c\n')
##FILE.write('%s,%s,%s\n' %(oldx+i,oldy+j,oldz))
##FILE.write('%s,%s,%s\n' %(oldx,oldy,z))
#else:
##FILE.write('arc %s,%s,%s\n' %(oldx,oldy,z))
##FILE.write('c\n')
##FILE.write('%s,%s,%s\n' %(oldx+i,oldy+j,oldz))
##FILE.write('%s,%s,%s\n' %(x,y,z))
else:
self.add_line(x, y, z, a, b, c)
if (x == None) : x = oldx
if (y == None) : y = oldy
if (z == None) : z = oldz
scr_line = ('line %s,%s,%s %s,%s,%s \n' %(oldx,oldy,oldz,x,y,z))
#print scr_line
##FILE.write(scr_line)
self.end_path()
if (x != None) : oldx = x
if (y != None) : oldy = y
if (z != None) : oldz = z
#oldx = x
#oldy = y
#oldz = z
self.end_ncblock()
self.files_close()
#FILE.write('\n')
#FILE.close()
################################################################################
if __name__ == '__main__':
parser = CAD_backplot()
if len(sys.argv)>2:
parser.Parse(sys.argv[1],sys.argv[2])
else:
parser.Parse(sys.argv[1])

View File

@@ -0,0 +1,168 @@
################################################################################
# centroid1.py
#
# Post Processor for the centroid M40 machine
#
#
# Dan Falck, 7th March 2010
import nc
import iso_modal
import math
import datetime
now = datetime.datetime.now()
################################################################################
class Creator(iso_modal.Creator):
def __init__(self):
iso_modal.Creator.__init__(self)
self.useCrc = True
self.useCrcCenterline = True
self.absolute_flag = True
self.prev_g91 = ''
self.safe_z =None
def SPINDLE(self, format, speed): return(self.SPACE() + 'S' + (format % speed))
################################################################################
#cutter comp
#def crc_on(self):
# self.useCrc = True
# self.useCrcCenterline = True
#def crc_off(self):
# self.useCrc = False
################################################################################
# general
def comment(self, text):
self.write(';' + text +'\n')
def write_blocknum(self):
pass
################################################################################
# settings for absolute or incremental mode
def absolute(self):
self.write(self.ABSOLUTE()+'\n')
self.absolute_flag = True
def incremental(self):
self.write(self.INCREMENTAL()+'\n')
self.absolute_flag = False
################################################################################
# APT style INSERT- insert anything into program
def insert(self, text):
self.write((text + '\n'))
################################################################################
# program begin and end
def program_begin(self, id, name=''):
self.write(';time:'+str(now)+'\n')
self.write('G17 G20 G80 G40 G90\n')
def program_end(self):
self.write('M05\n')
self.write('M25\n')
self.write('G00 X-1.0 Y1.0\n')
self.write('G17 G80 G40 G90\n')
self.write('M99\n')
def program_stop(self, optional=False):
self.write_blocknum()
if (optional) :
self.write(self.STOP_OPTIONAL() + '\n')
else :
self.write('M05\n')
self.write('M25\n')
self.write(self.STOP() + '\n')
self.prev_g0123 = ''
################################################################################
# coordinate system ie G54-G59
def workplane(self, id):
self.write('M25\n')
if ((id >= 1) and (id <= 6)):
self.g_list.append(self.WORKPLANE() % (id + self.WORKPLANE_BASE()))
if ((id >= 7) and (id <= 9)):
self.g_list.append(((self.WORKPLANE() % (6 + self.WORKPLANE_BASE())) + ('.%i' % (id - 6))))
self.prev_g0123 = ''
################################################################################
# clearance plane
def clearanceplane(self,z=None):
self.safe_z = z
################################################################################
# return to home
def rapid_home(self, x=None, y=None, z=None, a=None, b=None, c=None):
"""Rapid relative to home position"""
self.write('M05\n')
self.write('M25\n')
self.write(self.RAPID())
self.write(self.X() + (self.fmt % x))
self.write(self.Y() + (self.fmt % y))
self.write('\n')
################################################################################
# tool info
def tool_change(self, id):
self.write_blocknum()
self.write((self.TOOL() % id) + '\n')
self.t = id
self.write('M25\n')
if self.safe_z == None:
self.write('G43 H'+ str(id) + ' Z')
self.write('1.0')
self.write ('\n')
else:
self.write('G43 H'+ str(id) + ' Z')
self.write(str(self.safe_z))
self.write ('\n')
def tool_defn(self, id, name='', params=None):
#self.write('G43 \n')
pass
def write_spindle(self):
pass
def spindle(self, s, clockwise):
if s < 0:
clockwise = not clockwise
s = abs(s)
self.s = self.SPINDLE(self.FORMAT_ANG(), s)
if clockwise:
#self.s = self.SPINDLE_CW() + self.s
self.s = self.SPINDLE_CW()
self.write(self.s + '\n')
self.write('G04 P2.0 \n')
else:
self.s = self.SPINDLE_CCW() + self.s
def end_canned_cycle(self):
self.write_blocknum()
self.write(self.SPACE() + self.END_CANNED_CYCLE() + '\n')
self.prev_drill = ''
self.prev_g0123 = ''
self.prev_z = ''
self.prev_f = ''
self.prev_retract = ''
self.write('M05\n')
self.write('M25\n')
self.write('G00 X-1.0 Y1.0\n')
nc.creator = Creator()

View File

@@ -0,0 +1,8 @@
import iso_read as iso
import sys
# just use the iso reader
class Parser(iso.Parser):
def __init__(self, writer):
iso.Parser.__init__(self, writer)

View File

@@ -0,0 +1,34 @@
def tool_defn(self, id, params):
self.write('(TOOL/')
type = params['type']
if type == 0:#eDrill = 0,
#;TOOL/DRILL, Diameter, Point Angle, Height
self.write('DRILL, ' + str(params['diameter']))
self.write(', ' + str(params['cutting edge angle'] * 2.0))
self.write(', ' + str(params['cutting edge height']))
elif type == 1:#eCentreDrill,
#;TOOL/CDRILL, D1, A1, L, D2, A2, H (see Fig. below)
self.write('CDRILL, ' + str(params['flat radius'] * 2))
self.write(', ' + str(params['cutting edge angle']))
self.write(', ' + str(params['flat radius'] * 2))
self.write(', ' + str(params['diameter']))
self.write(', ' + str(params['cutting edge angle'] * 2.0))
self.write(', ' + str(params['cutting edge height']))
elif type == 2 or type == 3 or type == 4:#eSlotCutter,#eEndmill,#eBallEndMill,
#TOOL/MILL, Diameter, Corner radius, Height, Taper Angle
self.write('MILL, ' + str(params['diameter']))
self.write(', ' + str(params['corner radius']))
self.write(', ' + str(params['cutting edge height']))
self.write(', ' + str(params['cutting edge angle']))
elif type == 5 or type == 6:#eChamfer,#eEngravingTool,
#;TOOL/CHAMFER, Diameter, Point Angle, Height
#;TOOL/CHAMFER, Diameter, Point Angle, Height, Chamfer Length
self.write('CHAMFER, ' + str(params['diameter']))
self.write(', ' + str(params['cutting edge angle']))
self.write(', ' + str(params['cutting edge height']))
else:#eUndefinedToolType
pass
self.write(')\n')
# to do
#;TOOL/CRMILL, Diameter1, Diameter2, Radius, Height, Length

View File

@@ -0,0 +1,72 @@
################################################################################
# drag knife.py
#
# NC code creator for attaching Z coordinates to a surface
#
# Dan Heeks 26th April 2012
import recreator
dragging = False
from kurve_funcs import cut_curve as cut_curve
import nc
import area
################################################################################
class Creator(recreator.Redirector):
def __init__(self, original, drag_distance):
recreator.Redirector.__init__(self, original)
self.drag_distance = drag_distance
self.path = None
def cut_path(self):
if self.path == None: return
print self.drag_distance
self.path.OffsetForward(self.drag_distance, False)
nc.creator = nc.creator.original
if self.path.getNumVertices() > 0:
v = self.path.FirstVertex()
nc.creator.feed(v.p.x, v.p.y)
cut_curve(self.path)
nc.creator = self
self.path = area.Curve()
def feed(self, x=None, y=None, z=None, a=None, b=None, c=None):
px = self.x
py = self.y
pz = self.z
recreator.Redirector.feed(self, x, y, z, a, b, c)
if self.x == None or self.y == None or self.z == None:
return
if px == self.x and py == self.y:
return
# add a line to the path
if self.path == None: self.path = area.Curve()
self.path.append(area.Point(self.x, self.y))
def arc(self, x=None, y=None, z=None, i=None, j=None, k=None, r=None, ccw = True):
recreator.Redirector.arc(self, x, y, z, i, j, k, r, ccw)
# add an arc to the path
if self.path == None: self.path = area.Curve()
self.path.append(area.Vertex(1 if ccw else -1, area.Point(self.x, self.y), area.Point(i, j)))
def drag_begin(drag_distance):
global dragging
if dragging == True:
drag_end()
nc.creator = Creator(nc.creator, drag_distance)
dragging = True
def drag_end():
global dragging
nc.creator.cut_path()
nc.creator = nc.creator.original
attached = False

View File

@@ -0,0 +1,38 @@
import nc
import iso
import math
import datetime
import time
from format import Format
now = datetime.datetime.now()
class Creator(iso.Creator):
def __init__(self):
iso.Creator.__init__(self)
self.output_tool_definitions = False
self.m_codes_on_their_own_line = True
self.output_g98_and_g99 = False
#self.fmt = Format(dp_wanted = False, add_trailing_zeros = True, add_plus = True)
#def SPACE_STR(self): return ' '
def PROGRAM(self): return None
def RETRACT(self, height): return('R' + (self.fmt.string(height)))
def PECK_DEPTH(self, depth): return('O' + (self.fmt.string(depth)))
def program_begin(self, id, name=''):
self.write('(' + name + ')\n')
def imperial(self):
#self.g_list.append(self.IMPERIAL())
self.fmt.number_of_decimal_places = 4
def metric(self):
#self.g_list.append(self.METRIC())
self.fmt.number_of_decimal_places = 3
def comment(self, text):
pass
nc.creator = Creator()

View File

@@ -0,0 +1,235 @@
import nc
import iso
import math
class Creator(iso.Creator):
def init(self):
iso.Creator.init(self)
def SPACE(self): return('')
def TAP(self): return('G33.1')
def TAP_DEPTH(self, format, depth): return(self.SPACE() + 'K' + (format.string(depth)))
def BORE_FEED_OUT(self): return('G85')
def BORE_SPINDLE_STOP_RAPID_OUT(self): return('G86')
def BORE_DWELL_FEED_OUT(self, format, dwell): return('G89') + self.SPACE() + (format.string(dwell))
def FEEDRATE(self): return((self.SPACE() + ' F'))
def program_begin(self, id, comment):
self.write( ('(' + comment + ')' + '\n') )
############################################################################
## Settings
def imperial(self):
self.write( self.IMPERIAL() + '\t (Imperial Values)\n')
self.fmt.number_of_decimal_places = 4
def metric(self):
self.fmt.number_of_decimal_places = 3
self.write( self.METRIC() + '\t (Metric Values)\n' )
def absolute(self):
self.write( self.ABSOLUTE() + '\t (Absolute Coordinates)\n')
def incremental(self):
self.write( self.INCREMENTAL() + '\t (Incremental Coordinates)\n' )
def polar(self, on=True):
if (on) :
self.write(self.POLAR_ON() + '\t (Polar ON)\n' )
else :
self.write(self.POLAR_OFF() + '\t (Polar OFF)\n' )
def set_plane(self, plane):
if (plane == 0) :
self.write(self.PLANE_XY() + '\t (Select XY Plane)\n')
elif (plane == 1) :
self.write(self.PLANE_XZ() + '\t (Select XZ Plane)\n')
elif (plane == 2) :
self.write(self.PLANE_YZ() + '\t (Select YZ Plane)\n')
def comment(self, text):
self.write((self.COMMENT(text) + '\n'))
# This is the coordinate system we're using. G54->G59, G59.1, G59.2, G59.3
# These are selected by values from 1 to 9 inclusive.
def workplane(self, id):
if ((id >= 1) and (id <= 6)):
self.write( (self.WORKPLANE() % (id + self.WORKPLANE_BASE())) + '\t (Select Relative Coordinate System)\n')
if ((id >= 7) and (id <= 9)):
self.write( ((self.WORKPLANE() % (6 + self.WORKPLANE_BASE())) + ('.%i' % (id - 6))) + '\t (Select Relative Coordinate System)\n')
def report_probe_results(self, x1=None, y1=None, z1=None, x2=None, y2=None, z2=None, x3=None, y3=None, z3=None, x4=None, y4=None, z4=None, x5=None, y5=None, z5=None, x6=None, y6=None, z6=None, xml_file_name=None ):
if (xml_file_name != None):
self.comment('Generate an XML document describing the probed coordinates found');
self.write('(LOGOPEN,')
self.write(xml_file_name)
self.write(')\n')
self.write('(LOG,<POINTS>)\n')
if ((x1 != None) or (y1 != None) or (z1 != None)):
self.write('(LOG,<POINT>)\n')
if (x1 != None):
self.write('#<_value>=[' + x1 + ']\n')
self.write('(LOG,<X>#<_value></X>)\n')
if (y1 != None):
self.write('#<_value>=[' + y1 + ']\n')
self.write('(LOG,<Y>#<_value></Y>)\n')
if (z1 != None):
self.write('#<_value>=[' + z1 + ']\n')
self.write('(LOG,<Z>#<_value></Z>)\n')
if ((x1 != None) or (y1 != None) or (z1 != None)):
self.write('(LOG,</POINT>)\n')
if ((x2 != None) or (y2 != None) or (z2 != None)):
self.write('(LOG,<POINT>)\n')
if (x2 != None):
self.write('#<_value>=[' + x2 + ']\n')
self.write('(LOG,<X>#<_value></X>)\n')
if (y2 != None):
self.write('#<_value>=[' + y2 + ']\n')
self.write('(LOG,<Y>#<_value></Y>)\n')
if (z2 != None):
self.write('#<_value>=[' + z2 + ']\n')
self.write('(LOG,<Z>#<_value></Z>)\n')
if ((x2 != None) or (y2 != None) or (z2 != None)):
self.write('(LOG,</POINT>)\n')
if ((x3 != None) or (y3 != None) or (z3 != None)):
self.write('(LOG,<POINT>)\n')
if (x3 != None):
self.write('#<_value>=[' + x3 + ']\n')
self.write('(LOG,<X>#<_value></X>)\n')
if (y3 != None):
self.write('#<_value>=[' + y3 + ']\n')
self.write('(LOG,<Y>#<_value></Y>)\n')
if (z3 != None):
self.write('#<_value>=[' + z3 + ']\n')
self.write('(LOG,<Z>#<_value></Z>)\n')
if ((x3 != None) or (y3 != None) or (z3 != None)):
self.write('(LOG,</POINT>)\n')
if ((x4 != None) or (y4 != None) or (z4 != None)):
self.write('(LOG,<POINT>)\n')
if (x4 != None):
self.write('#<_value>=[' + x4 + ']\n')
self.write('(LOG,<X>#<_value></X>)\n')
if (y4 != None):
self.write('#<_value>=[' + y4 + ']\n')
self.write('(LOG,<Y>#<_value></Y>)\n')
if (z4 != None):
self.write('#<_value>=[' + z4 + ']\n')
self.write('(LOG,<Z>#<_value></Z>)\n')
if ((x4 != None) or (y4 != None) or (z4 != None)):
self.write('(LOG,</POINT>)\n')
if ((x5 != None) or (y5 != None) or (z5 != None)):
self.write('(LOG,<POINT>)\n')
if (x5 != None):
self.write('#<_value>=[' + x5 + ']\n')
self.write('(LOG,<X>#<_value></X>)\n')
if (y5 != None):
self.write('#<_value>=[' + y5 + ']\n')
self.write('(LOG,<Y>#<_value></Y>)\n')
if (z5 != None):
self.write('#<_value>=[' + z5 + ']\n')
self.write('(LOG,<Z>#<_value></Z>)\n')
if ((x5 != None) or (y5 != None) or (z5 != None)):
self.write('(LOG,</POINT>)\n')
if ((x6 != None) or (y6 != None) or (z6 != None)):
self.write('(LOG,<POINT>)\n')
if (x6 != None):
self.write('#<_value>=[' + x6 + ']\n')
self.write('(LOG,<X>#<_value></X>)\n')
if (y6 != None):
self.write('#<_value>=[' + y6 + ']\n')
self.write('(LOG,<Y>#<_value></Y>)\n')
if (z6 != None):
self.write('#<_value>=[' + z6 + ']\n')
self.write('(LOG,<Z>#<_value></Z>)\n')
if ((x6 != None) or (y6 != None) or (z6 != None)):
self.write('(LOG,</POINT>)\n')
self.write('(LOG,</POINTS>)\n')
if (xml_file_name != None):
self.write('(LOGCLOSE)\n')
def open_log_file(self, xml_file_name=None ):
self.write('(LOGOPEN,')
self.write(xml_file_name)
self.write(')\n')
def close_log_file(self):
self.write('(LOGCLOSE)\n')
def log_coordinate(self, x=None, y=None, z=None):
if ((x != None) or (y != None) or (z != None)):
self.write('(LOG,<POINT>)\n')
if (x != None):
self.write('#<_value>=[' + x + ']\n')
self.write('(LOG,<X>#<_value></X>)\n')
if (y != None):
self.write('#<_value>=[' + y + ']\n')
self.write('(LOG,<Y>#<_value></Y>)\n')
if (z != None):
self.write('#<_value>=[' + z + ']\n')
self.write('(LOG,<Z>#<_value></Z>)\n')
if ((x != None) or (y != None) or (z != None)):
self.write('(LOG,</POINT>)\n')
def log_message(self, message=None ):
self.write('(LOG,' + message + ')\n')
def start_CRC(self, left = True, radius = 0.0):
if self.t == None:
raise "No tool specified for start_CRC()"
if left:
self.write(('G41' + self.SPACE() + 'D%i') % self.t + '\t (start left cutter radius compensation)\n' )
else:
self.write(('G42' + self.SPACE() + 'D%i') % self.t + '\t (start right cutter radius compensation)\n' )
def end_CRC(self):
self.g = 'G40'
self.write_preps()
self.write_misc()
self.write('\t (end cutter radius compensation)\n')
def tool_defn(self, id, name='', params=None):
pass
nc.creator = Creator()

View File

@@ -0,0 +1,39 @@
import nc
import iso_modal
import math
import datetime
import time
now = datetime.datetime.now()
class Creator(iso_modal.Creator):
def __init__(self):
iso_modal.Creator.__init__(self)
self.output_block_numbers = False
self.output_tool_definitions = False
self.output_g43_on_tool_change_line = True
def SPACE(self):
if self.start_of_line == True:
self.start_of_line = False
return ''
else:
return ' '
def PROGRAM(self): return None
def PROGRAM_END(self): return( 'T0' + self.SPACE() + 'M06' + self.SPACE() + 'M02')
############################################################################
## Begin Program
def program_begin(self, id, comment):
if (self.useCrc == False):
self.write( ('(Created with emc2b post processor ' + str(now.strftime("%Y/%m/%d %H:%M")) + ')' + '\n') )
else:
self.write( ('(Created with emc2b Cutter Radius Compensation post processor ' + str(now.strftime("%Y/%m/%d %H:%M")) + ')' + '\n') )
iso_modal.Creator.program_begin(self, id, comment)
nc.creator = Creator()

View File

@@ -0,0 +1,21 @@
################################################################################
# emc2b_crc.py
#
# a class derived from emc2b machine, with Cutter Radius Compensation turned on.
#
# Dan Heeks, 18th Jan 2011
import nc
import emc2b
import math
################################################################################
class Creator(emc2b.Creator):
def __init__(self):
emc2b.Creator.__init__(self)
self.useCrc = True
################################################################################
nc.creator = Creator()

View File

@@ -0,0 +1,85 @@
import nc
import iso_codes
import emc2
class CodesEMC2(iso_codes.Codes):
def SPACE(self): return(' ')
def TAP(self): return('G33.1')
def TAP_DEPTH(self, format, depth): return(self.SPACE() + 'K' + (format % depth))
# This version of COMMENT removes comments from the resultant GCode
#def COMMENT(self,comment): return('')
iso_codes.codes = CodesEMC2()
class CreatorEMC2tap(emc2.CreatorEMC2):
def init(self):
iso.CreatorEMC2.init(self)
# G33.1 tapping with EMC for now
# unsynchronized (chuck) taps NIY (tap_mode = 1)
def tap(self, x=None, y=None, z=None, zretract=None, depth=None, standoff=None, dwell_bottom=None, pitch=None, stoppos=None, spin_in=None, spin_out=None, tap_mode=None, direction=None):
# mystery parameters:
# zretract=None, dwell_bottom=None,pitch=None, stoppos=None, spin_in=None, spin_out=None):
# I dont see how to map these to EMC Gcode
if (standoff == None):
# This is a bad thing. All the drilling cycles need a retraction (and starting) height.
return
if (z == None):
return # We need a Z value as well. This input parameter represents the top of the hole
if (pitch == None):
return # We need a pitch value.
if (direction == None):
return # We need a direction value.
if (tap_mode != 0):
self.comment('only rigid tapping currently supported')
return
self.write_preps()
self.write_blocknum()
self.write_spindle()
self.write('\n')
# rapid to starting point; z first, then x,y iff given
# Set the retraction point to the 'standoff' distance above the starting z height.
retract_height = z + standoff
# unsure if this is needed:
if self.z != retract_height:
self.rapid(z = retract_height)
# then continue to x,y if given
if (x != None) or (y != None):
self.write_blocknum()
self.write(iso_codes.codes.RAPID() )
if (x != None):
self.write(iso_codes.codes.X() + (self.fmt % x))
self.x = x
if (y != None):
self.write(iso_codes.codes.Y() + (self.fmt % y))
self.y = y
self.write('\n')
self.write_blocknum()
self.write( iso_codes.codes.TAP() )
self.write( iso_codes.codes.TAP_DEPTH(self.ffmt,pitch) + iso_codes.codes.SPACE() )
self.write(iso_codes.codes.Z() + (self.fmt % (z - depth))) # This is the 'z' value for the bottom of the tap.
self.write_misc()
self.write('\n')
self.z = retract_height # this cycle returns to the start position, so remember that as z value
nc.creator = CreatorEMC2tap()

View File

@@ -0,0 +1,105 @@
import math
class Format:
def __init__(self, number_of_decimal_places = 3, add_leading_zeros = 1, add_trailing_zeros = False, dp_wanted = True, add_plus = False, no_minus = False, round_down = False):
self.number_of_decimal_places = number_of_decimal_places
self.add_leading_zeros = add_leading_zeros # fill the start of the number with zeros, so there are at least this number of digits before the decimal point
self.add_trailing_zeros = add_trailing_zeros # fill the end of the number with zeros, as defined by "number_of_decimal_places"
self.dp_wanted = dp_wanted
self.add_plus = add_plus
self.no_minus = no_minus
self.round_down = round_down
def string(self, number):
if number == None:
return 'None'
f = float(number) * math.pow(10, self.number_of_decimal_places)
s = str(f)
if self.round_down == False:
if f < 0: f = f - .5
else: f = f + .5
s = str(number)
if math.fabs(f) < 1.0:
s = '0'
minus = False
if s[0] == '-':
minus = True
if self.no_minus:
s = s[1:]
dot = s.find('.')
if dot == -1:
before_dp = s
after_dp = ''
else:
before_dp = s[0:dot]
after_dp = s[dot + 1: dot + 1 + self.number_of_decimal_places]
before_dp = before_dp.zfill(self.add_leading_zeros)
if self.add_trailing_zeros:
for i in range(0, self.number_of_decimal_places - len(after_dp)):
after_dp += '0'
else:
after_dp = after_dp.rstrip('0')
s = ''
if minus == False:
if self.add_plus == True:
s += '+'
s += before_dp
if len(after_dp):
if self.dp_wanted: s += '.'
s += after_dp
return s
class Address:
def __init__(self, text, fmt = Format(), modal = True):
self.text = text
self.fmt = fmt
self.modal = modal
self.str = None
self.previous = None
def set(self, number):
self.str = self.text + self.fmt.string(number)
def write(self, writer):
if self.str == None: return ''
if self.modal:
if self.str != self.previous:
writer.write(self.str)
self.previous = self.str
else:
writer.write(self.str)
self.str = None
class AddressPlusMinus(Address):
def __init__(self, text, fmt = Format(), modal = True):
Address.__init__(self, text, fmt, modal)
self.str2 = None
self.previous2 = None
def set(self, number, text_plus, text_minus):
Address.set(self, number)
if float(number) > 0.0:
self.str2 = text_plus
else:
self.str2 = text_minus
def write(self, writer):
Address.write(self, writer)
if self.str2 == None: return ''
if self.modal:
if self.str2 != self.previous2:
writer.write(writer.SPACE())
writer.write(self.str2)
self.previous2 = self.str2
else:
writer.write(writer.SPACE())
writer.write(self.str2)
self.str2 = None

View File

@@ -0,0 +1,18 @@
import nc
import emc2
class Creator(emc2.Creator):
def init(self):
emc2.Creator.init(self)
def program_begin(self, id, comment):
self.write( ('(' + comment + ')' + '\n') )
def tool_defn(self, id, name='', params=None):
pass
def spindle(self, s, clockwise):
pass
nc.creator = Creator()

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,152 @@
################################################################################
# heiden_read.py
#
# Simple ISO NC code parsing
#
import nc_read as nc
import re
import sys
import math
################################################################################
class Parser(nc.Parser):
def __init__(self, writer):
nc.Parser.__init__(self, writer)
self.pattern_main = re.compile('([(!;].*'
'|\s+|[a-zA-Z0-9_:](?:[+-])?\d*(?:\.\d*)?'
'|\w\#\d+|\(.*?\)'
'|\#\d+\=(?:[+-])?\d*(?:\.\d*)? )')
self.pattern_tool = re.compile('([(!;].*'
'|\S+'
'|\s+|\d)')
self.oldx = 0
self.oldy = 0
self.oldz = 150
self.olda = 0
self.oldb = 0
self.oldc = 0
def ParseTool(self, word):
# parse the first numeric parameter that comes after 'tool call'
try:
if (word[0:] == 'TOOL'):
self.col = "tool"
self.move = False
elif (word[0:] == 'CALL'):
self.col = "tool call"
self.move = False
elif self.col == 'tool call':
if not self.t > 0:
if word[0] >= '0' and word[0] <= '9':
self.t = eval(word[0:])
self.col = 'tool no'
except:
pass
def change_tool(self, t):
pass
def ParseWord(self, word):
try:
if (word[0] == 'A' or word[0] == 'a'):
self.col = "axis"
self.a = eval(word[1:])
self.move = True
elif (word[0] == 'B' or word[0] == 'b'):
self.col = "axis"
self.b = eval(word[1:])
self.move = True
elif (word[0] == 'C' or word[0] == 'c'):
self.col = "axis"
self.c = eval(word[1:])
self.move = True
elif (word[0] == 'F' or word[0] == 'f'):
self.col = "axis"
if word[1:] == 'FMAX':
self.rapid = True
self.path_col = "rapid"
self.col = "rapid"
else:
self.f = eval(word[1:])
self.rapid = False
self.path_col = "feed"
self.col = "feed"
self.move = True
elif (word == 'L' or word == 'l'):
self.arc = 0
self.move = True
elif (word[0] == 'X' or word[0] == 'x'):
self.col = "axis"
self.x = eval(word[1:])
self.move = True
elif (word[0] == 'Y' or word[0] == 'y'):
self.col = "axis"
self.y = eval(word[1:])
self.move = True
elif (word[0] == 'Z' or word[0] == 'z'):
self.col = "axis"
self.z = eval(word[1:])
self.move = True
self.t = eval(word[1:])
except:
pass
def Parsey(self, name):
self.files_open(name)
for_full_machine_sim = True # to do, make derived class to do this
#for_full_machine_sim = False
self.f = None
self.arc = 0
self.rapid = True
while (self.readline()):
self.a = None
self.b = None
self.c = None
self.h = None
self.i = None
self.j = None
self.k = None
self.p = None
self.q = None
self.r = None
self.s = None
self.x = None
self.y = None
self.z = None
self.t = 0
self.move = False
self.no_move = False
words = self.pattern_tool.findall(self.line)
for word in words:
self.ParseTool(word)
if not self.t:
words = self.pattern_main.findall(self.line)
for word in words:
self.ParseWord(word)
if (self.move and not self.no_move):
if (self.arc==0):
self.add_line(self.x, self.y, self.z, self.a, self.b, self.rapid)
else:
self.add_arc(self.x, self.y, self.z, self.i, self.j, self.k, self.r, self.arc)
if self.x != None: self.oldx = self.x
if self.y != None: self.oldy = self.y
if self.z != None: self.oldz = self.z
if self.a != None: self.olda = self.a
if self.b != None: self.oldb = self.b
if self.c != None: self.oldc = self.c
elif (self.t):
self.change_tool(self.t)
self.files_close()

View File

@@ -0,0 +1,24 @@
import nc
import emc2
class Creator(emc2.Creator):
def init(self):
iso.Creator.init(self)
def program_begin(self, id, comment):
self.write( ('(' + comment + ')' + '\n') )
def tool_change(self, id):
self.write_blocknum()
self.write('G53 G00 Z30\n')
self.write_blocknum()
self.write((self.TOOL() % id) + '\n')
self.write_blocknum()
self.write('G01 Z100.000 F800.000\n')
self.write_blocknum()
self.write('M0\n')
self.write_blocknum()
self.write('G01 Z10.000 F300.000\n')
nc.creator = Creator()

View File

@@ -0,0 +1,109 @@
# hpgl2d.py
#
# Copyright (c) 2009, Dan Heeks
# This program is released under the BSD license. See the file COPYING for details.
#
import nc
import math
class Creator(nc.Creator):
def __init__(self):
nc.Creator.__init__(self)
self.x = int(0)
self.y = int(0) # these are in machine units, like 0.01mm or maybe 0.25mm
self.metric() # set self.units_to_mc_units
def imperial(self):
self.units_to_mc_units = 2540 # multiplier from inches to machine units
def metric(self):
self.units_to_mc_units = 100 # multiplier from mm to machine units
def program_begin(self, id, name=''):
self.write('IN;\n')
self.write('VS32,1;\n')
self.write('VS32,2;\n')
self.write('VS32,3;\n')
self.write('VS32,4;\n')
self.write('VS32,5;\n')
self.write('VS32,6;\n')
self.write('VS32,7;\n')
self.write('VS32,8;\n')
self.write('WU0;\n')
self.write('PW0.349,1;\n')
self.write('PW0.349,2;\n')
self.write('PW0.349,3;\n')
self.write('PW0.349,4;\n')
self.write('PW0.349,5;\n')
self.write('PW0.349,6;\n')
self.write('PW0.349,7;\n')
self.write('PW0.349,8;\n')
self.write('SP1;\n')
def program_end(self):
self.write('SP0;\n')
def closest_int(self, f):
if math.fabs(f) < 0.3:
return 0
elif f > 0:
return int(f + 0.5)
else:
return int(f - 0.5)
def get_machine_x_y(self, x=None, y=None):
machine_x = self.x
machine_y = self.y
if x != None:
machine_x = self.closest_int(x * self.units_to_mc_units)
if y != None:
machine_y = self.closest_int(y * self.units_to_mc_units)
return machine_x, machine_y
def rapid(self, x=None, y=None, z=None, a=None, b=None, c=None):
# ignore the z, any rapid will be assumed to be done with the pen up
mx, my = self.get_machine_x_y(x, y)
if mx != self.x or my != self.y:
self.write(('PU%i' % mx) + (' %i;\n' % my))
self.x = mx
self.y = my
def feed(self, x=None, y=None, z=None, a=None, b=None, c=None):
# ignore the z, any feed will be assumed to be done with the pen down
mx, my = self.get_machine_x_y(x, y)
if mx != self.x or my != self.y:
self.write(('PD%i' % mx) + (' %i;\n' % my))
self.x = mx
self.y = my
def arc(self, cw, x=None, y=None, z=None, i=None, j=None, k=None, r=None):
mx, my = self.get_machine_x_y(x, y)
if mx != self.x or my != self.y:
cx = float(self.x) / self.units_to_mc_units + i
cy = float(self.y) / self.units_to_mc_units + j
sdx = -i
sdy = -j
edx = x - cx
edy = y - cy
start_angle = math.atan2(sdy, sdx)
end_angle = math.atan2(edy, edx)
if cw:
if start_angle < end_angle: start_angle += 2 * math.pi
else:
if end_angle < start_angle: end_angle += 2 * math.pi
a = math.fabs(end_angle - start_angle)
if cw: a = -a
mcx, mcy = self.get_machine_x_y(cx, cy)
self.write(('AA%i' % mcx) + (',%i' % mcy) + (',%d;\n' % (a * 180 / math.pi)))
def arc_cw(self, x=None, y=None, z=None, i=None, j=None, k=None, r=None):
self.arc(True, x, y, z, i, j, k, r)
def arc_ccw(self, x=None, y=None, z=None, i=None, j=None, k=None, r=None):
self.arc(False, x, y, z, i, j, k, r)
nc.creator = Creator()

View File

@@ -0,0 +1,90 @@
import num_reader
import sys
import math
class Parser(num_reader.NumReader):
def __init__(self, writer):
num_reader.NumReader.__init__(self, writer)
self.i = 0
self.j = 0
self.x = 0
self.y = 0
self.down_z = 0
self.up_z = 20
self.up = True
self.units_to_mm = 0.01
def ParsePuOrPd(self, up):
self.line_index = self.line_index + 1
x = self.get_number()
if len(x) > 0:
y = self.get_number()
if len(y) > 0:
if up: color = "rapid"
else: color = "feed"
self.add_word(color)
self.writer.begin_path(color)
if up: z = self.up_z
else: z = self.down_z
if self.up != up:
self.writer.add_line(self.x * self.units_to_mm, self.y * self.units_to_mm, z)
self.writer.add_line(int(x) * self.units_to_mm, int(y) * self.units_to_mm, z)
self.writer.end_path()
self.up = up
self.x = int(x)
self.y = int(y)
def ParseAA(self):
self.line_index = self.line_index + 1
cx = self.get_number()
if len(cx) > 0:
cy = self.get_number()
if len(cy) > 0:
a = self.get_number()
if len(a) > 0:
self.add_word("feed")
self.writer.begin_path("feed")
z = self.down_z
if self.up:
self.writer.add_line(self.x * self.units_to_mm, self.y * self.units_to_mm, z)
sdx = self.x - int(cx)
sdy = self.y - int(cy)
start_angle = math.atan2(sdy, sdx)
end_angle = start_angle + int(a) * math.pi/180
radius = math.sqrt(sdx*sdx + sdy*sdy)
ex = int(cx) + radius * math.cos(end_angle)
ey = int(cy) + radius * math.sin(end_angle)
if int(a) > 0: d = 1
else: d = -1
self.writer.add_arc(ex * self.units_to_mm, ey * self.units_to_mm, 0.0, i = int(-sdx) * self.units_to_mm, j = int(-sdy) * self.units_to_mm, d = d)
self.writer.end_path()
self.up = False
self.x = int(ex)
self.y = int(ey)
def ParseFromFirstLetter(self, c):
if c == 'P':
self.line_index = self.line_index + 1
if self.line_index < self.line_length:
c1 = self.line[self.line_index]
self.parse_word += c1
if c1 == 'U': # PU
self.ParsePuOrPd(True)
elif c1 == 'D': # PD
self.ParsePuOrPd(False)
elif c == 'A':
self.line_index = self.line_index + 1
if self.line_index < self.line_length:
c1 = self.line[self.line_index]
self.parse_word += c1
if c1 == 'A': # AA, arc absolute
self.ParseAA()

View File

@@ -0,0 +1,22 @@
# hpgl2dv.py
#
# Copyright (c) 2009, Dan Heeks
# This program is released under the BSD license. See the file COPYING for details.
#
# This is the same as the hpgl2d machine, but uses units of 0.25mm instead of 0.01mm
import nc
import hpgl2d
class Creator(hpgl2d.Creator):
def init(self):
hpgl2d.Creator.init(self)
def imperial(self):
self.units_to_mc_units = 101.6 # multiplier from inches to machine units
def metric(self):
self.units_to_mc_units = 4 # multiplier from mm to machine units
nc.creator = Creator()

View File

@@ -0,0 +1,9 @@
import hpgl2d_read as hpgl
import sys
# same as hpgl2d, but with 0.25mm units, instead of 0.01mm
class Parser(hpgl.Parser):
def __init__(self, writer):
hpgl.Parser.__init__(self, writer)
self.units_to_mm = 0.25

View File

@@ -0,0 +1,64 @@
# hpgl3d.py
#
# Copyright (c) 2009, Dan Heeks
# This program is released under the BSD license. See the file COPYING for details.
#
import nc
import hpgl2d
import math
class Creator(hpgl2d.Creator):
def __init__(self):
hpgl2d.Creator.__init__(self)
self.z = int(0)
self.metric() # set self.units_to_mc_units
self.doing_rapid = True
def program_begin(self, id, name=''):
self.write(';;^IN;!MC0;\n')
self.write('V50.0;^PR;Z0,0,10500;^PA;\n')
self.write('!RC15;\n')
self.write('!MC1;\n')
def program_end(self):
self.write('!VZ50.0;!ZM0;\n')
self.write('!MC0;^IN;\n')
def get_machine_xyz(self, x=None, y=None, z=None):
machine_x = self.x
machine_y = self.y
machine_z = self.z
if x != None:
machine_x = self.closest_int(x * self.units_to_mc_units)
if y != None:
machine_y = self.closest_int(y * self.units_to_mc_units)
if z != None:
machine_z = self.closest_int(z * self.units_to_mc_units)
return machine_x, machine_y, machine_z
def rapid(self, x=None, y=None, z=None, a=None, b=None, c=None):
# do a rapid move.
# for now, do all rapid moves at V50 ( 50 mm/s )
mx, my, mz = self.get_machine_xyz(x, y, z)
if mx != self.x or my != self.y or mz != self.z:
if self.doing_rapid == False: self.write('V50.0;')
self.write(('Z%i' % mx) + (',%i' % my) + (',%i;\n' % mz))
self.x = mx
self.y = my
self.z = mz
self.doing_rapid = True
def feed(self, x=None, y=None, z=None, a=None, b=None, c=None):
# do a feed move.
# for now, do all feed moves at V10 ( 10 mm/s )
mx, my, mz = self.get_machine_xyz(x, y, z)
if mx != self.x or my != self.y or mz != self.z:
if self.doing_rapid == True: self.write('V10.0;')
self.write(('Z%i' % mx) + (',%i' % my) + (',%i;\n' % mz))
self.x = mx
self.y = my
self.z = mz
self.doing_rapid = False
nc.creator = Creator()

View File

@@ -0,0 +1,45 @@
import num_reader
import sys
import math
class Parser(num_reader.NumReader):
def __init__(self, writer):
num_reader.NumReader.__init__(self, writer)
self.x = 0
self.y = 0
self.z = 10000
self.f = 0
self.units_to_mm = 0.01
def ParseV(self):
self.line_index = self.line_index + 1
f = self.get_number()
if len(f) > 0:
self.f = float(f)
self.add_word("prep")
def ParseZ(self):
self.line_index = self.line_index + 1
x = self.get_number()
if len(x) > 0:
y = self.get_number()
if len(y) > 0:
z = self.get_number()
if len(z) > 0:
if self.f > 40: color = "rapid"
else: color = "feed"
self.add_word(color)
self.writer.begin_path(color)
self.writer.add_line(int(x) * self.units_to_mm, int(y) * self.units_to_mm, int(z) * self.units_to_mm)
self.writer.end_path()
self.x = int(x)
self.y = int(y)
self.z = int(z)
def ParseFromFirstLetter(self, c):
if c == 'Z':
self.ParseZ()
elif c == 'V':
self.ParseV()

View File

@@ -0,0 +1,130 @@
import tempfile
class HxmlWriter:
def __init__(self):
self.file_out = open(tempfile.gettempdir()+'/backplot.xml', 'w')
self.file_out.write('<?xml version="1.0" ?>\n')
self.file_out.write('<nccode>\n')
self.t = None
self.oldx = None
self.oldy = None
self.oldz = None
def __del__(self):
self.file_out.write('</nccode>\n')
self.file_out.close()
def write(self, s):
self.file_out.write(s)
############################################
def begin_ncblock(self):
self.file_out.write('\t<ncblock>\n')
def end_ncblock(self):
self.file_out.write('\t</ncblock>\n')
def add_text(self, s, col, cdata):
s.replace('&', '&amp;')
s.replace('"', '&quot;')
s.replace('<', '&lt;')
s.replace('>', '&gt;')
if (cdata) : (cd1, cd2) = ('<![CDATA[', ']]>')
else : (cd1, cd2) = ('', '')
if (col != None) : self.file_out.write('\t\t<text col="'+col+'">'+cd1+s+cd2+'</text>\n')
else : self.file_out.write('\t\t<text>'+cd1+s+cd2+'</text>\n')
def set_mode(self, units):
self.file_out.write('\t\t<mode')
if (units != None) : self.file_out.write(' units="'+str(units)+'"')
self.file_out.write(' />\n')
def metric(self):
self.set_mode(units = 1.0)
def imperial(self):
self.set_mode(units = 25.4)
def begin_path(self, col):
if (col != None) : self.file_out.write('\t\t<path col="'+col+'">\n')
else : self.file_out.write('\t\t<path>\n')
def end_path(self):
self.file_out.write('\t\t</path>\n')
def rapid(self, x=None, y=None, z=None, a=None, b=None, c=None):
self.begin_path("rapid")
self.add_line(x, y, z, a, b, c)
self.end_path()
def feed(self, x=None, y=None, z=None, a=None, b=None, c=None):
self.begin_path("feed")
self.add_line(x, y, z, a, b, c)
self.end_path()
def arc_cw(self, x=None, y=None, z=None, i=None, j=None, k=None, r=None):
self.begin_path("feed")
self.add_arc(x, y, z, i, j, k, r, -1)
self.end_path()
def arc_ccw(self, x=None, y=None, z=None, i=None, j=None, k=None, r=None):
self.begin_path("feed")
self.add_arc(x, y, z, i, j, k, r, 1)
self.end_path()
def tool_change(self, id):
self.file_out.write('\t\t<tool')
if (id != None) :
self.file_out.write(' number="'+str(id)+'"')
self.file_out.write(' />\n')
self.t = id
def current_tool(self):
return self.t
def spindle(self, s, clockwise):
pass
def feedrate(self, f):
pass
def add_line(self, x, y, z, a = None, b = None, c = None):
self.file_out.write('\t\t\t<line')
if (x != None) :
self.file_out.write(' x="%.6f"' % x)
if (y != None) :
self.file_out.write(' y="%.6f"' % y)
if (z != None) :
self.file_out.write(' z="%.6f"' % z)
if (a != None) : self.file_out.write(' a="%.6f"' % a)
if (b != None) : self.file_out.write(' b="%.6f"' % b)
if (c != None) : self.file_out.write(' c="%.6f"' % c)
self.file_out.write(' />\n')
if x != None: self.oldx = x
if y != None: self.oldy = y
if z != None: self.oldz = z
def add_arc(self, x, y, z, i, j, k, r = None, d = None):
self.file_out.write('\t\t\t<arc')
if (x != None) :
self.file_out.write(' x="%.6f"' % x)
if (y != None) :
self.file_out.write(' y="%.6f"' % y)
if (z != None) :
self.file_out.write(' z="%.6f"' % z)
if (i != None):
if self.oldx == None: print 'arc move "i" without x set!'
else: self.file_out.write(' i="%.6f"' % (i - self.oldx))
if (j != None):
if self.oldy == None: print 'arc move "j" without y set!'
else: self.file_out.write(' j="%.6f"' % (j - self.oldy))
if (k != None):
if self.oldz == None: print 'arc move "k" without z set!'
else: self.file_out.write(' k="%.6f"' % (k - self.oldz))
if (r != None) : self.file_out.write(' r="%.6f"' % r)
if (d != None) : self.file_out.write(' d="%i"' % d)
self.file_out.write(' />\n')
if x != None: self.oldx = x
if y != None: self.oldy = y
if z != None: self.oldz = z

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,4 @@
class Codes():
pass
codes = Codes()

View File

@@ -0,0 +1,21 @@
################################################################################
# iso_crc.py
#
# a class derived from iso machine, with Cutter Radius Compensation turned on.
#
# Dan Heeks, 4th May 2010
import nc
import iso
import math
################################################################################
class Creator(iso.Creator):
def __init__(self):
iso.Creator.__init__(self)
self.useCrc = True
################################################################################
nc.creator = Creator()

View File

@@ -0,0 +1,22 @@
################################################################################
# iso_modal.py
#
# a class derived from iso machine, but with XYZF G1, G2 etc modal to reduce the size of the file.
#
# Dan Heeks, 4th May 2010
import nc
import iso
import math
################################################################################
class Creator(iso.Creator):
def __init__(self):
iso.Creator.__init__(self)
self.f_modal = True
self.g0123_modal = True
self.drill_modal = True
################################################################################
nc.creator = Creator()

View File

@@ -0,0 +1,164 @@
################################################################################
# iso_read.py
#
# Simple ISO NC code parsing
#
# Hirutso Enni, 2009-01-13
import nc_read as nc
import re
import sys
################################################################################
class Parser(nc.Parser):
def __init__(self, writer):
nc.Parser.__init__(self, writer)
self.pattern_main = re.compile('([(!;].*|\s+|[a-zA-Z0-9_:](?:[+-])?\d*(?:\.\d*)?|\w\#\d+|\(.*?\)|\#\d+\=(?:[+-])?\d*(?:\.\d*)?)')
self.arc_centre_absolute = False
self.arc_centre_positive = False
self.oldx = None
self.oldy = None
self.oldz = None
#if ( or ! or ; at least one space or a letter followed by some character or not followed by a +/- followed by decimal, with a possible decimal point
# followed by a possible deimcal, or a letter followed by # with a decimal . deimcal
# add your character here > [(!;] for comments char
# then look for the 'comment' function towards the end of the file and add another elif
def ParseWord(self, word):
word == word.upper()
if (word[0] == 'A'):
self.col = "axis"
self.a = eval(word[1:])
self.move = True
elif (word[0] == 'B'):
self.col = "axis"
self.b = eval(word[1:])
self.move = True
elif (word[0] == 'C'):
self.col = "axis"
self.c = eval(word[1:])
self.move = True
elif (word[0] == 'F'):
self.col = "axis"
self.writer.feedrate(word[1:])
elif (word[0] == 'H'):
self.col = "axis"
self.h = eval(word[1:])
self.move = True
elif (word == 'G0' or word == 'G00'):
self.path_col = "rapid"
self.col = "rapid"
self.arc = 0
elif (word == 'G1' or word == 'G01'):
self.path_col = "feed"
self.col = "feed"
self.arc = 0
elif (word == 'G2' or word == 'G02' or word == 'G12'):
self.path_col = "feed"
self.col = "feed"
self.arc = -1
elif (word == 'G3' or word == 'G03' or word == 'G13'):
self.path_col = "feed"
self.col = "feed"
self.arc = +1
elif (word == 'G10'):
self.no_move = True
elif (word == 'G53'):
self.no_move = True
elif (word == 'L1'):
self.no_move = True
elif (word == 'G61.1' or word == 'G61' or word == 'G64'):
self.no_move = True
elif (word == 'G20' or word == 'G70'):
self.col = "prep"
self.writer.imperial()
elif (word == 'G21' or word == 'G71'):
self.col = "prep"
self.writer.metric()
elif (word == 'G43'):
self.height_offset = True
self.move = True
self.path_col = "rapid"
self.col = "rapid"
elif (word == 'G80'):
self.drill_off = True
elif (word == 'G81'):
self.drill = True
self.no_move = True
self.path_col = "feed"
self.col = "feed"
elif (word == 'G82'):
self.drill = True;
self.no_move = True
self.path_col = "feed"
self.col = "feed"
elif (word == 'G83'):
self.drill = True
self.no_move = True
self.path_col = "feed"
self.col = "feed"
elif (word == 'G90'):
self.absolute()
elif (word == 'G91'):
self.incremental()
elif (word == 'G98'):
self.drilling_uses_clearance = True
elif (word == 'G99'):
self.drilling_uses_clearance = False
elif (word[0] == 'G') : col = "prep"
elif (word[0] == 'I'):
self.col = "axis"
self.i = eval(word[1:])
self.move = True
elif (word[0] == 'J'):
self.col = "axis"
self.j = eval(word[1:])
self.move = True
elif (word[0] == 'K'):
self.col = "axis"
self.k = eval(word[1:])
self.move = True
elif (word[0] == 'M') : self.col = "misc"
elif (word[0] == 'N') : self.col = "blocknum"
elif (word[0] == 'O') : self.col = "program"
elif (word[0] == 'P'):
if (self.no_move != True):
self.col = "axis"
self.p = eval(word[1:])
self.move = True
elif (word[0] == 'Q'):
if (self.no_move != True):
self.col = "axis"
self.q = eval(word[1:])
self.move = True
elif (word[0] == 'R'):
self.col = "axis"
self.r = eval(word[1:])
self.move = True
elif (word[0] == 'S'):
self.col = "axis"
self.writer.spindle(word[1:], (float(word[1:]) >= 0.0))
elif (word[0] == 'T') :
self.col = "tool"
self.writer.tool_change( eval(word[1:]) )
elif (word[0] == 'X'):
self.col = "axis"
self.x = eval(word[1:])
self.move = True
elif (word[0] == 'Y'):
self.col = "axis"
self.y = eval(word[1:])
self.move = True
elif (word[0] == 'Z'):
self.col = "axis"
self.z = eval(word[1:])
self.move = True
elif (word[0] == '(') : (self.col, self.cdata) = ("comment", True)
elif (word[0] == '!') : (self.col, self.cdata) = ("comment", True)
elif (word[0] == ';') : (self.col, self.cdata) = ("comment", True)
elif (word[0] == '#') : self.col = "variable"
elif (word[0] == ':') : self.col = "blocknum"
elif (ord(word[0]) <= 32) : self.cdata = True

View File

@@ -0,0 +1,20 @@
import nc
import iso
class Creator(iso.Creator):
def init(self):
iso.Creator.init(self)
def SPACE(self): return(' ')
def program_begin(self, id, comment):
self.write( ('(' + 'GCode created using the HeeksCNC Mach3 post processor' + ')' + '\n') )
self.write( ('(' + comment + ')' + '\n') )
def tool_change(self, id):
self.write('G43H%i'% id +'\n')
self.write((self.TOOL() % id) + '\n')
self.t = id
nc.creator = Creator()

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Machine post="emc2b" reader="iso_read" suffix=".ngc" description="LinuxCNC"/>
<Machine post="siegkx1" reader="iso_read" suffix=".tap" description="Mach3 Machine Controller"/>
<Machine post="DeckelFP4Ma" reader="iso_read" suffix=".ngc" description="Deckel FP4Ma"/>
<Machine post="hpgl2d" reader="hpgl2d_read" suffix=".tap" description="HPGL2D"/>
<Machine post="hpgl2dv" reader="hpgl2dv_read" suffix=".tap" description="HPGL2DV"/>
<Machine post="hpgl3d" reader="hpgl3d_read" suffix=".tap" description="HPGL3D"/>

View File

@@ -0,0 +1,306 @@
import nc
import makerbot_codes as maker
import datetime
import iso_modal
import math
now = datetime.datetime.now()
################################################################################
class CreatorMakerbotHBP(iso_modal.CreatorIsoModal):
def __init__(self):
iso_modal.CreatorIsoModal.__init__(self)
self.absolute_flag = True
self.prev_g91 = ''
################################################################################
# program begin and end
def program_begin(self, id, name=''):
self.write((maker.codes.COMMENT(now)))
self.write((maker.codes.EXTRUDER_TEMP('220')) + (maker.codes.COMMENT('Extruder Temp')) )
self.write((maker.codes.BUILD_BED_TEMP('110'))+ (maker.codes.COMMENT('Build Bed Temp')) )
self.write((maker.codes.FAN_OFF()) + (maker.codes.COMMENT('Fan Off')) )
self.write((maker.codes.METRIC()) + (maker.codes.COMMENT('Metric units')) )
self.write((maker.codes.ABSOLUTE()) + (maker.codes.COMMENT('Absolute units')) )
self.write('G92 X0 Y0 Z0 (You are now at 0,0,0)\n')
self.write('G0 Z15 (Move up for warmup)\n')
self.write((maker.codes.EXTRUDER_SPEED_PWM('255')) + (maker.codes.COMMENT('Extruder Speed')) )
self.write('M6 T0 (Wait for tool to heat up)\n')
self.write('G04 P5000 (Wait 5 seconds)\n')
self.write((maker.codes.EXTRUDER_ON_FWD()) + (maker.codes.COMMENT('Extruder On')) )
self.write('G04 P5000 (Wait 5 seconds)\n')
self.write((maker.codes.EXTRUDER_OFF()) + (maker.codes.COMMENT('Extruder Off')) )
self.write('M01 (The heated build platform is heating up. Wait until after the lights have turned off for the first time, clear the test extrusion, and click yes.)\n')
self.write('G0 Z0 (Go back to zero.)\n')
def program_end(self):
self.write((maker.codes.COMMENT('End of the file. Begin cool-down')))
self.write((maker.codes.EXTRUDER_TEMP('0')) + (maker.codes.COMMENT('Extruder Temp')) )
self.write((maker.codes.BUILD_BED_TEMP('0')) + (maker.codes.COMMENT('Build Bed Temp')) )
self.write((maker.codes.FAN_ON()) + (maker.codes.COMMENT('Fan On')) )
self.write('G92 Z0 (zero our z axis - hack b/c skeinforge mangles gcodes in end.txt)\n')
self.write('G1 Z10 (go up 10 b/c it was zeroed earlier.)\n')
self.write('G1 X0 Y0 Z10 (go to 0,0,z)\n')
self.write((maker.codes.STEPPERS_OFF()) + (maker.codes.COMMENT('Steppers Off')) )
def program_stop(self):
self.write((maker.codes.EXTRUDER_TEMP('0')))
self.write((maker.codes.BUILD_BED_TEMP('0')))
self.write((maker.codes.STEPPERS_OFF()))
################################################################################
# general
def write_blocknum(self):
pass
def set_plane(self, plane):
pass
def workplane(self, id):
pass
def spindle(self, s, clockwise):
pass
################################################################################
# Extruder Control
def extruder_on(self):
self.write((maker.codes.EXTRUDER_ON()) + ('\n'))
def extruder_off(self):
self.write((maker.codes.EXTRUDER_OFF()) + ('\n'))
def set_extruder_flowrate(self, flowrate):
self.write((maker.codes.EXTRUDER_SPEED_PWM(flowrate)) + ('\n'))
def extruder_temp(self, temp):
self.write((maker.codes.EXTRUDER_TEMP(temp)) + ('\n'))
################################################################################
# Build Environment Control
def build_bed_temp(self, temp):
self.write((maker.codes.BUILD_BED_TEMP(temp)) + ('\n'))
def chamber_temp(self, temp):
self.write((maker.codes.CHAMBER_TEMP(temp)) + ('\n'))
################################################################################
# Fan Control
def fan_on(self):
self.write((maker.codes.FAN_ON()) + ('\n'))
def fan_off(self):
self.write((maker.codes.FAN_OFF()) + ('\n'))
################################################################################
# Custom routines
def wipe(self):
self.write(('(This would be a good place for a custom wipe routine)\n'))
################################################################################
# APT style INSERT- insert anything into program
def insert(self, text):
self.write((text + '\n'))
################################################################################
# tool info
def tool_change(self, id):
pass
# self.write_blocknum()
# self.write((maker.codes.TOOL() % id) + '\n')
# self.t = id
def tool_defn(self, id, name='', params=None):
pass
############################################################################
## Moves
def rapid(self, x=None, y=None, z=None, a=None, b=None, c=None ):
self.write_blocknum()
if self.g0123_modal:
if self.prev_g0123 != maker.codes.RAPID():
self.write(maker.codes.RAPID())
self.prev_g0123 = maker.codes.RAPID()
else:
self.write(maker.codes.RAPID())
self.write_preps()
if (x != None):
dx = x - self.x
if (self.absolute_flag ):
self.write(maker.codes.X() + (self.fmt % x))
else:
self.write(maker.codes.X() + (self.fmt % dx))
self.x = x
if (y != None):
dy = y - self.y
if (self.absolute_flag ):
self.write(maker.codes.Y() + (self.fmt % y))
else:
self.write(maker.codes.Y() + (self.fmt % dy))
self.y = y
if (z != None):
dz = z - self.z
if (self.absolute_flag ):
self.write(maker.codes.Z() + (self.fmt % z))
else:
self.write(maker.codes.Z() + (self.fmt % dz))
self.z = z
if (a != None):
da = a - self.a
if (self.absolute_flag ):
self.write(maker.codes.A() + (self.fmt % a))
else:
self.write(maker.codes.A() + (self.fmt % da))
self.a = a
if (b != None):
db = b - self.b
if (self.absolute_flag ):
self.write(maker.codes.B() + (self.fmt % b))
else:
self.write(maker.codes.B() + (self.fmt % db))
self.b = b
if (c != None):
dc = c - self.c
if (self.absolute_flag ):
self.write(maker.codes.C() + (self.fmt % c))
else:
self.write(maker.codes.C() + (self.fmt % dc))
self.c = c
self.write_spindle()
self.write_misc()
self.write('\n')
def feed(self, x=None, y=None, z=None, a = None, b = None, c = None):
if self.same_xyz(x, y, z): return
self.write_blocknum()
if self.g0123_modal:
if self.prev_g0123 != maker.codes.FEED():
self.write(maker.codes.FEED())
self.prev_g0123 = maker.codes.FEED()
else:
self.write(maker.codes.FEED())
self.write_preps()
dx = dy = dz = 0
if (x != None):
dx = x - self.x
if (self.absolute_flag ):
self.write(maker.codes.X() + (self.fmt % x))
else:
self.write(maker.codes.X() + (self.fmt % dx))
self.x = x
if (y != None):
dy = y - self.y
if (self.absolute_flag ):
self.write(maker.codes.Y() + (self.fmt % y))
else:
self.write(maker.codes.Y() + (self.fmt % dy))
self.y = y
if (z != None):
dz = z - self.z
if (self.absolute_flag ):
self.write(maker.codes.Z() + (self.fmt % z))
else:
self.write(maker.codes.Z() + (self.fmt % dz))
self.z = z
if (self.fhv) : self.calc_feedrate_hv(math.sqrt(dx*dx+dy*dy), math.fabs(dz))
self.write_feedrate()
self.write_spindle()
self.write_misc()
self.write('\n')
def same_xyz(self, x=None, y=None, z=None):
if (x != None):
if (self.fmt % x) != (self.fmt % self.x):
return False
if (y != None):
if (self.fmt % y) != (self.fmt % self.y):
return False
if (z != None):
if (self.fmt % z) != (self.fmt % self.z):
return False
return True
def arc(self, cw, x=None, y=None, z=None, i=None, j=None, k=None, r=None):
if self.same_xyz(x, y, z): return
self.write_blocknum()
arc_g_code = ''
if cw: arc_g_code = maker.codes.ARC_CW()
else: arc_g_code = maker.codes.ARC_CCW()
if self.g0123_modal:
if self.prev_g0123 != arc_g_code:
self.write(arc_g_code)
self.prev_g0123 = arc_g_code
else:
self.write(arc_g_code)
self.write_preps()
if (x != None):
dx = x - self.x
if (self.absolute_flag ):
self.write(maker.codes.X() + (self.fmt % x))
else:
self.write(maker.codes.X() + (self.fmt % dx))
self.x = x
if (y != None):
dy = y - self.y
if (self.absolute_flag ):
self.write(maker.codes.Y() + (self.fmt % y))
else:
self.write(maker.codes.Y() + (self.fmt % dy))
self.y = y
if (z != None):
dz = z - self.z
if (self.absolute_flag ):
self.write(maker.codes.Z() + (self.fmt % z))
else:
self.write(maker.codes.Z() + (self.fmt % dz))
self.z = z
if (i != None) : self.write(maker.codes.CENTRE_X() + (self.fmt % i))
if (j != None) : self.write(maker.codes.CENTRE_Y() + (self.fmt % j))
if (k != None) : self.write(maker.codes.CENTRE_Z() + (self.fmt % k))
if (r != None) : self.write(maker.codes.RADIUS() + (self.fmt % r))
# use horizontal feed rate
if (self.fhv) : self.calc_feedrate_hv(1, 0)
self.write_feedrate()
self.write_spindle()
self.write_misc()
self.write('\n')
def arc_cw(self, x=None, y=None, z=None, i=None, j=None, k=None, r=None):
self.arc(True, x, y, z, i, j, k, r)
def arc_ccw(self, x=None, y=None, z=None, i=None, j=None, k=None, r=None):
self.arc(False, x, y, z, i, j, k, r)
def dwell(self, t):
self.write_blocknum()
self.write_preps()
self.write(maker.codes.DWELL() + (maker.codes.TIME() % t))
self.write_misc()
self.write('\n')
def rapid_home(self, x=None, y=None, z=None, a=None, b=None, c=None):
pass
def rapid_unhome(self):
pass
def set_machine_coordinates(self):
self.write(maker.codes.MACHINE_COORDINATES())
self.prev_g0123 = ''
nc.creator = CreatorMakerbotHBP()

View File

@@ -0,0 +1,128 @@
################################################################################
# makerbot_codes.py
#
# a lot like iso_codes.py but with reprap/makerbot specific M codes.
#
# Brad Collette, 12th Sept 2010
#
# Many of these codes have nothing to do with reprap/additive machining but are left here in anticipation of future hybrid machines.
class Codes():
def SPACE(self): return(' ')
def FORMAT_FEEDRATE(self): return('%.2f')
def FORMAT_IN(self): return('%.5f')
def FORMAT_MM(self): return('%.3f')
def FORMAT_ANG(self): return('%.1f')
def FORMAT_TIME(self): return('%.2f')
def FORMAT_DWELL(self): return('P%f')
def BLOCK(self): return('N%i' + self.SPACE())
def COMMENT(self,comment): return( (' (%s)\n' % comment ) )
def VARIABLE(self): return( '#%i')
def VARIABLE_SET(self): return( '=%.3f')
def PROGRAM(self): return( 'O%i')
def PROGRAM_END(self): return( 'M02')
def SUBPROG_CALL(self): return( 'M98' + self.SPACE() + 'P%i')
def SUBPROG_END(self): return( 'M99')
def STOP_OPTIONAL(self): return('M01')
def STOP(self): return('M00')
def IMPERIAL(self): return(self.SPACE() + 'G20')
def METRIC(self): return(self.SPACE() + 'G21' + self.SPACE())
def ABSOLUTE(self): return(self.SPACE() + 'G90' + self.SPACE())
def INCREMENTAL(self): return(self.SPACE() + 'G91')
def SET_TEMPORARY_COORDINATE_SYSTEM(self): return('G92' + self.SPACE())
def REMOVE_TEMPORARY_COORDINATE_SYSTEM(self): return('G92.1' + self.SPACE())
def POLAR_ON(self): return(self.SPACE() + 'G16')
def POLAR_OFF(self): return(self.SPACE() + 'G15')
def PLANE_XY(self): return(self.SPACE() + 'G17')
def PLANE_XZ(self): return(self.SPACE() + 'G18')
def PLANE_YZ(self): return(self.SPACE() + 'G19')
def TOOL(self): return(self.SPACE() +'T%i')
def TOOL_DEFINITION(self): return('G10' + self.SPACE() + 'L1' + self.SPACE())
def WORKPLANE(self): return('G%i')
def WORKPLANE_BASE(self): return(53)
def FEEDRATE(self): return((self.SPACE() + ' F'))
def SPINDLE(self, format, speed): return(self.SPACE() + 'S' + (format % speed))
def SPINDLE_CW(self): return(self.SPACE() + 'M03')
def SPINDLE_CCW(self): return(self.SPACE() + 'M04')
def COOLANT_OFF(self): return(self.SPACE() + 'M09')
def COOLANT_MIST(self): return(self.SPACE() + 'M07')
def COOLANT_FLOOD(self): return(self.SPACE() + 'M08')
def GEAR_OFF(self): return(self.SPACE() + '?')
def GEAR(self): return('M%i')
def GEAR_BASE(self): return(37)
def RAPID(self): return('G0')
def FEED(self): return('G1')
def ARC_CW(self): return('G2')
def ARC_CCW(self): return('G3')
def DWELL(self): return('G04')
def DRILL(self): return(self.SPACE() + 'G81')
def DRILL_WITH_DWELL(self, format, dwell): return(self.SPACE() + 'G82' + (format % dwell))
def PECK_DRILL(self): return(self.SPACE() + 'G83')
def PECK_DEPTH(self, format, depth): return(self.SPACE() + 'Q' + (format % depth))
def RETRACT(self, format, height): return(self.SPACE() + 'R' + (format % height))
def END_CANNED_CYCLE(self): return(self.SPACE() + 'G80')
def X(self): return(self.SPACE() + 'X')
def Y(self): return(self.SPACE() + 'Y')
def Z(self): return(self.SPACE() + 'Z')
def A(self): return(self.SPACE() + 'A')
def B(self): return(self.SPACE() + 'B')
def C(self): return(self.SPACE() + 'C')
def CENTRE_X(self): return(self.SPACE() + 'I')
def CENTRE_Y(self): return(self.SPACE() + 'J')
def CENTRE_Z(self): return(self.SPACE() + 'K')
def RADIUS(self): return(self.SPACE() + 'R')
def TIME(self): return(self.SPACE() + 'P')
def PROBE_TOWARDS_WITH_SIGNAL(self): return('G38.2' + self.SPACE())
def PROBE_TOWARDS_WITHOUT_SIGNAL(self): return('G38.3' + self.SPACE())
def PROBE_AWAY_WITH_SIGNAL(self): return('G38.4' + self.SPACE())
def PROBE_AWAY_WITHOUT_SIGNAL(self): return('G38.5' + self.SPACE())
def MACHINE_COORDINATES(self): return('G53' + self.SPACE())
def EXTRUDER_ON (self): return('M101') #deprecated
def EXTRUDER_OFF (self): return('M103')
def EXTRUDER_TEMP (self, degree_celsius): return('M104 S' + '%s' % degree_celsius)
def EXTRUDER_TEMP_WAIT (self, degree_celsius): return('M109 S' + '%s' % degree_celsius)
def READ_EXTRUDER_TEMP (self): return('M105')
def EXTRUDER_SPEED_PWM (self, speed_in_PWM): return('M108 S' + '%s' % speed_in_PWM) #deprecated
def EXTRUDER_SPEED_RPM (self, speed_in_RPM): return('M108 P' + '%s' % speed_in_RPM) #deprecated
def STEPPERS_OFF(self): return(self.SPACE() + 'M118')
def ALL_WAIT (self): return(self.SPACE() + 'M116') # Wait for all temperature and slow-changing variables to reach set values
def FAN_ON (self): return(self.SPACE() + 'M106')
def FAN_OFF (self): return(self.SPACE() + 'M107')
def VALVE_OPEN (self, delay): return(self.SPACE() + ('M126 P' + '%' % delay) )
def VALVE_CLOSE (self, delay): return(self.SPACE() + ('M127 P' + '%' % delay) )
def BUILD_BED_TEMP (self, degree_celsius): return('M140 S' + '%s' % degree_celsius)
def BED_HOLDING_PRESSURE (self, pressure): return('M142 S' + '%s' % pressure)
def CHAMBER_TEMP (self, degree_celsius): return('M141 S' + '%s' % degree_celsius)
#The following codes are listed on the reprap wiki page at http://reprap.org/wiki/Mendel_User_Manual:_RepRapGCodes but require more study.
#
#G28 G Y Xnnn Ynnn Znnn Move to origin (on specified axes only, if X/Y/Z parameters are present)
#M105 M N none Request current extruder and base temperatures (in Celsius)
#M110 M N none Set current line number to Nxxx value preceeding command
#M111 M N Snnn Set debug level bitfield to value of parameter (default 6)
#M112 M N none Emergency stop (stop immediately, discarding any buffered commands)
#M113 M N Snnn Set Extruder PWM (to value defined by pot, or to parameter value if present)
#M114 M N none Get Current Position (return current X, Y, Z and E values)
#M117 M N none Get Zero Position (return X, Y, Z and E values of endstop hits)
codes = Codes()

View File

@@ -0,0 +1,636 @@
################################################################################
# nc.py
#
# Base class for NC code creation
# And global functions for calling current creator
#
# Hirutso Enni, 2009-01-13
# altered by Dan Falck 2010-08-04
# added tap() arguments Michael Haberler 2010-10-07
################################################################################
ncOFF = 0
ncLEFT = -1
ncRIGHT = +1
ncCW = -1
ncCCW = +1
ncMIST = 1
ncFLOOD = 2
################################################################################
class Creator:
def __init__(self):
pass
############################################################################
## Internals
def file_open(self, name):
if name == "mem":
self.gcode = ""
else:
self.file = open(name, 'w')
self.filename = name
def file_close(self):
if self.filename != "mem":
self.file.close()
def write(self, s):
if self.filename == "mem":
self.gcode += s
else:
self.file.write(s)
def retrieve_gcode(self):
return self.gcode
############################################################################
## Programs
def program_begin(self, id, name=''):
"""Begin a program"""
pass
def add_stock(self, type_name, params):
pass
def program_stop(self, optional=False):
"""Stop the machine"""
pass
def program_end(self):
"""End the program"""
pass
def flush_nc(self):
"""Flush all pending codes"""
pass
############################################################################
## Subprograms
def sub_begin(self, id, name=''):
"""Begin a subprogram"""
pass
def sub_call(self, id):
"""Call a subprogram"""
pass
def sub_end(self):
"""Return from a subprogram"""
pass
############################################################################
## Settings
def imperial(self):
"""Set imperial units"""
pass
def metric(self):
"""Set metric units"""
pass
def absolute(self):
"""Set absolute coordinates"""
pass
def incremental(self):
"""Set incremental coordinates"""
pass
def polar(self, on=True):
"""Set polar coordinates"""
pass
def set_plane(self, plane):
"""Set plane"""
pass
def set_temporary_origin(self, x=None, y=None, z=None, a=None, b=None, c=None):
"""Set temporary origin G92"""
pass
def remove_temporary_origin(self):
"""Remote temporary origin G92.1"""
pass
############################################################################
## Tools
def tool_change(self, id):
"""Change the tool"""
pass
def tool_defn(self, id, name='', params=None):
"""Define a tool"""
pass
def offset_radius(self, id, radius=None):
"""Set tool radius offsetting"""
pass
def offset_length(self, id, length=None):
"""Set tool length offsetting"""
pass
def current_tool(self):
return None
############################################################################
## Datums
def datum_shift(self, x=None, y=None, z=None, a=None, b=None, c=None):
"""Shift the datum"""
pass
def datum_set(self, x=None, y=None, z=None, a=None, b=None, c=None):
"""Set the datum"""
pass
def workplane(self, id):
"""Set the workplane"""
pass
def clearanceplane(self,z=None):
"""set clearance plane"""
pass
############################################################################
## APT360 like Transformation Definitions
## These definitions were created while looking at Irvin Kraal's book on APT
## - Numerical Control Progamming in APT - page 211
def matrix(self,a1=None,b1=None,c1=None,a2=None,b2=None,c2=None,a3=None,b3=None,c3=None):
"""Create a matrix for transformations"""
pass
def translate(self,x=None,y=None,z=None):
"""Translate in x,y,z direction"""
pass
def rotate(self,xyrot=None,yzrot=None,zxrot=None,angle=None):
"""Rotate about a coordinate axis"""
pass
def scale(self,k=None):
"""Scale by factor k"""
pass
def matrix_product(self,matrix1=None,matrix2=None):
"""Create matrix that is the product of two other matrices"""
pass
def mirror_plane(self,plane1=None,plane2=None,plane3=None):
"""Mirror image about one or more coordinate planes"""
pass
def mirror_line(self,line=None):
"""Mirror about a line"""
pass
############################################################################
## Rates + Modes
def feedrate(self, f):
"""Set the feedrate"""
pass
def feedrate_hv(self, fh, fv):
"""Set the horizontal and vertical feedrates"""
pass
def spindle(self, s, clockwise=True):
"""Set the spindle speed"""
pass
def coolant(self, mode=0):
"""Set the coolant mode"""
pass
def gearrange(self, gear=0):
"""Set the gear range"""
pass
############################################################################
## Moves
def rapid(self, x=None, y=None, z=None):
"""Rapid move"""
pass
def feed(self, x=None, y=None, z=None):
"""Feed move"""
pass
def arc_cw(self, x=None, y=None, z=None, i=None, j=None, k=None, r=None):
"""Clockwise arc move"""
pass
def arc_ccw(self, x=None, y=None, z=None, i=None, j=None, k=None, r=None):
"""Counterclockwise arc move"""
pass
def dwell(self, t):
"""Dwell"""
pass
def rapid_home(self, x=None, y=None, z=None):
"""Rapid relative to home position"""
pass
def rapid_unhome(self):
"""Return from rapid home"""
pass
def set_machine_coordinates(self):
"""Set machine coordinates"""
pass
############################################################################
## Cutter radius compensation
def use_CRC(self):
"""CRC"""
return False
############################################################################
## Cycles
def pattern(self):
"""Simple pattern eg. circle, rect"""
pass
def pocket(self):
"""Pocket routine"""
pass
def profile(self):
"""Profile routine"""
pass
def drill(self, x=None, y=None, dwell=None, depthparams = None, retract_mode=None, spindle_mode=None, internal_coolant_on=None, rapid_to_clearance=None):
"""Drilling routines"""
pass
# original prototype was:
# def tap(self, x=None, y=None, z=None, zretract=None, depth=None, standoff=None, dwell_bottom=None, pitch=None, stoppos=None, spin_in=None, spin_out=None):
#
# current call is like so:
# tap(x=10, y=10, z=0, tap_mode=0, depth=12.7, standoff=6.35, direction=0, pitch=1.25)
# just add tap_mode & direction parameters
def tap(self, x=None, y=None, z=None, zretract=None, depth=None, standoff=None, dwell_bottom=None, pitch=None, stoppos=None, spin_in=None, spin_out=None, tap_mode=None, direction=None):
"""Tapping routines"""
pass
def bore(self, x=None, y=None, z=None, zretract=None, depth=None, standoff=None, dwell_bottom=None, feed_in=None, feed_out=None, stoppos=None, shift_back=None, shift_right=None, backbore=False, stop=False):
"""Boring routines"""
pass
def end_canned_cycle(self):
pass
############################################################################
## Misc
def comment(self, text):
"""Insert a comment"""
pass
def insert(self, text):
"""APT style INSERT statement"""
pass
def block_delete(self, on=False):
"""block to ignore if block delete switch is on"""
pass
def variable(self, id):
"""Insert a variable"""
pass
def variable_set(self, id, value):
"""Set a variable"""
pass
def probe_linear_centre_outside(self, x1=None, y1=None, depth=None, x2=None, y2=None ):
pass
def probe_single_point(self, point_along_edge_x=None, point_along_edge_y=None, depth=None, retracted_point_x=None, retracted_point_y=None, destination_point_x=None, destination_point_y=None, intersection_variable_x=None, intersection_variable_y=None, probe_offset_x_component=None, probe_offset_y_component=None ):
pass
def probe_downward_point(self, x=None, y=None, depth=None, intersection_variable_z=None):
pass
def report_probe_results(self, x1=None, y1=None, z1=None, x2=None, y2=None, z2=None, x3=None, y3=None, z3=None, x4=None, y4=None, z4=None, x5=None, y5=None, z5=None, x6=None, y6=None, z6=None, xml_file_name=None ):
pass
def open_log_file(self, xml_file_name=None ):
pass
def log_coordinate(self, x=None, y=None, z=None):
pass
def log_message(self, message=None):
pass
def close_log_file(self):
pass
def rapid_to_midpoint(self, x1=None, y1=None, z1=None, x2=None, y2=None, z2=None):
pass
def rapid_to_intersection(self, x1, y1, x2, y2, x3, y3, x4, y4, intersection_x, intersection_y, ua_numerator, ua_denominator, ua, ub_numerator, ub):
pass
def rapid_to_rotated_coordinate(self, x1, y1, x2, y2, ref_x, ref_y, x_current, y_current, x_final, y_final):
pass
def set_path_control_mode(self, mode, motion_blending_tolerance, naive_cam_tolerance ):
pass
################################################################################
creator = Creator()
############################################################################
## Internals
def write(s):
creator.write(s)
def output(filename):
creator.file_open(filename)
def retrieve_gcode():
return creator.retrieve_gcode()
############################################################################
## Programs
def program_begin(id, name=''):
creator.program_begin(id, name)
def add_stock(type_name, params):
creator.add_stock(type_name, params)
def program_stop(optional=False):
creator.program_stop(optional)
def program_end():
creator.program_end()
def flush_nc():
creator.flush_nc()
############################################################################
## Subprograms
def sub_begin(id, name=''):
creator.sub_begin(id, name)
def sub_call(id):
creator.sub_call(id)
def sub_end():
creator.sub_end()
############################################################################
## Settings
def imperial():
creator.imperial()
def metric():
creator.metric()
def absolute():
creator.absolute()
def incremental():
creator.incremental()
def polar(on=True):
creator.polar(on)
def set_plane(plane):
creator.set_plane(plane)
def set_temporary_origin(x=None, y=None, z=None, a=None, b=None, c=None):
creator.set_temporary_origin(x,y,z,a,b,c)
def remove_temporary_origin():
creator.remove_temporary_origin()
############################################################################
## Tools
def tool_change(id):
creator.tool_change(id)
def tool_defn(id, name='', params=None):
creator.tool_defn(id, name, params)
def offset_radius(id, radius=None):
creator.offset_radius(id, radius)
def offset_length(id, length=None):
creator.offset_length(id, length)
def current_tool(self):
return creator.current_tool()
############################################################################
## Datums
def datum_shift(x=None, y=None, z=None, a=None, b=None, c=None):
creator.datum_shift(x, y, z, a, b, c)
def datum_set(x=None, y=None, z=None, a=None, b=None, c=None):
creator.datum_set(x, y, z, a, b, c)
def workplane(id):
creator.workplane(id)
def clearanceplane(z=None):
creator.clearanceplane(z)
############################################################################
## APT360 like Transformation Definitions
## These definitions were created while looking at Irvin Kraal's book on APT
## - Numerical Control Progamming in APT - page 211
def matrix(a1=None,b1=None,c1=None,a2=None,b2=None,c2=None,a3=None,b3=None,c3=None):
creator.matrix(a1,b1,c1,a2,b2,c2,a3,b3,c3)
def translate(x=None,y=None,z=None):
creator.translate(x,y,z)
def rotate(xyrot=None,yzrot=None,zxrot=None,angle=None):
creator.rotate(xyrot,yzrot,zxrot,angle)
def scale(k=None):
creator.scale(k)
def matrix_product(matrix1=None,matrix2=None):
creator.matrix_product(matrix1,matrix2)
def mirror_plane(plane1=None,plane2=None,plane3=None):
creator.mirror_plane(plane1,plane2,plane3)
def mirror_line(line=None):
creator.mirror_line(line)
############################################################################
## Rates + Modes
def feedrate(f):
creator.feedrate(f)
def feedrate_hv(fh, fv):
creator.feedrate_hv(fh, fv)
def spindle(s, clockwise=True):
creator.spindle(s, clockwise)
def coolant(mode=0):
creator.coolant(mode)
def gearrange(gear=0):
creator.gearrange(gear)
############################################################################
## Moves
def rapid(x=None, y=None, z=None):
creator.rapid(x, y, z)
def feed(x=None, y=None, z=None):
creator.feed(x, y, z)
def arc_cw(x=None, y=None, z=None, i=None, j=None, k=None, r=None):
creator.arc_cw(x, y, z, i, j, k, r)
def arc_ccw(x=None, y=None, z=None, i=None, j=None, k=None, r=None):
creator.arc_ccw(x, y, z, i, j, k, r)
def dwell(t):
creator.dwell(t)
def rapid_home(x=None, y=None, z=None):
creator.rapid_home(x, y, z)
def rapid_unhome():
creator.rapid_unhome()
def set_machine_coordinates():
creator.set_machine_coordinates()
############################################################################
## Cutter radius compensation
def use_CRC():
return creator.use_CRC()
def CRC_nominal_path():
return creator.CRC_nominal_path()
def start_CRC(left = True, radius = 0.0):
creator.start_CRC(left, radius)
def end_CRC():
creator.end_CRC()
############################################################################
## Cycles
def pattern():
creator.pattern()
def pocket():
creator.pocket()
def profile():
creator.profile()
def drill(x=None, y=None, dwell=None, depthparams = None, retract_mode=None, spindle_mode=None, internal_coolant_on=None, rapid_to_clearance=None):
creator.drill(x, y, dwell, depthparams, retract_mode, spindle_mode, internal_coolant_on, rapid_to_clearance)
def tap(x=None, y=None, z=None, zretract=None, depth=None, standoff=None, dwell_bottom=None, pitch=None, stoppos=None, spin_in=None, spin_out=None, tap_mode=None, direction=None):
creator.tap(x, y, z, zretract, depth, standoff, dwell_bottom, pitch, stoppos, spin_in, spin_out, tap_mode, direction)
def bore(x=None, y=None, z=None, zretract=None, depth=None, standoff=None, dwell_bottom=None, feed_in=None, feed_out=None, stoppos=None, shift_back=None, shift_right=None, backbore=False, stop=False):
creator.bore(x, y, z, zretract, depth, standoff, dwell_Bottom, feed_in, feed_out, stoppos, shift_back, shift_right, backbore, stop)
def end_canned_cycle():
creator.end_canned_cycle()
def peck(count, first, last=None, step=0.0):
pecks = []
peck = first
if (last == None) : last = first
for i in range(0,count):
pecks.append(peck)
if (peck - step > last) : peck -= step
return pecks
############################################################################
## Misc
def comment(text):
creator.comment(text)
def insert(text):
creator.insert(text)
def block_delete(on=False):
creator.block_delete(on)
def variable(id):
creator.variable(id)
def variable_set(id, value):
creator.variable_set(id, value)
def probe_single_point(point_along_edge_x=None, point_along_edge_y=None, depth=None, retracted_point_x=None, retracted_point_y=None, destination_point_x=None, destination_point_y=None, intersection_variable_x=None, intersection_variable_y=None, probe_offset_x_component=None, probe_offset_y_component=None ):
creator.probe_single_point(point_along_edge_x, point_along_edge_y, depth, retracted_point_x, retracted_point_y, destination_point_x, destination_point_y, intersection_variable_x, intersection_variable_y, probe_offset_x_component, probe_offset_y_component )
def probe_downward_point(x=None, y=None, depth=None, intersection_variable_z=None):
creator.probe_downward_point(x, y, depth, intersection_variable_z)
def report_probe_results(x1=None, y1=None, z1=None, x2=None, y2=None, z2=None, x3=None, y3=None, z3=None, x4=None, y4=None, z4=None, x5=None, y5=None, z5=None, x6=None, y6=None, z6=None, xml_file_name=None ):
creator.report_probe_results(x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4, x5, y5, z5, x6, y6, z6, xml_file_name)
def open_log_file(xml_file_name=None ):
creator.open_log_file(xml_file_name)
def log_coordinate(x=None, y=None, z=None):
creator.log_coordinate(x, y, z)
def log_message(message=None):
creator.log_message(message)
def close_log_file():
creator.close_log_file()
def rapid_to_midpoint(x1=None, y1=None, z1=None, x2=None, y2=None, z2=None):
creator.rapid_to_midpoint(x1, y1, z1, x2, y2, z2)
def rapid_to_intersection(x1, y1, x2, y2, x3, y3, x4, y4, intersection_x, intersection_y, ua_numerator, ua_denominator, ua, ub_numerator, ub):
creator.rapid_to_intersection(x1, y1, x2, y2, x3, y3, x4, y4, intersection_x, intersection_y, ua_numerator, ua_denominator, ua, ub_numerator, ub)
def rapid_to_rotated_coordinate(x1, y1, x2, y2, ref_x, ref_y, x_current, y_current, x_final, y_final):
creator.rapid_to_rotated_coordinate(x1, y1, x2, y2, ref_x, ref_y, x_current, y_current, x_final, y_final)
def set_path_control_mode(mode, motion_blending_tolerance, naive_cam_tolerance ):
creator.set_path_control_mode(mode, motion_blending_tolerance, naive_cam_tolerance )

View File

@@ -0,0 +1,171 @@
################################################################################
# nc_read.py
#
# Base class for NC code parsing
################################################################################
import area
import math
count = 0
class Program: # stores start and end lines of programs and subroutines
def __init__(self):
self.start_line = None
self.end_line = None
class Parser:
def __init__(self, writer):
self.writer = writer
self.currentx = None
self.currenty = None
self.currentz = None
self.absolute_flag = True
self.drillz = None
self.need_m6_for_t_change = True
def __del__(self):
self.file_in.close()
############################################################################
## Internals
def readline(self):
self.line = self.file_in.readline().rstrip()
if (len(self.line)) : return True
else : return False
def set_current_pos(self, x, y, z):
if (x != None) :
if self.absolute_flag or self.currentx == None: self.currentx = x
else: self.currentx = self.currentx + x
if (y != None) :
if self.absolute_flag or self.currenty == None: self.currenty = y
else: self.currenty = self.currenty + y
if (z != None) :
if self.absolute_flag or self.currentz == None: self.currentz = z
else: self.currentz = self.currentz + z
def incremental(self):
self.absolute_flag = False
def absolute(self):
self.absolute_flag = True
def Parse(self, name):
self.file_in = open(name, 'r')
self.path_col = None
self.f = None
self.arc = 0
self.q = None
self.r = None
self.drilling = None
self.drilling_uses_clearance = False
self.drilling_clearance_height = None
while (self.readline()):
self.a = None
self.b = None
self.c = None
self.h = None
self.i = None
self.j = None
self.k = None
self.p = None
self.s = None
self.x = None
self.y = None
self.z = None
self.t = None
self.m6 = False
self.writer.begin_ncblock()
self.move = False
self.height_offset = False
self.drill = False
self.drill_off = False
self.no_move = False
words = self.pattern_main.findall(self.line)
for word in words:
self.col = None
self.cdata = False
self.ParseWord(word)
self.writer.add_text(word, self.col, self.cdata)
if self.t != None:
if (self.m6 == True) or (self.need_m6_for_t_change == False):
self.writer.tool_change( self.t )
if self.height_offset and (self.z != None):
self.drilling_clearance_height = self.z
if self.drill:
self.drilling = True
if self.drill_off:
self.drilling = False
if self.drilling:
rapid_z = self.r
if self.drilling_uses_clearance and (self.drilling_clearance_height != None):
rapid_z = self.drilling_clearance_height
if self.z != None: self.drillz = self.z
self.writer.rapid(self.x, self.y, rapid_z)
self.writer.feed(self.x, self.y, self.drillz)
self.writer.feed(self.x, self.y, rapid_z)
else:
if (self.move and not self.no_move):
if (self.arc==0):
if self.path_col == "feed":
self.writer.feed(self.x, self.y, self.z)
else:
self.writer.rapid(self.x, self.y, self.z, self.a, self.b, self.c)
else:
i = self.i
j = self.j
k = self.k
if self.arc_centre_absolute == True:
pass
else:
if (self.arc_centre_positive == True) and (self.oldx != None) and (self.oldy != None):
x = self.oldx
if self.x != None: x = self.x
if (self.x > self.oldx) != (self.arc > 0):
j = -j
y = self.oldy
if self.y != None: y = self.y
if (self.y > self.oldy) != (self.arc < 0):
i = -i
#fix centre point
r = math.sqrt(i*i + j*j)
p0 = area.Point(self.oldx, self.oldy)
p1 = area.Point(x, y)
v = p1 - p0
l = v.length()
h = l/2
d = math.sqrt(r*r - h*h)
n = area.Point(-v.y, v.x)
n.normalize()
if self.arc == -1: d = -d
c = p0 + (v * 0.5) + (n * d)
i = c.x
j = c.y
else:
i = i + self.oldx
j = j + self.oldy
if self.arc == -1:
self.writer.arc_cw(self.x, self.y, self.z, i, j, k)
else:
self.writer.arc_ccw(self.x, self.y, self.z, i, j, k)
if self.x != None: self.oldx = self.x
if self.y != None: self.oldy = self.y
if self.z != None: self.oldz = self.z
self.writer.end_ncblock()

View File

@@ -0,0 +1,151 @@
################################################################################
# nc_read.py
#
# Base class for NC code parsing
#
# Hirutso Enni, 2009-01-13
################################################################################
class Parser:
def __init__(self):
self.currentx = 0.0
self.currenty = 0.0
self.currentz = 0.0
self.absolute_flag = True
############################################################################
## Internals
def files_open(self, name, oname=None):
if (oname == None ):
oname = (name+'.nc.xml')
self.file_in = open(name, 'r')
self.file_out = open(oname, 'w')
self.file_out.write('<?xml version="1.0" ?>\n')
self.file_out.write('<nccode>\n')
def files_close(self):
self.file_out.write('</nccode>\n')
self.file_in.close()
self.file_out.close()
def readline(self):
self.line = self.file_in.readline().rstrip()
if (len(self.line)) : return True
else : return False
def write(self, s):
self.file_out.write(s)
############################################################################
## Xml
def begin_ncblock(self):
self.file_out.write('\t<ncblock>\n')
def end_ncblock(self):
self.file_out.write('\t</ncblock>\n')
def add_text(self, s, col=None, cdata=False):
s.replace('&', '&amp;')
s.replace('"', '&quot;')
s.replace('<', '&lt;')
s.replace('>', '&gt;')
if (cdata) : (cd1, cd2) = ('<![CDATA[', ']]>')
else : (cd1, cd2) = ('', '')
if (col != None) : self.file_out.write('\t\t<text col="'+col+'">'+cd1+s+cd2+'</text>\n')
else : self.file_out.write('\t\t<text>'+cd1+s+cd2+'</text>\n')
def set_mode(self, units=None):
self.file_out.write('\t\t<mode')
if (units != None) : self.file_out.write(' units="'+str(units)+'"')
self.file_out.write(' />\n')
def set_tool(self, number=None):
self.file_out.write('\t\t<tool')
if (number != None) :
self.file_out.write(' number="'+str(number)+'"')
self.file_out.write(' />\n')
def begin_path(self, col=None):
if (col != None) : self.file_out.write('\t\t<path col="'+col+'">\n')
else : self.file_out.write('\t\t<path>\n')
def end_path(self):
self.file_out.write('\t\t</path>\n')
def add_line(self, x=None, y=None, z=None, a=None, b=None, c=None):
if (x == None and y == None and z == None and a == None and b == None and c == None) : return
self.file_out.write('\t\t\t<line')
if (x != None) :
if self.absolute_flag: self.currentx = x
else: self.currentx = self.currentx + x
self.file_out.write(' y="%.6f"' % (self.currentx/2))
if (y != None) :
if self.absolute_flag: self.currenty = y
else: self.currenty = self.currenty + y
#self.file_out.write(' y="%.6f"' % self.currenty)
if (z != None) :
if self.absolute_flag: self.currentz = z
else: self.currentz = self.currentz + z
self.file_out.write(' x="%.6f"' % self.currentz)
if (a != None) : self.file_out.write(' a="%.6f"' % a)
if (b != None) : self.file_out.write(' b="%.6f"' % b)
if (c != None) : self.file_out.write(' c="%.6f"' % c)
self.file_out.write(' />\n')
def add_lathe_increment_line(self, u=None, w=None):
# needed for representing U and W moves in lathe code- these are non modal incremental moves
# U == X and W == Z
if (u == None and w == None ) : return
self.file_out.write('\t\t\t<line')
if (u != None) :
self.currentx = self.currentx + u
self.file_out.write(' y="%.6f"' % (self.currentx/2))
if (w != None) :
self.currentz = self.currentz + w
self.file_out.write(' x="%.6f"' % self.currentz)
self.file_out.write(' />\n')
def add_arc(self, x=None, y=None, z=None, i=None, j=None, k=None, r=None, d=None):
if (x == None and y == None and z == None and i == None and j == None and k == None and r == None and d == None) : return
self.file_out.write('\t\t\t<arc')
if (x != None) :
if self.absolute_flag: self.currentx = x
else: self.currentx = self.currentx + x
self.file_out.write(' y="%.6f"' % (self.currentx/2))
if (y != None) :
if self.absolute_flag: self.currenty = y
else: self.currenty = self.currenty + y
#self.file_out.write(' y="%.6f"' % self.currenty)
if (z != None) :
if self.absolute_flag: self.currentz = z
else: self.currentz = self.currentz + z
self.file_out.write(' x="%.6f"' % self.currentz)
#if (j != None) : self.file_out.write(' i="%.6f"' % j)
#if (i != None) : self.file_out.write(' j="%.6f"' % i)
#if (k != None) : self.file_out.write(' k="%.6f"' % k)
if (k != None) : self.file_out.write(' i="%.6f"' % k)
if (i != None) : self.file_out.write(' j="%.6f"' % i)
if (j != None) : self.file_out.write(' k="%.6f"' % j)
if (r != None) : self.file_out.write(' r="%.6f"' % r)
if (d != None) : self.file_out.write(' d="%i"' % d)
self.file_out.write(' />\n')
def incremental(self):
self.absolute_flag = False
def absolute(self):
self.absolute_flag = True

View File

@@ -0,0 +1,63 @@
import nc_read as nc
import sys
import math
# a base class for hpgl parsers, and maybe others
class NumReader(nc.Parser):
def __init__(self, writer):
nc.Parser.__init__(self, writer)
def get_number(self):
number = ''
# skip spaces and commas at start of number
while(self.line_index < self.line_length):
c = self.line[self.line_index]
if c == ' ' or c == ',':
self.parse_word += c
else:
break
self.line_index = self.line_index + 1
while(self.line_index < self.line_length):
c = self.line[self.line_index]
if c == '.' or c == '0' or c == '1' or c == '2' or c == '3' or c == '4' or c == '5' or c == '6' or c == '7' or c == '8' or c == '9' or c == '-':
number += c
else:
break
self.parse_word += c
self.line_index = self.line_index + 1
return number
def add_word(self, color):
self.writer.add_text(self.parse_word, color, None)
self.parse_word = ""
def Parse(self, name):
self.file_in = open(name, 'r')
while self.readline():
self.writer.begin_ncblock()
self.parse_word = ""
self.line_index = 0
self.line_length = len(self.line)
while self.line_index < self.line_length:
c = self.line[self.line_index]
self.parse_word += c
self.ParseFromFirstLetter(c)
self.line_index = self.line_index + 1
self.writer.add_text(self.parse_word, None, None)
self.writer.end_ncblock()
self.file_in.close()

View File

@@ -0,0 +1,53 @@
################################################################################
# printbot3d.py
#
# Dan Heeks 18th October 2010
import nc
import iso_modal
import math
################################################################################
class CreatorPrintbot(iso_modal.CreatorIsoModal):
def __init__(self):
iso_modal.CreatorIsoModal.__init__(self)
def tool_defn(self, id, name='', params=None):
pass
def write_blocknum(self):
pass
def set_plane(self, plane):
pass
def workplane(self, id):
pass
# Extruder Control
def extruder_on(self):
self.write('M101\n')
def extruder_off(self):
self.write('M103\n')
def set_extruder_flowrate(self, flowrate):
# re-use the spindle speed function
self.spindle(flowrate, True)
def extruder_temp(self, temp):
self.write((maker.codes.EXTRUDER_TEMP(temp)) + ('\n'))
# General
def rapid(x=None, y=None, z=None, a=None, b=None, c=None):
# do a G1 even for rapid moves
iso_modal.CreatorIsoModal.feed(self, x, y, z)
def feed(self, x=None, y=None, z=None, a = None, b = None, c = None):
iso_modal.CreatorIsoModal.feed(self, x, y, z)
################################################################################
nc.creator = CreatorPrintbot()

View File

@@ -0,0 +1,17 @@
import iso_read as iso
import sys
# based on the iso reader
class Parser(iso.Parser):
def __init__(self, writer):
iso.Parser.__init__(self, writer)
def ParseWord(self, word):
iso.Parser.ParseWord(self, word)
if (word == 'M103'):
self.path_col = "rapid"
self.col = "rapid"
elif (word == 'M101'):
self.path_col = "feed"
self.col = "feed"

View File

@@ -0,0 +1,300 @@
import nc
units = 1.0
class Redirector(nc.Creator):
def __init__(self, original):
nc.Creator.__init__(self)
self.original = original
self.x = None
self.y = None
self.z = None
if original.x != None: self.x = original.x * units
if original.y != None: self.y = original.y * units
if original.z != None: self.z = original.z * units
self.imperial = False
def cut_path(self):
pass
############################################################################
## Programs
def write(self, s):
self.original.write(s)
def output_fixture(self):
self.original.output_fixture()
def increment_fixture(self):
self.original.increment_fixture()
def get_fixture(self):
return self.original.get_fixture()
def set_fixture(self, fixture):
self.original.set_fixture(fixture)
def program_begin(self, id, name=''):
self.cut_path()
self.original.program_begin(id, name)
def program_stop(self, optional=False):
self.cut_path()
self.original.program_stop(optional)
def program_end(self):
self.cut_path()
self.original.program_end()
def flush_nc(self):
self.cut_path()
self.original.flush_nc()
############################################################################
## Subprograms
def sub_begin(self, id, name=None):
self.cut_path()
self.original.sub_begin(id, name)
def sub_call(self, id):
self.cut_path()
self.original.sub_call(id)
def sub_end(self):
self.cut_path()
self.original.sub_end()
def disable_output(self):
self.original.disable_output()
def enable_output(self):
self.original.enable_output()
############################################################################
## Settings
def imperial(self):
self.cut_path()
self.imperial = True
self.original.imperial()
def metric(self):
self.cut_path()
self.original.metric()
def absolute(self):
self.cut_path()
self.original.absolute()
def incremental(self):
self.cut_path()
self.original.incremental()
def polar(self, on=True):
self.cut_path()
self.original.polar(on)
def set_plane(self, plane):
self.cut_path()
self.original.set_plane(plane)
def set_temporary_origin(self, x=None, y=None, z=None, a=None, b=None, c=None):
self.cut_path()
self.original.set_temporary_origin(x,y,z,a,b,c)
def remove_temporary_origin(self):
self.cut_path()
self.original.remove_temporary_origin()
############################################################################
## Tools
def tool_change(self, id):
self.cut_path()
self.original.tool_change(id)
def tool_defn(self, id, name='', params=None):
self.cut_path()
self.original.tool_defn(id, name, params)
def offset_radius(self, id, radius=None):
self.cut_path()
self.original.offset_radius(id, radius)
def offset_length(self, id, length=None):
self.cut_path()
self.original.offset_length(id, length)
############################################################################
## Datums
def datum_shift(self, x=None, y=None, z=None, a=None, b=None, c=None):
self.cut_path()
self.original.datum_shift(x, y, z, a, b, c)
def datum_set(self, x=None, y=None, z=None, a=None, b=None, c=None):
self.cut_path()
self.original.datum_set(x, y, z, a, b, c)
def workplane(self, id):
self.cut_path()
self.original.workplane(id)
############################################################################
## Rates + Modes
def feedrate(self, f):
self.cut_path()
self.original.feedrate(f)
def feedrate_hv(self, fh, fv):
self.cut_path()
self.original.feedrate_hv(fh, fv)
def spindle(self, s, clockwise=True):
self.cut_path()
self.original.spindle(s, clockwise)
def coolant(self, mode=0):
self.cut_path()
self.original.coolant(mode)
def gearrange(self, gear=0):
self.cut_path()
self.original.gearrange(gear)
############################################################################
## Moves
def rapid(self, x=None, y=None, z=None, a=None, b=None, c=None):
self.cut_path()
self.original.rapid(x, y, z, a, b, c)
if x != None: self.x = x * units
if y != None: self.y = y * units
if z != None: self.z = z * units
def cut_path(self):
pass
def z2(self, z):
return z
def feed(self, x=None, y=None, z=None, a = None, b = None, c = None):
px = self.x
py = self.y
pz = self.z
if x != None: self.x = x * units
if y != None: self.y = y * units
if z != None: self.z = z * units
if self.x == None or self.y == None or self.z == None:
self.cut_path()
self.original.feed(x, y, z)
return
if px == self.x and py == self.y:
# z move only
self.cut_path()
self.original.feed(self.x/units, self.y/units, self.z2(self.z)/units)
return
def arc(self, x=None, y=None, z=None, i=None, j=None, k=None, r=None, ccw = True):
if self.x == None or self.y == None or self.z == None:
raise "first attached move can't be an arc"
px = self.x
py = self.y
pz = self.z
if x != None: self.x = x * units
if y != None: self.y = y * units
if z != None: self.z = z * units
def arc_cw(self, x=None, y=None, z=None, i=None, j=None, k=None, r=None):
self.arc(x, y, z, i, j, k, r, False)
def arc_ccw(self, x=None, y=None, z=None, i=None, j=None, k=None, r=None):
self.arc(x, y, z, i, j, k, r, True)
def dwell(self, t):
self.cut_path()
self.original.dwell(t)
def rapid_home(self, x=None, y=None, z=None, a=None, b=None, c=None):
self.cut_path()
self.original.rapid_home(x, y, z, a, b, c)
def rapid_unhome(self):
self.cut_path()
self.original.rapid_unhome()
############################################################################
## Cutter radius compensation
def use_CRC(self):
return self.original.use_CRC()
def start_CRC(self, left = True, radius = 0.0):
self.cut_path()
self.original.start_CRC(left, radius)
def end_CRC(self):
self.cut_path()
self.original.end_CRC()
############################################################################
## Cycles
def pattern(self):
self.cut_path()
self.original.pattern()
def pattern_uses_subroutine(self):
return self.original.pattern_uses_subroutine()
def pocket(self):
self.cut_path()
self.original.pocket()
def profile(self):
self.cut_path()
self.original.profile()
def circular_pocket(self, x=None, y=None, ToolDiameter=None, HoleDiameter=None, ClearanceHeight=None, StartHeight=None, MaterialTop=None, FeedRate=None, SpindleRPM=None, HoleDepth=None, DepthOfCut=None, StepOver=None ):
self.cut_path()
self.circular_pocket(x, y, ToolDiameter, HoleDiameter, ClearanceHeight, StartHeight, MaterialTop, FeedRate, SpindleRPM, HoleDepth, DepthOfCut, StepOver)
def drill(self, x=None, y=None, dwell=None, depthparams = None, retract_mode=None, spindle_mode=None, internal_coolant_on=None, rapid_to_clearance=None):
self.cut_path()
self.original.drill(x, y, dwell, depthparams, spindle_mode, internal_coolant_on, rapid_to_clearance)
# argument list adapted for compatibility with Tapping module
# wild guess - I'm unsure about the purpose of this file and wether this works -haberlerm
def tap(self, x=None, y=None, z=None, zretract=None, depth=None, standoff=None, dwell_bottom=None, pitch=None, stoppos=None, spin_in=None, spin_out=None, tap_mode=None, direction=None):
self.cut_path()
self.original.tap( x, y, self.z2(z), self.z2(zretract), depth, standoff, dwell_bottom, pitch, stoppos, spin_in, spin_out, tap_mode, direction)
def bore(self, x=None, y=None, z=None, zretract=None, depth=None, standoff=None, dwell_bottom=None, feed_in=None, feed_out=None, stoppos=None, shift_back=None, shift_right=None, backbore=False, stop=False):
self.cut_path()
self.original.bore(x, y, self.z2(z), self.z2(zretract), depth, standoff, dwell_Bottom, feed_in, feed_out, stoppos, shift_back, shift_right, backbore, stop)
def end_canned_cycle(self):
self.original.end_canned_cycle()
############################################################################
## Misc
def comment(self, text):
self.cut_path()
self.original.comment(text)
def variable(self, id):
self.cut_path()
self.original.variable(id)
def variable_set(self, id, value):
self.cut_path()
self.original.variable_set(id, value)
def set_ocl_cutter(self, cutter):
self.original.set_ocl_cutter(cutter)

View File

@@ -0,0 +1,553 @@
# -*- coding: utf-8 -*-
################################################################################
# iso.py
#
# Simple ISO NC code creator
#
# Hirutso Enni, 2009-01-13
import nc
import math
import circular_pocket as circular
################################################################################
class Creator(nc.Creator):
def __init__(self):
nc.Creator.__init__(self)
self.a = 0
self.b = 0
self.c = 0
self.f = ''
self.fh = None
self.fv = None
self.fhv = False
self.g = ''
self.i = 0
self.j = 0
self.k = 0
self.m = []
self.n = 10
self.r = 0
self.s = ''
self.t = None
self.x = 0
self.y = 0
self.z = 500
self.x1=0
self.x2=0
self.y1=0
self.y2=0
self.SPACE=' '
self.fmt = self.FORMAT_MM()
pass
############################################################################
## Internals
def FORMAT_IN(self): return('%.5f')
def FORMAT_MM(self): return('%.3f')
def COMMENT(self,comment): return( ('(%s)' % comment ) )
def write_feedrate(self):
#self.write(self.f)
self.f = ''
def write_preps(self):
#self.write(self.g)
self.g = ''
def write_misc(self):
#if (len(self.m)) : self.write(self.m.pop())
pass
def write_blocknum(self):
#self.write(iso.BLOCK % self.n)
#self.write(iso.SPACE)
#self.n += 10
pass
def write_spindle(self):
#self.write(self.s)
#self.s = ''
pass
############################################################################
## Programs
def program_begin(self, id, name=''):
#self.write((iso.PROGRAM % id) + iso.SPACE + (iso.COMMENT % name))
#self.write("// program v jazyku"+self.SPACE+"REZ\nMA 0.0000 , 0.0000\n")
self.write("// program v jazyku"+self.SPACE+"REZ\nGO_LEFT\nMA 0.0000 , 0.0000\n")
#self.write('\n')
def program_stop(self, optional=False):
#self.write_blocknum()
#if (optional) : self.write(iso.STOP_OPTIONAL + '\n')
#else : self.write(iso.STOP + '\n')
self.write("// stop programu v jazyku REZ\n")
def program_end(self):
#self.write_blocknum()
#self.write(iso.PROGRAM_END + '\n')
self.write('PL_OFF \n')
self.write('PARK \n')
self.write('FS \n')
self.write('MA 0.0000 , 0.0000\n')
self.write("// koniec programu v jazyku REZ\n")
#self.write(iso.PROGRAM_END + '\n')
def flush_nc(self):
#self.write_blocknum()
self.write_preps()
self.write_misc()
#self.write('\n')
############################################################################
## Subprograms
def sub_begin(self, id, name=''):
#self.write((iso.PROGRAM % id) + iso.SPACE + (iso.COMMENT % name))
#self.write('\n')
pass
def sub_call(self, id):
#self.write_blocknum()
#self.write((iso.SUBPROG_CALL % id) + '\n')
#self.write('\n')
pass
def sub_end(self):
#self.write_blocknum()
#self.write(iso.SUBPROG_END + '\n')
#self.write('\n')
pass
############################################################################
## Settings
def imperial(self):
#self.g += iso.IMPERIAL
#self.fmt = iso.FORMAT_IN
#self.write('\n')
pass
def metric(self):
#self.g += iso.METRIC
#self.fmt = iso.FORMAT_MM
#self.write('\n')
pass
def absolute(self):
#self.g += iso.ABSOLUTE
#self.write('\n')
pass
def incremental(self):
#self.g += iso.INCREMENTAL
#self.write('\n')
pass
def polar(self, on=True):
#if (on) : self.g += iso.POLAR_ON
#else : self.g += iso.POLAR_OFF
#self.write('\n')
pass
def set_plane(self, plane):
#if (plane == 0) : self.g += iso.PLANE_XY
#elif (plane == 1) : self.g += iso.PLANE_XZ
#elif (plane == 2) : self.g += iso.PLANE_YZ
#self.write('\n')
pass
############################################################################
## Tools
def tool_change(self, id):
#self.write_blocknum()
#self.write((iso.TOOL % id) + '\n')
#self.write('\n')
pass
def tool_defn(self, id, name='', params=None):
pass
def offset_radius(self, id, radius=None):
pass
def offset_length(self, id, length=None):
pass
############################################################################
## Datums
def datum_shift(self, x=None, y=None, z=None, a=None, b=None, c=None):
pass
def datum_set(self, x=None, y=None, z=None, a=None, b=None, c=None):
pass
# This is the coordinate system we're using. G54->G59, G59.1, G59.2, G59.3
# These are selected by values from 1 to 9 inclusive.
def workplane(self, id):
#if ((id >= 1) and (id <= 6)):
# self.g += iso.WORKPLANE % (id + iso.WORKPLANE_BASE)
#if ((id >= 7) and (id <= 9)):
# self.g += ((iso.WORKPLANE % (6 + iso.WORKPLANE_BASE)) + ('.%i' % (id - 6)))
pass
############################################################################
## Rates + Modes
def feedrate(self, f):
#self.f = iso.FEEDRATE + (self.fmt % f)
#self.fhv = False
pass
def feedrate_hv(self, fh, fv):
#self.fh = fh
#self.fv = fv
#self.fhv = True
pass
def calc_feedrate_hv(self, h, v):
#l = math.sqrt(h*h+v*v)
#if (h == 0) : self.f = iso.FEEDRATE + (self.fmt % self.fv)
#elif (v == 0) : self.f = iso.FEEDRATE + (self.fmt % self.fh)
#else:
# self.f = iso.FEEDRATE + (self.fmt % (self.fh * l * min([1/h, 1/v])))
pass
def spindle(self, s, clockwise):
#if s < 0: clockwise = not clockwise
#s = abs(s)
#self.s = iso.SPINDLE % s
#if clockwise:
# self.s = self.s + iso.SPINDLE_CW
#else:
# self.s = self.s + iso.SPINDLE_CCW
pass
def coolant(self, mode=0):
#if (mode <= 0) : self.m.append(iso.COOLANT_OFF)
#elif (mode == 1) : self.m.append(iso.COOLANT_MIST)
#elif (mode == 2) : self.m.append(iso.COOLANT_FLOOD)
pass
def gearrange(self, gear=0):
#if (gear <= 0) : self.m.append(iso.GEAR_OFF)
#elif (gear <= 4) : self.m.append(iso.GEAR % (gear + GEAR_BASE))
pass
############################################################################
## Moves
#def rapid(self, x=None, y=None, z=None, a=None, b=None, c=None):
def rapid(self, x=0.0000, y=0.0000, z=0.0000, a=0.0000, b=0.0000, c=0.0000,how=False):
#self.write_blocknum()
if (x == None):
if (y == None):
return
print 'rychlopsuv'
print x
print y
print z
print a
print b
print c
self.write('PL_OFF\n')
self.write('PARK\n')
self.write('FS\n')
self.write('MA ')
#self.write_preps()
#if (x != None):
# dx = x - self.x
# self.write(iso.X + (self.fmt % x))
# self.x = x
#if (y != None):
# dy = y - self.y
# self.write(iso.Y + (self.fmt % y))
# self.y = y
#if (z != None):
# dz = z - self.z
# self.write(iso.Z + (self.fmt % z))
# self.z = z
#if (a != None) : self.write(iso.A + (iso.FORMAT_ANG % a))
#if (b != None) : self.write(iso.B + (iso.FORMAT_ANG % b))
#if (c != None) : self.write(iso.C + (iso.FORMAT_ANG % c))
#self.write_spindle()
#self.write_misc()
self.write((' %.4f' %x))
#self.write(('%f' %x) )
self.write(' , ')
self.write((' %.4f' %y))
self.write('\n')
self.write('SS\n')
self.write('AD_W\n')
self.write('PL_ON')
self.write('\n')
self.x=x
self.y=y
def feed(self, x=0.0000, y=0.0000, z=0.0000,how=False):
if self.same_xyz(x, y, z):
return
if (x == None):
if (y == None):
return
print 'MA rez'
print x
print y
print z
#self.write_blocknum()
#self.write(iso.FEED)
#self.write_preps()
#dx = dy = dz = 0
#if (x != None):
# dx = x - self.x
# self.write(iso.X + (self.fmt % x))
# self.x = x
#if (y != None):
# dy = y - self.y
# self.write(iso.Y + (self.fmt % y))
# self.y = y
#if (z != None):
# dz = z - self.z
# self.write(iso.Z + (self.fmt % z))
# self.z = z
#if (self.fhv) : self.calc_feedrate_hv(math.sqrt(dx*dx+dy*dy), math.fabs(dz))
#self.write_feedrate()
#self.write_spindle()
#self.write_misc()
self.write('MA ')
self.write((' %.4f' %x))
#self.write(('%f' %x) )
self.write(' , ')
self.write((' %.4f' %y))
self.write('\n')
self.x=x
self.y=y
def same_xyz(self, x=None, y=None, z=None):
if (x != None):
if (self.fmt % x) != (self.fmt % self.x):
return False
if (y != None):
if (self.fmt % y) != (self.fmt % self.y):
return False
if (z != None):
if (self.fmt % z) != (self.fmt % self.z):
return False
return True
def arc(self, cw, x=0.0000, y=0.0000, z=0.0000, i=0.0000, j=0.0000, k=0.0000, r=0.0000):
if self.same_xyz(x, y, z): return
if (x == None):
if (y == None):
return
#self.write_blocknum()
print 'ARC rez'
print x
print y
print z
print i
print j
print k
print r
self.write('C ')
# if cw: self.write(iso.ARC_CW)
# else: self.write(iso.ARC_CCW)
# self.write_preps()
#if (x != None):
# self.write(iso.X + (self.fmt % x))
# self.x = x
#if (y != None):
# self.write(iso.Y + (self.fmt % y))
# self.y = y
#if (z != None):
# self.write(iso.Z + (self.fmt % z))
# self.z = z
#if (i != None) : self.write(iso.CENTRE_X + (self.fmt % i))
#if (j != None) : self.write(iso.CENTRE_Y + (self.fmt % j))
#if (k != None) : self.write(iso.CENTRE_Z + (self.fmt % k))
#if (r != None) : self.write(iso.RADIUS + (self.fmt % r))
# use horizontal feed rate
#if (self.fhv) : self.calc_feedrate_hv(1, 0)
#self.write_feedrate()
#self.write_spindle()
#self.write_misc()
self.write((' %.4f' %(self.x + i)))
#self.write(('%f' %x) )
self.write(' , ')
self.write((' %.4f' %(self.y + j)))
self.write(' , ')
angle=0.0000
self.x1=-i
self.y1=-j
self.x2=x-(self.x+i)
self.y2=y-(self.y+j)
dx=self.x1*self.x2
dy=self.y1*self.y2
ssucin=dx+dy
r=math.sqrt((i*i)+(j*j))
#dx=i*(x-(self.x + i))
#dy=j*(y-(self.y + j))
#ssucin=dx+dy
#r=math.sqrt((i*i)+(j*j))
ratio=ssucin/(r*r)
angle= math.acos(ratio) * 180 / math.pi
print 'angle'
print angle
# while(angle>=90.0001):
# if(cw): self.write((' -90.0000\n' ))
# else: self.write((' 90.0000\n'))
#self.write(('90.0000\n' ))
# self.write('C ')
# self.write((' %.4f' %( self.x + i) ))
# self.write(' , ')
# self.write((' %.4f' %( self.y + j)))
# self.write(' , ')
# angle-=90
if(cw): self.write((' %.4f' %(-angle)))
else: self.write((' %.4f' %(angle)))
#self.write((', %.4f' % ))
self.write('\n')
self.x=x
self.y=y
self.write('// stred')
self.write((' %f' %i))
self.write(' ')
self.write( (' %f' %j))
self.write('\n')
self.write('// koniec')
self.write((' %f' %self.x))
self.write(' ')
self.write( (' %f' %self.y))
self.write('\n')
def arc_cw(self, x=None, y=None, z=None, i=None, j=None, k=None, r=None):
self.arc(True, x, y, z, i, j, k, r)
def arc_ccw(self, x=None, y=None, z=None, i=None, j=None, k=None, r=None):
self.arc(False, x, y, z, i, j, k, r)
def dwell(self, t):
self.write_blocknum()
self.write_preps()
self.write(iso.DWELL + (iso.TIME % t))
self.write_misc()
self.write('\n')
def rapid_home(self, x=None, y=None, z=None, a=None, b=None, c=None):
pass
def rapid_unhome(self):
pass
############################################################################
## Cycles
def pattern(self):
pass
def pocket(self):
pass
def profile(self):
pass
def circular_pocket(self, x=None, y=None, ToolDiameter=None, HoleDiameter=None, ClearanceHeight=None, StartHeight=None, MaterialTop=None, FeedRate=None, SpindleRPM=None, HoleDepth=None, DepthOfCut=None, StepOver=None ):
self.write_preps()
circular.pocket.block_number = self.n
(self.g_code, self.n) = circular.pocket.GeneratePath( x,y, ToolDiameter, HoleDiameter, ClearanceHeight, StartHeight, MaterialTop, FeedRate, SpindleRPM, HoleDepth, DepthOfCut, StepOver )
self.write(self.g_code)
# The drill routine supports drilling (G81), drilling with dwell (G82) and peck drilling (G83).
# The x,y,z values are INITIAL locations (above the hole to be made. This is in contrast to
# the Z value used in the G8[1-3] cycles where the Z value is that of the BOTTOM of the hole.
# Instead, this routine combines the Z value and the depth value to determine the bottom of
# the hole.
#
# The standoff value is the distance up from the 'z' value (normally just above the surface) where the bit retracts
# to in order to clear the swarf. This combines with 'z' to form the 'R' value in the G8[1-3] cycles.
#
# The peck_depth value is the incremental depth (Q value) that tells the peck drilling
# cycle how deep to go on each peck until the full depth is achieved.
#
# NOTE: This routine forces the mode to absolute mode so that the values passed into
# the G8[1-3] cycles make sense. I don't know how to find the mode to revert it so I won't
# revert it. I must set the mode so that I can be sure the values I'm passing in make
# sense to the end-machine.
#
def drill(self, x=None, y=None, dwell=None, depthparams = None, retract_mode=None, spindle_mode=None, internal_coolant_on=None, rapid_to_clearance=None):
if (standoff == None):
# This is a bad thing. All the drilling cycles need a retraction (and starting) height.
return
if (z == None): return # We need a Z value as well. This input parameter represents the top of the hole
self.write_blocknum()
self.write_preps()
if (peck_depth != 0):
# We're pecking. Let's find a tree.
self.write(iso.PECK_DRILL + iso.SPACE + iso.PECK_DEPTH + (self.fmt % peck_depth ))
else:
# We're either just drilling or drilling with dwell.
if (dwell == 0):
# We're just drilling.
self.write(iso.DRILL + iso.SPACE)
else:
# We're drilling with dwell.
self.write(iso.DRILL_WITH_DWELL + (iso.FORMAT_DWELL % dwell) + iso.SPACE)
# Set the retraction point to the 'standoff' distance above the starting z height.
retract_height = z + standoff
#self.write(iso.RETRACT + (self.fmt % retract_height))
if (x != None):
dx = x - self.x
self.write(iso.X + (self.fmt % x) + iso.SPACE)
self.x = x
if (y != None):
dy = y - self.y
self.write(iso.Y + (self.fmt % y) + iso.SPACE)
self.y = y
dz = (z + standoff) - self.z
# In the end, we will be standoff distance above the z value passed in.
self.write(iso.Z + (self.fmt % (z - depth)) + iso.SPACE) # This is the 'z' value for the bottom of the hole.
self.z = (z + standoff) # We want to remember where z is at the end (at the top of the hole)
self.write(iso.RETRACT + (self.fmt % retract_height))
self.write_spindle()
self.write_misc()
self.write('\n')
# def tap(self, x=None, y=None, z=None, zretract=None, depth=None, standoff=None, dwell_bottom=None, pitch=None, stoppos=None, spin_in=None, spin_out=None):
# pass
# argument list adapted for compatibility with Tapping module
def tap(self, x=None, y=None, z=None, zretract=None, depth=None, standoff=None, dwell_bottom=None, pitch=None, stoppos=None, spin_in=None, spin_out=None, tap_mode=None, direction=None):
pass
def bore(self, x=None, y=None, z=None, zretract=None, depth=None, standoff=None, dwell_bottom=None, feed_in=None, feed_out=None, stoppos=None, shift_back=None, shift_right=None, backbore=False, stop=False):
pass
############################################################################
## Misc
def comment(self, text):
self.write('// ' + (self.COMMENT( text)) + '\n')
def variable(self, id):
return (iso.VARIABLE % id)
def variable_set(self, id, value):
self.write_blocknum()
self.write((iso.VARIABLE % id) + (iso.VARIABLE_SET % value) + '\n')
################################################################################
nc.creator = Creator()

View File

@@ -0,0 +1,291 @@
# -*- coding: utf-8 -*-
################################################################################
# iso_.py
#
import nc_read as nc
import re
import sys
import math
################################################################################
class Parser(nc.Parser):
def __init__(self, writer):
nc.Parser.__init__(self, writer)
#self.pattern_main = re.compile('(\s+|\w(?:[+])?\d*(?:\.\d*)?|\w\#\d+|\(.*?\)|\#\d+\=(?:[+])?\d*(?:\.\d*)?)')
#rada
self.pattern_main = re.compile(r'(\s+|,|-?\w\+?\d*(?:\.\d*)?|\w#\d+|\(.*?\)|#\d+=\+?\d*(?:\.\d*)?)')
#self.pattern_main = re.compile('\s+\w')
#self.pattern_main = re.compile('(\s+|\w(?:[+])?[+-\w]\d*(?:\.\d*)?|\w\#[+-\w]\d+|\(.*?\)|[\#[+-\w]\d+\=(?:[+])?[+-\w]\d*(?:\.\d*)?)')
#self.pattern_main = re.compile('\s\w[\S]\w,\w[+-\w]\d*\w,\w[+-\w]\d*\w,\w[+-\w]\d*')
#self.pattern_main = re.compile('(\s|\w(?:)?\d*(?:\.\d*)?|\w\#\d+|\(.*?\)|\#\d+\=(?:)?\d*(?:\.\d*)?)')
#self.pattern_main = re.compile(' ')
self.a = 0
self.b = 0
self.c = 0
self.f = 0
self.i = 0
self.j = 0
self.k = 0
self.p = 0
self.q = 0
self.r = 0
self.s = 0
self.x = 0
self.y = 0
self.z = 500
self.FS = 1
self.endx=0
self.endy=0
self.startx=0
self.starty=0
self.x1=0
self.y1=0
self.dy=0
self.dx=0
self.angle=0
self.SPACE = ' '
def add_text(self, s, col=None):
s.replace('&', '&amp;')
s.replace('"', '&quot;')
s.replace('<', '&lt;')
s.replace('>', '&gt;')
s+=self.SPACE+'\n'
if (col != None) : self.file_out.write('\t\t<text col="'+col+'">'+s+' </text>\n')
else : self.file_out.write('\t\t<text>'+s+' </text>\n')
#def add_text(self, s, col=None):
# if (col != None) : self.file_out.write('\t\t<text col="'+col+'">'+s+'</text>\n')
# else : self.file_out.write('\t\t<text>'+s+'</text>\n')
def Parse(self, name, oname=None):
self.files_open(name,oname)
while (self.readline()):
self.begin_ncblock()
move = False;
arc = 0;
path_col = None
col=None
if(self.line[0]=='C'): col = "axis"
if(self.line[0]=='M' and self.line[1]=='A'): col = "feed"
if (self.line[0] == "/" and self.line[1] == "/") : col = "comment"
if (self.FS==1 and not (self.line[0]=='S' and self.line[1]=='S') and col=="feed" ): col="rapid"
self.add_text(self.line, col)
#words = self.pattern_main.findall(self.line)
words=self.line.split()
#print self.line
#print ' AAAA '
words[0]=words[0]+self.SPACE
print words
for word in words:
col = None
#if (word[0] == 'A' or word[0] == 'a'):
# col = "axis"
# self.a = eval(word[1:])
# move = True
#elif (word[0] == 'B' or word[0] == 'b'):
# col = "axis"
# self.b = eval(word[1:])
# move = True
if (word == ('C'+self.SPACE)):
#print words
col = "axis"
self.startx=self.x
self.starty=self.y
words[0]=words[0]+self.SPACE
words[2]=self.SPACE+words[2]+self.SPACE
words[4]=self.SPACE+words[4]+self.SPACE
#print 'x,y'
#print self.x
#print self.y
#self.x1=self.x-eval(words[1])
self.x1=self.x-eval(words[1])
#j=self.y-eval(words[5])
#self.y1=self.y-eval(words[3])
self.y1=self.y-eval(words[3])
#self.c = eval(word[1:])
#print 'self x,y'
#print self.x1
#print self.y1
self.dx=(self.x1)*1
self.dy=(self.y1)*0
#print 'x1'
#print self.x1
#print 'y1'
#print self.y1
ssucin=self.dx+self.dy
r=math.sqrt(((self.x1)*(self.x1))+((self.y1)*(self.y1)))
#print 'skalarny sucin'
#print ssucin
#print 'r'
#print r
if (ssucin!=0):
ratio=ssucin/(r*1)
#print 'ratio'
#print ratio
angle= (math.acos(ratio) * 180 / math.pi)
if(self.y1<0):angle=360-angle
elif (self.y1>0): angle=+90
elif (self.y1<0): angle=-90
else: angle=0
#print words[8]
#print 'angles'
#print angle
#if (i<0 and j<0): angle=180+angle
#if (i<0 and j>0): angle=180-angle
#if (j>0): angle=-angle
#print ('reverzacia')
#angle= angle+ eval(words[8])
#print angle
self.angle=+ angle+ eval(words[5])
#print self.angle
#if(angle>180): angle=360-angle
angle=self.angle*math.pi/180
#print eval(words[8])
self.endx=eval(words[1])+(r*math.cos(angle))
#j=eval(words[5])+(r*math.sin(angle))
self.endy=eval(words[3])+(r*math.sin(angle))
self.x=self.endx
self.y=self.endy
path_col = "feed"
#arc=-eval(words[8])/math.fabs(eval(words[8]))
arc=eval(words[5])/math.fabs(eval(words[5]))
#if(arc==-1): arc=0
#arc=-1
#col = "feed"
move = True
elif (word == 'P' and words[1]=='L' and words[4]=='F'):
self.FS=1
elif (word == 'P' and words[1]=='L' and words[4]=='N'):
self.FS=0
elif (word == ('FS'+self.SPACE)):
self.FS=1
elif (word == ('SS'+self.SPACE)):
self.FS=0
elif (word == ('MA'+self.SPACE)):
words[2]=self.SPACE+words[2]+self.SPACE
if (self.FS==1):
path_col = "rapid"
col = "rapid"
else:
path_col = "feed"
col = "feed"
self.x=eval(words[1])
#self.y=eval(words[6])
self.y=eval(words[3])
move=True
#elif (word == 'G1' or word == 'G01' or word == 'g1' or word == 'g01'):
# path_col = "feed"
# col = "feed"
#elif (word == 'G2' or word == 'G02' or word == 'g2' or word == 'g02' or word == 'G12' or word == 'g12'):
# path_col = "feed"
# col = "feed"
# arc = -1
#elif (word == 'G3' or word == 'G03' or word == 'g3' or word == 'g03' or word == 'G13' or word == 'g13'):
# path_col = "feed"
# col = "feed"
# arc = +1
#elif (word == 'G10' or word == 'g10'):
# move = False
#elif (word == 'L1' or word == 'l1'):
# move = False
#elif (word == 'G20'):
# col = "prep"
# self.set_mode(units=25.4)
#elif (word == 'G21'):
# col = "prep"
# self.set_mode(units=1.0)
#elif (word == 'G81' or word == 'g81'):
# path_col = "feed"
# col = "feed"
#elif (word == 'G82' or word == 'g82'):
# path_col = "feed"
# col = "feed"
#elif (word == 'G83' or word == 'g83'):
# path_col = "feed"
# col = "feed"
#elif (word[0] == 'G') : col = "prep"
#elif (word[0] == 'I' or word[0] == 'i'):
# col = "axis"
# self.i = eval(word[1:])
# move = True
#elif (word[0] == 'J' or word[0] == 'j'):
# col = "axis"
# self.j = eval(word[1:])
# move = True
#elif (word[0] == 'K' or word[0] == 'k'):
# col = "axis"
# self.k = eval(word[1:])
# move = True
#elif (word[0] == 'M') : col = "misc"
#elif (word[0] == 'N') : col = "blocknum"
#elif (word[0] == 'O') : col = "program"
#elif (word[0] == 'P' or word[0] == 'p'):
# col = "axis"
# self.p = eval(word[1:])
# move = True
#elif (word[0] == 'Q' or word[0] == 'q'):
# col = "axis"
# self.q = eval(word[1:])
# move = True
#elif (word[0] == 'R' or word[0] == 'r'):
# col = "axis"
# self.r = eval(word[1:])
# move = True
#elif (word[0] == 'S' or word[0zypp] == 's'):
# col = "axis"
# self.s = eval(word[1:])
# move = True
#elif (word[0] == 'T') : col = "tool"
#elif (word[0] == 'X' or word[0] == 'x'):
# col = "axis"
# = eval(word[1:])
# move = True
#elif (word[0] == 'Y' or word[0] == 'y'):
# col = "axis"
# self.y = eval(word[1:])
# move = True
#elif (word[0] == 'Z' or word[0] == 'z'):
# col = "axis"
# self.z = eval(word[1:])
# move = True
elif (word[0] == '(') : col = "comment"
elif (word[0] == '#') : col = "variable"
elif (words[0] == ("//"+self.SPACE)) : col = "comment"
elif (words[0] == ("/*"+self.SPACE)) : col = "comment"
#self.add_text(word, col)
if (move):
self.begin_path(path_col)
if (arc) :
#self.add_arc(self.x, self.y, 0.0000, self.i, self.j, 0.0000, arc)
#self.add_arc(self.i, self.j, 0.0000, eval(words[2])-self.x, eval(words[5])-self.y, 0.0000, arc)
#print ''
#print eval(words[2])-self.startx
#print eval(words[6])-self.starty
#self.add_arc(self.endx, self.endy, 0.0000, eval(words[1])-self.startx, eval(words[3])-self.starty, 0.0000, arc)
print arc
self.add_arc(self.endx, self.endy, 0.0000,eval(words[1])-self.startx, eval(words[3])-self.starty, 0.0000,0.0000, arc)
#self.add_arc(self.x, self.y, 0.0000, self.i, self.j, 0.0000, arc)
#self.x=self.i
#self.y=self.j
else :
self.add_line(self.x, self.y)
self.end_path()
self.end_ncblock()
self.files_close()

View File

@@ -0,0 +1,31 @@
import nc
import iso_modal
import math
################################################################################
class Creator(iso_modal.Creator):
def __init__(self):
iso_modal.Creator.__init__(self)
self.arc_centre_positive = True
self.drillExpanded = True
self.can_do_helical_arcs = False
self.fmt.number_of_decimal_places = 2
def tool_defn(self, id, name='', params=None):
pass
def dwell(self, t):
# to do, find out what dwell is on this machine
pass
def metric(self):
iso_modal.Creator.metric(self)
self.fmt.number_of_decimal_places = 2
def SPACE(self):
return('')
################################################################################
nc.creator = Creator()

View File

@@ -0,0 +1,9 @@
import iso_read as iso
import sys
# use the iso reader, but with i_and_j_always_positive
class Parser(iso.Parser):
def __init__(self, writer):
iso.Parser.__init__(self, writer)
self.arc_centre_positive = True

View File

@@ -0,0 +1,22 @@
################################################################################
# siegkx1.py
#
# Post Processor for the Sieg KX1 machine
# It is just an ISO machine, but I don't want the tool definition lines
#
# Dan Heeks, 5th March 2009
import nc
import iso_modal
import math
################################################################################
class Creator(iso_modal.Creator):
def __init__(self):
iso_modal.Creator.__init__(self)
self.output_tool_definitions = False
################################################################################
nc.creator = Creator()

View File

@@ -0,0 +1,54 @@
################################################################################
# attach.py
#
# NC code creator for attaching Z coordinates to a surface
#
import recreator
import nc
swap = False
PUT_Y_VALUE_IN_A = 1
################################################################################
class Creator(recreator.Redirector):
def __init__(self, original, type, factor):
recreator.Redirector.__init__(self, original)
self.factor = factor
self.type = type
def feed(self, x=None, y=None, z=None, a=None, b=None, c=None):
if self.type == PUT_Y_VALUE_IN_A:
a = None
if y != None: a = y * self.factor
self.original.feed(x, None, z, a, b, c)
def rapid(self, x=None, y=None, z=None, a=None, b=None, c=None):
if self.type == PUT_Y_VALUE_IN_A:
a = None
if y != None: a = y * self.factor
self.original.rapid(x, None, z, a, b, c)
def arc(self, x=None, y=None, z=None, i=None, j=None, k=None, r=None, ccw = True):
# to do
pass
################################################################################
def use_a_for_y(radius):
cancel_swap()
if radius < 0.001:
return
global swap
radians_factor = 1 / radius
factor = radians_factor * 180 / 3.1415926535897932384
nc.creator = Creator(nc.creator, PUT_Y_VALUE_IN_A, factor)
swap = True
def cancel_swap():
global swap
if swap:
nc.creator = nc.creator.original
swap = False

View File

@@ -0,0 +1,90 @@
################################################################################
# tnc151.py
#
# Post Processor for the Heidenhain TNC151 machine
#
import nc
import iso_modal
import math
################################################################################
class Creator(iso_modal.Creator):
def __init__(self):
iso_modal.Creator.__init__(self)
self.fmt.add_plus = True
self.fmt.add_trailing_zeros = True
self.f.fmt.add_plus = True
self.s.fmt.add_plus = True
self.n = 1
self.waiting_t = None
self.waiting_for_program_begin = False
######## Codes
def SPACE(self): return(' ')
def TOOL(self): return('T%i')
######## Overridden functions
def write_blocknum(self):
self.write(self.BLOCK() % self.n)
self.n += 1
def program_begin(self, id, name=''):
self.waiting_for_program_begin = True
def write_waiting_program_begin(self):
if self.waiting_for_program_begin == True:
self.write('% 123')
self.waiting_for_program_begin = False
def imperial(self):
self.write_waiting_program_begin()
self.write(' G70\n')
self.fmt.number_of_decimal_places = 4
def metric(self):
self.write_waiting_program_begin()
self.write(' G71\n')
self.fmt.number_of_decimal_places = 3
# no tool definition lines wanted
def tool_defn(self, id, name='', params=None):
pass
# no comments wanted
def comment(self, text):
pass
def spindle(self, s, clockwise):
iso_modal.Creator.spindle(self, s, clockwise)
self.write_waiting_tool_change()
def tool_change(self, id):
self.waiting_t = id
def write_waiting_tool_change(self):
if self.waiting_t:
if len(self.g_list) > 0:
self.write_blocknum()
for g in self.g_list:
self.write(self.SPACE() + g)
self.g_list = []
self.write('\n')
self.write_blocknum()
self.write(self.SPACE() + (self.TOOL() % self.waiting_t))
self.write_preps()
self.write_spindle()
self.write_misc()
self.write('\n')
self.t = self.waiting_t
self.waiting_t = None
def workplane(self, id):
pass
################################################################################
nc.creator = Creator()

View File

@@ -0,0 +1,270 @@
################################################################################
# transform.py
#
# NC code creator for attaching Z coordinates to a surface
#
import nc
import area
import recreator
transformed = False
class FeedXY:
def __init__(self, x, y):
self.x = x
self.y = y
def Do(self, original, matrix):
x,y,z = matrix.TransformedPoint(self.x, self.y, 0)
original.feed(x, y)
class FeedZ:
def __init__(self, z):
self.z = z
def Do(self, original, matrix):
original.feed(z = self.z)
class FeedXYZ:
def __init__(self, x, y, z):
self.x = x
self.y = y
self.z = z
def Do(self, original, matrix):
x,y,z = matrix.TransformedPoint(self.x, self.y, self.z)
original.feed(x,y,z)
class RapidXY:
def __init__(self, x, y):
self.x = x
self.y = y
def Do(self, original, matrix):
x,y,z = matrix.TransformedPoint(self.x, self.y, 0)
original.rapid(x, y)
class RapidZ:
def __init__(self, z):
self.z = z
def Do(self, original, matrix):
original.rapid(z = self.z)
class RapidXYZ:
def __init__(self, x, y, z):
self.x = x
self.y = y
self.z = z
def Do(self, original, matrix):
x,y,z = matrix.TransformedPoint(self.x, self.y, self.z)
original.rapid(x,y,z)
class Feedrate:
def __init__(self, h, v):
self.h = h
self.v = v
def Do(self, original, matrix):
original.feedrate_hv(self.h, self.v)
class Arc:
def __init__(self, x, y, z, i, j, ccw):
self.x = x
self.y = y
self.z = z
self.i = i
self.j = j
self.ccw = ccw
def Do(self, original, matrix):
x,y,z = matrix.TransformedPoint(self.x, self.y, self.z)
cx,cy,cz = matrix.TransformedPoint(original.x + self.i, original.y + self.j, self.z)
i = cx - original.x
j = cy - original.y
if self.ccw:
original.arc_ccw(x, y, z, i, j)
else:
original.arc_cw(x, y, z, i, j)
class Drill:
def __init__(self, x, y, dwell, depthparams, retract_mode, spindle_mode, internal_coolant_on, rapid_to_clearance):
self.x = x
self.y = y
self.dwell = dwell
self.depthparams = depthparams
self.retract_mode = retract_mode
self.spindle_mode = spindle_mode
self.internal_coolant_on = internal_coolant_on
self.rapid_to_clearance = rapid_to_clearance
def Do(self, original, matrix):
x,y,z = matrix.TransformedPoint(self.x, self.y, 0.0)
original.drill(x, y, self.dwell, self.depthparams, self.retract_mode, self.spindle_mode, self.internal_coolant_on, self.rapid_to_clearance)
class Absolute:
def __init__(self):
pass
def Do(self, original, matrix):
original.absolute()
class Incremental:
def __init__(self):
pass
def Do(self, original, matrix):
original.incremental()
class EndCannedCycle:
def __init__(self):
pass
def Do(self, original, matrix):
original.end_canned_cycle()
class Comment:
def __init__(self, text):
self.text = text
def Do(self, original, matrix):
original.comment(self.text)
################################################################################
matrix_fixtures = {}
class Creator(recreator.Redirector):
def __init__(self, original, matrix_list):
recreator.Redirector.__init__(self, original)
self.matrix_list = matrix_list
self.commands = []
# allocate fixtures to pattern positions
if self.pattern_uses_subroutine() == True:
save_fixture = self.get_fixture()
for matrix in self.matrix_list:
global matrix_fixtures
if (matrix in matrix_fixtures) == False:
matrix_fixtures[matrix] = self.get_fixture()
self.increment_fixture()
self.set_fixture(save_fixture)
def DoAllCommands(self):
subroutine_written = False
for matrix in self.matrix_list:
if len(self.commands) > 0:
if self.pattern_uses_subroutine() == True:
# set fixture
global matrix_fixtures
self.set_fixture(matrix_fixtures[matrix])
# rapid to the pattern point in x and y
x,y,z = matrix.TransformedPoint(0.0, 0.0, 0.0)
self.original.rapid(x, y)
subroutine_started = False
output_disabled = False
for command in self.commands:
if (output_disabled == False) and (self.pattern_uses_subroutine() == True):
# in main program do commands up to the first z move
cname = command.__class__.__name__
if cname == 'FeedZ' or cname == 'Drill':
if subroutine_written:
self.sub_call(None)
self.disable_output() # ignore all the other commands
output_disabled = True
else:
if subroutine_started == False:
self.sub_begin(None)
subroutine_started = True
self.incremental()
command.Do(self.original, matrix)
self.enable_output()
output_disabled = False
if subroutine_started:
self.absolute()
self.flush_nc()
self.sub_end()
subroutine_written = True
self.sub_call(None)
def tool_change(self, id):
if id != self.original.current_tool():
self.DoAllCommands()
self.commands = []
self.original.tool_change(id)
def feedrate(self, f):
self.commands.append(Feedrate(f, f))
def feedrate_hv(self, fh, fv):
self.commands.append(Feedrate(fh, fv))
def rapid(self, x=None, y=None, z=None, a=None, b=None, c=None):
if x != None: self.x = x
if y != None: self.y = y
if z != None: self.z = z
if self.x == None and self.y == None and self.z == None:
return
if z == None:
self.commands.append(RapidXY(self.x, self.y))
elif x == None and y == None:
self.commands.append(RapidZ(self.z))
else:
self.commands.append(RapidXYZ(self.x, self.y, self.z))
def feed(self, x=None, y=None, z=None, a = None, b = None, c = None):
if x != None: self.x = x
if y != None: self.y = y
if z != None: self.z = z
if self.x == None and self.y == None and self.z == None:
return
if z == None:
self.commands.append(FeedXY(self.x, self.y))
elif x == None and y == None:
self.commands.append(FeedZ(self.z))
else:
self.commands.append(FeedXYZ(self.x, self.y, self.z))
def arc(self, x=None, y=None, z=None, i=None, j=None, k=None, r=None, ccw = True):
if x != None: self.x = x
if y != None: self.y = y
if z != None: self.z = z
if self.x == None and self.y == None and self.z == None:
return
self.commands.append(Arc(self.x, self.y, self.z, i, j, ccw))
def drill(self, x=None, y=None, dwell=None, depthparams = None, retract_mode=None, spindle_mode=None, internal_coolant_on=None, rapid_to_clearance=None):
self.commands.append(Drill(x, y, dwell, depthparams, retract_mode, spindle_mode, internal_coolant_on, rapid_to_clearance))
def end_canned_cycle(self):
self.commands.append(EndCannedCycle())
# def absolute(self):
# self.commands.append(Absolute())
# def incremental(self):
# self.commands.append(Incremental())
def comment(self, text):
self.commands.append(Comment(text))
################################################################################
def transform_begin(matrix_list):
global transformed
if transformed == True:
transform_end()
nc.creator = Creator(nc.creator, matrix_list)
transformed = True
def transform_end():
global transformed
nc.creator.DoAllCommands()
nc.creator = nc.creator.original
transformed = False