jpcgt/flatcam/Beta слито с Beta
937
FlatCAMApp.py
179
FlatCAMCommon.py
|
@ -505,6 +505,94 @@ class ToolsDB(QtWidgets.QWidget):
|
||||||
self.table_widget.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
|
self.table_widget.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
|
||||||
table_hlay.addWidget(self.table_widget)
|
table_hlay.addWidget(self.table_widget)
|
||||||
|
|
||||||
|
# set the number of columns and the headers tool tips
|
||||||
|
self.configure_table()
|
||||||
|
|
||||||
|
# pal = QtGui.QPalette()
|
||||||
|
# pal.setColor(QtGui.QPalette.Background, Qt.white)
|
||||||
|
|
||||||
|
# New Bookmark
|
||||||
|
new_vlay = QtWidgets.QVBoxLayout()
|
||||||
|
layout.addLayout(new_vlay)
|
||||||
|
|
||||||
|
# new_tool_lbl = QtWidgets.QLabel('<b>%s</b>' % _("New Tool"))
|
||||||
|
# new_vlay.addWidget(new_tool_lbl, alignment=QtCore.Qt.AlignBottom)
|
||||||
|
|
||||||
|
self.buttons_frame = QtWidgets.QFrame()
|
||||||
|
self.buttons_frame.setContentsMargins(0, 0, 0, 0)
|
||||||
|
layout.addWidget(self.buttons_frame)
|
||||||
|
self.buttons_box = QtWidgets.QHBoxLayout()
|
||||||
|
self.buttons_box.setContentsMargins(0, 0, 0, 0)
|
||||||
|
self.buttons_frame.setLayout(self.buttons_box)
|
||||||
|
self.buttons_frame.show()
|
||||||
|
|
||||||
|
add_entry_btn = FCButton(_("Add Geometry Tool in DB"))
|
||||||
|
add_entry_btn.setToolTip(
|
||||||
|
_("Add a new tool in the Tools Database.\n"
|
||||||
|
"It will be used in the Geometry UI.\n"
|
||||||
|
"You can edit it after it is added.")
|
||||||
|
)
|
||||||
|
self.buttons_box.addWidget(add_entry_btn)
|
||||||
|
|
||||||
|
# add_fct_entry_btn = FCButton(_("Add Paint/NCC Tool in DB"))
|
||||||
|
# add_fct_entry_btn.setToolTip(
|
||||||
|
# _("Add a new tool in the Tools Database.\n"
|
||||||
|
# "It will be used in the Paint/NCC Tools UI.\n"
|
||||||
|
# "You can edit it after it is added.")
|
||||||
|
# )
|
||||||
|
# self.buttons_box.addWidget(add_fct_entry_btn)
|
||||||
|
|
||||||
|
remove_entry_btn = FCButton(_("Delete Tool from DB"))
|
||||||
|
remove_entry_btn.setToolTip(
|
||||||
|
_("Remove a selection of tools in the Tools Database.")
|
||||||
|
)
|
||||||
|
self.buttons_box.addWidget(remove_entry_btn)
|
||||||
|
|
||||||
|
export_db_btn = FCButton(_("Export DB"))
|
||||||
|
export_db_btn.setToolTip(
|
||||||
|
_("Save the Tools Database to a custom text file.")
|
||||||
|
)
|
||||||
|
self.buttons_box.addWidget(export_db_btn)
|
||||||
|
|
||||||
|
import_db_btn = FCButton(_("Import DB"))
|
||||||
|
import_db_btn.setToolTip(
|
||||||
|
_("Load the Tools Database information's from a custom text file.")
|
||||||
|
)
|
||||||
|
self.buttons_box.addWidget(import_db_btn)
|
||||||
|
|
||||||
|
self.add_tool_from_db = FCButton(_("Add Tool from Tools DB"))
|
||||||
|
self.add_tool_from_db.setToolTip(
|
||||||
|
_("Add a new tool in the Tools Table of the\n"
|
||||||
|
"active Geometry object after selecting a tool\n"
|
||||||
|
"in the Tools Database.")
|
||||||
|
)
|
||||||
|
self.add_tool_from_db.hide()
|
||||||
|
|
||||||
|
self.cancel_tool_from_db = FCButton(_("Cancel"))
|
||||||
|
self.cancel_tool_from_db.hide()
|
||||||
|
|
||||||
|
hlay = QtWidgets.QHBoxLayout()
|
||||||
|
layout.addLayout(hlay)
|
||||||
|
hlay.addWidget(self.add_tool_from_db)
|
||||||
|
hlay.addWidget(self.cancel_tool_from_db)
|
||||||
|
hlay.addStretch()
|
||||||
|
|
||||||
|
# ##############################################################################
|
||||||
|
# ######################## SIGNALS #############################################
|
||||||
|
# ##############################################################################
|
||||||
|
|
||||||
|
add_entry_btn.clicked.connect(self.on_tool_add)
|
||||||
|
remove_entry_btn.clicked.connect(self.on_tool_delete)
|
||||||
|
export_db_btn.clicked.connect(self.on_export_tools_db_file)
|
||||||
|
import_db_btn.clicked.connect(self.on_import_tools_db_file)
|
||||||
|
# closebtn.clicked.connect(self.accept)
|
||||||
|
|
||||||
|
self.add_tool_from_db.clicked.connect(self.on_tool_requested_from_app)
|
||||||
|
self.cancel_tool_from_db.clicked.connect(self.on_cancel_tool)
|
||||||
|
|
||||||
|
self.setup_db_ui()
|
||||||
|
|
||||||
|
def configure_table(self):
|
||||||
self.table_widget.setColumnCount(27)
|
self.table_widget.setColumnCount(27)
|
||||||
# self.table_widget.setColumnWidth(0, 20)
|
# self.table_widget.setColumnWidth(0, 20)
|
||||||
self.table_widget.setHorizontalHeaderLabels(
|
self.table_widget.setHorizontalHeaderLabels(
|
||||||
|
@ -648,83 +736,8 @@ class ToolsDB(QtWidgets.QWidget):
|
||||||
_("End Z.\n"
|
_("End Z.\n"
|
||||||
"A position on Z plane to move immediately after job stop."))
|
"A position on Z plane to move immediately after job stop."))
|
||||||
|
|
||||||
# pal = QtGui.QPalette()
|
|
||||||
# pal.setColor(QtGui.QPalette.Background, Qt.white)
|
|
||||||
|
|
||||||
# New Bookmark
|
|
||||||
new_vlay = QtWidgets.QVBoxLayout()
|
|
||||||
layout.addLayout(new_vlay)
|
|
||||||
|
|
||||||
# new_tool_lbl = QtWidgets.QLabel('<b>%s</b>' % _("New Tool"))
|
|
||||||
# new_vlay.addWidget(new_tool_lbl, alignment=QtCore.Qt.AlignBottom)
|
|
||||||
|
|
||||||
self.buttons_frame = QtWidgets.QFrame()
|
|
||||||
self.buttons_frame.setContentsMargins(0, 0, 0, 0)
|
|
||||||
layout.addWidget(self.buttons_frame)
|
|
||||||
self.buttons_box = QtWidgets.QHBoxLayout()
|
|
||||||
self.buttons_box.setContentsMargins(0, 0, 0, 0)
|
|
||||||
self.buttons_frame.setLayout(self.buttons_box)
|
|
||||||
self.buttons_frame.show()
|
|
||||||
|
|
||||||
add_entry_btn = FCButton(_("Add Tool to Tools DB"))
|
|
||||||
add_entry_btn.setToolTip(
|
|
||||||
_("Add a new tool in the Tools Database.\n"
|
|
||||||
"You can edit it after it is added.")
|
|
||||||
)
|
|
||||||
remove_entry_btn = FCButton(_("Remove Tool from Tools DB"))
|
|
||||||
remove_entry_btn.setToolTip(
|
|
||||||
_("Remove a selection of tools in the Tools Database.")
|
|
||||||
)
|
|
||||||
export_db_btn = FCButton(_("Export Tool DB"))
|
|
||||||
export_db_btn.setToolTip(
|
|
||||||
_("Save the Tools Database to a custom text file.")
|
|
||||||
)
|
|
||||||
import_db_btn = FCButton(_("Import Tool DB"))
|
|
||||||
import_db_btn.setToolTip(
|
|
||||||
_("Load the Tools Database information's from a custom text file.")
|
|
||||||
)
|
|
||||||
# button_hlay.addStretch()
|
|
||||||
self.buttons_box.addWidget(add_entry_btn)
|
|
||||||
self.buttons_box.addWidget(remove_entry_btn)
|
|
||||||
|
|
||||||
self.buttons_box.addWidget(export_db_btn)
|
|
||||||
self.buttons_box.addWidget(import_db_btn)
|
|
||||||
# self.buttons_box.addWidget(closebtn)
|
|
||||||
|
|
||||||
self.add_tool_from_db = FCButton(_("Add Tool from Tools DB"))
|
|
||||||
self.add_tool_from_db.setToolTip(
|
|
||||||
_("Add a new tool in the Tools Table of the\n"
|
|
||||||
"active Geometry object after selecting a tool\n"
|
|
||||||
"in the Tools Database.")
|
|
||||||
)
|
|
||||||
self.add_tool_from_db.hide()
|
|
||||||
|
|
||||||
self.cancel_tool_from_db = FCButton(_("Cancel"))
|
|
||||||
self.cancel_tool_from_db.hide()
|
|
||||||
|
|
||||||
hlay = QtWidgets.QHBoxLayout()
|
|
||||||
layout.addLayout(hlay)
|
|
||||||
hlay.addWidget(self.add_tool_from_db)
|
|
||||||
hlay.addWidget(self.cancel_tool_from_db)
|
|
||||||
hlay.addStretch()
|
|
||||||
|
|
||||||
# ##############################################################################
|
|
||||||
# ######################## SIGNALS #############################################
|
|
||||||
# ##############################################################################
|
|
||||||
|
|
||||||
add_entry_btn.clicked.connect(self.on_tool_add)
|
|
||||||
remove_entry_btn.clicked.connect(self.on_tool_delete)
|
|
||||||
export_db_btn.clicked.connect(self.on_export_tools_db_file)
|
|
||||||
import_db_btn.clicked.connect(self.on_import_tools_db_file)
|
|
||||||
# closebtn.clicked.connect(self.accept)
|
|
||||||
|
|
||||||
self.add_tool_from_db.clicked.connect(self.on_tool_requested_from_app)
|
|
||||||
self.cancel_tool_from_db.clicked.connect(self.on_cancel_tool)
|
|
||||||
|
|
||||||
self.setup_db_ui()
|
|
||||||
|
|
||||||
def setup_db_ui(self):
|
def setup_db_ui(self):
|
||||||
filename = self.app.data_path + '/tools_db.FlatConfig'
|
filename = self.app.data_path + '/tools_db.FlatDB'
|
||||||
|
|
||||||
# load the database tools from the file
|
# load the database tools from the file
|
||||||
try:
|
try:
|
||||||
|
@ -1007,7 +1020,17 @@ class ToolsDB(QtWidgets.QWidget):
|
||||||
|
|
||||||
dict_elem = dict()
|
dict_elem = dict()
|
||||||
dict_elem['name'] = 'new_tool'
|
dict_elem['name'] = 'new_tool'
|
||||||
dict_elem['tooldia'] = self.app.defaults["geometry_cnctooldia"]
|
if type(self.app.defaults["geometry_cnctooldia"]) == float:
|
||||||
|
dict_elem['tooldia'] = self.app.defaults["geometry_cnctooldia"]
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
tools_string = self.app.defaults["geometry_cnctooldia"].split(",")
|
||||||
|
tools_diameters = [eval(a) for a in tools_string if a != '']
|
||||||
|
dict_elem['tooldia'] = tools_diameters[0] if tools_diameters else 0.0
|
||||||
|
except Exception as e:
|
||||||
|
self.app.log.debug("ToolDB.on_tool_add() --> %s" % str(e))
|
||||||
|
return
|
||||||
|
|
||||||
dict_elem['offset'] = 'Path'
|
dict_elem['offset'] = 'Path'
|
||||||
dict_elem['offset_value'] = 0.0
|
dict_elem['offset_value'] = 0.0
|
||||||
dict_elem['type'] = 'Rough'
|
dict_elem['type'] = 'Rough'
|
||||||
|
@ -1151,7 +1174,7 @@ class ToolsDB(QtWidgets.QWidget):
|
||||||
def on_save_tools_db(self, silent=False):
|
def on_save_tools_db(self, silent=False):
|
||||||
self.app.log.debug("ToolsDB.on_save_button() --> Saving Tools Database to file.")
|
self.app.log.debug("ToolsDB.on_save_button() --> Saving Tools Database to file.")
|
||||||
|
|
||||||
filename = self.app.data_path + "/tools_db.FlatConfig"
|
filename = self.app.data_path + "/tools_db.FlatDB"
|
||||||
|
|
||||||
# Preferences save, update the color of the Tools DB Tab text
|
# Preferences save, update the color of the Tools DB Tab text
|
||||||
for idx in range(self.app.ui.plot_tab_area.count()):
|
for idx in range(self.app.ui.plot_tab_area.count()):
|
||||||
|
|
|
@ -659,8 +659,8 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
|
||||||
|
|
||||||
self.units_found = self.app.defaults['units']
|
self.units_found = self.app.defaults['units']
|
||||||
|
|
||||||
self.fill_color = self.app.defaults['global_plot_fill']
|
self.fill_color = self.app.defaults['gerber_plot_fill']
|
||||||
self.outline_color = self.app.defaults['global_plot_line']
|
self.outline_color = self.app.defaults['gerber_plot_line']
|
||||||
|
|
||||||
# Attributes to be included in serialization
|
# Attributes to be included in serialization
|
||||||
# Always append to it because it carries contents
|
# Always append to it because it carries contents
|
||||||
|
@ -738,6 +738,10 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
|
||||||
|
|
||||||
self.ui.tool_type_label.hide()
|
self.ui.tool_type_label.hide()
|
||||||
self.ui.tool_type_radio.hide()
|
self.ui.tool_type_radio.hide()
|
||||||
|
|
||||||
|
# override the Preferences Value; in Basic mode the Tool Type is always Circular ('C1')
|
||||||
|
self.ui.tool_type_radio.set_value('circular')
|
||||||
|
|
||||||
self.ui.tipdialabel.hide()
|
self.ui.tipdialabel.hide()
|
||||||
self.ui.tipdia_spinner.hide()
|
self.ui.tipdia_spinner.hide()
|
||||||
self.ui.tipanglelabel.hide()
|
self.ui.tipanglelabel.hide()
|
||||||
|
@ -1436,7 +1440,10 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
|
||||||
def iso_init(geo_obj, app_obj):
|
def iso_init(geo_obj, app_obj):
|
||||||
# Propagate options
|
# Propagate options
|
||||||
geo_obj.options["cnctooldia"] = str(self.options["isotooldia"])
|
geo_obj.options["cnctooldia"] = str(self.options["isotooldia"])
|
||||||
geo_obj.tool_type = self.ui.tool_type_radio.get_value().upper()
|
if self.ui.tool_type_radio.get_value() == 'v':
|
||||||
|
geo_obj.tool_type = 'V'
|
||||||
|
else:
|
||||||
|
geo_obj.tool_type = 'C1'
|
||||||
|
|
||||||
# if milling type is climb then the move is counter-clockwise around features
|
# if milling type is climb then the move is counter-clockwise around features
|
||||||
mill_t = 1 if milling_type == 'cl' else 0
|
mill_t = 1 if milling_type == 'cl' else 0
|
||||||
|
@ -1783,7 +1790,7 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
|
||||||
if 'color' in kwargs:
|
if 'color' in kwargs:
|
||||||
color = kwargs['color']
|
color = kwargs['color']
|
||||||
else:
|
else:
|
||||||
color = self.app.defaults['global_plot_fill']
|
color = self.app.defaults['gerber_plot_fill']
|
||||||
|
|
||||||
if 'marked_aperture' not in kwargs:
|
if 'marked_aperture' not in kwargs:
|
||||||
return
|
return
|
||||||
|
@ -3529,7 +3536,9 @@ class FlatCAMExcellon(FlatCAMObj, Excellon):
|
||||||
# Plot Excellon (All polygons?)
|
# Plot Excellon (All polygons?)
|
||||||
if self.options["solid"]:
|
if self.options["solid"]:
|
||||||
for geo in self.solid_geometry:
|
for geo in self.solid_geometry:
|
||||||
self.add_shape(shape=geo, color='#750000BF', face_color='#C40000BF',
|
self.add_shape(shape=geo,
|
||||||
|
color=self.app.defaults["excellon_plot_line"],
|
||||||
|
face_color=self.app.defaults["excellon_plot_fill"],
|
||||||
visible=visible,
|
visible=visible,
|
||||||
layer=2)
|
layer=2)
|
||||||
else:
|
else:
|
||||||
|
@ -3588,7 +3597,15 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
|
||||||
})
|
})
|
||||||
|
|
||||||
if "cnctooldia" not in self.options:
|
if "cnctooldia" not in self.options:
|
||||||
self.options["cnctooldia"] = self.app.defaults["geometry_cnctooldia"]
|
if type(self.app.defaults["geometry_cnctooldia"]) == float:
|
||||||
|
self.options["cnctooldia"] = self.app.defaults["geometry_cnctooldia"]
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
tools_string = self.app.defaults["geometry_cnctooldia"].split(",")
|
||||||
|
tools_diameters = [eval(a) for a in tools_string if a != '']
|
||||||
|
self.options["cnctooldia"] = tools_diameters[0] if tools_diameters else 0.0
|
||||||
|
except Exception as e:
|
||||||
|
log.debug("FlatCAMObj.FlatCAMGeometry.init() --> %s" % str(e))
|
||||||
|
|
||||||
self.options["startz"] = self.app.defaults["geometry_startz"]
|
self.options["startz"] = self.app.defaults["geometry_startz"]
|
||||||
|
|
||||||
|
@ -4059,7 +4076,6 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
|
||||||
|
|
||||||
# I use lambda's because the connected functions have parameters that could be used in certain scenarios
|
# I use lambda's because the connected functions have parameters that could be used in certain scenarios
|
||||||
self.ui.addtool_btn.clicked.connect(lambda: self.on_tool_add())
|
self.ui.addtool_btn.clicked.connect(lambda: self.on_tool_add())
|
||||||
self.ui.addtool_entry.returnPressed.connect(self.on_tool_add)
|
|
||||||
|
|
||||||
self.ui.copytool_btn.clicked.connect(lambda: self.on_tool_copy())
|
self.ui.copytool_btn.clicked.connect(lambda: self.on_tool_copy())
|
||||||
self.ui.deltool_btn.clicked.connect(lambda: self.on_tool_delete())
|
self.ui.deltool_btn.clicked.connect(lambda: self.on_tool_delete())
|
||||||
|
@ -4112,11 +4128,6 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
|
||||||
except (TypeError, AttributeError):
|
except (TypeError, AttributeError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
try:
|
|
||||||
self.ui.addtool_entry.returnPressed.disconnect()
|
|
||||||
except (TypeError, AttributeError):
|
|
||||||
pass
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.ui.copytool_btn.clicked.disconnect()
|
self.ui.copytool_btn.clicked.disconnect()
|
||||||
except (TypeError, AttributeError):
|
except (TypeError, AttributeError):
|
||||||
|
@ -5778,12 +5789,15 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
|
||||||
|
|
||||||
return factor
|
return factor
|
||||||
|
|
||||||
def plot_element(self, element, color='#FF0000FF', visible=None):
|
def plot_element(self, element, color=None, visible=None):
|
||||||
|
|
||||||
|
if color is None:
|
||||||
|
color = '#FF0000FF'
|
||||||
|
|
||||||
visible = visible if visible else self.options['plot']
|
visible = visible if visible else self.options['plot']
|
||||||
try:
|
try:
|
||||||
for sub_el in element:
|
for sub_el in element:
|
||||||
self.plot_element(sub_el)
|
self.plot_element(sub_el, color=color)
|
||||||
|
|
||||||
except TypeError: # Element is not iterable...
|
except TypeError: # Element is not iterable...
|
||||||
# if self.app.is_legacy is False:
|
# if self.app.is_legacy is False:
|
||||||
|
@ -5810,12 +5824,14 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
|
||||||
if self.multigeo is True: # geo multi tool usage
|
if self.multigeo is True: # geo multi tool usage
|
||||||
for tooluid_key in self.tools:
|
for tooluid_key in self.tools:
|
||||||
solid_geometry = self.tools[tooluid_key]['solid_geometry']
|
solid_geometry = self.tools[tooluid_key]['solid_geometry']
|
||||||
self.plot_element(solid_geometry, visible=visible)
|
self.plot_element(solid_geometry, visible=visible,
|
||||||
|
color=self.app.defaults["geometry_plot_line"])
|
||||||
else:
|
else:
|
||||||
# plot solid geometry that may be an direct attribute of the geometry object
|
# plot solid geometry that may be an direct attribute of the geometry object
|
||||||
# for SingleGeo
|
# for SingleGeo
|
||||||
if self.solid_geometry:
|
if self.solid_geometry:
|
||||||
self.plot_element(self.solid_geometry, visible=visible)
|
self.plot_element(self.solid_geometry, visible=visible,
|
||||||
|
color=self.app.defaults["geometry_plot_line"])
|
||||||
|
|
||||||
# self.plot_element(self.solid_geometry, visible=self.options['plot'])
|
# self.plot_element(self.solid_geometry, visible=self.options['plot'])
|
||||||
|
|
||||||
|
|
41
README.md
|
@ -9,19 +9,58 @@ CAD program, and create G-Code for Isolation routing.
|
||||||
|
|
||||||
=================================================
|
=================================================
|
||||||
|
|
||||||
|
27.12.2019
|
||||||
|
|
||||||
|
- updated the POT file and the translation files for German, Spanish and French languages
|
||||||
|
|
||||||
|
26.12.2019
|
||||||
|
|
||||||
|
- modified the ToolDB class and changed some strings
|
||||||
|
- Preferences classes now have access to the App attributes through app.setup_obj_classes() method
|
||||||
|
- moved app.setup_obj_classes() upper in the App.__init__()
|
||||||
|
- added a new Preferences setting allowing to modify the mouse cursor color
|
||||||
|
- remade the GUI in Preferences -> General grouping the settings in a more clear way
|
||||||
|
- made available the Jump To function in Excellon Editor
|
||||||
|
- added a clean_up() method in all the Editor Tools that need it, to be run when aborting using the ESC key
|
||||||
|
- fixed an error in the Gerber parser; it did not took into consideration the aperture size declared before the beginning of a Gerber region. Detected for Gerber files generated by KiCAD 5.x
|
||||||
|
- in Panelize Tool made sure that for Gerber objects if one of the apertures is without geometry then it is ignored
|
||||||
|
- further modifications in Preferences -> General GUI
|
||||||
|
- further modifications in Preferences -> General GUI - extended the changes
|
||||||
|
- in Legacy(2D) graphic engine made to work the mouse color change
|
||||||
|
- theme changing is no longer auto-reboot upon change; it require now to press a button
|
||||||
|
- cleaned the Preferences classes and added the signals and signal slots in those classes, removing them from the main app class
|
||||||
|
- each FlatCAM object found in Preferences has it's own set of controls for changing the colors
|
||||||
|
- added a set of gray icons to be used when the theme is complete dark (for now it is useful only for MacOS with dark theme because at the moment the app is not styled to dark UI except the plot area)
|
||||||
|
|
||||||
|
25.12.2019
|
||||||
|
|
||||||
|
- fixed an issue in old default file detection and in saving the factory defaults file
|
||||||
|
- in Preferences window removed the Import/Export Preferences buttons because they are redundant with the entries in the File -> Menu -> Backup. and added a button to Restore Defaults
|
||||||
|
- when in Basic mode the Tool type of the tool in the Geometry UI Tool Table after isolating a Gerber object is automatically selected as 'C1'
|
||||||
|
- let the multiprocessing Pool have as many processes as needed
|
||||||
|
- added a new Preferences setting allowing a custom mouse line width (to make it thicker or thinner)
|
||||||
|
- changed the extension of the Tool Database file to FlatDB for easy recognition (in the future double clicking such a file might import the new tools in the FC database)
|
||||||
|
|
||||||
|
24.12.2019
|
||||||
|
|
||||||
|
- edited some icons so they don't contain white background
|
||||||
|
- fixed an incorrect usage of object in the app.select_objects() method
|
||||||
|
- fixed a typo in ToolDB.on_tool_add()
|
||||||
|
|
||||||
23.12.2019
|
23.12.2019
|
||||||
|
|
||||||
- some fixes in the Legacy(2D) graphic mode regarding the possibility of changing the color of the Gerber objects
|
- some fixes in the Legacy(2D) graphic mode regarding the possibility of changing the color of the Gerber objects
|
||||||
- added a method to darken the outline color for Gerber objects when they have the color set
|
- added a method to darken the outline color for Gerber objects when they have the color set
|
||||||
- when Printing as PDF Gerber objects now the rendered color is the print color
|
- when Printing as PDF Gerber objects now the rendered color is the print color
|
||||||
- speed up the plotting in OpenGL(3D) graphic mode
|
- speed up the plotting in OpenGL(3D) graphic mode
|
||||||
- spped up the color setting for Gerber object when using the OpenGL(3D) graphic mode
|
- speed up the color setting for Gerber object when using the OpenGL(3D) graphic mode
|
||||||
- setting color for Gerber objects work on a selection of Gerber objects
|
- setting color for Gerber objects work on a selection of Gerber objects
|
||||||
- ~~when the selection is changed in the Project Tree the selection shape on canvas is deleted~~
|
- ~~when the selection is changed in the Project Tree the selection shape on canvas is deleted~~
|
||||||
- if an object is selected on Project Tree and it does not have the selection shape drawn, first click on canvas over it will draw the selection shape
|
- if an object is selected on Project Tree and it does not have the selection shape drawn, first click on canvas over it will draw the selection shape
|
||||||
- in Tool Transform added a new feature named 'Buffer'. For Geometry and Gerber objects will create (and replace) a geometry at a distance from the original geometry and for Excellon will adjust the Tool diameters
|
- in Tool Transform added a new feature named 'Buffer'. For Geometry and Gerber objects will create (and replace) a geometry at a distance from the original geometry and for Excellon will adjust the Tool diameters
|
||||||
- solved issue #355 - when the tool diameter field in the Edit → Preferences → Geometry → Geometry General → Tools → Tool dia is only one the app failed to read it
|
- solved issue #355 - when the tool diameter field in the Edit → Preferences → Geometry → Geometry General → Tools → Tool dia is only one the app failed to read it
|
||||||
- solved issue #356 - in Tools DB can not be added more than one tool if a translation is active
|
- solved issue #356 - in Tools DB can not be added more than one tool if a translation is active
|
||||||
|
- some changes related to the fact that the geometry default tool diameter value can be comma separated string of tool diameters
|
||||||
|
|
||||||
22.12.2019
|
22.12.2019
|
||||||
|
|
||||||
|
|
24
camlib.py
|
@ -3466,11 +3466,20 @@ class CNCjob(Geometry):
|
||||||
flat_geometry = self.flatten(temp_solid_geometry, pathonly=True)
|
flat_geometry = self.flatten(temp_solid_geometry, pathonly=True)
|
||||||
log.debug("%d paths" % len(flat_geometry))
|
log.debug("%d paths" % len(flat_geometry))
|
||||||
|
|
||||||
|
if type(self.app.defaults["geometry_cnctooldia"]) == float:
|
||||||
|
default_dia = self.app.defaults["geometry_cnctooldia"]
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
tools_string = self.defaults["geometry_cnctooldia"].split(",")
|
||||||
|
tools_diameters = [eval(a) for a in tools_string if a != '']
|
||||||
|
default_dia = tools_diameters[0] if tools_diameters else 0.0
|
||||||
|
except Exception as e:
|
||||||
|
self.app.log.debug("camlib.CNCJob.generate_from_geometry_2() --> %s" % str(e))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.tooldia = float(tooldia) if tooldia else self.app.defaults["geometry_cnctooldia"]
|
self.tooldia = float(tooldia) if tooldia else default_dia
|
||||||
except ValueError:
|
except ValueError:
|
||||||
self.tooldia = [float(el) for el in tooldia.split(',') if el != ''] if tooldia is not None else \
|
self.tooldia = [float(el) for el in tooldia.split(',') if el != ''] if tooldia is not None else default_dia
|
||||||
self.app.defaults["geometry_cnctooldia"]
|
|
||||||
|
|
||||||
self.z_cut = float(z_cut) if z_cut is not None else self.app.defaults["geometry_cutz"]
|
self.z_cut = float(z_cut) if z_cut is not None else self.app.defaults["geometry_cutz"]
|
||||||
self.z_move = float(z_move) if z_move is not None else self.app.defaults["geometry_travelz"]
|
self.z_move = float(z_move) if z_move is not None else self.app.defaults["geometry_travelz"]
|
||||||
|
@ -4243,8 +4252,7 @@ class CNCjob(Geometry):
|
||||||
# return fig
|
# return fig
|
||||||
|
|
||||||
def plot2(self, tooldia=None, dpi=75, margin=0.1, gcode_parsed=None,
|
def plot2(self, tooldia=None, dpi=75, margin=0.1, gcode_parsed=None,
|
||||||
color={"T": ["#F0E24D4C", "#B5AB3A4C"], "C": ["#5E6CFFFF", "#4650BDFF"]},
|
color=None, alpha={"T": 0.3, "C": 1.0}, tool_tolerance=0.0005, obj=None, visible=False, kind='all'):
|
||||||
alpha={"T": 0.3, "C": 1.0}, tool_tolerance=0.0005, obj=None, visible=False, kind='all'):
|
|
||||||
"""
|
"""
|
||||||
Plots the G-code job onto the given axes.
|
Plots the G-code job onto the given axes.
|
||||||
|
|
||||||
|
@ -4261,6 +4269,12 @@ class CNCjob(Geometry):
|
||||||
"""
|
"""
|
||||||
# units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().upper()
|
# units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().upper()
|
||||||
|
|
||||||
|
if color is None:
|
||||||
|
color = {
|
||||||
|
"T": [self.app.defaults["cncjob_travel_fill"], self.app.defaults["cncjob_travel_line"]],
|
||||||
|
"C": [self.app.defaults["cncjob_plot_fill"], self.app.defaults["cncjob_plot_line"]]
|
||||||
|
}
|
||||||
|
|
||||||
gcode_parsed = gcode_parsed if gcode_parsed else self.gcode_parsed
|
gcode_parsed = gcode_parsed if gcode_parsed else self.gcode_parsed
|
||||||
path_num = 0
|
path_num = 0
|
||||||
|
|
||||||
|
|
|
@ -56,8 +56,7 @@ class FCDrillAdd(FCShapeTool):
|
||||||
item = self.draw_app.tools_table_exc.item((self.draw_app.last_tool_selected - 1), 1)
|
item = self.draw_app.tools_table_exc.item((self.draw_app.last_tool_selected - 1), 1)
|
||||||
self.draw_app.tools_table_exc.setCurrentItem(item)
|
self.draw_app.tools_table_exc.setCurrentItem(item)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
self.draw_app.app.inform.emit('[WARNING_NOTCL] %s' %
|
self.draw_app.app.inform.emit('[WARNING_NOTCL] %s' % _("To add a drill first select a tool"))
|
||||||
_("To add a drill first select a tool"))
|
|
||||||
self.draw_app.select_tool("drill_select")
|
self.draw_app.select_tool("drill_select")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -75,6 +74,8 @@ class FCDrillAdd(FCShapeTool):
|
||||||
|
|
||||||
self.draw_app.app.inform.emit(_("Click to place ..."))
|
self.draw_app.app.inform.emit(_("Click to place ..."))
|
||||||
|
|
||||||
|
self.draw_app.app.jump_signal.connect(lambda x: self.draw_app.update_utility_geometry(data=x))
|
||||||
|
|
||||||
# Switch notebook to Selected page
|
# Switch notebook to Selected page
|
||||||
self.draw_app.app.ui.notebook.setCurrentWidget(self.draw_app.app.ui.selected_tab)
|
self.draw_app.app.ui.notebook.setCurrentWidget(self.draw_app.app.ui.selected_tab)
|
||||||
|
|
||||||
|
@ -119,8 +120,18 @@ class FCDrillAdd(FCShapeTool):
|
||||||
self.geometry = DrawToolShape(self.util_shape(self.points))
|
self.geometry = DrawToolShape(self.util_shape(self.points))
|
||||||
self.draw_app.in_action = False
|
self.draw_app.in_action = False
|
||||||
self.complete = True
|
self.complete = True
|
||||||
self.draw_app.app.inform.emit('[success] %s' %
|
self.draw_app.app.inform.emit('[success] %s' % _("Done. Drill added."))
|
||||||
_("Done. Drill added."))
|
self.draw_app.app.jump_signal.disconnect()
|
||||||
|
|
||||||
|
def clean_up(self):
|
||||||
|
self.draw_app.selected = list()
|
||||||
|
self.draw_app.tools_table_exc.clearSelection()
|
||||||
|
self.draw_app.plot_all()
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.draw_app.app.jump_signal.disconnect()
|
||||||
|
except (TypeError, AttributeError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class FCDrillArray(FCShapeTool):
|
class FCDrillArray(FCShapeTool):
|
||||||
|
@ -181,6 +192,8 @@ class FCDrillArray(FCShapeTool):
|
||||||
|
|
||||||
self.draw_app.app.inform.emit(_("Click on target location ..."))
|
self.draw_app.app.inform.emit(_("Click on target location ..."))
|
||||||
|
|
||||||
|
self.draw_app.app.jump_signal.connect(lambda x: self.draw_app.update_utility_geometry(data=x))
|
||||||
|
|
||||||
# Switch notebook to Selected page
|
# Switch notebook to Selected page
|
||||||
self.draw_app.app.ui.notebook.setCurrentWidget(self.draw_app.app.ui.selected_tab)
|
self.draw_app.app.ui.notebook.setCurrentWidget(self.draw_app.app.ui.selected_tab)
|
||||||
|
|
||||||
|
@ -292,7 +305,7 @@ class FCDrillArray(FCShapeTool):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
QtGui.QGuiApplication.restoreOverrideCursor()
|
QtGui.QGuiApplication.restoreOverrideCursor()
|
||||||
except Exception as e:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# add the point to drills if the diameter is a key in the dict, if not, create it add the drill location
|
# add the point to drills if the diameter is a key in the dict, if not, create it add the drill location
|
||||||
|
@ -322,6 +335,7 @@ class FCDrillArray(FCShapeTool):
|
||||||
if (self.drill_angle * self.drill_array_size) > 360:
|
if (self.drill_angle * self.drill_array_size) > 360:
|
||||||
self.draw_app.app.inform.emit('[WARNING_NOTCL] %s' %
|
self.draw_app.app.inform.emit('[WARNING_NOTCL] %s' %
|
||||||
_("Too many drills for the selected spacing angle."))
|
_("Too many drills for the selected spacing angle."))
|
||||||
|
self.draw_app.app.jump_signal.disconnect()
|
||||||
return
|
return
|
||||||
|
|
||||||
radius = distance(self.destination, self.origin)
|
radius = distance(self.destination, self.origin)
|
||||||
|
@ -338,11 +352,21 @@ class FCDrillArray(FCShapeTool):
|
||||||
geo = self.util_shape((x, y))
|
geo = self.util_shape((x, y))
|
||||||
self.geometry.append(DrawToolShape(geo))
|
self.geometry.append(DrawToolShape(geo))
|
||||||
self.complete = True
|
self.complete = True
|
||||||
self.draw_app.app.inform.emit('[success] %s' %
|
self.draw_app.app.inform.emit('[success] %s' % _("Done. Drill Array added."))
|
||||||
_("Done. Drill Array added."))
|
|
||||||
self.draw_app.in_action = False
|
self.draw_app.in_action = False
|
||||||
self.draw_app.array_frame.hide()
|
self.draw_app.array_frame.hide()
|
||||||
return
|
|
||||||
|
self.draw_app.app.jump_signal.disconnect()
|
||||||
|
|
||||||
|
def clean_up(self):
|
||||||
|
self.draw_app.selected = list()
|
||||||
|
self.draw_app.tools_table_exc.clearSelection()
|
||||||
|
self.draw_app.plot_all()
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.draw_app.app.jump_signal.disconnect()
|
||||||
|
except (TypeError, AttributeError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class FCSlot(FCShapeTool):
|
class FCSlot(FCShapeTool):
|
||||||
|
@ -391,6 +415,8 @@ class FCSlot(FCShapeTool):
|
||||||
|
|
||||||
self.draw_app.app.inform.emit(_("Click on target location ..."))
|
self.draw_app.app.inform.emit(_("Click on target location ..."))
|
||||||
|
|
||||||
|
self.draw_app.app.jump_signal.connect(lambda x: self.draw_app.update_utility_geometry(data=x))
|
||||||
|
|
||||||
# Switch notebook to Selected page
|
# Switch notebook to Selected page
|
||||||
self.draw_app.app.ui.notebook.setCurrentWidget(self.draw_app.app.ui.selected_tab)
|
self.draw_app.app.ui.notebook.setCurrentWidget(self.draw_app.app.ui.selected_tab)
|
||||||
|
|
||||||
|
@ -531,9 +557,19 @@ class FCSlot(FCShapeTool):
|
||||||
|
|
||||||
self.draw_app.in_action = False
|
self.draw_app.in_action = False
|
||||||
self.complete = True
|
self.complete = True
|
||||||
self.draw_app.app.inform.emit('[success] %s' %
|
self.draw_app.app.inform.emit('[success] %s' % _("Done. Adding Slot completed."))
|
||||||
_("Done. Adding Slot completed."))
|
|
||||||
self.draw_app.slot_frame.hide()
|
self.draw_app.slot_frame.hide()
|
||||||
|
self.draw_app.app.jump_signal.disconnect()
|
||||||
|
|
||||||
|
def clean_up(self):
|
||||||
|
self.draw_app.selected = list()
|
||||||
|
self.draw_app.tools_table_exc.clearSelection()
|
||||||
|
self.draw_app.plot_all()
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.draw_app.app.jump_signal.disconnect()
|
||||||
|
except (TypeError, AttributeError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class FCSlotArray(FCShapeTool):
|
class FCSlotArray(FCShapeTool):
|
||||||
|
@ -600,6 +636,8 @@ class FCSlotArray(FCShapeTool):
|
||||||
|
|
||||||
self.draw_app.app.inform.emit(_("Click on target location ..."))
|
self.draw_app.app.inform.emit(_("Click on target location ..."))
|
||||||
|
|
||||||
|
self.draw_app.app.jump_signal.connect(lambda x: self.draw_app.update_utility_geometry(data=x))
|
||||||
|
|
||||||
# Switch notebook to Selected page
|
# Switch notebook to Selected page
|
||||||
self.draw_app.app.ui.notebook.setCurrentWidget(self.draw_app.app.ui.selected_tab)
|
self.draw_app.app.ui.notebook.setCurrentWidget(self.draw_app.app.ui.selected_tab)
|
||||||
|
|
||||||
|
@ -821,6 +859,7 @@ class FCSlotArray(FCShapeTool):
|
||||||
if (self.slot_angle * self.slot_array_size) > 360:
|
if (self.slot_angle * self.slot_array_size) > 360:
|
||||||
self.draw_app.app.inform.emit('[WARNING_NOTCL] %s' %
|
self.draw_app.app.inform.emit('[WARNING_NOTCL] %s' %
|
||||||
_("Too many Slots for the selected spacing angle."))
|
_("Too many Slots for the selected spacing angle."))
|
||||||
|
self.draw_app.app.jump_signal.disconnect()
|
||||||
return
|
return
|
||||||
|
|
||||||
radius = distance(self.destination, self.origin)
|
radius = distance(self.destination, self.origin)
|
||||||
|
@ -842,18 +881,22 @@ class FCSlotArray(FCShapeTool):
|
||||||
|
|
||||||
self.geometry.append(DrawToolShape(geo))
|
self.geometry.append(DrawToolShape(geo))
|
||||||
self.complete = True
|
self.complete = True
|
||||||
self.draw_app.app.inform.emit('[success] %s' %
|
self.draw_app.app.inform.emit('[success] %s' % _("Done. Slot Array added."))
|
||||||
_("Done. Slot Array added."))
|
|
||||||
self.draw_app.in_action = False
|
self.draw_app.in_action = False
|
||||||
self.draw_app.slot_frame.hide()
|
self.draw_app.slot_frame.hide()
|
||||||
self.draw_app.slot_array_frame.hide()
|
self.draw_app.slot_array_frame.hide()
|
||||||
return
|
self.draw_app.app.jump_signal.disconnect()
|
||||||
|
|
||||||
def clean_up(self):
|
def clean_up(self):
|
||||||
self.draw_app.selected = []
|
self.draw_app.selected = list()
|
||||||
self.draw_app.apertures_table.clearSelection()
|
self.draw_app.tools_table_exc.clearSelection()
|
||||||
self.draw_app.plot_all()
|
self.draw_app.plot_all()
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.draw_app.app.jump_signal.disconnect()
|
||||||
|
except (TypeError, AttributeError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class FCDrillResize(FCShapeTool):
|
class FCDrillResize(FCShapeTool):
|
||||||
def __init__(self, draw_app):
|
def __init__(self, draw_app):
|
||||||
|
@ -1084,6 +1127,16 @@ class FCDrillResize(FCShapeTool):
|
||||||
# MS: always return to the Select Tool
|
# MS: always return to the Select Tool
|
||||||
self.draw_app.select_tool("drill_select")
|
self.draw_app.select_tool("drill_select")
|
||||||
|
|
||||||
|
def clean_up(self):
|
||||||
|
self.draw_app.selected = list()
|
||||||
|
self.draw_app.tools_table_exc.clearSelection()
|
||||||
|
self.draw_app.plot_all()
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.draw_app.app.jump_signal.disconnect()
|
||||||
|
except (TypeError, AttributeError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class FCDrillMove(FCShapeTool):
|
class FCDrillMove(FCShapeTool):
|
||||||
def __init__(self, draw_app):
|
def __init__(self, draw_app):
|
||||||
|
@ -1112,6 +1165,8 @@ class FCDrillMove(FCShapeTool):
|
||||||
dia_on_row = self.draw_app.tools_table_exc.item(row, 1).text()
|
dia_on_row = self.draw_app.tools_table_exc.item(row, 1).text()
|
||||||
self.selected_dia_list.append(float(dia_on_row))
|
self.selected_dia_list.append(float(dia_on_row))
|
||||||
|
|
||||||
|
self.draw_app.app.jump_signal.connect(lambda x: self.draw_app.update_utility_geometry(data=x))
|
||||||
|
|
||||||
# Switch notebook to Selected page
|
# Switch notebook to Selected page
|
||||||
self.draw_app.app.ui.notebook.setCurrentWidget(self.draw_app.app.ui.selected_tab)
|
self.draw_app.app.ui.notebook.setCurrentWidget(self.draw_app.app.ui.selected_tab)
|
||||||
|
|
||||||
|
@ -1156,8 +1211,8 @@ class FCDrillMove(FCShapeTool):
|
||||||
sel_shapes_to_be_deleted = []
|
sel_shapes_to_be_deleted = []
|
||||||
|
|
||||||
self.draw_app.build_ui()
|
self.draw_app.build_ui()
|
||||||
self.draw_app.app.inform.emit('[success] %s' %
|
self.draw_app.app.inform.emit('[success] %s' % _("Done. Drill(s) Move completed."))
|
||||||
_("Done. Drill(s) Move completed."))
|
self.draw_app.app.jump_signal.disconnect()
|
||||||
|
|
||||||
def selection_bbox(self):
|
def selection_bbox(self):
|
||||||
geo_list = []
|
geo_list = []
|
||||||
|
@ -1212,6 +1267,16 @@ class FCDrillMove(FCShapeTool):
|
||||||
ss_el = None
|
ss_el = None
|
||||||
return DrawToolUtilityShape(ss_el)
|
return DrawToolUtilityShape(ss_el)
|
||||||
|
|
||||||
|
def clean_up(self):
|
||||||
|
self.draw_app.selected = list()
|
||||||
|
self.draw_app.tools_table_exc.clearSelection()
|
||||||
|
self.draw_app.plot_all()
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.draw_app.app.jump_signal.disconnect()
|
||||||
|
except (TypeError, AttributeError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class FCDrillCopy(FCDrillMove):
|
class FCDrillCopy(FCDrillMove):
|
||||||
def __init__(self, draw_app):
|
def __init__(self, draw_app):
|
||||||
|
@ -1254,8 +1319,18 @@ class FCDrillCopy(FCDrillMove):
|
||||||
sel_shapes_to_be_deleted = []
|
sel_shapes_to_be_deleted = []
|
||||||
|
|
||||||
self.draw_app.build_ui()
|
self.draw_app.build_ui()
|
||||||
self.draw_app.app.inform.emit('[success] %s' %
|
self.draw_app.app.inform.emit('[success] %s' % _("Done. Drill(s) copied."))
|
||||||
_("Done. Drill(s) copied."))
|
self.draw_app.app.jump_signal.disconnect()
|
||||||
|
|
||||||
|
def clean_up(self):
|
||||||
|
self.draw_app.selected = list()
|
||||||
|
self.draw_app.tools_table_exc.clearSelection()
|
||||||
|
self.draw_app.plot_all()
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.draw_app.app.jump_signal.disconnect()
|
||||||
|
except (TypeError, AttributeError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class FCDrillSelect(DrawTool):
|
class FCDrillSelect(DrawTool):
|
||||||
|
@ -2919,6 +2994,11 @@ class FlatCAMExcEditor(QtCore.QObject):
|
||||||
except (TypeError, AttributeError):
|
except (TypeError, AttributeError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.app.jump_signal.disconnect()
|
||||||
|
except (TypeError, AttributeError):
|
||||||
|
pass
|
||||||
|
|
||||||
def clear(self):
|
def clear(self):
|
||||||
self.active_tool = None
|
self.active_tool = None
|
||||||
# self.shape_buffer = []
|
# self.shape_buffer = []
|
||||||
|
@ -3690,6 +3770,7 @@ class FlatCAMExcEditor(QtCore.QObject):
|
||||||
|
|
||||||
# Update cursor
|
# Update cursor
|
||||||
self.app.app_cursor.set_data(np.asarray([(x, y)]), symbol='++', edge_color=self.app.cursor_color_3D,
|
self.app.app_cursor.set_data(np.asarray([(x, y)]), symbol='++', edge_color=self.app.cursor_color_3D,
|
||||||
|
edge_width=self.app.defaults["global_cursor_width"],
|
||||||
size=self.app.defaults["global_cursor_size"])
|
size=self.app.defaults["global_cursor_size"])
|
||||||
|
|
||||||
self.snap_x = x
|
self.snap_x = x
|
||||||
|
@ -3709,12 +3790,7 @@ class FlatCAMExcEditor(QtCore.QObject):
|
||||||
"%.4f " % (dx, dy))
|
"%.4f " % (dx, dy))
|
||||||
|
|
||||||
# ## Utility geometry (animated)
|
# ## Utility geometry (animated)
|
||||||
geo = self.active_tool.utility_geometry(data=(x, y))
|
self.update_utility_geometry(data=(x, y))
|
||||||
|
|
||||||
if isinstance(geo, DrawToolShape) and geo.geo is not None:
|
|
||||||
# Remove any previous utility shape
|
|
||||||
self.tool_shape.clear(update=True)
|
|
||||||
self.draw_utility_geometry(geo=geo)
|
|
||||||
|
|
||||||
# ## Selection area on canvas section # ##
|
# ## Selection area on canvas section # ##
|
||||||
if event_is_dragging == 1 and event.button == 1:
|
if event_is_dragging == 1 and event.button == 1:
|
||||||
|
@ -3739,8 +3815,17 @@ class FlatCAMExcEditor(QtCore.QObject):
|
||||||
|
|
||||||
# Update cursor
|
# Update cursor
|
||||||
self.app.app_cursor.set_data(np.asarray([(x, y)]), symbol='++', edge_color=self.app.cursor_color_3D,
|
self.app.app_cursor.set_data(np.asarray([(x, y)]), symbol='++', edge_color=self.app.cursor_color_3D,
|
||||||
|
edge_width=self.app.defaults["global_cursor_width"],
|
||||||
size=self.app.defaults["global_cursor_size"])
|
size=self.app.defaults["global_cursor_size"])
|
||||||
|
|
||||||
|
def update_utility_geometry(self, data):
|
||||||
|
# ### Utility geometry (animated) ###
|
||||||
|
geo = self.active_tool.utility_geometry(data=data)
|
||||||
|
if isinstance(geo, DrawToolShape) and geo.geo is not None:
|
||||||
|
# Remove any previous utility shape
|
||||||
|
self.tool_shape.clear(update=True)
|
||||||
|
self.draw_utility_geometry(geo=geo)
|
||||||
|
|
||||||
def on_canvas_key_release(self, event):
|
def on_canvas_key_release(self, event):
|
||||||
self.key = None
|
self.key = None
|
||||||
|
|
||||||
|
|
|
@ -1883,6 +1883,7 @@ class DrawTool(object):
|
||||||
# Jump to coords
|
# Jump to coords
|
||||||
if key == QtCore.Qt.Key_J or key == 'J':
|
if key == QtCore.Qt.Key_J or key == 'J':
|
||||||
self.draw_app.app.on_jump_to()
|
self.draw_app.app.on_jump_to()
|
||||||
|
return
|
||||||
|
|
||||||
def utility_geometry(self, data=None):
|
def utility_geometry(self, data=None):
|
||||||
return None
|
return None
|
||||||
|
@ -1988,6 +1989,15 @@ class FCCircle(FCShapeTool):
|
||||||
|
|
||||||
self.draw_app.app.inform.emit('[success] %s' % _("Done. Adding Circle completed."))
|
self.draw_app.app.inform.emit('[success] %s' % _("Done. Adding Circle completed."))
|
||||||
|
|
||||||
|
def clean_up(self):
|
||||||
|
self.draw_app.selected = list()
|
||||||
|
self.draw_app.plot_all()
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.draw_app.app.jump_signal.disconnect()
|
||||||
|
except (TypeError, AttributeError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class FCArc(FCShapeTool):
|
class FCArc(FCShapeTool):
|
||||||
def __init__(self, draw_app):
|
def __init__(self, draw_app):
|
||||||
|
@ -2213,6 +2223,15 @@ class FCArc(FCShapeTool):
|
||||||
|
|
||||||
self.draw_app.app.inform.emit('[success] %s' % _("Done. Arc completed."))
|
self.draw_app.app.inform.emit('[success] %s' % _("Done. Arc completed."))
|
||||||
|
|
||||||
|
def clean_up(self):
|
||||||
|
self.draw_app.selected = list()
|
||||||
|
self.draw_app.plot_all()
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.draw_app.app.jump_signal.disconnect()
|
||||||
|
except (TypeError, AttributeError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class FCRectangle(FCShapeTool):
|
class FCRectangle(FCShapeTool):
|
||||||
"""
|
"""
|
||||||
|
@ -2271,6 +2290,15 @@ class FCRectangle(FCShapeTool):
|
||||||
self.draw_app.app.jump_signal.disconnect()
|
self.draw_app.app.jump_signal.disconnect()
|
||||||
self.draw_app.app.inform.emit('[success] %s' % _("Done. Rectangle completed."))
|
self.draw_app.app.inform.emit('[success] %s' % _("Done. Rectangle completed."))
|
||||||
|
|
||||||
|
def clean_up(self):
|
||||||
|
self.draw_app.selected = list()
|
||||||
|
self.draw_app.plot_all()
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.draw_app.app.jump_signal.disconnect()
|
||||||
|
except (TypeError, AttributeError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class FCPolygon(FCShapeTool):
|
class FCPolygon(FCShapeTool):
|
||||||
"""
|
"""
|
||||||
|
@ -2345,6 +2373,15 @@ class FCPolygon(FCShapeTool):
|
||||||
self.draw_app.draw_utility_geometry(geo=geo)
|
self.draw_app.draw_utility_geometry(geo=geo)
|
||||||
return _("Backtracked one point ...")
|
return _("Backtracked one point ...")
|
||||||
|
|
||||||
|
def clean_up(self):
|
||||||
|
self.draw_app.selected = list()
|
||||||
|
self.draw_app.plot_all()
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.draw_app.app.jump_signal.disconnect()
|
||||||
|
except (TypeError, AttributeError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class FCPath(FCPolygon):
|
class FCPath(FCPolygon):
|
||||||
"""
|
"""
|
||||||
|
@ -2401,6 +2438,15 @@ class FCPath(FCPolygon):
|
||||||
self.draw_app.draw_utility_geometry(geo=geo)
|
self.draw_app.draw_utility_geometry(geo=geo)
|
||||||
return _("Backtracked one point ...")
|
return _("Backtracked one point ...")
|
||||||
|
|
||||||
|
def clean_up(self):
|
||||||
|
self.draw_app.selected = list()
|
||||||
|
self.draw_app.plot_all()
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.draw_app.app.jump_signal.disconnect()
|
||||||
|
except (TypeError, AttributeError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class FCSelect(DrawTool):
|
class FCSelect(DrawTool):
|
||||||
def __init__(self, draw_app):
|
def __init__(self, draw_app):
|
||||||
|
@ -2533,6 +2579,15 @@ class FCExplode(FCShapeTool):
|
||||||
self.draw_app.on_shape_complete()
|
self.draw_app.on_shape_complete()
|
||||||
self.draw_app.app.inform.emit('[success] %s...' % _("Done. Polygons exploded into lines."))
|
self.draw_app.app.inform.emit('[success] %s...' % _("Done. Polygons exploded into lines."))
|
||||||
|
|
||||||
|
def clean_up(self):
|
||||||
|
self.draw_app.selected = list()
|
||||||
|
self.draw_app.plot_all()
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.draw_app.app.jump_signal.disconnect()
|
||||||
|
except (TypeError, AttributeError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class FCMove(FCShapeTool):
|
class FCMove(FCShapeTool):
|
||||||
def __init__(self, draw_app):
|
def __init__(self, draw_app):
|
||||||
|
@ -2555,8 +2610,10 @@ class FCMove(FCShapeTool):
|
||||||
if len(self.draw_app.get_selected()) == 0:
|
if len(self.draw_app.get_selected()) == 0:
|
||||||
self.draw_app.app.inform.emit('[WARNING_NOTCL] %s...' %
|
self.draw_app.app.inform.emit('[WARNING_NOTCL] %s...' %
|
||||||
_("MOVE: No shape selected. Select a shape to move"))
|
_("MOVE: No shape selected. Select a shape to move"))
|
||||||
|
return
|
||||||
else:
|
else:
|
||||||
self.draw_app.app.inform.emit(_(" MOVE: Click on reference point ..."))
|
self.draw_app.app.inform.emit(_(" MOVE: Click on reference point ..."))
|
||||||
|
self.draw_app.app.jump_signal.connect(lambda x: self.draw_app.update_utility_geometry(data=x))
|
||||||
|
|
||||||
def set_origin(self, origin):
|
def set_origin(self, origin):
|
||||||
self.draw_app.app.inform.emit(_(" Click on destination point ..."))
|
self.draw_app.app.inform.emit(_(" Click on destination point ..."))
|
||||||
|
@ -2593,8 +2650,8 @@ class FCMove(FCShapeTool):
|
||||||
# Delete old
|
# Delete old
|
||||||
self.draw_app.delete_selected()
|
self.draw_app.delete_selected()
|
||||||
self.complete = True
|
self.complete = True
|
||||||
self.draw_app.app.inform.emit('[success] %s' %
|
self.draw_app.app.inform.emit('[success] %s' % _("Done. Geometry(s) Move completed."))
|
||||||
_("Done. Geometry(s) Move completed."))
|
self.draw_app.app.jump_signal.disconnect()
|
||||||
|
|
||||||
def selection_bbox(self):
|
def selection_bbox(self):
|
||||||
geo_list = []
|
geo_list = []
|
||||||
|
@ -2701,6 +2758,15 @@ class FCMove(FCShapeTool):
|
||||||
log.error("[ERROR] Something went bad. %s" % str(e))
|
log.error("[ERROR] Something went bad. %s" % str(e))
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
def clean_up(self):
|
||||||
|
self.draw_app.selected = list()
|
||||||
|
self.draw_app.plot_all()
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.draw_app.app.jump_signal.disconnect()
|
||||||
|
except (TypeError, AttributeError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class FCCopy(FCMove):
|
class FCCopy(FCMove):
|
||||||
def __init__(self, draw_app):
|
def __init__(self, draw_app):
|
||||||
|
@ -2715,6 +2781,16 @@ class FCCopy(FCMove):
|
||||||
for geom in self.draw_app.get_selected()]
|
for geom in self.draw_app.get_selected()]
|
||||||
self.complete = True
|
self.complete = True
|
||||||
self.draw_app.app.inform.emit('[success] %s' % _("Done. Geometry(s) Copy completed."))
|
self.draw_app.app.inform.emit('[success] %s' % _("Done. Geometry(s) Copy completed."))
|
||||||
|
self.draw_app.app.jump_signal.disconnect()
|
||||||
|
|
||||||
|
def clean_up(self):
|
||||||
|
self.draw_app.selected = list()
|
||||||
|
self.draw_app.plot_all()
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.draw_app.app.jump_signal.disconnect()
|
||||||
|
except (TypeError, AttributeError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class FCText(FCShapeTool):
|
class FCText(FCShapeTool):
|
||||||
|
@ -2732,11 +2808,12 @@ class FCText(FCShapeTool):
|
||||||
|
|
||||||
self.app = draw_app.app
|
self.app = draw_app.app
|
||||||
|
|
||||||
self.draw_app.app.inform.emit(_("Click on 1st corner ..."))
|
self.draw_app.app.inform.emit(_("Click on 1st point ..."))
|
||||||
self.origin = (0, 0)
|
self.origin = (0, 0)
|
||||||
|
|
||||||
self.text_gui = TextInputTool(self.app)
|
self.text_gui = TextInputTool(self.app)
|
||||||
self.text_gui.run()
|
self.text_gui.run()
|
||||||
|
self.draw_app.app.jump_signal.connect(lambda x: self.draw_app.update_utility_geometry(data=x))
|
||||||
|
|
||||||
def click(self, point):
|
def click(self, point):
|
||||||
# Create new geometry
|
# Create new geometry
|
||||||
|
@ -2754,9 +2831,11 @@ class FCText(FCShapeTool):
|
||||||
self.text_gui.text_path = []
|
self.text_gui.text_path = []
|
||||||
self.text_gui.hide_tool()
|
self.text_gui.hide_tool()
|
||||||
self.draw_app.select_tool('select')
|
self.draw_app.select_tool('select')
|
||||||
|
self.draw_app.app.jump_signal.disconnect()
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
self.draw_app.app.inform.emit('[WARNING_NOTCL] %s' % _("No text to add."))
|
self.draw_app.app.inform.emit('[WARNING_NOTCL] %s' % _("No text to add."))
|
||||||
|
self.draw_app.app.jump_signal.disconnect()
|
||||||
return
|
return
|
||||||
|
|
||||||
self.text_gui.text_path = []
|
self.text_gui.text_path = []
|
||||||
|
@ -2780,6 +2859,15 @@ class FCText(FCShapeTool):
|
||||||
except Exception:
|
except Exception:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
def clean_up(self):
|
||||||
|
self.draw_app.selected = list()
|
||||||
|
self.draw_app.plot_all()
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.draw_app.app.jump_signal.disconnect()
|
||||||
|
except (TypeError, AttributeError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class FCBuffer(FCShapeTool):
|
class FCBuffer(FCShapeTool):
|
||||||
def __init__(self, draw_app):
|
def __init__(self, draw_app):
|
||||||
|
@ -2909,6 +2997,16 @@ class FCBuffer(FCShapeTool):
|
||||||
self.draw_app.select_tool("select")
|
self.draw_app.select_tool("select")
|
||||||
self.buff_tool.hide_tool()
|
self.buff_tool.hide_tool()
|
||||||
|
|
||||||
|
def clean_up(self):
|
||||||
|
self.draw_app.selected = list()
|
||||||
|
self.draw_app.plot_all()
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.draw_app.app.jump_signal.disconnect()
|
||||||
|
except (TypeError, AttributeError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class FCEraser(FCShapeTool):
|
class FCEraser(FCShapeTool):
|
||||||
def __init__(self, draw_app):
|
def __init__(self, draw_app):
|
||||||
|
@ -2931,6 +3029,7 @@ class FCEraser(FCShapeTool):
|
||||||
|
|
||||||
# Switch notebook to Selected page
|
# Switch notebook to Selected page
|
||||||
self.draw_app.app.ui.notebook.setCurrentWidget(self.draw_app.app.ui.selected_tab)
|
self.draw_app.app.ui.notebook.setCurrentWidget(self.draw_app.app.ui.selected_tab)
|
||||||
|
self.draw_app.app.jump_signal.connect(lambda x: self.draw_app.update_utility_geometry(data=x))
|
||||||
|
|
||||||
def set_origin(self, origin):
|
def set_origin(self, origin):
|
||||||
self.origin = origin
|
self.origin = origin
|
||||||
|
@ -2982,8 +3081,8 @@ class FCEraser(FCShapeTool):
|
||||||
|
|
||||||
self.draw_app.delete_utility_geometry()
|
self.draw_app.delete_utility_geometry()
|
||||||
self.draw_app.plot_all()
|
self.draw_app.plot_all()
|
||||||
self.draw_app.app.inform.emit('[success] %s' %
|
self.draw_app.app.inform.emit('[success] %s' % _("Done. Eraser tool action completed."))
|
||||||
_("Done. Eraser tool action completed."))
|
self.draw_app.app.jump_signal.disconnect()
|
||||||
|
|
||||||
def utility_geometry(self, data=None):
|
def utility_geometry(self, data=None):
|
||||||
"""
|
"""
|
||||||
|
@ -3013,9 +3112,14 @@ class FCEraser(FCShapeTool):
|
||||||
return DrawToolUtilityShape(geo_list)
|
return DrawToolUtilityShape(geo_list)
|
||||||
|
|
||||||
def clean_up(self):
|
def clean_up(self):
|
||||||
self.draw_app.selected = []
|
self.draw_app.selected = list()
|
||||||
self.draw_app.plot_all()
|
self.draw_app.plot_all()
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.draw_app.app.jump_signal.disconnect()
|
||||||
|
except (TypeError, AttributeError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class FCPaint(FCShapeTool):
|
class FCPaint(FCShapeTool):
|
||||||
def __init__(self, draw_app):
|
def __init__(self, draw_app):
|
||||||
|
@ -3557,6 +3661,11 @@ class FlatCAMGeoEditor(QtCore.QObject):
|
||||||
except (TypeError, AttributeError):
|
except (TypeError, AttributeError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.app.jump_signal.disconnect()
|
||||||
|
except (TypeError, AttributeError):
|
||||||
|
pass
|
||||||
|
|
||||||
def add_shape(self, shape):
|
def add_shape(self, shape):
|
||||||
"""
|
"""
|
||||||
Adds a shape to the shape storage.
|
Adds a shape to the shape storage.
|
||||||
|
@ -3831,6 +3940,7 @@ class FlatCAMGeoEditor(QtCore.QObject):
|
||||||
|
|
||||||
# Update cursor
|
# Update cursor
|
||||||
self.app.app_cursor.set_data(np.asarray([(x, y)]), symbol='++', edge_color=self.app.cursor_color_3D,
|
self.app.app_cursor.set_data(np.asarray([(x, y)]), symbol='++', edge_color=self.app.cursor_color_3D,
|
||||||
|
edge_width=self.app.defaults["global_cursor_width"],
|
||||||
size=self.app.defaults["global_cursor_size"])
|
size=self.app.defaults["global_cursor_size"])
|
||||||
|
|
||||||
self.snap_x = x
|
self.snap_x = x
|
||||||
|
|
|
@ -240,6 +240,8 @@ class FCPad(FCShapeTool):
|
||||||
|
|
||||||
self.draw_app.app.inform.emit(_("Click to place ..."))
|
self.draw_app.app.inform.emit(_("Click to place ..."))
|
||||||
|
|
||||||
|
self.draw_app.app.jump_signal.connect(lambda x: self.draw_app.update_utility_geometry(data=x))
|
||||||
|
|
||||||
# Switch notebook to Selected page
|
# Switch notebook to Selected page
|
||||||
self.draw_app.app.ui.notebook.setCurrentWidget(self.draw_app.app.ui.selected_tab)
|
self.draw_app.app.ui.notebook.setCurrentWidget(self.draw_app.app.ui.selected_tab)
|
||||||
|
|
||||||
|
@ -378,13 +380,17 @@ class FCPad(FCShapeTool):
|
||||||
|
|
||||||
self.draw_app.in_action = False
|
self.draw_app.in_action = False
|
||||||
self.complete = True
|
self.complete = True
|
||||||
self.draw_app.app.inform.emit('[success] %s' %
|
self.draw_app.app.inform.emit('[success] %s' % _("Done. Adding Pad completed."))
|
||||||
_("Done. Adding Pad completed."))
|
self.draw_app.app.jump_signal.disconnect()
|
||||||
|
|
||||||
def clean_up(self):
|
def clean_up(self):
|
||||||
self.draw_app.selected = []
|
self.draw_app.selected = []
|
||||||
self.draw_app.apertures_table.clearSelection()
|
self.draw_app.apertures_table.clearSelection()
|
||||||
self.draw_app.plot_all()
|
self.draw_app.plot_all()
|
||||||
|
try:
|
||||||
|
self.draw_app.app.jump_signal.disconnect()
|
||||||
|
except (TypeError, AttributeError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class FCPadArray(FCShapeTool):
|
class FCPadArray(FCShapeTool):
|
||||||
|
@ -464,6 +470,8 @@ class FCPadArray(FCShapeTool):
|
||||||
|
|
||||||
self.draw_app.app.inform.emit(_("Click on target location ..."))
|
self.draw_app.app.inform.emit(_("Click on target location ..."))
|
||||||
|
|
||||||
|
self.draw_app.app.jump_signal.connect(lambda x: self.draw_app.update_utility_geometry(data=x))
|
||||||
|
|
||||||
# Switch notebook to Selected page
|
# Switch notebook to Selected page
|
||||||
self.draw_app.app.ui.notebook.setCurrentWidget(self.draw_app.app.ui.selected_tab)
|
self.draw_app.app.ui.notebook.setCurrentWidget(self.draw_app.app.ui.selected_tab)
|
||||||
|
|
||||||
|
@ -726,12 +734,16 @@ class FCPadArray(FCShapeTool):
|
||||||
_("Done. Pad Array added."))
|
_("Done. Pad Array added."))
|
||||||
self.draw_app.in_action = False
|
self.draw_app.in_action = False
|
||||||
self.draw_app.array_frame.hide()
|
self.draw_app.array_frame.hide()
|
||||||
return
|
self.draw_app.app.jump_signal.disconnect()
|
||||||
|
|
||||||
def clean_up(self):
|
def clean_up(self):
|
||||||
self.draw_app.selected = []
|
self.draw_app.selected = []
|
||||||
self.draw_app.apertures_table.clearSelection()
|
self.draw_app.apertures_table.clearSelection()
|
||||||
self.draw_app.plot_all()
|
self.draw_app.plot_all()
|
||||||
|
try:
|
||||||
|
self.draw_app.app.jump_signal.disconnect()
|
||||||
|
except (TypeError, AttributeError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class FCPoligonize(FCShapeTool):
|
class FCPoligonize(FCShapeTool):
|
||||||
|
@ -1077,6 +1089,10 @@ class FCRegion(FCShapeTool):
|
||||||
self.draw_app.selected = []
|
self.draw_app.selected = []
|
||||||
self.draw_app.apertures_table.clearSelection()
|
self.draw_app.apertures_table.clearSelection()
|
||||||
self.draw_app.plot_all()
|
self.draw_app.plot_all()
|
||||||
|
try:
|
||||||
|
self.draw_app.app.jump_signal.disconnect()
|
||||||
|
except (TypeError, AttributeError):
|
||||||
|
pass
|
||||||
|
|
||||||
def on_key(self, key):
|
def on_key(self, key):
|
||||||
# Jump to coords
|
# Jump to coords
|
||||||
|
@ -1190,6 +1206,10 @@ class FCTrack(FCRegion):
|
||||||
self.draw_app.selected = []
|
self.draw_app.selected = []
|
||||||
self.draw_app.apertures_table.clearSelection()
|
self.draw_app.apertures_table.clearSelection()
|
||||||
self.draw_app.plot_all()
|
self.draw_app.plot_all()
|
||||||
|
try:
|
||||||
|
self.draw_app.app.jump_signal.disconnect()
|
||||||
|
except (TypeError, AttributeError):
|
||||||
|
pass
|
||||||
|
|
||||||
def click(self, point):
|
def click(self, point):
|
||||||
self.draw_app.in_action = True
|
self.draw_app.in_action = True
|
||||||
|
@ -1472,6 +1492,10 @@ class FCDisc(FCShapeTool):
|
||||||
self.draw_app.selected = []
|
self.draw_app.selected = []
|
||||||
self.draw_app.apertures_table.clearSelection()
|
self.draw_app.apertures_table.clearSelection()
|
||||||
self.draw_app.plot_all()
|
self.draw_app.plot_all()
|
||||||
|
try:
|
||||||
|
self.draw_app.app.jump_signal.disconnect()
|
||||||
|
except (TypeError, AttributeError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class FCSemiDisc(FCShapeTool):
|
class FCSemiDisc(FCShapeTool):
|
||||||
|
@ -1737,6 +1761,10 @@ class FCSemiDisc(FCShapeTool):
|
||||||
self.draw_app.selected = []
|
self.draw_app.selected = []
|
||||||
self.draw_app.apertures_table.clearSelection()
|
self.draw_app.apertures_table.clearSelection()
|
||||||
self.draw_app.plot_all()
|
self.draw_app.plot_all()
|
||||||
|
try:
|
||||||
|
self.draw_app.app.jump_signal.disconnect()
|
||||||
|
except (TypeError, AttributeError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class FCScale(FCShapeTool):
|
class FCScale(FCShapeTool):
|
||||||
|
@ -1921,6 +1949,8 @@ class FCApertureMove(FCShapeTool):
|
||||||
# Switch notebook to Selected page
|
# Switch notebook to Selected page
|
||||||
self.draw_app.app.ui.notebook.setCurrentWidget(self.draw_app.app.ui.selected_tab)
|
self.draw_app.app.ui.notebook.setCurrentWidget(self.draw_app.app.ui.selected_tab)
|
||||||
|
|
||||||
|
self.draw_app.app.jump_signal.connect(lambda x: self.draw_app.update_utility_geometry(data=x))
|
||||||
|
|
||||||
self.sel_limit = self.draw_app.app.defaults["gerber_editor_sel_limit"]
|
self.sel_limit = self.draw_app.app.defaults["gerber_editor_sel_limit"]
|
||||||
self.selection_shape = self.selection_bbox()
|
self.selection_shape = self.selection_bbox()
|
||||||
|
|
||||||
|
@ -2021,14 +2051,19 @@ class FCApertureMove(FCShapeTool):
|
||||||
|
|
||||||
self.draw_app.plot_all()
|
self.draw_app.plot_all()
|
||||||
self.draw_app.build_ui()
|
self.draw_app.build_ui()
|
||||||
self.draw_app.app.inform.emit('[success] %s' %
|
self.draw_app.app.inform.emit('[success] %s' % _("Done. Apertures Move completed."))
|
||||||
_("Done. Apertures Move completed."))
|
self.draw_app.app.jump_signal.disconnect()
|
||||||
|
|
||||||
def clean_up(self):
|
def clean_up(self):
|
||||||
self.draw_app.selected = []
|
self.draw_app.selected = []
|
||||||
self.draw_app.apertures_table.clearSelection()
|
self.draw_app.apertures_table.clearSelection()
|
||||||
self.draw_app.plot_all()
|
self.draw_app.plot_all()
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.draw_app.app.jump_signal.disconnect()
|
||||||
|
except (TypeError, AttributeError):
|
||||||
|
pass
|
||||||
|
|
||||||
def utility_geometry(self, data=None):
|
def utility_geometry(self, data=None):
|
||||||
"""
|
"""
|
||||||
Temporary geometry on screen while using this tool.
|
Temporary geometry on screen while using this tool.
|
||||||
|
@ -2098,8 +2133,8 @@ class FCApertureCopy(FCApertureMove):
|
||||||
sel_shapes_to_be_deleted = []
|
sel_shapes_to_be_deleted = []
|
||||||
|
|
||||||
self.draw_app.build_ui()
|
self.draw_app.build_ui()
|
||||||
self.draw_app.app.inform.emit('[success] %s' %
|
self.draw_app.app.inform.emit('[success] %s' % _("Done. Apertures copied."))
|
||||||
_("Done. Apertures copied."))
|
self.draw_app.app.jump_signal.disconnect()
|
||||||
|
|
||||||
|
|
||||||
class FCEraser(FCShapeTool):
|
class FCEraser(FCShapeTool):
|
||||||
|
@ -2130,6 +2165,8 @@ class FCEraser(FCShapeTool):
|
||||||
# Switch notebook to Selected page
|
# Switch notebook to Selected page
|
||||||
self.draw_app.app.ui.notebook.setCurrentWidget(self.draw_app.app.ui.selected_tab)
|
self.draw_app.app.ui.notebook.setCurrentWidget(self.draw_app.app.ui.selected_tab)
|
||||||
|
|
||||||
|
self.draw_app.app.jump_signal.connect(lambda x: self.draw_app.update_utility_geometry(data=x))
|
||||||
|
|
||||||
self.sel_limit = self.draw_app.app.defaults["gerber_editor_sel_limit"]
|
self.sel_limit = self.draw_app.app.defaults["gerber_editor_sel_limit"]
|
||||||
|
|
||||||
def set_origin(self, origin):
|
def set_origin(self, origin):
|
||||||
|
@ -2206,13 +2243,17 @@ class FCEraser(FCShapeTool):
|
||||||
|
|
||||||
self.draw_app.delete_utility_geometry()
|
self.draw_app.delete_utility_geometry()
|
||||||
self.draw_app.plot_all()
|
self.draw_app.plot_all()
|
||||||
self.draw_app.app.inform.emit('[success] %s' %
|
self.draw_app.app.inform.emit('[success] %s' % _("Done. Eraser tool action completed."))
|
||||||
_("Done. Eraser tool action completed."))
|
self.draw_app.app.jump_signal.disconnect()
|
||||||
|
|
||||||
def clean_up(self):
|
def clean_up(self):
|
||||||
self.draw_app.selected = []
|
self.draw_app.selected = []
|
||||||
self.draw_app.apertures_table.clearSelection()
|
self.draw_app.apertures_table.clearSelection()
|
||||||
self.draw_app.plot_all()
|
self.draw_app.plot_all()
|
||||||
|
try:
|
||||||
|
self.draw_app.app.jump_signal.disconnect()
|
||||||
|
except (TypeError, AttributeError):
|
||||||
|
pass
|
||||||
|
|
||||||
def utility_geometry(self, data=None):
|
def utility_geometry(self, data=None):
|
||||||
"""
|
"""
|
||||||
|
@ -3760,6 +3801,11 @@ class FlatCAMGrbEditor(QtCore.QObject):
|
||||||
except (TypeError, AttributeError):
|
except (TypeError, AttributeError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.app.jump_signal.disconnect()
|
||||||
|
except (TypeError, AttributeError):
|
||||||
|
pass
|
||||||
|
|
||||||
def clear(self):
|
def clear(self):
|
||||||
self.active_tool = None
|
self.active_tool = None
|
||||||
self.selected = []
|
self.selected = []
|
||||||
|
@ -4543,6 +4589,7 @@ class FlatCAMGrbEditor(QtCore.QObject):
|
||||||
|
|
||||||
# Update cursor
|
# Update cursor
|
||||||
self.app.app_cursor.set_data(np.asarray([(x, y)]), symbol='++', edge_color=self.app.cursor_color_3D,
|
self.app.app_cursor.set_data(np.asarray([(x, y)]), symbol='++', edge_color=self.app.cursor_color_3D,
|
||||||
|
edge_width=self.app.defaults["global_cursor_width"],
|
||||||
size=self.app.defaults["global_cursor_size"])
|
size=self.app.defaults["global_cursor_size"])
|
||||||
|
|
||||||
self.snap_x = x
|
self.snap_x = x
|
||||||
|
|
|
@ -1211,23 +1211,13 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
|
||||||
self.pref_tab_bottom_layout_1.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
|
self.pref_tab_bottom_layout_1.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
|
||||||
self.pref_tab_bottom_layout.addLayout(self.pref_tab_bottom_layout_1)
|
self.pref_tab_bottom_layout.addLayout(self.pref_tab_bottom_layout_1)
|
||||||
|
|
||||||
self.pref_import_button = QtWidgets.QPushButton()
|
self.pref_defaults_button = QtWidgets.QPushButton()
|
||||||
self.pref_import_button.setText(_("Import Preferences"))
|
self.pref_defaults_button.setText(_("Restore Defaults"))
|
||||||
self.pref_import_button.setMinimumWidth(130)
|
self.pref_defaults_button.setMinimumWidth(130)
|
||||||
self.pref_import_button.setToolTip(
|
self.pref_defaults_button.setToolTip(
|
||||||
_("Import a full set of FlatCAM settings from a file\n"
|
_("Restore the entire set of default values\n"
|
||||||
"previously saved on HDD.\n\n"
|
"to the initial values loaded after first launch."))
|
||||||
"FlatCAM automatically save a 'factory_defaults' file\n"
|
self.pref_tab_bottom_layout_1.addWidget(self.pref_defaults_button)
|
||||||
"on the first start. Do not delete that file."))
|
|
||||||
self.pref_tab_bottom_layout_1.addWidget(self.pref_import_button)
|
|
||||||
|
|
||||||
self.pref_export_button = QtWidgets.QPushButton()
|
|
||||||
self.pref_export_button.setText(_("Export Preferences"))
|
|
||||||
self.pref_export_button.setMinimumWidth(130)
|
|
||||||
self.pref_export_button.setToolTip(
|
|
||||||
_("Export a full set of FlatCAM settings in a file\n"
|
|
||||||
"that is saved on HDD."))
|
|
||||||
self.pref_tab_bottom_layout_1.addWidget(self.pref_export_button)
|
|
||||||
|
|
||||||
self.pref_open_button = QtWidgets.QPushButton()
|
self.pref_open_button = QtWidgets.QPushButton()
|
||||||
self.pref_open_button.setText(_("Open Pref Folder"))
|
self.pref_open_button.setText(_("Open Pref Folder"))
|
||||||
|
@ -1236,6 +1226,17 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
|
||||||
_("Open the folder where FlatCAM save the preferences files."))
|
_("Open the folder where FlatCAM save the preferences files."))
|
||||||
self.pref_tab_bottom_layout_1.addWidget(self.pref_open_button)
|
self.pref_tab_bottom_layout_1.addWidget(self.pref_open_button)
|
||||||
|
|
||||||
|
# Clear Settings
|
||||||
|
self.clear_btn = FCButton('%s' % _('Clear GUI Settings'))
|
||||||
|
self.clear_btn.setMinimumWidth(130)
|
||||||
|
|
||||||
|
self.clear_btn.setToolTip(
|
||||||
|
_("Clear the GUI settings for FlatCAM,\n"
|
||||||
|
"such as: layout, gui state, style, hdpi support etc.")
|
||||||
|
)
|
||||||
|
|
||||||
|
self.pref_tab_bottom_layout_1.addWidget(self.clear_btn)
|
||||||
|
|
||||||
self.pref_tab_bottom_layout_2 = QtWidgets.QHBoxLayout()
|
self.pref_tab_bottom_layout_2 = QtWidgets.QHBoxLayout()
|
||||||
self.pref_tab_bottom_layout_2.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
|
self.pref_tab_bottom_layout_2.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
|
||||||
self.pref_tab_bottom_layout.addLayout(self.pref_tab_bottom_layout_2)
|
self.pref_tab_bottom_layout.addLayout(self.pref_tab_bottom_layout_2)
|
||||||
|
@ -2332,7 +2333,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
|
||||||
:param event: QT event to filter
|
:param event: QT event to filter
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
if self.general_defaults_form.general_gui_set_group.toggle_tooltips_cb.get_value() is False:
|
if self.general_defaults_form.general_app_set_group.toggle_tooltips_cb.get_value() is False:
|
||||||
if event.type() == QtCore.QEvent.ToolTip:
|
if event.type() == QtCore.QEvent.ToolTip:
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
|
@ -3161,15 +3162,12 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
|
||||||
if key == QtCore.Qt.Key_Escape or key == 'Escape':
|
if key == QtCore.Qt.Key_Escape or key == 'Escape':
|
||||||
# TODO: ...?
|
# TODO: ...?
|
||||||
# self.on_tool_select("select")
|
# self.on_tool_select("select")
|
||||||
self.app.inform.emit('[WARNING_NOTCL] %s' %
|
self.app.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled."))
|
||||||
_("Cancelled."))
|
|
||||||
|
|
||||||
self.app.geo_editor.delete_utility_geometry()
|
self.app.geo_editor.delete_utility_geometry()
|
||||||
|
|
||||||
# deselect any shape that might be selected
|
self.app.geo_editor.active_tool.clean_up()
|
||||||
self.app.geo_editor.selected = []
|
|
||||||
|
|
||||||
self.app.geo_editor.replot()
|
|
||||||
self.app.geo_editor.select_tool('select')
|
self.app.geo_editor.select_tool('select')
|
||||||
|
|
||||||
# hide the notebook
|
# hide the notebook
|
||||||
|
@ -3207,6 +3205,25 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
|
||||||
if key == QtCore.Qt.Key_3 or key == '3':
|
if key == QtCore.Qt.Key_3 or key == '3':
|
||||||
self.app.on_select_tab('tool')
|
self.app.on_select_tab('tool')
|
||||||
|
|
||||||
|
# Grid Snap
|
||||||
|
if key == QtCore.Qt.Key_G or key == 'G':
|
||||||
|
self.app.ui.grid_snap_btn.trigger()
|
||||||
|
|
||||||
|
# make sure that the cursor shape is enabled/disabled, too
|
||||||
|
if self.app.geo_editor.options['grid_snap'] is True:
|
||||||
|
self.app.app_cursor.enabled = True
|
||||||
|
else:
|
||||||
|
self.app.app_cursor.enabled = False
|
||||||
|
|
||||||
|
# Corner Snap
|
||||||
|
if key == QtCore.Qt.Key_K or key == 'K':
|
||||||
|
self.app.geo_editor.on_corner_snap()
|
||||||
|
|
||||||
|
if key == QtCore.Qt.Key_V or key == 'V':
|
||||||
|
self.app.on_zoom_fit(None)
|
||||||
|
|
||||||
|
# we do this so we can reuse the following keys while inside a Tool
|
||||||
|
# the above keys are general enough so were left outside
|
||||||
if self.app.geo_editor.active_tool is not None and self.geo_select_btn.isChecked() is False:
|
if self.app.geo_editor.active_tool is not None and self.geo_select_btn.isChecked() is False:
|
||||||
response = self.app.geo_editor.active_tool.on_key(key=key)
|
response = self.app.geo_editor.active_tool.on_key(key=key)
|
||||||
if response is not None:
|
if response is not None:
|
||||||
|
@ -3240,16 +3257,6 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
|
||||||
messagebox.setDefaultButton(QtWidgets.QMessageBox.Ok)
|
messagebox.setDefaultButton(QtWidgets.QMessageBox.Ok)
|
||||||
messagebox.exec_()
|
messagebox.exec_()
|
||||||
|
|
||||||
# Grid Snap
|
|
||||||
if key == QtCore.Qt.Key_G or key == 'G':
|
|
||||||
self.app.ui.grid_snap_btn.trigger()
|
|
||||||
|
|
||||||
# make sure that the cursor shape is enabled/disabled, too
|
|
||||||
if self.app.geo_editor.options['grid_snap'] is True:
|
|
||||||
self.app.app_cursor.enabled = True
|
|
||||||
else:
|
|
||||||
self.app.app_cursor.enabled = False
|
|
||||||
|
|
||||||
# Paint
|
# Paint
|
||||||
if key == QtCore.Qt.Key_I or key == 'I':
|
if key == QtCore.Qt.Key_I or key == 'I':
|
||||||
self.app.geo_editor.select_tool('paint')
|
self.app.geo_editor.select_tool('paint')
|
||||||
|
@ -3258,10 +3265,6 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
|
||||||
if key == QtCore.Qt.Key_J or key == 'J':
|
if key == QtCore.Qt.Key_J or key == 'J':
|
||||||
self.app.on_jump_to()
|
self.app.on_jump_to()
|
||||||
|
|
||||||
# Corner Snap
|
|
||||||
if key == QtCore.Qt.Key_K or key == 'K':
|
|
||||||
self.app.geo_editor.on_corner_snap()
|
|
||||||
|
|
||||||
# Move
|
# Move
|
||||||
if key == QtCore.Qt.Key_M or key == 'M':
|
if key == QtCore.Qt.Key_M or key == 'M':
|
||||||
self.app.geo_editor.on_move_click()
|
self.app.geo_editor.on_move_click()
|
||||||
|
@ -3319,9 +3322,6 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
|
||||||
messagebox.setDefaultButton(QtWidgets.QMessageBox.Ok)
|
messagebox.setDefaultButton(QtWidgets.QMessageBox.Ok)
|
||||||
messagebox.exec_()
|
messagebox.exec_()
|
||||||
|
|
||||||
if key == QtCore.Qt.Key_V or key == 'V':
|
|
||||||
self.app.on_zoom_fit(None)
|
|
||||||
|
|
||||||
# Flip on X axis
|
# Flip on X axis
|
||||||
if key == QtCore.Qt.Key_X or key == 'X':
|
if key == QtCore.Qt.Key_X or key == 'X':
|
||||||
self.app.geo_editor.transform_tool.on_flipx()
|
self.app.geo_editor.transform_tool.on_flipx()
|
||||||
|
@ -3351,7 +3351,6 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
|
||||||
if key == QtCore.Qt.Key_M or key == 'M':
|
if key == QtCore.Qt.Key_M or key == 'M':
|
||||||
self.app.distance_tool.run()
|
self.app.distance_tool.run()
|
||||||
return
|
return
|
||||||
|
|
||||||
elif modifiers == QtCore.Qt.ShiftModifier:
|
elif modifiers == QtCore.Qt.ShiftModifier:
|
||||||
# Run Distance Minimum Tool
|
# Run Distance Minimum Tool
|
||||||
if key == QtCore.Qt.Key_M or key == 'M':
|
if key == QtCore.Qt.Key_M or key == 'M':
|
||||||
|
@ -3579,7 +3578,6 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
|
||||||
if key == QtCore.Qt.Key_M or key == 'M':
|
if key == QtCore.Qt.Key_M or key == 'M':
|
||||||
self.app.distance_tool.run()
|
self.app.distance_tool.run()
|
||||||
return
|
return
|
||||||
|
|
||||||
elif modifiers == QtCore.Qt.ShiftModifier:
|
elif modifiers == QtCore.Qt.ShiftModifier:
|
||||||
# Run Distance Minimum Tool
|
# Run Distance Minimum Tool
|
||||||
if key == QtCore.Qt.Key_M or key == 'M':
|
if key == QtCore.Qt.Key_M or key == 'M':
|
||||||
|
@ -3590,15 +3588,12 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
|
||||||
elif modifiers == QtCore.Qt.NoModifier:
|
elif modifiers == QtCore.Qt.NoModifier:
|
||||||
# Abort the current action
|
# Abort the current action
|
||||||
if key == QtCore.Qt.Key_Escape or key == 'Escape':
|
if key == QtCore.Qt.Key_Escape or key == 'Escape':
|
||||||
# TODO: ...?
|
|
||||||
# self.on_tool_select("select")
|
|
||||||
self.app.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled."))
|
self.app.inform.emit('[WARNING_NOTCL] %s' % _("Cancelled."))
|
||||||
|
|
||||||
self.app.exc_editor.delete_utility_geometry()
|
self.app.exc_editor.delete_utility_geometry()
|
||||||
|
|
||||||
self.app.exc_editor.replot()
|
self.app.exc_editor.active_tool.clean_up()
|
||||||
# self.select_btn.setChecked(True)
|
|
||||||
# self.on_tool_select('select')
|
|
||||||
self.app.exc_editor.select_tool('drill_select')
|
self.app.exc_editor.select_tool('drill_select')
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -3655,44 +3650,6 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
|
||||||
self.app.on_select_tab('tool')
|
self.app.on_select_tab('tool')
|
||||||
return
|
return
|
||||||
|
|
||||||
# Add Array of Drill Hole Tool
|
|
||||||
if key == QtCore.Qt.Key_A or key == 'A':
|
|
||||||
self.app.exc_editor.launched_from_shortcuts = True
|
|
||||||
self.app.inform.emit("Click on target point.")
|
|
||||||
self.app.ui.add_drill_array_btn.setChecked(True)
|
|
||||||
|
|
||||||
self.app.exc_editor.x = self.app.mouse[0]
|
|
||||||
self.app.exc_editor.y = self.app.mouse[1]
|
|
||||||
|
|
||||||
self.app.exc_editor.select_tool('drill_array')
|
|
||||||
return
|
|
||||||
|
|
||||||
# Copy
|
|
||||||
if key == QtCore.Qt.Key_C or key == 'C':
|
|
||||||
self.app.exc_editor.launched_from_shortcuts = True
|
|
||||||
if self.app.exc_editor.selected:
|
|
||||||
self.app.inform.emit(_("Click on target point."))
|
|
||||||
self.app.ui.copy_drill_btn.setChecked(True)
|
|
||||||
self.app.exc_editor.on_tool_select('drill_copy')
|
|
||||||
self.app.exc_editor.active_tool.set_origin(
|
|
||||||
(self.app.exc_editor.snap_x, self.app.exc_editor.snap_y))
|
|
||||||
else:
|
|
||||||
self.app.inform.emit('[WARNING_NOTCL] %s' %
|
|
||||||
_("Cancelled. Nothing selected to copy."))
|
|
||||||
return
|
|
||||||
|
|
||||||
# Add Drill Hole Tool
|
|
||||||
if key == QtCore.Qt.Key_D or key == 'D':
|
|
||||||
self.app.exc_editor.launched_from_shortcuts = True
|
|
||||||
self.app.inform.emit(_("Click on target point."))
|
|
||||||
self.app.ui.add_drill_btn.setChecked(True)
|
|
||||||
|
|
||||||
self.app.exc_editor.x = self.app.mouse[0]
|
|
||||||
self.app.exc_editor.y = self.app.mouse[1]
|
|
||||||
|
|
||||||
self.app.exc_editor.select_tool('drill_add')
|
|
||||||
return
|
|
||||||
|
|
||||||
# Grid Snap
|
# Grid Snap
|
||||||
if key == QtCore.Qt.Key_G or key == 'G':
|
if key == QtCore.Qt.Key_G or key == 'G':
|
||||||
self.app.exc_editor.launched_from_shortcuts = True
|
self.app.exc_editor.launched_from_shortcuts = True
|
||||||
|
@ -3704,69 +3661,12 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
|
||||||
self.app.ui.grid_snap_btn.trigger()
|
self.app.ui.grid_snap_btn.trigger()
|
||||||
return
|
return
|
||||||
|
|
||||||
# Jump to coords
|
|
||||||
if key == QtCore.Qt.Key_J or key == 'J':
|
|
||||||
self.app.on_jump_to()
|
|
||||||
|
|
||||||
# Corner Snap
|
# Corner Snap
|
||||||
if key == QtCore.Qt.Key_K or key == 'K':
|
if key == QtCore.Qt.Key_K or key == 'K':
|
||||||
self.app.exc_editor.launched_from_shortcuts = True
|
self.app.exc_editor.launched_from_shortcuts = True
|
||||||
self.app.ui.corner_snap_btn.trigger()
|
self.app.ui.corner_snap_btn.trigger()
|
||||||
return
|
return
|
||||||
|
|
||||||
# Move
|
|
||||||
if key == QtCore.Qt.Key_M or key == 'M':
|
|
||||||
self.app.exc_editor.launched_from_shortcuts = True
|
|
||||||
if self.app.exc_editor.selected:
|
|
||||||
self.app.inform.emit(_("Click on target point."))
|
|
||||||
self.app.ui.move_drill_btn.setChecked(True)
|
|
||||||
self.app.exc_editor.on_tool_select('drill_move')
|
|
||||||
self.app.exc_editor.active_tool.set_origin(
|
|
||||||
(self.app.exc_editor.snap_x, self.app.exc_editor.snap_y))
|
|
||||||
else:
|
|
||||||
self.app.inform.emit('[WARNING_NOTCL] %s' %
|
|
||||||
_("Cancelled. Nothing selected to move."))
|
|
||||||
return
|
|
||||||
|
|
||||||
# Add Array of Slote Hole Tool
|
|
||||||
if key == QtCore.Qt.Key_Q or key == 'Q':
|
|
||||||
self.app.exc_editor.launched_from_shortcuts = True
|
|
||||||
self.app.inform.emit("Click on target point.")
|
|
||||||
self.app.ui.add_slot_array_btn.setChecked(True)
|
|
||||||
|
|
||||||
self.app.exc_editor.x = self.app.mouse[0]
|
|
||||||
self.app.exc_editor.y = self.app.mouse[1]
|
|
||||||
|
|
||||||
self.app.exc_editor.select_tool('slot_array')
|
|
||||||
return
|
|
||||||
|
|
||||||
# Resize Tool
|
|
||||||
if key == QtCore.Qt.Key_R or key == 'R':
|
|
||||||
self.app.exc_editor.launched_from_shortcuts = True
|
|
||||||
self.app.exc_editor.select_tool('drill_resize')
|
|
||||||
return
|
|
||||||
|
|
||||||
# Add Tool
|
|
||||||
if key == QtCore.Qt.Key_T or key == 'T':
|
|
||||||
self.app.exc_editor.launched_from_shortcuts = True
|
|
||||||
# ## Current application units in Upper Case
|
|
||||||
self.units = self.general_defaults_form.general_app_group.units_radio.get_value().upper()
|
|
||||||
tool_add_popup = FCInputDialog(title=_("New Tool ..."),
|
|
||||||
text='%s:' % _('Enter a Tool Diameter'),
|
|
||||||
min=0.0000, max=99.9999, decimals=4)
|
|
||||||
tool_add_popup.setWindowIcon(QtGui.QIcon(self.app.resource_location + '/letter_t_32.png'))
|
|
||||||
|
|
||||||
val, ok = tool_add_popup.get_value()
|
|
||||||
if ok:
|
|
||||||
self.app.exc_editor.on_tool_add(tooldia=val)
|
|
||||||
formated_val = '%.*f' % (self.decimals, float(val))
|
|
||||||
self.app.inform.emit(
|
|
||||||
'[success] %s: %s %s' % (_("Added new tool with dia"), formated_val, str(self.units))
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
self.app.inform.emit('[WARNING_NOTCL] %s' % _("Adding Tool cancelled ..."))
|
|
||||||
return
|
|
||||||
|
|
||||||
# Zoom Fit
|
# Zoom Fit
|
||||||
if key == QtCore.Qt.Key_V or key == 'V':
|
if key == QtCore.Qt.Key_V or key == 'V':
|
||||||
self.app.exc_editor.launched_from_shortcuts = True
|
self.app.exc_editor.launched_from_shortcuts = True
|
||||||
|
@ -3787,15 +3687,113 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
|
||||||
|
|
||||||
# Propagate to tool
|
# Propagate to tool
|
||||||
response = None
|
response = None
|
||||||
if self.app.exc_editor.active_tool is not None:
|
|
||||||
response = self.app.exc_editor.active_tool.on_key(key=key)
|
|
||||||
if response is not None:
|
|
||||||
self.app.inform.emit(response)
|
|
||||||
|
|
||||||
# Show Shortcut list
|
# Show Shortcut list
|
||||||
if key == QtCore.Qt.Key_F3 or key == 'F3':
|
if key == QtCore.Qt.Key_F3 or key == 'F3':
|
||||||
self.app.on_shortcut_list()
|
self.app.on_shortcut_list()
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# we do this so we can reuse the following keys while inside a Tool
|
||||||
|
# the above keys are general enough so were left outside
|
||||||
|
if self.app.exc_editor.active_tool is not None and self.select_drill_btn.isChecked() is False:
|
||||||
|
response = self.app.exc_editor.active_tool.on_key(key=key)
|
||||||
|
if response is not None:
|
||||||
|
self.app.inform.emit(response)
|
||||||
|
else:
|
||||||
|
# Add Array of Drill Hole Tool
|
||||||
|
if key == QtCore.Qt.Key_A or key == 'A':
|
||||||
|
self.app.exc_editor.launched_from_shortcuts = True
|
||||||
|
self.app.inform.emit("Click on target point.")
|
||||||
|
self.app.ui.add_drill_array_btn.setChecked(True)
|
||||||
|
|
||||||
|
self.app.exc_editor.x = self.app.mouse[0]
|
||||||
|
self.app.exc_editor.y = self.app.mouse[1]
|
||||||
|
|
||||||
|
self.app.exc_editor.select_tool('drill_array')
|
||||||
|
return
|
||||||
|
|
||||||
|
# Copy
|
||||||
|
if key == QtCore.Qt.Key_C or key == 'C':
|
||||||
|
self.app.exc_editor.launched_from_shortcuts = True
|
||||||
|
if self.app.exc_editor.selected:
|
||||||
|
self.app.inform.emit(_("Click on target point."))
|
||||||
|
self.app.ui.copy_drill_btn.setChecked(True)
|
||||||
|
self.app.exc_editor.on_tool_select('drill_copy')
|
||||||
|
self.app.exc_editor.active_tool.set_origin(
|
||||||
|
(self.app.exc_editor.snap_x, self.app.exc_editor.snap_y))
|
||||||
|
else:
|
||||||
|
self.app.inform.emit('[WARNING_NOTCL] %s' %
|
||||||
|
_("Cancelled. Nothing selected to copy."))
|
||||||
|
return
|
||||||
|
|
||||||
|
# Add Drill Hole Tool
|
||||||
|
if key == QtCore.Qt.Key_D or key == 'D':
|
||||||
|
self.app.exc_editor.launched_from_shortcuts = True
|
||||||
|
self.app.inform.emit(_("Click on target point."))
|
||||||
|
self.app.ui.add_drill_btn.setChecked(True)
|
||||||
|
|
||||||
|
self.app.exc_editor.x = self.app.mouse[0]
|
||||||
|
self.app.exc_editor.y = self.app.mouse[1]
|
||||||
|
|
||||||
|
self.app.exc_editor.select_tool('drill_add')
|
||||||
|
return
|
||||||
|
|
||||||
|
# Jump to coords
|
||||||
|
if key == QtCore.Qt.Key_J or key == 'J':
|
||||||
|
self.app.on_jump_to()
|
||||||
|
|
||||||
|
# Move
|
||||||
|
if key == QtCore.Qt.Key_M or key == 'M':
|
||||||
|
self.app.exc_editor.launched_from_shortcuts = True
|
||||||
|
if self.app.exc_editor.selected:
|
||||||
|
self.app.inform.emit(_("Click on target point."))
|
||||||
|
self.app.ui.move_drill_btn.setChecked(True)
|
||||||
|
self.app.exc_editor.on_tool_select('drill_move')
|
||||||
|
self.app.exc_editor.active_tool.set_origin(
|
||||||
|
(self.app.exc_editor.snap_x, self.app.exc_editor.snap_y))
|
||||||
|
else:
|
||||||
|
self.app.inform.emit('[WARNING_NOTCL] %s' %
|
||||||
|
_("Cancelled. Nothing selected to move."))
|
||||||
|
return
|
||||||
|
|
||||||
|
# Add Array of Slots Hole Tool
|
||||||
|
if key == QtCore.Qt.Key_Q or key == 'Q':
|
||||||
|
self.app.exc_editor.launched_from_shortcuts = True
|
||||||
|
self.app.inform.emit("Click on target point.")
|
||||||
|
self.app.ui.add_slot_array_btn.setChecked(True)
|
||||||
|
|
||||||
|
self.app.exc_editor.x = self.app.mouse[0]
|
||||||
|
self.app.exc_editor.y = self.app.mouse[1]
|
||||||
|
|
||||||
|
self.app.exc_editor.select_tool('slot_array')
|
||||||
|
return
|
||||||
|
|
||||||
|
# Resize Tool
|
||||||
|
if key == QtCore.Qt.Key_R or key == 'R':
|
||||||
|
self.app.exc_editor.launched_from_shortcuts = True
|
||||||
|
self.app.exc_editor.select_tool('drill_resize')
|
||||||
|
return
|
||||||
|
|
||||||
|
# Add Tool
|
||||||
|
if key == QtCore.Qt.Key_T or key == 'T':
|
||||||
|
self.app.exc_editor.launched_from_shortcuts = True
|
||||||
|
# ## Current application units in Upper Case
|
||||||
|
self.units = self.general_defaults_form.general_app_group.units_radio.get_value().upper()
|
||||||
|
tool_add_popup = FCInputDialog(title=_("New Tool ..."),
|
||||||
|
text='%s:' % _('Enter a Tool Diameter'),
|
||||||
|
min=0.0000, max=99.9999, decimals=4)
|
||||||
|
tool_add_popup.setWindowIcon(QtGui.QIcon(self.app.resource_location + '/letter_t_32.png'))
|
||||||
|
|
||||||
|
val, ok = tool_add_popup.get_value()
|
||||||
|
if ok:
|
||||||
|
self.app.exc_editor.on_tool_add(tooldia=val)
|
||||||
|
formated_val = '%.*f' % (self.decimals, float(val))
|
||||||
|
self.app.inform.emit(
|
||||||
|
'[success] %s: %s %s' % (_("Added new tool with dia"), formated_val, str(self.units))
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
self.app.inform.emit('[WARNING_NOTCL] %s' % _("Adding Tool cancelled ..."))
|
||||||
|
return
|
||||||
elif self.app.call_source == 'measurement':
|
elif self.app.call_source == 'measurement':
|
||||||
if modifiers == QtCore.Qt.ControlModifier:
|
if modifiers == QtCore.Qt.ControlModifier:
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -310,6 +310,7 @@ class PlotCanvas(QtCore.QObject, VisPyCanvas):
|
||||||
# Update cursor
|
# Update cursor
|
||||||
self.fcapp.app_cursor.set_data(np.asarray([(pos[0], pos[1])]),
|
self.fcapp.app_cursor.set_data(np.asarray([(pos[0], pos[1])]),
|
||||||
symbol='++', edge_color=self.fcapp.cursor_color_3D,
|
symbol='++', edge_color=self.fcapp.cursor_color_3D,
|
||||||
|
edge_width=self.fcapp.defaults["global_cursor_width"],
|
||||||
size=self.fcapp.defaults["global_cursor_size"])
|
size=self.fcapp.defaults["global_cursor_size"])
|
||||||
|
|
||||||
def new_text_group(self, collection=None):
|
def new_text_group(self, collection=None):
|
||||||
|
|
|
@ -375,16 +375,19 @@ class PlotCanvasLegacy(QtCore.QObject):
|
||||||
pass
|
pass
|
||||||
# log.debug("Cache updated the screen!")
|
# log.debug("Cache updated the screen!")
|
||||||
|
|
||||||
def new_cursor(self, axes=None, big=None):
|
def new_cursor(self, axes=None, big=None, color=None):
|
||||||
# if axes is None:
|
# if axes is None:
|
||||||
# c = MplCursor(axes=self.axes, color='black', linewidth=1)
|
# c = MplCursor(axes=self.axes, color='black', linewidth=1)
|
||||||
# else:
|
# else:
|
||||||
# c = MplCursor(axes=axes, color='black', linewidth=1)
|
# c = MplCursor(axes=axes, color='black', linewidth=1)
|
||||||
|
|
||||||
if self.app.defaults['global_theme'] == 'white':
|
if color:
|
||||||
color = '#000000'
|
color = color
|
||||||
else:
|
else:
|
||||||
color = '#FFFFFF'
|
if self.app.defaults['global_theme'] == 'white':
|
||||||
|
color = '#000000'
|
||||||
|
else:
|
||||||
|
color = '#FFFFFF'
|
||||||
|
|
||||||
if big is True:
|
if big is True:
|
||||||
self.big_cursor = True
|
self.big_cursor = True
|
||||||
|
@ -398,20 +401,25 @@ class PlotCanvasLegacy(QtCore.QObject):
|
||||||
|
|
||||||
return c
|
return c
|
||||||
|
|
||||||
def draw_cursor(self, x_pos, y_pos):
|
def draw_cursor(self, x_pos, y_pos, color=None):
|
||||||
"""
|
"""
|
||||||
Draw a cursor at the mouse grid snapped position
|
Draw a cursor at the mouse grid snapped position
|
||||||
|
|
||||||
:param x_pos: mouse x position
|
:param x_pos: mouse x position
|
||||||
:param y_pos: mouse y position
|
:param y_pos: mouse y position
|
||||||
|
:param color: custom color of the mouse
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# there is no point in drawing mouse cursor when panning as it jumps in a confusing way
|
# there is no point in drawing mouse cursor when panning as it jumps in a confusing way
|
||||||
if self.app.app_cursor.enabled is True and self.panning is False:
|
if self.app.app_cursor.enabled is True and self.panning is False:
|
||||||
if self.app.defaults['global_theme'] == 'white':
|
if color:
|
||||||
color = '#000000'
|
color = color
|
||||||
else:
|
else:
|
||||||
color = '#FFFFFF'
|
if self.app.defaults['global_theme'] == 'white':
|
||||||
|
color = '#000000'
|
||||||
|
else:
|
||||||
|
color = '#FFFFFF'
|
||||||
|
|
||||||
if self.big_cursor is False:
|
if self.big_cursor is False:
|
||||||
try:
|
try:
|
||||||
|
@ -421,10 +429,11 @@ class PlotCanvasLegacy(QtCore.QObject):
|
||||||
# The size of the cursor is multiplied by 1.65 because that value made the cursor similar with the
|
# The size of the cursor is multiplied by 1.65 because that value made the cursor similar with the
|
||||||
# one in the OpenGL(3D) graphic engine
|
# one in the OpenGL(3D) graphic engine
|
||||||
pointer_size = int(float(self.app.defaults["global_cursor_size"] ) * 1.65)
|
pointer_size = int(float(self.app.defaults["global_cursor_size"] ) * 1.65)
|
||||||
elements = self.axes.plot(x, y, '+', color=color, ms=pointer_size, mew=1, animated=True)
|
elements = self.axes.plot(x, y, '+', color=color, ms=pointer_size,
|
||||||
|
mew=self.app.defaults["global_cursor_width"], animated=True)
|
||||||
for el in elements:
|
for el in elements:
|
||||||
self.axes.draw_artist(el)
|
self.axes.draw_artist(el)
|
||||||
except Exception as e:
|
except Exception:
|
||||||
# this happen at app initialization since self.app.geo_editor does not exist yet
|
# this happen at app initialization since self.app.geo_editor does not exist yet
|
||||||
# I could reshuffle the object instantiating order but what's the point?
|
# I could reshuffle the object instantiating order but what's the point?
|
||||||
# I could crash something else and that's pythonic, too
|
# I could crash something else and that's pythonic, too
|
||||||
|
@ -439,7 +448,10 @@ class PlotCanvasLegacy(QtCore.QObject):
|
||||||
def clear_cursor(self, state):
|
def clear_cursor(self, state):
|
||||||
|
|
||||||
if state is True:
|
if state is True:
|
||||||
self.draw_cursor(x_pos=self.mouse[0], y_pos=self.mouse[1])
|
if self.app.defaults["global_cursor_color_enabled"] is True:
|
||||||
|
self.draw_cursor(x_pos=self.mouse[0], y_pos=self.mouse[1], color=self.app.cursor_color_3D)
|
||||||
|
else:
|
||||||
|
self.draw_cursor(x_pos=self.mouse[0], y_pos=self.mouse[1])
|
||||||
else:
|
else:
|
||||||
if self.big_cursor is True:
|
if self.big_cursor is True:
|
||||||
self.ch_line.remove()
|
self.ch_line.remove()
|
||||||
|
@ -784,7 +796,10 @@ class PlotCanvasLegacy(QtCore.QObject):
|
||||||
self.panning = False
|
self.panning = False
|
||||||
|
|
||||||
# And update the cursor
|
# And update the cursor
|
||||||
self.draw_cursor(x_pos=self.mouse[0], y_pos=self.mouse[1])
|
if self.app.defaults["global_cursor_color_enabled"] is True:
|
||||||
|
self.draw_cursor(x_pos=self.mouse[0], y_pos=self.mouse[1], color=self.app.cursor_color_3D)
|
||||||
|
else:
|
||||||
|
self.draw_cursor(x_pos=self.mouse[0], y_pos=self.mouse[1])
|
||||||
|
|
||||||
def on_mouse_move(self, event):
|
def on_mouse_move(self, event):
|
||||||
"""
|
"""
|
||||||
|
@ -818,8 +833,10 @@ class PlotCanvasLegacy(QtCore.QObject):
|
||||||
# #### Temporary place-holder for cached update #####
|
# #### Temporary place-holder for cached update #####
|
||||||
self.update_screen_request.emit([0, 0, 0, 0, 0])
|
self.update_screen_request.emit([0, 0, 0, 0, 0])
|
||||||
|
|
||||||
self.draw_cursor(x_pos=x, y_pos=y)
|
if self.app.defaults["global_cursor_color_enabled"] is True:
|
||||||
|
self.draw_cursor(x_pos=x, y_pos=y, color=self.app.cursor_color_3D)
|
||||||
|
else:
|
||||||
|
self.draw_cursor(x_pos=x, y_pos=y)
|
||||||
# self.canvas.blit(self.axes.bbox)
|
# self.canvas.blit(self.axes.bbox)
|
||||||
|
|
||||||
def translate_coords(self, position):
|
def translate_coords(self, position):
|
||||||
|
@ -891,6 +908,7 @@ class FakeCursor(QtCore.QObject):
|
||||||
|
|
||||||
def set_data(self, pos, **kwargs):
|
def set_data(self, pos, **kwargs):
|
||||||
"""Internal event handler to draw the cursor when the mouse moves."""
|
"""Internal event handler to draw the cursor when the mouse moves."""
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
class ShapeCollectionLegacy:
|
class ShapeCollectionLegacy:
|
||||||
|
|
|
@ -50,7 +50,7 @@ def apply_patches():
|
||||||
try:
|
try:
|
||||||
self._update_child_widget_dim()
|
self._update_child_widget_dim()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(e)
|
print("VisPyPatches.apply_patches._update_clipper() -> %s" % str(e))
|
||||||
|
|
||||||
Grid._prepare_draw = _prepare_draw
|
Grid._prepare_draw = _prepare_draw
|
||||||
Grid._update_clipper = _update_clipper
|
Grid._update_clipper = _update_clipper
|
||||||
|
@ -72,7 +72,7 @@ def apply_patches():
|
||||||
|
|
||||||
if GL:
|
if GL:
|
||||||
GL.glDisable(GL.GL_LINE_SMOOTH)
|
GL.glDisable(GL.GL_LINE_SMOOTH)
|
||||||
GL.glLineWidth(1.0)
|
GL.glLineWidth(2.0)
|
||||||
|
|
||||||
if self._changed['pos']:
|
if self._changed['pos']:
|
||||||
self.pos_buf.set_data(self._pos)
|
self.pos_buf.set_data(self._pos)
|
||||||
|
|
|
@ -437,18 +437,20 @@ class Gerber(Geometry):
|
||||||
gline = gline.strip(' \r\n')
|
gline = gline.strip(' \r\n')
|
||||||
# log.debug("Line=%3s %s" % (line_num, gline))
|
# log.debug("Line=%3s %s" % (line_num, gline))
|
||||||
|
|
||||||
# ###################
|
# ###############################################################
|
||||||
# Ignored lines #####
|
# ################ Ignored lines ############################
|
||||||
# Comments #####
|
# ################ Comments ############################
|
||||||
# ###################
|
# ###############################################################
|
||||||
match = self.comm_re.search(gline)
|
match = self.comm_re.search(gline)
|
||||||
if match:
|
if match:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Polarity change ###### ##
|
# ###############################################################
|
||||||
# Example: %LPD*% or %LPC*%
|
# ################ Polarity change #############################
|
||||||
# If polarity changes, creates geometry from current
|
# ######## Example: %LPD*% or %LPC*% ###################
|
||||||
# buffer, then adds or subtracts accordingly.
|
# ######## If polarity changes, creates geometry from current #
|
||||||
|
# ######## buffer, then adds or subtracts accordingly. #
|
||||||
|
# ###############################################################
|
||||||
match = self.lpol_re.search(gline)
|
match = self.lpol_re.search(gline)
|
||||||
if match:
|
if match:
|
||||||
new_polarity = match.group(1)
|
new_polarity = match.group(1)
|
||||||
|
@ -491,11 +493,9 @@ class Gerber(Geometry):
|
||||||
# TODO: Remove when bug fixed
|
# TODO: Remove when bug fixed
|
||||||
if len(poly_buffer) > 0:
|
if len(poly_buffer) > 0:
|
||||||
if current_polarity == 'D':
|
if current_polarity == 'D':
|
||||||
# self.follow_geometry = self.follow_geometry.union(cascaded_union(follow_buffer))
|
|
||||||
self.solid_geometry = self.solid_geometry.union(cascaded_union(poly_buffer))
|
self.solid_geometry = self.solid_geometry.union(cascaded_union(poly_buffer))
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# self.follow_geometry = self.follow_geometry.difference(cascaded_union(follow_buffer))
|
|
||||||
self.solid_geometry = self.solid_geometry.difference(cascaded_union(poly_buffer))
|
self.solid_geometry = self.solid_geometry.difference(cascaded_union(poly_buffer))
|
||||||
|
|
||||||
# follow_buffer = []
|
# follow_buffer = []
|
||||||
|
@ -504,11 +504,11 @@ class Gerber(Geometry):
|
||||||
current_polarity = new_polarity
|
current_polarity = new_polarity
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# ############################################################# ##
|
# ################################################################
|
||||||
# Number format ############################################### ##
|
# ##################### Number format ###########################
|
||||||
# Example: %FSLAX24Y24*%
|
# ##################### Example: %FSLAX24Y24*% #################
|
||||||
# ############################################################# ##
|
# ################################################################
|
||||||
# TODO: This is ignoring most of the format. Implement the rest.
|
|
||||||
match = self.fmt_re.search(gline)
|
match = self.fmt_re.search(gline)
|
||||||
if match:
|
if match:
|
||||||
absolute = {'A': 'Absolute', 'I': 'Relative'}[match.group(2)]
|
absolute = {'A': 'Absolute', 'I': 'Relative'}[match.group(2)]
|
||||||
|
@ -524,8 +524,10 @@ class Gerber(Geometry):
|
||||||
log.debug("Gerber format found. Coordinates type = %s (Absolute or Relative)" % absolute)
|
log.debug("Gerber format found. Coordinates type = %s (Absolute or Relative)" % absolute)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# ## Mode (IN/MM)
|
# ################################################################
|
||||||
# Example: %MOIN*%
|
# ######################## Mode (IN/MM) #######################
|
||||||
|
# ##################### Example: %MOIN*% #####################
|
||||||
|
# ################################################################
|
||||||
match = self.mode_re.search(gline)
|
match = self.mode_re.search(gline)
|
||||||
if match:
|
if match:
|
||||||
self.units = match.group(1)
|
self.units = match.group(1)
|
||||||
|
@ -535,9 +537,9 @@ class Gerber(Geometry):
|
||||||
self.conversion_done = True
|
self.conversion_done = True
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# ############################################################# ##
|
# ################################################################
|
||||||
# Combined Number format and Mode --- Allegro does this ####### ##
|
# Combined Number format and Mode --- Allegro does this ##########
|
||||||
# ############################################################# ##
|
# ################################################################
|
||||||
match = self.fmt_re_alt.search(gline)
|
match = self.fmt_re_alt.search(gline)
|
||||||
if match:
|
if match:
|
||||||
absolute = {'A': 'Absolute', 'I': 'Relative'}[match.group(2)]
|
absolute = {'A': 'Absolute', 'I': 'Relative'}[match.group(2)]
|
||||||
|
@ -558,9 +560,9 @@ class Gerber(Geometry):
|
||||||
self.conversion_done = True
|
self.conversion_done = True
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# ############################################################# ##
|
# ################################################################
|
||||||
# Search for OrCAD way for having Number format
|
# #### Search for OrCAD way for having Number format ########
|
||||||
# ############################################################# ##
|
# ################################################################
|
||||||
match = self.fmt_re_orcad.search(gline)
|
match = self.fmt_re_orcad.search(gline)
|
||||||
if match:
|
if match:
|
||||||
if match.group(1) is not None:
|
if match.group(1) is not None:
|
||||||
|
@ -587,9 +589,9 @@ class Gerber(Geometry):
|
||||||
self.conversion_done = True
|
self.conversion_done = True
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# ############################################################# ##
|
# ################################################################
|
||||||
# Units (G70/1) OBSOLETE
|
# ############ Units (G70/1) OBSOLETE ######################
|
||||||
# ############################################################# ##
|
# ################################################################
|
||||||
match = self.units_re.search(gline)
|
match = self.units_re.search(gline)
|
||||||
if match:
|
if match:
|
||||||
obs_gerber_units = {'0': 'IN', '1': 'MM'}[match.group(1)]
|
obs_gerber_units = {'0': 'IN', '1': 'MM'}[match.group(1)]
|
||||||
|
@ -599,21 +601,21 @@ class Gerber(Geometry):
|
||||||
self.conversion_done = True
|
self.conversion_done = True
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# ############################################################# ##
|
# ################################################################
|
||||||
# Absolute/relative coordinates G90/1 OBSOLETE ######## ##
|
# ##### Absolute/relative coordinates G90/1 OBSOLETE ###########
|
||||||
# ##################################################### ##
|
# ################################################################
|
||||||
match = self.absrel_re.search(gline)
|
match = self.absrel_re.search(gline)
|
||||||
if match:
|
if match:
|
||||||
absolute = {'0': "Absolute", '1': "Relative"}[match.group(1)]
|
absolute = {'0': "Absolute", '1': "Relative"}[match.group(1)]
|
||||||
log.warning("Gerber obsolete coordinates type found = %s (Absolute or Relative) " % absolute)
|
log.warning("Gerber obsolete coordinates type found = %s (Absolute or Relative) " % absolute)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# ############################################################# ##
|
# ################################################################
|
||||||
# Aperture Macros ##################################### ##
|
# Aperture Macros ################################################
|
||||||
# Having this at the beginning will slow things down
|
# Having this at the beginning will slow things down
|
||||||
# but macros can have complicated statements than could
|
# but macros can have complicated statements than could
|
||||||
# be caught by other patterns.
|
# be caught by other patterns.
|
||||||
# ############################################################# ##
|
# ################################################################
|
||||||
if current_macro is None: # No macro started yet
|
if current_macro is None: # No macro started yet
|
||||||
match = self.am1_re.search(gline)
|
match = self.am1_re.search(gline)
|
||||||
# Start macro if match, else not an AM, carry on.
|
# Start macro if match, else not an AM, carry on.
|
||||||
|
@ -640,18 +642,20 @@ class Gerber(Geometry):
|
||||||
self.aperture_macros[current_macro].append(gline)
|
self.aperture_macros[current_macro].append(gline)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# ## Aperture definitions %ADD...
|
# ################################################################
|
||||||
|
# ############## Aperture definitions %ADD... #################
|
||||||
|
# ################################################################
|
||||||
match = self.ad_re.search(gline)
|
match = self.ad_re.search(gline)
|
||||||
if match:
|
if match:
|
||||||
# log.info("Found aperture definition. Line %d: %s" % (line_num, gline))
|
# log.info("Found aperture definition. Line %d: %s" % (line_num, gline))
|
||||||
self.aperture_parse(match.group(1), match.group(2), match.group(3))
|
self.aperture_parse(match.group(1), match.group(2), match.group(3))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# ############################################################# ##
|
# ################################################################
|
||||||
# Operation code alone ###################### ##
|
# ################ Operation code alone #########################
|
||||||
# Operation code alone, usually just D03 (Flash)
|
# ########### Operation code alone, usually just D03 (Flash) ###
|
||||||
# self.opcode_re = re.compile(r'^D0?([123])\*$')
|
# self.opcode_re = re.compile(r'^D0?([123])\*$')
|
||||||
# ############################################################# ##
|
# ################################################################
|
||||||
match = self.opcode_re.search(gline)
|
match = self.opcode_re.search(gline)
|
||||||
if match:
|
if match:
|
||||||
current_operation_code = int(match.group(1))
|
current_operation_code = int(match.group(1))
|
||||||
|
@ -690,10 +694,10 @@ class Gerber(Geometry):
|
||||||
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# ############################################################# ##
|
# ################################################################
|
||||||
# Tool/aperture change
|
# ################ Tool/aperture change ########################
|
||||||
# Example: D12*
|
# ################ Example: D12* ########################
|
||||||
# ############################################################# ##
|
# ################################################################
|
||||||
match = self.tool_re.search(gline)
|
match = self.tool_re.search(gline)
|
||||||
if match:
|
if match:
|
||||||
current_aperture = match.group(1)
|
current_aperture = match.group(1)
|
||||||
|
@ -740,12 +744,11 @@ class Gerber(Geometry):
|
||||||
self.apertures[last_path_aperture]['geometry'].append(deepcopy(geo_dict))
|
self.apertures[last_path_aperture]['geometry'].append(deepcopy(geo_dict))
|
||||||
|
|
||||||
path = [path[-1]]
|
path = [path[-1]]
|
||||||
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# ############################################################# ##
|
# ################################################################
|
||||||
# G36* - Begin region
|
# ################ G36* - Begin region ########################
|
||||||
# ############################################################# ##
|
# ################################################################
|
||||||
if self.regionon_re.search(gline):
|
if self.regionon_re.search(gline):
|
||||||
if len(path) > 1:
|
if len(path) > 1:
|
||||||
# Take care of what is left in the path
|
# Take care of what is left in the path
|
||||||
|
@ -780,9 +783,9 @@ class Gerber(Geometry):
|
||||||
making_region = True
|
making_region = True
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# ############################################################# ##
|
# ################################################################
|
||||||
# G37* - End region
|
# ################ G37* - End region ########################
|
||||||
# ############################################################# ##
|
# ################################################################
|
||||||
if self.regionoff_re.search(gline):
|
if self.regionoff_re.search(gline):
|
||||||
making_region = False
|
making_region = False
|
||||||
|
|
||||||
|
@ -830,20 +833,27 @@ class Gerber(Geometry):
|
||||||
|
|
||||||
# --- Buffered ---
|
# --- Buffered ---
|
||||||
geo_dict = dict()
|
geo_dict = dict()
|
||||||
region_f = Polygon(path).exterior
|
if current_aperture in self.apertures:
|
||||||
|
buff_value = float(self.apertures[current_aperture]['size']) / 2.0
|
||||||
|
# region_geo = Polygon(path).buffer(buff_value, int(self.steps_per_circle))
|
||||||
|
region_geo = Polygon(path) # Sprint Layout Gerbers with ground fill are crashed with above
|
||||||
|
else:
|
||||||
|
region_geo = Polygon(path)
|
||||||
|
|
||||||
|
region_f = region_geo.exterior
|
||||||
if not region_f.is_empty:
|
if not region_f.is_empty:
|
||||||
follow_buffer.append(region_f)
|
follow_buffer.append(region_f)
|
||||||
geo_dict['follow'] = region_f
|
geo_dict['follow'] = region_f
|
||||||
|
|
||||||
region_s = Polygon(path)
|
region_s = region_geo
|
||||||
if not region_s.is_valid:
|
if not region_s.is_valid:
|
||||||
region_s = region_s.buffer(0, int(self.steps_per_circle / 4))
|
region_s = region_s.buffer(0, int(self.steps_per_circle))
|
||||||
|
|
||||||
if not region_s.is_empty:
|
if not region_s.is_empty:
|
||||||
if self.app.defaults['gerber_simplification']:
|
if self.app.defaults['gerber_simplification']:
|
||||||
poly_buffer.append(region_s.simplify(s_tol))
|
poly_buffer.append(region_s.simplify(s_tol))
|
||||||
else:
|
else:
|
||||||
poly_buffer.append(region_s)
|
poly_buffer.append(region_s)
|
||||||
|
|
||||||
if self.is_lpc is True:
|
if self.is_lpc is True:
|
||||||
geo_dict['clear'] = region_s
|
geo_dict['clear'] = region_s
|
||||||
else:
|
else:
|
||||||
|
@ -855,18 +865,22 @@ class Gerber(Geometry):
|
||||||
path = [[current_x, current_y]] # Start new path
|
path = [[current_x, current_y]] # Start new path
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# ## G01/2/3* - Interpolation mode change
|
# ################################################################
|
||||||
# Can occur along with coordinates and operation code but
|
# ################ G01/2/3* - Interpolation mode change #########
|
||||||
# sometimes by itself (handled here).
|
# #### Can occur along with coordinates and operation code but ##
|
||||||
# Example: G01*
|
# #### sometimes by itself (handled here). #####################
|
||||||
|
# #### Example: G01* #####################
|
||||||
|
# ################################################################
|
||||||
match = self.interp_re.search(gline)
|
match = self.interp_re.search(gline)
|
||||||
if match:
|
if match:
|
||||||
current_interpolation_mode = int(match.group(1))
|
current_interpolation_mode = int(match.group(1))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# ## G01 - Linear interpolation plus flashes
|
# ################################################################
|
||||||
# Operation code (D0x) missing is deprecated... oh well I will support it.
|
# ######### G01 - Linear interpolation plus flashes #############
|
||||||
|
# ######### Operation code (D0x) missing is deprecated #########
|
||||||
# REGEX: r'^(?:G0?(1))?(?:X(-?\d+))?(?:Y(-?\d+))?(?:D0([123]))?\*$'
|
# REGEX: r'^(?:G0?(1))?(?:X(-?\d+))?(?:Y(-?\d+))?(?:D0([123]))?\*$'
|
||||||
|
# ################################################################
|
||||||
match = self.lin_re.search(gline)
|
match = self.lin_re.search(gline)
|
||||||
if match:
|
if match:
|
||||||
# Dxx alone?
|
# Dxx alone?
|
||||||
|
@ -1147,7 +1161,9 @@ class Gerber(Geometry):
|
||||||
# log.debug("Line_number=%3s X=%s Y=%s (%s)" % (line_num, linear_x, linear_y, gline))
|
# log.debug("Line_number=%3s X=%s Y=%s (%s)" % (line_num, linear_x, linear_y, gline))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# ## G74/75* - Single or multiple quadrant arcs
|
# ################################################################
|
||||||
|
# ######### G74/75* - Single or multiple quadrant arcs ##########
|
||||||
|
# ################################################################
|
||||||
match = self.quad_re.search(gline)
|
match = self.quad_re.search(gline)
|
||||||
if match:
|
if match:
|
||||||
if match.group(1) == '4':
|
if match.group(1) == '4':
|
||||||
|
@ -1156,9 +1172,12 @@ class Gerber(Geometry):
|
||||||
quadrant_mode = 'MULTI'
|
quadrant_mode = 'MULTI'
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# ## G02/3 - Circular interpolation
|
# ################################################################
|
||||||
# 2-clockwise, 3-counterclockwise
|
# ######### G02/3 - Circular interpolation #####################
|
||||||
# Ex. format: G03 X0 Y50 I-50 J0 where the X, Y coords are the coords of the End Point
|
# ######### 2-clockwise, 3-counterclockwise #####################
|
||||||
|
# ######### Ex. format: G03 X0 Y50 I-50 J0 where the #########
|
||||||
|
# ######### X, Y coords are the coords of the End Point #########
|
||||||
|
# ################################################################
|
||||||
match = self.circ_re.search(gline)
|
match = self.circ_re.search(gline)
|
||||||
if match:
|
if match:
|
||||||
arcdir = [None, None, "cw", "ccw"]
|
arcdir = [None, None, "cw", "ccw"]
|
||||||
|
@ -1339,12 +1358,16 @@ class Gerber(Geometry):
|
||||||
else:
|
else:
|
||||||
log.warning("Invalid arc in line %d." % line_num)
|
log.warning("Invalid arc in line %d." % line_num)
|
||||||
|
|
||||||
# ## EOF
|
# ################################################################
|
||||||
|
# ######### EOF - END OF FILE ####################################
|
||||||
|
# ################################################################
|
||||||
match = self.eof_re.search(gline)
|
match = self.eof_re.search(gline)
|
||||||
if match:
|
if match:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# ## Line did not match any pattern. Warn user.
|
# ################################################################
|
||||||
|
# ######### Line did not match any pattern. Warn user. ##########
|
||||||
|
# ################################################################
|
||||||
log.warning("Line ignored (%d): %s" % (line_num, gline))
|
log.warning("Line ignored (%d): %s" % (line_num, gline))
|
||||||
|
|
||||||
if len(path) > 1:
|
if len(path) > 1:
|
||||||
|
@ -1433,16 +1456,16 @@ class Gerber(Geometry):
|
||||||
|
|
||||||
self.solid_geometry = final_poly
|
self.solid_geometry = final_poly
|
||||||
|
|
||||||
# FIX for issue #347 - Sprint Layout generate strange Gerber files when the copper pour is enabled
|
# FIX for issue #347 - Sprint Layout generate Gerber files when the copper pour is enabled
|
||||||
# it use a filled bounding box polygon to which add clear polygons (negative) to isolate the copper
|
# it use a filled bounding box polygon to which add clear polygons (negative) to isolate the copper
|
||||||
# features
|
# features
|
||||||
if self.app.defaults['gerber_extra_buffering']:
|
if self.app.defaults['gerber_extra_buffering']:
|
||||||
candidate_geo = list()
|
candidate_geo = list()
|
||||||
try:
|
try:
|
||||||
for p in self.solid_geometry:
|
for p in self.solid_geometry:
|
||||||
candidate_geo.append(p.buffer(0.0000001))
|
candidate_geo.append(p.buffer(-0.0000001))
|
||||||
except TypeError:
|
except TypeError:
|
||||||
candidate_geo.append(self.solid_geometry.buffer(0.0000001))
|
candidate_geo.append(self.solid_geometry.buffer(-0.0000001))
|
||||||
self.solid_geometry = candidate_geo
|
self.solid_geometry = candidate_geo
|
||||||
|
|
||||||
# try:
|
# try:
|
||||||
|
|
|
@ -902,6 +902,7 @@ class ToolCopperThieving(FlatCAMTool):
|
||||||
|
|
||||||
self.app.app_cursor.set_data(np.asarray([(curr_pos[0], curr_pos[1])]),
|
self.app.app_cursor.set_data(np.asarray([(curr_pos[0], curr_pos[1])]),
|
||||||
symbol='++', edge_color=self.app.cursor_color_3D,
|
symbol='++', edge_color=self.app.cursor_color_3D,
|
||||||
|
edge_width=self.app.defaults["global_cursor_width"],
|
||||||
size=self.app.defaults["global_cursor_size"])
|
size=self.app.defaults["global_cursor_size"])
|
||||||
|
|
||||||
# update the positions on status bar
|
# update the positions on status bar
|
||||||
|
|
|
@ -396,6 +396,7 @@ class Distance(FlatCAMTool):
|
||||||
# Update cursor
|
# Update cursor
|
||||||
self.app.app_cursor.set_data(np.asarray([(pos[0], pos[1])]),
|
self.app.app_cursor.set_data(np.asarray([(pos[0], pos[1])]),
|
||||||
symbol='++', edge_color=self.app.cursor_color_3D,
|
symbol='++', edge_color=self.app.cursor_color_3D,
|
||||||
|
edge_width=self.app.defaults["global_cursor_width"],
|
||||||
size=self.app.defaults["global_cursor_size"])
|
size=self.app.defaults["global_cursor_size"])
|
||||||
else:
|
else:
|
||||||
pos = (pos_canvas[0], pos_canvas[1])
|
pos = (pos_canvas[0], pos_canvas[1])
|
||||||
|
|
|
@ -698,11 +698,11 @@ class NonCopperClear(FlatCAMTool, Gerber):
|
||||||
"paintcontour": self.app.defaults["tools_paintcontour"],
|
"paintcontour": self.app.defaults["tools_paintcontour"],
|
||||||
"paintoverlap": self.app.defaults["tools_paintoverlap"],
|
"paintoverlap": self.app.defaults["tools_paintoverlap"],
|
||||||
|
|
||||||
"nccoverlap": self.app.defaults["tools_nccoverlap"],
|
|
||||||
"nccmargin": self.app.defaults["tools_nccmargin"],
|
"nccmargin": self.app.defaults["tools_nccmargin"],
|
||||||
"nccmethod": self.app.defaults["tools_nccmethod"],
|
"nccmethod": self.app.defaults["tools_nccmethod"],
|
||||||
"nccconnect": self.app.defaults["tools_nccconnect"],
|
"nccconnect": self.app.defaults["tools_nccconnect"],
|
||||||
"ncccontour": self.app.defaults["tools_ncccontour"],
|
"ncccontour": self.app.defaults["tools_ncccontour"],
|
||||||
|
"nccoverlap": self.app.defaults["tools_nccoverlap"],
|
||||||
"nccrest": self.app.defaults["tools_nccrest"]
|
"nccrest": self.app.defaults["tools_nccrest"]
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -1349,6 +1349,7 @@ class NonCopperClear(FlatCAMTool, Gerber):
|
||||||
|
|
||||||
self.app.app_cursor.set_data(np.asarray([(curr_pos[0], curr_pos[1])]),
|
self.app.app_cursor.set_data(np.asarray([(curr_pos[0], curr_pos[1])]),
|
||||||
symbol='++', edge_color=self.app.cursor_color_3D,
|
symbol='++', edge_color=self.app.cursor_color_3D,
|
||||||
|
edge_width=self.app.defaults["global_cursor_width"],
|
||||||
size=self.app.defaults["global_cursor_size"])
|
size=self.app.defaults["global_cursor_size"])
|
||||||
|
|
||||||
# update the positions on status bar
|
# update the positions on status bar
|
||||||
|
|
|
@ -1290,6 +1290,7 @@ class ToolPaint(FlatCAMTool, Gerber):
|
||||||
|
|
||||||
self.app.app_cursor.set_data(np.asarray([(curr_pos[0], curr_pos[1])]),
|
self.app.app_cursor.set_data(np.asarray([(curr_pos[0], curr_pos[1])]),
|
||||||
symbol='++', edge_color=self.app.cursor_color_3D,
|
symbol='++', edge_color=self.app.cursor_color_3D,
|
||||||
|
edge_width=self.app.defaults["global_cursor_width"],
|
||||||
size=self.app.defaults["global_cursor_size"])
|
size=self.app.defaults["global_cursor_size"])
|
||||||
|
|
||||||
# update the positions on status bar
|
# update the positions on status bar
|
||||||
|
|
|
@ -608,22 +608,22 @@ class Panelize(FlatCAMTool):
|
||||||
if panel_obj.multigeo is True:
|
if panel_obj.multigeo is True:
|
||||||
for tool in panel_obj.tools:
|
for tool in panel_obj.tools:
|
||||||
try:
|
try:
|
||||||
for pol in panel_obj.tools[tool]['solid_geometry']:
|
geo_len += len(panel_obj.tools[tool]['solid_geometry'])
|
||||||
geo_len += 1
|
|
||||||
except TypeError:
|
except TypeError:
|
||||||
geo_len = 1
|
geo_len += 1
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
for pol in panel_obj.solid_geometry:
|
geo_len = len(panel_obj.solid_geometry)
|
||||||
geo_len += 1
|
|
||||||
except TypeError:
|
except TypeError:
|
||||||
geo_len = 1
|
geo_len = 1
|
||||||
elif isinstance(panel_obj, FlatCAMGerber):
|
elif isinstance(panel_obj, FlatCAMGerber):
|
||||||
for ap in panel_obj.apertures:
|
for ap in panel_obj.apertures:
|
||||||
for elem in panel_obj.apertures[ap]['geometry']:
|
if 'geometry' in panel_obj.apertures[ap]:
|
||||||
geo_len += 1
|
try:
|
||||||
|
geo_len += len(panel_obj.apertures[ap]['geometry'])
|
||||||
|
except TypeError:
|
||||||
|
geo_len += 1
|
||||||
|
|
||||||
self.app.progress.emit(0)
|
|
||||||
element = 0
|
element = 0
|
||||||
for row in range(rows):
|
for row in range(rows):
|
||||||
currentx = 0.0
|
currentx = 0.0
|
||||||
|
@ -724,49 +724,48 @@ class Panelize(FlatCAMTool):
|
||||||
if self.app.abort_flag:
|
if self.app.abort_flag:
|
||||||
# graceful abort requested by the user
|
# graceful abort requested by the user
|
||||||
raise FlatCAMApp.GracefulException
|
raise FlatCAMApp.GracefulException
|
||||||
|
if 'geometry' in panel_obj.apertures[apid]:
|
||||||
|
try:
|
||||||
|
# calculate the number of polygons
|
||||||
|
geo_len = len(panel_obj.apertures[apid]['geometry'])
|
||||||
|
except TypeError:
|
||||||
|
geo_len = 1
|
||||||
|
pol_nr = 0
|
||||||
|
for el in panel_obj.apertures[apid]['geometry']:
|
||||||
|
if self.app.abort_flag:
|
||||||
|
# graceful abort requested by the user
|
||||||
|
raise FlatCAMApp.GracefulException
|
||||||
|
|
||||||
try:
|
new_el = dict()
|
||||||
# calculate the number of polygons
|
if 'solid' in el:
|
||||||
geo_len = len(panel_obj.apertures[apid]['geometry'])
|
geo_aper = translate_recursion(el['solid'])
|
||||||
except TypeError:
|
new_el['solid'] = geo_aper
|
||||||
geo_len = 1
|
|
||||||
pol_nr = 0
|
|
||||||
for el in panel_obj.apertures[apid]['geometry']:
|
|
||||||
if self.app.abort_flag:
|
|
||||||
# graceful abort requested by the user
|
|
||||||
raise FlatCAMApp.GracefulException
|
|
||||||
|
|
||||||
new_el = dict()
|
if 'clear' in el:
|
||||||
if 'solid' in el:
|
geo_aper = translate_recursion(el['clear'])
|
||||||
geo_aper = translate_recursion(el['solid'])
|
new_el['clear'] = geo_aper
|
||||||
new_el['solid'] = geo_aper
|
|
||||||
|
|
||||||
if 'clear' in el:
|
if 'follow' in el:
|
||||||
geo_aper = translate_recursion(el['clear'])
|
geo_aper = translate_recursion(el['follow'])
|
||||||
new_el['clear'] = geo_aper
|
new_el['follow'] = geo_aper
|
||||||
|
|
||||||
if 'follow' in el:
|
obj_fin.apertures[apid]['geometry'].append(deepcopy(new_el))
|
||||||
geo_aper = translate_recursion(el['follow'])
|
|
||||||
new_el['follow'] = geo_aper
|
|
||||||
|
|
||||||
obj_fin.apertures[apid]['geometry'].append(deepcopy(new_el))
|
pol_nr += 1
|
||||||
|
disp_number = int(np.interp(pol_nr, [0, geo_len], [0, 100]))
|
||||||
|
|
||||||
pol_nr += 1
|
if old_disp_number < disp_number <= 100:
|
||||||
disp_number = int(np.interp(pol_nr, [0, geo_len], [0, 100]))
|
self.app.proc_container.update_view_text(' %s: %d %d%%' %
|
||||||
|
(_("Copy"),
|
||||||
if old_disp_number < disp_number <= 100:
|
int(element),
|
||||||
self.app.proc_container.update_view_text(' %s: %d %d%%' %
|
disp_number))
|
||||||
(_("Copy"),
|
old_disp_number = disp_number
|
||||||
int(element),
|
|
||||||
disp_number))
|
|
||||||
old_disp_number = disp_number
|
|
||||||
|
|
||||||
currentx += lenghtx
|
currentx += lenghtx
|
||||||
currenty += lenghty
|
currenty += lenghty
|
||||||
|
|
||||||
if panel_type == 'gerber':
|
if panel_type == 'gerber':
|
||||||
self.app.inform.emit('%s' %
|
self.app.inform.emit('%s' % _("Generating panel ... Adding the Gerber code."))
|
||||||
_("Generating panel ... Adding the Gerber code."))
|
|
||||||
obj_fin.source_file = self.app.export_gerber(obj_name=self.outname, filename=None,
|
obj_fin.source_file = self.app.export_gerber(obj_name=self.outname, filename=None,
|
||||||
local_use=obj_fin, use_thread=False)
|
local_use=obj_fin, use_thread=False)
|
||||||
|
|
||||||
|
@ -777,15 +776,11 @@ class Panelize(FlatCAMTool):
|
||||||
# app_obj.log.debug("Finished creating a cascaded union for the panel.")
|
# app_obj.log.debug("Finished creating a cascaded union for the panel.")
|
||||||
self.app.proc_container.update_view_text('')
|
self.app.proc_container.update_view_text('')
|
||||||
|
|
||||||
self.app.inform.emit('%s: %d' %
|
self.app.inform.emit('%s: %d' % (_("Generating panel... Spawning copies"), (int(rows * columns))))
|
||||||
(_("Generating panel... Spawning copies"), (int(rows * columns))))
|
|
||||||
if isinstance(panel_obj, FlatCAMExcellon):
|
if isinstance(panel_obj, FlatCAMExcellon):
|
||||||
self.app.progress.emit(50)
|
|
||||||
self.app.new_object("excellon", self.outname, job_init_excellon, plot=True, autoselected=True)
|
self.app.new_object("excellon", self.outname, job_init_excellon, plot=True, autoselected=True)
|
||||||
else:
|
else:
|
||||||
self.app.progress.emit(50)
|
self.app.new_object(panel_type, self.outname, job_init_geometry, plot=True, autoselected=True)
|
||||||
self.app.new_object(panel_type, self.outname, job_init_geometry,
|
|
||||||
plot=True, autoselected=True)
|
|
||||||
|
|
||||||
if self.constrain_flag is False:
|
if self.constrain_flag is False:
|
||||||
self.app.inform.emit('[success] %s' % _("Panel done..."))
|
self.app.inform.emit('[success] %s' % _("Panel done..."))
|
||||||
|
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
BIN
share/copy32.png
Before Width: | Height: | Size: 618 B After Width: | Height: | Size: 669 B |
Before Width: | Height: | Size: 500 B After Width: | Height: | Size: 407 B |
Before Width: | Height: | Size: 565 B After Width: | Height: | Size: 540 B |
Before Width: | Height: | Size: 595 B After Width: | Height: | Size: 679 B |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 30 KiB |
After Width: | Height: | Size: 29 KiB |
After Width: | Height: | Size: 420 B |
After Width: | Height: | Size: 30 KiB |
After Width: | Height: | Size: 509 B |
After Width: | Height: | Size: 29 KiB |
After Width: | Height: | Size: 406 B |
After Width: | Height: | Size: 234 B |
After Width: | Height: | Size: 157 B |
After Width: | Height: | Size: 176 B |
After Width: | Height: | Size: 251 B |
After Width: | Height: | Size: 468 B |
After Width: | Height: | Size: 479 B |
After Width: | Height: | Size: 482 B |
After Width: | Height: | Size: 512 B |
After Width: | Height: | Size: 505 B |
After Width: | Height: | Size: 505 B |
After Width: | Height: | Size: 481 B |
After Width: | Height: | Size: 461 B |
After Width: | Height: | Size: 492 B |
After Width: | Height: | Size: 516 B |
After Width: | Height: | Size: 500 B |
After Width: | Height: | Size: 482 B |
After Width: | Height: | Size: 481 B |
After Width: | Height: | Size: 553 B |
After Width: | Height: | Size: 469 B |
After Width: | Height: | Size: 460 B |
After Width: | Height: | Size: 508 B |
After Width: | Height: | Size: 168 B |
After Width: | Height: | Size: 123 B |
After Width: | Height: | Size: 165 B |
After Width: | Height: | Size: 168 B |
After Width: | Height: | Size: 150 B |
After Width: | Height: | Size: 296 B |
After Width: | Height: | Size: 326 B |
After Width: | Height: | Size: 445 B |
After Width: | Height: | Size: 625 B |
After Width: | Height: | Size: 297 B |
After Width: | Height: | Size: 199 B |
After Width: | Height: | Size: 177 B |
After Width: | Height: | Size: 186 B |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 459 B |
After Width: | Height: | Size: 491 B |
After Width: | Height: | Size: 589 B |
After Width: | Height: | Size: 136 B |
After Width: | Height: | Size: 226 B |
After Width: | Height: | Size: 470 B |
After Width: | Height: | Size: 148 B |
After Width: | Height: | Size: 466 B |
After Width: | Height: | Size: 170 B |
After Width: | Height: | Size: 191 B |
After Width: | Height: | Size: 189 B |
After Width: | Height: | Size: 341 B |
After Width: | Height: | Size: 340 B |
After Width: | Height: | Size: 499 B |
After Width: | Height: | Size: 242 B |
After Width: | Height: | Size: 366 B |
After Width: | Height: | Size: 453 B |
After Width: | Height: | Size: 696 B |
After Width: | Height: | Size: 271 B |
After Width: | Height: | Size: 640 B |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 289 B |
After Width: | Height: | Size: 252 B |
After Width: | Height: | Size: 431 B |