chiark / gitweb /
Removed old code
[cura.git] / Cura / gui / util / engineResultView.py
1 __copyright__ = "Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License"
2
3 import wx
4 import numpy
5 import math
6
7 import OpenGL
8 #OpenGL.ERROR_CHECKING = False
9 from OpenGL.GLU import *
10 from OpenGL.GL import *
11
12 from Cura.util import profile
13 from Cura.gui.util import openglHelpers
14 from Cura.gui.util import openglGui
15
16 class engineResultView(object):
17         def __init__(self, parent):
18                 self._parent = parent
19                 self._result = None
20                 self._enabled = False
21                 self._gcodeLoadProgress = 0
22                 self._layerVBOs = []
23                 self._layer20VBOs = []
24
25                 self.layerSelect = openglGui.glSlider(self._parent, 10000, 0, 1, (-1,-2), lambda : self._parent.QueueRefresh())
26
27         def setResult(self, result):
28                 if self._result == result:
29                         return
30
31                 self._result = result
32
33                 #Clean the saved VBO's
34                 for layer in self._layerVBOs:
35                         for typeName in layer.keys():
36                                 self._parent.glReleaseList.append(layer[typeName])
37                 for layer in self._layer20VBOs:
38                         for typeName in layer.keys():
39                                 self._parent.glReleaseList.append(layer[typeName])
40                 self._layerVBOs = []
41                 self._layer20VBOs = []
42
43         def setEnabled(self, enabled):
44                 self._enabled = enabled
45                 self.layerSelect.setHidden(not enabled)
46
47         def _gcodeLoadCallback(self, result, progress):
48                 if result != self._result:
49                         #Abort loading from this thread.
50                         return True
51                 self._gcodeLoadProgress = progress
52                 self._parent._queueRefresh()
53                 return False
54
55         def OnDraw(self):
56                 if not self._enabled:
57                         return
58
59                 result = self._result
60                 if result is not None and result._polygons is not None:
61                         self.layerSelect.setRange(1, len(result._polygons))
62                 if result is not None:
63                         gcodeLayers = result.getGCodeLayers(self._gcodeLoadCallback)
64                 else:
65                         gcodeLayers = None
66
67                 glPushMatrix()
68                 glEnable(GL_BLEND)
69                 if profile.getMachineSetting('machine_center_is_zero') != 'True':
70                         glTranslate(-profile.getMachineSettingFloat('machine_width') / 2, -profile.getMachineSettingFloat('machine_depth') / 2, 0)
71                 glLineWidth(2)
72
73                 layerNr = self.layerSelect.getValue()
74                 if layerNr == self.layerSelect.getMaxValue():
75                         layerNr = max(layerNr, len(result._polygons))
76                 viewZ = (layerNr - 1) * profile.getProfileSettingFloat('layer_height') + profile.getProfileSettingFloat('bottom_thickness')
77                 self._parent._viewTarget[2] = viewZ
78                 msize = max(profile.getMachineSettingFloat('machine_width'), profile.getMachineSettingFloat('machine_depth'))
79                 lineTypeList = [
80                         ('inset0',     'WALL-OUTER', [1,0,0,1]),
81                         ('insetx',     'WALL-INNER', [0,1,0,1]),
82                         ('openoutline', None,        [1,0,0,1]),
83                         ('skin',       'FILL',       [1,1,0,1]),
84                         ('infill',      None,        [1,1,0,1]),
85                         ('support',    'SUPPORT',    [0,1,1,1]),
86                         ('skirt',      'SKIRT',      [0,1,1,1]),
87                         ('outline',     None,        [0,0,0,1])
88                 ]
89                 n = layerNr - 1
90                 generatedVBO = False
91                 while n >= 0:
92                         if layerNr - n > 30 and n % 20 == 0:
93                                 idx = n / 20
94                                 while len(self._layer20VBOs) < idx + 1:
95                                         self._layer20VBOs.append({})
96                                 if result is not None and result._polygons is not None and n + 20 < len(result._polygons):
97                                         layerVBOs = self._layer20VBOs[idx]
98                                         for typeName, typeNameGCode, color in lineTypeList:
99                                                 if (typeName in result._polygons[n + 19]) or (typeName == 'skirt' and typeName in result._polygons[n]):
100                                                         if typeName not in layerVBOs:
101                                                                 if generatedVBO:
102                                                                         continue
103                                                                 polygons = []
104                                                                 for i in xrange(0, 20):
105                                                                         if typeName in result._polygons[n + i]:
106                                                                                 polygons += result._polygons[n + i][typeName]
107                                                                 layerVBOs[typeName] = self._polygonsToVBO_lines(polygons)
108                                                                 generatedVBO = True
109                                                         glColor4f(color[0]*0.5,color[1]*0.5,color[2]*0.5,color[3])
110                                                         layerVBOs[typeName].render()
111                                 n -= 20
112                         else:
113                                 c = 1.0 - ((layerNr - n) - 1) * 0.05
114                                 c = max(0.5, c)
115                                 while len(self._layerVBOs) < n + 1:
116                                         self._layerVBOs.append({})
117                                 layerVBOs = self._layerVBOs[n]
118                                 if gcodeLayers is not None and layerNr - 10 < n < (len(gcodeLayers) - 1):
119                                         for typeNamePolygons, typeName, color in lineTypeList:
120                                                 if typeName is None:
121                                                         continue
122                                                 if 'GCODE-' + typeName not in layerVBOs:
123                                                         layerVBOs['GCODE-' + typeName] = self._gcodeToVBO_quads(gcodeLayers[n+1:n+2], typeName)
124                                                 glColor4f(color[0]*c,color[1]*c,color[2]*c,color[3])
125                                                 layerVBOs['GCODE-' + typeName].render()
126
127                                         if n == layerNr - 1:
128                                                 if 'GCODE-MOVE' not in layerVBOs:
129                                                         layerVBOs['GCODE-MOVE'] = self._gcodeToVBO_lines(gcodeLayers[n+1:n+2])
130                                                 glColor4f(0,0,c,1)
131                                                 layerVBOs['GCODE-MOVE'].render()
132                                 elif result is not None and result._polygons is not None and n < len(result._polygons):
133                                         polygons = result._polygons[n]
134                                         for typeName, typeNameGCode, color in lineTypeList:
135                                                 if typeName in polygons:
136                                                         if typeName not in layerVBOs:
137                                                                 layerVBOs[typeName] = self._polygonsToVBO_lines(polygons[typeName])
138                                                         glColor4f(color[0]*c,color[1]*c,color[2]*c,color[3])
139                                                         layerVBOs[typeName].render()
140                                 n -= 1
141                 glPopMatrix()
142                 if generatedVBO:
143                         self._parent._queueRefresh()
144
145                 if gcodeLayers is not None and self._gcodeLoadProgress != 0.0 and self._gcodeLoadProgress != 1.0:
146                         glPushMatrix()
147                         glLoadIdentity()
148                         glTranslate(0,-0.8,-2)
149                         glColor4ub(60,60,60,255)
150                         openglHelpers.glDrawStringCenter(_("Loading toolpath for visualization (%d%%)") % (self._gcodeLoadProgress * 100))
151                         glPopMatrix()
152
153         def _polygonsToVBO_lines(self, polygons):
154                 verts = numpy.zeros((0, 3), numpy.float32)
155                 indices = numpy.zeros((0), numpy.uint32)
156                 for poly in polygons:
157                         if len(poly) > 2:
158                                 i = numpy.arange(len(verts), len(verts) + len(poly) + 1, 1, numpy.uint32)
159                                 i[-1] = len(verts)
160                                 i = numpy.dstack((i[0:-1],i[1:])).flatten()
161                         else:
162                                 i = numpy.arange(len(verts), len(verts) + len(poly), 1, numpy.uint32)
163                         indices = numpy.concatenate((indices, i), 0)
164                         verts = numpy.concatenate((verts, poly), 0)
165                 return openglHelpers.GLVBO(GL_LINES, verts, indicesArray=indices)
166
167         def _polygonsToVBO_quads(self, polygons):
168                 verts = numpy.zeros((0, 3), numpy.float32)
169                 indices = numpy.zeros((0), numpy.uint32)
170                 for poly in polygons:
171                         i = numpy.arange(len(verts), len(verts) + len(poly) + 1, 1, numpy.uint32)
172                         i2 = numpy.arange(len(verts) + len(poly), len(verts) + len(poly) + len(poly) + 1, 1, numpy.uint32)
173                         i[-1] = len(verts)
174                         i2[-1] = len(verts) + len(poly)
175                         i = numpy.dstack((i[0:-1],i2[0:-1],i2[1:],i[1:])).flatten()
176                         indices = numpy.concatenate((indices, i), 0)
177                         verts = numpy.concatenate((verts, poly), 0)
178                         verts = numpy.concatenate((verts, poly * numpy.array([1,0,1],numpy.float32) + numpy.array([0,-100,0],numpy.float32)), 0)
179                 return openglHelpers.GLVBO(GL_QUADS, verts, indicesArray=indices)
180
181         def _gcodeToVBO_lines(self, gcodeLayers, extrudeType):
182                 if ':' in extrudeType:
183                         extruder = int(extrudeType[extrudeType.find(':')+1:])
184                         extrudeType = extrudeType[0:extrudeType.find(':')]
185                 else:
186                         extruder = None
187                 verts = numpy.zeros((0, 3), numpy.float32)
188                 indices = numpy.zeros((0), numpy.uint32)
189                 for layer in gcodeLayers:
190                         for path in layer:
191                                 if path['type'] == 'extrude' and path['pathType'] == extrudeType and (extruder is None or path['extruder'] == extruder):
192                                         i = numpy.arange(len(verts), len(verts) + len(path['points']), 1, numpy.uint32)
193                                         i = numpy.dstack((i[0:-1],i[1:])).flatten()
194                                         indices = numpy.concatenate((indices, i), 0)
195                                         verts = numpy.concatenate((verts, path['points']))
196                 return openglHelpers.GLVBO(GL_LINES, verts, indicesArray=indices)
197
198         def _gcodeToVBO_quads(self, gcodeLayers, extrudeType):
199                 useFilamentArea = profile.getMachineSetting('gcode_flavor') == 'UltiGCode'
200                 filamentRadius = profile.getProfileSettingFloat('filament_diameter') / 2
201                 filamentArea = math.pi * filamentRadius * filamentRadius
202
203                 if ':' in extrudeType:
204                         extruder = int(extrudeType[extrudeType.find(':')+1:])
205                         extrudeType = extrudeType[0:extrudeType.find(':')]
206                 else:
207                         extruder = None
208
209                 verts = numpy.zeros((0, 3), numpy.float32)
210                 indices = numpy.zeros((0), numpy.uint32)
211                 for layer in gcodeLayers:
212                         for path in layer:
213                                 if path['type'] == 'extrude' and path['pathType'] == extrudeType and (extruder is None or path['extruder'] == extruder):
214                                         a = path['points']
215                                         if extrudeType == 'FILL':
216                                                 a[:,2] += 0.01
217
218                                         #Construct the normals of each line 90deg rotated on the X/Y plane
219                                         normals = a[1:] - a[:-1]
220                                         lengths = numpy.sqrt(normals[:,0]**2 + normals[:,1]**2)
221                                         normals[:,0], normals[:,1] = -normals[:,1] / lengths, normals[:,0] / lengths
222                                         normals[:,2] /= lengths
223
224                                         ePerDist = path['extrusion'][1:] / lengths
225                                         if useFilamentArea:
226                                                 lineWidth = ePerDist / path['layerThickness'] / 2.0
227                                         else:
228                                                 lineWidth = ePerDist * (filamentArea / path['layerThickness'] / 2)
229
230                                         normals[:,0] *= lineWidth
231                                         normals[:,1] *= lineWidth
232
233                                         b = numpy.zeros((len(a)-1, 0), numpy.float32)
234                                         b = numpy.concatenate((b, a[1:] + normals), 1)
235                                         b = numpy.concatenate((b, a[1:] - normals), 1)
236                                         b = numpy.concatenate((b, a[:-1] - normals), 1)
237                                         b = numpy.concatenate((b, a[:-1] + normals), 1)
238                                         b = b.reshape((len(b) * 4, 3))
239
240                                         i = numpy.arange(len(verts), len(verts) + len(b), 1, numpy.uint32)
241
242                                         verts = numpy.concatenate((verts, b))
243                                         indices = numpy.concatenate((indices, i))
244                 return openglHelpers.GLVBO(GL_QUADS, verts, indicesArray=indices)
245
246         def _gcodeToVBO_lines(self, gcodeLayers):
247                 verts = numpy.zeros((0,3), numpy.float32)
248                 indices = numpy.zeros((0), numpy.uint32)
249                 for layer in gcodeLayers:
250                         for path in layer:
251                                 if path['type'] == 'move':
252                                         a = path['points'] + numpy.array([0,0,0.02], numpy.float32)
253                                         i = numpy.arange(len(verts), len(verts) + len(a), 1, numpy.uint32)
254                                         i = numpy.dstack((i[0:-1],i[1:])).flatten()
255                                         verts = numpy.concatenate((verts, a))
256                                         indices = numpy.concatenate((indices, i))
257                                 if path['type'] == 'retract':
258                                         a = path['points'] + numpy.array([0,0,0.02], numpy.float32)
259                                         a = numpy.concatenate((a[:-1], a[1:] + numpy.array([0,0,1], numpy.float32)), 1)
260                                         a = a.reshape((len(a) * 2, 3))
261                                         i = numpy.arange(len(verts), len(verts) + len(a), 1, numpy.uint32)
262                                         verts = numpy.concatenate((verts, a))
263                                         indices = numpy.concatenate((indices, i))
264                 return openglHelpers.GLVBO(GL_LINES, verts, indicesArray=indices)
265
266         def OnKeyChar(self, keyCode):
267                 if not self._enabled:
268                         return
269
270                 if wx.GetKeyState(wx.WXK_SHIFT) or wx.GetKeyState(wx.WXK_CONTROL):
271                         if keyCode == wx.WXK_UP:
272                                 self.layerSelect.setValue(self.layerSelect.getValue() + 1)
273                                 self._parent.QueueRefresh()
274                                 return True
275                         elif keyCode == wx.WXK_DOWN:
276                                 self.layerSelect.setValue(self.layerSelect.getValue() - 1)
277                                 self._parent.QueueRefresh()
278                                 return True
279                         elif keyCode == wx.WXK_PAGEUP:
280                                 self.layerSelect.setValue(self.layerSelect.getValue() + 10)
281                                 self._parent.QueueRefresh()
282                                 return True
283                         elif keyCode == wx.WXK_PAGEDOWN:
284                                 self.layerSelect.setValue(self.layerSelect.getValue() - 10)
285                                 self._parent.QueueRefresh()
286                                 return True
287                 return False