- 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)
This commit is contained in:
parent
4be989fa5c
commit
dfc0b98181
|
@ -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
|
||||
|
||||
|
|
|
@ -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):
|
||||
"""
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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):
|
||||
"""
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
98
camlib.py
98
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):
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
# ##########################################################
|
||||
|
||||
import math
|
||||
import sys
|
||||
|
||||
|
||||
def norm(v):
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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):
|
||||
|
||||
|
|
|
@ -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):
|
||||
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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):
|
||||
"""
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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")
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -5,12 +5,18 @@
|
|||
# MIT Licence #
|
||||
# ##########################################################
|
||||
|
||||
from PyQt5 import QtWidgets, QtCore
|
||||
|
||||
from FlatCAMTool import FlatCAMTool
|
||||
# from copy import copy, deepcopy
|
||||
from ObjectCollection import *
|
||||
import time
|
||||
from flatcamGUI.GUIElements import FCCheckBox, FCButton
|
||||
|
||||
from shapely.geometry import Polygon, MultiPolygon, MultiLineString, LineString
|
||||
from shapely.ops import cascaded_union
|
||||
|
||||
import traceback
|
||||
from copy import deepcopy
|
||||
import time
|
||||
import logging
|
||||
import gettext
|
||||
import FlatCAMTranslation as fcTranslate
|
||||
import builtins
|
||||
|
@ -19,6 +25,8 @@ fcTranslate.apply_language('strings')
|
|||
if '_' not in builtins.__dict__:
|
||||
_ = gettext.gettext
|
||||
|
||||
log = logging.getLogger('base')
|
||||
|
||||
|
||||
class ToolSub(FlatCAMTool):
|
||||
|
||||
|
|
|
@ -5,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)
|
||||
|
|
Loading…
Reference in New Issue