فهرست منبع

- moved the initialization of the FlatCAM editors after a read of the default values. If I don't do this then only at the first start of the application the Editors are not functional as the Editor objects are most likely destroyed
- fixed bug in FlatCAM editors that caused the shapes to be drawn without resolution when the app units where INCH
- modified the transformation functions in all classes in camlib.py and FlatCAMObj.py to work with empty geometries

Marius Stanciu 6 سال پیش
والد
کامیت
b20203eace
8فایلهای تغییر یافته به همراه184 افزوده شده و 64 حذف شده
  1. 20 16
      FlatCAMApp.py
  2. 13 4
      FlatCAMObj.py
  3. 3 0
      README.md
  4. 84 27
      camlib.py
  5. 15 1
      flatcamEditors/FlatCAMExcEditor.py
  6. 3 0
      flatcamEditors/FlatCAMGeoEditor.py
  7. 44 14
      flatcamEditors/FlatCAMGrbEditor.py
  8. 2 2
      flatcamParsers/ParseDXF.py

+ 20 - 16
FlatCAMApp.py

@@ -1395,18 +1395,11 @@ class App(QtCore.QObject):
         end_plot_time = time.time()
         end_plot_time = time.time()
         self.log.debug("Finished Canvas initialization in %s seconds." % (str(end_plot_time - start_plot_time)))
         self.log.debug("Finished Canvas initialization in %s seconds." % (str(end_plot_time - start_plot_time)))
 
 
-        # ### EDITOR section
-        self.geo_editor = FlatCAMGeoEditor(self, disabled=True)
-        self.exc_editor = FlatCAMExcEditor(self)
-        self.grb_editor = FlatCAMGrbEditor(self)
-
         # ### Adjust tabs width ## ##
         # ### Adjust tabs width ## ##
         # self.collection.view.setMinimumWidth(self.ui.options_scroll_area.widget().sizeHint().width() +
         # self.collection.view.setMinimumWidth(self.ui.options_scroll_area.widget().sizeHint().width() +
         #     self.ui.options_scroll_area.verticalScrollBar().sizeHint().width())
         #     self.ui.options_scroll_area.verticalScrollBar().sizeHint().width())
         self.collection.view.setMinimumWidth(290)
         self.collection.view.setMinimumWidth(290)
 
 
-        self.log.debug("Finished adding FlatCAM Editor's.")
-
         # ### Worker ####
         # ### Worker ####
         if self.defaults["global_worker_number"]:
         if self.defaults["global_worker_number"]:
             self.workers = WorkerStack(workers_number=int(self.defaults["global_worker_number"]))
             self.workers = WorkerStack(workers_number=int(self.defaults["global_worker_number"]))
@@ -2102,6 +2095,17 @@ class App(QtCore.QObject):
         filename_factory = self.data_path + '/factory_defaults.FlatConfig'
         filename_factory = self.data_path + '/factory_defaults.FlatConfig'
         os.chmod(filename_factory, S_IREAD | S_IRGRP | S_IROTH)
         os.chmod(filename_factory, S_IREAD | S_IRGRP | S_IROTH)
 
 
+        ####################################################
+        # ### EDITOR section ###############################
+        ####################################################
+
+        # watch out for the position of the editors instantiation ... if it is done before a save of the default values
+        # at the first launch of the App , the editors will not be functional.
+        self.geo_editor = FlatCAMGeoEditor(self, disabled=True)
+        self.exc_editor = FlatCAMExcEditor(self)
+        self.grb_editor = FlatCAMGrbEditor(self)
+        self.log.debug("Finished adding FlatCAM Editor's.")
+
         # Post-GUI initialization: Experimental attempt
         # Post-GUI initialization: Experimental attempt
         # to perform unit tests on the GUI.
         # to perform unit tests on the GUI.
         # if post_gui is not None:
         # if post_gui is not None:
@@ -2378,9 +2382,6 @@ class App(QtCore.QObject):
             # we set the notebook to hidden
             # we set the notebook to hidden
             self.ui.splitter.setSizes([0, 1])
             self.ui.splitter.setSizes([0, 1])
 
 
-            # set call source to the Editor we go into
-            self.call_source = 'geo_editor'
-
             if edited_object.multigeo is True:
             if edited_object.multigeo is True:
                 edited_tools = [int(x.text()) for x in edited_object.ui.geo_tools_table.selectedItems()]
                 edited_tools = [int(x.text()) for x in edited_object.ui.geo_tools_table.selectedItems()]
                 if len(edited_tools) > 1:
                 if len(edited_tools) > 1:
@@ -2402,30 +2403,33 @@ class App(QtCore.QObject):
             else:
             else:
                 self.geo_editor.edit_fcgeometry(edited_object)
                 self.geo_editor.edit_fcgeometry(edited_object)
 
 
+            # set call source to the Editor we go into
+            self.call_source = 'geo_editor'
+
         elif isinstance(edited_object, FlatCAMExcellon):
         elif isinstance(edited_object, FlatCAMExcellon):
             # store the Excellon Editor Toolbar visibility before entering in the Editor
             # store the Excellon Editor Toolbar visibility before entering in the Editor
             self.exc_editor.toolbar_old_state = True if self.ui.exc_edit_toolbar.isVisible() else False
             self.exc_editor.toolbar_old_state = True if self.ui.exc_edit_toolbar.isVisible() else False
 
 
-            # set call source to the Editor we go into
-            self.call_source = 'exc_editor'
-
             if self.ui.splitter.sizes()[0] == 0:
             if self.ui.splitter.sizes()[0] == 0:
                 self.ui.splitter.setSizes([1, 1])
                 self.ui.splitter.setSizes([1, 1])
 
 
             self.exc_editor.edit_fcexcellon(edited_object)
             self.exc_editor.edit_fcexcellon(edited_object)
 
 
+            # set call source to the Editor we go into
+            self.call_source = 'exc_editor'
+
         elif isinstance(edited_object, FlatCAMGerber):
         elif isinstance(edited_object, FlatCAMGerber):
             # store the Gerber Editor Toolbar visibility before entering in the Editor
             # store the Gerber Editor Toolbar visibility before entering in the Editor
             self.grb_editor.toolbar_old_state = True if self.ui.grb_edit_toolbar.isVisible() else False
             self.grb_editor.toolbar_old_state = True if self.ui.grb_edit_toolbar.isVisible() else False
 
 
-            # set call source to the Editor we go into
-            self.call_source = 'grb_editor'
-
             if self.ui.splitter.sizes()[0] == 0:
             if self.ui.splitter.sizes()[0] == 0:
                 self.ui.splitter.setSizes([1, 1])
                 self.ui.splitter.setSizes([1, 1])
 
 
             self.grb_editor.edit_fcgerber(edited_object)
             self.grb_editor.edit_fcgerber(edited_object)
 
 
+            # set call source to the Editor we go into
+            self.call_source = 'grb_editor'
+
         # make sure that we can't select another object while in Editor Mode:
         # make sure that we can't select another object while in Editor Mode:
         # self.collection.view.setSelectionMode(QtWidgets.QAbstractItemView.NoSelection)
         # self.collection.view.setSelectionMode(QtWidgets.QAbstractItemView.NoSelection)
         self.ui.project_frame.setDisabled(True)
         self.ui.project_frame.setDisabled(True)

+ 13 - 4
FlatCAMObj.py

@@ -5000,14 +5000,20 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
                     geoms.append(scale_recursion(local_geom))
                     geoms.append(scale_recursion(local_geom))
                 return geoms
                 return geoms
             else:
             else:
-                return affinity.scale(geom, xfactor, yfactor, origin=(px, py))
+                try:
+                    return affinity.scale(geom, xfactor, yfactor, origin=(px, py))
+                except AttributeError:
+                    return geom
 
 
         if self.multigeo is True:
         if self.multigeo is True:
             for tool in self.tools:
             for tool in self.tools:
                 self.tools[tool]['solid_geometry'] = scale_recursion(self.tools[tool]['solid_geometry'])
                 self.tools[tool]['solid_geometry'] = scale_recursion(self.tools[tool]['solid_geometry'])
         else:
         else:
-            self.solid_geometry = scale_recursion(self.solid_geometry)
-
+            try:
+                self.solid_geometry = scale_recursion(self.solid_geometry)
+            except AttributeError:
+                self.solid_geometry = []
+                return
         self.app.inform.emit(_(
         self.app.inform.emit(_(
             "[success] Geometry Scale done."
             "[success] Geometry Scale done."
         ))
         ))
@@ -5038,7 +5044,10 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
                     geoms.append(translate_recursion(local_geom))
                     geoms.append(translate_recursion(local_geom))
                 return geoms
                 return geoms
             else:
             else:
-                return affinity.translate(geom, xoff=dx, yoff=dy)
+                try:
+                    return affinity.translate(geom, xoff=dx, yoff=dy)
+                except AttributeError:
+                    return geom
 
 
         if self.multigeo is True:
         if self.multigeo is True:
             for tool in self.tools:
             for tool in self.tools:

+ 3 - 0
README.md

@@ -18,6 +18,9 @@ CAD program, and create G-Code for Isolation routing.
 - updated translations and changed version
 - updated translations and changed version
 - fixed installer issue for the x64 version due of the used CX_FREEZE python package which was in unofficial version (obviously not ready to be used)
 - fixed installer issue for the x64 version due of the used CX_FREEZE python package which was in unofficial version (obviously not ready to be used)
 - fixed bug in Geometry Editor, in disconnect_canvas_event_handlers() where I left some part of code without adding a try - except block which was required
 - fixed bug in Geometry Editor, in disconnect_canvas_event_handlers() where I left some part of code without adding a try - except block which was required
