- finished Copper Thieving Tool improvements
This commit is contained in:
@@ -14,6 +14,7 @@ CAD program, and create G-Code for Isolation routing.
|
|||||||
- finished the Dots and Squares options in the Copper Thieving Tool
|
- finished the Dots and Squares options in the Copper Thieving Tool
|
||||||
- working on the Lines option in Copper Thieving Tool
|
- working on the Lines option in Copper Thieving Tool
|
||||||
- finished the Lines option in the Copper Thieving Tool; still have to add threading to maximize performance
|
- finished the Lines option in the Copper Thieving Tool; still have to add threading to maximize performance
|
||||||
|
- finished Copper Thieving Tool improvements
|
||||||
|
|
||||||
17.11.2019
|
17.11.2019
|
||||||
|
|
||||||
|
|||||||
@@ -336,6 +336,9 @@ class ToolCopperThieving(FlatCAMTool):
|
|||||||
self.ref_obj = None
|
self.ref_obj = None
|
||||||
self.sel_rect = list()
|
self.sel_rect = list()
|
||||||
|
|
||||||
|
# store the flattened geometry here:
|
||||||
|
self.flat_geometry = list()
|
||||||
|
|
||||||
# Events ID
|
# Events ID
|
||||||
self.mr = None
|
self.mr = None
|
||||||
self.mm = None
|
self.mm = None
|
||||||
@@ -405,6 +408,7 @@ class ToolCopperThieving(FlatCAMTool):
|
|||||||
self.line_size_entry.set_value(self.app.defaults["tools_copper_thieving_lines_size"])
|
self.line_size_entry.set_value(self.app.defaults["tools_copper_thieving_lines_size"])
|
||||||
self.lines_spacing_entry.set_value(self.app.defaults["tools_copper_thieving_lines_spacing"])
|
self.lines_spacing_entry.set_value(self.app.defaults["tools_copper_thieving_lines_spacing"])
|
||||||
|
|
||||||
|
# INIT SECTION
|
||||||
self.area_method = False
|
self.area_method = False
|
||||||
|
|
||||||
def on_combo_box_type(self):
|
def on_combo_box_type(self):
|
||||||
@@ -428,6 +432,11 @@ class ToolCopperThieving(FlatCAMTool):
|
|||||||
self.bbox_type_label.show()
|
self.bbox_type_label.show()
|
||||||
self.bbox_type_radio.show()
|
self.bbox_type_radio.show()
|
||||||
else:
|
else:
|
||||||
|
if self.fill_type_radio.get_value() == 'line':
|
||||||
|
self.reference_radio.set_value('itself')
|
||||||
|
self.app.inform.emit('[WARNING_NOTCL] %s' % _("Lines Grid works only for 'itself' reference ..."))
|
||||||
|
return
|
||||||
|
|
||||||
self.bbox_type_label.hide()
|
self.bbox_type_label.hide()
|
||||||
self.bbox_type_radio.hide()
|
self.bbox_type_radio.hide()
|
||||||
|
|
||||||
@@ -436,15 +445,21 @@ class ToolCopperThieving(FlatCAMTool):
|
|||||||
self.dots_frame.hide()
|
self.dots_frame.hide()
|
||||||
self.squares_frame.hide()
|
self.squares_frame.hide()
|
||||||
self.lines_frame.hide()
|
self.lines_frame.hide()
|
||||||
|
self.app.inform.emit(_("Solid fill selected."))
|
||||||
elif choice == 'dot':
|
elif choice == 'dot':
|
||||||
self.dots_frame.show()
|
self.dots_frame.show()
|
||||||
self.squares_frame.hide()
|
self.squares_frame.hide()
|
||||||
self.lines_frame.hide()
|
self.lines_frame.hide()
|
||||||
|
self.app.inform.emit(_("Dots grid fill selected."))
|
||||||
elif choice == 'square':
|
elif choice == 'square':
|
||||||
self.dots_frame.hide()
|
self.dots_frame.hide()
|
||||||
self.squares_frame.show()
|
self.squares_frame.show()
|
||||||
self.lines_frame.hide()
|
self.lines_frame.hide()
|
||||||
|
self.app.inform.emit(_("Squares grid fill selected."))
|
||||||
else:
|
else:
|
||||||
|
if self.reference_radio.get_value() != 'itself':
|
||||||
|
self.reference_radio.set_value('itself')
|
||||||
|
self.app.inform.emit('[WARNING_NOTCL] %s' % _("Lines Grid works only for 'itself' reference ..."))
|
||||||
self.dots_frame.hide()
|
self.dots_frame.hide()
|
||||||
self.squares_frame.hide()
|
self.squares_frame.hide()
|
||||||
self.lines_frame.show()
|
self.lines_frame.show()
|
||||||
@@ -656,11 +671,12 @@ class ToolCopperThieving(FlatCAMTool):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
if run_threaded:
|
if run_threaded:
|
||||||
proc = self.app.proc_container.new('%s ...' % _("Copper thieving"))
|
proc = self.app.proc_container.new('%s ...' % _("Thieving"))
|
||||||
else:
|
else:
|
||||||
self.app.proc_container.view.set_busy('%s ...' % _("Copper thieving"))
|
|
||||||
QtWidgets.QApplication.processEvents()
|
QtWidgets.QApplication.processEvents()
|
||||||
|
|
||||||
|
self.app.proc_container.view.set_busy('%s ...' % _("Thieving"))
|
||||||
|
|
||||||
# #####################################################################
|
# #####################################################################
|
||||||
# ####### Read the parameters #########################################
|
# ####### Read the parameters #########################################
|
||||||
# #####################################################################
|
# #####################################################################
|
||||||
@@ -686,16 +702,17 @@ class ToolCopperThieving(FlatCAMTool):
|
|||||||
if not isinstance(self.grb_object.solid_geometry, Iterable):
|
if not isinstance(self.grb_object.solid_geometry, Iterable):
|
||||||
self.grb_object.solid_geometry = [self.grb_object.solid_geometry]
|
self.grb_object.solid_geometry = [self.grb_object.solid_geometry]
|
||||||
|
|
||||||
|
def job_thread_thieving(app_obj):
|
||||||
# #########################################################################################
|
# #########################################################################################
|
||||||
# Prepare isolation polygon. This will create the clearance over the Gerber features ######
|
# Prepare isolation polygon. This will create the clearance over the Gerber features ######
|
||||||
# #########################################################################################
|
# #########################################################################################
|
||||||
log.debug("Copper Thieving Tool. Preparing isolation polygons.")
|
log.debug("Copper Thieving Tool. Preparing isolation polygons.")
|
||||||
self.app.inform.emit(_("Copper Thieving Tool. Preparing isolation polygons."))
|
app_obj.app.inform.emit(_("Copper Thieving Tool. Preparing isolation polygons."))
|
||||||
|
|
||||||
# variables to display the percentage of work done
|
# variables to display the percentage of work done
|
||||||
geo_len = 0
|
geo_len = 0
|
||||||
try:
|
try:
|
||||||
for pol in self.grb_object.solid_geometry:
|
for pol in app_obj.grb_object.solid_geometry:
|
||||||
geo_len += 1
|
geo_len += 1
|
||||||
except TypeError:
|
except TypeError:
|
||||||
geo_len = 1
|
geo_len = 1
|
||||||
@@ -705,37 +722,37 @@ class ToolCopperThieving(FlatCAMTool):
|
|||||||
|
|
||||||
clearance_geometry = []
|
clearance_geometry = []
|
||||||
try:
|
try:
|
||||||
for pol in self.grb_object.solid_geometry:
|
for pol in app_obj.grb_object.solid_geometry:
|
||||||
if self.app.abort_flag:
|
if app_obj.app.abort_flag:
|
||||||
# graceful abort requested by the user
|
# graceful abort requested by the user
|
||||||
raise FlatCAMApp.GracefulException
|
raise FlatCAMApp.GracefulException
|
||||||
|
|
||||||
clearance_geometry.append(
|
clearance_geometry.append(
|
||||||
pol.buffer(c_val, int(int(self.geo_steps_per_circle) / 4))
|
pol.buffer(c_val, int(int(app_obj.geo_steps_per_circle) / 4))
|
||||||
)
|
)
|
||||||
|
|
||||||
pol_nr += 1
|
pol_nr += 1
|
||||||
disp_number = int(np.interp(pol_nr, [0, geo_len], [0, 100]))
|
disp_number = int(np.interp(pol_nr, [0, geo_len], [0, 100]))
|
||||||
|
|
||||||
if old_disp_number < disp_number <= 100:
|
if old_disp_number < disp_number <= 100:
|
||||||
self.app.proc_container.update_view_text(' %s ... %d%%' %
|
app_obj.app.proc_container.update_view_text(' %s ... %d%%' %
|
||||||
(_("Buffering"), int(disp_number)))
|
(_("Thieving"), int(disp_number)))
|
||||||
old_disp_number = disp_number
|
old_disp_number = disp_number
|
||||||
except TypeError:
|
except TypeError:
|
||||||
# taking care of the case when the self.solid_geometry is just a single Polygon, not a list or a
|
# taking care of the case when the self.solid_geometry is just a single Polygon, not a list or a
|
||||||
# MultiPolygon (not an iterable)
|
# MultiPolygon (not an iterable)
|
||||||
clearance_geometry.append(
|
clearance_geometry.append(
|
||||||
self.grb_object.solid_geometry.buffer(c_val, int(int(self.geo_steps_per_circle) / 4))
|
app_obj.grb_object.solid_geometry.buffer(c_val, int(int(app_obj.geo_steps_per_circle) / 4))
|
||||||
)
|
)
|
||||||
|
|
||||||
self.app.proc_container.update_view_text(' %s' % _("Buffering"))
|
app_obj.app.proc_container.update_view_text(' %s ...' % _("Buffering"))
|
||||||
clearance_geometry = unary_union(clearance_geometry)
|
clearance_geometry = unary_union(clearance_geometry)
|
||||||
|
|
||||||
# #########################################################################################
|
# #########################################################################################
|
||||||
# Prepare the area to fill with copper. ###################################################
|
# Prepare the area to fill with copper. ###################################################
|
||||||
# #########################################################################################
|
# #########################################################################################
|
||||||
log.debug("Copper Thieving Tool. Preparing areas to fill with copper.")
|
log.debug("Copper Thieving Tool. Preparing areas to fill with copper.")
|
||||||
self.app.inform.emit(_("Copper Thieving Tool. Preparing areas to fill with copper."))
|
app_obj.app.inform.emit(_("Copper Thieving Tool. Preparing areas to fill with copper."))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if ref_obj is None or ref_obj == 'itself':
|
if ref_obj is None or ref_obj == 'itself':
|
||||||
@@ -746,12 +763,12 @@ class ToolCopperThieving(FlatCAMTool):
|
|||||||
log.debug("ToolCopperThieving.on_copper_thieving() --> %s" % str(e))
|
log.debug("ToolCopperThieving.on_copper_thieving() --> %s" % str(e))
|
||||||
return 'fail'
|
return 'fail'
|
||||||
|
|
||||||
bounding_box = None
|
app_obj.app.proc_container.update_view_text(' %s' % _("Working..."))
|
||||||
if ref_selected == 'itself':
|
if ref_selected == 'itself':
|
||||||
geo_n = working_obj.solid_geometry
|
geo_n = working_obj.solid_geometry
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if self.bbox_type_radio.get_value() == 'min':
|
if app_obj.bbox_type_radio.get_value() == 'min':
|
||||||
if isinstance(geo_n, MultiPolygon):
|
if isinstance(geo_n, MultiPolygon):
|
||||||
env_obj = geo_n.convex_hull
|
env_obj = geo_n.convex_hull
|
||||||
elif (isinstance(geo_n, MultiPolygon) and len(geo_n) == 1) or \
|
elif (isinstance(geo_n, MultiPolygon) and len(geo_n) == 1) or \
|
||||||
@@ -760,45 +777,39 @@ class ToolCopperThieving(FlatCAMTool):
|
|||||||
else:
|
else:
|
||||||
env_obj = cascaded_union(geo_n)
|
env_obj = cascaded_union(geo_n)
|
||||||
env_obj = env_obj.convex_hull
|
env_obj = env_obj.convex_hull
|
||||||
|
bounding_box = env_obj.buffer(distance=margin, join_style=base.JOIN_STYLE.mitre)
|
||||||
else:
|
else:
|
||||||
if isinstance(geo_n, Polygon):
|
if isinstance(geo_n, Polygon):
|
||||||
env_obj = geo_n.buffer(0, join_style=base.JOIN_STYLE.mitre).exterior
|
bounding_box = geo_n.buffer(distance=margin, join_style=base.JOIN_STYLE.mitre).exterior
|
||||||
elif isinstance(geo_n, list):
|
elif isinstance(geo_n, list):
|
||||||
geo_n = unary_union(geo_n)
|
geo_n = unary_union(geo_n)
|
||||||
env_obj = geo_n.buffer(0, join_style=base.JOIN_STYLE.mitre).exterior
|
bounding_box = geo_n.buffer(distance=margin, 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
|
||||||
geo = box(x0, y0, x1, y1)
|
geo = box(x0, y0, x1, y1)
|
||||||
env_obj = geo.buffer(0, join_style=base.JOIN_STYLE.mitre)
|
bounding_box = geo.buffer(distance=margin, join_style=base.JOIN_STYLE.mitre)
|
||||||
else:
|
else:
|
||||||
self.app.inform.emit(
|
app_obj.app.inform.emit(
|
||||||
'[ERROR_NOTCL] %s: %s' % (_("Geometry not supported for bounding box"), type(geo_n))
|
'[ERROR_NOTCL] %s: %s' % (_("Geometry not supported for bounding box"), type(geo_n))
|
||||||
)
|
)
|
||||||
return 'fail'
|
return 'fail'
|
||||||
|
|
||||||
bounding_box = env_obj.buffer(distance=margin, join_style=base.JOIN_STYLE.mitre)
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
log.debug("ToolCopperFIll.on_copper_thieving() 'itself' --> %s" % str(e))
|
log.debug("ToolCopperFIll.on_copper_thieving() 'itself' --> %s" % str(e))
|
||||||
self.app.inform.emit('[ERROR_NOTCL] %s' % _("No object available."))
|
app_obj.app.inform.emit('[ERROR_NOTCL] %s' % _("No object available."))
|
||||||
return 'fail'
|
return 'fail'
|
||||||
|
|
||||||
elif ref_selected == 'area':
|
elif ref_selected == 'area':
|
||||||
geo_n = cascaded_union(working_obj)
|
|
||||||
try:
|
|
||||||
__ = iter(geo_n)
|
|
||||||
except Exception as e:
|
|
||||||
log.debug("ToolCopperFIll.on_copper_thieving() 'area' --> %s" % str(e))
|
|
||||||
geo_n = [geo_n]
|
|
||||||
|
|
||||||
geo_buff_list = []
|
geo_buff_list = []
|
||||||
for poly in geo_n:
|
try:
|
||||||
if self.app.abort_flag:
|
for poly in working_obj:
|
||||||
|
if app_obj.app.abort_flag:
|
||||||
# graceful abort requested by the user
|
# graceful abort requested by the user
|
||||||
raise FlatCAMApp.GracefulException
|
raise FlatCAMApp.GracefulException
|
||||||
geo_buff_list.append(poly.buffer(distance=margin, join_style=base.JOIN_STYLE.mitre))
|
geo_buff_list.append(poly.buffer(distance=margin, join_style=base.JOIN_STYLE.mitre))
|
||||||
|
except TypeError:
|
||||||
|
geo_buff_list.append(working_obj.buffer(distance=margin, join_style=base.JOIN_STYLE.mitre))
|
||||||
|
|
||||||
bounding_box = cascaded_union(geo_buff_list)
|
bounding_box = MultiPolygon(geo_buff_list)
|
||||||
|
|
||||||
else: # ref_selected == 'box'
|
else: # ref_selected == 'box'
|
||||||
geo_n = working_obj.solid_geometry
|
geo_n = working_obj.solid_geometry
|
||||||
|
|
||||||
@@ -811,7 +822,7 @@ class ToolCopperThieving(FlatCAMTool):
|
|||||||
|
|
||||||
geo_buff_list = []
|
geo_buff_list = []
|
||||||
for poly in geo_n:
|
for poly in geo_n:
|
||||||
if self.app.abort_flag:
|
if app_obj.app.abort_flag:
|
||||||
# graceful abort requested by the user
|
# graceful abort requested by the user
|
||||||
raise FlatCAMApp.GracefulException
|
raise FlatCAMApp.GracefulException
|
||||||
geo_buff_list.append(poly.buffer(distance=margin, join_style=base.JOIN_STYLE.mitre))
|
geo_buff_list.append(poly.buffer(distance=margin, join_style=base.JOIN_STYLE.mitre))
|
||||||
@@ -822,12 +833,12 @@ class ToolCopperThieving(FlatCAMTool):
|
|||||||
bounding_box = cascaded_union(thieving_obj.solid_geometry).convex_hull.intersection(geo_n)
|
bounding_box = cascaded_union(thieving_obj.solid_geometry).convex_hull.intersection(geo_n)
|
||||||
bounding_box = bounding_box.buffer(distance=margin, join_style=base.JOIN_STYLE.mitre)
|
bounding_box = bounding_box.buffer(distance=margin, join_style=base.JOIN_STYLE.mitre)
|
||||||
else:
|
else:
|
||||||
self.app.inform.emit('[ERROR_NOTCL] %s' % _("The reference object type is not supported."))
|
app_obj.app.inform.emit('[ERROR_NOTCL] %s' % _("The reference object type is not supported."))
|
||||||
return 'fail'
|
return 'fail'
|
||||||
|
|
||||||
log.debug("Copper Thieving Tool. Finished creating areas to fill with copper.")
|
log.debug("Copper Thieving Tool. Finished creating areas to fill with copper.")
|
||||||
|
|
||||||
self.app.inform.emit(_("Copper Thieving Tool. Appending new geometry and buffering."))
|
app_obj.app.inform.emit(_("Copper Thieving Tool. Appending new geometry and buffering."))
|
||||||
|
|
||||||
# #########################################################################################
|
# #########################################################################################
|
||||||
# ########## Generate filling geometry. ###################################################
|
# ########## Generate filling geometry. ###################################################
|
||||||
@@ -836,13 +847,20 @@ class ToolCopperThieving(FlatCAMTool):
|
|||||||
new_solid_geometry = bounding_box.difference(clearance_geometry)
|
new_solid_geometry = bounding_box.difference(clearance_geometry)
|
||||||
|
|
||||||
# determine the bounding box polygon for the entire Gerber object to which we add copper thieving
|
# determine the bounding box polygon for the entire Gerber object to which we add copper thieving
|
||||||
if isinstance(geo_n, list):
|
# if isinstance(geo_n, list):
|
||||||
env_obj = unary_union(geo_n).buffer(distance=margin, join_style=base.JOIN_STYLE.mitre)
|
# env_obj = unary_union(geo_n).buffer(distance=margin, join_style=base.JOIN_STYLE.mitre)
|
||||||
else:
|
# else:
|
||||||
env_obj = geo_n.buffer(distance=margin, join_style=base.JOIN_STYLE.mitre)
|
# 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)
|
||||||
|
app_obj.app.proc_container.update_view_text(' %s' % _("Create geometry"))
|
||||||
|
|
||||||
x0, y0, x1, y1 = env_obj.bounds
|
bounding_box = thieving_obj.solid_geometry.envelope.buffer(
|
||||||
bounding_box = box(x0, y0, x1, y1)
|
distance=margin,
|
||||||
|
join_style=base.JOIN_STYLE.mitre
|
||||||
|
)
|
||||||
|
x0, y0, x1, y1 = bounding_box.bounds
|
||||||
|
|
||||||
if fill_type == 'dot' or fill_type == 'square':
|
if fill_type == 'dot' or fill_type == 'square':
|
||||||
# build the MultiPolygon of dots/squares that will fill the entire bounding box
|
# build the MultiPolygon of dots/squares that will fill the entire bounding box
|
||||||
@@ -902,33 +920,33 @@ class ToolCopperThieving(FlatCAMTool):
|
|||||||
# create a thick polygon-line that surrounds the copper features
|
# create a thick polygon-line that surrounds the copper features
|
||||||
outline_geometry = []
|
outline_geometry = []
|
||||||
try:
|
try:
|
||||||
for pol in self.grb_object.solid_geometry:
|
for pol in app_obj.grb_object.solid_geometry:
|
||||||
if self.app.abort_flag:
|
if app_obj.app.abort_flag:
|
||||||
# graceful abort requested by the user
|
# graceful abort requested by the user
|
||||||
raise FlatCAMApp.GracefulException
|
raise FlatCAMApp.GracefulException
|
||||||
|
|
||||||
outline_geometry.append(
|
outline_geometry.append(
|
||||||
pol.buffer(c_val+half_thick_line, int(int(self.geo_steps_per_circle) / 4))
|
pol.buffer(c_val+half_thick_line, int(int(app_obj.geo_steps_per_circle) / 4))
|
||||||
)
|
)
|
||||||
|
|
||||||
pol_nr += 1
|
pol_nr += 1
|
||||||
disp_number = int(np.interp(pol_nr, [0, geo_len], [0, 100]))
|
disp_number = int(np.interp(pol_nr, [0, geo_len], [0, 100]))
|
||||||
|
|
||||||
if old_disp_number < disp_number <= 100:
|
if old_disp_number < disp_number <= 100:
|
||||||
self.app.proc_container.update_view_text(' %s ... %d%%' %
|
app_obj.app.proc_container.update_view_text(' %s ... %d%%' %
|
||||||
(_("Buffering"), int(disp_number)))
|
(_("Buffering"), int(disp_number)))
|
||||||
old_disp_number = disp_number
|
old_disp_number = disp_number
|
||||||
except TypeError:
|
except TypeError:
|
||||||
# taking care of the case when the self.solid_geometry is just a single Polygon, not a list or a
|
# taking care of the case when the self.solid_geometry is just a single Polygon, not a list or a
|
||||||
# MultiPolygon (not an iterable)
|
# MultiPolygon (not an iterable)
|
||||||
outline_geometry.append(
|
outline_geometry.append(
|
||||||
self.grb_object.solid_geometry.buffer(
|
app_obj.grb_object.solid_geometry.buffer(
|
||||||
c_val+half_thick_line,
|
c_val+half_thick_line,
|
||||||
int(int(self.geo_steps_per_circle) / 4)
|
int(int(app_obj.geo_steps_per_circle) / 4)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
self.app.proc_container.update_view_text(' %s' % _("Buffering"))
|
app_obj.app.proc_container.update_view_text(' %s' % _("Buffering"))
|
||||||
outline_geometry = unary_union(outline_geometry)
|
outline_geometry = unary_union(outline_geometry)
|
||||||
|
|
||||||
outline_line = list()
|
outline_line = list()
|
||||||
@@ -936,13 +954,13 @@ class ToolCopperThieving(FlatCAMTool):
|
|||||||
for geo_o in outline_geometry:
|
for geo_o in outline_geometry:
|
||||||
outline_line.append(
|
outline_line.append(
|
||||||
geo_o.exterior.buffer(
|
geo_o.exterior.buffer(
|
||||||
half_thick_line, resolution=int(int(self.geo_steps_per_circle) / 4)
|
half_thick_line, resolution=int(int(app_obj.geo_steps_per_circle) / 4)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
except TypeError:
|
except TypeError:
|
||||||
outline_line.append(
|
outline_line.append(
|
||||||
outline_geometry.exterior.buffer(
|
outline_geometry.exterior.buffer(
|
||||||
half_thick_line, resolution=int(int(self.geo_steps_per_circle) / 4)
|
half_thick_line, resolution=int(int(app_obj.geo_steps_per_circle) / 4)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -953,7 +971,7 @@ class ToolCopperThieving(FlatCAMTool):
|
|||||||
box_outline_geo_exterior = box_outline_geo.exterior
|
box_outline_geo_exterior = box_outline_geo.exterior
|
||||||
box_outline_geometry = box_outline_geo_exterior.buffer(
|
box_outline_geometry = box_outline_geo_exterior.buffer(
|
||||||
half_thick_line,
|
half_thick_line,
|
||||||
resolution=int(int(self.geo_steps_per_circle) / 4)
|
resolution=int(int(app_obj.geo_steps_per_circle) / 4)
|
||||||
)
|
)
|
||||||
|
|
||||||
bx0, by0, bx1, by1 = box_outline_geo.bounds
|
bx0, by0, bx1, by1 = box_outline_geo.bounds
|
||||||
@@ -963,7 +981,7 @@ class ToolCopperThieving(FlatCAMTool):
|
|||||||
while new_x <= x1 - half_thick_line:
|
while new_x <= x1 - half_thick_line:
|
||||||
line_geo = LineString([(new_x, by0), (new_x, by1)]).buffer(
|
line_geo = LineString([(new_x, by0), (new_x, by1)]).buffer(
|
||||||
half_thick_line,
|
half_thick_line,
|
||||||
resolution=int(int(self.geo_steps_per_circle) / 4)
|
resolution=int(int(app_obj.geo_steps_per_circle) / 4)
|
||||||
)
|
)
|
||||||
thieving_lines_geo.append(line_geo)
|
thieving_lines_geo.append(line_geo)
|
||||||
new_x += line_size + line_spacing
|
new_x += line_size + line_spacing
|
||||||
@@ -971,26 +989,29 @@ class ToolCopperThieving(FlatCAMTool):
|
|||||||
while new_y <= y1 - half_thick_line:
|
while new_y <= y1 - half_thick_line:
|
||||||
line_geo = LineString([(bx0, new_y), (bx1, new_y)]).buffer(
|
line_geo = LineString([(bx0, new_y), (bx1, new_y)]).buffer(
|
||||||
half_thick_line,
|
half_thick_line,
|
||||||
resolution=int(int(self.geo_steps_per_circle) / 4)
|
resolution=int(int(app_obj.geo_steps_per_circle) / 4)
|
||||||
)
|
)
|
||||||
thieving_lines_geo.append(line_geo)
|
thieving_lines_geo.append(line_geo)
|
||||||
new_y += line_size + line_spacing
|
new_y += line_size + line_spacing
|
||||||
|
|
||||||
thieving_box_geo = cascaded_union(thieving_lines_geo)
|
|
||||||
|
|
||||||
# merge everything together
|
# merge everything together
|
||||||
diff_lines_geo = thieving_box_geo.difference(clearance_geometry)
|
diff_lines_geo = list()
|
||||||
new_solid_geometry = unary_union([outline_geometry, box_outline_geometry, diff_lines_geo])
|
for line_poly in thieving_lines_geo:
|
||||||
|
rest_line = line_poly.difference(clearance_geometry)
|
||||||
|
diff_lines_geo.append(rest_line)
|
||||||
|
app_obj.flatten([outline_geometry, box_outline_geometry, diff_lines_geo])
|
||||||
|
new_solid_geometry = app_obj.flat_geometry
|
||||||
|
|
||||||
geo_list = self.grb_object.solid_geometry
|
app_obj.app.proc_container.update_view_text(' %s' % _("Append geometry"))
|
||||||
if isinstance(self.grb_object.solid_geometry, MultiPolygon):
|
geo_list = app_obj.grb_object.solid_geometry
|
||||||
geo_list = list(self.grb_object.solid_geometry.geoms)
|
if isinstance(app_obj.grb_object.solid_geometry, MultiPolygon):
|
||||||
|
geo_list = list(app_obj.grb_object.solid_geometry.geoms)
|
||||||
|
|
||||||
if '0' not in self.grb_object.apertures:
|
if '0' not in app_obj.grb_object.apertures:
|
||||||
self.grb_object.apertures['0'] = dict()
|
app_obj.grb_object.apertures['0'] = dict()
|
||||||
self.grb_object.apertures['0']['geometry'] = list()
|
app_obj.grb_object.apertures['0']['geometry'] = list()
|
||||||
self.grb_object.apertures['0']['type'] = 'REG'
|
app_obj.grb_object.apertures['0']['type'] = 'REG'
|
||||||
self.grb_object.apertures['0']['size'] = 0.0
|
app_obj.grb_object.apertures['0']['size'] = 0.0
|
||||||
|
|
||||||
try:
|
try:
|
||||||
for poly in new_solid_geometry:
|
for poly in new_solid_geometry:
|
||||||
@@ -1001,7 +1022,7 @@ class ToolCopperThieving(FlatCAMTool):
|
|||||||
geo_elem = dict()
|
geo_elem = dict()
|
||||||
geo_elem['solid'] = poly
|
geo_elem['solid'] = poly
|
||||||
geo_elem['follow'] = poly.exterior
|
geo_elem['follow'] = poly.exterior
|
||||||
self.grb_object.apertures['0']['geometry'].append(deepcopy(geo_elem))
|
app_obj.grb_object.apertures['0']['geometry'].append(deepcopy(geo_elem))
|
||||||
except TypeError:
|
except TypeError:
|
||||||
# append to the new solid geometry
|
# append to the new solid geometry
|
||||||
geo_list.append(new_solid_geometry)
|
geo_list.append(new_solid_geometry)
|
||||||
@@ -1010,16 +1031,24 @@ class ToolCopperThieving(FlatCAMTool):
|
|||||||
geo_elem = dict()
|
geo_elem = dict()
|
||||||
geo_elem['solid'] = new_solid_geometry
|
geo_elem['solid'] = new_solid_geometry
|
||||||
geo_elem['follow'] = new_solid_geometry.exterior
|
geo_elem['follow'] = new_solid_geometry.exterior
|
||||||
self.grb_object.apertures['0']['geometry'].append(deepcopy(geo_elem))
|
app_obj.grb_object.apertures['0']['geometry'].append(deepcopy(geo_elem))
|
||||||
|
|
||||||
self.grb_object.solid_geometry = MultiPolygon(geo_list).buffer(0.0000001).buffer(-0.0000001)
|
app_obj.grb_object.solid_geometry = MultiPolygon(geo_list).buffer(0.0000001).buffer(-0.0000001)
|
||||||
|
|
||||||
|
app_obj.app.proc_container.update_view_text(' %s' % _("Append source file"))
|
||||||
# update the source file with the new geometry:
|
# update the source file with the new geometry:
|
||||||
self.grb_object.source_file = self.app.export_gerber(obj_name=self.grb_object.options['name'], filename=None,
|
app_obj.grb_object.source_file = app_obj.app.export_gerber(obj_name=app_obj.grb_object.options['name'],
|
||||||
local_use=self.grb_object, use_thread=False)
|
filename=None,
|
||||||
|
local_use=app_obj.grb_object,
|
||||||
|
use_thread=False)
|
||||||
|
app_obj.app.proc_container.update_view_text(' %s' % '')
|
||||||
|
app_obj.on_exit()
|
||||||
|
app_obj.app.inform.emit('[success] %s' % _("Copper Thieving Tool done."))
|
||||||
|
|
||||||
self.on_exit()
|
if run_threaded:
|
||||||
self.app.inform.emit('[success] %s' % _("Copper Thieving Tool done."))
|
self.app.worker_task.emit({'fcn': job_thread_thieving, 'params': [self]})
|
||||||
|
else:
|
||||||
|
job_thread_thieving(self)
|
||||||
|
|
||||||
def replot(self, obj):
|
def replot(self, obj):
|
||||||
def worker_task():
|
def worker_task():
|
||||||
@@ -1077,3 +1106,23 @@ class ToolCopperThieving(FlatCAMTool):
|
|||||||
|
|
||||||
self.app.call_source = "app"
|
self.app.call_source = "app"
|
||||||
self.app.inform.emit('[success] %s' % _("Copper Thieving Tool exit."))
|
self.app.inform.emit('[success] %s' % _("Copper Thieving Tool exit."))
|
||||||
|
|
||||||
|
def flatten(self, geometry):
|
||||||
|
"""
|
||||||
|
Creates a list of non-iterable linear geometry objects.
|
||||||
|
:param geometry: Shapely type or list or list of list of such.
|
||||||
|
|
||||||
|
Results are placed in self.flat_geometry
|
||||||
|
"""
|
||||||
|
|
||||||
|
# ## If iterable, expand recursively.
|
||||||
|
try:
|
||||||
|
for geo in geometry:
|
||||||
|
if geo is not None:
|
||||||
|
self.flatten(geometry=geo)
|
||||||
|
|
||||||
|
# ## Not iterable, do the actual indexing and add.
|
||||||
|
except TypeError:
|
||||||
|
self.flat_geometry.append(geometry)
|
||||||
|
|
||||||
|
return self.flat_geometry
|
||||||
|
|||||||
@@ -25,7 +25,10 @@
|
|||||||
# scipy.sparse.sparsetools._csr.pyd, scipy.sparse.sparsetools._csc.pyd,
|
# scipy.sparse.sparsetools._csr.pyd, scipy.sparse.sparsetools._csc.pyd,
|
||||||
# scipy.sparse.sparsetools._coo.pyd
|
# scipy.sparse.sparsetools._coo.pyd
|
||||||
|
|
||||||
import os, site, sys, platform
|
import os
|
||||||
|
import site
|
||||||
|
import sys
|
||||||
|
import platform
|
||||||
from cx_Freeze import setup, Executable
|
from cx_Freeze import setup, Executable
|
||||||
|
|
||||||
# this is done to solve the tkinter not being found
|
# this is done to solve the tkinter not being found
|
||||||
@@ -101,7 +104,6 @@ def getTargetName():
|
|||||||
return "FlatCAM.dmg"
|
return "FlatCAM.dmg"
|
||||||
|
|
||||||
|
|
||||||
# execfile('clean.py')
|
|
||||||
exe = Executable("FlatCAM.py", icon='share/flatcam_icon48.ico', base=base, targetName=getTargetName())
|
exe = Executable("FlatCAM.py", icon='share/flatcam_icon48.ico', base=base, targetName=getTargetName())
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
|
|||||||
Reference in New Issue
Block a user