- added Rtree optimization for Drilling Plugin

This commit is contained in:
Marius Stanciu
2021-11-17 18:59:37 +02:00
committed by Marius Stanciu
parent 9761e8a4d1
commit 370e8f8ec1
3 changed files with 70 additions and 12 deletions

View File

@@ -11,6 +11,7 @@ CHANGELOG for FlatCAM beta
- fixed an issue when using Python 3.10, in GUI elements - fixed an issue when using Python 3.10, in GUI elements
- added fix such that the application will work without having the ortools package installed: TSA and RTree algorithms will be automatically used in that case - added fix such that the application will work without having the ortools package installed: TSA and RTree algorithms will be automatically used in that case
- added Rtree optimization for Drilling Plugin
10.11.2021 10.11.2021

View File

@@ -231,20 +231,23 @@ class ExcellonGenPrefGroupUI(OptionsGroupUI):
self.excellon_optimization_label = FCLabel(_('Algorithm:')) self.excellon_optimization_label = FCLabel(_('Algorithm:'))
self.excellon_optimization_label.setToolTip( self.excellon_optimization_label.setToolTip(
_("This sets the optimization type for the Excellon drill path.\n" _("This sets the path optimization algorithm.\n"
"If <<MetaHeuristic>> is checked then Google OR-Tools algorithm with\n" "- Rtre -> Rtree algorithm\n"
"- MetaHeuristic -> Google OR-Tools algorithm with\n"
"MetaHeuristic Guided Local Path is used. Default search time is 3sec.\n" "MetaHeuristic Guided Local Path is used. Default search time is 3sec.\n"
"If <<Basic>> is checked then Google OR-Tools Basic algorithm is used.\n" "- Basic -> Using Google OR-Tools Basic algorithm\n"
"If <<TSA>> is checked then Travelling Salesman algorithm is used for\n" "- TSA -> Using Travelling Salesman algorithm\n"
"drill path optimization.\n"
"\n" "\n"
"Some options are disabled when the application works in 32bit mode.") "Some options are disabled when the application works in 32bit mode.")
) )
self.excellon_optimization_radio = RadioSet([{'label': _('MetaHeuristic'), 'value': 'M'}, self.excellon_optimization_radio = RadioSet(
{'label': _('Basic'), 'value': 'B'}, [
{'label': _('TSA'), 'value': 'T'}], {'label': _('Rtree'), 'value': 'R'},
orientation='vertical', compact=True) {'label': _('MetaHeuristic'), 'value': 'M'},
{'label': _('Basic'), 'value': 'B'},
{'label': _('TSA'), 'value': 'T'}
], orientation='vertical', compact=True)
opt_grid.addWidget(self.excellon_optimization_label, 0, 0) opt_grid.addWidget(self.excellon_optimization_label, 0, 0)
opt_grid.addWidget(self.excellon_optimization_radio, 0, 1) opt_grid.addWidget(self.excellon_optimization_radio, 0, 1)

View File

@@ -3201,6 +3201,49 @@ class CNCjob(Geometry):
return locations return locations
def exc_optimized_rtree(self, geometry):
locations = []
# ## Index first and last points in paths. What points to index.
def get_pts(o):
return [(o.x, o.y)]
# Create the indexed storage.
storage = FlatCAMRTreeStorage()
storage.get_points = get_pts
# Store the geometry
log.debug("Indexing geometry before generating G-Code...")
self.app.inform.emit(_("Indexing geometry before generating G-Code..."))
for geo_shape in geometry:
if self.app.abort_flag:
# graceful abort requested by the user
raise grace
if geo_shape is not None:
try:
storage.insert(geo_shape)
except Exception:
pass
current_pt = (0, 0)
pt, geo = storage.nearest(current_pt)
try:
while True:
storage.remove(geo)
locations.append((pt, geo))
current_pt = (geo.x, geo.y)
pt, geo = storage.nearest(current_pt)
except StopIteration:
pass
# if there are no locations then go to the next tool
if not locations:
return 'fail'
return locations
def check_zcut(self, zcut): def check_zcut(self, zcut):
if zcut > 0: if zcut > 0:
self.app.inform.emit('[WARNING] %s' % self.app.inform.emit('[WARNING] %s' %
@@ -3251,12 +3294,18 @@ class CNCjob(Geometry):
# ################################## DRILLING !!! ######################################################### # ################################## DRILLING !!! #########################################################
# ############################################################################################################# # #############################################################################################################
# ############################################################################################################# # #############################################################################################################
if not HAS_ORTOOLS:
if opt_type in ['M', 'B']:
opt_type = 'R'
if opt_type == 'M': if opt_type == 'M':
log.debug("Using OR-Tools Metaheuristic Guided Local Search drill path optimization.") log.debug("Using OR-Tools Metaheuristic Guided Local Search drill path optimization.")
elif opt_type == 'B': elif opt_type == 'B':
log.debug("Using OR-Tools Basic drill path optimization.") log.debug("Using OR-Tools Basic drill path optimization.")
elif opt_type == 'T': elif opt_type == 'T':
log.debug("Using Travelling Salesman drill path optimization.") log.debug("Using Travelling Salesman drill path optimization.")
elif opt_type == 'R':
log.debug("Using RTree path optimization.")
else: else:
log.debug("Using no path optimization.") log.debug("Using no path optimization.")
@@ -3367,9 +3416,6 @@ class CNCjob(Geometry):
locations = [] locations = []
optimized_path = [] optimized_path = []
if not HAS_ORTOOLS:
opt_type = 'T'
if opt_type == 'M': if opt_type == 'M':
locations = self.create_tool_data_array(points=points) locations = self.create_tool_data_array(points=points)
# if there are no locations then go to the next tool # if there are no locations then go to the next tool
@@ -3389,6 +3435,11 @@ class CNCjob(Geometry):
if not locations: if not locations:
return 'fail' return 'fail'
optimized_path = self.optimized_travelling_salesman(locations) optimized_path = self.optimized_travelling_salesman(locations)
elif opt_type == 'R':
temp_solid_geometry = tools[tool]['drills']
optimized_path = self.exc_optimized_rtree(temp_solid_geometry)
if optimized_path == 'fail':
return 'fail'
else: else:
# it's actually not optimized path but here we build a list of (x,y) coordinates # it's actually not optimized path but here we build a list of (x,y) coordinates
# out of the tool's drills # out of the tool's drills
@@ -3464,6 +3515,9 @@ class CNCjob(Geometry):
if opt_type == 'T': if opt_type == 'T':
locx = point[0] locx = point[0]
locy = point[1] locy = point[1]
elif opt_type == 'R':
locx = point[0][0]
locy = point[0][1]
else: else:
locx = locations[point][0] locx = locations[point][0]
locy = locations[point][1] locy = locations[point][1]