- finished adding new feature in Cutout Tool: cut a geometry by drilling along its path

This commit is contained in:
Marius Stanciu
2020-11-11 00:37:30 +02:00
committed by Marius
parent f3fb0bb497
commit 953be31f6e
6 changed files with 125 additions and 4 deletions

View File

@@ -19,6 +19,7 @@ CHANGELOG for FlatCAM beta
- updated the UI for Cutout Tool
- fixed Paint Tcl command; fixes issue #437
- updated the setup_ubuntu.sh script
- finished adding new feature in Cutout Tool: cut a geometry by drilling along its path
9.11.2020

View File

@@ -437,6 +437,10 @@ class PreferencesUIManager:
"tools_cutout_mb_dia": self.ui.tools_defaults_form.tools_cutout_group.mb_dia_entry,
"tools_cutout_mb_spacing": self.ui.tools_defaults_form.tools_cutout_group.mb_spacing_entry,
"tools_cutout_drill_dia": self.ui.tools_defaults_form.tools_cutout_group.drill_dia_entry,
"tools_cutout_drill_pitch": self.ui.tools_defaults_form.tools_cutout_group.drill_pitch_entry,
"tools_cutout_drill_margin": self.ui.tools_defaults_form.tools_cutout_group.drill_margin_entry,
# Paint Area Tool
"tools_paint_tooldia": self.ui.tools_defaults_form.tools_paint_group.painttooldia_entry,
"tools_paint_order": self.ui.tools_defaults_form.tools_paint_group.paint_order_radio,

View File

@@ -242,4 +242,45 @@ class ToolsCutoutPrefGroupUI(OptionsGroupUI):
_("Use a big cursor when adding manual gaps."))
grid0.addWidget(self.big_cursor_cb, 19, 0, 1, 2)
# Drill Cut
# Drill Tool Diameter
self.drill_dia_entry = FCDoubleSpinner()
self.drill_dia_entry.set_precision(self.decimals)
self.drill_dia_entry.set_range(0.0000, 10000.0000)
self.drill_dia_label = FCLabel('%s:' % _("Drill Dia"))
self.drill_dia_label.setToolTip(
_("Diameter of the tool used to cutout\n"
"the PCB by drilling.")
)
grid0.addWidget(self.drill_dia_label, 21, 0)
grid0.addWidget(self.drill_dia_entry, 21, 1)
# Drill Tool Pitch
self.drill_pitch_entry = FCDoubleSpinner()
self.drill_pitch_entry.set_precision(self.decimals)
self.drill_pitch_entry.set_range(0.0000, 10000.0000)
self.drill_pitch_label = FCLabel('%s:' % _("Pitch"))
self.drill_pitch_label.setToolTip(
_("Distance between the center of\n"
"two neighboring drill holes.")
)
grid0.addWidget(self.drill_pitch_label, 23, 0)
grid0.addWidget(self.drill_pitch_entry, 23, 1)
# Drill Tool Margin
self.drill_margin_entry = FCDoubleSpinner()
self.drill_margin_entry.set_precision(self.decimals)
self.drill_margin_entry.set_range(0.0000, 10000.0000)
self.drill_margin_label = FCLabel('%s:' % _("Margin"))
self.drill_margin_label.setToolTip(
_("Margin over bounds. A positive value here\n"
"will make the cutout of the PCB further from\n"
"the actual PCB border")
)
grid0.addWidget(self.drill_margin_label, 25, 0)
grid0.addWidget(self.drill_margin_entry, 25, 1)
self.layout.addStretch()

View File

