- added a new TclCommand named PlotObjects which will plot a list of FlatCAM objects

- made that after opening an object in FlatCAM it is not automatically plotted. If the user wants to plot it can use the TclCommands PlotAll or PlotObjects
- modified the TclCommands that open files to not plot the opened files automatically
This commit is contained in:
Marius Stanciu
2019-09-16 00:47:15 +03:00
committed by Marius
parent c06317374e
commit 2f553c9005
10 changed files with 122 additions and 51 deletions

View File

@@ -1898,7 +1898,8 @@ class App(QtCore.QObject):
'mirror', 'ncc', 'mirror', 'ncc',
'ncc_clear', 'ncr', 'new', 'new_geometry', 'non_copper_regions', 'offset', 'ncc_clear', 'ncr', 'new', 'new_geometry', 'non_copper_regions', 'offset',
'open_excellon', 'open_gcode', 'open_gerber', 'open_project', 'options', 'paint', 'open_excellon', 'open_gcode', 'open_gerber', 'open_project', 'options', 'paint',
'pan', 'panel', 'panelize', 'plot', 'save', 'save_project', 'save_sys', 'scale', 'pan', 'panel', 'panelize', 'plot_all', 'plot_objects', 'save', 'save_project',
'save_sys', 'scale',
'set_active', 'set_sys', 'setsys', 'skew', 'subtract_poly', 'subtract_rectangle', 'set_active', 'set_sys', 'setsys', 'skew', 'subtract_poly', 'subtract_rectangle',
'version', 'write_gcode' 'version', 'write_gcode'
] ]
@@ -1917,7 +1918,8 @@ class App(QtCore.QObject):
'use_threads', 'value', 'x', 'x0', 'x1', 'y', 'y0', 'y1', 'z_cut', 'z_move', 'use_threads', 'value', 'x', 'x0', 'x1', 'y', 'y0', 'y1', 'z_cut', 'z_move',
'default', 'feedrate_z', 'grbl_11', 'grbl_laser', 'hpgl', 'line_xyz', 'marlin', 'default', 'feedrate_z', 'grbl_11', 'grbl_laser', 'hpgl', 'line_xyz', 'marlin',
'Paste_1', 'Repetier', 'Toolchange_Custom', 'Roland_MDX_20', 'Toolchange_manual', 'Paste_1', 'Repetier', 'Toolchange_Custom', 'Roland_MDX_20', 'Toolchange_manual',
'Toolchange_Probe_MACH3', 'dwell', 'dwelltime', 'toolchange_xy', 'iso_type' 'Toolchange_Probe_MACH3', 'dwell', 'dwelltime', 'toolchange_xy', 'iso_type',
'Desktop', 'FlatPrj', 'FlatConfig', 'Users', 'Documents', 'My Documents', 'Marius'
] ]
self.tcl_keywords = [ self.tcl_keywords = [
@@ -2253,6 +2255,9 @@ class App(QtCore.QObject):
# Variable to store the GCODE that was edited # Variable to store the GCODE that was edited
self.gcode_edited = "" self.gcode_edited = ""
# reference for the self.ui.code_editor
self.reference_code_editor = None
# if Preferences are changed in the Edit -> Preferences tab the value will be set to True # if Preferences are changed in the Edit -> Preferences tab the value will be set to True
self.preferences_changed_flag = False self.preferences_changed_flag = False
@@ -3062,8 +3067,8 @@ class App(QtCore.QObject):
result = self.exec_command_test(text, False) result = self.exec_command_test(text, False)
# MS: added this method call so the geometry is updated once the TCL command is executed # MS: added this method call so the geometry is updated once the TCL command is executed
if no_plot is None: # if no_plot is None:
self.plot_all() # self.plot_all()
return result return result
@@ -5941,6 +5946,7 @@ class App(QtCore.QObject):
old_line = '' old_line = ''
except tk.TclError as e: except tk.TclError as e:
log.debug("App.handleRunCode() --> %s" % str(e))
old_line = old_line + tcl_command_line + '\n' old_line = old_line + tcl_command_line + '\n'
if old_line != '': if old_line != '':
@@ -8199,6 +8205,9 @@ class App(QtCore.QObject):
self.ui.code_editor.completer_enable = False self.ui.code_editor.completer_enable = False
self.ui.buttonRun.hide() self.ui.buttonRun.hide()
# make sure to keep a reference to the code editor
self.reference_code_editor = self.ui.code_editor
# Switch plot_area to CNCJob tab # Switch plot_area to CNCJob tab
self.ui.plot_tab_area.setCurrentWidget(self.ui.cncjob_tab) self.ui.plot_tab_area.setCurrentWidget(self.ui.cncjob_tab)
@@ -9387,7 +9396,7 @@ class App(QtCore.QObject):
self.inform.emit('[success] %s: %s' % self.inform.emit('[success] %s: %s' %
(_("Opened"), filename)) (_("Opened"), filename))
def open_excellon(self, filename, outname=None): def open_excellon(self, filename, outname=None, plot=True):
""" """
Opens an Excellon file, parses it and creates a new object for Opens an Excellon file, parses it and creates a new object for
it in the program. Thread-safe. it in the program. Thread-safe.
@@ -9441,7 +9450,7 @@ class App(QtCore.QObject):
# Object name # Object name
name = outname or filename.split('/')[-1].split('\\')[-1] name = outname or filename.split('/')[-1].split('\\')[-1]
ret_val = self.new_object("excellon", name, obj_init, autoselected=False) ret_val = self.new_object("excellon", name, obj_init, autoselected=False, plot=plot)
if ret_val == 'fail': if ret_val == 'fail':
self.inform.emit('[ERROR_NOTCL] %s' % self.inform.emit('[ERROR_NOTCL] %s' %
_('Open Excellon file failed. Probable not an Excellon file.')) _('Open Excellon file failed. Probable not an Excellon file.'))
@@ -9454,7 +9463,7 @@ class App(QtCore.QObject):
self.inform.emit('[success] %s: %s' % self.inform.emit('[success] %s: %s' %
(_("Opened"), filename)) (_("Opened"), filename))
def open_gcode(self, filename, outname=None): def open_gcode(self, filename, outname=None, plot=True):
""" """
Opens a G-gcode file, parses it and creates a new object for Opens a G-gcode file, parses it and creates a new object for
it in the program. Thread-safe. it in the program. Thread-safe.
@@ -9506,7 +9515,7 @@ class App(QtCore.QObject):
name = outname or filename.split('/')[-1].split('\\')[-1] name = outname or filename.split('/')[-1].split('\\')[-1]
# New object creation and file processing # New object creation and file processing
ret = self.new_object("cncjob", name, obj_init, autoselected=False) ret = self.new_object("cncjob", name, obj_init, autoselected=False, plot=plot)
if ret == 'fail': if ret == 'fail':
self.inform.emit('[ERROR_NOTCL] %s' % self.inform.emit('[ERROR_NOTCL] %s' %
_("Failed to create CNCJob Object. Probable not a GCode file.\n " _("Failed to create CNCJob Object. Probable not a GCode file.\n "
@@ -9554,7 +9563,7 @@ class App(QtCore.QObject):
(_("Failed to open config file"), filename)) (_("Failed to open config file"), filename))
return return
def open_project(self, filename, run_from_arg=None): def open_project(self, filename, run_from_arg=None, plot=True, cli=None):
""" """
Loads a project from the specified file. Loads a project from the specified file.
@@ -9568,11 +9577,14 @@ class App(QtCore.QObject):
:param filename: Name of the file from which to load. :param filename: Name of the file from which to load.
:type filename: str :type filename: str
:param run_from_arg: True if run for arguments :param run_from_arg: True if run for arguments
:param plot: If True plot all objects in the project
:param cli: run from command line
:return: None :return: None
""" """
App.log.debug("Opening project: " + filename) App.log.debug("Opening project: " + filename)
self.set_ui_title(name=_("Loading Project ... Please Wait ...")) if cli is None:
self.set_ui_title(name=_("Loading Project ... Please Wait ..."))
# Open and parse an uncompressed Project file # Open and parse an uncompressed Project file
try: try:
@@ -9604,7 +9616,7 @@ class App(QtCore.QObject):
# Clear the current project # Clear the current project
# # NOT THREAD SAFE # ## # # NOT THREAD SAFE # ##
if run_from_arg is True: if run_from_arg is True or cli is True:
pass pass
else: else:
self.on_file_new() self.on_file_new()
@@ -9620,16 +9632,18 @@ class App(QtCore.QObject):
for obj in d['objs']: for obj in d['objs']:
def obj_init(obj_inst, app_inst): def obj_init(obj_inst, app_inst):
obj_inst.from_dict(obj) obj_inst.from_dict(obj)
App.log.debug("Recreating from opened project an %s object: %s" % App.log.debug("Recreating from opened project an %s object: %s" %
(obj['kind'].capitalize(), obj['options']['name'])) (obj['kind'].capitalize(), obj['options']['name']))
self.set_ui_title(name="{} {}: {}".format(_("Loading Project ... restoring"), if cli is None:
obj['kind'].upper(), self.set_ui_title(name="{} {}: {}".format(_("Loading Project ... restoring"),
obj['options']['name'] obj['kind'].upper(),
) obj['options']['name']
) )
)
self.new_object(obj['kind'], obj['options']['name'], obj_init, active=False, fit=False, plot=True) self.new_object(obj['kind'], obj['options']['name'], obj_init, active=False, fit=False, plot=plot)
# self.plot_all() # self.plot_all()
self.inform.emit('[success] %s: %s' % self.inform.emit('[success] %s: %s' %

View File

@@ -21,6 +21,9 @@ CAD program, and create G-Code for Isolation routing.
- added some more keywords in the data_model for auto-completer - added some more keywords in the data_model for auto-completer
- fixed isolate TclCommand to use correctly the -outname parameter - fixed isolate TclCommand to use correctly the -outname parameter
- added possibility to see the GCode when right clicking on the Project tab on a CNCJob object and then clicking View Source - added possibility to see the GCode when right clicking on the Project tab on a CNCJob object and then clicking View Source
- added a new TclCommand named PlotObjects which will plot a list of FlatCAM objects
- made that after opening an object in FlatCAM it is not automatically plotted. If the user wants to plot it can use the TclCommands PlotAll or PlotObjects
- modified the TclCommands that open files to not plot the opened files automatically
14.09.2019 14.09.2019

View File

@@ -163,35 +163,36 @@ class TclCommand(object):
@staticmethod @staticmethod
def parse_arguments(args): def parse_arguments(args):
""" """
Pre-processes arguments to detect '-keyword value' pairs into dictionary Pre-processes arguments to detect '-keyword value' pairs into dictionary
and standalone parameters into list. and standalone parameters into list.
This is copy from FlatCAMApp.setup_shell().h() just for accessibility, This is copy from FlatCAMApp.setup_shell().h() just for accessibility,
original should be removed after all commands will be converted original should be removed after all commands will be converted
:param args: arguments from tcl to parse :param args: arguments from tcl to parse
:return: arguments, options :return: arguments, options
""" """
options = {} options = {}
arguments = [] arguments = []
n = len(args) n = len(args)
name = None
for i in range(n):
match = re.search(r'^-([a-zA-Z].*)', args[i])
if match:
assert name is None
name = match.group(1)
continue
if name is None: name = None
arguments.append(args[i]) for i in range(n):
else: match = re.search(r'^-([a-zA-Z].*)', args[i])
options[name] = args[i] if match:
name = None assert name is None
name = match.group(1)
continue
return arguments, options if name is None:
arguments.append(args[i])
else:
options[name] = args[i]
name = None
return arguments, options
def check_args(self, args): def check_args(self, args):
""" """
@@ -274,7 +275,6 @@ class TclCommand(object):
""" """
# self.worker_task.emit({'fcn': self.exec_command_test, 'params': [text, False]}) # self.worker_task.emit({'fcn': self.exec_command_test, 'params': [text, False]})
try: try:
self.log.debug("TCL command '%s' executed." % str(self.__class__)) self.log.debug("TCL command '%s' executed." % str(self.__class__))
self.original_args = args self.original_args = args

View File

@@ -47,4 +47,5 @@ class TclCommandOpenExcellon(TclCommandSignaled):
filename = args.pop('filename') filename = args.pop('filename')
args['plot'] = False
self.app.open_excellon(filename, **args) self.app.open_excellon(filename, **args)

View File

@@ -45,5 +45,5 @@ class TclCommandOpenGCode(TclCommandSignaled):
without -somename and we do not have them in known arg_names without -somename and we do not have them in known arg_names
:return: None or exception :return: None or exception
""" """
args['plot'] = False
self.app.open_gcode(args['filename'], **args) self.app.open_gcode(args['filename'], **args)

View File

@@ -30,7 +30,7 @@ class TclCommandOpenGerber(TclCommandSignaled):
('filename', 'Path to file to open.'), ('filename', 'Path to file to open.'),
('outname', 'Name of the resulting Gerber object.') ('outname', 'Name of the resulting Gerber object.')
]), ]),
'examples': [] 'examples': ["open_gerber gerber_object_path -outname bla"]
} }
def execute(self, args, unnamed_args): def execute(self, args, unnamed_args):
@@ -76,12 +76,13 @@ class TclCommandOpenGerber(TclCommandSignaled):
outname = filename.split('/')[-1].split('\\')[-1] outname = filename.split('/')[-1].split('\\')[-1]
if 'follow' in args: if 'follow' in args:
self.raise_tcl_error("The 'follow' parameter is obsolete. To create 'follow' geometry use the 'follow' parameter for the Tcl Command isolate()") self.raise_tcl_error("The 'follow' parameter is obsolete. To create 'follow' geometry use the 'follow' "
"parameter for the Tcl Command isolate()")
with self.app.proc_container.new("Opening Gerber"): with self.app.proc_container.new("Opening Gerber"):
# Object creation # Object creation
self.app.new_object("gerber", outname, obj_init) self.app.new_object("gerber", outname, obj_init, plot=False)
# Register recent file # Register recent file
self.app.file_opened.emit("gerber", filename) self.app.file_opened.emit("gerber", filename)

View File

@@ -43,5 +43,5 @@ class TclCommandOpenProject(TclCommandSignaled):
without -somename and we do not have them in known arg_names without -somename and we do not have them in known arg_names
:return: None or exception :return: None or exception
""" """
filename = args['filename']
self.app.open_project(args['filename']) self.app.open_project(filename, cli=True, plot=False)

View File

@@ -2,7 +2,7 @@ from ObjectCollection import *
from tclCommands.TclCommand import TclCommand from tclCommands.TclCommand import TclCommand
class TclCommandPlot(TclCommand): class TclCommandPlotAll(TclCommand):
""" """
Tcl shell command to update the plot on the user interface. Tcl shell command to update the plot on the user interface.
@@ -11,7 +11,7 @@ class TclCommandPlot(TclCommand):
""" """
# List of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon) # List of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon)
aliases = ['plot'] aliases = ['plot_all']
# Dictionary of types from Tcl command, needs to be ordered # Dictionary of types from Tcl command, needs to be ordered
arg_names = collections.OrderedDict([ arg_names = collections.OrderedDict([

View File

@@ -0,0 +1,51 @@
from ObjectCollection import *
from tclCommands.TclCommand import TclCommand
class TclCommandPlotObjects(TclCommand):
"""
Tcl shell command to update the plot on the user interface.
example:
plot
"""
# List of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon)
aliases = ['plot_objects']
# Dictionary of types from Tcl command, needs to be ordered
arg_names = collections.OrderedDict([
('names', str)
])
# Dictionary of types from Tcl command, needs to be ordered , this is for options like -optionname value
option_types = collections.OrderedDict([
])
# array of mandatory options for current Tcl command: required = {'name','outname'}
required = []
# structured help for current command, args needs to be ordered
help = {
'main': "Plot a list of objects.",
'args': collections.OrderedDict([
('names', "UA list of object names to be plotted.")
]),
'examples': ["plot_objects"]
}
def execute(self, args, unnamed_args):
"""
:param args:
:param unnamed_args:
:return:
"""
names = [x.strip() for x in args['names'].split(",")]
objs = []
for name in names:
objs.append(self.app.collection.get_by_name(name))
for obj in objs:
obj.plot()

View File

@@ -44,7 +44,8 @@ import tclCommands.TclCommandOpenProject
import tclCommands.TclCommandOptions import tclCommands.TclCommandOptions
import tclCommands.TclCommandPaint import tclCommands.TclCommandPaint
import tclCommands.TclCommandPanelize import tclCommands.TclCommandPanelize
import tclCommands.TclCommandPlot import tclCommands.TclCommandPlotAll
import tclCommands.TclCommandPlotObjects
import tclCommands.TclCommandSaveProject import tclCommands.TclCommandSaveProject
import tclCommands.TclCommandSaveSys import tclCommands.TclCommandSaveSys
import tclCommands.TclCommandScale import tclCommands.TclCommandScale