- 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
- 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.geometry import Polygon, MultiPolygon, Point
from shapely.geometry import box as box
import shapely.affinity as affinity
import logging
from copy import deepcopy
@ -760,9 +761,10 @@ class ToolCopperThieving(FlatCAMTool):
env_obj = cascaded_union(geo_n)
env_obj = env_obj.convex_hull
else:
if isinstance(geo_n, Polygon) or \
(isinstance(geo_n, list) and len(geo_n) == 1) or \
(isinstance(geo_n, MultiPolygon) and len(geo_n) == 1):
if isinstance(geo_n, Polygon):
env_obj = geo_n.buffer(0, join_style=base.JOIN_STYLE.mitre).exterior
elif isinstance(geo_n, list):
geo_n = unary_union(geo_n)
env_obj = geo_n.buffer(0, join_style=base.JOIN_STYLE.mitre).exterior
elif isinstance(geo_n, MultiPolygon):
x0, y0, x1, y1 = geo_n.bounds
@ -797,7 +799,7 @@ class ToolCopperThieving(FlatCAMTool):
bounding_box = cascaded_union(geo_buff_list)
elif ref_selected == 'box':
else: # ref_selected == 'box'
geo_n = working_obj.solid_geometry
if isinstance(working_obj, FlatCAMGeometry):
@ -831,15 +833,119 @@ class ToolCopperThieving(FlatCAMTool):
# ########## Generate filling geometry. ###################################################
# #########################################################################################
if fill_type == 'solid':
new_solid_geometry = bounding_box.difference(clearance_geometry)
elif fill_type == 'dots':
dot_geo = Point((0, 0)).buffer(dot_dia / 2.0)
new_solid_geometry = bounding_box.difference(clearance_geometry)
# determine the bounding box polygon for the entire Gerber object to which we add copper thieving
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:
for bb in bounding_box:
pass
_it = iter(new_solid_geometry)
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
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]
try:
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
dia = float(self.drill_dia.get_value())
if dia is '':
self.app.inform.emit('[WARNING_NOTCL] %s' %
_("No value or wrong format in Drill Dia entry. Add it and retry."))
return
tools = {"1": {"C": dia}}
# holes = self.alignment_holes.get_value()