+- moved the initialization of the FlatCAM editors after a read of the default values. If I don't do this then only at the first start of the application the Editors are not functional as the Editor objects are most likely destroyed
+- fixed bug in FlatCAM editors that caused the shapes to be drawn without resolution when the app units where INCH
+- modified the transformation functions in all classes in camlib.py and FlatCAMObj.py to work with empty geometries
 - RELEASE 8.95
 - RELEASE 8.95
 
 
 17.08.2019
 17.08.2019

+ 84 - 27
camlib.py

@@ -1389,7 +1389,10 @@ class Geometry(object):
                     new_obj.append(mirror_geom(g))
                     new_obj.append(mirror_geom(g))
                 return new_obj
                 return new_obj
             else:
             else:
-                return affinity.scale(obj, xscale, yscale, origin=(px, py))
+                try:
+                    return affinity.scale(obj, xscale, yscale, origin=(px, py))
+                except AttributeError:
+                    return obj
 
 
         try:
         try:
             if self.multigeo is True:
             if self.multigeo is True:
@@ -1427,7 +1430,10 @@ class Geometry(object):
                     new_obj.append(rotate_geom(g))
                     new_obj.append(rotate_geom(g))
                 return new_obj
                 return new_obj
             else:
             else:
-                return affinity.rotate(obj, angle, origin=(px, py))
+                try:
+                    return affinity.rotate(obj, angle, origin=(px, py))
+                except AttributeError:
+                    return obj
 
 
         try:
         try:
             if self.multigeo is True:
             if self.multigeo is True:
@@ -1463,7 +1469,10 @@ class Geometry(object):
                     new_obj.append(skew_geom(g))
                     new_obj.append(skew_geom(g))
                 return new_obj
                 return new_obj
             else:
             else:
-                return affinity.skew(obj, angle_x, angle_y, origin=(px, py))
+                try:
+                    return affinity.skew(obj, angle_x, angle_y, origin=(px, py))
+                except AttributeError:
+                    return obj
 
 
         try:
         try:
             if self.multigeo is True:
             if self.multigeo is True:
@@ -3380,7 +3389,10 @@ class Gerber (Geometry):
                     new_obj.append(scale_geom(g))
                     new_obj.append(scale_geom(g))
                 return new_obj
                 return new_obj
             else:
             else:
-                return affinity.scale(obj, xfactor, yfactor, origin=(px, py))
+                try:
+                    return affinity.scale(obj, xfactor, yfactor, origin=(px, py))
+                except AttributeError:
+                    return obj
 
 
         self.solid_geometry = scale_geom(self.solid_geometry)
         self.solid_geometry = scale_geom(self.solid_geometry)
         self.follow_geometry = scale_geom(self.follow_geometry)
         self.follow_geometry = scale_geom(self.follow_geometry)
@@ -3444,7 +3456,10 @@ class Gerber (Geometry):
                     new_obj.append(offset_geom(g))
                     new_obj.append(offset_geom(g))
                 return new_obj
                 return new_obj
             else:
             else:
-                return affinity.translate(obj, xoff=dx, yoff=dy)
+                try:
+                    return affinity.translate(obj, xoff=dx, yoff=dy)
+                except AttributeError:
+                    return obj
 
 
         # ## Solid geometry
         # ## Solid geometry
         self.solid_geometry = offset_geom(self.solid_geometry)
         self.solid_geometry = offset_geom(self.solid_geometry)
@@ -3500,7 +3515,10 @@ class Gerber (Geometry):
                     new_obj.append(mirror_geom(g))
                     new_obj.append(mirror_geom(g))
                 return new_obj
                 return new_obj
             else:
             else:
-                return affinity.scale(obj, xscale, yscale, origin=(px, py))
+                try:
+                    return affinity.scale(obj, xscale, yscale, origin=(px, py))
+                except AttributeError:
+                    return obj
 
 
         self.solid_geometry = mirror_geom(self.solid_geometry)
         self.solid_geometry = mirror_geom(self.solid_geometry)
         self.follow_geometry = mirror_geom(self.follow_geometry)
         self.follow_geometry = mirror_geom(self.follow_geometry)
@@ -3546,7 +3564,10 @@ class Gerber (Geometry):
                     new_obj.append(skew_geom(g))
                     new_obj.append(skew_geom(g))
                 return new_obj
                 return new_obj
             else:
             else:
-                return affinity.skew(obj, angle_x, angle_y, origin=(px, py))
+                try:
+                    return affinity.skew(obj, angle_x, angle_y, origin=(px, py))
+                except AttributeError:
+                    return obj
 
 
         self.solid_geometry = skew_geom(self.solid_geometry)
         self.solid_geometry = skew_geom(self.solid_geometry)
         self.follow_geometry = skew_geom(self.follow_geometry)
         self.follow_geometry = skew_geom(self.follow_geometry)
@@ -3585,7 +3606,10 @@ class Gerber (Geometry):
                     new_obj.append(rotate_geom(g))
                     new_obj.append(rotate_geom(g))
                 return new_obj
                 return new_obj
             else:
             else:
-                return affinity.rotate(obj, angle, origin=(px, py))
+                try:
+                    return affinity.rotate(obj, angle, origin=(px, py))
+                except AttributeError:
+                    return obj
 
 
         self.solid_geometry = rotate_geom(self.solid_geometry)
         self.solid_geometry = rotate_geom(self.solid_geometry)
         self.follow_geometry = rotate_geom(self.follow_geometry)
         self.follow_geometry = rotate_geom(self.follow_geometry)
@@ -4703,8 +4727,10 @@ class Excellon(Geometry):
                     new_obj.append(scale_geom(g))
                     new_obj.append(scale_geom(g))
                 return new_obj
                 return new_obj
             else:
             else:
-                return affinity.scale(obj, xfactor,
-                                             yfactor, origin=(px, py))
+                try:
+                    return affinity.scale(obj, xfactor, yfactor, origin=(px, py))
+                except AttributeError:
+                    return obj
 
 
         # Drills
         # Drills
         for drill in self.drills:
         for drill in self.drills:
@@ -4739,7 +4765,10 @@ class Excellon(Geometry):
                     new_obj.append(offset_geom(g))
                     new_obj.append(offset_geom(g))
                 return new_obj
                 return new_obj
             else:
             else:
-                return affinity.translate(obj, xoff=dx, yoff=dy)
+                try:
+                    return affinity.translate(obj, xoff=dx, yoff=dy)
+                except AttributeError:
+                    return obj
 
 
         # Drills
         # Drills
         for drill in self.drills:
         for drill in self.drills:
@@ -4776,7 +4805,10 @@ class Excellon(Geometry):
                     new_obj.append(mirror_geom(g))
                     new_obj.append(mirror_geom(g))
                 return new_obj
                 return new_obj
             else:
             else:
-                return affinity.scale(obj, xscale, yscale, origin=(px, py))
+                try:
+                    return affinity.scale(obj, xscale, yscale, origin=(px, py))
+                except AttributeError:
+                    return obj
 
 
         # Modify data
         # Modify data
         # Drills
         # Drills
@@ -4823,7 +4855,10 @@ class Excellon(Geometry):
                     new_obj.append(skew_geom(g))
                     new_obj.append(skew_geom(g))
                 return new_obj
                 return new_obj
             else:
             else:
-                return affinity.skew(obj, angle_x, angle_y, origin=(px, py))
+                try:
+                    return affinity.skew(obj, angle_x, angle_y, origin=(px, py))
+                except AttributeError:
+                    return obj
 
 
         if point is None:
         if point is None:
             px, py = 0, 0
             px, py = 0, 0
@@ -4874,9 +4909,15 @@ class Excellon(Geometry):
                 return new_obj
                 return new_obj
             else:
             else:
                 if origin:
                 if origin:
-                    return affinity.rotate(obj, angle, origin=origin)
+                    try:
+                        return affinity.rotate(obj, angle, origin=origin)
+                    except AttributeError:
+                        return obj
                 else:
                 else:
-                    return affinity.rotate(obj, angle, origin=(px, py))
+                    try:
+                        return affinity.rotate(obj, angle, origin=(px, py))
+                    except AttributeError:
+                        return obj
 
 
         if point is None:
         if point is None:
             # Drills
             # Drills
@@ -7135,7 +7176,10 @@ class CNCjob(Geometry):
             self.gcode = scale_g(self.gcode)
             self.gcode = scale_g(self.gcode)
             # offset geometry
             # offset geometry
             for g in self.gcode_parsed:
             for g in self.gcode_parsed:
-                g['geom'] = affinity.scale(g['geom'], xfactor, yfactor, origin=(px, py))
+                try:
+                    g['geom'] = affinity.scale(g['geom'], xfactor, yfactor, origin=(px, py))
+                except AttributeError:
+                    return g['geom']
             self.create_geometry()
             self.create_geometry()
         else:
         else:
             for k, v in self.cnc_tools.items():
             for k, v in self.cnc_tools.items():
@@ -7143,9 +7187,11 @@ class CNCjob(Geometry):
                 v['gcode'] = scale_g(v['gcode'])
                 v['gcode'] = scale_g(v['gcode'])
                 # scale gcode_parsed
                 # scale gcode_parsed
                 for g in v['gcode_parsed']:
                 for g in v['gcode_parsed']:
-                    g['geom'] = affinity.scale(g['geom'], xfactor, yfactor, origin=(px, py))
+                    try:
+                        g['geom'] = affinity.scale(g['geom'], xfactor, yfactor, origin=(px, py))
+                    except AttributeError:
+                        return g['geom']
                 v['solid_geometry'] = cascaded_union([geo['geom'] for geo in v['gcode_parsed']])
                 v['solid_geometry'] = cascaded_union([geo['geom'] for geo in v['gcode_parsed']])
