Bladeren bron

- fixed bug in Panelization Tool for which in case of Excellon objects, the panel kept a reference to the source object which created issues when moving or disabling/enabling the plots
- cleaned up the module imports throughout the app (the TclCommands are not yet verified)

Marius Stanciu 6 jaren geleden
bovenliggende
commit
dfc0b98181

+ 5 - 1
FlatCAMApp.py

@@ -9,6 +9,8 @@
 import urllib.request
 import urllib.parse
 import urllib.error
+import webbrowser
+
 import getopt
 import random
 import simplejson as json
@@ -40,10 +42,12 @@ import vispy.scene as scene
 # #######################################
 from ObjectCollection import *
 from FlatCAMObj import *
+from camlib import to_dict, dict2obj, ET, ParseError
+
 from flatcamGUI.PlotCanvas import *
 from flatcamGUI.PlotCanvasLegacy import *
-
 from flatcamGUI.FlatCAMGUI import *
+
 from FlatCAMCommon import LoudDict
 from FlatCAMPostProc import load_postprocessors
 

+ 16 - 7
FlatCAMObj.py

@@ -10,24 +10,33 @@
 # File modified by: Marius Stanciu                         #
 # ##########################################################
 
-from PyQt5.QtCore import Qt
-from PyQt5.QtGui import QTextDocument
+
+from shapely.geometry import Point, Polygon, MultiPolygon, MultiLineString, LineString, LinearRing
+from shapely.ops import cascaded_union
+import shapely.affinity as affinity
+
 import copy
+from copy import deepcopy
+from io import StringIO
+import traceback
 import inspect  # TODO: For debugging only.
 from datetime import datetime
 
 from flatcamEditors.FlatCAMTextEditor import TextEditor
-
 from flatcamGUI.ObjectUI import *
 from FlatCAMCommon import LoudDict
 from flatcamGUI.PlotCanvasLegacy import ShapeCollectionLegacy
-from camlib import *
 from flatcamParsers.ParseExcellon import Excellon
 from flatcamParsers.ParseGerber import Gerber
+from camlib import Geometry, CNCjob
+import FlatCAMApp
 
-import itertools
 import tkinter as tk
-import sys
+import os, sys, itertools
+import ezdxf
+
+import math
+import numpy as np
 
 import gettext
 import FlatCAMTranslation as fcTranslate
@@ -66,7 +75,7 @@ class FlatCAMObj(QtCore.QObject):
     app = None
 
     # signal to plot a single object
-    plot_single_object = pyqtSignal()
+    plot_single_object = QtCore.pyqtSignal()
 
     def __init__(self, name):
         """

+ 0 - 2
FlatCAMPostProc.py

@@ -9,8 +9,6 @@
 from importlib.machinery import SourceFileLoader
 import os
 from abc import ABCMeta, abstractmethod
-from datetime import datetime
-import math
 
 # module-root dictionary of postprocessors
 import FlatCAMApp

+ 13 - 4
ObjectCollection.py

@@ -11,13 +11,20 @@
 # File modified by: Marius Stanciu                         #
 # ##########################################################
 
+from PyQt5 import QtGui, QtCore, QtWidgets
+from PyQt5.QtCore import Qt, QSettings
+from PyQt5.QtGui import QColor
 # from PyQt5.QtCore import QModelIndex
-from FlatCAMObj import *
+
+from FlatCAMObj import FlatCAMGerber, FlatCAMGeometry, FlatCAMExcellon, FlatCAMCNCjob, FlatCAMDocument, FlatCAMScript
 import inspect  # TODO: Remove
 import FlatCAMApp
-from PyQt5 import QtGui, QtCore, QtWidgets
-from PyQt5.QtCore import Qt, QSettings
-# import webbrowser
+
+import re
+import logging
+import collections
+from copy import deepcopy
+from numpy import Inf
 
 import gettext
 import FlatCAMTranslation as fcTranslate
@@ -27,6 +34,8 @@ fcTranslate.apply_language('strings')
 if '_' not in builtins.__dict__:
     _ = gettext.gettext
 
+log = logging.getLogger('base')
+
 
 class KeySensitiveListView(QtWidgets.QTreeView):
     """

+ 2 - 0
README.md

@@ -12,6 +12,8 @@ CAD program, and create G-Code for Isolation routing.
 15.10.2019
 
 - adjusted the layout in NCC Tool
+- fixed bug in Panelization Tool for which in case of Excellon objects, the panel kept a reference to the source object which created issues when moving or disabling/enabling the plots
+- cleaned up the module imports throughout the app (the TclCommands are not yet verified)
 
 14.10.2019
 

+ 47 - 51
camlib.py

@@ -11,12 +11,9 @@ from PyQt5 import QtWidgets
 from io import StringIO
 
 import numpy as np
-from numpy import arctan2, Inf, array, sqrt, pi, ceil, sin, cos, dot, float32, \
-    transpose
 from numpy.linalg import solve, norm
 
-import re, sys, os, platform
-import math
+import platform
 from copy import deepcopy
 
 import traceback
@@ -26,8 +23,8 @@ from rtree import index as rtindex
 from lxml import etree as ET
 
 # See: http://toblerity.org/shapely/manual.html
-from shapely.geometry import Polygon, LineString, Point, LinearRing, MultiLineString
-from shapely.geometry import MultiPoint, MultiPolygon
+from shapely.geometry import Polygon, LineString, Point, LinearRing, MultiLineString, MultiPoint, MultiPolygon
+
 from shapely.geometry import box as shply_box
 from shapely.ops import cascaded_union, unary_union, polygonize
 import shapely.affinity as affinity
@@ -64,7 +61,6 @@ import gettext
 import FlatCAMTranslation as fcTranslate
 import builtins
 
-
 fcTranslate.apply_language('strings')
 
 log = logging.getLogger('base2')
@@ -336,8 +332,8 @@ class ApertureMacro:
         points = [(0, 0)]*nverts
 
         for i in range(nverts):
-            points[i] = (x + 0.5 * dia * cos(2*pi * i/nverts),
-                         y + 0.5 * dia * sin(2*pi * i/nverts))
+            points[i] = (x + 0.5 * dia * np.cos(2*np.pi * i/nverts),
+                         y + 0.5 * dia * np.sin(2*np.pi * i/nverts))
 
         poly = Polygon(points)
         poly_rotated = affinity.rotate(poly, angle, origin=(0, 0))
@@ -637,10 +633,10 @@ class Geometry(object):
 
         def bounds_rec(obj):
             if type(obj) is list:
-                minx = Inf
-                miny = Inf
-                maxx = -Inf
-                maxy = -Inf
+                minx = np.Inf
+                miny = np.Inf
+                maxx = -np.Inf
+                maxy = -np.Inf
 
                 for k in obj:
                     if type(k) is dict:
@@ -1155,7 +1151,7 @@ class Geometry(object):
             log.debug("Image import as monochrome.")
         else:
             mask_setting = (red <= mask[1]) + (green <= mask[2]) + (blue <= mask[3])
-            total = np.zeros(red.shape, dtype=float32)
+            total = np.zeros(red.shape, dtype=np.float32)
             for band in red, green, blue:
                 total += band
             total /= 3
@@ -3298,10 +3294,10 @@ class CNCjob(Geometry):
 
         def bounds_rec(obj):
             if type(obj) is list:
-                minx = Inf
-                miny = Inf
-                maxx = -Inf
-                maxy = -Inf
+                minx = np.Inf
+                miny = np.Inf
+                maxx = -np.Inf
+                maxy = -np.Inf
 
                 for k in obj:
                     if type(k) is dict:
@@ -4049,9 +4045,9 @@ class CNCjob(Geometry):
                 arcdir = [None, None, "cw", "ccw"]
                 if current['G'] in [2, 3]:  # arc
                     center = [gobj['I'] + current['X'], gobj['J'] + current['Y']]
-                    radius = sqrt(gobj['I']**2 + gobj['J']**2)
-                    start = arctan2(-gobj['J'], -gobj['I'])
-                    stop = arctan2(-center[1] + y, -center[0] + x)
+                    radius = np.sqrt(gobj['I']**2 + gobj['J']**2)
+                    start = np.arctan2(-gobj['J'], -gobj['I'])
+                    stop = np.arctan2(-center[1] + y, -center[0] + x)
                     path += arc(center, radius, start, stop, arcdir[current['G']], int(self.steps_per_circle / 4))
 
             # Update current instruction
@@ -4710,10 +4706,10 @@ class CNCjob(Geometry):
 
         def bounds_rec(obj):
             if type(obj) is list:
-                minx = Inf
-                miny = Inf
-                maxx = -Inf
-                maxy = -Inf
+                minx = np.Inf
+                miny = np.Inf
+                maxx = -np.Inf
+                maxy = -np.Inf
 
                 for k in obj:
                     if type(k) is dict:
@@ -4742,15 +4738,15 @@ class CNCjob(Geometry):
 
             bounds_coords = bounds_rec(self.solid_geometry)
         else:
-            minx = Inf
-            miny = Inf
-            maxx = -Inf
-            maxy = -Inf
+            minx = np.Inf
+            miny = np.Inf
+            maxx = -np.Inf
+            maxy = -np.Inf
             for k, v in self.cnc_tools.items():
-                minx = Inf
-                miny = Inf
-                maxx = -Inf
-                maxy = -Inf
+                minx = np.Inf
+                miny = np.Inf
+                maxx = -np.Inf
+                maxy = -np.Inf
                 try:
                     for k in v['solid_geometry']:
                         minx_, miny_, maxx_, maxy_ = bounds_rec(k)
@@ -5186,10 +5182,10 @@ class CNCjob(Geometry):
 
 
 def get_bounds(geometry_list):
-    xmin = Inf
-    ymin = Inf
-    xmax = -Inf
-    ymax = -Inf
+    xmin = np.Inf
+    ymin = np.Inf
+    xmax = -np.Inf
+    ymax = -np.Inf
 
     for gs in geometry_list:
         try:
@@ -5229,33 +5225,33 @@ def arc(center, radius, start, stop, direction, steps_per_circ):
     da_sign = {"cw": -1.0, "ccw": 1.0}
     points = []
     if direction == "ccw" and stop <= start:
-        stop += 2 * pi
+        stop += 2 * np.pi
     if direction == "cw" and stop >= start:
-        stop -= 2 * pi
+        stop -= 2 * np.pi
     
     angle = abs(stop - start)
         
     # angle = stop-start
-    steps = max([int(ceil(angle / (2 * pi) * steps_per_circ)), 2])
+    steps = max([int(np.ceil(angle / (2 * np.pi) * steps_per_circ)), 2])
     delta_angle = da_sign[direction] * angle * 1.0 / steps
     for i in range(steps + 1):
         theta = start + delta_angle * i
-        points.append((center[0] + radius * cos(theta), center[1] + radius * sin(theta)))
+        points.append((center[0] + radius * np.cos(theta), center[1] + radius * np.sin(theta)))
     return points
 
 
 def arc2(p1, p2, center, direction, steps_per_circ):
-    r = sqrt((center[0] - p1[0]) ** 2 + (center[1] - p1[1]) ** 2)
-    start = arctan2(p1[1] - center[1], p1[0] - center[0])
-    stop = arctan2(p2[1] - center[1], p2[0] - center[0])
+    r = np.sqrt((center[0] - p1[0]) ** 2 + (center[1] - p1[1]) ** 2)
+    start = np.arctan2(p1[1] - center[1], p1[0] - center[0])
+    stop = np.arctan2(p2[1] - center[1], p2[0] - center[0])
     return arc(center, r, start, stop, direction, steps_per_circ)
 
 
 def arc_angle(start, stop, direction):
     if direction == "ccw" and stop <= start:
-        stop += 2 * pi
+        stop += 2 * np.pi
     if direction == "cw" and stop >= start:
-        stop -= 2 * pi
+        stop -= 2 * np.pi
 
     angle = abs(stop - start)
     return angle
@@ -5665,12 +5661,12 @@ def three_point_circle(p1, p2, p3):
     a2 = (p2 + p3) / 2.0
 
     # Normals
-    b1 = dot((p2 - p1), array([[0, -1], [1, 0]], dtype=float32))
-    b2 = dot((p3 - p2), array([[0, 1], [-1, 0]], dtype=float32))
+    b1 = np.dot((p2 - p1), np.array([[0, -1], [1, 0]], dtype=np.float32))
+    b2 = np.dot((p3 - p2), np.array([[0, 1], [-1, 0]], dtype=np.float32))
 
     # Params
     try:
