Просмотр исходного кода

- 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 лет назад
Родитель
Сommit
dfc0b98181

+ 5 - 1
FlatCAMApp.py

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

+ 16 - 7
FlatCAMObj.py

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

+ 0 - 2
FlatCAMPostProc.py

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

+ 13 - 4
ObjectCollection.py

@@ -11,13 +11,20 @@
 # File modified by: Marius Stanciu                         #
 # 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 PyQt5.QtCore import QModelIndex
-from FlatCAMObj import *
+
+from FlatCAMObj import FlatCAMGerber, FlatCAMGeometry, FlatCAMExcellon, FlatCAMCNCjob, FlatCAMDocument, FlatCAMScript
 import inspect  # TODO: Remove
 import inspect  # TODO: Remove
 import FlatCAMApp
 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 gettext
 import FlatCAMTranslation as fcTranslate
 import FlatCAMTranslation as fcTranslate
@@ -27,6 +34,8 @@ fcTranslate.apply_language('strings')
 if '_' not in builtins.__dict__:
 if '_' not in builtins.__dict__:
     _ = gettext.gettext
     _ = gettext.gettext
 
 
+log = logging.getLogger('base')
+
 
 
 class KeySensitiveListView(QtWidgets.QTreeView):
 class KeySensitiveListView(QtWidgets.QTreeView):
     """
     """

+ 2 - 0
README.md

@@ -12,6 +12,8 @@ CAD program, and create G-Code for Isolation routing.
 15.10.2019
 15.10.2019
 
 
 - adjusted the layout in NCC Tool
 - 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
 14.10.2019
 
 

+ 47 - 51
camlib.py

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

+ 20 - 15
flatcamEditors/FlatCAMExcEditor.py

@@ -8,19 +8,23 @@
 from PyQt5 import QtGui, QtCore, QtWidgets
 from PyQt5 import QtGui, QtCore, QtWidgets
 from PyQt5.QtCore import Qt, QSettings
 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 flatcamGUI.GUIElements import FCEntry, FCComboBox, FCTable, FCDoubleSpinner, LengthEntry, RadioSet, SpinBoxDelegate
 from flatcamEditors.FlatCAMGeoEditor import FCShapeTool, DrawTool, DrawToolShape, DrawToolUtilityShape, FlatCAMGeoEditor
 from flatcamEditors.FlatCAMGeoEditor import FCShapeTool, DrawTool, DrawToolShape, DrawToolUtilityShape, FlatCAMGeoEditor
 from flatcamParsers.ParseExcellon import Excellon
 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 gettext
 import FlatCAMTranslation as fcTranslate
 import FlatCAMTranslation as fcTranslate
@@ -30,6 +34,8 @@ fcTranslate.apply_language('strings')
 if '_' not in builtins.__dict__:
 if '_' not in builtins.__dict__:
     _ = gettext.gettext
     _ = gettext.gettext
 
 
+log = logging.getLogger('base')
+
 
 
 class FCDrillAdd(FCShapeTool):
 class FCDrillAdd(FCShapeTool):
     """
     """
@@ -3214,8 +3220,7 @@ class FlatCAMExcEditor(QtCore.QObject):
                       _("An internal error has ocurred. See Shell.\n")
                       _("An internal error has ocurred. See Shell.\n")
                 msg += traceback.format_exc()
                 msg += traceback.format_exc()
                 app_obj.inform.emit(msg)
                 app_obj.inform.emit(msg)
-                raise
-                # raise
+                return
 
 
         with self.app.proc_container.new(_("Creating Excellon.")):
         with self.app.proc_container.new(_("Creating Excellon.")):
 
 
@@ -3998,10 +4003,10 @@ class FlatCAMExcEditor(QtCore.QObject):
 
 
 
 
 def get_shapely_list_bounds(geometry_list):
 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:
     for gs in geometry_list:
         try:
         try:

+ 62 - 68
flatcamEditors/FlatCAMGeoEditor.py

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

+ 88 - 90
flatcamEditors/FlatCAMGrbEditor.py

@@ -8,29 +8,28 @@
 from PyQt5 import QtGui, QtCore, QtWidgets
 from PyQt5 import QtGui, QtCore, QtWidgets
 from PyQt5.QtCore import Qt, QSettings
 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
 import shapely.affinity as affinity
 
 
-from numpy import arctan2, Inf, array, sqrt, sign, dot
-from rtree import index as rtindex
 import threading
 import threading
 import time
 import time
 from copy import copy, deepcopy
 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, \
 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
 from FlatCAMTool import FlatCAMTool
+import FlatCAMApp
 
 
+import numpy as np
 from numpy.linalg import norm as numpy_norm
 from numpy.linalg import norm as numpy_norm
+import math
 
 
 # from vispy.io import read_png
 # from vispy.io import read_png
 # import pngcanvas
 # import pngcanvas
-
+import traceback
 import gettext
 import gettext
 import FlatCAMTranslation as fcTranslate
 import FlatCAMTranslation as fcTranslate
 import builtins
 import builtins
@@ -39,6 +38,8 @@ fcTranslate.apply_language('strings')
 if '_' not in builtins.__dict__:
 if '_' not in builtins.__dict__:
     _ = gettext.gettext
     _ = gettext.gettext
 
 
