- finished work in ToolSolderPaste
This commit is contained in:
parent
d5768d3b34
commit
d453c31bf5
|
@ -489,8 +489,11 @@ class App(QtCore.QObject):
|
|||
"tools_solderpaste_z_dispense": self.tools_defaults_form.tools_solderpaste_group.z_dispense_entry,
|
||||
"tools_solderpaste_z_stop": self.tools_defaults_form.tools_solderpaste_group.z_stop_entry,
|
||||
"tools_solderpaste_z_travel": self.tools_defaults_form.tools_solderpaste_group.z_travel_entry,
|
||||
"tools_solderpaste_z_toolchange": self.tools_defaults_form.tools_solderpaste_group.z_toolchange_entry,
|
||||
"tools_solderpaste_xy_toolchange": self.tools_defaults_form.tools_solderpaste_group.xy_toolchange_entry,
|
||||
"tools_solderpaste_frxy": self.tools_defaults_form.tools_solderpaste_group.frxy_entry,
|
||||
"tools_solderpaste_frz": self.tools_defaults_form.tools_solderpaste_group.frz_entry,
|
||||
"tools_solderpaste_frz_dispense": self.tools_defaults_form.tools_solderpaste_group.frz_dispense_entry,
|
||||
"tools_solderpaste_speedfwd": self.tools_defaults_form.tools_solderpaste_group.speedfwd_entry,
|
||||
"tools_solderpaste_dwellfwd": self.tools_defaults_form.tools_solderpaste_group.dwellfwd_entry,
|
||||
"tools_solderpaste_speedrev": self.tools_defaults_form.tools_solderpaste_group.speedrev_entry,
|
||||
|
@ -499,16 +502,13 @@ class App(QtCore.QObject):
|
|||
|
||||
}
|
||||
|
||||
|
||||
#############################
|
||||
#### LOAD POSTPROCESSORS ####
|
||||
#############################
|
||||
|
||||
|
||||
self.postprocessors = load_postprocessors(self)
|
||||
|
||||
for name in list(self.postprocessors.keys()):
|
||||
|
||||
# 'Paste' postprocessors are to be used only in the Solder Paste Dispensing Tool
|
||||
if name.partition('_')[0] == 'Paste':
|
||||
self.tools_defaults_form.tools_solderpaste_group.pp_combo.addItem(name)
|
||||
|
@ -743,13 +743,16 @@ class App(QtCore.QObject):
|
|||
"tools_solderpaste_z_dispense": 0.01,
|
||||
"tools_solderpaste_z_stop": 0.005,
|
||||
"tools_solderpaste_z_travel": 0.1,
|
||||
"tools_solderpaste_z_toolchange": 1.0,
|
||||
"tools_solderpaste_xy_toolchange": "0.0, 0.0",
|
||||
"tools_solderpaste_frxy": 3.0,
|
||||
"tools_solderpaste_frz": 3.0,
|
||||
"tools_solderpaste_frz_dispense": 1.0,
|
||||
"tools_solderpaste_speedfwd": 20,
|
||||
"tools_solderpaste_dwellfwd": 1,
|
||||
"tools_solderpaste_speedrev": 10,
|
||||
"tools_solderpaste_dwellrev": 1,
|
||||
"tools_solderpaste_pp": ''
|
||||
"tools_solderpaste_pp": 'Paste_1'
|
||||
})
|
||||
|
||||
###############################
|
||||
|
@ -1623,14 +1626,14 @@ class App(QtCore.QObject):
|
|||
self.film_tool = Film(self)
|
||||
self.film_tool.install(icon=QtGui.QIcon('share/film16.png'))
|
||||
|
||||
self.paste_tool = ToolSolderPaste(self)
|
||||
self.paste_tool = SolderPaste(self)
|
||||
self.paste_tool.install(icon=QtGui.QIcon('share/solderpastebis32.png'), separator=True)
|
||||
|
||||
self.move_tool = ToolMove(self)
|
||||
self.move_tool.install(icon=QtGui.QIcon('share/move16.png'), pos=self.ui.menuedit,
|
||||
before=self.ui.menueditorigin)
|
||||
|
||||
self.cutout_tool = ToolCutOut(self)
|
||||
self.cutout_tool = CutOut(self)
|
||||
self.cutout_tool.install(icon=QtGui.QIcon('share/cut16.png'), pos=self.ui.menutool,
|
||||
before=self.measurement_tool.menuAction)
|
||||
|
||||
|
|
|
@ -5224,14 +5224,33 @@ class ToolsSolderpastePrefGroupUI(OptionsGroupUI):
|
|||
grid0.addWidget(self.z_travel_label, 5, 0)
|
||||
grid0.addWidget(self.z_travel_entry, 5, 1)
|
||||
|
||||
# Z toolchange location
|
||||
self.z_toolchange_entry = FCEntry()
|
||||
self.z_toolchange_label = QtWidgets.QLabel("Z Toolchange:")
|
||||
self.z_toolchange_label.setToolTip(
|
||||
"The height (Z) for tool (nozzle) change."
|
||||
)
|
||||
grid0.addWidget(self.z_toolchange_label, 6, 0)
|
||||
grid0.addWidget(self.z_toolchange_entry, 6, 1)
|
||||
|
||||
# X,Y Toolchange location
|
||||
self.xy_toolchange_entry = FCEntry()
|
||||
self.xy_toolchange_label = QtWidgets.QLabel("XY Toolchange:")
|
||||
self.xy_toolchange_label.setToolTip(
|
||||
"The X,Y location for tool (nozzle) change.\n"
|
||||
"The format is (x, y) where x and y are real numbers."
|
||||
)
|
||||
grid0.addWidget(self.xy_toolchange_label, 7, 0)
|
||||
grid0.addWidget(self.xy_toolchange_entry, 7, 1)
|
||||
|
||||
# Feedrate X-Y
|
||||
self.frxy_entry = FCEntry()
|
||||
self.frxy_label = QtWidgets.QLabel("Feedrate X-Y:")
|
||||
self.frxy_label.setToolTip(
|
||||
"Feedrate (speed) while moving on the X-Y plane."
|
||||
)
|
||||
grid0.addWidget(self.frxy_label, 6, 0)
|
||||
grid0.addWidget(self.frxy_entry, 6, 1)
|
||||
grid0.addWidget(self.frxy_label, 8, 0)
|
||||
grid0.addWidget(self.frxy_entry, 8, 1)
|
||||
|
||||
# Feedrate Z
|
||||
self.frz_entry = FCEntry()
|
||||
|
@ -5240,8 +5259,18 @@ class ToolsSolderpastePrefGroupUI(OptionsGroupUI):
|
|||
"Feedrate (speed) while moving vertically\n"
|
||||
"(on Z plane)."
|
||||
)
|
||||
grid0.addWidget(self.frz_label, 7, 0)
|
||||
grid0.addWidget(self.frz_entry, 7, 1)
|
||||
grid0.addWidget(self.frz_label, 9, 0)
|
||||
grid0.addWidget(self.frz_entry, 9, 1)
|
||||
|
||||
# Feedrate Z Dispense
|
||||
self.frz_dispense_entry = FCEntry()
|
||||
self.frz_dispense_label = QtWidgets.QLabel("Feedrate Z Dispense:")
|
||||
self.frz_dispense_label.setToolTip(
|
||||
"Feedrate (speed) while moving up vertically\n"
|
||||
" to Dispense position (on Z plane)."
|
||||
)
|
||||
grid0.addWidget(self.frz_dispense_label, 10, 0)
|
||||
grid0.addWidget(self.frz_dispense_entry, 10, 1)
|
||||
|
||||
# Spindle Speed Forward
|
||||
self.speedfwd_entry = FCEntry()
|
||||
|
@ -5250,8 +5279,8 @@ class ToolsSolderpastePrefGroupUI(OptionsGroupUI):
|
|||
"The dispenser speed while pushing solder paste\n"
|
||||
"through the dispenser nozzle."
|
||||
)
|
||||
grid0.addWidget(self.speedfwd_label, 8, 0)
|
||||
grid0.addWidget(self.speedfwd_entry, 8, 1)
|
||||
grid0.addWidget(self.speedfwd_label, 11, 0)
|
||||
grid0.addWidget(self.speedfwd_entry, 11, 1)
|
||||
|
||||
# Dwell Forward
|
||||
self.dwellfwd_entry = FCEntry()
|
||||
|
@ -5259,8 +5288,8 @@ class ToolsSolderpastePrefGroupUI(OptionsGroupUI):
|
|||
self.dwellfwd_label.setToolTip(
|
||||
"Pause after solder dispensing."
|
||||
)
|
||||
grid0.addWidget(self.dwellfwd_label, 9, 0)
|
||||
grid0.addWidget(self.dwellfwd_entry, 9, 1)
|
||||
grid0.addWidget(self.dwellfwd_label, 12, 0)
|
||||
grid0.addWidget(self.dwellfwd_entry, 12, 1)
|
||||
|
||||
# Spindle Speed Reverse
|
||||
self.speedrev_entry = FCEntry()
|
||||
|
@ -5269,8 +5298,8 @@ class ToolsSolderpastePrefGroupUI(OptionsGroupUI):
|
|||
"The dispenser speed while retracting solder paste\n"
|
||||
"through the dispenser nozzle."
|
||||
)
|
||||
grid0.addWidget(self.speedrev_label, 10, 0)
|
||||
grid0.addWidget(self.speedrev_entry, 10, 1)
|
||||
grid0.addWidget(self.speedrev_label, 13, 0)
|
||||
grid0.addWidget(self.speedrev_entry, 13, 1)
|
||||
|
||||
# Dwell Reverse
|
||||
self.dwellrev_entry = FCEntry()
|
||||
|
@ -5279,8 +5308,8 @@ class ToolsSolderpastePrefGroupUI(OptionsGroupUI):
|
|||
"Pause after solder paste dispenser retracted,\n"
|
||||
"to allow pressure equilibrium."
|
||||
)
|
||||
grid0.addWidget(self.dwellrev_label, 11, 0)
|
||||
grid0.addWidget(self.dwellrev_entry, 11, 1)
|
||||
grid0.addWidget(self.dwellrev_label, 14, 0)
|
||||
grid0.addWidget(self.dwellrev_entry, 14, 1)
|
||||
|
||||
# Postprocessors
|
||||
pp_label = QtWidgets.QLabel('PostProcessors:')
|
||||
|
@ -5289,8 +5318,8 @@ class ToolsSolderpastePrefGroupUI(OptionsGroupUI):
|
|||
)
|
||||
|
||||
self.pp_combo = FCComboBox()
|
||||
grid0.addWidget(pp_label, 12, 0)
|
||||
grid0.addWidget(self.pp_combo, 12, 1)
|
||||
grid0.addWidget(pp_label, 15, 0)
|
||||
grid0.addWidget(self.pp_combo, 15, 1)
|
||||
|
||||
self.layout.addStretch()
|
||||
|
||||
|
|
|
@ -4695,6 +4695,9 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob):
|
|||
'''
|
||||
self.exc_cnc_tools = {}
|
||||
|
||||
# flag to store if the CNCJob is part of a special group of CNCJob objects that can't be processed by the
|
||||
# default engine of FlatCAM. They generated by some of tools and are special cases of CNCJob objects.
|
||||
self. special_group = None
|
||||
|
||||
# for now it show if the plot will be done for multi-tool CNCJob (True) or for single tool
|
||||
# (like the one in the TCL Command), False
|
||||
|
@ -4944,11 +4947,22 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob):
|
|||
preamble = str(self.ui.prepend_text.get_value())
|
||||
postamble = str(self.ui.append_text.get_value())
|
||||
|
||||
self.export_gcode(filename, preamble=preamble, postamble=postamble)
|
||||
gc = self.export_gcode(filename, preamble=preamble, postamble=postamble)
|
||||
if gc == 'fail':
|
||||
return
|
||||
|
||||
self.app.file_saved.emit("gcode", filename)
|
||||
self.app.inform.emit("[success] Machine Code file saved to: %s" % filename)
|
||||
|
||||
def on_modifygcode_button_click(self, *args):
|
||||
preamble = str(self.ui.prepend_text.get_value())
|
||||
postamble = str(self.ui.append_text.get_value())
|
||||
gc = self.export_gcode(preamble=preamble, postamble=postamble, to_file=True)
|
||||
if gc == 'fail':
|
||||
return
|
||||
else:
|
||||
self.app.gcode_edited = gc
|
||||
|
||||
# add the tab if it was closed
|
||||
self.app.ui.plot_tab_area.addTab(self.app.ui.cncjob_tab, "Code Editor")
|
||||
|
||||
|
@ -4959,10 +4973,6 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob):
|
|||
# Switch plot_area to CNCJob tab
|
||||
self.app.ui.plot_tab_area.setCurrentWidget(self.app.ui.cncjob_tab)
|
||||
|
||||
preamble = str(self.ui.prepend_text.get_value())
|
||||
postamble = str(self.ui.append_text.get_value())
|
||||
self.app.gcode_edited = self.export_gcode(preamble=preamble, postamble=postamble, to_file=True)
|
||||
|
||||
# first clear previous text in text editor (if any)
|
||||
self.app.ui.code_editor.clear()
|
||||
|
||||
|
@ -5076,6 +5086,14 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob):
|
|||
roland = False
|
||||
hpgl = False
|
||||
|
||||
try:
|
||||
if self.special_group:
|
||||
self.app.inform.emit("[WARNING_NOTCL]This CNCJob object can't be processed because "
|
||||
"it is a %s CNCJob object." % str(self.special_group))
|
||||
return 'fail'
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
# detect if using Roland postprocessor
|
||||
try:
|
||||
for key in self.cnc_tools:
|
||||
|
|
|
@ -20,6 +20,7 @@ class ABCPostProcRegister(ABCMeta):
|
|||
postprocessors[newclass.__name__] = newclass() # here is your register function
|
||||
return newclass
|
||||
|
||||
|
||||
class FlatCAMPostProc(object, metaclass=ABCPostProcRegister):
|
||||
@abstractmethod
|
||||
def start_code(self, p):
|
||||
|
@ -65,6 +66,77 @@ class FlatCAMPostProc(object, metaclass=ABCPostProcRegister):
|
|||
def spindle_stop_code(self,p):
|
||||
pass
|
||||
|
||||
|
||||
class FlatCAMPostProc_Tools(object, metaclass=ABCPostProcRegister):
|
||||
@abstractmethod
|
||||
def start_code(self, p):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def lift_code(self, p):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def down_z_start_code(self, p):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def lift_z_dispense_code(self, p):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def down_z_stop_code(self, p):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def toolchange_code(self, p):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def rapid_code(self, p):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def linear_code(self, p):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def end_code(self, p):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def feedrate_xy_code(self, p):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def feedrate_z_code(self, p):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def feedrate_z_dispense_code(self,p):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def spindle_fwd_code(self,p):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def spindle_rev_code(self,p):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def spindle_off_code(self,p):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def dwell_fwd_code(self,p):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def dwell_rev_code(self,p):
|
||||
pass
|
||||
|
||||
|
||||
def load_postprocessors(app):
|
||||
postprocessors_path_search = [os.path.join(app.data_path,'postprocessors','*.py'),
|
||||
os.path.join('postprocessors', '*.py')]
|
||||
|
|
|
@ -19,6 +19,7 @@ CAD program, and create G-Code for Isolation routing.
|
|||
- added protection against trying to create a CNCJob from a solder_paste dispenser geometry. This one is different than the default Geometry and can be handled only by SolderPaste Tool.
|
||||
- ToolSolderPaste tools (nozzles) now have each it's own settings
|
||||
- creating the camlib functions for the ToolSolderPaste gcode generation functions
|
||||
- finished work in ToolSolderPaste
|
||||
|
||||
20.02.2019
|
||||
|
||||
|
|
241
camlib.py
241
camlib.py
|
@ -4503,6 +4503,9 @@ class CNCjob(Geometry):
|
|||
self.pp_excellon_name = pp_excellon_name
|
||||
self.pp_excellon = self.app.postprocessors[self.pp_excellon_name]
|
||||
|
||||
self.pp_solderpaste_name = None
|
||||
|
||||
|
||||
# Controls if the move from Z_Toolchange to Z_Move is done fast with G0 or normally with G1
|
||||
self.f_plunge = None
|
||||
|
||||
|
@ -4527,6 +4530,8 @@ class CNCjob(Geometry):
|
|||
self.oldx = None
|
||||
self.oldy = None
|
||||
|
||||
self.tool = 0.0
|
||||
|
||||
# Attributes to be included in serialization
|
||||
# Always append to it because it carries contents
|
||||
# from Geometry.
|
||||
|
@ -5191,99 +5196,6 @@ class CNCjob(Geometry):
|
|||
|
||||
return self.gcode
|
||||
|
||||
def generate_gcode_from_solderpaste_geo(self, **kwargs):
|
||||
"""
|
||||
Algorithm to generate from multitool Geometry.
|
||||
|
||||
Algorithm description:
|
||||
----------------------
|
||||
Uses RTree to find the nearest path to follow.
|
||||
|
||||
:return: Gcode string
|
||||
"""
|
||||
|
||||
log.debug("Generate_from_solderpaste_geometry()")
|
||||
|
||||
## Index first and last points in paths
|
||||
# What points to index.
|
||||
def get_pts(o):
|
||||
return [o.coords[0], o.coords[-1]]
|
||||
|
||||
self.gcode = ""
|
||||
|
||||
if not kwargs:
|
||||
log.debug("camlib.generate_from_solderpaste_geo() --> No tool in the solderpaste geometry.")
|
||||
self.app.inform.emit("[ERROR_NOTCL] There is no tool data in the SolderPaste geometry.")
|
||||
|
||||
|
||||
# this is the tool diameter, it is used as such to accommodate the postprocessor who need the tool diameter
|
||||
# given under the name 'toolC'
|
||||
|
||||
self.postdata['toolC'] = kwargs['tooldia']
|
||||
|
||||
# Initial G-Code
|
||||
pp_solderpaste_name = kwargs['data']['tools_solderpaste_pp'] if kwargs['data']['tools_solderpaste_pp'] else \
|
||||
self.app.defaults['tools_solderpaste_pp']
|
||||
p = self.app.postprocessors[pp_solderpaste_name]
|
||||
|
||||
self.gcode = self.doformat(p.start_code)
|
||||
|
||||
## Flatten the geometry. Only linear elements (no polygons) remain.
|
||||
flat_geometry = self.flatten(kwargs['solid_geometry'], pathonly=True)
|
||||
log.debug("%d paths" % len(flat_geometry))
|
||||
|
||||
# Create the indexed storage.
|
||||
storage = FlatCAMRTreeStorage()
|
||||
storage.get_points = get_pts
|
||||
|
||||
# Store the geometry
|
||||
log.debug("Indexing geometry before generating G-Code...")
|
||||
for shape in flat_geometry:
|
||||
if shape is not None:
|
||||
storage.insert(shape)
|
||||
|
||||
# kwargs length will tell actually the number of tools used so if we have more than one tools then
|
||||
# we have toolchange event
|
||||
if len(kwargs) > 1:
|
||||
self.gcode += self.doformat(p.toolchange_code)
|
||||
else:
|
||||
self.gcode += self.doformat(p.lift_code, x=0, y=0) # Move (up) to travel height
|
||||
|
||||
## Iterate over geometry paths getting the nearest each time.
|
||||
log.debug("Starting SolderPaste G-Code...")
|
||||
path_count = 0
|
||||
current_pt = (0, 0)
|
||||
|
||||
pt, geo = storage.nearest(current_pt)
|
||||
|
||||
try:
|
||||
while True:
|
||||
path_count += 1
|
||||
|
||||
# Remove before modifying, otherwise deletion will fail.
|
||||
storage.remove(geo)
|
||||
|
||||
# If last point in geometry is the nearest but prefer the first one if last point == first point
|
||||
# then reverse coordinates.
|
||||
if pt != geo.coords[0] and pt == geo.coords[-1]:
|
||||
geo.coords = list(geo.coords)[::-1]
|
||||
|
||||
self.gcode += self.create_soldepaste_gcode(geo, p=p)
|
||||
current_pt = geo.coords[-1]
|
||||
pt, geo = storage.nearest(current_pt) # Next
|
||||
|
||||
except StopIteration: # Nothing found in storage.
|
||||
pass
|
||||
|
||||
log.debug("Finishing SolderPste G-Code... %s paths traced." % path_count)
|
||||
|
||||
# Finish
|
||||
self.gcode += self.doformat(p.lift_code)
|
||||
self.gcode += self.doformat(p.end_code)
|
||||
|
||||
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,
|
||||
|
@ -5536,41 +5448,152 @@ class CNCjob(Geometry):
|
|||
|
||||
return self.gcode
|
||||
|
||||
def generate_gcode_from_solderpaste_geo(self, **kwargs):
|
||||
"""
|
||||
Algorithm to generate from multitool Geometry.
|
||||
|
||||
Algorithm description:
|
||||
----------------------
|
||||
Uses RTree to find the nearest path to follow.
|
||||
|
||||
:return: Gcode string
|
||||
"""
|
||||
|
||||
log.debug("Generate_from_solderpaste_geometry()")
|
||||
|
||||
## Index first and last points in paths
|
||||
# What points to index.
|
||||
def get_pts(o):
|
||||
return [o.coords[0], o.coords[-1]]
|
||||
|
||||
self.gcode = ""
|
||||
|
||||
if not kwargs:
|
||||
log.debug("camlib.generate_from_solderpaste_geo() --> No tool in the solderpaste geometry.")
|
||||
self.app.inform.emit("[ERROR_NOTCL] There is no tool data in the SolderPaste geometry.")
|
||||
|
||||
|
||||
# this is the tool diameter, it is used as such to accommodate the postprocessor who need the tool diameter
|
||||
# given under the name 'toolC'
|
||||
|
||||
self.postdata['z_start'] = kwargs['data']['tools_solderpaste_z_start']
|
||||
self.postdata['z_dispense'] = kwargs['data']['tools_solderpaste_z_dispense']
|
||||
self.postdata['z_stop'] = kwargs['data']['tools_solderpaste_z_stop']
|
||||
self.postdata['z_travel'] = kwargs['data']['tools_solderpaste_z_travel']
|
||||
self.postdata['z_toolchange'] = kwargs['data']['tools_solderpaste_z_toolchange']
|
||||
self.postdata['xy_toolchange'] = kwargs['data']['tools_solderpaste_xy_toolchange']
|
||||
self.postdata['frxy'] = kwargs['data']['tools_solderpaste_frxy']
|
||||
self.postdata['frz'] = kwargs['data']['tools_solderpaste_frz']
|
||||
self.postdata['frz_dispense'] = kwargs['data']['tools_solderpaste_frz_dispense']
|
||||
self.postdata['speedfwd'] = kwargs['data']['tools_solderpaste_speedfwd']
|
||||
self.postdata['dwellfwd'] = kwargs['data']['tools_solderpaste_dwellfwd']
|
||||
self.postdata['speedrev'] = kwargs['data']['tools_solderpaste_speedrev']
|
||||
self.postdata['dwellrev'] = kwargs['data']['tools_solderpaste_dwellrev']
|
||||
self.postdata['pp_solderpaste_name'] = kwargs['data']['tools_solderpaste_pp']
|
||||
|
||||
self.postdata['toolC'] = kwargs['tooldia']
|
||||
|
||||
self.pp_solderpaste_name = kwargs['data']['tools_solderpaste_pp'] if kwargs['data']['tools_solderpaste_pp'] \
|
||||
else self.app.defaults['tools_solderpaste_pp']
|
||||
p = self.app.postprocessors[self.pp_solderpaste_name]
|
||||
|
||||
## Flatten the geometry. Only linear elements (no polygons) remain.
|
||||
flat_geometry = self.flatten(kwargs['solid_geometry'], pathonly=True)
|
||||
log.debug("%d paths" % len(flat_geometry))
|
||||
|
||||
# Create the indexed storage.
|
||||
storage = FlatCAMRTreeStorage()
|
||||
storage.get_points = get_pts
|
||||
|
||||
# Store the geometry
|
||||
log.debug("Indexing geometry before generating G-Code...")
|
||||
for shape in flat_geometry:
|
||||
if shape is not None:
|
||||
storage.insert(shape)
|
||||
|
||||
# Initial G-Code
|
||||
self.gcode = self.doformat(p.start_code)
|
||||
self.gcode += self.doformat(p.spindle_off_code)
|
||||
self.gcode += self.doformat(p.toolchange_code)
|
||||
|
||||
## Iterate over geometry paths getting the nearest each time.
|
||||
log.debug("Starting SolderPaste G-Code...")
|
||||
path_count = 0
|
||||
current_pt = (0, 0)
|
||||
|
||||
pt, geo = storage.nearest(current_pt)
|
||||
|
||||
try:
|
||||
while True:
|
||||
path_count += 1
|
||||
|
||||
# Remove before modifying, otherwise deletion will fail.
|
||||
storage.remove(geo)
|
||||
|
||||
# If last point in geometry is the nearest but prefer the first one if last point == first point
|
||||
# then reverse coordinates.
|
||||
if pt != geo.coords[0] and pt == geo.coords[-1]:
|
||||
geo.coords = list(geo.coords)[::-1]
|
||||
|
||||
self.gcode += self.create_soldepaste_gcode(geo, p=p)
|
||||
current_pt = geo.coords[-1]
|
||||
pt, geo = storage.nearest(current_pt) # Next
|
||||
|
||||
except StopIteration: # Nothing found in storage.
|
||||
pass
|
||||
|
||||
log.debug("Finishing SolderPste G-Code... %s paths traced." % path_count)
|
||||
|
||||
# Finish
|
||||
self.gcode += self.doformat(p.lift_code)
|
||||
self.gcode += self.doformat(p.end_code)
|
||||
|
||||
return self.gcode
|
||||
|
||||
def create_soldepaste_gcode(self, geometry, p):
|
||||
gcode = ''
|
||||
path = self.segment(geometry.coords)
|
||||
path = geometry.coords
|
||||
|
||||
if type(geometry) == LineString or type(geometry) == LinearRing:
|
||||
# Move fast to 1st point
|
||||
gcode += self.doformat(p.rapid_code) # Move to first point
|
||||
gcode += self.doformat(p.rapid_code, x=path[0][0], y=path[0][1]) # Move to first point
|
||||
|
||||
# Move down to cutting depth
|
||||
gcode += self.doformat(p.feedrate_z_code)
|
||||
gcode += self.doformat(p.down_z_start_code)
|
||||
gcode += self.doformat(p.spindle_on_fwd_code) # Start dispensing
|
||||
gcode += self.doformat(p.spindle_fwd_code) # Start dispensing
|
||||
gcode += self.doformat(p.dwell_fwd_code)
|
||||
gcode += self.doformat(p.feedrate_z_dispense_code)
|
||||
gcode += self.doformat(p.lift_z_dispense_code)
|
||||
gcode += self.doformat(p.feedrate_xy_code)
|
||||
|
||||
# Cutting...
|
||||
for pt in path[1:]:
|
||||
gcode += self.doformat(p.linear_code) # Linear motion to point
|
||||
gcode += self.doformat(p.linear_code, x=pt[0], y=pt[1]) # Linear motion to point
|
||||
|
||||
# Up to travelling height.
|
||||
gcode += self.doformat(p.spindle_off_code) # Stop dispensing
|
||||
gcode += self.doformat(p.spindle_on_rev_code)
|
||||
gcode += self.doformat(p.spindle_rev_code)
|
||||
gcode += self.doformat(p.down_z_stop_code)
|
||||
gcode += self.doformat(p.spindle_off_code)
|
||||
gcode += self.doformat(p.dwell_rev_code)
|
||||
gcode += self.doformat(p.feedrate_z_code)
|
||||
gcode += self.doformat(p.lift_code)
|
||||
elif type(geometry) == Point:
|
||||
gcode += self.doformat(p.linear_code) # Move to first point
|
||||
gcode += self.doformat(p.linear_code, x=path[0][0], y=path[0][1]) # Move to first point
|
||||
|
||||
gcode += self.doformat(p.feedrate_z_code)
|
||||
gcode += self.doformat(p.feedrate_z_dispense_code)
|
||||
gcode += self.doformat(p.down_z_start_code)
|
||||
gcode += self.doformat(p.spindle_on_fwd_code) # Start dispensing
|
||||
# TODO A dwell time for dispensing?
|
||||
gcode += self.doformat(p.spindle_fwd_code) # Start dispensing
|
||||
gcode += self.doformat(p.dwell_fwd_code)
|
||||
gcode += self.doformat(p.lift_z_dispense_code)
|
||||
|
||||
gcode += self.doformat(p.spindle_off_code) # Stop dispensing
|
||||
gcode += self.doformat(p.spindle_on_rev_code)
|
||||
gcode += self.doformat(p.down_z_stop_code)
|
||||
gcode += self.doformat(p.spindle_rev_code)
|
||||
gcode += self.doformat(p.spindle_off_code)
|
||||
gcode += self.doformat(p.down_z_stop_code)
|
||||
gcode += self.doformat(p.dwell_rev_code)
|
||||
gcode += self.doformat(p.feedrate_z_code)
|
||||
gcode += self.doformat(p.lift_code)
|
||||
return gcode
|
||||
|
||||
|
@ -5685,7 +5708,8 @@ class CNCjob(Geometry):
|
|||
else:
|
||||
command['Z'] = 0
|
||||
|
||||
elif 'grbl_laser' in self.pp_excellon_name or 'grbl_laser' in self.pp_geometry_name:
|
||||
elif 'grbl_laser' in self.pp_excellon_name or 'grbl_laser' in self.pp_geometry_name or \
|
||||
(self.pp_solderpaste_name is not None and 'Paste' in self.pp_solderpaste_name):
|
||||
match_lsr = re.search(r"X([\+-]?\d+.[\+-]?\d+)\s*Y([\+-]?\d+.[\+-]?\d+)", gline)
|
||||
if match_lsr:
|
||||
command['X'] = float(match_lsr.group(1).replace(" ", ""))
|
||||
|
@ -5699,7 +5723,12 @@ class CNCjob(Geometry):
|
|||
command['Z'] = 1
|
||||
else:
|
||||
command['Z'] = 0
|
||||
|
||||
elif self.pp_solderpaste is not None:
|
||||
if 'Paste' in self.pp_solderpaste:
|
||||
match_paste = re.search(r"X([\+-]?\d+.[\+-]?\d+)\s*Y([\+-]?\d+.[\+-]?\d+)", gline)
|
||||
if match_paste:
|
||||
command['X'] = float(match_paste.group(1).replace(" ", ""))
|
||||
command['Y'] = float(match_paste.group(2).replace(" ", ""))
|
||||
else:
|
||||
match = re.search(r'^\s*([A-Z])\s*([\+\-\.\d\s]+)', gline)
|
||||
while match:
|
||||
|
|
|
@ -1,14 +1,9 @@
|
|||
from FlatCAMTool import FlatCAMTool
|
||||
from copy import copy,deepcopy
|
||||
from ObjectCollection import *
|
||||
from FlatCAMApp import *
|
||||
from PyQt5 import QtGui, QtCore, QtWidgets
|
||||
from GUIElements import IntEntry, RadioSet, LengthEntry, FloatEntry
|
||||
|
||||
from FlatCAMObj import FlatCAMGeometry, FlatCAMExcellon, FlatCAMGerber
|
||||
|
||||
|
||||
class ToolCutOut(FlatCAMTool):
|
||||
class CutOut(FlatCAMTool):
|
||||
|
||||
toolName = "Cutout PCB"
|
||||
|
||||
|
@ -472,4 +467,3 @@ class ToolCutOut(FlatCAMTool):
|
|||
|
||||
def reset_fields(self):
|
||||
self.obj_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex()))
|
||||
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
from FlatCAMTool import FlatCAMTool
|
||||
from copy import copy,deepcopy
|
||||
# from GUIElements import IntEntry, RadioSet, FCEntry
|
||||
# from FlatCAMObj import FlatCAMGeometry, FlatCAMExcellon, FlatCAMGerber
|
||||
from ObjectCollection import *
|
||||
import time
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ from FlatCAMCommon import LoudDict
|
|||
from FlatCAMObj import FlatCAMGeometry, FlatCAMExcellon, FlatCAMGerber
|
||||
|
||||
|
||||
class ToolSolderPaste(FlatCAMTool):
|
||||
class SolderPaste(FlatCAMTool):
|
||||
|
||||
toolName = "Solder Paste Tool"
|
||||
|
||||
|
@ -177,6 +177,23 @@ class ToolSolderPaste(FlatCAMTool):
|
|||
)
|
||||
self.gcode_form_layout.addRow(self.z_travel_label, self.z_travel_entry)
|
||||
|
||||
# Z toolchange location
|
||||
self.z_toolchange_entry = FCEntry()
|
||||
self.z_toolchange_label = QtWidgets.QLabel("Z Toolchange:")
|
||||
self.z_toolchange_label.setToolTip(
|
||||
"The height (Z) for tool (nozzle) change."
|
||||
)
|
||||
self.gcode_form_layout.addRow(self.z_toolchange_label, self.z_toolchange_entry)
|
||||
|
||||
# X,Y Toolchange location
|
||||
self.xy_toolchange_entry = FCEntry()
|
||||
self.xy_toolchange_label = QtWidgets.QLabel("XY Toolchange:")
|
||||
self.xy_toolchange_label.setToolTip(
|
||||
"The X,Y location for tool (nozzle) change.\n"
|
||||
"The format is (x, y) where x and y are real numbers."
|
||||
)
|
||||
self.gcode_form_layout.addRow(self.xy_toolchange_label, self.xy_toolchange_entry)
|
||||
|
||||
# Feedrate X-Y
|
||||
self.frxy_entry = FCEntry()
|
||||
self.frxy_label = QtWidgets.QLabel("Feedrate X-Y:")
|
||||
|
@ -194,6 +211,15 @@ class ToolSolderPaste(FlatCAMTool):
|
|||
)
|
||||
self.gcode_form_layout.addRow(self.frz_label, self.frz_entry)
|
||||
|
||||
# Feedrate Z Dispense
|
||||
self.frz_dispense_entry = FCEntry()
|
||||
self.frz_dispense_label = QtWidgets.QLabel("Feedrate Z Dispense:")
|
||||
self.frz_dispense_label.setToolTip(
|
||||
"Feedrate (speed) while moving up vertically\n"
|
||||
" to Dispense position (on Z plane)."
|
||||
)
|
||||
self.gcode_form_layout.addRow(self.frz_dispense_label, self.frz_dispense_entry)
|
||||
|
||||
# Spindle Speed Forward
|
||||
self.speedfwd_entry = FCEntry()
|
||||
self.speedfwd_label = QtWidgets.QLabel("Spindle Speed FWD:")
|
||||
|
@ -332,6 +358,8 @@ class ToolSolderPaste(FlatCAMTool):
|
|||
self.options = LoudDict()
|
||||
self.form_fields = {}
|
||||
|
||||
self.units = ''
|
||||
|
||||
## Signals
|
||||
self.addtool_btn.clicked.connect(self.on_tool_add)
|
||||
self.deltool_btn.clicked.connect(self.on_tool_delete)
|
||||
|
@ -366,8 +394,11 @@ class ToolSolderPaste(FlatCAMTool):
|
|||
"tools_solderpaste_z_dispense": self.z_dispense_entry,
|
||||
"tools_solderpaste_z_stop": self.z_stop_entry,
|
||||
"tools_solderpaste_z_travel": self.z_travel_entry,
|
||||
"tools_solderpaste_z_toolchange": self.z_toolchange_entry,
|
||||
"tools_solderpaste_xy_toolchange": self.xy_toolchange_entry,
|
||||
"tools_solderpaste_frxy": self.frxy_entry,
|
||||
"tools_solderpaste_frz": self.frz_entry,
|
||||
"tools_solderpaste_frz_dispense": self.frz_dispense_entry,
|
||||
"tools_solderpaste_speedfwd": self.speedfwd_entry,
|
||||
"tools_solderpaste_dwellfwd": self.dwellfwd_entry,
|
||||
"tools_solderpaste_speedrev": self.speedrev_entry,
|
||||
|
@ -707,7 +738,6 @@ class ToolSolderPaste(FlatCAMTool):
|
|||
self.ui_disconnect()
|
||||
|
||||
deleted_tools_list = []
|
||||
|
||||
if all:
|
||||
self.tools.clear()
|
||||
self.build_ui()
|
||||
|
@ -810,12 +840,17 @@ class ToolSolderPaste(FlatCAMTool):
|
|||
|
||||
diagonal_1 = LineString([min, max])
|
||||
diagonal_2 = LineString([min_r, max_r])
|
||||
round_diag_1 = round(diagonal_1.intersection(p).length, 2)
|
||||
round_diag_2 = round(diagonal_2.intersection(p).length, 2)
|
||||
if self.units == 'MM':
|
||||
round_diag_1 = round(diagonal_1.intersection(p).length, 1)
|
||||
round_diag_2 = round(diagonal_2.intersection(p).length, 1)
|
||||
else:
|
||||
round_diag_1 = round(diagonal_1.intersection(p).length, 2)
|
||||
round_diag_2 = round(diagonal_2.intersection(p).length, 2)
|
||||
|
||||
if round_diag_1 == round_diag_2:
|
||||
l = distance((xmin, ymin), (xmax, ymin))
|
||||
h = distance((xmin, ymin), (xmin, ymax))
|
||||
|
||||
if offset >= l /2 or offset >= h / 2:
|
||||
return "fail"
|
||||
if l > h:
|
||||
|
@ -859,7 +894,7 @@ class ToolSolderPaste(FlatCAMTool):
|
|||
geo_obj.tools[tooluid]['offset'] = 'Path'
|
||||
geo_obj.tools[tooluid]['offset_value'] = 0.0
|
||||
geo_obj.tools[tooluid]['type'] = 'SolderPaste'
|
||||
geo_obj.tools[tooluid]['tool_type'] = 'Dispenser Nozzle'
|
||||
geo_obj.tools[tooluid]['tool_type'] = 'DN'
|
||||
|
||||
for g in work_geo:
|
||||
if type(g) == MultiPolygon:
|
||||
|
@ -914,6 +949,8 @@ class ToolSolderPaste(FlatCAMTool):
|
|||
# self.app.ui.notebook.setCurrentWidget(self.app.ui.project_tab)
|
||||
|
||||
def on_view_gcode(self):
|
||||
time_str = "{:%A, %d %B %Y at %H:%M}".format(datetime.now())
|
||||
|
||||
# add the tab if it was closed
|
||||
self.app.ui.plot_tab_area.addTab(self.app.ui.cncjob_tab, "Code Editor")
|
||||
|
||||
|
@ -923,15 +960,40 @@ class ToolSolderPaste(FlatCAMTool):
|
|||
name = self.cnc_obj_combo.currentText()
|
||||
obj = self.app.collection.get_by_name(name)
|
||||
|
||||
try:
|
||||
if obj.special_group != 'solder_paste_tool':
|
||||
self.app.inform.emit("[WARNING_NOTCL]This CNCJob object can't be processed. "
|
||||
"NOT a solder_paste_tool CNCJob object.")
|
||||
return
|
||||
except AttributeError:
|
||||
self.app.inform.emit("[WARNING_NOTCL]This CNCJob object can't be processed. "
|
||||
"NOT a solder_paste_tool CNCJob object.")
|
||||
return
|
||||
|
||||
gcode = '(G-CODE GENERATED BY FLATCAM v%s - www.flatcam.org - Version Date: %s)\n' % \
|
||||
(str(self.app.version), str(self.app.version_date)) + '\n'
|
||||
|
||||
gcode += '(Name: ' + str(name) + ')\n'
|
||||
gcode += '(Type: ' + "G-code from " + str(obj.options['type']) + " for Solder Paste dispenser" + ')\n'
|
||||
|
||||
# if str(p['options']['type']) == 'Excellon' or str(p['options']['type']) == 'Excellon Geometry':
|
||||
# gcode += '(Tools in use: ' + str(p['options']['Tools_in_use']) + ')\n'
|
||||
|
||||
gcode += '(Units: ' + self.units.upper() + ')\n' + "\n"
|
||||
gcode += '(Created on ' + time_str + ')\n' + '\n'
|
||||
|
||||
for tool in obj.cnc_tools:
|
||||
gcode += obj.cnc_tools[tool]['gcode']
|
||||
|
||||
# then append the text from GCode to the text editor
|
||||
try:
|
||||
file = StringIO(obj.gcode)
|
||||
lines = StringIO(gcode)
|
||||
except:
|
||||
self.app.inform.emit("[ERROR_NOTCL] No Gcode in the object...")
|
||||
return
|
||||
|
||||
try:
|
||||
for line in file:
|
||||
for line in lines:
|
||||
proc_line = str(line).strip('\n')
|
||||
self.app.ui.code_editor.append(proc_line)
|
||||
except Exception as e:
|
||||
|
@ -949,6 +1011,11 @@ class ToolSolderPaste(FlatCAMTool):
|
|||
name = self.cnc_obj_combo.currentText()
|
||||
obj = self.app.collection.get_by_name(name)
|
||||
|
||||
if obj.special_group != 'solder_paste_tool':
|
||||
self.app.inform.emit("[WARNING_NOTCL]This CNCJob object can't be processed. "
|
||||
"NOT a solder_paste_tool CNCJob object.")
|
||||
return
|
||||
|
||||
_filter_ = "G-Code Files (*.nc);;G-Code Files (*.txt);;G-Code Files (*.tap);;G-Code Files (*.cnc);;" \
|
||||
"G-Code Files (*.g-code);;All Files (*.*)"
|
||||
|
||||
|
@ -978,7 +1045,8 @@ class ToolSolderPaste(FlatCAMTool):
|
|||
gcode += '(Units: ' + self.units.upper() + ')\n' + "\n"
|
||||
gcode += '(Created on ' + time_str + ')\n' + '\n'
|
||||
|
||||
gcode += obj.gcode
|
||||
for tool in obj.cnc_tools:
|
||||
gcode += obj.cnc_tools[tool]['gcode']
|
||||
lines = StringIO(gcode)
|
||||
|
||||
## Write
|
||||
|
@ -1040,6 +1108,7 @@ class ToolSolderPaste(FlatCAMTool):
|
|||
job_obj.multitool = True
|
||||
job_obj.multigeo = True
|
||||
job_obj.cnc_tools.clear()
|
||||
job_obj.special_group = 'solder_paste_tool'
|
||||
|
||||
job_obj.options['xmin'] = xmin
|
||||
job_obj.options['ymin'] = ymin
|
||||
|
@ -1063,13 +1132,14 @@ class ToolSolderPaste(FlatCAMTool):
|
|||
|
||||
job_obj.coords_decimals = self.app.defaults["cncjob_coords_decimals"]
|
||||
job_obj.fr_decimals = self.app.defaults["cncjob_fr_decimals"]
|
||||
job_obj.tool = int(tooluid_key)
|
||||
|
||||
# Propagate options
|
||||
job_obj.options["tooldia"] = tool_dia
|
||||
job_obj.options['tool_dia'] = tool_dia
|
||||
|
||||
### CREATE GCODE ###
|
||||
res = job_obj.generate_gcode_from_solderpaste_geo(**tool_cnc_dict)
|
||||
res = job_obj.generate_gcode_from_solderpaste_geo(**tooluid_value)
|
||||
|
||||
if res == 'fail':
|
||||
log.debug("FlatCAMGeometry.mtool_gen_cncjob() --> generate_from_geometry2() failed")
|
||||
|
@ -1089,7 +1159,7 @@ class ToolSolderPaste(FlatCAMTool):
|
|||
app_obj.progress.emit(80)
|
||||
|
||||
job_obj.cnc_tools.update({
|
||||
tooluid_key: copy.deepcopy(tool_cnc_dict)
|
||||
tooluid_key: deepcopy(tool_cnc_dict)
|
||||
})
|
||||
tool_cnc_dict.clear()
|
||||
|
||||
|
|
|
@ -6,13 +6,13 @@ from flatcamTools.ToolFilm import Film
|
|||
from flatcamTools.ToolMove import ToolMove
|
||||
from flatcamTools.ToolDblSided import DblSidedTool
|
||||
|
||||
from flatcamTools.ToolCutOut import ToolCutOut
|
||||
from flatcamTools.ToolCutOut import CutOut
|
||||
from flatcamTools.ToolCalculators import ToolCalculator
|
||||
from flatcamTools.ToolProperties import Properties
|
||||
from flatcamTools.ToolImage import ToolImage
|
||||
from flatcamTools.ToolPaint import ToolPaint
|
||||
from flatcamTools.ToolNonCopperClear import NonCopperClear
|
||||
from flatcamTools.ToolTransform import ToolTransform
|
||||
from flatcamTools.ToolSolderPaste import ToolSolderPaste
|
||||
from flatcamTools.ToolSolderPaste import SolderPaste
|
||||
|
||||
from flatcamTools.ToolShell import FCShell
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
from FlatCAMPostProc import *
|
||||
|
||||
|
||||
class Paste_1(FlatCAMPostProc):
|
||||
class Paste_1(FlatCAMPostProc_Tools):
|
||||
|
||||
coordinate_format = "%.*f"
|
||||
feedrate_format = '%.*f'
|
||||
|
||||
def start_code(self, p):
|
||||
units = ' ' + str(p['units']).lower()
|
||||
coords_xy = p['toolchange_xy']
|
||||
coords_xy = [float(eval(a)) for a in p['xy_toolchange'].split(",")]
|
||||
|
||||
gcode = ''
|
||||
|
||||
xmin = '%.*f' % (p.coords_decimals, p['options']['xmin'])
|
||||
|
@ -16,181 +17,135 @@ class Paste_1(FlatCAMPostProc):
|
|||
ymin = '%.*f' % (p.coords_decimals, p['options']['ymin'])
|
||||
ymax = '%.*f' % (p.coords_decimals, p['options']['ymax'])
|
||||
|
||||
if str(p['options']['type']) == 'Geometry':
|
||||
gcode += '(TOOL DIAMETER: ' + str(p['options']['tool_dia']) + units + ')\n'
|
||||
gcode += '(TOOL DIAMETER: ' + str(p['options']['tool_dia']) + units + ')\n'
|
||||
gcode += '(Feedrate_XY: ' + str(p['frxy']) + units + '/min' + ')\n'
|
||||
gcode += '(Feedrate_Z: ' + str(p['frz']) + units + '/min' + ')\n'
|
||||
gcode += '(Feedrate_Z_Dispense: ' + str(p['frz_dispense']) + units + '/min' + ')\n'
|
||||
|
||||
gcode += '(Feedrate: ' + str(p['feedrate']) + units + '/min' + ')\n'
|
||||
gcode += '(Z_Dispense_Start: ' + str(p['z_start']) + units + ')\n'
|
||||
gcode += '(Z_Dispense: ' + str(p['z_dispense']) + units + ')\n'
|
||||
gcode += '(Z_Dispense_Stop: ' + str(p['z_stop']) + units + ')\n'
|
||||
gcode += '(Z_Travel: ' + str(p['z_travel']) + units + ')\n'
|
||||
gcode += '(Z Toolchange: ' + str(p['z_toolchange']) + units + ')\n'
|
||||
|
||||
if str(p['options']['type']) == 'Geometry':
|
||||
gcode += '(Feedrate_Z: ' + str(p['feedrate_z']) + units + '/min' + ')\n'
|
||||
gcode += '(X,Y Toolchange: ' + "%.4f, %.4f" % (coords_xy[0], coords_xy[1]) + units + ')\n'
|
||||
|
||||
gcode += '(Feedrate rapids ' + str(p['feedrate_rapid']) + units + '/min' + ')\n' + '\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['depthpercut']) + units + ' <=>' + \
|
||||
str(math.ceil(abs(p['z_cut']) / p['depthpercut'])) + ' passes' + ')\n'
|
||||
|
||||
gcode += '(Z_Move: ' + str(p['z_move']) + units + ')\n'
|
||||
gcode += '(Z Toolchange: ' + str(p['toolchangez']) + units + ')\n'
|
||||
|
||||
if coords_xy is not None:
|
||||
gcode += '(X,Y Toolchange: ' + "%.4f, %.4f" % (coords_xy[0], 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['endz']) + 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 += '(Postprocessor Excellon: ' + str(p['pp_excellon_name']) + ')\n' + '\n'
|
||||
else:
|
||||
gcode += '(Postprocessor Geometry: ' + str(p['pp_geometry_name']) + ')\n' + '\n'
|
||||
if 'Paste' in p.pp_solderpaste_name:
|
||||
gcode += '(Postprocessor SolderPaste Dispensing Geometry: ' + str(p.pp_solderpaste_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 += '(Spindle Speed: %s RPM)\n' % str(p['spindlespeed'])
|
||||
gcode += '(Spindle Speed FWD: %s RPM)\n' % str(p['speedfwd'])
|
||||
gcode += '(Spindle Speed REV: %s RPM)\n' % str(p['speedrev'])
|
||||
gcode += '(Dwell FWD: %s RPM)\n' % str(p['dwellfwd'])
|
||||
gcode += '(Dwell REV: %s RPM)\n' % str(p['dwellrev'])
|
||||
|
||||
gcode += ('G20\n' if p.units.upper() == 'IN' else 'G21\n')
|
||||
gcode += 'G90\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)
|
||||
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, float(p['z_travel']))
|
||||
|
||||
def down_code(self, p):
|
||||
return 'G01 Z' + self.coordinate_format%(p.coords_decimals, p.z_cut)
|
||||
def down_z_start_code(self, p):
|
||||
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']))
|
||||
|
||||
def down_z_stop_code(self, p):
|
||||
return 'G01 Z' + self.coordinate_format%(p.coords_decimals, float(p['z_stop']))
|
||||
|
||||
def toolchange_code(self, p):
|
||||
toolchangez = p.toolchangez
|
||||
toolchangexy = p.toolchange_xy
|
||||
f_plunge = p.f_plunge
|
||||
toolchangez = float(p['z_toolchange'])
|
||||
toolchangexy = [float(eval(a)) for a in p['xy_toolchange'].split(",")]
|
||||
gcode = ''
|
||||
|
||||
if toolchangexy is not None:
|
||||
toolchangex = toolchangexy[0]
|
||||
toolchangey = toolchangexy[1]
|
||||
|
||||
no_drills = 1
|
||||
|
||||
if int(p.tool) == 1 and p.startz is not None:
|
||||
toolchangez = p.startz
|
||||
|
||||
if p.units.upper() == 'MM':
|
||||
toolC_formatted = format(p.toolC, '.2f')
|
||||
toolC_formatted = format(float(p['toolC']), '.2f')
|
||||
else:
|
||||
toolC_formatted = format(p.toolC, '.4f')
|
||||
toolC_formatted = format(float(p['toolC']), '.4f')
|
||||
|
||||
if str(p['options']['type']) == 'Excellon':
|
||||
for i in p['options']['Tools_in_use']:
|
||||
if i[0] == p.tool:
|
||||
no_drills = i[2]
|
||||
|
||||
if toolchangexy is not None:
|
||||
gcode = """
|
||||
M5
|
||||
G00 Z{toolchangez}
|
||||
G00 X{toolchangex} Y{toolchangey}
|
||||
T{tool}
|
||||
M6
|
||||
(MSG, Change to Tool Dia = {toolC} ||| Total drills for tool T{tool} = {t_drills})
|
||||
M0""".format(toolchangex=self.coordinate_format % (p.coords_decimals, toolchangex),
|
||||
toolchangey=self.coordinate_format % (p.coords_decimals, toolchangey),
|
||||
toolchangez=self.coordinate_format % (p.coords_decimals, toolchangez),
|
||||
tool=int(p.tool),
|
||||
t_drills=no_drills,
|
||||
toolC=toolC_formatted)
|
||||
else:
|
||||
gcode = """
|
||||
M5
|
||||
G00 Z{toolchangez}
|
||||
T{tool}
|
||||
M6
|
||||
(MSG, Change to Tool Dia = {toolC} ||| Total drills for tool T{tool} = {t_drills})
|
||||
M0""".format(toolchangez=self.coordinate_format % (p.coords_decimals, toolchangez),
|
||||
tool=int(p.tool),
|
||||
t_drills=no_drills,
|
||||
toolC=toolC_formatted)
|
||||
if f_plunge is True:
|
||||
gcode += '\nG00 Z%.*f' % (p.coords_decimals, p.z_move)
|
||||
return gcode
|
||||
|
||||
else:
|
||||
if toolchangexy is not None:
|
||||
gcode = """
|
||||
M5
|
||||
if toolchangexy is not None:
|
||||
gcode = """
|
||||
G00 Z{toolchangez}
|
||||
G00 X{toolchangex} Y{toolchangey}
|
||||
T{tool}
|
||||
M6
|
||||
(MSG, Change to Tool Dia = {toolC})
|
||||
M0""".format(toolchangex=self.coordinate_format % (p.coords_decimals, toolchangex),
|
||||
toolchangey=self.coordinate_format % (p.coords_decimals, toolchangey),
|
||||
toolchangez=self.coordinate_format % (p.coords_decimals, toolchangez),
|
||||
tool=int(p.tool),
|
||||
toolC=toolC_formatted)
|
||||
else:
|
||||
gcode = """
|
||||
M5
|
||||
(MSG, Change to Tool with Nozzle Dia = {toolC})
|
||||
M0
|
||||
""".format(toolchangex=self.coordinate_format % (p.coords_decimals, toolchangex),
|
||||
toolchangey=self.coordinate_format % (p.coords_decimals, toolchangey),
|
||||
toolchangez=self.coordinate_format % (p.coords_decimals, toolchangez),
|
||||
tool=int(int(p.tool)),
|
||||
toolC=toolC_formatted)
|
||||
|
||||
else:
|
||||
gcode = """
|
||||
G00 Z{toolchangez}
|
||||
T{tool}
|
||||
M6
|
||||
(MSG, Change to Tool Dia = {toolC})
|
||||
M0""".format(toolchangez=self.coordinate_format%(p.coords_decimals, toolchangez),
|
||||
tool=int(p.tool),
|
||||
toolC=toolC_formatted)
|
||||
(MSG, Change to Tool with Nozzle Dia = {toolC})
|
||||
M0
|
||||
""".format(toolchangez=self.coordinate_format % (p.coords_decimals, toolchangez),
|
||||
tool=int(int(p.tool)),
|
||||
toolC=toolC_formatted)
|
||||
|
||||
if f_plunge is True:
|
||||
gcode += '\nG00 Z%.*f' % (p.coords_decimals, p.z_move)
|
||||
return gcode
|
||||
|
||||
def up_to_zero_code(self, p):
|
||||
return 'G01 Z0'
|
||||
return gcode
|
||||
|
||||
def position_code(self, p):
|
||||
return ('X' + self.coordinate_format + ' Y' + self.coordinate_format) % \
|
||||
(p.coords_decimals, p.x, p.coords_decimals, p.y)
|
||||
|
||||
def rapid_code(self, p):
|
||||
return ('G00 ' + self.position_code(p)).format(**p)
|
||||
return ('G00 ' + self.position_code(p)).format(**p) + '\nG00 Z' + \
|
||||
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 = p['toolchange_xy']
|
||||
gcode = ('G00 Z' + self.feedrate_format %(p.fr_decimals, p.endz) + "\n")
|
||||
coords_xy = [float(eval(a)) for a in p['xy_toolchange'].split(",")]
|
||||
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_code(self, p):
|
||||
return 'G01 F' + str(self.feedrate_format %(p.fr_decimals, p.feedrate))
|
||||
def feedrate_xy_code(self, p):
|
||||
return 'G01 F' + str(self.feedrate_format %(p.fr_decimals, float(p['frxy'])))
|
||||
|
||||
def feedrate_z_code(self, p):
|
||||
return 'G01 F' + str(self.feedrate_format %(p.fr_decimals, p.feedrate_z))
|
||||
return 'G01 F' + str(self.feedrate_format %(p.fr_decimals, float(p['frz'])))
|
||||
|
||||
def spindle_code(self, p):
|
||||
def feedrate_z_dispense_code(self, p):
|
||||
return 'G01 F' + str(self.feedrate_format %(p.fr_decimals, float(p['frz_dispense'])))
|
||||
|
||||
def spindle_fwd_code(self, p):
|
||||
if p.spindlespeed:
|
||||
return 'M03 S' + str(p.spindlespeed)
|
||||
return 'M03 S' + str(float(p['speedfwd']))
|
||||
else:
|
||||
return 'M03'
|
||||
|
||||
def dwell_code(self, p):
|
||||
if p.dwelltime:
|
||||
return 'G4 P' + str(p.dwelltime)
|
||||
def spindle_rev_code(self, p):
|
||||
if p.spindlespeed:
|
||||
return 'M04 S' + str(float(p['speedrev']))
|
||||
else:
|
||||
return 'M04'
|
||||
|
||||
def spindle_stop_code(self,p):
|
||||
def spindle_off_code(self,p):
|
||||
return 'M05'
|
||||
|
||||
def dwell_fwd_code(self, p):
|
||||
if p.dwelltime:
|
||||
return 'G4 P' + str(float(p['dwellfwd']))
|
||||
|
||||
def dwell_rev_code(self, p):
|
||||
if p.dwelltime:
|
||||
return 'G4 P' + str(float(p['dwellrev']))
|
||||
|
|
Loading…
Reference in New Issue