-        T = solve(transpose(array([-b1, b2])), a1 - a2)
+        T = solve(np.transpose(np.array([-b1, b2])), a1 - a2)
     except Exception as e:
         log.debug("camlib.three_point_circle() --> %s" % str(e))
         return
@@ -5685,11 +5681,11 @@ def three_point_circle(p1, p2, p3):
 
 
 def distance(pt1, pt2):
-    return sqrt((pt1[0] - pt2[0]) ** 2 + (pt1[1] - pt2[1]) ** 2)
+    return np.sqrt((pt1[0] - pt2[0]) ** 2 + (pt1[1] - pt2[1]) ** 2)
 
 
 def distance_euclidian(x1, y1, x2, y2):
-    return sqrt((x1 - x2) ** 2 + (y1 - y2) ** 2)
+    return np.sqrt((x1 - x2) ** 2 + (y1 - y2) ** 2)
 
 
 class FlatCAMRTree(object):

+ 20 - 15
flatcamEditors/FlatCAMExcEditor.py

@@ -8,19 +8,23 @@
 from PyQt5 import QtGui, QtCore, QtWidgets
 from PyQt5.QtCore import Qt, QSettings
 
-from shapely.geometry import LineString, LinearRing, MultiLineString
-from shapely.ops import cascaded_union
-import shapely.affinity as affinity
-
-from numpy import arctan2, Inf, array, sqrt, sign, dot
-from rtree import index as rtindex
-
-from camlib import *
+from camlib import distance, arc, FlatCAMRTreeStorage
 from flatcamGUI.GUIElements import FCEntry, FCComboBox, FCTable, FCDoubleSpinner, LengthEntry, RadioSet, SpinBoxDelegate
 from flatcamEditors.FlatCAMGeoEditor import FCShapeTool, DrawTool, DrawToolShape, DrawToolUtilityShape, FlatCAMGeoEditor
 from flatcamParsers.ParseExcellon import Excellon
+import FlatCAMApp
+
+from shapely.geometry import LineString, LinearRing, MultiLineString, Polygon, MultiPolygon, Point
+import shapely.affinity as affinity
 
-from copy import copy, deepcopy
+import numpy as np
+
+from rtree import index as rtindex
+
+import traceback
+import math
+import logging
+from copy import deepcopy
 
 import gettext
 import FlatCAMTranslation as fcTranslate
@@ -30,6 +34,8 @@ fcTranslate.apply_language('strings')
 if '_' not in builtins.__dict__:
     _ = gettext.gettext
 
+log = logging.getLogger('base')
+
 
 class FCDrillAdd(FCShapeTool):
     """
@@ -3214,8 +3220,7 @@ class FlatCAMExcEditor(QtCore.QObject):
                       _("An internal error has ocurred. See Shell.\n")
                 msg += traceback.format_exc()
                 app_obj.inform.emit(msg)
-                raise
-                # raise
+                return
 
         with self.app.proc_container.new(_("Creating Excellon.")):
 
@@ -3998,10 +4003,10 @@ class FlatCAMExcEditor(QtCore.QObject):
 
 
 def get_shapely_list_bounds(geometry_list):
-    xmin = Inf
-    ymin = Inf
-    xmax = -Inf
-    ymax = -Inf
+    xmin = np.Inf
+    ymin = np.Inf
+    xmax = -np.Inf
+    ymax = -np.Inf
 
     for gs in geometry_list:
         try:

+ 62 - 68
flatcamEditors/FlatCAMGeoEditor.py

@@ -13,24 +13,26 @@
 
 from PyQt5 import QtGui, QtCore, QtWidgets
 from PyQt5.QtCore import Qt, QSettings
-from camlib import *
+
+from camlib import distance, arc, three_point_circle, Geometry, FlatCAMRTreeStorage
 from FlatCAMTool import FlatCAMTool
-from flatcamGUI.ObjectUI import LengthEntry, RadioSet
+from flatcamGUI.ObjectUI import RadioSet
+from flatcamGUI.GUIElements import OptionalInputSection, FCCheckBox, FCEntry, FCComboBox, FCTextAreaRich, \
+    FCTable, FCDoubleSpinner, FCButton, EvalEntry2, FCInputDialog
+from flatcamParsers.ParseFont import *
+import FlatCAMApp
 
 from shapely.geometry import LineString, LinearRing, MultiLineString, Polygon, MultiPolygon
-# from shapely.geometry import mapping
 from shapely.ops import cascaded_union, unary_union
 import shapely.affinity as affinity
 from shapely.geometry.polygon import orient
 
-from numpy import arctan2, Inf, array, sqrt, sign, dot
+import numpy as np
 from numpy.linalg import norm as numpy_norm
 
 from rtree import index as rtindex
-from flatcamGUI.GUIElements import OptionalInputSection, FCCheckBox, FCEntry, FCComboBox, FCTextAreaRich, \
-    FCTable, FCDoubleSpinner, FCButton, EvalEntry2, FCInputDialog
-from flatcamParsers.ParseFont import *
 
+from copy import deepcopy
 # from vispy.io import read_png
 import gettext
 import FlatCAMTranslation as fcTranslate
@@ -684,8 +686,8 @@ class TransformEditorTool(FlatCAMTool):
         self.rotate_button.set_value(_("Rotate"))
         self.rotate_button.setToolTip(
             _("Rotate the selected shape(s).\n"
-            "The point of reference is the middle of\n"
-            "the bounding box for all selected shapes.")
+              "The point of reference is the middle of\n"
+              "the bounding box for all selected shapes.")
         )
         self.rotate_button.setFixedWidth(60)
 
@@ -802,7 +804,7 @@ class TransformEditorTool(FlatCAMTool):
         self.scale_link_cb.setText(_("Link"))
         self.scale_link_cb.setToolTip(
             _("Scale the selected shape(s)\n"
-             "using the Scale Factor X for both axis."))
+              "using the Scale Factor X for both axis."))
         self.scale_link_cb.setFixedWidth(50)
 
         self.scale_zero_ref_cb = FCCheckBox()
@@ -1060,7 +1062,6 @@ class TransformEditorTool(FlatCAMTool):
                                  _("Transformation cancelled. No shape selected."))
             return
 
-
         self.draw_app.select_tool("select")
         self.app.ui.notebook.setTabText(2, "Tools")
         self.app.ui.notebook.setCurrentWidget(self.app.ui.project_tab)
@@ -1081,10 +1082,7 @@ class TransformEditorTool(FlatCAMTool):
                     self.app.inform.emit('[ERROR_NOTCL] %s' %
                                          _("Wrong value format entered, use a number."))
                     return
-        self.app.worker_task.emit({'fcn': self.on_rotate_action,
-                                       'params': [value]})
-        # self.on_rotate_action(value)
-        return
+        self.app.worker_task.emit({'fcn': self.on_rotate_action, 'params': [value]})
 
     def on_flipx(self):
         # self.on_flip("Y")
@@ -1205,13 +1203,9 @@ class TransformEditorTool(FlatCAMTool):
         axis = 'Y'
         point = (0, 0)
         if self.scale_zero_ref_cb.get_value():
-            self.app.worker_task.emit({'fcn': self.on_scale,
-                                       'params': [axis, xvalue, yvalue, point]})
-            # self.on_scale("Y", xvalue, yvalue, point=(0,0))
+            self.app.worker_task.emit({'fcn': self.on_scale, 'params': [axis, xvalue, yvalue, point]})
         else:
-            # self.on_scale("Y", xvalue, yvalue)
-            self.app.worker_task.emit({'fcn': self.on_scale,
-                                       'params': [axis, xvalue, yvalue]})
+            self.app.worker_task.emit({'fcn': self.on_scale, 'params': [axis, xvalue, yvalue]})
 
         return
 
@@ -1304,7 +1298,7 @@ class TransformEditorTool(FlatCAMTool):
 
                 except Exception as e:
                     self.app.inform.emit('[ERROR_NOTCL] %s: %s' %
-                                         (_("Rotation action was not executed"),str(e)))
+                                         (_("Rotation action was not executed"), str(e)))
                     return
 
     def on_flip(self, axis):
@@ -1664,10 +1658,10 @@ class DrawToolShape(object):
         # now it can get bounds for nested lists of objects
         def bounds_rec(shape_el):
             if type(shape_el) is list:
-                minx = Inf
-                miny = Inf
-                maxx = -Inf
-                maxy = -Inf
+                minx = np.Inf
+                miny = np.Inf
+                maxx = -np.Inf
+                maxy = -np.Inf
 
                 for k in shape_el:
                     minx_, miny_, maxx_, maxy_ = bounds_rec(k)
@@ -1904,10 +1898,10 @@ class DrawTool(object):
     def bounds(self, obj):
         def bounds_rec(o):
             if type(o) is list:
-                minx = Inf
-                miny = Inf
-                maxx = -Inf
-                maxy = -Inf
+                minx = np.Inf
+                miny = np.Inf
+                maxx = -np.Inf
+                maxy = -np.Inf
 
                 for k in o:
                     try:
@@ -1977,7 +1971,7 @@ class FCCircle(FCShapeTool):
         if len(self.points) == 1:
             p1 = self.points[0]
             p2 = data
-            radius = sqrt((p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2)
+            radius = np.sqrt((p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2)
             return DrawToolUtilityShape(Point(p1).buffer(radius, int(self.steps_per_circ / 4)))
 
         return None
@@ -2086,36 +2080,36 @@ class FCArc(FCShapeTool):
                 p1 = self.points[1]
                 p2 = data
 
-                radius = sqrt((center[0] - p1[0]) ** 2 + (center[1] - p1[1]) ** 2)
-                startangle = arctan2(p1[1] - center[1], p1[0] - center[0])
-                stopangle = arctan2(p2[1] - center[1], p2[0] - center[0])
+                radius = np.sqrt((center[0] - p1[0]) ** 2 + (center[1] - p1[1]) ** 2)
+                startangle = np.arctan2(p1[1] - center[1], p1[0] - center[0])
+                stopangle = np.arctan2(p2[1] - center[1], p2[0] - center[0])
 
                 return DrawToolUtilityShape([LineString(arc(center, radius, startangle, stopangle,
                                                             self.direction, self.steps_per_circ)),
                                              Point(center)])
 
             elif self.mode == '132':
-                p1 = array(self.points[0])
-                p3 = array(self.points[1])
-                p2 = array(data)
+                p1 = np.array(self.points[0])
+                p3 = np.array(self.points[1])
+                p2 = np.array(data)
 
                 try:
                     center, radius, t = three_point_circle(p1, p2, p3)
                 except TypeError:
                     return
 
-                direction = 'cw' if sign(t) > 0 else 'ccw'
+                direction = 'cw' if np.sign(t) > 0 else 'ccw'
 
-                startangle = arctan2(p1[1] - center[1], p1[0] - center[0])
-                stopangle = arctan2(p3[1] - center[1], p3[0] - center[0])
+                startangle = np.arctan2(p1[1] - center[1], p1[0] - center[0])
+                stopangle = np.arctan2(p3[1] - center[1], p3[0] - center[0])
 
                 return DrawToolUtilityShape([LineString(arc(center, radius, startangle, stopangle,
                                                             direction, self.steps_per_circ)),
                                              Point(center), Point(p1), Point(p3)])
 
             else:  # '12c'
-                p1 = array(self.points[0])
-                p2 = array(self.points[1])
+                p1 = np.array(self.points[0])
+                p2 = np.array(self.points[1])
 
                 # Midpoint
                 a = (p1 + p2) / 2.0
@@ -2124,7 +2118,7 @@ class FCArc(FCShapeTool):
                 c = p2 - p1
 
                 # Perpendicular vector
-                b = dot(c, array([[0, -1], [1, 0]], dtype=float32))
+                b = np.dot(c, np.array([[0, -1], [1, 0]], dtype=np.float32))
                 b /= numpy_norm(b)
 
                 # Distance
@@ -2133,14 +2127,14 @@ class FCArc(FCShapeTool):
                 # Which side? Cross product with c.
                 # cross(M-A, B-A), where line is AB and M is test point.
                 side = (data[0] - p1[0]) * c[1] - (data[1] - p1[1]) * c[0]
-                t *= sign(side)
+                t *= np.sign(side)
 
                 # Center = a + bt
                 center = a + b * t
 
                 radius = numpy_norm(center - p1)
-                startangle = arctan2(p1[1] - center[1], p1[0] - center[0])
-                stopangle = arctan2(p2[1] - center[1], p2[0] - center[0])
+                startangle = np.arctan2(p1[1] - center[1], p1[0] - center[0])
+                stopangle = np.arctan2(p2[1] - center[1], p2[0] - center[0])
 
                 return DrawToolUtilityShape([LineString(arc(center, radius, startangle, stopangle,
                                                             self.direction, self.steps_per_circ)),
@@ -2156,29 +2150,29 @@ class FCArc(FCShapeTool):
             p2 = self.points[2]
 
             radius = distance(center, p1)
-            startangle = arctan2(p1[1] - center[1], p1[0] - center[0])
-            stopangle = arctan2(p2[1] - center[1], p2[0] - center[0])
+            startangle = np.arctan2(p1[1] - center[1], p1[0] - center[0])
+            stopangle = np.arctan2(p2[1] - center[1], p2[0] - center[0])
             self.geometry = DrawToolShape(LineString(arc(center, radius, startangle, stopangle,
                                                          self.direction, self.steps_per_circ)))
 
         elif self.mode == '132':
-            p1 = array(self.points[0])
-            p3 = array(self.points[1])
-            p2 = array(self.points[2])
+            p1 = np.array(self.points[0])
+            p3 = np.array(self.points[1])
+            p2 = np.array(self.points[2])
 
             center, radius, t = three_point_circle(p1, p2, p3)
-            direction = 'cw' if sign(t) > 0 else 'ccw'
+            direction = 'cw' if np.sign(t) > 0 else 'ccw'
 
-            startangle = arctan2(p1[1] - center[1], p1[0] - center[0])
-            stopangle = arctan2(p3[1] - center[1], p3[0] - center[0])
+            startangle = np.arctan2(p1[1] - center[1], p1[0] - center[0])
+            stopangle = np.arctan2(p3[1] - center[1], p3[0] - center[0])
 
             self.geometry = DrawToolShape(LineString(arc(center, radius, startangle, stopangle,
                                                          direction, self.steps_per_circ)))
 
         else:  # self.mode == '12c'
-            p1 = array(self.points[0])
-            p2 = array(self.points[1])
-            pc = array(self.points[2])
+            p1 = np.array(self.points[0])
+            p2 = np.array(self.points[1])
+            pc = np.array(self.points[2])
 
             # Midpoint
             a = (p1 + p2) / 2.0
@@ -2187,7 +2181,7 @@ class FCArc(FCShapeTool):
             c = p2 - p1
 
             # Perpendicular vector
-            b = dot(c, array([[0, -1], [1, 0]], dtype=float32))
+            b = np.dot(c, np.array([[0, -1], [1, 0]], dtype=np.float32))
             b /= numpy_norm(b)
 
             # Distance
@@ -2196,14 +2190,14 @@ class FCArc(FCShapeTool):
             # Which side? Cross product with c.
             # cross(M-A, B-A), where line is AB and M is test point.
             side = (pc[0] - p1[0]) * c[1] - (pc[1] - p1[1]) * c[0]
-            t *= sign(side)
+            t *= np.sign(side)
 
             # Center = a + bt
             center = a + b * t
 
             radius = numpy_norm(center - p1)
-            startangle = arctan2(p1[1] - center[1], p1[0] - center[0])
-            stopangle = arctan2(p2[1] - center[1], p2[0] - center[0])
+            startangle = np.arctan2(p1[1] - center[1], p1[0] - center[0])
+            stopangle = np.arctan2(p2[1] - center[1], p2[0] - center[0])
 
             self.geometry = DrawToolShape(LineString(arc(center, radius, startangle, stopangle,
                                                          self.direction, self.steps_per_circ)))
@@ -4237,7 +4231,7 @@ class FlatCAMGeoEditor(QtCore.QObject):
         """
 
         snap_x, snap_y = (x, y)
-        snap_distance = Inf
+        snap_distance = np.Inf
 
         # # ## Object (corner?) snap
         # # ## No need for the objects, just the coordinates
@@ -4814,11 +4808,11 @@ class FlatCAMGeoEditor(QtCore.QObject):
 
 
 def distance(pt1, pt2):
-    return sqrt((pt1[0] - pt2[0]) ** 2 + (pt1[1] - pt2[1]) ** 2)
+    return np.sqrt((pt1[0] - pt2[0]) ** 2 + (pt1[1] - pt2[1]) ** 2)
 
 
 def mag(vec):
-    return sqrt(vec[0] ** 2 + vec[1] ** 2)
+    return np.sqrt(vec[0] ** 2 + vec[1] ** 2)
 
 
 def poly2rings(poly):
@@ -4826,10 +4820,10 @@ def poly2rings(poly):
 
 
 def get_shapely_list_bounds(geometry_list):
-    xmin = Inf
-    ymin = Inf
-    xmax = -Inf
-    ymax = -Inf
+    xmin = np.Inf
+    ymin = np.Inf
+    xmax = -np.Inf
+    ymax = -np.Inf
 
     for gs in geometry_list:
         try:

+ 88 - 90
flatcamEditors/FlatCAMGrbEditor.py

@@ -8,29 +8,28 @@
 from PyQt5 import QtGui, QtCore, QtWidgets
 from PyQt5.QtCore import Qt, QSettings
 
-from shapely.geometry import LineString, LinearRing, MultiLineString
-# from shapely.geometry import mapping
-from shapely.ops import cascaded_union, unary_union
+from shapely.geometry import LineString, LinearRing, MultiLineString, Point, Polygon, MultiPolygon
+from shapely.ops import cascaded_union
 import shapely.affinity as affinity
 
-from numpy import arctan2, Inf, array, sqrt, sign, dot
-from rtree import index as rtindex
 import threading
 import time
 from copy import copy, deepcopy
+import logging
 
-from camlib import *
+from camlib import distance, arc, three_point_circle
 from flatcamGUI.GUIElements import FCEntry, FCComboBox, FCTable, FCDoubleSpinner, LengthEntry, RadioSet, \
-    SpinBoxDelegate, EvalEntry, EvalEntry2, FCInputDialog, FCButton, OptionalInputSection, FCCheckBox
-from FlatCAMObj import FlatCAMGerber
-from flatcamParsers.ParseGerber import Gerber
+    EvalEntry2, FCInputDialog, FCButton, OptionalInputSection, FCCheckBox
 from FlatCAMTool import FlatCAMTool
+import FlatCAMApp
 
+import numpy as np
 from numpy.linalg import norm as numpy_norm
+import math
 
 # from vispy.io import read_png
 # import pngcanvas
-
+import traceback
 import gettext
 import FlatCAMTranslation as fcTranslate
 import builtins
@@ -39,6 +38,8 @@ fcTranslate.apply_language('strings')
 if '_' not in builtins.__dict__:
     _ = gettext.gettext
 