+log = logging.getLogger('base')
+
 
 
 class DrawToolShape(object):
 class DrawToolShape(object):
     """
     """
@@ -147,10 +148,10 @@ class DrawTool(object):
     def bounds(obj):
     def bounds(obj):
         def bounds_rec(o):
         def bounds_rec(o):
             if type(o) is list:
             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:
                 for k in o:
                     try:
                     try:
@@ -311,13 +312,13 @@ class FCPad(FCShapeTool):
                 p4 = (point_x - self.half_width, point_y + self.half_height - self.half_width)
                 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]
                 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
                 d_stop_angle = 0.0
                 down_arc = arc(down_center, self.half_width, d_start_angle, d_stop_angle, 'ccw', self.steps_per_circ)
                 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]
                 up_center = [point_x, point_y + self.half_height - self.half_width]
                 u_start_angle = 0.0
                 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)
                 up_arc = arc(up_center, self.half_width, u_start_angle, u_stop_angle, 'ccw', self.steps_per_circ)
 
 
                 geo.append(p1)
                 geo.append(p1)
@@ -340,13 +341,13 @@ class FCPad(FCShapeTool):
                 p4 = (point_x - self.half_width + self.half_height, point_y + self.half_height)
                 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]
                 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)
                 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]
                 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)
                 right_arc = arc(right_center, self.half_height, u_start_angle, u_stop_angle, 'ccw', self.steps_per_circ)
 
 
                 geo.append(p1)
                 geo.append(p1)
@@ -618,13 +619,13 @@ class FCPadArray(FCShapeTool):
                 p4 = (point_x - self.half_width, point_y + self.half_height - self.half_width)
                 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]
                 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
                 d_stop_angle = 0.0
                 down_arc = arc(down_center, self.half_width, d_start_angle, d_stop_angle, 'ccw', self.steps_per_circ)
                 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]
                 up_center = [point_x, point_y + self.half_height - self.half_width]
                 u_start_angle = 0.0
                 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)
                 up_arc = arc(up_center, self.half_width, u_start_angle, u_stop_angle, 'ccw', self.steps_per_circ)
 
 
                 geo.append(p1)
                 geo.append(p1)
@@ -647,13 +648,13 @@ class FCPadArray(FCShapeTool):
                 p4 = (point_x - self.half_width + self.half_height, point_y + self.half_height)
                 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]
                 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)
                 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]
                 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)
                 right_arc = arc(right_center, self.half_height, u_start_angle, u_stop_angle, 'ccw', self.steps_per_circ)
 
 
                 geo.append(p1)
                 geo.append(p1)
@@ -1296,7 +1297,7 @@ class FCTrack(FCRegion):
                 self.draw_app.bend_mode = 2
                 self.draw_app.bend_mode = 2
                 self.cursor = QtGui.QCursor(QtGui.QPixmap('share/aero_path2.png'))
                 self.cursor = QtGui.QCursor(QtGui.QPixmap('share/aero_path2.png'))
                 QtGui.QGuiApplication.setOverrideCursor(self.cursor)
                 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:
             elif self.draw_app.bend_mode == 2:
                 self.draw_app.bend_mode = 3
                 self.draw_app.bend_mode = 3
                 self.cursor = QtGui.QCursor(QtGui.QPixmap('share/aero_path3.png'))
                 self.cursor = QtGui.QCursor(QtGui.QPixmap('share/aero_path3.png'))
@@ -1415,7 +1416,7 @@ class FCDisc(FCShapeTool):
         if len(self.points) == 1:
         if len(self.points) == 1:
             p1 = self.points[0]
             p1 = self.points[0]
             p2 = data
             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))
             new_geo_el['solid'] = Point(p1).buffer((radius + self.buf_val / 2), int(self.steps_per_circ / 4))
             return DrawToolUtilityShape(new_geo_el)
             return DrawToolUtilityShape(new_geo_el)
 
 
@@ -1557,9 +1558,9 @@ class FCSemiDisc(FCShapeTool):
                 p1 = self.points[1]
                 p1 = self.points[1]
                 p2 = data
                 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(
                 new_geo_el['solid'] = LineString(
                     arc(center, radius, startangle, stopangle, self.direction, self.steps_per_circ))
                     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])
                 return DrawToolUtilityShape([new_geo_el, new_geo_el_pt1])
 
 
             elif self.mode == '132':
             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:
                 try:
                     center, radius, t = three_point_circle(p1, p2, p3)
                     center, radius, t = three_point_circle(p1, p2, p3)
                 except TypeError:
                 except TypeError:
                     return
                     return
 
 
-                direction = 'cw' if sign(t) > 0 else 'ccw'
+                direction = 'cw' if np.sign(t) > 0 else 'ccw'
                 radius += (self.buf_val / 2)
                 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(
                 new_geo_el['solid'] = LineString(
                     arc(center, radius, startangle, stopangle, direction, self.steps_per_circ))
                     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])
                 return DrawToolUtilityShape([new_geo_el, new_geo_el_pt2, new_geo_el_pt1, new_geo_el_pt3])
 
 
             else:  # '12c'
             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
                 # Midpoint
                 a = (p1 + p2) / 2.0
                 a = (p1 + p2) / 2.0
 
 
