if not options.output:
options.output = args[0] + profile.getGCodeExtension()
with open(options.output, "wb") as f:
- f.write(engine.getResult().getGCode())
+ gcode = engine.getResult().getGCode()
+ while True:
+ data = gcode.read()
+ if len(data) == 0:
+ break
+ f.write(data)
print 'GCode file saved : %s' % options.output
engine.cleanup()
connection.window = printWindow.printWindowBasic(self, connection)
connection.window.Show()
connection.window.Raise()
- if not connection.loadGCodeData(StringIO.StringIO(self._engine.getResult().getGCode())):
+ if not connection.loadGCodeData(self._engine.getResult().getGCode()):
if connection.isPrinting():
self.notification.message("Cannot start print, because other print still running.")
else:
threading.Thread(target=self._saveGCode,args=(filename,)).start()
def _saveGCode(self, targetFilename, ejectDrive = False):
- data = self._engine.getResult().getGCode()
+ gcode = self._engine.getResult().getGCode()
try:
- size = float(len(data))
- fsrc = StringIO.StringIO(data)
+ size = float(len(gcode))
+ read_pos = 0
with open(targetFilename, 'wb') as fdst:
while 1:
- buf = fsrc.read(16*1024)
- if not buf:
+ buf = gcode.read(16*1024)
+ if len(buf) < 1:
break
+ read_pos += len(buf)
fdst.write(buf)
- self.printButton.setProgressBar(float(fsrc.tell()) / size)
+ self.printButton.setProgressBar(read_pos / size)
self._queueRefresh()
except:
import sys, traceback
--- /dev/null
+import cStringIO as StringIO\r
+\r
+class BigDataStorage(object):\r
+ """\r
+ The StringIO from python aborts with an out-of-memory error after 250MB.\r
+ So the BigDataStorage stores data in multiple StringIOs to prevent this issue.\r
+ """\r
+ def __init__(self):\r
+ self._active = StringIO.StringIO()\r
+ self._list = [self._active]\r
+ self._read_index = None\r
+\r
+ def write(self, data):\r
+ self._active.write(data)\r
+ if self._active.tell() > 1024 * 1024 * 100:\r
+ self._active = StringIO.StringIO()\r
+ self._list.append(self._active)\r
+\r
+ def seekStart(self):\r
+ self._active = self._list[0]\r
+ self._active.seek(0)\r
+ self._read_index = 0\r
+\r
+ def read(self, size=None):\r
+ ret = self._active.read(size)\r
+ if ret == '':\r
+ if self._read_index + 1 < len(self._list):\r
+ self._read_index += 1\r
+ self._active = self._list[self._read_index]\r
+ self._active.seek(0)\r
+ ret = self._active.read(size)\r
+ return ret\r
+\r
+ def replaceAtStart(self, key, value):\r
+ data = self._list[0].getvalue()\r
+ block0 = data[0:2048]\r
+ value = (value + ' ' * len(key))[:len(key)]\r
+ block0 = block0.replace(key, value)\r
+ self._list[0] = StringIO.StringIO()\r
+ self._list[0].write(block0)\r
+ self._list[0].write(data[2048:])\r
+\r
+ def __len__(self):\r
+ ret = 0\r
+ for data in self._list:\r
+ pos = data.tell()\r
+ data.seek(0, 2)\r
+ ret += data.tell()\r
+ data.seek(pos)\r
+ return ret\r
+\r
+ def __iter__(self):\r
+ self._iter_index = 0\r
+ return self\r
+\r
+ def next(self):\r
+ if self._iter_index < len(self._list):\r
+ ret = self._list[self._iter_index].readline()\r
+ if ret == '':\r
+ self._iter_index += 1\r
+ if self._iter_index < len(self._list):\r
+ self._list[self._iter_index].seek(0)\r
+ return self.next()\r
+ return ret\r
+ raise StopIteration\r
+\r
+ def tell(self):\r
+ pos = 0\r
+ for data in self._list[:self._iter_index]:\r
+ pos += data.tell()\r
+ if self._iter_index < len(self._list):\r
+ pos += self._list[self._iter_index].tell()\r
+ return pos\r
+\r
+ def clone(self):\r
+ clone = BigDataStorage()\r
+ clone._list = []\r
+ for item in self._list:\r
+ clone._list.append(StringIO.StringIO(item.getvalue()))\r
+ clone._active = clone._list[-1]\r
+ return clone
\ No newline at end of file
elif type(data) is list:
self._load(data)
else:
- data = data.getvalue()
self._fileSize = len(data)
- self._load(StringIO.StringIO(data))
+ data.seekStart()
+ self._load(data)
def calculateWeight(self):
#Calculates the weight of the filament in kg
if tempfilename is None:
f = tempfile.NamedTemporaryFile(prefix='CuraPluginTemp', delete=False)
tempfilename = f.name
- f.write(engineResult.getGCode())
+ gcode = engineResult.getGCode()
+ while True:
+ data = gcode.read()
+ if len(data) == 0:
+ break
+ f.write(data)
f.close()
locals = {'filename': tempfilename}
import socket
import struct
import errno
-import cStringIO as StringIO
+from Cura.util.bigDataStorage import BigDataStorage
from Cura.util import profile
from Cura.util import pluginInfo
from Cura.util import version
if platform.system() == 'Windows':
if version.isDevVersion() and os.path.exists('C:/Software/Cura_SteamEngine/_bin/Release/Cura_SteamEngine.exe'):
return 'C:/Software/Cura_SteamEngine/_bin/Release/Cura_SteamEngine.exe'
+ if version.isDevVersion() and os.path.exists('C:/Program Files (x86)/Cura_14.09/CuraEngine.exe'):
+ return 'C:/Program Files (x86)/Cura_14.09/CuraEngine.exe'
return os.path.abspath(os.path.join(os.path.dirname(__file__), '../..', 'CuraEngine.exe'))
if hasattr(sys, 'frozen'):
return os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../../..', 'CuraEngine'))
"""
def __init__(self):
self._engineLog = []
- self._gcodeData = StringIO.StringIO()
+ self._gcodeData = BigDataStorage()
self._polygons = []
self._replaceInfo = {}
self._success = False
return self._engineLog
def getGCode(self):
- data = self._gcodeData.getvalue()
- if len(self._replaceInfo) > 0:
- block0 = data[0:2048]
- for k, v in self._replaceInfo.items():
- v = (v + ' ' * len(k))[:len(k)]
- block0 = block0.replace(k, v)
- return block0 + data[2048:]
- return data
+ self._gcodeData.seekStart()
+ return self._gcodeData
def setGCode(self, gcode):
- self._gcodeData = StringIO.StringIO(gcode)
+ self._gcodeData = BigDataStorage()
+ self._gcodeData.write(gcode)
self._replaceInfo = {}
def addLog(self, line):
self._modelHash = hash
def setFinished(self, result):
+ if result:
+ for k, v in self._replaceInfo.items():
+ self._gcodeData.replaceAtStart(k, v)
self._finished = result
def isFinished(self):
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 = threading.Thread(target=lambda : self._gcodeInterpreter.load(self._gcodeData.clone()))
self._gcodeLoadCallback = loadCallback
self._gcodeLoadThread.daemon = True
self._gcodeLoadThread.start()