- made some changes in the Region Tool from the Gerber Editor

This commit is contained in:
Marius Stanciu
2020-11-07 03:45:04 +02:00
committed by Marius
parent a4b5d117b8
commit d526d16cdf
2 changed files with 189 additions and 137 deletions

View File

@@ -19,6 +19,7 @@ CHANGELOG for FlatCAM beta
- Turkish language strings updated (by Mehmet Kaya) - Turkish language strings updated (by Mehmet Kaya)
- both for Excellon and Gerber editor fixed the direction of slots/pads when adding a circular array - both for Excellon and Gerber editor fixed the direction of slots/pads when adding a circular array
- in Gerber editor added the G key shortcut to toggle the grid snapping - in Gerber editor added the G key shortcut to toggle the grid snapping
- made some changes in the Region Tool from the Gerber Editor
5.11.2020 5.11.2020

View File

@@ -1026,144 +1026,195 @@ class RegionEditorGrb(ShapeToolEditorGrb):
return return
new_geo_el = {} new_geo_el = {}
x = data[0] x = data[0]
y = data[1] y = data[1]
if len(self.points) == 0: if len(self.points) == 0:
new_geo_el['solid'] = Point(data).buffer(self.buf_val, resolution=int(self.steps_per_circle / 4)) new_geo_el['solid'] = Point((x, y)).buffer(self.buf_val, resolution=int(self.steps_per_circle / 4))
return DrawToolUtilityShape(new_geo_el) return DrawToolUtilityShape(new_geo_el)
if len(self.points) == 1: elif len(self.points) == 1:
self.temp_points = [x for x in self.points] self.temp_points = [x for x in self.points]
# previous point coordinates
old_x = self.points[0][0] old_x = self.points[0][0]
old_y = self.points[0][1] old_y = self.points[0][1]
# how many grid sections between old point and new point
mx = abs(round((x - old_x) / self.gridx_size)) mx = abs(round((x - old_x) / self.gridx_size))
my = abs(round((y - old_y) / self.gridy_size)) my = abs(round((y - old_y) / self.gridy_size))
if mx and my: if self.draw_app.app.ui.grid_snap_btn.isChecked() and mx and my:
if self.draw_app.app.ui.grid_snap_btn.isChecked(): # calculate intermediary point
if self.draw_app.bend_mode != 5: if self.draw_app.bend_mode != 5:
if self.draw_app.bend_mode == 1: if self.draw_app.bend_mode == 1:
if x > old_x: # if we move from left to right
if mx > my: if x > old_x:
self.inter_point = (old_x + self.gridx_size * (mx - my), old_y) # if the number of grid sections is greater on the X axis
if mx < my: if mx > my:
if y < old_y: self.inter_point = (old_x + self.gridx_size * (mx - my), old_y)
self.inter_point = (old_x, old_y - self.gridy_size * (my - mx)) # if the number of grid sections is greater on the Y axis
else: if mx < my:
self.inter_point = (old_x, old_y - self.gridy_size * (mx - my)) # if we move from top to down
if x < old_x: if y < old_y:
if mx > my: self.inter_point = (old_x, old_y - self.gridy_size * (my - mx))
self.inter_point = (old_x - self.gridx_size * (mx - my), old_y) # if we move from down to top or at the same height
if mx < my: else:
if y < old_y: self.inter_point = (old_x, old_y - self.gridy_size * (mx - my))
self.inter_point = (old_x, old_y - self.gridy_size * (my - mx)) # if we move from right to left
else: elif x < old_x:
self.inter_point = (old_x, old_y - self.gridy_size * (mx - my)) # if the number of grid sections is greater on the X axis
elif self.draw_app.bend_mode == 2: if mx > my:
if x > old_x: self.inter_point = (old_x - self.gridx_size * (mx - my), old_y)
if mx > my: # if the number of grid sections is greater on the Y axis
self.inter_point = (old_x + self.gridx_size * my, y) if mx < my:
if mx < my: # if we move from top to down
if y < old_y: if y < old_y:
self.inter_point = (x, old_y - self.gridy_size * mx) self.inter_point = (old_x, old_y - self.gridy_size * (my - mx))
else: # if we move from down to top or at the same height
self.inter_point = (x, old_y + self.gridy_size * mx) else:
if x < old_x: self.inter_point = (old_x, old_y - self.gridy_size * (mx - my))
if mx > my: elif self.draw_app.bend_mode == 2:
self.inter_point = (old_x - self.gridx_size * my, y) if x > old_x:
if mx < my: if mx > my:
if y < old_y: self.inter_point = (old_x + self.gridx_size * my, y)
self.inter_point = (x, old_y - self.gridy_size * mx) if mx < my:
else: if y < old_y:
self.inter_point = (x, old_y + self.gridy_size * mx) self.inter_point = (x, old_y - self.gridy_size * mx)
elif self.draw_app.bend_mode == 3: else:
self.inter_point = (x, old_y) self.inter_point = (x, old_y + self.gridy_size * mx)
elif self.draw_app.bend_mode == 4: if x < old_x:
self.inter_point = (old_x, y) if mx > my:
self.inter_point = (old_x - self.gridx_size * my, y)
if self.inter_point is not None: if mx < my:
self.temp_points.append(self.inter_point) if y < old_y:
else: self.inter_point = (x, old_y - self.gridy_size * mx)
self.inter_point = data else:
self.inter_point = (x, old_y + self.gridy_size * mx)
elif self.draw_app.bend_mode == 3:
self.inter_point = (x, old_y)
elif self.draw_app.bend_mode == 4:
self.inter_point = (old_x, y)
# add the intermediary point to the points storage
if self.inter_point is not None:
self.temp_points.append(self.inter_point)
else:
self.inter_point = (x, y)
else: else:
self.inter_point = data self.inter_point = None
self.temp_points.append(data) else:
new_geo_el = {} self.inter_point = (x, y)
# add click point to the points storage
self.temp_points.append(
(x, y)
)
if len(self.temp_points) > 1: if len(self.temp_points) > 1:
try: try:
new_geo_el['solid'] = LineString(self.temp_points).buffer(self.buf_val, geo_sol = LineString(self.temp_points)
resolution=int(self.steps_per_circle / 4), geo_sol = geo_sol.buffer(self.buf_val, int(self.steps_per_circle / 4), join_style=1)
join_style=1) new_geo_el = {
'solid': geo_sol
}
return DrawToolUtilityShape(new_geo_el) return DrawToolUtilityShape(new_geo_el)
except Exception as e: except Exception as e:
log.debug("AppGerberEditor.RegionEditorGrb.utility_geometry() --> %s" % str(e)) log.debug("AppGerberEditor.RegionEditorGrb.utility_geometry() --> %s" % str(e))
else: else:
new_geo_el['solid'] = Point(self.temp_points).buffer(self.buf_val, geo_sol = Point(self.temp_points).buffer(self.buf_val, resolution=int(self.steps_per_circle / 4))
resolution=int(self.steps_per_circle / 4)) new_geo_el = {
'solid': geo_sol
}
return DrawToolUtilityShape(new_geo_el) return DrawToolUtilityShape(new_geo_el)
if len(self.points) > 2: elif len(self.points) > 1:
self.temp_points = [x for x in self.points] self.temp_points = [x for x in self.points]
# previous point coordinates
old_x = self.points[-1][0] old_x = self.points[-1][0]
old_y = self.points[-1][1] old_y = self.points[-1][1]
# how many grid sections between old point and new point
mx = abs(round((x - old_x) / self.gridx_size)) mx = abs(round((x - old_x) / self.gridx_size))
my = abs(round((y - old_y) / self.gridy_size)) my = abs(round((y - old_y) / self.gridy_size))
if mx and my: if self.draw_app.app.ui.grid_snap_btn.isChecked() and mx and my:
if self.draw_app.app.ui.grid_snap_btn.isChecked(): # calculate intermediary point
if self.draw_app.bend_mode != 5: if self.draw_app.bend_mode != 5:
if self.draw_app.bend_mode == 1: if self.draw_app.bend_mode == 1:
if x > old_x: # if we move from left to right
if mx > my: if x > old_x:
self.inter_point = (old_x + self.gridx_size * (mx - my), old_y) # if the number of grid sections is greater on the X axis
if mx < my: if mx > my:
if y < old_y: self.inter_point = (old_x + self.gridx_size * (mx - my), old_y)
self.inter_point = (old_x, old_y - self.gridy_size * (my - mx)) # if the number of grid sections is greater on the Y axis
else: elif mx < my:
self.inter_point = (old_x, old_y - self.gridy_size * (mx - my)) # if we move from top to down
if x < old_x: if y < old_y:
if mx > my: self.inter_point = (old_x, old_y - self.gridy_size * (my - mx))
self.inter_point = (old_x - self.gridx_size * (mx - my), old_y) # if we move from down to top or at the same height
if mx < my: else:
if y < old_y: self.inter_point = (old_x, old_y + self.gridy_size * (my - mx))
self.inter_point = (old_x, old_y - self.gridy_size * (my - mx)) elif mx == my:
else: pass
self.inter_point = (old_x, old_y - self.gridy_size * (mx - my)) # if we move from right to left
elif self.draw_app.bend_mode == 2: if x < old_x:
if x > old_x: # if the number of grid sections is greater on the X axis
if mx > my: if mx > my:
self.inter_point = (old_x + self.gridx_size * my, y) self.inter_point = (old_x - self.gridx_size * (mx - my), old_y)
if mx < my: # if the number of grid sections is greater on the Y axis
if y < old_y: elif mx < my:
self.inter_point = (x, old_y - self.gridy_size * mx) # if we move from top to down
else: if y < old_y:
self.inter_point = (x, old_y + self.gridy_size * mx) self.inter_point = (old_x, old_y - self.gridy_size * (my - mx))
if x < old_x: # if we move from down to top or at the same height
if mx > my: else:
self.inter_point = (old_x - self.gridx_size * my, y) self.inter_point = (old_x, old_y + self.gridy_size * (my - mx))
if mx < my: elif mx == my:
if y < old_y: pass
self.inter_point = (x, old_y - self.gridy_size * mx) elif self.draw_app.bend_mode == 2:
else: if x > old_x:
self.inter_point = (x, old_y + self.gridy_size * mx) if mx > my:
elif self.draw_app.bend_mode == 3: self.inter_point = (old_x + self.gridx_size * my, y)
self.inter_point = (x, old_y) if mx < my:
elif self.draw_app.bend_mode == 4: if y < old_y:
self.inter_point = (old_x, y) self.inter_point = (x, old_y - self.gridy_size * mx)
else:
self.inter_point = (x, old_y + self.gridy_size * mx)
if x < old_x:
if mx > my:
self.inter_point = (old_x - self.gridx_size * my, y)
if mx < my:
if y < old_y:
self.inter_point = (x, old_y - self.gridy_size * mx)
else:
self.inter_point = (x, old_y + self.gridy_size * mx)
elif self.draw_app.bend_mode == 3:
self.inter_point = (x, old_y)
elif self.draw_app.bend_mode == 4:
self.inter_point = (old_x, y)
# add the intermediary point to the points storage
# self.temp_points.append(self.inter_point)
if self.inter_point is not None:
self.temp_points.append(self.inter_point) self.temp_points.append(self.inter_point)
self.temp_points.append(data) else:
self.inter_point = None
else:
self.inter_point = (x, y)
# add click point to the points storage
self.temp_points.append(
(x, y)
)
# create the geometry
geo_line = LinearRing(self.temp_points)
geo_sol = geo_line.buffer(self.buf_val, int(self.steps_per_circle / 4), join_style=1)
new_geo_el = { new_geo_el = {
'solid': LinearRing(self.temp_points).buffer(self.buf_val, 'solid': geo_sol,
resolution=int(self.steps_per_circle / 4), 'follow': geo_line
join_style=1), }
'follow': LinearRing(self.temp_points)}
return DrawToolUtilityShape(new_geo_el) return DrawToolUtilityShape(new_geo_el)
@@ -1180,9 +1231,8 @@ class RegionEditorGrb(ShapeToolEditorGrb):
self.draw_app.last_aperture_selected = '0' self.draw_app.last_aperture_selected = '0'
new_geo_el = { new_geo_el = {
'solid': Polygon(self.points).buffer(self.buf_val, 'solid': Polygon(self.points).buffer(self.buf_val, int(self.steps_per_circle / 4), join_style=2),
resolution=int(self.steps_per_circle / 4), 'follow': Polygon(self.points).exterior
join_style=2), 'follow': Polygon(self.points).exterior
} }
self.geometry = DrawToolShape(new_geo_el) self.geometry = DrawToolShape(new_geo_el)
@@ -2556,17 +2606,17 @@ class SelectEditorGrb(QtCore.QObject, DrawTool):
self.results = [] self.results = []
with editor_obj.app.proc_container.new('%s' % _("Working ...")): with editor_obj.app.proc_container.new('%s' % _("Working ...")):
def divide_chunks(l, n): def divide_chunks(lst, n):
# looping till length l # looping till length of lst
for i in range(0, len(l), n): for i in range(0, len(lst), n):
yield l[i:i + n] yield lst[i:i + n]
# divide in chunks of 77 elements # divide in chunks of 77 elements
n = 77 n_chunks = 77
for ap_key, storage_val in editor_obj.storage_dict.items(): for ap_key, storage_val in editor_obj.storage_dict.items():
# divide in chunks of 77 elements # divide in chunks of 77 elements
geo_list = list(divide_chunks(storage_val['geometry'], n)) geo_list = list(divide_chunks(storage_val['geometry'], n_chunks))
for chunk, list30 in enumerate(geo_list): for chunk, list30 in enumerate(geo_list):
self.results.append( self.results.append(
editor_obj.pool.apply_async( editor_obj.pool.apply_async(
@@ -2581,7 +2631,7 @@ class SelectEditorGrb(QtCore.QObject, DrawTool):
if ret_val: if ret_val:
k = ret_val[0] k = ret_val[0]
part = ret_val[1] part = ret_val[1]
idx = ret_val[2] + (part * n) idx = ret_val[2] + (part * n_chunks)
shape_stored = editor_obj.storage_dict[k]['geometry'][idx] shape_stored = editor_obj.storage_dict[k]['geometry'][idx]
if shape_stored in editor_obj.selected: if shape_stored in editor_obj.selected:
@@ -3127,31 +3177,32 @@ class AppGerberEditor(QtCore.QObject):
if ap_code == '0': if ap_code == '0':
if ap_code not in self.tid2apcode: if ap_code not in self.tid2apcode:
self.storage_dict[ap_code] = {} self.storage_dict[ap_code] = {
self.storage_dict[ap_code]['type'] = 'REG' 'type': 'REG',
size_val = 0 'size': 0.0,
self.ui.apsize_entry.set_value(size_val) 'geometry': []
self.storage_dict[ap_code]['size'] = size_val }
self.ui.apsize_entry.set_value(0.0)
self.storage_dict[ap_code]['geometry'] = []
# self.oldapcode_newapcode dict keeps the evidence on current aperture codes as keys and # self.oldapcode_newapcode dict keeps the evidence on current aperture codes as keys and
# gets updated on values each time a aperture code is edited or added # gets updated on values each time a aperture code is edited or added
self.oldapcode_newapcode[ap_code] = ap_code self.oldapcode_newapcode[ap_code] = ap_code
else: else:
if ap_code not in self.oldapcode_newapcode: if ap_code not in self.oldapcode_newapcode:
self.storage_dict[ap_code] = {}
type_val = self.ui.aptype_cb.currentText() type_val = self.ui.aptype_cb.currentText()
self.storage_dict[ap_code]['type'] = type_val
if type_val == 'R' or type_val == 'O': if type_val == 'R' or type_val == 'O':
try: try:
dims = self.ui.apdim_entry.get_value() dims = self.ui.apdim_entry.get_value()
self.storage_dict[ap_code]['width'] = dims[0]
self.storage_dict[ap_code]['height'] = dims[1]
size_val = np.sqrt((dims[0] ** 2) + (dims[1] ** 2)) size_val = np.sqrt((dims[0] ** 2) + (dims[1] ** 2))
self.storage_dict[ap_code] = {
'type': type_val,
'size': size_val,
'width': dims[0],
'height': dims[1],
'geometry': []
}
self.ui.apsize_entry.set_value(size_val) self.ui.apsize_entry.set_value(size_val)
except Exception as e: except Exception as e:
@@ -3173,16 +3224,18 @@ class AppGerberEditor(QtCore.QObject):
self.app.inform.emit('[WARNING_NOTCL] %s' % self.app.inform.emit('[WARNING_NOTCL] %s' %
_("Aperture size value is missing or wrong format. Add it and retry.")) _("Aperture size value is missing or wrong format. Add it and retry."))
return return
self.storage_dict[ap_code]['size'] = size_val
self.storage_dict[ap_code]['geometry'] = [] self.storage_dict[ap_code] = {
'type': type_val,
'size': size_val,
'geometry': []
}
# self.oldapcode_newapcode dict keeps the evidence on current aperture codes as keys and gets updated on # self.oldapcode_newapcode dict keeps the evidence on current aperture codes as keys and gets updated on
# values each time a aperture code is edited or added # values each time a aperture code is edited or added
self.oldapcode_newapcode[ap_code] = ap_code self.oldapcode_newapcode[ap_code] = ap_code
else: else:
self.app.inform.emit('[WARNING_NOTCL] %s' % self.app.inform.emit('[WARNING_NOTCL] %s' % _("Aperture already in the aperture table."))
_("Aperture already in the aperture table."))
return return
# since we add a new tool, we update also the initial state of the tool_table through it's dictionary # since we add a new tool, we update also the initial state of the tool_table through it's dictionary
@@ -4791,7 +4844,7 @@ class AppGerberEditor(QtCore.QObject):
except KeyError: except KeyError:
pass pass
if geo_el in self.selected: if geo_el in self.selected:
self.selected.remove(geo_el) # TODO: Check performance self.selected.remove(geo_el)
def delete_utility_geometry(self): def delete_utility_geometry(self):
# for_deletion = [shape for shape in self.shape_buffer if shape.utility] # for_deletion = [shape for shape in self.shape_buffer if shape.utility]
@@ -5034,11 +5087,9 @@ class AppGerberEditor(QtCore.QObject):
self.ma_annotation.set(text=text, pos=position, visible=True, self.ma_annotation.set(text=text, pos=position, visible=True,
font_size=self.app.defaults["cncjob_annotation_fontsize"], font_size=self.app.defaults["cncjob_annotation_fontsize"],
color='#000000FF') color='#000000FF')
self.app.inform.emit('[success] %s' % self.app.inform.emit('[success] %s' % _("Polygons marked."))
_("Polygons marked."))
else: else:
self.app.inform.emit('[WARNING_NOTCL] %s' % self.app.inform.emit('[WARNING_NOTCL] %s' % _("No polygons were marked. None fit within the limits."))
_("No polygons were marked. None fit within the limits."))
def delete_marked_polygons(self): def delete_marked_polygons(self):
for shape_sel in self.geo_to_delete: for shape_sel in self.geo_to_delete: