diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 5947df32..2b2f0b61 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -9,6 +9,8 @@ import urllib.request import urllib.parse import urllib.error +import webbrowser + import getopt import random import simplejson as json @@ -40,10 +42,12 @@ import vispy.scene as scene # ####################################### from ObjectCollection import * from FlatCAMObj import * +from camlib import to_dict, dict2obj, ET, ParseError + from flatcamGUI.PlotCanvas import * from flatcamGUI.PlotCanvasLegacy import * - from flatcamGUI.FlatCAMGUI import * + from FlatCAMCommon import LoudDict from FlatCAMPostProc import load_postprocessors diff --git a/FlatCAMObj.py b/FlatCAMObj.py index 7429a937..d1c6005e 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -10,24 +10,33 @@ # File modified by: Marius Stanciu # # ########################################################## -from PyQt5.QtCore import Qt -from PyQt5.QtGui import QTextDocument + +from shapely.geometry import Point, Polygon, MultiPolygon, MultiLineString, LineString, LinearRing +from shapely.ops import cascaded_union +import shapely.affinity as affinity + import copy +from copy import deepcopy +from io import StringIO +import traceback import inspect # TODO: For debugging only. from datetime import datetime from flatcamEditors.FlatCAMTextEditor import TextEditor - from flatcamGUI.ObjectUI import * from FlatCAMCommon import LoudDict from flatcamGUI.PlotCanvasLegacy import ShapeCollectionLegacy -from camlib import * from flatcamParsers.ParseExcellon import Excellon from flatcamParsers.ParseGerber import Gerber +from camlib import Geometry, CNCjob +import FlatCAMApp -import itertools import tkinter as tk -import sys +import os, sys, itertools +import ezdxf + +import math +import numpy as np import gettext import FlatCAMTranslation as fcTranslate @@ -66,7 +75,7 @@ class FlatCAMObj(QtCore.QObject): app = None # signal to plot a single object - plot_single_object = pyqtSignal() + plot_single_object = QtCore.pyqtSignal() def __init__(self, name): """ diff --git a/FlatCAMPostProc.py b/FlatCAMPostProc.py index b6137672..cfb99577 100644 --- a/FlatCAMPostProc.py +++ b/FlatCAMPostProc.py @@ -9,8 +9,6 @@ from importlib.machinery import SourceFileLoader import os from abc import ABCMeta, abstractmethod -from datetime import datetime -import math # module-root dictionary of postprocessors import FlatCAMApp diff --git a/ObjectCollection.py b/ObjectCollection.py index 58c4fed8..570779e2 100644 --- a/ObjectCollection.py +++ b/ObjectCollection.py @@ -11,13 +11,20 @@ # File modified by: Marius Stanciu # # ########################################################## -# from PyQt5.QtCore import QModelIndex -from FlatCAMObj import * -import inspect # TODO: Remove -import FlatCAMApp from PyQt5 import QtGui, QtCore, QtWidgets from PyQt5.QtCore import Qt, QSettings -# import webbrowser +from PyQt5.QtGui import QColor +# from PyQt5.QtCore import QModelIndex + +from FlatCAMObj import FlatCAMGerber, FlatCAMGeometry, FlatCAMExcellon, FlatCAMCNCjob, FlatCAMDocument, FlatCAMScript +import inspect # TODO: Remove +import FlatCAMApp + +import re +import logging +import collections +from copy import deepcopy +from numpy import Inf import gettext import FlatCAMTranslation as fcTranslate @@ -27,6 +34,8 @@ fcTranslate.apply_language('strings') if '_' not in builtins.__dict__: _ = gettext.gettext +log = logging.getLogger('base') + class KeySensitiveListView(QtWidgets.QTreeView): """ diff --git a/README.md b/README.md index 7d9d3f01..b8826d9b 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,8 @@ CAD program, and create G-Code for Isolation routing. 15.10.2019 - adjusted the layout in NCC Tool +- fixed bug in Panelization Tool for which in case of Excellon objects, the panel kept a reference to the source object which created issues when moving or disabling/enabling the plots +- cleaned up the module imports throughout the app (the TclCommands are not yet verified) 14.10.2019 diff --git a/camlib.py b/camlib.py index 3ba10034..e0bdd9e1 100644 --- a/camlib.py +++ b/camlib.py @@ -11,12 +11,9 @@ from PyQt5 import QtWidgets from io import StringIO import numpy as np -from numpy import arctan2, Inf, array, sqrt, pi, ceil, sin, cos, dot, float32, \ - transpose from numpy.linalg import solve, norm -import re, sys, os, platform -import math +import platform from copy import deepcopy import traceback @@ -26,8 +23,8 @@ from rtree import index as rtindex from lxml import etree as ET # See: http://toblerity.org/shapely/manual.html -from shapely.geometry import Polygon, LineString, Point, LinearRing, MultiLineString -from shapely.geometry import MultiPoint, MultiPolygon +from shapely.geometry import Polygon, LineString, Point, LinearRing, MultiLineString, MultiPoint, MultiPolygon + from shapely.geometry import box as shply_box from shapely.ops import cascaded_union, unary_union, polygonize import shapely.affinity as affinity @@ -64,7 +61,6 @@ import gettext import FlatCAMTranslation as fcTranslate import builtins - fcTranslate.apply_language('strings') log = logging.getLogger('base2') @@ -336,8 +332,8 @@ class ApertureMacro: points = [(0, 0)]*nverts for i in range(nverts): - points[i] = (x + 0.5 * dia * cos(2*pi * i/nverts), - y + 0.5 * dia * sin(2*pi * i/nverts)) + points[i] = (x + 0.5 * dia * np.cos(2*np.pi * i/nverts), + y + 0.5 * dia * np.sin(2*np.pi * i/nverts)) poly = Polygon(points) poly_rotated = affinity.rotate(poly, angle, origin=(0, 0)) @@ -637,10 +633,10 @@ class Geometry(object): def bounds_rec(obj): if type(obj) is list: - minx = Inf - miny = Inf - maxx = -Inf - maxy = -Inf + minx = np.Inf + miny = np.Inf + maxx = -np.Inf + maxy = -np.Inf for k in obj: if type(k) is dict: @@ -1155,7 +1151,7 @@ class Geometry(object): log.debug("Image import as monochrome.") else: mask_setting = (red <= mask[1]) + (green <= mask[2]) + (blue <= mask[3]) - total = np.zeros(red.shape, dtype=float32) + total = np.zeros(red.shape, dtype=np.float32) for band in red, green, blue: total += band total /= 3 @@ -3298,10 +3294,10 @@ class CNCjob(Geometry): def bounds_rec(obj): if type(obj) is list: - minx = Inf - miny = Inf - maxx = -Inf - maxy = -Inf + minx = np.Inf + miny = np.Inf + maxx = -np.Inf + maxy = -np.Inf for k in obj: if type(k) is dict: @@ -4049,9 +4045,9 @@ class CNCjob(Geometry): arcdir = [None, None, "cw", "ccw"] if current['G'] in [2, 3]: # arc center = [gobj['I'] + current['X'], gobj['J'] + current['Y']] - radius = sqrt(gobj['I']**2 + gobj['J']**2) - start = arctan2(-gobj['J'], -gobj['I']) - stop = arctan2(-center[1] + y, -center[0] + x) + radius = np.sqrt(gobj['I']**2 + gobj['J']**2) + start = np.arctan2(-gobj['J'], -gobj['I']) + stop = np.arctan2(-center[1] + y, -center[0] + x) path += arc(center, radius, start, stop, arcdir[current['G']], int(self.steps_per_circle / 4)) # Update current instruction @@ -4710,10 +4706,10 @@ class CNCjob(Geometry): def bounds_rec(obj): if type(obj) is list: - minx = Inf - miny = Inf - maxx = -Inf - maxy = -Inf + minx = np.Inf + miny = np.Inf + maxx = -np.Inf + maxy = -np.Inf for k in obj: if type(k) is dict: @@ -4742,15 +4738,15 @@ class CNCjob(Geometry): bounds_coords = bounds_rec(self.solid_geometry) else: - minx = Inf - miny = Inf - maxx = -Inf - maxy = -Inf + minx = np.Inf + miny = np.Inf + maxx = -np.Inf + maxy = -np.Inf for k, v in self.cnc_tools.items(): - minx = Inf - miny = Inf - maxx = -Inf - maxy = -Inf + minx = np.Inf + miny = np.Inf + maxx = -np.Inf + maxy = -np.Inf try: for k in v['solid_geometry']: minx_, miny_, maxx_, maxy_ = bounds_rec(k) @@ -5186,10 +5182,10 @@ class CNCjob(Geometry): def get_bounds(geometry_list): - xmin = Inf - ymin = Inf - xmax = -Inf - ymax = -Inf + xmin = np.Inf + ymin = np.Inf + xmax = -np.Inf + ymax = -np.Inf for gs in geometry_list: try: @@ -5229,33 +5225,33 @@ def arc(center, radius, start, stop, direction, steps_per_circ): da_sign = {"cw": -1.0, "ccw": 1.0} points = [] if direction == "ccw" and stop <= start: - stop += 2 * pi + stop += 2 * np.pi if direction == "cw" and stop >= start: - stop -= 2 * pi + stop -= 2 * np.pi angle = abs(stop - start) # angle = stop-start - steps = max([int(ceil(angle / (2 * pi) * steps_per_circ)), 2]) + steps = max([int(np.ceil(angle / (2 * np.pi) * steps_per_circ)), 2]) delta_angle = da_sign[direction] * angle * 1.0 / steps for i in range(steps + 1): theta = start + delta_angle * i - points.append((center[0] + radius * cos(theta), center[1] + radius * sin(theta))) + points.append((center[0] + radius * np.cos(theta), center[1] + radius * np.sin(theta))) return points def arc2(p1, p2, center, direction, steps_per_circ): - r = sqrt((center[0] - p1[0]) ** 2 + (center[1] - p1[1]) ** 2) - start = arctan2(p1[1] - center[1], p1[0] - center[0]) - stop = arctan2(p2[1] - center[1], p2[0] - center[0]) + r = np.sqrt((center[0] - p1[0]) ** 2 + (center[1] - p1[1]) ** 2) + start = np.arctan2(p1[1] - center[1], p1[0] - center[0]) + stop = np.arctan2(p2[1] - center[1], p2[0] - center[0]) return arc(center, r, start, stop, direction, steps_per_circ) def arc_angle(start, stop, direction): if direction == "ccw" and stop <= start: - stop += 2 * pi + stop += 2 * np.pi if direction == "cw" and stop >= start: - stop -= 2 * pi + stop -= 2 * np.pi angle = abs(stop - start) return angle @@ -5665,12 +5661,12 @@ def three_point_circle(p1, p2, p3): a2 = (p2 + p3) / 2.0 # Normals - b1 = dot((p2 - p1), array([[0, -1], [1, 0]], dtype=float32)) - b2 = dot((p3 - p2), array([[0, 1], [-1, 0]], dtype=float32)) + b1 = np.dot((p2 - p1), np.array([[0, -1], [1, 0]], dtype=np.float32)) + b2 = np.dot((p3 - p2), np.array([[0, 1], [-1, 0]], dtype=np.float32)) # Params try: - T = solve(transpose(array([-b1, b2])), a1 - a2) + T = solve(np.transpose(np.array([-b1, b2])), a1 - a2) except Exception as e: log.debug("camlib.three_point_circle() --> %s" % str(e)) return @@ -5685,11 +5681,11 @@ def three_point_circle(p1, p2, p3): def distance(pt1, pt2): - return sqrt((pt1[0] - pt2[0]) ** 2 + (pt1[1] - pt2[1]) ** 2) + return np.sqrt((pt1[0] - pt2[0]) ** 2 + (pt1[1] - pt2[1]) ** 2) def distance_euclidian(x1, y1, x2, y2): - return sqrt((x1 - x2) ** 2 + (y1 - y2) ** 2) + return np.sqrt((x1 - x2) ** 2 + (y1 - y2) ** 2) class FlatCAMRTree(object): diff --git a/flatcamEditors/FlatCAMExcEditor.py b/flatcamEditors/FlatCAMExcEditor.py index ede5dc69..3294992c 100644 --- a/flatcamEditors/FlatCAMExcEditor.py +++ b/flatcamEditors/FlatCAMExcEditor.py @@ -8,19 +8,23 @@ from PyQt5 import QtGui, QtCore, QtWidgets from PyQt5.QtCore import Qt, QSettings -from shapely.geometry import LineString, LinearRing, MultiLineString -from shapely.ops import cascaded_union -import shapely.affinity as affinity - -from numpy import arctan2, Inf, array, sqrt, sign, dot -from rtree import index as rtindex - -from camlib import * +from camlib import distance, arc, FlatCAMRTreeStorage from flatcamGUI.GUIElements import FCEntry, FCComboBox, FCTable, FCDoubleSpinner, LengthEntry, RadioSet, SpinBoxDelegate from flatcamEditors.FlatCAMGeoEditor import FCShapeTool, DrawTool, DrawToolShape, DrawToolUtilityShape, FlatCAMGeoEditor from flatcamParsers.ParseExcellon import Excellon +import FlatCAMApp -from copy import copy, deepcopy +from shapely.geometry import LineString, LinearRing, MultiLineString, Polygon, MultiPolygon, Point +import shapely.affinity as affinity + +import numpy as np + +from rtree import index as rtindex + +import traceback +import math +import logging +from copy import deepcopy import gettext import FlatCAMTranslation as fcTranslate @@ -30,6 +34,8 @@ fcTranslate.apply_language('strings') if '_' not in builtins.__dict__: _ = gettext.gettext +log = logging.getLogger('base') + class FCDrillAdd(FCShapeTool): """ @@ -3214,8 +3220,7 @@ class FlatCAMExcEditor(QtCore.QObject): _("An internal error has ocurred. See Shell.\n") msg += traceback.format_exc() app_obj.inform.emit(msg) - raise - # raise + return with self.app.proc_container.new(_("Creating Excellon.")): @@ -3998,10 +4003,10 @@ class FlatCAMExcEditor(QtCore.QObject): def get_shapely_list_bounds(geometry_list): - xmin = Inf - ymin = Inf - xmax = -Inf - ymax = -Inf + xmin = np.Inf + ymin = np.Inf + xmax = -np.Inf + ymax = -np.Inf for gs in geometry_list: try: diff --git a/flatcamEditors/FlatCAMGeoEditor.py b/flatcamEditors/FlatCAMGeoEditor.py index ce158e02..1dfe679d 100644 --- a/flatcamEditors/FlatCAMGeoEditor.py +++ b/flatcamEditors/FlatCAMGeoEditor.py @@ -13,24 +13,26 @@ from PyQt5 import QtGui, QtCore, QtWidgets from PyQt5.QtCore import Qt, QSettings -from camlib import * + +from camlib import distance, arc, three_point_circle, Geometry, FlatCAMRTreeStorage from FlatCAMTool import FlatCAMTool -from flatcamGUI.ObjectUI import LengthEntry, RadioSet +from flatcamGUI.ObjectUI import RadioSet +from flatcamGUI.GUIElements import OptionalInputSection, FCCheckBox, FCEntry, FCComboBox, FCTextAreaRich, \ + FCTable, FCDoubleSpinner, FCButton, EvalEntry2, FCInputDialog +from flatcamParsers.ParseFont import * +import FlatCAMApp from shapely.geometry import LineString, LinearRing, MultiLineString, Polygon, MultiPolygon -# from shapely.geometry import mapping from shapely.ops import cascaded_union, unary_union import shapely.affinity as affinity from shapely.geometry.polygon import orient -from numpy import arctan2, Inf, array, sqrt, sign, dot +import numpy as np from numpy.linalg import norm as numpy_norm from rtree import index as rtindex -from flatcamGUI.GUIElements import OptionalInputSection, FCCheckBox, FCEntry, FCComboBox, FCTextAreaRich, \ - FCTable, FCDoubleSpinner, FCButton, EvalEntry2, FCInputDialog -from flatcamParsers.ParseFont import * +from copy import deepcopy # from vispy.io import read_png import gettext import FlatCAMTranslation as fcTranslate @@ -684,8 +686,8 @@ class TransformEditorTool(FlatCAMTool): self.rotate_button.set_value(_("Rotate")) self.rotate_button.setToolTip( _("Rotate the selected shape(s).\n" - "The point of reference is the middle of\n" - "the bounding box for all selected shapes.") + "The point of reference is the middle of\n" + "the bounding box for all selected shapes.") ) self.rotate_button.setFixedWidth(60) @@ -802,7 +804,7 @@ class TransformEditorTool(FlatCAMTool): self.scale_link_cb.setText(_("Link")) self.scale_link_cb.setToolTip( _("Scale the selected shape(s)\n" - "using the Scale Factor X for both axis.")) + "using the Scale Factor X for both axis.")) self.scale_link_cb.setFixedWidth(50) self.scale_zero_ref_cb = FCCheckBox() @@ -1060,7 +1062,6 @@ class TransformEditorTool(FlatCAMTool): _("Transformation cancelled. No shape selected.")) return - self.draw_app.select_tool("select") self.app.ui.notebook.setTabText(2, "Tools") self.app.ui.notebook.setCurrentWidget(self.app.ui.project_tab) @@ -1081,10 +1082,7 @@ class TransformEditorTool(FlatCAMTool): self.app.inform.emit('[ERROR_NOTCL] %s' % _("Wrong value format entered, use a number.")) return - self.app.worker_task.emit({'fcn': self.on_rotate_action, - 'params': [value]}) - # self.on_rotate_action(value) - return + self.app.worker_task.emit({'fcn': self.on_rotate_action, 'params': [value]}) def on_flipx(self): # self.on_flip("Y") @@ -1205,13 +1203,9 @@ class TransformEditorTool(FlatCAMTool): axis = 'Y' point = (0, 0) if self.scale_zero_ref_cb.get_value(): - self.app.worker_task.emit({'fcn': self.on_scale, - 'params': [axis, xvalue, yvalue, point]}) - # self.on_scale("Y", xvalue, yvalue, point=(0,0)) + self.app.worker_task.emit({'fcn': self.on_scale, 'params': [axis, xvalue, yvalue, point]}) else: - # self.on_scale("Y", xvalue, yvalue) - self.app.worker_task.emit({'fcn': self.on_scale, - 'params': [axis, xvalue, yvalue]}) + self.app.worker_task.emit({'fcn': self.on_scale, 'params': [axis, xvalue, yvalue]}) return @@ -1304,7 +1298,7 @@ class TransformEditorTool(FlatCAMTool): except Exception as e: self.app.inform.emit('[ERROR_NOTCL] %s: %s' % - (_("Rotation action was not executed"),str(e))) + (_("Rotation action was not executed"), str(e))) return def on_flip(self, axis): @@ -1664,10 +1658,10 @@ class DrawToolShape(object): # now it can get bounds for nested lists of objects def bounds_rec(shape_el): if type(shape_el) is list: - minx = Inf - miny = Inf - maxx = -Inf - maxy = -Inf + minx = np.Inf + miny = np.Inf + maxx = -np.Inf + maxy = -np.Inf for k in shape_el: minx_, miny_, maxx_, maxy_ = bounds_rec(k) @@ -1904,10 +1898,10 @@ class DrawTool(object): def bounds(self, obj): def bounds_rec(o): if type(o) is list: - minx = Inf - miny = Inf - maxx = -Inf - maxy = -Inf + minx = np.Inf + miny = np.Inf + maxx = -np.Inf + maxy = -np.Inf for k in o: try: @@ -1977,7 +1971,7 @@ class FCCircle(FCShapeTool): if len(self.points) == 1: p1 = self.points[0] p2 = data - radius = sqrt((p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2) + radius = np.sqrt((p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2) return DrawToolUtilityShape(Point(p1).buffer(radius, int(self.steps_per_circ / 4))) return None @@ -2086,36 +2080,36 @@ class FCArc(FCShapeTool): p1 = self.points[1] p2 = data - radius = sqrt((center[0] - p1[0]) ** 2 + (center[1] - p1[1]) ** 2) - startangle = arctan2(p1[1] - center[1], p1[0] - center[0]) - stopangle = arctan2(p2[1] - center[1], p2[0] - center[0]) + radius = np.sqrt((center[0] - p1[0]) ** 2 + (center[1] - p1[1]) ** 2) + startangle = np.arctan2(p1[1] - center[1], p1[0] - center[0]) + stopangle = np.arctan2(p2[1] - center[1], p2[0] - center[0]) return DrawToolUtilityShape([LineString(arc(center, radius, startangle, stopangle, self.direction, self.steps_per_circ)), Point(center)]) elif self.mode == '132': - p1 = array(self.points[0]) - p3 = array(self.points[1]) - p2 = array(data) + p1 = np.array(self.points[0]) + p3 = np.array(self.points[1]) + p2 = np.array(data) try: center, radius, t = three_point_circle(p1, p2, p3) except TypeError: return - direction = 'cw' if sign(t) > 0 else 'ccw' + direction = 'cw' if np.sign(t) > 0 else 'ccw' - startangle = arctan2(p1[1] - center[1], p1[0] - center[0]) - stopangle = arctan2(p3[1] - center[1], p3[0] - center[0]) + startangle = np.arctan2(p1[1] - center[1], p1[0] - center[0]) + stopangle = np.arctan2(p3[1] - center[1], p3[0] - center[0]) return DrawToolUtilityShape([LineString(arc(center, radius, startangle, stopangle, direction, self.steps_per_circ)), Point(center), Point(p1), Point(p3)]) else: # '12c' - p1 = array(self.points[0]) - p2 = array(self.points[1]) + p1 = np.array(self.points[0]) + p2 = np.array(self.points[1]) # Midpoint a = (p1 + p2) / 2.0 @@ -2124,7 +2118,7 @@ class FCArc(FCShapeTool): c = p2 - p1 # Perpendicular vector - b = dot(c, array([[0, -1], [1, 0]], dtype=float32)) + b = np.dot(c, np.array([[0, -1], [1, 0]], dtype=np.float32)) b /= numpy_norm(b) # Distance @@ -2133,14 +2127,14 @@ class FCArc(FCShapeTool): # Which side? Cross product with c. # cross(M-A, B-A), where line is AB and M is test point. side = (data[0] - p1[0]) * c[1] - (data[1] - p1[1]) * c[0] - t *= sign(side) + t *= np.sign(side) # Center = a + bt center = a + b * t radius = numpy_norm(center - p1) - startangle = arctan2(p1[1] - center[1], p1[0] - center[0]) - stopangle = arctan2(p2[1] - center[1], p2[0] - center[0]) + startangle = np.arctan2(p1[1] - center[1], p1[0] - center[0]) + stopangle = np.arctan2(p2[1] - center[1], p2[0] - center[0]) return DrawToolUtilityShape([LineString(arc(center, radius, startangle, stopangle, self.direction, self.steps_per_circ)), @@ -2156,29 +2150,29 @@ class FCArc(FCShapeTool): p2 = self.points[2] radius = distance(center, p1) - startangle = arctan2(p1[1] - center[1], p1[0] - center[0]) - stopangle = arctan2(p2[1] - center[1], p2[0] - center[0]) + startangle = np.arctan2(p1[1] - center[1], p1[0] - center[0]) + stopangle = np.arctan2(p2[1] - center[1], p2[0] - center[0]) self.geometry = DrawToolShape(LineString(arc(center, radius, startangle, stopangle, self.direction, self.steps_per_circ))) elif self.mode == '132': - p1 = array(self.points[0]) - p3 = array(self.points[1]) - p2 = array(self.points[2]) + p1 = np.array(self.points[0]) + p3 = np.array(self.points[1]) + p2 = np.array(self.points[2]) center, radius, t = three_point_circle(p1, p2, p3) - direction = 'cw' if sign(t) > 0 else 'ccw' + direction = 'cw' if np.sign(t) > 0 else 'ccw' - startangle = arctan2(p1[1] - center[1], p1[0] - center[0]) - stopangle = arctan2(p3[1] - center[1], p3[0] - center[0]) + startangle = np.arctan2(p1[1] - center[1], p1[0] - center[0]) + stopangle = np.arctan2(p3[1] - center[1], p3[0] - center[0]) self.geometry = DrawToolShape(LineString(arc(center, radius, startangle, stopangle, direction, self.steps_per_circ))) else: # self.mode == '12c' - p1 = array(self.points[0]) - p2 = array(self.points[1]) - pc = array(self.points[2]) + p1 = np.array(self.points[0]) + p2 = np.array(self.points[1]) + pc = np.array(self.points[2]) # Midpoint a = (p1 + p2) / 2.0 @@ -2187,7 +2181,7 @@ class FCArc(FCShapeTool): c = p2 - p1 # Perpendicular vector - b = dot(c, array([[0, -1], [1, 0]], dtype=float32)) + b = np.dot(c, np.array([[0, -1], [1, 0]], dtype=np.float32)) b /= numpy_norm(b) # Distance @@ -2196,14 +2190,14 @@ class FCArc(FCShapeTool): # Which side? Cross product with c. # cross(M-A, B-A), where line is AB and M is test point. side = (pc[0] - p1[0]) * c[1] - (pc[1] - p1[1]) * c[0] - t *= sign(side) + t *= np.sign(side) # Center = a + bt center = a + b * t radius = numpy_norm(center - p1) - startangle = arctan2(p1[1] - center[1], p1[0] - center[0]) - stopangle = arctan2(p2[1] - center[1], p2[0] - center[0]) + startangle = np.arctan2(p1[1] - center[1], p1[0] - center[0]) + stopangle = np.arctan2(p2[1] - center[1], p2[0] - center[0]) self.geometry = DrawToolShape(LineString(arc(center, radius, startangle, stopangle, self.direction, self.steps_per_circ))) @@ -4237,7 +4231,7 @@ class FlatCAMGeoEditor(QtCore.QObject): """ snap_x, snap_y = (x, y) - snap_distance = Inf + snap_distance = np.Inf # # ## Object (corner?) snap # # ## No need for the objects, just the coordinates @@ -4814,11 +4808,11 @@ class FlatCAMGeoEditor(QtCore.QObject): def distance(pt1, pt2): - return sqrt((pt1[0] - pt2[0]) ** 2 + (pt1[1] - pt2[1]) ** 2) + return np.sqrt((pt1[0] - pt2[0]) ** 2 + (pt1[1] - pt2[1]) ** 2) def mag(vec): - return sqrt(vec[0] ** 2 + vec[1] ** 2) + return np.sqrt(vec[0] ** 2 + vec[1] ** 2) def poly2rings(poly): @@ -4826,10 +4820,10 @@ def poly2rings(poly): def get_shapely_list_bounds(geometry_list): - xmin = Inf - ymin = Inf - xmax = -Inf - ymax = -Inf + xmin = np.Inf + ymin = np.Inf + xmax = -np.Inf + ymax = -np.Inf for gs in geometry_list: try: diff --git a/flatcamEditors/FlatCAMGrbEditor.py b/flatcamEditors/FlatCAMGrbEditor.py index 75acce0f..7f4a45d4 100644 --- a/flatcamEditors/FlatCAMGrbEditor.py +++ b/flatcamEditors/FlatCAMGrbEditor.py @@ -8,29 +8,28 @@ from PyQt5 import QtGui, QtCore, QtWidgets from PyQt5.QtCore import Qt, QSettings -from shapely.geometry import LineString, LinearRing, MultiLineString -# from shapely.geometry import mapping -from shapely.ops import cascaded_union, unary_union +from shapely.geometry import LineString, LinearRing, MultiLineString, Point, Polygon, MultiPolygon +from shapely.ops import cascaded_union import shapely.affinity as affinity -from numpy import arctan2, Inf, array, sqrt, sign, dot -from rtree import index as rtindex import threading import time from copy import copy, deepcopy +import logging -from camlib import * +from camlib import distance, arc, three_point_circle from flatcamGUI.GUIElements import FCEntry, FCComboBox, FCTable, FCDoubleSpinner, LengthEntry, RadioSet, \ - SpinBoxDelegate, EvalEntry, EvalEntry2, FCInputDialog, FCButton, OptionalInputSection, FCCheckBox -from FlatCAMObj import FlatCAMGerber -from flatcamParsers.ParseGerber import Gerber + EvalEntry2, FCInputDialog, FCButton, OptionalInputSection, FCCheckBox from FlatCAMTool import FlatCAMTool +import FlatCAMApp +import numpy as np from numpy.linalg import norm as numpy_norm +import math # from vispy.io import read_png # import pngcanvas - +import traceback import gettext import FlatCAMTranslation as fcTranslate import builtins @@ -39,6 +38,8 @@ fcTranslate.apply_language('strings') if '_' not in builtins.__dict__: _ = gettext.gettext +log = logging.getLogger('base') + class DrawToolShape(object): """ @@ -147,10 +148,10 @@ class DrawTool(object): def bounds(obj): def bounds_rec(o): if type(o) is list: - minx = Inf - miny = Inf - maxx = -Inf - maxy = -Inf + minx = np.Inf + miny = np.Inf + maxx = -np.Inf + maxy = -np.Inf for k in o: try: @@ -311,13 +312,13 @@ class FCPad(FCShapeTool): p4 = (point_x - self.half_width, point_y + self.half_height - self.half_width) down_center = [point_x, point_y - self.half_height + self.half_width] - d_start_angle = math.pi + d_start_angle = np.pi d_stop_angle = 0.0 down_arc = arc(down_center, self.half_width, d_start_angle, d_stop_angle, 'ccw', self.steps_per_circ) up_center = [point_x, point_y + self.half_height - self.half_width] u_start_angle = 0.0 - u_stop_angle = math.pi + u_stop_angle = np.pi up_arc = arc(up_center, self.half_width, u_start_angle, u_stop_angle, 'ccw', self.steps_per_circ) geo.append(p1) @@ -340,13 +341,13 @@ class FCPad(FCShapeTool): p4 = (point_x - self.half_width + self.half_height, point_y + self.half_height) left_center = [point_x - self.half_width + self.half_height, point_y] - d_start_angle = math.pi / 2 - d_stop_angle = 1.5 * math.pi + d_start_angle = np.pi / 2 + d_stop_angle = 1.5 * np.pi left_arc = arc(left_center, self.half_height, d_start_angle, d_stop_angle, 'ccw', self.steps_per_circ) right_center = [point_x + self.half_width - self.half_height, point_y] - u_start_angle = 1.5 * math.pi - u_stop_angle = math.pi / 2 + u_start_angle = 1.5 * np.pi + u_stop_angle = np.pi / 2 right_arc = arc(right_center, self.half_height, u_start_angle, u_stop_angle, 'ccw', self.steps_per_circ) geo.append(p1) @@ -618,13 +619,13 @@ class FCPadArray(FCShapeTool): p4 = (point_x - self.half_width, point_y + self.half_height - self.half_width) down_center = [point_x, point_y - self.half_height + self.half_width] - d_start_angle = math.pi + d_start_angle = np.pi d_stop_angle = 0.0 down_arc = arc(down_center, self.half_width, d_start_angle, d_stop_angle, 'ccw', self.steps_per_circ) up_center = [point_x, point_y + self.half_height - self.half_width] u_start_angle = 0.0 - u_stop_angle = math.pi + u_stop_angle = np.pi up_arc = arc(up_center, self.half_width, u_start_angle, u_stop_angle, 'ccw', self.steps_per_circ) geo.append(p1) @@ -647,13 +648,13 @@ class FCPadArray(FCShapeTool): p4 = (point_x - self.half_width + self.half_height, point_y + self.half_height) left_center = [point_x - self.half_width + self.half_height, point_y] - d_start_angle = math.pi / 2 - d_stop_angle = 1.5 * math.pi + d_start_angle = np.pi / 2 + d_stop_angle = 1.5 * np.pi left_arc = arc(left_center, self.half_height, d_start_angle, d_stop_angle, 'ccw', self.steps_per_circ) right_center = [point_x + self.half_width - self.half_height, point_y] - u_start_angle = 1.5 * math.pi - u_stop_angle = math.pi / 2 + u_start_angle = 1.5 * np.pi + u_stop_angle = np.pi / 2 right_arc = arc(right_center, self.half_height, u_start_angle, u_stop_angle, 'ccw', self.steps_per_circ) geo.append(p1) @@ -1296,7 +1297,7 @@ class FCTrack(FCRegion): self.draw_app.bend_mode = 2 self.cursor = QtGui.QCursor(QtGui.QPixmap('share/aero_path2.png')) QtGui.QGuiApplication.setOverrideCursor(self.cursor) - msg = _('Track Mode 2: Reverse 45 degrees ...') + msg = _('Track Mode 2: Reverse 45 degrees ...') elif self.draw_app.bend_mode == 2: self.draw_app.bend_mode = 3 self.cursor = QtGui.QCursor(QtGui.QPixmap('share/aero_path3.png')) @@ -1415,7 +1416,7 @@ class FCDisc(FCShapeTool): if len(self.points) == 1: p1 = self.points[0] p2 = data - radius = sqrt((p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2) + radius = math.sqrt((p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2) new_geo_el['solid'] = Point(p1).buffer((radius + self.buf_val / 2), int(self.steps_per_circ / 4)) return DrawToolUtilityShape(new_geo_el) @@ -1557,9 +1558,9 @@ class FCSemiDisc(FCShapeTool): p1 = self.points[1] p2 = data - radius = sqrt((center[0] - p1[0]) ** 2 + (center[1] - p1[1]) ** 2) + (self.buf_val / 2) - startangle = arctan2(p1[1] - center[1], p1[0] - center[0]) - stopangle = arctan2(p2[1] - center[1], p2[0] - center[0]) + radius = np.sqrt((center[0] - p1[0]) ** 2 + (center[1] - p1[1]) ** 2) + (self.buf_val / 2) + startangle = np.arctan2(p1[1] - center[1], p1[0] - center[0]) + stopangle = np.arctan2(p2[1] - center[1], p2[0] - center[0]) new_geo_el['solid'] = LineString( arc(center, radius, startangle, stopangle, self.direction, self.steps_per_circ)) @@ -1567,20 +1568,20 @@ class FCSemiDisc(FCShapeTool): return DrawToolUtilityShape([new_geo_el, new_geo_el_pt1]) elif self.mode == '132': - p1 = array(self.points[0]) - p3 = array(self.points[1]) - p2 = array(data) + p1 = np.array(self.points[0]) + p3 = np.array(self.points[1]) + p2 = np.array(data) try: center, radius, t = three_point_circle(p1, p2, p3) except TypeError: return - direction = 'cw' if sign(t) > 0 else 'ccw' + direction = 'cw' if np.sign(t) > 0 else 'ccw' radius += (self.buf_val / 2) - startangle = arctan2(p1[1] - center[1], p1[0] - center[0]) - stopangle = arctan2(p3[1] - center[1], p3[0] - center[0]) + startangle = np.arctan2(p1[1] - center[1], p1[0] - center[0]) + stopangle = np.arctan2(p3[1] - center[1], p3[0] - center[0]) new_geo_el['solid'] = LineString( arc(center, radius, startangle, stopangle, direction, self.steps_per_circ)) @@ -1591,8 +1592,8 @@ class FCSemiDisc(FCShapeTool): return DrawToolUtilityShape([new_geo_el, new_geo_el_pt2, new_geo_el_pt1, new_geo_el_pt3]) else: # '12c' - p1 = array(self.points[0]) - p2 = array(self.points[1]) + p1 = np.array(self.points[0]) + p2 = np.array(self.points[1]) # Midpoint a = (p1 + p2) / 2.0 @@ -1600,7 +1601,7 @@ class FCSemiDisc(FCShapeTool): c = p2 - p1 # Perpendicular vector - b = dot(c, array([[0, -1], [1, 0]], dtype=float32)) + b = np.dot(c, np.array([[0, -1], [1, 0]], dtype=np.float32)) b /= numpy_norm(b) # Distance @@ -1609,14 +1610,14 @@ class FCSemiDisc(FCShapeTool): # Which side? Cross product with c. # cross(M-A, B-A), where line is AB and M is test point. side = (data[0] - p1[0]) * c[1] - (data[1] - p1[1]) * c[0] - t *= sign(side) + t *= np.sign(side) # Center = a + bt center = a + b * t radius = numpy_norm(center - p1) + (self.buf_val / 2) - startangle = arctan2(p1[1] - center[1], p1[0] - center[0]) - stopangle = arctan2(p2[1] - center[1], p2[0] - center[0]) + startangle = np.arctan2(p1[1] - center[1], p1[0] - center[0]) + stopangle = np.arctan2(p2[1] - center[1], p2[0] - center[0]) new_geo_el['solid'] = LineString( arc(center, radius, startangle, stopangle, self.direction, self.steps_per_circ)) @@ -1636,8 +1637,8 @@ class FCSemiDisc(FCShapeTool): p2 = self.points[2] radius = distance(center, p1) + (self.buf_val / 2) - start_angle = arctan2(p1[1] - center[1], p1[0] - center[0]) - stop_angle = arctan2(p2[1] - center[1], p2[0] - center[0]) + start_angle = np.arctan2(p1[1] - center[1], p1[0] - center[0]) + stop_angle = np.arctan2(p2[1] - center[1], p2[0] - center[0]) new_geo_el['solid'] = Polygon( arc(center, radius, start_angle, stop_angle, self.direction, self.steps_per_circ)) new_geo_el['follow'] = Polygon( @@ -1645,16 +1646,16 @@ class FCSemiDisc(FCShapeTool): self.geometry = DrawToolShape(new_geo_el) elif self.mode == '132': - p1 = array(self.points[0]) - p3 = array(self.points[1]) - p2 = array(self.points[2]) + p1 = np.array(self.points[0]) + p3 = np.array(self.points[1]) + p2 = np.array(self.points[2]) center, radius, t = three_point_circle(p1, p2, p3) - direction = 'cw' if sign(t) > 0 else 'ccw' + direction = 'cw' if np.sign(t) > 0 else 'ccw' radius += (self.buf_val / 2) - start_angle = arctan2(p1[1] - center[1], p1[0] - center[0]) - stop_angle = arctan2(p3[1] - center[1], p3[0] - center[0]) + start_angle = np.arctan2(p1[1] - center[1], p1[0] - center[0]) + stop_angle = np.arctan2(p3[1] - center[1], p3[0] - center[0]) new_geo_el['solid'] = Polygon(arc(center, radius, start_angle, stop_angle, direction, self.steps_per_circ)) new_geo_el['follow'] = Polygon( @@ -1662,9 +1663,9 @@ class FCSemiDisc(FCShapeTool): self.geometry = DrawToolShape(new_geo_el) else: # self.mode == '12c' - p1 = array(self.points[0]) - p2 = array(self.points[1]) - pc = array(self.points[2]) + p1 = np.array(self.points[0]) + p2 = np.array(self.points[1]) + pc = np.array(self.points[2]) # Midpoint a = (p1 + p2) / 2.0 @@ -1673,7 +1674,7 @@ class FCSemiDisc(FCShapeTool): c = p2 - p1 # Perpendicular vector - b = dot(c, array([[0, -1], [1, 0]], dtype=float32)) + b = np.dot(c, np.array([[0, -1], [1, 0]], dtype=np.float32)) b /= numpy_norm(b) # Distance @@ -1682,14 +1683,14 @@ class FCSemiDisc(FCShapeTool): # Which side? Cross product with c. # cross(M-A, B-A), where line is AB and M is test point. side = (pc[0] - p1[0]) * c[1] - (pc[1] - p1[1]) * c[0] - t *= sign(side) + t *= np.sign(side) # Center = a + bt center = a + b * t radius = numpy_norm(center - p1) + (self.buf_val / 2) - start_angle = arctan2(p1[1] - center[1], p1[0] - center[0]) - stop_angle = arctan2(p2[1] - center[1], p2[0] - center[0]) + start_angle = np.arctan2(p1[1] - center[1], p1[0] - center[0]) + stop_angle = np.arctan2(p2[1] - center[1], p2[0] - center[0]) new_geo_el['solid'] = Polygon( arc(center, radius, start_angle, stop_angle, self.direction, self.steps_per_circ)) @@ -2437,9 +2438,7 @@ class FlatCAMGrbEditor(QtCore.QObject): self.apertures_box.addLayout(grid1) apcode_lbl = QtWidgets.QLabel('%s:' % _('Aperture Code')) - apcode_lbl.setToolTip( - _("Code for the new aperture") - ) + apcode_lbl.setToolTip(_("Code for the new aperture")) grid1.addWidget(apcode_lbl, 1, 0) self.apcode_entry = FCEntry() @@ -2448,11 +2447,11 @@ class FlatCAMGrbEditor(QtCore.QObject): apsize_lbl = QtWidgets.QLabel('%s:' % _('Aperture Size')) apsize_lbl.setToolTip( - _("Size for the new aperture.\n" - "If aperture type is 'R' or 'O' then\n" - "this value is automatically\n" - "calculated as:\n" - "sqrt(width**2 + height**2)") + _("Size for the new aperture.\n" + "If aperture type is 'R' or 'O' then\n" + "this value is automatically\n" + "calculated as:\n" + "sqrt(width**2 + height**2)") ) grid1.addWidget(apsize_lbl, 2, 0) @@ -2462,10 +2461,10 @@ class FlatCAMGrbEditor(QtCore.QObject): aptype_lbl = QtWidgets.QLabel('%s:' % _('Aperture Type')) aptype_lbl.setToolTip( - _("Select the type of new aperture. Can be:\n" - "C = circular\n" - "R = rectangular\n" - "O = oblong") + _("Select the type of new aperture. Can be:\n" + "C = circular\n" + "R = rectangular\n" + "O = oblong") ) grid1.addWidget(aptype_lbl, 3, 0) @@ -2475,9 +2474,9 @@ class FlatCAMGrbEditor(QtCore.QObject): self.apdim_lbl = QtWidgets.QLabel('%s:' % _('Aperture Dim')) self.apdim_lbl.setToolTip( - _("Dimensions for the new aperture.\n" - "Active only for rectangular apertures (type R).\n" - "The format is (width, height)") + _("Dimensions for the new aperture.\n" + "Active only for rectangular apertures (type R).\n" + "The format is (width, height)") ) grid1.addWidget(self.apdim_lbl, 4, 0) @@ -2495,12 +2494,12 @@ class FlatCAMGrbEditor(QtCore.QObject): self.addaperture_btn = QtWidgets.QPushButton(_('Add')) self.addaperture_btn.setToolTip( - _( "Add a new aperture to the aperture list.") + _("Add a new aperture to the aperture list.") ) self.delaperture_btn = QtWidgets.QPushButton(_('Delete')) self.delaperture_btn.setToolTip( - _( "Delete a aperture in the aperture list") + _("Delete a aperture in the aperture list") ) hlay_ad.addWidget(self.addaperture_btn) hlay_ad.addWidget(self.delaperture_btn) @@ -2677,8 +2676,8 @@ class FlatCAMGrbEditor(QtCore.QObject): self.array_type_combo = FCComboBox() self.array_type_combo.setToolTip( - _( "Select the type of pads array to create.\n" - "It can be Linear X(Y) or Circular") + _("Select the type of pads array to create.\n" + "It can be Linear X(Y) or Circular") ) self.array_type_combo.addItem(_("Linear")) self.array_type_combo.addItem(_("Circular")) @@ -2733,10 +2732,10 @@ class FlatCAMGrbEditor(QtCore.QObject): self.linear_angle_label = QtWidgets.QLabel('%s:' % _('Angle')) self.linear_angle_label.setToolTip( - _( "Angle at which the linear array is placed.\n" - "The precision is of max 2 decimals.\n" - "Min value is: -359.99 degrees.\n" - "Max value is: 360.00 degrees.") + _("Angle at which the linear array is placed.\n" + "The precision is of max 2 decimals.\n" + "Min value is: -359.99 degrees.\n" + "Max value is: 360.00 degrees.") ) self.linear_angle_label.setMinimumWidth(100) @@ -2808,9 +2807,9 @@ class FlatCAMGrbEditor(QtCore.QObject): "scale": {"button": self.app.ui.aperture_scale_btn, "constructor": FCScale}, "markarea": {"button": self.app.ui.aperture_markarea_btn, - "constructor": FCMarkArea}, + "constructor": FCMarkArea}, "eraser": {"button": self.app.ui.aperture_eraser_btn, - "constructor": FCEraser}, + "constructor": FCEraser}, "copy": {"button": self.app.ui.aperture_copy_btn, "constructor": FCApertureCopy}, "transform": {"button": self.app.ui.grb_transform_btn, @@ -3245,7 +3244,7 @@ class FlatCAMGrbEditor(QtCore.QObject): self.storage_dict[ap_id]['width'] = dims[0] self.storage_dict[ap_id]['height'] = dims[1] - size_val = math.sqrt((dims[0] ** 2) + (dims[1] ** 2)) + size_val = np.sqrt((dims[0] ** 2) + (dims[1] ** 2)) self.apsize_entry.set_value(size_val) except Exception as e: @@ -3613,7 +3612,6 @@ class FlatCAMGrbEditor(QtCore.QObject): self.app.ui.grb_draw_eraser.triggered.connect(self.on_eraser) self.app.ui.grb_draw_transformations.triggered.connect(self.on_transform) - def disconnect_canvas_event_handlers(self): # we restore the key and mouse control to FlatCAMApp method @@ -3803,7 +3801,7 @@ class FlatCAMGrbEditor(QtCore.QObject): # we subtract the big "negative" (clear) geometry from each solid polygon but only the part of clear geometry # that fits inside the solid. otherwise we may loose the solid for apid in self.gerber_obj.apertures: - temp_solid_geometry= [] + temp_solid_geometry = [] if 'geometry' in self.gerber_obj.apertures[apid]: # for elem in self.gerber_obj.apertures[apid]['geometry']: # if 'solid' in elem: @@ -6032,10 +6030,10 @@ class TransformEditorTool(FlatCAMTool): def get_shapely_list_bounds(geometry_list): - xmin = Inf - ymin = Inf - xmax = -Inf - ymax = -Inf + xmin = np.Inf + ymin = np.Inf + xmax = -np.Inf + ymax = -np.Inf for gs in geometry_list: try: diff --git a/flatcamGUI/FlatCAMGUI.py b/flatcamGUI/FlatCAMGUI.py index 0f0753ab..ea44c147 100644 --- a/flatcamGUI/FlatCAMGUI.py +++ b/flatcamGUI/FlatCAMGUI.py @@ -14,6 +14,8 @@ from flatcamGUI.PreferencesUI import * from matplotlib.backend_bases import KeyEvent as mpl_key_event +from copy import deepcopy +from datetime import datetime import gettext import FlatCAMTranslation as fcTranslate import builtins @@ -3696,7 +3698,7 @@ class FlatCAMSystemTray(QtWidgets.QSystemTrayIcon): class BookmarkManager(QtWidgets.QWidget): - mark_rows = pyqtSignal() + mark_rows = QtCore.pyqtSignal() def __init__(self, app, storage, parent=None): super(BookmarkManager, self).__init__(parent) diff --git a/flatcamGUI/GUIElements.py b/flatcamGUI/GUIElements.py index 58012e3c..c95a6ea9 100644 --- a/flatcamGUI/GUIElements.py +++ b/flatcamGUI/GUIElements.py @@ -12,18 +12,14 @@ # ########################################################## from PyQt5 import QtGui, QtCore, QtWidgets -from PyQt5.QtCore import Qt, pyqtSignal, pyqtSlot +from PyQt5.QtCore import Qt, pyqtSlot from PyQt5.QtWidgets import QTextEdit, QCompleter, QAction -from PyQt5.QtGui import QColor, QKeySequence, QPalette, QTextCursor +from PyQt5.QtGui import QKeySequence, QTextCursor from copy import copy import re import logging import html -import webbrowser -from copy import deepcopy -import sys -from datetime import datetime log = logging.getLogger('base') @@ -513,7 +509,7 @@ class EvalEntry2(QtWidgets.QLineEdit): class FCSpinner(QtWidgets.QSpinBox): - returnPressed = pyqtSignal() + returnPressed = QtCore.pyqtSignal() def __init__(self, parent=None): super(FCSpinner, self).__init__(parent) @@ -580,7 +576,7 @@ class FCSpinner(QtWidgets.QSpinBox): class FCDoubleSpinner(QtWidgets.QDoubleSpinBox): - returnPressed = pyqtSignal() + returnPressed = QtCore.pyqtSignal() def __init__(self, parent=None): super(FCDoubleSpinner, self).__init__(parent) @@ -869,16 +865,16 @@ class FCTextAreaExtended(QtWidgets.QTextEdit): if self.textCursor().block().text().startswith(" "): # skip the white space self.moveCursor(QtGui.QTextCursor.NextWord) - self.moveCursor(QtGui.QTextCursor.NextCharacter,QtGui.QTextCursor.KeepAnchor) + self.moveCursor(QtGui.QTextCursor.NextCharacter, QtGui.QTextCursor.KeepAnchor) character = self.textCursor().selectedText() if character == "#": # delete # self.textCursor().deletePreviousChar() # delete white space - self.moveCursor(QtGui.QTextCursor.NextWord,QtGui.QTextCursor.KeepAnchor) + self.moveCursor(QtGui.QTextCursor.NextWord, QtGui.QTextCursor.KeepAnchor) self.textCursor().removeSelectedText() else: - self.moveCursor(QtGui.QTextCursor.PreviousCharacter,QtGui.QTextCursor.KeepAnchor) + self.moveCursor(QtGui.QTextCursor.PreviousCharacter, QtGui.QTextCursor.KeepAnchor) self.textCursor().insertText("# ") cursor = QtGui.QTextCursor(self.textCursor()) cursor.setPosition(pos) @@ -1261,7 +1257,6 @@ class FCDetachableTab(QtWidgets.QTabWidget): attached = True break - # If the tab is not attached, close it's window and # remove the reference to it if not attached: @@ -1342,8 +1337,8 @@ class FCDetachableTab(QtWidgets.QTabWidget): can be re-attached by closing the dialog or by dragging the window into the tab bar """ - onCloseSignal = pyqtSignal(QtWidgets.QWidget, str, QtGui.QIcon) - onDropSignal = pyqtSignal(str, QtCore.QPoint) + onCloseSignal = QtCore.pyqtSignal(QtWidgets.QWidget, str, QtGui.QIcon) + onDropSignal = QtCore.pyqtSignal(str, QtCore.QPoint) def __init__(self, name, contentWidget): QtWidgets.QMainWindow.__init__(self, None) @@ -1384,7 +1379,7 @@ class FCDetachableTab(QtWidgets.QTabWidget): An event filter class to detect a QMainWindow drop event """ - onDropSignal = pyqtSignal(QtCore.QPoint) + onDropSignal = QtCore.pyqtSignal(QtCore.QPoint) def __init__(self): QtCore.QObject.__init__(self) @@ -1416,11 +1411,11 @@ class FCDetachableTab(QtWidgets.QTabWidget): return False class FCTabBar(QtWidgets.QTabBar): - onDetachTabSignal = pyqtSignal(int, QtCore.QPoint) - onMoveTabSignal = pyqtSignal(int, int) - detachedTabDropSignal = pyqtSignal(str, int, QtCore.QPoint) + onDetachTabSignal = QtCore.pyqtSignal(int, QtCore.QPoint) + onMoveTabSignal = QtCore.pyqtSignal(int, int) + detachedTabDropSignal = QtCore.pyqtSignal(str, int, QtCore.QPoint) - right_click = pyqtSignal(int) + right_click = QtCore.pyqtSignal(int) def __init__(self, parent=None): QtWidgets.QTabBar.__init__(self, parent) @@ -1498,7 +1493,7 @@ class FCDetachableTab(QtWidgets.QTabWidget): self.dragInitiated = True # If the current movement is a drag initiated by the left button - if (((event.buttons() & QtCore.Qt.LeftButton)) and self.dragInitiated and self.can_be_dragged): + if ((event.buttons() & QtCore.Qt.LeftButton)) and self.dragInitiated and self.can_be_dragged: # Stop the move event finishMoveEvent = QtGui.QMouseEvent( @@ -1591,7 +1586,7 @@ class FCDetachableTab(QtWidgets.QTabWidget): class FCDetachableTab2(FCDetachableTab): - tab_closed_signal = pyqtSignal(object) + tab_closed_signal = QtCore.pyqtSignal(object) def __init__(self, protect=None, protect_by_name=None, parent=None): super(FCDetachableTab2, self).__init__(protect=protect, protect_by_name=protect_by_name, parent=parent) @@ -1729,7 +1724,7 @@ class OptionalHideInputSection: class FCTable(QtWidgets.QTableWidget): - drag_drop_sig = pyqtSignal() + drag_drop_sig = QtCore.pyqtSignal() def __init__(self, drag_drop=False, protected_rows=None, parent=None): super(FCTable, self).__init__(parent) @@ -2024,8 +2019,8 @@ class _ExpandableTextEdit(QTextEdit): Class implements edit line, which expands themselves automatically """ - historyNext = pyqtSignal() - historyPrev = pyqtSignal() + historyNext = QtCore.pyqtSignal() + historyPrev = QtCore.pyqtSignal() def __init__(self, termwidget, *args): QTextEdit.__init__(self, *args) @@ -2148,7 +2143,7 @@ class _ExpandableTextEdit(QTextEdit): class MyCompleter(QCompleter): - insertText = pyqtSignal(str) + insertText = QtCore.pyqtSignal(str) def __init__(self, parent=None): QCompleter.__init__(self) @@ -2166,4 +2161,3 @@ class MyCompleter(QCompleter): def getSelected(self): return self.lastSelected - diff --git a/flatcamGUI/ObjectUI.py b/flatcamGUI/ObjectUI.py index 21e23545..d66df03b 100644 --- a/flatcamGUI/ObjectUI.py +++ b/flatcamGUI/ObjectUI.py @@ -11,8 +11,6 @@ # Date: 3/10/2019 # # ########################################################## -from PyQt5 import QtGui, QtCore, QtWidgets -from PyQt5.QtCore import Qt from flatcamGUI.GUIElements import * import sys diff --git a/flatcamGUI/PlotCanvasLegacy.py b/flatcamGUI/PlotCanvasLegacy.py index 27fd05eb..01780ae6 100644 --- a/flatcamGUI/PlotCanvasLegacy.py +++ b/flatcamGUI/PlotCanvasLegacy.py @@ -7,7 +7,7 @@ # Modified by Marius Stanciu 09/21/2019 # ############################################################ -from PyQt5 import QtGui, QtCore, QtWidgets +from PyQt5 import QtCore from PyQt5.QtCore import pyqtSignal # needed for legacy mode diff --git a/flatcamGUI/PreferencesUI.py b/flatcamGUI/PreferencesUI.py index edf2b1ca..cb2eab05 100644 --- a/flatcamGUI/PreferencesUI.py +++ b/flatcamGUI/PreferencesUI.py @@ -8,11 +8,8 @@ from PyQt5.QtCore import QSettings from flatcamGUI.GUIElements import * import platform -import webbrowser import sys -from flatcamEditors.FlatCAMGeoEditor import FCShapeTool - import gettext import FlatCAMTranslation as fcTranslate import builtins diff --git a/flatcamGUI/VisPyCanvas.py b/flatcamGUI/VisPyCanvas.py index cef600ad..cd7a41a1 100644 --- a/flatcamGUI/VisPyCanvas.py +++ b/flatcamGUI/VisPyCanvas.py @@ -6,12 +6,15 @@ # MIT Licence # # ########################################################## -import numpy as np from PyQt5.QtGui import QPalette from PyQt5.QtCore import QSettings + +import numpy as np + import vispy.scene as scene from vispy.scene.cameras.base_camera import BaseCamera from vispy.color import Color + import time white = Color("#ffffff") diff --git a/flatcamParsers/ParseDXF_Spline.py b/flatcamParsers/ParseDXF_Spline.py index 3c504483..4aaf1f95 100644 --- a/flatcamParsers/ParseDXF_Spline.py +++ b/flatcamParsers/ParseDXF_Spline.py @@ -9,7 +9,6 @@ # ########################################################## import math -import sys def norm(v): diff --git a/flatcamParsers/ParseExcellon.py b/flatcamParsers/ParseExcellon.py index ba00a476..2843e7ec 100644 --- a/flatcamParsers/ParseExcellon.py +++ b/flatcamParsers/ParseExcellon.py @@ -1,4 +1,14 @@ -from camlib import * + +from camlib import Geometry +import FlatCAMApp + +import shapely.affinity as affinity +from shapely.geometry import Point, LineString +import numpy as np + +import re +import logging +import traceback import FlatCAMTranslation as fcTranslate @@ -8,6 +18,8 @@ import builtins if '_' not in builtins.__dict__: _ = gettext.gettext +log = logging.getLogger('base') + class Excellon(Geometry): """ @@ -1017,10 +1029,10 @@ class Excellon(Geometry): def bounds_rec(obj): if type(obj) is list: - minx = Inf - miny = Inf - maxx = -Inf - maxy = -Inf + minx = np.Inf + miny = np.Inf + maxx = -np.Inf + maxy = -np.Inf for k in obj: if type(k) is dict: diff --git a/flatcamParsers/ParseFont.py b/flatcamParsers/ParseFont.py index 88d32c47..cb09a862 100644 --- a/flatcamParsers/ParseFont.py +++ b/flatcamParsers/ParseFont.py @@ -11,12 +11,11 @@ # ###################################################################### import re, os, sys, glob -import itertools from shapely.geometry import Point, Polygon -from shapely.affinity import translate, scale, rotate +from shapely.affinity import translate, scale from shapely.geometry import MultiPolygon -from shapely.geometry.base import BaseGeometry + import freetype as ft from fontTools import ttLib diff --git a/flatcamParsers/ParseGerber.py b/flatcamParsers/ParseGerber.py index 07c26728..64f7aa8c 100644 --- a/flatcamParsers/ParseGerber.py +++ b/flatcamParsers/ParseGerber.py @@ -1,4 +1,19 @@ -from camlib import * + +from camlib import Geometry, arc, arc_angle, ApertureMacro +import FlatCAMApp + +import numpy as np +import re +import logging +import traceback +from copy import deepcopy +import sys + +from shapely.ops import cascaded_union +from shapely.geometry import Polygon, MultiPolygon, LineString, Point +import shapely.affinity as affinity +from shapely.geometry import box as shply_box + import FlatCAMTranslation as fcTranslate import gettext @@ -7,6 +22,8 @@ import builtins if '_' not in builtins.__dict__: _ = gettext.gettext +log = logging.getLogger('base') + class Gerber(Geometry): """ @@ -253,14 +270,14 @@ class Gerber(Geometry): self.apertures[apid] = {"type": "R", "width": float(paramList[0]), "height": float(paramList[1]), - "size": sqrt(float(paramList[0]) ** 2 + float(paramList[1]) ** 2)} # Hack + "size": np.sqrt(float(paramList[0]) ** 2 + float(paramList[1]) ** 2)} # Hack return apid if apertureType == "O": # Obround self.apertures[apid] = {"type": "O", "width": float(paramList[0]), "height": float(paramList[1]), - "size": sqrt(float(paramList[0]) ** 2 + float(paramList[1]) ** 2)} # Hack + "size": np.sqrt(float(paramList[0]) ** 2 + float(paramList[1]) ** 2)} # Hack return apid if apertureType == "P": # Polygon (regular) @@ -1231,15 +1248,15 @@ class Gerber(Geometry): if quadrant_mode == 'MULTI': center = [i + current_x, j + current_y] - radius = sqrt(i ** 2 + j ** 2) - start = arctan2(-j, -i) # Start angle + radius = np.sqrt(i ** 2 + j ** 2) + start = np.arctan2(-j, -i) # Start angle # Numerical errors might prevent start == stop therefore # we check ahead of time. This should result in a # 360 degree arc. if current_x == circular_x and current_y == circular_y: stop = start else: - stop = arctan2(-center[1] + circular_y, -center[0] + circular_x) # Stop angle + stop = np.arctan2(-center[1] + circular_y, -center[0] + circular_x) # Stop angle this_arc = arc(center, radius, start, stop, arcdir[current_interpolation_mode], @@ -1273,10 +1290,10 @@ class Gerber(Geometry): valid = False log.debug("I: %f J: %f" % (i, j)) for center in center_candidates: - radius = sqrt(i ** 2 + j ** 2) + radius = np.sqrt(i ** 2 + j ** 2) # Make sure radius to start is the same as radius to end. - radius2 = sqrt((center[0] - circular_x) ** 2 + (center[1] - circular_y) ** 2) + radius2 = np.sqrt((center[0] - circular_x) ** 2 + (center[1] - circular_y) ** 2) if radius2 < radius * 0.95 or radius2 > radius * 1.05: continue # Not a valid center. @@ -1284,16 +1301,16 @@ class Gerber(Geometry): i = center[0] - current_x j = center[1] - current_y - start = arctan2(-j, -i) # Start angle - stop = arctan2(-center[1] + circular_y, -center[0] + circular_x) # Stop angle + start = np.arctan2(-j, -i) # Start angle + stop = np.arctan2(-center[1] + circular_y, -center[0] + circular_x) # Stop angle angle = abs(arc_angle(start, stop, arcdir[current_interpolation_mode])) log.debug("ARC START: %f, %f CENTER: %f, %f STOP: %f, %f" % (current_x, current_y, center[0], center[1], circular_x, circular_y)) log.debug("START Ang: %f, STOP Ang: %f, DIR: %s, ABS: %.12f <= %.12f: %s" % - (start * 180 / pi, stop * 180 / pi, arcdir[current_interpolation_mode], - angle * 180 / pi, pi / 2 * 180 / pi, angle <= (pi + 1e-6) / 2)) + (start * 180 / np.pi, stop * 180 / np.pi, arcdir[current_interpolation_mode], + angle * 180 / np.pi, np.pi / 2 * 180 / np.pi, angle <= (np.pi + 1e-6) / 2)) - if angle <= (pi + 1e-6) / 2: + if angle <= (np.pi + 1e-6) / 2: log.debug("########## ACCEPTING ARC ############") this_arc = arc(center, radius, start, stop, arcdir[current_interpolation_mode], @@ -1478,8 +1495,8 @@ class Gerber(Geometry): n_vertices = aperture['nVertices'] points = [] for i in range(0, n_vertices): - x = loc[0] + 0.5 * diam * (cos(2 * pi * i / n_vertices)) - y = loc[1] + 0.5 * diam * (sin(2 * pi * i / n_vertices)) + x = loc[0] + 0.5 * diam * (np.cos(2 * np.pi * i / n_vertices)) + y = loc[1] + 0.5 * diam * (np.sin(2 * np.pi * i / n_vertices)) points.append((x, y)) ply = Polygon(points) if 'rotation' in aperture: @@ -1553,10 +1570,10 @@ class Gerber(Geometry): def bounds_rec(obj): if type(obj) is list and type(obj) is not MultiPolygon: - minx = Inf - miny = Inf - maxx = -Inf - maxy = -Inf + minx = np.Inf + miny = np.Inf + maxx = -np.Inf + maxy = -np.Inf for k in obj: if type(k) is dict: diff --git a/flatcamTools/ToolCalculators.py b/flatcamTools/ToolCalculators.py index 8aff7242..a6a8aa3f 100644 --- a/flatcamTools/ToolCalculators.py +++ b/flatcamTools/ToolCalculators.py @@ -5,8 +5,9 @@ # MIT Licence # # ########################################################## +from PyQt5 import QtWidgets from FlatCAMTool import FlatCAMTool -from FlatCAMObj import * +from flatcamGUI.GUIElements import FCSpinner, FCDoubleSpinner, FCEntry import math import gettext @@ -321,11 +322,11 @@ class ToolCalculator(FlatCAMTool): def on_calculate_inch_units(self): mm_val = float(self.mm_entry.get_value()) - self.inch_entry.set_value('%.*f' % (self.decimals,(mm_val / 25.4))) + self.inch_entry.set_value('%.*f' % (self.decimals, (mm_val / 25.4))) def on_calculate_mm_units(self): inch_val = float(self.inch_entry.get_value()) - self.mm_entry.set_value('%.*f' % (self.decimals,(inch_val * 25.4))) + self.mm_entry.set_value('%.*f' % (self.decimals, (inch_val * 25.4))) def on_calculate_eplate(self): length = float(self.pcblength_entry.get_value()) diff --git a/flatcamTools/ToolCutOut.py b/flatcamTools/ToolCutOut.py index 2cb2ee66..cddd7b70 100644 --- a/flatcamTools/ToolCutOut.py +++ b/flatcamTools/ToolCutOut.py @@ -5,12 +5,21 @@ # MIT Licence # # ########################################################## +from PyQt5 import QtWidgets, QtGui, QtCore from FlatCAMTool import FlatCAMTool -from ObjectCollection import * -from FlatCAMApp import * -from shapely.geometry import box -from shapely.ops import cascaded_union, unary_union +from flatcamGUI.GUIElements import FCDoubleSpinner, FCCheckBox, RadioSet, FCComboBox +from FlatCAMObj import FlatCAMGerber +from shapely.geometry import box, MultiPolygon, Polygon, LineString, LinearRing +from shapely.ops import cascaded_union, unary_union +import shapely.affinity as affinity + +from matplotlib.backend_bases import KeyEvent as mpl_key_event + +from numpy import Inf +from copy import deepcopy +import math +import logging import gettext import FlatCAMTranslation as fcTranslate import builtins @@ -19,6 +28,8 @@ fcTranslate.apply_language('strings') if '_' not in builtins.__dict__: _ = gettext.gettext +log = logging.getLogger('base') + class CutOut(FlatCAMTool): diff --git a/flatcamTools/ToolDblSided.py b/flatcamTools/ToolDblSided.py index 0b58c94e..9747bb4a 100644 --- a/flatcamTools/ToolDblSided.py +++ b/flatcamTools/ToolDblSided.py @@ -1,9 +1,14 @@ + +from PyQt5 import QtWidgets, QtCore + from FlatCAMTool import FlatCAMTool -from FlatCAMObj import * +from flatcamGUI.GUIElements import RadioSet, FCDoubleSpinner, EvalEntry +from FlatCAMObj import FlatCAMGerber, FlatCAMExcellon, FlatCAMGeometry + from shapely.geometry import Point from shapely import affinity -from PyQt5 import QtCore +import logging import gettext import FlatCAMTranslation as fcTranslate import builtins @@ -12,6 +17,8 @@ fcTranslate.apply_language('strings') if '_' not in builtins.__dict__: _ = gettext.gettext +log = logging.getLogger('base') + class DblSidedTool(FlatCAMTool): diff --git a/flatcamTools/ToolDistance.py b/flatcamTools/ToolDistance.py index 3438dacb..c9fe7183 100644 --- a/flatcamTools/ToolDistance.py +++ b/flatcamTools/ToolDistance.py @@ -5,12 +5,15 @@ # MIT Licence # # ########################################################## +from PyQt5 import QtWidgets, QtCore + from FlatCAMTool import FlatCAMTool -from FlatCAMObj import * from flatcamGUI.VisPyVisuals import * +from flatcamGUI.GUIElements import FCEntry -from math import sqrt - +import copy +import math +import logging import gettext import FlatCAMTranslation as fcTranslate import builtins @@ -19,6 +22,8 @@ fcTranslate.apply_language('strings') if '_' not in builtins.__dict__: _ = gettext.gettext +log = logging.getLogger('base') + class Distance(FlatCAMTool): @@ -335,7 +340,7 @@ class Distance(FlatCAMTool): elif len(self.points) == 2: dx = self.points[1][0] - self.points[0][0] dy = self.points[1][1] - self.points[0][1] - d = sqrt(dx ** 2 + dy ** 2) + d = math.sqrt(dx ** 2 + dy ** 2) self.stop_entry.set_value("(%.*f, %.*f)" % (self.decimals, pos[0], self.decimals, pos[1])) self.app.inform.emit(_("MEASURING: Result D(x) = {d_x} | D(y) = {d_y} | Distance = {d_z}").format( diff --git a/flatcamTools/ToolDistanceMin.py b/flatcamTools/ToolDistanceMin.py index 942060a5..d99f3f77 100644 --- a/flatcamTools/ToolDistanceMin.py +++ b/flatcamTools/ToolDistanceMin.py @@ -5,14 +5,16 @@ # MIT Licence # # ########################################################## +from PyQt5 import QtWidgets, QtCore from FlatCAMTool import FlatCAMTool -from FlatCAMObj import * from flatcamGUI.VisPyVisuals import * +from flatcamGUI.GUIElements import FCEntry from shapely.ops import nearest_points +from shapely.geometry import Point -from math import sqrt - +import math +import logging import gettext import FlatCAMTranslation as fcTranslate import builtins @@ -21,6 +23,8 @@ fcTranslate.apply_language('strings') if '_' not in builtins.__dict__: _ = gettext.gettext +log = logging.getLogger('base') + class DistanceMin(FlatCAMTool): @@ -260,7 +264,7 @@ class DistanceMin(FlatCAMTool): except Exception as e: pass - d = sqrt(dx ** 2 + dy ** 2) + d = math.sqrt(dx ** 2 + dy ** 2) self.total_distance_entry.set_value('%.*f' % (self.decimals, abs(d))) self.h_point = (min(first_pos.x, last_pos.x) + (abs(dx) / 2), min(first_pos.y, last_pos.y) + (abs(dy) / 2)) diff --git a/flatcamTools/ToolFilm.py b/flatcamTools/ToolFilm.py index 300bf0af..bb1ecfdb 100644 --- a/flatcamTools/ToolFilm.py +++ b/flatcamTools/ToolFilm.py @@ -5,14 +5,15 @@ # MIT Licence # # ########################################################## -from FlatCAMTool import FlatCAMTool -from FlatCAMObj import * - -from flatcamGUI.GUIElements import RadioSet, FCDoubleSpinner, FCCheckBox, \ - OptionalHideInputSection, OptionalInputSection from PyQt5 import QtGui, QtCore, QtWidgets +from FlatCAMTool import FlatCAMTool +from flatcamGUI.GUIElements import RadioSet, FCDoubleSpinner, FCCheckBox, \ + OptionalHideInputSection, OptionalInputSection + from copy import deepcopy +import logging +from shapely.geometry import Polygon, MultiPolygon, Point import gettext import FlatCAMTranslation as fcTranslate @@ -22,6 +23,8 @@ fcTranslate.apply_language('strings') if '_' not in builtins.__dict__: _ = gettext.gettext +log = logging.getLogger('base') + class Film(FlatCAMTool): @@ -166,7 +169,7 @@ class Film(FlatCAMTool): self.ois_scale = OptionalInputSection(self.film_scale_cb, [self.film_scalex_label, self.film_scalex_entry, self.film_scaley_label, self.film_scaley_entry]) # Skew Geometry - self.film_skew_cb =FCCheckBox('%s' % _("Skew Film geometry")) + self.film_skew_cb = FCCheckBox('%s' % _("Skew Film geometry")) self.film_skew_cb.setToolTip( _("Positive values will skew to the right\n" "while negative values will skew to the left.") @@ -202,9 +205,9 @@ class Film(FlatCAMTool): "It can be one of the four points of the geometry bounding box.") ) self.film_skew_reference = RadioSet([{'label': _('Bottom Left'), 'value': 'bottomleft'}, - {'label': _('Top Left'), 'value': 'topleft'}, - {'label': _('Bottom Right'), 'value': 'bottomright'}, - {'label': _('Top right'), 'value': 'topright'}], + {'label': _('Top Left'), 'value': 'topleft'}, + {'label': _('Bottom Right'), 'value': 'bottomright'}, + {'label': _('Top right'), 'value': 'topright'}], orientation='vertical', stretch=False) diff --git a/flatcamTools/ToolImage.py b/flatcamTools/ToolImage.py index 715f2c52..b6253949 100644 --- a/flatcamTools/ToolImage.py +++ b/flatcamTools/ToolImage.py @@ -5,11 +5,11 @@ # MIT Licence # # ########################################################## -from FlatCAMTool import FlatCAMTool - -from flatcamGUI.GUIElements import RadioSet, FCComboBox, FCSpinner from PyQt5 import QtGui, QtWidgets +from FlatCAMTool import FlatCAMTool +from flatcamGUI.GUIElements import RadioSet, FCComboBox, FCSpinner + import gettext import FlatCAMTranslation as fcTranslate import builtins diff --git a/flatcamTools/ToolMove.py b/flatcamTools/ToolMove.py index 3ca87862..fcf2d262 100644 --- a/flatcamTools/ToolMove.py +++ b/flatcamTools/ToolMove.py @@ -5,12 +5,13 @@ # MIT Licence # # ########################################################## +from PyQt5 import QtWidgets, QtCore from FlatCAMTool import FlatCAMTool -from FlatCAMObj import * from flatcamGUI.VisPyVisuals import * +from FlatCAMObj import FlatCAMGerber from copy import copy - +import logging import gettext import FlatCAMTranslation as fcTranslate import builtins @@ -19,11 +20,13 @@ fcTranslate.apply_language('strings') if '_' not in builtins.__dict__: _ = gettext.gettext +log = logging.getLogger('base') + class ToolMove(FlatCAMTool): toolName = _("Move") - replot_signal = pyqtSignal(list) + replot_signal = QtCore.pyqtSignal(list) def __init__(self, app): FlatCAMTool.__init__(self, app) diff --git a/flatcamTools/ToolNonCopperClear.py b/flatcamTools/ToolNonCopperClear.py index f0c03738..16817ab7 100644 --- a/flatcamTools/ToolNonCopperClear.py +++ b/flatcamTools/ToolNonCopperClear.py @@ -5,12 +5,23 @@ # MIT Licence # # ########################################################## +from PyQt5 import QtWidgets, QtCore, QtGui from FlatCAMTool import FlatCAMTool -from copy import copy, deepcopy -from ObjectCollection import * -import time -from shapely.geometry import base +from flatcamGUI.GUIElements import FCCheckBox, FCDoubleSpinner, RadioSet, FCTable, FCInputDialog +from flatcamParsers.ParseGerber import Gerber +from FlatCAMObj import FlatCAMGeometry, FlatCAMGerber +import FlatCAMApp +from copy import deepcopy + +import numpy as np +import math +from shapely.geometry import base +from shapely.ops import cascaded_union +from shapely.geometry import MultiPolygon, Polygon, MultiLineString, LineString, LinearRing + +import logging +import traceback import gettext import FlatCAMTranslation as fcTranslate import builtins @@ -19,6 +30,8 @@ fcTranslate.apply_language('strings') if '_' not in builtins.__dict__: _ = gettext.gettext +log = logging.getLogger('base') + class NonCopperClear(FlatCAMTool, Gerber): @@ -473,7 +486,7 @@ class NonCopperClear(FlatCAMTool, Gerber): "Add", self.on_add_tool_by_key, icon=QtGui.QIcon("share/plus16.png")) self.tools_table.addContextMenu( "Delete", lambda: - self.on_tool_delete(rows_to_delete=None, all=None), icon=QtGui.QIcon("share/delete32.png")) + self.on_tool_delete(rows_to_delete=None, all_tools=None), icon=QtGui.QIcon("share/delete32.png")) # ############################################################################# # ########################## VARIABLES ######################################## @@ -1040,12 +1053,19 @@ class NonCopperClear(FlatCAMTool, Gerber): "New diameter value is already in the Tool Table.")) self.build_ui() - def on_tool_delete(self, rows_to_delete=None, all=None): + def on_tool_delete(self, rows_to_delete=None, all_tools=None): + """ + Will delete a tool in the tool table + + :param rows_to_delete: which rows to delete; can be a list + :param all_tools: delete all tools in the tool table + :return: + """ self.ui_disconnect() deleted_tools_list = [] - if all: + if all_tools: self.paint_tools.clear() self.build_ui() return diff --git a/flatcamTools/ToolOptimal.py b/flatcamTools/ToolOptimal.py index cf9cbc89..83a4a90f 100644 --- a/flatcamTools/ToolOptimal.py +++ b/flatcamTools/ToolOptimal.py @@ -5,13 +5,19 @@ # MIT Licence # # ########################################################## -from FlatCAMTool import FlatCAMTool -from FlatCAMObj import * -from shapely.geometry import Point -from shapely import affinity -from shapely.ops import nearest_points -from PyQt5 import QtCore +from PyQt5 import QtWidgets, QtCore, QtGui +from FlatCAMTool import FlatCAMTool +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 + +import numpy as np + +import logging import gettext import FlatCAMTranslation as fcTranslate import builtins @@ -20,13 +26,15 @@ fcTranslate.apply_language('strings') if '_' not in builtins.__dict__: _ = gettext.gettext +log = logging.getLogger('base') + class ToolOptimal(FlatCAMTool): toolName = _("Optimal Tool") - update_text = pyqtSignal(list) - update_sec_distances = pyqtSignal(dict) + update_text = QtCore.pyqtSignal(list) + update_sec_distances = QtCore.pyqtSignal(dict) def __init__(self, app): FlatCAMTool.__init__(self, app) diff --git a/flatcamTools/ToolPDF.py b/flatcamTools/ToolPDF.py index de438864..862b1391 100644 --- a/flatcamTools/ToolPDF.py +++ b/flatcamTools/ToolPDF.py @@ -5,19 +5,22 @@ # MIT Licence # # ########################################################## +from PyQt5 import QtWidgets, QtCore + from FlatCAMTool import FlatCAMTool -from shapely.geometry import Point, Polygon, LineString -from shapely.ops import cascaded_union, unary_union +import FlatCAMApp -from FlatCAMObj import * +from shapely.geometry import Point, Polygon, LineString, MultiPolygon +from shapely.ops import unary_union -import math from copy import copy, deepcopy import numpy as np import zlib import re import time +import logging +import traceback import gettext import FlatCAMTranslation as fcTranslate @@ -27,6 +30,8 @@ fcTranslate.apply_language('strings') if '_' not in builtins.__dict__: _ = gettext.gettext +log = logging.getLogger('base') + class ToolPDF(FlatCAMTool): """ diff --git a/flatcamTools/ToolPaint.py b/flatcamTools/ToolPaint.py index 5dfe751a..cca0c827 100644 --- a/flatcamTools/ToolPaint.py +++ b/flatcamTools/ToolPaint.py @@ -5,10 +5,25 @@ # MIT Licence # # ########################################################## +from PyQt5 import QtWidgets, QtGui, QtCore +from PyQt5.QtCore import Qt + from FlatCAMTool import FlatCAMTool -from copy import copy, deepcopy -from ObjectCollection import * -from shapely.geometry import base +from copy import deepcopy +# from ObjectCollection import * +from flatcamParsers.ParseGerber import Gerber +from FlatCAMObj import FlatCAMGerber, FlatCAMGeometry +from camlib import Geometry +from flatcamGUI.GUIElements import FCTable, FCDoubleSpinner, FCCheckBox, FCInputDialog, RadioSet +import FlatCAMApp + +from shapely.geometry import base, Polygon, MultiPolygon, LinearRing +from shapely.ops import cascaded_union + +import numpy as np +from numpy import Inf +import traceback +import logging import gettext import FlatCAMTranslation as fcTranslate @@ -18,6 +33,8 @@ fcTranslate.apply_language('strings') if '_' not in builtins.__dict__: _ = gettext.gettext +log = logging.getLogger('base') + class ToolPaint(FlatCAMTool, Gerber): @@ -374,6 +391,7 @@ class ToolPaint(FlatCAMTool, Gerber): self.mm = None self.mp = None + self.mr = None self.sel_rect = [] @@ -641,10 +659,10 @@ class ToolPaint(FlatCAMTool, Gerber): for tooluid_key, tooluid_value in self.paint_tools.items(): if float('%.*f' % (self.decimals, tooluid_value['tooldia'])) == tool_sorted: tool_id += 1 - id = QtWidgets.QTableWidgetItem('%d' % int(tool_id)) - id.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) + id_item = QtWidgets.QTableWidgetItem('%d' % int(tool_id)) + id_item.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) row_no = tool_id - 1 - self.tools_table.setItem(row_no, 0, id) # Tool name/id + self.tools_table.setItem(row_no, 0, id_item) # Tool name/id # Make sure that the drill diameter when in MM is with no more than 2 decimals # There are no drill bits in MM with more than 2 decimals diameter @@ -2213,7 +2231,7 @@ class ToolPaint(FlatCAMTool, Gerber): log.debug("Could not Paint the polygons. %s" % str(e)) self.app.inform.emit('[ERROR] %s\n%s' % (_("Could not do Paint All. Try a different combination of parameters. " - "Or a different Method of paint"), str(e))) + "Or a different Method of paint"), str(e))) return pol_nr += 1 @@ -2373,7 +2391,7 @@ class ToolPaint(FlatCAMTool, Gerber): log.debug("Could not Paint the polygons. %s" % str(e)) self.app.inform.emit('[ERROR] %s\n%s' % (_("Could not do Paint All. Try a different combination of parameters. " - "Or a different Method of paint"), str(e))) + "Or a different Method of paint"), str(e))) return pol_nr += 1 diff --git a/flatcamTools/ToolPanelize.py b/flatcamTools/ToolPanelize.py index 464702ca..1c97b0fa 100644 --- a/flatcamTools/ToolPanelize.py +++ b/flatcamTools/ToolPanelize.py @@ -5,19 +5,29 @@ # MIT Licence # # ########################################################## +from PyQt5 import QtWidgets, QtGui, QtCore from FlatCAMTool import FlatCAMTool -from copy import copy, deepcopy -from ObjectCollection import * -import time + +from flatcamGUI.GUIElements import FCSpinner, FCDoubleSpinner, RadioSet, FCCheckBox, OptionalInputSection +from FlatCAMObj import FlatCAMGeometry, FlatCAMGerber, FlatCAMExcellon +import FlatCAMApp +from copy import deepcopy +# from ObjectCollection import * +import numpy as np + +import shapely.affinity as affinity import gettext import FlatCAMTranslation as fcTranslate import builtins +import logging fcTranslate.apply_language('strings') if '_' not in builtins.__dict__: _ = gettext.gettext +log = logging.getLogger('base') + class Panelize(FlatCAMTool): @@ -367,15 +377,13 @@ class Panelize(FlatCAMTool): # Get source object. try: - obj = self.app.collection.get_by_name(str(name)) + panel_obj = self.app.collection.get_by_name(str(name)) except Exception as e: log.debug("Panelize.on_panelize() --> %s" % str(e)) self.app.inform.emit('[ERROR_NOTCL] %s: %s' % (_("Could not retrieve object"), name)) return "Could not retrieve object: %s" % name - panel_obj = obj - if panel_obj is None: self.app.inform.emit('[ERROR_NOTCL] %s: %s' % (_("Object not found"), panel_obj)) @@ -443,6 +451,18 @@ class Panelize(FlatCAMTool): rows -= 1 panel_lengthy = ((ymax - ymin) * rows) + (spacing_rows * (rows - 1)) + if isinstance(panel_obj, FlatCAMExcellon) or isinstance(panel_obj, FlatCAMGeometry): + # make a copy of the panelized Excellon or Geometry tools + copied_tools = dict() + for tt, tt_val in list(panel_obj.tools.items()): + copied_tools[tt] = deepcopy(tt_val) + + if isinstance(panel_obj, FlatCAMGerber): + # make a copy of the panelized Gerber apertures + copied_apertures = dict() + for tt, tt_val in list(panel_obj.apertures.items()): + copied_apertures[tt] = deepcopy(tt_val) + def panelize_2(): if panel_obj is not None: self.app.inform.emit(_("Generating panel ... ")) @@ -452,7 +472,7 @@ class Panelize(FlatCAMTool): def job_init_excellon(obj_fin, app_obj): currenty = 0.0 self.app.progress.emit(10) - obj_fin.tools = panel_obj.tools.copy() + obj_fin.tools = copied_tools obj_fin.drills = [] obj_fin.slots = [] obj_fin.solid_geometry = [] @@ -472,7 +492,6 @@ class Panelize(FlatCAMTool): currentx = 0.0 for col in range(columns): element += 1 - disp_number = 0 old_disp_number = 0 if panel_obj.drills: @@ -493,7 +512,7 @@ class Panelize(FlatCAMTool): drill_nr += 1 disp_number = int(np.interp(drill_nr, [0, geo_len_drills], [0, 100])) - if disp_number > old_disp_number and disp_number <= 100: + if old_disp_number < disp_number <= 100: self.app.proc_container.update_view_text(' %s: %d D:%d%%' % (_("Copy"), int(element), @@ -520,7 +539,7 @@ class Panelize(FlatCAMTool): slot_nr += 1 disp_number = int(np.interp(slot_nr, [0, geo_len_slots], [0, 100])) - if disp_number > old_disp_number and disp_number <= 100: + if old_disp_number < disp_number <= 100: self.app.proc_container.update_view_text(' %s: %d S:%d%%' % (_("Copy"), int(element), @@ -557,12 +576,12 @@ class Panelize(FlatCAMTool): # create the initial structure on which to create the panel if isinstance(panel_obj, FlatCAMGeometry): obj_fin.multigeo = panel_obj.multigeo - obj_fin.tools = deepcopy(panel_obj.tools) + obj_fin.tools = copied_tools if panel_obj.multigeo is True: for tool in panel_obj.tools: obj_fin.tools[tool]['solid_geometry'][:] = [] elif isinstance(panel_obj, FlatCAMGerber): - obj_fin.apertures = deepcopy(panel_obj.apertures) + obj_fin.apertures = copied_apertures for ap in obj_fin.apertures: obj_fin.apertures[ap]['geometry'] = list() @@ -594,7 +613,6 @@ class Panelize(FlatCAMTool): for col in range(columns): element += 1 - disp_number = 0 old_disp_number = 0 if isinstance(panel_obj, FlatCAMGeometry): diff --git a/flatcamTools/ToolPcbWizard.py b/flatcamTools/ToolPcbWizard.py index f0b7c82f..e176bf37 100644 --- a/flatcamTools/ToolPcbWizard.py +++ b/flatcamTools/ToolPcbWizard.py @@ -5,11 +5,11 @@ # MIT Licence # # ########################################################## -from FlatCAMTool import FlatCAMTool +from PyQt5 import QtWidgets, QtCore + +from FlatCAMTool import FlatCAMTool +from flatcamGUI.GUIElements import RadioSet, FCSpinner, FCButton, FCTable -from flatcamGUI.GUIElements import RadioSet, FCComboBox, FCSpinner, FCButton, FCTable -from PyQt5 import QtGui, QtWidgets, QtCore -from PyQt5.QtCore import pyqtSignal import re import os from datetime import datetime @@ -26,7 +26,7 @@ if '_' not in builtins.__dict__: class PcbWizard(FlatCAMTool): - file_loaded = pyqtSignal(str, str) + file_loaded = QtCore.pyqtSignal(str, str) toolName = _("PcbWizard Import Tool") diff --git a/flatcamTools/ToolProperties.py b/flatcamTools/ToolProperties.py index dec0bc07..b05dc289 100644 --- a/flatcamTools/ToolProperties.py +++ b/flatcamTools/ToolProperties.py @@ -6,10 +6,14 @@ # ########################################################## from PyQt5 import QtGui, QtCore, QtWidgets -from PyQt5.QtCore import Qt from FlatCAMTool import FlatCAMTool -from FlatCAMObj import * +from FlatCAMObj import FlatCAMCNCjob +from shapely.geometry import MultiPolygon, Polygon +from shapely.ops import cascaded_union + +from copy import deepcopy +import logging import gettext import FlatCAMTranslation as fcTranslate import builtins @@ -18,11 +22,13 @@ fcTranslate.apply_language('strings') if '_' not in builtins.__dict__: _ = gettext.gettext +log = logging.getLogger('base') + class Properties(FlatCAMTool): toolName = _("Properties") - calculations_finished = pyqtSignal(float, float, float, float, object) + calculations_finished = QtCore.pyqtSignal(float, float, float, float, object) def __init__(self, app): FlatCAMTool.__init__(self, app) @@ -150,18 +156,18 @@ class Properties(FlatCAMTool): self.addChild(obj_name, [obj.options['name']]) - def job_thread(obj): + def job_thread(obj_prop): proc = self.app.proc_container.new(_("Calculating dimensions ... Please wait.")) length = 0.0 width = 0.0 area = 0.0 - geo = obj.solid_geometry + geo = obj_prop.solid_geometry if geo: # calculate physical dimensions try: - xmin, ymin, xmax, ymax = obj.bounds() + xmin, ymin, xmax, ymax = obj_prop.bounds() length = abs(xmax - xmin) width = abs(ymax - ymin) @@ -179,9 +185,9 @@ class Properties(FlatCAMTool): xmax = [] ymax = [] - for tool in obj.tools: + for tool_k in obj_prop.tools: try: - x0, y0, x1, y1 = cascaded_union(obj.tools[tool]['solid_geometry']).bounds + x0, y0, x1, y1 = cascaded_union(obj_prop.tools[tool_k]['solid_geometry']).bounds xmin.append(x0) ymin.append(y0) xmax.append(x1) @@ -207,25 +213,25 @@ class Properties(FlatCAMTool): log.debug("Properties.addItems() --> %s" % str(e)) area_chull = 0.0 - if not isinstance(obj, FlatCAMCNCjob): + if not isinstance(obj_prop, FlatCAMCNCjob): # calculate and add convex hull area if geo: if isinstance(geo, MultiPolygon): env_obj = geo.convex_hull elif (isinstance(geo, MultiPolygon) and len(geo) == 1) or \ (isinstance(geo, list) and len(geo) == 1) and isinstance(geo[0], Polygon): - env_obj = cascaded_union(obj.solid_geometry) + env_obj = cascaded_union(obj_prop.solid_geometry) env_obj = env_obj.convex_hull else: - env_obj = cascaded_union(obj.solid_geometry) + env_obj = cascaded_union(obj_prop.solid_geometry) env_obj = env_obj.convex_hull area_chull = env_obj.area else: try: area_chull = [] - for tool in obj.tools: - area_el = cascaded_union(obj.tools[tool]['solid_geometry']).convex_hull + for tool_k in obj_prop.tools: + area_el = cascaded_union(obj_prop.tools[tool_k]['solid_geometry']).convex_hull area_chull.append(area_el.area) area_chull = max(area_chull) except Exception as e: diff --git a/flatcamTools/ToolRulesCheck.py b/flatcamTools/ToolRulesCheck.py index e33df197..dbca1789 100644 --- a/flatcamTools/ToolRulesCheck.py +++ b/flatcamTools/ToolRulesCheck.py @@ -5,15 +5,18 @@ # MIT Licence # # ########################################################## -from FlatCAMTool import FlatCAMTool -from copy import copy, deepcopy -from ObjectCollection import * -import time -from FlatCAMPool import * -from os import getpid -from shapely.ops import nearest_points -from shapely.geometry.base import BaseGeometry +from PyQt5 import QtWidgets +from FlatCAMTool import FlatCAMTool +from flatcamGUI.GUIElements import FCDoubleSpinner, FCCheckBox, OptionalInputSection +from copy import deepcopy + +from FlatCAMPool import * +# from os import getpid +from shapely.ops import nearest_points +from shapely.geometry import MultiPolygon, Polygon + +import logging import gettext import FlatCAMTranslation as fcTranslate import builtins @@ -22,12 +25,14 @@ fcTranslate.apply_language('strings') if '_' not in builtins.__dict__: _ = gettext.gettext +log = logging.getLogger('base') + class RulesCheck(FlatCAMTool): toolName = _("Check Rules") - tool_finished = pyqtSignal(list) + tool_finished = QtCore.pyqtSignal(list) def __init__(self, app): super(RulesCheck, self).__init__(self) diff --git a/flatcamTools/ToolShell.py b/flatcamTools/ToolShell.py index c80e7071..97e46f42 100644 --- a/flatcamTools/ToolShell.py +++ b/flatcamTools/ToolShell.py @@ -6,7 +6,7 @@ # MIT Licence # # ########################################################## -# from PyQt5.QtCore import pyqtSignal + from PyQt5.QtCore import Qt from PyQt5.QtGui import QTextCursor from PyQt5.QtWidgets import QVBoxLayout, QWidget diff --git a/flatcamTools/ToolSub.py b/flatcamTools/ToolSub.py index 517fff06..04a968ca 100644 --- a/flatcamTools/ToolSub.py +++ b/flatcamTools/ToolSub.py @@ -5,12 +5,18 @@ # MIT Licence # # ########################################################## +from PyQt5 import QtWidgets, QtCore from FlatCAMTool import FlatCAMTool -# from copy import copy, deepcopy -from ObjectCollection import * -import time +from flatcamGUI.GUIElements import FCCheckBox, FCButton +from shapely.geometry import Polygon, MultiPolygon, MultiLineString, LineString +from shapely.ops import cascaded_union + +import traceback +from copy import deepcopy +import time +import logging import gettext import FlatCAMTranslation as fcTranslate import builtins @@ -19,6 +25,8 @@ fcTranslate.apply_language('strings') if '_' not in builtins.__dict__: _ = gettext.gettext +log = logging.getLogger('base') + class ToolSub(FlatCAMTool): diff --git a/flatcamTools/ToolTransform.py b/flatcamTools/ToolTransform.py index dbbaa4dd..9a7247a9 100644 --- a/flatcamTools/ToolTransform.py +++ b/flatcamTools/ToolTransform.py @@ -5,8 +5,10 @@ # MIT Licence # # ########################################################## +from PyQt5 import QtWidgets from FlatCAMTool import FlatCAMTool -from FlatCAMObj import * +from flatcamGUI.GUIElements import FCDoubleSpinner, FCCheckBox, FCButton, OptionalInputSection, EvalEntry2 +from FlatCAMObj import FlatCAMCNCjob import gettext import FlatCAMTranslation as fcTranslate @@ -271,7 +273,7 @@ class ToolTransform(FlatCAMTool): _("Flip the selected object(s) over the X axis.") ) - hlay0= QtWidgets.QHBoxLayout() + hlay0 = QtWidgets.QHBoxLayout() self.transform_lay.addLayout(hlay0) hlay0.addWidget(self.flipx_button) @@ -312,7 +314,7 @@ class ToolTransform(FlatCAMTool): self.ois_flip = OptionalInputSection(self.flip_ref_cb, [self.flip_ref_entry, self.flip_ref_button], logic=True) - hlay1= QtWidgets.QHBoxLayout() + hlay1 = QtWidgets.QHBoxLayout() self.transform_lay.addLayout(hlay1) hlay1.addWidget(self.flip_ref_label)