lineTypeList = [
('inset0', 'WALL-OUTER', [1,0,0,1]),
('insetx', 'WALL-INNER', [0,1,0,1]),
- ('openoutline', None, [1,0,0,1]),
- ('skin', 'FILL', [1,1,0,1]),
- ('infill', None, [1,1,0,1]),
- ('support', 'SUPPORT',[0,1,1,1]),
- ('outline', None, [0,0,0,1])
+ ('openoutline', None, [1,0,0,1]),
+ ('skin', 'FILL', [1,1,0,1]),
+ ('infill', None, [1,1,0,1]),
+ ('support', 'SUPPORT', [0,1,1,1]),
+ ('outline', None, [0,0,0,1])
]
n = 0
gcodeLayers = self._result.getGCodeLayers()
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)
+ while len(self._layerVBOs) < n + 1:
+ self._layerVBOs.append({})
layerVBOs = self._layerVBOs[n]
if gcodeLayers is not None and layerNr - 10 < n < len(gcodeLayers):
for _, typeName, color in lineTypeList:
import urllib
import urllib2
import hashlib
+import socket
+import struct
import cStringIO as StringIO
from Cura.util import profile
pass
class Engine(object):
+ GUI_CMD_REQUEST_MESH = 0x01
+ GUI_CMD_SEND_POLYGONS = 0x02
+
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
+ self._serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ self._serverPortNr = 0xC20A
+ while True:
+ try:
+ self._serversocket.bind(('127.0.0.1', self._serverPortNr))
+ except:
+ print "Failed to listen on port: %d" % (self._serverPortNr)
+ self._serverPortNr += 1
+ if self._serverPortNr > 0xFFFF:
+ print "Failed to listen on any port..."
+ break
+ else:
+ break
+ print 'Listening for engine communications on %d' % (self._serverPortNr)
+ self._serversocket.listen(1)
+ thread = threading.Thread(target=self._socketListenThread)
+ thread.daemon = True
+ thread.start()
+
+ def _socketListenThread(self):
+ while True:
+ sock, _ = self._serversocket.accept()
+ thread = threading.Thread(target=self._socketConnectionThread, args=(sock,))
+ thread.daemon = True
+ thread.start()
+
+ def _socketConnectionThread(self, sock):
+ print "Connection", sock
+ while True:
+ try:
+ data = sock.recv(4)
+ except:
+ data = ''
+ if len(data) == 0:
+ print "Connection closed"
+ sock.close()
+ return
+ cmd = struct.unpack('@i', data)[0]
+ if cmd == self.GUI_CMD_REQUEST_MESH:
+ meshInfo = self._modelData[0]
+ self._modelData = self._modelData[1:]
+ sock.sendall(struct.pack('@i', meshInfo[0]))
+ sock.sendall(meshInfo[1].tostring())
+ elif cmd == self.GUI_CMD_SEND_POLYGONS:
+ cnt = struct.unpack('@i', sock.recv(4))[0]
+ layerNr = struct.unpack('@i', sock.recv(4))[0]
+ z = struct.unpack('@i', sock.recv(4))[0]
+ z = float(z) / 1000.0
+ typeNameLen = struct.unpack('@i', sock.recv(4))[0]
+ typeName = sock.recv(typeNameLen)
+ while len(self._result._polygons) < layerNr + 1:
+ self._result._polygons.append({})
+ polygons = self._result._polygons[layerNr]
+ if typeName not in polygons:
+ polygons[typeName] = []
+ for n in xrange(0, cnt):
+ length = struct.unpack('@i', sock.recv(4))[0]
+ data = ''
+ while len(data) < length * 8 * 2:
+ recvData = sock.recv(length * 8 * 2 - len(data))
+ if len(recvData) < 1:
+ return
+ data += recvData
+ polygon2d = numpy.array(numpy.fromstring(data, numpy.int64), numpy.float32) / 1000.0
+ polygon2d = polygon2d.reshape((len(polygon2d) / 2, 2))
+ polygon = numpy.empty((len(polygon2d), 3), numpy.float32)
+ polygon[:,:-1] = polygon2d
+ polygon[:,2] = z
+ polygons[typeName].append(polygon)
+ else:
+ print "Unknown command on socket: %x" % (cmd)
+
def cleanup(self):
self.abortEngine()
- try:
- os.remove(self._binaryStorageFilename)
- except:
- pass
+ self._serversocket.close()
def abortEngine(self):
if self._process is not None:
commandList = [getEngineFilename(), '-vvv']
for k, v in self._engineSettings(extruderCount).iteritems():
commandList += ['-s', '%s=%s' % (k, str(v))]
- commandList += ['-b', self._binaryStorageFilename]
+ commandList += ['-g', '%d' % self._serverPortNr]
self._objCount = 0
- with open(self._binaryStorageFilename, "wb") as f:
- hash = hashlib.sha512()
- order = scene.printOrder()
- if order is None:
- pos = numpy.array(profile.getMachineCenterCoords()) * 1000
- objMin = None
- objMax = None
+ engineModelData = []
+ hash = hashlib.sha512()
+ order = scene.printOrder()
+ if order is None:
+ pos = numpy.array(profile.getMachineCenterCoords()) * 1000
+ objMin = None
+ objMax = None
+ for obj in scene.objects():
+ if scene.checkPlatform(obj):
+ oMin = obj.getMinimum()[0:2] + obj.getPosition()
+ oMax = obj.getMaximum()[0:2] + obj.getPosition()
+ if objMin is None:
+ objMin = oMin
+ objMax = oMax
+ else:
+ objMin[0] = min(oMin[0], objMin[0])
+ 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])]
+
+ vertexTotal = [0] * 4
+ meshMax = 1
+ for obj in scene.objects():
+ if scene.checkPlatform(obj):
+ meshMax = max(meshMax, len(obj._meshList))
+ for n in xrange(0, len(obj._meshList)):
+ vertexTotal[n] += obj._meshList[n].vertexCount
+
+ for n in xrange(0, meshMax):
+ verts = numpy.zeros((0, 3), numpy.float32)
for obj in scene.objects():
if scene.checkPlatform(obj):
- oMin = obj.getMinimum()[0:2] + obj.getPosition()
- oMax = obj.getMaximum()[0:2] + obj.getPosition()
- if objMin is None:
- objMin = oMin
- objMax = oMax
- else:
- objMin[0] = min(oMin[0], objMin[0])
- 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
+ if n < len(obj._meshList):
+ vertexes = (numpy.matrix(obj._meshList[n].vertexes, copy = False) * numpy.matrix(obj._matrix, numpy.float32)).getA()
+ vertexes -= obj._drawOffset
+ vertexes += numpy.array([obj.getPosition()[0], obj.getPosition()[1], 0.0])
+ verts = numpy.concatenate((verts, vertexes))
+ hash.update(obj._meshList[n].vertexes.tostring())
+ engineModelData.append((vertexTotal[n], verts))
+
+ commandList += ['$' * meshMax]
+ self._objCount = 1
+ else:
+ for n in order:
+ obj = scene.objects()[n]
+ for mesh in obj._meshList:
+ engineModelData.append((mesh.vertexCount, mesh.vertexes))
+ hash.update(mesh.vertexes.tostring())
+ pos = obj.getPosition() * 1000
+ pos += numpy.array(profile.getMachineCenterCoords()) * 1000
+ commandList += ['-m', ','.join(map(str, obj._matrix.getA().flatten()))]
commandList += ['-s', 'posx=%d' % int(pos[0]), '-s', 'posy=%d' % int(pos[1])]
-
- vertexTotal = [0] * 4
- meshMax = 1
- for obj in scene.objects():
- if scene.checkPlatform(obj):
- meshMax = max(meshMax, len(obj._meshList))
- for n in xrange(0, len(obj._meshList)):
- vertexTotal[n] += obj._meshList[n].vertexCount
-
- for n in xrange(0, meshMax):
- f.write(numpy.array([vertexTotal[n]], numpy.int32).tostring())
- for obj in scene.objects():
- if scene.checkPlatform(obj):
- if n < len(obj._meshList):
- vertexes = (numpy.matrix(obj._meshList[n].vertexes, copy = False) * numpy.matrix(obj._matrix, numpy.float32)).getA()
- vertexes -= obj._drawOffset
- vertexes += numpy.array([obj.getPosition()[0], obj.getPosition()[1], 0.0])
- f.write(vertexes.tostring())
- hash.update(obj._meshList[n].vertexes.tostring())
-
- commandList += ['#' * meshMax]
- self._objCount = 1
- else:
- for n in order:
- obj = scene.objects()[n]
- for mesh in obj._meshList:
- f.write(numpy.array([mesh.vertexCount], numpy.int32).tostring())
- s = mesh.vertexes.tostring()
- f.write(s)
- hash.update(s)
- pos = obj.getPosition() * 1000
- pos += numpy.array(profile.getMachineCenterCoords()) * 1000
- commandList += ['-m', ','.join(map(str, obj._matrix.getA().flatten()))]
- commandList += ['-s', 'posx=%d' % int(pos[0]), '-s', 'posy=%d' % int(pos[1])]
- commandList += ['#' * len(obj._meshList)]
- self._objCount += 1
- modelHash = hash.hexdigest()
+ commandList += ['$' * len(obj._meshList)]
+ self._objCount += 1
+ modelHash = hash.hexdigest()
if self._objCount > 0:
+ self._modelData = engineModelData
self._thread = threading.Thread(target=self._watchProcess, args=(commandList, self._thread, modelHash))
self._thread.daemon = True
self._thread.start()
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._result._printTimeSeconds = int(line.split(':')[1].strip())
elif line.startswith('Filament:'):
settings['gcodeFlavor'] = 1
if profile.getProfileSetting('spiralize') == 'True':
settings['spiralizeMode'] = 1
- if profile.getProfileSetting('wipe_tower') == 'True':
+ if profile.getProfileSetting('wipe_tower') == 'True' and extruderCount > 1:
settings['wipeTowerSize'] = int(math.sqrt(profile.getProfileSettingFloat('wipe_tower_volume') * 1000 * 1000 * 1000 / settings['layerThickness']))
if profile.getProfileSetting('ooze_shield') == 'True':
settings['enableOozeShield'] = 1