diff --git a/FlatCAMApp.py b/FlatCAMApp.py index cbd3e0c5..c7e89985 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -4633,9 +4633,14 @@ class App(QtCore.QObject): if obj.tools: obj_init.tools = obj.tools - def initialize_excellon(obj, app): - objs = self.collection.get_selected() - FlatCAMGeometry.merge(objs, obj) + def initialize_excellon(obj_init, app): + # objs = self.collection.get_selected() + # FlatCAMGeometry.merge(objs, obj) + solid_geo = [] + for tool in obj.tools: + for geo in obj.tools[tool]['solid_geometry']: + solid_geo.append(geo) + obj_init.solid_geometry = deepcopy(solid_geo) for obj in self.collection.get_selected(): diff --git a/ObjectCollection.py b/ObjectCollection.py index c4468993..3ec1e9d1 100644 --- a/ObjectCollection.py +++ b/ObjectCollection.py @@ -397,23 +397,25 @@ class ObjectCollection(QtCore.QAbstractItemModel): if index.isValid(): obj = index.internalPointer().obj if obj: - old_name = obj.options['name'] - # rename the object - obj.options["name"] = str(data) - new_name = obj.options['name'] + old_name = str(obj.options['name']) + new_name = str(data) + if old_name != new_name: + # rename the object + obj.options["name"] = str(data) - # update the SHELL auto-completer model data - try: - self.app.myKeywords.remove(old_name) - self.app.myKeywords.append(new_name) - self.app.shell._edit.set_model_data(self.app.myKeywords) - self.app.ui.code_editor.set_model_data(self.app.myKeywords) - except: - log.debug( - "setData() --> Could not remove the old object name from auto-completer model list") + # update the SHELL auto-completer model data + try: + self.app.myKeywords.remove(old_name) + self.app.myKeywords.append(new_name) + self.app.shell._edit.set_model_data(self.app.myKeywords) + self.app.ui.code_editor.set_model_data(self.app.myKeywords) + except: + log.debug( + "setData() --> Could not remove the old object name from auto-completer model list") - obj.build_ui() - self.app.inform.emit(_("Object renamed from {old} to {new}").format(old=old_name, new=new_name)) + obj.build_ui() + self.app.inform.emit(_("Object renamed from {old} to {new}").format(old=old_name, + new=new_name)) return True @@ -721,7 +723,7 @@ class ObjectCollection(QtCore.QAbstractItemModel): color='red', name=str(obj.options['name']))) except IndexError: - FlatCAMApp.App.log.debug("on_list_selection_change(): Index Error (Nothing selected?)") + # FlatCAMApp.App.log.debug("on_list_selection_change(): Index Error (Nothing selected?)") self.app.inform.emit('') try: self.app.ui.selected_scroll_area.takeWidget() diff --git a/README.md b/README.md index 606c8501..38c7e281 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,9 @@ CAD program, and create G-Code for Isolation routing. - Geometry Editor: modified the intersection (if the selected shapes don't intersects preserve them) and substract functions (delete all shapes that were used in the process) - work in the ToolSilk - for all objects, if in Selected the object name is changed to the same name, the rename is not done (because there is nothing changed) +- fixed Edit -> Copy as Geom function handler to work for Excellon objects, too +- made sure that the mouse pointer is restored to default on Editor exit +- 24.04.2019 diff --git a/flatcamEditors/FlatCAMExcEditor.py b/flatcamEditors/FlatCAMExcEditor.py index 25d44fc9..caa62102 100644 --- a/flatcamEditors/FlatCAMExcEditor.py +++ b/flatcamEditors/FlatCAMExcEditor.py @@ -1653,6 +1653,11 @@ class FlatCAMExcEditor(QtCore.QObject): self.drills_frame.show() def deactivate(self): + try: + QtGui.QGuiApplication.restoreOverrideCursor() + except: + pass + # adjust the status of the menu entries related to the editor self.app.ui.menueditedit.setDisabled(False) self.app.ui.menueditok.setDisabled(True) diff --git a/flatcamEditors/FlatCAMGeoEditor.py b/flatcamEditors/FlatCAMGeoEditor.py index d37cfc3e..17b7c6c8 100644 --- a/flatcamEditors/FlatCAMGeoEditor.py +++ b/flatcamEditors/FlatCAMGeoEditor.py @@ -2979,6 +2979,11 @@ class FlatCAMGeoEditor(QtCore.QObject): self.editor_active = True def deactivate(self): + try: + QtGui.QGuiApplication.restoreOverrideCursor() + except: + pass + # adjust the status of the menu entries related to the editor self.app.ui.menueditedit.setDisabled(False) self.app.ui.menueditok.setDisabled(True) diff --git a/flatcamEditors/FlatCAMGrbEditor.py b/flatcamEditors/FlatCAMGrbEditor.py index a27db07c..18c3dac0 100644 --- a/flatcamEditors/FlatCAMGrbEditor.py +++ b/flatcamEditors/FlatCAMGrbEditor.py @@ -2690,6 +2690,11 @@ class FlatCAMGrbEditor(QtCore.QObject): self.editor_active = True def deactivate_grb_editor(self): + try: + QtGui.QGuiApplication.restoreOverrideCursor() + except: + pass + # adjust the status of the menu entries related to the editor self.app.ui.menueditedit.setDisabled(False) self.app.ui.menueditok.setDisabled(True) diff --git a/flatcamTools/ToolSilk.py b/flatcamTools/ToolSilk.py index 6fec08bf..ce20cf31 100644 --- a/flatcamTools/ToolSilk.py +++ b/flatcamTools/ToolSilk.py @@ -105,6 +105,13 @@ class ToolSilk(FlatCAMTool): self.solder_union = None + # object to hold a flattened geometry + self.flat_geometry = [] + + try: + self.intersect_btn.clicked.disconnect(self.on_intersection_click) + except: + pass self.intersect_btn.clicked.connect(self.on_intersection_click) def install(self, icon=None, separator=None, **kwargs): @@ -162,10 +169,10 @@ class ToolSilk(FlatCAMTool): self.new_apertures[apid]['size'] = self.silk_obj.apertures[apid]['size'] self.new_apertures[apid]['solid_geometry'] = [] - geo_union_list = [] - for apid1 in self.sm_obj.apertures: - geo_union_list += self.sm_obj.apertures[apid1]['solid_geometry'] - self.solder_union = cascaded_union(geo_union_list) + # geo_union_list = [] + # for apid1 in self.sm_obj.apertures: + # geo_union_list += self.sm_obj.apertures[apid1]['solid_geometry'] + # self.solder_union = cascaded_union(geo_union_list) # start the QTimer with 1 second period check self.periodic_check(1000) @@ -178,30 +185,29 @@ class ToolSilk(FlatCAMTool): def aperture_intersection(self, apid, geo_list): self.promises.append(apid) new_solid_geometry = [] - for g in geo_list: - print(g.exterior.wkt) with self.app.proc_container.new(_("Parsing aperture %s geometry ..." % str(apid))): for geo_silk in geo_list: - if geo_silk.exterior.intersects(self.solder_union.exterior): - print("yes") - new_geo = geo_silk.exterior.difference(self.solder_union.exterior) - # if the resulting geometry is not empty add it to the new_apertures solid_geometry - try: - for g in new_geo: - new_solid_geometry.append(g) - except TypeError: - new_solid_geometry.append(new_geo) - - else: - print("no") - new_solid_geometry.append(geo_silk) + for ap in self.sm_obj.apertures: + for solder_poly in self.sm_obj.apertures[ap]['solid_geometry']: + if geo_silk.exterior.intersects(solder_poly): + new_geo = self.subtract_polygon(geo_silk, solder_poly) + if not new_geo.is_empty: + print(new_geo.wkt) + # if the resulting geometry is not empty add it to the new_apertures solid_geometry + try: + for g in new_geo: + new_solid_geometry.append(g) + except TypeError: + new_solid_geometry.append(new_geo) + # else: + # new_solid_geometry.append(geo_silk) if new_solid_geometry: try: while not self.new_apertures[apid]['solid_geometry']: self.new_apertures[apid]['solid_geometry'] = new_solid_geometry - time.sleep(0.1) + time.sleep(0.5) except: pass @@ -213,11 +219,72 @@ class ToolSilk(FlatCAMTool): self.promises.remove(apid) else: break - time.sleep(0.1) + time.sleep(0.5) except: log.debug("Promise fulfilled: %s" % str(apid)) pass + def subtract_polygon(self, geometry, polygon): + """ + Subtract polygon from the given object. This only operates on the paths in the original geometry, i.e. it converts polygons into paths. + + :param points: The vertices of the polygon. + :return: none + """ + + # pathonly should be always True, otherwise polygons are not subtracted + flat_geometry = self.flatten(geometry=geometry, pathonly=True) + log.debug("%d paths" % len(flat_geometry)) + + toolgeo=cascaded_union(polygon) + diffs=[] + for target in flat_geometry: + if type(target) == LineString or type(target) == LinearRing: + diffs.append(target.difference(toolgeo)) + else: + log.warning("Not implemented.") + + return cascaded_union(diffs) + + def flatten(self, geometry=None, reset=True, pathonly=False): + """ + Creates a list of non-iterable linear geometry objects. + Polygons are expanded into its exterior and interiors if specified. + + Results are placed in self.flat_geometry + + :param geometry: Shapely type or list or list of list of such. + :param reset: Clears the contents of self.flat_geometry. + :param pathonly: Expands polygons into linear elements. + """ + + if geometry is None: + log.debug("ToolSilk.flatten() --> There is no Geometry to flatten") + return + + if reset: + self.flat_geometry = [] + + ## If iterable, expand recursively. + try: + for geo in geometry: + if geo is not None: + self.flatten(geometry=geo, + reset=False, + pathonly=pathonly) + + ## Not iterable, do the actual indexing and add. + except TypeError: + if pathonly and type(geometry) == Polygon: + self.flat_geometry.append(geometry.exterior) + self.flatten(geometry=geometry.interiors, + reset=False, + pathonly=True) + else: + self.flat_geometry.append(geometry) + + return self.flat_geometry + def periodic_check(self, check_period, reset=False): """ This function starts an QTimer and it will periodically check if intersections are done @@ -259,7 +326,7 @@ class ToolSilk(FlatCAMTool): self.app.worker_task.emit({'fcn': self.new_silkscreen_object, 'params': [outname]}) - log.debug("ToolPDF --> Periodic check finished.") + log.debug("ToolSilk --> Periodic check finished.") except Exception: traceback.print_exc()