- added new parameters to improve Gerber parsing

- small optimizations in the Preferences UI
This commit is contained in:
Marius Stanciu 2019-12-18 03:14:17 +02:00 committed by Marius
parent 0b50734578
commit e745f3f836
6 changed files with 101 additions and 37 deletions

View File

@ -511,6 +511,9 @@ class App(QtCore.QObject):
"gerber_multicolored": False,
"gerber_circle_steps": 64,
"gerber_use_buffer_for_union": True,
"gerber_clean_apertures": True,
"gerber_extra_buffering": True,
"gerber_def_units": 'IN',
"gerber_def_zeros": 'L',
"gerber_save_filters": "Gerber File (*.gbr);;Gerber File (*.bot);;Gerber File (*.bsm);;"
@ -1121,6 +1124,8 @@ class App(QtCore.QObject):
"gerber_circle_steps": self.ui.gerber_defaults_form.gerber_gen_group.circle_steps_entry,
"gerber_def_units": self.ui.gerber_defaults_form.gerber_gen_group.gerber_units_radio,
"gerber_def_zeros": self.ui.gerber_defaults_form.gerber_gen_group.gerber_zeros_radio,
"gerber_clean_apertures": self.ui.gerber_defaults_form.gerber_gen_group.gerber_clean_cb,
"gerber_extra_buffering": self.ui.gerber_defaults_form.gerber_gen_group.gerber_extra_buffering,
# Gerber Options
"gerber_isotooldia": self.ui.gerber_defaults_form.gerber_opt_group.iso_tool_dia_entry,

View File

@ -5173,8 +5173,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
if self.tools[tooluid_key]['solid_geometry'] is None:
a += 1
if a == len(self.tools):
self.app.inform.emit('[ERROR_NOTCL] %s...' %
_('Cancelled. Empty file, it has no geometry'))
self.app.inform.emit('[ERROR_NOTCL] %s...' % _('Cancelled. Empty file, it has no geometry'))
return 'fail'
for tooluid_key in list(tools_dict.keys()):

View File

@ -9,6 +9,11 @@ CAD program, and create G-Code for Isolation routing.
=================================================
18.12.2019
- added new parameters to improve Gerber parsing
- small optimizations in the Preferences UI
17.12.2019
- more optimizations in NCC Tool

View File

@ -4594,19 +4594,21 @@ class FlatCAMGrbEditor(QtCore.QObject):
self.shapes.clear(update=True)
for storage in self.storage_dict:
for elem in self.storage_dict[storage]['geometry']:
if 'solid' in elem.geo:
geometric_data = elem.geo['solid']
if geometric_data is None:
continue
# fix for apertures with now geometry inside
if 'geometry' in self.storage_dict[storage]:
for elem in self.storage_dict[storage]['geometry']:
if 'solid' in elem.geo:
geometric_data = elem.geo['solid']
if geometric_data is None:
continue
if elem in self.selected:
self.plot_shape(geometry=geometric_data,
color=self.app.defaults['global_sel_draw_color'] + 'FF',
linewidth=2)
else:
self.plot_shape(geometry=geometric_data,
color=self.app.defaults['global_draw_color'] + 'FF')
if elem in self.selected:
self.plot_shape(geometry=geometric_data,
color=self.app.defaults['global_sel_draw_color'] + 'FF',
linewidth=2)
else:
self.plot_shape(geometry=geometric_data,
color=self.app.defaults['global_draw_color'] + 'FF')
if self.utility:
for elem in self.utility:

View File

