def Win32SocketListener(self, port):
import socket
- sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
- sock.bind(("127.0.0.1", port))
- while True:
- data, addr = sock.recvfrom(2048)
- self.mainWindow.OnDropFiles(data.split('\0'))
+ try:
+ sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+ sock.bind(("127.0.0.1", port))
+ while True:
+ data, addr = sock.recvfrom(2048)
+ self.mainWindow.OnDropFiles(data.split('\0'))
+ except:
+ pass
def afterSplashCallback(self):
#These imports take most of the time and thus should be done after showing the splashscreen
self.machineName = self.AddLabelTextCtrl(_("Machine name"), "RepRap")
self.machineWidth = self.AddLabelTextCtrl(_("Machine width (mm)"), "80")
self.machineDepth = self.AddLabelTextCtrl(_("Machine depth (mm)"), "80")
- self.machineHeight = self.AddLabelTextCtrl(_("Machine height (mm)"), "60")
+ self.machineHeight = self.AddLabelTextCtrl(_("Machine height (mm)"), "55")
self.nozzleSize = self.AddLabelTextCtrl(_("Nozzle size (mm)"), "0.5")
self.heatedBed = self.AddCheckbox(_("Heated bed"))
self.HomeAtCenter = self.AddCheckbox(_("Bed center is 0,0,0 (RoStock)"))
profile.putMachineSetting('extruder_head_size_min_y', '18.0')
profile.putMachineSetting('extruder_head_size_max_x', '18.0')
profile.putMachineSetting('extruder_head_size_max_y', '35.0')
- profile.putMachineSetting('extruder_head_size_height', '60.0')
+ profile.putMachineSetting('extruder_head_size_height', '55.0')
else:
profile.putMachineSetting('machine_width', '80')
profile.putMachineSetting('machine_depth', '80')
#HACK: Set the paint function of the glCanvas to nothing so it won't keep refreshing. Which can keep wxWidgets from quiting.
print "Closing down"
self.scene.OnPaint = lambda e : e
- self.scene._slicer.cleanup()
+ self.scene._engine.cleanup()
self.Destroy()
def OnQuit(self, e):
gcodeList.append(line)
prevLineType = lineType
gcode = gcodeInterpreter.gcode()
- gcode.loadList(gcodeList)
+ gcode.load(gcodeList)
#print "Loaded: %s (%d)" % (filename, len(gcodeList))
self.filename = filename
self.gcode = gcode
import threading
import math
import platform
+import cStringIO as StringIO
import OpenGL
-OpenGL.ERROR_CHECKING = False
+#OpenGL.ERROR_CHECKING = False
from OpenGL.GLU import *
from OpenGL.GL import *
from Cura.util import sliceEngine
from Cura.util import machineCom
from Cura.util import removableStorage
-from Cura.util import gcodeInterpreter
from Cura.util import explorer
from Cura.util.printerConnection import printerConnectionManager
from Cura.gui.util import previewTools
from Cura.gui.util import opengl
from Cura.gui.util import openglGui
+from Cura.gui.util import engineResultView
from Cura.gui.tools import youmagineGui
from Cura.gui.tools import imageToMesh
self._pitch = 60
self._zoom = 300
self._scene = objectScene.Scene()
- self._gcode = None
- self._gcodeVBOs = []
- self._gcodeFilename = None
- self._gcodeLoadThread = None
self._objectShader = None
self._objectLoadShader = None
self._focusObj = None
self.scaleUniform = openglGui.glCheckbox(self.scaleForm, True, (1,8), None)
self.viewSelection = openglGui.glComboButton(self, _("View mode"), [7,19,11,15,23], [_("Normal"), _("Overhang"), _("Transparent"), _("X-Ray"), _("Layers")], (-1,0), self.OnViewChange)
- self.layerSelect = openglGui.glSlider(self, 10000, 0, 1, (-1,-2), lambda : self.QueueRefresh())
self.youMagineButton = openglGui.glButton(self, 26, _("Share on YouMagine"), (2,0), lambda button: youmagineGui.youmagineManager(self.GetTopLevelParent(), self._scene))
self.youMagineButton.setDisabled(True)
self.notification = openglGui.glNotification(self, (0, 0))
- self._slicer = sliceEngine.Slicer(self._updateSliceProgress)
+ self._engine = sliceEngine.Engine(self._updateEngineProgress)
+ self._engineResultView = engineResultView.engineResultView(self)
self._sceneUpdateTimer = wx.Timer(self)
- self.Bind(wx.EVT_TIMER, self._onRunSlicer, self._sceneUpdateTimer)
+ self.Bind(wx.EVT_TIMER, self._onRunEngine, self._sceneUpdateTimer)
self.Bind(wx.EVT_MOUSEWHEEL, self.OnMouseWheel)
self.Bind(wx.EVT_LEAVE_WINDOW, self.OnMouseLeave)
def loadGCodeFile(self, filename):
self.OnDeleteAll(None)
- if self._gcode is not None:
- self._gcode = None
- for layerVBOlist in self._gcodeVBOs:
- for vbo in layerVBOlist:
- self.glReleaseList.append(vbo)
- self._gcodeVBOs = []
- self._gcode = gcodeInterpreter.gcode()
- self._gcodeFilename = filename
+ #TODO: Load straight GCodeFile
self.printButton.setBottomText('')
self.viewSelection.setValue(4)
self.printButton.setDisabled(False)
else:
drive = drives[0]
filename = self._scene._objectList[0].getName() + '.gcode'
- threading.Thread(target=self._copyFile,args=(self._gcodeFilename, drive[1] + filename, drive[1])).start()
+ threading.Thread(target=self._saveGCode,args=(drive[1] + filename, drive[1])).start()
elif connectionGroup is not None:
connections = connectionGroup.getAvailableConnections()
if len(connections) < 2:
menu.connectionMap[i.GetId()] = connection
self.Bind(wx.EVT_MENU, lambda e: self._openPrintWindowForConnection(e.GetEventObject().connectionMap[e.GetId()]), i)
self.Bind(wx.EVT_MENU, lambda e: self.showSaveGCode(), menu.Append(-1, _("Save GCode...")))
- self.Bind(wx.EVT_MENU, lambda e: self._showSliceLog(), menu.Append(-1, _("Slice engine log...")))
+ self.Bind(wx.EVT_MENU, lambda e: self._showEngineLog(), menu.Append(-1, _("Slice engine log...")))
self.PopupMenu(menu)
menu.Destroy()
connection.window = printWindow2.printWindow(connection)
connection.window.Show()
connection.window.Raise()
+ #TODO: Fix for _engine.getResult
if not connection.loadFile(self._gcodeFilename):
if connection.isPrinting():
self.notification.message("Cannot start print, because other print still running.")
if profile.getMachineSetting('gcode_flavor') == 'UltiGCode':
wx.MessageBox(_("USB printing on the Ultimaker2 is not supported."), _("USB Printing Error"), wx.OK | wx.ICON_WARNING)
return
- self._usbPrintMonitor.loadFile(self._gcodeFilename, self._slicer.getID())
- if self._gcodeFilename == self._slicer.getGCodeFilename():
- self._slicer.submitSliceInfoOnline()
+ #TODO: Fix for _engine.getResult
+ self._usbPrintMonitor.loadFile(self._gcodeFilename, self._engine.getID())
+ if self._gcodeFilename is None:
+ self._engine.submitInfoOnline()
def showSaveGCode(self):
if len(self._scene._objectList) < 1:
filename = dlg.GetPath()
dlg.Destroy()
- threading.Thread(target=self._copyFile,args=(self._gcodeFilename, filename)).start()
+ threading.Thread(target=self._saveGCode,args=(filename,)).start()
- def _copyFile(self, fileA, fileB, allowEject = False):
+ def _saveGCode(self, targetFilename, ejectDrive = False):
+ data = self._engine.getResult().getGCode()
try:
- size = float(os.stat(fileA).st_size)
- with open(fileA, 'rb') as fsrc:
- with open(fileB, 'wb') as fdst:
- while 1:
- buf = fsrc.read(16*1024)
- if not buf:
- break
- fdst.write(buf)
- self.printButton.setProgressBar(float(fsrc.tell()) / size)
- self._queueRefresh()
+ size = float(len(data))
+ fsrc = StringIO.StringIO(data)
+ with open(targetFilename, 'wb') as fdst:
+ while 1:
+ buf = fsrc.read(16*1024)
+ if not buf:
+ break
+ fdst.write(buf)
+ self.printButton.setProgressBar(float(fsrc.tell()) / size)
+ self._queueRefresh()
except:
- import sys
- print sys.exc_info()
+ import sys, traceback
+ traceback.print_exc()
self.notification.message("Failed to save")
else:
- if allowEject:
- self.notification.message("Saved as %s" % (fileB), lambda : self._doEjectSD(allowEject), 31, 'Eject')
+ if ejectDrive:
+ self.notification.message("Saved as %s" % (targetFilename), lambda : self._doEjectSD(ejectDrive), 31, 'Eject')
elif explorer.hasExplorer():
- self.notification.message("Saved as %s" % (fileB), lambda : explorer.openExplorer(fileB), 4, 'Open folder')
+ self.notification.message("Saved as %s" % (targetFilename), lambda : explorer.openExplorer(targetFilename), 4, 'Open folder')
else:
- self.notification.message("Saved as %s" % (fileB))
+ self.notification.message("Saved as %s" % (targetFilename))
self.printButton.setProgressBar(None)
- if fileA == self._slicer.getGCodeFilename():
- self._slicer.submitSliceInfoOnline()
+ self._engine.getResult().submitInfoOnline()
def _doEjectSD(self, drive):
if removableStorage.ejectDrive(drive):
else:
self.notification.message('Safe remove failed...')
- def _showSliceLog(self):
- dlg = wx.TextEntryDialog(self, _("The slicing engine reported the following"), _("Engine log..."), '\n'.join(self._slicer.getSliceLog()), wx.TE_MULTILINE | wx.OK | wx.CENTRE)
+ def _showEngineLog(self):
+ dlg = wx.TextEntryDialog(self, _("The slicing engine reported the following"), _("Engine log..."), '\n'.join(self._engine.getResult().getLog()), wx.TE_MULTILINE | wx.OK | wx.CENTRE)
dlg.ShowModal()
dlg.Destroy()
def OnViewChange(self):
if self.viewSelection.getValue() == 4:
self.viewMode = 'gcode'
- if self._gcode is not None and self._gcode.layerList is not None:
- self.layerSelect.setRange(1, len(self._gcode.layerList) - 1)
- self._selectObject(None)
elif self.viewSelection.getValue() == 1:
self.viewMode = 'overhang'
elif self.viewSelection.getValue() == 2:
self.viewMode = 'xray'
else:
self.viewMode = 'normal'
- self.layerSelect.setHidden(self.viewMode != 'gcode')
+ self._engineResultView.setEnabled(self.viewMode == 'gcode')
self.QueueRefresh()
def OnRotateReset(self, button):
def sceneUpdated(self):
self._sceneUpdateTimer.Start(500, True)
- self._slicer.abortSlicer()
+ self._engine.abortEngine()
self._scene.updateSizeOffsets()
self.QueueRefresh()
- def _onRunSlicer(self, e):
+ def _onRunEngine(self, e):
if self._isSimpleMode:
self.GetTopLevelParent().simpleSettingsPanel.setupSlice()
- self._slicer.runSlicer(self._scene)
+ self._engine.runEngine(self._scene)
if self._isSimpleMode:
profile.resetTempOverride()
- def _updateSliceProgress(self, progressValue, ready):
- if not ready:
+ def _updateEngineProgress(self, progressValue):
+ result = self._engine.getResult()
+ finished = result is not None and result.isFinished()
+ if not finished:
if self.printButton.getProgressBar() is not None and progressValue >= 0.0 and abs(self.printButton.getProgressBar() - progressValue) < 0.01:
return
- self.printButton.setDisabled(not ready)
+ self.printButton.setDisabled(not finished)
if progressValue >= 0.0:
self.printButton.setProgressBar(progressValue)
else:
self.printButton.setProgressBar(None)
- if self._gcode is not None:
- self._gcode = None
- for layerVBOlist in self._gcodeVBOs:
- for vbo in layerVBOlist:
- self.glReleaseList.append(vbo)
- self._gcodeVBOs = []
- if ready:
+ self._engineResultView.setResult(result)
+ if finished:
self.printButton.setProgressBar(None)
- text = '%s' % (self._slicer.getPrintTime())
+ text = '%s' % (result.getPrintTime())
for e in xrange(0, int(profile.getMachineSetting('extruder_amount'))):
- amount = self._slicer.getFilamentAmount(e)
+ amount = result.getFilamentAmount(e)
if amount is None:
continue
text += '\n%s' % (amount)
- cost = self._slicer.getFilamentCost(e)
+ cost = result.getFilamentCost(e)
if cost is not None:
text += '\n%s' % (cost)
self.printButton.setBottomText(text)
- self._gcode = gcodeInterpreter.gcode()
- self._gcodeFilename = self._slicer.getGCodeFilename()
else:
self.printButton.setBottomText('')
self.QueueRefresh()
- def _loadGCode(self):
- self._gcode.progressCallback = self._gcodeLoadCallback
- self._gcode.load(self._gcodeFilename)
-
- def _gcodeLoadCallback(self, progress):
- if not self or self._gcode is None:
- return True
- if len(self._gcode.layerList) % 15 == 0:
- time.sleep(0.1)
- if self._gcode is None:
- return True
- self.layerSelect.setRange(1, len(self._gcode.layerList) - 1)
- if self.viewMode == 'gcode':
- self._queueRefresh()
- return False
-
def loadScene(self, fileList):
for filename in fileList:
try:
self.scaleZmmctrl.setValue(round(size[2], 2))
def OnKeyChar(self, keyCode):
+ if self._engineResultView.OnKeyChar(keyCode):
+ return
if keyCode == wx.WXK_DELETE or keyCode == wx.WXK_NUMPAD_DELETE or (keyCode == wx.WXK_BACK and platform.system() == "Darwin"):
if self._selectedObj is not None:
self._deleteObject(self._selectedObj)
self.QueueRefresh()
- if self.viewMode == 'gcode' and (wx.GetKeyState(wx.WXK_SHIFT) or wx.GetKeyState(wx.WXK_CONTROL)):
- if keyCode == wx.WXK_UP:
- self.layerSelect.setValue(self.layerSelect.getValue() + 1)
- self.QueueRefresh()
- elif keyCode == wx.WXK_DOWN:
- self.layerSelect.setValue(self.layerSelect.getValue() - 1)
- self.QueueRefresh()
- elif keyCode == wx.WXK_PAGEUP:
- self.layerSelect.setValue(self.layerSelect.getValue() + 10)
- self.QueueRefresh()
- elif keyCode == wx.WXK_PAGEDOWN:
- self.layerSelect.setValue(self.layerSelect.getValue() - 10)
- self.QueueRefresh()
- else:
- if keyCode == wx.WXK_UP:
- if wx.GetKeyState(wx.WXK_SHIFT):
- self._zoom /= 1.2
- if self._zoom < 1:
- self._zoom = 1
- else:
- self._pitch -= 15
- self.QueueRefresh()
- elif keyCode == wx.WXK_DOWN:
- if wx.GetKeyState(wx.WXK_SHIFT):
- self._zoom *= 1.2
- if self._zoom > numpy.max(self._machineSize) * 3:
- self._zoom = numpy.max(self._machineSize) * 3
- else:
- self._pitch += 15
- self.QueueRefresh()
- elif keyCode == wx.WXK_LEFT:
- self._yaw -= 15
- self.QueueRefresh()
- elif keyCode == wx.WXK_RIGHT:
- self._yaw += 15
- self.QueueRefresh()
- elif keyCode == wx.WXK_NUMPAD_ADD or keyCode == wx.WXK_ADD or keyCode == ord('+') or keyCode == ord('='):
+ if keyCode == wx.WXK_UP:
+ if wx.GetKeyState(wx.WXK_SHIFT):
self._zoom /= 1.2
if self._zoom < 1:
self._zoom = 1
- self.QueueRefresh()
- elif keyCode == wx.WXK_NUMPAD_SUBTRACT or keyCode == wx.WXK_SUBTRACT or keyCode == ord('-'):
+ else:
+ self._pitch -= 15
+ self.QueueRefresh()
+ elif keyCode == wx.WXK_DOWN:
+ if wx.GetKeyState(wx.WXK_SHIFT):
self._zoom *= 1.2
if self._zoom > numpy.max(self._machineSize) * 3:
self._zoom = numpy.max(self._machineSize) * 3
- self.QueueRefresh()
- elif keyCode == wx.WXK_HOME:
- self._yaw = 30
- self._pitch = 60
- self.QueueRefresh()
- elif keyCode == wx.WXK_PAGEUP:
- self._yaw = 0
- self._pitch = 0
- self.QueueRefresh()
- elif keyCode == wx.WXK_PAGEDOWN:
- self._yaw = 0
- self._pitch = 90
- self.QueueRefresh()
- elif keyCode == wx.WXK_END:
- self._yaw = 90
- self._pitch = 90
- self.QueueRefresh()
+ else:
+ self._pitch += 15
+ self.QueueRefresh()
+ elif keyCode == wx.WXK_LEFT:
+ self._yaw -= 15
+ self.QueueRefresh()
+ elif keyCode == wx.WXK_RIGHT:
+ self._yaw += 15
+ self.QueueRefresh()
+ elif keyCode == wx.WXK_NUMPAD_ADD or keyCode == wx.WXK_ADD or keyCode == ord('+') or keyCode == ord('='):
+ self._zoom /= 1.2
+ if self._zoom < 1:
+ self._zoom = 1
+ self.QueueRefresh()
+ elif keyCode == wx.WXK_NUMPAD_SUBTRACT or keyCode == wx.WXK_SUBTRACT or keyCode == ord('-'):
+ self._zoom *= 1.2
+ if self._zoom > numpy.max(self._machineSize) * 3:
+ self._zoom = numpy.max(self._machineSize) * 3
+ self.QueueRefresh()
+ elif keyCode == wx.WXK_HOME:
+ self._yaw = 30
+ self._pitch = 60
+ self.QueueRefresh()
+ elif keyCode == wx.WXK_PAGEUP:
+ self._yaw = 0
+ self._pitch = 0
+ self.QueueRefresh()
+ elif keyCode == wx.WXK_PAGEDOWN:
+ self._yaw = 0
+ self._pitch = 90
+ self.QueueRefresh()
+ elif keyCode == wx.WXK_END:
+ self._yaw = 90
+ self._pitch = 90
+ self.QueueRefresh()
if keyCode == wx.WXK_F3 and wx.GetKeyState(wx.WXK_SHIFT):
shaderEditor(self, self.ShaderUpdate, self._objectLoadShader.getVertexShader(), self._objectLoadShader.getFragmentShader())
self._zoom = self._animZoom.getPosition()
if self._animZoom.isDone():
self._animZoom = None
- if self.viewMode == 'gcode' and self._gcode is not None:
- try:
- self._viewTarget[2] = self._gcode.layerList[self.layerSelect.getValue()][-1]['points'][0][2]
- except:
- pass
if self._objectShader is None:
if opengl.hasShaderSupport():
self._objectShader = opengl.GLShader("""
glRotate(self._yaw, 0,0,1)
glTranslate(-self._viewTarget[0],-self._viewTarget[1],-self._viewTarget[2])
- if self.viewMode == 'gcode':
- if self._gcode is not None and self._gcode.layerList is None:
- self._gcodeLoadThread = threading.Thread(target=self._loadGCode)
- self._gcodeLoadThread.daemon = True
- self._gcodeLoadThread.start()
- if self._gcode is not None and self._gcode.layerList is not None:
- glPushMatrix()
- if profile.getMachineSetting('machine_center_is_zero') != 'True':
- glTranslate(-self._machineSize[0] / 2, -self._machineSize[1] / 2, 0)
- t = time.time()
- drawUpTill = min(len(self._gcode.layerList), self.layerSelect.getValue() + 1)
- for n in xrange(0, drawUpTill):
- c = 1.0 - float(drawUpTill - n) / 15
- c = max(0.3, c)
- if len(self._gcodeVBOs) < n + 1:
- self._gcodeVBOs.append(self._generateGCodeVBOs(self._gcode.layerList[n]))
- if time.time() - t > 0.5:
- self.QueueRefresh()
- break
- #['WALL-OUTER', 'WALL-INNER', 'FILL', 'SUPPORT', 'SKIRT']
- if n == drawUpTill - 1:
- if len(self._gcodeVBOs[n]) < 9:
- self._gcodeVBOs[n] += self._generateGCodeVBOs2(self._gcode.layerList[n])
- glColor3f(c, 0, 0)
- self._gcodeVBOs[n][8].render(GL_QUADS)
- glColor3f(c/2, 0, c)
- self._gcodeVBOs[n][9].render(GL_QUADS)
- glColor3f(0, c, c/2)
- self._gcodeVBOs[n][10].render(GL_QUADS)
- glColor3f(c, 0, 0)
- self._gcodeVBOs[n][11].render(GL_QUADS)
-
- glColor3f(0, c, 0)
- self._gcodeVBOs[n][12].render(GL_QUADS)
- glColor3f(c/2, c/2, 0.0)
- self._gcodeVBOs[n][13].render(GL_QUADS)
- glColor3f(0, c, c)
- self._gcodeVBOs[n][14].render(GL_QUADS)
- self._gcodeVBOs[n][15].render(GL_QUADS)
- glColor3f(0, 0, c)
- self._gcodeVBOs[n][16].render(GL_LINES)
- else:
- glColor3f(c, 0, 0)
- self._gcodeVBOs[n][0].render(GL_LINES)
- glColor3f(c/2, 0, c)
- self._gcodeVBOs[n][1].render(GL_LINES)
- glColor3f(0, c, c/2)
- self._gcodeVBOs[n][2].render(GL_LINES)
- glColor3f(c, 0, 0)
- self._gcodeVBOs[n][3].render(GL_LINES)
-
- glColor3f(0, c, 0)
- self._gcodeVBOs[n][4].render(GL_LINES)
- glColor3f(c/2, c/2, 0.0)
- self._gcodeVBOs[n][5].render(GL_LINES)
- glColor3f(0, c, c)
- self._gcodeVBOs[n][6].render(GL_LINES)
- self._gcodeVBOs[n][7].render(GL_LINES)
- glPopMatrix()
- else:
+ self._objectShader.unbind()
+ self._engineResultView.OnDraw()
+ if self.viewMode != 'gcode':
glStencilFunc(GL_ALWAYS, 1, 1)
glStencilOp(GL_INCR, GL_INCR, GL_INCR)
self._drawMachine()
- if self._usbPrintMonitor.getState() == 'PRINTING' and self._usbPrintMonitor.getID() == self._slicer.getID():
+ if self._usbPrintMonitor.getState() == 'PRINTING' and self._usbPrintMonitor.getID() == self._engine.getID():
z = self._usbPrintMonitor.getZ()
if self.viewMode == 'gcode':
layer_height = profile.getProfileSettingFloat('layer_height')
glVertex3f(-size[0]/2, size[1]/2, z)
glEnd()
- if self.viewMode == 'gcode':
- if self._gcodeLoadThread is not None and self._gcodeLoadThread.isAlive():
- glDisable(GL_DEPTH_TEST)
- glPushMatrix()
- glLoadIdentity()
- glTranslate(0,-4,-10)
- glColor4ub(60,60,60,255)
- opengl.glDrawStringCenter(_("Loading toolpath for visualization..."))
- glPopMatrix()
- else:
+ if self.viewMode != 'gcode':
#Draw the object box-shadow, so you can see where it will collide with other objects.
if self._selectedObj is not None:
glEnable(GL_BLEND)
n = 0
for m in obj._meshList:
if m.vbo is None:
- m.vbo = opengl.GLVBO(m.vertexes, m.normal)
+ m.vbo = opengl.GLVBO(GL_TRIANGLES, m.vertexes, m.normal)
if brightness:
glColor4fv(map(lambda n: n * brightness, self._objColors[n]))
n += 1
glDisable(GL_BLEND)
glDisable(GL_CULL_FACE)
- def _generateGCodeVBOs(self, layer):
- ret = []
- for extrudeType in ['WALL-OUTER:0', 'WALL-OUTER:1', 'WALL-OUTER:2', 'WALL-OUTER:3', 'WALL-INNER', 'FILL', 'SUPPORT', 'SKIRT']:
- if ':' in extrudeType:
- extruder = int(extrudeType[extrudeType.find(':')+1:])
- extrudeType = extrudeType[0:extrudeType.find(':')]
- else:
- extruder = None
- pointList = numpy.zeros((0,3), numpy.float32)
- for path in layer:
- if path['type'] == 'extrude' and path['pathType'] == extrudeType and (extruder is None or path['extruder'] == extruder):
- a = path['points']
- a = numpy.concatenate((a[:-1], a[1:]), 1)
- a = a.reshape((len(a) * 2, 3))
- pointList = numpy.concatenate((pointList, a))
- ret.append(opengl.GLVBO(pointList))
- return ret
-
- def _generateGCodeVBOs2(self, layer):
- filamentRadius = profile.getProfileSettingFloat('filament_diameter') / 2
- filamentArea = math.pi * filamentRadius * filamentRadius
- useFilamentArea = profile.getMachineSetting('gcode_flavor') == 'UltiGCode'
-
- ret = []
- for extrudeType in ['WALL-OUTER:0', 'WALL-OUTER:1', 'WALL-OUTER:2', 'WALL-OUTER:3', 'WALL-INNER', 'FILL', 'SUPPORT', 'SKIRT']:
- if ':' in extrudeType:
- extruder = int(extrudeType[extrudeType.find(':')+1:])
- extrudeType = extrudeType[0:extrudeType.find(':')]
- else:
- extruder = None
- pointList = numpy.zeros((0,3), numpy.float32)
- for path in layer:
- if path['type'] == 'extrude' and path['pathType'] == extrudeType and (extruder is None or path['extruder'] == extruder):
- a = path['points']
- if extrudeType == 'FILL':
- a[:,2] += 0.01
-
- normal = a[1:] - a[:-1]
- lens = numpy.sqrt(normal[:,0]**2 + normal[:,1]**2)
- normal[:,0], normal[:,1] = -normal[:,1] / lens, normal[:,0] / lens
- normal[:,2] /= lens
-
- ePerDist = path['extrusion'][1:] / lens
- if useFilamentArea:
- lineWidth = ePerDist / path['layerThickness'] / 2.0
- else:
- lineWidth = ePerDist * (filamentArea / path['layerThickness'] / 2)
-
- normal[:,0] *= lineWidth
- normal[:,1] *= lineWidth
-
- b = numpy.zeros((len(a)-1, 0), numpy.float32)
- b = numpy.concatenate((b, a[1:] + normal), 1)
- b = numpy.concatenate((b, a[1:] - normal), 1)
- b = numpy.concatenate((b, a[:-1] - normal), 1)
- b = numpy.concatenate((b, a[:-1] + normal), 1)
- b = b.reshape((len(b) * 4, 3))
-
- if len(a) > 2:
- normal2 = normal[:-1] + normal[1:]
- lens2 = numpy.sqrt(normal2[:,0]**2 + normal2[:,1]**2)
- normal2[:,0] /= lens2
- normal2[:,1] /= lens2
- normal2[:,0] *= lineWidth[:-1]
- normal2[:,1] *= lineWidth[:-1]
-
- c = numpy.zeros((len(a)-2, 0), numpy.float32)
- c = numpy.concatenate((c, a[1:-1]), 1)
- c = numpy.concatenate((c, a[1:-1]+normal[1:]), 1)
- c = numpy.concatenate((c, a[1:-1]+normal2), 1)
- c = numpy.concatenate((c, a[1:-1]+normal[:-1]), 1)
-
- c = numpy.concatenate((c, a[1:-1]), 1)
- c = numpy.concatenate((c, a[1:-1]-normal[1:]), 1)
- c = numpy.concatenate((c, a[1:-1]-normal2), 1)
- c = numpy.concatenate((c, a[1:-1]-normal[:-1]), 1)
-
- c = c.reshape((len(c) * 8, 3))
-
- pointList = numpy.concatenate((pointList, b, c))
- else:
- pointList = numpy.concatenate((pointList, b))
- ret.append(opengl.GLVBO(pointList))
-
- pointList = numpy.zeros((0,3), numpy.float32)
- for path in layer:
- if path['type'] == 'move':
- a = path['points'] + numpy.array([0,0,0.01], numpy.float32)
- a = numpy.concatenate((a[:-1], a[1:]), 1)
- a = a.reshape((len(a) * 2, 3))
- pointList = numpy.concatenate((pointList, a))
- if path['type'] == 'retract':
- a = path['points'] + numpy.array([0,0,0.01], numpy.float32)
- a = numpy.concatenate((a[:-1], a[1:] + numpy.array([0,0,1], numpy.float32)), 1)
- a = a.reshape((len(a) * 2, 3))
- pointList = numpy.concatenate((pointList, a))
- ret.append(opengl.GLVBO(pointList))
-
- return ret
-
def getObjectCenterPos(self):
if self._selectedObj is None:
return [0.0, 0.0, 0.0]
--- /dev/null
+__copyright__ = "Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License"
+
+import wx
+import numpy
+import math
+
+import OpenGL
+#OpenGL.ERROR_CHECKING = False
+from OpenGL.GLU import *
+from OpenGL.GL import *
+
+from Cura.util import profile
+from Cura.gui.util import opengl
+from Cura.gui.util import openglGui
+
+class engineResultView(object):
+ def __init__(self, parent):
+ self._parent = parent
+ self._result = None
+ self._enabled = False
+ self._layerVBOs = []
+ self._layer20VBOs = []
+
+ self.layerSelect = openglGui.glSlider(self._parent, 10000, 0, 1, (-1,-2), lambda : self._parent.QueueRefresh())
+
+ def setResult(self, result):
+ if self._result == result:
+ return
+
+ self._result = result
+
+ #Clean the saved VBO's
+ for layer in self._layerVBOs:
+ for typeName in layer.keys():
+ self._parent.glReleaseList.append(layer[typeName])
+ for layer in self._layer20VBOs:
+ for typeName in layer.keys():
+ self._parent.glReleaseList.append(layer[typeName])
+ self._layerVBOs = []
+ self._layer20VBOs = []
+
+ def setEnabled(self, enabled):
+ self._enabled = enabled
+ self.layerSelect.setHidden(not enabled)
+
+ def OnDraw(self):
+ if not self._enabled:
+ return
+
+ if self._result is not None and self._result._polygons is not None:
+ self.layerSelect.setRange(1, len(self._result._polygons))
+
+ glPushMatrix()
+ glEnable(GL_BLEND)
+ if profile.getMachineSetting('machine_center_is_zero') != 'True':
+ glTranslate(-profile.getMachineSettingFloat('machine_width') / 2, -profile.getMachineSettingFloat('machine_depth') / 2, 0)
+ glLineWidth(2)
+
+ layerNr = self.layerSelect.getValue()
+ if layerNr == self.layerSelect.getMaxValue():
+ layerNr = max(layerNr, len(self._result._polygons))
+ viewZ = (layerNr - 1) * profile.getProfileSettingFloat('layer_height') + profile.getProfileSettingFloat('bottom_thickness')
+ self._parent._viewTarget[2] = viewZ
+ msize = max(profile.getMachineSettingFloat('machine_width'), profile.getMachineSettingFloat('machine_depth'))
+ lineTypeList = [('inset0',[1,0,0,1]), ('insetx',[0,1,0,1]), ('openoutline',[1,0,0,1]), ('skin',[1,1,0,1]), ('infill',[1,1,0,1]), ('support',[0,1,1,1]), ('outline',[0,0,0,1])]
+ n = 0
+ layers = None #self._result.getGCodeLayers()
+ generatedVBO = False
+ while n < layerNr:
+ if layerNr - n > 30:
+ idx = n / 20
+ while len(self._layer20VBOs) < idx + 1:
+ self._layer20VBOs.append({})
+ if self._result is not None and self._result._polygons is not None and n + 20 < len(self._result._polygons):
+ layerVBOs = self._layer20VBOs[idx]
+ for typeName, color in lineTypeList:
+ if typeName in self._result._polygons[n + 19]:
+ if typeName not in self._layer20VBOs[idx]:
+ if generatedVBO:
+ continue
+ polygons = []
+ for i in xrange(0, 20):
+ if typeName in self._result._polygons[n + i]:
+ polygons += self._result._polygons[n + i][typeName]
+ layerVBOs[typeName] = self._polygonsToVBO_lines(polygons)
+ generatedVBO = True
+ glColor4f(color[0]*0.5,color[1]*0.5,color[2]*0.5,color[3])
+ layerVBOs[typeName].render()
+ n += 20
+ else:
+ while len(self._layerVBOs) < n + 1:
+ self._layerVBOs.append({})
+ c = 1.0 - ((layerNr - n) - 1) * 0.05
+ c = max(0.5, c)
+ layerVBOs = self._layerVBOs[n]
+ if layers is not None and n < len(layers):
+ if 'GCODE-FILL' not in layerVBOs:
+ layerVBOs['GCODE-FILL'] = self._gcodeToVBO_quads(layers[n:n+1], 'FILL')
+ glColor4f(c,c,0,1)
+ layerVBOs['GCODE-FILL'].render()
+ elif self._result is not None and self._result._polygons is not None and n < len(self._result._polygons):
+ polygons = self._result._polygons[n]
+ for typeName, color in lineTypeList:
+ if typeName in polygons:
+ if typeName not in layerVBOs:
+ layerVBOs[typeName] = self._polygonsToVBO_lines(polygons[typeName])
+ glColor4f(color[0]*c,color[1]*c,color[2]*c,color[3])
+ layerVBOs[typeName].render()
+ n += 1
+ glPopMatrix()
+ if generatedVBO:
+ self._parent._queueRefresh()
+
+ def _polygonsToVBO_lines(self, polygons):
+ verts = numpy.zeros((0, 3), numpy.float32)
+ indices = numpy.zeros((0), numpy.uint32)
+ for poly in polygons:
+ i = numpy.arange(len(verts), len(verts) + len(poly) + 1, 1, numpy.uint32)
+ i[-1] = len(verts)
+ i = numpy.dstack((i[0:-1],i[1:])).flatten()
+ indices = numpy.concatenate((indices, i), 0)
+ verts = numpy.concatenate((verts, poly), 0)
+ return opengl.GLVBO(GL_LINES, verts, indicesArray=indices)
+
+ def _polygonsToVBO_quads(self, polygons):
+ verts = numpy.zeros((0, 3), numpy.float32)
+ indices = numpy.zeros((0), numpy.uint32)
+ for poly in polygons:
+ i = numpy.arange(len(verts), len(verts) + len(poly) + 1, 1, numpy.uint32)
+ i2 = numpy.arange(len(verts) + len(poly), len(verts) + len(poly) + len(poly) + 1, 1, numpy.uint32)
+ i[-1] = len(verts)
+ i2[-1] = len(verts) + len(poly)
+ i = numpy.dstack((i[0:-1],i2[0:-1],i2[1:],i[1:])).flatten()
+ indices = numpy.concatenate((indices, i), 0)
+ verts = numpy.concatenate((verts, poly), 0)
+ verts = numpy.concatenate((verts, poly * numpy.array([1,0,1],numpy.float32) + numpy.array([0,-100,0],numpy.float32)), 0)
+ return opengl.GLVBO(GL_QUADS, verts, indicesArray=indices)
+
+ def _gcodeToVBO_lines(self, gcodeLayers, extrudeType):
+ if ':' in extrudeType:
+ extruder = int(extrudeType[extrudeType.find(':')+1:])
+ extrudeType = extrudeType[0:extrudeType.find(':')]
+ else:
+ extruder = None
+ verts = numpy.zeros((0, 3), numpy.float32)
+ indices = numpy.zeros((0), numpy.uint32)
+ for layer in gcodeLayers:
+ for path in layer:
+ if path['type'] == 'extrude' and path['pathType'] == extrudeType and (extruder is None or path['extruder'] == extruder):
+ i = numpy.arange(len(verts), len(verts) + len(path['points']), 1, numpy.uint32)
+ i = numpy.dstack((i[0:-1],i[1:])).flatten()
+ indices = numpy.concatenate((indices, i), 0)
+ verts = numpy.concatenate((verts, path['points']))
+ return opengl.GLVBO(GL_LINES, verts, indicesArray=indices)
+
+ def _gcodeToVBO_quads(self, gcodeLayers, extrudeType):
+ useFilamentArea = profile.getMachineSetting('gcode_flavor') == 'UltiGCode'
+ filamentRadius = profile.getProfileSettingFloat('filament_diameter') / 2
+ filamentArea = math.pi * filamentRadius * filamentRadius
+
+ if ':' in extrudeType:
+ extruder = int(extrudeType[extrudeType.find(':')+1:])
+ extrudeType = extrudeType[0:extrudeType.find(':')]
+ else:
+ extruder = None
+
+ verts = numpy.zeros((0, 3), numpy.float32)
+ indices = numpy.zeros((0), numpy.uint32)
+ for layer in gcodeLayers:
+ for path in layer:
+ if path['type'] == 'extrude' and path['pathType'] == extrudeType and (extruder is None or path['extruder'] == extruder):
+ a = path['points']
+ if extrudeType == 'FILL':
+ a[:,2] += 0.01
+
+ #Construct the normals of each line 90deg rotated on the X/Y plane
+ normals = a[1:] - a[:-1]
+ lengths = numpy.sqrt(normals[:,0]**2 + normals[:,1]**2)
+ normals[:,0], normals[:,1] = -normals[:,1] / lengths, normals[:,0] / lengths
+ normals[:,2] /= lengths
+
+ ePerDist = path['extrusion'][1:] / lengths
+ if useFilamentArea:
+ lineWidth = ePerDist / path['layerThickness'] / 2.0
+ else:
+ lineWidth = ePerDist * (filamentArea / path['layerThickness'] / 2)
+
+ normals[:,0] *= lineWidth
+ normals[:,1] *= lineWidth
+
+ b = numpy.zeros((len(a)-1, 0), numpy.float32)
+ b = numpy.concatenate((b, a[1:] + normals), 1)
+ b = numpy.concatenate((b, a[1:] - normals), 1)
+ b = numpy.concatenate((b, a[:-1] - normals), 1)
+ b = numpy.concatenate((b, a[:-1] + normals), 1)
+ b = b.reshape((len(b) * 4, 3))
+
+ i = numpy.arange(len(verts), len(verts) + len(b), 1, numpy.uint32)
+
+ verts = numpy.concatenate((verts, b))
+ indices = numpy.concatenate((indices, i))
+ return opengl.GLVBO(GL_QUADS, verts, indicesArray=indices)
+
+ def OnKeyChar(self, keyCode):
+ if not self._enabled:
+ return
+
+ if wx.GetKeyState(wx.WXK_SHIFT) or wx.GetKeyState(wx.WXK_CONTROL):
+ if keyCode == wx.WXK_UP:
+ self.layerSelect.setValue(self.layerSelect.getValue() + 1)
+ self._parent.QueueRefresh()
+ return True
+ elif keyCode == wx.WXK_DOWN:
+ self.layerSelect.setValue(self.layerSelect.getValue() - 1)
+ self._parent.QueueRefresh()
+ return True
+ elif keyCode == wx.WXK_PAGEUP:
+ self.layerSelect.setValue(self.layerSelect.getValue() + 10)
+ self._parent.QueueRefresh()
+ return True
+ elif keyCode == wx.WXK_PAGEDOWN:
+ self.layerSelect.setValue(self.layerSelect.getValue() - 10)
+ self._parent.QueueRefresh()
+ return True
+ return False
+
+ # if self.viewMode == 'gcode' and self._gcode is not None:
+ # try:
+ # self._viewTarget[2] = self._gcode.layerList[self.layerSelect.getValue()][-1]['points'][0][2]
+ # except:
+ # pass
+
+ # def _loadGCode(self):
+ # self._gcode.progressCallback = self._gcodeLoadCallback
+ # if self._gcodeFilename is not None:
+ # self._gcode.load(self._gcodeFilename)
+ # else:
+ # self._gcode.load(self._gcodeData)
+ #
+ # def _gcodeLoadCallback(self, progress):
+ # if not self or self._gcode is None:
+ # return True
+ # if len(self._gcode.layerList) % 15 == 0:
+ # time.sleep(0.1)
+ # if self._gcode is None:
+ # return True
+ # self.layerSelect.setRange(1, len(self._gcode.layerList) - 1)
+ # if self.viewMode == 'gcode':
+ # self._queueRefresh()
+ # return False
+
+ # if self._gcodeLoadThread is not None and self._gcodeLoadThread.isAlive():
+ # glDisable(GL_DEPTH_TEST)
+ # glPushMatrix()
+ # glLoadIdentity()
+ # glTranslate(0,-4,-10)
+ # glColor4ub(60,60,60,255)
+ # opengl.glDrawStringCenter(_("Loading toolpath for visualization..."))
+ # glPopMatrix()
+
+
+# if self._gcode is not None:
+# self._gcode = None
+# for layerVBOlist in self._gcodeVBOs:
+# for vbo in layerVBOlist:
+# self.glReleaseList.append(vbo)
+# self._gcodeVBOs = []
+
+ # if self._gcode is not None and self._gcode.layerList is None:
+ # self._gcodeLoadThread = threading.Thread(target=self._loadGCode)
+ # self._gcodeLoadThread.daemon = True
+ # self._gcodeLoadThread.start()
+ #
+
+ #
+ # if self._gcode is not None and self._gcode.layerList is not None:
+ # glPushMatrix()
+ # if profile.getMachineSetting('machine_center_is_zero') != 'True':
+ # glTranslate(-self._machineSize[0] / 2, -self._machineSize[1] / 2, 0)
+ # t = time.time()
+ # drawUpTill = min(len(self._gcode.layerList), self.layerSelect.getValue() + 1)
+ # for n in xrange(0, drawUpTill):
+ # c = 1.0 - float(drawUpTill - n) / 15
+ # c = max(0.3, c)
+ # if len(self._gcodeVBOs) < n + 1:
+ # self._gcodeVBOs.append(self._generateGCodeVBOs(self._gcode.layerList[n]))
+ # if time.time() - t > 0.5:
+ # self.QueueRefresh()
+ # break
+ # #['WALL-OUTER', 'WALL-INNER', 'FILL', 'SUPPORT', 'SKIRT']
+ # if n == drawUpTill - 1:
+ # if len(self._gcodeVBOs[n]) < 9:
+ # self._gcodeVBOs[n] += self._generateGCodeVBOs2(self._gcode.layerList[n])
+ # glColor3f(c, 0, 0)
+ # self._gcodeVBOs[n][8].render(GL_QUADS)
+ # glColor3f(c/2, 0, c)
+ # self._gcodeVBOs[n][9].render(GL_QUADS)
+ # glColor3f(0, c, c/2)
+ # self._gcodeVBOs[n][10].render(GL_QUADS)
+ # glColor3f(c, 0, 0)
+ # self._gcodeVBOs[n][11].render(GL_QUADS)
+ #
+ # glColor3f(0, c, 0)
+ # self._gcodeVBOs[n][12].render(GL_QUADS)
+ # glColor3f(c/2, c/2, 0.0)
+ # self._gcodeVBOs[n][13].render(GL_QUADS)
+ # glColor3f(0, c, c)
+ # self._gcodeVBOs[n][14].render(GL_QUADS)
+ # self._gcodeVBOs[n][15].render(GL_QUADS)
+ # glColor3f(0, 0, c)
+ # self._gcodeVBOs[n][16].render(GL_LINES)
+ # else:
+ # glColor3f(c, 0, 0)
+ # self._gcodeVBOs[n][0].render(GL_LINES)
+ # glColor3f(c/2, 0, c)
+ # self._gcodeVBOs[n][1].render(GL_LINES)
+ # glColor3f(0, c, c/2)
+ # self._gcodeVBOs[n][2].render(GL_LINES)
+ # glColor3f(c, 0, 0)
+ # self._gcodeVBOs[n][3].render(GL_LINES)
+ #
+ # glColor3f(0, c, 0)
+ # self._gcodeVBOs[n][4].render(GL_LINES)
+ # glColor3f(c/2, c/2, 0.0)
+ # self._gcodeVBOs[n][5].render(GL_LINES)
+ # glColor3f(0, c, c)
+ # self._gcodeVBOs[n][6].render(GL_LINES)
+ # self._gcodeVBOs[n][7].render(GL_LINES)
+ # glPopMatrix()
+ #
+ # def _generateGCodeVBOs(self, layer):
+ # ret = []
+ # for extrudeType in ['WALL-OUTER:0', 'WALL-OUTER:1', 'WALL-OUTER:2', 'WALL-OUTER:3', 'WALL-INNER', 'FILL', 'SUPPORT', 'SKIRT']:
+ # if ':' in extrudeType:
+ # extruder = int(extrudeType[extrudeType.find(':')+1:])
+ # extrudeType = extrudeType[0:extrudeType.find(':')]
+ # else:
+ # extruder = None
+ # pointList = numpy.zeros((0,3), numpy.float32)
+ # for path in layer:
+ # if path['type'] == 'extrude' and path['pathType'] == extrudeType and (extruder is None or path['extruder'] == extruder):
+ # a = path['points']
+ # a = numpy.concatenate((a[:-1], a[1:]), 1)
+ # a = a.reshape((len(a) * 2, 3))
+ # pointList = numpy.concatenate((pointList, a))
+ # ret.append(opengl.GLVBO(pointList))
+ # return ret
+ #
+ # def _generateGCodeVBOs2(self, layer):
+ # filamentRadius = profile.getProfileSettingFloat('filament_diameter') / 2
+ # filamentArea = math.pi * filamentRadius * filamentRadius
+ # useFilamentArea = profile.getMachineSetting('gcode_flavor') == 'UltiGCode'
+ #
+ # ret = []
+ # for extrudeType in ['WALL-OUTER:0', 'WALL-OUTER:1', 'WALL-OUTER:2', 'WALL-OUTER:3', 'WALL-INNER', 'FILL', 'SUPPORT', 'SKIRT']:
+ # if ':' in extrudeType:
+ # extruder = int(extrudeType[extrudeType.find(':')+1:])
+ # extrudeType = extrudeType[0:extrudeType.find(':')]
+ # else:
+ # extruder = None
+ # pointList = numpy.zeros((0,3), numpy.float32)
+ # for path in layer:
+ # if path['type'] == 'extrude' and path['pathType'] == extrudeType and (extruder is None or path['extruder'] == extruder):
+ # a = path['points']
+ # if extrudeType == 'FILL':
+ # a[:,2] += 0.01
+ #
+ # normal = a[1:] - a[:-1]
+ # lens = numpy.sqrt(normal[:,0]**2 + normal[:,1]**2)
+ # normal[:,0], normal[:,1] = -normal[:,1] / lens, normal[:,0] / lens
+ # normal[:,2] /= lens
+ #
+ # ePerDist = path['extrusion'][1:] / lens
+ # if useFilamentArea:
+ # lineWidth = ePerDist / path['layerThickness'] / 2.0
+ # else:
+ # lineWidth = ePerDist * (filamentArea / path['layerThickness'] / 2)
+ #
+ # normal[:,0] *= lineWidth
+ # normal[:,1] *= lineWidth
+ #
+ # b = numpy.zeros((len(a)-1, 0), numpy.float32)
+ # b = numpy.concatenate((b, a[1:] + normal), 1)
+ # b = numpy.concatenate((b, a[1:] - normal), 1)
+ # b = numpy.concatenate((b, a[:-1] - normal), 1)
+ # b = numpy.concatenate((b, a[:-1] + normal), 1)
+ # b = b.reshape((len(b) * 4, 3))
+ #
+ # if len(a) > 2:
+ # normal2 = normal[:-1] + normal[1:]
+ # lens2 = numpy.sqrt(normal2[:,0]**2 + normal2[:,1]**2)
+ # normal2[:,0] /= lens2
+ # normal2[:,1] /= lens2
+ # normal2[:,0] *= lineWidth[:-1]
+ # normal2[:,1] *= lineWidth[:-1]
+ #
+ # c = numpy.zeros((len(a)-2, 0), numpy.float32)
+ # c = numpy.concatenate((c, a[1:-1]), 1)
+ # c = numpy.concatenate((c, a[1:-1]+normal[1:]), 1)
+ # c = numpy.concatenate((c, a[1:-1]+normal2), 1)
+ # c = numpy.concatenate((c, a[1:-1]+normal[:-1]), 1)
+ #
+ # c = numpy.concatenate((c, a[1:-1]), 1)
+ # c = numpy.concatenate((c, a[1:-1]-normal[1:]), 1)
+ # c = numpy.concatenate((c, a[1:-1]-normal2), 1)
+ # c = numpy.concatenate((c, a[1:-1]-normal[:-1]), 1)
+ #
+ # c = c.reshape((len(c) * 8, 3))
+ #
+ # pointList = numpy.concatenate((pointList, b, c))
+ # else:
+ # pointList = numpy.concatenate((pointList, b))
+ # ret.append(opengl.GLVBO(pointList))
+ #
+ # pointList = numpy.zeros((0,3), numpy.float32)
+ # for path in layer:
+ # if path['type'] == 'move':
+ # a = path['points'] + numpy.array([0,0,0.01], numpy.float32)
+ # a = numpy.concatenate((a[:-1], a[1:]), 1)
+ # a = a.reshape((len(a) * 2, 3))
+ # pointList = numpy.concatenate((pointList, a))
+ # if path['type'] == 'retract':
+ # a = path['points'] + numpy.array([0,0,0.01], numpy.float32)
+ # a = numpy.concatenate((a[:-1], a[1:] + numpy.array([0,0,1], numpy.float32)), 1)
+ # a = a.reshape((len(a) * 2, 3))
+ # pointList = numpy.concatenate((pointList, a))
+ # ret.append(opengl.GLVBO(pointList))
+ #
+ # return ret
import wx
import time
-from Cura.util import meshLoader
-from Cura.util import util3d
-from Cura.util import profile
-from Cura.util.resources import getPathForMesh, getPathForImage
+from Cura.util.resources import getPathForImage
import OpenGL
-OpenGL.ERROR_CHECKING = False
+#OpenGL.ERROR_CHECKING = False
from OpenGL.GLUT import *
from OpenGL.GLU import *
from OpenGL.GL import *
return ''
class GLVBO(GLReferenceCounter):
- def __init__(self, vertexArray, normalArray = None):
+ def __init__(self, renderType, vertexArray, normalArray = None, indicesArray = None):
super(GLVBO, self).__init__()
+ self._renderType = renderType
if not bool(glGenBuffers):
self._vertexArray = vertexArray
self._normalArray = normalArray
+ self._indicesArray = indicesArray
self._size = len(vertexArray)
self._buffer = None
self._hasNormals = self._normalArray is not None
+ self._hasIndices = self._indicesArray is not None
else:
self._buffer = glGenBuffers(1)
self._size = len(vertexArray)
self._hasNormals = normalArray is not None
+ self._hasIndices = indicesArray is not None
glBindBuffer(GL_ARRAY_BUFFER, self._buffer)
if self._hasNormals:
glBufferData(GL_ARRAY_BUFFER, numpy.concatenate((vertexArray, normalArray), 1), GL_STATIC_DRAW)
else:
glBufferData(GL_ARRAY_BUFFER, vertexArray, GL_STATIC_DRAW)
glBindBuffer(GL_ARRAY_BUFFER, 0)
+ if self._hasIndices:
+ self._size = len(indicesArray)
+ self._bufferIndices = glGenBuffers(1)
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, self._bufferIndices)
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, numpy.array(indicesArray, numpy.uint32), GL_STATIC_DRAW)
- def render(self, render_type = GL_TRIANGLES):
+ def render(self):
glEnableClientState(GL_VERTEX_ARRAY)
if self._buffer is None:
glVertexPointer(3, GL_FLOAT, 0, self._vertexArray)
glNormalPointer(GL_FLOAT, 2*3*4, c_void_p(3 * 4))
else:
glVertexPointer(3, GL_FLOAT, 3*4, c_void_p(0))
+ if self._hasIndices:
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, self._bufferIndices)
- batchSize = 996 #Warning, batchSize needs to be dividable by 4, 3 and 2
- extraStartPos = int(self._size / batchSize) * batchSize
- extraCount = self._size - extraStartPos
+ if self._hasIndices:
+ glDrawElements(self._renderType, self._size, GL_UNSIGNED_INT, c_void_p(0))
+ else:
+ batchSize = 996 #Warning, batchSize needs to be dividable by 4, 3 and 2
+ extraStartPos = int(self._size / batchSize) * batchSize
+ extraCount = self._size - extraStartPos
+ for i in xrange(0, int(self._size / batchSize)):
+ glDrawArrays(self._renderType, i * batchSize, batchSize)
+ glDrawArrays(self._renderType, extraStartPos, extraCount)
- for i in xrange(0, int(self._size / batchSize)):
- glDrawArrays(render_type, i * batchSize, batchSize)
- glDrawArrays(render_type, extraStartPos, extraCount)
if self._buffer is not None:
glBindBuffer(GL_ARRAY_BUFFER, 0)
+ if self._hasIndices:
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)
glDisableClientState(GL_VERTEX_ARRAY)
if self._hasNormals:
glVertex3f(mesh.vertexes[i + 1][0], mesh.vertexes[i + 1][1], mesh.vertexes[i + 1][2])
glEnd()
glDepthFunc(GL_LESS)
-
-def DrawGCodeLayer(layer, drawQuick = True):
- filamentRadius = profile.getProfileSettingFloat('filament_diameter') / 2
- filamentArea = math.pi * filamentRadius * filamentRadius
- lineWidth = profile.getProfileSettingFloat('nozzle_size') / 2 / 10
-
- fillCycle = 0
- fillColorCycle = [[0.5, 0.5, 0.0, 1], [0.0, 0.5, 0.5, 1], [0.5, 0.0, 0.5, 1]]
- moveColor = [0, 0, 1, 0.5]
- retractColor = [1, 0, 0.5, 0.5]
- supportColor = [0, 1, 1, 1]
- extrudeColor = [[1, 0, 0, 1], [0, 1, 1, 1], [1, 1, 0, 1], [1, 0, 1, 1]]
- innerWallColor = [0, 1, 0, 1]
- skirtColor = [0, 0.5, 0.5, 1]
- prevPathWasRetract = False
-
- glDisable(GL_CULL_FACE)
- for path in layer:
- if path.type == 'move':
- if prevPathWasRetract:
- c = retractColor
- else:
- c = moveColor
- if drawQuick:
- continue
- zOffset = 0.01
- if path.type == 'extrude':
- if path.pathType == 'FILL':
- c = fillColorCycle[fillCycle]
- fillCycle = (fillCycle + 1) % len(fillColorCycle)
- elif path.pathType == 'WALL-INNER':
- c = innerWallColor
- zOffset = 0.02
- elif path.pathType == 'SUPPORT':
- c = supportColor
- elif path.pathType == 'SKIRT':
- c = skirtColor
- else:
- c = extrudeColor[path.extruder]
- if path.type == 'retract':
- c = retractColor
- if path.type == 'extrude' and not drawQuick:
- drawLength = 0.0
- prevNormal = None
- for i in xrange(0, len(path.points) - 1):
- v0 = path.points[i]
- v1 = path.points[i + 1]
-
- # Calculate line width from ePerDistance (needs layer thickness and filament diameter)
- dist = (v0 - v1).vsize()
- if dist > 0 and path.layerThickness > 0:
- extrusionMMperDist = (v1.e - v0.e) / dist
- lineWidth = extrusionMMperDist * filamentArea / path.layerThickness / 2 * v1.extrudeAmountMultiply
-
- drawLength += (v0 - v1).vsize()
- normal = (v0 - v1).cross(util3d.Vector3(0, 0, 1))
- normal.normalize()
-
- vv2 = v0 + normal * lineWidth
- vv3 = v1 + normal * lineWidth
- vv0 = v0 - normal * lineWidth
- vv1 = v1 - normal * lineWidth
-
- glBegin(GL_QUADS)
- glColor4fv(c)
- glVertex3f(vv0.x, vv0.y, vv0.z - zOffset)
- glVertex3f(vv1.x, vv1.y, vv1.z - zOffset)
- glVertex3f(vv3.x, vv3.y, vv3.z - zOffset)
- glVertex3f(vv2.x, vv2.y, vv2.z - zOffset)
- glEnd()
- if prevNormal is not None:
- n = (normal + prevNormal)
- n.normalize()
- vv4 = v0 + n * lineWidth
- vv5 = v0 - n * lineWidth
- glBegin(GL_QUADS)
- glColor4fv(c)
- glVertex3f(vv2.x, vv2.y, vv2.z - zOffset)
- glVertex3f(vv4.x, vv4.y, vv4.z - zOffset)
- glVertex3f(prevVv3.x, prevVv3.y, prevVv3.z - zOffset)
- glVertex3f(v0.x, v0.y, v0.z - zOffset)
-
- glVertex3f(vv0.x, vv0.y, vv0.z - zOffset)
- glVertex3f(vv5.x, vv5.y, vv5.z - zOffset)
- glVertex3f(prevVv1.x, prevVv1.y, prevVv1.z - zOffset)
- glVertex3f(v0.x, v0.y, v0.z - zOffset)
- glEnd()
-
- prevNormal = normal
- prevVv1 = vv1
- prevVv3 = vv3
- else:
- glColor4fv(c)
- glBegin(GL_TRIANGLES)
- for v in path.points:
- glVertex3f(v[0], v[1], v[2])
- glEnd()
-
- if not path.type == 'move':
- prevPathWasRetract = False
- #if path.type == 'retract' and path.points[0].almostEqual(path.points[-1]):
- # prevPathWasRetract = True
- glEnable(GL_CULL_FACE)
from wx import glcanvas
import OpenGL
-OpenGL.ERROR_CHECKING = False
+#OpenGL.ERROR_CHECKING = False
from OpenGL.GL import *
from Cura.util import version
locationInfo = tb[n]
errStr += "\n @ %s:%s:%d" % (os.path.basename(locationInfo[0]), locationInfo[2], locationInfo[1])
if not self._shownError:
+ traceback.print_exc()
wx.CallAfter(wx.MessageBox, errStr, _("3D window error"), wx.OK | wx.ICON_EXCLAMATION)
self._shownError = True
# glVertex2f(0, 0)
# glEnd()
# glDisable(GL_TEXTURE_2D)
- glPopMatrix()
+ # glPopMatrix()
def _OnEraseBackground(self,event):
#Workaround for windows background redraw flicker.
import numpy
import OpenGL
-OpenGL.ERROR_CHECKING = False
+#OpenGL.ERROR_CHECKING = False
from OpenGL.GLU import *
from OpenGL.GL import *
import os
import time
import numpy
+import types
+import cStringIO as StringIO
from Cura.util import profile
-#class gcodePath(object):
-# def __init__(self, newType, pathType, layerThickness, startPoint):
-# self.type = newType
-# self.pathType = pathType
-# self.layerThickness = layerThickness
-# self.points = [startPoint]
-# self.extrusion = [0.0]
def gcodePath(newType, pathType, layerThickness, startPoint):
return {'type': newType,
'pathType': pathType,
self.regMatch = {}
self.layerList = None
self.extrusionAmount = 0
- self.totalMoveTimeMinute = 0
self.filename = None
self.progressCallback = None
- def load(self, filename):
- if os.path.isfile(filename):
- self.filename = filename
- self._fileSize = os.stat(filename).st_size
- gcodeFile = open(filename, 'r')
+ def load(self, data):
+ self.filename = None
+ if type(data) in types.StringTypes and os.path.isfile(data):
+ self.filename = data
+ self._fileSize = os.stat(data).st_size
+ gcodeFile = open(data, 'r')
self._load(gcodeFile)
gcodeFile.close()
-
- def loadList(self, l):
- self.filename = None
- self._load(l)
-
+ elif type(data) is list:
+ self._load(data)
+ else:
+ self._fileSize = len(data.getvalue())
+ self._load(StringIO.StringIO(data.getvalue()))
+
def calculateWeight(self):
#Calculates the weight of the filament in kg
radius = float(profile.getProfileSetting('filament_diameter')) / 2
pos = [0.0,0.0,0.0]
posOffset = [0.0, 0.0, 0.0]
currentE = 0.0
- totalExtrusion = 0.0
- maxExtrusion = 0.0
currentExtruder = 0
extrudeAmountMultiply = 1.0
- totalMoveTimeMinute = 0.0
absoluteE = True
scale = 1.0
posAbs = True
pos[1] += y * scale
if z is not None:
pos[2] += z * scale
- #if f is not None:
- # feedRate = f
- #if x is not None or y is not None or z is not None:
- # diffX = oldPos[0] - pos[0]
- # diffY = oldPos[1] - pos[1]
- # totalMoveTimeMinute += math.sqrt(diffX * diffX + diffY * diffY) / feedRate
moveType = 'move'
if e is not None:
if absoluteE:
moveType = 'extrude'
if e < 0.0:
moveType = 'retract'
- totalExtrusion += e
currentE += e
- if totalExtrusion > maxExtrusion:
- maxExtrusion = totalExtrusion
else:
e = 0.0
if moveType == 'move' and oldPos[2] != pos[2]:
currentPath['extrusion'].append(e * extrudeAmountMultiply)
elif G == 4: #Delay
S = getCodeFloat(line, 'S')
- if S is not None:
- totalMoveTimeMinute += S / 60.0
P = getCodeFloat(line, 'P')
- if P is not None:
- totalMoveTimeMinute += P / 60.0 / 1000.0
elif G == 10: #Retract
currentPath = gcodePath('retract', pathType, layerThickness, currentPath['points'][-1])
currentPath['extruder'] = currentExtruder
self.layerList.append(currentLayer)
if self.progressCallback is not None and self._fileSize > 0:
self.progressCallback(float(gcodeFile.tell()) / float(self._fileSize))
- self.extrusionAmount = maxExtrusion
- self.totalMoveTimeMinute = totalMoveTimeMinute
- #print "Extruded a total of: %d mm of filament" % (self.extrusionAmount)
- #print "Estimated print duration: %.2f minutes" % (self.totalMoveTimeMinute)
def getCodeInt(line, code):
n = line.find(code) + 1
for filename in sys.argv[1:]:
g = gcode()
g.load(filename)
- print g.totalMoveTimeMinute
print time.time() - t
setting('language', 'English', str, 'preference', 'hidden').setLabel(_('Language'), _('Change the language in which Cura runs. Switching language requires a restart of Cura'))
setting('active_machine', '0', int, 'preference', 'hidden')
-setting('model_colour', '#FFC924', str, 'preference', 'hidden').setLabel(_('Model colour'))
-setting('model_colour2', '#CB3030', str, 'preference', 'hidden').setLabel(_('Model colour (2)'))
-setting('model_colour3', '#DDD93C', str, 'preference', 'hidden').setLabel(_('Model colour (3)'))
-setting('model_colour4', '#4550D3', str, 'preference', 'hidden').setLabel(_('Model colour (4)'))
+setting('model_colour', '#FFC924', str, 'preference', 'hidden').setLabel(_('Model colour'), _('Display color for first extruder'))
+setting('model_colour2', '#CB3030', str, 'preference', 'hidden').setLabel(_('Model colour (2)'), _('Display color for second extruder'))
+setting('model_colour3', '#DDD93C', str, 'preference', 'hidden').setLabel(_('Model colour (3)'), _('Display color for third extruder'))
+setting('model_colour4', '#4550D3', str, 'preference', 'hidden').setLabel(_('Model colour (4)'), _('Display color for forth extruder'))
setting('window_maximized', 'True', bool, 'preference', 'hidden')
setting('window_pos_x', '-1', float, 'preference', 'hidden')
import urllib
import urllib2
import hashlib
+import cStringIO as StringIO
from Cura.util import profile
from Cura.util import version
+from Cura.util import gcodeInterpreter
def getEngineFilename():
if platform.system() == 'Windows':
warnings.simplefilter('default')
return ret
-class Slicer(object):
- def __init__(self, progressCallback):
- self._process = None
- self._thread = None
- self._callback = progressCallback
- self._binaryStorageFilename = getTempFilename()
- self._exportFilename = getTempFilename()
- self._progressSteps = ['inset', 'skin', 'export']
- self._objCount = 0
- self._sliceLog = []
+class EngineResult(object):
+ def __init__(self):
+ self._engineLog = []
+ self._gcodeData = StringIO.StringIO()
+ self._polygons = []
+ self._success = False
self._printTimeSeconds = None
- self._filamentMM = [0.0, 0.0]
+ self._filamentMM = [0.0] * 4
self._modelHash = None
- self._id = 0
-
- def cleanup(self):
- self.abortSlicer()
- try:
- os.remove(self._binaryStorageFilename)
- except:
- pass
- try:
- os.remove(self._exportFilename)
- except:
- pass
-
- def abortSlicer(self):
- if self._process is not None:
- try:
- self._process.terminate()
- except:
- pass
- self._thread.join()
- self._thread = None
-
- def wait(self):
- if self._thread is not None:
- self._thread.join()
-
- def getGCodeFilename(self):
- return self._exportFilename
-
- def getSliceLog(self):
- return self._sliceLog
-
- def getID(self):
- return self._id
+ self._profileString = profile.getProfileString()
+ self._preferencesString = profile.getPreferencesString()
+ self._gcodeInterpreter = gcodeInterpreter.gcode()
+ self._gcodeLoadThread = None
+ self._finished = False
def getFilamentWeight(self, e=0):
#Calculates the weight of the filament in kg
return None
return '%0.2f meter %0.0f gram' % (float(self._filamentMM[e]) / 1000.0, self.getFilamentWeight(e) * 1000.0)
- def runSlicer(self, scene):
+ def getLog(self):
+ return self._engineLog
+
+ def getGCode(self):
+ return self._gcodeData.getvalue()
+
+ def addLog(self, line):
+ self._engineLog.append(line)
+
+ def setHash(self, hash):
+ self._modelHash = hash
+
+ def setFinished(self, result):
+ self._finished = result
+
+ def isFinished(self):
+ return self._finished
+
+ def getGCodeLayers(self):
+ if not self._finished:
+ return None
+ if self._gcodeInterpreter.layerList is None and self._gcodeLoadThread is None:
+ self._gcodeInterpreter.progressCallback = self._gcodeInterpreterCallback
+ self._gcodeLoadThread = threading.Thread(target=lambda : self._gcodeInterpreter.load(self._gcodeData))
+ self._gcodeLoadThread.daemon = True
+ self._gcodeLoadThread.start()
+ return self._gcodeInterpreter.layerList
+
+ def _gcodeInterpreterCallback(self, progress):
+ if len(self._gcodeInterpreter.layerList) % 15 == 0:
+ time.sleep(0.1)
+ return False
+
+ def submitInfoOnline(self):
+ if profile.getPreference('submit_slice_information') != 'True':
+ return
+ if version.isDevVersion():
+ return
+ data = {
+ 'processor': platform.processor(),
+ 'machine': platform.machine(),
+ 'platform': platform.platform(),
+ 'profile': self._profileString,
+ 'preferences': self._preferencesString,
+ 'modelhash': self._modelHash,
+ 'version': version.getVersion(),
+ }
+ try:
+ f = urllib2.urlopen("http://www.youmagine.com/curastats/", data = urllib.urlencode(data), timeout = 1)
+ f.read()
+ f.close()
+ except:
+ pass
+
+class Engine(object):
+ def __init__(self, progressCallback):
+ self._process = None
+ self._thread = None
+ self._callback = progressCallback
+ self._binaryStorageFilename = getTempFilename()
+ self._progressSteps = ['inset', 'skin', 'export']
+ self._objCount = 0
+ self._result = None
+
+ def cleanup(self):
+ self.abortEngine()
+ try:
+ os.remove(self._binaryStorageFilename)
+ except:
+ pass
+
+ def abortEngine(self):
+ if self._process is not None:
+ try:
+ self._process.terminate()
+ except:
+ pass
+ if self._thread is not None:
+ self._thread.join()
+ self._thread = None
+
+ def wait(self):
+ if self._thread is not None:
+ self._thread.join()
+
+ def getResult(self):
+ return self._result
+
+ def runEngine(self, scene):
if len(scene.objects()) < 1:
return
extruderCount = 1
extruderCount = max(extruderCount, profile.minimalExtruderCount())
- commandList = [getEngineFilename(), '-vv']
+ commandList = [getEngineFilename(), '-vvv']
for k, v in self._engineSettings(extruderCount).iteritems():
commandList += ['-s', '%s=%s' % (k, str(v))]
- commandList += ['-o', self._exportFilename]
commandList += ['-b', self._binaryStorageFilename]
self._objCount = 0
with open(self._binaryStorageFilename, "wb") as f:
objMin[1] = min(oMin[1], objMin[1])
objMax[0] = max(oMax[0], objMax[0])
objMax[1] = max(oMax[1], objMax[1])
+ if objMin is None:
+ return
pos += (objMin + objMax) / 2.0 * 1000
commandList += ['-s', 'posx=%d' % int(pos[0]), '-s', 'posy=%d' % int(pos[1])]
commandList += ['-s', 'posx=%d' % int(pos[0]), '-s', 'posy=%d' % int(pos[1])]
commandList += ['#' * len(obj._meshList)]
self._objCount += 1
- self._modelHash = hash.hexdigest()
+ modelHash = hash.hexdigest()
if self._objCount > 0:
- self._thread = threading.Thread(target=self._watchProcess, args=(commandList, self._thread))
+ self._thread = threading.Thread(target=self._watchProcess, args=(commandList, self._thread, modelHash))
self._thread.daemon = True
self._thread.start()
- def _watchProcess(self, commandList, oldThread):
+ def _watchProcess(self, commandList, oldThread, modelHash):
if oldThread is not None:
if self._process is not None:
self._process.terminate()
oldThread.join()
- self._id += 1
- self._callback(-1.0, False)
+ self._callback(-1.0)
try:
- self._process = self._runSliceProcess(commandList)
+ self._process = self._runEngineProcess(commandList)
except OSError:
traceback.print_exc()
return
if self._thread != threading.currentThread():
self._process.terminate()
- self._callback(0.0, False)
- self._sliceLog = []
- self._printTimeSeconds = None
- self._filamentMM = [0.0, 0.0]
- line = self._process.stdout.readline()
+ self._result = EngineResult()
+ self._result.setHash(modelHash)
+ self._callback(0.0)
+
+ logThread = threading.Thread(target=self._watchStderr, args=(self._process.stderr,))
+ logThread.daemon = True
+ logThread.start()
+
+ data = self._process.stdout.read(4096)
+ while len(data) > 0:
+ self._result._gcodeData.write(data)
+ data = self._process.stdout.read(4096)
+
+ returnCode = self._process.wait()
+ logThread.join()
+ if returnCode == 0:
+ pluginError = None #profile.runPostProcessingPlugins(self._exportFilename)
+ if pluginError is not None:
+ print pluginError
+ self._result.addLog(pluginError)
+ self._result.setFinished(True)
+ self._callback(1.0)
+ else:
+ for line in self._result.getLog():
+ print line
+ self._callback(-1.0)
+ self._process = None
+
+ def _watchStderr(self, stderr):
objectNr = 0
- while len(line):
+
+ # data = stderr.read(4096)
+ # tmp = StringIO.StringIO()
+ # while len(data):
+ # tmp.write(data)
+ # data = stderr.read(4096)
+ # stderr = StringIO.StringIO(tmp.getvalue())
+
+ line = stderr.readline()
+ while len(line) > 0:
line = line.strip()
if line.startswith('Progress:'):
line = line.split(':')
progressValue /= self._objCount
progressValue += 1.0 / self._objCount * objectNr
try:
- self._callback(progressValue, False)
+ self._callback(progressValue)
except:
pass
+ elif line.startswith('Polygons:'):
+ line = line.split(':')
+ typeName = line[1]
+ layerNr = int(line[2])
+ size = int(line[3])
+ z = float(line[4])
+ while len(self._result._polygons) < layerNr + 1:
+ self._result._polygons.append({})
+ polygons = self._result._polygons[layerNr]
+ for n in xrange(0, size):
+ polygon = stderr.readline().strip()
+ if not polygon:
+ continue
+ polygon2d = numpy.fromstring(polygon, dtype=numpy.float32, sep=' ')
+ polygon2d = polygon2d.reshape((len(polygon2d) / 2, 2))
+ polygon = numpy.empty((len(polygon2d), 3), numpy.float32)
+ polygon[:,:-1] = polygon2d
+ polygon[:,2] = z
+ if typeName not in polygons:
+ polygons[typeName] = []
+ polygons[typeName].append(polygon)
elif line.startswith('Print time:'):
- self._printTimeSeconds = int(line.split(':')[1].strip())
+ self._result._printTimeSeconds = int(line.split(':')[1].strip())
elif line.startswith('Filament:'):
- self._filamentMM[0] = int(line.split(':')[1].strip())
+ self._result._filamentMM[0] = int(line.split(':')[1].strip())
if profile.getMachineSetting('gcode_flavor') == 'UltiGCode':
radius = profile.getProfileSettingFloat('filament_diameter') / 2.0
- self._filamentMM[0] /= (math.pi * radius * radius)
+ self._result._filamentMM[0] /= (math.pi * radius * radius)
elif line.startswith('Filament2:'):
- self._filamentMM[1] = int(line.split(':')[1].strip())
+ self._result._filamentMM[1] = int(line.split(':')[1].strip())
if profile.getMachineSetting('gcode_flavor') == 'UltiGCode':
radius = profile.getProfileSettingFloat('filament_diameter') / 2.0
- self._filamentMM[1] /= (math.pi * radius * radius)
+ self._result._filamentMM[1] /= (math.pi * radius * radius)
else:
- self._sliceLog.append(line.strip())
- line = self._process.stdout.readline()
- for line in self._process.stderr:
- self._sliceLog.append(line.strip())
- returnCode = self._process.wait()
- try:
- if returnCode == 0:
- pluginError = profile.runPostProcessingPlugins(self._exportFilename)
- if pluginError is not None:
- print pluginError
- self._sliceLog.append(pluginError)
- self._callback(1.0, True)
- else:
- for line in self._sliceLog:
- print line
- self._callback(-1.0, False)
- except:
- pass
- self._process = None
+ self._result.addLog(line)
+ line = stderr.readline()
def _engineSettings(self, extruderCount):
settings = {
settings['enableOozeShield'] = 1
return settings
- def _runSliceProcess(self, cmdList):
+ def _runEngineProcess(self, cmdList):
kwargs = {}
if subprocess.mswindows:
su = subprocess.STARTUPINFO()
kwargs['startupinfo'] = su
kwargs['creationflags'] = 0x00004000 #BELOW_NORMAL_PRIORITY_CLASS
return subprocess.Popen(cmdList, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, **kwargs)
-
- def submitSliceInfoOnline(self):
- if profile.getPreference('submit_slice_information') != 'True':
- return
- if version.isDevVersion():
- return
- data = {
- 'processor': platform.processor(),
- 'machine': platform.machine(),
- 'platform': platform.platform(),
- 'profile': profile.getProfileString(),
- 'preferences': profile.getPreferencesString(),
- 'modelhash': self._modelHash,
- 'version': version.getVersion(),
- }
- try:
- f = urllib2.urlopen("http://www.youmagine.com/curastats/", data = urllib.urlencode(data), timeout = 1)
- f.read()
- f.close()
- except:
- pass