diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 881ff785..499ab362 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -190,7 +190,7 @@ class App(QtCore.QObject): thread_exception = QtCore.pyqtSignal(object) # used to signal that there are arguments for the app - args_at_startup = QtCore.pyqtSignal() + args_at_startup = QtCore.pyqtSignal(list) def __init__(self, user_defaults=True, post_gui=None): """ @@ -204,10 +204,6 @@ class App(QtCore.QObject): self.main_thread = QtWidgets.QApplication.instance().thread() - self.new_launch = ArgsThread() - self.new_launch.start() - self.new_launch.open_signal[list].connect(self.on_startup_args) - # ####################### # # ## OS-specific ###### # ####################### @@ -216,6 +212,14 @@ class App(QtCore.QObject): # Folder for user settings. if sys.platform == 'win32': + + # ######################################################################### + # Setup the listening thread for another instance launching with args ##### + # ######################################################################### + self.new_launch = ArgsThread() + self.new_launch.start(priority=QtCore.QThread.IdlePriority) + self.new_launch.open_signal[list].connect(self.on_startup_args) + from win32com.shell import shell, shellcon if platform.architecture()[0] == '32bit': App.log.debug("Win32!") @@ -1768,7 +1772,7 @@ class App(QtCore.QObject): self.on_excellon_options_button) # when there are arguments at application startup this get launched - self.args_at_startup.connect(lambda: self.on_startup_args()) + self.args_at_startup[list].connect(lambda: self.on_startup_args()) # connect the 'Apply' buttons from the Preferences/File Associations self.ui.fa_defaults_form.fa_excellon_group.exc_list_btn.clicked.connect( @@ -2233,7 +2237,7 @@ class App(QtCore.QObject): # accept some type file as command line parameter: FlatCAM project, FlatCAM preferences or scripts # the path/file_name must be enclosed in quotes if it contain spaces if App.args: - self.args_at_startup.emit() + self.args_at_startup.emit(App.args) @staticmethod def copy_and_overwrite(from_path, to_path): @@ -2257,7 +2261,8 @@ class App(QtCore.QObject): args_to_process = args else: args_to_process = App.args - log.debug("Application was started with an argument. Processing ...") + + log.debug("Application was started with arguments: %s. Processing ..." % str(args_to_process)) for argument in args_to_process: if '.FlatPrj' in argument: @@ -2305,12 +2310,13 @@ class App(QtCore.QObject): else: exc_list = self.ui.fa_defaults_form.fa_excellon_group.exc_list_text.get_value().split(',') + proc_arg = argument.lower() for ext in exc_list: proc_ext = ext.replace(' ', '') - if proc_ext.lower() in argument.lower(): + if proc_ext.lower() in proc_arg and proc_ext != '': file_name = str(argument) if file_name == "": - self.inform.emit(_("Open Script file failed.")) + self.inform.emit(_("Open Excellon file failed.")) else: self.on_fileopenexcellon(name=file_name) return @@ -2318,10 +2324,10 @@ class App(QtCore.QObject): gco_list = self.ui.fa_defaults_form.fa_gcode_group.gco_list_text.get_value().split(',') for ext in gco_list: proc_ext = ext.replace(' ', '') - if proc_ext.lower() in argument.lower(): + if proc_ext.lower() in proc_arg and proc_ext != '': file_name = str(argument) if file_name == "": - self.inform.emit(_("Open Script file failed.")) + self.inform.emit(_("Open GCode file failed.")) else: self.on_fileopengcode(name=file_name) return @@ -2329,10 +2335,10 @@ class App(QtCore.QObject): grb_list = self.ui.fa_defaults_form.fa_gerber_group.grb_list_text.get_value().split(',') for ext in grb_list: proc_ext = ext.replace(' ', '') - if proc_ext.lower() in argument.lower(): + if proc_ext.lower() in proc_arg and proc_ext != '': file_name = str(argument) if file_name == "": - self.inform.emit(_("Open Script file failed.")) + self.inform.emit(_("Open Gerber file failed.")) else: self.on_fileopengerber(name=file_name) return diff --git a/FlatCAMObj.py b/FlatCAMObj.py index 53f97c88..94b7217d 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -4788,7 +4788,16 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): dia_cnc_dict['gcode_parsed'] = job_obj.gcode_parse() # TODO this serve for bounding box creation only; should be optimized - dia_cnc_dict['solid_geometry'] = cascaded_union([geo['geom'] for geo in dia_cnc_dict['gcode_parsed']]) + # commented this; there is no need for the actual GCode geometry - the original one will serve as well + # for bounding box values + # geo_for_bound_values = cascaded_union([ + # geo['geom'] for geo in dia_cnc_dict['gcode_parsed'] if geo['geom'].is_valid is True + # ]) + try: + dia_cnc_dict['solid_geometry'] = cascaded_union(tool_solid_geometry) + self.app.inform.emit(_("[success] Finished G-Code processing...")) + except Exception as e: + self.app.inform.emit(_("[ERROR] G-Code processing failed with error: %s") % str(e)) # tell gcode_parse from which point to start drawing the lines depending on what kind of # object is the source of gcode @@ -4953,6 +4962,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): # source of gcode job_obj.toolchange_xy_type = "geometry" job_obj.gcode_parse() + self.app.inform.emit(_("[success] Finished G-Code processing...")) app_obj.progress.emit(80) diff --git a/FlatCAMWorkerStack.py b/FlatCAMWorkerStack.py index 7845697b..3ce56011 100644 --- a/FlatCAMWorkerStack.py +++ b/FlatCAMWorkerStack.py @@ -25,7 +25,7 @@ class WorkerStack(QtCore.QObject): thread.started.connect(worker.run) worker.task_completed.connect(self.on_task_completed) - thread.start(QtCore.QThread.LowPriority) + thread.start(QtCore.QThread.NormalPriority) self.workers.append(worker) self.threads.append(thread) diff --git a/README.md b/README.md index ff88fc3b..e7b87c95 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,13 @@ CAD program, and create G-Code for Isolation routing. ================================================= +5.09.2019 + +- fixed issue with loading files at start-up +- fixed issue with generating bounding box geometry for CNCJob objects +- added some more infobar messages and log.debug +- increased the priority for the worker tasks + 4.09.2019 - started to work on support for G91 in Gcode (relative coordinates) diff --git a/camlib.py b/camlib.py index 508c1643..8681f873 100644 --- a/camlib.py +++ b/camlib.py @@ -5966,7 +5966,7 @@ class CNCjob(Geometry): except StopIteration: # Nothing found in storage. pass - log.debug("Finishing G-Code... %s paths traced." % path_count) + log.debug("Finished G-Code... %s paths traced." % path_count) # add move to end position total_travel += abs(distance_euclidian(current_pt[0], current_pt[1], 0, 0)) @@ -5977,7 +5977,7 @@ class CNCjob(Geometry): self.gcode += self.doformat(p.spindle_stop_code) self.gcode += self.doformat(p.lift_code, x=current_pt[0], y=current_pt[1]) self.gcode += self.doformat(p.end_code, x=0, y=0) - + self.app.inform.emit(_("Finished G-Code generation... %s paths traced.") % str(path_count)) return self.gcode def generate_from_geometry_2(self, geometry, append=True, @@ -6270,6 +6270,7 @@ class CNCjob(Geometry): self.gcode += self.doformat(p.spindle_stop_code) self.gcode += self.doformat(p.lift_code, x=current_pt[0], y=current_pt[1]) self.gcode += self.doformat(p.end_code, x=0, y=0) + self.app.inform.emit(_("Finished G-Code generation... %s paths traced.") % str(path_count)) return self.gcode @@ -6844,7 +6845,6 @@ class CNCjob(Geometry): ) for geo in gcode_parsed: - print(list(geo['geom'].coordsner)) if geo['kind'][0] == 'T': current_position = ( geo['geom'].coords[0][0] + old_pos[0], diff --git a/flatcamTools/ToolNonCopperClear.py b/flatcamTools/ToolNonCopperClear.py index 5259bac8..03896799 100644 --- a/flatcamTools/ToolNonCopperClear.py +++ b/flatcamTools/ToolNonCopperClear.py @@ -1324,6 +1324,7 @@ class NonCopperClear(FlatCAMTool, Gerber): # ####### Read the parameters ######################################### # ##################################################################### + log.debug("Copper clearing started. Reading parameters.") ncc_method = method if method else self.ncc_method_radio.get_value() if margin is not None: @@ -1387,6 +1388,7 @@ class NonCopperClear(FlatCAMTool, Gerber): # ############################################################################################################## # Prepare non-copper polygons. Create the bounding box area from which the copper features will be subtracted ## # ############################################################################################################## + log.debug("Copper clearing. Preparing non-copper polygons.") try: if sel_obj is None or sel_obj == 'itself': ncc_sel_obj = ncc_obj @@ -1450,6 +1452,7 @@ class NonCopperClear(FlatCAMTool, Gerber): self.app.inform.emit(_("[ERROR_NOTCL] The reference object type is not supported.")) return 'fail' + log.debug("Copper clearing. Finished non-copper polygons.") # ######################################################################################################## # set the name for the future Geometry object # I do it here because it is also stored inside the gen_clear_area() and gen_clear_area_rest() methods @@ -1467,6 +1470,8 @@ class NonCopperClear(FlatCAMTool, Gerber): assert isinstance(geo_obj, FlatCAMGeometry), \ "Initializer expected a FlatCAMGeometry, got %s" % type(geo_obj) + log.debug("Copper clearing. Normal copper clearing task started.") + # a flag to signal that the isolation is broken by the bounding box in 'area' and 'box' cases # will store the number of tools for which the isolation is broken warning_flag = 0 @@ -1496,6 +1501,7 @@ class NonCopperClear(FlatCAMTool, Gerber): # ################################################################################################### # Calculate the empty area by subtracting the solid_geometry from the object bounding box geometry ## # ################################################################################################### + log.debug("Copper clearing. Calculate 'empty' area.") if isinstance(ncc_obj, FlatCAMGerber) and not isotooldia: sol_geo = ncc_obj.solid_geometry if has_offset is True: @@ -1601,8 +1607,10 @@ class NonCopperClear(FlatCAMTool, Gerber): if type(empty) is Polygon: empty = MultiPolygon([empty]) + log.debug("Copper clearing. Finished calculation of 'empty' area.") cp = None for tool in sorted_tools: + log.debug("Starting geometry processing for tool: %s" % str(tool)) app_obj.inform.emit(_('[success] Non-Copper Clearing with ToolDia = %s started.') % str(tool)) cleared_geo[:] = [] @@ -1730,7 +1738,7 @@ class NonCopperClear(FlatCAMTool, Gerber): assert isinstance(geo_obj, FlatCAMGeometry), \ "Initializer expected a FlatCAMGeometry, got %s" % type(geo_obj) - + log.debug("Copper clearing. Rest machining copper clearing task started.") # a flag to signal that the isolation is broken by the bounding box in 'area' and 'box' cases # will store the number of tools for which the isolation is broken warning_flag = 0 @@ -1748,7 +1756,7 @@ class NonCopperClear(FlatCAMTool, Gerber): # repurposed flag for final object, geo_obj. True if it has any solid_geometry, False if not. app_obj.poly_not_cleared = True - + log.debug("Copper clearing. Calculate 'empty' area.") # ################################################################################################### # Calculate the empty area by subtracting the solid_geometry from the object bounding box geometry ## # ################################################################################################### @@ -1858,9 +1866,13 @@ class NonCopperClear(FlatCAMTool, Gerber): empty = MultiPolygon([empty]) area = empty.buffer(0) + + log.debug("Copper clearing. Finished calculation of 'empty' area.") # Generate area for each tool while sorted_tools: tool = sorted_tools.pop(0) + log.debug("Starting geometry processing for tool: %s" % str(tool)) + app_obj.inform.emit(_('[success] Non-Copper Rest Clearing with ToolDia = %s started.') % str(tool)) tool_used = tool - 1e-12