printrun-src/printrun/gcview.py

changeset 46
cce0af6351f0
parent 15
0bbb006204fc
equal deleted inserted replaced
45:c82943fb205f 46:cce0af6351f0
1 #!/usr/bin/env python 1 #!/usr/bin/env python3
2 2
3 # This file is part of the Printrun suite. 3 # This file is part of the Printrun suite.
4 # 4 #
5 # Printrun is free software: you can redistribute it and/or modify 5 # Printrun is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by 6 # it under the terms of the GNU General Public License as published by
49 if field.startswith("color_"): 49 if field.startswith("color_"):
50 root_fieldname = "gcview_" + field 50 root_fieldname = "gcview_" + field
51 if hasattr(root, root_fieldname): 51 if hasattr(root, root_fieldname):
52 setattr(model, field, getattr(root, root_fieldname)) 52 setattr(model, field, getattr(root, root_fieldname))
53 53
54 def recreate_platform(self, build_dimensions, circular): 54 def recreate_platform(self, build_dimensions, circular, grid):
55 self.platform = actors.Platform(build_dimensions, circular = circular) 55 self.platform = actors.Platform(build_dimensions, circular = circular, grid = grid)
56 self.objects[0].model = self.platform 56 self.objects[0].model = self.platform
57 wx.CallAfter(self.Refresh) 57 wx.CallAfter(self.Refresh)
58 58
59 def set_gcview_params(self, path_width, path_height): 59 def set_gcview_params(self, path_width, path_height):
60 self.path_halfwidth = path_width / 2 60 self.path_halfwidth = path_width / 2
64 if isinstance(obj.model, actors.GcodeModel): 64 if isinstance(obj.model, actors.GcodeModel):
65 obj.model.set_path_size(self.path_halfwidth, self.path_halfheight) 65 obj.model.set_path_size(self.path_halfwidth, self.path_halfheight)
66 has_changed = True 66 has_changed = True
67 return has_changed 67 return has_changed
68 68
69 # E selected for Up because is above D
70 LAYER_UP_KEYS = ord('U'), ord('E'), wx.WXK_UP
71 LAYER_DOWN_KEYS = ord('D'), wx.WXK_DOWN
72 ZOOM_IN_KEYS = wx.WXK_PAGEDOWN, 388, wx.WXK_RIGHT, ord('=')
73 ZOOM_OUT_KEYS = wx.WXK_PAGEUP, 390, wx.WXK_LEFT, ord('-')
74 FIT_KEYS = [ord('F')]
75 CURRENT_LAYER_KEYS = [ord('C')]
76 RESET_KEYS = [ord('R')]
77
69 class GcodeViewPanel(wxGLPanel): 78 class GcodeViewPanel(wxGLPanel):
70 79
71 def __init__(self, parent, id = wx.ID_ANY, 80 def __init__(self, parent,
72 build_dimensions = None, realparent = None, 81 build_dimensions = (200, 200, 100, 0, 0, 0),
73 antialias_samples = 0): 82 realparent = None, antialias_samples = 0):
74 super(GcodeViewPanel, self).__init__(parent, id, wx.DefaultPosition, 83 super().__init__(parent, wx.DefaultPosition,
75 wx.DefaultSize, 0, 84 wx.DefaultSize, 0,
76 antialias_samples = antialias_samples) 85 antialias_samples = antialias_samples)
77 self.canvas.Bind(wx.EVT_MOUSE_EVENTS, self.move) 86 self.canvas.Bind(wx.EVT_MOUSE_EVENTS, self.move)
78 self.canvas.Bind(wx.EVT_LEFT_DCLICK, self.double) 87 self.canvas.Bind(wx.EVT_LEFT_DCLICK, self.double)
79 self.canvas.Bind(wx.EVT_KEY_DOWN, self.keypress) 88 # self.canvas.Bind(wx.EVT_KEY_DOWN, self.keypress)
89 # in Windows event inspector shows only EVT_CHAR_HOOK events
90 self.canvas.Bind(wx.EVT_CHAR_HOOK, self.keypress)
80 self.initialized = 0 91 self.initialized = 0
81 self.canvas.Bind(wx.EVT_MOUSEWHEEL, self.wheel) 92 self.canvas.Bind(wx.EVT_MOUSEWHEEL, self.wheel)
82 self.parent = realparent if realparent else parent 93 self.parent = realparent or parent
83 self.initpos = None 94 self.initpos = None
84 if build_dimensions: 95 self.build_dimensions = build_dimensions
85 self.build_dimensions = build_dimensions 96 self.dist = max(self.build_dimensions[:2])
86 else:
87 self.build_dimensions = [200, 200, 100, 0, 0, 0]
88 self.dist = max(self.build_dimensions[0], self.build_dimensions[1])
89 self.basequat = [0, 0, 0, 1] 97 self.basequat = [0, 0, 0, 1]
90 self.mousepos = [0, 0] 98 self.mousepos = [0, 0]
91 99
92 def inject(self): 100 def inject(self):
93 l = self.parent.model.num_layers_to_draw 101 l = self.parent.model.num_layers_to_draw
94 filtered = [k for k, v in self.parent.model.layer_idxs_map.iteritems() if v == l] 102 filtered = [k for k, v in self.parent.model.layer_idxs_map.items() if v == l]
95 if filtered: 103 if filtered:
96 injector(self.parent.model.gcode, l, filtered[0]) 104 injector(self.parent.model.gcode, l, filtered[0])
97 else: 105 else:
98 logging.error(_("Invalid layer for injection")) 106 logging.error(_("Invalid layer for injection"))
99 107
100 def editlayer(self): 108 def editlayer(self):
101 l = self.parent.model.num_layers_to_draw 109 l = self.parent.model.num_layers_to_draw
102 filtered = [k for k, v in self.parent.model.layer_idxs_map.iteritems() if v == l] 110 filtered = [k for k, v in self.parent.model.layer_idxs_map.items() if v == l]
103 if filtered: 111 if filtered:
104 injector_edit(self.parent.model.gcode, l, filtered[0]) 112 injector_edit(self.parent.model.gcode, l, filtered[0])
105 else: 113 else:
106 logging.error(_("Invalid layer for edition")) 114 logging.error(_("Invalid layer for edition"))
107 115
108 def setlayercb(self, layer): 116 def setlayercb(self, layer):
109 pass 117 pass
110 118
111 def OnInitGL(self, *args, **kwargs): 119 def OnInitGL(self, *args, **kwargs):
112 super(GcodeViewPanel, self).OnInitGL(*args, **kwargs) 120 super().OnInitGL(*args, **kwargs)
113 if hasattr(self.parent, "filenames") and self.parent.filenames: 121 filenames = getattr(self.parent, 'filenames', None)
114 for filename in self.parent.filenames: 122 if filenames:
123 for filename in filenames:
115 self.parent.load_file(filename) 124 self.parent.load_file(filename)
116 self.parent.autoplate() 125 self.parent.autoplate()
117 if hasattr(self.parent, "loadcb"): 126 getattr(self.parent, 'loadcb', bool)()
118 self.parent.loadcb()
119 self.parent.filenames = None 127 self.parent.filenames = None
120 128
121 def create_objects(self): 129 def create_objects(self):
122 '''create opengl objects when opengl is initialized''' 130 '''create opengl objects when opengl is initialized'''
123 for obj in self.parent.objects: 131 for obj in self.parent.objects:
124 if obj.model and obj.model.loaded and not obj.model.initialized: 132 if obj.model and obj.model.loaded and not obj.model.initialized:
125 obj.model.init() 133 obj.model.init()
126 134
127 def update_object_resize(self): 135 def update_object_resize(self):
128 '''called when the window recieves only if opengl is initialized''' 136 '''called when the window receives only if opengl is initialized'''
129 pass 137 pass
130 138
131 def draw_objects(self): 139 def draw_objects(self):
132 '''called in the middle of ondraw after the buffer has been cleared''' 140 '''called in the middle of ondraw after the buffer has been cleared'''
133 self.create_objects() 141 self.create_objects()
140 platformy0 = -self.build_dimensions[4] - self.parent.platform.depth / 2 148 platformy0 = -self.build_dimensions[4] - self.parent.platform.depth / 2
141 glTranslatef(platformx0, platformy0, 0) 149 glTranslatef(platformx0, platformy0, 0)
142 150
143 for obj in self.parent.objects: 151 for obj in self.parent.objects:
144 if not obj.model \ 152 if not obj.model \
145 or not obj.model.loaded \ 153 or not obj.model.loaded:
146 or not obj.model.initialized:
147 continue 154 continue
155 # Skip (comment out) initialized check, which safely causes empty
156 # model during progressive load. This can cause exceptions/garbage
157 # render, but seems fine for now
158 # May need to lock init() and draw_objects() together
159 # if not obj.model.initialized:
160 # continue
148 glPushMatrix() 161 glPushMatrix()
149 glTranslatef(*(obj.offsets)) 162 glTranslatef(*(obj.offsets))
150 glRotatef(obj.rot, 0.0, 0.0, 1.0) 163 glRotatef(obj.rot, 0.0, 0.0, 1.0)
151 glTranslatef(*(obj.centeroffset)) 164 glTranslatef(*(obj.centeroffset))
152 glScalef(*obj.scale) 165 glScalef(*obj.scale)
173 else: 186 else:
174 glGetDoublev(GL_MODELVIEW_MATRIX, mvmat) 187 glGetDoublev(GL_MODELVIEW_MATRIX, mvmat)
175 return mvmat 188 return mvmat
176 189
177 def double(self, event): 190 def double(self, event):
178 if hasattr(self.parent, "clickcb") and self.parent.clickcb: 191 getattr(self.parent, 'clickcb', bool)(event)
179 self.parent.clickcb(event)
180 192
181 def move(self, event): 193 def move(self, event):
182 """react to mouse actions: 194 """react to mouse actions:
183 no mouse: show red mousedrop 195 no mouse: show red mousedrop
184 LMB: rotate viewport 196 LMB: rotate viewport
186 """ 198 """
187 if event.Entering(): 199 if event.Entering():
188 self.canvas.SetFocus() 200 self.canvas.SetFocus()
189 event.Skip() 201 event.Skip()
190 return 202 return
191 if event.Dragging() and event.LeftIsDown(): 203 if event.Dragging():
192 self.handle_rotation(event) 204 if event.LeftIsDown():
193 elif event.Dragging() and event.RightIsDown(): 205 self.handle_rotation(event)
194 self.handle_translation(event) 206 elif event.RightIsDown():
195 elif event.LeftUp(): 207 self.handle_translation(event)
208 self.Refresh(False)
209 elif event.LeftUp() or event.RightUp():
196 self.initpos = None 210 self.initpos = None
197 elif event.RightUp():
198 self.initpos = None
199 else:
200 event.Skip()
201 return
202 event.Skip() 211 event.Skip()
203 wx.CallAfter(self.Refresh)
204 212
205 def layerup(self): 213 def layerup(self):
206 if not hasattr(self.parent, "model") or not self.parent.model: 214 if not getattr(self.parent, 'model', False):
207 return 215 return
208 max_layers = self.parent.model.max_layers 216 max_layers = self.parent.model.max_layers
209 current_layer = self.parent.model.num_layers_to_draw 217 current_layer = self.parent.model.num_layers_to_draw
210 # accept going up to max_layers + 1 218 # accept going up to max_layers + 1
211 # max_layers means visualizing the last layer differently, 219 # max_layers means visualizing the last layer differently,
214 self.parent.model.num_layers_to_draw = new_layer 222 self.parent.model.num_layers_to_draw = new_layer
215 self.parent.setlayercb(new_layer) 223 self.parent.setlayercb(new_layer)
216 wx.CallAfter(self.Refresh) 224 wx.CallAfter(self.Refresh)
217 225
218 def layerdown(self): 226 def layerdown(self):
219 if not hasattr(self.parent, "model") or not self.parent.model: 227 if not getattr(self.parent, 'model', False):
220 return 228 return
221 current_layer = self.parent.model.num_layers_to_draw 229 current_layer = self.parent.model.num_layers_to_draw
222 new_layer = max(1, current_layer - 1) 230 new_layer = max(1, current_layer - 1)
223 self.parent.model.num_layers_to_draw = new_layer 231 self.parent.model.num_layers_to_draw = new_layer
224 self.parent.setlayercb(new_layer) 232 self.parent.setlayercb(new_layer)
225 wx.CallAfter(self.Refresh) 233 wx.CallAfter(self.Refresh)
226 234
235 wheelTimestamp = None
227 def handle_wheel(self, event): 236 def handle_wheel(self, event):
237 if self.wheelTimestamp == event.Timestamp:
238 # filter duplicate event delivery in Ubuntu, Debian issue #1110
239 return
240
241 self.wheelTimestamp = event.Timestamp
242
228 delta = event.GetWheelRotation() 243 delta = event.GetWheelRotation()
229 factor = 1.05 244 factor = 1.05
230 if event.ControlDown(): 245 if event.ControlDown():
231 factor = 1.02 246 factor = 1.02
232 if hasattr(self.parent, "model") and event.ShiftDown(): 247 if hasattr(self.parent, "model") and event.ShiftDown():
235 count = 1 if not event.ControlDown() else 10 250 count = 1 if not event.ControlDown() else 10
236 for i in range(count): 251 for i in range(count):
237 if delta > 0: self.layerup() 252 if delta > 0: self.layerup()
238 else: self.layerdown() 253 else: self.layerdown()
239 return 254 return
240 x, y = event.GetPositionTuple() 255 x, y = event.GetPosition()
241 x, y, _ = self.mouse_to_3d(x, y) 256 x, y, _ = self.mouse_to_3d(x, y)
242 if delta > 0: 257 if delta > 0:
243 self.zoom(factor, (x, y)) 258 self.zoom(factor, (x, y))
244 else: 259 else:
245 self.zoom(1 / factor, (x, y)) 260 self.zoom(1 / factor, (x, y))
267 glScalef(ratio, ratio, 1) 282 glScalef(ratio, ratio, 1)
268 glTranslatef(center_x, center_y, 0) 283 glTranslatef(center_x, center_y, 0)
269 wx.CallAfter(self.Refresh) 284 wx.CallAfter(self.Refresh)
270 285
271 def keypress(self, event): 286 def keypress(self, event):
272 """gets keypress events and moves/rotates acive shape""" 287 """gets keypress events and moves/rotates active shape"""
273 step = 1.1 288 if event.HasModifiers():
274 if event.ControlDown(): 289 # let alt+c bubble up
275 step = 1.05 290 event.Skip()
276 kup = [85, 315] # Up keys 291 return
277 kdo = [68, 317] # Down Keys 292 step = event.ControlDown() and 1.05 or 1.1
278 kzi = [wx.WXK_PAGEDOWN, 388, 316, 61] # Zoom In Keys
279 kzo = [wx.WXK_PAGEUP, 390, 314, 45] # Zoom Out Keys
280 kfit = [70] # Fit to print keys
281 kshowcurrent = [67] # Show only current layer keys
282 kreset = [82] # Reset keys
283 key = event.GetKeyCode() 293 key = event.GetKeyCode()
284 if key in kup: 294 if key in LAYER_UP_KEYS:
285 self.layerup() 295 self.layerup()
286 if key in kdo: 296 return # prevent shifting focus to other controls
297 elif key in LAYER_DOWN_KEYS:
287 self.layerdown() 298 self.layerdown()
288 x, y, _ = self.mouse_to_3d(self.width / 2, self.height / 2) 299 return
289 if key in kzi: 300 # x, y, _ = self.mouse_to_3d(self.width / 2, self.height / 2)
301 elif key in ZOOM_IN_KEYS:
290 self.zoom_to_center(step) 302 self.zoom_to_center(step)
291 if key in kzo: 303 return
304 elif key in ZOOM_OUT_KEYS:
292 self.zoom_to_center(1 / step) 305 self.zoom_to_center(1 / step)
293 if key in kfit: 306 return
307 elif key in FIT_KEYS:
294 self.fit() 308 self.fit()
295 if key in kshowcurrent: 309 elif key in CURRENT_LAYER_KEYS:
296 if not self.parent.model or not self.parent.model.loaded: 310 if not self.parent.model or not self.parent.model.loaded:
297 return 311 return
298 self.parent.model.only_current = not self.parent.model.only_current 312 self.parent.model.only_current = not self.parent.model.only_current
299 wx.CallAfter(self.Refresh) 313 wx.CallAfter(self.Refresh)
300 if key in kreset: 314 elif key in RESET_KEYS:
301 self.resetview() 315 self.resetview()
302 event.Skip() 316 event.Skip()
303 317
304 def resetview(self): 318 def resetview(self):
305 self.canvas.SetCurrent(self.context) 319 self.canvas.SetCurrent(self.context)
306 self.reset_mview(0.9) 320 self.reset_mview(0.9)
307 self.basequat = [0, 0, 0, 1] 321 self.basequat = [0, 0, 0, 1]
308 wx.CallAfter(self.Refresh) 322 wx.CallAfter(self.Refresh)
309 323
310 class GCObject(object): 324 class GCObject:
311 325
312 def __init__(self, model): 326 def __init__(self, model):
313 self.offsets = [0, 0, 0] 327 self.offsets = [0, 0, 0]
314 self.centeroffset = [0, 0, 0] 328 self.centeroffset = [0, 0, 0]
315 self.rot = 0 329 self.rot = 0
316 self.curlayer = 0.0 330 self.curlayer = 0.0
317 self.scale = [1.0, 1.0, 1.0] 331 self.scale = [1.0, 1.0, 1.0]
318 self.model = model 332 self.model = model
319 333
320 class GcodeViewLoader(object): 334 class GcodeViewLoader:
321 335
322 path_halfwidth = 0.2 336 path_halfwidth = 0.2
323 path_halfheight = 0.15 337 path_halfheight = 0.15
324 338
325 def addfile_perlayer(self, gcode = None, showall = False): 339 def addfile_perlayer(self, gcode = None, showall = False):
330 self.objects[-1].model = self.model 344 self.objects[-1].model = self.model
331 if self.root: 345 if self.root:
332 set_model_colors(self.model, self.root) 346 set_model_colors(self.model, self.root)
333 if gcode is not None: 347 if gcode is not None:
334 generator = self.model.load_data(gcode) 348 generator = self.model.load_data(gcode)
335 generator_output = generator.next() 349 generator_output = next(generator)
336 while generator_output is not None: 350 while generator_output is not None:
337 yield generator_output 351 yield generator_output
338 generator_output = generator.next() 352 generator_output = next(generator)
339 wx.CallAfter(self.Refresh) 353 wx.CallAfter(self.Refresh)
340 yield None 354 yield None
341 355
342 def addfile(self, gcode = None, showall = False): 356 def addfile(self, gcode = None, showall = False):
343 generator = self.addfile_perlayer(gcode, showall) 357 generator = self.addfile_perlayer(gcode, showall)
344 while generator.next() is not None: 358 while next(generator) is not None:
345 continue 359 continue
346 360
347 def set_gcview_params(self, path_width, path_height): 361 def set_gcview_params(self, path_width, path_height):
348 return set_gcview_params(self, path_width, path_height) 362 return set_gcview_params(self, path_width, path_height)
349 363
350 class GcodeViewMainWrapper(GcodeViewLoader): 364 from printrun.gviz import BaseViz
351 365 class GcodeViewMainWrapper(GcodeViewLoader, BaseViz):
352 def __init__(self, parent, build_dimensions, root, circular, antialias_samples): 366
367 def __init__(self, parent, build_dimensions, root, circular, antialias_samples, grid):
353 self.root = root 368 self.root = root
354 self.glpanel = GcodeViewPanel(parent, realparent = self, 369 self.glpanel = GcodeViewPanel(parent, realparent = self,
355 build_dimensions = build_dimensions, 370 build_dimensions = build_dimensions,
356 antialias_samples = antialias_samples) 371 antialias_samples = antialias_samples)
357 self.glpanel.SetMinSize((150, 150)) 372 self.glpanel.SetMinSize((150, 150))
359 self.glpanel.color_background = self.root.gcview_color_background 374 self.glpanel.color_background = self.root.gcview_color_background
360 self.clickcb = None 375 self.clickcb = None
361 self.widget = self.glpanel 376 self.widget = self.glpanel
362 self.refresh_timer = wx.CallLater(100, self.Refresh) 377 self.refresh_timer = wx.CallLater(100, self.Refresh)
363 self.p = self # Hack for backwards compatibility with gviz API 378 self.p = self # Hack for backwards compatibility with gviz API
364 self.platform = actors.Platform(build_dimensions, circular = circular) 379 self.grid = grid
380 self.platform = actors.Platform(build_dimensions, circular = circular, grid = grid)
365 self.model = None 381 self.model = None
366 self.objects = [GCObject(self.platform), GCObject(None)] 382 self.objects = [GCObject(self.platform), GCObject(None)]
367 383
368 def __getattr__(self, name): 384 def __getattr__(self, name):
369 return getattr(self.glpanel, name) 385 return getattr(self.glpanel, name)
386
387 def on_settings_change(self, changed_settings):
388 if self.model:
389 for s in changed_settings:
390 if s.name.startswith('gcview_color_'):
391 self.model.update_colors()
392 break
370 393
371 def set_current_gline(self, gline): 394 def set_current_gline(self, gline):
372 if gline.is_move and gline.gcview_end_vertex is not None \ 395 if gline.is_move and gline.gcview_end_vertex is not None \
373 and self.model and self.model.loaded: 396 and self.model and self.model.loaded:
374 self.model.printed_until = gline.gcview_end_vertex 397 self.model.printed_until = gline.gcview_end_vertex
375 if not self.refresh_timer.IsRunning(): 398 if not self.refresh_timer.IsRunning():
376 self.refresh_timer.Start() 399 self.refresh_timer.Start()
377 400
378 def recreate_platform(self, build_dimensions, circular): 401 def recreate_platform(self, build_dimensions, circular, grid):
379 return recreate_platform(self, build_dimensions, circular) 402 return recreate_platform(self, build_dimensions, circular, grid)
380
381 def addgcodehighlight(self, *a):
382 pass
383 403
384 def setlayer(self, layer): 404 def setlayer(self, layer):
385 if layer in self.model.layer_idxs_map: 405 if layer in self.model.layer_idxs_map:
386 viz_layer = self.model.layer_idxs_map[layer] 406 viz_layer = self.model.layer_idxs_map[layer]
387 self.parent.model.num_layers_to_draw = viz_layer 407 self.parent.model.num_layers_to_draw = viz_layer
396 '''A simple class for using OpenGL with wxPython.''' 416 '''A simple class for using OpenGL with wxPython.'''
397 417
398 def __init__(self, parent, ID, title, build_dimensions, objects = None, 418 def __init__(self, parent, ID, title, build_dimensions, objects = None,
399 pos = wx.DefaultPosition, size = wx.DefaultSize, 419 pos = wx.DefaultPosition, size = wx.DefaultSize,
400 style = wx.DEFAULT_FRAME_STYLE, root = None, circular = False, 420 style = wx.DEFAULT_FRAME_STYLE, root = None, circular = False,
401 antialias_samples = 0): 421 antialias_samples = 0,
422 grid = (1, 10)):
402 GvizBaseFrame.__init__(self, parent, ID, title, 423 GvizBaseFrame.__init__(self, parent, ID, title,
403 pos, size, style) 424 pos, size, style)
404 self.root = root 425 self.root = root
405 426
406 panel, vbox = self.create_base_ui() 427 panel, vbox = self.create_base_ui()
407 428
408 self.refresh_timer = wx.CallLater(100, self.Refresh) 429 self.refresh_timer = wx.CallLater(100, self.Refresh)
409 self.p = self # Hack for backwards compatibility with gviz API 430 self.p = self # Hack for backwards compatibility with gviz API
410 self.clonefrom = objects 431 self.clonefrom = objects
411 self.platform = actors.Platform(build_dimensions, circular = circular) 432 self.platform = actors.Platform(build_dimensions, circular = circular, grid = grid)
412 if objects: 433 self.model = objects[1].model if objects else None
413 self.model = objects[1].model
414 else:
415 self.model = None
416 self.objects = [GCObject(self.platform), GCObject(None)] 434 self.objects = [GCObject(self.platform), GCObject(None)]
417 435
418 fit_image = wx.Image(imagefile('fit.png'), wx.BITMAP_TYPE_PNG).ConvertToBitmap() 436 fit_image = wx.Image(imagefile('fit.png'), wx.BITMAP_TYPE_PNG).ConvertToBitmap()
419 self.toolbar.InsertLabelTool(6, 8, " " + _("Fit to plate"), fit_image, 437 self.toolbar.InsertTool(6, 8, " " + _("Fit to plate"), fit_image,
420 shortHelp = _("Fit to plate [F]"), 438 shortHelp = _("Fit to plate [F]"),
421 longHelp = '') 439 longHelp = '')
422 self.toolbar.Realize() 440 self.toolbar.Realize()
423 self.glpanel = GcodeViewPanel(panel, 441 self.glpanel = GcodeViewPanel(panel,
424 build_dimensions = build_dimensions, 442 build_dimensions = build_dimensions,
439 self.layerslider.SetValue(layer) 457 self.layerslider.SetValue(layer)
440 self.update_status("") 458 self.update_status("")
441 459
442 def update_status(self, extra): 460 def update_status(self, extra):
443 layer = self.model.num_layers_to_draw 461 layer = self.model.num_layers_to_draw
444 filtered = [k for k, v in self.model.layer_idxs_map.iteritems() if v == layer] 462 filtered = [k for k, v in self.model.layer_idxs_map.items() if v == layer]
445 if filtered: 463 if filtered:
446 true_layer = filtered[0] 464 true_layer = filtered[0]
447 z = self.model.gcode.all_layers[true_layer].z 465 z = self.model.gcode.all_layers[true_layer].z
448 message = _("Layer %d -%s Z = %.03f mm") % (layer, extra, z) 466 message = _("Layer %d -%s Z = %.03f mm") % (layer, extra, z)
449 else: 467 else:
463 and self.model and self.model.loaded: 481 and self.model and self.model.loaded:
464 self.model.printed_until = gline.gcview_end_vertex 482 self.model.printed_until = gline.gcview_end_vertex
465 if not self.refresh_timer.IsRunning(): 483 if not self.refresh_timer.IsRunning():
466 self.refresh_timer.Start() 484 self.refresh_timer.Start()
467 485
468 def recreate_platform(self, build_dimensions, circular): 486 def recreate_platform(self, build_dimensions, circular, grid):
469 return recreate_platform(self, build_dimensions, circular) 487 return recreate_platform(self, build_dimensions, circular, grid)
470 488
471 def addfile(self, gcode = None): 489 def addfile(self, gcode = None):
472 if self.clonefrom: 490 if self.clonefrom:
473 self.model = self.clonefrom[-1].model.copy() 491 self.model = self.clonefrom[-1].model.copy()
474 self.objects[-1].model = self.model 492 self.objects[-1].model = self.model

mercurial