Merge remote-tracking branch 'remotes/jpcgt/flatcam/Beta' into Beta
This commit is contained in:
commit
762e460614
|
@ -140,8 +140,8 @@ class App(QtCore.QObject):
|
|||
# ##########################################################################
|
||||
# ################## Version and VERSION DATE ##############################
|
||||
# ##########################################################################
|
||||
version = 8.99
|
||||
version_date = "2019/12/15"
|
||||
version = 8.991
|
||||
version_date = "2019/12/30"
|
||||
beta = True
|
||||
engine = '3D'
|
||||
|
||||
|
@ -237,6 +237,9 @@ class App(QtCore.QObject):
|
|||
# should be disconnected after use so it can be reused
|
||||
replot_signal = pyqtSignal(list)
|
||||
|
||||
# signal emitted when jumping
|
||||
jump_signal = pyqtSignal(tuple)
|
||||
|
||||
def __init__(self, user_defaults=True):
|
||||
"""
|
||||
Starts the application.
|
||||
|
@ -3810,7 +3813,7 @@ class App(QtCore.QObject):
|
|||
|
||||
if 'version' not in defaults or defaults['version'] != self.defaults['version']:
|
||||
for k, v in defaults.items():
|
||||
if k in self.defaults:
|
||||
if k in self.defaults and k != 'version':
|
||||
self.defaults[k] = v
|
||||
|
||||
# delete old factory defaults
|
||||
|
@ -7355,10 +7358,6 @@ class App(QtCore.QObject):
|
|||
"""
|
||||
self.report_usage("on_jump_to()")
|
||||
|
||||
# if self.is_legacy is True:
|
||||
# self.inform.emit(_("Not available with the current Graphic Engine Legacy(2D)."))
|
||||
# return
|
||||
|
||||
if not custom_location:
|
||||
dia_box_location = None
|
||||
|
||||
|
@ -7372,17 +7371,29 @@ class App(QtCore.QObject):
|
|||
else:
|
||||
dia_box_location = None
|
||||
|
||||
dia_box = Dialog_box(title=_("Jump to ..."),
|
||||
label=_("Enter the coordinates in format X,Y:"),
|
||||
icon=QtGui.QIcon(self.resource_location + '/jump_to16.png'),
|
||||
initial_text=dia_box_location)
|
||||
# dia_box = Dialog_box(title=_("Jump to ..."),
|
||||
# label=_("Enter the coordinates in format X,Y:"),
|
||||
# icon=QtGui.QIcon(self.resource_location + '/jump_to16.png'),
|
||||
# initial_text=dia_box_location)
|
||||
|
||||
dia_box = DialogBoxRadio(title=_("Jump to ..."),
|
||||
label=_("Enter the coordinates in format X,Y:"),
|
||||
icon=QtGui.QIcon(self.resource_location + '/jump_to16.png'),
|
||||
initial_text=dia_box_location)
|
||||
|
||||
if dia_box.ok is True:
|
||||
try:
|
||||
location = eval(dia_box.location)
|
||||
|
||||
if not isinstance(location, tuple):
|
||||
self.inform.emit(_("Wrong coordinates. Enter coordinates in format: X,Y"))
|
||||
return
|
||||
|
||||
if dia_box.reference == 'rel':
|
||||
rel_x = self.mouse[0] + location[0]
|
||||
rel_y = self.mouse[1] + location[1]
|
||||
location = (rel_x, rel_y)
|
||||
|
||||
except Exception:
|
||||
return
|
||||
else:
|
||||
|
@ -7390,6 +7401,8 @@ class App(QtCore.QObject):
|
|||
else:
|
||||
location = custom_location
|
||||
|
||||
self.jump_signal.emit(location)
|
||||
|
||||
units = self.defaults['units'].upper()
|
||||
|
||||
if fit_center:
|
||||
|
@ -9962,11 +9975,11 @@ class App(QtCore.QObject):
|
|||
|
||||
flt = "All Files (*.*)"
|
||||
if obj.kind == 'gerber':
|
||||
flt = "Gerber Files (*.GBR);;All Files (*.*)"
|
||||
flt = "Gerber Files (*.GBR);;PDF Files (*.PDF);;All Files (*.*)"
|
||||
elif obj.kind == 'excellon':
|
||||
flt = "Excellon Files (*.DRL);;All Files (*.*)"
|
||||
flt = "Excellon Files (*.DRL);;PDF Files (*.PDF);;All Files (*.*)"
|
||||
elif obj.kind == 'cncjob':
|
||||
"GCode Files (*.NC);;All Files (*.*)"
|
||||
flt = "GCode Files (*.NC);;PDF Files (*.PDF);;All Files (*.*)"
|
||||
|
||||
self.source_editor_tab = TextEditor(app=self, plain_text=True)
|
||||
|
||||
|
@ -10241,13 +10254,6 @@ class App(QtCore.QObject):
|
|||
self.inform.emit('[WARNING_NOTCL] %s' % _("Save Project cancelled."))
|
||||
return
|
||||
|
||||
try:
|
||||
f = open(filename, 'r')
|
||||
f.close()
|
||||
except IOError:
|
||||
self.inform.emit('[ERROR_NOTCL] %s' % _("The object is used by another application."))
|
||||
return
|
||||
|
||||
if use_thread is True:
|
||||
self.worker_task.emit({'fcn': self.save_project,
|
||||
'params': [filename, quit_action]})
|
||||
|
@ -12154,14 +12160,14 @@ class App(QtCore.QObject):
|
|||
g = json.dumps(d, default=to_dict, indent=2, sort_keys=True).encode('utf-8')
|
||||
# # Write
|
||||
f.write(g)
|
||||
self.inform.emit('[success] %s: %s' %
|
||||
(_("Project saved to"), filename))
|
||||
self.inform.emit('[success] %s: %s' % (_("Project saved to"), filename))
|
||||
else:
|
||||
# Open file
|
||||
try:
|
||||
f = open(filename, 'w')
|
||||
except IOError:
|
||||
App.log.error("Failed to open file for saving: %s", filename)
|
||||
self.inform.emit('[ERROR_NOTCL] %s' % _("The object is used by another application."))
|
||||
return
|
||||
|
||||
# Write
|
||||
|
@ -12175,8 +12181,7 @@ class App(QtCore.QObject):
|
|||
except IOError:
|
||||
if silent is False:
|
||||
self.inform.emit('[ERROR_NOTCL] %s: %s %s' %
|
||||
(_("Failed to verify project file"), filename, _("Retry to save it."))
|
||||
)
|
||||
(_("Failed to verify project file"), filename, _("Retry to save it.")))
|
||||
return
|
||||
|
||||
try:
|
||||
|
@ -12184,8 +12189,7 @@ class App(QtCore.QObject):
|
|||
except Exception:
|
||||
if silent is False:
|
||||
self.inform.emit('[ERROR_NOTCL] %s: %s %s' %
|
||||
(_("Failed to parse saved project file"), filename, _("Retry to save it."))
|
||||
)
|
||||
(_("Failed to parse saved project file"), filename, _("Retry to save it.")))
|
||||
f.close()
|
||||
return
|
||||
saved_f.close()
|
||||
|
@ -12196,8 +12200,7 @@ class App(QtCore.QObject):
|
|||
(_("Project saved to"), filename))
|
||||
else:
|
||||
self.inform.emit('[ERROR_NOTCL] %s: %s %s' %
|
||||
(_("Failed to parse saved project file"), filename, _("Retry to save it."))
|
||||
)
|
||||
(_("Failed to parse saved project file"), filename, _("Retry to save it.")))
|
||||
|
||||
tb_settings = QSettings("Open Source", "FlatCAM")
|
||||
lock_state = self.ui.lock_action.isChecked()
|
||||
|
|
311
FlatCAMObj.py
311
FlatCAMObj.py
|
@ -1288,6 +1288,8 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
|
|||
def iso_init(geo_obj, app_obj):
|
||||
# Propagate options
|
||||
geo_obj.options["cnctooldia"] = str(self.options["isotooldia"])
|
||||
geo_obj.tool_type = self.ui.tool_type_radio.get_value().upper()
|
||||
|
||||
geo_obj.solid_geometry = []
|
||||
for i in range(passes):
|
||||
iso_offset = dia * ((2 * i + 1) / 2.0) - (i * (overlap / 100) * dia)
|
||||
|
@ -1417,6 +1419,7 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
|
|||
def iso_init(geo_obj, app_obj):
|
||||
# Propagate options
|
||||
geo_obj.options["cnctooldia"] = str(self.options["isotooldia"])
|
||||
geo_obj.tool_type = self.ui.tool_type_radio.get_value().upper()
|
||||
|
||||
# if milling type is climb then the move is counter-clockwise around features
|
||||
mill_t = 1 if milling_type == 'cl' else 0
|
||||
|
@ -3603,6 +3606,9 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
|
|||
self.old_toolchangeg_state = self.app.defaults["geometry_toolchange"]
|
||||
self.units_found = self.app.defaults['units']
|
||||
|
||||
# this variable can be updated by the Object that generates the geometry
|
||||
self.tool_type = 'C1'
|
||||
|
||||
# Attributes to be included in serialization
|
||||
# Always append to it because it carries contents
|
||||
# from predecessors.
|
||||
|
@ -3745,11 +3751,11 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
|
|||
self.ui.geo_tools_table.setColumnHidden(6, False)
|
||||
|
||||
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'])
|
||||
self.ui_connect()
|
||||
|
||||
def set_ui(self, ui):
|
||||
FlatCAMObj.set_ui(self, ui)
|
||||
|
@ -3859,7 +3865,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
|
|||
'offset': 'Path',
|
||||
'offset_value': 0.0,
|
||||
'type': _('Rough'),
|
||||
'tool_type': 'C1',
|
||||
'tool_type': self.tool_type,
|
||||
'data': new_data,
|
||||
'solid_geometry': self.solid_geometry
|
||||
}
|
||||
|
@ -3883,7 +3889,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
|
|||
self.ui.tool_offset_entry.hide()
|
||||
self.ui.tool_offset_lbl.hide()
|
||||
|
||||
# used to store the state of the mpass_cb if the selected postproc for geometry is hpgl
|
||||
# used to store the state of the mpass_cb if the selected preprocessor for geometry is hpgl
|
||||
self.old_pp_state = self.default_data['multidepth']
|
||||
self.old_toolchangeg_state = self.default_data['toolchange']
|
||||
|
||||
|
@ -3934,7 +3940,6 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
|
|||
self.ui.paint_tool_button.clicked.connect(lambda: self.app.paint_tool.run(toggle=False))
|
||||
self.ui.generate_ncc_button.clicked.connect(lambda: self.app.ncclear_tool.run(toggle=False))
|
||||
self.ui.pp_geometry_name_cb.activated.connect(self.on_pp_changed)
|
||||
self.ui.addtool_entry.returnPressed.connect(lambda: self.on_tool_add())
|
||||
|
||||
self.ui.tipdia_entry.valueChanged.connect(self.update_cutz)
|
||||
self.ui.tipangle_entry.valueChanged.connect(self.update_cutz)
|
||||
|
@ -4010,6 +4015,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
|
|||
|
||||
# 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_entry.returnPressed.connect(self.on_tool_add)
|
||||
|
||||
self.ui.copytool_btn.clicked.connect(lambda: self.on_tool_copy())
|
||||
self.ui.deltool_btn.clicked.connect(lambda: self.on_tool_delete())
|
||||
|
@ -4062,6 +4068,11 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
|
|||
except (TypeError, AttributeError):
|
||||
pass
|
||||
|
||||
try:
|
||||
self.ui.addtool_entry.returnPressed.disconnect()
|
||||
except (TypeError, AttributeError):
|
||||
pass
|
||||
|
||||
try:
|
||||
self.ui.copytool_btn.clicked.disconnect()
|
||||
except (TypeError, AttributeError):
|
||||
|
@ -4103,59 +4114,26 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
|
|||
|
||||
self.units = self.app.defaults['units'].upper()
|
||||
|
||||
# if a Tool diameter entered is a char instead a number the final message of Tool adding is changed
|
||||
# because the Default value for Tool is used.
|
||||
change_message = False
|
||||
|
||||
if dia is not None:
|
||||
tooldia = dia
|
||||
else:
|
||||
try:
|
||||
tooldia = float(self.ui.addtool_entry.get_value())
|
||||
except ValueError:
|
||||
# try to convert comma to decimal point. if it's still not working error message and return
|
||||
try:
|
||||
tooldia = float(self.ui.addtool_entry.get_value().replace(',', '.'))
|
||||
except ValueError:
|
||||
change_message = True
|
||||
tooldia = float(self.options["cnctooldia"][0])
|
||||
|
||||
if tooldia is None:
|
||||
self.build_ui()
|
||||
self.app.inform.emit('[ERROR_NOTCL] %s' %
|
||||
_("Please enter the desired tool diameter in Float format."))
|
||||
return
|
||||
tooldia = float(self.ui.addtool_entry.get_value())
|
||||
|
||||
# construct a list of all 'tooluid' in the self.tools
|
||||
tool_uid_list = []
|
||||
for tooluid_key in self.tools:
|
||||
tool_uid_item = int(tooluid_key)
|
||||
tool_uid_list.append(tool_uid_item)
|
||||
# tool_uid_list = list()
|
||||
# for tooluid_key in self.tools:
|
||||
# tool_uid_list.append(int(tooluid_key))
|
||||
tool_uid_list = [int(tooluid_key) for tooluid_key in self.tools]
|
||||
|
||||
# find maximum from the temp_uid, add 1 and this is the new 'tooluid'
|
||||
if not tool_uid_list:
|
||||
max_uid = 0
|
||||
else:
|
||||
max_uid = max(tool_uid_list)
|
||||
max_uid = max(tool_uid_list) if tool_uid_list else 0
|
||||
self.tooluid = max_uid + 1
|
||||
|
||||
tooldia = float('%.*f' % (self.decimals, tooldia))
|
||||
|
||||
# here we actually add the new tool; if there is no tool in the tool table we add a tool with default data
|
||||
# otherwise we add a tool with data copied from last tool
|
||||
if not self.tools:
|
||||
self.tools.update({
|
||||
self.tooluid: {
|
||||
'tooldia': tooldia,
|
||||
'offset': 'Path',
|
||||
'offset_value': 0.0,
|
||||
'type': _('Rough'),
|
||||
'tool_type': 'C1',
|
||||
'data': deepcopy(self.default_data),
|
||||
'solid_geometry': self.solid_geometry
|
||||
}
|
||||
})
|
||||
else:
|
||||
if self.tools:
|
||||
last_data = self.tools[max_uid]['data']
|
||||
last_offset = self.tools[max_uid]['offset']
|
||||
last_offset_value = self.tools[max_uid]['offset_value']
|
||||
|
@ -4179,6 +4157,18 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
|
|||
'solid_geometry': deepcopy(last_solid_geometry)
|
||||
}
|
||||
})
|
||||
else:
|
||||
self.tools.update({
|
||||
self.tooluid: {
|
||||
'tooldia': tooldia,
|
||||
'offset': 'Path',
|
||||
'offset_value': 0.0,
|
||||
'type': _('Rough'),
|
||||
'tool_type': 'C1',
|
||||
'data': deepcopy(self.default_data),
|
||||
'solid_geometry': self.solid_geometry
|
||||
}
|
||||
})
|
||||
|
||||
self.tools[self.tooluid]['data']['name'] = self.options['name']
|
||||
|
||||
|
@ -4192,12 +4182,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
|
|||
pass
|
||||
self.ser_attrs.append('tools')
|
||||
|
||||
if change_message is False:
|
||||
self.app.inform.emit('[success] %s' % _("Tool added in Tool Table."))
|
||||
else:
|
||||
change_message = False
|
||||
self.app.inform.emit('[WARNING_NOTCL] %s' %
|
||||
_("Default Tool added. Wrong value format entered."))
|
||||
self.app.inform.emit('[success] %s' % _("Tool added in Tool Table."))
|
||||
self.build_ui()
|
||||
|
||||
# if there is no tool left in the Tools Table, enable the parameters GUI
|
||||
|
@ -5735,12 +5720,17 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
|
|||
self.tools = deepcopy(temp_tools_dict)
|
||||
|
||||
# if there is a value in the new tool field then convert that one too
|
||||
try:
|
||||
self.ui.addtool_entry.returnPressed.disconnect()
|
||||
except TypeError:
|
||||
pass
|
||||
tooldia = self.ui.addtool_entry.get_value()
|
||||
if tooldia:
|
||||
tooldia *= factor
|
||||
tooldia = float('%.*f' % (self.decimals, tooldia))
|
||||
|
||||
self.ui.addtool_entry.set_value(tooldia)
|
||||
self.ui.addtool_entry.returnPressed.connect(self.on_tool_add)
|
||||
|
||||
return factor
|
||||
|
||||
|
@ -6621,9 +6611,12 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob):
|
|||
:param to_file: if False then no actual file is saved but the app will know that a file was created
|
||||
:return: None
|
||||
"""
|
||||
gcode = ''
|
||||
roland = False
|
||||
hpgl = False
|
||||
# gcode = ''
|
||||
# roland = False
|
||||
# hpgl = False
|
||||
# isel_icp = False
|
||||
|
||||
include_header = True
|
||||
|
||||
try:
|
||||
if self.special_group:
|
||||
|
@ -6635,58 +6628,184 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob):
|
|||
except AttributeError:
|
||||
pass
|
||||
|
||||
# detect if using Roland preprocessor
|
||||
try:
|
||||
for key in self.cnc_tools:
|
||||
if self.cnc_tools[key]['data']['ppname_g'] == 'Roland_MDX_20':
|
||||
roland = True
|
||||
break
|
||||
if self.cnc_tools[key]['data']['ppname_g'] == 'hpgl':
|
||||
hpgl = True
|
||||
break
|
||||
except Exception as e:
|
||||
try:
|
||||
for key in self.cnc_tools:
|
||||
if self.cnc_tools[key]['data']['ppname_e'] == 'Roland_MDX_20':
|
||||
roland = True
|
||||
break
|
||||
except Exception as e:
|
||||
pass
|
||||
# if this dict is not empty then the object is a Geometry object
|
||||
if self.cnc_tools:
|
||||
first_key = next(iter(self.cnc_tools))
|
||||
include_header = self.app.preprocessors[self.cnc_tools[first_key]['data']['ppname_g']].include_header
|
||||
|
||||
# if this dict is not empty then the object is an Excellon object
|
||||
if self.exc_cnc_tools:
|
||||
first_key = next(iter(self.exc_cnc_tools))
|
||||
include_header = self.app.preprocessors[self.exc_cnc_tools[first_key]['data']['ppname_e']].include_header
|
||||
|
||||
# # detect if using Roland preprocessor
|
||||
# try:
|
||||
# for key in self.cnc_tools:
|
||||
# if self.cnc_tools[key]['data']['ppname_g'] == 'Roland_MDX_20':
|
||||
# roland = True
|
||||
# break
|
||||
# except Exception:
|
||||
# try:
|
||||
# for key in self.cnc_tools:
|
||||
# if self.cnc_tools[key]['data']['ppname_e'] == 'Roland_MDX_20':
|
||||
# roland = True
|
||||
# break
|
||||
# except Exception:
|
||||
# pass
|
||||
#
|
||||
# # detect if using HPGL preprocessor
|
||||
# try:
|
||||
# for key in self.cnc_tools:
|
||||
# if self.cnc_tools[key]['data']['ppname_g'] == 'hpgl':
|
||||
# hpgl = True
|
||||
# break
|
||||
# except Exception:
|
||||
# try:
|
||||
# for key in self.cnc_tools:
|
||||
# if self.cnc_tools[key]['data']['ppname_e'] == 'hpgl':
|
||||
# hpgl = True
|
||||
# break
|
||||
# except Exception:
|
||||
# pass
|
||||
#
|
||||
# # detect if using ISEL_ICP_CNC preprocessor
|
||||
# try:
|
||||
# for key in self.cnc_tools:
|
||||
# if 'ISEL_ICP' in self.cnc_tools[key]['data']['ppname_g'].upper():
|
||||
# isel_icp = True
|
||||
# break
|
||||
# except Exception:
|
||||
# try:
|
||||
# for key in self.cnc_tools:
|
||||
# if 'ISEL_ICP' in self.cnc_tools[key]['data']['ppname_e'].upper():
|
||||
# isel_icp = True
|
||||
# break
|
||||
# except Exception:
|
||||
# pass
|
||||
|
||||
# do not add gcode_header when using the Roland preprocessor, add it for every other preprocessor
|
||||
if roland is False and hpgl is False:
|
||||
gcode = self.gcode_header()
|
||||
# if roland is False and hpgl is False and isel_icp is False:
|
||||
# gcode = self.gcode_header()
|
||||
|
||||
# detect if using multi-tool and make the Gcode summation correctly for each case
|
||||
if self.multitool is True:
|
||||
for tooluid_key in self.cnc_tools:
|
||||
for key, value in self.cnc_tools[tooluid_key].items():
|
||||
if key == 'gcode':
|
||||
gcode += value
|
||||
break
|
||||
else:
|
||||
gcode += self.gcode
|
||||
# do not add gcode_header when using the Roland, HPGL or ISEP_ICP_CNC preprocessor (or any other preprocessor
|
||||
# that has the include_header attribute set as False, add it for every other preprocessor
|
||||
# if include_header:
|
||||
# gcode = self.gcode_header()
|
||||
# else:
|
||||
# gcode = ''
|
||||
|
||||
if roland is True:
|
||||
g = preamble + gcode + postamble
|
||||
elif hpgl is True:
|
||||
g = self.gcode_header() + preamble + gcode + postamble
|
||||
# # detect if using multi-tool and make the Gcode summation correctly for each case
|
||||
# if self.multitool is True:
|
||||
# for tooluid_key in self.cnc_tools:
|
||||
# for key, value in self.cnc_tools[tooluid_key].items():
|
||||
# if key == 'gcode':
|
||||
# gcode += value
|
||||
# break
|
||||
# else:
|
||||
# gcode += self.gcode
|
||||
|
||||
# if roland is True:
|
||||
# g = preamble + gcode + postamble
|
||||
# elif hpgl is True:
|
||||
# g = self.gcode_header() + preamble + gcode + postamble
|
||||
# else:
|
||||
# # fix so the preamble gets inserted in between the comments header and the actual start of GCODE
|
||||
# g_idx = gcode.rfind('G20')
|
||||
#
|
||||
# # if it did not find 'G20' then search for 'G21'
|
||||
# if g_idx == -1:
|
||||
# g_idx = gcode.rfind('G21')
|
||||
#
|
||||
# # if it did not find 'G20' and it did not find 'G21' then there is an error and return
|
||||
# # but only when the preprocessor is not ISEL_ICP who is allowed not to have the G20/G21 command
|
||||
# if g_idx == -1 and isel_icp is False:
|
||||
# self.app.inform.emit('[ERROR_NOTCL] %s' % _("G-code does not have a units code: either G20 or G21"))
|
||||
# return
|
||||
#
|
||||
# footer = self.app.defaults['cncjob_footer']
|
||||
# end_gcode = self.gcode_footer() if footer is True else ''
|
||||
# g = gcode[:g_idx] + preamble + '\n' + gcode[g_idx:] + postamble + end_gcode
|
||||
|
||||
gcode = ''
|
||||
if include_header is False:
|
||||
g = preamble
|
||||
# detect if using multi-tool and make the Gcode summation correctly for each case
|
||||
if self.multitool is True:
|
||||
for tooluid_key in self.cnc_tools:
|
||||
for key, value in self.cnc_tools[tooluid_key].items():
|
||||
if key == 'gcode':
|
||||
gcode += value
|
||||
break
|
||||
else:
|
||||
gcode += self.gcode
|
||||
|
||||
g = g + gcode + postamble
|
||||
else:
|
||||
# search for the GCode beginning which is usually a G20 or G21
|
||||
# fix so the preamble gets inserted in between the comments header and the actual start of GCODE
|
||||
g_idx = gcode.rfind('G20')
|
||||
# g_idx = gcode.rfind('G20')
|
||||
#
|
||||
# # if it did not find 'G20' then search for 'G21'
|
||||
# if g_idx == -1:
|
||||
# g_idx = gcode.rfind('G21')
|
||||
#
|
||||
# # if it did not find 'G20' and it did not find 'G21' then there is an error and return
|
||||
# if g_idx == -1:
|
||||
# self.app.inform.emit('[ERROR_NOTCL] %s' % _("G-code does not have a units code: either G20 or G21"))
|
||||
# return
|
||||
|
||||
# if it did not find 'G20' then search for 'G21'
|
||||
if g_idx == -1:
|
||||
g_idx = gcode.rfind('G21')
|
||||
# detect if using multi-tool and make the Gcode summation correctly for each case
|
||||
if self.multitool is True:
|
||||
for tooluid_key in self.cnc_tools:
|
||||
for key, value in self.cnc_tools[tooluid_key].items():
|
||||
if key == 'gcode':
|
||||
gcode += value
|
||||
break
|
||||
else:
|
||||
gcode += self.gcode
|
||||
|
||||
# if it did not find 'G20' and it did not find 'G21' then there is an error and return
|
||||
if g_idx == -1:
|
||||
self.app.inform.emit('[ERROR_NOTCL] %s' % _("G-code does not have a units code: either G20 or G21"))
|
||||
return
|
||||
end_gcode = self.gcode_footer() if self.app.defaults['cncjob_footer'] is True else ''
|
||||
|
||||
footer = self.app.defaults['cncjob_footer']
|
||||
end_gcode = self.gcode_footer() if footer is True else ''
|
||||
g = gcode[:g_idx] + preamble + '\n' + gcode[g_idx:] + postamble + end_gcode
|
||||
# detect if using a HPGL preprocessor
|
||||
hpgl = False
|
||||
if self.cnc_tools:
|
||||
for key in self.cnc_tools:
|
||||
if 'ppname_g' in self.cnc_tools[key]['data']:
|
||||
if 'hpgl' in self.cnc_tools[key]['data']['ppname_g']:
|
||||
hpgl = True
|
||||
break
|
||||
elif self.exc_cnc_tools:
|
||||
for key in self.cnc_tools:
|
||||
if 'ppname_e' in self.cnc_tools[key]['data']:
|
||||
if 'hpgl' in self.cnc_tools[key]['data']['ppname_e']:
|
||||
hpgl = True
|
||||
break
|
||||
|
||||
if hpgl:
|
||||
processed_gcode = ''
|
||||
pa_re = re.compile(r"^PA\s*(-?\d+\.\d*),?\s*(-?\d+\.\d*)*;?$")
|
||||
for gline in gcode.splitlines():
|
||||
match = pa_re.search(gline)
|
||||
if match:
|
||||
x_int = int(float(match.group(1)))
|
||||
y_int = int(float(match.group(2)))
|
||||
new_line = 'PA%d,%d;\n' % (x_int, y_int)
|
||||
processed_gcode += new_line
|
||||
else:
|
||||
processed_gcode += gline + '\n'
|
||||
|
||||
gcode = processed_gcode
|
||||
g = self.gcode_header() + '\n' + preamble + '\n' + gcode + postamble + end_gcode
|
||||
else:
|
||||
try:
|
||||
g_idx = gcode.index('G94')
|
||||
g = self.gcode_header() + gcode[:g_idx + 3] + '\n\n' + preamble + '\n' + \
|
||||
gcode[(g_idx + 3):] + postamble + end_gcode
|
||||
except ValueError:
|
||||
self.app.inform.emit('[ERROR_NOTCL] %s' %
|
||||
_("G-code does not have a G94 code and we will not include the code in the "
|
||||
"'Prepend to GCode' text box"))
|
||||
g = self.gcode_header() + '\n' + gcode + postamble + end_gcode
|
||||
|
||||
# if toolchange custom is used, replace M6 code with the code from the Toolchange Custom Text box
|
||||
if self.ui.toolchange_cb.get_value() is True:
|
||||
|
|
32
README.md
32
README.md
|
@ -9,6 +9,34 @@ CAD program, and create G-Code for Isolation routing.
|
|||
|
||||
=================================================
|
||||
|
||||
17.12.2019
|
||||
|
||||
- more optimizations in NCC Tool
|
||||
- optimizations in Paint Tool
|
||||
- maximum range for Cut Z is now zero to deal with the situation when using V-shape with tip-dia same value with cut width
|
||||
- modified QValidator in FCDoubleSpinner() GUI element to allow entering the minus sign when the range maximum is set as 0.0; also for positive numbers allowed entering the symbol plus
|
||||
- made sure that if in Gerber UI the isolation is made with a V-Shape tool then the tool type is automatically updated on the generated Geometry Object
|
||||
- added ability to save the Source File as PDF (still have to adjust the page size)
|
||||
- fixed the generate_from_geometry_2() method to use the default values in case the parameters are None
|
||||
- added ability to save the Source File as PDF - fixed page size and added line breaks
|
||||
- more mods to generate_from_geometry_2() method
|
||||
- fixed bug saving the FlatCAM project saying the file is used by another application
|
||||
|
||||
16.12.2019
|
||||
|
||||
- in Geometry Editor added support for Jump To function such as that it works within the Editor Tools themselves. For now it works only in absolute jumps
|
||||
- modified the Jump To method such that now allows relative jump from the current mouse location
|
||||
- fixed the Defaults upgrade overwriting the new version number with the old one
|
||||
- fixed issue with clear_polygon3() - the one who makes 'lines' and fixed the NCC Tool
|
||||
- some small changes in the FlatCAMGeometry.on_tool_add() method
|
||||
- made sure that in Geometry Editor the self.app.mouse attribute is updated with the current mouse position (x, y)
|
||||
- updated the preprocessor files
|
||||
- fixed the HPGL preprocessor
|
||||
- fixed the CNCJob geometry created with HPGL preprocessor
|
||||
- fixed GCode generated with HPGL preprocessor to output only integer coordinates
|
||||
- fixed the HPGL2 import parsing for absolute linear movements
|
||||
- fixed the line endings for setup_ubuntu.sh
|
||||
|
||||
15.12.2019
|
||||
|
||||
- fixed a bug that created a crash in special conditions; it's related to the QSettings in FlatCAMGui.py
|
||||
|
@ -17,6 +45,10 @@ CAD program, and create G-Code for Isolation routing.
|
|||
- updated the languages
|
||||
- fixed a typo
|
||||
- fixed layout on first launch of the app
|
||||
- fixed some issues with the recent preparation for dark icons resource usage
|
||||
- added a new preprocessor file contributed by Daniel Friderich and added fixes for it
|
||||
- modified the export_gcode() method and the preprocessors such that the preprocessors now have the information if to include the gcode header
|
||||
- updated all the translation PO files and the POT file
|
||||
- RELEASE 8.99
|
||||
|
||||
14.12.2019
|
||||
|
|
176
camlib.py
176
camlib.py
|
@ -1381,9 +1381,10 @@ class Geometry(object):
|
|||
inner_edges.append(y)
|
||||
# geoms += outer_edges + inner_edges
|
||||
for g in outer_edges + inner_edges:
|
||||
geoms.insert(g)
|
||||
if prog_plot:
|
||||
self.plot_temp_shapes(g)
|
||||
if g and not g.is_empty:
|
||||
geoms.insert(g)
|
||||
if prog_plot:
|
||||
self.plot_temp_shapes(g)
|
||||
|
||||
if prog_plot:
|
||||
self.temp_shapes.redraw()
|
||||
|
@ -1395,7 +1396,9 @@ class Geometry(object):
|
|||
# Optimization: Reduce lifts
|
||||
if connect:
|
||||
# log.debug("Reducing tool lifts...")
|
||||
geoms = Geometry.paint_connect(geoms, polygon_to_clear, tooldia, steps_per_circle)
|
||||
geoms_conn = Geometry.paint_connect(geoms, polygon_to_clear, tooldia, steps_per_circle)
|
||||
if geoms_conn:
|
||||
return geoms_conn
|
||||
|
||||
return geoms
|
||||
|
||||
|
@ -1419,6 +1422,9 @@ class Geometry(object):
|
|||
"""
|
||||
|
||||
# log.debug("camlib.clear_polygon3()")
|
||||
if not isinstance(polygon, Polygon):
|
||||
log.debug("camlib.Geometry.clear_polygon3() --> Not a Polygon but %s" % str(type(polygon)))
|
||||
return None
|
||||
|
||||
# ## The toolpaths
|
||||
# Index first and last points in paths
|
||||
|
@ -1433,41 +1439,43 @@ class Geometry(object):
|
|||
# Bounding box
|
||||
left, bot, right, top = polygon.bounds
|
||||
|
||||
margin_poly = polygon.buffer(-tooldia / 1.99999999, (int(steps_per_circle)))
|
||||
try:
|
||||
margin_poly = polygon.buffer(-tooldia / 1.99999999, (int(steps_per_circle)))
|
||||
except Exception as e:
|
||||
log.debug("camlib.Geometry.clear_polygon3() --> Could not buffer the Polygon")
|
||||
return None
|
||||
|
||||
# First line
|
||||
y = top - tooldia / 1.99999999
|
||||
while y > bot + tooldia / 1.999999999:
|
||||
if self.app.abort_flag:
|
||||
# graceful abort requested by the user
|
||||
raise FlatCAMApp.GracefulException
|
||||
try:
|
||||
y = top - tooldia / 1.99999999
|
||||
while y > bot + tooldia / 1.999999999:
|
||||
if self.app.abort_flag:
|
||||
# graceful abort requested by the user
|
||||
raise FlatCAMApp.GracefulException
|
||||
|
||||
# provide the app with a way to process the GUI events when in a blocking loop
|
||||
QtWidgets.QApplication.processEvents()
|
||||
# provide the app with a way to process the GUI events when in a blocking loop
|
||||
QtWidgets.QApplication.processEvents()
|
||||
|
||||
line = LineString([(left, y), (right, y)])
|
||||
line = line.intersection(margin_poly)
|
||||
lines_trimmed.append(line)
|
||||
y -= tooldia * (1 - overlap)
|
||||
if prog_plot:
|
||||
self.plot_temp_shapes(line)
|
||||
self.temp_shapes.redraw()
|
||||
|
||||
# Last line
|
||||
y = bot + tooldia / 2
|
||||
line = LineString([(left, y), (right, y)])
|
||||
line = line.intersection(margin_poly)
|
||||
lines_trimmed.append(line)
|
||||
y -= tooldia * (1 - overlap)
|
||||
if prog_plot:
|
||||
self.plot_temp_shapes(line)
|
||||
self.temp_shapes.redraw()
|
||||
|
||||
# Last line
|
||||
y = bot + tooldia / 2
|
||||
line = LineString([(left, y), (right, y)])
|
||||
line = line.intersection(margin_poly)
|
||||
for ll in line:
|
||||
lines_trimmed.append(ll)
|
||||
if prog_plot:
|
||||
self.plot_temp_shapes(line)
|
||||
|
||||
# Combine
|
||||
# linesgeo = unary_union(lines)
|
||||
|
||||
# Trim to the polygon
|
||||
# margin_poly = polygon.buffer(-tooldia / 1.99999999, (int(steps_per_circle)))
|
||||
# lines_trimmed = linesgeo.intersection(margin_poly)
|
||||
for ll in line:
|
||||
lines_trimmed.append(ll)
|
||||
if prog_plot:
|
||||
self.plot_temp_shapes(line)
|
||||
except Exception as e:
|
||||
log.debug('camlib.Geometry.clear_polygon3() Processing poly --> %s' % str(e))
|
||||
return None
|
||||
|
||||
if prog_plot:
|
||||
self.temp_shapes.redraw()
|
||||
|
@ -1477,27 +1485,33 @@ class Geometry(object):
|
|||
# Add lines to storage
|
||||
try:
|
||||
for line in lines_trimmed:
|
||||
geoms.insert(line)
|
||||
if isinstance(line, LineString) or isinstance(line, LinearRing):
|
||||
geoms.insert(line)
|
||||
else:
|
||||
log.debug("camlib.Geometry.clear_polygon3(). Not a line: %s" % str(type(line)))
|
||||
except TypeError:
|
||||
# in case lines_trimmed are not iterable (Linestring, LinearRing)
|
||||
geoms.insert(lines_trimmed)
|
||||
|
||||
# Add margin (contour) to storage
|
||||
if contour:
|
||||
if isinstance(margin_poly, Polygon):
|
||||
geoms.insert(margin_poly.exterior)
|
||||
if prog_plot:
|
||||
self.plot_temp_shapes(margin_poly.exterior)
|
||||
for ints in margin_poly.interiors:
|
||||
geoms.insert(ints)
|
||||
if prog_plot:
|
||||
self.plot_temp_shapes(ints)
|
||||
elif isinstance(margin_poly, MultiPolygon):
|
||||
try:
|
||||
for poly in margin_poly:
|
||||
geoms.insert(poly.exterior)
|
||||
if isinstance(poly, Polygon) and not poly.is_empty:
|
||||
geoms.insert(poly.exterior)
|
||||
if prog_plot:
|
||||
self.plot_temp_shapes(poly.exterior)
|
||||
for ints in poly.interiors:
|
||||
geoms.insert(ints)
|
||||
if prog_plot:
|
||||
self.plot_temp_shapes(ints)
|
||||
except TypeError:
|
||||
if isinstance(margin_poly, Polygon) and not margin_poly.is_empty:
|
||||
marg_ext = margin_poly.exterior
|
||||
geoms.insert(marg_ext)
|
||||
if prog_plot:
|
||||
self.plot_temp_shapes(poly.exterior)
|
||||
for ints in poly.interiors:
|
||||
self.plot_temp_shapes(margin_poly.exterior)
|
||||
for ints in margin_poly.interiors:
|
||||
geoms.insert(ints)
|
||||
if prog_plot:
|
||||
self.plot_temp_shapes(ints)
|
||||
|
@ -1508,7 +1522,9 @@ class Geometry(object):
|
|||
# Optimization: Reduce lifts
|
||||
if connect:
|
||||
# log.debug("Reducing tool lifts...")
|
||||
geoms = Geometry.paint_connect(geoms, polygon, tooldia, steps_per_circle)
|
||||
geoms_conn = Geometry.paint_connect(geoms, polygon, tooldia, steps_per_circle)
|
||||
if geoms_conn:
|
||||
return geoms_conn
|
||||
|
||||
return geoms
|
||||
|
||||
|
@ -1581,8 +1597,14 @@ class Geometry(object):
|
|||
optimized_paths.get_points = get_pts
|
||||
path_count = 0
|
||||
current_pt = (0, 0)
|
||||
pt, geo = storage.nearest(current_pt)
|
||||
try:
|
||||
pt, geo = storage.nearest(current_pt)
|
||||
except StopIteration:
|
||||
log.debug("camlib.Geometry.paint_connect(). Storage empty")
|
||||
return None
|
||||
|
||||
storage.remove(geo)
|
||||
|
||||
geo = LineString(geo)
|
||||
current_pt = geo.coords[-1]
|
||||
try:
|
||||
|
@ -1592,6 +1614,7 @@ class Geometry(object):
|
|||
|
||||
pt, candidate = storage.nearest(current_pt)
|
||||
storage.remove(candidate)
|
||||
|
||||
candidate = LineString(candidate)
|
||||
|
||||
# If last point in geometry is the nearest
|
||||
|
@ -2448,11 +2471,17 @@ class CNCjob(Geometry):
|
|||
except KeyError:
|
||||
z_off = 0
|
||||
|
||||
default_data = dict()
|
||||
for k, v in list(self.options.items()):
|
||||
default_data[k] = deepcopy(v)
|
||||
|
||||
self.exc_cnc_tools[it[1]] = dict()
|
||||
self.exc_cnc_tools[it[1]]['tool'] = it[0]
|
||||
self.exc_cnc_tools[it[1]]['nr_drills'] = drill_no
|
||||
self.exc_cnc_tools[it[1]]['nr_slots'] = slot_no
|
||||
self.exc_cnc_tools[it[1]]['offset_z'] = z_off
|
||||
self.exc_cnc_tools[it[1]]['data'] = default_data
|
||||
|
||||
self.exc_cnc_tools[it[1]]['solid_geometry'] = deepcopy(sol_geo)
|
||||
|
||||
self.app.inform.emit(_("Creating a list of points to drill..."))
|
||||
|
@ -3275,14 +3304,12 @@ class CNCjob(Geometry):
|
|||
return self.gcode
|
||||
|
||||
def generate_from_geometry_2(
|
||||
self, geometry, append=True,
|
||||
tooldia=None, offset=0.0, tolerance=0,
|
||||
z_cut=1.0, z_move=2.0,
|
||||
feedrate=2.0, feedrate_z=2.0, feedrate_rapid=30,
|
||||
spindlespeed=None, spindledir='CW', dwell=False, dwelltime=1.0,
|
||||
self, geometry, append=True, tooldia=None, offset=0.0, tolerance=0, z_cut=None, z_move=None,
|
||||
feedrate=None, feedrate_z=None, feedrate_rapid=None,
|
||||
spindlespeed=None, spindledir='CW', dwell=False, dwelltime=None,
|
||||
multidepth=False, depthpercut=None,
|
||||
toolchange=False, toolchangez=1.0, toolchangexy="0.0, 0.0",
|
||||
extracut=False, extracut_length=0.1, startz=None, endz=2.0,
|
||||
toolchange=False, toolchangez=None, toolchangexy="0.0, 0.0",
|
||||
extracut=False, extracut_length=None, startz=None, endz=None,
|
||||
pp_geometry_name=None, tool_no=1):
|
||||
"""
|
||||
Second algorithm to generate from Geometry.
|
||||
|
@ -3377,27 +3404,31 @@ class CNCjob(Geometry):
|
|||
log.debug("%d paths" % len(flat_geometry))
|
||||
|
||||
try:
|
||||
self.tooldia = float(tooldia) if tooldia else None
|
||||
self.tooldia = float(tooldia) if tooldia else self.app.defaults["geometry_cnctooldia"]
|
||||
except ValueError:
|
||||
self.tooldia = [float(el) for el in tooldia.split(',') if el != ''] if tooldia else None
|
||||
self.tooldia = [float(el) for el in tooldia.split(',') if el != ''] if tooldia is not None else \
|
||||
self.app.defaults["geometry_cnctooldia"]
|
||||
|
||||
self.z_cut = float(z_cut) if z_cut is not None else None
|
||||
self.z_move = float(z_move) if z_move is not None else None
|
||||
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.feedrate = float(feedrate) if feedrate else None
|
||||
self.z_feedrate = float(feedrate_z) if feedrate_z is not None else None
|
||||
self.feedrate_rapid = float(feedrate_rapid) if feedrate_rapid else None
|
||||
self.feedrate = float(feedrate) if feedrate is not None else self.app.defaults["geometry_feedrate"]
|
||||
self.z_feedrate = float(feedrate_z) if feedrate_z is not None else self.app.defaults["geometry_feedrate_z"]
|
||||
self.feedrate_rapid = float(feedrate_rapid) if feedrate_rapid is not None else \
|
||||
self.app.defaults["geometry_feedrate_rapid"]
|
||||
|
||||
self.spindlespeed = int(spindlespeed) if spindlespeed != 0 else None
|
||||
self.spindledir = spindledir
|
||||
self.dwell = dwell
|
||||
self.dwelltime = float(dwelltime) if dwelltime else None
|
||||
self.dwelltime = float(dwelltime) if dwelltime is not None else self.app.defaults["geometry_dwelltime"]
|
||||
|
||||
self.startz = float(startz) if startz is not None else None
|
||||
self.z_end = float(endz) if endz is not None else None
|
||||
self.z_depthpercut = float(depthpercut) if depthpercut else None
|
||||
self.startz = float(startz) if startz is not None else self.app.defaults["geometry_startz"]
|
||||
self.z_end = float(endz) if endz is not None else self.app.defaults["geometry_endz"]
|
||||
self.z_depthpercut = float(depthpercut) if depthpercut is not None else 0.0
|
||||
self.multidepth = multidepth
|
||||
self.z_toolchange = float(toolchangez) if toolchangez is not None else None
|
||||
self.z_toolchange = float(toolchangez) if toolchangez is not None else self.app.defaults["geometry_toolchangez"]
|
||||
self.extracut_length = float(extracut_length) if extracut_length is not None else \
|
||||
self.app.defaults["geometry_extracut_length"]
|
||||
|
||||
try:
|
||||
if toolchangexy == '':
|
||||
|
@ -3457,7 +3488,10 @@ class CNCjob(Geometry):
|
|||
return 'fail'
|
||||
|
||||
# made sure that depth_per_cut is no more then the z_cut
|
||||
if abs(self.z_cut) < self.z_depthpercut:
|
||||
try:
|
||||
if abs(self.z_cut) < self.z_depthpercut:
|
||||
self.z_depthpercut = abs(self.z_cut)
|
||||
except TypeError:
|
||||
self.z_depthpercut = abs(self.z_cut)
|
||||
|
||||
# ## Index first and last points in paths
|
||||
|
@ -3572,7 +3606,7 @@ class CNCjob(Geometry):
|
|||
if not multidepth:
|
||||
# calculate the cut distance
|
||||
total_cut += geo.length
|
||||
self.gcode += self.create_gcode_single_pass(geo, extracut, extracut_length, tolerance,
|
||||
self.gcode += self.create_gcode_single_pass(geo, extracut, self.extracut_length, tolerance,
|
||||
old_point=current_pt)
|
||||
|
||||
# --------- Multi-pass ---------
|
||||
|
@ -3587,7 +3621,7 @@ class CNCjob(Geometry):
|
|||
|
||||
total_cut += (geo.length * nr_cuts)
|
||||
|
||||
self.gcode += self.create_gcode_multi_pass(geo, extracut, extracut_length, tolerance,
|
||||
self.gcode += self.create_gcode_multi_pass(geo, extracut, self.extracut_length, tolerance,
|
||||
postproc=p, old_point=current_pt)
|
||||
|
||||
# calculate the travel distance
|
||||
|
@ -3916,8 +3950,8 @@ class CNCjob(Geometry):
|
|||
match_pa = re.search(r"^PA(\s*-?\d+\.\d+?),(\s*\s*-?\d+\.\d+?)*;$", gline)
|
||||
if match_pa:
|
||||
command['G'] = 0
|
||||
command['X'] = float(match_pa.group(1).replace(" ", ""))
|
||||
command['Y'] = float(match_pa.group(2).replace(" ", ""))
|
||||
command['X'] = float(match_pa.group(1).replace(" ", "")) / 40
|
||||
command['Y'] = float(match_pa.group(2).replace(" ", "")) / 40
|
||||
match_pen = re.search(r"^(P[U|D])", gline)
|
||||
if match_pen:
|
||||
if match_pen.group(1) == 'PU':
|
||||
|
|
|
@ -1880,7 +1880,10 @@ class DrawTool(object):
|
|||
return ""
|
||||
|
||||
def on_key(self, key):
|
||||
return None
|
||||
|
||||
# Jump to coords
|
||||
if key == QtCore.Qt.Key_J or key == 'J':
|
||||
self.draw_app.app.on_jump_to()
|
||||
|
||||
def utility_geometry(self, data=None):
|
||||
return None
|
||||
|
@ -1934,13 +1937,17 @@ class FCCircle(FCShapeTool):
|
|||
DrawTool.__init__(self, draw_app)
|
||||
self.name = 'circle'
|
||||
|
||||
self.draw_app = draw_app
|
||||
|
||||
try:
|
||||
QtGui.QGuiApplication.restoreOverrideCursor()
|
||||
except Exception:
|
||||
pass
|
||||
self.cursor = QtGui.QCursor(QtGui.QPixmap(self.app.resource_location + '/aero_circle_geo.png'))
|
||||
self.cursor = QtGui.QCursor(QtGui.QPixmap(self.draw_app.app.resource_location + '/aero_circle_geo.png'))
|
||||
QtGui.QGuiApplication.setOverrideCursor(self.cursor)
|
||||
|
||||
self.draw_app.app.jump_signal.connect(lambda x: self.draw_app.update_utility_geometry(data=x))
|
||||
|
||||
self.draw_app.app.inform.emit(_("Click on Center point ..."))
|
||||
self.steps_per_circ = self.draw_app.app.defaults["geometry_circle_steps"]
|
||||
|
||||
|
@ -1977,8 +1984,10 @@ class FCCircle(FCShapeTool):
|
|||
radius = distance(p1, p2)
|
||||
self.geometry = DrawToolShape(Point(p1).buffer(radius, int(self.steps_per_circ / 4)))
|
||||
self.complete = True
|
||||
self.draw_app.app.inform.emit('[success] %s' %
|
||||
_("Done. Adding Circle completed."))
|
||||
|
||||
self.draw_app.app.jump_signal.disconnect()
|
||||
|
||||
self.draw_app.app.inform.emit('[success] %s' % _("Done. Adding Circle completed."))
|
||||
|
||||
|
||||
class FCArc(FCShapeTool):
|
||||
|
@ -1986,11 +1995,13 @@ class FCArc(FCShapeTool):
|
|||
DrawTool.__init__(self, draw_app)
|
||||
self.name = 'arc'
|
||||
|
||||
self.draw_app = draw_app
|
||||
|
||||
try:
|
||||
QtGui.QGuiApplication.restoreOverrideCursor()
|
||||
except Exception:
|
||||
pass
|
||||
self.cursor = QtGui.QCursor(QtGui.QPixmap(self.app.resource_location + '/aero_arc.png'))
|
||||
self.cursor = QtGui.QCursor(QtGui.QPixmap(self.draw_app.app.resource_location + '/aero_arc.png'))
|
||||
QtGui.QGuiApplication.setOverrideCursor(self.cursor)
|
||||
|
||||
self.draw_app.app.inform.emit(_("Click on Center point ..."))
|
||||
|
@ -2006,6 +2017,8 @@ class FCArc(FCShapeTool):
|
|||
# 132 = p1, p3, p2
|
||||
self.mode = "c12" # Center, p1, p2
|
||||
|
||||
self.draw_app.app.jump_signal.connect(lambda x: self.draw_app.update_utility_geometry(data=x))
|
||||
|
||||
self.steps_per_circ = self.draw_app.app.defaults["geometry_circle_steps"]
|
||||
|
||||
def click(self, point):
|
||||
|
@ -2040,6 +2053,10 @@ class FCArc(FCShapeTool):
|
|||
self.direction = 'cw' if self.direction == 'ccw' else 'ccw'
|
||||
return _('Direction: %s') % self.direction.upper()
|
||||
|
||||
# Jump to coords
|
||||
if key == QtCore.Qt.Key_J or key == 'J':
|
||||
self.draw_app.app.on_jump_to()
|
||||
|
||||
if key == 'M' or key == QtCore.Qt.Key_M:
|
||||
# delete the possible points made before this action; we want to start anew
|
||||
self.points[:] = []
|
||||
|
@ -2192,8 +2209,10 @@ class FCArc(FCShapeTool):
|
|||
self.geometry = DrawToolShape(LineString(arc(center, radius, startangle, stopangle,
|
||||
self.direction, self.steps_per_circ)))
|
||||
self.complete = True
|
||||
self.draw_app.app.inform.emit('[success] %s' %
|
||||
_("Done. Arc completed."))
|
||||
|
||||
self.draw_app.app.jump_signal.disconnect()
|
||||
|
||||
self.draw_app.app.inform.emit('[success] %s' % _("Done. Arc completed."))
|
||||
|
||||
|
||||
class FCRectangle(FCShapeTool):
|
||||
|
@ -2204,14 +2223,17 @@ class FCRectangle(FCShapeTool):
|
|||
def __init__(self, draw_app):
|
||||
DrawTool.__init__(self, draw_app)
|
||||
self.name = 'rectangle'
|
||||
self.draw_app = draw_app
|
||||
|
||||
try:
|
||||
QtGui.QGuiApplication.restoreOverrideCursor()
|
||||
except Exception:
|
||||
pass
|
||||
self.cursor = QtGui.QCursor(QtGui.QPixmap(self.app.resource_location + '/aero.png'))
|
||||
self.cursor = QtGui.QCursor(QtGui.QPixmap(self.draw_app.app.resource_location + '/aero.png'))
|
||||
QtGui.QGuiApplication.setOverrideCursor(self.cursor)
|
||||
|
||||
self.draw_app.app.jump_signal.connect(lambda x: self.draw_app.update_utility_geometry(data=x))
|
||||
|
||||
self.draw_app.app.inform.emit(_("Click on 1st corner ..."))
|
||||
|
||||
def click(self, point):
|
||||
|
@ -2246,8 +2268,9 @@ class FCRectangle(FCShapeTool):
|
|||
# self.geometry = LinearRing([p1, (p2[0], p1[1]), p2, (p1[0], p2[1])])
|
||||
self.geometry = DrawToolShape(Polygon([p1, (p2[0], p1[1]), p2, (p1[0], p2[1])]))
|
||||
self.complete = True
|
||||
self.draw_app.app.inform.emit('[success] %s' %
|
||||
_("Done. Rectangle completed."))
|
||||
|
||||
self.draw_app.app.jump_signal.disconnect()
|
||||
self.draw_app.app.inform.emit('[success] %s' % _("Done. Rectangle completed."))
|
||||
|
||||
|
||||
class FCPolygon(FCShapeTool):
|
||||
|
@ -2258,14 +2281,17 @@ class FCPolygon(FCShapeTool):
|
|||
def __init__(self, draw_app):
|
||||
DrawTool.__init__(self, draw_app)
|
||||
self.name = 'polygon'
|
||||
self.draw_app = draw_app
|
||||
|
||||
try:
|
||||
QtGui.QGuiApplication.restoreOverrideCursor()
|
||||
except Exception:
|
||||
pass
|
||||
self.cursor = QtGui.QCursor(QtGui.QPixmap(self.app.resource_location + '/aero.png'))
|
||||
self.cursor = QtGui.QCursor(QtGui.QPixmap(self.draw_app.app.resource_location + '/aero.png'))
|
||||
QtGui.QGuiApplication.setOverrideCursor(self.cursor)
|
||||
|
||||
self.draw_app.app.jump_signal.connect(lambda x: self.draw_app.update_utility_geometry(data=x))
|
||||
|
||||
self.draw_app.app.inform.emit(_("Click on 1st corner ..."))
|
||||
|
||||
def click(self, point):
|
||||
|
@ -2301,10 +2327,16 @@ class FCPolygon(FCShapeTool):
|
|||
self.geometry = DrawToolShape(Polygon(self.points))
|
||||
self.draw_app.in_action = False
|
||||
self.complete = True
|
||||
self.draw_app.app.inform.emit('[success] %s' %
|
||||
_("Done. Polygon completed."))
|
||||
|
||||
self.draw_app.app.jump_signal.disconnect()
|
||||
|
||||
self.draw_app.app.inform.emit('[success] %s' % _("Done. Polygon completed."))
|
||||
|
||||
def on_key(self, key):
|
||||
# Jump to coords
|
||||
if key == QtCore.Qt.Key_J or key == 'J':
|
||||
self.draw_app.app.on_jump_to()
|
||||
|
||||
if key == 'Backspace' or key == QtCore.Qt.Key_Backspace:
|
||||
if len(self.points) > 0:
|
||||
self.points = self.points[0:-1]
|
||||
|
@ -2321,14 +2353,17 @@ class FCPath(FCPolygon):
|
|||
"""
|
||||
def __init__(self, draw_app):
|
||||
FCPolygon.__init__(self, draw_app)
|
||||
self.draw_app = draw_app
|
||||
|
||||
try:
|
||||
QtGui.QGuiApplication.restoreOverrideCursor()
|
||||
except Exception:
|
||||
pass
|
||||
self.cursor = QtGui.QCursor(QtGui.QPixmap(self.app.resource_location + '/aero_path5.png'))
|
||||
self.cursor = QtGui.QCursor(QtGui.QPixmap(self.draw_app.app.resource_location + '/aero_path5.png'))
|
||||
QtGui.QGuiApplication.setOverrideCursor(self.cursor)
|
||||
|
||||
self.draw_app.app.jump_signal.connect(lambda x: self.draw_app.update_utility_geometry(data=x))
|
||||
|
||||
def make(self):
|
||||
self.geometry = DrawToolShape(LineString(self.points))
|
||||
self.name = 'path'
|
||||
|
@ -2340,6 +2375,9 @@ class FCPath(FCPolygon):
|
|||
|
||||
self.draw_app.in_action = False
|
||||
self.complete = True
|
||||
|
||||
self.draw_app.app.jump_signal.disconnect()
|
||||
|
||||
self.draw_app.app.inform.emit('[success] %s' % _("Done. Path completed."))
|
||||
|
||||
def utility_geometry(self, data=None):
|
||||
|
@ -2351,6 +2389,10 @@ class FCPath(FCPolygon):
|
|||
return None
|
||||
|
||||
def on_key(self, key):
|
||||
# Jump to coords
|
||||
if key == QtCore.Qt.Key_J or key == 'J':
|
||||
self.draw_app.app.on_jump_to()
|
||||
|
||||
if key == 'Backspace' or key == QtCore.Qt.Key_Backspace:
|
||||
if len(self.points) > 0:
|
||||
self.points = self.points[0:-1]
|
||||
|
@ -2365,6 +2407,7 @@ class FCSelect(DrawTool):
|
|||
def __init__(self, draw_app):
|
||||
DrawTool.__init__(self, draw_app)
|
||||
self.name = 'select'
|
||||
self.draw_app = draw_app
|
||||
|
||||
try:
|
||||
QtGui.QGuiApplication.restoreOverrideCursor()
|
||||
|
@ -2443,12 +2486,11 @@ class FCExplode(FCShapeTool):
|
|||
def __init__(self, draw_app):
|
||||
FCShapeTool.__init__(self, draw_app)
|
||||
self.name = 'explode'
|
||||
|
||||
self.draw_app = draw_app
|
||||
|
||||
try:
|
||||
QtGui.QGuiApplication.restoreOverrideCursor()
|
||||
except Exception as e:
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
self.storage = self.draw_app.storage
|
||||
|
@ -2457,8 +2499,7 @@ class FCExplode(FCShapeTool):
|
|||
|
||||
self.draw_app.active_tool = self
|
||||
if len(self.draw_app.get_selected()) == 0:
|
||||
self.draw_app.app.inform.emit('[WARNING_NOTCL] %s...' %
|
||||
_("No shape selected. Select a shape to explode"))
|
||||
self.draw_app.app.inform.emit('[WARNING_NOTCL] %s...' % ("No shape selected. Select a shape to explode"))
|
||||
else:
|
||||
self.make()
|
||||
|
||||
|
@ -2498,6 +2539,7 @@ class FCMove(FCShapeTool):
|
|||
def __init__(self, draw_app):
|
||||
FCShapeTool.__init__(self, draw_app)
|
||||
self.name = 'move'
|
||||
self.draw_app = draw_app
|
||||
|
||||
try:
|
||||
QtGui.QGuiApplication.restoreOverrideCursor()
|
||||
|
@ -2673,24 +2715,22 @@ class FCCopy(FCMove):
|
|||
self.geometry = [DrawToolShape(affinity.translate(geom.geo, xoff=dx, yoff=dy))
|
||||
for geom in self.draw_app.get_selected()]
|
||||
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."))
|
||||
|
||||
|
||||
class FCText(FCShapeTool):
|
||||
def __init__(self, draw_app):
|
||||
FCShapeTool.__init__(self, draw_app)
|
||||
self.name = 'text'
|
||||
self.draw_app = draw_app
|
||||
|
||||
try:
|
||||
QtGui.QGuiApplication.restoreOverrideCursor()
|
||||
except Exception:
|
||||
pass
|
||||
self.cursor = QtGui.QCursor(QtGui.QPixmap(self.app.resource_location + '/aero_text.png'))
|
||||
self.cursor = QtGui.QCursor(QtGui.QPixmap(self.draw_app.app.resource_location + '/aero_text.png'))
|
||||
QtGui.QGuiApplication.setOverrideCursor(self.cursor)
|
||||
|
||||
# self.shape_buffer = self.draw_app.shape_buffer
|
||||
self.draw_app = draw_app
|
||||
self.app = draw_app.app
|
||||
|
||||
self.draw_app.app.inform.emit(_("Click on 1st corner ..."))
|
||||
|
@ -2762,8 +2802,7 @@ class FCBuffer(FCShapeTool):
|
|||
|
||||
def on_buffer(self):
|
||||
if not self.draw_app.selected:
|
||||
self.app.inform.emit('[WARNING_NOTCL] %s' %
|
||||
_("Buffer cancelled. No shape selected."))
|
||||
self.app.inform.emit('[WARNING_NOTCL] %s' % _("Buffer cancelled. No shape selected."))
|
||||
return
|
||||
|
||||
try:
|
||||
|
@ -2876,6 +2915,7 @@ class FCEraser(FCShapeTool):
|
|||
def __init__(self, draw_app):
|
||||
DrawTool.__init__(self, draw_app)
|
||||
self.name = 'eraser'
|
||||
self.draw_app = draw_app
|
||||
|
||||
self.origin = None
|
||||
self.destination = None
|
||||
|
@ -2982,8 +3022,6 @@ class FCPaint(FCShapeTool):
|
|||
def __init__(self, draw_app):
|
||||
FCShapeTool.__init__(self, draw_app)
|
||||
self.name = 'paint'
|
||||
|
||||
# self.shape_buffer = self.draw_app.shape_buffer
|
||||
self.draw_app = draw_app
|
||||
self.app = draw_app.app
|
||||
|
||||
|
@ -2997,7 +3035,6 @@ class FCTransform(FCShapeTool):
|
|||
FCShapeTool.__init__(self, draw_app)
|
||||
self.name = 'transformation'
|
||||
|
||||
# self.shape_buffer = self.draw_app.shape_buffer
|
||||
self.draw_app = draw_app
|
||||
self.app = draw_app.app
|
||||
|
||||
|
@ -3798,6 +3835,7 @@ class FlatCAMGeoEditor(QtCore.QObject):
|
|||
|
||||
self.snap_x = x
|
||||
self.snap_y = y
|
||||
self.app.mouse = [x, y]
|
||||
|
||||
# update the position label in the infobar since the APP mouse event handlers are disconnected
|
||||
self.app.ui.position_label.setText(" <b>X</b>: %.4f "
|
||||
|
@ -3815,12 +3853,7 @@ class FlatCAMGeoEditor(QtCore.QObject):
|
|||
if event.button == 1 and event_is_dragging and isinstance(self.active_tool, FCEraser):
|
||||
pass
|
||||
else:
|
||||
# ### Utility geometry (animated) ###
|
||||
geo = self.active_tool.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)
|
||||
self.update_utility_geometry(data=(x, y))
|
||||
|
||||
# ### Selection area on canvas section ###
|
||||
dx = pos[0] - self.pos[0]
|
||||
|
@ -3837,6 +3870,14 @@ class FlatCAMGeoEditor(QtCore.QObject):
|
|||
else:
|
||||
self.app.selection_type = None
|
||||
|
||||
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_geo_click_release(self, event):
|
||||
if self.app.is_legacy is False:
|
||||
event_pos = event.pos
|
||||
|
|
|
@ -4530,13 +4530,7 @@ class FlatCAMGrbEditor(QtCore.QObject):
|
|||
self.app.ui.rel_position_label.setText("<b>Dx</b>: %.4f <b>Dy</b>: "
|
||||
"%.4f " % (dx, dy))
|
||||
|
||||
# # ## Utility geometry (animated)
|
||||
geo = self.active_tool.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)
|
||||
self.update_utility_geometry(data=(x, y))
|
||||
|
||||
# # ## Selection area on canvas section # ##
|
||||
if event_is_dragging == 1 and event.button == 1:
|
||||
|
@ -4558,6 +4552,15 @@ class FlatCAMGrbEditor(QtCore.QObject):
|
|||
else:
|
||||
self.app.selection_type = None
|
||||
|
||||
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 draw_utility_geometry(self, geo):
|
||||
if type(geo.geo) == list:
|
||||
for el in geo.geo:
|
||||
|
|
|
@ -8,6 +8,12 @@
|
|||
from flatcamGUI.GUIElements import *
|
||||
from PyQt5 import QtPrintSupport
|
||||
|
||||
from reportlab.platypus import SimpleDocTemplate, Paragraph
|
||||
from reportlab.lib.styles import getSampleStyleSheet
|
||||
from reportlab.lib.units import inch, mm
|
||||
|
||||
from io import StringIO
|
||||
|
||||
import gettext
|
||||
import FlatCAMTranslation as fcTranslate
|
||||
import builtins
|
||||
|
@ -217,9 +223,38 @@ class TextEditor(QtWidgets.QWidget):
|
|||
else:
|
||||
try:
|
||||
my_gcode = self.code_editor.toPlainText()
|
||||
with open(filename, 'w') as f:
|
||||
for line in my_gcode:
|
||||
f.write(line)
|
||||
if filename.rpartition('.')[2].lower() == 'pdf':
|
||||
page_size = (
|
||||
self.app.plotcanvas.pagesize_dict[self.app.defaults['global_workspaceT']][0] * mm,
|
||||
self.app.plotcanvas.pagesize_dict[self.app.defaults['global_workspaceT']][1] * mm
|
||||
)
|
||||
|
||||
# add new line after each line
|
||||
lined_gcode = my_gcode.replace("\n", "<br />")
|
||||
|
||||
styles = getSampleStyleSheet()
|
||||
styleN = styles['Normal']
|
||||
styleH = styles['Heading1']
|
||||
story = []
|
||||
|
||||
doc = SimpleDocTemplate(
|
||||
filename,
|
||||
pagesize=page_size,
|
||||
bottomMargin=0.4 * inch,
|
||||
topMargin=0.6 * inch,
|
||||
rightMargin=0.8 * inch,
|
||||
leftMargin=0.8 * inch)
|
||||
|
||||
P = Paragraph(lined_gcode, styleN)
|
||||
story.append(P)
|
||||
|
||||
doc.build(
|
||||
story,
|
||||
)
|
||||
else:
|
||||
with open(filename, 'w') as f:
|
||||
for line in my_gcode:
|
||||
f.write(line)
|
||||
except FileNotFoundError:
|
||||
self.app.inform.emit('[WARNING] %s' % _("No such file or directory"))
|
||||
return
|
||||
|
|
|
@ -21,8 +21,16 @@ import re
|
|||
import logging
|
||||
import html
|
||||
|
||||
import gettext
|
||||
import FlatCAMTranslation as fcTranslate
|
||||
import builtins
|
||||
|
||||
log = logging.getLogger('base')
|
||||
|
||||
fcTranslate.apply_language('strings')
|
||||
if '_' not in builtins.__dict__:
|
||||
_ = gettext.gettext
|
||||
|
||||
EDIT_SIZE_HINT = 70
|
||||
|
||||
|
||||
|
@ -624,7 +632,7 @@ class FCDoubleSpinner(QtWidgets.QDoubleSpinBox):
|
|||
# by default don't allow the minus sign to be entered as the default for QDoubleSpinBox is the positive range
|
||||
# between 0.00 and 99.00 (2 decimals)
|
||||
self.lineEdit().setValidator(
|
||||
QtGui.QRegExpValidator(QtCore.QRegExp("[0-9]*[.,]?[0-9]{%d}" % self.decimals()), self))
|
||||
QtGui.QRegExpValidator(QtCore.QRegExp("\+?[0-9]*[.,]?[0-9]{%d}" % self.decimals()), self))
|
||||
|
||||
if suffix:
|
||||
self.setSuffix(' %s' % str(suffix))
|
||||
|
@ -710,15 +718,15 @@ class FCDoubleSpinner(QtWidgets.QDoubleSpinBox):
|
|||
self.setDecimals(val)
|
||||
|
||||
# make sure that the user can't type more decimals than the set precision
|
||||
if self.minimum() < 0 or self.maximum() < 0:
|
||||
if self.minimum() < 0 or self.maximum() <= 0:
|
||||
self.lineEdit().setValidator(
|
||||
QtGui.QRegExpValidator(QtCore.QRegExp("-?[0-9]*[.,]?[0-9]{%d}" % self.decimals()), self))
|
||||
else:
|
||||
self.lineEdit().setValidator(
|
||||
QtGui.QRegExpValidator(QtCore.QRegExp("[0-9]*[.,]?[0-9]{%d}" % self.decimals()), self))
|
||||
QtGui.QRegExpValidator(QtCore.QRegExp("\+?[0-9]*[.,]?[0-9]{%d}" % self.decimals()), self))
|
||||
|
||||
def set_range(self, min_val, max_val):
|
||||
if min_val < 0 or max_val < 0:
|
||||
if min_val < 0 or max_val <= 0:
|
||||
self.lineEdit().setValidator(
|
||||
QtGui.QRegExpValidator(QtCore.QRegExp("-?[0-9]*[.,]?[0-9]{%d}" % self.decimals()), self))
|
||||
|
||||
|
@ -2230,6 +2238,72 @@ class Dialog_box(QtWidgets.QWidget):
|
|||
self.readyToEdit = True
|
||||
|
||||
|
||||
class DialogBoxRadio(QtWidgets.QDialog):
|
||||
def __init__(self, title=None, label=None, icon=None, initial_text=None):
|
||||
"""
|
||||
|
||||
:param title: string with the window title
|
||||
:param label: string with the message inside the dialog box
|
||||
"""
|
||||
super(DialogBoxRadio, self).__init__()
|
||||
if initial_text is None:
|
||||
self.location = str((0, 0))
|
||||
else:
|
||||
self.location = initial_text
|
||||
|
||||
self.ok = False
|
||||
|
||||
self.setWindowIcon(icon)
|
||||
self.setWindowTitle(str(title))
|
||||
|
||||
self.form = QtWidgets.QFormLayout(self)
|
||||
|
||||
self.form.addRow(QtWidgets.QLabel(''))
|
||||
|
||||
self.wdg_label = QtWidgets.QLabel('<b>%s</b>' % str(label))
|
||||
self.form.addRow(self.wdg_label)
|
||||
|
||||
self.ref_label = QtWidgets.QLabel('%s:' % _("Reference"))
|
||||
self.ref_label.setToolTip(
|
||||
_("The reference can be:\n"
|
||||
"- Absolute -> the reference point is point (0,0)\n"
|
||||
"- Relative -> the reference point is the mouse position before Jump")
|
||||
)
|
||||
self.ref_radio = RadioSet([
|
||||
{"label": _("Abs"), "value": "abs"},
|
||||
{"label": _("Relative"), "value": "rel"}
|
||||
], orientation='horizontal', stretch=False)
|
||||
self.ref_radio.set_value('abs')
|
||||
self.form.addRow(self.ref_label, self.ref_radio)
|
||||
|
||||
self.loc_label = QtWidgets.QLabel('<b>%s:</b>' % _("Location"))
|
||||
self.loc_label.setToolTip(
|
||||
_("The Location value is a tuple (x,y).\n"
|
||||
"If the reference is Absolute then the Jump will be at the position (x,y).\n"
|
||||
"If the reference is Relative then the Jump will be at the (x,y) distance\n"
|
||||
"from the current mouse location point.")
|
||||
)
|
||||
self.lineEdit = EvalEntry()
|
||||
self.lineEdit.setText(str(self.location).replace('(', '').replace(')', ''))
|
||||
self.form.addRow(self.loc_label, self.lineEdit)
|
||||
|
||||
self.button_box = QtWidgets.QDialogButtonBox(QtWidgets.QDialogButtonBox.Ok | QtWidgets.QDialogButtonBox.Cancel,
|
||||
Qt.Horizontal, parent=self)
|
||||
self.form.addRow(self.button_box)
|
||||
|
||||
self.button_box.accepted.connect(self.accept)
|
||||
self.button_box.rejected.connect(self.reject)
|
||||
|
||||
self.readyToEdit = True
|
||||
|
||||
if self.exec_() == QtWidgets.QDialog.Accepted:
|
||||
self.ok = True
|
||||
self.location = self.lineEdit.text()
|
||||
self.reference = self.ref_radio.get_value()
|
||||
else:
|
||||
self.ok = False
|
||||
|
||||
|
||||
class _BrowserTextEdit(QTextEdit):
|
||||
|
||||
def __init__(self, version):
|
||||
|
|
|
@ -348,7 +348,7 @@ class GerberObjectUI(ObjectUI):
|
|||
"below the copper surface.")
|
||||
)
|
||||
self.cutz_spinner = FCDoubleSpinner()
|
||||
self.cutz_spinner.set_range(-9999.9999, -0.0001)
|
||||
self.cutz_spinner.set_range(-9999.9999, 0.0000)
|
||||
self.cutz_spinner.set_precision(self.decimals)
|
||||
self.cutz_spinner.setSingleStep(0.1)
|
||||
self.cutz_spinner.setWrapping(True)
|
||||
|
@ -381,7 +381,7 @@ class GerberObjectUI(ObjectUI):
|
|||
)
|
||||
passlabel.setMinimumWidth(90)
|
||||
self.iso_width_entry = FCSpinner()
|
||||
self.iso_width_entry.setRange(1, 999)
|
||||
self.iso_width_entry.set_range(1, 999)
|
||||
grid1.addWidget(passlabel, 5, 0)
|
||||
grid1.addWidget(self.iso_width_entry, 5, 1, 1, 2)
|
||||
|
||||
|
@ -394,7 +394,7 @@ class GerberObjectUI(ObjectUI):
|
|||
self.iso_overlap_entry = FCDoubleSpinner(suffix='%')
|
||||
self.iso_overlap_entry.set_precision(self.decimals)
|
||||
self.iso_overlap_entry.setWrapping(True)
|
||||
self.iso_overlap_entry.setRange(0.0000, 99.9999)
|
||||
self.iso_overlap_entry.set_range(0.0000, 99.9999)
|
||||
self.iso_overlap_entry.setSingleStep(0.1)
|
||||
grid1.addWidget(overlabel, 6, 0)
|
||||
grid1.addWidget(self.iso_overlap_entry, 6, 1, 1, 2)
|
||||
|
@ -827,9 +827,9 @@ class ExcellonObjectUI(ObjectUI):
|
|||
self.cutz_entry.set_precision(self.decimals)
|
||||
|
||||
if machinist_setting == 0:
|
||||
self.cutz_entry.setRange(-9999.9999, -0.000001)
|
||||
self.cutz_entry.set_range(-9999.9999, 0.0000)
|
||||
else:
|
||||
self.cutz_entry.setRange(-9999.9999, 9999.9999)
|
||||
self.cutz_entry.set_range(-9999.9999, 9999.9999)
|
||||
|
||||
self.cutz_entry.setSingleStep(0.1)
|
||||
|
||||
|
@ -846,9 +846,9 @@ class ExcellonObjectUI(ObjectUI):
|
|||
self.travelz_entry.set_precision(self.decimals)
|
||||
|
||||
if machinist_setting == 0:
|
||||
self.travelz_entry.setRange(0.00001, 9999.9999)
|
||||
self.travelz_entry.set_range(0.00001, 9999.9999)
|
||||
else:
|
||||
self.travelz_entry.setRange(-9999.9999, 9999.9999)
|
||||
self.travelz_entry.set_range(-9999.9999, 9999.9999)
|
||||
|
||||
self.travelz_entry.setSingleStep(0.1)
|
||||
|
||||
|
@ -873,9 +873,9 @@ class ExcellonObjectUI(ObjectUI):
|
|||
self.toolchangez_entry.set_precision(self.decimals)
|
||||
|
||||
if machinist_setting == 0:
|
||||
self.toolchangez_entry.setRange(0.0, 9999.9999)
|
||||
self.toolchangez_entry.set_range(0.0, 9999.9999)
|
||||
else:
|
||||
self.toolchangez_entry.setRange(-9999.9999, 9999.9999)
|
||||
self.toolchangez_entry.set_range(-9999.9999, 9999.9999)
|
||||
|
||||
self.toolchangez_entry.setSingleStep(0.1)
|
||||
|
||||
|
@ -883,7 +883,7 @@ class ExcellonObjectUI(ObjectUI):
|
|||
self.ois_tcz_e = OptionalInputSection(self.toolchange_cb, [self.toolchangez_entry])
|
||||
|
||||
# Start move Z:
|
||||
self.estartz_label = QtWidgets.QLabel('%s:' % _("Start move Z"))
|
||||
self.estartz_label = QtWidgets.QLabel('%s:' % _("Start Z"))
|
||||
self.estartz_label.setToolTip(
|
||||
_("Height of the tool just after start.\n"
|
||||
"Delete the value if you don't need this feature.")
|
||||
|
@ -903,9 +903,9 @@ class ExcellonObjectUI(ObjectUI):
|
|||
self.eendz_entry.set_precision(self.decimals)
|
||||
|
||||
if machinist_setting == 0:
|
||||
self.eendz_entry.setRange(0.0, 9999.9999)
|
||||
self.eendz_entry.set_range(0.0, 9999.9999)
|
||||
else:
|
||||
self.eendz_entry.setRange(-9999.9999, 9999.9999)
|
||||
self.eendz_entry.set_range(-9999.9999, 9999.9999)
|
||||
|
||||
self.eendz_entry.setSingleStep(0.1)
|
||||
|
||||
|
@ -922,7 +922,7 @@ class ExcellonObjectUI(ObjectUI):
|
|||
grid1.addWidget(frlabel, 6, 0)
|
||||
self.feedrate_entry = FCDoubleSpinner()
|
||||
self.feedrate_entry.set_precision(self.decimals)
|
||||
self.feedrate_entry.setRange(0.0, 9999.9999)
|
||||
self.feedrate_entry.set_range(0.0, 9999.9999)
|
||||
self.feedrate_entry.setSingleStep(0.1)
|
||||
|
||||
grid1.addWidget(self.feedrate_entry, 6, 1)
|
||||
|
@ -939,7 +939,7 @@ class ExcellonObjectUI(ObjectUI):
|
|||
grid1.addWidget(self.feedrate_rapid_label, 7, 0)
|
||||
self.feedrate_rapid_entry = FCDoubleSpinner()
|
||||
self.feedrate_rapid_entry.set_precision(self.decimals)
|
||||
self.feedrate_rapid_entry.setRange(0.0, 9999.9999)
|
||||
self.feedrate_rapid_entry.set_range(0.0, 9999.9999)
|
||||
self.feedrate_rapid_entry.setSingleStep(0.1)
|
||||
|
||||
grid1.addWidget(self.feedrate_rapid_entry, 7, 1)
|
||||
|
@ -967,7 +967,7 @@ class ExcellonObjectUI(ObjectUI):
|
|||
)
|
||||
self.dwelltime_entry = FCDoubleSpinner()
|
||||
self.dwelltime_entry.set_precision(self.decimals)
|
||||
self.dwelltime_entry.setRange(0.0, 9999.9999)
|
||||
self.dwelltime_entry.set_range(0.0, 9999.9999)
|
||||
self.dwelltime_entry.setSingleStep(0.1)
|
||||
|
||||
self.dwelltime_entry.setToolTip(
|
||||
|
@ -998,7 +998,7 @@ class ExcellonObjectUI(ObjectUI):
|
|||
grid1.addWidget(self.pdepth_label, 11, 0)
|
||||
self.pdepth_entry = FCDoubleSpinner()
|
||||
self.pdepth_entry.set_precision(self.decimals)
|
||||
self.pdepth_entry.setRange(-9999.9999, 9999.9999)
|
||||
self.pdepth_entry.set_range(-9999.9999, 9999.9999)
|
||||
self.pdepth_entry.setSingleStep(0.1)
|
||||
|
||||
grid1.addWidget(self.pdepth_entry, 11, 1)
|
||||
|
@ -1013,7 +1013,7 @@ class ExcellonObjectUI(ObjectUI):
|
|||
|
||||
self.feedrate_probe_entry = FCDoubleSpinner()
|
||||
self.feedrate_probe_entry.set_precision(self.decimals)
|
||||
self.feedrate_probe_entry.setRange(0.0, 9999.9999)
|
||||
self.feedrate_probe_entry.set_range(0.0, 9999.9999)
|
||||
self.feedrate_probe_entry.setSingleStep(0.1)
|
||||
|
||||
grid1.addWidget(self.feedrate_probe_label, 12, 0)
|
||||
|
@ -1077,7 +1077,7 @@ class ExcellonObjectUI(ObjectUI):
|
|||
)
|
||||
self.tooldia_entry = FCDoubleSpinner()
|
||||
self.tooldia_entry.set_precision(self.decimals)
|
||||
self.tooldia_entry.setRange(0.0, 9999.9999)
|
||||
self.tooldia_entry.set_range(0.0, 9999.9999)
|
||||
self.tooldia_entry.setSingleStep(0.1)
|
||||
|
||||
self.generate_milling_button = QtWidgets.QPushButton(_('Mill Drills Geo'))
|
||||
|
@ -1104,7 +1104,7 @@ class ExcellonObjectUI(ObjectUI):
|
|||
|
||||
self.slot_tooldia_entry = FCDoubleSpinner()
|
||||
self.slot_tooldia_entry.set_precision(self.decimals)
|
||||
self.slot_tooldia_entry.setRange(0.0, 9999.9999)
|
||||
self.slot_tooldia_entry.set_range(0.0, 9999.9999)
|
||||
self.slot_tooldia_entry.setSingleStep(0.1)
|
||||
|
||||
self.generate_milling_slots_button = QtWidgets.QPushButton(_('Mill Slots Geo'))
|
||||
|
@ -1286,7 +1286,7 @@ class GeometryObjectUI(ObjectUI):
|
|||
)
|
||||
self.tool_offset_entry = FCDoubleSpinner()
|
||||
self.tool_offset_entry.set_precision(self.decimals)
|
||||
self.tool_offset_entry.setRange(-9999.9999, 9999.9999)
|
||||
self.tool_offset_entry.set_range(-9999.9999, 9999.9999)
|
||||
self.tool_offset_entry.setSingleStep(0.1)
|
||||
|
||||
self.grid1.addWidget(self.tool_offset_lbl, 0, 0)
|
||||
|
@ -1298,7 +1298,7 @@ class GeometryObjectUI(ObjectUI):
|
|||
)
|
||||
self.addtool_entry = FCDoubleSpinner()
|
||||
self.addtool_entry.set_precision(self.decimals)
|
||||
self.addtool_entry.setRange(0.00001, 9999.9999)
|
||||
self.addtool_entry.set_range(0.00001, 9999.9999)
|
||||
self.addtool_entry.setSingleStep(0.1)
|
||||
|
||||
self.addtool_btn = QtWidgets.QPushButton(_('Add'))
|
||||
|
@ -1379,7 +1379,7 @@ class GeometryObjectUI(ObjectUI):
|
|||
)
|
||||
self.tipdia_entry = FCDoubleSpinner()
|
||||
self.tipdia_entry.set_precision(self.decimals)
|
||||
self.tipdia_entry.setRange(0.00001, 9999.9999)
|
||||
self.tipdia_entry.set_range(0.00001, 9999.9999)
|
||||
self.tipdia_entry.setSingleStep(0.1)
|
||||
|
||||
self.grid3.addWidget(self.tipdialabel, 1, 0)
|
||||
|
@ -1395,7 +1395,7 @@ class GeometryObjectUI(ObjectUI):
|
|||
)
|
||||
self.tipangle_entry = FCDoubleSpinner()
|
||||
self.tipangle_entry.set_precision(self.decimals)
|
||||
self.tipangle_entry.setRange(0.0, 180.0)
|
||||
self.tipangle_entry.set_range(0.0, 180.0)
|
||||
self.tipangle_entry.setSingleStep(1)
|
||||
|
||||
self.grid3.addWidget(self.tipanglelabel, 2, 0)
|
||||
|
@ -1413,9 +1413,9 @@ class GeometryObjectUI(ObjectUI):
|
|||
self.cutz_entry.set_precision(self.decimals)
|
||||
|
||||
if machinist_setting == 0:
|
||||
self.cutz_entry.setRange(-9999.9999, -0.00001)
|
||||
self.cutz_entry.set_range(-9999.9999, 0.0000)
|
||||
else:
|
||||
self.cutz_entry.setRange(-9999.9999, 9999.9999)
|
||||
self.cutz_entry.set_range(-9999.9999, 9999.9999)
|
||||
|
||||
self.cutz_entry.setSingleStep(0.1)
|
||||
|
||||
|
@ -1435,7 +1435,7 @@ class GeometryObjectUI(ObjectUI):
|
|||
|
||||
self.maxdepth_entry = FCDoubleSpinner()
|
||||
self.maxdepth_entry.set_precision(self.decimals)
|
||||
self.maxdepth_entry.setRange(0, 9999.9999)
|
||||
self.maxdepth_entry.set_range(0, 9999.9999)
|
||||
self.maxdepth_entry.setSingleStep(0.1)
|
||||
|
||||
self.maxdepth_entry.setToolTip(
|
||||
|
@ -1458,9 +1458,9 @@ class GeometryObjectUI(ObjectUI):
|
|||
self.travelz_entry.set_precision(self.decimals)
|
||||
|
||||
if machinist_setting == 0:
|
||||
self.travelz_entry.setRange(0.00001, 9999.9999)
|
||||
self.travelz_entry.set_range(0.00001, 9999.9999)
|
||||
else:
|
||||
self.travelz_entry.setRange(-9999.9999, 9999.9999)
|
||||
self.travelz_entry.set_range(-9999.9999, 9999.9999)
|
||||
|
||||
self.travelz_entry.setSingleStep(0.1)
|
||||
|
||||
|
@ -1486,9 +1486,9 @@ class GeometryObjectUI(ObjectUI):
|
|||
self.toolchangez_entry.set_precision(self.decimals)
|
||||
|
||||
if machinist_setting == 0:
|
||||
self.toolchangez_entry.setRange(0, 9999.9999)
|
||||
self.toolchangez_entry.set_range(0, 9999.9999)
|
||||
else:
|
||||
self.toolchangez_entry.setRange(-9999.9999, 9999.9999)
|
||||
self.toolchangez_entry.set_range(-9999.9999, 9999.9999)
|
||||
|
||||
self.toolchangez_entry.setSingleStep(0.1)
|
||||
|
||||
|
@ -1518,9 +1518,9 @@ class GeometryObjectUI(ObjectUI):
|
|||
self.gendz_entry.set_precision(self.decimals)
|
||||
|
||||
if machinist_setting == 0:
|
||||
self.gendz_entry.setRange(0, 9999.9999)
|
||||
self.gendz_entry.set_range(0, 9999.9999)
|
||||
else:
|
||||
self.gendz_entry.setRange(-9999.9999, 9999.9999)
|
||||
self.gendz_entry.set_range(-9999.9999, 9999.9999)
|
||||
|
||||
self.gendz_entry.setSingleStep(0.1)
|
||||
|
||||
|
@ -1535,7 +1535,7 @@ class GeometryObjectUI(ObjectUI):
|
|||
)
|
||||
self.cncfeedrate_entry = FCDoubleSpinner()
|
||||
self.cncfeedrate_entry.set_precision(self.decimals)
|
||||
self.cncfeedrate_entry.setRange(0, 9999.9999)
|
||||
self.cncfeedrate_entry.set_range(0, 9999.9999)
|
||||
self.cncfeedrate_entry.setSingleStep(0.1)
|
||||
|
||||
self.grid3.addWidget(frlabel, 10, 0)
|
||||
|
@ -1550,7 +1550,7 @@ class GeometryObjectUI(ObjectUI):
|
|||
)
|
||||
self.cncplunge_entry = FCDoubleSpinner()
|
||||
self.cncplunge_entry.set_precision(self.decimals)
|
||||
self.cncplunge_entry.setRange(0, 9999.9999)
|
||||
self.cncplunge_entry.set_range(0, 9999.9999)
|
||||
self.cncplunge_entry.setSingleStep(0.1)
|
||||
|
||||
self.grid3.addWidget(frzlabel, 11, 0)
|
||||
|
@ -1567,7 +1567,7 @@ class GeometryObjectUI(ObjectUI):
|
|||
)
|
||||
self.cncfeedrate_rapid_entry = FCDoubleSpinner()
|
||||
self.cncfeedrate_rapid_entry.set_precision(self.decimals)
|
||||
self.cncfeedrate_rapid_entry.setRange(0, 9999.9999)
|
||||
self.cncfeedrate_rapid_entry.set_range(0, 9999.9999)
|
||||
self.cncfeedrate_rapid_entry.setSingleStep(0.1)
|
||||
|
||||
self.grid3.addWidget(self.fr_rapidlabel, 12, 0)
|
||||
|
@ -1627,7 +1627,7 @@ class GeometryObjectUI(ObjectUI):
|
|||
)
|
||||
self.dwelltime_entry = FCDoubleSpinner()
|
||||
self.dwelltime_entry.set_precision(self.decimals)
|
||||
self.dwelltime_entry.setRange(0, 9999.9999)
|
||||
self.dwelltime_entry.set_range(0, 9999.9999)
|
||||
self.dwelltime_entry.setSingleStep(0.1)
|
||||
|
||||
self.dwelltime_entry.setToolTip(
|
||||
|
@ -1658,7 +1658,7 @@ class GeometryObjectUI(ObjectUI):
|
|||
)
|
||||
self.pdepth_entry = FCDoubleSpinner()
|
||||
self.pdepth_entry.set_precision(self.decimals)
|
||||
self.pdepth_entry.setRange(-9999.9999, 9999.9999)
|
||||
self.pdepth_entry.set_range(-9999.9999, 9999.9999)
|
||||
self.pdepth_entry.setSingleStep(0.1)
|
||||
|
||||
self.grid3.addWidget(self.pdepth_label, 17, 0)
|
||||
|
@ -1674,7 +1674,7 @@ class GeometryObjectUI(ObjectUI):
|
|||
)
|
||||
self.feedrate_probe_entry = FCDoubleSpinner()
|
||||
self.feedrate_probe_entry.set_precision(self.decimals)
|
||||
self.feedrate_probe_entry.setRange(0.0, 9999.9999)
|
||||
self.feedrate_probe_entry.set_range(0.0, 9999.9999)
|
||||
self.feedrate_probe_entry.setSingleStep(0.1)
|
||||
|
||||
self.grid3.addWidget(self.feedrate_probe_label, 18, 0)
|
||||
|
|
|
@ -1682,7 +1682,7 @@ class GerberAdvOptPrefGroupUI(OptionsGroupUI):
|
|||
)
|
||||
self.cutz_spinner = FCDoubleSpinner()
|
||||
self.cutz_spinner.set_precision(self.decimals)
|
||||
self.cutz_spinner.set_range(-99.9999, -0.0001)
|
||||
self.cutz_spinner.set_range(-99.9999, 0.0000)
|
||||
self.cutz_spinner.setSingleStep(0.1)
|
||||
self.cutz_spinner.setWrapping(True)
|
||||
|
||||
|
@ -2352,7 +2352,7 @@ class ExcellonOptPrefGroupUI(OptionsGroupUI):
|
|||
self.cutz_entry = FCDoubleSpinner()
|
||||
|
||||
if machinist_setting == 0:
|
||||
self.cutz_entry.set_range(-9999.9999, -0.000001)
|
||||
self.cutz_entry.set_range(-9999.9999, 0.0000)
|
||||
else:
|
||||
self.cutz_entry.set_range(-9999.9999, 9999.9999)
|
||||
|
||||
|
@ -2584,7 +2584,7 @@ class ExcellonAdvOptPrefGroupUI(OptionsGroupUI):
|
|||
self.toolchangexy_entry = FCEntry()
|
||||
grid1.addWidget(self.toolchangexy_entry, 1, 1)
|
||||
|
||||
startzlabel = QtWidgets.QLabel('%s:' % _('Start move Z'))
|
||||
startzlabel = QtWidgets.QLabel('%s:' % _('Start Z'))
|
||||
startzlabel.setToolTip(
|
||||
_("Height of the tool just after start.\n"
|
||||
"Delete the value if you don't need this feature.")
|
||||
|
@ -2617,7 +2617,7 @@ class ExcellonAdvOptPrefGroupUI(OptionsGroupUI):
|
|||
)
|
||||
self.pdepth_entry = FCDoubleSpinner()
|
||||
self.pdepth_entry.set_precision(self.decimals)
|
||||
self.pdepth_entry.set_range(-99999, -0.000001)
|
||||
self.pdepth_entry.set_range(-99999.9999, 0.0000)
|
||||
|
||||
grid1.addWidget(self.pdepth_label, 4, 0)
|
||||
grid1.addWidget(self.pdepth_entry, 4, 1)
|
||||
|
@ -3196,7 +3196,7 @@ class GeometryOptPrefGroupUI(OptionsGroupUI):
|
|||
self.cutz_entry = FCDoubleSpinner()
|
||||
|
||||
if machinist_setting == 0:
|
||||
self.cutz_entry.set_range(-9999.9999, -0.000001)
|
||||
self.cutz_entry.set_range(-9999.9999, 0.0000)
|
||||
else:
|
||||
self.cutz_entry.set_range(-9999.9999, 9999.9999)
|
||||
|
||||
|
@ -3429,7 +3429,7 @@ class GeometryAdvOptPrefGroupUI(OptionsGroupUI):
|
|||
grid1.addWidget(self.toolchangexy_entry, 1, 1)
|
||||
|
||||
# Start move Z
|
||||
startzlabel = QtWidgets.QLabel('%s:' % _('Start move Z'))
|
||||
startzlabel = QtWidgets.QLabel('%s:' % _('Start Z'))
|
||||
startzlabel.setToolTip(
|
||||
_("Height of the tool just after starting the work.\n"
|
||||
"Delete the value if you don't need this feature.")
|
||||
|
@ -3486,7 +3486,7 @@ class GeometryAdvOptPrefGroupUI(OptionsGroupUI):
|
|||
"to probe. Negative value, in current units.")
|
||||
)
|
||||
self.pdepth_entry = FCDoubleSpinner()
|
||||
self.pdepth_entry.set_range(-99999, -0.000001)
|
||||
self.pdepth_entry.set_range(-99999, 0.0000)
|
||||
self.pdepth_entry.set_precision(self.decimals)
|
||||
self.pdepth_entry.setSingleStep(0.1)
|
||||
self.pdepth_entry.setWrapping(True)
|
||||
|
@ -4052,7 +4052,7 @@ class ToolsNCCPrefGroupUI(OptionsGroupUI):
|
|||
)
|
||||
self.cutz_entry = FCDoubleSpinner()
|
||||
self.cutz_entry.set_precision(self.decimals)
|
||||
self.cutz_entry.set_range(-9999.9999, -0.000001)
|
||||
self.cutz_entry.set_range(-9999.9999, 0.0000)
|
||||
self.cutz_entry.setSingleStep(0.1)
|
||||
|
||||
self.cutz_entry.setToolTip(
|
||||
|
@ -4310,7 +4310,7 @@ class ToolsCutoutPrefGroupUI(OptionsGroupUI):
|
|||
self.cutz_entry.set_precision(self.decimals)
|
||||
|
||||
if machinist_setting == 0:
|
||||
self.cutz_entry.setRange(-9999.9999, -0.00001)
|
||||
self.cutz_entry.setRange(-9999.9999, 0.0000)
|
||||
else:
|
||||
self.cutz_entry.setRange(-9999.9999, 9999.9999)
|
||||
|
||||
|
@ -5119,7 +5119,7 @@ class ToolsCalculatorsPrefGroupUI(OptionsGroupUI):
|
|||
|
||||
# ## Depth-of-cut Cut Z
|
||||
self.cut_z_entry = FCDoubleSpinner()
|
||||
self.cut_z_entry.set_range(-9999.9999, -0.00001)
|
||||
self.cut_z_entry.set_range(-9999.9999, 0.0000)
|
||||
self.cut_z_entry.set_precision(self.decimals)
|
||||
self.cut_z_entry.setSingleStep(0.01)
|
||||
|
||||
|
|
|
@ -111,9 +111,9 @@ class HPGL2:
|
|||
self.initialize_re = re.compile(r'^(IN);?$')
|
||||
|
||||
# Absolute linear interpolation
|
||||
self.abs_move_re = re.compile(r"^PA\s*(-?\d+\.?\d+?),?\s*(-?\d+\.?\d+?)*;?$")
|
||||
self.abs_move_re = re.compile(r"^PA\s*(-?\d+\.?\d*),?\s*(-?\d+\.?\d*)*;?$")
|
||||
# Relative linear interpolation
|
||||
self.rel_move_re = re.compile(r"^PR\s*(-?\d+\.\d+?),?\s*(-?\d+\.\d+?)*;?$")
|
||||
self.rel_move_re = re.compile(r"^PR\s*(-?\d+\.?\d*),?\s*(-?\d+\.?\d*)*;?$")
|
||||
|
||||
# Circular interpolation with radius
|
||||
self.circ_re = re.compile(r"^CI\s*(\+?\d+\.?\d+?)?\s*;?\s*$")
|
||||
|
|
|
@ -258,7 +258,7 @@ class NonCopperClear(FlatCAMTool, Gerber):
|
|||
)
|
||||
self.cutz_entry = FCDoubleSpinner()
|
||||
self.cutz_entry.set_precision(self.decimals)
|
||||
self.cutz_entry.set_range(-99999, -0.00000000000001)
|
||||
self.cutz_entry.set_range(-99999.9999, 0.0000)
|
||||
|
||||
self.cutz_entry.setToolTip(
|
||||
_("Depth of cut into material. Negative value.\n"
|
||||
|
@ -1810,8 +1810,43 @@ class NonCopperClear(FlatCAMTool, Gerber):
|
|||
if self.app.abort_flag:
|
||||
# graceful abort requested by the user
|
||||
raise FlatCAMApp.GracefulException
|
||||
if p is not None:
|
||||
|
||||
# clean the polygon
|
||||
p = p.buffer(0)
|
||||
|
||||
if p is not None and p.is_valid:
|
||||
poly_processed = list()
|
||||
try:
|
||||
for pol in p:
|
||||
if pol is not None and isinstance(pol, Polygon):
|
||||
if ncc_method == 'standard':
|
||||
cp = self.clear_polygon(pol, tool,
|
||||
self.grb_circle_steps,
|
||||
overlap=overlap, contour=contour,
|
||||
connect=connect,
|
||||
prog_plot=prog_plot)
|
||||
elif ncc_method == 'seed':
|
||||
cp = self.clear_polygon2(pol, tool,
|
||||
self.grb_circle_steps,
|
||||
overlap=overlap, contour=contour,
|
||||
connect=connect,
|
||||
prog_plot=prog_plot)
|
||||
else:
|
||||
cp = self.clear_polygon3(pol, tool,
|
||||
self.grb_circle_steps,
|
||||
overlap=overlap, contour=contour,
|
||||
connect=connect,
|
||||
prog_plot=prog_plot)
|
||||
if cp:
|
||||
cleared_geo += list(cp.get_objects())
|
||||
poly_processed.append(True)
|
||||
else:
|
||||
poly_processed.append(False)
|
||||
log.warning("Polygon in MultiPolygon can not be cleared.")
|
||||
else:
|
||||
log.warning("Geo in Iterable can not be cleared beacuse it is not Polygon. "
|
||||
"It is: %s" % str(type(pol)))
|
||||
except TypeError:
|
||||
if isinstance(p, Polygon):
|
||||
if ncc_method == 'standard':
|
||||
cp = self.clear_polygon(p, tool, self.grb_circle_steps,
|
||||
|
@ -1827,32 +1862,20 @@ class NonCopperClear(FlatCAMTool, Gerber):
|
|||
prog_plot=prog_plot)
|
||||
if cp:
|
||||
cleared_geo += list(cp.get_objects())
|
||||
elif isinstance(p, MultiPolygon):
|
||||
for pol in p:
|
||||
if pol is not None:
|
||||
if ncc_method == 'standard':
|
||||
cp = self.clear_polygon(pol, tool,
|
||||
self.grb_circle_steps,
|
||||
overlap=overlap, contour=contour,
|
||||
connect=connect,
|
||||
prog_plot=prog_plot)
|
||||
elif ncc_method == 'seed':
|
||||
cp = self.clear_polygon2(pol, tool,
|
||||
self.grb_circle_steps,
|
||||
overlap=overlap, contour=contour,
|
||||
connect=connect,
|
||||
prog_plot=prog_plot)
|
||||
else:
|
||||
cp = self.clear_polygon3(pol, tool,
|
||||
self.grb_circle_steps,
|
||||
overlap=overlap, contour=contour,
|
||||
connect=connect,
|
||||
prog_plot=prog_plot)
|
||||
if cp:
|
||||
cleared_geo += list(cp.get_objects())
|
||||
except Exception as e:
|
||||
log.warning("Polygon can not be cleared. %s" % str(e))
|
||||
poly_processed.append(True)
|
||||
else:
|
||||
poly_processed.append(False)
|
||||
log.warning("Polygon can not be cleared.")
|
||||
else:
|
||||
log.warning("Geo can not be cleared because it is: %s" % str(type(p)))
|
||||
|
||||
p_cleared = poly_processed.count(True)
|
||||
p_not_cleared = poly_processed.count(False)
|
||||
|
||||
if p_not_cleared:
|
||||
app_obj.poly_not_cleared = True
|
||||
|
||||
if p_cleared == 0:
|
||||
continue
|
||||
|
||||
pol_nr += 1
|
||||
|
@ -2182,7 +2205,10 @@ class NonCopperClear(FlatCAMTool, Gerber):
|
|||
# graceful abort requested by the user
|
||||
raise FlatCAMApp.GracefulException
|
||||
|
||||
if p is not None:
|
||||
# clean the polygon
|
||||
p = p.buffer(0)
|
||||
|
||||
if p is not None and p.is_valid:
|
||||
# provide the app with a way to process the GUI events when in a blocking loop
|
||||
QtWidgets.QApplication.processEvents()
|
||||
|
||||
|
|
|
@ -1450,8 +1450,7 @@ class ToolPaint(FlatCAMTool, Gerber):
|
|||
geo_obj.solid_geometry += list(cpoly.get_objects())
|
||||
return cpoly
|
||||
else:
|
||||
app_obj.inform.emit('[ERROR_NOTCL] %s' %
|
||||
_('Geometry could not be painted completely'))
|
||||
app_obj.inform.emit('[ERROR_NOTCL] %s' % _('Geometry could not be painted completely'))
|
||||
return None
|
||||
|
||||
current_uid = int(1)
|
||||
|
@ -1769,62 +1768,162 @@ class ToolPaint(FlatCAMTool, Gerber):
|
|||
|
||||
pol_nr = 0
|
||||
for geo in painted_area:
|
||||
try:
|
||||
# Polygons are the only really paintable geometries, lines in theory have no area to be painted
|
||||
if not isinstance(geo, Polygon):
|
||||
|
||||
# provide the app with a way to process the GUI events when in a blocking loop
|
||||
QtWidgets.QApplication.processEvents()
|
||||
|
||||
if self.app.abort_flag:
|
||||
# graceful abort requested by the user
|
||||
raise FlatCAMApp.GracefulException
|
||||
|
||||
# try to clean the Polygon but it may result into a MultiPolygon
|
||||
geo = geo.buffer(0)
|
||||
poly_buf = geo.buffer(-paint_margin)
|
||||
|
||||
if geo is not None and geo.is_valid:
|
||||
poly_processed = list()
|
||||
try:
|
||||
for pol in poly_buf:
|
||||
if pol is not None and isinstance(pol, Polygon):
|
||||
if paint_method == 'standard':
|
||||
cp = self.clear_polygon(pol,
|
||||
tooldia=tool_dia,
|
||||
steps_per_circle=self.app.defaults[
|
||||
"geometry_circle_steps"],
|
||||
overlap=over,
|
||||
contour=cont,
|
||||
connect=conn,
|
||||
prog_plot=prog_plot)
|
||||
elif paint_method == 'seed':
|
||||
cp = self.clear_polygon2(pol,
|
||||
tooldia=tool_dia,
|
||||
steps_per_circle=self.app.defaults[
|
||||
"geometry_circle_steps"],
|
||||
overlap=over,
|
||||
contour=cont,
|
||||
connect=conn,
|
||||
prog_plot=prog_plot)
|
||||
else:
|
||||
cp = self.clear_polygon3(pol,
|
||||
tooldia=tool_dia,
|
||||
steps_per_circle=self.app.defaults[
|
||||
"geometry_circle_steps"],
|
||||
overlap=over,
|
||||
contour=cont,
|
||||
connect=conn,
|
||||
prog_plot=prog_plot)
|
||||
if cp:
|
||||
total_geometry += list(cp.get_objects())
|
||||
poly_processed.append(True)
|
||||
else:
|
||||
poly_processed.append(False)
|
||||
log.warning("Polygon in MultiPolygon can not be cleared.")
|
||||
else:
|
||||
log.warning("Geo in Iterable can not be cleared because it is not Polygon. "
|
||||
"It is: %s" % str(type(pol)))
|
||||
except TypeError:
|
||||
if isinstance(poly_buf, Polygon):
|
||||
if paint_method == 'standard':
|
||||
cp = self.clear_polygon(poly_buf,
|
||||
tooldia=tool_dia,
|
||||
steps_per_circle=self.app.defaults[
|
||||
"geometry_circle_steps"],
|
||||
overlap=over,
|
||||
contour=cont,
|
||||
connect=conn,
|
||||
prog_plot=prog_plot)
|
||||
elif paint_method == 'seed':
|
||||
cp = self.clear_polygon2(poly_buf,
|
||||
tooldia=tool_dia,
|
||||
steps_per_circle=self.app.defaults[
|
||||
"geometry_circle_steps"],
|
||||
overlap=over,
|
||||
contour=cont,
|
||||
connect=conn,
|
||||
prog_plot=prog_plot)
|
||||
else:
|
||||
cp = self.clear_polygon3(poly_buf,
|
||||
tooldia=tool_dia,
|
||||
steps_per_circle=self.app.defaults[
|
||||
"geometry_circle_steps"],
|
||||
overlap=over,
|
||||
contour=cont,
|
||||
connect=conn,
|
||||
prog_plot=prog_plot)
|
||||
if cp:
|
||||
total_geometry += list(cp.get_objects())
|
||||
poly_processed.append(True)
|
||||
else:
|
||||
poly_processed.append(False)
|
||||
log.warning("Polygon can not be cleared.")
|
||||
else:
|
||||
log.warning("Geo can not be cleared because it is: %s" % str(type(poly_buf)))
|
||||
|
||||
p_cleared = poly_processed.count(True)
|
||||
p_not_cleared = poly_processed.count(False)
|
||||
|
||||
if p_not_cleared:
|
||||
app_obj.poly_not_cleared = True
|
||||
|
||||
if p_cleared == 0:
|
||||
continue
|
||||
poly_buf = geo.buffer(-paint_margin)
|
||||
|
||||
if paint_method == "seed":
|
||||
# Type(cp) == FlatCAMRTreeStorage | None
|
||||
cp = self.clear_polygon2(poly_buf,
|
||||
tooldia=tool_dia,
|
||||
steps_per_circle=self.app.defaults["geometry_circle_steps"],
|
||||
overlap=over,
|
||||
contour=cont,
|
||||
connect=conn,
|
||||
prog_plot=prog_plot)
|
||||
# try:
|
||||
# # Polygons are the only really paintable geometries, lines in theory have no area to be painted
|
||||
# if not isinstance(geo, Polygon):
|
||||
# continue
|
||||
# poly_buf = geo.buffer(-paint_margin)
|
||||
#
|
||||
# if paint_method == "seed":
|
||||
# # Type(cp) == FlatCAMRTreeStorage | None
|
||||
# cp = self.clear_polygon2(poly_buf,
|
||||
# tooldia=tool_dia,
|
||||
# steps_per_circle=self.app.defaults["geometry_circle_steps"],
|
||||
# overlap=over,
|
||||
# contour=cont,
|
||||
# connect=conn,
|
||||
# prog_plot=prog_plot)
|
||||
#
|
||||
# elif paint_method == "lines":
|
||||
# # Type(cp) == FlatCAMRTreeStorage | None
|
||||
# cp = self.clear_polygon3(poly_buf,
|
||||
# tooldia=tool_dia,
|
||||
# steps_per_circle=self.app.defaults["geometry_circle_steps"],
|
||||
# overlap=over,
|
||||
# contour=cont,
|
||||
# connect=conn,
|
||||
# prog_plot=prog_plot)
|
||||
#
|
||||
# else:
|
||||
# # Type(cp) == FlatCAMRTreeStorage | None
|
||||
# cp = self.clear_polygon(poly_buf,
|
||||
# tooldia=tool_dia,
|
||||
# steps_per_circle=self.app.defaults["geometry_circle_steps"],
|
||||
# overlap=over,
|
||||
# contour=cont,
|
||||
# connect=conn,
|
||||
# prog_plot=prog_plot)
|
||||
#
|
||||
# if cp is not None:
|
||||
# total_geometry += list(cp.get_objects())
|
||||
# except FlatCAMApp.GracefulException:
|
||||
# return "fail"
|
||||
# except Exception as e:
|
||||
# log.debug("Could not Paint the polygons. %s" % str(e))
|
||||
# self.app.inform.emit('[ERROR] %s\n%s' %
|
||||
# (_("Could not do Paint All. Try a different combination of parameters. "
|
||||
# "Or a different Method of paint"),
|
||||
# str(e)))
|
||||
# return "fail"
|
||||
|
||||
elif paint_method == "lines":
|
||||
# Type(cp) == FlatCAMRTreeStorage | None
|
||||
cp = self.clear_polygon3(poly_buf,
|
||||
tooldia=tool_dia,
|
||||
steps_per_circle=self.app.defaults["geometry_circle_steps"],
|
||||
overlap=over,
|
||||
contour=cont,
|
||||
connect=conn,
|
||||
prog_plot=prog_plot)
|
||||
pol_nr += 1
|
||||
disp_number = int(np.interp(pol_nr, [0, geo_len], [0, 100]))
|
||||
# log.debug("Polygons cleared: %d" % pol_nr)
|
||||
|
||||
else:
|
||||
# Type(cp) == FlatCAMRTreeStorage | None
|
||||
cp = self.clear_polygon(poly_buf,
|
||||
tooldia=tool_dia,
|
||||
steps_per_circle=self.app.defaults["geometry_circle_steps"],
|
||||
overlap=over,
|
||||
contour=cont,
|
||||
connect=conn,
|
||||
prog_plot=prog_plot)
|
||||
|
||||
if cp is not None:
|
||||
total_geometry += list(cp.get_objects())
|
||||
except FlatCAMApp.GracefulException:
|
||||
return "fail"
|
||||
except Exception as e:
|
||||
log.debug("Could not Paint the polygons. %s" % str(e))
|
||||
self.app.inform.emit('[ERROR] %s\n%s' %
|
||||
(_("Could not do Paint All. Try a different combination of parameters. "
|
||||
"Or a different Method of paint"),
|
||||
str(e)))
|
||||
return "fail"
|
||||
|
||||
pol_nr += 1
|
||||
disp_number = int(np.interp(pol_nr, [0, geo_len], [0, 100]))
|
||||
# log.debug("Polygons cleared: %d" % pol_nr)
|
||||
|
||||
if old_disp_number < disp_number <= 100:
|
||||
app_obj.proc_container.update_view_text(' %d%%' % disp_number)
|
||||
old_disp_number = disp_number
|
||||
# log.debug("Polygons cleared: %d. Percentage done: %d%%" % (pol_nr, disp_number))
|
||||
if old_disp_number < disp_number <= 100:
|
||||
app_obj.proc_container.update_view_text(' %d%%' % disp_number)
|
||||
old_disp_number = disp_number
|
||||
# log.debug("Polygons cleared: %d. Percentage done: %d%%" % (pol_nr, disp_number))
|
||||
|
||||
# add the solid_geometry to the current too in self.paint_tools (tools_storage)
|
||||
# dictionary and then reset the temporary list that stored that solid_geometry
|
||||
|
@ -1837,17 +1936,24 @@ class ToolPaint(FlatCAMTool, Gerber):
|
|||
if self.app.defaults["tools_paint_plotting"] == 'progressive':
|
||||
self.temp_shapes.clear(update=True)
|
||||
|
||||
# # delete tools with empty geometry
|
||||
# keys_to_delete = []
|
||||
# # look for keys in the tools_storage dict that have 'solid_geometry' values empty
|
||||
# for uid in tools_storage:
|
||||
# # if the solid_geometry (type=list) is empty
|
||||
# if not tools_storage[uid]['solid_geometry']:
|
||||
# keys_to_delete.append(uid)
|
||||
#
|
||||
# # actual delete of keys from the tools_storage dict
|
||||
# for k in keys_to_delete:
|
||||
# tools_storage.pop(k, None)
|
||||
|
||||
# delete tools with empty geometry
|
||||
keys_to_delete = []
|
||||
# look for keys in the tools_storage dict that have 'solid_geometry' values empty
|
||||
for uid in tools_storage:
|
||||
for uid in list(tools_storage.keys()):
|
||||
# if the solid_geometry (type=list) is empty
|
||||
if not tools_storage[uid]['solid_geometry']:
|
||||
keys_to_delete.append(uid)
|
||||
|
||||
# actual delete of keys from the tools_storage dict
|
||||
for k in keys_to_delete:
|
||||
tools_storage.pop(k, None)
|
||||
tools_storage.pop(uid, None)
|
||||
|
||||
geo_obj.options["cnctooldia"] = str(tool_dia)
|
||||
# this turn on the FlatCAMCNCJob plot for multiple tools
|
||||
|
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -14,6 +14,8 @@ from FlatCAMPostProc import *
|
|||
|
||||
|
||||
class Berta_CNC(FlatCAMPostProc):
|
||||
|
||||
include_header = True
|
||||
coordinate_format = "%.*f"
|
||||
feedrate_format = '%.*f'
|
||||
|
||||
|
@ -66,18 +68,19 @@ class Berta_CNC(FlatCAMPostProc):
|
|||
|
||||
gcode += '(Spindle Speed: %s RPM)\n' % str(p['spindlespeed'])
|
||||
|
||||
gcode += '(Berta)\n'
|
||||
gcode += 'G90 G94 G17 G91.1'
|
||||
gcode += (
|
||||
# This line allow you to sets the machine to METRIC / INCH in the GUI
|
||||
'G20\n' if p.units.upper() == 'IN' else 'G21\n')
|
||||
'G20\n' if p.units.upper() == 'IN' else 'G21\n') + '\n'
|
||||
# gcode += 'G21\n' # This line sets the machine to METRIC ONLY
|
||||
# gcode += 'G20\n' # This line sets the machine to INCH ONLY
|
||||
|
||||
gcode += 'G90 G17 G91.1\n'
|
||||
gcode += 'G64 P0.03\n'
|
||||
gcode += 'M110\n'
|
||||
gcode += 'G54\n'
|
||||
gcode += 'G0\n'
|
||||
gcode += '(Berta)\n'
|
||||
gcode += 'G94\n'
|
||||
|
||||
return gcode
|
||||
|
||||
|
@ -97,7 +100,6 @@ class Berta_CNC(FlatCAMPostProc):
|
|||
z_toolchange = p.z_toolchange
|
||||
toolchangexy = p.xy_toolchange
|
||||
f_plunge = p.f_plunge
|
||||
gcode = ''
|
||||
|
||||
if toolchangexy is not None:
|
||||
x_toolchange = toolchangexy[0]
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
# ########################################################## ##
|
||||
# ##########################################################
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://flatcam.org #
|
||||
# File Author: Matthieu Berthomé #
|
||||
# Date: 5/26/2017 #
|
||||
# MIT Licence #
|
||||
# ########################################################## ##
|
||||
# ##########################################################
|
||||
|
||||
from FlatCAMPostProc import *
|
||||
|
||||
|
||||
class ISEL_CNC(FlatCAMPostProc):
|
||||
|
||||
include_header = True
|
||||
coordinate_format = "%.*f"
|
||||
feedrate_format = '%.*f'
|
||||
|
||||
|
@ -71,15 +71,15 @@ class ISEL_CNC(FlatCAMPostProc):
|
|||
|
||||
def startz_code(self, p):
|
||||
if p.startz is not None:
|
||||
return 'G00 Z' + self.coordinate_format%(p.coords_decimals, p.startz)
|
||||
return 'G00 Z' + self.coordinate_format % (p.coords_decimals, p.startz)
|
||||
else:
|
||||
return ''
|
||||
|
||||
def lift_code(self, p):
|
||||
return 'G00 Z' + self.coordinate_format%(p.coords_decimals, p.z_move)
|
||||
return 'G00 Z' + self.coordinate_format % (p.coords_decimals, p.z_move)
|
||||
|
||||
def down_code(self, p):
|
||||
return 'G01 Z' + self.coordinate_format%(p.coords_decimals, p.z_cut)
|
||||
return 'G01 Z' + self.coordinate_format % (p.coords_decimals, p.z_cut)
|
||||
|
||||
def toolchange_code(self, p):
|
||||
f_plunge = p.f_plunge
|
||||
|
@ -130,17 +130,17 @@ M01""".format(tool=int(p.tool), toolC=toolC_formatted)
|
|||
|
||||
def end_code(self, p):
|
||||
coords_xy = p['xy_toolchange']
|
||||
gcode = ('G00 Z' + self.feedrate_format %(p.fr_decimals, p.z_end) + "\n")
|
||||
gcode = ('G00 Z' + self.feedrate_format % (p.fr_decimals, p.z_end) + "\n")
|
||||
|
||||
if coords_xy is not None:
|
||||
gcode += 'G00 X{x} Y{y}'.format(x=coords_xy[0], y=coords_xy[1]) + "\n"
|
||||
return gcode
|
||||
|
||||
def feedrate_code(self, p):
|
||||
return 'G01 F' + str(self.feedrate_format %(p.fr_decimals, p.feedrate))
|
||||
return 'G01 F' + str(self.feedrate_format % (p.fr_decimals, p.feedrate))
|
||||
|
||||
def z_feedrate_code(self, p):
|
||||
return 'G01 F' + str(self.feedrate_format %(p.fr_decimals, p.z_feedrate))
|
||||
return 'G01 F' + str(self.feedrate_format % (p.fr_decimals, p.z_feedrate))
|
||||
|
||||
def spindle_code(self, p):
|
||||
sdir = {'CW': 'M03', 'CCW': 'M04'}[p.spindledir]
|
||||
|
@ -153,5 +153,5 @@ M01""".format(tool=int(p.tool), toolC=toolC_formatted)
|
|||
if p.dwelltime:
|
||||
return 'G4 P' + str(p.dwelltime)
|
||||
|
||||
def spindle_stop_code(self,p):
|
||||
def spindle_stop_code(self, p):
|
||||
return 'M05'
|
||||
|
|
|
@ -0,0 +1,136 @@
|
|||
# ##########################################################
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://flatcam.org #
|
||||
# File Author: Matthieu Berthomé, Daniel Friderich #
|
||||
# Date: 12/15/2019 #
|
||||
# MIT Licence #
|
||||
# ##########################################################
|
||||
|
||||
from FlatCAMPostProc import *
|
||||
|
||||
|
||||
class ISEL_ICP_CNC(FlatCAMPostProc):
|
||||
include_header = False
|
||||
|
||||
def start_code(self, p):
|
||||
units = ' ' + str(p['units']).lower()
|
||||
coords_xy = p['xy_toolchange']
|
||||
gcode = ''
|
||||
|
||||
xmin = '%.*f' % (p.coords_decimals, p['options']['xmin'])
|
||||
xmax = '%.*f' % (p.coords_decimals, p['options']['xmax'])
|
||||
ymin = '%.*f' % (p.coords_decimals, p['options']['ymin'])
|
||||
ymax = '%.*f' % (p.coords_decimals, p['options']['ymax'])
|
||||
|
||||
gcode += 'IMF_PBL flatcam\n\n'
|
||||
|
||||
if str(p['options']['type']) == 'Geometry':
|
||||
gcode += '; TOOL DIAMETER: ' + str(p['options']['tool_dia']) + units + '\n'
|
||||
gcode += '; Spindle Speed: %s RPM\n' % str(p['spindlespeed'])
|
||||
gcode += '; Feedrate: ' + str(p['feedrate']) + units + '/min' + '\n'
|
||||
if str(p['options']['type']) == 'Geometry':
|
||||
gcode += '; Feedrate_Z: ' + str(p['z_feedrate']) + units + '/min' + '\n'
|
||||
gcode += '\n'
|
||||
gcode += '; Z_Cut: ' + str(p['z_cut']) + units + '\n'
|
||||
|
||||
if str(p['options']['type']) == 'Geometry':
|
||||
if p['multidepth'] is True:
|
||||
gcode += '; DepthPerCut: ' + str(p['z_depthpercut']) + units + ' <=>' + \
|
||||
str(math.ceil(abs(p['z_cut']) / p['z_depthpercut'])) + ' passes' + '\n'
|
||||
gcode += '; Z_Move: ' + str(p['z_move']) + units + '\n'
|
||||
gcode += '; Z Toolchange: ' + str(p['z_toolchange']) + units + '\n'
|
||||
if coords_xy is not None:
|
||||
gcode += '; X,Y Toolchange: ' + "%.*f, %.*f" % (p.decimals, coords_xy[0],
|
||||
p.decimals, coords_xy[1]) + units + '\n'
|
||||
else:
|
||||
gcode += '; X,Y Toolchange: ' + "None" + units + '\n'
|
||||
gcode += '; Z Start: ' + str(p['startz']) + units + '\n'
|
||||
gcode += '; Z End: ' + str(p['z_end']) + units + '\n'
|
||||
gcode += '; Steps per circle: ' + str(p['steps_per_circle']) + '\n'
|
||||
if str(p['options']['type']) == 'Excellon' or str(p['options']['type']) == 'Excellon Geometry':
|
||||
gcode += '; Preprocessor Excellon: ' + str(p['pp_excellon_name']) + '\n'
|
||||
else:
|
||||
gcode += '; Preprocessor Geometry: ' + str(p['pp_geometry_name']) + '\n'
|
||||
gcode += '\n'
|
||||
|
||||
gcode += '; X range: ' + '{: >9s}'.format(xmin) + ' ... ' + '{: >9s}'.format(xmax) + ' ' + units + '\n'
|
||||
gcode += '; Y range: ' + '{: >9s}'.format(ymin) + ' ... ' + '{: >9s}'.format(ymax) + ' ' + units + '\n'
|
||||
|
||||
return gcode
|
||||
|
||||
def startz_code(self, p):
|
||||
if p.startz is not None:
|
||||
return 'FASTABS Z' + str(int(p.startz * 1000))
|
||||
else:
|
||||
return ''
|
||||
|
||||
def lift_code(self, p):
|
||||
return 'FASTABS Z' + str(int(p.z_move * 1000))
|
||||
|
||||
def down_code(self, p):
|
||||
return 'MOVEABS Z' + str(int(p.z_cut * 1000))
|
||||
|
||||
def toolchange_code(self, p):
|
||||
f_plunge = p.f_plunge
|
||||
no_drills = 1
|
||||
|
||||
toolC_formatted = '%.*f' % (p.decimals, p.toolC)
|
||||
|
||||
if str(p['options']['type']) == 'Excellon':
|
||||
for i in p['options']['Tools_in_use']:
|
||||
if i[0] == p.tool:
|
||||
no_drills = i[2]
|
||||
|
||||
gcode = "GETTOOL {tool}\n; Changed to Tool Dia = {toolC}".format(tool=int(p.tool), t_drills=no_drills,
|
||||
toolC=toolC_formatted)
|
||||
|
||||
if f_plunge is True:
|
||||
gcode += '\nFASTABS Z' + str(int(p.z_move * 1000))
|
||||
return gcode
|
||||
|
||||
else:
|
||||
gcode = "GETTOOL {tool}\n; Changed to Tool Dia = {toolC}".format(tool=int(p.tool), toolC=toolC_formatted)
|
||||
|
||||
if f_plunge is True:
|
||||
gcode += '\nFASTABS Z' + str(int(p.z_move * 1000))
|
||||
return gcode
|
||||
|
||||
def up_to_zero_code(self, p):
|
||||
return 'MOVEABS Z0'
|
||||
|
||||
def position_code(self, p):
|
||||
return 'X' + str(int(p.x * 1000)) + ' Y' + str(int(p.y * 1000))
|
||||
|
||||
def rapid_code(self, p):
|
||||
return ('FASTABS ' + self.position_code(p)).format(**p)
|
||||
|
||||
def linear_code(self, p):
|
||||
return ('MOVEABS ' + self.position_code(p)).format(**p)
|
||||
|
||||
def end_code(self, p):
|
||||
gcode = ''
|
||||
gcode += 'WPCLEAR\n'
|
||||
gcode += 'FASTABS Z0\n'
|
||||
gcode += 'FASTABS X0 Y0\n'
|
||||
gcode += 'PROGEND'
|
||||
return gcode
|
||||
|
||||
def feedrate_code(self, p):
|
||||
return 'VEL ' + str(int(p.feedrate / 60 * 1000))
|
||||
|
||||
def z_feedrate_code(self, p):
|
||||
return 'VEL ' + str(int(p.z_feedrate / 60 * 1000))
|
||||
|
||||
def spindle_code(self, p):
|
||||
sdir = {'CW': 'SPINDLE CW', 'CCW': 'SPINDLE CCW'}[p.spindledir]
|
||||
if p.spindlespeed:
|
||||
return '%s RPM%s' % (sdir, str(int(p.spindlespeed)))
|
||||
else:
|
||||
return sdir
|
||||
|
||||
def dwell_code(self, p):
|
||||
if p.dwelltime:
|
||||
return 'WAIT ' + str(int(p.dwelltime * 1000))
|
||||
|
||||
def spindle_stop_code(self, p):
|
||||
return 'SPINDLE OFF'
|
|
@ -1,16 +1,17 @@
|
|||
# ########################################################## ##
|
||||
# ##########################################################
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://flatcam.org #
|
||||
# File Author: Marius Adrian Stanciu (c) #
|
||||
# Date: 3/10/2019 #
|
||||
# MIT Licence #
|
||||
# ########################################################## ##
|
||||
# ##########################################################
|
||||
|
||||
from FlatCAMPostProc import *
|
||||
|
||||
|
||||
class Paste_1(FlatCAMPostProc_Tools):
|
||||
|
||||
include_header = True
|
||||
coordinate_format = "%.*f"
|
||||
feedrate_format = '%.*f'
|
||||
|
||||
|
@ -56,21 +57,20 @@ class Paste_1(FlatCAMPostProc_Tools):
|
|||
return gcode
|
||||
|
||||
def lift_code(self, p):
|
||||
return 'G00 Z' + self.coordinate_format%(p.coords_decimals, float(p['z_travel']))
|
||||
return 'G00 Z' + self.coordinate_format % (p.coords_decimals, float(p['z_travel']))
|
||||
|
||||
def down_z_start_code(self, p):
|
||||
return 'G01 Z' + self.coordinate_format%(p.coords_decimals, float(p['z_start']))
|
||||
return 'G01 Z' + self.coordinate_format % (p.coords_decimals, float(p['z_start']))
|
||||
|
||||
def lift_z_dispense_code(self, p):
|
||||
return 'G01 Z' + self.coordinate_format%(p.coords_decimals, float(p['z_dispense']))
|
||||
return 'G01 Z' + self.coordinate_format % (p.coords_decimals, float(p['z_dispense']))
|
||||
|
||||
def down_z_stop_code(self, p):
|
||||
return 'G01 Z' + self.coordinate_format%(p.coords_decimals, float(p['z_stop']))
|
||||
return 'G01 Z' + self.coordinate_format % (p.coords_decimals, float(p['z_stop']))
|
||||
|
||||
def toolchange_code(self, p):
|
||||
z_toolchange = float(p['z_toolchange'])
|
||||
toolchangexy = [float(eval(a)) for a in p['xy_toolchange'].split(",") if a != '']
|
||||
gcode = ''
|
||||
|
||||
if toolchangexy is not None:
|
||||
x_toolchange = toolchangexy[0]
|
||||
|
@ -116,27 +116,27 @@ G00 Z{z_toolchange}
|
|||
|
||||
def rapid_code(self, p):
|
||||
return ('G00 ' + self.position_code(p)).format(**p) + '\nG00 Z' + \
|
||||
self.coordinate_format%(p.coords_decimals, float(p['z_travel']))
|
||||
self.coordinate_format % (p.coords_decimals, float(p['z_travel']))
|
||||
|
||||
def linear_code(self, p):
|
||||
return ('G01 ' + self.position_code(p)).format(**p)
|
||||
|
||||
def end_code(self, p):
|
||||
coords_xy = [float(eval(a)) for a in p['xy_toolchange'].split(",") if a != '']
|
||||
gcode = ('G00 Z' + self.feedrate_format %(p.fr_decimals, float(p['z_toolchange'])) + "\n")
|
||||
gcode = ('G00 Z' + self.feedrate_format % (p.fr_decimals, float(p['z_toolchange'])) + "\n")
|
||||
|
||||
if coords_xy is not None:
|
||||
gcode += 'G00 X{x} Y{y}'.format(x=coords_xy[0], y=coords_xy[1]) + "\n"
|
||||
return gcode
|
||||
|
||||
def feedrate_xy_code(self, p):
|
||||
return 'G01 F' + str(self.feedrate_format %(p.fr_decimals, float(p['frxy'])))
|
||||
return 'G01 F' + str(self.feedrate_format % (p.fr_decimals, float(p['frxy'])))
|
||||
|
||||
def z_feedrate_code(self, p):
|
||||
return 'G01 F' + str(self.feedrate_format %(p.fr_decimals, float(p['frz'])))
|
||||
return 'G01 F' + str(self.feedrate_format % (p.fr_decimals, float(p['frz'])))
|
||||
|
||||
def feedrate_z_dispense_code(self, p):
|
||||
return 'G01 F' + str(self.feedrate_format %(p.fr_decimals, float(p['frz_dispense'])))
|
||||
return 'G01 F' + str(self.feedrate_format % (p.fr_decimals, float(p['frz_dispense'])))
|
||||
|
||||
def spindle_fwd_code(self, p):
|
||||
if p.spindlespeed:
|
||||
|
@ -150,7 +150,7 @@ G00 Z{z_toolchange}
|
|||
else:
|
||||
return 'M04'
|
||||
|
||||
def spindle_off_code(self,p):
|
||||
def spindle_off_code(self, p):
|
||||
return 'M05'
|
||||
|
||||
def dwell_fwd_code(self, p):
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
# ########################################################## ##
|
||||
# ##########################################################
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://flatcam.org #
|
||||
# File Author: Marius Adrian Stanciu (c) #
|
||||
# Date: 3/10/2019 #
|
||||
# MIT Licence #
|
||||
# ########################################################## ##
|
||||
# ##########################################################
|
||||
|
||||
from FlatCAMPostProc import *
|
||||
|
||||
|
||||
class Repetier(FlatCAMPostProc):
|
||||
|
||||
include_header = True
|
||||
coordinate_format = "%.*f"
|
||||
feedrate_format = '%.*f'
|
||||
feedrate_rapid_format = feedrate_format
|
||||
|
@ -66,6 +67,7 @@ class Repetier(FlatCAMPostProc):
|
|||
|
||||
gcode += ('G20' if p.units.upper() == 'IN' else 'G21') + "\n"
|
||||
gcode += 'G90\n'
|
||||
gcode += 'G94\n'
|
||||
|
||||
return gcode
|
||||
|
||||
|
@ -76,20 +78,22 @@ class Repetier(FlatCAMPostProc):
|
|||
return ''
|
||||
|
||||
def lift_code(self, p):
|
||||
return 'G0 Z' + self.coordinate_format%(p.coords_decimals, p.z_move) + " " + self.feedrate_rapid_code(p)
|
||||
return 'G0 Z' + self.coordinate_format % (p.coords_decimals, p.z_move) + " " + self.feedrate_rapid_code(p)
|
||||
|
||||
def down_code(self, p):
|
||||
return 'G1 Z' + self.coordinate_format%(p.coords_decimals, p.z_cut) + " " + self.inline_z_feedrate_code(p)
|
||||
return 'G1 Z' + self.coordinate_format % (p.coords_decimals, p.z_cut) + " " + self.inline_z_feedrate_code(p)
|
||||
|
||||
def toolchange_code(self, p):
|
||||
z_toolchange = p.z_toolchange
|
||||
toolchangexy = p.xy_toolchange
|
||||
f_plunge = p.f_plunge
|
||||
gcode = ''
|
||||
|
||||
if toolchangexy is not None:
|
||||
x_toolchange = toolchangexy[0]
|
||||
y_toolchange = toolchangexy[1]
|
||||
else:
|
||||
x_toolchange = 0.0
|
||||
y_toolchange = 0.0
|
||||
|
||||
no_drills = 1
|
||||
|
||||
|
@ -151,7 +155,7 @@ G0 Z{z_toolchange}
|
|||
M84
|
||||
@pause Change to tool T{tool} with Tool Dia = {toolC}
|
||||
G0 Z{z_toolchange}
|
||||
""".format(z_toolchange=self.coordinate_format%(p.coords_decimals, z_toolchange),
|
||||
""".format(z_toolchange=self.coordinate_format % (p.coords_decimals, z_toolchange),
|
||||
tool=int(p.tool),
|
||||
toolC=toolC_formatted)
|
||||
|
||||
|
@ -175,7 +179,7 @@ G0 Z{z_toolchange}
|
|||
|
||||
def end_code(self, p):
|
||||
coords_xy = p['xy_toolchange']
|
||||
gcode = ('G0 Z' + self.feedrate_format %(p.fr_decimals, p.z_end) + " " + self.feedrate_rapid_code(p) + "\n")
|
||||
gcode = ('G0 Z' + self.feedrate_format % (p.fr_decimals, p.z_end) + " " + self.feedrate_rapid_code(p) + "\n")
|
||||
|
||||
if coords_xy is not None:
|
||||
gcode += 'G0 X{x} Y{y}'.format(x=coords_xy[0], y=coords_xy[1]) + " " + self.feedrate_rapid_code(p) + "\n"
|
||||
|
@ -183,21 +187,21 @@ G0 Z{z_toolchange}
|
|||
return gcode
|
||||
|
||||
def feedrate_code(self, p):
|
||||
return 'G1 F' + str(self.feedrate_format %(p.fr_decimals, p.feedrate))
|
||||
return 'G1 F' + str(self.feedrate_format % (p.fr_decimals, p.feedrate))
|
||||
|
||||
def inline_feedrate_code(self, p):
|
||||
return 'F' + self.feedrate_format %(p.fr_decimals, p.feedrate)
|
||||
return 'F' + self.feedrate_format % (p.fr_decimals, p.feedrate)
|
||||
|
||||
def inline_z_feedrate_code(self, p):
|
||||
return 'F' + self.feedrate_format %(p.fr_decimals, p.z_feedrate)
|
||||
return 'F' + self.feedrate_format % (p.fr_decimals, p.z_feedrate)
|
||||
|
||||
def z_feedrate_code(self, p):
|
||||
return 'G1 F' + str(self.feedrate_format %(p.fr_decimals, p.z_feedrate))
|
||||
return 'G1 F' + str(self.feedrate_format % (p.fr_decimals, p.z_feedrate))
|
||||
|
||||
def feedrate_rapid_code(self, p):
|
||||
return 'F' + self.feedrate_rapid_format % (p.fr_decimals, p.feedrate_rapid)
|
||||
|
||||
def spindle_code(self,p):
|
||||
def spindle_code(self, p):
|
||||
if p.spindlespeed:
|
||||
return 'M106 S%d' % p.spindlespeed
|
||||
else:
|
||||
|
@ -207,5 +211,5 @@ G0 Z{z_toolchange}
|
|||
if p.dwelltime:
|
||||
return 'G4 P' + str(p.dwelltime)
|
||||
|
||||
def spindle_stop_code(self,p):
|
||||
def spindle_stop_code(self, p):
|
||||
return 'M107'
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
# ########################################################## ##
|
||||
# ##########################################################
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://flatcam.org #
|
||||
# File Author: Marius Adrian Stanciu (c) #
|
||||
# Date: 3/10/2019 #
|
||||
# MIT Licence #
|
||||
# ########################################################## ##
|
||||
# ##########################################################
|
||||
|
||||
from FlatCAMPostProc import *
|
||||
|
||||
|
@ -13,6 +13,7 @@ from FlatCAMPostProc import *
|
|||
# the same) to contain the following keyword, case-sensitive: 'Roland' without the quotes.
|
||||
class Roland_MDX_20(FlatCAMPostProc):
|
||||
|
||||
include_header = False
|
||||
coordinate_format = "%.1f"
|
||||
feedrate_format = '%.1f'
|
||||
feedrate_rapid_format = '%.1f'
|
||||
|
@ -123,5 +124,5 @@ class Roland_MDX_20(FlatCAMPostProc):
|
|||
def dwell_code(self, p):
|
||||
return''
|
||||
|
||||
def spindle_stop_code(self,p):
|
||||
def spindle_stop_code(self, p):
|
||||
return '!MC0'
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
# ########################################################## ##
|
||||
# ##########################################################
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://flatcam.org #
|
||||
# File Author: Marius Adrian Stanciu (c) #
|
||||
# Date: 3/10/2019 #
|
||||
# MIT Licence #
|
||||
# ########################################################## ##
|
||||
# ##########################################################
|
||||
|
||||
from FlatCAMPostProc import *
|
||||
|
||||
|
||||
class Toolchange_Custom(FlatCAMPostProc):
|
||||
|
||||
include_header = True
|
||||
coordinate_format = "%.*f"
|
||||
feedrate_format = '%.*f'
|
||||
|
||||
|
@ -74,10 +75,10 @@ class Toolchange_Custom(FlatCAMPostProc):
|
|||
return ''
|
||||
|
||||
def lift_code(self, p):
|
||||
return 'G00 Z' + self.coordinate_format%(p.coords_decimals, p.z_move)
|
||||
return 'G00 Z' + self.coordinate_format % (p.coords_decimals, p.z_move)
|
||||
|
||||
def down_code(self, p):
|
||||
return 'G01 Z' + self.coordinate_format%(p.coords_decimals, p.z_cut)
|
||||
return 'G01 Z' + self.coordinate_format % (p.coords_decimals, p.z_cut)
|
||||
|
||||
def toolchange_code(self, p):
|
||||
z_toolchange = p.z_toolchange
|
||||
|
@ -88,6 +89,9 @@ class Toolchange_Custom(FlatCAMPostProc):
|
|||
if toolchangexy is not None:
|
||||
x_toolchange = toolchangexy[0]
|
||||
y_toolchange = toolchangexy[1]
|
||||
else:
|
||||
x_toolchange = 0.0
|
||||
y_toolchange = 0.0
|
||||
|
||||
no_drills = 1
|
||||
|
||||
|
@ -142,17 +146,17 @@ M6
|
|||
|
||||
def end_code(self, p):
|
||||
coords_xy = p['xy_toolchange']
|
||||
gcode = ('G00 Z' + self.feedrate_format %(p.fr_decimals, p.z_end) + "\n")
|
||||
gcode = ('G00 Z' + self.feedrate_format % (p.fr_decimals, p.z_end) + "\n")
|
||||
|
||||
if coords_xy is not None:
|
||||
gcode += 'G00 X{x} Y{y}'.format(x=coords_xy[0], y=coords_xy[1]) + "\n"
|
||||
return gcode
|
||||
|
||||
def feedrate_code(self, p):
|
||||
return 'G01 F' + str(self.feedrate_format %(p.fr_decimals, p.feedrate))
|
||||
return 'G01 F' + str(self.feedrate_format % (p.fr_decimals, p.feedrate))
|
||||
|
||||
def z_feedrate_code(self, p):
|
||||
return 'G01 F' + str(self.feedrate_format %(p.fr_decimals, p.z_feedrate))
|
||||
return 'G01 F' + str(self.feedrate_format % (p.fr_decimals, p.z_feedrate))
|
||||
|
||||
def spindle_code(self, p):
|
||||
sdir = {'CW': 'M03', 'CCW': 'M04'}[p.spindledir]
|
||||
|
@ -165,5 +169,5 @@ M6
|
|||
if p.dwelltime:
|
||||
return 'G4 P' + str(p.dwelltime)
|
||||
|
||||
def spindle_stop_code(self,p):
|
||||
def spindle_stop_code(self, p):
|
||||
return 'M05'
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
# ########################################################## ##
|
||||
# ##########################################################
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://flatcam.org #
|
||||
# File Author: Marius Adrian Stanciu (c) #
|
||||
# Date: 3/10/2019 #
|
||||
# MIT Licence #
|
||||
# ########################################################## ##
|
||||
# ##########################################################
|
||||
|
||||
from FlatCAMPostProc import *
|
||||
|
||||
|
||||
class Toolchange_Probe_MACH3(FlatCAMPostProc):
|
||||
|
||||
include_header = True
|
||||
coordinate_format = "%.*f"
|
||||
feedrate_format = '%.*f'
|
||||
|
||||
|
@ -69,14 +70,14 @@ class Toolchange_Probe_MACH3(FlatCAMPostProc):
|
|||
gcode += 'G90\n'
|
||||
gcode += 'G17\n'
|
||||
gcode += 'G94\n'
|
||||
gcode += '(MSG, WARNING: Make sure you do zero on all axis. ' \
|
||||
'For Z axis, since it will be probed, make a rough estimate and do a zero.)\n'
|
||||
gcode += 'M0'
|
||||
|
||||
return gcode
|
||||
|
||||
def startz_code(self, p):
|
||||
return ''
|
||||
g = '(MSG, WARNING: Make sure you do zero on all axis. ' \
|
||||
'For Z axis, since it will be probed, make a rough estimate and do a zero.)\n'
|
||||
g += 'M0'
|
||||
return g
|
||||
|
||||
def lift_code(self, p):
|
||||
return 'G00 Z' + self.coordinate_format%(p.coords_decimals, p.z_move)
|
||||
|
@ -89,11 +90,12 @@ class Toolchange_Probe_MACH3(FlatCAMPostProc):
|
|||
toolchangexy = p.xy_toolchange
|
||||
f_plunge = p.f_plunge
|
||||
|
||||
gcode = ''
|
||||
|
||||
if toolchangexy is not None:
|
||||
x_toolchange = toolchangexy[0]
|
||||
y_toolchange = toolchangexy[1]
|
||||
else:
|
||||
x_toolchange = 0.0
|
||||
y_toolchange = 0.0
|
||||
|
||||
no_drills = 1
|
||||
|
||||
|
@ -131,7 +133,7 @@ M0
|
|||
z_toolchange=self.coordinate_format % (p.coords_decimals, z_toolchange),
|
||||
z_move=self.coordinate_format % (p.coords_decimals, p.z_move),
|
||||
z_in_between=self.coordinate_format % (p.coords_decimals, p.z_move / 2),
|
||||
feedrate_probe=str(self.feedrate_format %(p.fr_decimals, p.feedrate_probe)),
|
||||
feedrate_probe=str(self.feedrate_format % (p.fr_decimals, p.feedrate_probe)),
|
||||
feedrate_probe_slow=str(self.feedrate_format % (p.fr_decimals, (p.feedrate_probe / 2))),
|
||||
z_pdepth=self.coordinate_format % (p.coords_decimals, p.z_pdepth),
|
||||
tool=int(p.tool),
|
||||
|
@ -158,7 +160,7 @@ M0
|
|||
""".format(z_toolchange=self.coordinate_format % (p.coords_decimals, z_toolchange),
|
||||
z_move=self.coordinate_format % (p.coords_decimals, p.z_move),
|
||||
z_in_between=self.coordinate_format % (p.coords_decimals, p.z_move / 2),
|
||||
feedrate_probe=str(self.feedrate_format %(p.fr_decimals, p.feedrate_probe)),
|
||||
feedrate_probe=str(self.feedrate_format % (p.fr_decimals, p.feedrate_probe)),
|
||||
feedrate_probe_slow=str(self.feedrate_format % (p.fr_decimals, (p.feedrate_probe / 2))),
|
||||
z_pdepth=self.coordinate_format % (p.coords_decimals, p.z_pdepth),
|
||||
tool=int(p.tool),
|
||||
|
@ -194,7 +196,7 @@ M0
|
|||
z_toolchange=self.coordinate_format % (p.coords_decimals, z_toolchange),
|
||||
z_move=self.coordinate_format % (p.coords_decimals, p.z_move),
|
||||
z_in_between=self.coordinate_format % (p.coords_decimals, p.z_move / 2),
|
||||
feedrate_probe=str(self.feedrate_format %(p.fr_decimals, p.feedrate_probe)),
|
||||
feedrate_probe=str(self.feedrate_format % (p.fr_decimals, p.feedrate_probe)),
|
||||
feedrate_probe_slow=str(self.feedrate_format % (p.fr_decimals, (p.feedrate_probe / 2))),
|
||||
z_pdepth=self.coordinate_format % (p.coords_decimals, p.z_pdepth),
|
||||
tool=int(p.tool),
|
||||
|
@ -220,7 +222,7 @@ M0
|
|||
""".format(z_toolchange=self.coordinate_format % (p.coords_decimals, z_toolchange),
|
||||
z_move=self.coordinate_format % (p.coords_decimals, p.z_move),
|
||||
z_in_between=self.coordinate_format % (p.coords_decimals, p.z_move / 2),
|
||||
feedrate_probe=str(self.feedrate_format %(p.fr_decimals, p.feedrate_probe)),
|
||||
feedrate_probe=str(self.feedrate_format % (p.fr_decimals, p.feedrate_probe)),
|
||||
feedrate_probe_slow=str(self.feedrate_format % (p.fr_decimals, (p.feedrate_probe / 2))),
|
||||
z_pdepth=self.coordinate_format % (p.coords_decimals, p.z_pdepth),
|
||||
tool=int(p.tool),
|
||||
|
@ -245,17 +247,17 @@ M0
|
|||
|
||||
def end_code(self, p):
|
||||
coords_xy = p['xy_toolchange']
|
||||
gcode = ('G00 Z' + self.feedrate_format %(p.fr_decimals, p.z_end) + "\n")
|
||||
gcode = ('G00 Z' + self.feedrate_format % (p.fr_decimals, p.z_end) + "\n")
|
||||
|
||||
if coords_xy is not None:
|
||||
gcode += 'G00 X{x} Y{y}'.format(x=coords_xy[0], y=coords_xy[1]) + "\n"
|
||||
return gcode
|
||||
|
||||
def feedrate_code(self, p):
|
||||
return 'G01 F' + str(self.feedrate_format %(p.fr_decimals, p.feedrate))
|
||||
return 'G01 F' + str(self.feedrate_format % (p.fr_decimals, p.feedrate))
|
||||
|
||||
def z_feedrate_code(self, p):
|
||||
return 'G01 F' + str(self.feedrate_format %(p.fr_decimals, p.z_feedrate))
|
||||
return 'G01 F' + str(self.feedrate_format % (p.fr_decimals, p.z_feedrate))
|
||||
|
||||
def spindle_code(self, p):
|
||||
sdir = {'CW': 'M03', 'CCW': 'M04'}[p.spindledir]
|
||||
|
@ -268,5 +270,5 @@ M0
|
|||
if p.dwelltime:
|
||||
return 'G4 P' + str(p.dwelltime)
|
||||
|
||||
def spindle_stop_code(self,p):
|
||||
def spindle_stop_code(self, p):
|
||||
return 'M05'
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
# ########################################################## ##
|
||||
# ##########################################################
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://flatcam.org #
|
||||
# File Author: Marius Adrian Stanciu (c) #
|
||||
# Date: 3/10/2019 #
|
||||
# MIT Licence #
|
||||
# ########################################################## ##
|
||||
# ##########################################################
|
||||
|
||||
from FlatCAMPostProc import *
|
||||
|
||||
|
||||
class Toolchange_manual(FlatCAMPostProc):
|
||||
|
||||
include_header = True
|
||||
coordinate_format = "%.*f"
|
||||
feedrate_format = '%.*f'
|
||||
|
||||
|
@ -84,11 +85,13 @@ class Toolchange_manual(FlatCAMPostProc):
|
|||
z_toolchange = p.z_toolchange
|
||||
toolchangexy = p.xy_toolchange
|
||||
f_plunge = p.f_plunge
|
||||
gcode = ''
|
||||
|
||||
if toolchangexy is not None:
|
||||
x_toolchange = toolchangexy[0]
|
||||
y_toolchange = toolchangexy[1]
|
||||
else:
|
||||
x_toolchange = 0.0
|
||||
y_toolchange = 0.0
|
||||
|
||||
no_drills = 1
|
||||
|
||||
|
@ -116,9 +119,9 @@ M0
|
|||
G00 Z{z_toolchange}
|
||||
(MSG, Now the tool can be tightened more securely.)
|
||||
M0
|
||||
""".format(x_toolchange=self.coordinate_format%(p.coords_decimals, x_toolchange),
|
||||
y_toolchange=self.coordinate_format%(p.coords_decimals, y_toolchange),
|
||||
z_toolchange=self.coordinate_format%(p.coords_decimals, z_toolchange),
|
||||
""".format(x_toolchange=self.coordinate_format % (p.coords_decimals, x_toolchange),
|
||||
y_toolchange=self.coordinate_format % (p.coords_decimals, y_toolchange),
|
||||
z_toolchange=self.coordinate_format % (p.coords_decimals, z_toolchange),
|
||||
tool=int(p.tool),
|
||||
t_drills=no_drills,
|
||||
toolC=toolC_formatted)
|
||||
|
@ -137,7 +140,7 @@ G00 Z{z_toolchange}
|
|||
(MSG, Now the tool can be tightened more securely.)
|
||||
M0
|
||||
""".format(
|
||||
z_toolchange=self.coordinate_format%(p.coords_decimals, z_toolchange),
|
||||
z_toolchange=self.coordinate_format % (p.coords_decimals, z_toolchange),
|
||||
tool=int(p.tool),
|
||||
t_drills=no_drills,
|
||||
toolC=toolC_formatted)
|
||||
|
@ -161,9 +164,9 @@ M0
|
|||
G00 Z{z_toolchange}
|
||||
(MSG, Now the tool can be tightened more securely.)
|
||||
M0
|
||||
""".format(x_toolchange=self.coordinate_format%(p.coords_decimals, x_toolchange),
|
||||
y_toolchange=self.coordinate_format%(p.coords_decimals, y_toolchange),
|
||||
z_toolchange=self.coordinate_format%(p.coords_decimals, z_toolchange),
|
||||
""".format(x_toolchange=self.coordinate_format % (p.coords_decimals, x_toolchange),
|
||||
y_toolchange=self.coordinate_format % (p.coords_decimals, y_toolchange),
|
||||
z_toolchange=self.coordinate_format % (p.coords_decimals, z_toolchange),
|
||||
tool=int(p.tool),
|
||||
toolC=toolC_formatted)
|
||||
else:
|
||||
|
@ -179,8 +182,7 @@ M0
|
|||
G00 Z{z_toolchange}
|
||||
(MSG, Now the tool can be tightened more securely.)
|
||||
M0
|
||||
""".format(z_toolchange=self.coordinate_format%(p.coords_decimals, z_toolchange),
|
||||
tool=int(p.tool),
|
||||
""".format(z_toolchange=self.coordinate_format % (p.coords_decimals, z_toolchange), tool=int(p.tool),
|
||||
toolC=toolC_formatted)
|
||||
|
||||
if f_plunge is True:
|
||||
|
@ -202,7 +204,7 @@ M0
|
|||
|
||||
def end_code(self, p):
|
||||
coords_xy = p['xy_toolchange']
|
||||
gcode = ('G00 Z' + self.feedrate_format %(p.fr_decimals, p.z_end) + "\n")
|
||||
gcode = ('G00 Z' + self.feedrate_format % (p.fr_decimals, p.z_end) + "\n")
|
||||
if coords_xy is not None:
|
||||
gcode += 'G00 X{x} Y{y}'.format(x=coords_xy[0], y=coords_xy[1]) + "\n"
|
||||
else:
|
||||
|
@ -210,10 +212,10 @@ M0
|
|||
return gcode
|
||||
|
||||
def feedrate_code(self, p):
|
||||
return 'G01 F' + str(self.feedrate_format %(p.fr_decimals, p.feedrate))
|
||||
return 'G01 F' + str(self.feedrate_format % (p.fr_decimals, p.feedrate))
|
||||
|
||||
def z_feedrate_code(self, p):
|
||||
return 'G01 F' + str(self.feedrate_format %(p.fr_decimals, p.z_feedrate))
|
||||
return 'G01 F' + str(self.feedrate_format % (p.fr_decimals, p.z_feedrate))
|
||||
|
||||
def spindle_code(self, p):
|
||||
sdir = {'CW': 'M03', 'CCW': 'M04'}[p.spindledir]
|
||||
|
@ -226,5 +228,5 @@ M0
|
|||
if p.dwelltime:
|
||||
return 'G4 P' + str(p.dwelltime)
|
||||
|
||||
def spindle_stop_code(self,p):
|
||||
def spindle_stop_code(self, p):
|
||||
return 'M05'
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
# ########################################################## ##
|
||||
# ##########################################################
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://flatcam.org #
|
||||
# File Author: Matthieu Berthomé #
|
||||
# Date: 5/26/2017 #
|
||||
# MIT Licence #
|
||||
# ########################################################## ##
|
||||
# ##########################################################
|
||||
|
||||
from FlatCAMPostProc import *
|
||||
|
||||
|
||||
class default(FlatCAMPostProc):
|
||||
|
||||
include_header = True
|
||||
coordinate_format = "%.*f"
|
||||
feedrate_format = '%.*f'
|
||||
|
||||
|
@ -71,25 +72,27 @@ class default(FlatCAMPostProc):
|
|||
|
||||
def startz_code(self, p):
|
||||
if p.startz is not None:
|
||||
return 'G00 Z' + self.coordinate_format%(p.coords_decimals, p.startz)
|
||||
return 'G00 Z' + self.coordinate_format % (p.coords_decimals, p.startz)
|
||||
else:
|
||||
return ''
|
||||
|
||||
def lift_code(self, p):
|
||||
return 'G00 Z' + self.coordinate_format%(p.coords_decimals, p.z_move)
|
||||
return 'G00 Z' + self.coordinate_format % (p.coords_decimals, p.z_move)
|
||||
|
||||
def down_code(self, p):
|
||||
return 'G01 Z' + self.coordinate_format%(p.coords_decimals, p.z_cut)
|
||||
return 'G01 Z' + self.coordinate_format % (p.coords_decimals, p.z_cut)
|
||||
|
||||
def toolchange_code(self, p):
|
||||
z_toolchange = p.z_toolchange
|
||||
toolchangexy = p.xy_toolchange
|
||||
f_plunge = p.f_plunge
|
||||
gcode = ''
|
||||
|
||||
if toolchangexy is not None:
|
||||
x_toolchange = toolchangexy[0]
|
||||
y_toolchange = toolchangexy[1]
|
||||
else:
|
||||
x_toolchange = 0.0
|
||||
y_toolchange = 0.0
|
||||
|
||||
no_drills = 1
|
||||
|
||||
|
@ -163,7 +166,7 @@ M6
|
|||
(MSG, Change to Tool Dia = {toolC})
|
||||
M0
|
||||
G00 Z{z_toolchange}
|
||||
""".format(z_toolchange=self.coordinate_format%(p.coords_decimals, z_toolchange),
|
||||
""".format(z_toolchange=self.coordinate_format % (p.coords_decimals, z_toolchange),
|
||||
tool=int(p.tool),
|
||||
toolC=toolC_formatted)
|
||||
|
||||
|
@ -186,17 +189,17 @@ G00 Z{z_toolchange}
|
|||
|
||||
def end_code(self, p):
|
||||
coords_xy = p['xy_toolchange']
|
||||
gcode = ('G00 Z' + self.feedrate_format %(p.fr_decimals, p.z_end) + "\n")
|
||||
gcode = ('G00 Z' + self.feedrate_format % (p.fr_decimals, p.z_end) + "\n")
|
||||
|
||||
if coords_xy is not None:
|
||||
gcode += 'G00 X{x} Y{y}'.format(x=coords_xy[0], y=coords_xy[1]) + "\n"
|
||||
return gcode
|
||||
|
||||
def feedrate_code(self, p):
|
||||
return 'G01 F' + str(self.feedrate_format %(p.fr_decimals, p.feedrate))
|
||||
return 'G01 F' + str(self.feedrate_format % (p.fr_decimals, p.feedrate))
|
||||
|
||||
def z_feedrate_code(self, p):
|
||||
return 'G01 F' + str(self.feedrate_format %(p.fr_decimals, p.z_feedrate))
|
||||
return 'G01 F' + str(self.feedrate_format % (p.fr_decimals, p.z_feedrate))
|
||||
|
||||
def spindle_code(self, p):
|
||||
sdir = {'CW': 'M03', 'CCW': 'M04'}[p.spindledir]
|
||||
|
@ -209,5 +212,5 @@ G00 Z{z_toolchange}
|
|||
if p.dwelltime:
|
||||
return 'G4 P' + str(p.dwelltime)
|
||||
|
||||
def spindle_stop_code(self,p):
|
||||
def spindle_stop_code(self, p):
|
||||
return 'M05'
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
# ########################################################## ##
|
||||
# ##########################################################
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://flatcam.org #
|
||||
# File Author: Matthieu Berthomé #
|
||||
# Date: 5/26/2017 #
|
||||
# MIT Licence #
|
||||
# ########################################################## ##
|
||||
# ##########################################################
|
||||
|
||||
from FlatCAMPostProc import *
|
||||
|
||||
|
||||
class grbl_11(FlatCAMPostProc):
|
||||
|
||||
include_header = True
|
||||
coordinate_format = "%.*f"
|
||||
feedrate_format = '%.*f'
|
||||
|
||||
|
@ -63,32 +64,34 @@ class grbl_11(FlatCAMPostProc):
|
|||
|
||||
gcode += ('G20' if p.units.upper() == 'IN' else 'G21') + "\n"
|
||||
gcode += 'G90\n'
|
||||
gcode += 'G94\n'
|
||||
gcode += 'G17\n'
|
||||
gcode += 'G94\n'
|
||||
|
||||
return gcode
|
||||
|
||||
def startz_code(self, p):
|
||||
if p.startz is not None:
|
||||
return 'G00 Z' + self.coordinate_format%(p.coords_decimals, p.startz)
|
||||
return 'G00 Z' + self.coordinate_format % (p.coords_decimals, p.startz)
|
||||
else:
|
||||
return ''
|
||||
|
||||
def lift_code(self, p):
|
||||
return 'G00 Z' + self.coordinate_format%(p.coords_decimals, p.z_move)
|
||||
return 'G00 Z' + self.coordinate_format % (p.coords_decimals, p.z_move)
|
||||
|
||||
def down_code(self, p):
|
||||
return 'G01 Z' + self.coordinate_format%(p.coords_decimals, p.z_cut)
|
||||
return 'G01 Z' + self.coordinate_format % (p.coords_decimals, p.z_cut)
|
||||
|
||||
def toolchange_code(self, p):
|
||||
z_toolchange = p.z_toolchange
|
||||
toolchangexy = p.xy_toolchange
|
||||
f_plunge = p.f_plunge
|
||||
gcode = ''
|
||||
|
||||
if toolchangexy is not None:
|
||||
x_toolchange = toolchangexy[0]
|
||||
y_toolchange = toolchangexy[1]
|
||||
else:
|
||||
x_toolchange = 0.0
|
||||
y_toolchange = 0.0
|
||||
|
||||
no_drills = 1
|
||||
|
||||
|
@ -161,7 +164,7 @@ M6
|
|||
(MSG, Change to Tool Dia = {toolC})
|
||||
M0
|
||||
G00 Z{z_toolchange}
|
||||
""".format(z_toolchange=self.coordinate_format%(p.coords_decimals, z_toolchange),
|
||||
""".format(z_toolchange=self.coordinate_format % (p.coords_decimals, z_toolchange),
|
||||
tool=int(p.tool),
|
||||
toolC=toolC_formatted)
|
||||
|
||||
|
@ -181,21 +184,21 @@ G00 Z{z_toolchange}
|
|||
|
||||
def linear_code(self, p):
|
||||
return ('G01 ' + self.position_code(p)).format(**p) + \
|
||||
' F' + str(self.feedrate_format %(p.fr_decimals, p.feedrate))
|
||||
' F' + str(self.feedrate_format % (p.fr_decimals, p.feedrate))
|
||||
|
||||
def end_code(self, p):
|
||||
coords_xy = p['xy_toolchange']
|
||||
gcode = ('G00 Z' + self.feedrate_format %(p.fr_decimals, p.z_end) + "\n")
|
||||
gcode = ('G00 Z' + self.feedrate_format % (p.fr_decimals, p.z_end) + "\n")
|
||||
|
||||
if coords_xy is not None:
|
||||
gcode += 'G00 X{x} Y{y}'.format(x=coords_xy[0], y=coords_xy[1]) + "\n"
|
||||
return gcode
|
||||
|
||||
def feedrate_code(self, p):
|
||||
return 'G01 F' + str(self.feedrate_format %(p.fr_decimals, p.feedrate))
|
||||
return 'G01 F' + str(self.feedrate_format % (p.fr_decimals, p.feedrate))
|
||||
|
||||
def z_feedrate_code(self, p):
|
||||
return 'G01 F' + str(self.feedrate_format %(p.fr_decimals, p.z_feedrate))
|
||||
return 'G01 F' + str(self.feedrate_format % (p.fr_decimals, p.z_feedrate))
|
||||
|
||||
def spindle_code(self, p):
|
||||
sdir = {'CW': 'M03', 'CCW': 'M04'}[p.spindledir]
|
||||
|
@ -208,5 +211,5 @@ G00 Z{z_toolchange}
|
|||
if p.dwelltime:
|
||||
return 'G4 P' + str(p.dwelltime)
|
||||
|
||||
def spindle_stop_code(self,p):
|
||||
def spindle_stop_code(self, p):
|
||||
return 'M05'
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
# ########################################################## ##
|
||||
# ##########################################################
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://flatcam.org #
|
||||
# File Author: Matthieu Berthomé #
|
||||
# Date: 5/26/2017 #
|
||||
# MIT Licence #
|
||||
# ########################################################## ##
|
||||
# ##########################################################
|
||||
|
||||
from FlatCAMPostProc import *
|
||||
|
||||
|
@ -14,6 +14,7 @@ from FlatCAMPostProc import *
|
|||
|
||||
class grbl_laser(FlatCAMPostProc):
|
||||
|
||||
include_header = True
|
||||
coordinate_format = "%.*f"
|
||||
feedrate_format = '%.*f'
|
||||
|
||||
|
@ -34,15 +35,15 @@ class grbl_laser(FlatCAMPostProc):
|
|||
if str(p['options']['type']) == 'Excellon' or str(p['options']['type']) == 'Excellon Geometry':
|
||||
gcode += '(Preprocessor Excellon: ' + str(p['pp_excellon_name']) + ')\n'
|
||||
else:
|
||||
gcode += '(Preprocessor Geometry: ' + str(p['pp_geometry_name']) + ')\n'
|
||||
gcode += ('G20' if p.units.upper() == 'IN' else 'G21') + "\n" + '\n'
|
||||
gcode += '(Preprocessor Geometry: ' + str(p['pp_geometry_name']) + ')\n' + '\n'
|
||||
|
||||
gcode += '(X range: ' + '{: >9s}'.format(xmin) + ' ... ' + '{: >9s}'.format(xmax) + ' ' + units + ')\n'
|
||||
gcode += '(Y range: ' + '{: >9s}'.format(ymin) + ' ... ' + '{: >9s}'.format(ymax) + ' ' + units + ')\n\n'
|
||||
|
||||
gcode += ('G20' if p.units.upper() == 'IN' else 'G21') + "\n"
|
||||
gcode += 'G90\n'
|
||||
gcode += 'G94\n'
|
||||
gcode += 'G17\n'
|
||||
gcode += 'G94\n'
|
||||
|
||||
return gcode
|
||||
|
||||
|
@ -73,21 +74,21 @@ class grbl_laser(FlatCAMPostProc):
|
|||
|
||||
def linear_code(self, p):
|
||||
return ('G01 ' + self.position_code(p)).format(**p) + \
|
||||
' F' + str(self.feedrate_format %(p.fr_decimals, p.feedrate))
|
||||
' F' + str(self.feedrate_format % (p.fr_decimals, p.feedrate))
|
||||
|
||||
def end_code(self, p):
|
||||
coords_xy = p['xy_toolchange']
|
||||
gcode = ('G00 Z' + self.feedrate_format %(p.fr_decimals, p.z_end) + "\n")
|
||||
gcode = ('G00 Z' + self.feedrate_format % (p.fr_decimals, p.z_end) + "\n")
|
||||
|
||||
if coords_xy is not None:
|
||||
gcode += 'G00 X{x} Y{y}'.format(x=coords_xy[0], y=coords_xy[1]) + "\n"
|
||||
return gcode
|
||||
|
||||
def feedrate_code(self, p):
|
||||
return 'G01 F' + str(self.feedrate_format %(p.fr_decimals, p.feedrate))
|
||||
return 'G01 F' + str(self.feedrate_format % (p.fr_decimals, p.feedrate))
|
||||
|
||||
def z_feedrate_code(self, p):
|
||||
return 'G01 F' + str(self.feedrate_format %(p.fr_decimals, p.z_feedrate))
|
||||
return 'G01 F' + str(self.feedrate_format % (p.fr_decimals, p.z_feedrate))
|
||||
|
||||
def spindle_code(self, p):
|
||||
sdir = {'CW': 'M03', 'CCW': 'M04'}[p.spindledir]
|
||||
|
@ -99,5 +100,5 @@ class grbl_laser(FlatCAMPostProc):
|
|||
def dwell_code(self, p):
|
||||
return ''
|
||||
|
||||
def spindle_stop_code(self,p):
|
||||
def spindle_stop_code(self, p):
|
||||
return 'M05'
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
# ########################################################## ##
|
||||
# ##########################################################
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://flatcam.org #
|
||||
# File Author: Marius Adrian Stanciu (c) #
|
||||
# Date: 3/10/2019 #
|
||||
# MIT Licence #
|
||||
# ########################################################## ##
|
||||
# ##########################################################
|
||||
|
||||
from FlatCAMPostProc import *
|
||||
|
||||
|
@ -12,11 +12,12 @@ from FlatCAMPostProc import *
|
|||
# for Roland Preprocessors it is mandatory for the preprocessor name (python file and class name, both of them must be
|
||||
# the same) to contain the following keyword, case-sensitive: 'Roland' without the quotes.
|
||||
class hpgl(FlatCAMPostProc):
|
||||
|
||||
include_header = True
|
||||
coordinate_format = "%.*f"
|
||||
|
||||
def start_code(self, p):
|
||||
gcode = 'IN;'
|
||||
gcode = 'IN;\n'
|
||||
gcode += 'PU;'
|
||||
return gcode
|
||||
|
||||
def startz_code(self, p):
|
||||
|
@ -49,8 +50,19 @@ class hpgl(FlatCAMPostProc):
|
|||
y = p.y
|
||||
|
||||
# we need to have the coordinates as multiples of 0.025mm
|
||||
x = round(x / 0.025) * 25 / 1000
|
||||
y = round(y / 0.025) * 25 / 1000
|
||||
x = round(x * 40)
|
||||
y = round(y * 40)
|
||||
|
||||
# constrain the x and y values within the domain of valid values: [-32767 ... 32768]
|
||||
if x <= -32767:
|
||||
x = -32767
|
||||
if x >= 32768:
|
||||
x = 32768
|
||||
|
||||
if y <= -32767:
|
||||
y = -32767
|
||||
if y >= 32768:
|
||||
y = 32768
|
||||
|
||||
return ('PA' + self.coordinate_format + ',' + self.coordinate_format + ';') % \
|
||||
(p.coords_decimals, x, p.coords_decimals, y)
|
||||
|
@ -80,5 +92,5 @@ class hpgl(FlatCAMPostProc):
|
|||
def dwell_code(self, p):
|
||||
return ''
|
||||
|
||||
def spindle_stop_code(self,p):
|
||||
def spindle_stop_code(self, p):
|
||||
return ''
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
# ########################################################## ##
|
||||
# ##########################################################
|
||||
# FlatCAM: 2D Post-processing for Manufacturing #
|
||||
# http://flatcam.org #
|
||||
# File Author: Marius Adrian Stanciu (c) #
|
||||
# Date: 3/10/2019 #
|
||||
# MIT Licence #
|
||||
# ########################################################## ##
|
||||
# ##########################################################
|
||||
|
||||
from FlatCAMPostProc import *
|
||||
|
||||
|
||||
class line_xyz(FlatCAMPostProc):
|
||||
|
||||
include_header = True
|
||||
coordinate_format = "%.*f"
|
||||
feedrate_format = '%.*f'
|
||||
|
||||
|
@ -69,9 +70,9 @@ class line_xyz(FlatCAMPostProc):
|
|||
|
||||
def startz_code(self, p):
|
||||
if p.startz is not None:
|
||||
g = 'G00 ' + 'X' + self.coordinate_format%(p.coords_decimals, p.x) + \
|
||||
' Y' + self.coordinate_format%(p.coords_decimals, p.y) + \
|
||||
' Z' + self.coordinate_format%(p.coords_decimals, p.startz)
|
||||
g = 'G00 ' + 'X' + self.coordinate_format % (p.coords_decimals, p.x) + \
|
||||
' Y' + self.coordinate_format % (p.coords_decimals, p.y) + \
|
||||
' Z' + self.coordinate_format % (p.coords_decimals, p.startz)
|
||||
return g
|
||||
else:
|
||||
return ''
|
||||
|
@ -92,7 +93,6 @@ class line_xyz(FlatCAMPostProc):
|
|||
z_toolchange = p.z_toolchange
|
||||
xy_toolchange = p.xy_toolchange
|
||||
f_plunge = p.f_plunge
|
||||
gcode = ''
|
||||
|
||||
if xy_toolchange is not None:
|
||||
x_toolchange = xy_toolchange[0]
|
||||
|
@ -122,7 +122,7 @@ G00 X{x_toolchange} Y{x_toolchange} Z{z_toolchange}
|
|||
T{tool}
|
||||
M6
|
||||
(MSG, Change to Tool Dia = {toolC} ||| Total drills for tool T{tool} = {t_drills})
|
||||
M0""".format(x_toolchange=self.coordinate_format%(p.coords_decimals, x_toolchange),
|
||||
M0""".format(x_toolchange=self.coordinate_format % (p.coords_decimals, x_toolchange),
|
||||
y_toolchange=self.coordinate_format % (p.coords_decimals, y_toolchange),
|
||||
z_toolchange=self.coordinate_format % (p.coords_decimals, z_toolchange),
|
||||
tool=int(p.tool),
|
||||
|
@ -131,7 +131,7 @@ M0""".format(x_toolchange=self.coordinate_format%(p.coords_decimals, x_toolchang
|
|||
|
||||
if f_plunge is True:
|
||||
gcode += """\nG00 X{x_toolchange} Y{x_toolchange} Z{z_move}""".format(
|
||||
x_toolchange=self.coordinate_format%(p.coords_decimals, x_toolchange),
|
||||
x_toolchange=self.coordinate_format % (p.coords_decimals, x_toolchange),
|
||||
y_toolchange=self.coordinate_format % (p.coords_decimals, y_toolchange),
|
||||
z_move=self.coordinate_format % (p.coords_decimals, p.z_move))
|
||||
return gcode
|
||||
|
@ -142,7 +142,7 @@ G00 X{x_toolchange} Y{x_toolchange} Z{z_toolchange}
|
|||
T{tool}
|
||||
M6
|
||||
(MSG, Change to Tool Dia = {toolC})
|
||||
M0""".format(x_toolchange=self.coordinate_format%(p.coords_decimals, x_toolchange),
|
||||
M0""".format(x_toolchange=self.coordinate_format % (p.coords_decimals, x_toolchange),
|
||||
y_toolchange=self.coordinate_format % (p.coords_decimals, y_toolchange),
|
||||
z_toolchange=self.coordinate_format % (p.coords_decimals, z_toolchange),
|
||||
tool=int(p.tool),
|
||||
|
@ -185,10 +185,10 @@ M0""".format(x_toolchange=self.coordinate_format%(p.coords_decimals, x_toolchang
|
|||
return g
|
||||
|
||||
def feedrate_code(self, p):
|
||||
return 'G01 F' + str(self.feedrate_format %(p.fr_decimals, p.feedrate))
|
||||
return 'G01 F' + str(self.feedrate_format % (p.fr_decimals, p.feedrate))
|
||||
|
||||
def z_feedrate_code(self, p):
|
||||
return 'G01 F' + str(self.feedrate_format %(p.fr_decimals, p.z_feedrate))
|
||||
return 'G01 F' + str(self.feedrate_format % (p.fr_decimals, p.z_feedrate))
|
||||
|
||||
def spindle_code(self, p):
|
||||
sdir = {'CW': 'M03', 'CCW': 'M04'}[p.spindledir]
|
||||
|
@ -201,5 +201,5 @@ M0""".format(x_toolchange=self.coordinate_format%(p.coords_decimals, x_toolchang
|
|||
if p.dwelltime:
|
||||
return 'G4 P' + str(p.dwelltime)
|
||||
|
||||
def spindle_stop_code(self,p):
|
||||
def spindle_stop_code(self, p):
|
||||
return 'M05'
|
||||
|
|
|
@ -11,6 +11,7 @@ from FlatCAMPostProc import *
|
|||
|
||||
class marlin(FlatCAMPostProc):
|
||||
|
||||
include_header = True
|
||||
coordinate_format = "%.*f"
|
||||
feedrate_format = '%.*f'
|
||||
feedrate_rapid_format = feedrate_format
|
||||
|
@ -66,6 +67,7 @@ class marlin(FlatCAMPostProc):
|
|||
|
||||
gcode += ('G20' if p.units.upper() == 'IN' else 'G21') + "\n"
|
||||
gcode += 'G90\n'
|
||||
gcode += 'G94\n'
|
||||
|
||||
return gcode
|
||||
|
||||
|
@ -76,20 +78,22 @@ class marlin(FlatCAMPostProc):
|
|||
return ''
|
||||
|
||||
def lift_code(self, p):
|
||||
return 'G0 Z' + self.coordinate_format%(p.coords_decimals, p.z_move) + " " + self.feedrate_rapid_code(p)
|
||||
return 'G0 Z' + self.coordinate_format % (p.coords_decimals, p.z_move) + " " + self.feedrate_rapid_code(p)
|
||||
|
||||
def down_code(self, p):
|
||||
return 'G1 Z' + self.coordinate_format%(p.coords_decimals, p.z_cut) + " " + self.inline_z_feedrate_code(p)
|
||||
return 'G1 Z' + self.coordinate_format % (p.coords_decimals, p.z_cut) + " " + self.inline_z_feedrate_code(p)
|
||||
|
||||
def toolchange_code(self, p):
|
||||
z_toolchange = p.z_toolchange
|
||||
toolchangexy = p.xy_toolchange
|
||||
f_plunge = p.f_plunge
|
||||
gcode = ''
|
||||
|
||||
if toolchangexy is not None:
|
||||
x_toolchange = toolchangexy[0]
|
||||
y_toolchange = toolchangexy[1]
|
||||
else:
|
||||
x_toolchange = 0.0
|
||||
y_toolchange = 0.0
|
||||
|
||||
no_drills = 1
|
||||
|
||||
|
@ -162,7 +166,7 @@ M6
|
|||
;MSG, Change to Tool Dia = {toolC}
|
||||
M0
|
||||
G0 Z{z_toolchange}
|
||||
""".format(z_toolchange=self.coordinate_format%(p.coords_decimals, z_toolchange),
|
||||
""".format(z_toolchange=self.coordinate_format % (p.coords_decimals, z_toolchange),
|
||||
tool=int(p.tool),
|
||||
toolC=toolC_formatted)
|
||||
|
||||
|
@ -185,7 +189,7 @@ G0 Z{z_toolchange}
|
|||
|
||||
def end_code(self, p):
|
||||
coords_xy = p['xy_toolchange']
|
||||
gcode = ('G0 Z' + self.feedrate_format %(p.fr_decimals, p.z_end) + " " + self.feedrate_rapid_code(p) + "\n")
|
||||
gcode = ('G0 Z' + self.feedrate_format % (p.fr_decimals, p.z_end) + " " + self.feedrate_rapid_code(p) + "\n")
|
||||
|
||||
if coords_xy is not None:
|
||||
gcode += 'G0 X{x} Y{y}'.format(x=coords_xy[0], y=coords_xy[1]) + " " + self.feedrate_rapid_code(p) + "\n"
|
||||
|
@ -193,16 +197,16 @@ G0 Z{z_toolchange}
|
|||
return gcode
|
||||
|
||||
def feedrate_code(self, p):
|
||||
return 'G1 F' + str(self.feedrate_format %(p.fr_decimals, p.feedrate))
|
||||
return 'G1 F' + str(self.feedrate_format % (p.fr_decimals, p.feedrate))
|
||||
|
||||
def inline_feedrate_code(self, p):
|
||||
return 'F' + self.feedrate_format %(p.fr_decimals, p.feedrate)
|
||||
return 'F' + self.feedrate_format % (p.fr_decimals, p.feedrate)
|
||||
|
||||
def inline_z_feedrate_code(self, p):
|
||||
return 'F' + self.feedrate_format %(p.fr_decimals, p.z_feedrate)
|
||||
return 'F' + self.feedrate_format % (p.fr_decimals, p.z_feedrate)
|
||||
|
||||
def z_feedrate_code(self, p):
|
||||
return 'G1 F' + str(self.feedrate_format %(p.fr_decimals, p.z_feedrate))
|
||||
return 'G1 F' + str(self.feedrate_format % (p.fr_decimals, p.z_feedrate))
|
||||
|
||||
def feedrate_rapid_code(self, p):
|
||||
return 'F' + self.feedrate_rapid_format % (p.fr_decimals, p.feedrate_rapid)
|
||||
|
@ -218,5 +222,5 @@ G0 Z{z_toolchange}
|
|||
if p.dwelltime:
|
||||
return 'G4 P' + str(p.dwelltime)
|
||||
|
||||
def spindle_stop_code(self,p):
|
||||
def spindle_stop_code(self, p):
|
||||
return 'M5'
|
||||
|
|
Loading…
Reference in New Issue