@ -1435,6 +1435,29 @@ class GerberGenPrefGroupUI(OptionsGroupUI):
grid0.addWidget(self.gerber_zeros_label, 5, 0)
grid0.addWidget(self.gerber_zeros_radio, 5, 1, 1, 2)
separator_line = QtWidgets.QFrame()
separator_line.setFrameShape(QtWidgets.QFrame.HLine)
separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
grid0.addWidget(separator_line, 6, 0, 1, 3)
# Apertures Cleaning
self.gerber_clean_cb = FCCheckBox(label='%s' % _('Clean Apertures'))
self.gerber_clean_cb.setToolTip(
_("Will remove apertures that do not have geometry\n"
"thus lowering the number of apertures in the Gerber object.")
)
grid0.addWidget(self.gerber_clean_cb, 7, 0, 1, 3)
# Apply Extra Buffering
self.gerber_extra_buffering = FCCheckBox(label='%s' % _('Polarity change buffer'))
self.gerber_extra_buffering.setToolTip(
_("Will apply extra buffering for the\n"
"solid geometry when we have polarity changes.\n"
"May help loading Gerber files that otherwise\n"
"do not load correctly.")
)
grid0.addWidget(self.gerber_extra_buffering, 8, 0, 1, 3)
self.layout.addStretch()
@ -1528,6 +1551,11 @@ class GerberOptPrefGroupUI(OptionsGroupUI):
)
grid0.addWidget(self.combine_passes_cb, 5, 0, 1, 2)
separator_line = QtWidgets.QFrame()
separator_line.setFrameShape(QtWidgets.QFrame.HLine)
separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
grid0.addWidget(separator_line, 6, 0, 1, 2)
# ## Clear non-copper regions
self.clearcopper_label = QtWidgets.QLabel("<b>%s:</b>" % _("Non-copper regions"))
self.clearcopper_label.setToolTip(
@ -1564,6 +1592,11 @@ class GerberOptPrefGroupUI(OptionsGroupUI):
)
grid1.addWidget(self.noncopper_rounded_cb, 1, 0, 1, 2)
separator_line = QtWidgets.QFrame()
separator_line.setFrameShape(QtWidgets.QFrame.HLine)
separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
grid1.addWidget(separator_line, 2, 0, 1, 2)
# ## Bounding box
self.boundingbox_label = QtWidgets.QLabel('<b>%s:</b>' % _('Bounding Box'))
self.layout.addWidget(self.boundingbox_label)
@ -1634,6 +1667,11 @@ class GerberAdvOptPrefGroupUI(OptionsGroupUI):
)
grid0.addWidget(self.aperture_table_visibility_cb, 1, 0, 1, 2)
separator_line = QtWidgets.QFrame()
separator_line.setFrameShape(QtWidgets.QFrame.HLine)
separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
grid0.addWidget(separator_line, 2, 0, 1, 2)
# Tool Type
self.tool_type_label = QtWidgets.QLabel('<b>%s</b>' % _('Tool Type'))
self.tool_type_label.setToolTip(
@ -1645,8 +1683,8 @@ class GerberAdvOptPrefGroupUI(OptionsGroupUI):
self.tool_type_radio = RadioSet([{'label': 'Circular', 'value': 'circular'},
{'label': 'V-Shape', 'value': 'v'}])
grid0.addWidget(self.tool_type_label, 2, 0)
grid0.addWidget(self.tool_type_radio, 2, 1, 1, 2)
grid0.addWidget(self.tool_type_label, 3, 0)
grid0.addWidget(self.tool_type_radio, 3, 1, 1, 2)
# Tip Dia
self.tipdialabel = QtWidgets.QLabel('%s:' % _('V-Tip Dia'))
@ -1658,8 +1696,8 @@ class GerberAdvOptPrefGroupUI(OptionsGroupUI):
self.tipdia_spinner.set_range(-99.9999, 99.9999)
self.tipdia_spinner.setSingleStep(0.1)
self.tipdia_spinner.setWrapping(True)
grid0.addWidget(self.tipdialabel, 3, 0)
grid0.addWidget(self.tipdia_spinner, 3, 1, 1, 2)
grid0.addWidget(self.tipdialabel, 4, 0)
grid0.addWidget(self.tipdia_spinner, 4, 1, 1, 2)
# Tip Angle
self.tipanglelabel = QtWidgets.QLabel('%s:' % _('V-Tip Angle'))
@ -1671,8 +1709,8 @@ class GerberAdvOptPrefGroupUI(OptionsGroupUI):
self.tipangle_spinner.set_range(0, 180)
self.tipangle_spinner.setSingleStep(5)
self.tipangle_spinner.setWrapping(True)
grid0.addWidget(self.tipanglelabel, 4, 0)
grid0.addWidget(self.tipangle_spinner, 4, 1, 1, 2)
grid0.addWidget(self.tipanglelabel, 5, 0)
grid0.addWidget(self.tipangle_spinner, 5, 1, 1, 2)
# Cut Z
self.cutzlabel = QtWidgets.QLabel('%s:' % _('Cut Z'))
@ -1686,8 +1724,8 @@ class GerberAdvOptPrefGroupUI(OptionsGroupUI):
self.cutz_spinner.setSingleStep(0.1)
self.cutz_spinner.setWrapping(True)
grid0.addWidget(self.cutzlabel, 5, 0)
grid0.addWidget(self.cutz_spinner, 5, 1, 1, 2)
grid0.addWidget(self.cutzlabel, 6, 0)
grid0.addWidget(self.cutz_spinner, 6, 1, 1, 2)
# Isolation Type
self.iso_type_label = QtWidgets.QLabel('%s:' % _('Isolation Type'))
@ -1705,8 +1743,13 @@ class GerberAdvOptPrefGroupUI(OptionsGroupUI):
{'label': _('Exterior'), 'value': 'ext'},
{'label': _('Interior'), 'value': 'int'}])
grid0.addWidget(self.iso_type_label, 6, 0,)
grid0.addWidget(self.iso_type_radio, 6, 1, 1, 2)
grid0.addWidget(self.iso_type_label, 7, 0,)
grid0.addWidget(self.iso_type_radio, 7, 1, 1, 2)
separator_line = QtWidgets.QFrame()
separator_line.setFrameShape(QtWidgets.QFrame.HLine)
separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
grid0.addWidget(separator_line, 8, 0, 1, 2)
# Buffering Type
buffering_label = QtWidgets.QLabel('%s:' % _('Buffering'))
@ -1718,8 +1761,8 @@ class GerberAdvOptPrefGroupUI(OptionsGroupUI):
)
self.buffering_radio = RadioSet([{'label': _('None'), 'value': 'no'},
{'label': _('Full'), 'value': 'full'}])
grid0.addWidget(buffering_label, 7, 0)
grid0.addWidget(self.buffering_radio, 7, 1)
grid0.addWidget(buffering_label, 9, 0)
grid0.addWidget(self.buffering_radio, 9, 1)
# Simplification
self.simplify_cb = FCCheckBox(label=_('Simplify'))
@ -1728,7 +1771,7 @@ class GerberAdvOptPrefGroupUI(OptionsGroupUI):
"loaded with simplification having a set tolerance.\n"
"<<WARNING>>: Don't change this unless you know what you are doing !!!")
)
grid0.addWidget(self.simplify_cb, 8, 0, 1, 2)
grid0.addWidget(self.simplify_cb, 10, 0, 1, 2)
# Simplification tolerance
self.simplification_tol_label = QtWidgets.QLabel(_('Tolerance'))
@ -1740,8 +1783,8 @@ class GerberAdvOptPrefGroupUI(OptionsGroupUI):
self.simplification_tol_spinner.setRange(0.00000, 0.01000)
self.simplification_tol_spinner.setSingleStep(0.0001)
grid0.addWidget(self.simplification_tol_label, 9, 0)
grid0.addWidget(self.simplification_tol_spinner, 9, 1)
grid0.addWidget(self.simplification_tol_label, 11, 0)
grid0.addWidget(self.simplification_tol_spinner, 11, 1)
self.ois_simplif = OptionalInputSection(
self.simplify_cb,
[

View File

@ -72,6 +72,8 @@ class Gerber(Geometry):
# "use_buffer_for_union": True
# }
app = None
def __init__(self, steps_per_circle=None):
"""
The constructor takes no parameters. Use ``gerber.parse_files()``
@ -1412,14 +1414,7 @@ class Gerber(Geometry):
if current_polarity == 'D':
self.app.inform.emit('%s' % _("Gerber processing. Applying Gerber polarity."))
if new_poly.is_valid:
# self.solid_geometry = self.solid_geometry.union(new_poly)
# FIX for issue #347 - Sprint Layout generate strange Gerber files when the copper pour is enabled
# it use a filled bounding box polygon to which add clear polygons (negative) to isolate the copper
# features
candidate_geo = list()
for p in self.solid_geometry.union(new_poly):
candidate_geo.append(p.buffer(-0.0000001))
self.solid_geometry = candidate_geo
self.solid_geometry = self.solid_geometry.union(new_poly)
else:
# I do this so whenever the parsed geometry of the file is not valid (intersections) it is still
# loaded. Instead of applying a union I add to a list of polygons.
@ -1438,6 +1433,15 @@ class Gerber(Geometry):
self.solid_geometry = final_poly
# FIX for issue #347 - Sprint Layout generate strange Gerber files when the copper pour is enabled
# it use a filled bounding box polygon to which add clear polygons (negative) to isolate the copper
# features
if self.app.defaults['gerber_extra_buffering']:
candidate_geo = list()
for p in self.solid_geometry:
candidate_geo.append(p.buffer(0.0000001))
self.solid_geometry = candidate_geo
# try:
# self.solid_geometry = self.solid_geometry.union(new_poly)
# except Exception as e:
@ -1450,6 +1454,12 @@ class Gerber(Geometry):
else:
self.solid_geometry = self.solid_geometry.difference(new_poly)
if self.app.defaults['gerber_clean_apertures']:
# clean the Gerber file of apertures with no geometry
for apid, apvalue in list(self.apertures.items()):
if 'geometry' not in apvalue:
self.apertures.pop(apid)
# init this for the following operations
self.conversion_done = False
except Exception as err: