from Cura.util import machineCom
from Cura.util import removableStorage
from Cura.util import gcodeInterpreter
+from Cura.util.printerConnection import printerConnectionManager
from Cura.gui.util import previewTools
from Cura.gui.util import opengl
from Cura.gui.util import openglGui
self._platformMesh = {}
self._isSimpleMode = True
self._usbPrintMonitor = printWindow.printProcessMonitor(lambda : self._queueRefresh())
+ self._printerConnectionManager = printerConnectionManager.PrinterConnectionManager()
self._viewport = None
self._modelMatrix = None
def sceneUpdated(self):
self._sceneUpdateTimer.Start(500, True)
self._slicer.abortSlicer()
- self._scene.setSizeOffsets(numpy.array(profile.calculateObjectSizeOffsets(), numpy.float32))
+ self._scene.updateSizeOffsets()
self.QueueRefresh()
def _onRunSlicer(self, e):
self._objColors[2] = profile.getPreferenceColour('model_colour3')
self._objColors[3] = profile.getPreferenceColour('model_colour4')
self._scene.setMachineSize(self._machineSize)
- self._scene.setSizeOffsets(numpy.array(profile.calculateObjectSizeOffsets(), numpy.float32))
self._scene.setHeadSize(profile.getMachineSettingFloat('extruder_head_size_min_x'), profile.getMachineSettingFloat('extruder_head_size_max_x'), profile.getMachineSettingFloat('extruder_head_size_min_y'), profile.getMachineSettingFloat('extruder_head_size_max_y'), profile.getMachineSettingFloat('extruder_head_size_height'))
- for n in xrange(1, 4):
- self._scene.setExtruderOffset(n, profile.getMachineSettingFloat('extruder_offset_x%d' % (n)), profile.getMachineSettingFloat('extruder_offset_y%d' % (n)))
if self._selectedObj is not None:
scale = self._selectedObj.getScale()
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)
def OnPaint(self,e):
+ connectionEntry = self._printerConnectionManager.getAvailableConnection()
if machineCom.machineIsConnected():
self.printButton._imageID = 6
self.printButton._tooltip = _("Print")
- elif len(removableStorage.getPossibleSDcardDrives()) > 0:
+ elif len(removableStorage.getPossibleSDcardDrives()) > 0 and (connectionEntry is None or connectionEntry.priority < 0):
self.printButton._imageID = 2
self.printButton._tooltip = _("Toolpath to SD")
+ elif connectionEntry is not None:
+ self.printButton._imageID = connectionEntry.icon
+ self.printButton._tooltip = _("Print with %s") % (connectionEntry.name)
else:
self.printButton._imageID = 3
self.printButton._tooltip = _("Save toolpath")
glPopMatrix()
else:
#Draw the object box-shadow, so you can see where it will collide with other objects.
- if self._selectedObj is not None and len(self._scene.objects()) > 1:
- size = self._selectedObj.getSize()[0:2] / 2 + self._scene.getObjectExtend()
- glPushMatrix()
- glTranslatef(self._selectedObj.getPosition()[0], self._selectedObj.getPosition()[1], 0)
+ if self._selectedObj is not None:
glEnable(GL_BLEND)
glEnable(GL_CULL_FACE)
- glColor4f(0,0,0,0.12)
- glBegin(GL_QUADS)
- glVertex3f(-size[0], size[1], 0.1)
- glVertex3f(-size[0], -size[1], 0.1)
- glVertex3f( size[0], -size[1], 0.1)
- glVertex3f( size[0], size[1], 0.1)
+ glColor4f(0,0,0,0.16)
+ glDepthMask(False)
+ for obj in self._scene.objects():
+ glPushMatrix()
+ glTranslatef(obj.getPosition()[0], obj.getPosition()[1], 0)
+ glBegin(GL_TRIANGLE_FAN)
+ for p in obj._boundaryHull[::-1]:
+ glVertex3f(p[0], p[1], 0)
+ glEnd()
+ glPopMatrix()
+ glPushMatrix()
+ glColor4f(0,0,0,0.06)
+ glTranslatef(self._selectedObj.getPosition()[0], self._selectedObj.getPosition()[1], 0)
+ glBegin(GL_TRIANGLE_FAN)
+ for p in self._selectedObj._printAreaHull[::-1]:
+ glVertex3f(p[0], p[1], 0)
+ glEnd()
+ glBegin(GL_TRIANGLE_FAN)
+ for p in self._selectedObj._headAreaHull[::-1]:
+ glVertex3f(p[0], p[1], 0)
glEnd()
+ glDepthMask(True)
glDisable(GL_CULL_FACE)
glPopMatrix()
glEnableClientState(GL_VERTEX_ARRAY)
glVertexPointer(3, GL_FLOAT, 3*4, vList)
+ glDepthMask(False)
glColor4ub(5, 171, 231, 64)
glDrawArrays(GL_QUADS, 0, 4)
glColor4ub(5, 171, 231, 96)
else:
glColor4ub(5 * 8 / 10, 171 * 8 / 10, 231 * 8 / 10, 128)
glBegin(GL_QUADS)
- glVertex3f(x1, y1, -0.02) #Draw bit below z0 to prevent zfighting.
- glVertex3f(x2, y1, -0.02)
- glVertex3f(x2, y2, -0.02)
- glVertex3f(x1, y2, -0.02)
+ glVertex3f(x1, y1, 0)
+ glVertex3f(x2, y1, 0)
+ glVertex3f(x2, y2, 0)
+ glVertex3f(x1, y2, 0)
glEnd()
if machine == 'ultimaker2':
posX = sx / 2 - clipWidth
posY = sy / 2 - clipHeight
glBegin(GL_QUADS)
- glVertex3f(posX, posY, 0.1)
- glVertex3f(posX+clipWidth, posY, 0.1)
- glVertex3f(posX+clipWidth, posY+clipHeight, 0.1)
- glVertex3f(posX, posY+clipHeight, 0.1)
+ glVertex3f(posX, posY, 0)
+ glVertex3f(posX+clipWidth, posY, 0)
+ glVertex3f(posX+clipWidth, posY+clipHeight, 0)
+ glVertex3f(posX, posY+clipHeight, 0)
glEnd()
#UpperLeft
clipWidth = 25
posX = -sx / 2
posY = sy / 2 - clipHeight
glBegin(GL_QUADS)
- glVertex3f(posX, posY, 0.1)
- glVertex3f(posX+clipWidth, posY, 0.1)
- glVertex3f(posX+clipWidth, posY+clipHeight, 0.1)
- glVertex3f(posX, posY+clipHeight, 0.1)
+ glVertex3f(posX, posY, 0)
+ glVertex3f(posX+clipWidth, posY, 0)
+ glVertex3f(posX+clipWidth, posY+clipHeight, 0)
+ glVertex3f(posX, posY+clipHeight, 0)
glEnd()
#LowerRight
clipWidth = 25
posX = sx / 2 - clipWidth
posY = -sy / 2
glBegin(GL_QUADS)
- glVertex3f(posX, posY, 0.1)
- glVertex3f(posX+clipWidth, posY, 0.1)
- glVertex3f(posX+clipWidth, posY+clipHeight, 0.1)
- glVertex3f(posX, posY+clipHeight, 0.1)
+ glVertex3f(posX, posY, 0)
+ glVertex3f(posX+clipWidth, posY, 0)
+ glVertex3f(posX+clipWidth, posY+clipHeight, 0)
+ glVertex3f(posX, posY+clipHeight, 0)
glEnd()
#LowerLeft
clipWidth = 25
posX = -sx / 2
posY = -sy / 2
glBegin(GL_QUADS)
- glVertex3f(posX, posY, 0.1)
- glVertex3f(posX+clipWidth, posY, 0.1)
- glVertex3f(posX+clipWidth, posY+clipHeight, 0.1)
- glVertex3f(posX, posY+clipHeight, 0.1)
+ glVertex3f(posX, posY, 0)
+ glVertex3f(posX+clipWidth, posY, 0)
+ glVertex3f(posX+clipWidth, posY+clipHeight, 0)
+ glVertex3f(posX, posY+clipHeight, 0)
glEnd()
+ glDepthMask(True)
glDisable(GL_BLEND)
glDisable(GL_CULL_FACE)
pass
elif M == 1: #Message with possible wait (ignored)
pass
+ elif M == 25: #Stop SD printing
+ pass
elif M == 80: #Enable power supply
pass
elif M == 81: #Suicide/disable power supply
import numpy
numpy.seterr(all='ignore')
-def convexHull(pointList):
- def _isRightTurn((p, q, r)):
- sum1 = q[0]*r[1] + p[0]*q[1] + r[0]*p[1]
- sum2 = q[0]*p[1] + r[0]*q[1] + p[0]*r[1]
-
- if sum1 - sum2 < 0:
- return 1
- else:
- return 0
-
- unique = {}
- for p in pointList:
- unique[(int(p[0]),int(p[1]))] = 1
-
- points = unique.keys()
- points.sort()
-
- # Build upper half of the hull.
- upper = [points[0], points[1]]
- for p in points[2:]:
- upper.append(p)
- while len(upper) > 2 and not _isRightTurn(upper[-3:]):
- del upper[-2]
-
- # Build lower half of the hull.
- points = points[::-1]
- lower = [points[0], points[1]]
- for p in points[2:]:
- lower.append(p)
- while len(lower) > 2 and not _isRightTurn(lower[-3:]):
- del lower[-2]
-
- # Remove duplicates.
- del lower[0]
- del lower[-1]
-
- return numpy.array(upper + lower, numpy.float32) - numpy.array([0.0,0.0], numpy.float32)
+from Cura.util import polygon
class printableObject(object):
def __init__(self, originFilename):
self._transformedSize = None
self._boundaryCircleSize = None
self._drawOffset = None
+ self._boundaryHull = None
+ self._printAreaExtend = numpy.array([[-1,-1],[ 1,-1],[ 1, 1],[-1, 1]], numpy.float32)
+ self._headAreaExtend = numpy.array([[-1,-1],[ 1,-1],[ 1, 1],[-1, 1]], numpy.float32)
+ self._printAreaHull = None
+ self._headAreaHull = None
+
self._loadAnim = None
def copy(self):
ret._transformedSize = self._transformedSize.copy()
ret._boundaryCircleSize = self._boundaryCircleSize
ret._boundaryHull = self._boundaryHull.copy()
+ ret._printAreaExtend = self._printAreaExtend.copy()
+ ret._printAreaHull = self._printAreaHull.copy()
ret._drawOffset = self._drawOffset.copy()
for m in self._meshList[:]:
m2 = ret._addMesh()
self._transformedMax = numpy.array([-999999999999,-999999999999,-999999999999], numpy.float64)
self._boundaryCircleSize = 0
- hull = numpy.zeros((0, 2), numpy.float32)
+ hull = numpy.zeros((0, 2), numpy.int)
for m in self._meshList:
transformedVertexes = m.getTransformedVertexes()
- hull = convexHull(numpy.concatenate((transformedVertexes[:,0:2], hull), 0))
+ hull = polygon.convexHull(numpy.concatenate((numpy.rint(transformedVertexes[:,0:2]).astype(int), hull), 0))
transformedMin = transformedVertexes.min(0)
transformedMax = transformedVertexes.max(0)
for n in xrange(0, 3):
self._transformedSize = self._transformedMax - self._transformedMin
self._drawOffset = (self._transformedMax + self._transformedMin) / 2
self._drawOffset[2] = self._transformedMin[2]
- self._boundaryHull = hull - self._drawOffset[0:2]
self._transformedMax -= self._drawOffset
self._transformedMin -= self._drawOffset
+ self._boundaryHull = polygon.minkowskiHull((hull.astype(numpy.float32) - self._drawOffset[0:2]), numpy.array([[-1,-1],[-1,1],[1,1],[1,-1]],numpy.float32))
+ self._printAreaHull = polygon.minkowskiHull(self._boundaryHull, self._printAreaExtend)
+ self._headAreaHull = polygon.minkowskiHull(self._printAreaHull, self._headAreaExtend)
+
def getName(self):
return self._name
def getOriginFilename(self):
def getBoundaryCircle(self):
return self._boundaryCircleSize
+ def setPrintAreaExtends(self, poly):
+ self._printAreaExtend = poly
+ self._printAreaHull = polygon.minkowskiHull(self._boundaryHull, self._printAreaExtend)
+ self._headAreaHull = polygon.minkowskiHull(self._printAreaHull, self._headAreaExtend)
+
+ def setHeadArea(self, poly):
+ self._headAreaExtend = poly
+ self._headAreaHull = polygon.minkowskiHull(self._printAreaHull, self._headAreaExtend)
+
def mirror(self, axis):
matrix = [[1,0,0], [0, 1, 0], [0, 0, 1]]
matrix[axis][axis] = -1
__copyright__ = "Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License"
import random
import numpy
+
from Cura.util import profile
+from Cura.util import polygon
class _objectOrder(object):
def __init__(self, order, todo):
#Check if printing one object will cause printhead colission with other object.
def _checkHit(self, addIdx, idx):
- addPos = self._scene._objectList[addIdx].getPosition()
- addSize = self._scene._objectList[addIdx].getSize()
- pos = self._scene._objectList[idx].getPosition()
- size = self._scene._objectList[idx].getSize()
-
- if self._leftToRight:
- if addPos[0] - addSize[0] / 2 - self._offset[0] >= pos[0] + size[0] / 2:
- return False
- else:
- if addPos[0] + addSize[0] / 2 + self._offset[0] <= pos[0] - size[0] / 2:
- return False
-
- if self._frontToBack:
- if addPos[1] - addSize[1] / 2 - self._offset[1] >= pos[1] + size[1] / 2:
- return False
- else:
- if addPos[1] + addSize[1] / 2 + self._offset[1] <= pos[1] - size[1] / 2:
- return False
-
- return True
+ obj = self._scene._objectList[idx]
+ addObj = self._scene._objectList[addIdx]
+ return polygon.polygonCollision(obj._headAreaHull + obj.getPosition(), addObj._boundaryHull + addObj.getPosition())
class Scene(object):
def __init__(self):
self._leftToRight = False
self._frontToBack = True
self._gantryHeight = 60
+ self._oneAtATime = True
+
# Physical (square) machine size.
def setMachineSize(self, machineSize):
self._machineSize = machineSize
# Size offsets are offsets caused by brim, skirt, etc.
- def setSizeOffsets(self, sizeOffsets):
- self._sizeOffsets = sizeOffsets
+ def updateSizeOffsets(self, force=False):
+ newOffsets = numpy.array(profile.calculateObjectSizeOffsets(), numpy.float32)
+ if not force and numpy.array_equal(self._sizeOffsets, newOffsets):
+ return
+ self._sizeOffsets = newOffsets
+
+ extends = numpy.array([[-newOffsets[0],-newOffsets[1]],[ newOffsets[0],-newOffsets[1]],[ newOffsets[0], newOffsets[1]],[-newOffsets[0], newOffsets[1]]], numpy.float32)
+ for obj in self._objectList:
+ obj.setPrintAreaExtends(extends)
#size of the printing head.
def setHeadSize(self, xMin, xMax, yMin, yMax, gantryHeight):
self._headSizeOffsets[0] = min(xMin, xMax)
self._headSizeOffsets[1] = min(yMin, yMax)
self._gantryHeight = gantryHeight
+ self._oneAtATime = self._gantryHeight > 0
+
+ headArea = numpy.array([[-xMin,-yMin],[ xMax,-yMin],[ xMax, yMax],[-xMin, yMax]], numpy.float32)
+ for obj in self._objectList:
+ obj.setHeadArea(headArea)
def setExtruderOffset(self, extruderNr, offsetX, offsetY):
self._extruderOffset[extruderNr] = numpy.array([offsetX, offsetY], numpy.float32)
scale = numpy.max(self._machineSize[0:2]) * 2.5 / numpy.max(obj.getSize()[0:2])
matrix = [[scale,0,0], [0, scale, 0], [0, 0, scale]]
obj.applyMatrix(numpy.matrix(matrix, numpy.float64))
+ self.updateSizeOffsets(True)
def remove(self, obj):
self._objectList.remove(obj)
self.pushFree()
def pushFree(self):
+ return
n = 1000
while self._pushFree():
n -= 1
obj.setPosition(obj.getPosition() + offset)
def printOrder(self):
- order = _objectOrderFinder(self, self._headSizeOffsets + self._sizeOffsets, self._leftToRight, self._frontToBack, self._gantryHeight).order
+ if self._oneAtATime:
+ order = _objectOrderFinder(self, self._headSizeOffsets + self._sizeOffsets, self._leftToRight, self._frontToBack, self._gantryHeight).order
+ else:
+ order = None
return order
def _pushFree(self):
def _checkHit(self, a, b):
if a == b:
return False
- posDiff = a.getPosition() - b.getPosition()
- if abs(posDiff[0]) < (a.getSize()[0] + b.getSize()[0]) / 2 + self._sizeOffsets[0] + self._headSizeOffsets[0]:
- if abs(posDiff[1]) < (a.getSize()[1] + b.getSize()[1]) / 2 + self._sizeOffsets[1] + self._headSizeOffsets[1]:
- return True
- return False
+ if self._oneAtATime:
+ return polygon.polygonCollision(a._headAreaHull + a.getPosition(), b._boundaryHull + b.getPosition())
+ else:
+ return polygon.polygonCollision(a._boundaryHull + a.getPosition(), b._boundaryHull + b.getPosition())
def checkPlatform(self, obj):
p = obj.getPosition()