Up version. Update ru translate.
This commit is contained in:
parent
66539798e6
commit
ef2a36cac4
191
FlatCAMApp.py
191
FlatCAMApp.py
|
@ -94,8 +94,8 @@ class App(QtCore.QObject):
|
|||
log.addHandler(handler)
|
||||
|
||||
# Version
|
||||
version = 8.918
|
||||
version_date = "2019/06/11"
|
||||
version = 8.919
|
||||
version_date = "2019/06/23"
|
||||
beta = True
|
||||
|
||||
# current date now
|
||||
|
@ -780,7 +780,7 @@ class App(QtCore.QObject):
|
|||
# Geometry General
|
||||
"geometry_plot": True,
|
||||
"geometry_circle_steps": 128,
|
||||
"geometry_cnctooldia": 0.016,
|
||||
"geometry_cnctooldia": "0.016",
|
||||
|
||||
# Geometry Options
|
||||
"geometry_cutz": -0.002,
|
||||
|
@ -2059,9 +2059,9 @@ class App(QtCore.QObject):
|
|||
except Exception as e:
|
||||
log.debug("App.defaults_read_form() --> %s" % str(e))
|
||||
|
||||
def defaults_write_form(self, factor=None):
|
||||
def defaults_write_form(self, factor=None, fl_units=None):
|
||||
for option in self.defaults:
|
||||
self.defaults_write_form_field(option, factor=factor)
|
||||
self.defaults_write_form_field(option, factor=factor, units=fl_units)
|
||||
# try:
|
||||
# self.defaults_form_fields[option].set_value(self.defaults[option])
|
||||
# except KeyError:
|
||||
|
@ -2069,12 +2069,22 @@ class App(QtCore.QObject):
|
|||
# # TODO: Rethink this?
|
||||
# pass
|
||||
|
||||
def defaults_write_form_field(self, field, factor=None):
|
||||
def defaults_write_form_field(self, field, factor=None, units=None):
|
||||
try:
|
||||
if factor is None:
|
||||
self.defaults_form_fields[field].set_value(self.defaults[field])
|
||||
if units is None:
|
||||
self.defaults_form_fields[field].set_value(self.defaults[field])
|
||||
elif units == 'IN' and (field == 'global_gridx' or field == 'global_gridy'):
|
||||
self.defaults_form_fields[field].set_value(self.defaults[field], decimals=6)
|
||||
elif units == 'MM' and (field == 'global_gridx' or field == 'global_gridy'):
|
||||
self.defaults_form_fields[field].set_value(self.defaults[field], decimals=4)
|
||||
else:
|
||||
self.defaults_form_fields[field].set_value(self.defaults[field] * factor)
|
||||
if units is None:
|
||||
self.defaults_form_fields[field].set_value(self.defaults[field] * factor)
|
||||
elif units == 'IN' and (field == 'global_gridx' or field == 'global_gridy'):
|
||||
self.defaults_form_fields[field].set_value((self.defaults[field] * factor), decimals=6)
|
||||
elif units == 'MM' and (field == 'global_gridx' or field == 'global_gridy'):
|
||||
self.defaults_form_fields[field].set_value((self.defaults[field] * factor), decimals=4)
|
||||
except KeyError:
|
||||
# self.log.debug("defaults_write_form(): No field for: %s" % option)
|
||||
# TODO: Rethink this?
|
||||
|
@ -2108,11 +2118,10 @@ class App(QtCore.QObject):
|
|||
self.paste_tool.install(icon=QtGui.QIcon('share/solderpastebis32.png'))
|
||||
|
||||
self.calculator_tool = ToolCalculator(self)
|
||||
self.calculator_tool.install(icon=QtGui.QIcon('share/calculator24.png'))
|
||||
self.calculator_tool.install(icon=QtGui.QIcon('share/calculator24.png'), separator=True)
|
||||
|
||||
self.sub_tool = ToolSub(self)
|
||||
self.sub_tool.install(icon=QtGui.QIcon('share/sub32.png'), pos=self.ui.menuedit_convert,
|
||||
before=self.ui.menuedit_convert_sg2mg)
|
||||
self.sub_tool.install(icon=QtGui.QIcon('share/sub32.png'), pos=self.ui.menutool, separator=True)
|
||||
|
||||
self.move_tool = ToolMove(self)
|
||||
self.move_tool.install(icon=QtGui.QIcon('share/move16.png'), pos=self.ui.menuedit,
|
||||
|
@ -2245,7 +2254,18 @@ class App(QtCore.QObject):
|
|||
self.inform.emit(_("[WARNING_NOTCL] Simultanoeus editing of tools geometry in a MultiGeo Geometry "
|
||||
"is not possible.\n"
|
||||
"Edit only one geometry at a time."))
|
||||
self.geo_editor.edit_fcgeometry(edited_object, multigeo_tool=edited_tools[0])
|
||||
|
||||
# determine the tool dia of the selected tool
|
||||
selected_tooldia = float(edited_object.ui.geo_tools_table.item((edited_tools[0] - 1), 1).text())
|
||||
|
||||
# now find the key in the edited_object.tools that has this tooldia
|
||||
multi_tool = 1
|
||||
for tool in edited_object.tools:
|
||||
if edited_object.tools[tool]['tooldia'] == selected_tooldia:
|
||||
multi_tool = tool
|
||||
break
|
||||
|
||||
self.geo_editor.edit_fcgeometry(edited_object, multigeo_tool=multi_tool)
|
||||
else:
|
||||
self.geo_editor.edit_fcgeometry(edited_object)
|
||||
|
||||
|
@ -3618,9 +3638,10 @@ class App(QtCore.QObject):
|
|||
if self.toggle_units_ignore:
|
||||
return
|
||||
|
||||
new_units = self.ui.general_defaults_form.general_app_group.units_radio.get_value().upper()
|
||||
|
||||
# If option is the same, then ignore
|
||||
if self.ui.general_defaults_form.general_app_group.units_radio.get_value().upper() == \
|
||||
self.defaults["units"].upper():
|
||||
if new_units == self.defaults["units"].upper():
|
||||
self.log.debug("on_toggle_units(): Same as defaults, so ignoring.")
|
||||
return
|
||||
|
||||
|
@ -3667,21 +3688,60 @@ class App(QtCore.QObject):
|
|||
coords_xy[0] *= sfactor
|
||||
coords_xy[1] *= sfactor
|
||||
self.options['geometry_toolchangexy'] = "%f, %f" % (coords_xy[0], coords_xy[1])
|
||||
elif dim == 'geometry_cnctooldia':
|
||||
tools_diameters = []
|
||||
try:
|
||||
tools_string = self.defaults["geometry_cnctooldia"].split(",")
|
||||
tools_diameters = [eval(a) for a in tools_string if a != '']
|
||||
except Exception as e:
|
||||
log.debug("App.on_toggle_units().scale_options() --> %s" % str(e))
|
||||
|
||||
self.options['geometry_cnctooldia'] = ''
|
||||
for t in range(len(tools_diameters)):
|
||||
tools_diameters[t] *= sfactor
|
||||
self.options['geometry_cnctooldia'] += "%f," % tools_diameters[t]
|
||||
elif dim == 'tools_ncctools':
|
||||
ncctols = [float(eval(a)) for a in self.defaults["tools_ncctools"].split(",")]
|
||||
ncctols[0] *= sfactor
|
||||
ncctols[1] *= sfactor
|
||||
self.options['tools_ncctools'] = "%f, %f" % (ncctols[0], ncctols[1])
|
||||
ncctools = []
|
||||
try:
|
||||
tools_string = self.defaults["tools_ncctools"].split(",")
|
||||
ncctools = [eval(a) for a in tools_string if a != '']
|
||||
except Exception as e:
|
||||
log.debug("App.on_toggle_units().scale_options() --> %s" % str(e))
|
||||
|
||||
self.options['tools_ncctools'] = ''
|
||||
for t in range(len(ncctools)):
|
||||
ncctools[t] *= sfactor
|
||||
self.options['tools_ncctools'] += "%f," % ncctools[t]
|
||||
elif dim == 'tools_solderpaste_tools':
|
||||
sp_tools = [float(eval(a)) for a in self.defaults["tools_solderpaste_tools"].split(",")]
|
||||
sp_tools[0] *= sfactor
|
||||
sp_tools[1] *= sfactor
|
||||
self.options['tools_solderpaste_tools'] = "%f, %f" % (sp_tools[0], sp_tools[1])
|
||||
sptools = []
|
||||
try:
|
||||
tools_string = self.defaults["tools_solderpaste_tools"].split(",")
|
||||
sptools = [eval(a) for a in tools_string if a != '']
|
||||
except Exception as e:
|
||||
log.debug("App.on_toggle_units().scale_options() --> %s" % str(e))
|
||||
|
||||
self.options['tools_solderpaste_tools'] = ""
|
||||
for t in range(len(sptools)):
|
||||
sptools[t] *= sfactor
|
||||
self.options['tools_solderpaste_tools'] += "%f," % sptools[t]
|
||||
elif dim == 'tools_solderpaste_xy_toolchange':
|
||||
sp_coords = [float(eval(a)) for a in self.defaults["tools_solderpaste_xy_toolchange"].split(",")]
|
||||
sp_coords[0] *= sfactor
|
||||
sp_coords[1] *= sfactor
|
||||
self.options['tools_solderpaste_xy_toolchange'] = "%f, %f" % (sp_coords[0], sp_coords[1])
|
||||
elif dim == 'global_gridx' or dim == 'global_gridy':
|
||||
if new_units == 'IN':
|
||||
try:
|
||||
val = float(self.defaults[dim]) * sfactor
|
||||
self.options[dim] = float('%.6f' % val)
|
||||
except Exception as e:
|
||||
log.debug('App.on_toggle_units().scale_defaults() --> %s' % str(e))
|
||||
else:
|
||||
try:
|
||||
val = float(self.defaults[dim]) * sfactor
|
||||
self.options[dim] = float('%.4f' % val)
|
||||
except Exception as e:
|
||||
log.debug('App.on_toggle_units().scale_defaults() --> %s' % str(e))
|
||||
else:
|
||||
try:
|
||||
self.options[dim] = float(self.options[dim]) * sfactor
|
||||
|
@ -3700,21 +3760,60 @@ class App(QtCore.QObject):
|
|||
coords_xy[0] *= sfactor
|
||||
coords_xy[1] *= sfactor
|
||||
self.defaults['geometry_toolchangexy'] = "%.4f, %.4f" % (coords_xy[0], coords_xy[1])
|
||||
elif dim == 'geometry_cnctooldia':
|
||||
tools_diameters = []
|
||||
try:
|
||||
tools_string = self.defaults["geometry_cnctooldia"].split(",")
|
||||
tools_diameters = [eval(a) for a in tools_string if a != '']
|
||||
except Exception as e:
|
||||
log.debug("App.on_toggle_units().scale_options() --> %s" % str(e))
|
||||
|
||||
self.defaults['geometry_cnctooldia'] = ''
|
||||
for t in range(len(tools_diameters)):
|
||||
tools_diameters[t] *= sfactor
|
||||
self.defaults['geometry_cnctooldia'] += "%.4f," % tools_diameters[t]
|
||||
elif dim == 'tools_ncctools':
|
||||
ncctols = [float(eval(a)) for a in self.defaults["tools_ncctools"].split(",")]
|
||||
ncctols[0] *= sfactor
|
||||
ncctols[1] *= sfactor
|
||||
self.defaults['tools_ncctools'] = "%.4f, %.4f" % (ncctols[0], ncctols[1])
|
||||
ncctools = []
|
||||
try:
|
||||
tools_string = self.defaults["tools_ncctools"].split(",")
|
||||
ncctools = [eval(a) for a in tools_string if a != '']
|
||||
except Exception as e:
|
||||
log.debug("App.on_toggle_units().scale_options() --> %s" % str(e))
|
||||
|
||||
self.defaults['tools_ncctools'] = ''
|
||||
for t in range(len(ncctools)):
|
||||
ncctools[t] *= sfactor
|
||||
self.defaults['tools_ncctools'] += "%.4f," % ncctools[t]
|
||||
elif dim == 'tools_solderpaste_tools':
|
||||
sp_tools = [float(eval(a)) for a in self.defaults["tools_solderpaste_tools"].split(",")]
|
||||
sp_tools[0] *= sfactor
|
||||
sp_tools[1] *= sfactor
|
||||
self.defaults['tools_solderpaste_tools'] = "%.4f, %.4f" % (sp_tools[0], sp_tools[1])
|
||||
sptools = []
|
||||
try:
|
||||
tools_string = self.defaults["tools_solderpaste_tools"].split(",")
|
||||
sptools = [eval(a) for a in tools_string if a != '']
|
||||
except Exception as e:
|
||||
log.debug("App.on_toggle_units().scale_options() --> %s" % str(e))
|
||||
|
||||
self.defaults['tools_solderpaste_tools'] = ""
|
||||
for t in range(len(sptools)):
|
||||
sptools[t] *= sfactor
|
||||
self.defaults['tools_solderpaste_tools'] += "%.4f," % sptools[t]
|
||||
elif dim == 'tools_solderpaste_xy_toolchange':
|
||||
sp_coords = [float(eval(a)) for a in self.defaults["tools_solderpaste_xy_toolchange"].split(",")]
|
||||
sp_coords[0] *= sfactor
|
||||
sp_coords[1] *= sfactor
|
||||
self.defaults['tools_solderpaste_xy_toolchange'] = "%.4f, %.4f" % (sp_coords[0], sp_coords[1])
|
||||
elif dim == 'global_gridx' or dim == 'global_gridy':
|
||||
if new_units == 'IN':
|
||||
try:
|
||||
val = float(self.defaults[dim]) * sfactor
|
||||
self.defaults[dim] = float('%.6f' % val)
|
||||
except Exception as e:
|
||||
log.debug('App.on_toggle_units().scale_defaults() --> %s' % str(e))
|
||||
else:
|
||||
try:
|
||||
val = float(self.defaults[dim]) * sfactor
|
||||
self.defaults[dim] = float('%.4f' % val)
|
||||
except Exception as e:
|
||||
log.debug('App.on_toggle_units().scale_defaults() --> %s' % str(e))
|
||||
else:
|
||||
try:
|
||||
self.defaults[dim] = float(self.defaults[dim]) * sfactor
|
||||
|
@ -3723,7 +3822,7 @@ class App(QtCore.QObject):
|
|||
|
||||
# The scaling factor depending on choice of units.
|
||||
factor = 1/25.4
|
||||
if self.ui.general_defaults_form.general_app_group.units_radio.get_value().upper() == 'MM':
|
||||
if new_units == 'MM':
|
||||
factor = 25.4
|
||||
|
||||
# Changing project units. Warn user.
|
||||
|
@ -3748,7 +3847,7 @@ class App(QtCore.QObject):
|
|||
|
||||
self.defaults_read_form()
|
||||
scale_defaults(factor)
|
||||
self.defaults_write_form()
|
||||
self.defaults_write_form(fl_units=new_units)
|
||||
|
||||
self.should_we_save = True
|
||||
|
||||
|
@ -3757,12 +3856,15 @@ class App(QtCore.QObject):
|
|||
self.plotcanvas.draw_workspace()
|
||||
|
||||
# adjust the grid values on the main toolbar
|
||||
self.ui.grid_gap_x_entry.set_value(float(self.ui.grid_gap_x_entry.get_value()) * factor)
|
||||
self.ui.grid_gap_y_entry.set_value(float(self.ui.grid_gap_y_entry.get_value()) * factor)
|
||||
dec = 6 if new_units == 'IN'else 4
|
||||
val_x = float(self.ui.grid_gap_x_entry.get_value()) * factor
|
||||
self.ui.grid_gap_x_entry.set_value(val_x, decimals=dec)
|
||||
if not self.ui.grid_gap_link_cb.isChecked():
|
||||
val_y = float(self.ui.grid_gap_y_entry.get_value()) * factor
|
||||
self.ui.grid_gap_y_entry.set_value(val_y, decimals=dec)
|
||||
|
||||
units = self.ui.general_defaults_form.general_app_group.units_radio.get_value().upper()
|
||||
for obj in self.collection.get_list():
|
||||
obj.convert_units(units)
|
||||
obj.convert_units(new_units)
|
||||
|
||||
# make that the properties stored in the object are also updated
|
||||
self.object_changed.emit(obj)
|
||||
|
@ -3775,9 +3877,9 @@ class App(QtCore.QObject):
|
|||
current.to_form()
|
||||
|
||||
self.plot_all()
|
||||
self.inform.emit(_("[success] Converted units to %s") % units)
|
||||
self.inform.emit(_("[success] Converted units to %s") % new_units)
|
||||
# self.ui.units_label.setText("[" + self.options["units"] + "]")
|
||||
self.set_screen_units(units)
|
||||
self.set_screen_units(new_units)
|
||||
else:
|
||||
# Undo toggling
|
||||
self.toggle_units_ignore = True
|
||||
|
@ -5249,6 +5351,7 @@ class App(QtCore.QObject):
|
|||
if index.isValid():
|
||||
if index.internalPointer().parent_item != self.collection.root_item:
|
||||
self.ui.notebook.setCurrentWidget(self.ui.selected_tab)
|
||||
self.collection.on_item_activated(index)
|
||||
|
||||
def grid_status(self):
|
||||
if self.ui.grid_snap_btn.isChecked():
|
||||
|
@ -5423,6 +5526,7 @@ class App(QtCore.QObject):
|
|||
self.click_noproject = True
|
||||
|
||||
self.clipboard.setText(self.defaults["global_point_clipboard_format"] % (self.pos[0], self.pos[1]))
|
||||
self.inform.emit(_("[success] Coordinates copied to clipboard."))
|
||||
return
|
||||
|
||||
self.on_mouse_move_over_plot(event, origin_click=True)
|
||||
|
@ -5579,6 +5683,10 @@ class App(QtCore.QObject):
|
|||
if self.command_active is None:
|
||||
self.select_objects(key='CTRL')
|
||||
self.delete_hover_shape()
|
||||
elif modifiers == QtCore.Qt.ShiftModifier:
|
||||
# if SHIFT was pressed and LMB is clicked then we have a coordinates copy to clipboard
|
||||
# therefore things should stay as they are
|
||||
pass
|
||||
else:
|
||||
# If there is no active command (self.command_active is None) then we check if we clicked
|
||||
# on a object by checking the bounding limits against mouse click position
|
||||
|
@ -8044,7 +8152,7 @@ class App(QtCore.QObject):
|
|||
|
||||
This behavior works only within main thread,
|
||||
errors with promissed tasks can be catched and detected only with log.
|
||||
TODO: this problem have to be addressed somehow, maybe rewrite promissing to be blocking somehow for
|
||||
TODO: this problem have to be addressed somehow, maybe rewrite promissing to be blocking somehow for
|
||||
TCL shell.
|
||||
|
||||
Kamil's comment: I will rewrite existing TCL commands from time to time to follow this rules.
|
||||
|
@ -8252,7 +8360,10 @@ The normal flow when working in FlatCAM is the following:</span></p>
|
|||
"""
|
||||
FlatCAMObj.app = self
|
||||
ObjectCollection.app = self
|
||||
|
||||
Gerber.app = self
|
||||
Excellon.app = self
|
||||
Geometry.app = self
|
||||
CNCjob.app = self
|
||||
FCProcess.app = self
|
||||
FCProcessContainer.app = self
|
||||
|
||||
|
|
155
FlatCAMObj.py
155
FlatCAMObj.py
|
@ -68,6 +68,9 @@ class FlatCAMObj(QtCore.QObject):
|
|||
|
||||
self.form_fields = {}
|
||||
|
||||
# store here the default data for Geometry Data
|
||||
self.default_data = {}
|
||||
|
||||
self.kind = None # Override with proper name
|
||||
|
||||
# self.shapes = ShapeCollection(parent=self.app.plotcanvas.vispy_canvas.view.scene)
|
||||
|
@ -137,7 +140,7 @@ class FlatCAMObj(QtCore.QObject):
|
|||
if key == 'plot':
|
||||
self.visible = self.options['plot']
|
||||
|
||||
# self.optionChanged.emit(key)
|
||||
self.optionChanged.emit(key)
|
||||
|
||||
def set_ui(self, ui):
|
||||
self.ui = ui
|
||||
|
@ -199,6 +202,8 @@ class FlatCAMObj(QtCore.QObject):
|
|||
log.debug("on_name_activate() --> Could not remove the old object name from auto-completer model list")
|
||||
|
||||
self.options["name"] = self.ui.name_entry.get_value()
|
||||
self.default_data["name"] = self.ui.name_entry.get_value()
|
||||
self.app.collection.update_view()
|
||||
self.app.inform.emit(_("[success] Name changed from {old} to {new}").format(old=old_name, new=new_name))
|
||||
|
||||
def on_offset_button_click(self):
|
||||
|
@ -338,7 +343,7 @@ class FlatCAMObj(QtCore.QObject):
|
|||
return self.shapes.visible
|
||||
|
||||
@visible.setter
|
||||
def visible(self, value):
|
||||
def visible(self, value, threaded=False):
|
||||
log.debug("FlatCAMObj.visible()")
|
||||
|
||||
def worker_task(app_obj):
|
||||
|
@ -350,7 +355,10 @@ class FlatCAMObj(QtCore.QObject):
|
|||
except Exception as e:
|
||||
pass
|
||||
|
||||
self.app.worker_task.emit({'fcn': worker_task, 'params': [self]})
|
||||
if threaded is False:
|
||||
worker_task(self)
|
||||
else:
|
||||
self.app.worker_task.emit({'fcn': worker_task, 'params': [self]})
|
||||
|
||||
@property
|
||||
def drawing_tolerance(self):
|
||||
|
@ -810,7 +818,7 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
|
|||
|
||||
def follow_init(follow_obj, app):
|
||||
# Propagate options
|
||||
follow_obj.options["cnctooldia"] = float(self.options["isotooldia"])
|
||||
follow_obj.options["cnctooldia"] = str(self.options["isotooldia"])
|
||||
follow_obj.solid_geometry = self.follow_geometry
|
||||
|
||||
# TODO: Do something if this is None. Offer changing name?
|
||||
|
@ -832,7 +840,6 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
|
|||
:return: None
|
||||
"""
|
||||
|
||||
|
||||
if dia is None:
|
||||
dia = float(self.options["isotooldia"])
|
||||
if passes is None:
|
||||
|
@ -893,7 +900,7 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
|
|||
# TODO: This is ugly. Create way to pass data into init function.
|
||||
def iso_init(geo_obj, app_obj):
|
||||
# Propagate options
|
||||
geo_obj.options["cnctooldia"] = float(self.options["isotooldia"])
|
||||
geo_obj.options["cnctooldia"] = str(self.options["isotooldia"])
|
||||
geo_obj.solid_geometry = []
|
||||
for i in range(passes):
|
||||
iso_offset = (((2 * i + 1) / 2.0) * dia) - (i * overlap * dia)
|
||||
|
@ -950,7 +957,7 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
|
|||
# TODO: This is ugly. Create way to pass data into init function.
|
||||
def iso_init(geo_obj, app_obj):
|
||||
# Propagate options
|
||||
geo_obj.options["cnctooldia"] = float(self.options["isotooldia"])
|
||||
geo_obj.options["cnctooldia"] = str(self.options["isotooldia"])
|
||||
|
||||
# if milling type is climb then the move is counter-clockwise around features
|
||||
if milling_type == 'cl':
|
||||
|
@ -1638,7 +1645,7 @@ class FlatCAMExcellon(FlatCAMObj, Excellon):
|
|||
exc.app.log.warning("Failed to copy option.", option)
|
||||
|
||||
for drill in exc.drills:
|
||||
exc_tool_dia = float('%.3f' % exc.tools[drill['tool']]['C'])
|
||||
exc_tool_dia = float('%.4f' % exc.tools[drill['tool']]['C'])
|
||||
|
||||
if exc_tool_dia not in custom_dict_drills:
|
||||
custom_dict_drills[exc_tool_dia] = [drill['point']]
|
||||
|
@ -1646,7 +1653,7 @@ class FlatCAMExcellon(FlatCAMObj, Excellon):
|
|||
custom_dict_drills[exc_tool_dia].append(drill['point'])
|
||||
|
||||
for slot in exc.slots:
|
||||
exc_tool_dia = float('%.3f' % exc.tools[slot['tool']]['C'])
|
||||
exc_tool_dia = float('%.4f' % exc.tools[slot['tool']]['C'])
|
||||
|
||||
if exc_tool_dia not in custom_dict_slots:
|
||||
custom_dict_slots[exc_tool_dia] = [[slot['start'], slot['stop']]]
|
||||
|
@ -1739,7 +1746,7 @@ class FlatCAMExcellon(FlatCAMObj, Excellon):
|
|||
temp_tools[tool_name_temp] = spec_temp
|
||||
|
||||
for drill in exc_final.drills:
|
||||
exc_tool_dia = float('%.3f' % exc_final.tools[drill['tool']]['C'])
|
||||
exc_tool_dia = float('%.4f' % exc_final.tools[drill['tool']]['C'])
|
||||
if exc_tool_dia == ordered_dia:
|
||||
temp_drills.append(
|
||||
{
|
||||
|
@ -1749,7 +1756,7 @@ class FlatCAMExcellon(FlatCAMObj, Excellon):
|
|||
)
|
||||
|
||||
for slot in exc_final.slots:
|
||||
slot_tool_dia = float('%.3f' % exc_final.tools[slot['tool']]['C'])
|
||||
slot_tool_dia = float('%.4f' % exc_final.tools[slot['tool']]['C'])
|
||||
if slot_tool_dia == ordered_dia:
|
||||
temp_slots.append(
|
||||
{
|
||||
|
@ -1825,7 +1832,7 @@ class FlatCAMExcellon(FlatCAMObj, Excellon):
|
|||
if self.units == 'MM':
|
||||
dia = QtWidgets.QTableWidgetItem('%.2f' % (self.tools[tool_no]['C']))
|
||||
else:
|
||||
dia = QtWidgets.QTableWidgetItem('%.3f' % (self.tools[tool_no]['C']))
|
||||
dia = QtWidgets.QTableWidgetItem('%.4f' % (self.tools[tool_no]['C']))
|
||||
|
||||
dia.setFlags(QtCore.Qt.ItemIsEnabled)
|
||||
|
||||
|
@ -1843,7 +1850,7 @@ class FlatCAMExcellon(FlatCAMObj, Excellon):
|
|||
if self.units == 'MM':
|
||||
t_offset = self.tool_offset[float('%.2f' % float(self.tools[tool_no]['C']))]
|
||||
else:
|
||||
t_offset = self.tool_offset[float('%.3f' % float(self.tools[tool_no]['C']))]
|
||||
t_offset = self.tool_offset[float('%.4f' % float(self.tools[tool_no]['C']))]
|
||||
except KeyError:
|
||||
t_offset = self.app.defaults['excellon_offset']
|
||||
tool_offset_item = QtWidgets.QTableWidgetItem('%s' % str(t_offset))
|
||||
|
@ -1934,10 +1941,6 @@ class FlatCAMExcellon(FlatCAMObj, Excellon):
|
|||
self.ui.tools_table.setColumnWidth(5, 17)
|
||||
|
||||
# horizontal_header.setStretchLastSection(True)
|
||||
|
||||
|
||||
|
||||
|
||||
# horizontal_header.setColumnWidth(2, QtWidgets.QHeaderView.ResizeToContents)
|
||||
|
||||
# horizontal_header.setStretchLastSection(True)
|
||||
|
@ -2022,7 +2025,7 @@ class FlatCAMExcellon(FlatCAMObj, Excellon):
|
|||
if self.units == 'MM':
|
||||
dia = float('%.2f' % float(value['C']))
|
||||
else:
|
||||
dia = float('%.3f' % float(value['C']))
|
||||
dia = float('%.4f' % float(value['C']))
|
||||
self.tool_offset[dia] = t_default_offset
|
||||
|
||||
# Show/Hide Advanced Options
|
||||
|
@ -2086,7 +2089,7 @@ class FlatCAMExcellon(FlatCAMObj, Excellon):
|
|||
if self.units == 'MM':
|
||||
dia = float('%.2f' % float(self.ui.tools_table.item(row_of_item_changed, 1).text()))
|
||||
else:
|
||||
dia = float('%.3f' % float(self.ui.tools_table.item(row_of_item_changed, 1).text()))
|
||||
dia = float('%.4f' % float(self.ui.tools_table.item(row_of_item_changed, 1).text()))
|
||||
|
||||
current_table_offset_edited = None
|
||||
if self.ui.tools_table.currentItem() is not None:
|
||||
|
@ -2349,6 +2352,7 @@ class FlatCAMExcellon(FlatCAMObj, Excellon):
|
|||
|
||||
geo_obj.options['Tools_in_use'] = tool_table_items
|
||||
geo_obj.options['type'] = 'Excellon Geometry'
|
||||
geo_obj.options["cnctooldia"] = str(tooldia)
|
||||
|
||||
geo_obj.solid_geometry = []
|
||||
|
||||
|
@ -2443,6 +2447,7 @@ class FlatCAMExcellon(FlatCAMObj, Excellon):
|
|||
|
||||
geo_obj.options['Tools_in_use'] = tool_table_items
|
||||
geo_obj.options['type'] = 'Excellon Geometry'
|
||||
geo_obj.options["cnctooldia"] = str(tooldia)
|
||||
|
||||
geo_obj.solid_geometry = []
|
||||
|
||||
|
@ -2953,6 +2958,14 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
|
|||
|
||||
if "cnctooldia" not in self.options:
|
||||
self.options["cnctooldia"] = self.app.defaults["geometry_cnctooldia"]
|
||||
# try:
|
||||
# self.options["cnctooldia"] = [
|
||||
# float(eval(dia)) for dia in str(self.app.defaults["geometry_cnctooldia"]).split(",")
|
||||
# ]
|
||||
# except Exception as e:
|
||||
# log.error("At least one tool diameter needed. Verify in Edit -> Preferences -> Geometry General -> "
|
||||
# "Tool dia. %s" % str(e))
|
||||
# return
|
||||
|
||||
self.options["startz"] = self.app.defaults["geometry_startz"]
|
||||
|
||||
|
@ -2998,9 +3011,6 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
|
|||
self.old_pp_state = ''
|
||||
self.old_toolchangeg_state = ''
|
||||
|
||||
# store here the default data for Geometry Data
|
||||
self.default_data = {}
|
||||
|
||||
# Attributes to be included in serialization
|
||||
# Always append to it because it carries contents
|
||||
# from predecessors.
|
||||
|
@ -3009,7 +3019,6 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
|
|||
def build_ui(self):
|
||||
|
||||
self.ui_disconnect()
|
||||
|
||||
FlatCAMObj.build_ui(self)
|
||||
|
||||
offset = 0
|
||||
|
@ -3147,6 +3156,10 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
|
|||
self.set_tool_offset_visibility(selected_row)
|
||||
self.ui_connect()
|
||||
|
||||
# HACK: for whatever reasons the name in Selected tab is reverted to the original one after a successful rename
|
||||
# done in the collection view but only for Geometry objects. Perhaps some references remains. Should be fixed.
|
||||
self.ui.name_entry.set_value(self.options['name'])
|
||||
|
||||
def set_ui(self, ui):
|
||||
FlatCAMObj.set_ui(self, ui)
|
||||
|
||||
|
@ -3221,21 +3234,33 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
|
|||
for def_key in self.default_data:
|
||||
for opt_key, opt_val in self.options.items():
|
||||
if def_key == opt_key:
|
||||
self.default_data[def_key] = opt_val
|
||||
self.default_data[def_key] = deepcopy(opt_val)
|
||||
|
||||
try:
|
||||
tools_list = [
|
||||
float(eval(dia)) for dia in self.options["cnctooldia"].split(",")
|
||||
]
|
||||
except Exception as e:
|
||||
log.error("At least one tool diameter needed. Verify in Edit -> Preferences -> Geometry General -> "
|
||||
"Tool dia. %s" % str(e))
|
||||
return
|
||||
|
||||
self.tooluid += 1
|
||||
|
||||
if not self.tools:
|
||||
self.tools.update({
|
||||
self.tooluid: {
|
||||
'tooldia': float(self.options["cnctooldia"]),
|
||||
'offset': ('Path'),
|
||||
'offset_value': 0.0,
|
||||
'type': _('Rough'),
|
||||
'tool_type': 'C1',
|
||||
'data': self.default_data,
|
||||
'solid_geometry': self.solid_geometry
|
||||
}
|
||||
})
|
||||
for toold in tools_list:
|
||||
self.tools.update({
|
||||
self.tooluid: {
|
||||
'tooldia': float(toold),
|
||||
'offset': ('Path'),
|
||||
'offset_value': 0.0,
|
||||
'type': _('Rough'),
|
||||
'tool_type': 'C1',
|
||||
'data': self.default_data,
|
||||
'solid_geometry': self.solid_geometry
|
||||
}
|
||||
})
|
||||
self.tooluid += 1
|
||||
else:
|
||||
# if self.tools is not empty then it can safely be assumed that it comes from an opened project.
|
||||
# Because of the serialization the self.tools list on project save, the dict keys (members of self.tools
|
||||
|
@ -3321,10 +3346,11 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
|
|||
return
|
||||
|
||||
def on_offset_value_edited(self):
|
||||
'''
|
||||
This will save the offset_value into self.tools storage whenever the oofset value is edited
|
||||
"""
|
||||
This will save the offset_value into self.tools storage whenever the offset value is edited
|
||||
:return:
|
||||
'''
|
||||
"""
|
||||
|
||||
for current_row in self.ui.geo_tools_table.selectedItems():
|
||||
# sometime the header get selected and it has row number -1
|
||||
# we don't want to do anything with the header :)
|
||||
|
@ -3367,7 +3393,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
|
|||
# works for Entry
|
||||
try:
|
||||
self.ui.grid3.itemAt(i).widget().editingFinished.connect(self.gui_form_to_storage)
|
||||
except:
|
||||
except Exception as e3:
|
||||
pass
|
||||
|
||||
for row in range(self.ui.geo_tools_table.rowCount()):
|
||||
|
@ -3405,56 +3431,56 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
|
|||
isinstance(self.ui.grid3.itemAt(i).widget(), IntEntry) or \
|
||||
isinstance(self.ui.grid3.itemAt(i).widget(), FCEntry):
|
||||
self.ui.grid3.itemAt(i).widget().editingFinished.disconnect()
|
||||
except:
|
||||
except Exception as e:
|
||||
pass
|
||||
|
||||
try:
|
||||
for row in range(self.ui.geo_tools_table.rowCount()):
|
||||
for col in [2, 3, 4]:
|
||||
self.ui.geo_tools_table.cellWidget(row, col).currentIndexChanged.disconnect()
|
||||
except:
|
||||
except Exception as e:
|
||||
pass
|
||||
|
||||
# I use lambda's because the connected functions have parameters that could be used in certain scenarios
|
||||
try:
|
||||
self.ui.addtool_btn.clicked.disconnect()
|
||||
except:
|
||||
except Exception as e:
|
||||
pass
|
||||
|
||||
try:
|
||||
self.ui.copytool_btn.clicked.disconnect()
|
||||
except:
|
||||
except Exception as e:
|
||||
pass
|
||||
|
||||
try:
|
||||
self.ui.deltool_btn.clicked.disconnect()
|
||||
except:
|
||||
except Exception as e:
|
||||
pass
|
||||
|
||||
try:
|
||||
self.ui.geo_tools_table.currentItemChanged.disconnect()
|
||||
except:
|
||||
except Exception as e:
|
||||
pass
|
||||
|
||||
try:
|
||||
self.ui.geo_tools_table.itemChanged.disconnect()
|
||||
except:
|
||||
except Exception as e:
|
||||
pass
|
||||
|
||||
try:
|
||||
self.ui.tool_offset_entry.editingFinished.disconnect()
|
||||
except:
|
||||
except Exception as e:
|
||||
pass
|
||||
|
||||
for row in range(self.ui.geo_tools_table.rowCount()):
|
||||
try:
|
||||
self.ui.geo_tools_table.cellWidget(row, 6).clicked.disconnect()
|
||||
except:
|
||||
except Exception as e:
|
||||
pass
|
||||
|
||||
try:
|
||||
self.ui.plot_cb.stateChanged.disconnect()
|
||||
except:
|
||||
except Exception as e:
|
||||
pass
|
||||
|
||||
def on_tool_add(self, dia=None):
|
||||
|
@ -3475,7 +3501,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
|
|||
tooldia = float(self.ui.addtool_entry.get_value().replace(',', '.'))
|
||||
except ValueError:
|
||||
change_message = True
|
||||
tooldia = float(self.app.defaults["geometry_cnctooldia"])
|
||||
tooldia = self.options["cnctooldia"][0]
|
||||
|
||||
if tooldia is None:
|
||||
self.build_ui()
|
||||
|
@ -3541,6 +3567,8 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
|
|||
}
|
||||
})
|
||||
|
||||
self.tools[self.tooluid]['data']['name'] = self.options['name']
|
||||
|
||||
self.ui.tool_offset_entry.hide()
|
||||
self.ui.tool_offset_lbl.hide()
|
||||
|
||||
|
@ -3772,7 +3800,11 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
|
|||
|
||||
# populate the form with the data from the tool associated with the row parameter
|
||||
try:
|
||||
tooluid = int(self.ui.geo_tools_table.item(current_row, 5).text())
|
||||
item = self.ui.geo_tools_table.item(current_row, 5)
|
||||
if item is not None:
|
||||
tooluid = int(item.text())
|
||||
else:
|
||||
return
|
||||
except Exception as e:
|
||||
log.debug("Tool missing. Add a tool in Geo Tool Table. %s" % str(e))
|
||||
return
|
||||
|
@ -3780,8 +3812,12 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
|
|||
# update the form with the V-Shape fields if V-Shape selected in the geo_tool_table
|
||||
# also modify the Cut Z form entry to reflect the calculated Cut Z from values got from V-Shape Fields
|
||||
try:
|
||||
tool_type_txt = self.ui.geo_tools_table.cellWidget(current_row, 4).currentText()
|
||||
self.ui_update_v_shape(tool_type_txt=tool_type_txt)
|
||||
item = self.ui.geo_tools_table.cellWidget(current_row, 4)
|
||||
if item is not None:
|
||||
tool_type_txt = item.currentText()
|
||||
self.ui_update_v_shape(tool_type_txt=tool_type_txt)
|
||||
else:
|
||||
return
|
||||
except Exception as e:
|
||||
log.debug("Tool missing. Add a tool in Geo Tool Table. %s" % str(e))
|
||||
return
|
||||
|
@ -4137,7 +4173,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
|
|||
self.ui.cncfeedrate_rapid_entry.hide()
|
||||
|
||||
def on_generatecnc_button_click(self, *args):
|
||||
|
||||
log.debug("Generating CNCJob from Geometry ...")
|
||||
self.app.report_usage("geometry_on_generatecnc_button")
|
||||
self.read_form()
|
||||
|
||||
|
@ -5291,6 +5327,7 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob):
|
|||
else:
|
||||
self.ui.cnc_tools_table.hide()
|
||||
|
||||
self.units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().upper()
|
||||
|
||||
offset = 0
|
||||
tool_idx = 0
|
||||
|
@ -5891,13 +5928,19 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob):
|
|||
self.shapes.clear(update=True)
|
||||
self.annotation.clear(update=True)
|
||||
|
||||
if self.ui.annotation_cb.get_value() and self.ui.plot_cb.get_value():
|
||||
self.app.plotcanvas.text_collection.enabled = True
|
||||
else:
|
||||
self.app.plotcanvas.text_collection.enabled = False
|
||||
|
||||
def on_annotation_change(self):
|
||||
if self.ui.annotation_cb.get_value():
|
||||
self.app.plotcanvas.text_collection.enabled = True
|
||||
else:
|
||||
self.app.plotcanvas.text_collection.enabled = False
|
||||
kind = self.ui.cncplot_method_combo.get_value()
|
||||
self.plot(kind=kind)
|
||||
# kind = self.ui.cncplot_method_combo.get_value()
|
||||
# self.plot(kind=kind)
|
||||
self.annotation.redraw()
|
||||
|
||||
def convert_units(self, units):
|
||||
factor = CNCjob.convert_units(self, units)
|
||||
|
|
|
@ -263,10 +263,9 @@ class ObjectCollection(QtCore.QAbstractItemModel):
|
|||
|
||||
# ## GUI Events
|
||||
self.view.selectionModel().selectionChanged.connect(self.on_list_selection_change)
|
||||
self.view.activated.connect(self.on_item_activated)
|
||||
# self.view.keyPressed.connect(self.on_key)
|
||||
# self.view.activated.connect(self.on_item_activated)
|
||||
self.view.keyPressed.connect(self.app.ui.keyPressEvent)
|
||||
self.view.clicked.connect(self.on_mouse_down)
|
||||
# self.view.clicked.connect(self.on_mouse_down)
|
||||
self.view.customContextMenuRequested.connect(self.on_menu_request)
|
||||
|
||||
self.click_modifier = None
|
||||
|
@ -398,8 +397,9 @@ class ObjectCollection(QtCore.QAbstractItemModel):
|
|||
def setData(self, index, data, role=None):
|
||||
if index.isValid():
|
||||
obj = index.internalPointer().obj
|
||||
|
||||
if obj:
|
||||
old_name = obj.options['name']
|
||||
old_name = deepcopy(obj.options['name'])
|
||||
new_name = str(data)
|
||||
if old_name != new_name and new_name != '':
|
||||
# rename the object
|
||||
|
|
48
README.md
48
README.md
|
@ -9,6 +9,54 @@ CAD program, and create G-Code for Isolation routing.
|
|||
|
||||
=================================================
|
||||
|
||||
23.06.2019
|
||||
|
||||
- fixes issues with units conversion when the tool diameters are a list of comma separated values (NCC Tool, SolderPaste Tool and Geometry Object)
|
||||
- fixed a "typo" kind of bug in SolderPaste Tool
|
||||
- RELEASE 8.919
|
||||
|
||||
22.06.2019
|
||||
|
||||
- some GUI layout optimizations in Edit -> Preferences
|
||||
- added the possibility for multiple tool diameters in the Edit -> Preferences -> Geometry -> Geometry General -> Tool dia separated by comma
|
||||
- fixed scaling for the multiple tool diameters in Edit -> Preferences -> Geometry -> Geometry General -> Tool dia, for NCC tools more than 2 and for Solderpaste nozzles more than 2
|
||||
- fixed bug in CNCJob where the CNC Tools table will show always only 2 decimals for Tool diameters regardless of the current measuring units
|
||||
- made the tools diameters decimals in case of INCH FlatCAM units to be 4 instead of 3
|
||||
- fixed bug in updating Grid values whenever toggling the FlatCAM units and the X, Y Grid values are linked, bugs which caused the Y value to be scaled incorrectly
|
||||
- set the decimals for Grid values to be set to 6 if the units of FlatCAM is INCH and to set to 4 if FlatCAM units are METRIC
|
||||
- updated translations
|
||||
- updated the Russian translation from 51% complete to 69% complete using the Yandex translation engine
|
||||
- fixed recently introduced bug in milling drills/slots functions
|
||||
- moved Substract Tool from Menu -> Edit -> Conversions to Menu -> Tool
|
||||
- fixed bug in Gerber isolation (Geometry expects now a value in string format and not float)
|
||||
- fixed bug in Paint tool: now it is possible to paint geometry generated by External Isolation (or Internal isolation)
|
||||
- fixed bug in editing a multigeo Geometry object if previously a tool was deleted
|
||||
- optimized the toggle of annotations; now there is no need to replot the entire CNCJob object too on toggling of the annotations
|
||||
- on toggling off the plot visibility the annotations are turned off too
|
||||
- updated translations; Russian translation at 76% (using Yandex translator engine - needs verification by a native speaker of Russian)
|
||||
|
||||
20.06.2019
|
||||
|
||||
- fixed Scale and Buffer Tool in Gerber Editor
|
||||
- fixed Editor Transform Tool in Gerber Editor
|
||||
- added a message in the status bar when copying coordinates to clipboard with SHIFT + LMB click combo
|
||||
- languages update
|
||||
|
||||
19.06.2019
|
||||
|
||||
- milling an Excellon file (holes and/or slots) will now transfer the chosen milling bit diameter to the resulting Geometry object
|
||||
|
||||
17.06.2019
|
||||
|
||||
- fixed bug where for Geometry objects after a successful object rename done in the Object collection view (Project tab), deselect the object and reselect it and then in the Selected tab the name is not the new one but the old one
|
||||
- for Geometry objects, adding a new tool to the Tools table after a successful rename will now store the new name in the tool data
|
||||
|
||||
15.06.2019
|
||||
|
||||
- fixed bug in Gerber parser that made the Gerber files generated by Altium Designer 18 not to be loaded
|
||||
- fixed bug in Gerber editor - on multiple edits on the same object, the aperture size and dims were continuously multiplied due of the file units not being updated
|
||||
- restored the FlatCAMObj.visible() to a non-threaded default
|
||||
|
||||
11.06.2019
|
||||
|
||||
- fixed the Edit -> Conversion -> Join ... functions (merge() functions)
|
||||
|
|
23
camlib.py
23
camlib.py
|
@ -112,9 +112,9 @@ class Geometry(object):
|
|||
|
||||
self.geo_steps_per_circle = geo_steps_per_circle
|
||||
|
||||
if geo_steps_per_circle is None:
|
||||
geo_steps_per_circle = int(Geometry.defaults["geo_steps_per_circle"])
|
||||
self.geo_steps_per_circle = geo_steps_per_circle
|
||||
# if geo_steps_per_circle is None:
|
||||
# geo_steps_per_circle = int(Geometry.defaults["geo_steps_per_circle"])
|
||||
# self.geo_steps_per_circle = geo_steps_per_circle
|
||||
|
||||
def make_index(self):
|
||||
self.flatten()
|
||||
|
@ -1849,6 +1849,8 @@ class ApertureMacro:
|
|||
|
||||
class Gerber (Geometry):
|
||||
"""
|
||||
Here it is done all the Gerber parsing.
|
||||
|
||||
**ATTRIBUTES**
|
||||
|
||||
* ``apertures`` (dict): The keys are names/identifiers of each aperture.
|
||||
|
@ -2452,7 +2454,6 @@ class Gerber (Geometry):
|
|||
# --- Buffered ---
|
||||
try:
|
||||
log.debug("Bare op-code %d." % current_operation_code)
|
||||
|
||||
geo_dict = dict()
|
||||
flash = self.create_flash_geometry(
|
||||
Point(current_x, current_y), self.apertures[current_aperture],
|
||||
|
@ -2467,7 +2468,7 @@ class Gerber (Geometry):
|
|||
else:
|
||||
geo_dict['solid'] = flash
|
||||
|
||||
if last_path_aperture not in self.apertures:
|
||||
if current_aperture not in self.apertures:
|
||||
self.apertures[current_aperture] = dict()
|
||||
if 'geometry' not in self.apertures[current_aperture]:
|
||||
self.apertures[current_aperture]['geometry'] = []
|
||||
|
@ -3598,6 +3599,8 @@ class Gerber (Geometry):
|
|||
|
||||
class Excellon(Geometry):
|
||||
"""
|
||||
Here it is done all the Excellon parsing.
|
||||
|
||||
*ATTRIBUTES*
|
||||
|
||||
* ``tools`` (dict): The key is the tool name and the value is
|
||||
|
@ -5350,7 +5353,7 @@ class CNCjob(Geometry):
|
|||
if self.units == 'MM':
|
||||
current_tooldia = float('%.2f' % float(exobj.tools[tool]["C"]))
|
||||
else:
|
||||
current_tooldia = float('%.3f' % float(exobj.tools[tool]["C"]))
|
||||
current_tooldia = float('%.4f' % float(exobj.tools[tool]["C"]))
|
||||
|
||||
# TODO apply offset only when using the GUI, for TclCommand this will create an error
|
||||
# because the values for Z offset are created in build_ui()
|
||||
|
@ -5448,7 +5451,7 @@ class CNCjob(Geometry):
|
|||
if self.units == 'MM':
|
||||
current_tooldia = float('%.2f' % float(exobj.tools[tool]["C"]))
|
||||
else:
|
||||
current_tooldia = float('%.3f' % float(exobj.tools[tool]["C"]))
|
||||
current_tooldia = float('%.4f' % float(exobj.tools[tool]["C"]))
|
||||
|
||||
# TODO apply offset only when using the GUI, for TclCommand this will create an error
|
||||
# because the values for Z offset are created in build_ui()
|
||||
|
@ -5504,7 +5507,7 @@ class CNCjob(Geometry):
|
|||
if self.units == 'MM':
|
||||
current_tooldia = float('%.2f' % float(exobj.tools[tool]["C"]))
|
||||
else:
|
||||
current_tooldia = float('%.3f' % float(exobj.tools[tool]["C"]))
|
||||
current_tooldia = float('%.4f' % float(exobj.tools[tool]["C"]))
|
||||
|
||||
# TODO apply offset only when using the GUI, for TclCommand this will create an error
|
||||
# because the values for Z offset are created in build_ui()
|
||||
|
@ -6139,7 +6142,7 @@ class CNCjob(Geometry):
|
|||
gcode += self.doformat(p.down_z_start_code)
|
||||
gcode += self.doformat(p.spindle_fwd_code) # Start dispensing
|
||||
gcode += self.doformat(p.dwell_fwd_code)
|
||||
gcode += self.doformat(p.z_feedrate_dispense_code)
|
||||
gcode += self.doformat(p.feedrate_z_dispense_code)
|
||||
gcode += self.doformat(p.lift_z_dispense_code)
|
||||
gcode += self.doformat(p.feedrate_xy_code)
|
||||
|
||||
|
@ -6158,7 +6161,7 @@ class CNCjob(Geometry):
|
|||
elif type(geometry) == Point:
|
||||
gcode += self.doformat(p.linear_code, x=path[0][0], y=path[0][1]) # Move to first point
|
||||
|
||||
gcode += self.doformat(p.z_feedrate_dispense_code)
|
||||
gcode += self.doformat(p.feedrate_z_dispense_code)
|
||||
gcode += self.doformat(p.down_z_start_code)
|
||||
gcode += self.doformat(p.spindle_fwd_code) # Start dispensing
|
||||
gcode += self.doformat(p.dwell_fwd_code)
|
||||
|
|
|
@ -1209,7 +1209,7 @@ class FlatCAMExcEditor(QtCore.QObject):
|
|||
for drill in self.exc_obj.drills:
|
||||
if drill['tool'] in self.exc_obj.tools:
|
||||
if self.units == 'IN':
|
||||
tool_dia = float('%.3f' % self.exc_obj.tools[drill['tool']]['C'])
|
||||
tool_dia = float('%.4f' % self.exc_obj.tools[drill['tool']]['C'])
|
||||
else:
|
||||
tool_dia = float('%.2f' % self.exc_obj.tools[drill['tool']]['C'])
|
||||
|
||||
|
@ -1238,7 +1238,7 @@ class FlatCAMExcEditor(QtCore.QObject):
|
|||
# but use the real order found in the exc_obj.tools
|
||||
for k, v in self.exc_obj.tools.items():
|
||||
if self.units == 'IN':
|
||||
tool_dia = float('%.3f' % v['C'])
|
||||
tool_dia = float('%.4f' % v['C'])
|
||||
else:
|
||||
tool_dia = float('%.2f' % v['C'])
|
||||
self.tool2tooldia[int(k)] = tool_dia
|
||||
|
@ -1324,7 +1324,7 @@ class FlatCAMExcEditor(QtCore.QObject):
|
|||
if self.units == 'MM':
|
||||
dia = QtWidgets.QTableWidgetItem('%.2f' % self.olddia_newdia[tool_no])
|
||||
else:
|
||||
dia = QtWidgets.QTableWidgetItem('%.3f' % self.olddia_newdia[tool_no])
|
||||
dia = QtWidgets.QTableWidgetItem('%.4f' % self.olddia_newdia[tool_no])
|
||||
|
||||
dia.setFlags(QtCore.Qt.ItemIsEnabled)
|
||||
|
||||
|
|
|
@ -3059,8 +3059,11 @@ class FlatCAMGeoEditor(QtCore.QObject):
|
|||
val = float(self.app.ui.grid_gap_x_entry.get_value())
|
||||
except ValueError:
|
||||
return
|
||||
|
||||
units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().upper()
|
||||
dec = 6 if units == 'IN' else 4
|
||||
if self.app.ui.grid_gap_link_cb.isChecked():
|
||||
self.app.ui.grid_gap_y_entry.set_value(val)
|
||||
self.app.ui.grid_gap_y_entry.set_value(val, decimals=dec)
|
||||
|
||||
self.app.ui.grid_gap_x_entry.setValidator(QtGui.QDoubleValidator())
|
||||
self.app.ui.grid_gap_x_entry.textChanged.connect(
|
||||
|
@ -3999,7 +4002,7 @@ class FlatCAMGeoEditor(QtCore.QObject):
|
|||
|
||||
def update_options(self, obj):
|
||||
if self.paint_tooldia:
|
||||
obj.options['cnctooldia'] = self.paint_tooldia
|
||||
obj.options['cnctooldia'] = deepcopy(str(self.paint_tooldia))
|
||||
self.paint_tooldia = None
|
||||
return True
|
||||
else:
|
||||
|
|
|
@ -3445,7 +3445,6 @@ class FlatCAMGrbEditor(QtCore.QObject):
|
|||
|
||||
file_units = self.gerber_obj.gerber_units if self.gerber_obj.gerber_units else 'IN'
|
||||
app_units = self.app.defaults['units']
|
||||
|
||||
self.conversion_factor = 25.4 if file_units == 'IN' else (1 / 25.4) if file_units != app_units else 1
|
||||
|
||||
# Hide original geometry
|
||||
|
@ -3478,6 +3477,7 @@ class FlatCAMGrbEditor(QtCore.QObject):
|
|||
conv_apertures[apid][key] = self.gerber_obj.apertures[apid][key]
|
||||
|
||||
self.gerber_obj.apertures = conv_apertures
|
||||
self.gerber_obj.gerber_units = app_units
|
||||
|
||||
# ############################################################# ##
|
||||
# APPLY CLEAR_GEOMETRY on the SOLID_GEOMETRY
|
||||
|
@ -3575,7 +3575,6 @@ class FlatCAMGrbEditor(QtCore.QObject):
|
|||
|
||||
:return: None
|
||||
"""
|
||||
|
||||
new_grb_name = self.edited_obj_name
|
||||
|
||||
# if the 'delayed plot' malfunctioned stop the QTimer
|
||||
|
@ -3710,6 +3709,7 @@ class FlatCAMGrbEditor(QtCore.QObject):
|
|||
grb_obj.source_file = []
|
||||
grb_obj.multigeo = False
|
||||
grb_obj.follow = False
|
||||
grb_obj.gerber_units = app_obj.defaults['units']
|
||||
|
||||
try:
|
||||
grb_obj.create_geometry()
|
||||
|
@ -3890,7 +3890,17 @@ class FlatCAMGrbEditor(QtCore.QObject):
|
|||
"%.4f " % (0, 0))
|
||||
|
||||
# Selection with left mouse button
|
||||
if self.active_tool is not None and event.button is 1:
|
||||
if self.active_tool is not None:
|
||||
modifiers = QtWidgets.QApplication.keyboardModifiers()
|
||||
|
||||
# If the SHIFT key is pressed when LMB is clicked then the coordinates are copied to clipboard
|
||||
if modifiers == QtCore.Qt.ShiftModifier:
|
||||
self.app.clipboard.setText(
|
||||
self.app.defaults["global_point_clipboard_format"] % (self.pos[0], self.pos[1])
|
||||
)
|
||||
self.app.inform.emit(_("[success] Coordinates copied to clipboard."))
|
||||
return
|
||||
|
||||
# Dispatch event to active_tool
|
||||
self.active_tool.click(self.app.geo_editor.snap(self.pos[0], self.pos[1]))
|
||||
|
||||
|
@ -4406,19 +4416,13 @@ class FlatCAMGrbEditor(QtCore.QObject):
|
|||
if geom_el in selection:
|
||||
geometric_data = geom_el.geo
|
||||
buffered_geom_el = dict()
|
||||
if 'solid' in geom_el:
|
||||
buffered_geom_el['solid'] = DrawToolShape(
|
||||
geometric_data['solid'].buffer(buff_value, join_style=join_style)
|
||||
)
|
||||
if 'follow' in geom_el:
|
||||
buffered_geom_el['follow'] = DrawToolShape(
|
||||
geometric_data['follow'].buffer(buff_value, join_style=join_style)
|
||||
)
|
||||
if 'clear' in geom_el:
|
||||
buffered_geom_el['clear'] = DrawToolShape(
|
||||
geometric_data['clear'].buffer(buff_value, join_style=join_style)
|
||||
)
|
||||
return buffered_geom_el
|
||||
if 'solid' in geometric_data:
|
||||
buffered_geom_el['solid'] = geometric_data['solid'].buffer(buff_value, join_style=join_style)
|
||||
if 'follow' in geometric_data:
|
||||
buffered_geom_el['follow'] = geometric_data['follow'].buffer(buff_value, join_style=join_style)
|
||||
if 'clear' in geometric_data:
|
||||
buffered_geom_el['clear'] = geometric_data['clear'].buffer(buff_value, join_style=join_style)
|
||||
return DrawToolShape(buffered_geom_el)
|
||||
else:
|
||||
return geom_el
|
||||
|
||||
|
@ -4435,9 +4439,10 @@ class FlatCAMGrbEditor(QtCore.QObject):
|
|||
temp_storage = deepcopy(buffer_recursion(self.storage_dict[apid]['geometry'], self.selected))
|
||||
self.storage_dict[apid]['geometry'] = []
|
||||
self.storage_dict[apid]['geometry'] = temp_storage
|
||||
|
||||
except Exception as e:
|
||||
log.debug("FlatCAMGrbEditor.buffer() --> %s" % str(e))
|
||||
log.debug("FlatCAMGrbEditor.buffer() --> %s\n%s" % str(e))
|
||||
self.app.inform.emit(_("[ERROR_NOTCL] Failed.\n%s") % str(traceback.print_exc()))
|
||||
return
|
||||
self.plot_all()
|
||||
self.app.inform.emit(_("[success] Done. Buffer Tool completed."))
|
||||
|
||||
|
@ -4467,17 +4472,20 @@ class FlatCAMGrbEditor(QtCore.QObject):
|
|||
if geom_el in selection:
|
||||
geometric_data = geom_el.geo
|
||||
scaled_geom_el = dict()
|
||||
if 'solid' in geom_el:
|
||||
scaled_geom_el['solid'] = DrawToolShape(
|
||||
affinity.scale(geometric_data['solid'], scale_factor, scale_factor, origin='center'))
|
||||
if 'follow' in geom_el:
|
||||
scaled_geom_el['follow'] = DrawToolShape(
|
||||
affinity.scale(geometric_data['follow'], scale_factor, scale_factor, origin='center'))
|
||||
if 'clear' in geom_el:
|
||||
scaled_geom_el['clear'] = DrawToolShape(
|
||||
affinity.scale(geometric_data['clear'], scale_factor, scale_factor, origin='center'))
|
||||
if 'solid' in geometric_data:
|
||||
scaled_geom_el['solid'] = affinity.scale(
|
||||
geometric_data['solid'], scale_factor, scale_factor, origin='center'
|
||||
)
|
||||
if 'follow' in geometric_data:
|
||||
scaled_geom_el['follow'] = affinity.scale(
|
||||
geometric_data['follow'], scale_factor, scale_factor, origin='center'
|
||||
)
|
||||
if 'clear' in geometric_data:
|
||||
scaled_geom_el['clear'] = affinity.scale(
|
||||
geometric_data['clear'], scale_factor, scale_factor, origin='center'
|
||||
)
|
||||
|
||||
return scaled_geom_el
|
||||
return DrawToolShape(scaled_geom_el)
|
||||
else:
|
||||
return geom_el
|
||||
|
||||
|
@ -5229,9 +5237,10 @@ class TransformEditorTool(FlatCAMTool):
|
|||
try:
|
||||
# first get a bounding box to fit all; we use only the 'solids' as those should provide the biggest
|
||||
# bounding box
|
||||
for el in elem_list:
|
||||
for el_shape in elem_list:
|
||||
el = el_shape.geo
|
||||
if 'solid' in el:
|
||||
xmin, ymin, xmax, ymax = el['solid'].bounds()
|
||||
xmin, ymin, xmax, ymax = el['solid'].bounds
|
||||
xminlist.append(xmin)
|
||||
yminlist.append(ymin)
|
||||
xmaxlist.append(xmax)
|
||||
|
@ -5247,13 +5256,14 @@ class TransformEditorTool(FlatCAMTool):
|
|||
px = 0.5 * (xminimal + xmaximal)
|
||||
py = 0.5 * (yminimal + ymaximal)
|
||||
|
||||
for sel_el in elem_list:
|
||||
for sel_el_shape in elem_list:
|
||||
sel_el = sel_el_shape.geo
|
||||
if 'solid' in sel_el:
|
||||
sel_el['solid'].rotate(-num, point=(px, py))
|
||||
sel_el['solid'] = affinity.rotate(sel_el['solid'], angle=-num, origin=(px, py))
|
||||
if 'follow' in sel_el:
|
||||
sel_el['follow'].rotate(-num, point=(px, py))
|
||||
sel_el['follow'] = affinity.rotate(sel_el['follow'], angle=-num, origin=(px, py))
|
||||
if 'clear' in sel_el:
|
||||
sel_el['clear'].rotate(-num, point=(px, py))
|
||||
sel_el['clear'] = affinity.rotate(sel_el['clear'], angle=-num, origin=(px, py))
|
||||
self.draw_app.plot_all()
|
||||
|
||||
self.app.inform.emit(_("[success] Done. Rotate completed."))
|
||||
|
@ -5287,9 +5297,10 @@ class TransformEditorTool(FlatCAMTool):
|
|||
else:
|
||||
# first get a bounding box to fit all; we use only the 'solids' as those should provide the biggest
|
||||
# bounding box
|
||||
for el in elem_list:
|
||||
for el_shape in elem_list:
|
||||
el = el_shape.geo
|
||||
if 'solid' in el:
|
||||
xmin, ymin, xmax, ymax = el['solid'].bounds()
|
||||
xmin, ymin, xmax, ymax = el['solid'].bounds
|
||||
xminlist.append(xmin)
|
||||
yminlist.append(ymin)
|
||||
xmaxlist.append(xmax)
|
||||
|
@ -5307,22 +5318,23 @@ class TransformEditorTool(FlatCAMTool):
|
|||
self.app.progress.emit(20)
|
||||
|
||||
# execute mirroring
|
||||
for sel_el in elem_list:
|
||||
for sel_el_shape in elem_list:
|
||||
sel_el = sel_el_shape.geo
|
||||
if axis is 'X':
|
||||
if 'solid' in sel_el:
|
||||
sel_el['solid'].mirror('X', (px, py))
|
||||
sel_el['solid'] = affinity.scale(sel_el['solid'], xfact=1, yfact=-1, origin=(px, py))
|
||||
if 'follow' in sel_el:
|
||||
sel_el['follow'].mirror('X', (px, py))
|
||||
sel_el['follow'] = affinity.scale(sel_el['follow'], xfact=1, yfact=-1, origin=(px, py))
|
||||
if 'clear' in sel_el:
|
||||
sel_el['clear'].mirror('X', (px, py))
|
||||
sel_el['clear'] = affinity.scale(sel_el['clear'], xfact=1, yfact=-1, origin=(px, py))
|
||||
self.app.inform.emit(_('[success] Flip on the Y axis done ...'))
|
||||
elif axis is 'Y':
|
||||
if 'solid' in sel_el:
|
||||
sel_el['solid'].mirror('Y', (px, py))
|
||||
sel_el['solid'] = affinity.scale(sel_el['solid'], xfact=-1, yfact=1, origin=(px, py))
|
||||
if 'follow' in sel_el:
|
||||
sel_el['follow'].mirror('Y', (px, py))
|
||||
sel_el['follow'] = affinity.scale(sel_el['follow'], xfact=-1, yfact=1, origin=(px, py))
|
||||
if 'clear' in sel_el:
|
||||
sel_el['clear'].mirror('Y', (px, py))
|
||||
sel_el['clear'] = affinity.scale(sel_el['clear'], xfact=-1, yfact=1, origin=(px, py))
|
||||
self.app.inform.emit(_('[success] Flip on the X axis done ...'))
|
||||
self.draw_app.plot_all()
|
||||
self.app.progress.emit(100)
|
||||
|
@ -5350,9 +5362,10 @@ class TransformEditorTool(FlatCAMTool):
|
|||
try:
|
||||
# first get a bounding box to fit all; we use only the 'solids' as those should provide the biggest
|
||||
# bounding box
|
||||
for el in elem_list:
|
||||
for el_shape in elem_list:
|
||||
el = el_shape.geo
|
||||
if 'solid' in el:
|
||||
xmin, ymin, xmax, ymax = el['solid'].bounds()
|
||||
xmin, ymin, xmax, ymax = el['solid'].bounds
|
||||
xminlist.append(xmin)
|
||||
yminlist.append(ymin)
|
||||
|
||||
|
@ -5362,21 +5375,22 @@ class TransformEditorTool(FlatCAMTool):
|
|||
|
||||
self.app.progress.emit(20)
|
||||
|
||||
for sel_el in elem_list:
|
||||
for sel_el_shape in elem_list:
|
||||
sel_el = sel_el_shape.geo
|
||||
if axis is 'X':
|
||||
if 'solid' in sel_el:
|
||||
sel_el['solid'].skew(num, 0, point=(xminimal, yminimal))
|
||||
sel_el['solid'] = affinity.skew(sel_el['solid'], num, 0, origin=(xminimal, yminimal))
|
||||
if 'follow' in sel_el:
|
||||
sel_el['follow'].skew(num, 0, point=(xminimal, yminimal))
|
||||
sel_el['follow'] = affinity.skew(sel_el['follow'], num, 0, origin=(xminimal, yminimal))
|
||||
if 'clear' in sel_el:
|
||||
sel_el['clear'].skew(num, 0, point=(xminimal, yminimal))
|
||||
sel_el['clear'] = affinity.skew(sel_el['clear'], num, 0, origin=(xminimal, yminimal))
|
||||
elif axis is 'Y':
|
||||
if 'solid' in sel_el:
|
||||
sel_el['solid'].skew(0, num, point=(xminimal, yminimal))
|
||||
sel_el['solid'] = affinity.skew(sel_el['solid'], 0, num, origin=(xminimal, yminimal))
|
||||
if 'follow' in sel_el:
|
||||
sel_el['follow'].skew(0, num, point=(xminimal, yminimal))
|
||||
sel_el['follow'] = affinity.skew(sel_el['follow'], 0, num, origin=(xminimal, yminimal))
|
||||
if 'clear' in sel_el:
|
||||
sel_el['clear'].skew(0, num, point=(xminimal, yminimal))
|
||||
sel_el['clear'] = affinity.skew(sel_el['clear'], 0, num, origin=(xminimal, yminimal))
|
||||
self.draw_app.plot_all()
|
||||
|
||||
self.app.inform.emit(_('[success] Skew on the %s axis done ...') % str(axis))
|
||||
|
@ -5409,9 +5423,10 @@ class TransformEditorTool(FlatCAMTool):
|
|||
try:
|
||||
# first get a bounding box to fit all; we use only the 'solids' as those should provide the biggest
|
||||
# bounding box
|
||||
for el in elem_list:
|
||||
for el_shape in elem_list:
|
||||
el = el_shape.geo
|
||||
if 'solid' in el:
|
||||
xmin, ymin, xmax, ymax = el['solid'].bounds()
|
||||
xmin, ymin, xmax, ymax = el['solid'].bounds
|
||||
xminlist.append(xmin)
|
||||
yminlist.append(ymin)
|
||||
xmaxlist.append(xmax)
|
||||
|
@ -5432,13 +5447,14 @@ class TransformEditorTool(FlatCAMTool):
|
|||
px = 0
|
||||
py = 0
|
||||
|
||||
for sel_el in elem_list:
|
||||
for sel_el_shape in elem_list:
|
||||
sel_el = sel_el_shape.geo
|
||||
if 'solid' in sel_el:
|
||||
sel_el['solid'].scale(xfactor, yfactor, point=(px, py))
|
||||
sel_el['solid'] = affinity.scale(sel_el['solid'], xfactor, yfactor, origin=(px, py))
|
||||
if 'follow' in sel_el:
|
||||
sel_el['follow'].scale(xfactor, yfactor, point=(px, py))
|
||||
sel_el['follow'] = affinity.scale(sel_el['follow'], xfactor, yfactor, origin=(px, py))
|
||||
if 'clear' in sel_el:
|
||||
sel_el['clear'].scale(xfactor, yfactor, point=(px, py))
|
||||
sel_el['clear'] = affinity.scale(sel_el['clear'], xfactor, yfactor, origin=(px, py))
|
||||
self.draw_app.plot_all()
|
||||
|
||||
self.app.inform.emit(_('[success] Scale on the %s axis done ...') % str(axis))
|
||||
|
@ -5464,21 +5480,22 @@ class TransformEditorTool(FlatCAMTool):
|
|||
try:
|
||||
self.app.progress.emit(20)
|
||||
|
||||
for sel_el in elem_list:
|
||||
for sel_el_shape in elem_list:
|
||||
sel_el = sel_el_shape.geo
|
||||
if axis is 'X':
|
||||
if 'solid' in sel_el:
|
||||
sel_el['solid'].offset((num, 0))
|
||||
sel_el['solid'] = affinity.translate(sel_el['solid'], num, 0)
|
||||
if 'follow' in sel_el:
|
||||
sel_el['follow'].offset((num, 0))
|
||||
sel_el['follow'] = affinity.translate(sel_el['follow'], num, 0)
|
||||
if 'clear' in sel_el:
|
||||
sel_el['clear'].offset((num, 0))
|
||||
sel_el['clear'] = affinity.translate(sel_el['clear'], num, 0)
|
||||
elif axis is 'Y':
|
||||
if 'solid' in sel_el:
|
||||
sel_el['solid'].offset((0, num))
|
||||
sel_el['solid'] = affinity.translate(sel_el['solid'], 0, num)
|
||||
if 'follow' in sel_el:
|
||||
sel_el['follow'].offset((0, num))
|
||||
sel_el['follow'] = affinity.translate(sel_el['follow'], 0, num)
|
||||
if 'clear' in sel_el:
|
||||
sel_el['clear'].offset((0, num))
|
||||
sel_el['clear'] = affinity.translate(sel_el['clear'], 0, num)
|
||||
self.draw_app.plot_all()
|
||||
|
||||
self.app.inform.emit(_('[success] Offset on the %s axis done ...') % str(axis))
|
||||
|
|
|
@ -3330,14 +3330,14 @@ class GeneralGUIPrefGroupUI(OptionsGroupUI):
|
|||
self.gridx_label.setToolTip(
|
||||
_("This is the Grid snap value on X axis.")
|
||||
)
|
||||
self.gridx_entry = LengthEntry()
|
||||
self.gridx_entry = FCEntry3()
|
||||
|
||||
# Grid Y Entry
|
||||
self.gridy_label = QtWidgets.QLabel(_('Grid Y value:'))
|
||||
self.gridy_label.setToolTip(
|
||||
_("This is the Grid snap value on Y axis.")
|
||||
)
|
||||
self.gridy_entry = LengthEntry()
|
||||
self.gridy_entry = FCEntry3()
|
||||
|
||||
# Snap Max Entry
|
||||
self.snap_max_label = QtWidgets.QLabel(_('Snap Max:'))
|
||||
|
@ -4096,7 +4096,7 @@ class GerberOptPrefGroupUI(OptionsGroupUI):
|
|||
self.combine_passes_cb.setToolTip(
|
||||
_("Combine all passes into one object")
|
||||
)
|
||||
grid0.addWidget(self.combine_passes_cb, 4, 0)
|
||||
grid0.addWidget(self.combine_passes_cb, 4, 0, 1, 2)
|
||||
|
||||
# ## Clear non-copper regions
|
||||
self.clearcopper_label = QtWidgets.QLabel(_("<b>Clear non-copper:</b>"))
|
||||
|
@ -4468,8 +4468,8 @@ class ExcellonGenPrefGroupUI(OptionsGroupUI):
|
|||
hlay2.addWidget(self.excellon_format_lower_mm_entry, QtCore.Qt.AlignLeft)
|
||||
hlay2.addStretch()
|
||||
|
||||
hlay3 = QtWidgets.QHBoxLayout()
|
||||
self.layout.addLayout(hlay3)
|
||||
grid2 = QtWidgets.QGridLayout()
|
||||
self.layout.addLayout(grid2)
|
||||
|
||||
self.excellon_zeros_label = QtWidgets.QLabel(_('Default <b>Zeros</b>:'))
|
||||
self.excellon_zeros_label.setAlignment(QtCore.Qt.AlignLeft)
|
||||
|
@ -4480,7 +4480,7 @@ class ExcellonGenPrefGroupUI(OptionsGroupUI):
|
|||
"If TZ is checked then Trailing Zeros are kept\n"
|
||||
"and Leading Zeros are removed.")
|
||||
)
|
||||
hlay3.addWidget(self.excellon_zeros_label)
|
||||
grid2.addWidget(self.excellon_zeros_label, 0, 0)
|
||||
|
||||
self.excellon_zeros_radio = RadioSet([{'label': 'LZ', 'value': 'L'},
|
||||
{'label': 'TZ', 'value': 'T'}])
|
||||
|
@ -4493,11 +4493,7 @@ class ExcellonGenPrefGroupUI(OptionsGroupUI):
|
|||
"If TZ is checked then Trailing Zeros are kept\n"
|
||||
"and Leading Zeros are removed.")
|
||||
)
|
||||
hlay3.addStretch()
|
||||
hlay3.addWidget(self.excellon_zeros_radio, QtCore.Qt.AlignRight)
|
||||
|
||||
hlay4 = QtWidgets.QHBoxLayout()
|
||||
self.layout.addLayout(hlay4)
|
||||
grid2.addWidget(self.excellon_zeros_radio, 0, 1)
|
||||
|
||||
self.excellon_units_label = QtWidgets.QLabel(_('Default <b>Units</b>:'))
|
||||
self.excellon_units_label.setAlignment(QtCore.Qt.AlignLeft)
|
||||
|
@ -4508,7 +4504,7 @@ class ExcellonGenPrefGroupUI(OptionsGroupUI):
|
|||
"Some Excellon files don't have an header\n"
|
||||
"therefore this parameter will be used.")
|
||||
)
|
||||
hlay4.addWidget(self.excellon_units_label)
|
||||
grid2.addWidget(self.excellon_units_label, 1, 0)
|
||||
|
||||
self.excellon_units_radio = RadioSet([{'label': 'INCH', 'value': 'INCH'},
|
||||
{'label': 'MM', 'value': 'METRIC'}])
|
||||
|
@ -4517,27 +4513,14 @@ class ExcellonGenPrefGroupUI(OptionsGroupUI):
|
|||
"Some Excellon files don't have an header\n"
|
||||
"therefore this parameter will be used.")
|
||||
)
|
||||
hlay4.addStretch()
|
||||
hlay4.addWidget(self.excellon_units_radio, QtCore.Qt.AlignRight)
|
||||
grid2.addWidget(self.excellon_units_radio, 1, 1)
|
||||
|
||||
hlay5 = QtWidgets.QVBoxLayout()
|
||||
self.layout.addLayout(hlay5)
|
||||
|
||||
self.empty_label = QtWidgets.QLabel("")
|
||||
hlay5.addWidget(self.empty_label)
|
||||
|
||||
hlay6 = QtWidgets.QVBoxLayout()
|
||||
self.layout.addLayout(hlay6)
|
||||
grid2.addWidget(QtWidgets.QLabel(""), 2, 0)
|
||||
|
||||
self.excellon_general_label = QtWidgets.QLabel(_("<b>Excellon Optimization:</b>"))
|
||||
hlay6.addWidget(self.excellon_general_label)
|
||||
|
||||
# Create a form layout for the Excellon general settings
|
||||
form_box_excellon = QtWidgets.QFormLayout()
|
||||
hlay6.addLayout(form_box_excellon)
|
||||
grid2.addWidget(self.excellon_general_label, 3, 0, 1, 2)
|
||||
|
||||
self.excellon_optimization_label = QtWidgets.QLabel(_('Algorithm: '))
|
||||
self.excellon_optimization_label.setAlignment(QtCore.Qt.AlignLeft)
|
||||
self.excellon_optimization_label.setToolTip(
|
||||
_("This sets the optimization type for the Excellon drill path.\n"
|
||||
"If MH is checked then Google OR-Tools algorithm with MetaHeuristic\n"
|
||||
|
@ -4548,6 +4531,7 @@ class ExcellonGenPrefGroupUI(OptionsGroupUI):
|
|||
"If DISABLED, then FlatCAM works in 32bit mode and it uses \n"
|
||||
"Travelling Salesman algorithm for path optimization.")
|
||||
)
|
||||
grid2.addWidget(self.excellon_optimization_label, 4, 0)
|
||||
|
||||
self.excellon_optimization_radio = RadioSet([{'label': 'MH', 'value': 'M'},
|
||||
{'label': 'Basic', 'value': 'B'}])
|
||||
|
@ -4561,8 +4545,7 @@ class ExcellonGenPrefGroupUI(OptionsGroupUI):
|
|||
"If DISABLED, then FlatCAM works in 32bit mode and it uses \n"
|
||||
"Travelling Salesman algorithm for path optimization.")
|
||||
)
|
||||
|
||||
form_box_excellon.addRow(self.excellon_optimization_label, self.excellon_optimization_radio)
|
||||
grid2.addWidget(self.excellon_optimization_radio, 4, 1)
|
||||
|
||||
self.optimization_time_label = QtWidgets.QLabel(_('Optimization Time: '))
|
||||
self.optimization_time_label.setAlignment(QtCore.Qt.AlignLeft)
|
||||
|
@ -4573,10 +4556,11 @@ class ExcellonGenPrefGroupUI(OptionsGroupUI):
|
|||
"In seconds.")
|
||||
|
||||
)
|
||||
grid2.addWidget(self.optimization_time_label, 5, 0)
|
||||
|
||||
self.optimization_time_entry = IntEntry()
|
||||
self.optimization_time_entry.setValidator(QtGui.QIntValidator(0, 999))
|
||||
form_box_excellon.addRow(self.optimization_time_label, self.optimization_time_entry)
|
||||
grid2.addWidget(self.optimization_time_entry, 5, 1)
|
||||
|
||||
current_platform = platform.architecture()[0]
|
||||
if current_platform == '64bit':
|
||||
|
@ -4744,25 +4728,23 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI):
|
|||
self.mill_hole_label.setToolTip(
|
||||
_("Create Geometry for milling holes.")
|
||||
)
|
||||
self.layout.addWidget(self.mill_hole_label)
|
||||
grid2.addWidget(excellon_gcode_type_label, 11, 0, 1, 2)
|
||||
|
||||
grid3 = QtWidgets.QGridLayout()
|
||||
self.layout.addLayout(grid3)
|
||||
tdlabel = QtWidgets.QLabel(_('Drill Tool dia:'))
|
||||
tdlabel.setToolTip(
|
||||
_("Diameter of the cutting tool.")
|
||||
)
|
||||
grid3.addWidget(tdlabel, 0, 0)
|
||||
grid2.addWidget(tdlabel, 12, 0)
|
||||
self.tooldia_entry = LengthEntry()
|
||||
grid3.addWidget(self.tooldia_entry, 0, 1)
|
||||
grid2.addWidget(self.tooldia_entry, 12, 1)
|
||||
stdlabel = QtWidgets.QLabel(_('Slot Tool dia:'))
|
||||
stdlabel.setToolTip(
|
||||
_("Diameter of the cutting tool\n"
|
||||
"when milling slots.")
|
||||
)
|
||||
grid3.addWidget(stdlabel, 1, 0)
|
||||
grid2.addWidget(stdlabel, 13, 0)
|
||||
self.slot_tooldia_entry = LengthEntry()
|
||||
grid3.addWidget(self.slot_tooldia_entry, 1, 1)
|
||||
grid2.addWidget(self.slot_tooldia_entry, 13, 1)
|
||||
|
||||
grid4 = QtWidgets.QGridLayout()
|
||||
self.layout.addLayout(grid4)
|
||||
|
@ -5162,6 +5144,7 @@ class GeometryGenPrefGroupUI(OptionsGroupUI):
|
|||
|
||||
grid0 = QtWidgets.QGridLayout()
|
||||
self.layout.addLayout(grid0)
|
||||
|
||||
# Number of circle steps for circular aperture linear approximation
|
||||
self.circle_steps_label = QtWidgets.QLabel(_("Circle Steps:"))
|
||||
self.circle_steps_label.setToolTip(
|
||||
|
@ -5173,21 +5156,17 @@ class GeometryGenPrefGroupUI(OptionsGroupUI):
|
|||
grid0.addWidget(self.circle_steps_entry, 1, 1)
|
||||
|
||||
# Tools
|
||||
self.tools_label = QtWidgets.QLabel(_("<b>Tools</b>"))
|
||||
self.layout.addWidget(self.tools_label)
|
||||
|
||||
grid0_b = QtWidgets.QGridLayout()
|
||||
self.layout.addLayout(grid0_b)
|
||||
self.tools_label = QtWidgets.QLabel(_("<b>Tools:</b>"))
|
||||
grid0.addWidget(self.tools_label, 2, 0, 1, 2)
|
||||
|
||||
# Tooldia
|
||||
tdlabel = QtWidgets.QLabel(_('Tool dia: '))
|
||||
tdlabel = QtWidgets.QLabel(_('Tool dia:'))
|
||||
tdlabel.setToolTip(
|
||||
_("The diameter of the cutting\n"
|
||||
"tool..")
|
||||
_("Diameters of the cutting tools, separated by ','")
|
||||
)
|
||||
grid0_b.addWidget(tdlabel, 0, 0)
|
||||
self.cnctooldia_entry = LengthEntry()
|
||||
grid0_b.addWidget(self.cnctooldia_entry, 0, 1)
|
||||
grid0.addWidget(tdlabel, 3, 0)
|
||||
self.cnctooldia_entry = FCEntry()
|
||||
grid0.addWidget(self.cnctooldia_entry, 3, 1)
|
||||
|
||||
self.layout.addStretch()
|
||||
|
||||
|
|
|
@ -190,7 +190,7 @@ class LengthEntry(QtWidgets.QLineEdit):
|
|||
units = raw[-2:]
|
||||
units = self.scales[self.output_units][units.upper()]
|
||||
value = raw[:-2]
|
||||
return float(eval(value))*units
|
||||
return float(eval(value))* units
|
||||
except IndexError:
|
||||
value = raw
|
||||
return float(eval(value))
|
||||
|
@ -390,12 +390,40 @@ class FCEntry2(FCEntry):
|
|||
def on_edit_finished(self):
|
||||
self.clearFocus()
|
||||
|
||||
def set_value(self, val):
|
||||
def set_value(self, val, decimals=4):
|
||||
try:
|
||||
fval = float(val)
|
||||
except ValueError:
|
||||
return
|
||||
self.setText('%.4f' % fval)
|
||||
|
||||
self.setText('%.*f' % (decimals, fval))
|
||||
|
||||
|
||||
class FCEntry3(FCEntry):
|
||||
def __init__(self, parent=None):
|
||||
super(FCEntry3, self).__init__(parent)
|
||||
self.readyToEdit = True
|
||||
self.editingFinished.connect(self.on_edit_finished)
|
||||
|
||||
def on_edit_finished(self):
|
||||
self.clearFocus()
|
||||
|
||||
def set_value(self, val, decimals=4):
|
||||
try:
|
||||
fval = float(val)
|
||||
except ValueError:
|
||||
return
|
||||
|
||||
self.setText('%.*f' % (decimals, fval))
|
||||
|
||||
def get_value(self):
|
||||
value = str(self.text()).strip(' ')
|
||||
|
||||
try:
|
||||
return float(eval(value))
|
||||
except Exception as e:
|
||||
log.warning("Could not parse value in entry: %s" % str(e))
|
||||
return None
|
||||
|
||||
|
||||
class EvalEntry(QtWidgets.QLineEdit):
|
||||
|
@ -680,7 +708,7 @@ class FCTextAreaExtended(QtWidgets.QTextEdit):
|
|||
if character == "#":
|
||||
# delete #
|
||||
self.textCursor().deletePreviousChar()
|
||||
# delete white space
|
||||
# delete white space
|
||||
self.moveCursor(QtGui.QTextCursor.NextWord,QtGui.QTextCursor.KeepAnchor)
|
||||
self.textCursor().removeSelectedText()
|
||||
else:
|
||||
|
@ -1059,7 +1087,6 @@ class FCDetachableTab(QtWidgets.QTabWidget):
|
|||
# Re-attach the tab at the given index
|
||||
self.attachTab(contentWidget, name, icon, index)
|
||||
|
||||
|
||||
# If the drop did not occur on an existing tab, determine if the drop
|
||||
# occurred in the tab bar area (the area to the side of the QTabBar)
|
||||
else:
|
||||
|
@ -1227,14 +1254,17 @@ class FCDetachableTab(QtWidgets.QTabWidget):
|
|||
:return:
|
||||
"""
|
||||
# Determine if the current movement is detected as a drag
|
||||
if not self.dragStartPos.isNull() and ((event.pos() - self.dragStartPos).manhattanLength() < QtWidgets.QApplication.startDragDistance()):
|
||||
if not self.dragStartPos.isNull() and \
|
||||
((event.pos() - self.dragStartPos).manhattanLength() < QtWidgets.QApplication.startDragDistance()):
|
||||
self.dragInitiated = True
|
||||
|
||||
# If the current movement is a drag initiated by the left button
|
||||
if (((event.buttons() & QtCore.Qt.LeftButton)) and self.dragInitiated):
|
||||
|
||||
# Stop the move event
|
||||
finishMoveEvent = QtGui.QMouseEvent(QtCore.QEvent.MouseMove, event.pos(), QtCore.Qt.NoButton, QtCore.Qt.NoButton, QtCore.Qt.NoModifier)
|
||||
finishMoveEvent = QtGui.QMouseEvent(
|
||||
QtCore.QEvent.MouseMove, event.pos(), QtCore.Qt.NoButton, QtCore.Qt.NoButton, QtCore.Qt.NoModifier
|
||||
)
|
||||
QtWidgets.QTabBar.mouseMoveEvent(self, finishMoveEvent)
|
||||
|
||||
# Convert the move event into a drag
|
||||
|
@ -1261,13 +1291,11 @@ class FCDetachableTab(QtWidgets.QTabWidget):
|
|||
# Initiate the drag
|
||||
dropAction = drag.exec_(QtCore.Qt.MoveAction | QtCore.Qt.CopyAction)
|
||||
|
||||
|
||||
# For Linux: Here, drag.exec_() will not return MoveAction on Linux. So it
|
||||
# must be set manually
|
||||
if self.dragDropedPos.x() != 0 and self.dragDropedPos.y() != 0:
|
||||
dropAction = QtCore.Qt.MoveAction
|
||||
|
||||
|
||||
# If the drag completed outside of the tab bar, detach the tab and move
|
||||
# the content to the current cursor position
|
||||
if dropAction == QtCore.Qt.IgnoreAction:
|
||||
|
|
|
@ -91,7 +91,7 @@ def dxfarc2shapely(arc, n_points=100):
|
|||
# angle += step_angle
|
||||
#
|
||||
#
|
||||
# log.debug("X = %.3f, Y = %.3f, Radius = %.3f, start_angle = %.1f, stop_angle = %.1f, step_angle = %.3f, dir=%s" %
|
||||
# log.debug("X = %.4f, Y = %.4f, Radius = %.4f, start_angle = %.1f, stop_angle = %.1f, step_angle = %.4f, dir=%s" %
|
||||
# (center_x, center_y, radius, start_angle, end_angle, step_angle, dir))
|
||||
#
|
||||
# geo = LineString(point_list)
|
||||
|
@ -142,7 +142,7 @@ def dxfarc2shapely(arc, n_points=100):
|
|||
y = center_y + radius * math.sin(math.radians(- end_angle))
|
||||
point_list.append((x, y))
|
||||
|
||||
# log.debug("X = %.3f, Y = %.3f, Radius = %.3f, start_angle = %.1f, stop_angle = %.1f, step_angle = %.3f" %
|
||||
# log.debug("X = %.4f, Y = %.4f, Radius = %.4f, start_angle = %.1f, stop_angle = %.1f, step_angle = %.4f" %
|
||||
# (center_x, center_y, radius, start_angle, end_angle, step_angle))
|
||||
|
||||
geo = LineString(point_list)
|
||||
|
@ -450,4 +450,4 @@ def getdxftext(exf_object, object_type, units=None):
|
|||
# geo = rotate(geo, phi, origin=tr)
|
||||
#
|
||||
# geo_block_transformed.append(geo)
|
||||
# return geo_block_transformed
|
||||
# return geo_block_transformed
|
||||
|
|
|
@ -343,7 +343,7 @@ class NonCopperClear(FlatCAMTool, Gerber):
|
|||
})
|
||||
|
||||
try:
|
||||
dias = [float(eval(dia)) for dia in self.app.defaults["tools_ncctools"].split(",")]
|
||||
dias = [float(eval(dia)) for dia in self.app.defaults["tools_ncctools"].split(",") if dia != '']
|
||||
except:
|
||||
log.error("At least one tool diameter needed. Verify in Edit -> Preferences -> TOOLS -> NCC Tools.")
|
||||
return
|
||||
|
@ -404,7 +404,7 @@ class NonCopperClear(FlatCAMTool, Gerber):
|
|||
if self.units == 'MM':
|
||||
dia = QtWidgets.QTableWidgetItem('%.2f' % tooluid_value['tooldia'])
|
||||
else:
|
||||
dia = QtWidgets.QTableWidgetItem('%.3f' % tooluid_value['tooldia'])
|
||||
dia = QtWidgets.QTableWidgetItem('%.4f' % tooluid_value['tooldia'])
|
||||
|
||||
dia.setFlags(QtCore.Qt.ItemIsEnabled)
|
||||
|
||||
|
@ -787,7 +787,7 @@ class NonCopperClear(FlatCAMTool, Gerber):
|
|||
else:
|
||||
log.debug("There are no geometries in the cleared polygon.")
|
||||
|
||||
geo_obj.options["cnctooldia"] = tool
|
||||
geo_obj.options["cnctooldia"] = str(tool)
|
||||
geo_obj.multigeo = True
|
||||
|
||||
def job_thread(app_obj):
|
||||
|
@ -929,7 +929,7 @@ class NonCopperClear(FlatCAMTool, Gerber):
|
|||
log.debug("There are no geometries in the cleared polygon.")
|
||||
|
||||
geo_obj.multigeo = True
|
||||
geo_obj.options["cnctooldia"] = tool
|
||||
geo_obj.options["cnctooldia"] = str(tool)
|
||||
|
||||
# check to see if geo_obj.tools is empty
|
||||
# it will be updated only if there is a solid_geometry for tools
|
||||
|
|
|
@ -468,7 +468,7 @@ class ToolPaint(FlatCAMTool, Gerber):
|
|||
if self.units == 'MM':
|
||||
dia = QtWidgets.QTableWidgetItem('%.2f' % tooluid_value['tooldia'])
|
||||
else:
|
||||
dia = QtWidgets.QTableWidgetItem('%.3f' % tooluid_value['tooldia'])
|
||||
dia = QtWidgets.QTableWidgetItem('%.4f' % tooluid_value['tooldia'])
|
||||
|
||||
dia.setFlags(QtCore.Qt.ItemIsEnabled)
|
||||
|
||||
|
@ -920,7 +920,7 @@ class ToolPaint(FlatCAMTool, Gerber):
|
|||
log.debug("Could not Paint the polygons. %s" % str(e))
|
||||
self.app.inform.emit(
|
||||
_("[ERROR] Could not do Paint. Try a different combination of parameters. "
|
||||
"Or a different strategy of paint\n%s") % str(e))
|
||||
"Or a different strategy of paint\n%s") % str(e))
|
||||
return
|
||||
|
||||
if cp is not None:
|
||||
|
@ -930,7 +930,7 @@ class ToolPaint(FlatCAMTool, Gerber):
|
|||
else:
|
||||
geo_obj.solid_geometry = list(cp.get_objects())
|
||||
|
||||
geo_obj.options["cnctooldia"] = tooldia
|
||||
geo_obj.options["cnctooldia"] = str(tooldia)
|
||||
# this turn on the FlatCAMCNCJob plot for multiple tools
|
||||
geo_obj.multigeo = False
|
||||
geo_obj.multitool = True
|
||||
|
@ -1043,7 +1043,11 @@ class ToolPaint(FlatCAMTool, Gerber):
|
|||
|
||||
# ## Not iterable, do the actual indexing and add.
|
||||
except TypeError:
|
||||
self.flat_geometry.append(geometry)
|
||||
if isinstance(geometry, LinearRing):
|
||||
g = Polygon(geometry)
|
||||
self.flat_geometry.append(g)
|
||||
else:
|
||||
self.flat_geometry.append(geometry)
|
||||
|
||||
return self.flat_geometry
|
||||
|
||||
|
@ -1127,7 +1131,7 @@ class ToolPaint(FlatCAMTool, Gerber):
|
|||
self.paint_tools[current_uid]['data']['name'] = name
|
||||
total_geometry[:] = []
|
||||
|
||||
geo_obj.options["cnctooldia"] = tool_dia
|
||||
geo_obj.options["cnctooldia"] = str(tool_dia)
|
||||
# this turn on the FlatCAMCNCJob plot for multiple tools
|
||||
geo_obj.multigeo = True
|
||||
geo_obj.multitool = True
|
||||
|
@ -1141,8 +1145,8 @@ class ToolPaint(FlatCAMTool, Gerber):
|
|||
has_solid_geo += 1
|
||||
if has_solid_geo == 0:
|
||||
self.app.inform.emit(_("[ERROR] There is no Painting Geometry in the file.\n"
|
||||
"Usually it means that the tool diameter is too big for the painted geometry.\n"
|
||||
"Change the painting parameters and try again."))
|
||||
"Usually it means that the tool diameter is too big for the painted geometry.\n"
|
||||
"Change the painting parameters and try again."))
|
||||
return
|
||||
|
||||
# Experimental...
|
||||
|
@ -1222,7 +1226,7 @@ class ToolPaint(FlatCAMTool, Gerber):
|
|||
self.paint_tools[current_uid]['data']['name'] = name
|
||||
cleared_geo[:] = []
|
||||
|
||||
geo_obj.options["cnctooldia"] = tool_dia
|
||||
geo_obj.options["cnctooldia"] = str(tool_dia)
|
||||
# this turn on the FlatCAMCNCJob plot for multiple tools
|
||||
geo_obj.multigeo = True
|
||||
geo_obj.multitool = True
|
||||
|
|
|
@ -482,7 +482,7 @@ class SolderPaste(FlatCAMTool):
|
|||
self.on_tool_delete(rows_to_delete=None, all=None), icon=QtGui.QIcon("share/delete32.png"))
|
||||
|
||||
try:
|
||||
dias = [float(eval(dia)) for dia in self.app.defaults["tools_solderpaste_tools"].split(",")]
|
||||
dias = [float(eval(dia)) for dia in self.app.defaults["tools_solderpaste_tools"].split(",") if dia != '']
|
||||
except:
|
||||
log.error("At least one Nozzle tool diameter needed. "
|
||||
"Verify in Edit -> Preferences -> TOOLS -> Solder Paste Tools.")
|
||||
|
@ -548,7 +548,7 @@ class SolderPaste(FlatCAMTool):
|
|||
if self.units == 'MM':
|
||||
dia = QtWidgets.QTableWidgetItem('%.2f' % tooluid_value['tooldia'])
|
||||
else:
|
||||
dia = QtWidgets.QTableWidgetItem('%.3f' % tooluid_value['tooldia'])
|
||||
dia = QtWidgets.QTableWidgetItem('%.4f' % tooluid_value['tooldia'])
|
||||
|
||||
dia.setFlags(QtCore.Qt.ItemIsEnabled)
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue