- more work in the new Laser Mode in the Paint Tool

This commit is contained in:
Marius Stanciu 2020-02-15 21:11:06 +02:00 committed by Marius
parent d24290a2b6
commit 25c9a31179
3 changed files with 930 additions and 166 deletions

View File

@ -13,6 +13,7 @@ CAD program, and create G-Code for Isolation routing.
- in Paint Tool added a new method of painting named Combo who will pass through all the methods until the polygon is cleared
- in Paint Tool attempting to add a new mode suitable for Laser usage
- more work in the new Laser Mode in the Paint Tool
14.02.2020

View File

@ -1582,7 +1582,7 @@ class Geometry(object):
"""
# log.debug("camlib.fill_with_lines()")
if not isinstance(line, LineString) or not isinstance(line, MultiLineString):
if not isinstance(line, LineString) and not isinstance(line, MultiLineString):
log.debug("camlib.Geometry.fill_with_lines() --> Not a LineString/MultiLineString but %s" % str(type(line)))
return None
@ -1596,10 +1596,10 @@ class Geometry(object):
lines_trimmed = []
polygon = line.buffer(aperture_size / 1.99999999999999999, int(steps_per_circle))
polygon = line.buffer(aperture_size / 2.0, int(steps_per_circle))
try:
margin_poly = polygon.buffer(-tooldia / 1.99999999, int(steps_per_circle))
margin_poly = polygon.buffer(-tooldia / 2.0, int(steps_per_circle))
except Exception:
log.debug("camlib.Geometry.fill_with_lines() --> Could not buffer the Polygon, tool diameter too high")
return None
@ -1615,41 +1615,51 @@ class Geometry(object):
# provide the app with a way to process the GUI events when in a blocking loop
QtWidgets.QApplication.processEvents()
line = line.parallel_offset(distance=delta, side='left', resolution=int(steps_per_circle))
line = line.intersection(margin_poly)
lines_trimmed.append(line)
new_line = line.parallel_offset(distance=delta, side='left', resolution=int(steps_per_circle))
new_line = new_line.intersection(margin_poly)
lines_trimmed.append(new_line)
line = line.parallel_offset(distance=delta, side='right', resolution=int(steps_per_circle))
line = line.intersection(margin_poly)
lines_trimmed.append(line)
new_line = line.parallel_offset(distance=delta, side='right', resolution=int(steps_per_circle))
new_line = new_line.intersection(margin_poly)
lines_trimmed.append(new_line)
delta += tooldia * (1 - overlap)
if prog_plot:
self.plot_temp_shapes(line)
self.plot_temp_shapes(new_line)
self.temp_shapes.redraw()
# Last line
delta = aperture_size / 2
delta = (aperture_size / 2) - (tooldia / 2.00000001)
line = line.parallel_offset(distance=delta, side='left', resolution=int(steps_per_circle))
line = line.intersection(margin_poly)
for ll in line:
lines_trimmed.append(ll)
if prog_plot:
self.plot_temp_shapes(line)
line = line.parallel_offset(distance=delta, side='left', resolution=int(steps_per_circle))
line = line.intersection(margin_poly)
for ll in line:
lines_trimmed.append(ll)
if prog_plot:
self.plot_temp_shapes(line)
new_line = line.parallel_offset(distance=delta, side='left', resolution=int(steps_per_circle))
new_line = new_line.intersection(margin_poly)
except Exception as e:
log.debug('camlib.Geometry.fill_with_lines() Processing poly --> %s' % str(e))
return None
try:
for ll in new_line:
lines_trimmed.append(ll)
if prog_plot:
self.plot_temp_shapes(ll)
except TypeError:
lines_trimmed.append(new_line)
if prog_plot:
self.plot_temp_shapes(new_line)
new_line = line.parallel_offset(distance=delta, side='right', resolution=int(steps_per_circle))
new_line = new_line.intersection(margin_poly)
try:
for ll in new_line:
lines_trimmed.append(ll)
if prog_plot:
self.plot_temp_shapes(ll)
except TypeError:
lines_trimmed.append(new_line)
if prog_plot:
self.plot_temp_shapes(new_line)
if prog_plot:
self.temp_shapes.redraw()
@ -3434,10 +3444,13 @@ class CNCjob(Geometry):
self.f_plunge = self.app.defaults["geometry_f_plunge"]
if self.z_cut is None:
if 'laser' not in self.pp_geometry_name:
self.app.inform.emit('[ERROR_NOTCL] %s' %
_("Cut_Z parameter is None or zero. Most likely a bad combinations of "
"other parameters."))
return 'fail'
else:
self.z_cut = 0
if self.machinist_setting == 0:
if self.z_cut > 0:
@ -3448,7 +3461,7 @@ class CNCjob(Geometry):
"therefore the app will convert the value to negative."
"Check the resulting CNC code (Gcode etc)."))
self.z_cut = -self.z_cut
elif self.z_cut == 0:
elif self.z_cut == 0 and 'laser' not in self.pp_geometry_name:
self.app.inform.emit('[WARNING] %s: %s' %
(_("The Cut Z parameter is zero. There will be no cut, skipping file"),
self.options['name']))
@ -3793,11 +3806,14 @@ class CNCjob(Geometry):
if self.machinist_setting == 0:
if self.z_cut is None:
if 'laser' not in self.pp_geometry_name:
self.app.inform.emit(
'[ERROR_NOTCL] %s' % _("Cut_Z parameter is None or zero. Most likely a bad combinations of "
"other parameters.")
)
return 'fail'
else:
self.z_cut = 0.0
if self.z_cut > 0:
self.app.inform.emit('[WARNING] %s' %
@ -3807,7 +3823,7 @@ class CNCjob(Geometry):
"therefore the app will convert the value to negative."
"Check the resulting CNC code (Gcode etc)."))
self.z_cut = -self.z_cut
elif self.z_cut == 0:
elif self.z_cut == 0 and 'laser' not in self.pp_geometry_name:
self.app.inform.emit(
'[WARNING] %s: %s' % (_("The Cut Z parameter is zero. There will be no cut, skipping file"),
geometry.options['name'])

View File

@ -13,12 +13,12 @@ from copy import deepcopy
# from ObjectCollection import *
from flatcamParsers.ParseGerber import Gerber
from FlatCAMObj import FlatCAMGerber, FlatCAMGeometry
from camlib import Geometry
from camlib import Geometry, FlatCAMRTreeStorage
from flatcamGUI.GUIElements import FCTable, FCDoubleSpinner, FCCheckBox, FCInputDialog, RadioSet, FCButton
import FlatCAMApp
from shapely.geometry import base, Polygon, MultiPolygon, LinearRing, Point
from shapely.ops import cascaded_union
from shapely.geometry import base, Polygon, MultiPolygon, LinearRing, Point, MultiLineString
from shapely.ops import cascaded_union, unary_union, linemerge
import numpy as np
import math
@ -447,7 +447,6 @@ class ToolPaint(FlatCAMTool, Gerber):
)
grid4.addWidget(self.rest_cb, 16, 0, 1, 2)
# Laser Mode
self.laser_cb = FCCheckBox(_("Laser Mode"))
self.laser_cb.setToolTip(
@ -681,6 +680,7 @@ class ToolPaint(FlatCAMTool, Gerber):
def run(self, toggle=True):
self.app.report_usage("ToolPaint()")
log.debug("ToolPaint().run() was launched ...")
if toggle:
# if the splitter is hidden, display it, else hide it but only if the current widget is the same
@ -795,9 +795,9 @@ class ToolPaint(FlatCAMTool, Gerber):
self.blockSignals(True)
row = self.tools_table.currentRow()
if row < 0:
row = 0
# row = self.tools_table.currentRow()
# if row < 0:
# row = 0
# this new dict will hold the actual useful data, another dict that is the value of key 'data'
temp_tools = {}
@ -952,32 +952,8 @@ class ToolPaint(FlatCAMTool, Gerber):
self.tools_frame.show()
self.reset_fields()
# ## Init the GUI interface
self.order_radio.set_value(self.app.defaults["tools_paintorder"])
self.paintmargin_entry.set_value(self.app.defaults["tools_paintmargin"])
self.paintmethod_combo.set_value(self.app.defaults["tools_paintmethod"])
self.selectmethod_combo.set_value(self.app.defaults["tools_selectmethod"])
self.pathconnect_cb.set_value(self.app.defaults["tools_pathconnect"])
self.paintcontour_cb.set_value(self.app.defaults["tools_paintcontour"])
self.paintoverlap_entry.set_value(self.app.defaults["tools_paintoverlap"])
self.cutz_entry.set_value(self.app.defaults["tools_paintcutz"])
self.tool_type_radio.set_value(self.app.defaults["tools_painttool_type"])
self.tipdia_entry.set_value(self.app.defaults["tools_painttipdia"])
self.tipangle_entry.set_value(self.app.defaults["tools_painttipangle"])
self.addtool_entry.set_value(self.app.defaults["tools_paintnewdia"])
self.rest_cb.set_value(self.app.defaults["tools_paintrest"])
self.old_tool_dia = self.app.defaults["tools_paintnewdia"]
self.on_tool_type(val=self.tool_type_radio.get_value())
# make the default object type, "Geometry"
self.type_obj_combo.setCurrentIndex(2)
# make the Laser Mode disabled because the Geometry object is default
self.laser_cb.setEnabled(False)
# updated units
self.units = self.app.defaults['units'].upper()
@ -1020,6 +996,30 @@ class ToolPaint(FlatCAMTool, Gerber):
"paintrest": self.app.defaults["tools_paintrest"],
})
# ## Init the GUI interface
self.order_radio.set_value(self.app.defaults["tools_paintorder"])
self.paintmargin_entry.set_value(self.app.defaults["tools_paintmargin"])
self.paintmethod_combo.set_value(self.app.defaults["tools_paintmethod"])
self.selectmethod_combo.set_value(self.app.defaults["tools_selectmethod"])
self.pathconnect_cb.set_value(self.app.defaults["tools_pathconnect"])
self.paintcontour_cb.set_value(self.app.defaults["tools_paintcontour"])
self.paintoverlap_entry.set_value(self.app.defaults["tools_paintoverlap"])
self.cutz_entry.set_value(self.app.defaults["tools_paintcutz"])
self.tool_type_radio.set_value(self.app.defaults["tools_painttool_type"])
self.tipdia_entry.set_value(self.app.defaults["tools_painttipdia"])
self.tipangle_entry.set_value(self.app.defaults["tools_painttipangle"])
self.addtool_entry.set_value(self.app.defaults["tools_paintnewdia"])
self.rest_cb.set_value(self.app.defaults["tools_paintrest"])
self.on_tool_type(val=self.tool_type_radio.get_value())
# make the default object type, "Geometry"
self.type_obj_combo.setCurrentIndex(2)
# make the Laser Mode disabled because the Geometry object is default
self.laser_cb.setEnabled(False)
try:
diameters = [float(self.app.defaults["tools_painttooldia"])]
except (ValueError, TypeError):
@ -1718,7 +1718,7 @@ class ToolPaint(FlatCAMTool, Gerber):
polygon_list = None
if inside_pt and poly_list is None:
polygon_list = [self.find_polygon(point=inside_pt, geoset=obj.solid_geometry)]
elif inside_pt is None and poly_list:
elif (inside_pt is None and poly_list) or (inside_pt and poly_list):
polygon_list = poly_list
# No polygon?
@ -1797,34 +1797,152 @@ class ToolPaint(FlatCAMTool, Gerber):
connect=conn,
prog_plot=prog_plot)
elif paint_method == "laser_lines":
line = None
aperture_size = None
# line = None
# aperture_size = None
# determine the Gerber follow line
# the key is the aperture type and the val is a list of geo elements
flash_el_dict = dict()
# the key is the aperture size, the val is a list of geo elements
traces_el_dict = dict()
# find the flashes and the lines that are in the selected polygon and store them separately
for apid, apval in obj.apertures.items():
for geo_el in apval['geometry']:
if 'solid' in geo_el:
if Point(inside_pt).within(geo_el['solid']):
if not isinstance(geo_el['follow'], Point):
line = geo_el['follow']
if apval["size"] == 0.0:
if apval["size"] in traces_el_dict:
traces_el_dict[apval["size"]].append(geo_el)
else:
traces_el_dict[apval["size"]] = [geo_el]
if apval['type'] == 'C':
if 'follow' in geo_el and geo_el['follow'].within(polyg):
if isinstance(geo_el['follow'], Point):
if apval["type"] == 'C':
if 'C' in flash_el_dict:
flash_el_dict['C'].append(geo_el)
else:
flash_el_dict['C'] = [geo_el]
elif apval["type"] == 'O':
if 'O' in flash_el_dict:
flash_el_dict['O'].append(geo_el)
else:
flash_el_dict['O'] = [geo_el]
elif apval["type"] == 'R':
if 'R' in flash_el_dict:
flash_el_dict['R'].append(geo_el)
else:
flash_el_dict['R'] = [geo_el]
else:
aperture_size = apval['size']
if aperture_size in traces_el_dict:
traces_el_dict[aperture_size].append(geo_el)
else:
if apval['width'] > apval['height']:
aperture_size = apval['height']
else:
aperture_size = apval['width']
print(line, aperture_size)
if line:
cpoly = self.fill_with_lines(line, aperture_size,
traces_el_dict[aperture_size] = [geo_el]
cpoly = FlatCAMRTreeStorage()
pads_lines_list = list()
# process the flashes found in the selected polygon with the 'lines' method for rectangular
# flashes and with 'seed' for oblong and circular flashes
# and pads (flahes) need the contour therefore I override the GUI settings with always True
for ap_type in flash_el_dict:
for elem in flash_el_dict[ap_type]:
if 'solid' in elem:
if ap_type == 'C':
f_o = self.clear_polygon2(elem['solid'],
tooldia=tooldiameter,
steps_per_circle=self.app.defaults["geometry_circle_steps"],
steps_per_circle=self.app.defaults[
"geometry_circle_steps"],
overlap=over,
contour=True,
connect=conn,
prog_plot=prog_plot)
pads_lines_list += [p for p in f_o.get_objects() if p]
elif ap_type == 'O':
f_o = self.clear_polygon2(elem['solid'],
tooldia=tooldiameter,
steps_per_circle=self.app.defaults[
"geometry_circle_steps"],
overlap=over,
contour=True,
connect=conn,
prog_plot=prog_plot)
pads_lines_list += [p for p in f_o.get_objects() if p]
elif ap_type == 'R':
f_o = self.clear_polygon3(elem['solid'],
tooldia=tooldiameter,
steps_per_circle=self.app.defaults[
"geometry_circle_steps"],
overlap=over,
contour=True,
connect=conn,
prog_plot=prog_plot)
pads_lines_list += [p for p in f_o.get_objects() if p]
# add the lines from pads to the storage
try:
for lin in pads_lines_list:
if lin:
cpoly.insert(lin)
except TypeError:
cpoly.insert(pads_lines_list)
copper_lines_list = list()
# process the traces found in the selected polygon using the 'laser_lines' method,
# method which will follow the 'follow' line therefore use the longer path possible for the
# laser, therefore the acceleration will play a smaller factor
for aperture_size in traces_el_dict:
for elem in traces_el_dict[aperture_size]:
line = elem['follow']
if line:
t_o = self.fill_with_lines(line, aperture_size,
tooldia=tooldiameter,
steps_per_circle=self.app.defaults[
"geometry_circle_steps"],
overlap=over,
contour=cont,
connect=conn,
prog_plot=prog_plot)
copper_lines_list += [p for p in t_o.get_objects() if p]
# add the lines from copper features to storage but first try to make as few lines as possible
# by trying to fuse them
lines_union = linemerge(unary_union(copper_lines_list))
try:
for lin in lines_union:
if lin:
cpoly.insert(lin)
except TypeError:
cpoly.insert(lines_union)
# # determine the Gerber follow line
# for apid, apval in obj.apertures.items():
# for geo_el in apval['geometry']:
# if 'solid' in geo_el:
# if Point(inside_pt).within(geo_el['solid']):
# if not isinstance(geo_el['follow'], Point):
# line = geo_el['follow']
#
# if apval['type'] == 'C':
# aperture_size = apval['size']
# else:
# if apval['width'] > apval['height']:
# aperture_size = apval['height']
# else:
# aperture_size = apval['width']
#
# if line:
# cpoly = self.fill_with_lines(line, aperture_size,
# tooldia=tooldiameter,
# steps_per_circle=self.app.defaults["geometry_circle_steps"],
# overlap=over,
# contour=cont,
# connect=conn,
# prog_plot=prog_plot)
elif paint_method == "combo":
self.app.inform.emit(_("Painting polygon with method: lines."))
cpoly = self.clear_polygon3(polyg,
@ -2225,6 +2343,132 @@ class ToolPaint(FlatCAMTool, Gerber):
contour=cont,
connect=conn,
prog_plot=prog_plot)
elif paint_method == "laser_lines":
# line = None
# aperture_size = None
# the key is the aperture type and the val is a list of geo elements
flash_el_dict = dict()
# the key is the aperture size, the val is a list of geo elements
traces_el_dict = dict()
# find the flashes and the lines that are in the selected polygon and store
# them separately
for apid, apval in obj.apertures.items():
for geo_el in apval['geometry']:
if apval["size"] == 0.0:
if apval["size"] in traces_el_dict:
traces_el_dict[apval["size"]].append(geo_el)
else:
traces_el_dict[apval["size"]] = [geo_el]
if 'follow' in geo_el and geo_el['follow'].within(pol):
if isinstance(geo_el['follow'], Point):
if apval["type"] == 'C':
if 'C' in flash_el_dict:
flash_el_dict['C'].append(geo_el)
else:
flash_el_dict['C'] = [geo_el]
elif apval["type"] == 'O':
if 'O' in flash_el_dict:
flash_el_dict['O'].append(geo_el)
else:
flash_el_dict['O'] = [geo_el]
elif apval["type"] == 'R':
if 'R' in flash_el_dict:
flash_el_dict['R'].append(geo_el)
else:
flash_el_dict['R'] = [geo_el]
else:
aperture_size = apval['size']
if aperture_size in traces_el_dict:
traces_el_dict[aperture_size].append(geo_el)
else:
traces_el_dict[aperture_size] = [geo_el]
cp = FlatCAMRTreeStorage()
pads_lines_list = list()
# process the flashes found in the selected polygon with the 'lines' method
# for rectangular flashes and with 'seed' for oblong and circular flashes
# and pads (flahes) need the contour therefore I override the GUI settings
# with always True
for ap_type in flash_el_dict:
for elem in flash_el_dict[ap_type]:
if 'solid' in elem:
if ap_type == 'C':
f_o = self.clear_polygon2(elem['solid'],
tooldia=tool_dia,
steps_per_circle=self.app.defaults[
"geometry_circle_steps"],
overlap=over,
contour=True,
connect=conn,
prog_plot=prog_plot)
pads_lines_list += [p for p in f_o.get_objects() if p]
elif ap_type == 'O':
f_o = self.clear_polygon2(elem['solid'],
tooldia=tool_dia,
steps_per_circle=self.app.defaults[
"geometry_circle_steps"],
overlap=over,
contour=True,
connect=conn,
prog_plot=prog_plot)
pads_lines_list += [p for p in f_o.get_objects() if p]
elif ap_type == 'R':
f_o = self.clear_polygon3(elem['solid'],
tooldia=tool_dia,
steps_per_circle=self.app.defaults[
"geometry_circle_steps"],
overlap=over,
contour=True,
connect=conn,
prog_plot=prog_plot)
pads_lines_list += [p for p in f_o.get_objects() if p]
# add the lines from pads to the storage
try:
for lin in pads_lines_list:
if lin:
cp.insert(lin)
except TypeError:
cp.insert(pads_lines_list)
copper_lines_list = list()
# process the traces found in the selected polygon using the 'laser_lines'
# method, method which will follow the 'follow' line therefore use the longer
# path possible for the laser, therefore the acceleration will play
# a smaller factor
for aperture_size in traces_el_dict:
for elem in traces_el_dict[aperture_size]:
line = elem['follow']
if line:
t_o = self.fill_with_lines(line, aperture_size,
tooldia=tool_dia,
steps_per_circle=self.app.defaults[
"geometry_circle_steps"],
overlap=over,
contour=cont,
connect=conn,
prog_plot=prog_plot)
copper_lines_list += [p for p in t_o.get_objects() if p]
# add the lines from copper features to storage but first try to make as few
# lines as possible
# by trying to fuse them
lines_union = linemerge(unary_union(copper_lines_list))
try:
for lin in lines_union:
if lin:
cp.insert(lin)
except TypeError:
cp.insert(lines_union)
elif paint_method == "combo":
self.app.inform.emit(_("Painting polygons with method: lines."))
cp = self.clear_polygon3(pol,
@ -2301,6 +2545,132 @@ class ToolPaint(FlatCAMTool, Gerber):
contour=cont,
connect=conn,
prog_plot=prog_plot)
elif paint_method == "laser_lines":
# line = None
# aperture_size = None
# the key is the aperture type and the val is a list of geo elements
flash_el_dict = dict()
# the key is the aperture size, the val is a list of geo elements
traces_el_dict = dict()
# find the flashes and the lines that are in the selected polygon and store
# them separately
for apid, apval in obj.apertures.items():
for geo_el in apval['geometry']:
if apval["size"] == 0.0:
if apval["size"] in traces_el_dict:
traces_el_dict[apval["size"]].append(geo_el)
else:
traces_el_dict[apval["size"]] = [geo_el]
if 'follow' in geo_el and geo_el['follow'].within(poly_buf):
if isinstance(geo_el['follow'], Point):
if apval["type"] == 'C':
if 'C' in flash_el_dict:
flash_el_dict['C'].append(geo_el)
else:
flash_el_dict['C'] = [geo_el]
elif apval["type"] == 'O':
if 'O' in flash_el_dict:
flash_el_dict['O'].append(geo_el)
else:
flash_el_dict['O'] = [geo_el]
elif apval["type"] == 'R':
if 'R' in flash_el_dict:
flash_el_dict['R'].append(geo_el)
else:
flash_el_dict['R'] = [geo_el]
else:
aperture_size = apval['size']
if aperture_size in traces_el_dict:
traces_el_dict[aperture_size].append(geo_el)
else:
traces_el_dict[aperture_size] = [geo_el]
cp = FlatCAMRTreeStorage()
pads_lines_list = list()
# process the flashes found in the selected polygon with the 'lines' method
# for rectangular flashes and with 'seed' for oblong and circular flashes
# and pads (flahes) need the contour therefore I override the GUI settings
# with always True
for ap_type in flash_el_dict:
for elem in flash_el_dict[ap_type]:
if 'solid' in elem:
if ap_type == 'C':
f_o = self.clear_polygon2(elem['solid'],
tooldia=tool_dia,
steps_per_circle=self.app.defaults[
"geometry_circle_steps"],
overlap=over,
contour=True,
connect=conn,
prog_plot=prog_plot)
pads_lines_list += [p for p in f_o.get_objects() if p]
elif ap_type == 'O':
f_o = self.clear_polygon2(elem['solid'],
tooldia=tool_dia,
steps_per_circle=self.app.defaults[
"geometry_circle_steps"],
overlap=over,
contour=True,
connect=conn,
prog_plot=prog_plot)
pads_lines_list += [p for p in f_o.get_objects() if p]
elif ap_type == 'R':
f_o = self.clear_polygon3(elem['solid'],
tooldia=tool_dia,
steps_per_circle=self.app.defaults[
"geometry_circle_steps"],
overlap=over,
contour=True,
connect=conn,
prog_plot=prog_plot)
pads_lines_list += [p for p in f_o.get_objects() if p]
# add the lines from pads to the storage
try:
for lin in pads_lines_list:
if lin:
cp.insert(lin)
except TypeError:
cp.insert(pads_lines_list)
copper_lines_list = list()
# process the traces found in the selected polygon using the 'laser_lines'
# method, method which will follow the 'follow' line therefore use the longer
# path possible for the laser, therefore the acceleration will play
# a smaller factor
for aperture_size in traces_el_dict:
for elem in traces_el_dict[aperture_size]:
line = elem['follow']
if line:
t_o = self.fill_with_lines(line, aperture_size,
tooldia=tool_dia,
steps_per_circle=self.app.defaults[
"geometry_circle_steps"],
overlap=over,
contour=cont,
connect=conn,
prog_plot=prog_plot)
copper_lines_list += [p for p in t_o.get_objects() if p]
# add the lines from copper features to storage but first try to make as few
# lines as possible
# by trying to fuse them
lines_union = linemerge(unary_union(copper_lines_list))
try:
for lin in lines_union:
if lin:
cp.insert(lin)
except TypeError:
cp.insert(lines_union)
elif paint_method == "combo":
self.app.inform.emit(_("Painting polygons with method: lines."))
cp = self.clear_polygon3(poly_buf,
@ -2553,6 +2923,132 @@ class ToolPaint(FlatCAMTool, Gerber):
steps_per_circle=self.app.defaults["geometry_circle_steps"],
overlap=over, contour=cont, connect=conn,
prog_plot=prog_plot)
elif paint_method == "laser_lines":
# line = None
# aperture_size = None
# the key is the aperture type and the val is a list of geo elements
flash_el_dict = dict()
# the key is the aperture size, the val is a list of geo elements
traces_el_dict = dict()
# find the flashes and the lines that are in the selected polygon and store
# them separately
for apid, apval in obj.apertures.items():
for geo_el in apval['geometry']:
if apval["size"] == 0.0:
if apval["size"] in traces_el_dict:
traces_el_dict[apval["size"]].append(geo_el)
else:
traces_el_dict[apval["size"]] = [geo_el]
if 'follow' in geo_el and geo_el['follow'].within(poly_buf):
if isinstance(geo_el['follow'], Point):
if apval["type"] == 'C':
if 'C' in flash_el_dict:
flash_el_dict['C'].append(geo_el)
else:
flash_el_dict['C'] = [geo_el]
elif apval["type"] == 'O':
if 'O' in flash_el_dict:
flash_el_dict['O'].append(geo_el)
else:
flash_el_dict['O'] = [geo_el]
elif apval["type"] == 'R':
if 'R' in flash_el_dict:
flash_el_dict['R'].append(geo_el)
else:
flash_el_dict['R'] = [geo_el]
else:
aperture_size = apval['size']
if aperture_size in traces_el_dict:
traces_el_dict[aperture_size].append(geo_el)
else:
traces_el_dict[aperture_size] = [geo_el]
cp = FlatCAMRTreeStorage()
pads_lines_list = list()
# process the flashes found in the selected polygon with the 'lines' method
# for rectangular flashes and with 'seed' for oblong and circular flashes
# and pads (flahes) need the contour therefore I override the GUI settings
# with always True
for ap_type in flash_el_dict:
for elem in flash_el_dict[ap_type]:
if 'solid' in elem:
if ap_type == 'C':
f_o = self.clear_polygon2(elem['solid'],
tooldia=tool_dia,
steps_per_circle=self.app.defaults[
"geometry_circle_steps"],
overlap=over,
contour=True,
connect=conn,
prog_plot=prog_plot)
pads_lines_list += [p for p in f_o.get_objects() if p]
elif ap_type == 'O':
f_o = self.clear_polygon2(elem['solid'],
tooldia=tool_dia,
steps_per_circle=self.app.defaults[
"geometry_circle_steps"],
overlap=over,
contour=True,
connect=conn,
prog_plot=prog_plot)
pads_lines_list += [p for p in f_o.get_objects() if p]
elif ap_type == 'R':
f_o = self.clear_polygon3(elem['solid'],
tooldia=tool_dia,
steps_per_circle=self.app.defaults[
"geometry_circle_steps"],
overlap=over,
contour=True,
connect=conn,
prog_plot=prog_plot)
pads_lines_list += [p for p in f_o.get_objects() if p]
# add the lines from pads to the storage
try:
for lin in pads_lines_list:
if lin:
cp.insert(lin)
except TypeError:
cp.insert(pads_lines_list)
copper_lines_list = list()
# process the traces found in the selected polygon using the 'laser_lines'
# method, method which will follow the 'follow' line therefore use the longer
# path possible for the laser, therefore the acceleration will play
# a smaller factor
for aperture_size in traces_el_dict:
for elem in traces_el_dict[aperture_size]:
line = elem['follow']
if line:
t_o = self.fill_with_lines(line, aperture_size,
tooldia=tool_dia,
steps_per_circle=self.app.defaults[
"geometry_circle_steps"],
overlap=over,
contour=cont,
connect=conn,
prog_plot=prog_plot)
copper_lines_list += [p for p in t_o.get_objects() if p]
# add the lines from copper features to storage but first try to make as few
# lines as possible
# by trying to fuse them
lines_union = linemerge(unary_union(copper_lines_list))
try:
for lin in lines_union:
if lin:
cp.insert(lin)
except TypeError:
cp.insert(lines_union)
elif paint_method == "combo":
self.app.inform.emit(_("Painting polygons with method: lines."))
cp = self.clear_polygon3(poly_buf,
@ -2907,6 +3403,132 @@ class ToolPaint(FlatCAMTool, Gerber):
contour=cont,
connect=conn,
prog_plot=prog_plot)
elif paint_method == "laser_lines":
# line = None
# aperture_size = None
# the key is the aperture type and the val is a list of geo elements
flash_el_dict = dict()
# the key is the aperture size, the val is a list of geo elements
traces_el_dict = dict()
# find the flashes and the lines that are in the selected polygon and store
# them separately
for apid, apval in obj.apertures.items():
for geo_el in apval['geometry']:
if apval["size"] == 0.0:
if apval["size"] in traces_el_dict:
traces_el_dict[apval["size"]].append(geo_el)
else:
traces_el_dict[apval["size"]] = [geo_el]
if 'follow' in geo_el and geo_el['follow'].within(poly_buf):
if isinstance(geo_el['follow'], Point):
if apval["type"] == 'C':
if 'C' in flash_el_dict:
flash_el_dict['C'].append(geo_el)
else:
flash_el_dict['C'] = [geo_el]
elif apval["type"] == 'O':
if 'O' in flash_el_dict:
flash_el_dict['O'].append(geo_el)
else:
flash_el_dict['O'] = [geo_el]
elif apval["type"] == 'R':
if 'R' in flash_el_dict:
flash_el_dict['R'].append(geo_el)
else:
flash_el_dict['R'] = [geo_el]
else:
aperture_size = apval['size']
if aperture_size in traces_el_dict:
traces_el_dict[aperture_size].append(geo_el)
else:
traces_el_dict[aperture_size] = [geo_el]
cp = FlatCAMRTreeStorage()
pads_lines_list = list()
# process the flashes found in the selected polygon with the 'lines' method
# for rectangular flashes and with 'seed' for oblong and circular flashes
# and pads (flahes) need the contour therefore I override the GUI settings
# with always True
for ap_type in flash_el_dict:
for elem in flash_el_dict[ap_type]:
if 'solid' in elem:
if ap_type == 'C':
f_o = self.clear_polygon2(elem['solid'],
tooldia=tool_dia,
steps_per_circle=self.app.defaults[
"geometry_circle_steps"],
overlap=over,
contour=True,
connect=conn,
prog_plot=prog_plot)
pads_lines_list += [p for p in f_o.get_objects() if p]
elif ap_type == 'O':
f_o = self.clear_polygon2(elem['solid'],
tooldia=tool_dia,
steps_per_circle=self.app.defaults[
"geometry_circle_steps"],
overlap=over,
contour=True,
connect=conn,
prog_plot=prog_plot)
pads_lines_list += [p for p in f_o.get_objects() if p]
elif ap_type == 'R':
f_o = self.clear_polygon3(elem['solid'],
tooldia=tool_dia,
steps_per_circle=self.app.defaults[
"geometry_circle_steps"],
overlap=over,
contour=True,
connect=conn,
prog_plot=prog_plot)
pads_lines_list += [p for p in f_o.get_objects() if p]
# add the lines from pads to the storage
try:
for lin in pads_lines_list:
if lin:
cp.insert(lin)
except TypeError:
cp.insert(pads_lines_list)
copper_lines_list = list()
# process the traces found in the selected polygon using the 'laser_lines'
# method, method which will follow the 'follow' line therefore use the longer
# path possible for the laser, therefore the acceleration will play
# a smaller factor
for aperture_size in traces_el_dict:
for elem in traces_el_dict[aperture_size]:
line = elem['follow']
if line:
t_o = self.fill_with_lines(line, aperture_size,
tooldia=tool_dia,
steps_per_circle=self.app.defaults[
"geometry_circle_steps"],
overlap=over,
contour=cont,
connect=conn,
prog_plot=prog_plot)
copper_lines_list += [p for p in t_o.get_objects() if p]
# add the lines from copper features to storage but first try to make as few
# lines as possible
# by trying to fuse them
lines_union = linemerge(unary_union(copper_lines_list))
try:
for lin in lines_union:
if lin:
cp.insert(lin)
except TypeError:
cp.insert(lines_union)
elif paint_method == "combo":
self.app.inform.emit(_("Painting polygons with method: lines."))
cp = self.clear_polygon3(poly_buf,
@ -3101,12 +3723,137 @@ class ToolPaint(FlatCAMTool, Gerber):
steps_per_circle=self.app.defaults["geometry_circle_steps"],
overlap=over, contour=cont, connect=conn,
prog_plot=prog_plot)
elif paint_method == "laser_lines":
# line = None
# aperture_size = None
# the key is the aperture type and the val is a list of geo elements
flash_el_dict = dict()
# the key is the aperture size, the val is a list of geo elements
copper_el_dict = dict()
# find the flashes and the lines that are in the selected polygon and store
# them separately
for apid, apval in obj.apertures.items():
for geo_el in apval['geometry']:
if apval["size"] == 0.0:
if apval["size"] in copper_el_dict:
copper_el_dict[apval["size"]].append(geo_el)
else:
copper_el_dict[apval["size"]] = [geo_el]
if 'follow' in geo_el and geo_el['follow'].within(poly_buf):
if isinstance(geo_el['follow'], Point):
if apval["type"] == 'C':
if 'C' in flash_el_dict:
flash_el_dict['C'].append(geo_el)
else:
flash_el_dict['C'] = [geo_el]
elif apval["type"] == 'O':
if 'O' in flash_el_dict:
flash_el_dict['O'].append(geo_el)
else:
flash_el_dict['O'] = [geo_el]
elif apval["type"] == 'R':
if 'R' in flash_el_dict:
flash_el_dict['R'].append(geo_el)
else:
flash_el_dict['R'] = [geo_el]
else:
aperture_size = apval['size']
if aperture_size in copper_el_dict:
copper_el_dict[aperture_size].append(geo_el)
else:
copper_el_dict[aperture_size] = [geo_el]
cp = FlatCAMRTreeStorage()
pads_lines_list = list()
# process the flashes found in the selected polygon with the 'lines' method
# for rectangular flashes and with 'seed' for oblong and circular flashes
# and pads (flahes) need the contour therefore I override the GUI settings
# with always True
for ap_type in flash_el_dict:
for elem in flash_el_dict[ap_type]:
if 'solid' in elem:
if ap_type == 'C':
f_o = self.clear_polygon2(elem['solid'],
tooldia=tool_dia,
steps_per_circle=self.app.defaults[
"geometry_circle_steps"],
overlap=over,
contour=True,
connect=conn,
prog_plot=prog_plot)
pads_lines_list += [p for p in f_o.get_objects() if p]
elif ap_type == 'O':
f_o = self.clear_polygon2(elem['solid'],
tooldia=tool_dia,
steps_per_circle=self.app.defaults[
"geometry_circle_steps"],
overlap=over,
contour=True,
connect=conn,
prog_plot=prog_plot)
pads_lines_list += [p for p in f_o.get_objects() if p]
elif ap_type == 'R':
f_o = self.clear_polygon3(elem['solid'],
tooldia=tool_dia,
steps_per_circle=self.app.defaults[
"geometry_circle_steps"],
overlap=over,
contour=True,
connect=conn,
prog_plot=prog_plot)
pads_lines_list += [p for p in f_o.get_objects() if p]
# add the lines from pads to the storage
try:
for lin in pads_lines_list:
if lin:
cp.insert(lin)
except TypeError:
cp.insert(pads_lines_list)
copper_lines_list = list()
# process the traces found in the selected polygon using the 'laser_lines'
# method, method which will follow the 'follow' line therefore use the longer
# path possible for the laser, therefore the acceleration will play
# a smaller factor
for aperture_size in copper_el_dict:
for elem in copper_el_dict[aperture_size]:
line = elem['follow']
if line:
t_o = self.fill_with_lines(line, aperture_size,
tooldia=tool_dia,
steps_per_circle=self.app.defaults[
"geometry_circle_steps"],
overlap=over,
contour=cont,
connect=conn,
prog_plot=prog_plot)
copper_lines_list += [p for p in t_o.get_objects() if p]
# add the lines from copper features to storage but first try to make as few
# lines as possible
# by trying to fuse them
lines_union = linemerge(unary_union(copper_lines_list))
try:
for lin in lines_union:
if lin:
cp.insert(lin)
except TypeError:
cp.insert(lines_union)
elif paint_method == "combo":
self.app.inform.emit(_("Painting polygons with method: lines."))
cp = self.clear_polygon3(poly_buf,
tooldia=tool_dia,
steps_per_circle=self.app.defaults[
"geometry_circle_steps"],
steps_per_circle=self.app.defaults["geometry_circle_steps"],
overlap=over,
contour=cont,
connect=conn,