Merged marius_stanciu/flatcam_beta/Beta_8.993 into Beta

This commit is contained in:
Marius Stanciu 2020-05-12 16:52:38 +03:00
commit 752113c035
10 changed files with 121 additions and 58 deletions

View File

@ -7,6 +7,13 @@ CHANGELOG for FlatCAM beta
=================================================
12.05.2020
- fixed recent issues introduced in Tcl command Drillcncjob
- updated the Cncjob to use the 'endxy' parameter which dictates the x,y position at the end of the job
- now the Tcl commands Drillcncjob and Cncjob can use the toolchangexy and endxy parameters with or without parenthesis (but no spaces allowed)
- modified the Tcl command Paint "single" parameter. Now it's value is a tuple with the x,y coordinates of the single polygon to be painted.
11.05.2020
- removed the labels in status bar that display X,Y positions and replaced it with a HUD display on canvas (combo key SHIFT+H) will toggle the display of the HUD

View File

@ -2676,7 +2676,7 @@ class CNCjob(Geometry):
if self.xy_toolchange and self.xy_toolchange != '':
self.xy_toolchange = [float(eval(a)) for a in self.xy_toolchange.split(",")]
if self.xy_toolchange and len(self.xy_toolchange) < 2:
if self.xy_toolchange and len(self.xy_toolchange) != 2:
self.app.inform.emit('[ERROR]%s' %
_("The Toolchange X,Y field in Edit -> Preferences has to be "
"in the format (x, y) \nbut now there is only one value, not two. "))

View File

@ -3438,8 +3438,8 @@ class FlatCAMExcEditor(QtCore.QObject):
self.pos = (self.pos[0], self.pos[1])
if event.button == 1:
self.app.ui.rel_position_label.setText("<b>Dx</b>: %.4f&nbsp;&nbsp; <b>Dy</b>: "
"%.4f&nbsp;&nbsp;&nbsp;&nbsp;" % (0, 0))
# self.app.ui.rel_position_label.setText("<b>Dx</b>: %.4f&nbsp;&nbsp; <b>Dy</b>: "
# "%.4f&nbsp;&nbsp;&nbsp;&nbsp;" % (0, 0))
# Selection with left mouse button
if self.active_tool is not None and event.button == 1:

View File

@ -4161,8 +4161,8 @@ class FlatCAMGeoEditor(QtCore.QObject):
self.pos = (self.pos[0], self.pos[1])
if event.button == 1:
self.app.ui.rel_position_label.setText("<b>Dx</b>: %.4f&nbsp;&nbsp; <b>Dy</b>: "
"%.4f&nbsp;&nbsp;&nbsp;&nbsp;" % (0, 0))
# self.app.ui.rel_position_label.setText("<b>Dx</b>: %.4f&nbsp;&nbsp; <b>Dy</b>: "
# "%.4f&nbsp;&nbsp;&nbsp;&nbsp;" % (0, 0))
modifiers = QtWidgets.QApplication.keyboardModifiers()
# If the SHIFT key is pressed when LMB is clicked then the coordinates are copied to clipboard

View File

@ -2095,7 +2095,7 @@ class GeometryObject(FlatCAMObj, Geometry):
def generatecncjob(self, outname=None, dia=None, offset=None, z_cut=None, z_move=None,
feedrate=None, feedrate_z=None, feedrate_rapid=None, spindlespeed=None, dwell=None, dwelltime=None,
multidepth=None, dpp=None, toolchange=None, toolchangez=None, toolchangexy=None,
extracut=None, extracut_length=None, startz=None, endz=None, pp=None, segx=None, segy=None,
extracut=None, extracut_length=None, startz=None, endz=None, endxy=None, pp=None, segx=None, segy=None,
use_thread=True, plot=True):
"""
Only used by the TCL Command Cncjob.
@ -2118,11 +2118,14 @@ class GeometryObject(FlatCAMObj, Geometry):
:param dpp: Depth for each pass when multidepth parameter is True
:param toolchange:
:param toolchangez:
:param toolchangexy:
:param toolchangexy: A sequence ox X,Y coordinates: a 2-length tuple or a string.
Coordinates in X,Y plane for the Toolchange event
:param extracut:
:param extracut_length:
:param startz:
:param endz:
:param endxy: A sequence ox X,Y coordinates: a 2-length tuple or a string.
Coordinates in X, Y plane for the last move after ending the job.
:param pp: Name of the preprocessor
:param segx:
:param segy:
@ -2152,10 +2155,21 @@ class GeometryObject(FlatCAMObj, Geometry):
startz = startz if startz is not None else self.options["startz"]
endz = endz if endz is not None else float(self.options["endz"])
endxy = self.options["endxy"]
endxy = endxy if endxy else self.options["endxy"]
if isinstance(endxy, str):
endxy = re.sub('[()\[\]]', '', endxy)
if endxy and endxy != '':
endxy = [float(eval(a)) for a in endxy.split(",")]
toolchangez = toolchangez if toolchangez else float(self.options["toolchangez"])
toolchangexy = toolchangexy if toolchangexy else self.options["toolchangexy"]
if isinstance(toolchangexy, str):
toolchangexy = re.sub('[()\[\]]', '', toolchangexy)
if toolchangexy and toolchangexy != '':
toolchangexy = [float(eval(a)) for a in toolchangexy.split(",")]
toolchange = toolchange if toolchange else self.options["toolchange"]
offset = offset if offset else 0.0

View File

@ -469,9 +469,9 @@ class Distance(FlatCAMTool):
# Reset here the relative coordinates so there is a new reference on the click position
if self.rel_point1 is None:
self.app.ui.rel_position_label.setText("<b>Dx</b>: %.*f&nbsp;&nbsp; <b>Dy</b>: "
"%.*f&nbsp;&nbsp;&nbsp;&nbsp;" %
(self.decimals, 0.0, self.decimals, 0.0))
# self.app.ui.rel_position_label.setText("<b>Dx</b>: %.*f&nbsp;&nbsp; <b>Dy</b>: "
# "%.*f&nbsp;&nbsp;&nbsp;&nbsp;" %
# (self.decimals, 0.0, self.decimals, 0.0))
self.rel_point1 = pos
else:
self.rel_point2 = copy(self.rel_point1)
@ -510,11 +510,11 @@ class Distance(FlatCAMTool):
pass
self.total_distance_entry.set_value('%.*f' % (self.decimals, abs(d)))
self.app.ui.rel_position_label.setText(
"<b>Dx</b>: {}&nbsp;&nbsp; <b>Dy</b>: {}&nbsp;&nbsp;&nbsp;&nbsp;".format(
'%.*f' % (self.decimals, pos[0]), '%.*f' % (self.decimals, pos[1])
)
)
# self.app.ui.rel_position_label.setText(
# "<b>Dx</b>: {}&nbsp;&nbsp; <b>Dy</b>: {}&nbsp;&nbsp;&nbsp;&nbsp;".format(
# '%.*f' % (self.decimals, pos[0]), '%.*f' % (self.decimals, pos[1])
# )
# )
self.tool_done = True
self.deactivate_measure_tool()
@ -562,11 +562,11 @@ class Distance(FlatCAMTool):
dx = pos[0]
dy = pos[1]
self.app.ui.rel_position_label.setText(
"<b>Dx</b>: {}&nbsp;&nbsp; <b>Dy</b>: {}&nbsp;&nbsp;&nbsp;&nbsp;".format(
'%.*f' % (self.decimals, dx), '%.*f' % (self.decimals, dy)
)
)
# self.app.ui.rel_position_label.setText(
# "<b>Dx</b>: {}&nbsp;&nbsp; <b>Dy</b>: {}&nbsp;&nbsp;&nbsp;&nbsp;".format(
# '%.*f' % (self.decimals, dx), '%.*f' % (self.decimals, dy)
# )
# )
# update utility geometry
if len(self.points) == 1:

View File

@ -37,9 +37,10 @@ class TclCommandCncjob(TclCommandSignaled):
('extracut_length', float),
('dpp', float),
('toolchangez', float),
('toolchangexy', tuple),
('toolchangexy', str),
('startz', float),
('endz', float),
('endxy', str),
('spindlespeed', int),
('dwelltime', float),
('pp', str),
@ -65,9 +66,12 @@ class TclCommandCncjob(TclCommandSignaled):
('dpp', 'If present then use multidepth cnc cut. Height of one layer for multidepth.'),
('toolchangez', 'Z distance for toolchange (example: 30.0).\n'
'If used in the command then a toolchange event will be included in gcode'),
('toolchangexy', 'X, Y coordonates for toolchange in format (x, y) (example: (2.0, 3.1) ).'),
('toolchangexy', 'The X,Y coordinates at Toolchange event in format (x, y) (example: (30.0, 15.2) or '
'without parenthesis like: 0.3,1.0). WARNING: no spaces allowed in the value.'),
('startz', 'Height before the first move.'),
('endz', 'Height where the last move will park.'),
('endxy', 'The X,Y coordinates at job end in format (x, y) (example: (2.0, 1.2) or without parenthesis'
'like: 0.3,1.0). WARNING: no spaces allowed in the value.'),
('spindlespeed', 'Speed of the spindle in rpm (example: 4000).'),
('dwelltime', 'Time to pause to allow the spindle to reach the full speed.\n'
'If it is not used in command then it will not be included'),
@ -161,6 +165,17 @@ class TclCommandCncjob(TclCommandSignaled):
self.app.defaults["geometry_startz"]
args["endz"] = args["endz"] if "endz" in args and args["endz"] else self.app.defaults["geometry_endz"]
if "endxy" in args and args["endxy"]:
args["endxy"] = args["endxy"]
else:
if self.app.defaults["geometry_endxy"]:
args["endxy"] = self.app.defaults["geometry_endxy"]
else:
args["endxy"] = '0, 0'
if len(eval(args["endxy"])) != 2:
self.raise_tcl_error("The entered value for 'endxy' needs to have the format x,y or "
"in format (x, y) - no spaces allowed. But always two comma separated values.")
args["spindlespeed"] = args["spindlespeed"] if "spindlespeed" in args and args["spindlespeed"] != 0 else None
if 'dwelltime' in args:
@ -180,13 +195,21 @@ class TclCommandCncjob(TclCommandSignaled):
if args["toolchangez"] is not None:
args["toolchangez"] = args["toolchangez"]
else:
args["toolchangez"] = obj.options["toolchangez"]
args["toolchangez"] = self.app.defaults["geometry_toolchangez"]
else:
args["toolchange"] = self.app.defaults["geometry_toolchange"]
args["toolchangez"] = self.app.defaults["geometry_toolchangez"]
args["toolchangexy"] = args["toolchangexy"] if "toolchangexy" in args and args["toolchangexy"] else \
self.app.defaults["geometry_toolchangexy"]
if "toolchangexy" in args and args["toolchangexy"]:
args["toolchangexy"] = args["toolchangexy"]
else:
if self.app.defaults["geometry_toolchangexy"]:
args["toolchangexy"] = self.app.defaults["geometry_toolchangexy"]
else:
args["toolchangexy"] = '0, 0'
if len(eval(args["toolchangexy"])) != 2:
self.raise_tcl_error("The entered value for 'toolchangexy' needs to have the format x,y or "
"in format (x, y) - no spaces allowed. But always two comma separated values.")
del args['name']
@ -195,7 +218,7 @@ class TclCommandCncjob(TclCommandSignaled):
continue
else:
if args[arg] is None:
print(arg, args[arg])
print("None parameters: %s is None" % arg)
if muted is False:
self.raise_tcl_error('One of the command parameters that have to be not None, is None.\n'
'The parameter that is None is in the default values found in the list \n'
@ -234,6 +257,7 @@ class TclCommandCncjob(TclCommandSignaled):
local_tools_dict[tool_uid]['data']['toolchangexy'] = args["toolchangexy"]
local_tools_dict[tool_uid]['data']['startz'] = args["startz"]
local_tools_dict[tool_uid]['data']['endz'] = args["endz"]
local_tools_dict[tool_uid]['data']['endxy'] = args["endxy"]
local_tools_dict[tool_uid]['data']['spindlespeed'] = args["spindlespeed"]
local_tools_dict[tool_uid]['data']['dwell'] = args["dwell"]
local_tools_dict[tool_uid]['data']['dwelltime'] = args["dwelltime"]

View File

@ -54,8 +54,8 @@ class TclCommandCopperClear(TclCommand):
'main': "Clear excess copper in polygons. Basically it's a negative Paint.",
'args': collections.OrderedDict([
('name', 'Name of the source Geometry object. String.'),
('tooldia', 'Diameter of the tool to be used. Can be a comma separated list of diameters. No space is '
'allowed between tool diameters. E.g: correct: 0.5,1 / incorrect: 0.5, 1'),
('tooldia', 'Diameter of the tool to be used. Can be a comma separated list of diameters.\n'
'WARNING: No space is allowed between tool diameters. E.g: correct: 0.5,1 / incorrect: 0.5, 1'),
('overlap', 'Percentage of tool diameter to overlap current pass over previous pass. Float [0, 99.9999]\n'
'E.g: for a 25% from tool diameter overlap use -overlap 25'),
('margin', 'Bounding box margin. Float number.'),
@ -72,7 +72,7 @@ class TclCommandCopperClear(TclCommand):
('all', 'If used will copper clear the whole object. Either "-all" or "-box <value>" has to be used.'),
('box', 'Name of the object to be used as reference. Either "-all" or "-box <value>" has to be used. '
'String.'),
('outname', 'Name of the resulting Geometry object. String.'),
('outname', 'Name of the resulting Geometry object. String. No spaces.'),
]),
'examples': ["ncc obj_name -tooldia 0.3,1 -overlap 10 -margin 1.0 -method 'lines' -all"]
}

View File

@ -37,10 +37,10 @@ class TclCommandDrillcncjob(TclCommandSignaled):
('feedrate_rapid', float),
('spindlespeed', int),
('toolchangez', float),
('toolchangexy', tuple),
('toolchangexy', str),
('startz', float),
('endz', float),
('endxy', tuple),
('endxy', str),
('dwelltime', float),
('pp', str),
('opt_type', str),
@ -59,7 +59,7 @@ class TclCommandDrillcncjob(TclCommandSignaled):
('name', 'Name of the source object.'),
('drilled_dias',
'Comma separated tool diameters of the drills to be drilled (example: 0.6,1.0 or 3.125). '
'No space allowed'),
'WARNING: No space allowed'),
('drillz', 'Drill depth into material (example: -2.0). Negative value.'),
('dpp', 'Progressive drilling into material with a specified step (example: 0.7). Positive value.'),
('travelz', 'Travel distance above material (example: 2.0).'),
@ -68,10 +68,12 @@ class TclCommandDrillcncjob(TclCommandSignaled):
('spindlespeed', 'Speed of the spindle in rpm (example: 4000).'),
('toolchangez', 'Z distance for toolchange (example: 30.0).\n'
'If used in the command then a toolchange event will be included in gcode'),
('toolchangexy', 'X, Y coordonates for toolchange in format (x, y) (example: (2.0, 3.1) ).'),
('toolchangexy', 'The X,Y coordinates at Toolchange event in format (x, y) (example: (30.0, 15.2) or '
'without parenthesis like: 0.3,1.0). WARNING: no spaces allowed in the value.'),
('startz', 'The Z coordinate at job start (example: 30.0).'),
('endz', 'The Z coordinate at job end (example: 30.0).'),
('endxy', 'The X,Y coordinates at job end in format (x, y) (example: (30.0, 15.2)).'),
('endxy', 'The X,Y coordinates at job end in format (x, y) (example: (2.0, 1.2) or without parenthesis'
'like: 0.3,1.0). WARNING: no spaces allowed in the value.'),
('dwelltime', 'Time to pause to allow the spindle to reach the full speed.\n'
'If it is not used in command then it will not be included'),
('pp', 'This is the Excellon preprocessor name: case_sensitive, no_quotes'),
@ -230,20 +232,30 @@ class TclCommandDrillcncjob(TclCommandSignaled):
toolchange = self.app.defaults["excellon_toolchange"]
toolchangez = float(self.app.defaults["excellon_toolchangez"])
xy_toolchange = args["toolchangexy"] if "toolchangexy" in args and args["toolchangexy"] else \
self.app.defaults["excellon_toolchangexy"]
xy_toolchange = ','.join([xy_toolchange[0], xy_toolchange[2]])
if "toolchangexy" in args and args["toolchangexy"]:
xy_toolchange = args["toolchangexy"]
else:
if self.app.defaults["excellon_toolchangexy"]:
xy_toolchange = self.app.defaults["excellon_toolchangexy"]
else:
xy_toolchange = '0, 0'
if len(eval(xy_toolchange)) != 2:
self.raise_tcl_error("The entered value for 'toolchangexy' needs to have the format x,y or "
"in format (x, y) - no spaces allowed. But always two comma separated values.")
endz = args["endz"] if "endz" in args and args["endz"] is not None else self.app.defaults["excellon_endz"]
if "endxy" in args and args["endxy"]:
xy_end = args["endxy"]
else:
if self.app.defaults["excellon_endxy"]:
xy_end = self.app.defaults["excellon_endxy"]
else:
xy_end = (0, 0)
xy_end = '0, 0'
xy_end = ','.join([xy_end[0], xy_end[2]])
if len(eval(xy_end)) != 2:
self.raise_tcl_error("The entered value for 'xy_end' needs to have the format x,y or "
"in format (x, y) - no spaces allowed. But always two comma separated values.")
opt_type = args["opt_type"] if "opt_type" in args and args["opt_type"] else 'B'

View File

@ -43,8 +43,6 @@ class TclCommandPaint(TclCommand):
('single', str),
('ref', str),
('box', str),
('x', float),
('y', float),
('outname', str),
])
@ -53,30 +51,32 @@ class TclCommandPaint(TclCommand):
# structured help for current command, args needs to be ordered
help = {
'main': "Paint polygons in the specified object by covering them with toolpaths.",
'main': "Paint polygons in the specified object by covering them with toolpaths.\n"
"Can use only one of the parameters: 'all', 'box', 'single'.",
'args': collections.OrderedDict([
('name', 'Name of the source Geometry object. String.'),
('tooldia', 'Diameter of the tool to be used. Can be a comma separated list of diameters. No space is '
'allowed between tool diameters. E.g: correct: 0.5,1 / incorrect: 0.5, 1'),
('tooldia', 'Diameter of the tools to be used. Can be a comma separated list of diameters.\n'
'WARNING: No space is allowed between tool diameters. E.g: correct: 0.5,1 / incorrect: 0.5, 1'),
('overlap', 'Percentage of tool diameter to overlap current pass over previous pass. Float [0, 99.9999]\n'
'E.g: for a 25% from tool diameter overlap use -overlap 25'),
('margin', 'Bounding box margin. Float number.'),
('order', 'Can have the values: "no", "fwd" and "rev". String.'
'It is useful when there are multiple tools in tooldia parameter.'
'"no" -> the order used is the one provided.'
'"fwd" -> tools are ordered from smallest to biggest.'
('order', 'Can have the values: "no", "fwd" and "rev". String.\n'
'It is useful when there are multiple tools in tooldia parameter.\n'
'"no" -> the order used is the one provided.\n'
'"fwd" -> tools are ordered from smallest to biggest.\n'
'"rev" -> tools are ordered from biggest to smallest.'),
('method', 'Algorithm for painting. Can be: "standard", "seed", "lines", "laser_lines", "combo".'),
('connect', 'Draw lines to minimize tool lifts. True (1) or False (0)'),
('contour', 'Cut around the perimeter of the painting. True (1) or False (0)'),
('all', 'If used, paint all polygons in the object.'),
('box', 'name of the object to be used as paint reference. String.'),
('single', 'Paint a single polygon specified by "x" and "y" parameters. True (1) or False (0)'),
('x', 'X value of coordinate for the selection of a single polygon. Float number.'),
('y', 'Y value of coordinate for the selection of a single polygon. Float number.'),
('outname', 'Name of the resulting Geometry object. String.'),
('single', 'Value is in format x,y or (x,y). Example: 2.0,1.1\n'
'If used will paint a single polygon specified by "x" and "y" values.\n'
'WARNING: No spaces allowed in the value. Use dot decimals separator.'),
('outname', 'Name of the resulting Geometry object. String. No spaces.'),
]),
'examples': ["paint obj_name -tooldia 0.3 -margin 0.1 -method 'seed' -all"]
'examples': ["paint obj_name -tooldia 0.3 -margin 0.1 -method 'seed' -all",
"paint obj_name -tooldia 0.3 -margin 0.1 -method 'seed' -single 3.3,2.0"]
}
def execute(self, args, unnamed_args):
@ -245,11 +245,17 @@ class TclCommandPaint(TclCommand):
# Paint single polygon in the painted object
if 'single' in args:
if 'x' not in args and 'y' not in args:
self.raise_tcl_error('%s' % _("Expected -x <value> and -y <value>."))
if not args['single'] or args['single'] == '':
self.raise_tcl_error('%s Got: %s' %
(_("Expected a tuple value like -single 3.2,0.1."), str(args['single'])))
else:
x = args['x']
y = args['y']
coords_xy = [float(eval(a)) for a in args['single'].split(",") if a != '']
if coords_xy and len(coords_xy) != 2:
self.raise_tcl_error('%s Got: %s' %
(_("Expected a tuple value like -single 3.2,0.1."), str(coords_xy)))
x = coords_xy[0]
y = coords_xy[1]
self.app.paint_tool.paint_poly(obj=obj,
inside_pt=[x, y],