- finished the Dots and Squares options in the Copper Thieving Tool

- working on the Lines option in Copper Thieving Tool
This commit is contained in:
Marius Stanciu
2019-11-18 17:44:52 +02:00
parent b41ecd87f8
commit 057ab93ef8
3 changed files with 124 additions and 23 deletions

View File

@@ -9,6 +9,11 @@ CAD program, and create G-Code for Isolation routing.
================================================= =================================================
18.11.2019
- finished the Dots and Squares options in the Copper Thieving Tool
- working on the Lines option in Copper Thieving Tool
17.11.2019 17.11.2019
- optimized the storage of the Gerber mark shapes by making them one layer only - optimized the storage of the Gerber mark shapes by making them one layer only

View File

@@ -16,6 +16,7 @@ import shapely.geometry.base as base
from shapely.ops import cascaded_union, unary_union from shapely.ops import cascaded_union, unary_union
from shapely.geometry import Polygon, MultiPolygon, Point from shapely.geometry import Polygon, MultiPolygon, Point
from shapely.geometry import box as box from shapely.geometry import box as box
import shapely.affinity as affinity
import logging import logging
from copy import deepcopy from copy import deepcopy
@@ -760,9 +761,10 @@ class ToolCopperThieving(FlatCAMTool):
env_obj = cascaded_union(geo_n) env_obj = cascaded_union(geo_n)
env_obj = env_obj.convex_hull env_obj = env_obj.convex_hull
else: else:
if isinstance(geo_n, Polygon) or \ if isinstance(geo_n, Polygon):
(isinstance(geo_n, list) and len(geo_n) == 1) or \ env_obj = geo_n.buffer(0, join_style=base.JOIN_STYLE.mitre).exterior
(isinstance(geo_n, MultiPolygon) and len(geo_n) == 1): elif isinstance(geo_n, list):
geo_n = unary_union(geo_n)
env_obj = geo_n.buffer(0, join_style=base.JOIN_STYLE.mitre).exterior env_obj = geo_n.buffer(0, join_style=base.JOIN_STYLE.mitre).exterior
elif isinstance(geo_n, MultiPolygon): elif isinstance(geo_n, MultiPolygon):
x0, y0, x1, y1 = geo_n.bounds x0, y0, x1, y1 = geo_n.bounds
@@ -797,7 +799,7 @@ class ToolCopperThieving(FlatCAMTool):
bounding_box = cascaded_union(geo_buff_list) bounding_box = cascaded_union(geo_buff_list)
elif ref_selected == 'box': else: # ref_selected == 'box'
geo_n = working_obj.solid_geometry geo_n = working_obj.solid_geometry
if isinstance(working_obj, FlatCAMGeometry): if isinstance(working_obj, FlatCAMGeometry):
@@ -831,15 +833,119 @@ class ToolCopperThieving(FlatCAMTool):
# ########## Generate filling geometry. ################################################### # ########## Generate filling geometry. ###################################################
# ######################################################################################### # #########################################################################################
if fill_type == 'solid': new_solid_geometry = bounding_box.difference(clearance_geometry)
new_solid_geometry = bounding_box.difference(clearance_geometry)
elif fill_type == 'dots': # determine the bounding box polygon for the entire Gerber object to which we add copper thieving
dot_geo = Point((0, 0)).buffer(dot_dia / 2.0) if isinstance(geo_n, list):
env_obj = unary_union(geo_n).buffer(distance=margin, join_style=base.JOIN_STYLE.mitre)
else:
env_obj = geo_n.buffer(distance=margin, join_style=base.JOIN_STYLE.mitre)
x0, y0, x1, y1 = env_obj.bounds
bounding_box = box(x0, y0, x1, y1)
if fill_type == 'dot' or fill_type == 'square':
# build the MultiPolygon of dots/squares that will fill the entire bounding box
thieving_list = list()
if fill_type == 'dot':
radius = dot_dia / 2.0
new_x = x0 + radius
new_y = y0 + radius
while new_x <= x1 - radius:
while new_y <= y1 - radius:
dot_geo = Point((new_x, new_y)).buffer(radius, resolution=64)
thieving_list.append(dot_geo)
new_y += dot_dia + dot_spacing
new_x += dot_dia + dot_spacing
new_y = y0 + radius
else:
h_size = square_size / 2.0
new_x = x0 + h_size
new_y = y0 + h_size
while new_x <= x1 - h_size:
while new_y <= y1 - h_size:
a, b, c, d = (Point((new_x, new_y)).buffer(h_size)).bounds
square_geo = box(a, b, c, d)
thieving_list.append(square_geo)
new_y += square_size + square_spacing
new_x += square_size + square_spacing
new_y = y0 + h_size
thieving_box_geo = MultiPolygon(thieving_list)
dx = bounding_box.centroid.x - thieving_box_geo.centroid.x
dy = bounding_box.centroid.y - thieving_box_geo.centroid.y
thieving_box_geo = affinity.translate(thieving_box_geo, xoff=dx, yoff=dy)
try: try:
for bb in bounding_box: _it = iter(new_solid_geometry)
pass
except TypeError: except TypeError:
pass new_solid_geometry = [new_solid_geometry]
try:
_it = iter(thieving_box_geo)
except TypeError:
thieving_box_geo = [thieving_box_geo]
thieving_geo = list()
for dot_geo in thieving_box_geo:
for geo_t in new_solid_geometry:
if dot_geo.within(geo_t):
thieving_geo.append(dot_geo)
new_solid_geometry = thieving_geo
if fill_type == 'line':
half_thick_line = line_size / 2.0
outline_geometry = []
try:
for pol in self.grb_object.solid_geometry:
if self.app.abort_flag:
# graceful abort requested by the user
raise FlatCAMApp.GracefulException
outline_geometry.append(
pol.buffer(c_val+half_thick_line, int(int(self.geo_steps_per_circle) / 4)).exterior
)
pol_nr += 1
disp_number = int(np.interp(pol_nr, [0, geo_len], [0, 100]))
if old_disp_number < disp_number <= 100:
self.app.proc_container.update_view_text(' %s ... %d%%' %
(_("Buffering"), int(disp_number)))
old_disp_number = disp_number
except TypeError:
# taking care of the case when the self.solid_geometry is just a single Polygon, not a list or a
# MultiPolygon (not an iterable)
outline_geometry.append(
self.grb_object.solid_geometry.buffer(
c_val+half_thick_line,
int(int(self.geo_steps_per_circle) / 4).exterior
)
)
self.app.proc_container.update_view_text(' %s' % _("Buffering"))
t = list()
for l in outline_geometry:
t.append(l.buffer(half_thick_line, resolution=int(int(self.geo_steps_per_circle) / 4)))
outline_geometry = unary_union(t)
try:
_it = iter(new_solid_geometry)
except TypeError:
new_solid_geometry = [new_solid_geometry]
# thieving_outlines = list()
# for geo_t in new_solid_geometry:
# for interior in geo_t.interiors:
# thieving_geo = interior.buffer(distance=half_thick_line)
#
# if thieving_geo.is_valid:
# thieving_outlines.append(thieving_geo)
new_solid_geometry = outline_geometry
geo_list = self.grb_object.solid_geometry geo_list = self.grb_object.solid_geometry
if isinstance(self.grb_object.solid_geometry, MultiPolygon): if isinstance(self.grb_object.solid_geometry, MultiPolygon):

View File

@@ -368,22 +368,12 @@ class DblSidedTool(FlatCAMTool):
xscale, yscale = {"X": (1.0, -1.0), "Y": (-1.0, 1.0)}[axis] xscale, yscale = {"X": (1.0, -1.0), "Y": (-1.0, 1.0)}[axis]
try: dia = float(self.drill_dia.get_value())
dia = float(self.drill_dia.get_value())
except ValueError:
# try to convert comma to decimal point. if it's still not working error message and return
try:
dia = float(self.drill_dia.get_value().replace(',', '.'))
self.drill_dia.set_value(dia)
except ValueError:
self.app.inform.emit('[WARNING_NOTCL] %s' % _("Tool diameter value is missing or wrong format. "
"Add it and retry."))
return
if dia is '': if dia is '':
self.app.inform.emit('[WARNING_NOTCL] %s' % self.app.inform.emit('[WARNING_NOTCL] %s' %
_("No value or wrong format in Drill Dia entry. Add it and retry.")) _("No value or wrong format in Drill Dia entry. Add it and retry."))
return return
tools = {"1": {"C": dia}} tools = {"1": {"C": dia}}
# holes = self.alignment_holes.get_value() # holes = self.alignment_holes.get_value()