- more work in the new Laser Mode in the Paint Tool
This commit is contained in:
@@ -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 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
|
- 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
|
14.02.2020
|
||||||
|
|
||||||
|
|||||||
72
camlib.py
72
camlib.py
@@ -1582,7 +1582,7 @@ class Geometry(object):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
# log.debug("camlib.fill_with_lines()")
|
# 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)))
|
log.debug("camlib.Geometry.fill_with_lines() --> Not a LineString/MultiLineString but %s" % str(type(line)))
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@@ -1596,10 +1596,10 @@ class Geometry(object):
|
|||||||
|
|
||||||
lines_trimmed = []
|
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:
|
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:
|
except Exception:
|
||||||
log.debug("camlib.Geometry.fill_with_lines() --> Could not buffer the Polygon, tool diameter too high")
|
log.debug("camlib.Geometry.fill_with_lines() --> Could not buffer the Polygon, tool diameter too high")
|
||||||
return None
|
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
|
# provide the app with a way to process the GUI events when in a blocking loop
|
||||||
QtWidgets.QApplication.processEvents()
|
QtWidgets.QApplication.processEvents()
|
||||||
|
|
||||||
line = line.parallel_offset(distance=delta, side='left', resolution=int(steps_per_circle))
|
new_line = line.parallel_offset(distance=delta, side='left', resolution=int(steps_per_circle))
|
||||||
line = line.intersection(margin_poly)
|
new_line = new_line.intersection(margin_poly)
|
||||||
lines_trimmed.append(line)
|
lines_trimmed.append(new_line)
|
||||||
|
|
||||||
line = line.parallel_offset(distance=delta, side='right', resolution=int(steps_per_circle))
|
new_line = line.parallel_offset(distance=delta, side='right', resolution=int(steps_per_circle))
|
||||||
line = line.intersection(margin_poly)
|
new_line = new_line.intersection(margin_poly)
|
||||||
lines_trimmed.append(line)
|
lines_trimmed.append(new_line)
|
||||||
|
|
||||||
delta += tooldia * (1 - overlap)
|
delta += tooldia * (1 - overlap)
|
||||||
if prog_plot:
|
if prog_plot:
|
||||||
self.plot_temp_shapes(line)
|
self.plot_temp_shapes(new_line)
|
||||||
self.temp_shapes.redraw()
|
self.temp_shapes.redraw()
|
||||||
|
|
||||||
# Last line
|
# 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))
|
new_line = line.parallel_offset(distance=delta, side='left', resolution=int(steps_per_circle))
|
||||||
line = line.intersection(margin_poly)
|
new_line = new_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)
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
log.debug('camlib.Geometry.fill_with_lines() Processing poly --> %s' % str(e))
|
log.debug('camlib.Geometry.fill_with_lines() Processing poly --> %s' % str(e))
|
||||||
return None
|
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:
|
if prog_plot:
|
||||||
self.temp_shapes.redraw()
|
self.temp_shapes.redraw()
|
||||||
|
|
||||||
@@ -3434,10 +3444,13 @@ class CNCjob(Geometry):
|
|||||||
self.f_plunge = self.app.defaults["geometry_f_plunge"]
|
self.f_plunge = self.app.defaults["geometry_f_plunge"]
|
||||||
|
|
||||||
if self.z_cut is None:
|
if self.z_cut is None:
|
||||||
|
if 'laser' not in self.pp_geometry_name:
|
||||||
self.app.inform.emit('[ERROR_NOTCL] %s' %
|
self.app.inform.emit('[ERROR_NOTCL] %s' %
|
||||||
_("Cut_Z parameter is None or zero. Most likely a bad combinations of "
|
_("Cut_Z parameter is None or zero. Most likely a bad combinations of "
|
||||||
"other parameters."))
|
"other parameters."))
|
||||||
return 'fail'
|
return 'fail'
|
||||||
|
else:
|
||||||
|
self.z_cut = 0
|
||||||
|
|
||||||
if self.machinist_setting == 0:
|
if self.machinist_setting == 0:
|
||||||
if self.z_cut > 0:
|
if self.z_cut > 0:
|
||||||
@@ -3448,7 +3461,7 @@ class CNCjob(Geometry):
|
|||||||
"therefore the app will convert the value to negative."
|
"therefore the app will convert the value to negative."
|
||||||
"Check the resulting CNC code (Gcode etc)."))
|
"Check the resulting CNC code (Gcode etc)."))
|
||||||
self.z_cut = -self.z_cut
|
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' %
|
self.app.inform.emit('[WARNING] %s: %s' %
|
||||||
(_("The Cut Z parameter is zero. There will be no cut, skipping file"),
|
(_("The Cut Z parameter is zero. There will be no cut, skipping file"),
|
||||||
self.options['name']))
|
self.options['name']))
|
||||||
@@ -3793,11 +3806,14 @@ class CNCjob(Geometry):
|
|||||||
|
|
||||||
if self.machinist_setting == 0:
|
if self.machinist_setting == 0:
|
||||||
if self.z_cut is None:
|
if self.z_cut is None:
|
||||||
|
if 'laser' not in self.pp_geometry_name:
|
||||||
self.app.inform.emit(
|
self.app.inform.emit(
|
||||||
'[ERROR_NOTCL] %s' % _("Cut_Z parameter is None or zero. Most likely a bad combinations of "
|
'[ERROR_NOTCL] %s' % _("Cut_Z parameter is None or zero. Most likely a bad combinations of "
|
||||||
"other parameters.")
|
"other parameters.")
|
||||||
)
|
)
|
||||||
return 'fail'
|
return 'fail'
|
||||||
|
else:
|
||||||
|
self.z_cut = 0.0
|
||||||
|
|
||||||
if self.z_cut > 0:
|
if self.z_cut > 0:
|
||||||
self.app.inform.emit('[WARNING] %s' %
|
self.app.inform.emit('[WARNING] %s' %
|
||||||
@@ -3807,7 +3823,7 @@ class CNCjob(Geometry):
|
|||||||
"therefore the app will convert the value to negative."
|
"therefore the app will convert the value to negative."
|
||||||
"Check the resulting CNC code (Gcode etc)."))
|
"Check the resulting CNC code (Gcode etc)."))
|
||||||
self.z_cut = -self.z_cut
|
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(
|
self.app.inform.emit(
|
||||||
'[WARNING] %s: %s' % (_("The Cut Z parameter is zero. There will be no cut, skipping file"),
|
'[WARNING] %s: %s' % (_("The Cut Z parameter is zero. There will be no cut, skipping file"),
|
||||||
geometry.options['name'])
|
geometry.options['name'])
|
||||||
|
|||||||
@@ -13,12 +13,12 @@ from copy import deepcopy
|
|||||||
# from ObjectCollection import *
|
# from ObjectCollection import *
|
||||||
from flatcamParsers.ParseGerber import Gerber
|
from flatcamParsers.ParseGerber import Gerber
|
||||||
from FlatCAMObj import FlatCAMGerber, FlatCAMGeometry
|
from FlatCAMObj import FlatCAMGerber, FlatCAMGeometry
|
||||||
from camlib import Geometry
|
from camlib import Geometry, FlatCAMRTreeStorage
|
||||||
from flatcamGUI.GUIElements import FCTable, FCDoubleSpinner, FCCheckBox, FCInputDialog, RadioSet, FCButton
|
from flatcamGUI.GUIElements import FCTable, FCDoubleSpinner, FCCheckBox, FCInputDialog, RadioSet, FCButton
|
||||||
import FlatCAMApp
|
import FlatCAMApp
|
||||||
|
|
||||||
from shapely.geometry import base, Polygon, MultiPolygon, LinearRing, Point
|
from shapely.geometry import base, Polygon, MultiPolygon, LinearRing, Point, MultiLineString
|
||||||
from shapely.ops import cascaded_union
|
from shapely.ops import cascaded_union, unary_union, linemerge
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import math
|
import math
|
||||||
@@ -447,7 +447,6 @@ class ToolPaint(FlatCAMTool, Gerber):
|
|||||||
)
|
)
|
||||||
grid4.addWidget(self.rest_cb, 16, 0, 1, 2)
|
grid4.addWidget(self.rest_cb, 16, 0, 1, 2)
|
||||||
|
|
||||||
|
|
||||||
# Laser Mode
|
# Laser Mode
|
||||||
self.laser_cb = FCCheckBox(_("Laser Mode"))
|
self.laser_cb = FCCheckBox(_("Laser Mode"))
|
||||||
self.laser_cb.setToolTip(
|
self.laser_cb.setToolTip(
|
||||||
@@ -681,6 +680,7 @@ class ToolPaint(FlatCAMTool, Gerber):
|
|||||||
|
|
||||||
def run(self, toggle=True):
|
def run(self, toggle=True):
|
||||||
self.app.report_usage("ToolPaint()")
|
self.app.report_usage("ToolPaint()")
|
||||||
|
log.debug("ToolPaint().run() was launched ...")
|
||||||
|
|
||||||
if toggle:
|
if toggle:
|
||||||
# if the splitter is hidden, display it, else hide it but only if the current widget is the same
|
# 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)
|
self.blockSignals(True)
|
||||||
|
|
||||||
row = self.tools_table.currentRow()
|
# row = self.tools_table.currentRow()
|
||||||
if row < 0:
|
# if row < 0:
|
||||||
row = 0
|
# row = 0
|
||||||
|
|
||||||
# this new dict will hold the actual useful data, another dict that is the value of key 'data'
|
# this new dict will hold the actual useful data, another dict that is the value of key 'data'
|
||||||
temp_tools = {}
|
temp_tools = {}
|
||||||
@@ -952,32 +952,8 @@ class ToolPaint(FlatCAMTool, Gerber):
|
|||||||
self.tools_frame.show()
|
self.tools_frame.show()
|
||||||
self.reset_fields()
|
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.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
|
# updated units
|
||||||
self.units = self.app.defaults['units'].upper()
|
self.units = self.app.defaults['units'].upper()
|
||||||
|
|
||||||
@@ -1020,6 +996,30 @@ class ToolPaint(FlatCAMTool, Gerber):
|
|||||||
"paintrest": self.app.defaults["tools_paintrest"],
|
"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:
|
try:
|
||||||
diameters = [float(self.app.defaults["tools_painttooldia"])]
|
diameters = [float(self.app.defaults["tools_painttooldia"])]
|
||||||
except (ValueError, TypeError):
|
except (ValueError, TypeError):
|
||||||
@@ -1718,7 +1718,7 @@ class ToolPaint(FlatCAMTool, Gerber):
|
|||||||
polygon_list = None
|
polygon_list = None
|
||||||
if inside_pt and poly_list is None:
|
if inside_pt and poly_list is None:
|
||||||
polygon_list = [self.find_polygon(point=inside_pt, geoset=obj.solid_geometry)]
|
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
|
polygon_list = poly_list
|
||||||
|
|
||||||
# No polygon?
|
# No polygon?
|
||||||
@@ -1797,34 +1797,152 @@ class ToolPaint(FlatCAMTool, Gerber):
|
|||||||
connect=conn,
|
connect=conn,
|
||||||
prog_plot=prog_plot)
|
prog_plot=prog_plot)
|
||||||
elif paint_method == "laser_lines":
|
elif paint_method == "laser_lines":
|
||||||
line = None
|
# line = None
|
||||||
aperture_size = 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 apid, apval in obj.apertures.items():
|
||||||
for geo_el in apval['geometry']:
|
for geo_el in apval['geometry']:
|
||||||
if 'solid' in geo_el:
|
if apval["size"] == 0.0:
|
||||||
if Point(inside_pt).within(geo_el['solid']):
|
if apval["size"] in traces_el_dict:
|
||||||
if not isinstance(geo_el['follow'], Point):
|
traces_el_dict[apval["size"]].append(geo_el)
|
||||||
line = geo_el['follow']
|
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']
|
aperture_size = apval['size']
|
||||||
|
|
||||||
|
if aperture_size in traces_el_dict:
|
||||||
|
traces_el_dict[aperture_size].append(geo_el)
|
||||||
else:
|
else:
|
||||||
if apval['width'] > apval['height']:
|
traces_el_dict[aperture_size] = [geo_el]
|
||||||
aperture_size = apval['height']
|
|
||||||
else:
|
cpoly = FlatCAMRTreeStorage()
|
||||||
aperture_size = apval['width']
|
pads_lines_list = list()
|
||||||
print(line, aperture_size)
|
|
||||||
if line:
|
# process the flashes found in the selected polygon with the 'lines' method for rectangular
|
||||||
cpoly = self.fill_with_lines(line, aperture_size,
|
# 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,
|
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,
|
overlap=over,
|
||||||
contour=cont,
|
contour=cont,
|
||||||
connect=conn,
|
connect=conn,
|
||||||
prog_plot=prog_plot)
|
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":
|
elif paint_method == "combo":
|
||||||
self.app.inform.emit(_("Painting polygon with method: lines."))
|
self.app.inform.emit(_("Painting polygon with method: lines."))
|
||||||
cpoly = self.clear_polygon3(polyg,
|
cpoly = self.clear_polygon3(polyg,
|
||||||
@@ -2225,6 +2343,132 @@ class ToolPaint(FlatCAMTool, Gerber):
|
|||||||
contour=cont,
|
contour=cont,
|
||||||
connect=conn,
|
connect=conn,
|
||||||
prog_plot=prog_plot)
|
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":
|
elif paint_method == "combo":
|
||||||
self.app.inform.emit(_("Painting polygons with method: lines."))
|
self.app.inform.emit(_("Painting polygons with method: lines."))
|
||||||
cp = self.clear_polygon3(pol,
|
cp = self.clear_polygon3(pol,
|
||||||
@@ -2301,6 +2545,132 @@ class ToolPaint(FlatCAMTool, Gerber):
|
|||||||
contour=cont,
|
contour=cont,
|
||||||
connect=conn,
|
connect=conn,
|
||||||
prog_plot=prog_plot)
|
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":
|
elif paint_method == "combo":
|
||||||
self.app.inform.emit(_("Painting polygons with method: lines."))
|
self.app.inform.emit(_("Painting polygons with method: lines."))
|
||||||
cp = self.clear_polygon3(poly_buf,
|
cp = self.clear_polygon3(poly_buf,
|
||||||
@@ -2553,6 +2923,132 @@ class ToolPaint(FlatCAMTool, Gerber):
|
|||||||
steps_per_circle=self.app.defaults["geometry_circle_steps"],
|
steps_per_circle=self.app.defaults["geometry_circle_steps"],
|
||||||
overlap=over, contour=cont, connect=conn,
|
overlap=over, contour=cont, connect=conn,
|
||||||
prog_plot=prog_plot)
|
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":
|
elif paint_method == "combo":
|
||||||
self.app.inform.emit(_("Painting polygons with method: lines."))
|
self.app.inform.emit(_("Painting polygons with method: lines."))
|
||||||
cp = self.clear_polygon3(poly_buf,
|
cp = self.clear_polygon3(poly_buf,
|
||||||
@@ -2907,6 +3403,132 @@ class ToolPaint(FlatCAMTool, Gerber):
|
|||||||
contour=cont,
|
contour=cont,
|
||||||
connect=conn,
|
connect=conn,
|
||||||
prog_plot=prog_plot)
|
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":
|
elif paint_method == "combo":
|
||||||
self.app.inform.emit(_("Painting polygons with method: lines."))
|
self.app.inform.emit(_("Painting polygons with method: lines."))
|
||||||
cp = self.clear_polygon3(poly_buf,
|
cp = self.clear_polygon3(poly_buf,
|
||||||
@@ -3101,12 +3723,137 @@ class ToolPaint(FlatCAMTool, Gerber):
|
|||||||
steps_per_circle=self.app.defaults["geometry_circle_steps"],
|
steps_per_circle=self.app.defaults["geometry_circle_steps"],
|
||||||
overlap=over, contour=cont, connect=conn,
|
overlap=over, contour=cont, connect=conn,
|
||||||
prog_plot=prog_plot)
|
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":
|
elif paint_method == "combo":
|
||||||
self.app.inform.emit(_("Painting polygons with method: lines."))
|
self.app.inform.emit(_("Painting polygons with method: lines."))
|
||||||
cp = self.clear_polygon3(poly_buf,
|
cp = self.clear_polygon3(poly_buf,
|
||||||
tooldia=tool_dia,
|
tooldia=tool_dia,
|
||||||
steps_per_circle=self.app.defaults[
|
steps_per_circle=self.app.defaults["geometry_circle_steps"],
|
||||||
"geometry_circle_steps"],
|
|
||||||
overlap=over,
|
overlap=over,
|
||||||
contour=cont,
|
contour=cont,
|
||||||
connect=conn,
|
connect=conn,
|
||||||
|
|||||||
Reference in New Issue
Block a user