+log = logging.getLogger('base')
+
 
 class DrawToolShape(object):
     """
@@ -147,10 +148,10 @@ class DrawTool(object):
     def bounds(obj):
         def bounds_rec(o):
             if type(o) is list:
-                minx = Inf
-                miny = Inf
-                maxx = -Inf
-                maxy = -Inf
+                minx = np.Inf
+                miny = np.Inf
+                maxx = -np.Inf
+                maxy = -np.Inf
 
                 for k in o:
                     try:
@@ -311,13 +312,13 @@ class FCPad(FCShapeTool):
                 p4 = (point_x - self.half_width, point_y + self.half_height - self.half_width)
 
                 down_center = [point_x, point_y - self.half_height + self.half_width]
-                d_start_angle = math.pi
+                d_start_angle = np.pi
                 d_stop_angle = 0.0
                 down_arc = arc(down_center, self.half_width, d_start_angle, d_stop_angle, 'ccw', self.steps_per_circ)
 
                 up_center = [point_x, point_y + self.half_height - self.half_width]
                 u_start_angle = 0.0
-                u_stop_angle = math.pi
+                u_stop_angle = np.pi
                 up_arc = arc(up_center, self.half_width, u_start_angle, u_stop_angle, 'ccw', self.steps_per_circ)
 
                 geo.append(p1)
@@ -340,13 +341,13 @@ class FCPad(FCShapeTool):
                 p4 = (point_x - self.half_width + self.half_height, point_y + self.half_height)
 
                 left_center = [point_x - self.half_width + self.half_height, point_y]
-                d_start_angle = math.pi / 2
-                d_stop_angle = 1.5 * math.pi
+                d_start_angle = np.pi / 2
+                d_stop_angle = 1.5 * np.pi
                 left_arc = arc(left_center, self.half_height, d_start_angle, d_stop_angle, 'ccw', self.steps_per_circ)
 
                 right_center = [point_x + self.half_width - self.half_height, point_y]
-                u_start_angle = 1.5 * math.pi
-                u_stop_angle = math.pi / 2
+                u_start_angle = 1.5 * np.pi
+                u_stop_angle = np.pi / 2
                 right_arc = arc(right_center, self.half_height, u_start_angle, u_stop_angle, 'ccw', self.steps_per_circ)
 
                 geo.append(p1)
@@ -618,13 +619,13 @@ class FCPadArray(FCShapeTool):
                 p4 = (point_x - self.half_width, point_y + self.half_height - self.half_width)
 
                 down_center = [point_x, point_y - self.half_height + self.half_width]
-                d_start_angle = math.pi
+                d_start_angle = np.pi
                 d_stop_angle = 0.0
                 down_arc = arc(down_center, self.half_width, d_start_angle, d_stop_angle, 'ccw', self.steps_per_circ)
 
                 up_center = [point_x, point_y + self.half_height - self.half_width]
                 u_start_angle = 0.0
-                u_stop_angle = math.pi
+                u_stop_angle = np.pi
                 up_arc = arc(up_center, self.half_width, u_start_angle, u_stop_angle, 'ccw', self.steps_per_circ)
 
                 geo.append(p1)
@@ -647,13 +648,13 @@ class FCPadArray(FCShapeTool):
                 p4 = (point_x - self.half_width + self.half_height, point_y + self.half_height)
 
                 left_center = [point_x - self.half_width + self.half_height, point_y]
-                d_start_angle = math.pi / 2
-                d_stop_angle = 1.5 * math.pi
+                d_start_angle = np.pi / 2
+                d_stop_angle = 1.5 * np.pi
                 left_arc = arc(left_center, self.half_height, d_start_angle, d_stop_angle, 'ccw', self.steps_per_circ)
 
                 right_center = [point_x + self.half_width - self.half_height, point_y]
-                u_start_angle = 1.5 * math.pi
-                u_stop_angle = math.pi / 2
+                u_start_angle = 1.5 * np.pi
+                u_stop_angle = np.pi / 2
                 right_arc = arc(right_center, self.half_height, u_start_angle, u_stop_angle, 'ccw', self.steps_per_circ)
 
                 geo.append(p1)
@@ -1296,7 +1297,7 @@ class FCTrack(FCRegion):
                 self.draw_app.bend_mode = 2
                 self.cursor = QtGui.QCursor(QtGui.QPixmap('share/aero_path2.png'))
                 QtGui.QGuiApplication.setOverrideCursor(self.cursor)
-                msg =  _('Track Mode 2: Reverse 45 degrees ...')
+                msg = _('Track Mode 2: Reverse 45 degrees ...')
             elif self.draw_app.bend_mode == 2:
                 self.draw_app.bend_mode = 3
                 self.cursor = QtGui.QCursor(QtGui.QPixmap('share/aero_path3.png'))
@@ -1415,7 +1416,7 @@ class FCDisc(FCShapeTool):
         if len(self.points) == 1:
             p1 = self.points[0]
             p2 = data
-            radius = sqrt((p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2)
+            radius = math.sqrt((p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2)
             new_geo_el['solid'] = Point(p1).buffer((radius + self.buf_val / 2), int(self.steps_per_circ / 4))
             return DrawToolUtilityShape(new_geo_el)
 
@@ -1557,9 +1558,9 @@ class FCSemiDisc(FCShapeTool):
                 p1 = self.points[1]
                 p2 = data
 
-                radius = sqrt((center[0] - p1[0]) ** 2 + (center[1] - p1[1]) ** 2) + (self.buf_val / 2)
-                startangle = arctan2(p1[1] - center[1], p1[0] - center[0])
-                stopangle = arctan2(p2[1] - center[1], p2[0] - center[0])
+                radius = np.sqrt((center[0] - p1[0]) ** 2 + (center[1] - p1[1]) ** 2) + (self.buf_val / 2)
+                startangle = np.arctan2(p1[1] - center[1], p1[0] - center[0])
+                stopangle = np.arctan2(p2[1] - center[1], p2[0] - center[0])
 
                 new_geo_el['solid'] = LineString(
                     arc(center, radius, startangle, stopangle, self.direction, self.steps_per_circ))
@@ -1567,20 +1568,20 @@ class FCSemiDisc(FCShapeTool):
                 return DrawToolUtilityShape([new_geo_el, new_geo_el_pt1])
 
             elif self.mode == '132':
-                p1 = array(self.points[0])
-                p3 = array(self.points[1])
-                p2 = array(data)
+                p1 = np.array(self.points[0])
+                p3 = np.array(self.points[1])
+                p2 = np.array(data)
 
                 try:
                     center, radius, t = three_point_circle(p1, p2, p3)
                 except TypeError:
                     return
 
-                direction = 'cw' if sign(t) > 0 else 'ccw'
+                direction = 'cw' if np.sign(t) > 0 else 'ccw'
                 radius += (self.buf_val / 2)
 
-                startangle = arctan2(p1[1] - center[1], p1[0] - center[0])
-                stopangle = arctan2(p3[1] - center[1], p3[0] - center[0])
+                startangle = np.arctan2(p1[1] - center[1], p1[0] - center[0])
+                stopangle = np.arctan2(p3[1] - center[1], p3[0] - center[0])
 
                 new_geo_el['solid'] = LineString(
                     arc(center, radius, startangle, stopangle, direction, self.steps_per_circ))
@@ -1591,8 +1592,8 @@ class FCSemiDisc(FCShapeTool):
                 return DrawToolUtilityShape([new_geo_el, new_geo_el_pt2, new_geo_el_pt1, new_geo_el_pt3])
 
             else:  # '12c'
-                p1 = array(self.points[0])
-                p2 = array(self.points[1])
+                p1 = np.array(self.points[0])
+                p2 = np.array(self.points[1])
                 # Midpoint
                 a = (p1 + p2) / 2.0
 
@@ -1600,7 +1601,7 @@ class FCSemiDisc(FCShapeTool):
                 c = p2 - p1
 
                 # Perpendicular vector
-                b = dot(c, array([[0, -1], [1, 0]], dtype=float32))
+                b = np.dot(c, np.array([[0, -1], [1, 0]], dtype=np.float32))
                 b /= numpy_norm(b)
 
                 # Distance
@@ -1609,14 +1610,14 @@ class FCSemiDisc(FCShapeTool):
                 # Which side? Cross product with c.
                 # cross(M-A, B-A), where line is AB and M is test point.
                 side = (data[0] - p1[0]) * c[1] - (data[1] - p1[1]) * c[0]
-                t *= sign(side)
+                t *= np.sign(side)
 
                 # Center = a + bt
                 center = a + b * t
 
                 radius = numpy_norm(center - p1) + (self.buf_val / 2)
-                startangle = arctan2(p1[1] - center[1], p1[0] - center[0])
-                stopangle = arctan2(p2[1] - center[1], p2[0] - center[0])
+                startangle = np.arctan2(p1[1] - center[1], p1[0] - center[0])
+                stopangle = np.arctan2(p2[1] - center[1], p2[0] - center[0])
 
                 new_geo_el['solid'] = LineString(
                     arc(center, radius, startangle, stopangle, self.direction, self.steps_per_circ))
@@ -1636,8 +1637,8 @@ class FCSemiDisc(FCShapeTool):
             p2 = self.points[2]
 
             radius = distance(center, p1) + (self.buf_val / 2)
-            start_angle = arctan2(p1[1] - center[1], p1[0] - center[0])
-            stop_angle = arctan2(p2[1] - center[1], p2[0] - center[0])
+            start_angle = np.arctan2(p1[1] - center[1], p1[0] - center[0])
+            stop_angle = np.arctan2(p2[1] - center[1], p2[0] - center[0])
             new_geo_el['solid'] = Polygon(
                 arc(center, radius, start_angle, stop_angle, self.direction, self.steps_per_circ))
             new_geo_el['follow'] = Polygon(
@@ -1645,16 +1646,16 @@ class FCSemiDisc(FCShapeTool):
             self.geometry = DrawToolShape(new_geo_el)
 
         elif self.mode == '132':
-            p1 = array(self.points[0])
-            p3 = array(self.points[1])
-            p2 = array(self.points[2])
+            p1 = np.array(self.points[0])
+            p3 = np.array(self.points[1])
+            p2 = np.array(self.points[2])
 
             center, radius, t = three_point_circle(p1, p2, p3)
-            direction = 'cw' if sign(t) > 0 else 'ccw'
+            direction = 'cw' if np.sign(t) > 0 else 'ccw'
             radius += (self.buf_val / 2)
 
-            start_angle = arctan2(p1[1] - center[1], p1[0] - center[0])
-            stop_angle = arctan2(p3[1] - center[1], p3[0] - center[0])
+            start_angle = np.arctan2(p1[1] - center[1], p1[0] - center[0])
+            stop_angle = np.arctan2(p3[1] - center[1], p3[0] - center[0])
 
             new_geo_el['solid'] = Polygon(arc(center, radius, start_angle, stop_angle, direction, self.steps_per_circ))
             new_geo_el['follow'] = Polygon(
@@ -1662,9 +1663,9 @@ class FCSemiDisc(FCShapeTool):
             self.geometry = DrawToolShape(new_geo_el)
 
         else:  # self.mode == '12c'
-            p1 = array(self.points[0])
-            p2 = array(self.points[1])
-            pc = array(self.points[2])
+            p1 = np.array(self.points[0])
+            p2 = np.array(self.points[1])
+            pc = np.array(self.points[2])
 
             # Midpoint
             a = (p1 + p2) / 2.0
@@ -1673,7 +1674,7 @@ class FCSemiDisc(FCShapeTool):
             c = p2 - p1
 
             # Perpendicular vector
-            b = dot(c, array([[0, -1], [1, 0]], dtype=float32))
+            b = np.dot(c, np.array([[0, -1], [1, 0]], dtype=np.float32))
             b /= numpy_norm(b)
 
             # Distance
@@ -1682,14 +1683,14 @@ class FCSemiDisc(FCShapeTool):
             # Which side? Cross product with c.
             # cross(M-A, B-A), where line is AB and M is test point.
             side = (pc[0] - p1[0]) * c[1] - (pc[1] - p1[1]) * c[0]
-            t *= sign(side)
+            t *= np.sign(side)
 
             # Center = a + bt
             center = a + b * t
 
             radius = numpy_norm(center - p1) + (self.buf_val / 2)
-            start_angle = arctan2(p1[1] - center[1], p1[0] - center[0])
-            stop_angle = arctan2(p2[1] - center[1], p2[0] - center[0])
+            start_angle = np.arctan2(p1[1] - center[1], p1[0] - center[0])
+            stop_angle = np.arctan2(p2[1] - center[1], p2[0] - center[0])
 
             new_geo_el['solid'] = Polygon(
                 arc(center, radius, start_angle, stop_angle, self.direction, self.steps_per_circ))
@@ -2437,9 +2438,7 @@ class FlatCAMGrbEditor(QtCore.QObject):
         self.apertures_box.addLayout(grid1)
 
         apcode_lbl = QtWidgets.QLabel('%s:' % _('Aperture Code'))
-        apcode_lbl.setToolTip(
-        _("Code for the new aperture")
-        )
+        apcode_lbl.setToolTip(_("Code for the new aperture"))
         grid1.addWidget(apcode_lbl, 1, 0)
 
         self.apcode_entry = FCEntry()
@@ -2448,11 +2447,11 @@ class FlatCAMGrbEditor(QtCore.QObject):
 
         apsize_lbl = QtWidgets.QLabel('%s:' % _('Aperture Size'))
         apsize_lbl.setToolTip(
-        _("Size for the new aperture.\n"
-          "If aperture type is 'R' or 'O' then\n"
-          "this value is automatically\n"
-          "calculated as:\n"
-          "sqrt(width**2 + height**2)")
+            _("Size for the new aperture.\n"
+              "If aperture type is 'R' or 'O' then\n"
+              "this value is automatically\n"
+              "calculated as:\n"
+              "sqrt(width**2 + height**2)")
         )
         grid1.addWidget(apsize_lbl, 2, 0)
 
@@ -2462,10 +2461,10 @@ class FlatCAMGrbEditor(QtCore.QObject):
 
         aptype_lbl = QtWidgets.QLabel('%s:' % _('Aperture Type'))
         aptype_lbl.setToolTip(
-        _("Select the type of new aperture. Can be:\n"
-          "C = circular\n"
-          "R = rectangular\n"
-          "O = oblong")
+            _("Select the type of new aperture. Can be:\n"
+              "C = circular\n"
+              "R = rectangular\n"
+              "O = oblong")
         )
         grid1.addWidget(aptype_lbl, 3, 0)
 
@@ -2475,9 +2474,9 @@ class FlatCAMGrbEditor(QtCore.QObject):
 
         self.apdim_lbl = QtWidgets.QLabel('%s:' % _('Aperture Dim'))
         self.apdim_lbl.setToolTip(
-        _("Dimensions for the new aperture.\n"
-          "Active only for rectangular apertures (type R).\n"
-          "The format is (width, height)")
+            _("Dimensions for the new aperture.\n"
+              "Active only for rectangular apertures (type R).\n"
+              "The format is (width, height)")
         )
         grid1.addWidget(self.apdim_lbl, 4, 0)
 
@@ -2495,12 +2494,12 @@ class FlatCAMGrbEditor(QtCore.QObject):
 
         self.addaperture_btn = QtWidgets.QPushButton(_('Add'))
         self.addaperture_btn.setToolTip(
-           _( "Add a new aperture to the aperture list.")
+           _("Add a new aperture to the aperture list.")
         )
 
         self.delaperture_btn = QtWidgets.QPushButton(_('Delete'))
         self.delaperture_btn.setToolTip(
-           _( "Delete a aperture in the aperture list")
+           _("Delete a aperture in the aperture list")
         )
         hlay_ad.addWidget(self.addaperture_btn)
         hlay_ad.addWidget(self.delaperture_btn)
@@ -2677,8 +2676,8 @@ class FlatCAMGrbEditor(QtCore.QObject):
 
         self.array_type_combo = FCComboBox()
         self.array_type_combo.setToolTip(
-           _( "Select the type of pads array to create.\n"
-              "It can be Linear X(Y) or Circular")
+           _("Select the type of pads array to create.\n"
+             "It can be Linear X(Y) or Circular")
         )
         self.array_type_combo.addItem(_("Linear"))
         self.array_type_combo.addItem(_("Circular"))
@@ -2733,10 +2732,10 @@ class FlatCAMGrbEditor(QtCore.QObject):
 
         self.linear_angle_label = QtWidgets.QLabel('%s:' % _('Angle'))
         self.linear_angle_label.setToolTip(
-           _( "Angle at which the linear array is placed.\n"
-              "The precision is of max 2 decimals.\n"
-              "Min value is: -359.99 degrees.\n"
-              "Max value is:  360.00 degrees.")
+           _("Angle at which the linear array is placed.\n"
+             "The precision is of max 2 decimals.\n"
+             "Min value is: -359.99 degrees.\n"
+             "Max value is:  360.00 degrees.")
         )
         self.linear_angle_label.setMinimumWidth(100)
 
@@ -2808,9 +2807,9 @@ class FlatCAMGrbEditor(QtCore.QObject):
             "scale": {"button": self.app.ui.aperture_scale_btn,
                       "constructor": FCScale},
             "markarea": {"button": self.app.ui.aperture_markarea_btn,
-                      "constructor": FCMarkArea},
+                         "constructor": FCMarkArea},
             "eraser": {"button": self.app.ui.aperture_eraser_btn,
-                      "constructor": FCEraser},
+                       "constructor": FCEraser},
             "copy": {"button": self.app.ui.aperture_copy_btn,
                      "constructor": FCApertureCopy},
             "transform": {"button": self.app.ui.grb_transform_btn,
@@ -3245,7 +3244,7 @@ class FlatCAMGrbEditor(QtCore.QObject):
                         self.storage_dict[ap_id]['width'] = dims[0]
                         self.storage_dict[ap_id]['height'] = dims[1]
 
-                        size_val = math.sqrt((dims[0] ** 2) + (dims[1] ** 2))
+                        size_val = np.sqrt((dims[0] ** 2) + (dims[1] ** 2))
                         self.apsize_entry.set_value(size_val)
 
                     except Exception as e:
@@ -3613,7 +3612,6 @@ class FlatCAMGrbEditor(QtCore.QObject):
         self.app.ui.grb_draw_eraser.triggered.connect(self.on_eraser)
         self.app.ui.grb_draw_transformations.triggered.connect(self.on_transform)
 
-
     def disconnect_canvas_event_handlers(self):
 
         # we restore the key and mouse control to FlatCAMApp method
@@ -3803,7 +3801,7 @@ class FlatCAMGrbEditor(QtCore.QObject):
         # we subtract the big "negative" (clear) geometry from each solid polygon but only the part of clear geometry
         # that fits inside the solid. otherwise we may loose the solid
         for apid in self.gerber_obj.apertures:
-            temp_solid_geometry= []
+            temp_solid_geometry = []
             if 'geometry' in self.gerber_obj.apertures[apid]:
                 # for elem in self.gerber_obj.apertures[apid]['geometry']:
                 #     if 'solid' in elem:
@@ -6032,10 +6030,10 @@ class TransformEditorTool(FlatCAMTool):
 
 
 def get_shapely_list_bounds(geometry_list):
-    xmin = Inf
-    ymin = Inf
-    xmax = -Inf
-    ymax = -Inf
+    xmin = np.Inf
+    ymin = np.Inf
+    xmax = -np.Inf
+    ymax = -np.Inf
 
     for gs in geometry_list:
         try:

+ 3 - 1
flatcamGUI/FlatCAMGUI.py

@@ -14,6 +14,8 @@
 from flatcamGUI.PreferencesUI import *
 from matplotlib.backend_bases import KeyEvent as mpl_key_event
 
+from copy import deepcopy
+from datetime import datetime
 import gettext
 import FlatCAMTranslation as fcTranslate
 import builtins
@@ -3696,7 +3698,7 @@ class FlatCAMSystemTray(QtWidgets.QSystemTrayIcon):
 
 class BookmarkManager(QtWidgets.QWidget):
 
-    mark_rows = pyqtSignal()
+    mark_rows = QtCore.pyqtSignal()
 
     def __init__(self, app, storage, parent=None):
         super(BookmarkManager, self).__init__(parent)

+ 20 - 26
flatcamGUI/GUIElements.py

@@ -12,18 +12,14 @@
 # ##########################################################
 
 from PyQt5 import QtGui, QtCore, QtWidgets
-from PyQt5.QtCore import Qt, pyqtSignal, pyqtSlot
+from PyQt5.QtCore import Qt, pyqtSlot
 from PyQt5.QtWidgets import QTextEdit, QCompleter, QAction
-from PyQt5.QtGui import QColor, QKeySequence, QPalette, QTextCursor
+from PyQt5.QtGui import QKeySequence, QTextCursor
 
 from copy import copy
 import re
 import logging
 import html
-import webbrowser
-from copy import deepcopy
-import sys
-from datetime import datetime
 
 log = logging.getLogger('base')
 
@@ -513,7 +509,7 @@ class EvalEntry2(QtWidgets.QLineEdit):
 
 class FCSpinner(QtWidgets.QSpinBox):
 
-    returnPressed = pyqtSignal()
+    returnPressed = QtCore.pyqtSignal()
 
     def __init__(self, parent=None):
         super(FCSpinner, self).__init__(parent)
@@ -580,7 +576,7 @@ class FCSpinner(QtWidgets.QSpinBox):
 
 class FCDoubleSpinner(QtWidgets.QDoubleSpinBox):
 
-    returnPressed = pyqtSignal()
+    returnPressed = QtCore.pyqtSignal()
 
     def __init__(self, parent=None):
         super(FCDoubleSpinner, self).__init__(parent)
@@ -869,16 +865,16 @@ class FCTextAreaExtended(QtWidgets.QTextEdit):
         if self.textCursor().block().text().startswith(" "):
             # skip the white space
             self.moveCursor(QtGui.QTextCursor.NextWord)
-        self.moveCursor(QtGui.QTextCursor.NextCharacter,QtGui.QTextCursor.KeepAnchor)
+        self.moveCursor(QtGui.QTextCursor.NextCharacter, QtGui.QTextCursor.KeepAnchor)
         character = self.textCursor().selectedText()
         if character == "#":
             # delete #
             self.textCursor().deletePreviousChar()
             # delete white space 
-            self.moveCursor(QtGui.QTextCursor.NextWord,QtGui.QTextCursor.KeepAnchor)
+            self.moveCursor(QtGui.QTextCursor.NextWord, QtGui.QTextCursor.KeepAnchor)
             self.textCursor().removeSelectedText()
         else:
-            self.moveCursor(QtGui.QTextCursor.PreviousCharacter,QtGui.QTextCursor.KeepAnchor)
+            self.moveCursor(QtGui.QTextCursor.PreviousCharacter, QtGui.QTextCursor.KeepAnchor)
             self.textCursor().insertText("# ")
         cursor = QtGui.QTextCursor(self.textCursor())
         cursor.setPosition(pos)
@@ -1261,7 +1257,6 @@ class FCDetachableTab(QtWidgets.QTabWidget):
                 attached = True
                 break
 
-
         # If the tab is not attached, close it's window and
         # remove the reference to it
         if not attached:
@@ -1342,8 +1337,8 @@ class FCDetachableTab(QtWidgets.QTabWidget):
         can be re-attached by closing the dialog or by dragging the window into the tab bar
         """
 
-        onCloseSignal = pyqtSignal(QtWidgets.QWidget, str, QtGui.QIcon)
-        onDropSignal = pyqtSignal(str, QtCore.QPoint)
+        onCloseSignal = QtCore.pyqtSignal(QtWidgets.QWidget, str, QtGui.QIcon)
+        onDropSignal = QtCore.pyqtSignal(str, QtCore.QPoint)
 
         def __init__(self, name, contentWidget):
             QtWidgets.QMainWindow.__init__(self, None)
@@ -1384,7 +1379,7 @@ class FCDetachableTab(QtWidgets.QTabWidget):
             An event filter class to detect a QMainWindow drop event
             """
 
-            onDropSignal = pyqtSignal(QtCore.QPoint)
+            onDropSignal = QtCore.pyqtSignal(QtCore.QPoint)
 
             def __init__(self):
                 QtCore.QObject.__init__(self)
@@ -1416,11 +1411,11 @@ class FCDetachableTab(QtWidgets.QTabWidget):
                     return False
 
     class FCTabBar(QtWidgets.QTabBar):
-        onDetachTabSignal = pyqtSignal(int, QtCore.QPoint)
-        onMoveTabSignal = pyqtSignal(int, int)
-        detachedTabDropSignal = pyqtSignal(str, int, QtCore.QPoint)
+        onDetachTabSignal = QtCore.pyqtSignal(int, QtCore.QPoint)
+        onMoveTabSignal = QtCore.pyqtSignal(int, int)
+        detachedTabDropSignal = QtCore.pyqtSignal(str, int, QtCore.QPoint)
 
-        right_click = pyqtSignal(int)
+        right_click = QtCore.pyqtSignal(int)
 
         def __init__(self, parent=None):
             QtWidgets.QTabBar.__init__(self, parent)
@@ -1498,7 +1493,7 @@ class FCDetachableTab(QtWidgets.QTabWidget):
                 self.dragInitiated = True
 
             # If the current movement is a drag initiated by the left button
-            if (((event.buttons() & QtCore.Qt.LeftButton)) and self.dragInitiated and self.can_be_dragged):
+            if ((event.buttons() & QtCore.Qt.LeftButton)) and self.dragInitiated and self.can_be_dragged:
 
                 # Stop the move event
                 finishMoveEvent = QtGui.QMouseEvent(
@@ -1591,7 +1586,7 @@ class FCDetachableTab(QtWidgets.QTabWidget):
 
 
 class FCDetachableTab2(FCDetachableTab):
-    tab_closed_signal = pyqtSignal(object)
+    tab_closed_signal = QtCore.pyqtSignal(object)
 
     def __init__(self, protect=None, protect_by_name=None, parent=None):
         super(FCDetachableTab2, self).__init__(protect=protect, protect_by_name=protect_by_name, parent=parent)
@@ -1729,7 +1724,7 @@ class OptionalHideInputSection:
 
 class FCTable(QtWidgets.QTableWidget):
 
-    drag_drop_sig = pyqtSignal()
+    drag_drop_sig = QtCore.pyqtSignal()
 
     def __init__(self, drag_drop=False, protected_rows=None, parent=None):
         super(FCTable, self).__init__(parent)
@@ -2024,8 +2019,8 @@ class _ExpandableTextEdit(QTextEdit):
     Class implements edit line, which expands themselves automatically
     """
 
-    historyNext = pyqtSignal()
-    historyPrev = pyqtSignal()
+    historyNext = QtCore.pyqtSignal()
+    historyPrev = QtCore.pyqtSignal()
 
     def __init__(self, termwidget, *args):
         QTextEdit.__init__(self, *args)
@@ -2148,7 +2143,7 @@ class _ExpandableTextEdit(QTextEdit):
 
 
 class MyCompleter(QCompleter):
-    insertText = pyqtSignal(str)
+    insertText = QtCore.pyqtSignal(str)
 
     def __init__(self, parent=None):
         QCompleter.__init__(self)
@@ -2166,4 +2161,3 @@ class MyCompleter(QCompleter):
 
     def getSelected(self):
         return self.lastSelected
-

+ 0 - 2
flatcamGUI/ObjectUI.py

@@ -11,8 +11,6 @@
 # Date: 3/10/2019                                          #
 # ##########################################################
 
-from PyQt5 import QtGui, QtCore, QtWidgets
-from PyQt5.QtCore import Qt
 from flatcamGUI.GUIElements import *
 import sys
 

+ 1 - 1
flatcamGUI/PlotCanvasLegacy.py

@@ -7,7 +7,7 @@
 # Modified by Marius Stanciu 09/21/2019                    #
 ############################################################
 
-from PyQt5 import QtGui, QtCore, QtWidgets
+from PyQt5 import QtCore
 from PyQt5.QtCore import pyqtSignal
 
 # needed for legacy mode

+ 0 - 3
flatcamGUI/PreferencesUI.py

@@ -8,11 +8,8 @@
 from PyQt5.QtCore import QSettings
 from flatcamGUI.GUIElements import *
 import platform
-import webbrowser
 import sys
 
-from flatcamEditors.FlatCAMGeoEditor import FCShapeTool
-
 import gettext
 import FlatCAMTranslation as fcTranslate
 import builtins

+ 4 - 1
flatcamGUI/VisPyCanvas.py

@@ -6,12 +6,15 @@
 # MIT Licence                                              #
 # ##########################################################
 
-import numpy as np
 from PyQt5.QtGui import QPalette
 from PyQt5.QtCore import QSettings
+
+import numpy as np
+
 import vispy.scene as scene
 from vispy.scene.cameras.base_camera import BaseCamera
 from vispy.color import Color
+
 import time
 
 white = Color("#ffffff")

+ 0 - 1
flatcamParsers/ParseDXF_Spline.py

@@ -9,7 +9,6 @@
 # ##########################################################
 
 import math
-import sys
 
 
 def norm(v):

+ 17 - 5
flatcamParsers/ParseExcellon.py

@@ -1,4 +1,14 @@
-from camlib import *
+
+from camlib import Geometry
+import FlatCAMApp
+
+import shapely.affinity as affinity
+from shapely.geometry import Point, LineString
+import numpy as np
+
+import re
+import logging
+import traceback
 
 import FlatCAMTranslation as fcTranslate
 
@@ -8,6 +18,8 @@ import builtins
 if '_' not in builtins.__dict__:
     _ = gettext.gettext
 
+log = logging.getLogger('base')
+
 
 class Excellon(Geometry):
     """
@@ -1017,10 +1029,10 @@ class Excellon(Geometry):
 
         def bounds_rec(obj):
             if type(obj) is list:
-                minx = Inf
-                miny = Inf
-                maxx = -Inf
-                maxy = -Inf
+                minx = np.Inf
+                miny = np.Inf
+                maxx = -np.Inf
+                maxy = -np.Inf
 
                 for k in obj:
                     if type(k) is dict:

+ 2 - 3
flatcamParsers/ParseFont.py

@@ -11,12 +11,11 @@
 # ######################################################################
 
 import re, os, sys, glob
-import itertools
 
 from shapely.geometry import Point, Polygon
-from shapely.affinity import translate, scale, rotate
+from shapely.affinity import translate, scale
 from shapely.geometry import MultiPolygon
-from shapely.geometry.base import BaseGeometry
+
 
 import freetype as ft
 from fontTools import ttLib

+ 36 - 19
flatcamParsers/ParseGerber.py

@@ -1,4 +1,19 @@
-from camlib import *
+
+from camlib import Geometry, arc, arc_angle, ApertureMacro
+import FlatCAMApp
+
+import numpy as np
+import re
+import logging
+import traceback
+from copy import deepcopy
+import sys
+
+from shapely.ops import cascaded_union
+from shapely.geometry import Polygon, MultiPolygon, LineString, Point
+import shapely.affinity as affinity
+from shapely.geometry import box as shply_box
+
 import FlatCAMTranslation as fcTranslate
 
 import gettext
@@ -7,6 +22,8 @@ import builtins
 if '_' not in builtins.__dict__:
     _ = gettext.gettext
 
+log = logging.getLogger('base')
+
 
 class Gerber(Geometry):
     """
@@ -253,14 +270,14 @@ class Gerber(Geometry):
             self.apertures[apid] = {"type": "R",
                                     "width": float(paramList[0]),
                                     "height": float(paramList[1]),
-                                    "size": sqrt(float(paramList[0]) ** 2 + float(paramList[1]) ** 2)}  # Hack
+                                    "size": np.sqrt(float(paramList[0]) ** 2 + float(paramList[1]) ** 2)}  # Hack
             return apid
 
         if apertureType == "O":  # Obround
             self.apertures[apid] = {"type": "O",
                                     "width": float(paramList[0]),
                                     "height": float(paramList[1]),
-                                    "size": sqrt(float(paramList[0]) ** 2 + float(paramList[1]) ** 2)}  # Hack
+                                    "size": np.sqrt(float(paramList[0]) ** 2 + float(paramList[1]) ** 2)}  # Hack
             return apid
 
         if apertureType == "P":  # Polygon (regular)
@@ -1231,15 +1248,15 @@ class Gerber(Geometry):
 
                     if quadrant_mode == 'MULTI':
                         center = [i + current_x, j + current_y]
-                        radius = sqrt(i ** 2 + j ** 2)
-                        start = arctan2(-j, -i)  # Start angle
+                        radius = np.sqrt(i ** 2 + j ** 2)
+                        start = np.arctan2(-j, -i)  # Start angle
                         # Numerical errors might prevent start == stop therefore
                         # we check ahead of time. This should result in a
                         # 360 degree arc.
                         if current_x == circular_x and current_y == circular_y:
                             stop = start
                         else:
-                            stop = arctan2(-center[1] + circular_y, -center[0] + circular_x)  # Stop angle
+                            stop = np.arctan2(-center[1] + circular_y, -center[0] + circular_x)  # Stop angle
 
                         this_arc = arc(center, radius, start, stop,
                                        arcdir[current_interpolation_mode],
@@ -1273,10 +1290,10 @@ class Gerber(Geometry):
                         valid = False
                         log.debug("I: %f  J: %f" % (i, j))
                         for center in center_candidates:
-                            radius = sqrt(i ** 2 + j ** 2)
+                            radius = np.sqrt(i ** 2 + j ** 2)
 
                             # Make sure radius to start is the same as radius to end.
-                            radius2 = sqrt((center[0] - circular_x) ** 2 + (center[1] - circular_y) ** 2)
+                            radius2 = np.sqrt((center[0] - circular_x) ** 2 + (center[1] - circular_y) ** 2)
                             if radius2 < radius * 0.95 or radius2 > radius * 1.05:
                                 continue  # Not a valid center.
 
@@ -1284,16 +1301,16 @@ class Gerber(Geometry):
                             i = center[0] - current_x
                             j = center[1] - current_y
 
-                            start = arctan2(-j, -i)  # Start angle
-                            stop = arctan2(-center[1] + circular_y, -center[0] + circular_x)  # Stop angle
+                            start = np.arctan2(-j, -i)  # Start angle
+                            stop = np.arctan2(-center[1] + circular_y, -center[0] + circular_x)  # Stop angle
                             angle = abs(arc_angle(start, stop, arcdir[current_interpolation_mode]))
                             log.debug("ARC START: %f, %f  CENTER: %f, %f  STOP: %f, %f" %
                                       (current_x, current_y, center[0], center[1], circular_x, circular_y))
                             log.debug("START Ang: %f, STOP Ang: %f, DIR: %s, ABS: %.12f <= %.12f: %s" %
-                                      (start * 180 / pi, stop * 180 / pi, arcdir[current_interpolation_mode],
-                                       angle * 180 / pi, pi / 2 * 180 / pi, angle <= (pi + 1e-6) / 2))
+                                      (start * 180 / np.pi, stop * 180 / np.pi, arcdir[current_interpolation_mode],
+                                       angle * 180 / np.pi, np.pi / 2 * 180 / np.pi, angle <= (np.pi + 1e-6) / 2))
 
-                            if angle <= (pi + 1e-6) / 2:
+                            if angle <= (np.pi + 1e-6) / 2:
                                 log.debug("########## ACCEPTING ARC ############")
                                 this_arc = arc(center, radius, start, stop,
                                                arcdir[current_interpolation_mode],
@@ -1478,8 +1495,8 @@ class Gerber(Geometry):
             n_vertices = aperture['nVertices']
             points = []
             for i in range(0, n_vertices):
-                x = loc[0] + 0.5 * diam * (cos(2 * pi * i / n_vertices))
-                y = loc[1] + 0.5 * diam * (sin(2 * pi * i / n_vertices))
+                x = loc[0] + 0.5 * diam * (np.cos(2 * np.pi * i / n_vertices))
+                y = loc[1] + 0.5 * diam * (np.sin(2 * np.pi * i / n_vertices))
                 points.append((x, y))
             ply = Polygon(points)
             if 'rotation' in aperture:
@@ -1553,10 +1570,10 @@ class Gerber(Geometry):
 
         def bounds_rec(obj):
             if type(obj) is list and type(obj) is not MultiPolygon:
-                minx = Inf
-                miny = Inf
-                maxx = -Inf
-                maxy = -Inf
+                minx = np.Inf
+                miny = np.Inf
+                maxx = -np.Inf
+                maxy = -np.Inf
 
                 for k in obj:
                     if type(k) is dict:

+ 4 - 3
flatcamTools/ToolCalculators.py

@@ -5,8 +5,9 @@
 # MIT Licence                                              #
 # ##########################################################
 
+from PyQt5 import QtWidgets
 from FlatCAMTool import FlatCAMTool
-from FlatCAMObj import *
+from flatcamGUI.GUIElements import FCSpinner, FCDoubleSpinner, FCEntry
 import math
 
 import gettext
@@ -321,11 +322,11 @@ class ToolCalculator(FlatCAMTool):
 
     def on_calculate_inch_units(self):
         mm_val = float(self.mm_entry.get_value())
-        self.inch_entry.set_value('%.*f' % (self.decimals,(mm_val / 25.4)))
+        self.inch_entry.set_value('%.*f' % (self.decimals, (mm_val / 25.4)))
 
     def on_calculate_mm_units(self):
         inch_val = float(self.inch_entry.get_value())
-        self.mm_entry.set_value('%.*f' % (self.decimals,(inch_val * 25.4)))
+        self.mm_entry.set_value('%.*f' % (self.decimals, (inch_val * 25.4)))
 
     def on_calculate_eplate(self):
         length = float(self.pcblength_entry.get_value())

+ 14 - 3
flatcamTools/ToolCutOut.py

@@ -5,12 +5,21 @@
 # MIT Licence                                              #
 # ##########################################################
 
+from PyQt5 import QtWidgets, QtGui, QtCore
 from FlatCAMTool import FlatCAMTool
-from ObjectCollection import *
-from FlatCAMApp import *
-from shapely.geometry import box
+from flatcamGUI.GUIElements import FCDoubleSpinner, FCCheckBox, RadioSet, FCComboBox
+from FlatCAMObj import FlatCAMGerber
+
+from shapely.geometry import box, MultiPolygon, Polygon, LineString, LinearRing
 from shapely.ops import cascaded_union, unary_union
+import shapely.affinity as affinity
+
+from matplotlib.backend_bases import KeyEvent as mpl_key_event
 
+from numpy import Inf
+from copy import deepcopy
+import math
+import logging
 import gettext
 import FlatCAMTranslation as fcTranslate
 import builtins
@@ -19,6 +28,8 @@ fcTranslate.apply_language('strings')
 if '_' not in builtins.__dict__:
     _ = gettext.gettext
 
+log = logging.getLogger('base')
+
 
 class CutOut(FlatCAMTool):
 

+ 9 - 2
flatcamTools/ToolDblSided.py

@@ -1,9 +1,14 @@
+
+from PyQt5 import QtWidgets, QtCore
+
 from FlatCAMTool import FlatCAMTool
-from FlatCAMObj import *
+from flatcamGUI.GUIElements import RadioSet, FCDoubleSpinner, EvalEntry
+from FlatCAMObj import FlatCAMGerber, FlatCAMExcellon, FlatCAMGeometry
+
 from shapely.geometry import Point
 from shapely import affinity
-from PyQt5 import QtCore
 
+import logging
 import gettext
 import FlatCAMTranslation as fcTranslate
 import builtins
@@ -12,6 +17,8 @@ fcTranslate.apply_language('strings')
 if '_' not in builtins.__dict__:
     _ = gettext.gettext
 
+log = logging.getLogger('base')
+
 
 class DblSidedTool(FlatCAMTool):
 

+ 9 - 4
flatcamTools/ToolDistance.py

@@ -5,12 +5,15 @@
 # MIT Licence                                              #
 # ##########################################################
 
+from PyQt5 import QtWidgets, QtCore
+
 from FlatCAMTool import FlatCAMTool
-from FlatCAMObj import *
 from flatcamGUI.VisPyVisuals import *
+from flatcamGUI.GUIElements import FCEntry
 
-from math import sqrt
-
+import copy
+import math
+import logging
 import gettext
 import FlatCAMTranslation as fcTranslate
 import builtins
@@ -19,6 +22,8 @@ fcTranslate.apply_language('strings')
 if '_' not in builtins.__dict__:
     _ = gettext.gettext
 
+log = logging.getLogger('base')
+
 
 class Distance(FlatCAMTool):
 
@@ -335,7 +340,7 @@ class Distance(FlatCAMTool):
             elif len(self.points) == 2:
                 dx = self.points[1][0] - self.points[0][0]
                 dy = self.points[1][1] - self.points[0][1]
-                d = sqrt(dx ** 2 + dy ** 2)
+                d = math.sqrt(dx ** 2 + dy ** 2)
                 self.stop_entry.set_value("(%.*f, %.*f)" % (self.decimals, pos[0], self.decimals, pos[1]))
 
                 self.app.inform.emit(_("MEASURING: Result D(x) = {d_x} | D(y) = {d_y} | Distance = {d_z}").format(

+ 8 - 4
flatcamTools/ToolDistanceMin.py

@@ -5,14 +5,16 @@
 # MIT Licence                                              #
 # ##########################################################
 
+from PyQt5 import QtWidgets, QtCore
 from FlatCAMTool import FlatCAMTool
-from FlatCAMObj import *
 from flatcamGUI.VisPyVisuals import *
+from flatcamGUI.GUIElements import FCEntry
 
 from shapely.ops import nearest_points
+from shapely.geometry import Point
 
-from math import sqrt
-
+import math
+import logging
 import gettext
 import FlatCAMTranslation as fcTranslate
 import builtins
@@ -21,6 +23,8 @@ fcTranslate.apply_language('strings')
 if '_' not in builtins.__dict__:
     _ = gettext.gettext
 
+log = logging.getLogger('base')
+
 
 class DistanceMin(FlatCAMTool):
 
@@ -260,7 +264,7 @@ class DistanceMin(FlatCAMTool):
         except Exception as e:
             pass
 
-        d = sqrt(dx ** 2 + dy ** 2)
+        d = math.sqrt(dx ** 2 + dy ** 2)
         self.total_distance_entry.set_value('%.*f' % (self.decimals, abs(d)))
 
         self.h_point = (min(first_pos.x, last_pos.x) + (abs(dx) / 2), min(first_pos.y, last_pos.y) + (abs(dy) / 2))

+ 10 - 7
flatcamTools/ToolFilm.py

@@ -5,14 +5,15 @@
 # MIT Licence                                              #
 # ##########################################################
 
-from FlatCAMTool import FlatCAMTool
-from FlatCAMObj import *
+from PyQt5 import QtGui, QtCore, QtWidgets
 
+from FlatCAMTool import FlatCAMTool
 from flatcamGUI.GUIElements import RadioSet, FCDoubleSpinner, FCCheckBox, \
     OptionalHideInputSection, OptionalInputSection
-from PyQt5 import QtGui, QtCore, QtWidgets
 
 from copy import deepcopy
+import logging
+from shapely.geometry import Polygon, MultiPolygon, Point
 
 import gettext
 import FlatCAMTranslation as fcTranslate
@@ -22,6 +23,8 @@ fcTranslate.apply_language('strings')
 if '_' not in builtins.__dict__:
     _ = gettext.gettext
 
+log = logging.getLogger('base')
+
 
 class Film(FlatCAMTool):
 
@@ -166,7 +169,7 @@ class Film(FlatCAMTool):
         self.ois_scale = OptionalInputSection(self.film_scale_cb, [self.film_scalex_label, self.film_scalex_entry,
                                                                    self.film_scaley_label,  self.film_scaley_entry])
         # Skew Geometry
-        self.film_skew_cb =FCCheckBox('%s' % _("Skew Film geometry"))
+        self.film_skew_cb = FCCheckBox('%s' % _("Skew Film geometry"))
         self.film_skew_cb.setToolTip(
             _("Positive values will skew to the right\n"
               "while negative values will skew to the left.")
@@ -202,9 +205,9 @@ class Film(FlatCAMTool):
               "It can be one of the four points of the geometry bounding box.")
         )
         self.film_skew_reference = RadioSet([{'label': _('Bottom Left'), 'value': 'bottomleft'},
-                                          {'label': _('Top Left'), 'value': 'topleft'},
-                                          {'label': _('Bottom Right'), 'value': 'bottomright'},
-                                          {'label': _('Top right'), 'value': 'topright'}],
+                                             {'label': _('Top Left'), 'value': 'topleft'},
+                                             {'label': _('Bottom Right'), 'value': 'bottomright'},
+                                             {'label': _('Top right'), 'value': 'topright'}],
                                             orientation='vertical',
                                             stretch=False)
 

+ 2 - 2
flatcamTools/ToolImage.py

@@ -5,10 +5,10 @@
 # MIT Licence                                              #
 # ##########################################################
 
-from FlatCAMTool import FlatCAMTool
+from PyQt5 import QtGui, QtWidgets
 
+from FlatCAMTool import FlatCAMTool
 from flatcamGUI.GUIElements import RadioSet, FCComboBox, FCSpinner
-from PyQt5 import QtGui, QtWidgets
 
 import gettext
 import FlatCAMTranslation as fcTranslate

+ 6 - 3
flatcamTools/ToolMove.py

@@ -5,12 +5,13 @@
 # MIT Licence                                              #
 # ##########################################################
 
+from PyQt5 import QtWidgets, QtCore
 from FlatCAMTool import FlatCAMTool
-from FlatCAMObj import *
 from flatcamGUI.VisPyVisuals import *
+from FlatCAMObj import FlatCAMGerber
 
 from copy import copy
-
+import logging
 import gettext
 import FlatCAMTranslation as fcTranslate
 import builtins
@@ -19,11 +20,13 @@ fcTranslate.apply_language('strings')
 if '_' not in builtins.__dict__:
     _ = gettext.gettext
 
+log = logging.getLogger('base')
+
 
 class ToolMove(FlatCAMTool):
 
     toolName = _("Move")
-    replot_signal = pyqtSignal(list)
+    replot_signal = QtCore.pyqtSignal(list)
 
     def __init__(self, app):
         FlatCAMTool.__init__(self, app)

+ 26 - 6
flatcamTools/ToolNonCopperClear.py

@@ -5,12 +5,23 @@
 # MIT Licence                                              #
 # ##########################################################
 
+from PyQt5 import QtWidgets, QtCore, QtGui
 from FlatCAMTool import FlatCAMTool
-from copy import copy, deepcopy
-from ObjectCollection import *
-import time
+from flatcamGUI.GUIElements import FCCheckBox, FCDoubleSpinner, RadioSet, FCTable, FCInputDialog
+from flatcamParsers.ParseGerber import Gerber
+from FlatCAMObj import FlatCAMGeometry, FlatCAMGerber
+import FlatCAMApp
+
+from copy import deepcopy
+
+import numpy as np
+import math
 from shapely.geometry import base
+from shapely.ops import cascaded_union
+from shapely.geometry import MultiPolygon, Polygon, MultiLineString, LineString, LinearRing
 
+import logging
+import traceback
 import gettext
 import FlatCAMTranslation as fcTranslate
 import builtins
@@ -19,6 +30,8 @@ fcTranslate.apply_language('strings')
 if '_' not in builtins.__dict__:
     _ = gettext.gettext
 
+log = logging.getLogger('base')
+
 
 class NonCopperClear(FlatCAMTool, Gerber):
 
@@ -473,7 +486,7 @@ class NonCopperClear(FlatCAMTool, Gerber):
             "Add", self.on_add_tool_by_key, icon=QtGui.QIcon("share/plus16.png"))
         self.tools_table.addContextMenu(
             "Delete", lambda:
-            self.on_tool_delete(rows_to_delete=None, all=None), icon=QtGui.QIcon("share/delete32.png"))
+            self.on_tool_delete(rows_to_delete=None, all_tools=None), icon=QtGui.QIcon("share/delete32.png"))
 
         # #############################################################################
         # ########################## VARIABLES ########################################
@@ -1040,12 +1053,19 @@ class NonCopperClear(FlatCAMTool, Gerber):
                                                               "New diameter value is already in the Tool Table."))
         self.build_ui()
 
-    def on_tool_delete(self, rows_to_delete=None, all=None):
+    def on_tool_delete(self, rows_to_delete=None, all_tools=None):
+        """
+        Will delete a tool in the tool table
+
+        :param rows_to_delete: which rows to delete; can be a list
+        :param all_tools: delete all tools in the tool table
+        :return:
+        """
         self.ui_disconnect()
 
         deleted_tools_list = []
 
-        if all:
+        if all_tools:
             self.paint_tools.clear()
             self.build_ui()
             return

+ 14 - 6
flatcamTools/ToolOptimal.py

@@ -5,13 +5,19 @@
 # MIT Licence                                              #
 # ##########################################################
 
+from PyQt5 import QtWidgets, QtCore, QtGui
+
 from FlatCAMTool import FlatCAMTool
-from FlatCAMObj import *
-from shapely.geometry import Point
-from shapely import affinity
+from flatcamGUI.GUIElements import OptionalHideInputSection, FCTextArea, FCEntry, FCSpinner, FCCheckBox
+from FlatCAMObj import FlatCAMGerber
+import FlatCAMApp
+
+from shapely.geometry import MultiPolygon
 from shapely.ops import nearest_points
-from PyQt5 import QtCore
 
+import numpy as np
+
+import logging
 import gettext
 import FlatCAMTranslation as fcTranslate
 import builtins
@@ -20,13 +26,15 @@ fcTranslate.apply_language('strings')
 if '_' not in builtins.__dict__:
     _ = gettext.gettext
 
+log = logging.getLogger('base')
+
 
 class ToolOptimal(FlatCAMTool):
 
     toolName = _("Optimal Tool")
 
-    update_text = pyqtSignal(list)
-    update_sec_distances = pyqtSignal(dict)
+    update_text = QtCore.pyqtSignal(list)
+    update_sec_distances = QtCore.pyqtSignal(dict)
 
     def __init__(self, app):
         FlatCAMTool.__init__(self, app)

+ 9 - 4
flatcamTools/ToolPDF.py

@@ -5,19 +5,22 @@
 # MIT Licence                                              #
 # ##########################################################
 
+from PyQt5 import QtWidgets, QtCore
+
 from FlatCAMTool import FlatCAMTool
-from shapely.geometry import Point, Polygon, LineString
-from shapely.ops import cascaded_union, unary_union
+import FlatCAMApp
 
-from FlatCAMObj import *
+from shapely.geometry import Point, Polygon, LineString, MultiPolygon
+from shapely.ops import unary_union
 
-import math
 from copy import copy, deepcopy
 import numpy as np
 
 import zlib
 import re
 import time
+import logging
+import traceback
 
 import gettext
 import FlatCAMTranslation as fcTranslate
@@ -27,6 +30,8 @@ fcTranslate.apply_language('strings')
 if '_' not in builtins.__dict__:
     _ = gettext.gettext
 
