- updated Tool Optimal with display of all distances (and locations of the middle point between where they happen) found in the Gerber Object

This commit is contained in:
Marius Stanciu
2019-10-06 17:37:33 +03:00
committed by Marius
parent 1a841e3fdc
commit aafe2c9e89
4 changed files with 94 additions and 25 deletions

View File

@@ -2368,7 +2368,7 @@ class App(QtCore.QObject):
self.shell.setWindowTitle("FlatCAM Shell") self.shell.setWindowTitle("FlatCAM Shell")
self.shell.resize(*self.defaults["global_shell_shape"]) self.shell.resize(*self.defaults["global_shell_shape"])
self.shell.append_output("FlatCAM %s - " % self.version) self.shell.append_output("FlatCAM %s - " % self.version)
self.shell.append_output(_("Open Source Software - Type help to get started\n\n")) self.shell.append_output(_("Type >help< to get started\n\n"))
self.init_tcl() self.init_tcl()
@@ -4371,7 +4371,7 @@ class App(QtCore.QObject):
license_label = QtWidgets.QLabel( license_label = QtWidgets.QLabel(
_( _(
'(c) Copyright 2014 Juan Pablo Caram.\n\n' '\n'
'Licensed under the MIT license:\n' 'Licensed under the MIT license:\n'
'http://www.opensource.org/licenses/mit-license.php\n\n' 'http://www.opensource.org/licenses/mit-license.php\n\n'
'Permission is hereby granted, free of charge, to any person obtaining a copy\n' 'Permission is hereby granted, free of charge, to any person obtaining a copy\n'
@@ -4379,7 +4379,7 @@ class App(QtCore.QObject):
'in the Software without restriction, including without limitation the rights\n' 'in the Software without restriction, including without limitation the rights\n'
'to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n' 'to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n'
'copies of the Software, and to permit persons to whom the Software is\n' 'copies of the Software, and to permit persons to whom the Software is\n'
' furnished to do so, subject to the following conditions:\n\n' 'furnished to do so, subject to the following conditions:\n\n'
'The above copyright notice and this permission notice shall be included in\n' 'The above copyright notice and this permission notice shall be included in\n'
'all copies or substantial portions of the Software.\n\n' 'all copies or substantial portions of the Software.\n\n'
@@ -4480,10 +4480,10 @@ class App(QtCore.QObject):
self.prog_form_lay.addRow(QtWidgets.QLabel('%s' % "Denis Hayrullin")) self.prog_form_lay.addRow(QtWidgets.QLabel('%s' % "Denis Hayrullin"))
self.prog_form_lay.addRow(QtWidgets.QLabel('%s' % "Kamil Sopko")) self.prog_form_lay.addRow(QtWidgets.QLabel('%s' % "Kamil Sopko"))
self.prog_form_lay.addRow(QtWidgets.QLabel('%s' % "Marius Stanciu"), self.prog_form_lay.addRow(QtWidgets.QLabel('%s' % "Marius Stanciu"),
QtWidgets.QLabel('%s' % _("Maintainer >=2019"))) QtWidgets.QLabel('%s' % _("Maintainer >= 2019")))
self.prog_form_lay.addRow(QtWidgets.QLabel('')) self.prog_form_lay.addRow(QtWidgets.QLabel(''))
self.prog_form_lay.addRow(QtWidgets.QLabel('%s' % "Alexandru Lazar")) self.prog_form_lay.addRow(QtWidgets.QLabel('%s' % "Alex Lazar"))
self.prog_form_lay.addRow(QtWidgets.QLabel('%s' % "Matthieu Berthomé")) self.prog_form_lay.addRow(QtWidgets.QLabel('%s' % "Matthieu Berthomé"))
self.prog_form_lay.addRow(QtWidgets.QLabel('%s' % "Mike Evans")) self.prog_form_lay.addRow(QtWidgets.QLabel('%s' % "Mike Evans"))
self.prog_form_lay.addRow(QtWidgets.QLabel('%s' % "Victor Benso")) self.prog_form_lay.addRow(QtWidgets.QLabel('%s' % "Victor Benso"))

View File

@@ -20,6 +20,7 @@ CAD program, and create G-Code for Isolation routing.
- moved back the ApertureMacro class to camlib for now and made some import changes in the new ParseGerber and ParseExcellon classes - moved back the ApertureMacro class to camlib for now and made some import changes in the new ParseGerber and ParseExcellon classes
- some changes to the tests - perhaps I will try adding a few tests in the future - some changes to the tests - perhaps I will try adding a few tests in the future
- changed the Jump To icon and reverted some changes to the parseGerber and ParseExcellon classes - changed the Jump To icon and reverted some changes to the parseGerber and ParseExcellon classes
- updated Tool Optimal with display of all distances (and locations of the middle point between where they happen) found in the Gerber Object
5.10.2019 5.10.2019

View File

@@ -1809,7 +1809,7 @@ class _BrowserTextEdit(QTextEdit):
def clear(self): def clear(self):
QTextEdit.clear(self) QTextEdit.clear(self)
text = "FlatCAM %s - Open Source Software - Type help to get started\n\n" % self.version text = "FlatCAM %s - Type >help< to get started\n\n" % self.version
text = html.escape(text) text = html.escape(text)
text = text.replace('\n', '<br/>') text = text.replace('\n', '<br/>')
self.moveCursor(QTextCursor.End) self.moveCursor(QTextCursor.End)

View File

@@ -27,7 +27,7 @@ class ToolOptimal(FlatCAMTool):
toolName = _("Optimal Tool") toolName = _("Optimal Tool")
update_text = pyqtSignal(list) update_text = pyqtSignal(list)
update_sec_text = pyqtSignal(dict) update_sec_distances = pyqtSignal(dict)
def __init__(self, app): def __init__(self, app):
FlatCAMTool.__init__(self, app) FlatCAMTool.__init__(self, app)
@@ -196,8 +196,16 @@ class ToolOptimal(FlatCAMTool):
self.loc_ois = OptionalHideInputSection(self.locations_cb, [self.locations_textb, self.locate_button]) self.loc_ois = OptionalHideInputSection(self.locations_cb, [self.locations_textb, self.locate_button])
self.sec_loc_ois = OptionalHideInputSection(self.sec_locations_cb, [self.sec_locations_frame]) self.sec_loc_ois = OptionalHideInputSection(self.sec_locations_cb, [self.sec_locations_frame])
# this is the line selected in the textbox with the locations of the minimum
self.selected_text = '' self.selected_text = ''
# this is the line selected in the textbox with the locations of the other distances found in the Gerber object
self.selected_locations_text = ''
# dict to hold the distances between every two elements in Gerber as keys and the actual locations where that
# distances happen as values
self.min_dict = dict()
# ## Signals # ## Signals
self.calculate_button.clicked.connect(self.find_minimum_distance) self.calculate_button.clicked.connect(self.find_minimum_distance)
self.locate_button.clicked.connect(self.on_locate_position) self.locate_button.clicked.connect(self.on_locate_position)
@@ -205,8 +213,9 @@ class ToolOptimal(FlatCAMTool):
self.locations_textb.cursorPositionChanged.connect(self.on_textbox_clicked) self.locations_textb.cursorPositionChanged.connect(self.on_textbox_clicked)
self.locate_sec_button.clicked.connect(self.on_locate_sec_position) self.locate_sec_button.clicked.connect(self.on_locate_sec_position)
self.update_sec_text.connect(self.on_update_sec_text) self.update_sec_distances.connect(self.on_update_sec_distances_txt)
self.locations_sec_textb.cursorPositionChanged.connect(self.on_textbox_sec_clicked) self.distances_textb.cursorPositionChanged.connect(self.on_distances_textb_clicked)
self.locations_sec_textb.cursorPositionChanged.connect(self.on_locations_sec_clicked)
self.layout.addStretch() self.layout.addStretch()
@@ -315,7 +324,7 @@ class ToolOptimal(FlatCAMTool):
'%s: %s' % (_("Optimal Tool. Finding the distances between each two elements. Iterations"), '%s: %s' % (_("Optimal Tool. Finding the distances between each two elements. Iterations"),
str(geo_len))) str(geo_len)))
min_dict = dict() self.min_dict = dict()
idx = 1 idx = 1
for geo in total_geo: for geo in total_geo:
for s_geo in total_geo[idx:]: for s_geo in total_geo[idx:]:
@@ -333,10 +342,10 @@ class ToolOptimal(FlatCAMTool):
loc = (float('%.*f' % (self.decimals, (min(loc_1.x, loc_2.x) + (abs(dx) / 2)))), loc = (float('%.*f' % (self.decimals, (min(loc_1.x, loc_2.x) + (abs(dx) / 2)))),
float('%.*f' % (self.decimals, (min(loc_1.y, loc_2.y) + (abs(dy) / 2))))) float('%.*f' % (self.decimals, (min(loc_1.y, loc_2.y) + (abs(dy) / 2)))))
if dist in min_dict: if dist in self.min_dict:
min_dict[dist].append(loc) self.min_dict[dist].append(loc)
else: else:
min_dict[dist] = [loc] self.min_dict[dist] = [loc]
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]))
@@ -349,19 +358,19 @@ class ToolOptimal(FlatCAMTool):
app_obj.inform.emit( app_obj.inform.emit(
_("Optimal Tool. Finding the minimum distance.")) _("Optimal Tool. Finding the minimum distance."))
min_list = list(min_dict.keys()) min_list = list(self.min_dict.keys())
min_dist = min(min_list) min_dist = min(min_list)
min_dist_string = '%.*f' % (self.decimals, float(min_dist)) min_dist_string = '%.*f' % (self.decimals, float(min_dist))
self.result_entry.set_value(min_dist_string) self.result_entry.set_value(min_dist_string)
freq = len(min_dict[min_dist]) freq = len(self.min_dict[min_dist])
freq = '%d' % int(freq) freq = '%d' % int(freq)
self.freq_entry.set_value(freq) self.freq_entry.set_value(freq)
min_locations = min_dict.pop(min_dist) min_locations = self.min_dict.pop(min_dist)
self.update_text.emit(min_locations) self.update_text.emit(min_locations)
self.update_sec_text.emit(min_dict) self.update_sec_distances.emit(self.min_dict)
app_obj.inform.emit('[success] %s' % _("Optimal Tool. Finished successfully.")) app_obj.inform.emit('[success] %s' % _("Optimal Tool. Finished successfully."))
except Exception as ee: except Exception as ee:
@@ -379,11 +388,9 @@ class ToolOptimal(FlatCAMTool):
loc = eval(self.selected_text) loc = eval(self.selected_text)
self.app.on_jump_to(custom_location=loc) self.app.on_jump_to(custom_location=loc)
except Exception as e: except Exception as e:
log.debug("ToolOptimal.on_locate_position() --> %s" % str(e))
self.app.inform.emit("[ERROR_NOTCL] The selected text is no valid location in the format (x, y).") self.app.inform.emit("[ERROR_NOTCL] The selected text is no valid location in the format (x, y).")
def on_locate_sec_position(self):
pass
def on_update_text(self, data): def on_update_text(self, data):
txt = '' txt = ''
for loc in data: for loc in data:
@@ -391,9 +398,6 @@ class ToolOptimal(FlatCAMTool):
self.locations_textb.setPlainText(txt) self.locations_textb.setPlainText(txt)
self.locate_button.setDisabled(False) self.locate_button.setDisabled(False)
def on_update_sec_text(self, data):
pass
def on_textbox_clicked(self): def on_textbox_clicked(self):
# new cursor - select all document # new cursor - select all document
cursor = self.locations_textb.textCursor() cursor = self.locations_textb.textCursor()
@@ -415,8 +419,72 @@ class ToolOptimal(FlatCAMTool):
self.selected_text = cursor.selectedText() self.selected_text = cursor.selectedText()
def on_textbox_sec_clicked(self): def on_update_sec_distances_txt(self, data):
pass distance_list = sorted(list(data.keys()))
txt = ''
for loc in distance_list:
txt += '%s\n' % str(loc)
self.distances_textb.setPlainText(txt)
self.locate_sec_button.setDisabled(False)
def on_distances_textb_clicked(self):
# new cursor - select all document
cursor = self.distances_textb.textCursor()
cursor.select(QtGui.QTextCursor.Document)
# clear previous selection highlight
tmp = cursor.blockFormat()
tmp.clearBackground()
cursor.setBlockFormat(tmp)
# new cursor - select the current line
cursor = self.distances_textb.textCursor()
cursor.select(QtGui.QTextCursor.LineUnderCursor)
# highlight the current selected line
tmp = cursor.blockFormat()
tmp.setBackground(QtGui.QBrush(QtCore.Qt.yellow))
cursor.setBlockFormat(tmp)
distance_text = cursor.selectedText()
key_in_min_dict = eval(distance_text)
self.on_update_locations_text(dist=key_in_min_dict)
def on_update_locations_text(self, dist):
distance_list = self.min_dict[dist]
txt = ''
for loc in distance_list:
txt += '%s\n' % str(loc)
self.locations_sec_textb.setPlainText(txt)
def on_locations_sec_clicked(self):
# new cursor - select all document
cursor = self.locations_sec_textb.textCursor()
cursor.select(QtGui.QTextCursor.Document)
# clear previous selection highlight
tmp = cursor.blockFormat()
tmp.clearBackground()
cursor.setBlockFormat(tmp)
# new cursor - select the current line
cursor = self.locations_sec_textb.textCursor()
cursor.select(QtGui.QTextCursor.LineUnderCursor)
# highlight the current selected line
tmp = cursor.blockFormat()
tmp.setBackground(QtGui.QBrush(QtCore.Qt.yellow))
cursor.setBlockFormat(tmp)
self.selected_locations_text = cursor.selectedText()
def on_locate_sec_position(self):
try:
loc = eval(self.selected_locations_text)
self.app.on_jump_to(custom_location=loc)
except Exception as e:
log.debug("ToolOptimal.on_locate_sec_position() --> %s" % str(e))
self.app.inform.emit("[ERROR_NOTCL] The selected text is no valid location in the format (x, y).")
def reset_fields(self): def reset_fields(self):
self.gerber_object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex())) self.gerber_object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex()))