diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 21aad659..3821dd84 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -1035,15 +1035,15 @@ class App(QtCore.QObject): 'Toolchange_Probe_MACH3, ' 'Toolchange_manual, Users, all, axis, auto, axisoffset, ' 'box, center_x, center_y, columns, combine, connect, contour, default, ' - 'depthperpass, dia, diatol, dist, drilled_dias, drillz, dwelltime, ' - 'extracut_length, f, ' + 'depthperpass, dia, diatol, dist, drilled_dias, drillz, dpp, dwelltime, ' + 'endxy, endz, extracut_length, f, feedrate, ' 'feedrate_z, grbl_11, GRBL_laser, gridoffsety, gridx, gridy, has_offset, ' 'holes, hpgl, iso_type, line_xyz, margin, marlin, method, milled_dias, ' 'minoffset, name, offset, opt_type, order, outname, overlap, ' 'passes, postamble, pp, ppname_e, ppname_g, preamble, radius, ref, rest, ' 'rows, shellvar_, scale_factor, spacing_columns, spacing_rows, spindlespeed, ' - 'toolchange_xy, toolchangez, ' - 'tooldia, use_threads, value, x, x0, x1, y, y0, y1, z_cut, ' + 'startz, startxy, toolchange_xy, toolchangez, ' + 'tooldia, travelz, use_threads, value, x, x0, x1, y, y0, y1, z_cut, ' 'z_move', "script_autocompleter": True, "script_text": "", @@ -2331,15 +2331,16 @@ class App(QtCore.QObject): 'all', 'auto', 'axis', 'axisoffset', 'box', 'center_x', 'center_y', 'columns', 'combine', 'connect', 'contour', 'default', - 'depthperpass', 'dia', 'diatol', 'dist', 'drilled_dias', 'drillz', - 'dwelltime', 'extracut_length', 'f', + 'depthperpass', 'dia', 'diatol', 'dist', 'drilled_dias', 'drillz', 'dpp', + 'dwelltime', 'extracut_length', 'endxy', 'enz', 'f', 'feedrate', 'feedrate_z', 'grbl_11', 'GRBL_laser', 'gridoffsety', 'gridx', 'gridy', 'has_offset', 'holes', 'hpgl', 'iso_type', 'line_xyz', 'margin', 'marlin', 'method', 'milled_dias', 'minoffset', 'name', 'offset', 'opt_type', 'order', 'outname', 'overlap', 'passes', 'postamble', 'pp', 'ppname_e', 'ppname_g', 'preamble', 'radius', 'ref', 'rest', 'rows', 'shellvar_', 'scale_factor', 'spacing_columns', - 'spacing_rows', 'spindlespeed', 'toolchange_xy', 'toolchangez', + 'spacing_rows', 'spindlespeed', 'startz', 'startxy', + 'toolchange_xy', 'toolchangez', 'travelz', 'tooldia', 'use_threads', 'value', 'x', 'x0', 'x1', 'y', 'y0', 'y1', 'z_cut', 'z_move' ] diff --git a/FlatCAMObj.py b/FlatCAMObj.py index a8b388bf..0256853a 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -3725,8 +3725,6 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): job_obj.options['type'] = 'Excellon' job_obj.options['ppname_e'] = pp_excellon_name - job_obj.z_cut = float(self.options["cutz"]) - job_obj.multidepth = self.options["multidepth"] job_obj.z_depthpercut = self.options["depthperpass"] diff --git a/README.md b/README.md index 4996be13..4c787ef8 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,8 @@ CAD program, and create G-Code for Isolation routing. - minor update to the autocomplete dictionary - the Show Shell in Edit -> Preferences will now toggle the Tcl shell based on the current status of the Tcl Shell - updated the Tcl command Isolate help for follow parameter +- updated DrillCncJob Tcl Command with new parameters and fixed it to work in the new format of the Excellon methods +- changed CncJob Tcl Command parameter 'depthperpass' to a shorter 'dpp' 11.04.2020 diff --git a/camlib.py b/camlib.py index bb192a4b..40d84cc0 100644 --- a/camlib.py +++ b/camlib.py @@ -2742,9 +2742,12 @@ class CNCjob(Geometry): LineString([start, stop]).buffer((it[1] / 2.0), resolution=self.geo_steps_per_circle) ) - try: - z_off = float(exobj.tools[it[0]]['data']['offset']) * (-1) - except KeyError: + if self.use_ui: + try: + z_off = float(exobj.tools[it[0]]['data']['offset']) * (-1) + except KeyError: + z_off = 0 + else: z_off = 0 default_data = {} @@ -2790,7 +2793,7 @@ class CNCjob(Geometry): # Initialization gcode = self.doformat(p.start_code) - if not use_ui: + if use_ui is False: gcode += self.doformat(p.z_feedrate_code) if self.toolchange is False: @@ -2873,7 +2876,7 @@ class CNCjob(Geometry): self.postdata['toolC'] = exobj.tools[tool]["C"] self.tooldia = exobj.tools[tool]["C"] - if use_ui: + if self.use_ui: self.z_feedrate = exobj.tools[tool]['data']['feedrate_z'] self.feedrate = exobj.tools[tool]['data']['feedrate'] gcode += self.doformat(p.z_feedrate_code) @@ -2906,6 +2909,8 @@ class CNCjob(Geometry): self.dwelltime = exobj.tools[tool]['data']['dwelltime'] self.multidepth = exobj.tools[tool]['data']['multidepth'] self.z_depthpercut = exobj.tools[tool]['data']['depthperpass'] + else: + old_zcut = deepcopy(self.z_cut) # ############################################### # ############ Create the data. ################# @@ -3000,8 +3005,10 @@ class CNCjob(Geometry): str(self.units)) ) - # TODO apply offset only when using the GUI, for TclCommand this will create an error + # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + # APPLY Offset only when using the GUI, for TclCommand this will create an error # because the values for Z offset are created in build_ui() + # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! try: z_offset = float(exobj.tools[tool]['data']['offset']) * (-1) except KeyError: @@ -3099,7 +3106,7 @@ class CNCjob(Geometry): self.postdata['toolC']=exobj.tools[tool]["C"] self.tooldia = exobj.tools[tool]["C"] - if use_ui: + if self.use_ui: self.z_feedrate = exobj.tools[tool]['data']['feedrate_z'] self.feedrate = exobj.tools[tool]['data']['feedrate'] gcode += self.doformat(p.z_feedrate_code) @@ -3132,6 +3139,8 @@ class CNCjob(Geometry): self.dwelltime = exobj.tools[tool]['data']['dwelltime'] self.multidepth = exobj.tools[tool]['data']['multidepth'] self.z_depthpercut = exobj.tools[tool]['data']['depthperpass'] + else: + old_zcut = deepcopy(self.z_cut) # ############################################### # ############ Create the data. ################# @@ -3215,8 +3224,10 @@ class CNCjob(Geometry): str(self.units)) ) - # TODO apply offset only when using the GUI, for TclCommand this will create an error + # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + # APPLY Offset only when using the GUI, for TclCommand this will create an error # because the values for Z offset are created in build_ui() + # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! try: z_offset = float(exobj.tools[tool]['data']['offset']) * (-1) except KeyError: @@ -3316,7 +3327,7 @@ class CNCjob(Geometry): self.postdata['toolC'] = exobj.tools[tool]["C"] self.tooldia = exobj.tools[tool]["C"] - if use_ui: + if self.use_ui: self.z_feedrate = exobj.tools[tool]['data']['feedrate_z'] self.feedrate = exobj.tools[tool]['data']['feedrate'] gcode += self.doformat(p.z_feedrate_code) @@ -3349,6 +3360,8 @@ class CNCjob(Geometry): self.dwelltime = exobj.tools[tool]['data']['dwelltime'] self.multidepth = exobj.tools[tool]['data']['multidepth'] self.z_depthpercut = exobj.tools[tool]['data']['depthperpass'] + else: + old_zcut = deepcopy(self.z_cut) # Only if tool has points. if tool in points: @@ -3375,8 +3388,10 @@ class CNCjob(Geometry): str(self.units)) ) - # TODO apply offset only when using the GUI, for TclCommand this will create an error + # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + # APPLY Offset only when using the GUI, for TclCommand this will create an error # because the values for Z offset are created in build_ui() + # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! try: z_offset = float(exobj.tools[tool]['data']['offset']) * (-1) except KeyError: diff --git a/tclCommands/TclCommandCncjob.py b/tclCommands/TclCommandCncjob.py index 70bfbcbc..6f41e1df 100644 --- a/tclCommands/TclCommandCncjob.py +++ b/tclCommands/TclCommandCncjob.py @@ -36,7 +36,7 @@ class TclCommandCncjob(TclCommandSignaled): ('feedrate_z', float), ('feedrate_rapid', float), ('extracut_length', float), - ('depthperpass', float), + ('dpp', float), ('toolchangez', float), ('toolchangexy', tuple), ('startz', float), @@ -63,7 +63,7 @@ class TclCommandCncjob(TclCommandSignaled): ('feedrate_z', 'Moving speed on Z plane when cutting.'), ('feedrate_rapid', 'Rapid moving at speed when cutting.'), ('extracut_length', 'The value for extra cnccut over the first point in path,in the job end; float'), - ('depthperpass', 'If present then use multidepth cnc cut. Height of one layer for multidepth.'), + ('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) ).'), @@ -141,12 +141,12 @@ class TclCommandCncjob(TclCommandSignaled): else: args["extracut"] = False - if "depthperpass" in args: + if "dpp" in args: args["multidepth"] = True - if args["depthperpass"] is None: - args["depthperpass"] = obj.options["depthperpass"] + if args["dpp"] is None: + args["dpp"] = obj.options["dpp"] else: - args["depthperpass"] = float(args["depthperpass"]) + args["dpp"] = float(args["dpp"]) else: args["multidepth"] = False @@ -221,7 +221,7 @@ class TclCommandCncjob(TclCommandSignaled): else: local_tools_dict[tool_uid]['data']['extracut_length'] = None - local_tools_dict[tool_uid]['data']['depthperpass'] = args["depthperpass"] + local_tools_dict[tool_uid]['data']['depthperpass'] = args["dpp"] local_tools_dict[tool_uid]['data']['toolchange'] = args["toolchange"] local_tools_dict[tool_uid]['data']['toolchangez'] = args["toolchangez"] local_tools_dict[tool_uid]['data']['toolchangexy'] = args["toolchangexy"] diff --git a/tclCommands/TclCommandDrillcncjob.py b/tclCommands/TclCommandDrillcncjob.py index e0fd5dae..d2f31021 100644 --- a/tclCommands/TclCommandDrillcncjob.py +++ b/tclCommands/TclCommandDrillcncjob.py @@ -4,6 +4,14 @@ from FlatCAMObj import FlatCAMExcellon import collections import math +import gettext +import FlatCAMTranslation as fcTranslate +import builtins + +fcTranslate.apply_language('strings') +if '_' not in builtins.__dict__: + _ = gettext.gettext + class TclCommandDrillcncjob(TclCommandSignaled): """ @@ -24,13 +32,16 @@ class TclCommandDrillcncjob(TclCommandSignaled): option_types = collections.OrderedDict([ ('drilled_dias', str), ('drillz', float), + ('dpp', float), ('travelz', float), - ('feedrate', float), + ('feedrate_z', float), ('feedrate_rapid', float), ('spindlespeed', int), ('toolchangez', float), ('toolchangexy', tuple), + ('startz', float), ('endz', float), + ('endxy', tuple), ('dwelltime', float), ('pp', str), ('opt_type', str), @@ -50,15 +61,18 @@ class TclCommandDrillcncjob(TclCommandSignaled): ('drilled_dias', 'Comma separated tool diameters of the drills to be drilled (example: 0.6,1.0 or 3.125). ' 'No space allowed'), - ('drillz', 'Drill depth into material (example: -2.0).'), + ('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).'), - ('feedrate', 'Drilling feed rate.'), + ('feedrate_z', 'Drilling feed rate. It is the speed on the Z axis.'), ('feedrate_rapid', 'Rapid drilling feed rate.'), ('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) ).'), - ('endz', 'Z distance at job end (example: 30.0).'), + ('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)).'), ('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'), @@ -73,9 +87,10 @@ class TclCommandDrillcncjob(TclCommandSignaled): ('muted', 'It will not put errors in the Shell or status bar. Can be True (1) or False (0).'), ('outname', 'Name of the resulting Geometry object.') ]), - 'examples': ['drillcncjob test.TXT -drillz -1.5 -travelz 14 -feedrate 222 -feedrate_rapid 456 -spindlespeed 777' - ' -toolchangez 33 -endz 22 -pp default\n' - 'Usage of -feedrate_rapid matter only when the preprocessor is using it, like -marlin-.'] + 'examples': ['drillcncjob test.TXT -drillz -1.5 -travelz 14 -feedrate_z 222 -feedrate_rapid 456 ' + '-spindlespeed 777 -toolchangez 33 -endz 22 -pp default\n' + 'Usage of -feedrate_rapid matter only when the preprocessor is using it, like -marlin-.', + 'drillcncjob test.DRL -drillz -1.7 -dpp 0.5 -travelz 2 -feedrate_z 800 -endxy 3,3'] } def execute(self, args, unnamed_args): @@ -171,6 +186,35 @@ class TclCommandDrillcncjob(TclCommandSignaled): else: return "fail" + used_tools_info = [] + used_tools_info.insert(0, [_("Tool_nr"), _("Diameter"), _("Drills_Nr"), _("Slots_Nr")]) + + # populate the information's list for used tools + if tools == 'all': + sort = [] + for k, v in list(obj.tools.items()): + sort.append((k, v.get('C'))) + sorted_tools = sorted(sort, key=lambda t1: t1[1]) + use_tools = [i[0] for i in sorted_tools] + + for tool_no in use_tools: + tool_dia_used = obj.tools[tool_no]['C'] + + drill_cnt = 0 # variable to store the nr of drills per tool + slot_cnt = 0 # variable to store the nr of slots per tool + + # Find no of drills for the current tool + for drill in obj.drills: + if drill['tool'] == tool_no: + drill_cnt += 1 + + # Find no of slots for the current tool + for slot in obj.slots: + if slot['tool'] == tool_no: + slot_cnt += 1 + + used_tools_info.append([str(tool_no), str(tool_dia_used), str(drill_cnt), str(slot_cnt)]) + drillz = args["drillz"] if "drillz" in args and args["drillz"] is not None else obj.options["cutz"] if "toolchangez" in args: @@ -183,17 +227,48 @@ class TclCommandDrillcncjob(TclCommandSignaled): toolchange = False toolchangez = 0.0 + xy_toolchange = args["toolchangexy"] if "toolchangexy" in args and args["toolchangexy"] else \ + obj.options["toolchangexy"] + xy_toolchange = ','.join([xy_toolchange[0], xy_toolchange[2]]) + endz = args["endz"] if "endz" in args and args["endz"] is not None else obj.options["endz"] + xy_end = args["endxy"] if "endxy" in args and args["endxy"] else '0,0' + xy_end = ','.join([xy_end[0], xy_end[2]]) + print(xy_end) opt_type = args["opt_type"] if "opt_type" in args and args["opt_type"] else 'B' - job_obj.z_move = args["travelz"] if "travelz" in args and args["travelz"] else obj.options["travelz"] + # ########################################################################################## + # ################# Set parameters ######################################################### + # ########################################################################################## + job_obj.origin_kind = 'excellon' - job_obj.feedrate = args["feedrate"] if "feedrate" in args and args["feedrate"] else obj.options["feedrate"] - job_obj.z_feedrate = args["feedrate"] if "feedrate" in args and args["feedrate"] else \ - obj.options["feedrate"] - job_obj.feedrate_rapid = args["feedrate_rapid"] \ + job_obj.options['Tools_in_use'] = used_tools_info + job_obj.options['type'] = 'Excellon' + + pp_excellon_name = args["pp"] if "pp" in args and args["pp"] else obj.options["ppname_e"] + job_obj.pp_excellon_name = pp_excellon_name + job_obj.options['ppname_e'] = pp_excellon_name + + if 'dpp' in args: + job_obj.multidepth = True + if args['dpp'] is not None: + job_obj.z_depthpercut = float(args['dpp']) + else: + job_obj.z_depthpercut = float(obj.options["dpp"]) + else: + job_obj.multidepth = False + job_obj.z_depthpercut = 0.0 + + job_obj.z_move = float(args["travelz"]) if "travelz" in args and args["travelz"] else obj.options["travelz"] + job_obj.feedrate = float(args["feedrate_z"]) if "feedrate_z" in args and args["feedrate_z"] else \ + obj.options["feedrate_z"] + job_obj.z_feedrate = float(args["feedrate_z"]) if "feedrate_z" in args and args["feedrate_z"] else \ + obj.options["feedrate_z"] + job_obj.feedrate_rapid = float(args["feedrate_rapid"]) \ if "feedrate_rapid" in args and args["feedrate_rapid"] else obj.options["feedrate_rapid"] + job_obj.spindlespeed = float(args["spindlespeed"]) if "spindlespeed" in args else None + job_obj.spindledir = self.app.defaults['excellon_spindledir'] if 'dwelltime' in args: job_obj.dwell = True if args['dwelltime'] is not None: @@ -204,35 +279,34 @@ class TclCommandDrillcncjob(TclCommandSignaled): job_obj.dwell = False job_obj.dwelltime = 0.0 - job_obj.spindlespeed = args["spindlespeed"] if "spindlespeed" in args else None - job_obj.pp_excellon_name = args["pp"] if "pp" in args and args["pp"] \ - else obj.options["ppname_e"] - + job_obj.toolchange_xy_type = "excellon" job_obj.coords_decimals = int(self.app.defaults["cncjob_coords_decimals"]) job_obj.fr_decimals = int(self.app.defaults["cncjob_fr_decimals"]) - job_obj.options['type'] = 'Excellon' - - job_obj.toolchangexy = args["toolchangexy"] if "toolchangexy" in args and args["toolchangexy"] else \ - obj.options["toolchangexy"] - - job_obj.toolchange_xy_type = "excellon" - job_obj.options['xmin'] = xmin job_obj.options['ymin'] = ymin job_obj.options['xmax'] = xmax job_obj.options['ymax'] = ymax - job_obj.generate_from_excellon_by_tool(obj, tools, drillz=drillz, toolchangez=toolchangez, endz=endz, - toolchange=toolchange, excellon_optimization_type=opt_type) + job_obj.z_cut = float(drillz) + job_obj.toolchange = toolchange + job_obj.xy_toolchange = xy_toolchange + job_obj.z_toolchange = float(toolchangez) + job_obj.startz = float(args["startz"]) if "endz" in args and args["endz"] is not None else (0, 0) + job_obj.endz = float(endz) + job_obj.xy_end = xy_end + job_obj.excellon_optimization_type = opt_type + + ret_val = job_obj.generate_from_excellon_by_tool(obj, tools, use_ui=False) + + if ret_val == 'fail': + return 'fail' for t_item in job_obj.exc_cnc_tools: job_obj.exc_cnc_tools[t_item]['data']['offset'] = \ float(job_obj.exc_cnc_tools[t_item]['offset_z']) + float(drillz) job_obj.exc_cnc_tools[t_item]['data']['ppname_e'] = obj.options['ppname_e'] - job_obj.origin_kind = 'excellon' - job_obj.gcode_parse() job_obj.create_geometry()