+log = logging.getLogger('base')
+
 
 class ToolPDF(FlatCAMTool):
     """

+ 26 - 8
flatcamTools/ToolPaint.py

@@ -5,10 +5,25 @@
 # MIT Licence                                              #
 # ##########################################################
 
+from PyQt5 import QtWidgets, QtGui, QtCore
+from PyQt5.QtCore import Qt
+
 from FlatCAMTool import FlatCAMTool
-from copy import copy, deepcopy
-from ObjectCollection import *
-from shapely.geometry import base
+from copy import deepcopy
+# from ObjectCollection import *
+from flatcamParsers.ParseGerber import Gerber
+from FlatCAMObj import FlatCAMGerber, FlatCAMGeometry
+from camlib import Geometry
+from flatcamGUI.GUIElements import FCTable, FCDoubleSpinner, FCCheckBox, FCInputDialog, RadioSet
+import FlatCAMApp
+
+from shapely.geometry import base, Polygon, MultiPolygon, LinearRing
+from shapely.ops import cascaded_union
+
+import numpy as np
+from numpy import Inf
+import traceback
+import logging
 
 import gettext
 import FlatCAMTranslation as fcTranslate
@@ -18,6 +33,8 @@ fcTranslate.apply_language('strings')
 if '_' not in builtins.__dict__:
     _ = gettext.gettext
 
+log = logging.getLogger('base')
+
 
 class ToolPaint(FlatCAMTool, Gerber):
 
@@ -374,6 +391,7 @@ class ToolPaint(FlatCAMTool, Gerber):
 
         self.mm = None
         self.mp = None
+        self.mr = None
 
         self.sel_rect = []
 
@@ -641,10 +659,10 @@ class ToolPaint(FlatCAMTool, Gerber):
             for tooluid_key, tooluid_value in self.paint_tools.items():
                 if float('%.*f' % (self.decimals, tooluid_value['tooldia'])) == tool_sorted:
                     tool_id += 1
-                    id = QtWidgets.QTableWidgetItem('%d' % int(tool_id))
-                    id.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
+                    id_item = QtWidgets.QTableWidgetItem('%d' % int(tool_id))
+                    id_item.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
                     row_no = tool_id - 1
-                    self.tools_table.setItem(row_no, 0, id)  # Tool name/id
+                    self.tools_table.setItem(row_no, 0, id_item)  # Tool name/id
 
                     # Make sure that the drill diameter when in MM is with no more than 2 decimals
                     # There are no drill bits in MM with more than 2 decimals diameter
@@ -2213,7 +2231,7 @@ class ToolPaint(FlatCAMTool, Gerber):
                         log.debug("Could not Paint the polygons. %s" % str(e))
                         self.app.inform.emit('[ERROR] %s\n%s' %
                                              (_("Could not do Paint All. Try a different combination of parameters. "
-                                               "Or a different Method of paint"), str(e)))
+                                                "Or a different Method of paint"), str(e)))
                         return
 
                     pol_nr += 1
@@ -2373,7 +2391,7 @@ class ToolPaint(FlatCAMTool, Gerber):
                         log.debug("Could not Paint the polygons. %s" % str(e))
                         self.app.inform.emit('[ERROR] %s\n%s' %
                                              (_("Could not do Paint All. Try a different combination of parameters. "
-                                               "Or a different Method of paint"), str(e)))
+                                                "Or a different Method of paint"), str(e)))
                         return
 
                     pol_nr += 1

+ 31 - 13
flatcamTools/ToolPanelize.py

@@ -5,19 +5,29 @@
 # MIT Licence                                              #
 # ##########################################################
 
+from PyQt5 import QtWidgets, QtGui, QtCore
 from FlatCAMTool import FlatCAMTool
-from copy import copy, deepcopy
-from ObjectCollection import *
-import time
+
+from flatcamGUI.GUIElements import FCSpinner, FCDoubleSpinner, RadioSet, FCCheckBox, OptionalInputSection
+from FlatCAMObj import FlatCAMGeometry, FlatCAMGerber, FlatCAMExcellon
+import FlatCAMApp
+from copy import deepcopy
+# from ObjectCollection import *
+import numpy as np
+
+import shapely.affinity as affinity
 
 import gettext
 import FlatCAMTranslation as fcTranslate
 import builtins
+import logging
 
 fcTranslate.apply_language('strings')
 if '_' not in builtins.__dict__:
     _ = gettext.gettext
 
+log = logging.getLogger('base')
+
 
 class Panelize(FlatCAMTool):
 
@@ -367,15 +377,13 @@ class Panelize(FlatCAMTool):
 
         # Get source object.
         try:
-            obj = self.app.collection.get_by_name(str(name))
+            panel_obj = self.app.collection.get_by_name(str(name))
         except Exception as e:
             log.debug("Panelize.on_panelize() --> %s" % str(e))
             self.app.inform.emit('[ERROR_NOTCL] %s: %s' %
                                  (_("Could not retrieve object"), name))
             return "Could not retrieve object: %s" % name
 
-        panel_obj = obj
-
         if panel_obj is None:
             self.app.inform.emit('[ERROR_NOTCL] %s: %s' %
                                  (_("Object not found"), panel_obj))
@@ -443,6 +451,18 @@ class Panelize(FlatCAMTool):
                     rows -= 1
                     panel_lengthy = ((ymax - ymin) * rows) + (spacing_rows * (rows - 1))
 
+        if isinstance(panel_obj, FlatCAMExcellon) or isinstance(panel_obj, FlatCAMGeometry):
+            # make a copy of the panelized Excellon or Geometry tools
+            copied_tools = dict()
+            for tt, tt_val in list(panel_obj.tools.items()):
+                copied_tools[tt] = deepcopy(tt_val)
+
+        if isinstance(panel_obj, FlatCAMGerber):
+            # make a copy of the panelized Gerber apertures
+            copied_apertures = dict()
+            for tt, tt_val in list(panel_obj.apertures.items()):
+                copied_apertures[tt] = deepcopy(tt_val)
+
         def panelize_2():
             if panel_obj is not None:
                 self.app.inform.emit(_("Generating panel ... "))
@@ -452,7 +472,7 @@ class Panelize(FlatCAMTool):
                 def job_init_excellon(obj_fin, app_obj):
                     currenty = 0.0
                     self.app.progress.emit(10)
-                    obj_fin.tools = panel_obj.tools.copy()
+                    obj_fin.tools = copied_tools
                     obj_fin.drills = []
                     obj_fin.slots = []
                     obj_fin.solid_geometry = []
@@ -472,7 +492,6 @@ class Panelize(FlatCAMTool):
                         currentx = 0.0
                         for col in range(columns):
                             element += 1
-                            disp_number = 0
                             old_disp_number = 0
 
                             if panel_obj.drills:
@@ -493,7 +512,7 @@ class Panelize(FlatCAMTool):
                                     drill_nr += 1
                                     disp_number = int(np.interp(drill_nr, [0, geo_len_drills], [0, 100]))
 
-                                    if disp_number > old_disp_number and disp_number <= 100:
+                                    if old_disp_number < disp_number <= 100:
                                         self.app.proc_container.update_view_text(' %s: %d D:%d%%' %
                                                                                  (_("Copy"),
                                                                                   int(element),
@@ -520,7 +539,7 @@ class Panelize(FlatCAMTool):
                                     slot_nr += 1
                                     disp_number = int(np.interp(slot_nr, [0, geo_len_slots], [0, 100]))
 
-                                    if disp_number > old_disp_number and disp_number <= 100:
+                                    if old_disp_number < disp_number <= 100:
                                         self.app.proc_container.update_view_text(' %s: %d S:%d%%' %
                                                                                  (_("Copy"),
                                                                                   int(element),
@@ -557,12 +576,12 @@ class Panelize(FlatCAMTool):
                     # create the initial structure on which to create the panel
                     if isinstance(panel_obj, FlatCAMGeometry):
                         obj_fin.multigeo = panel_obj.multigeo
-                        obj_fin.tools = deepcopy(panel_obj.tools)
+                        obj_fin.tools = copied_tools
                         if panel_obj.multigeo is True:
                             for tool in panel_obj.tools:
                                 obj_fin.tools[tool]['solid_geometry'][:] = []
                     elif isinstance(panel_obj, FlatCAMGerber):
-                        obj_fin.apertures = deepcopy(panel_obj.apertures)
+                        obj_fin.apertures = copied_apertures
                         for ap in obj_fin.apertures:
                             obj_fin.apertures[ap]['geometry'] = list()
 
@@ -594,7 +613,6 @@ class Panelize(FlatCAMTool):
 
                         for col in range(columns):
                             element += 1
-                            disp_number = 0
                             old_disp_number = 0
 
                             if isinstance(panel_obj, FlatCAMGeometry):

+ 4 - 4
flatcamTools/ToolPcbWizard.py

@@ -5,11 +5,11 @@
 # MIT Licence                                              #
 # ##########################################################
 
+from PyQt5 import QtWidgets, QtCore
+
 from FlatCAMTool import FlatCAMTool
+from flatcamGUI.GUIElements import RadioSet, FCSpinner, FCButton, FCTable
 
-from flatcamGUI.GUIElements import RadioSet, FCComboBox, FCSpinner, FCButton, FCTable
-from PyQt5 import QtGui, QtWidgets, QtCore
-from PyQt5.QtCore import pyqtSignal
 import re
 import os
 from datetime import datetime
@@ -26,7 +26,7 @@ if '_' not in builtins.__dict__:
 
 class PcbWizard(FlatCAMTool):
 
-    file_loaded = pyqtSignal(str, str)
+    file_loaded = QtCore.pyqtSignal(str, str)
 
     toolName = _("PcbWizard Import Tool")
 

+ 19 - 13
flatcamTools/ToolProperties.py

@@ -6,10 +6,14 @@
 # ##########################################################
 
 from PyQt5 import QtGui, QtCore, QtWidgets
-from PyQt5.QtCore import Qt
 from FlatCAMTool import FlatCAMTool
-from FlatCAMObj import *
+from FlatCAMObj import FlatCAMCNCjob
 
+from shapely.geometry import MultiPolygon, Polygon
+from shapely.ops import cascaded_union
+
+from copy import deepcopy
+import logging
 import gettext
 import FlatCAMTranslation as fcTranslate
 import builtins
@@ -18,11 +22,13 @@ fcTranslate.apply_language('strings')
 if '_' not in builtins.__dict__:
     _ = gettext.gettext
 
+log = logging.getLogger('base')
+
 
 class Properties(FlatCAMTool):
     toolName = _("Properties")
 
-    calculations_finished = pyqtSignal(float, float, float, float, object)
+    calculations_finished = QtCore.pyqtSignal(float, float, float, float, object)
 
     def __init__(self, app):
         FlatCAMTool.__init__(self, app)
@@ -150,18 +156,18 @@ class Properties(FlatCAMTool):
 
         self.addChild(obj_name, [obj.options['name']])
 
-        def job_thread(obj):
+        def job_thread(obj_prop):
             proc = self.app.proc_container.new(_("Calculating dimensions ... Please wait."))
 
             length = 0.0
             width = 0.0
             area = 0.0
 
-            geo = obj.solid_geometry
+            geo = obj_prop.solid_geometry
             if geo:
                 # calculate physical dimensions
                 try:
-                    xmin, ymin, xmax, ymax = obj.bounds()
+                    xmin, ymin, xmax, ymax = obj_prop.bounds()
 
                     length = abs(xmax - xmin)
                     width = abs(ymax - ymin)
@@ -179,9 +185,9 @@ class Properties(FlatCAMTool):
                 xmax = []
                 ymax = []
 
-                for tool in obj.tools:
+                for tool_k in obj_prop.tools:
                     try:
-                        x0, y0, x1, y1 = cascaded_union(obj.tools[tool]['solid_geometry']).bounds
+                        x0, y0, x1, y1 = cascaded_union(obj_prop.tools[tool_k]['solid_geometry']).bounds
                         xmin.append(x0)
                         ymin.append(y0)
                         xmax.append(x1)
@@ -207,25 +213,25 @@ class Properties(FlatCAMTool):
                     log.debug("Properties.addItems() --> %s" % str(e))
 
             area_chull = 0.0
-            if not isinstance(obj, FlatCAMCNCjob):
+            if not isinstance(obj_prop, FlatCAMCNCjob):
                 # calculate and add convex hull area
                 if geo:
                     if isinstance(geo, MultiPolygon):
                         env_obj = geo.convex_hull
                     elif (isinstance(geo, MultiPolygon) and len(geo) == 1) or \
                             (isinstance(geo, list) and len(geo) == 1) and isinstance(geo[0], Polygon):
-                        env_obj = cascaded_union(obj.solid_geometry)
+                        env_obj = cascaded_union(obj_prop.solid_geometry)
                         env_obj = env_obj.convex_hull
                     else:
-                        env_obj = cascaded_union(obj.solid_geometry)
+                        env_obj = cascaded_union(obj_prop.solid_geometry)
                         env_obj = env_obj.convex_hull
 
                     area_chull = env_obj.area
                 else:
                     try:
                         area_chull = []
-                        for tool in obj.tools:
-                            area_el = cascaded_union(obj.tools[tool]['solid_geometry']).convex_hull
+                        for tool_k in obj_prop.tools:
+                            area_el = cascaded_union(obj_prop.tools[tool_k]['solid_geometry']).convex_hull
                             area_chull.append(area_el.area)
                         area_chull = max(area_chull)
                     except Exception as e:

+ 11 - 6
flatcamTools/ToolRulesCheck.py

@@ -5,15 +5,18 @@
 # MIT Licence                                              #
 # ##########################################################
 
+from PyQt5 import QtWidgets
+
 from FlatCAMTool import FlatCAMTool
-from copy import copy, deepcopy
-from ObjectCollection import *
-import time
+from flatcamGUI.GUIElements import FCDoubleSpinner, FCCheckBox, OptionalInputSection
+from copy import deepcopy
+
 from FlatCAMPool import *
-from os import getpid
+# from os import getpid
 from shapely.ops import nearest_points
-from shapely.geometry.base import BaseGeometry
+from shapely.geometry import MultiPolygon, Polygon
 
+import logging
 import gettext
 import FlatCAMTranslation as fcTranslate
 import builtins
@@ -22,12 +25,14 @@ fcTranslate.apply_language('strings')
 if '_' not in builtins.__dict__:
     _ = gettext.gettext
 
+log = logging.getLogger('base')
+
 
 class RulesCheck(FlatCAMTool):
 
     toolName = _("Check Rules")
 
-    tool_finished = pyqtSignal(list)
+    tool_finished = QtCore.pyqtSignal(list)
 
     def __init__(self, app):
         super(RulesCheck, self).__init__(self)

+ 1 - 1
flatcamTools/ToolShell.py

@@ -6,7 +6,7 @@
 # MIT Licence                                              #
 # ##########################################################
 
-# from PyQt5.QtCore import pyqtSignal
+
 from PyQt5.QtCore import Qt
 from PyQt5.QtGui import QTextCursor
 from PyQt5.QtWidgets import QVBoxLayout, QWidget

+ 11 - 3
flatcamTools/ToolSub.py

@@ -5,12 +5,18 @@
 # MIT Licence                                              #
 # ##########################################################
 
+from PyQt5 import QtWidgets, QtCore
 
 from FlatCAMTool import FlatCAMTool
-# from copy import copy, deepcopy
-from ObjectCollection import *
-import time
+from flatcamGUI.GUIElements import FCCheckBox, FCButton
+
+from shapely.geometry import Polygon, MultiPolygon, MultiLineString, LineString
+from shapely.ops import cascaded_union
 
+import traceback
+from copy import deepcopy
+import time
+import logging
 import gettext
 import FlatCAMTranslation as fcTranslate
 import builtins
@@ -19,6 +25,8 @@ fcTranslate.apply_language('strings')
 if '_' not in builtins.__dict__:
     _ = gettext.gettext
 
+log = logging.getLogger('base')
+
 
 class ToolSub(FlatCAMTool):
 

+ 5 - 3
flatcamTools/ToolTransform.py

@@ -5,8 +5,10 @@
 # MIT Licence                                              #
 # ##########################################################
 
+from PyQt5 import QtWidgets
 from FlatCAMTool import FlatCAMTool
-from FlatCAMObj import *
+from flatcamGUI.GUIElements import FCDoubleSpinner, FCCheckBox, FCButton, OptionalInputSection, EvalEntry2
+from FlatCAMObj import FlatCAMCNCjob
 
 import gettext
 import FlatCAMTranslation as fcTranslate
@@ -271,7 +273,7 @@ class ToolTransform(FlatCAMTool):
             _("Flip the selected object(s) over the X axis.")
         )
 
-        hlay0= QtWidgets.QHBoxLayout()
+        hlay0 = QtWidgets.QHBoxLayout()
         self.transform_lay.addLayout(hlay0)
 
         hlay0.addWidget(self.flipx_button)
@@ -312,7 +314,7 @@ class ToolTransform(FlatCAMTool):
 
         self.ois_flip = OptionalInputSection(self.flip_ref_cb, [self.flip_ref_entry, self.flip_ref_button], logic=True)
 
-        hlay1= QtWidgets.QHBoxLayout()
+        hlay1 = QtWidgets.QHBoxLayout()
         self.transform_lay.addLayout(hlay1)
 
         hlay1.addWidget(self.flip_ref_label)