- Excellon Editor - added possibility to create an linear drill array rotated at an custom angle
This commit is contained in:
@@ -91,7 +91,7 @@ class App(QtCore.QObject):
|
|||||||
|
|
||||||
# Version
|
# Version
|
||||||
version = 8.904
|
version = 8.904
|
||||||
version_date = "2019/01/24"
|
version_date = "2019/01/25"
|
||||||
beta = True
|
beta = True
|
||||||
|
|
||||||
# URL for update checks and statistics
|
# URL for update checks and statistics
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ from numpy.linalg import solve
|
|||||||
|
|
||||||
from rtree import index as rtindex
|
from rtree import index as rtindex
|
||||||
from GUIElements import OptionalInputSection, FCCheckBox, FCEntry, FCEntry2, FCComboBox, FCTextAreaRich, \
|
from GUIElements import OptionalInputSection, FCCheckBox, FCEntry, FCEntry2, FCComboBox, FCTextAreaRich, \
|
||||||
VerticalScrollArea, FCTable
|
VerticalScrollArea, FCTable, FCDoubleSpinner
|
||||||
from ParseFont import *
|
from ParseFont import *
|
||||||
from vispy.scene.visuals import Markers
|
from vispy.scene.visuals import Markers
|
||||||
from copy import copy
|
from copy import copy
|
||||||
@@ -1464,6 +1464,7 @@ class FCDrillArray(FCShapeTool):
|
|||||||
self.drill_array = 'linear'
|
self.drill_array = 'linear'
|
||||||
self.drill_array_size = None
|
self.drill_array_size = None
|
||||||
self.drill_pitch = None
|
self.drill_pitch = None
|
||||||
|
self.drill_linear_angle = None
|
||||||
|
|
||||||
self.drill_angle = None
|
self.drill_angle = None
|
||||||
self.drill_direction = None
|
self.drill_direction = None
|
||||||
@@ -1529,6 +1530,7 @@ class FCDrillArray(FCShapeTool):
|
|||||||
self.drill_array_size = int(self.draw_app.drill_array_size_entry.get_value())
|
self.drill_array_size = int(self.draw_app.drill_array_size_entry.get_value())
|
||||||
try:
|
try:
|
||||||
self.drill_pitch = float(self.draw_app.drill_pitch_entry.get_value())
|
self.drill_pitch = float(self.draw_app.drill_pitch_entry.get_value())
|
||||||
|
self.drill_linear_angle = float(self.draw_app.linear_angle_spinner.get_value())
|
||||||
self.drill_angle = float(self.draw_app.drill_angle_entry.get_value())
|
self.drill_angle = float(self.draw_app.drill_angle_entry.get_value())
|
||||||
except TypeError:
|
except TypeError:
|
||||||
self.draw_app.app.inform.emit(
|
self.draw_app.app.inform.emit(
|
||||||
@@ -1556,6 +1558,13 @@ class FCDrillArray(FCShapeTool):
|
|||||||
geo = self.util_shape(((data[0] + (self.drill_pitch * item)), data[1]))
|
geo = self.util_shape(((data[0] + (self.drill_pitch * item)), data[1]))
|
||||||
if self.drill_axis == 'Y':
|
if self.drill_axis == 'Y':
|
||||||
geo = self.util_shape((data[0], (data[1] + (self.drill_pitch * item))))
|
geo = self.util_shape((data[0], (data[1] + (self.drill_pitch * item))))
|
||||||
|
if self.drill_axis == 'A':
|
||||||
|
x_adj = self.drill_pitch * math.cos(math.radians(self.drill_linear_angle))
|
||||||
|
y_adj = self.drill_pitch * math.sin(math.radians(self.drill_linear_angle))
|
||||||
|
geo = self.util_shape(
|
||||||
|
((data[0] + (x_adj * item)), (data[1] + (y_adj * item)))
|
||||||
|
)
|
||||||
|
|
||||||
if static is None or static is False:
|
if static is None or static is False:
|
||||||
geo_list.append(affinity.translate(geo, xoff=(dx - self.last_dx), yoff=(dy - self.last_dy)))
|
geo_list.append(affinity.translate(geo, xoff=(dx - self.last_dx), yoff=(dy - self.last_dy)))
|
||||||
else:
|
else:
|
||||||
@@ -1571,7 +1580,6 @@ class FCDrillArray(FCShapeTool):
|
|||||||
temp_points.append(data)
|
temp_points.append(data)
|
||||||
return DrawToolUtilityShape(LineString(temp_points))
|
return DrawToolUtilityShape(LineString(temp_points))
|
||||||
|
|
||||||
|
|
||||||
def util_shape(self, point):
|
def util_shape(self, point):
|
||||||
start_hor_line = ((point[0] - (self.selected_dia / 2)), point[1])
|
start_hor_line = ((point[0] - (self.selected_dia / 2)), point[1])
|
||||||
stop_hor_line = ((point[0] + (self.selected_dia / 2)), point[1])
|
stop_hor_line = ((point[0] + (self.selected_dia / 2)), point[1])
|
||||||
@@ -1599,6 +1607,12 @@ class FCDrillArray(FCShapeTool):
|
|||||||
geo = self.util_shape(((self.points[0] + (self.drill_pitch * item)), self.points[1]))
|
geo = self.util_shape(((self.points[0] + (self.drill_pitch * item)), self.points[1]))
|
||||||
if self.drill_axis == 'Y':
|
if self.drill_axis == 'Y':
|
||||||
geo = self.util_shape((self.points[0], (self.points[1] + (self.drill_pitch * item))))
|
geo = self.util_shape((self.points[0], (self.points[1] + (self.drill_pitch * item))))
|
||||||
|
if self.drill_axis == 'A':
|
||||||
|
x_adj = self.drill_pitch * math.cos(math.radians(self.drill_linear_angle))
|
||||||
|
y_adj = self.drill_pitch * math.sin(math.radians(self.drill_linear_angle))
|
||||||
|
geo = self.util_shape(
|
||||||
|
((self.points[0] + (x_adj * item)), (self.points[1] + (y_adj * item)))
|
||||||
|
)
|
||||||
|
|
||||||
self.geometry.append(DrawToolShape(geo))
|
self.geometry.append(DrawToolShape(geo))
|
||||||
else:
|
else:
|
||||||
@@ -3469,6 +3483,21 @@ class FlatCAMExcEditor(QtCore.QObject):
|
|||||||
self.linear_form = QtWidgets.QFormLayout()
|
self.linear_form = QtWidgets.QFormLayout()
|
||||||
self.linear_box.addLayout(self.linear_form)
|
self.linear_box.addLayout(self.linear_form)
|
||||||
|
|
||||||
|
self.drill_axis_label = QtWidgets.QLabel('Direction:')
|
||||||
|
self.drill_axis_label.setToolTip(
|
||||||
|
"Direction on which the linear array is oriented:\n"
|
||||||
|
"- 'X' - horizontal axis \n"
|
||||||
|
"- 'Y' - vertical axis or \n"
|
||||||
|
"- 'Angle' - a custom angle for the array inclination"
|
||||||
|
)
|
||||||
|
self.drill_axis_label.setFixedWidth(100)
|
||||||
|
|
||||||
|
self.drill_axis_radio = RadioSet([{'label': 'X', 'value': 'X'},
|
||||||
|
{'label': 'Y', 'value': 'Y'},
|
||||||
|
{'label': 'Angle', 'value': 'A'}])
|
||||||
|
self.drill_axis_radio.set_value('X')
|
||||||
|
self.linear_form.addRow(self.drill_axis_label, self.drill_axis_radio)
|
||||||
|
|
||||||
self.drill_pitch_label = QtWidgets.QLabel('Pitch:')
|
self.drill_pitch_label = QtWidgets.QLabel('Pitch:')
|
||||||
self.drill_pitch_label.setToolTip(
|
self.drill_pitch_label.setToolTip(
|
||||||
"Pitch = Distance between elements of the array."
|
"Pitch = Distance between elements of the array."
|
||||||
@@ -3478,16 +3507,19 @@ class FlatCAMExcEditor(QtCore.QObject):
|
|||||||
self.drill_pitch_entry = LengthEntry()
|
self.drill_pitch_entry = LengthEntry()
|
||||||
self.linear_form.addRow(self.drill_pitch_label, self.drill_pitch_entry)
|
self.linear_form.addRow(self.drill_pitch_label, self.drill_pitch_entry)
|
||||||
|
|
||||||
self.drill_axis_label = QtWidgets.QLabel('Axis:')
|
self.linear_angle_label = QtWidgets.QLabel('Angle:')
|
||||||
self.drill_axis_label.setToolTip(
|
self.linear_angle_label.setToolTip(
|
||||||
"Axis on which the linear array is oriented: 'X' or 'Y'."
|
"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.drill_axis_label.setFixedWidth(100)
|
self.linear_angle_label.setFixedWidth(100)
|
||||||
|
|
||||||
self.drill_axis_radio = RadioSet([{'label': 'X', 'value': 'X'},
|
self.linear_angle_spinner = FCDoubleSpinner()
|
||||||
{'label': 'Y', 'value': 'Y'}])
|
self.linear_angle_spinner.set_precision(2)
|
||||||
self.drill_axis_radio.set_value('X')
|
self.linear_angle_spinner.setRange(-359.99, 360.00)
|
||||||
self.linear_form.addRow(self.drill_axis_label, self.drill_axis_radio)
|
self.linear_form.addRow(self.linear_angle_label, self.linear_angle_spinner)
|
||||||
|
|
||||||
self.array_circular_frame = QtWidgets.QFrame()
|
self.array_circular_frame = QtWidgets.QFrame()
|
||||||
self.array_circular_frame.setContentsMargins(0, 0, 0, 0)
|
self.array_circular_frame.setContentsMargins(0, 0, 0, 0)
|
||||||
@@ -3496,18 +3528,6 @@ class FlatCAMExcEditor(QtCore.QObject):
|
|||||||
self.circular_box.setContentsMargins(0, 0, 0, 0)
|
self.circular_box.setContentsMargins(0, 0, 0, 0)
|
||||||
self.array_circular_frame.setLayout(self.circular_box)
|
self.array_circular_frame.setLayout(self.circular_box)
|
||||||
|
|
||||||
self.drill_angle_label = QtWidgets.QLabel('Angle:')
|
|
||||||
self.drill_angle_label.setToolTip(
|
|
||||||
"Angle at which each element in circular array is placed."
|
|
||||||
)
|
|
||||||
self.drill_angle_label.setFixedWidth(100)
|
|
||||||
|
|
||||||
self.circular_form = QtWidgets.QFormLayout()
|
|
||||||
self.circular_box.addLayout(self.circular_form)
|
|
||||||
|
|
||||||
self.drill_angle_entry = LengthEntry()
|
|
||||||
self.circular_form.addRow(self.drill_angle_label, self.drill_angle_entry)
|
|
||||||
|
|
||||||
self.drill_direction_label = QtWidgets.QLabel('Direction:')
|
self.drill_direction_label = QtWidgets.QLabel('Direction:')
|
||||||
self.drill_direction_label.setToolTip(
|
self.drill_direction_label.setToolTip(
|
||||||
"Direction for circular array."
|
"Direction for circular array."
|
||||||
@@ -3515,12 +3535,28 @@ class FlatCAMExcEditor(QtCore.QObject):
|
|||||||
)
|
)
|
||||||
self.drill_direction_label.setFixedWidth(100)
|
self.drill_direction_label.setFixedWidth(100)
|
||||||
|
|
||||||
|
self.circular_form = QtWidgets.QFormLayout()
|
||||||
|
self.circular_box.addLayout(self.circular_form)
|
||||||
|
|
||||||
self.drill_direction_radio = RadioSet([{'label': 'CW', 'value': 'CW'},
|
self.drill_direction_radio = RadioSet([{'label': 'CW', 'value': 'CW'},
|
||||||
{'label': 'CCW.', 'value': 'CCW'}])
|
{'label': 'CCW.', 'value': 'CCW'}])
|
||||||
self.drill_direction_radio.set_value('CW')
|
self.drill_direction_radio.set_value('CW')
|
||||||
self.circular_form.addRow(self.drill_direction_label, self.drill_direction_radio)
|
self.circular_form.addRow(self.drill_direction_label, self.drill_direction_radio)
|
||||||
|
|
||||||
|
self.drill_angle_label = QtWidgets.QLabel('Angle:')
|
||||||
|
self.drill_angle_label.setToolTip(
|
||||||
|
"Angle at which each element in circular array is placed."
|
||||||
|
)
|
||||||
|
self.drill_angle_label.setFixedWidth(100)
|
||||||
|
|
||||||
|
self.drill_angle_entry = LengthEntry()
|
||||||
|
self.circular_form.addRow(self.drill_angle_label, self.drill_angle_entry)
|
||||||
|
|
||||||
self.array_circular_frame.hide()
|
self.array_circular_frame.hide()
|
||||||
|
|
||||||
|
self.linear_angle_spinner.hide()
|
||||||
|
self.linear_angle_label.hide()
|
||||||
|
|
||||||
self.array_frame.hide()
|
self.array_frame.hide()
|
||||||
self.tools_box.addStretch()
|
self.tools_box.addStretch()
|
||||||
|
|
||||||
@@ -3577,6 +3613,8 @@ class FlatCAMExcEditor(QtCore.QObject):
|
|||||||
self.tools_table_exc.selectionModel().currentChanged.connect(self.on_row_selected)
|
self.tools_table_exc.selectionModel().currentChanged.connect(self.on_row_selected)
|
||||||
self.array_type_combo.currentIndexChanged.connect(self.on_array_type_combo)
|
self.array_type_combo.currentIndexChanged.connect(self.on_array_type_combo)
|
||||||
|
|
||||||
|
self.drill_axis_radio.activated_custom.connect(self.on_linear_angle_radio)
|
||||||
|
|
||||||
self.drill_array_size_entry.set_value(5)
|
self.drill_array_size_entry.set_value(5)
|
||||||
self.drill_pitch_entry.set_value(2.54)
|
self.drill_pitch_entry.set_value(2.54)
|
||||||
self.drill_angle_entry.set_value(12)
|
self.drill_angle_entry.set_value(12)
|
||||||
@@ -5038,6 +5076,15 @@ class FlatCAMExcEditor(QtCore.QObject):
|
|||||||
self.array_linear_frame.hide()
|
self.array_linear_frame.hide()
|
||||||
self.app.inform.emit("Click on the circular array Center position")
|
self.app.inform.emit("Click on the circular array Center position")
|
||||||
|
|
||||||
|
def on_linear_angle_radio(self):
|
||||||
|
val = self.drill_axis_radio.get_value()
|
||||||
|
if val == 'A':
|
||||||
|
self.linear_angle_spinner.show()
|
||||||
|
self.linear_angle_label.show()
|
||||||
|
else:
|
||||||
|
self.linear_angle_spinner.hide()
|
||||||
|
self.linear_angle_label.hide()
|
||||||
|
|
||||||
def exc_add_drill(self):
|
def exc_add_drill(self):
|
||||||
self.select_tool('add')
|
self.select_tool('add')
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -685,13 +685,36 @@ class FCSpinner(QtWidgets.QSpinBox):
|
|||||||
try:
|
try:
|
||||||
k = int(val)
|
k = int(val)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise e
|
log.debug(str(e))
|
||||||
|
return
|
||||||
self.setValue(k)
|
self.setValue(k)
|
||||||
|
|
||||||
# def sizeHint(self):
|
# def sizeHint(self):
|
||||||
# default_hint_size = super(FCSpinner, self).sizeHint()
|
# default_hint_size = super(FCSpinner, self).sizeHint()
|
||||||
# return QtCore.QSize(EDIT_SIZE_HINT, default_hint_size.height())
|
# return QtCore.QSize(EDIT_SIZE_HINT, default_hint_size.height())
|
||||||
|
|
||||||
|
class FCDoubleSpinner(QtWidgets.QDoubleSpinBox):
|
||||||
|
def __init__(self, parent=None):
|
||||||
|
super(FCDoubleSpinner, self).__init__(parent)
|
||||||
|
|
||||||
|
def get_value(self):
|
||||||
|
return str(self.value())
|
||||||
|
|
||||||
|
def set_value(self, val):
|
||||||
|
try:
|
||||||
|
k = int(val)
|
||||||
|
except Exception as e:
|
||||||
|
log.debug(str(e))
|
||||||
|
return
|
||||||
|
self.setValue(k)
|
||||||
|
|
||||||
|
def set_precision(self, val):
|
||||||
|
self.setDecimals(val)
|
||||||
|
|
||||||
|
def set_range(self, min_val, max_val):
|
||||||
|
self.setRange(self, min_val, max_val)
|
||||||
|
|
||||||
|
|
||||||
class Dialog_box(QtWidgets.QWidget):
|
class Dialog_box(QtWidgets.QWidget):
|
||||||
def __init__(self, title=None, label=None):
|
def __init__(self, title=None, label=None):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -15,9 +15,10 @@ CAD program, and create G-Code for Isolation routing.
|
|||||||
- fixed the Copy Object function when the object is Gerber
|
- fixed the Copy Object function when the object is Gerber
|
||||||
- added the Copy entry to the Project context menu
|
- added the Copy entry to the Project context menu
|
||||||
- made the functions behind Disable and Enable project context menu entries, non-threaded to fix a possible issue
|
- made the functions behind Disable and Enable project context menu entries, non-threaded to fix a possible issue
|
||||||
- added multiple object selection on Open ... and Import ... (idea and code snippet came from Travers Carter, BitBucket user https://bitbucket.org/travc/
|
- added multiple object selection on Open ... and Import ... (idea and code snippet came from Travers Carter, BitBucket user https://bitbucket.org/travc/)
|
||||||
- fixed 'grbl_laser' postprocessor bugs (missing functions)
|
- fixed 'grbl_laser' postprocessor bugs (missing functions)
|
||||||
- fixed display geometry for 'grbl_laser' postprocessor
|
- fixed display geometry for 'grbl_laser' postprocessor
|
||||||
|
- Excellon Editor - added possibility to create an linear drill array rotated at an custom angle
|
||||||
|
|
||||||
23.01.2019
|
23.01.2019
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user