- in Solderpast Plugin fixed the GCode generation; make sure that if no object is selected then the first Gerber object is autoselected
- in Solderpaste Plugin fixed the CNCJob plotting - in Solderpaste Plugin added a new parameter 'Margin' which allows reducing how much solderpaste is added and therefore adding a space between the solderpaste and the pad boundary - all CNCJob objects generated by the Solderpaste plugin now have the GCode saved as source_code which can be saved also from the CNCJob object context menu, and edited
This commit is contained in:
@@ -7,6 +7,13 @@ CHANGELOG for FlatCAM Evo beta
|
||||
|
||||
=================================================
|
||||
|
||||
20.04.2022
|
||||
|
||||
- in Solderpast Plugin fixed the GCode generation; make sure that if no object is selected then the first Gerber object is autoselected
|
||||
- in Solderpaste Plugin fixed the CNCJob plotting
|
||||
- in Solderpaste Plugin added a new parameter 'Margin' which allows reducing how much solderpaste is added and therefore adding a space between the solderpaste and the pad boundary
|
||||
- all CNCJob objects generated by the Solderpaste plugin now have the GCode saved as source_code which can be saved also from the CNCJob object context menu, and edited
|
||||
|
||||
19.04.2022
|
||||
|
||||
- fixed and prettified the 'Light' theme
|
||||
|
||||
@@ -575,6 +575,7 @@ class PreferencesUIManager(QtCore.QObject):
|
||||
# SolderPaste Dispensing Tool
|
||||
"tools_solderpaste_tools": self.ui.plugin_pref_form.tools_solderpaste_group.nozzle_tool_dia_entry,
|
||||
"tools_solderpaste_new": self.ui.plugin_pref_form.tools_solderpaste_group.addtool_entry,
|
||||
"tools_solderpaste_margin": self.ui.plugin_pref_form.tools_solderpaste_group.margin_entry,
|
||||
"tools_solderpaste_z_start": self.ui.plugin_pref_form.tools_solderpaste_group.z_start_entry,
|
||||
"tools_solderpaste_z_dispense": self.ui.plugin_pref_form.tools_solderpaste_group.z_dispense_entry,
|
||||
"tools_solderpaste_z_stop": self.ui.plugin_pref_form.tools_solderpaste_group.z_stop_entry,
|
||||
|
||||
@@ -60,8 +60,23 @@ class ToolsSolderpastePrefGroupUI(OptionsGroupUI):
|
||||
self.addtool_entry.set_range(0.0000001, 10000.0000)
|
||||
self.addtool_entry.setSingleStep(0.1)
|
||||
|
||||
param_grid.addWidget(self.addtool_entry_lbl, 1, 0)
|
||||
param_grid.addWidget(self.addtool_entry, 1, 1)
|
||||
param_grid.addWidget(self.addtool_entry_lbl, 2, 0)
|
||||
param_grid.addWidget(self.addtool_entry, 2, 1)
|
||||
|
||||
# Margin
|
||||
self.margin_label = FCLabel('%s:' % _("Margin"))
|
||||
self.margin_label.setToolTip('%s %s' % (
|
||||
_("Offset from the boundary."),
|
||||
_("Fraction of tool diameter.")
|
||||
)
|
||||
)
|
||||
self.margin_entry = FCDoubleSpinner(suffix='%')
|
||||
self.margin_entry.set_range(-100.0000, 100.0000)
|
||||
self.margin_entry.set_precision(self.decimals)
|
||||
self.margin_entry.setSingleStep(0.1)
|
||||
|
||||
param_grid.addWidget(self.margin_label, 4, 0)
|
||||
param_grid.addWidget(self.margin_entry, 4, 1)
|
||||
|
||||
# Z dispense start
|
||||
self.z_start_entry = FCDoubleSpinner()
|
||||
@@ -73,8 +88,8 @@ class ToolsSolderpastePrefGroupUI(OptionsGroupUI):
|
||||
self.z_start_label.setToolTip(
|
||||
_("The height (Z) when solder paste dispensing starts.")
|
||||
)
|
||||
param_grid.addWidget(self.z_start_label, 2, 0)
|
||||
param_grid.addWidget(self.z_start_entry, 2, 1)
|
||||
param_grid.addWidget(self.z_start_label, 6, 0)
|
||||
param_grid.addWidget(self.z_start_entry, 6, 1)
|
||||
|
||||
# Z dispense
|
||||
self.z_dispense_entry = FCDoubleSpinner()
|
||||
@@ -86,8 +101,8 @@ class ToolsSolderpastePrefGroupUI(OptionsGroupUI):
|
||||
self.z_dispense_label.setToolTip(
|
||||
_("The height (Z) when doing solder paste dispensing.")
|
||||
)
|
||||
param_grid.addWidget(self.z_dispense_label, 3, 0)
|
||||
param_grid.addWidget(self.z_dispense_entry, 3, 1)
|
||||
param_grid.addWidget(self.z_dispense_label, 8, 0)
|
||||
param_grid.addWidget(self.z_dispense_entry, 8, 1)
|
||||
|
||||
# Z dispense stop
|
||||
self.z_stop_entry = FCDoubleSpinner()
|
||||
@@ -99,8 +114,8 @@ class ToolsSolderpastePrefGroupUI(OptionsGroupUI):
|
||||
self.z_stop_label.setToolTip(
|
||||
_("The height (Z) when solder paste dispensing stops.")
|
||||
)
|
||||
param_grid.addWidget(self.z_stop_label, 4, 0)
|
||||
param_grid.addWidget(self.z_stop_entry, 4, 1)
|
||||
param_grid.addWidget(self.z_stop_label, 10, 0)
|
||||
param_grid.addWidget(self.z_stop_entry, 101, 1)
|
||||
|
||||
# Z travel
|
||||
self.z_travel_entry = FCDoubleSpinner()
|
||||
@@ -113,8 +128,8 @@ class ToolsSolderpastePrefGroupUI(OptionsGroupUI):
|
||||
_("The height (Z) for travel between pads\n"
|
||||
"(without dispensing solder paste).")
|
||||
)
|
||||
param_grid.addWidget(self.z_travel_label, 5, 0)
|
||||
param_grid.addWidget(self.z_travel_entry, 5, 1)
|
||||
param_grid.addWidget(self.z_travel_label, 12, 0)
|
||||
param_grid.addWidget(self.z_travel_entry, 12, 1)
|
||||
|
||||
# Z toolchange location
|
||||
self.z_toolchange_entry = FCDoubleSpinner()
|
||||
@@ -126,8 +141,8 @@ class ToolsSolderpastePrefGroupUI(OptionsGroupUI):
|
||||
self.z_toolchange_label.setToolTip(
|
||||
_("The height (Z) for tool (nozzle) change.")
|
||||
)
|
||||
param_grid.addWidget(self.z_toolchange_label, 6, 0)
|
||||
param_grid.addWidget(self.z_toolchange_entry, 6, 1)
|
||||
param_grid.addWidget(self.z_toolchange_label, 14, 0)
|
||||
param_grid.addWidget(self.z_toolchange_entry, 14, 1)
|
||||
|
||||
# X,Y Toolchange location
|
||||
self.xy_toolchange_entry = NumericalEvalTupleEntry(border_color='#0069A9')
|
||||
@@ -136,8 +151,8 @@ class ToolsSolderpastePrefGroupUI(OptionsGroupUI):
|
||||
_("The X,Y location for tool (nozzle) change.\n"
|
||||
"The format is (x, y) where x and y are real numbers.")
|
||||
)
|
||||
param_grid.addWidget(self.xy_toolchange_label, 7, 0)
|
||||
param_grid.addWidget(self.xy_toolchange_entry, 7, 1)
|
||||
param_grid.addWidget(self.xy_toolchange_label, 16, 0)
|
||||
param_grid.addWidget(self.xy_toolchange_entry, 16, 1)
|
||||
|
||||
# Feedrate X-Y
|
||||
self.frxy_entry = FCDoubleSpinner()
|
||||
@@ -149,8 +164,8 @@ class ToolsSolderpastePrefGroupUI(OptionsGroupUI):
|
||||
self.frxy_label.setToolTip(
|
||||
_("Feedrate (speed) while moving on the X-Y plane.")
|
||||
)
|
||||
param_grid.addWidget(self.frxy_label, 8, 0)
|
||||
param_grid.addWidget(self.frxy_entry, 8, 1)
|
||||
param_grid.addWidget(self.frxy_label, 18, 0)
|
||||
param_grid.addWidget(self.frxy_entry, 18, 1)
|
||||
|
||||
# Feedrate Z
|
||||
self.frz_entry = FCDoubleSpinner()
|
||||
@@ -163,8 +178,8 @@ class ToolsSolderpastePrefGroupUI(OptionsGroupUI):
|
||||
_("Feedrate (speed) while moving vertically\n"
|
||||
"(on Z plane).")
|
||||
)
|
||||
param_grid.addWidget(self.frz_label, 9, 0)
|
||||
param_grid.addWidget(self.frz_entry, 9, 1)
|
||||
param_grid.addWidget(self.frz_label, 20, 0)
|
||||
param_grid.addWidget(self.frz_entry, 20, 1)
|
||||
|
||||
# Feedrate Z Dispense
|
||||
self.frz_dispense_entry = FCDoubleSpinner()
|
||||
@@ -177,8 +192,8 @@ class ToolsSolderpastePrefGroupUI(OptionsGroupUI):
|
||||
_("Feedrate (speed) while moving up vertically\n"
|
||||
"to Dispense position (on Z plane).")
|
||||
)
|
||||
param_grid.addWidget(self.frz_dispense_label, 10, 0)
|
||||
param_grid.addWidget(self.frz_dispense_entry, 10, 1)
|
||||
param_grid.addWidget(self.frz_dispense_label, 22, 0)
|
||||
param_grid.addWidget(self.frz_dispense_entry, 22, 1)
|
||||
|
||||
# Spindle Speed Forward
|
||||
self.speedfwd_entry = FCSpinner()
|
||||
@@ -190,25 +205,25 @@ class ToolsSolderpastePrefGroupUI(OptionsGroupUI):
|
||||
_("The dispenser speed while pushing solder paste\n"
|
||||
"through the dispenser nozzle.")
|
||||
)
|
||||
param_grid.addWidget(self.speedfwd_label, 11, 0)
|
||||
param_grid.addWidget(self.speedfwd_entry, 11, 1)
|
||||
param_grid.addWidget(self.speedfwd_label, 24, 0)
|
||||
param_grid.addWidget(self.speedfwd_entry, 24, 1)
|
||||
|
||||
# Dwell Forward
|
||||
self.dwellfwd_entry = FCDoubleSpinner()
|
||||
self.dwellfwd_entry.set_precision(self.decimals)
|
||||
self.dwellfwd_entry.set_range(0.0000001, 10000.0000)
|
||||
self.dwellfwd_entry.set_range(0.0000, 10000.0000)
|
||||
self.dwellfwd_entry.setSingleStep(0.1)
|
||||
|
||||
self.dwellfwd_label = FCLabel('%s:' % _("Dwell FWD"))
|
||||
self.dwellfwd_label.setToolTip(
|
||||
_("Pause after solder dispensing.")
|
||||
)
|
||||
param_grid.addWidget(self.dwellfwd_label, 12, 0)
|
||||
param_grid.addWidget(self.dwellfwd_entry, 12, 1)
|
||||
param_grid.addWidget(self.dwellfwd_label, 26, 0)
|
||||
param_grid.addWidget(self.dwellfwd_entry, 26, 1)
|
||||
|
||||
# Spindle Speed Reverse
|
||||
self.speedrev_entry = FCSpinner()
|
||||
self.speedrev_entry.set_range(0, 999999)
|
||||
self.speedrev_entry.set_range(0, 1000000)
|
||||
self.speedrev_entry.set_step(1000)
|
||||
|
||||
self.speedrev_label = FCLabel('%s:' % _("Spindle Speed REV"))
|
||||
@@ -216,13 +231,13 @@ class ToolsSolderpastePrefGroupUI(OptionsGroupUI):
|
||||
_("The dispenser speed while retracting solder paste\n"
|
||||
"through the dispenser nozzle.")
|
||||
)
|
||||
param_grid.addWidget(self.speedrev_label, 13, 0)
|
||||
param_grid.addWidget(self.speedrev_entry, 13, 1)
|
||||
param_grid.addWidget(self.speedrev_label, 28, 0)
|
||||
param_grid.addWidget(self.speedrev_entry, 28, 1)
|
||||
|
||||
# Dwell Reverse
|
||||
self.dwellrev_entry = FCDoubleSpinner()
|
||||
self.dwellrev_entry.set_precision(self.decimals)
|
||||
self.dwellrev_entry.set_range(0.0000001, 10000.0000)
|
||||
self.dwellrev_entry.set_range(0.0000, 10000.0000)
|
||||
self.dwellrev_entry.setSingleStep(0.1)
|
||||
|
||||
self.dwellrev_label = FCLabel('%s:' % _("Dwell REV"))
|
||||
@@ -230,8 +245,8 @@ class ToolsSolderpastePrefGroupUI(OptionsGroupUI):
|
||||
_("Pause after solder paste dispenser retracted,\n"
|
||||
"to allow pressure equilibrium.")
|
||||
)
|
||||
param_grid.addWidget(self.dwellrev_label, 14, 0)
|
||||
param_grid.addWidget(self.dwellrev_entry, 14, 1)
|
||||
param_grid.addWidget(self.dwellrev_label, 30, 0)
|
||||
param_grid.addWidget(self.dwellrev_entry, 30, 1)
|
||||
|
||||
# Preprocessors
|
||||
pp_label = FCLabel('%s:' % _('Preprocessor'))
|
||||
@@ -246,7 +261,7 @@ class ToolsSolderpastePrefGroupUI(OptionsGroupUI):
|
||||
for it in range(self.pp_combo.count()):
|
||||
self.pp_combo.setItemData(it, self.pp_combo.itemText(it), QtCore.Qt.ItemDataRole.ToolTipRole)
|
||||
|
||||
param_grid.addWidget(pp_label, 15, 0)
|
||||
param_grid.addWidget(self.pp_combo, 15, 1)
|
||||
param_grid.addWidget(pp_label, 32, 0)
|
||||
param_grid.addWidget(self.pp_combo, 32, 1)
|
||||
|
||||
self.layout.addStretch()
|
||||
|
||||
@@ -1001,15 +1001,15 @@ class CNCJobObject(FlatCAMObj, CNCjob):
|
||||
if postamble == '':
|
||||
postamble = self.app.options["cncjob_append"]
|
||||
|
||||
try:
|
||||
if self.special_group:
|
||||
self.app.inform.emit('[WARNING_NOTCL] %s %s %s.' %
|
||||
(_("This CNCJob object can't be processed because it is a"),
|
||||
str(self.special_group),
|
||||
_("CNCJob object")))
|
||||
return 'fail'
|
||||
except AttributeError:
|
||||
pass
|
||||
# try:
|
||||
# if self.special_group:
|
||||
# self.app.inform.emit('[WARNING_NOTCL] %s %s %s.' %
|
||||
# (_("This CNCJob object can't be processed because it is a"),
|
||||
# str(self.special_group),
|
||||
# _("CNCJob object")))
|
||||
# return 'fail'
|
||||
# except AttributeError:
|
||||
# pass
|
||||
|
||||
# if this dict is not empty then the object is a Geometry object
|
||||
if self.obj_options['type'].lower() == 'geometry':
|
||||
@@ -1357,7 +1357,8 @@ class CNCJobObject(FlatCAMObj, CNCjob):
|
||||
self.plot2(tooldia=dia_plot, obj=self, visible=visible, gcode_parsed=gcode_parsed,
|
||||
kind=kind)
|
||||
self.shapes.redraw()
|
||||
except (ObjectDeleted, AttributeError):
|
||||
except (ObjectDeleted, AttributeError) as err:
|
||||
self.app.log.debug("CNCJobObject.plot() --> %s" % str(err))
|
||||
self.shapes.clear(update=True)
|
||||
if self.app.use_3d_engine:
|
||||
self.annotation.clear(update=True)
|
||||
|
||||
@@ -154,6 +154,7 @@ class SolderPaste(AppTool):
|
||||
"tools_solderpaste_z_dispense": self.ui.z_dispense_entry,
|
||||
"tools_solderpaste_z_stop": self.ui.z_stop_entry,
|
||||
"tools_solderpaste_z_travel": self.ui.z_travel_entry,
|
||||
"tools_solderpaste_margin": self.ui.margin_entry,
|
||||
"tools_solderpaste_z_toolchange": self.ui.z_toolchange_entry,
|
||||
"tools_solderpaste_xy_toolchange": self.ui.xy_toolchange_entry,
|
||||
"tools_solderpaste_frxy": self.ui.frxy_entry,
|
||||
@@ -217,6 +218,12 @@ class SolderPaste(AppTool):
|
||||
if obj and obj.kind == 'gerber':
|
||||
obj_name = obj.obj_options['name']
|
||||
self.ui.obj_combo.set_value(obj_name)
|
||||
else:
|
||||
# select first Gerber object found
|
||||
for o in self.app.collection.get_list():
|
||||
if o.kind == 'gerber':
|
||||
obj_name = o.obj_options['name']
|
||||
self.ui.obj_combo.set_value(obj_name)
|
||||
|
||||
def build_ui(self):
|
||||
"""
|
||||
@@ -451,6 +458,8 @@ class SolderPaste(AppTool):
|
||||
|
||||
current_row = self.ui.tools_table.currentRow()
|
||||
uid = tooluid if tooluid else int(self.ui.tools_table.item(current_row, 2).text())
|
||||
if uid < 0:
|
||||
return
|
||||
for key in self.form_fields:
|
||||
self.tooltable_tools[uid]['data'].update({
|
||||
key: self.form_fields[key].get_value()
|
||||
@@ -718,6 +727,10 @@ class SolderPaste(AppTool):
|
||||
:param use_thread: use thread, True or False
|
||||
:return: a Geometry type object
|
||||
"""
|
||||
|
||||
# this is a percentage of the tool diameter
|
||||
tool_margin = self.ui.margin_entry.get_value()
|
||||
|
||||
proc = self.app.proc_container.new('%s...' % _("Working"))
|
||||
obj = work_object
|
||||
|
||||
@@ -795,7 +808,7 @@ class SolderPaste(AppTool):
|
||||
tooluid = 1
|
||||
|
||||
for tool in sorted_tools:
|
||||
offset = tool / 2
|
||||
offset = ((tool_margin * tool) * 0.01) + (tool / 2)
|
||||
for uid, vl in self.tooltable_tools.items():
|
||||
if float('%.*f' % (self.decimals, float(vl['tooldia']))) == tool:
|
||||
tooluid = int(uid)
|
||||
@@ -817,7 +830,7 @@ class SolderPaste(AppTool):
|
||||
# so we do a hack: get first the exterior in a form of LinearRings and then convert back to Polygon
|
||||
# because intersection does not work on LinearRings
|
||||
for g in work_geo:
|
||||
# for whatever reason intersection on LinearRings does not work so we convert back to Polygons
|
||||
# for whatever reason intersection on LinearRings does not work, so we convert back to Polygons
|
||||
poly = Polygon(g)
|
||||
x_min, y_min, x_max, y_max = poly.bounds
|
||||
|
||||
@@ -1002,13 +1015,13 @@ class SolderPaste(AppTool):
|
||||
app_obj.log.debug("GeometryObject.mtool_gen_cncjob() --> generate_from_geometry2() failed")
|
||||
return 'fail'
|
||||
else:
|
||||
tool_cnc_dict['gcode'] = StringIO(res)
|
||||
tool_cnc_dict['gcode'] = res
|
||||
total_gcode += res
|
||||
|
||||
# ## PARSE GCODE # ##
|
||||
tool_cnc_dict['gcode_parsed'] = new_obj.gcode_parse(tool_data=tool_cnc_dict['data'])
|
||||
|
||||
# TODO this serve for bounding box creation only; should be optimized
|
||||
# TODO this serve for bounding box creation only; should be optimized. Using recursive bounds()?
|
||||
tool_cnc_dict['solid_geometry'] = unary_union([geo['geom'] for geo in tool_cnc_dict['gcode_parsed']])
|
||||
|
||||
# tell gcode_parse from which point to start drawing the lines depending on what kind of
|
||||
@@ -1019,6 +1032,9 @@ class SolderPaste(AppTool):
|
||||
})
|
||||
tool_cnc_dict.clear()
|
||||
|
||||
used_tools = list(obj.tools.keys())
|
||||
new_obj.used_tools = used_tools
|
||||
|
||||
new_obj.source_file = StringIO(total_gcode)
|
||||
|
||||
if use_thread:
|
||||
@@ -1330,6 +1346,21 @@ class SolderUI:
|
||||
param_grid.addWidget(self.z_travel_label, 0, 0)
|
||||
param_grid.addWidget(self.z_travel_entry, 0, 1)
|
||||
|
||||
# MARGIN
|
||||
self.margin_label = FCLabel('%s:' % _("Margin"))
|
||||
self.margin_label.setToolTip('%s %s' % (
|
||||
_("Offset from the boundary."),
|
||||
_("Fraction of tool diameter.")
|
||||
)
|
||||
)
|
||||
self.margin_entry = FCDoubleSpinner(suffix='%')
|
||||
self.margin_entry.set_range(-100.0000, 100.0000)
|
||||
self.margin_entry.set_precision(self.decimals)
|
||||
self.margin_entry.setSingleStep(0.1)
|
||||
|
||||
param_grid.addWidget(self.margin_label, 2, 0)
|
||||
param_grid.addWidget(self.margin_entry, 2, 1)
|
||||
|
||||
# #############################################################################################################
|
||||
# Dispense Frame
|
||||
# #############################################################################################################
|
||||
|
||||
@@ -650,6 +650,7 @@ class AppDefaults:
|
||||
# SolderPaste Tool
|
||||
"tools_solderpaste_tools": "1.0, 0.3",
|
||||
"tools_solderpaste_new": 0.3,
|
||||
"tools_solderpaste_margin": 0.0,
|
||||
"tools_solderpaste_z_start": 0.05,
|
||||
"tools_solderpaste_z_dispense": 0.1,
|
||||
"tools_solderpaste_z_stop": 0.05,
|
||||
|
||||
Reference in New Issue
Block a user