Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Print from layer #1197

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions printrun/gcview.py
Original file line number Diff line number Diff line change
Expand Up @@ -459,17 +459,17 @@ def setlayercb(self, layer):

def update_status(self, extra):
layer = self.model.num_layers_to_draw
filtered = [k for k, v in self.model.layer_idxs_map.items() if v == layer]
if filtered:
true_layer = filtered[0]
z = self.model.gcode.all_layers[true_layer].z
message = _("Layer %d -%s Z = %.03f mm") % (layer, extra, z)
else:
true_layer = next((k for k, v in self.model.layer_idxs_map.items() if v == layer), -1)
if true_layer == -1:
message = _("Entire object")
else:
z = self.model.gcode.all_layers[true_layer].z
# count the first layer as 0 to match slicer gcode comments
message = _("Layer %d -%s Z = %.03f mm") % (layer-1, extra, z)
wx.CallAfter(self.SetStatusText, message, 0)

def process_slider(self, event):
new_layer = self.layerslider.GetValue()
new_layer = self.layerslider.Value
new_layer = min(self.model.max_layers + 1, new_layer)
new_layer = max(1, new_layer)
self.model.num_layers_to_draw = new_layer
Expand Down
67 changes: 66 additions & 1 deletion printrun/pronterface.py
Original file line number Diff line number Diff line change
Expand Up @@ -660,7 +660,7 @@ def btemp_change(self, event):
def tool_change(self, event):
self.do_tool(self.extrudersel.GetValue())

def show_viz_window(self, event):
def show_viz_window(self, event = None):
if self.fgcode:
self.gwindow.Show(True)
self.gwindow.SetToolTip(wx.ToolTip("Mousewheel zooms the display\nShift / Mousewheel scrolls layers"))
Expand Down Expand Up @@ -840,6 +840,10 @@ def create_menu(self):
self.recoverbtn = m.Append(-1, _("Recover"), _(" Recover previous print after a disconnect (homes X, Y, restores Z and E status)"))
self.recoverbtn.Disable = lambda *a: self.recoverbtn.Enable(False)
self.Bind(wx.EVT_MENU, self.recover, self.recoverbtn)

self.print_layer_btn = m.Append(-1, _("Print from layer"), _("Start print from the standalone 3D view layer slider position"))
self.Bind(wx.EVT_MENU, self.print_from_layer, self.print_layer_btn)

self.menustrip.Append(m, _("&Advanced"))

if self.settings.slic3rintegration:
Expand Down Expand Up @@ -1279,6 +1283,67 @@ def on_startprint(self):
wx.CallAfter(self.printbtn.SetLabel, _("Restart"))
wx.CallAfter(self.toolbarsizer.Layout)

def print_from_layer(self, event):
if not self.fgcode:
self.loadfile(None)
return

top_layer = self.gwindow.model.num_layers_to_draw - 1
if self.gwindow.model:
if top_layer not in self.fgcode.layer_idxs:
self.show_viz_window()
msg = _("Select a layer with the slider from which to continue printing")
self.gwindow.SetToolTip(wx.ToolTip(msg))
self.gwindow.SetStatusText(msg)
return

if not self.p.online:
# wx.CallAfter(self.statusbar.SetStatusText, _("Not connected to printer."))
dialog = wx.MessageDialog(self, _("Connect to %s?" % self.serialport.Value), style = wx.YES_NO | wx.YES_DEFAULT | wx.ICON_QUESTION)
if dialog.ShowModal() == wx.ID_YES:
self.connect()
else:
return

# replay skipped commands to track E, coords relativity, temp
first_layer_line = self.fgcode.layer_idxs.index(top_layer)

# collect the last values of state changing cmds and apply them
last_cmds = {}
tracked_cmds = 'M190', 'M104', 'M109'
cmds = []
for ln in self.fgcode.lines[:first_layer_line]:
if ln.command in tracked_cmds:
last_cmds[ln.command] = ln
for cmd in tracked_cmds:
if cmd in last_cmds:
# self.p.send_now(last_cmds[cmd].raw)
cmds.append(last_cmds[cmd].raw)

self.p.analyzer._preprocess(self.fgcode.lines[:first_layer_line])
# explicit handling for cmds canceling each other
cmds.append('G20' if self.p.analyzer.imperial else 'G21')
cmds.append('G91' if self.p.analyzer.relative else 'G90')
cmds.append('M83' if self.p.analyzer.relative_e else 'M82')

if not self.p.analyzer.relative_e:
# the printer did not extrude anything till now,
# so pretend it did, otherwise it will extrude all the skipped
# filament on the next extrusion
cmds.append('G92 E' + str(self.p.analyzer.abs_e))

dialog = wx.MessageDialog(self,
_("Confirm starting commands") + ':\n'
+ '\n'.join(cmds + [ln.raw for ln in self.fgcode.lines[first_layer_line:first_layer_line + 10]]),
style = wx.OK | wx.CANCEL | wx.CANCEL_DEFAULT | wx.ICON_QUESTION)
if dialog.ShowModal() == wx.ID_OK:
for cmd in cmds:
self.p.send_now(cmd)

self.gviz.model.num_layers_to_draw = self.gviz.model.max_layers + 1
self.p.startprint(self.fgcode, first_layer_line)
self.on_startprint()

def printfile(self, event=None):
self.extra_print_time = 0
if self.paused:
Expand Down
43 changes: 34 additions & 9 deletions testtools/mock-printer.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,49 @@
# ...> load sliced.gcode
# ...> print
# ...> etc...
import socket
import socket, re
import time

def send(line):
c.write((line + "\n").encode('ascii'))
c.flush()

with socket.socket() as s:
s.bind(('127.0.0.1', 8080))
addr = '127.0.0.1', 8080
s.bind(addr)
s.listen(1)
c, addr = s.accept()
print('Listening. You can connect from pronterface to %s:%d' % addr)
cs, addr = s.accept()
print(cs)
#text mode causes loss of incoming lines in Ubuntu 20.04.2 LTS, python 3.8.5
c = cs.makefile('rwb') # , encoding='utf8', newline="\n"
print(c)
temp = 0
pos = {'X': 0, 'Y': 0, 'Z': 0, 'F': 0}
try:
c.sendall(b'start\n')
#c.sendall(b'start\n')
send('start')
while True:
msg = c.recv(1024)
# for msg in c:
#msg = c.recv(1024).decode('ascii').strip()
time.sleep(1/20.)
msg = c.readline().decode('utf8').strip()
print('(', msg, ')')
if not msg:
break
print(msg)
if msg == b'M105\n':
c.sendall(('ok T:%d\n'%(20 + temp)).encode('ascii'))
if msg == 'M105':
send('ok T:%d'%(20 + temp))
temp = (temp + 1)%30
elif msg == 'M114':
send(f'ok C: X:{pos["X"]} Y:{pos["Y"]} Z:{pos["Z"]} E:1')
else:
c.sendall(b'ok\n')
m = re.match('^G0 ([XYZF])([-0-9.]+)', msg)
if m:
pos[m.group(1)] += float(m.group(2))
print(pos)

send('ok')
finally:
c.close()
cs.close()
s.close()