@@ -10,7 +10,7 @@ from appTool import AppTool
from appGUI.GUIElements import FCDoubleSpinner, FCCheckBox, RadioSet, FCComboBox, OptionalInputSection, FCButton, \
FCLabel
from shapely.geometry import box, MultiPolygon, Polygon, LineString, LinearRing, MultiLineString
from shapely.geometry import box, MultiPolygon, Polygon, LineString, LinearRing, MultiLineString, Point
from shapely.ops import unary_union, linemerge
import shapely.affinity as affinity
@@ -115,6 +115,7 @@ class CutOut(AppTool):
self.ui.man_geo_creation_btn.clicked.connect(self.on_manual_geo)
self.ui.man_gaps_creation_btn.clicked.connect(self.on_manual_gap_click)
self.ui.drillcut_btn.clicked.connect(self.on_drill_cut_click)
self.ui.reset_button.clicked.connect(self.set_tool_ui)
def on_type_obj_changed(self, val):
@@ -250,6 +251,10 @@ class CutOut(AppTool):
self.ui.cutout_type_radio.set_value('a')
self.on_cutout_type(val='a')
self.ui.drill_dia_entry.set_value(float(self.app.defaults["tools_cutout_drill_dia"]))
self.ui.drill_pitch_entry.set_value(float(self.app.defaults["tools_cutout_drill_pitch"]))
self.ui.drill_margin_entry.set_value(float(self.app.defaults["tools_cutout_drill_margin"]))
def update_ui(self, tool_dict):
self.ui.obj_kind_combo.set_value(self.default_data["tools_cutout_kind"])
self.ui.big_cursor_cb.set_value(self.default_data['tools_cutout_big_cursor'])
@@ -1320,6 +1325,75 @@ class CutOut(AppTool):
self.app.worker_task.emit({'fcn': job_thread, 'params': [self.app]})
def on_drill_cut_click(self):
log.debug("Cutout.on_drill_cut_click() was launched ...")
margin = self.ui.drill_margin_entry.get_value()
pitch = self.ui.drill_pitch_entry.get_value()
drill_dia = self.ui.drill_dia_entry.get_value()
name = self.ui.drillcut_object_combo.currentText()
# Get source object.
try:
obj = self.app.collection.get_by_name(str(name))
except Exception as e:
log.debug("CutOut.on_freeform_cutout() --> %s" % str(e))
self.app.inform.emit('[ERROR_NOTCL] %s: %s' % (_("Could not retrieve object"), name))
return "Could not retrieve object: %s" % name
if obj is None:
self.app.inform.emit('[ERROR_NOTCL] %s' %
_("There is no object selected for Cutout.\nSelect one and try again."))
return
cut_geo = unary_union(obj.solid_geometry).buffer(margin, join_style=2).exterior
geo_length = cut_geo.length
drill_list = []
dist = 0
while dist <= geo_length:
drill_list.append(cut_geo.interpolate(dist))
dist += pitch
if dist < geo_length:
drill_list.append(Point(list(cut_geo.coords)[-1]))
if not drill_list:
self.app.inform.emit('[WARNING_NOTCL] %s %s' % (_("Failed."), _("Could not add drills.")))
return
tools = {
1: {
"tooldia": drill_dia,
"drills": drill_list,
"slots": [],
"solid_geometry": []
}
}
formatted_name = obj.options['name'].rpartition('.')[0]
if formatted_name == '':
formatted_name = obj.options['name']
outname = '%s_drillcut' % formatted_name
def obj_init(obj_inst, app_inst):
obj_inst.tools = deepcopy(tools)
obj_inst.create_geometry()
obj_inst.source_file = app_inst.f_handlers.export_excellon(obj_name=outname, local_use=obj_inst,
filename=None,
use_thread=False)
with self.app.proc_container.new(_("Working ...")):
try:
ret = self.app.app_obj.new_object("excellon", outname, obj_init)
except Exception as e:
log.error("Error on Drill Cutting Excellon object creation: %s" % str(e))
return
if ret != 'fail':
self.app.inform.emit('[success] %s' % _("Done."))
def on_manual_gap_click(self):
name = self.ui.man_object_combo.currentText()
@@ -2451,7 +2525,7 @@ class CutoutUI:
separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
grid0.addWidget(separator_line, 60, 0, 1, 2)
grid0.addWidget(FCLabel(""), 62, 0, 1, 2)
# grid0.addWidget(FCLabel(""), 62, 0, 1, 2)
# Cut by Drilling Title
title_drillcut_label = FCLabel("<b>%s</b>:" % _('Cut by Drilling'))

View File

@@ -159,7 +159,6 @@ class ToolExtract(AppTool):
prop_factor = self.ui.factor_entry.get_value() / 100.0
drills = []
tools = {}
selection_index = self.ui.gerber_object_combo.currentIndex()
@@ -401,7 +400,6 @@ class ToolExtract(AppTool):
def obj_init(obj_inst, app_inst):
obj_inst.tools = tools
obj_inst.drills = drills
obj_inst.create_geometry()
obj_inst.source_file = app_inst.f_handlers.export_excellon(obj_name=outname, local_use=obj_inst,
filename=None,

View File

@@ -503,6 +503,9 @@ class FlatCAMDefaults:
"tools_cutout_gap_depth": -1.0,
"tools_cutout_mb_dia": 0.6,
"tools_cutout_mb_spacing": 0.3,
"tools_cutout_drill_dia": 1.0,
"tools_cutout_drill_pitch": 1.0,
"tools_cutout_drill_margin": 0.0,
# Paint Tool
"tools_paint_tooldia": 0.3,