implement basic set of tests for tcl_shell, need to be completed
This commit is contained in:
parent
e2eb5f293a
commit
fd1c8afef9
400
FlatCAMApp.py
400
FlatCAMApp.py
|
@ -675,8 +675,19 @@ class App(QtCore.QObject):
|
|||
"""
|
||||
Handles input from the shell. See FlatCAMApp.setup_shell for shell commands.
|
||||
|
||||
:param text:
|
||||
:return: output if there was any
|
||||
"""
|
||||
|
||||
return self.exec_command_test(self, text, False)
|
||||
|
||||
def exec_command_test(self, text, reraise=True):
|
||||
"""
|
||||
Handles input from the shell. See FlatCAMApp.setup_shell for shell commands.
|
||||
|
||||
:param text: Input command
|
||||
:return: None
|
||||
:param reraise: raise exception and not hide it, used mainly in unittests
|
||||
:return: output if there was any
|
||||
"""
|
||||
|
||||
self.report_usage('exec_command')
|
||||
|
@ -691,8 +702,10 @@ class App(QtCore.QObject):
|
|||
result = self.tcl.eval("set errorInfo")
|
||||
self.log.error("Exec command Exception: %s" % (result + '\n'))
|
||||
self.shell.append_error('ERROR: ' + result + '\n')
|
||||
#show error in console and just return
|
||||
return
|
||||
#show error in console and just return or in test raise exception
|
||||
if reraise:
|
||||
raise e
|
||||
return result
|
||||
|
||||
"""
|
||||
Code below is unsused. Saved for later.
|
||||
|
@ -2167,85 +2180,96 @@ class App(QtCore.QObject):
|
|||
return 'Ok'
|
||||
|
||||
|
||||
def geocutout(name, *args):
|
||||
"""
|
||||
def geocutout(name=None, *args):
|
||||
'''
|
||||
TCL shell command - see help section
|
||||
|
||||
Subtract gaps from geometry, this will not create new object
|
||||
|
||||
:param name:
|
||||
:param args:
|
||||
:return:
|
||||
"""
|
||||
a, kwa = h(*args)
|
||||
types = {'dia': float,
|
||||
'gapsize': float,
|
||||
'gaps': str}
|
||||
|
||||
# How gaps wil be rendered:
|
||||
# lr - left + right
|
||||
# tb - top + bottom
|
||||
# 4 - left + right +top + bottom
|
||||
# 2lr - 2*left + 2*right
|
||||
# 2tb - 2*top + 2*bottom
|
||||
# 8 - 2*left + 2*right +2*top + 2*bottom
|
||||
|
||||
for key in kwa:
|
||||
if key not in types:
|
||||
return 'Unknown parameter: %s' % key
|
||||
kwa[key] = types[key](kwa[key])
|
||||
:param name: name of object
|
||||
:param args: array of arguments
|
||||
:return: "Ok" if completed without errors
|
||||
'''
|
||||
|
||||
try:
|
||||
obj = self.collection.get_by_name(str(name))
|
||||
except:
|
||||
return "Could not retrieve object: %s" % name
|
||||
a, kwa = h(*args)
|
||||
types = {'dia': float,
|
||||
'gapsize': float,
|
||||
'gaps': str}
|
||||
|
||||
# Get min and max data for each object as we just cut rectangles across X or Y
|
||||
xmin, ymin, xmax, ymax = obj.bounds()
|
||||
px = 0.5 * (xmin + xmax)
|
||||
py = 0.5 * (ymin + ymax)
|
||||
lenghtx = (xmax - xmin)
|
||||
lenghty = (ymax - ymin)
|
||||
gapsize = kwa['gapsize'] + kwa['dia'] / 2
|
||||
# How gaps wil be rendered:
|
||||
# lr - left + right
|
||||
# tb - top + bottom
|
||||
# 4 - left + right +top + bottom
|
||||
# 2lr - 2*left + 2*right
|
||||
# 2tb - 2*top + 2*bottom
|
||||
# 8 - 2*left + 2*right +2*top + 2*bottom
|
||||
|
||||
if kwa['gaps'] == '8' or kwa['gaps']=='2lr':
|
||||
if name is None:
|
||||
self.raiseTclError('Argument name is missing.')
|
||||
|
||||
subtract_rectangle(name,
|
||||
xmin - gapsize,
|
||||
py - gapsize + lenghty / 4,
|
||||
xmax + gapsize,
|
||||
py + gapsize + lenghty / 4)
|
||||
subtract_rectangle(name,
|
||||
xmin-gapsize,
|
||||
py - gapsize - lenghty / 4,
|
||||
xmax + gapsize,
|
||||
py + gapsize - lenghty / 4)
|
||||
for key in kwa:
|
||||
if key not in types:
|
||||
self.raiseTclError('Unknown parameter: %s' % key)
|
||||
try:
|
||||
kwa[key] = types[key](kwa[key])
|
||||
except Exception, e:
|
||||
self.raiseTclError("Cannot cast argument '%s' to type %s." % (key, str(types[key])))
|
||||
|
||||
if kwa['gaps'] == '8' or kwa['gaps']=='2tb':
|
||||
subtract_rectangle(name,
|
||||
px - gapsize + lenghtx / 4,
|
||||
ymin-gapsize,
|
||||
px + gapsize + lenghtx / 4,
|
||||
ymax + gapsize)
|
||||
subtract_rectangle(name,
|
||||
px - gapsize - lenghtx / 4,
|
||||
ymin - gapsize,
|
||||
px + gapsize - lenghtx / 4,
|
||||
ymax + gapsize)
|
||||
try:
|
||||
obj = self.collection.get_by_name(str(name))
|
||||
except:
|
||||
self.raiseTclError("Could not retrieve object: %s" % name)
|
||||
|
||||
if kwa['gaps'] == '4' or kwa['gaps']=='lr':
|
||||
subtract_rectangle(name,
|
||||
xmin - gapsize,
|
||||
py - gapsize,
|
||||
xmax + gapsize,
|
||||
py + gapsize)
|
||||
# Get min and max data for each object as we just cut rectangles across X or Y
|
||||
xmin, ymin, xmax, ymax = obj.bounds()
|
||||
px = 0.5 * (xmin + xmax)
|
||||
py = 0.5 * (ymin + ymax)
|
||||
lenghtx = (xmax - xmin)
|
||||
lenghty = (ymax - ymin)
|
||||
gapsize = kwa['gapsize'] + kwa['dia'] / 2
|
||||
|
||||
if kwa['gaps'] == '4' or kwa['gaps']=='tb':
|
||||
subtract_rectangle(name,
|
||||
px - gapsize,
|
||||
ymin - gapsize,
|
||||
px + gapsize,
|
||||
ymax + gapsize)
|
||||
if kwa['gaps'] == '8' or kwa['gaps']=='2lr':
|
||||
|
||||
return 'Ok'
|
||||
subtract_rectangle(name,
|
||||
xmin - gapsize,
|
||||
py - gapsize + lenghty / 4,
|
||||
xmax + gapsize,
|
||||
py + gapsize + lenghty / 4)
|
||||
subtract_rectangle(name,
|
||||
xmin-gapsize,
|
||||
py - gapsize - lenghty / 4,
|
||||
xmax + gapsize,
|
||||
py + gapsize - lenghty / 4)
|
||||
|
||||
if kwa['gaps'] == '8' or kwa['gaps']=='2tb':
|
||||
subtract_rectangle(name,
|
||||
px - gapsize + lenghtx / 4,
|
||||
ymin-gapsize,
|
||||
px + gapsize + lenghtx / 4,
|
||||
ymax + gapsize)
|
||||
subtract_rectangle(name,
|
||||
px - gapsize - lenghtx / 4,
|
||||
ymin - gapsize,
|
||||
px + gapsize - lenghtx / 4,
|
||||
ymax + gapsize)
|
||||
|
||||
if kwa['gaps'] == '4' or kwa['gaps']=='lr':
|
||||
subtract_rectangle(name,
|
||||
xmin - gapsize,
|
||||
py - gapsize,
|
||||
xmax + gapsize,
|
||||
py + gapsize)
|
||||
|
||||
if kwa['gaps'] == '4' or kwa['gaps']=='tb':
|
||||
subtract_rectangle(name,
|
||||
px - gapsize,
|
||||
ymin - gapsize,
|
||||
px + gapsize,
|
||||
ymax + gapsize)
|
||||
|
||||
except Exception as unknown:
|
||||
self.raiseTclUnknownError(unknown)
|
||||
|
||||
def mirror(name, *args):
|
||||
a, kwa = h(*args)
|
||||
|
@ -2519,59 +2543,63 @@ class App(QtCore.QObject):
|
|||
:param args: array of arguments
|
||||
:return: "Ok" if completed without errors
|
||||
'''
|
||||
a, kwa = h(*args)
|
||||
types = {'tools': str,
|
||||
'outname': str,
|
||||
'drillz': float,
|
||||
'travelz': float,
|
||||
'feedrate': float,
|
||||
'spindlespeed': int,
|
||||
'toolchange': int
|
||||
}
|
||||
|
||||
if name is None:
|
||||
self.raiseTclError('Argument name is missing.')
|
||||
try:
|
||||
a, kwa = h(*args)
|
||||
types = {'tools': str,
|
||||
'outname': str,
|
||||
'drillz': float,
|
||||
'travelz': float,
|
||||
'feedrate': float,
|
||||
'spindlespeed': int,
|
||||
'toolchange': int
|
||||
}
|
||||
|
||||
if name is None:
|
||||
self.raiseTclError('Argument name is missing.')
|
||||
|
||||
for key in kwa:
|
||||
if key not in types:
|
||||
self.raiseTclError('Unknown parameter: %s' % key)
|
||||
try:
|
||||
kwa[key] = types[key](kwa[key])
|
||||
except Exception, e:
|
||||
self.raiseTclError("Cannot cast argument '%s' to type %s." % (key, str(types[key])))
|
||||
|
||||
for key in kwa:
|
||||
if key not in types:
|
||||
self.raiseTclError('Unknown parameter: %s' % key)
|
||||
try:
|
||||
kwa[key] = types[key](kwa[key])
|
||||
obj = self.collection.get_by_name(str(name))
|
||||
except:
|
||||
self.raiseTclError("Could not retrieve object: %s" % name)
|
||||
|
||||
if obj is None:
|
||||
self.raiseTclError('Object not found: %s' % name)
|
||||
|
||||
if not isinstance(obj, FlatCAMExcellon):
|
||||
self.raiseTclError('Only Excellon objects can be drilled, got %s %s.' % (name, type(obj)))
|
||||
|
||||
try:
|
||||
# Get the tools from the list
|
||||
job_name = kwa["outname"]
|
||||
|
||||
# Object initialization function for app.new_object()
|
||||
def job_init(job_obj, app_obj):
|
||||
job_obj.z_cut = kwa["drillz"]
|
||||
job_obj.z_move = kwa["travelz"]
|
||||
job_obj.feedrate = kwa["feedrate"]
|
||||
job_obj.spindlespeed = kwa["spindlespeed"] if "spindlespeed" in kwa else None
|
||||
toolchange = True if "toolchange" in kwa and kwa["toolchange"] == 1 else False
|
||||
job_obj.generate_from_excellon_by_tool(obj, kwa["tools"], toolchange)
|
||||
job_obj.gcode_parse()
|
||||
job_obj.create_geometry()
|
||||
|
||||
obj.app.new_object("cncjob", job_name, job_init)
|
||||
|
||||
except Exception, e:
|
||||
self.raiseTclError("Cannot cast argument '%s' to type %s." % (key, str(types[key])))
|
||||
self.raiseTclError("Operation failed: %s" % str(e))
|
||||
|
||||
try:
|
||||
obj = self.collection.get_by_name(str(name))
|
||||
except:
|
||||
self.raiseTclError("Could not retrieve object: %s" % name)
|
||||
except Exception as unknown:
|
||||
self.raiseTclUnknownError(unknown)
|
||||
|
||||
if obj is None:
|
||||
self.raiseTclError('Object not found: %s' % name)
|
||||
|
||||
if not isinstance(obj, FlatCAMExcellon):
|
||||
self.raiseTclError('Only Excellon objects can be drilled, got %s %s.' % (name, type(obj)))
|
||||
|
||||
try:
|
||||
# Get the tools from the list
|
||||
job_name = kwa["outname"]
|
||||
|
||||
# Object initialization function for app.new_object()
|
||||
def job_init(job_obj, app_obj):
|
||||
job_obj.z_cut = kwa["drillz"]
|
||||
job_obj.z_move = kwa["travelz"]
|
||||
job_obj.feedrate = kwa["feedrate"]
|
||||
job_obj.spindlespeed = kwa["spindlespeed"] if "spindlespeed" in kwa else None
|
||||
toolchange = True if "toolchange" in kwa and kwa["toolchange"] == 1 else False
|
||||
job_obj.generate_from_excellon_by_tool(obj, kwa["tools"], toolchange)
|
||||
job_obj.gcode_parse()
|
||||
job_obj.create_geometry()
|
||||
|
||||
obj.app.new_object("cncjob", job_name, job_init)
|
||||
|
||||
except Exception, e:
|
||||
self.raiseTclError("Operation failed: %s" % str(e))
|
||||
|
||||
return 'Ok'
|
||||
|
||||
def millholes(name=None, *args):
|
||||
'''
|
||||
|
@ -2580,48 +2608,51 @@ class App(QtCore.QObject):
|
|||
:param args: array of arguments
|
||||
:return: "Ok" if completed without errors
|
||||
'''
|
||||
a, kwa = h(*args)
|
||||
types = {'tooldia': float,
|
||||
'tools': str,
|
||||
'outname': str}
|
||||
|
||||
if name is None:
|
||||
self.raiseTclError('Argument name is missing.')
|
||||
try:
|
||||
a, kwa = h(*args)
|
||||
types = {'tooldia': float,
|
||||
'tools': str,
|
||||
'outname': str}
|
||||
|
||||
if name is None:
|
||||
self.raiseTclError('Argument name is missing.')
|
||||
|
||||
for key in kwa:
|
||||
if key not in types:
|
||||
self.raiseTclError('Unknown parameter: %s' % key)
|
||||
try:
|
||||
kwa[key] = types[key](kwa[key])
|
||||
except Exception, e:
|
||||
self.raiseTclError("Cannot cast argument '%s' to type %s." % (key, types[key]))
|
||||
|
||||
for key in kwa:
|
||||
if key not in types:
|
||||
self.raiseTclError('Unknown parameter: %s' % key)
|
||||
try:
|
||||
kwa[key] = types[key](kwa[key])
|
||||
except Exception, e:
|
||||
self.raiseTclError("Cannot cast argument '%s' to type %s." % (key, types[key]))
|
||||
if 'tools' in kwa:
|
||||
kwa['tools'] = [x.strip() for x in kwa['tools'].split(",")]
|
||||
except Exception as e:
|
||||
self.raiseTclError("Bad tools: %s" % str(e))
|
||||
|
||||
try:
|
||||
if 'tools' in kwa:
|
||||
kwa['tools'] = [x.strip() for x in kwa['tools'].split(",")]
|
||||
except Exception as e:
|
||||
self.raiseTclError("Bad tools: %s" % str(e))
|
||||
try:
|
||||
obj = self.collection.get_by_name(str(name))
|
||||
except:
|
||||
self.raiseTclError("Could not retrieve object: %s" % name)
|
||||
|
||||
try:
|
||||
obj = self.collection.get_by_name(str(name))
|
||||
except:
|
||||
self.raiseTclError("Could not retrieve object: %s" % name)
|
||||
if obj is None:
|
||||
self.raiseTclError("Object not found: %s" % name)
|
||||
|
||||
if obj is None:
|
||||
self.raiseTclError("Object not found: %s" % name)
|
||||
if not isinstance(obj, FlatCAMExcellon):
|
||||
self.raiseTclError('Only Excellon objects can be mill drilled, got %s %s.' % (name, type(obj)))
|
||||
|
||||
if not isinstance(obj, FlatCAMExcellon):
|
||||
self.raiseTclError('Only Excellon objects can be mill drilled, got %s %s.' % (name, type(obj)))
|
||||
try:
|
||||
success, msg = obj.generate_milling(**kwa)
|
||||
except Exception as e:
|
||||
self.raiseTclError("Operation failed: %s" % str(e))
|
||||
|
||||
try:
|
||||
success, msg = obj.generate_milling(**kwa)
|
||||
except Exception as e:
|
||||
self.raiseTclError("Operation failed: %s" % str(e))
|
||||
if not success:
|
||||
self.raiseTclError(msg)
|
||||
|
||||
if not success:
|
||||
self.raiseTclError(msg)
|
||||
|
||||
return 'Ok'
|
||||
except Exception as unknown:
|
||||
self.raiseTclUnknownError(unknown)
|
||||
|
||||
def exteriors(name=None, *args):
|
||||
'''
|
||||
|
@ -2630,46 +2661,49 @@ class App(QtCore.QObject):
|
|||
:param args: array of arguments
|
||||
:return: "Ok" if completed without errors
|
||||
'''
|
||||
a, kwa = h(*args)
|
||||
types = {'outname': str}
|
||||
|
||||
if name is None:
|
||||
self.raiseTclError('Argument name is missing.')
|
||||
try:
|
||||
a, kwa = h(*args)
|
||||
types = {'outname': str}
|
||||
|
||||
if name is None:
|
||||
self.raiseTclError('Argument name is missing.')
|
||||
|
||||
for key in kwa:
|
||||
if key not in types:
|
||||
self.raiseTclError('Unknown parameter: %s' % key)
|
||||
try:
|
||||
kwa[key] = types[key](kwa[key])
|
||||
except Exception, e:
|
||||
self.raiseTclError("Cannot cast argument '%s' to type %s." % (key, types[key]))
|
||||
|
||||
for key in kwa:
|
||||
if key not in types:
|
||||
self.raiseTclError('Unknown parameter: %s' % key)
|
||||
try:
|
||||
kwa[key] = types[key](kwa[key])
|
||||
except Exception, e:
|
||||
self.raiseTclError("Cannot cast argument '%s' to type %s." % (key, types[key]))
|
||||
obj = self.collection.get_by_name(str(name))
|
||||
except:
|
||||
self.raiseTclError("Could not retrieve object: %s" % name)
|
||||
|
||||
try:
|
||||
obj = self.collection.get_by_name(str(name))
|
||||
except:
|
||||
self.raiseTclError("Could not retrieve object: %s" % name)
|
||||
if obj is None:
|
||||
self.raiseTclError("Object not found: %s" % name)
|
||||
|
||||
if obj is None:
|
||||
self.raiseTclError("Object not found: %s" % name)
|
||||
if not isinstance(obj, Geometry):
|
||||
self.raiseTclError('Expected Geometry, got %s %s.' % (name, type(obj)))
|
||||
|
||||
if not isinstance(obj, Geometry):
|
||||
self.raiseTclError('Expected Geometry, got %s %s.' % (name, type(obj)))
|
||||
def geo_init(geo_obj, app_obj):
|
||||
geo_obj.solid_geometry = obj_exteriors
|
||||
|
||||
def geo_init(geo_obj, app_obj):
|
||||
geo_obj.solid_geometry = obj_exteriors
|
||||
if 'outname' in kwa:
|
||||
outname = kwa['outname']
|
||||
else:
|
||||
outname = name + ".exteriors"
|
||||
|
||||
if 'outname' in kwa:
|
||||
outname = kwa['outname']
|
||||
else:
|
||||
outname = name + ".exteriors"
|
||||
try:
|
||||
obj_exteriors = obj.get_exteriors()
|
||||
self.new_object('geometry', outname, geo_init)
|
||||
except Exception as e:
|
||||
self.raiseTclError("Failed: %s" % str(e))
|
||||
|
||||
try:
|
||||
obj_exteriors = obj.get_exteriors()
|
||||
self.new_object('geometry', outname, geo_init)
|
||||
except Exception as e:
|
||||
self.raiseTclError("Failed: %s" % str(e))
|
||||
|
||||
return 'Ok'
|
||||
except Exception as unknown:
|
||||
self.raiseTclUnknownError(unknown)
|
||||
|
||||
def interiors(name=None, *args):
|
||||
'''
|
||||
|
@ -2722,8 +2756,6 @@ class App(QtCore.QObject):
|
|||
except Exception as unknown:
|
||||
self.raiseTclUnknownError(unknown)
|
||||
|
||||
return 'Ok'
|
||||
|
||||
def isolate(name=None, *args):
|
||||
'''
|
||||
TCL shell command - see help section
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
G04 MADE WITH FRITZING*
|
||||
G04 WWW.FRITZING.ORG*
|
||||
G04 DOUBLE SIDED*
|
||||
G04 HOLES PLATED*
|
||||
G04 CONTOUR ON CENTER OF CONTOUR VECTOR*
|
||||
%ASAXBY*%
|
||||
%FSLAX23Y23*%
|
||||
%MOIN*%
|
||||
%OFA0B0*%
|
||||
%SFA1.0B1.0*%
|
||||
%ADD10R,1.771650X1.181100*%
|
||||
%ADD11C,0.008000*%
|
||||
%ADD10C,0.008*%
|
||||
%LNCONTOUR*%
|
||||
G90*
|
||||
G70*
|
||||
G54D10*
|
||||
G54D11*
|
||||
X4Y1177D02*
|
||||
X1768Y1177D01*
|
||||
X1768Y4D01*
|
||||
X4Y4D01*
|
||||
X4Y1177D01*
|
||||
D02*
|
||||
G04 End of contour*
|
||||
M02*
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,71 @@
|
|||
G04 MADE WITH FRITZING*
|
||||
G04 WWW.FRITZING.ORG*
|
||||
G04 DOUBLE SIDED*
|
||||
G04 HOLES PLATED*
|
||||
G04 CONTOUR ON CENTER OF CONTOUR VECTOR*
|
||||
%ASAXBY*%
|
||||
%FSLAX23Y23*%
|
||||
%MOIN*%
|
||||
%OFA0B0*%
|
||||
%SFA1.0B1.0*%
|
||||
%ADD10C,0.075000*%
|
||||
%ADD11C,0.099055*%
|
||||
%ADD12C,0.078740*%
|
||||
%ADD13R,0.075000X0.075000*%
|
||||
%ADD14C,0.024000*%
|
||||
%ADD15C,0.020000*%
|
||||
%LNCOPPER1*%
|
||||
G90*
|
||||
G70*
|
||||
G54D10*
|
||||
X1149Y872D03*
|
||||
X1349Y872D03*
|
||||
X749Y722D03*
|
||||
X749Y522D03*
|
||||
X1149Y522D03*
|
||||
X1449Y522D03*
|
||||
X1149Y422D03*
|
||||
X1449Y422D03*
|
||||
X1149Y322D03*
|
||||
X1449Y322D03*
|
||||
X1149Y222D03*
|
||||
X1449Y222D03*
|
||||
X949Y472D03*
|
||||
X949Y72D03*
|
||||
G54D11*
|
||||
X749Y972D03*
|
||||
X599Y972D03*
|
||||
X349Y322D03*
|
||||
X349Y472D03*
|
||||
X349Y672D03*
|
||||
X349Y822D03*
|
||||
G54D10*
|
||||
X699Y122D03*
|
||||
X699Y322D03*
|
||||
G54D12*
|
||||
X699Y222D03*
|
||||
X949Y972D03*
|
||||
X749Y622D03*
|
||||
X1049Y222D03*
|
||||
X1249Y872D03*
|
||||
G54D13*
|
||||
X1149Y872D03*
|
||||
X1149Y522D03*
|
||||
G54D14*
|
||||
X952Y946D02*
|
||||
X1045Y249D01*
|
||||
G54D15*
|
||||
X776Y695D02*
|
||||
X721Y695D01*
|
||||
X721Y750D01*
|
||||
X776Y750D01*
|
||||
X776Y695D01*
|
||||
D02*
|
||||
X671Y150D02*
|
||||
X726Y150D01*
|
||||
X726Y95D01*
|
||||
X671Y95D01*
|
||||
X671Y150D01*
|
||||
D02*
|
||||
G04 End of Copper1*
|
||||
M02*
|
|
@ -0,0 +1,46 @@
|
|||
; NON-PLATED HOLES START AT T1
|
||||
; THROUGH (PLATED) HOLES START AT T100
|
||||
M48
|
||||
INCH
|
||||
T1C0.125984
|
||||
T100C0.031496
|
||||
T101C0.035000
|
||||
T102C0.059055
|
||||
%
|
||||
T1
|
||||
X001488Y010223
|
||||
X001488Y001223
|
||||
X016488Y001223
|
||||
X016488Y010223
|
||||
T100
|
||||
X009488Y009723
|
||||
X007488Y006223
|
||||
X012488Y008723
|
||||
X010488Y002223
|
||||
X006988Y002223
|
||||
T101
|
||||
X014488Y004223
|
||||
X006988Y003223
|
||||
X013488Y008723
|
||||
X011488Y008723
|
||||
X007488Y005223
|
||||
X014488Y003223
|
||||
X014488Y002223
|
||||
X011488Y005223
|
||||
X009488Y000723
|
||||
X011488Y004223
|
||||
X006988Y001223
|
||||
X009488Y004723
|
||||
X007488Y007223
|
||||
X011488Y003223
|
||||
X014488Y005223
|
||||
X011488Y002223
|
||||
T102
|
||||
X003488Y008223
|
||||
X003488Y004723
|
||||
X007488Y009723
|
||||
X003488Y006723
|
||||
X005988Y009723
|
||||
X003488Y003223
|
||||
T00
|
||||
M30
|
|
@ -0,0 +1,155 @@
|
|||
import sys
|
||||
import unittest
|
||||
from PyQt4 import QtGui
|
||||
from FlatCAMApp import App
|
||||
from FlatCAMObj import FlatCAMGerber, FlatCAMGeometry, FlatCAMCNCjob, FlatCAMExcellon
|
||||
from ObjectUI import GerberObjectUI, GeometryObjectUI
|
||||
from time import sleep
|
||||
import os
|
||||
import tempfile
|
||||
|
||||
class TclShellCommandTest(unittest.TestCase):
|
||||
|
||||
gerber_files = 'tests/gerber_files'
|
||||
copper_bottom_filename = 'detector_copper_bottom.gbr'
|
||||
copper_top_filename = 'detector_copper_top.gbr'
|
||||
cutout_filename = 'detector_contour.gbr'
|
||||
excellon_filename = 'detector_drill.txt'
|
||||
excellon_name = "excellon"
|
||||
gerber_top_name = "top"
|
||||
gerber_bottom_name = "bottom"
|
||||
gerber_cutout_name = "cutout"
|
||||
engraver_diameter = 0.3
|
||||
cutout_diameter = 3
|
||||
drill_diameter = 0.8
|
||||
|
||||
def setUp(self):
|
||||
self.app = QtGui.QApplication(sys.argv)
|
||||
|
||||
# Create App, keep app defaults (do not load
|
||||
# user-defined defaults).
|
||||
self.fc = App(user_defaults=False)
|
||||
|
||||
def tearDown(self):
|
||||
del self.fc
|
||||
del self.app
|
||||
|
||||
def test_set_get_units(self):
|
||||
|
||||
self.fc.exec_command_test('set_sys units IN')
|
||||
self.fc.exec_command_test('new')
|
||||
units=self.fc.exec_command_test('get_sys units')
|
||||
self.assertEquals(units, "IN")
|
||||
|
||||
self.fc.exec_command_test('set_sys units MM')
|
||||
self.fc.exec_command_test('new')
|
||||
units=self.fc.exec_command_test('get_sys units')
|
||||
self.assertEquals(units, "MM")
|
||||
|
||||
def test_gerber_flow(self):
|
||||
|
||||
# open gerber files top, bottom and cutout
|
||||
|
||||
self.fc.exec_command_test('set_sys units MM')
|
||||
self.fc.exec_command_test('new')
|
||||
|
||||
self.fc.exec_command_test('open_gerber %s/%s -outname %s' % (self.gerber_files, self.copper_top_filename, self.gerber_top_name))
|
||||
gerber_top_obj = self.fc.collection.get_by_name(self.gerber_top_name)
|
||||
self.assertTrue(isinstance(gerber_top_obj, FlatCAMGerber),
|
||||
"Expected FlatCAMGerber, instead, %s is %s" %
|
||||
(self.gerber_top_name, type(gerber_top_obj)))
|
||||
|
||||
self.fc.exec_command_test('open_gerber %s/%s -outname %s' % (self.gerber_files, self.copper_bottom_filename, self.gerber_bottom_name))
|
||||
gerber_bottom_obj = self.fc.collection.get_by_name(self.gerber_bottom_name)
|
||||
self.assertTrue(isinstance(gerber_bottom_obj, FlatCAMGerber),
|
||||
"Expected FlatCAMGerber, instead, %s is %s" %
|
||||
(self.gerber_bottom_name, type(gerber_bottom_obj)))
|
||||
|
||||
self.fc.exec_command_test('open_gerber %s/%s -outname %s' % (self.gerber_files, self.cutout_filename, self.gerber_cutout_name))
|
||||
gerber_cutout_obj = self.fc.collection.get_by_name(self.gerber_cutout_name)
|
||||
self.assertTrue(isinstance(gerber_cutout_obj, FlatCAMGerber),
|
||||
"Expected FlatCAMGerber, instead, %s is %s" %
|
||||
(self.gerber_cutout_name, type(gerber_cutout_obj)))
|
||||
|
||||
# exteriors delete and join geometries for top layer
|
||||
self.fc.exec_command_test('isolate %s -dia %f' % (self.gerber_cutout_name, self.engraver_diameter))
|
||||
self.fc.exec_command_test('exteriors %s -outname %s' % (self.gerber_cutout_name + '_iso', self.gerber_cutout_name + '_iso_exterior'))
|
||||
self.fc.exec_command_test('delete %s' % (self.gerber_cutout_name + '_iso'))
|
||||
obj = self.fc.collection.get_by_name(self.gerber_cutout_name + '_iso_exterior')
|
||||
self.assertTrue(isinstance(obj, FlatCAMGeometry),
|
||||
"Expected FlatCAMGeometry, instead, %s is %s" %
|
||||
(self.gerber_cutout_name + '_iso_exterior', type(obj)))
|
||||
|
||||
# mirror bottom gerbers
|
||||
self.fc.exec_command_test('mirror %s -box %s -axis X' % (self.gerber_bottom_name, self.gerber_cutout_name))
|
||||
self.fc.exec_command_test('mirror %s -box %s -axis X' % (self.gerber_cutout_name, self.gerber_cutout_name))
|
||||
|
||||
# exteriors delete and join geometries for bottom layer
|
||||
self.fc.exec_command_test('isolate %s -dia %f -outname %s' % (self.gerber_cutout_name, self.engraver_diameter, self.gerber_cutout_name + '_bottom_iso'))
|
||||
self.fc.exec_command_test('exteriors %s -outname %s' % (self.gerber_cutout_name + '_bottom_iso', self.gerber_cutout_name + '_bottom_iso_exterior'))
|
||||
self.fc.exec_command_test('delete %s' % (self.gerber_cutout_name + '_bottom_iso'))
|
||||
obj = self.fc.collection.get_by_name(self.gerber_cutout_name + '_bottom_iso_exterior')
|
||||
self.assertTrue(isinstance(obj, FlatCAMGeometry),
|
||||
"Expected FlatCAMGeometry, instead, %s is %s" %
|
||||
(self.gerber_cutout_name + '_bottom_iso_exterior', type(obj)))
|
||||
|
||||
# at this stage we should have 5 objects
|
||||
names = self.fc.collection.get_names()
|
||||
self.assertEqual(len(names), 5,
|
||||
"Expected 5 objects, found %d" % len(names))
|
||||
|
||||
# isolate traces
|
||||
self.fc.exec_command_test('isolate %s -dia %f' % (self.gerber_top_name, self.engraver_diameter))
|
||||
self.fc.exec_command_test('isolate %s -dia %f' % (self.gerber_bottom_name, self.engraver_diameter))
|
||||
|
||||
# join isolated geometries for top and bottom
|
||||
self.fc.exec_command_test('join_geometries %s %s %s' % (self.gerber_top_name + '_join_iso', self.gerber_top_name + '_iso', self.gerber_cutout_name + '_iso_exterior'))
|
||||
self.fc.exec_command_test('join_geometries %s %s %s' % (self.gerber_bottom_name + '_join_iso', self.gerber_bottom_name + '_iso', self.gerber_cutout_name + '_bottom_iso_exterior'))
|
||||
|
||||
# at this stage we should have 9 objects
|
||||
names = self.fc.collection.get_names()
|
||||
self.assertEqual(len(names), 9,
|
||||
"Expected 9 objects, found %d" % len(names))
|
||||
|
||||
# clean unused isolations
|
||||
self.fc.exec_command_test('delete %s' % (self.gerber_bottom_name + '_iso'))
|
||||
self.fc.exec_command_test('delete %s' % (self.gerber_top_name + '_iso'))
|
||||
self.fc.exec_command_test('delete %s' % (self.gerber_cutout_name + '_iso_exterior'))
|
||||
self.fc.exec_command_test('delete %s' % (self.gerber_cutout_name + '_bottom_iso_exterior'))
|
||||
|
||||
# at this stage we should have 5 objects again
|
||||
names = self.fc.collection.get_names()
|
||||
self.assertEqual(len(names), 5,
|
||||
"Expected 5 objects, found %d" % len(names))
|
||||
|
||||
# geocutout bottom test (it cuts to same object)
|
||||
self.fc.exec_command_test('isolate %s -dia %f -outname %s' % (self.gerber_cutout_name, self.cutout_diameter, self.gerber_cutout_name + '_bottom_iso'))
|
||||
self.fc.exec_command_test('exteriors %s -outname %s' % (self.gerber_cutout_name + '_bottom_iso', self.gerber_cutout_name + '_bottom_iso_exterior'))
|
||||
self.fc.exec_command_test('delete %s' % (self.gerber_cutout_name + '_bottom_iso'))
|
||||
obj = self.fc.collection.get_by_name(self.gerber_cutout_name + '_bottom_iso_exterior')
|
||||
self.assertTrue(isinstance(obj, FlatCAMGeometry),
|
||||
"Expected FlatCAMGeometry, instead, %s is %s" %
|
||||
(self.gerber_cutout_name + '_bottom_iso_exterior', type(obj)))
|
||||
self.fc.exec_command_test('geocutout %s -dia %f -gapsize 0.3 -gaps 4' % (self.gerber_cutout_name + '_bottom_iso_exterior', self.cutout_diameter))
|
||||
|
||||
# at this stage we should have 6 objects
|
||||
names = self.fc.collection.get_names()
|
||||
self.assertEqual(len(names), 6,
|
||||
"Expected 6 objects, found %d" % len(names))
|
||||
|
||||
# TODO: tests for tcl
|
||||
|
||||
def test_excellon_flow(self):
|
||||
|
||||
|
||||
self.fc.exec_command_test('set_sys units MM')
|
||||
self.fc.exec_command_test('open_excellon %s/%s -outname %s' % (self.gerber_files, self.excellon_filename, self.excellon_name))
|
||||
excellon_obj = self.fc.collection.get_by_name(self.excellon_name)
|
||||
self.assertTrue(isinstance(excellon_obj, FlatCAMExcellon),
|
||||
"Expected FlatCAMExcellon, instead, %s is %s" %
|
||||
(self.excellon_name, type(excellon_obj)))
|
||||
|
||||
# mirror bottom excellon
|
||||
self.fc.exec_command_test('mirror %s -box %s -axis X' % (self.excellon_name, self.gerber_cutout_name))
|
||||
|
||||
# TODO: tests for tcl
|
Loading…
Reference in New Issue