- Cutout Tool - finished adding the Mouse Bites feature by adding mouse bites for manual cutouts

This commit is contained in:
Marius Stanciu 2020-08-30 01:08:21 +03:00
parent 26ac02e484
commit 15a8f718c9
2 changed files with 72 additions and 6 deletions

View File

@ -19,6 +19,7 @@ CHANGELOG for FlatCAM beta
- Cutout Tool - fixed mouse bites feature in case of using a Geometry object and Freeform cutout
- Cutout Tool - can do cutouts on multigeo Geometry objects: it will automatically select the geometry of first tool
- Geometry Editor - fixed exception raised when trying to move and there is no shape to move
- Cutout Tool - finished adding the Mouse Bites feature by adding mouse bites for manual cutouts
28.08.2020

View File

@ -93,6 +93,12 @@ class CutOut(AppTool):
# store original geometry for manual cutout
self.manual_solid_geo = None
# here will store the original geometry for manual cutout with mouse bytes
self.mb_manual_solid_geo = None
# here will store the geo rests when doing manual cutouts with mouse bites
self.mb_manual_cuts = []
# here store the tool data for the Cutout Tool
self.cut_tool_dict = {}
@ -1286,13 +1292,18 @@ class CutOut(AppTool):
self.manual_solid_geo = deepcopy(self.flatten(self.man_cutout_obj.solid_geometry))
self.cutting_dia = float(self.ui.dia.get_value())
self.cutting_dia = self.ui.dia.get_value()
if 0 in {self.cutting_dia}:
self.app.inform.emit('[ERROR_NOTCL] %s' %
_("Tool Diameter is zero value. Change it to a positive real number."))
return
self.cutting_gapsize = float(self.ui.gapsize.get_value())
if self.ui.gaptype_radio.get_value() == 'mb':
mb_dia = self.ui.mb_dia_entry.get_value()
b_dia = (self.cutting_dia / 2.0) - (mb_dia / 2.0)
self.mb_manual_solid_geo = self.flatten(unary_union(self.manual_solid_geo).buffer(b_dia).interiors)
self.cutting_gapsize = self.ui.gapsize.get_value()
name = self.ui.man_object_combo.currentText()
# Get Geometry source object to be used as target for Manual adding Gaps
@ -1328,8 +1339,8 @@ class CutOut(AppTool):
def on_manual_cutout(self, click_pos):
if self.man_cutout_obj is None:
self.app.inform.emit('[ERROR_NOTCL] %s: %s' %
(_("Geometry object for manual cutout not found"), self.man_cutout_obj))
msg = '[ERROR_NOTCL] %s: %s' % (_("Geometry object for manual cutout not found"), self.man_cutout_obj)
self.app.inform.emit(msg)
return
# use the snapped position as reference
@ -1337,10 +1348,18 @@ class CutOut(AppTool):
cut_poly = self.cutting_geo(pos=(snapped_pos[0], snapped_pos[1]))
gap_type = self.ui.gaptype_radio.get_value()
gaps_solid_geo = None
if self.ui.gaptype_radio.get_value() == 'bt' and self.ui.thin_depth_entry.get_value() != 0:
if gap_type == 'bt' and self.ui.thin_depth_entry.get_value() != 0:
gaps_solid_geo = self.intersect_geo(self.manual_solid_geo, cut_poly)
if gap_type == 'mb':
rests_geo = self.intersect_geo(self.mb_manual_solid_geo, cut_poly)
if isinstance(rests_geo, list):
self.mb_manual_cuts += rests_geo
else:
self.mb_manual_cuts.append(rests_geo)
# first subtract geometry for the total solid_geometry
new_solid_geometry = CutOut.subtract_geo(self.man_cutout_obj.solid_geometry, cut_poly)
new_solid_geometry = linemerge(new_solid_geometry)
@ -1359,7 +1378,7 @@ class CutOut(AppTool):
self.app.inform.emit('[ERROR_NOTCL] %s' % _("No tool in the Geometry object."))
return
dia = float(self.ui.dia.get_value())
dia = self.ui.dia.get_value()
if gaps_solid_geo:
if 9999 not in self.man_cutout_obj.tools:
self.man_cutout_obj.tools.update({
@ -1549,6 +1568,52 @@ class CutOut(AppTool):
# plot the final object
self.man_cutout_obj.plot()
# mouse bytes
if self.ui.gaptype_radio.get_value() == 'mb':
with self.app.proc_container.new("Generating Excellon ..."):
outname_exc = self.man_cutout_obj.options["name"] + "_mouse_bites"
self.app.collection.promise(outname_exc)
def job_thread(app_obj):
# list of Shapely Points to mark the drill points centers
holes = []
mb_dia = self.ui.mb_dia_entry.get_value()
mb_spacing = self.ui.mb_spacing_entry.get_value()
for line in self.mb_manual_cuts:
calc_len = 0
while calc_len < line.length:
holes.append(line.interpolate(calc_len))
calc_len += mb_dia + mb_spacing
self.mb_manual_cuts[:] = []
def excellon_init(exc_obj, app_o):
if not holes:
return 'fail'
tools = {}
tools[1] = {}
tools[1]["tooldia"] = mb_dia
tools[1]['drills'] = holes
tools[1]['solid_geometry'] = []
exc_obj.tools = tools
exc_obj.create_geometry()
exc_obj.source_file = app_o.export_excellon(obj_name=exc_obj.options['name'],
local_use=exc_obj,
filename=None, use_thread=False)
# calculate the bounds
xmin, ymin, xmax, ymax = CutOut.recursive_bounds(exc_obj.solid_geometry)
exc_obj.options['xmin'] = xmin
exc_obj.options['ymin'] = ymin
exc_obj.options['xmax'] = xmax
exc_obj.options['ymax'] = ymax
ret = app_obj.app_obj.new_object('excellon', outname_exc, excellon_init)
if ret == 'fail':
app_obj.inform.emit('[ERROR_NOTCL] %s' % _("Mouse bites failed."))
self.app.worker_task.emit({'fcn': job_thread, 'params': [self.app]})
self.app.inform.emit('[success] %s' % _("Finished manual adding of gaps."))
def on_mouse_move(self, event):