- Gerber Editor: added support for Oblong type of aperture

- fixed an issue with automatically filled in aperture size when the edited Gerber file has no apertures; established an default with value 10 (according to Gerber specifications)
This commit is contained in:
Marius Stanciu 2019-04-12 02:09:01 +03:00
parent 3f421b234d
commit 2297f99502
2 changed files with 135 additions and 16 deletions

View File

@ -9,6 +9,11 @@ CAD program, and create G-Code for Isolation routing.
=================================================
12.04.2019
- Gerber Editor: added support for Oblong type of aperture
- fixed an issue with automatically filled in aperture size when the edited Gerber file has no apertures; established an default with value 10 (according to Gerber specifications)
11.04.2019
- changed the color of the marked apertures to the global_selection_color

View File

@ -38,6 +38,7 @@ class FCPad(FCShapeTool):
self.storage_obj = self.draw_app.storage_dict[self.draw_app.last_aperture_selected]['solid_geometry']
self.radius = float(self.draw_app.storage_dict[self.draw_app.last_aperture_selected]['size']) / 2
self.steps_per_circ = self.draw_app.app.defaults["geometry_circle_steps"]
# if those cause KeyError exception it means that the aperture type is not 'R'. Only 'R' type has those keys
try:
@ -91,8 +92,61 @@ class FCPad(FCShapeTool):
p3 = (point_x + self.half_width, point_y + self.half_height)
p4 = (point_x - self.half_width, point_y + self.half_height)
return Polygon([p1, p2, p3, p4, p1])
elif ap_type == 'O':
geo = []
if self.half_height > self.half_width:
p1 = (point_x - self.half_width, point_y - self.half_height + self.half_width)
p2 = (point_x + self.half_width, point_y - self.half_height + self.half_width)
p3 = (point_x + self.half_width, point_y + self.half_height - self.half_width)
p4 = (point_x - self.half_width, point_y + self.half_height - self.half_width)
down_center = (point_x, point_y - self.half_height + self.half_width)
d_start_angle = math.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
up_arc = arc(up_center, self.half_width, u_start_angle, u_stop_angle, 'ccw', self.steps_per_circ)
geo.append(p1)
for pt in down_arc:
geo.append(pt)
geo.append(p2)
geo.append(p3)
for pt in up_arc:
geo.append(pt)
geo.append(p4)
return Polygon(geo)
else:
p1 = (point_x - self.half_width + self.half_height, point_y - self.half_height)
p2 = (point_x + self.half_width - self.half_height, point_y - self.half_height)
p3 = (point_x + self.half_width - self.half_height, point_y + self.half_height)
p4 = (point_x - self.half_width + self.half_height, point_y + self.half_height)
left_center = (point_x - self.half_width + self.half_height, point_y)
d_start_angle = math.pi / 2
d_stop_angle = 1.5 * math.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
right_arc = arc(right_center, self.half_height, u_start_angle, u_stop_angle, 'ccw', self.steps_per_circ)
geo.append(p1)
geo.append(p2)
for pt in right_arc:
geo.append(pt)
geo.append(p3)
geo.append(p4)
for pt in left_arc:
geo.append(pt)
return Polygon(geo)
else:
self.draw_app.app.inform.emit(_("Incompatible aperture type. Select an aperture with type 'C' or 'R'."))
self.draw_app.app.inform.emit(_(
"Incompatible aperture type. Select an aperture with type 'C', 'R' or 'O'."))
return None
def make(self):
@ -119,6 +173,7 @@ class FCPadArray(FCShapeTool):
self.storage_obj = self.draw_app.storage_dict[self.draw_app.last_aperture_selected]['solid_geometry']
self.radius = float(self.draw_app.storage_dict[self.draw_app.last_aperture_selected]['size']) / 2
self.steps_per_circ = self.draw_app.app.defaults["geometry_circle_steps"]
# if those cause KeyError exception it means that the aperture type is not 'R'. Only 'R' type has those keys
try:
@ -274,8 +329,61 @@ class FCPadArray(FCShapeTool):
p3 = (point_x + self.half_width, point_y + self.half_height)
p4 = (point_x - self.half_width, point_y + self.half_height)
return Polygon([p1, p2, p3, p4, p1])
elif ap_type == 'O':
geo = []
if self.half_height > self.half_width:
p1 = (point_x - self.half_width, point_y - self.half_height + self.half_width)
p2 = (point_x + self.half_width, point_y - self.half_height + self.half_width)
p3 = (point_x + self.half_width, point_y + self.half_height - self.half_width)
p4 = (point_x - self.half_width, point_y + self.half_height - self.half_width)
down_center = (point_x, point_y - self.half_height + self.half_width)
d_start_angle = math.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
up_arc = arc(up_center, self.half_width, u_start_angle, u_stop_angle, 'ccw', self.steps_per_circ)
geo.append(p1)
for pt in down_arc:
geo.append(pt)
geo.append(p2)
geo.append(p3)
for pt in up_arc:
geo.append(pt)
geo.append(p4)
return Polygon(geo)
else:
p1 = (point_x - self.half_width + self.half_height, point_y - self.half_height)
p2 = (point_x + self.half_width - self.half_height, point_y - self.half_height)
p3 = (point_x + self.half_width - self.half_height, point_y + self.half_height)
p4 = (point_x - self.half_width + self.half_height, point_y + self.half_height)
left_center = (point_x - self.half_width + self.half_height, point_y)
d_start_angle = math.pi / 2
d_stop_angle = 1.5 * math.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
right_arc = arc(right_center, self.half_height, u_start_angle, u_stop_angle, 'ccw', self.steps_per_circ)
geo.append(p1)
geo.append(p2)
for pt in right_arc:
geo.append(pt)
geo.append(p3)
geo.append(p4)
for pt in left_arc:
geo.append(pt)
return Polygon(geo)
else:
self.draw_app.app.inform.emit(_("Incompatible aperture type. Select an aperture with type 'C' or 'R'."))
self.draw_app.app.inform.emit(_(
"Incompatible aperture type. Select an aperture with type 'C', 'R' or 'O'."))
return None
def make(self):
@ -318,7 +426,7 @@ class FCPadArray(FCShapeTool):
if self.pad_direction == 'CW':
geo = affinity.rotate(geo, angle=(math.pi - angle_radians), use_radians=True)
else:
geo = affinity.rotate(geo, angle=angle_radians, use_radians=True)
geo = affinity.rotate(geo, angle=(angle_radians - math.pi), use_radians=True)
self.geometry.append(DrawToolShape(geo))
self.complete = True
@ -802,8 +910,9 @@ class FlatCAMGrbEditor(QtCore.QObject):
apsize_lbl = QtWidgets.QLabel(_('Aperture Size:'))
apsize_lbl.setToolTip(
_("Size for the new aperture.\n"
"If aperture type is 'R' then this value\n"
"is automatically calculated as:\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)
@ -816,12 +925,13 @@ class FlatCAMGrbEditor(QtCore.QObject):
aptype_lbl.setToolTip(
_("Select the type of new aperture. Can be:\n"
"C = circular\n"
"R = rectangular")
"R = rectangular\n"
"O = oblong")
)
grid1.addWidget(aptype_lbl, 3, 0)
self.aptype_cb = FCComboBox()
self.aptype_cb.addItems(['C', 'R'])
self.aptype_cb.addItems(['C', 'R', 'O'])
grid1.addWidget(self.aptype_cb, 3, 1)
self.apdim_lbl = QtWidgets.QLabel(_('Aperture Dim:'))
@ -1409,7 +1519,11 @@ class FlatCAMGrbEditor(QtCore.QObject):
self.apertures_table.cellPressed.connect(self.on_row_selected)
# for convenience set the next aperture code in the apcode field
self.apcode_entry.set_value(max(self.tool2tooldia.values()) + 1)
try:
self.apcode_entry.set_value(max(self.tool2tooldia.values()) + 1)
except ValueError:
# this means that the edited object has no apertures so we start with 10 (Gerber specifications)
self.apcode_entry.set_value(10)
def on_aperture_add(self, apid=None):
self.is_modified = True
@ -1433,7 +1547,7 @@ class FlatCAMGrbEditor(QtCore.QObject):
type_val = self.aptype_cb.currentText()
self.storage_dict[ap_id]['type'] = type_val
if type_val == 'R':
if type_val == 'R' or type_val == 'O':
try:
dims = self.apdim_entry.get_value()
self.storage_dict[ap_id]['width'] = dims[0]
@ -1443,7 +1557,7 @@ class FlatCAMGrbEditor(QtCore.QObject):
self.apsize_entry.set_value(size_val)
except Exception as e:
log.error("FlatCAMGrbEditor.on_aperture_add() --> the R aperture dims has to be in a "
log.error("FlatCAMGrbEditor.on_aperture_add() --> the R or O aperture dims has to be in a "
"tuple format (x,y)\nError: %s" % str(e))
self.app.inform.emit(_("[WARNING_NOTCL] Aperture dimensions value is missing or wrong format. "
"Add it in format (width, height) and retry."))
@ -1594,7 +1708,7 @@ class FlatCAMGrbEditor(QtCore.QObject):
self.edited_obj_name = self.name_entry.get_value()
def on_aptype_changed(self, current_text):
if current_text == 'R':
if current_text == 'R' or current_text == 'O':
self.apdim_lbl.show()
self.apdim_entry.show()
self.apsize_entry.setReadOnly(True)
@ -2129,12 +2243,11 @@ class FlatCAMGrbEditor(QtCore.QObject):
# MS: always return to the Select Tool if modifier key is not pressed
# else return to the current tool
key_modifier = QtWidgets.QApplication.keyboardModifiers()
if self.app.defaults["global_mselect_key"] == 'Control':
modifier_to_use = Qt.ControlModifier
else:
modifier_to_use = Qt.ShiftModifier
if (self.app.defaults["global_mselect_key"] == 'Control' and
key_modifier == Qt.ControlModifier) or \
(self.app.defaults["global_mselect_key"] == 'Shift' and
key_modifier == Qt.ShiftModifier):
if key_modifier == modifier_to_use:
self.select_tool(self.active_tool.name)
else:
self.select_tool("select")
@ -2620,6 +2733,7 @@ class FlatCAMGrbEditor(QtCore.QObject):
self.app.ui.notebook.setCurrentWidget(self.app.ui.selected_tab)
class TransformEditorTool(FlatCAMTool):
"""
Inputs to specify how to paint the selected polygons.