-
         self.create_geometry()
         self.create_geometry()
 
 
     def offset(self, vect):
     def offset(self, vect):
@@ -7201,7 +7247,10 @@ class CNCjob(Geometry):
             self.gcode = offset_g(self.gcode)
             self.gcode = offset_g(self.gcode)
             # offset geometry
             # offset geometry
             for g in self.gcode_parsed:
             for g in self.gcode_parsed:
-                g['geom'] = affinity.translate(g['geom'], xoff=dx, yoff=dy)
+                try:
+                    g['geom'] = affinity.translate(g['geom'], xoff=dx, yoff=dy)
+                except AttributeError:
+                    return g['geom']
             self.create_geometry()
             self.create_geometry()
         else:
         else:
             for k, v in self.cnc_tools.items():
             for k, v in self.cnc_tools.items():
@@ -7209,7 +7258,10 @@ class CNCjob(Geometry):
                 v['gcode'] = offset_g(v['gcode'])
                 v['gcode'] = offset_g(v['gcode'])
                 # offset gcode_parsed
                 # offset gcode_parsed
                 for g in v['gcode_parsed']:
                 for g in v['gcode_parsed']:
-                    g['geom'] = affinity.translate(g['geom'], xoff=dx, yoff=dy)
+                    try:
+                        g['geom'] = affinity.translate(g['geom'], xoff=dx, yoff=dy)
+                    except AttributeError:
+                        return g['geom']
                 v['solid_geometry'] = cascaded_union([geo['geom'] for geo in v['gcode_parsed']])
                 v['solid_geometry'] = cascaded_union([geo['geom'] for geo in v['gcode_parsed']])
 
 
     def mirror(self, axis, point):
     def mirror(self, axis, point):
@@ -7223,8 +7275,10 @@ class CNCjob(Geometry):
         xscale, yscale = {"X": (1.0, -1.0), "Y": (-1.0, 1.0)}[axis]
         xscale, yscale = {"X": (1.0, -1.0), "Y": (-1.0, 1.0)}[axis]
 
 
         for g in self.gcode_parsed:
         for g in self.gcode_parsed:
-            g['geom'] = affinity.scale(g['geom'], xscale, yscale, origin=(px, py))
-
+            try:
+                g['geom'] = affinity.scale(g['geom'], xscale, yscale, origin=(px, py))
+            except AttributeError:
+                return g['geom']
         self.create_geometry()
         self.create_geometry()
 
 
     def skew(self, angle_x, angle_y, point):
     def skew(self, angle_x, angle_y, point):
@@ -7245,9 +7299,10 @@ class CNCjob(Geometry):
         px, py = point
         px, py = point
 
 
         for g in self.gcode_parsed:
         for g in self.gcode_parsed:
-            g['geom'] = affinity.skew(g['geom'], angle_x, angle_y,
-                                      origin=(px, py))
-
+            try:
+                g['geom'] = affinity.skew(g['geom'], angle_x, angle_y, origin=(px, py))
+            except AttributeError:
+                return g['geom']
         self.create_geometry()
         self.create_geometry()
 
 
     def rotate(self, angle, point):
     def rotate(self, angle, point):
@@ -7261,8 +7316,10 @@ class CNCjob(Geometry):
         px, py = point
         px, py = point
 
 
         for g in self.gcode_parsed:
         for g in self.gcode_parsed:
-            g['geom'] = affinity.rotate(g['geom'], angle, origin=(px, py))
-
+            try:
+                g['geom'] = affinity.rotate(g['geom'], angle, origin=(px, py))
+            except AttributeError:
+                return g['geom']
         self.create_geometry()
         self.create_geometry()
 
 
 
 

+ 15 - 1
flatcamEditors/FlatCAMExcEditor.py

@@ -1,3 +1,11 @@
+# ##########################################################
+# FlatCAM: 2D Post-processing for Manufacturing            #
+# http://flatcam.org                                       #
+# File Author: Marius Adrian Stanciu (c)                   #
+# Date: 8/17/2019                                          #
+# MIT Licence                                              #
+# ##########################################################
+
 from PyQt5 import QtGui, QtCore, QtWidgets
 from PyQt5 import QtGui, QtCore, QtWidgets
 from PyQt5.QtCore import Qt, QSettings
 from PyQt5.QtCore import Qt, QSettings
 
 
@@ -1945,6 +1953,11 @@ class FlatCAMExcEditor(QtCore.QObject):
         # this var will store the state of the toolbar before starting the editor
         # this var will store the state of the toolbar before starting the editor
         self.toolbar_old_state = False
         self.toolbar_old_state = False
 
 
+        if self.units == 'MM':
+            self.tolerance = float(self.app.defaults["global_tolerance"])
+        else:
+            self.tolerance = float(self.app.defaults["global_tolerance"]) / 20
+
         self.app.ui.delete_drill_btn.triggered.connect(self.on_delete_btn)
         self.app.ui.delete_drill_btn.triggered.connect(self.on_delete_btn)
         self.name_entry.returnPressed.connect(self.on_name_activate)
         self.name_entry.returnPressed.connect(self.on_name_activate)
         self.addtool_btn.clicked.connect(self.on_tool_add)
         self.addtool_btn.clicked.connect(self.on_tool_add)
@@ -2048,6 +2061,7 @@ class FlatCAMExcEditor(QtCore.QObject):
 
 
         # store the status of the editor so the Delete at object level will not work until the edit is finished
         # store the status of the editor so the Delete at object level will not work until the edit is finished
         self.editor_active = False
         self.editor_active = False
+        log.debug("Initialization of the FlatCAM Excellon Editor is finished ...")
 
 
     def pool_recreated(self, pool):
     def pool_recreated(self, pool):
         self.shapes.pool = pool
         self.shapes.pool = pool
@@ -3727,7 +3741,7 @@ class FlatCAMExcEditor(QtCore.QObject):
                 plot_elements += self.plot_shape(geometry=geometry.interiors, color=color, linewidth=linewidth)
                 plot_elements += self.plot_shape(geometry=geometry.interiors, color=color, linewidth=linewidth)
 
 
             if type(geometry) == LineString or type(geometry) == LinearRing:
             if type(geometry) == LineString or type(geometry) == LinearRing:
-                plot_elements.append(self.shapes.add(shape=geometry, color=color, layer=0))
+                plot_elements.append(self.shapes.add(shape=geometry, color=color, layer=0, tolerance=self.tolerance))
 
 
             if type(geometry) == Point:
             if type(geometry) == Point:
                 pass
                 pass

+ 3 - 0
flatcamEditors/FlatCAMGeoEditor.py

@@ -3118,6 +3118,7 @@ class FlatCAMGeoEditor(QtCore.QObject):
 
 
         # store the status of the editor so the Delete at object level will not work until the edit is finished
         # store the status of the editor so the Delete at object level will not work until the edit is finished
         self.editor_active = False
         self.editor_active = False
+        log.debug("Initialization of the FlatCAM Geometry Editor is finished ...")
 
 
     def pool_recreated(self, pool):
     def pool_recreated(self, pool):
         self.shapes.pool = pool
         self.shapes.pool = pool
@@ -3174,6 +3175,7 @@ class FlatCAMGeoEditor(QtCore.QObject):
 
 
         # Tell the App that the editor is active
         # Tell the App that the editor is active
         self.editor_active = True
         self.editor_active = True
+        log.debug("Finished activating the Geometry Editor...")
 
 
     def deactivate(self):
     def deactivate(self):
         try:
         try:
@@ -3253,6 +3255,7 @@ class FlatCAMGeoEditor(QtCore.QObject):
         # Show original geometry
         # Show original geometry
         if self.fcgeometry:
         if self.fcgeometry:
             self.fcgeometry.visible = True
             self.fcgeometry.visible = True
+        log.debug("Finished deactivating the Geometry Editor...")
 
 
     def connect_canvas_event_handlers(self):
     def connect_canvas_event_handlers(self):
         # Canvas events
         # Canvas events

+ 44 - 14
flatcamEditors/FlatCAMGrbEditor.py

@@ -1,3 +1,11 @@
+# ##########################################################
+# FlatCAM: 2D Post-processing for Manufacturing            #
+# http://flatcam.org                                       #
+# File Author: Marius Adrian Stanciu (c)                   #
+# Date: 8/17/2019                                          #
+# MIT Licence                                              #
+# ##########################################################
+
 from PyQt5 import QtGui, QtCore, QtWidgets
 from PyQt5 import QtGui, QtCore, QtWidgets
 from PyQt5.QtCore import Qt, QSettings
 from PyQt5.QtCore import Qt, QSettings
 
 
@@ -839,6 +847,8 @@ class FCRegion(FCShapeTool):
         self.name = 'region'
         self.name = 'region'
         self.draw_app = draw_app
         self.draw_app = draw_app
 
 
+        self.steps_per_circle = self.draw_app.app.defaults["gerber_circle_steps"]
+
         size_ap = float(self.draw_app.storage_dict[self.draw_app.last_aperture_selected]['size'])
         size_ap = float(self.draw_app.storage_dict[self.draw_app.last_aperture_selected]['size'])
         self.buf_val = (size_ap / 2) if size_ap > 0 else 0.0000001
         self.buf_val = (size_ap / 2) if size_ap > 0 else 0.0000001
 
 
@@ -885,7 +895,7 @@ class FCRegion(FCShapeTool):
         y = data[1]
         y = data[1]
 
 
         if len(self.points) == 0:
         if len(self.points) == 0:
-            new_geo_el['solid'] = Point(data).buffer(self.buf_val)
+            new_geo_el['solid'] = Point(data).buffer(self.buf_val, resolution=int(self.steps_per_circle / 4))
             return DrawToolUtilityShape(new_geo_el)
             return DrawToolUtilityShape(new_geo_el)
 
 
         if len(self.points) == 1:
         if len(self.points) == 1:
@@ -951,12 +961,15 @@ class FCRegion(FCShapeTool):
 
 
             if len(self.temp_points) > 1:
             if len(self.temp_points) > 1:
                 try:
                 try:
-                    new_geo_el['solid'] = LineString(self.temp_points).buffer(self.buf_val, join_style=1)
+                    new_geo_el['solid'] = LineString(self.temp_points).buffer(self.buf_val,
+                                                                              resolution=int(self.steps_per_circle / 4),
+                                                                              join_style=1)
                     return DrawToolUtilityShape(new_geo_el)
                     return DrawToolUtilityShape(new_geo_el)
                 except Exception as e:
                 except Exception as e:
                     log.debug("FlatCAMGrbEditor.FCRegion.utility_geometry() --> %s" % str(e))
                     log.debug("FlatCAMGrbEditor.FCRegion.utility_geometry() --> %s" % str(e))
             else:
             else:
-                new_geo_el['solid'] = Point(self.temp_points).buffer(self.buf_val)
+                new_geo_el['solid'] = Point(self.temp_points).buffer(self.buf_val,
+                                                                     resolution=int(self.steps_per_circle / 4))
                 return DrawToolUtilityShape(new_geo_el)
                 return DrawToolUtilityShape(new_geo_el)
 
 
         if len(self.points) > 2:
         if len(self.points) > 2:
@@ -1012,7 +1025,9 @@ class FCRegion(FCShapeTool):
             self.temp_points.append(data)
             self.temp_points.append(data)
             new_geo_el = dict()
             new_geo_el = dict()
 
 
-            new_geo_el['solid'] = LinearRing(self.temp_points).buffer(self.buf_val, join_style=1)
+            new_geo_el['solid'] = LinearRing(self.temp_points).buffer(self.buf_val,
+                                                                      resolution=int(self.steps_per_circle / 4),
+                                                                      join_style=1)
             new_geo_el['follow'] = LinearRing(self.temp_points)
             new_geo_el['follow'] = LinearRing(self.temp_points)
 
 
             return DrawToolUtilityShape(new_geo_el)
             return DrawToolUtilityShape(new_geo_el)
@@ -1031,7 +1046,9 @@ class FCRegion(FCShapeTool):
 
 
             new_geo_el = dict()
             new_geo_el = dict()
 
 
-            new_geo_el['solid'] = Polygon(self.points).buffer(self.buf_val, join_style=2)
+            new_geo_el['solid'] = Polygon(self.points).buffer(self.buf_val,
+                                                              resolution=int(self.steps_per_circle / 4),
+                                                              join_style=2)
             new_geo_el['follow'] = Polygon(self.points).exterior
             new_geo_el['follow'] = Polygon(self.points).exterior
 
 
             self.geometry = DrawToolShape(new_geo_el)
             self.geometry = DrawToolShape(new_geo_el)
@@ -1128,10 +1145,12 @@ class FCTrack(FCRegion):
     def make(self):
     def make(self):
         new_geo_el = dict()
         new_geo_el = dict()
         if len(self.temp_points) == 1:
         if len(self.temp_points) == 1:
-            new_geo_el['solid'] = Point(self.temp_points).buffer(self.buf_val)
+            new_geo_el['solid'] = Point(self.temp_points).buffer(self.buf_val,
+                                                                 resolution=int(self.steps_per_circle / 4))
             new_geo_el['follow'] = Point(self.temp_points)
             new_geo_el['follow'] = Point(self.temp_points)
         else:
         else:
-            new_geo_el['solid'] = (LineString(self.temp_points).buffer(self.buf_val)).buffer(0)
+            new_geo_el['solid'] = (LineString(self.temp_points).buffer(
+                self.buf_val, resolution=int(self.steps_per_circle / 4))).buffer(0)
             new_geo_el['follow'] = LineString(self.temp_points)
             new_geo_el['follow'] = LineString(self.temp_points)
 
 
         self.geometry = DrawToolShape(new_geo_el)
         self.geometry = DrawToolShape(new_geo_el)
@@ -1156,10 +1175,12 @@ class FCTrack(FCRegion):
         new_geo_el = dict()
         new_geo_el = dict()
 
 
         if len(self.temp_points) == 1:
         if len(self.temp_points) == 1:
-            new_geo_el['solid'] = Point(self.temp_points).buffer(self.buf_val)
+            new_geo_el['solid'] = Point(self.temp_points).buffer(self.buf_val,
+                                                                 resolution=int(self.steps_per_circle / 4))
             new_geo_el['follow'] = Point(self.temp_points)
             new_geo_el['follow'] = Point(self.temp_points)
         else:
         else:
-            new_geo_el['solid'] = LineString(self.temp_points).buffer(self.buf_val)
+            new_geo_el['solid'] = LineString(self.temp_points).buffer(self.buf_val,
+                                                                      resolution=int(self.steps_per_circle / 4))
             new_geo_el['follow'] = LineString(self.temp_points)
             new_geo_el['follow'] = LineString(self.temp_points)
 
 
         self.draw_app.add_gerber_shape(DrawToolShape(new_geo_el),
         self.draw_app.add_gerber_shape(DrawToolShape(new_geo_el),
@@ -1177,7 +1198,8 @@ class FCTrack(FCRegion):
         new_geo_el = dict()
         new_geo_el = dict()
 
 
         if len(self.points) == 0:
         if len(self.points) == 0:
-            new_geo_el['solid'] = Point(data).buffer(self.buf_val)
+            new_geo_el['solid'] = Point(data).buffer(self.buf_val,
+                                                     resolution=int(self.steps_per_circle / 4))
 
 
             return DrawToolUtilityShape(new_geo_el)
             return DrawToolUtilityShape(new_geo_el)
         elif len(self.points) > 0:
         elif len(self.points) > 0:
@@ -1235,10 +1257,12 @@ class FCTrack(FCRegion):
 
 
             self.temp_points.append(data)
             self.temp_points.append(data)
             if len(self.temp_points) == 1:
             if len(self.temp_points) == 1:
-                new_geo_el['solid'] = Point(self.temp_points).buffer(self.buf_val)
+                new_geo_el['solid'] = Point(self.temp_points).buffer(self.buf_val,
+                                                                     resolution=int(self.steps_per_circle / 4))
                 return DrawToolUtilityShape(new_geo_el)
                 return DrawToolUtilityShape(new_geo_el)
 
 
-            new_geo_el['solid'] = LineString(self.temp_points).buffer(self.buf_val)
+            new_geo_el['solid'] = LineString(self.temp_points).buffer(self.buf_val,
+                                                                      resolution=int(self.steps_per_circle / 4))
             return DrawToolUtilityShape(new_geo_el)
             return DrawToolUtilityShape(new_geo_el)
 
 
     def on_key(self, key):
     def on_key(self, key):
@@ -2802,6 +2826,11 @@ class FlatCAMGrbEditor(QtCore.QObject):
         # this will flag if the Editor "tools" are launched from key shortcuts (True) or from menu toolbar (False)
         # this will flag if the Editor "tools" are launched from key shortcuts (True) or from menu toolbar (False)
         self.launched_from_shortcuts = False
         self.launched_from_shortcuts = False
 
 
+        if self.units == 'MM':
+            self.tolerance = float(self.app.defaults["global_tolerance"])
+        else:
+            self.tolerance = float(self.app.defaults["global_tolerance"]) / 20
+
         def make_callback(the_tool):
         def make_callback(the_tool):
             def f():
             def f():
                 self.on_tool_select(the_tool)
                 self.on_tool_select(the_tool)
@@ -2887,6 +2916,7 @@ class FlatCAMGrbEditor(QtCore.QObject):
         self.conversion_factor = 1
         self.conversion_factor = 1
 
 
         self.set_ui()
         self.set_ui()
+        log.debug("Initialization of the FlatCAM Gerber Editor is finished ...")
 
 
     def pool_recreated(self, pool):
     def pool_recreated(self, pool):
         self.shapes.pool = pool
         self.shapes.pool = pool
@@ -4372,11 +4402,11 @@ class FlatCAMGrbEditor(QtCore.QObject):
             geometry = self.active_tool.geometry
             geometry = self.active_tool.geometry
 
 
         try:
         try:
-            self.shapes.add(shape=geometry.geo, color=color, face_color=color, layer=0)
+            self.shapes.add(shape=geometry.geo, color=color, face_color=color, layer=0, tolerance=self.tolerance)
         except AttributeError:
         except AttributeError:
             if type(geometry) == Point:
             if type(geometry) == Point:
                 return
                 return
-            self.shapes.add(shape=geometry, color=color, face_color=color+'AF', layer=0)
+            self.shapes.add(shape=geometry, color=color, face_color=color+'AF', layer=0, tolerance=self.tolerance)
 
 
     def start_delayed_plot(self, check_period):
     def start_delayed_plot(self, check_period):
         """
         """

+ 2 - 2
flatcamParsers/ParseDXF.py

@@ -1,10 +1,10 @@
-# ########################################################## ##
+# ##########################################################
 # FlatCAM: 2D Post-processing for Manufacturing            #
 # FlatCAM: 2D Post-processing for Manufacturing            #
 # http://flatcam.org                                       #
 # http://flatcam.org                                       #
 # File Author: Marius Adrian Stanciu (c)                   #
 # File Author: Marius Adrian Stanciu (c)                   #
 # Date: 3/10/2019                                          #
 # Date: 3/10/2019                                          #
 # MIT Licence                                              #
 # MIT Licence                                              #
-# ########################################################## ##
+# ##########################################################
 
 
 from shapely.geometry import LineString
 from shapely.geometry import LineString
 import logging
 import logging