- finished Copper Thieving Tool improvements

This commit is contained in:
Marius Stanciu
2019-11-18 23:03:04 +02:00
committed by Marius
parent 8888869d3b
commit 92b1ad6f05
3 changed files with 349 additions and 297 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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(