@@ -1600,7 +1601,7 @@ class FCSemiDisc(FCShapeTool):
                 c = p2 - p1
                 c = p2 - p1
 
 
                 # Perpendicular vector
                 # 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)
                 b /= numpy_norm(b)
 
 
                 # Distance
                 # Distance
@@ -1609,14 +1610,14 @@ class FCSemiDisc(FCShapeTool):
                 # Which side? Cross product with c.
                 # Which side? Cross product with c.
                 # cross(M-A, B-A), where line is AB and M is test point.
                 # 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]
                 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 + bt
                 center = a + b * t
                 center = a + b * t
 
 
                 radius = numpy_norm(center - p1) + (self.buf_val / 2)
                 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(
                 new_geo_el['solid'] = LineString(
                     arc(center, radius, startangle, stopangle, self.direction, self.steps_per_circ))
                     arc(center, radius, startangle, stopangle, self.direction, self.steps_per_circ))
@@ -1636,8 +1637,8 @@ class FCSemiDisc(FCShapeTool):
             p2 = self.points[2]
             p2 = self.points[2]
 
 
             radius = distance(center, p1) + (self.buf_val / 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(
             new_geo_el['solid'] = Polygon(
                 arc(center, radius, start_angle, stop_angle, self.direction, self.steps_per_circ))
                 arc(center, radius, start_angle, stop_angle, self.direction, self.steps_per_circ))
             new_geo_el['follow'] = Polygon(
             new_geo_el['follow'] = Polygon(
@@ -1645,16 +1646,16 @@ class FCSemiDisc(FCShapeTool):
             self.geometry = DrawToolShape(new_geo_el)
             self.geometry = DrawToolShape(new_geo_el)
 
 
         elif self.mode == '132':
         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)
             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)
             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['solid'] = Polygon(arc(center, radius, start_angle, stop_angle, direction, self.steps_per_circ))
             new_geo_el['follow'] = Polygon(
             new_geo_el['follow'] = Polygon(
@@ -1662,9 +1663,9 @@ class FCSemiDisc(FCShapeTool):
             self.geometry = DrawToolShape(new_geo_el)
             self.geometry = DrawToolShape(new_geo_el)
 
 
         else:  # self.mode == '12c'
         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
             # Midpoint
             a = (p1 + p2) / 2.0
             a = (p1 + p2) / 2.0
@@ -1673,7 +1674,7 @@ class FCSemiDisc(FCShapeTool):
             c = p2 - p1
             c = p2 - p1
 
 
             # Perpendicular vector
             # 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)
             b /= numpy_norm(b)
 
 
             # Distance
             # Distance
@@ -1682,14 +1683,14 @@ class FCSemiDisc(FCShapeTool):
             # Which side? Cross product with c.
             # Which side? Cross product with c.
             # cross(M-A, B-A), where line is AB and M is test point.
             # 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]
             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 + bt
             center = a + b * t
             center = a + b * t
 
 
             radius = numpy_norm(center - p1) + (self.buf_val / 2)
             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(
             new_geo_el['solid'] = Polygon(
                 arc(center, radius, start_angle, stop_angle, self.direction, self.steps_per_circ))
                 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)
         self.apertures_box.addLayout(grid1)
 
 
         apcode_lbl = QtWidgets.QLabel('%s:' % _('Aperture Code'))
         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)
         grid1.addWidget(apcode_lbl, 1, 0)
 
 
         self.apcode_entry = FCEntry()
         self.apcode_entry = FCEntry()
@@ -2448,11 +2447,11 @@ class FlatCAMGrbEditor(QtCore.QObject):
 
 
         apsize_lbl = QtWidgets.QLabel('%s:' % _('Aperture Size'))
         apsize_lbl = QtWidgets.QLabel('%s:' % _('Aperture Size'))
         apsize_lbl.setToolTip(
         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)
         grid1.addWidget(apsize_lbl, 2, 0)
 
 
@@ -2462,10 +2461,10 @@ class FlatCAMGrbEditor(QtCore.QObject):
 
 
         aptype_lbl = QtWidgets.QLabel('%s:' % _('Aperture Type'))
         aptype_lbl = QtWidgets.QLabel('%s:' % _('Aperture Type'))
         aptype_lbl.setToolTip(
         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)
         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 = QtWidgets.QLabel('%s:' % _('Aperture Dim'))
         self.apdim_lbl.setToolTip(
         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)
         grid1.addWidget(self.apdim_lbl, 4, 0)
 
 
@@ -2495,12 +2494,12 @@ class FlatCAMGrbEditor(QtCore.QObject):
 
 
         self.addaperture_btn = QtWidgets.QPushButton(_('Add'))
         self.addaperture_btn = QtWidgets.QPushButton(_('Add'))
         self.addaperture_btn.setToolTip(
         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 = QtWidgets.QPushButton(_('Delete'))
         self.delaperture_btn.setToolTip(
         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.addaperture_btn)
         hlay_ad.addWidget(self.delaperture_btn)
         hlay_ad.addWidget(self.delaperture_btn)
@@ -2677,8 +2676,8 @@ class FlatCAMGrbEditor(QtCore.QObject):
 
 
         self.array_type_combo = FCComboBox()
         self.array_type_combo = FCComboBox()
         self.array_type_combo.setToolTip(
         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(_("Linear"))
         self.array_type_combo.addItem(_("Circular"))
         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 = QtWidgets.QLabel('%s:' % _('Angle'))
         self.linear_angle_label.setToolTip(
         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)
         self.linear_angle_label.setMinimumWidth(100)
 
 
@@ -2808,9 +2807,9 @@ class FlatCAMGrbEditor(QtCore.QObject):
             "scale": {"button": self.app.ui.aperture_scale_btn,
             "scale": {"button": self.app.ui.aperture_scale_btn,
                       "constructor": FCScale},
                       "constructor": FCScale},
             "markarea": {"button": self.app.ui.aperture_markarea_btn,
             "markarea": {"button": self.app.ui.aperture_markarea_btn,
-                      "constructor": FCMarkArea},
+                         "constructor": FCMarkArea},
             "eraser": {"button": self.app.ui.aperture_eraser_btn,
             "eraser": {"button": self.app.ui.aperture_eraser_btn,
-                      "constructor": FCEraser},
+                       "constructor": FCEraser},
             "copy": {"button": self.app.ui.aperture_copy_btn,
             "copy": {"button": self.app.ui.aperture_copy_btn,
                      "constructor": FCApertureCopy},
                      "constructor": FCApertureCopy},
             "transform": {"button": self.app.ui.grb_transform_btn,
             "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]['width'] = dims[0]
                         self.storage_dict[ap_id]['height'] = dims[1]
                         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)
                         self.apsize_entry.set_value(size_val)
 
 
                     except Exception as e:
                     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_eraser.triggered.connect(self.on_eraser)
         self.app.ui.grb_draw_transformations.triggered.connect(self.on_transform)
         self.app.ui.grb_draw_transformations.triggered.connect(self.on_transform)
 
 
-
     def disconnect_canvas_event_handlers(self):
     def disconnect_canvas_event_handlers(self):
 
 
         # we restore the key and mouse control to FlatCAMApp method
         # 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
         # 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
         # that fits inside the solid. otherwise we may loose the solid
         for apid in self.gerber_obj.apertures:
         for apid in self.gerber_obj.apertures:
-            temp_solid_geometry= []
+            temp_solid_geometry = []
             if 'geometry' in self.gerber_obj.apertures[apid]:
             if 'geometry' in self.gerber_obj.apertures[apid]:
                 # for elem in self.gerber_obj.apertures[apid]['geometry']:
                 # for elem in self.gerber_obj.apertures[apid]['geometry']:
                 #     if 'solid' in elem:
                 #     if 'solid' in elem:
@@ -6032,10 +6030,10 @@ class TransformEditorTool(FlatCAMTool):
 
 
 
 
 def get_shapely_list_bounds(geometry_list):
 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:
     for gs in geometry_list:
         try:
         try:

+ 3 - 1
flatcamGUI/FlatCAMGUI.py

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

+ 20 - 26
flatcamGUI/GUIElements.py

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

+ 0 - 2
flatcamGUI/ObjectUI.py

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

+ 1 - 1
flatcamGUI/PlotCanvasLegacy.py

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

+ 0 - 3
flatcamGUI/PreferencesUI.py

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

+ 4 - 1
flatcamGUI/VisPyCanvas.py

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

+ 0 - 1
flatcamParsers/ParseDXF_Spline.py

@@ -9,7 +9,6 @@
 # ##########################################################
 # ##########################################################
 
 
 import math
 import math
-import sys
 
 
 
 
 def norm(v):
 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
 import FlatCAMTranslation as fcTranslate
 
 
@@ -8,6 +18,8 @@ import builtins
 if '_' not in builtins.__dict__:
 if '_' not in builtins.__dict__:
     _ = gettext.gettext
     _ = gettext.gettext
 
 
+log = logging.getLogger('base')
+
 
 
 class Excellon(Geometry):
 class Excellon(Geometry):
     """
     """
@@ -1017,10 +1029,10 @@ class Excellon(Geometry):
 
 
         def bounds_rec(obj):
         def bounds_rec(obj):
             if type(obj) is list:
             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:
                 for k in obj:
                     if type(k) is dict:
                     if type(k) is dict:

+ 2 - 3
flatcamParsers/ParseFont.py

@@ -11,12 +11,11 @@
 # ######################################################################
 # ######################################################################
 
 
 import re, os, sys, glob
 import re, os, sys, glob
-import itertools
 
 
 from shapely.geometry import Point, Polygon
 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 import MultiPolygon
-from shapely.geometry.base import BaseGeometry
+
 
 
 import freetype as ft
 import freetype as ft
 from fontTools import ttLib
 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 FlatCAMTranslation as fcTranslate
 
 
 import gettext
 import gettext
@@ -7,6 +22,8 @@ import builtins
 if '_' not in builtins.__dict__:
 if '_' not in builtins.__dict__:
     _ = gettext.gettext
     _ = gettext.gettext
 
 
+log = logging.getLogger('base')
+
 
 
 class Gerber(Geometry):
 class Gerber(Geometry):
     """
     """
@@ -253,14 +270,14 @@ class Gerber(Geometry):
             self.apertures[apid] = {"type": "R",
             self.apertures[apid] = {"type": "R",
                                     "width": float(paramList[0]),
                                     "width": float(paramList[0]),
                                     "height": float(paramList[1]),
                                     "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
             return apid
 
 
         if apertureType == "O":  # Obround
         if apertureType == "O":  # Obround
             self.apertures[apid] = {"type": "O",
             self.apertures[apid] = {"type": "O",
                                     "width": float(paramList[0]),
                                     "width": float(paramList[0]),
                                     "height": float(paramList[1]),
                                     "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
             return apid
 
 
         if apertureType == "P":  # Polygon (regular)
         if apertureType == "P":  # Polygon (regular)
@@ -1231,15 +1248,15 @@ class Gerber(Geometry):
 
 
                     if quadrant_mode == 'MULTI':
                     if quadrant_mode == 'MULTI':
                         center = [i + current_x, j + current_y]
                         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
                         # Numerical errors might prevent start == stop therefore
                         # we check ahead of time. This should result in a
                         # we check ahead of time. This should result in a
                         # 360 degree arc.
                         # 360 degree arc.
                         if current_x == circular_x and current_y == circular_y:
                         if current_x == circular_x and current_y == circular_y:
                             stop = start
                             stop = start
                         else:
                         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,
                         this_arc = arc(center, radius, start, stop,
                                        arcdir[current_interpolation_mode],
                                        arcdir[current_interpolation_mode],
@@ -1273,10 +1290,10 @@ class Gerber(Geometry):
                         valid = False
                         valid = False
                         log.debug("I: %f  J: %f" % (i, j))
                         log.debug("I: %f  J: %f" % (i, j))
                         for center in center_candidates:
                         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.
                             # 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:
                             if radius2 < radius * 0.95 or radius2 > radius * 1.05:
                                 continue  # Not a valid center.
                                 continue  # Not a valid center.
 
 
@@ -1284,16 +1301,16 @@ class Gerber(Geometry):
                             i = center[0] - current_x
                             i = center[0] - current_x
                             j = center[1] - current_y
                             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]))
                             angle = abs(arc_angle(start, stop, arcdir[current_interpolation_mode]))
                             log.debug("ARC START: %f, %f  CENTER: %f, %f  STOP: %f, %f" %
                             log.debug("ARC START: %f, %f  CENTER: %f, %f  STOP: %f, %f" %
                                       (current_x, current_y, center[0], center[1], circular_x, circular_y))
                                       (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" %
                             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 ############")
                                 log.debug("########## ACCEPTING ARC ############")
                                 this_arc = arc(center, radius, start, stop,
                                 this_arc = arc(center, radius, start, stop,
                                                arcdir[current_interpolation_mode],
                                                arcdir[current_interpolation_mode],
@@ -1478,8 +1495,8 @@ class Gerber(Geometry):
             n_vertices = aperture['nVertices']
             n_vertices = aperture['nVertices']
             points = []
             points = []
             for i in range(0, n_vertices):
             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))
                 points.append((x, y))
             ply = Polygon(points)
             ply = Polygon(points)
             if 'rotation' in aperture:
             if 'rotation' in aperture:
@@ -1553,10 +1570,10 @@ class Gerber(Geometry):
 
 
         def bounds_rec(obj):
         def bounds_rec(obj):
             if type(obj) is list and type(obj) is not MultiPolygon:
             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:
                 for k in obj:
                     if type(k) is dict:
                     if type(k) is dict:

+ 4 - 3
flatcamTools/ToolCalculators.py

@@ -5,8 +5,9 @@
 # MIT Licence                                              #
 # MIT Licence                                              #
 # ##########################################################
 # ##########################################################
 
 
+from PyQt5 import QtWidgets
 from FlatCAMTool import FlatCAMTool
 from FlatCAMTool import FlatCAMTool
-from FlatCAMObj import *
+from flatcamGUI.GUIElements import FCSpinner, FCDoubleSpinner, FCEntry
 import math
 import math
 
 
 import gettext
 import gettext
@@ -321,11 +322,11 @@ class ToolCalculator(FlatCAMTool):
 
 
     def on_calculate_inch_units(self):
     def on_calculate_inch_units(self):
         mm_val = float(self.mm_entry.get_value())
         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):
     def on_calculate_mm_units(self):
         inch_val = float(self.inch_entry.get_value())
         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):
     def on_calculate_eplate(self):
         length = float(self.pcblength_entry.get_value())
         length = float(self.pcblength_entry.get_value())

+ 14 - 3
flatcamTools/ToolCutOut.py

@@ -5,12 +5,21 @@
 # MIT Licence                                              #
 # MIT Licence                                              #
 # ##########################################################
 # ##########################################################
 
 
+from PyQt5 import QtWidgets, QtGui, QtCore
 from FlatCAMTool import FlatCAMTool
 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
 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 gettext
 import FlatCAMTranslation as fcTranslate
 import FlatCAMTranslation as fcTranslate
 import builtins
 import builtins
@@ -19,6 +28,8 @@ fcTranslate.apply_language('strings')
 if '_' not in builtins.__dict__:
 if '_' not in builtins.__dict__:
     _ = gettext.gettext
     _ = gettext.gettext
 
 
+log = logging.getLogger('base')
+
 
 
 class CutOut(FlatCAMTool):
 class CutOut(FlatCAMTool):
 
 

+ 9 - 2
flatcamTools/ToolDblSided.py

@@ -1,9 +1,14 @@
+
+from PyQt5 import QtWidgets, QtCore
+
 from FlatCAMTool import FlatCAMTool
 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.geometry import Point
 from shapely import affinity
 from shapely import affinity
-from PyQt5 import QtCore
 
 
+import logging
 import gettext
 import gettext
 import FlatCAMTranslation as fcTranslate
 import FlatCAMTranslation as fcTranslate
 import builtins
 import builtins
@@ -12,6 +17,8 @@ fcTranslate.apply_language('strings')
 if '_' not in builtins.__dict__:
 if '_' not in builtins.__dict__:
     _ = gettext.gettext
     _ = gettext.gettext
 
 
+log = logging.getLogger('base')
+
 
 
 class DblSidedTool(FlatCAMTool):
 class DblSidedTool(FlatCAMTool):
 
 

+ 9 - 4
flatcamTools/ToolDistance.py

@@ -5,12 +5,15 @@
 # MIT Licence                                              #
 # MIT Licence                                              #
 # ##########################################################
 # ##########################################################
 
 
+from PyQt5 import QtWidgets, QtCore
+
 from FlatCAMTool import FlatCAMTool
 from FlatCAMTool import FlatCAMTool
-from FlatCAMObj import *
 from flatcamGUI.VisPyVisuals import *
 from flatcamGUI.VisPyVisuals import *
+from flatcamGUI.GUIElements import FCEntry
 
 
-from math import sqrt
-
+import copy
+import math
+import logging
 import gettext
 import gettext
 import FlatCAMTranslation as fcTranslate
 import FlatCAMTranslation as fcTranslate
 import builtins
 import builtins
@@ -19,6 +22,8 @@ fcTranslate.apply_language('strings')
 if '_' not in builtins.__dict__:
 if '_' not in builtins.__dict__:
     _ = gettext.gettext
     _ = gettext.gettext
 
 
+log = logging.getLogger('base')
+
 
 
 class Distance(FlatCAMTool):
 class Distance(FlatCAMTool):
 
 
@@ -335,7 +340,7 @@ class Distance(FlatCAMTool):
             elif len(self.points) == 2:
             elif len(self.points) == 2:
                 dx = self.points[1][0] - self.points[0][0]
                 dx = self.points[1][0] - self.points[0][0]
                 dy = self.points[1][1] - self.points[0][1]
                 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.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(
                 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                                              #
 # MIT Licence                                              #
 # ##########################################################
 # ##########################################################
 
 
+from PyQt5 import QtWidgets, QtCore
 from FlatCAMTool import FlatCAMTool
 from FlatCAMTool import FlatCAMTool
-from FlatCAMObj import *
 from flatcamGUI.VisPyVisuals import *
 from flatcamGUI.VisPyVisuals import *
+from flatcamGUI.GUIElements import FCEntry
 
 
 from shapely.ops import nearest_points
 from shapely.ops import nearest_points
+from shapely.geometry import Point
 
 
-from math import sqrt
-
+import math
+import logging
 import gettext
 import gettext
 import FlatCAMTranslation as fcTranslate
 import FlatCAMTranslation as fcTranslate
 import builtins
 import builtins
@@ -21,6 +23,8 @@ fcTranslate.apply_language('strings')
 if '_' not in builtins.__dict__:
 if '_' not in builtins.__dict__:
     _ = gettext.gettext
     _ = gettext.gettext
 
 
+log = logging.getLogger('base')
+
 
 
 class DistanceMin(FlatCAMTool):
 class DistanceMin(FlatCAMTool):
 
 
@@ -260,7 +264,7 @@ class DistanceMin(FlatCAMTool):
         except Exception as e:
         except Exception as e:
             pass
             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.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))
         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                                              #
 # 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, \
 from flatcamGUI.GUIElements import RadioSet, FCDoubleSpinner, FCCheckBox, \
     OptionalHideInputSection, OptionalInputSection
     OptionalHideInputSection, OptionalInputSection
-from PyQt5 import QtGui, QtCore, QtWidgets
 
 
 from copy import deepcopy
 from copy import deepcopy
+import logging
+from shapely.geometry import Polygon, MultiPolygon, Point
 
 
 import gettext
 import gettext
 import FlatCAMTranslation as fcTranslate
 import FlatCAMTranslation as fcTranslate
@@ -22,6 +23,8 @@ fcTranslate.apply_language('strings')
 if '_' not in builtins.__dict__:
 if '_' not in builtins.__dict__:
     _ = gettext.gettext
     _ = gettext.gettext
 
 
+log = logging.getLogger('base')
+
 
 
 class Film(FlatCAMTool):
 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.ois_scale = OptionalInputSection(self.film_scale_cb, [self.film_scalex_label, self.film_scalex_entry,
                                                                    self.film_scaley_label,  self.film_scaley_entry])
                                                                    self.film_scaley_label,  self.film_scaley_entry])
         # Skew Geometry
         # 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(
         self.film_skew_cb.setToolTip(
             _("Positive values will skew to the right\n"
             _("Positive values will skew to the right\n"
               "while negative values will skew to the left.")
               "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.")
               "It can be one of the four points of the geometry bounding box.")
         )
         )
         self.film_skew_reference = RadioSet([{'label': _('Bottom Left'), 'value': 'bottomleft'},
         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',
                                             orientation='vertical',
                                             stretch=False)
                                             stretch=False)
 
 

+ 2 - 2
flatcamTools/ToolImage.py

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

+ 6 - 3
flatcamTools/ToolMove.py

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

+ 26 - 6
flatcamTools/ToolNonCopperClear.py

@@ -5,12 +5,23 @@
 # MIT Licence                                              #
 # MIT Licence                                              #
 # ##########################################################
 # ##########################################################
 
 
+from PyQt5 import QtWidgets, QtCore, QtGui
 from FlatCAMTool import FlatCAMTool
 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.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 gettext
 import FlatCAMTranslation as fcTranslate
 import FlatCAMTranslation as fcTranslate
 import builtins
 import builtins
@@ -19,6 +30,8 @@ fcTranslate.apply_language('strings')
 if '_' not in builtins.__dict__:
 if '_' not in builtins.__dict__:
     _ = gettext.gettext
     _ = gettext.gettext
 
 
+log = logging.getLogger('base')
+
 
 
 class NonCopperClear(FlatCAMTool, Gerber):
 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"))
             "Add", self.on_add_tool_by_key, icon=QtGui.QIcon("share/plus16.png"))
         self.tools_table.addContextMenu(
         self.tools_table.addContextMenu(
             "Delete", lambda:
             "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 ########################################
         # ########################## VARIABLES ########################################
@@ -1040,12 +1053,19 @@ class NonCopperClear(FlatCAMTool, Gerber):
                                                               "New diameter value is already in the Tool Table."))
                                                               "New diameter value is already in the Tool Table."))
         self.build_ui()
         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()
         self.ui_disconnect()
 
 
         deleted_tools_list = []
         deleted_tools_list = []
 
 
-        if all:
+        if all_tools:
             self.paint_tools.clear()
             self.paint_tools.clear()
             self.build_ui()
             self.build_ui()
             return
             return

+ 14 - 6
flatcamTools/ToolOptimal.py

@@ -5,13 +5,19 @@
 # MIT Licence                                              #
 # MIT Licence                                              #
 # ##########################################################
 # ##########################################################
 
 
+from PyQt5 import QtWidgets, QtCore, QtGui
+
 from FlatCAMTool import FlatCAMTool
 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 shapely.ops import nearest_points
-from PyQt5 import QtCore
 
 
+import numpy as np
+
+import logging
 import gettext
 import gettext
 import FlatCAMTranslation as fcTranslate
 import FlatCAMTranslation as fcTranslate
 import builtins
 import builtins
@@ -20,13 +26,15 @@ fcTranslate.apply_language('strings')
 if '_' not in builtins.__dict__:
 if '_' not in builtins.__dict__:
     _ = gettext.gettext
     _ = gettext.gettext
 
 
+log = logging.getLogger('base')
+
 
 
 class ToolOptimal(FlatCAMTool):
 class ToolOptimal(FlatCAMTool):
 
 
     toolName = _("Optimal Tool")
     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):
     def __init__(self, app):
         FlatCAMTool.__init__(self, app)
         FlatCAMTool.__init__(self, app)

