Package printrun_utilities :: Module gviz
[hide private]
[frames] | no frames]

Source Code for Module printrun_utilities.gviz

  1  """ 
  2  Gcode visualisation class extracted from Printrun application. 
  3   
  4  Credits: 
  5      Original Author: Kliment (https://github.com/kliment/Printrun) 
  6   
  7  """ 
  8  import wx, time, sys 
  9   
10 -class window(wx.Frame):
11 - def __init__(self, f, title="Layer view",size=(600, 600), bedsize=(200, 200), grid=(10, 50), extrusion_width=0.5):
12 wx.Frame.__init__(self, None, title="%s (Use shift+mousewheel to switch layers)"%title, size=(size[0], size[1])) 13 self.p = gviz(self, size=size, bedsize=bedsize, grid=grid, extrusion_width=extrusion_width) 14 s = time.time() 15 for i in f: 16 self.p.addgcode(i) 17 self.initpos = [0, 0] 18 self.p.Bind(wx.EVT_CHAR_HOOK, self.key) 19 self.Bind(wx.EVT_CHAR_HOOK, self.key) 20 self.p.Bind(wx.EVT_MOUSEWHEEL, self.zoom) 21 self.Bind(wx.EVT_MOUSEWHEEL, self.zoom) 22 self.p.Bind(wx.EVT_MOUSE_EVENTS, self.mouse) 23 self.Bind(wx.EVT_MOUSE_EVENTS, self.mouse)
24
25 - def mouse(self, event):
26 if event.ButtonUp(wx.MOUSE_BTN_LEFT): 27 if(self.initpos is not None): 28 self.initpos = None 29 elif event.Dragging(): 30 e = event.GetPositionTuple() 31 if self.initpos is None or not hasattr(self, "basetrans"): 32 self.initpos = e 33 self.basetrans = self.p.translate 34 self.p.translate = [ self.basetrans[0] + (e[0] - self.initpos[0]), 35 self.basetrans[1] + (e[1] - self.initpos[1]) ] 36 self.p.repaint() 37 self.p.Refresh() 38 39 else: 40 event.Skip()
41
42 - def key(self, event):
43 x = event.GetKeyCode() 44 if x == wx.WXK_UP: 45 self.p.layerup() 46 if x == wx.WXK_DOWN: 47 self.p.layerdown()
48
49 - def zoom(self, event):
50 z = event.GetWheelRotation() 51 if event.ShiftDown(): 52 if z > 0: self.p.layerdown() 53 elif z < 0: self.p.layerup() 54 else: 55 if z > 0: self.p.zoom(event.GetX(), event.GetY(), 1.2) 56 elif z < 0: self.p.zoom(event.GetX(), event.GetY(), 1 / 1.2)
57
58 -class gviz(wx.Panel):
59 - def __init__(self, parent, size=(200, 200), bedsize=(200, 200), grid=(10, 50), extrusion_width=0.5):
60 wx.Panel.__init__(self, parent, -1, size=(size[0], size[1])) 61 self.size = size 62 self.bedsize = bedsize 63 self.grid = grid 64 self.lastpos = [0, 0, 0, 0, 0, 0, 0] 65 self.hilightpos = self.lastpos[:] 66 self.Bind(wx.EVT_PAINT, self.paint) 67 self.Bind(wx.EVT_SIZE, lambda * e:(wx.CallAfter(self.repaint), wx.CallAfter(self.Refresh))) 68 self.lines = {} 69 self.pens = {} 70 self.arcs = {} 71 self.arcpens = {} 72 self.layers = [] 73 self.layerindex = 0 74 self.filament_width = extrusion_width # set it to 0 to disable scaling lines with zoom 75 self.scale = [min(float(size[0]) / bedsize[0], float(size[1]) / bedsize[1])] * 2 76 penwidth = max(1.0, self.filament_width * ((self.scale[0] + self.scale[1]) / 2.0)) 77 self.translate = [0.0, 0.0] 78 self.mainpen = wx.Pen(wx.Colour(0, 0, 0), penwidth) 79 self.arcpen = wx.Pen(wx.Colour(255, 0, 0), penwidth) 80 self.travelpen = wx.Pen(wx.Colour(10, 80, 80), penwidth) 81 self.hlpen = wx.Pen(wx.Colour(200, 50, 50), penwidth) 82 self.fades = [wx.Pen(wx.Colour(250 - 0.6 ** i * 100, 250 - 0.6 ** i * 100, 200 - 0.4 ** i * 50), penwidth) for i in xrange(6)] 83 self.penslist = [self.mainpen, self.travelpen, self.hlpen] + self.fades 84 self.showall = 0 85 self.hilight = [] 86 self.hilightarcs = [] 87 self.dirty = 1 88 self.blitmap = wx.EmptyBitmap(self.GetClientSize()[0], self.GetClientSize()[1], -1)
89
90 - def clear(self):
91 self.lastpos = [0, 0, 0, 0, 0, 0, 0] 92 self.lines = {} 93 self.pens = {} 94 self.layers = [] 95 self.layerindex = 0 96 self.showall = 0 97 self.dirty = 1
98
99 - def layerup(self):
100 if(self.layerindex + 1 < len(self.layers)): 101 self.layerindex += 1 102 self.repaint() 103 self.Refresh()
104
105 - def layerdown(self):
106 if(self.layerindex > 0): 107 self.layerindex -= 1 108 self.repaint() 109 self.Refresh()
110
111 - def setlayer(self, layer):
112 try: 113 self.layerindex = self.layers.index(layer) 114 self.repaint() 115 wx.CallAfter(self.Refresh) 116 self.showall = 0 117 except: 118 pass
119
120 - def zoom(self, x, y, factor):
121 self.scale = [s * factor for s in self.scale] 122 self.translate = [ x - (x - self.translate[0]) * factor, 123 y - (y - self.translate[1]) * factor] 124 penwidth = max(1.0, self.filament_width * ((self.scale[0] + self.scale[1]) / 2.0)) 125 for pen in self.penslist: 126 pen.SetWidth(penwidth) 127 self.repaint() 128 self.Refresh()
129
130 - def repaint(self):
131 self.blitmap = wx.EmptyBitmap(self.GetClientSize()[0], self.GetClientSize()[1], -1) 132 dc = wx.MemoryDC() 133 dc.SelectObject(self.blitmap) 134 dc.SetBackground(wx.Brush((250, 250, 200))) 135 dc.Clear() 136 dc.SetPen(wx.Pen(wx.Colour(180, 180, 150))) 137 for grid_unit in self.grid: 138 if grid_unit > 0: 139 for x in xrange(int(self.bedsize[0] / grid_unit) + 1): 140 dc.DrawLine(self.translate[0] + x * self.scale[0] * grid_unit, self.translate[1], self.translate[0] + x * self.scale[0] * grid_unit, self.translate[1] + self.scale[1] * self.bedsize[1]) 141 for y in xrange(int(self.bedsize[1] / grid_unit) + 1): 142 dc.DrawLine(self.translate[0], self.translate[1] + y * self.scale[1] * grid_unit, self.translate[0] + self.scale[0] * self.bedsize[0], self.translate[1] + y * self.scale[1] * grid_unit) 143 dc.SetPen(wx.Pen(wx.Colour(0, 0, 0))) 144 if not self.showall: 145 self.size = self.GetSize() 146 dc.SetBrush(wx.Brush((43, 144, 255))) 147 dc.DrawRectangle(self.size[0] - 15, 0, 15, self.size[1]) 148 dc.SetBrush(wx.Brush((0, 255, 0))) 149 if len(self.layers): 150 dc.DrawRectangle(self.size[0] - 14, (1.0 - (1.0 * (self.layerindex + 1)) / len(self.layers)) * self.size[1], 13, self.size[1] - 1) 151 152 def _drawlines(lines, pens): 153 def _scaler(x): 154 return (self.scale[0] * x[0] + self.translate[0], 155 self.scale[1] * x[1] + self.translate[1], 156 self.scale[0] * x[2] + self.translate[0], 157 self.scale[1] * x[3] + self.translate[1],)
158 scaled_lines = map(_scaler, lines) 159 dc.DrawLineList(scaled_lines, pens)
160 161 def _drawarcs(arcs, pens): 162 def _scaler(x): 163 return (self.scale[0] * x[0] + self.translate[0], 164 self.scale[1] * x[1] + self.translate[1], 165 self.scale[0] * x[2] + self.translate[0], 166 self.scale[1] * x[3] + self.translate[1], 167 self.scale[0] * x[4] + self.translate[0], 168 self.scale[1] * x[5] + self.translate[1],) 169 scaled_arcs = map(_scaler, arcs) 170 for i in range(len(scaled_arcs)): 171 dc.SetPen(pens[i] if type(pens).__name__ == 'list' else pens) 172 dc.SetBrush(wx.TRANSPARENT_BRUSH) 173 dc.DrawArc(*scaled_arcs[i]) 174 175 if self.showall: 176 l = [] 177 for i in self.layers: 178 dc.DrawLineList(l, self.fades[0]) 179 _drawlines(self.lines[i], self.pens[i]) 180 _drawarcs(self.arcs[i], self.arcpens[i]) 181 return 182 if self.layerindex < len(self.layers) and self.layers[self.layerindex] in self.lines.keys(): 183 for layer_i in xrange(max(0, self.layerindex - 6), self.layerindex): 184 _drawlines(self.lines[self.layers[layer_i]], self.fades[self.layerindex - layer_i - 1]) 185 _drawarcs(self.arcs[self.layers[layer_i]], self.fades[self.layerindex - layer_i - 1]) 186 _drawlines(self.lines[self.layers[self.layerindex]], self.pens[self.layers[self.layerindex]]) 187 _drawarcs(self.arcs[self.layers[self.layerindex]], self.arcpens[self.layers[self.layerindex]]) 188 189 _drawlines(self.hilight, self.hlpen) 190 _drawarcs(self.hilightarcs, self.hlpen) 191 192 dc.SelectObject(wx.NullBitmap) 193
194 - def paint(self, event):
195 dc = wx.PaintDC(self) 196 if(self.dirty): 197 self.repaint() 198 self.dirty = 0 199 sz = self.GetClientSize() 200 dc.DrawBitmap(self.blitmap, 0, 0) 201 del dc
202
203 - def addgcode(self, gcode="M105", hilight=0):
204 gcode = gcode.split("*")[0] 205 gcode = gcode.split(";")[0] 206 gcode = gcode.lower().strip().split() 207 if len(gcode) == 0: 208 return 209 210 def _readgcode(): 211 target = self.lastpos[:] 212 if hilight: 213 target = self.hilightpos[:] 214 for i in gcode: 215 if i[0] == "x": 216 target[0] = float(i[1:]) 217 elif i[0] == "y": 218 target[1] = float(i[1:]) 219 elif i[0] == "z": 220 target[2] = float(i[1:]) 221 elif i[0] == "e": 222 target[3] = float(i[1:]) 223 elif i[0] == "f": 224 target[4] = float(i[1:]) 225 elif i[0] == "i": 226 target[5] = float(i[1:]) 227 elif i[0] == "j": 228 target[6] = float(i[1:]) 229 if not hilight: 230 if not target[2] in self.lines.keys(): 231 self.lines[target[2]] = [] 232 self.pens[target[2]] = [] 233 self.arcs[target[2]] = [] 234 self.arcpens[target[2]] = [] 235 self.layers += [target[2]] 236 return target
237 238 def _y(y): 239 return self.bedsize[1] - y 240 241 start_pos = self.hilightpos[:] if hilight else self.lastpos[:] 242 243 if gcode[0] == "g1": 244 target = _readgcode() 245 line = [ start_pos[0], _y(start_pos[1]), target[0], _y(target[1]) ] 246 if not hilight: 247 self.lines[ target[2] ] += [line] 248 self.pens[ target[2] ] += [self.mainpen if target[3] != self.lastpos[3] else self.travelpen] 249 self.lastpos = target 250 else: 251 self.hilight += [line] 252 self.hilightpos = target 253 self.dirty = 1 254 255 if gcode[0] in [ "g2", "g3" ]: 256 target = _readgcode() 257 arc = [] 258 arc += [ start_pos[0], _y(start_pos[1]) ] 259 arc += [ target[0], _y(target[1]) ] 260 arc += [ start_pos[0] + target[5], _y(start_pos[1] + target[6]) ] # center 261 if gcode[0] == "g2": # clockwise, reverse endpoints 262 arc[0], arc[1], arc[2], arc[3] = arc[2], arc[3], arc[0], arc[1] 263 264 if not hilight: 265 self.arcs[ target[2] ] += [arc] 266 self.arcpens[ target[2] ] += [self.arcpen] 267 self.lastpos = target 268 else: 269 self.hilightarcs += [arc] 270 self.hilightpos = target 271 self.dirty = 1 272
273 -def main(argv=None):
274 if argv is None: 275 argv = sys.argv[1:] 276 app = wx.App(False) 277 main = window(open(argv[0])) 278 main.Show() 279 app.MainLoop()
280 281 if __name__ == '__main__': 282 main() 283