diff --git a/CHANGELOG.md b/CHANGELOG.md index ad909e0c..823be59e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ CHANGELOG for FlatCAM beta 22.04.2020 - added a new feature, project auto-saving controlled from Edit -> Preferences -> General -> APP. Preferences -> Enable Auto Save checkbox +- fixed some bugs in the Tcl Commands +- modified the Tcl Commands to be able to use as boolean values keywords with lower case like 'false' instead of expected 'False' 20.04.2020 diff --git a/tclCommands/TclCommandBbox.py b/tclCommands/TclCommandBbox.py index dd6ab627..ada78b4f 100644 --- a/tclCommands/TclCommandBbox.py +++ b/tclCommands/TclCommandBbox.py @@ -79,9 +79,14 @@ class TclCommandBbox(TclCommand): args['margin'] = float(self.app.defaults["gerber_bboxmargin"]) margin = args['margin'] - if 'rounded' not in args: - args['rounded'] = bool(eval(self.app.defaults["gerber_bboxrounded"])) - rounded = bool(eval(args['rounded'])) + if 'rounded' in args: + try: + par = args['rounded'].capitalize() + except AttributeError: + par = args['rounded'] + rounded = bool(eval(par)) + else: + rounded = bool(eval(self.app.defaults["gerber_bboxrounded"])) del args['name'] diff --git a/tclCommands/TclCommandCncjob.py b/tclCommands/TclCommandCncjob.py index 6f41e1df..0c897654 100644 --- a/tclCommands/TclCommandCncjob.py +++ b/tclCommands/TclCommandCncjob.py @@ -92,7 +92,11 @@ class TclCommandCncjob(TclCommandSignaled): name = '' if 'muted' in args: - muted = bool(eval(args['muted'])) + try: + par = args['muted'].capitalize() + except AttributeError: + par = args['muted'] + muted = bool(eval(par)) else: muted = False diff --git a/tclCommands/TclCommandCopperClear.py b/tclCommands/TclCommandCopperClear.py index 62eeb19e..29c73cd5 100644 --- a/tclCommands/TclCommandCopperClear.py +++ b/tclCommands/TclCommandCopperClear.py @@ -38,7 +38,6 @@ class TclCommandCopperClear(TclCommand): ('method', str), ('connect', str), ('contour', str), - ('has_offset', str), ('offset', float), ('rest', str), ('all', int), @@ -69,15 +68,13 @@ class TclCommandCopperClear(TclCommand): ('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)'), ('rest', 'Use rest-machining. True (1) or False (0)'), - ('has_offset', 'The offset will used only if this is set True or present in args. True (1) or False (0).'), - ('offset', 'The copper clearing will finish to a distance from copper features. Float number.'), - ('all', 'Will copper clear the whole object. 1 or True = enabled, anything else = disabled'), - ('ref', 'Will clear of extra copper all polygons within a specified object with the name in "box" ' - 'parameter. 1 or True = enabled, 0 or False = disabled'), - ('box', 'Name of the object to be used as reference. Required when selecting "ref" = 1 or True. String.'), + ('offset', 'If used, the copper clearing will finish to a distance from copper features. Float number.'), + ('all', 'If used will copper clear the whole object. Either "-all" or "-box " has to be used.'), + ('box', 'Name of the object to be used as reference. Either "-all" or "-box " has to be used. ' + 'String.'), ('outname', 'Name of the resulting Geometry object. String.'), ]), - 'examples': ["ncc obj_name -tooldia 0.3,1 -overlap 10 -margin 1.0 -method 'lines' -all True"] + 'examples': ["ncc obj_name -tooldia 0.3,1 -overlap 10 -margin 1.0 -method 'lines' -all"] } def execute(self, args, unnamed_args): @@ -129,24 +126,27 @@ class TclCommandCopperClear(TclCommand): method = str(self.app.defaults["tools_nccmethod"]) if 'connect' in args: - connect = bool(eval(args['connect'])) + try: + par = args['connect'].capitalize() + except AttributeError: + par = args['connect'] + connect = bool(eval(par)) else: connect = bool(eval(str(self.app.defaults["tools_nccconnect"]))) if 'contour' in args: - contour = bool(eval(args['contour'])) + try: + par = args['contour'].capitalize() + except AttributeError: + par = args['contour'] + contour = bool(eval(par)) else: contour = bool(eval(str(self.app.defaults["tools_ncccontour"]))) offset = 0.0 - if 'has_offset' in args: - has_offset = bool(eval(args['has_offset'])) - if args['has_offset'] is True: - if 'offset' in args: - offset = float(args['margin']) - else: - # 'offset' has to be in args if 'has_offset' is and it is set True - self.raise_tcl_error("%s: %s" % (_("Could not retrieve object"), name)) + if 'offset' in args: + offset = float(args['offset']) + has_offset = True else: has_offset = False @@ -208,7 +208,11 @@ class TclCommandCopperClear(TclCommand): }) if 'rest' in args: - rest = bool(eval(args['rest'])) + try: + par = args['rest'].capitalize() + except AttributeError: + par = args['rest'] + rest = bool(eval(par)) else: rest = bool(eval(str(self.app.defaults["tools_nccrest"]))) @@ -221,7 +225,7 @@ class TclCommandCopperClear(TclCommand): outname = name + "_ncc_rm" # Non-Copper clear all polygons in the non-copper clear object - if 'all' in args and bool(args['all']): + if 'all' in args: self.app.ncclear_tool.clear_copper_tcl(ncc_obj=obj, select_method='itself', ncctooldia=tooldia, @@ -241,40 +245,36 @@ class TclCommandCopperClear(TclCommand): return # Non-Copper clear all polygons found within the box object from the the non_copper cleared object - elif 'ref' in args and bool(eval(args['ref'])): - if 'box' not in args: - self.raise_tcl_error('%s' % _("Expected -box .")) - else: - box_name = args['box'] + if 'box' in args: + box_name = args['box'] - # Get box source object. - try: - box_obj = self.app.collection.get_by_name(str(box_name)) - except Exception as e: - log.debug("TclCommandCopperClear.execute() --> %s" % str(e)) - self.raise_tcl_error("%s: %s" % (_("Could not retrieve box object"), name)) - return "Could not retrieve object: %s" % name + # Get box source object. + try: + box_obj = self.app.collection.get_by_name(str(box_name)) + except Exception as e: + log.debug("TclCommandCopperClear.execute() --> %s" % str(e)) + self.raise_tcl_error("%s: %s" % (_("Could not retrieve box object"), name)) + return "Could not retrieve object: %s" % name - self.app.ncclear_tool.clear_copper_tcl(ncc_obj=obj, - sel_obj=box_obj, - select_method='box', - ncctooldia=tooldia, - overlap=overlap, - order=order, - margin=margin, - has_offset=has_offset, - offset=offset, - method=method, - outname=outname, - connect=connect, - contour=contour, - rest=rest, - tools_storage=ncc_tools, - plot=False, - run_threaded=False) + self.app.ncclear_tool.clear_copper_tcl(ncc_obj=obj, + sel_obj=box_obj, + select_method='box', + ncctooldia=tooldia, + overlap=overlap, + order=order, + margin=margin, + has_offset=has_offset, + offset=offset, + method=method, + outname=outname, + connect=connect, + contour=contour, + rest=rest, + tools_storage=ncc_tools, + plot=False, + run_threaded=False) return - else: - self.raise_tcl_error("%s:" % _("None of the following args: 'ref', 'all' were found or none was set to 1.\n" - "Copper clearing failed.")) - return "None of the following args: 'ref', 'all' were found or none was set to 1.\n" \ - "Copper clearing failed." + + # if the program reached this then it's an error because neither -all or -box was used. + self.raise_tcl_error('%s' % _("Expected either -box or -all.")) + return "Expected either -box or -all. Copper clearing failed." diff --git a/tclCommands/TclCommandDelete.py b/tclCommands/TclCommandDelete.py index 339a1120..1d8a71c1 100644 --- a/tclCommands/TclCommandDelete.py +++ b/tclCommands/TclCommandDelete.py @@ -65,7 +65,11 @@ class TclCommandDelete(TclCommand): if args['f'] is None: is_forced = True else: - is_forced = True if bool(eval(str(args['f']))) else False + try: + par = args['f'].capitalize() + except AttributeError: + par = args['f'] + is_forced = bool(eval(par)) except KeyError: is_forced = True diff --git a/tclCommands/TclCommandDrillcncjob.py b/tclCommands/TclCommandDrillcncjob.py index d2f31021..fb114e1e 100644 --- a/tclCommands/TclCommandDrillcncjob.py +++ b/tclCommands/TclCommandDrillcncjob.py @@ -111,7 +111,11 @@ class TclCommandDrillcncjob(TclCommandSignaled): args['outname'] = name + "_cnc" if 'muted' in args: - muted = bool(eval(args['muted'])) + try: + par = args['muted'].capitalize() + except AttributeError: + par = args['muted'] + muted = bool(eval(par)) else: muted = False diff --git a/tclCommands/TclCommandIsolate.py b/tclCommands/TclCommandIsolate.py index 9fc4d214..9c1b874e 100644 --- a/tclCommands/TclCommandIsolate.py +++ b/tclCommands/TclCommandIsolate.py @@ -83,8 +83,12 @@ class TclCommandIsolate(TclCommandSignaled): args['follow'] = None # evaluate this parameter so True, False, 0 and 1 works - if "combine" in args: - args['combine'] = bool(eval(args['combine'])) + if 'combine' in args: + try: + par = args['combine'].capitalize() + except AttributeError: + par = args['combine'] + args['combine'] = bool(eval(par)) else: args['combine'] = bool(eval(self.app.defaults["gerber_combine_passes"])) diff --git a/tclCommands/TclCommandMillDrills.py b/tclCommands/TclCommandMillDrills.py index e4e3df07..c68117f1 100644 --- a/tclCommands/TclCommandMillDrills.py +++ b/tclCommands/TclCommandMillDrills.py @@ -86,7 +86,11 @@ class TclCommandMillDrills(TclCommandSignaled): args['outname'] = name + "_mill_drills" if 'use_thread' in args: - args['use_thread'] = bool(eval(args['use_thread'])) + try: + par = args['use_thread'].capitalize() + except AttributeError: + par = args['use_thread'] + args['use_thread'] = bool(eval(par)) else: args['use_thread'] = False diff --git a/tclCommands/TclCommandMillSlots.py b/tclCommands/TclCommandMillSlots.py index 7d6b1f0c..74c06659 100644 --- a/tclCommands/TclCommandMillSlots.py +++ b/tclCommands/TclCommandMillSlots.py @@ -86,7 +86,11 @@ class TclCommandMillSlots(TclCommandSignaled): args['outname'] = name + "_mill_slots" if 'use_thread' in args: - args['use_thread'] = bool(eval(args['use_thread'])) + try: + par = args['use_thread'].capitalize() + except AttributeError: + par = args['use_thread'] + args['use_thread'] = bool(eval(par)) else: args['use_thread'] = False diff --git a/tclCommands/TclCommandNregions.py b/tclCommands/TclCommandNregions.py index f4b2a228..871db83c 100644 --- a/tclCommands/TclCommandNregions.py +++ b/tclCommands/TclCommandNregions.py @@ -78,9 +78,14 @@ class TclCommandNregions(TclCommand): args['margin'] = float(self.app.defaults["gerber_noncoppermargin"]) margin = float(args['margin']) - if 'rounded' not in args: - args['rounded'] = self.app.defaults["gerber_noncopperrounded"] - rounded = bool(eval(args['rounded'])) + if 'rounded' in args: + try: + par = args['rounded'].capitalize() + except AttributeError: + par = args['rounded'] + rounded = bool(eval(par)) + else: + rounded = bool(eval(self.app.defaults["gerber_noncopperrounded"])) del args['name'] diff --git a/tclCommands/TclCommandPaint.py b/tclCommands/TclCommandPaint.py index d0b099be..7e54e1c6 100644 --- a/tclCommands/TclCommandPaint.py +++ b/tclCommands/TclCommandPaint.py @@ -69,16 +69,14 @@ class TclCommandPaint(TclCommand): ('method', 'Algorithm for painting. Can be: "standard", "seed" or "lines".'), ('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', 'Paint all polygons in the object. 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)'), - ('ref', 'Paint all polygons within a specified object with the name in "box" parameter. ' - 'True (1) or False (0)'), - ('box', 'name of the object to be used as paint reference when selecting "ref"" True. String.'), ('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.'), ]), - 'examples': ["paint obj_name -tooldia 0.3 -margin 0.1 -method 'seed' -all True"] + 'examples': ["paint obj_name -tooldia 0.3 -margin 0.1 -method 'seed' -all"] } def execute(self, args, unnamed_args): @@ -127,14 +125,22 @@ class TclCommandPaint(TclCommand): method = str(self.app.defaults["tools_paintmethod"]) if 'connect' in args: - connect = bool(eval(args['connect'])) + try: + par = args['connect'].capitalize() + except AttributeError: + par = args['connect'] + connect = bool(eval(par)) else: - connect = eval(str(self.app.defaults["tools_pathconnect"])) + connect = bool(eval(str(self.app.defaults["tools_pathconnect"]))) if 'contour' in args: - contour = bool(eval(args['contour'])) + try: + par = args['contour'].capitalize() + except AttributeError: + par = args['contour'] + contour = bool(eval(par)) else: - contour = eval(str(self.app.defaults["tools_paintcontour"])) + contour = bool(eval(str(self.app.defaults["tools_paintcontour"]))) if 'outname' in args: outname = args['outname'] @@ -202,7 +208,7 @@ class TclCommandPaint(TclCommand): return "Object not found: %s" % name # Paint all polygons in the painted object - if 'all' in args and bool(eval(args['all'])) is True: + if 'all' in args: self.app.paint_tool.paint_poly_all(obj=obj, tooldia=tooldia, overlap=overlap, @@ -218,8 +224,8 @@ class TclCommandPaint(TclCommand): return # Paint single polygon in the painted object - elif 'single' in args and bool(eval(args['single'])) is True: - if 'x' not in args or 'y' not in args: + if 'single' in args: + if 'x' not in args and 'y' not in args: self.raise_tcl_error('%s' % _("Expected -x and -y .")) else: x = args['x'] @@ -241,37 +247,35 @@ class TclCommandPaint(TclCommand): return # Paint all polygons found within the box object from the the painted object - elif 'ref' in args and bool(eval(args['ref'])) is True: - if 'box' not in args: + if 'box' in args: + box_name = args['box'] + + if box_name is None: self.raise_tcl_error('%s' % _("Expected -box .")) - else: - box_name = args['box'] - # Get box source object. - try: - box_obj = self.app.collection.get_by_name(str(box_name)) - except Exception as e: - log.debug("TclCommandPaint.execute() --> %s" % str(e)) - self.raise_tcl_error("%s: %s" % (_("Could not retrieve box object"), name)) - return "Could not retrieve object: %s" % name + # Get box source object. + try: + box_obj = self.app.collection.get_by_name(str(box_name)) + except Exception as e: + log.debug("TclCommandPaint.execute() --> %s" % str(e)) + self.raise_tcl_error("%s: %s" % (_("Could not retrieve box object"), name)) + return "Could not retrieve object: %s" % name - self.app.paint_tool.paint_poly_ref(obj=obj, - sel_obj=box_obj, - tooldia=tooldia, - overlap=overlap, - order=order, - margin=margin, - method=method, - outname=outname, - connect=connect, - contour=contour, - tools_storage=paint_tools, - plot=False, - run_threaded=False) + self.app.paint_tool.paint_poly_ref(obj=obj, + sel_obj=box_obj, + tooldia=tooldia, + overlap=overlap, + order=order, + margin=margin, + method=method, + outname=outname, + connect=connect, + contour=contour, + tools_storage=paint_tools, + plot=False, + run_threaded=False) return - else: - self.raise_tcl_error("%s:" % _("There was none of the following args: 'ref', 'single', 'all'.\n" - "Paint failed.")) - return "There was none of the following args: 'ref', 'single', 'all'.\n" \ - "Paint failed." + self.raise_tcl_error("%s:" % _("None of the following args: 'box', 'single', 'all' were used.\n" + "Paint failed.")) + return "None of the following args: 'box', 'single', 'all' were used. Paint failed." diff --git a/tclCommands/TclCommandPanelize.py b/tclCommands/TclCommandPanelize.py index e2c64dbc..142c1512 100644 --- a/tclCommands/TclCommandPanelize.py +++ b/tclCommands/TclCommandPanelize.py @@ -37,7 +37,7 @@ class TclCommandPanelize(TclCommand): ('spacing_rows', float), ('box', str), ('outname', str), - ('run_threaded', str) + ('use_thread', str) ]) # array of mandatory options for current Tcl command: required = {'name','outname'} @@ -55,7 +55,7 @@ class TclCommandPanelize(TclCommand): ('columns', 'Number of columns.'), ('rows', 'Number of rows;'), ('outname', 'Name of the new geometry object.'), - ('run_threaded', 'False (0) = non-threaded execution or True (1) = threaded execution') + ('use_thread', 'False (0) = non-threaded execution or True (1) = threaded execution') ]), 'examples': [ 'panelize obj_name', @@ -113,8 +113,12 @@ class TclCommandPanelize(TclCommand): else: outname = name + '_panelized' - if 'run_threaded' in args: - threaded = bool(eval(args['run_threaded'])) + if 'use_thread' in args: + try: + par = args['use_thread'].capitalize() + except AttributeError: + par = args['use_thread'] + threaded = bool(eval(par)) else: threaded = False diff --git a/tclCommands/TclCommandPlotAll.py b/tclCommands/TclCommandPlotAll.py index 53da1e8f..4e9f8277 100644 --- a/tclCommands/TclCommandPlotAll.py +++ b/tclCommands/TclCommandPlotAll.py @@ -49,17 +49,27 @@ class TclCommandPlotAll(TclCommandSignaled): """ if 'use_thread' in args: - threaded = bool(eval(args['use_thread'])) + try: + par = args['use_thread'].capitalize() + except AttributeError: + par = args['use_thread'] + threaded = bool(eval(par)) else: threaded = False + plot_status = True if 'plot_status' in args: - if args['plot_status'] is None: + try: + if args['plot_status'] is None: + plot_status = True + else: + try: + par = args['plot_status'].capitalize() + except AttributeError: + par = args['plot_status'] + plot_status = bool(eval(par)) + except KeyError: plot_status = True - else: - plot_status = bool(eval(args['plot_status'])) - else: - plot_status = True for obj in self.app.collection.get_list(): obj.options["plot"] = True if plot_status is True else False diff --git a/tclCommands/TclCommandWriteGCode.py b/tclCommands/TclCommandWriteGCode.py index b96fdfd8..85b83627 100644 --- a/tclCommands/TclCommandWriteGCode.py +++ b/tclCommands/TclCommandWriteGCode.py @@ -69,11 +69,15 @@ class TclCommandWriteGCode(TclCommandSignaled): postamble = args['postamble'] if 'postamble' in args else '' if 'muted' in args: - muted = bool(eval(args['muted'])) + try: + par = args['muted'].capitalize() + except AttributeError: + par = args['muted'] + muted = bool(eval(par)) else: muted = False - # TODO: This is not needed any more? All targets should be present. + # This is not needed any more? All targets should be present. # If there are promised objects, wait until all promises have been fulfilled. # if self.collection.has_promises(): # def write_gcode_on_object(new_object):