+ 9 - 4
flatcamTools/ToolPDF.py

@@ -5,19 +5,22 @@
 # MIT Licence                                              #
 # MIT Licence                                              #
 # ##########################################################
 # ##########################################################
 
 
+from PyQt5 import QtWidgets, QtCore
+
 from FlatCAMTool import FlatCAMTool
 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
 from copy import copy, deepcopy
 import numpy as np
 import numpy as np
 
 
 import zlib
 import zlib
 import re
 import re
 import time
 import time
+import logging
+import traceback
 
 
 import gettext
 import gettext
 import FlatCAMTranslation as fcTranslate
 import FlatCAMTranslation as fcTranslate
@@ -27,6 +30,8 @@ fcTranslate.apply_language('strings')
 if '_' not in builtins.__dict__:
 if '_' not in builtins.__dict__:
     _ = gettext.gettext
     _ = gettext.gettext
 
 
+log = logging.getLogger('base')
+
 
 
 class ToolPDF(FlatCAMTool):
 class ToolPDF(FlatCAMTool):
     """
     """

+ 26 - 8
flatcamTools/ToolPaint.py

@@ -5,10 +5,25 @@
 # MIT Licence                                              #
 # MIT Licence                                              #
 # ##########################################################
 # ##########################################################
 
 
+from PyQt5 import QtWidgets, QtGui, QtCore
+from PyQt5.QtCore import Qt
+
 from FlatCAMTool import FlatCAMTool
 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 gettext
 import FlatCAMTranslation as fcTranslate
 import FlatCAMTranslation as fcTranslate
@@ -18,6 +33,8 @@ fcTranslate.apply_language('strings')
 if '_' not in builtins.__dict__:
 if '_' not in builtins.__dict__:
     _ = gettext.gettext
     _ = gettext.gettext
 
 
+log = logging.getLogger('base')
+
 
 
 class ToolPaint(FlatCAMTool, Gerber):
 class ToolPaint(FlatCAMTool, Gerber):
 
 
@@ -374,6 +391,7 @@ class ToolPaint(FlatCAMTool, Gerber):
 
 
         self.mm = None
         self.mm = None
         self.mp = None
         self.mp = None
+        self.mr = None
 
 
         self.sel_rect = []
         self.sel_rect = []
 
 
@@ -641,10 +659,10 @@ class ToolPaint(FlatCAMTool, Gerber):
             for tooluid_key, tooluid_value in self.paint_tools.items():
             for tooluid_key, tooluid_value in self.paint_tools.items():
                 if float('%.*f' % (self.decimals, tooluid_value['tooldia'])) == tool_sorted:
                 if float('%.*f' % (self.decimals, tooluid_value['tooldia'])) == tool_sorted:
                     tool_id += 1
                     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
                     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
                     # 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
                     # 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))
                         log.debug("Could not Paint the polygons. %s" % str(e))
                         self.app.inform.emit('[ERROR] %s\n%s' %
                         self.app.inform.emit('[ERROR] %s\n%s' %
                                              (_("Could not do Paint All. Try a different combination of parameters. "
                                              (_("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
                         return
 
 
                     pol_nr += 1
                     pol_nr += 1
@@ -2373,7 +2391,7 @@ class ToolPaint(FlatCAMTool, Gerber):
                         log.debug("Could not Paint the polygons. %s" % str(e))
                         log.debug("Could not Paint the polygons. %s" % str(e))
                         self.app.inform.emit('[ERROR] %s\n%s' %
                         self.app.inform.emit('[ERROR] %s\n%s' %
                                              (_("Could not do Paint All. Try a different combination of parameters. "
                                              (_("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
                         return
 
 
                     pol_nr += 1
                     pol_nr += 1

+ 31 - 13
flatcamTools/ToolPanelize.py

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

+ 4 - 4
flatcamTools/ToolPcbWizard.py

@@ -5,11 +5,11 @@
 # MIT Licence                                              #
 # MIT Licence                                              #
 # ##########################################################
 # ##########################################################
 
 
+from PyQt5 import QtWidgets, QtCore
+
 from FlatCAMTool import FlatCAMTool
 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 re
 import os
 import os
 from datetime import datetime
 from datetime import datetime
@@ -26,7 +26,7 @@ if '_' not in builtins.__dict__:
 
 
 class PcbWizard(FlatCAMTool):
 class PcbWizard(FlatCAMTool):
 
 
-    file_loaded = pyqtSignal(str, str)
+    file_loaded = QtCore.pyqtSignal(str, str)
 
 
     toolName = _("PcbWizard Import Tool")
     toolName = _("PcbWizard Import Tool")
 
 

+ 19 - 13
flatcamTools/ToolProperties.py

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

+ 11 - 6
flatcamTools/ToolRulesCheck.py

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

+ 1 - 1
flatcamTools/ToolShell.py

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

+ 11 - 3
flatcamTools/ToolSub.py

@@ -5,12 +5,18 @@
 # MIT Licence                                              #
 # MIT Licence                                              #
 # ##########################################################
 # ##########################################################
 
 
+from PyQt5 import QtWidgets, QtCore
 
 
 from FlatCAMTool import FlatCAMTool
 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 gettext
 import FlatCAMTranslation as fcTranslate
 import FlatCAMTranslation as fcTranslate
 import builtins
 import builtins
@@ -19,6 +25,8 @@ fcTranslate.apply_language('strings')
 if '_' not in builtins.__dict__:
 if '_' not in builtins.__dict__:
     _ = gettext.gettext
     _ = gettext.gettext
 
 
+log = logging.getLogger('base')
+
 
 
 class ToolSub(FlatCAMTool):
 class ToolSub(FlatCAMTool):
 
 

+ 5 - 3
flatcamTools/ToolTransform.py

@@ -5,8 +5,10 @@
 # MIT Licence                                              #
 # MIT Licence                                              #
 # ##########################################################
 # ##########################################################
 
 
+from PyQt5 import QtWidgets
 from FlatCAMTool import FlatCAMTool
 from FlatCAMTool import FlatCAMTool
-from FlatCAMObj import *
+from flatcamGUI.GUIElements import FCDoubleSpinner, FCCheckBox, FCButton, OptionalInputSection, EvalEntry2
+from FlatCAMObj import FlatCAMCNCjob
 
 
 import gettext
 import gettext
 import FlatCAMTranslation as fcTranslate
 import FlatCAMTranslation as fcTranslate
@@ -271,7 +273,7 @@ class ToolTransform(FlatCAMTool):
             _("Flip the selected object(s) over the X axis.")
             _("Flip the selected object(s) over the X axis.")
         )
         )
 
 
-        hlay0= QtWidgets.QHBoxLayout()
+        hlay0 = QtWidgets.QHBoxLayout()
         self.transform_lay.addLayout(hlay0)
         self.transform_lay.addLayout(hlay0)
 
 
         hlay0.addWidget(self.flipx_button)
         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)
         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)
         self.transform_lay.addLayout(hlay1)
 
 
         hlay1.addWidget(self.flip_ref_label)
         hlay1.addWidget(self.flip_ref_label)