Fix resources, imports and indentations.
parent
132e6381ea
commit
377ea03c15
30
Cura/cura.py
30
Cura/cura.py
|
@ -9,10 +9,7 @@ The slicing code is the same as Skeinforge. But the UI has been revamped to be..
|
|||
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
import __init__
|
||||
|
||||
import sys
|
||||
import platform
|
||||
from optparse import OptionParser
|
||||
|
||||
from util import profile
|
||||
|
@ -36,6 +33,7 @@ Reece.Arnott <http://forums.reprap.org/profile.php?12,152>
|
|||
Wade <http://forums.reprap.org/profile.php?12,489>
|
||||
Xsainnz <http://forums.reprap.org/profile.php?12,563>
|
||||
Zach Hoeken <http://blog.zachhoeken.com/>
|
||||
Ilya Kulakov (kulakov.ilya@gmail.com)
|
||||
|
||||
Organizations:
|
||||
Ultimaker <http://www.ultimaker.com>
|
||||
|
@ -45,12 +43,18 @@ __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agp
|
|||
|
||||
def main():
|
||||
parser = OptionParser(usage="usage: %prog [options] <filename>.stl")
|
||||
parser.add_option("-i", "--ini", action="store", type="string", dest="profileini", help="Load settings from a profile ini file")
|
||||
parser.add_option("-P", "--project", action="store_true", dest="openprojectplanner", help="Open the project planner")
|
||||
parser.add_option("-F", "--flat", action="store_true", dest="openflatslicer", help="Open the 2D SVG slicer (unfinished)")
|
||||
parser.add_option("-r", "--print", action="store", type="string", dest="printfile", help="Open the printing interface, instead of the normal cura interface.")
|
||||
parser.add_option("-p", "--profile", action="store", type="string", dest="profile", help="Internal option, do not use!")
|
||||
parser.add_option("-s", "--slice", action="store_true", dest="slice", help="Slice the given files instead of opening them in Cura")
|
||||
parser.add_option("-i", "--ini", action="store", type="string", dest="profileini",
|
||||
help="Load settings from a profile ini file")
|
||||
parser.add_option("-P", "--project", action="store_true", dest="openprojectplanner",
|
||||
help="Open the project planner")
|
||||
parser.add_option("-F", "--flat", action="store_true", dest="openflatslicer",
|
||||
help="Open the 2D SVG slicer (unfinished)")
|
||||
parser.add_option("-r", "--print", action="store", type="string", dest="printfile",
|
||||
help="Open the printing interface, instead of the normal cura interface.")
|
||||
parser.add_option("-p", "--profile", action="store", type="string", dest="profile",
|
||||
help="Internal option, do not use!")
|
||||
parser.add_option("-s", "--slice", action="store_true", dest="slice",
|
||||
help="Slice the given files instead of opening them in Cura")
|
||||
(options, args) = parser.parse_args()
|
||||
if options.profile != None:
|
||||
profile.loadGlobalProfileFromString(options.profile)
|
||||
|
@ -58,30 +62,36 @@ def main():
|
|||
profile.loadGlobalProfile(options.profileini)
|
||||
if options.openprojectplanner != None:
|
||||
from gui import projectPlanner
|
||||
|
||||
projectPlanner.main()
|
||||
return
|
||||
if options.openflatslicer != None:
|
||||
from gui import flatSlicerWindow
|
||||
|
||||
flatSlicerWindow.main()
|
||||
return
|
||||
if options.printfile != None:
|
||||
from gui import printWindow
|
||||
|
||||
printWindow.startPrintInterface(options.printfile)
|
||||
return
|
||||
|
||||
if options.slice != None:
|
||||
from util import sliceRun
|
||||
|
||||
sliceRun.runSlice(args)
|
||||
else:
|
||||
if len(args) > 0:
|
||||
profile.putPreference('lastFile', ';'.join(args))
|
||||
from gui import splashScreen
|
||||
|
||||
splashScreen.showSplash(mainWindowRunCallback)
|
||||
|
||||
|
||||
def mainWindowRunCallback(splash):
|
||||
from gui import mainWindow
|
||||
|
||||
mainWindow.main(splash)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,447 +1,458 @@
|
|||
import math, time, os
|
||||
|
||||
from util import meshLoader
|
||||
from util import util3d
|
||||
from util import profile
|
||||
|
||||
try:
|
||||
import OpenGL
|
||||
OpenGL.ERROR_CHECKING = False
|
||||
from OpenGL.GLU import *
|
||||
from OpenGL.GL import *
|
||||
hasOpenGLlibs = True
|
||||
except:
|
||||
print "Failed to find PyOpenGL: http://pyopengl.sourceforge.net/"
|
||||
hasOpenGLlibs = False
|
||||
|
||||
def InitGL(window, view3D, zoom):
|
||||
# set viewing projection
|
||||
glMatrixMode(GL_MODELVIEW)
|
||||
glLoadIdentity()
|
||||
size = window.GetSize()
|
||||
glViewport(0,0, size.GetWidth(), size.GetHeight())
|
||||
|
||||
glLightfv(GL_LIGHT0, GL_POSITION, [0.2, 0.2, 1.0, 0.0])
|
||||
glLightfv(GL_LIGHT1, GL_POSITION, [1.0, 1.0, 1.0, 0.0])
|
||||
|
||||
glEnable(GL_RESCALE_NORMAL)
|
||||
glEnable(GL_LIGHTING)
|
||||
glEnable(GL_LIGHT0)
|
||||
glEnable(GL_DEPTH_TEST)
|
||||
glEnable(GL_CULL_FACE)
|
||||
glDisable(GL_BLEND)
|
||||
|
||||
glClearColor(1.0, 1.0, 1.0, 1.0)
|
||||
glClearStencil(0)
|
||||
glClearDepth(1.0)
|
||||
|
||||
glMatrixMode(GL_PROJECTION)
|
||||
glLoadIdentity()
|
||||
aspect = float(size.GetWidth()) / float(size.GetHeight())
|
||||
if view3D:
|
||||
gluPerspective(45.0, aspect, 1.0, 1000.0)
|
||||
else:
|
||||
glOrtho(-aspect * (zoom), aspect * (zoom), -1.0 * (zoom), 1.0 * (zoom), -1000.0, 1000.0)
|
||||
|
||||
glMatrixMode(GL_MODELVIEW)
|
||||
glLoadIdentity()
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)
|
||||
|
||||
platformMesh = None
|
||||
|
||||
def DrawMachine(machineSize):
|
||||
if profile.getPreference('machine_type') == 'ultimaker':
|
||||
glPushMatrix()
|
||||
glEnable(GL_LIGHTING)
|
||||
glTranslate(100,200,-5)
|
||||
glLightfv(GL_LIGHT0, GL_DIFFUSE, [0.8,0.8,0.8])
|
||||
glLightfv(GL_LIGHT0, GL_AMBIENT, [0.5,0.5,0.5])
|
||||
glEnable(GL_BLEND)
|
||||
glBlendFunc(GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR)
|
||||
|
||||
global platformMesh
|
||||
if platformMesh == None:
|
||||
platformMesh = meshLoader.loadMesh(os.path.normpath(os.path.join(os.path.split(__file__)[0], "../images", 'ultimaker_platform.stl')))
|
||||
platformMesh.setRotateMirror(0, False, False, False, False, False)
|
||||
|
||||
DrawMesh(platformMesh)
|
||||
glPopMatrix()
|
||||
|
||||
glDisable(GL_LIGHTING)
|
||||
if False:
|
||||
glColor3f(0.7,0.7,0.7)
|
||||
glLineWidth(2)
|
||||
glBegin(GL_LINES)
|
||||
for i in xrange(0, int(machineSize.x), 10):
|
||||
glVertex3f(i, 0, 0)
|
||||
glVertex3f(i, machineSize.y, 0)
|
||||
for i in xrange(0, int(machineSize.y), 10):
|
||||
glVertex3f(0, i, 0)
|
||||
glVertex3f(machineSize.x, i, 0)
|
||||
glEnd()
|
||||
|
||||
glEnable(GL_LINE_SMOOTH)
|
||||
glEnable(GL_BLEND)
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
|
||||
glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
|
||||
|
||||
glColor3f(0.0,0.0,0.0)
|
||||
glLineWidth(4)
|
||||
glBegin(GL_LINE_LOOP)
|
||||
glVertex3f(0, 0, 0)
|
||||
glVertex3f(machineSize.x, 0, 0)
|
||||
glVertex3f(machineSize.x, machineSize.y, 0)
|
||||
glVertex3f(0, machineSize.y, 0)
|
||||
glEnd()
|
||||
|
||||
glLineWidth(2)
|
||||
glBegin(GL_LINE_LOOP)
|
||||
glVertex3f(0, 0, machineSize.z)
|
||||
glVertex3f(machineSize.x, 0, machineSize.z)
|
||||
glVertex3f(machineSize.x, machineSize.y, machineSize.z)
|
||||
glVertex3f(0, machineSize.y, machineSize.z)
|
||||
glEnd()
|
||||
glBegin(GL_LINES)
|
||||
glVertex3f(0, 0, 0)
|
||||
glVertex3f(0, 0, machineSize.z)
|
||||
glVertex3f(machineSize.x, 0, 0)
|
||||
glVertex3f(machineSize.x, 0, machineSize.z)
|
||||
glVertex3f(machineSize.x, machineSize.y, 0)
|
||||
glVertex3f(machineSize.x, machineSize.y, machineSize.z)
|
||||
glVertex3f(0, machineSize.y, 0)
|
||||
glVertex3f(0, machineSize.y, machineSize.z)
|
||||
glEnd()
|
||||
else:
|
||||
glDisable(GL_CULL_FACE)
|
||||
glEnable(GL_BLEND)
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
|
||||
glColor4ub(5,171,231,127)
|
||||
glBegin(GL_QUADS)
|
||||
for x in xrange(0, int(machineSize.x), 20):
|
||||
for y in xrange(0, int(machineSize.y), 20):
|
||||
glVertex3f(x, y, -0.01)
|
||||
glVertex3f(min(x+10, machineSize.x), y, -0.01)
|
||||
glVertex3f(min(x+10, machineSize.x), min(y+10, machineSize.y), -0.01)
|
||||
glVertex3f(x, min(y+10, machineSize.y), -0.01)
|
||||
for x in xrange(10, int(machineSize.x), 20):
|
||||
for y in xrange(10, int(machineSize.y), 20):
|
||||
glVertex3f(x, y, -0.01)
|
||||
glVertex3f(min(x+10, machineSize.x), y, -0.01)
|
||||
glVertex3f(min(x+10, machineSize.x), min(y+10, machineSize.y), -0.01)
|
||||
glVertex3f(x, min(y+10, machineSize.y), -0.01)
|
||||
glEnd()
|
||||
glColor4ub(5*8/10,171*8/10,231*8/10,128)
|
||||
glBegin(GL_QUADS)
|
||||
for x in xrange(10, int(machineSize.x), 20):
|
||||
for y in xrange(0, int(machineSize.y), 20):
|
||||
glVertex3f(x, y, -0.01)
|
||||
glVertex3f(min(x+10, machineSize.x), y, -0.01)
|
||||
glVertex3f(min(x+10, machineSize.x), min(y+10, machineSize.y), -0.01)
|
||||
glVertex3f(x, min(y+10, machineSize.y), -0.01)
|
||||
for x in xrange(0, int(machineSize.x), 20):
|
||||
for y in xrange(10, int(machineSize.y), 20):
|
||||
glVertex3f(x, y, -0.01)
|
||||
glVertex3f(min(x+10, machineSize.x), y, -0.01)
|
||||
glVertex3f(min(x+10, machineSize.x), min(y+10, machineSize.y), -0.01)
|
||||
glVertex3f(x, min(y+10, machineSize.y), -0.01)
|
||||
glEnd()
|
||||
glEnable(GL_CULL_FACE)
|
||||
|
||||
glColor4ub(5,171,231,64)
|
||||
glBegin(GL_QUADS)
|
||||
glVertex3f(0, 0, machineSize.z)
|
||||
glVertex3f(0, machineSize.y, machineSize.z)
|
||||
glVertex3f(machineSize.x, machineSize.y, machineSize.z)
|
||||
glVertex3f(machineSize.x, 0, machineSize.z)
|
||||
glEnd()
|
||||
|
||||
glColor4ub(5,171,231,96)
|
||||
glBegin(GL_QUADS)
|
||||
glVertex3f(0, 0, 0)
|
||||
glVertex3f(0, 0, machineSize.z)
|
||||
glVertex3f(machineSize.x, 0, machineSize.z)
|
||||
glVertex3f(machineSize.x, 0, 0)
|
||||
|
||||
glVertex3f(0, machineSize.y, machineSize.z)
|
||||
glVertex3f(0, machineSize.y, 0)
|
||||
glVertex3f(machineSize.x, machineSize.y, 0)
|
||||
glVertex3f(machineSize.x, machineSize.y, machineSize.z)
|
||||
glEnd()
|
||||
|
||||
glColor4ub(5,171,231,128)
|
||||
glBegin(GL_QUADS)
|
||||
glVertex3f(0, 0, machineSize.z)
|
||||
glVertex3f(0, 0, 0)
|
||||
glVertex3f(0, machineSize.y, 0)
|
||||
glVertex3f(0, machineSize.y, machineSize.z)
|
||||
|
||||
glVertex3f(machineSize.x, 0, 0)
|
||||
glVertex3f(machineSize.x, 0, machineSize.z)
|
||||
glVertex3f(machineSize.x, machineSize.y, machineSize.z)
|
||||
glVertex3f(machineSize.x, machineSize.y, 0)
|
||||
glEnd()
|
||||
|
||||
glDisable(GL_BLEND)
|
||||
|
||||
glPushMatrix()
|
||||
glTranslate(5,5,2)
|
||||
glLineWidth(2)
|
||||
glColor3f(0.5,0,0)
|
||||
glBegin(GL_LINES)
|
||||
glVertex3f(0,0,0)
|
||||
glVertex3f(20,0,0)
|
||||
glEnd()
|
||||
glColor3f(0,0.5,0)
|
||||
glBegin(GL_LINES)
|
||||
glVertex3f(0,0,0)
|
||||
glVertex3f(0,20,0)
|
||||
glEnd()
|
||||
glColor3f(0,0,0.5)
|
||||
glBegin(GL_LINES)
|
||||
glVertex3f(0,0,0)
|
||||
glVertex3f(0,0,20)
|
||||
glEnd()
|
||||
|
||||
glDisable(GL_DEPTH_TEST)
|
||||
#X
|
||||
glColor3f(1,0,0)
|
||||
glPushMatrix()
|
||||
glTranslate(23,0,0)
|
||||
noZ = ResetMatrixRotationAndScale()
|
||||
glBegin(GL_LINES)
|
||||
glVertex3f(-0.8,1,0)
|
||||
glVertex3f(0.8,-1,0)
|
||||
glVertex3f(0.8,1,0)
|
||||
glVertex3f(-0.8,-1,0)
|
||||
glEnd()
|
||||
glPopMatrix()
|
||||
|
||||
#Y
|
||||
glColor3f(0,1,0)
|
||||
glPushMatrix()
|
||||
glTranslate(0,23,0)
|
||||
ResetMatrixRotationAndScale()
|
||||
glBegin(GL_LINES)
|
||||
glVertex3f(-0.8, 1,0)
|
||||
glVertex3f( 0.0, 0,0)
|
||||
glVertex3f( 0.8, 1,0)
|
||||
glVertex3f(-0.8,-1,0)
|
||||
glEnd()
|
||||
glPopMatrix()
|
||||
|
||||
#Z
|
||||
if not noZ:
|
||||
glColor3f(0,0,1)
|
||||
glPushMatrix()
|
||||
glTranslate(0,0,23)
|
||||
ResetMatrixRotationAndScale()
|
||||
glBegin(GL_LINES)
|
||||
glVertex3f(-0.8, 1,0)
|
||||
glVertex3f( 0.8, 1,0)
|
||||
glVertex3f( 0.8, 1,0)
|
||||
glVertex3f(-0.8,-1,0)
|
||||
glVertex3f(-0.8,-1,0)
|
||||
glVertex3f( 0.8,-1,0)
|
||||
glEnd()
|
||||
glPopMatrix()
|
||||
|
||||
glPopMatrix()
|
||||
glEnable(GL_DEPTH_TEST)
|
||||
|
||||
def ResetMatrixRotationAndScale():
|
||||
matrix = glGetFloatv(GL_MODELVIEW_MATRIX)
|
||||
noZ = False
|
||||
if matrix[3][2] > 0:
|
||||
return False
|
||||
scale2D = matrix[0][0]
|
||||
matrix[0][0] = 1.0
|
||||
matrix[1][0] = 0.0
|
||||
matrix[2][0] = 0.0
|
||||
matrix[0][1] = 0.0
|
||||
matrix[1][1] = 1.0
|
||||
matrix[2][1] = 0.0
|
||||
matrix[0][2] = 0.0
|
||||
matrix[1][2] = 0.0
|
||||
matrix[2][2] = 1.0
|
||||
|
||||
if matrix[3][2] != 0.0:
|
||||
matrix[3][0] = matrix[3][0] / (-matrix[3][2] / 100)
|
||||
matrix[3][1] = matrix[3][1] / (-matrix[3][2] / 100)
|
||||
matrix[3][2] = -100
|
||||
else:
|
||||
matrix[0][0] = scale2D
|
||||
matrix[1][1] = scale2D
|
||||
matrix[2][2] = scale2D
|
||||
matrix[3][2] = -100
|
||||
noZ = True
|
||||
|
||||
glLoadMatrixf(matrix)
|
||||
return noZ
|
||||
|
||||
def DrawBox(vMin, vMax):
|
||||
glBegin(GL_LINE_LOOP)
|
||||
glVertex3f(vMin[0], vMin[1], vMin[2])
|
||||
glVertex3f(vMax[0], vMin[1], vMin[2])
|
||||
glVertex3f(vMax[0], vMax[1], vMin[2])
|
||||
glVertex3f(vMin[0], vMax[1], vMin[2])
|
||||
glEnd()
|
||||
|
||||
glBegin(GL_LINE_LOOP)
|
||||
glVertex3f(vMin[0], vMin[1], vMax[2])
|
||||
glVertex3f(vMax[0], vMin[1], vMax[2])
|
||||
glVertex3f(vMax[0], vMax[1], vMax[2])
|
||||
glVertex3f(vMin[0], vMax[1], vMax[2])
|
||||
glEnd()
|
||||
glBegin(GL_LINES)
|
||||
glVertex3f(vMin[0], vMin[1], vMin[2])
|
||||
glVertex3f(vMin[0], vMin[1], vMax[2])
|
||||
glVertex3f(vMax[0], vMin[1], vMin[2])
|
||||
glVertex3f(vMax[0], vMin[1], vMax[2])
|
||||
glVertex3f(vMax[0], vMax[1], vMin[2])
|
||||
glVertex3f(vMax[0], vMax[1], vMax[2])
|
||||
glVertex3f(vMin[0], vMax[1], vMin[2])
|
||||
glVertex3f(vMin[0], vMax[1], vMax[2])
|
||||
glEnd()
|
||||
|
||||
def DrawMeshOutline(mesh):
|
||||
glEnable(GL_CULL_FACE)
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glVertexPointer(3, GL_FLOAT, 0, mesh.vertexes)
|
||||
|
||||
glCullFace(GL_FRONT)
|
||||
glLineWidth(3)
|
||||
glPolygonMode(GL_BACK, GL_LINE)
|
||||
glDrawArrays(GL_TRIANGLES, 0, mesh.vertexCount)
|
||||
glPolygonMode(GL_BACK, GL_FILL)
|
||||
glCullFace(GL_BACK)
|
||||
|
||||
glDisableClientState(GL_VERTEX_ARRAY)
|
||||
|
||||
def DrawMesh(mesh):
|
||||
glEnable(GL_CULL_FACE)
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_NORMAL_ARRAY);
|
||||
glVertexPointer(3, GL_FLOAT, 0, mesh.vertexes)
|
||||
glNormalPointer(GL_FLOAT, 0, mesh.normal)
|
||||
|
||||
#Odd, drawing in batchs is a LOT faster then drawing it all at once.
|
||||
batchSize = 999 #Warning, batchSize needs to be dividable by 3
|
||||
extraStartPos = int(mesh.vertexCount / batchSize) * batchSize
|
||||
extraCount = mesh.vertexCount - extraStartPos
|
||||
|
||||
glCullFace(GL_BACK)
|
||||
for i in xrange(0, int(mesh.vertexCount / batchSize)):
|
||||
glDrawArrays(GL_TRIANGLES, i*batchSize, batchSize)
|
||||
glDrawArrays(GL_TRIANGLES, extraStartPos, extraCount)
|
||||
|
||||
glCullFace(GL_FRONT)
|
||||
glNormalPointer(GL_FLOAT, 0, mesh.invNormal)
|
||||
for i in xrange(0, int(mesh.vertexCount / batchSize)):
|
||||
glDrawArrays(GL_TRIANGLES, i*batchSize, batchSize)
|
||||
extraStartPos = int(mesh.vertexCount / batchSize) * batchSize
|
||||
extraCount = mesh.vertexCount - extraStartPos
|
||||
glDrawArrays(GL_TRIANGLES, extraStartPos, extraCount)
|
||||
glCullFace(GL_BACK)
|
||||
|
||||
glDisableClientState(GL_VERTEX_ARRAY)
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
|
||||
def DrawGCodeLayer(layer):
|
||||
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],[0.0,0.5,0.5],[0.5,0.0,0.5]]
|
||||
moveColor = [0,0,1]
|
||||
retractColor = [1,0,0.5]
|
||||
supportColor = [0,1,1]
|
||||
extrudeColor = [1,0,0]
|
||||
innerWallColor = [0,1,0]
|
||||
skirtColor = [0,0.5,0.5]
|
||||
prevPathWasRetract = False
|
||||
|
||||
glDisable(GL_CULL_FACE)
|
||||
for path in layer:
|
||||
if path.type == 'move':
|
||||
if prevPathWasRetract:
|
||||
c = retractColor
|
||||
else:
|
||||
c = moveColor
|
||||
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
|
||||
if path.type == 'retract':
|
||||
c = [0,1,1]
|
||||
if path.type == 'extrude':
|
||||
drawLength = 0.0
|
||||
prevNormal = None
|
||||
for i in xrange(0, len(path.list)-1):
|
||||
v0 = path.list[i]
|
||||
v1 = path.list[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)
|
||||
glColor3fv(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 != None:
|
||||
n = (normal + prevNormal)
|
||||
n.normalize()
|
||||
vv4 = v0 + n * lineWidth
|
||||
vv5 = v0 - n * lineWidth
|
||||
glBegin(GL_QUADS)
|
||||
glColor3fv(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:
|
||||
glBegin(GL_LINE_STRIP)
|
||||
glColor3fv(c)
|
||||
for v in path.list:
|
||||
glVertex3f(v.x, v.y, v.z)
|
||||
glEnd()
|
||||
if not path.type == 'move':
|
||||
prevPathWasRetract = False
|
||||
if path.type == 'retract' and path.list[0].almostEqual(path.list[-1]):
|
||||
prevPathWasRetract = True
|
||||
glEnable(GL_CULL_FACE)
|
||||
# coding=utf-8
|
||||
from __future__ import absolute_import
|
||||
|
||||
import math
|
||||
|
||||
from util import meshLoader
|
||||
from util import util3d
|
||||
from util import profile
|
||||
from util.resources import getPathForMesh
|
||||
|
||||
try:
|
||||
import OpenGL
|
||||
|
||||
OpenGL.ERROR_CHECKING = False
|
||||
from OpenGL.GLU import *
|
||||
from OpenGL.GL import *
|
||||
|
||||
hasOpenGLlibs = True
|
||||
except:
|
||||
print "Failed to find PyOpenGL: http://pyopengl.sourceforge.net/"
|
||||
hasOpenGLlibs = False
|
||||
|
||||
def InitGL(window, view3D, zoom):
|
||||
# set viewing projection
|
||||
glMatrixMode(GL_MODELVIEW)
|
||||
glLoadIdentity()
|
||||
size = window.GetSize()
|
||||
glViewport(0, 0, size.GetWidth(), size.GetHeight())
|
||||
|
||||
glLightfv(GL_LIGHT0, GL_POSITION, [0.2, 0.2, 1.0, 0.0])
|
||||
glLightfv(GL_LIGHT1, GL_POSITION, [1.0, 1.0, 1.0, 0.0])
|
||||
|
||||
glEnable(GL_RESCALE_NORMAL)
|
||||
glEnable(GL_LIGHTING)
|
||||
glEnable(GL_LIGHT0)
|
||||
glEnable(GL_DEPTH_TEST)
|
||||
glEnable(GL_CULL_FACE)
|
||||
glDisable(GL_BLEND)
|
||||
|
||||
glClearColor(1.0, 1.0, 1.0, 1.0)
|
||||
glClearStencil(0)
|
||||
glClearDepth(1.0)
|
||||
|
||||
glMatrixMode(GL_PROJECTION)
|
||||
glLoadIdentity()
|
||||
aspect = float(size.GetWidth()) / float(size.GetHeight())
|
||||
if view3D:
|
||||
gluPerspective(45.0, aspect, 1.0, 1000.0)
|
||||
else:
|
||||
glOrtho(-aspect * (zoom), aspect * (zoom), -1.0 * (zoom), 1.0 * (zoom), -1000.0, 1000.0)
|
||||
|
||||
glMatrixMode(GL_MODELVIEW)
|
||||
glLoadIdentity()
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)
|
||||
|
||||
platformMesh = None
|
||||
|
||||
def DrawMachine(machineSize):
|
||||
if profile.getPreference('machine_type') == 'ultimaker':
|
||||
glPushMatrix()
|
||||
glEnable(GL_LIGHTING)
|
||||
glTranslate(100, 200, -5)
|
||||
glLightfv(GL_LIGHT0, GL_DIFFUSE, [0.8, 0.8, 0.8])
|
||||
glLightfv(GL_LIGHT0, GL_AMBIENT, [0.5, 0.5, 0.5])
|
||||
glEnable(GL_BLEND)
|
||||
glBlendFunc(GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR)
|
||||
|
||||
global platformMesh
|
||||
if platformMesh == None:
|
||||
platformMesh = meshLoader.loadMesh(getPathForMesh('ultimaker_platform.stl'))
|
||||
platformMesh.setRotateMirror(0, False, False, False, False, False)
|
||||
|
||||
DrawMesh(platformMesh)
|
||||
glPopMatrix()
|
||||
|
||||
glDisable(GL_LIGHTING)
|
||||
if False:
|
||||
glColor3f(0.7, 0.7, 0.7)
|
||||
glLineWidth(2)
|
||||
glBegin(GL_LINES)
|
||||
for i in xrange(0, int(machineSize.x), 10):
|
||||
glVertex3f(i, 0, 0)
|
||||
glVertex3f(i, machineSize.y, 0)
|
||||
for i in xrange(0, int(machineSize.y), 10):
|
||||
glVertex3f(0, i, 0)
|
||||
glVertex3f(machineSize.x, i, 0)
|
||||
glEnd()
|
||||
|
||||
glEnable(GL_LINE_SMOOTH)
|
||||
glEnable(GL_BLEND)
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
|
||||
glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
|
||||
|
||||
glColor3f(0.0, 0.0, 0.0)
|
||||
glLineWidth(4)
|
||||
glBegin(GL_LINE_LOOP)
|
||||
glVertex3f(0, 0, 0)
|
||||
glVertex3f(machineSize.x, 0, 0)
|
||||
glVertex3f(machineSize.x, machineSize.y, 0)
|
||||
glVertex3f(0, machineSize.y, 0)
|
||||
glEnd()
|
||||
|
||||
glLineWidth(2)
|
||||
glBegin(GL_LINE_LOOP)
|
||||
glVertex3f(0, 0, machineSize.z)
|
||||
glVertex3f(machineSize.x, 0, machineSize.z)
|
||||
glVertex3f(machineSize.x, machineSize.y, machineSize.z)
|
||||
glVertex3f(0, machineSize.y, machineSize.z)
|
||||
glEnd()
|
||||
glBegin(GL_LINES)
|
||||
glVertex3f(0, 0, 0)
|
||||
glVertex3f(0, 0, machineSize.z)
|
||||
glVertex3f(machineSize.x, 0, 0)
|
||||
glVertex3f(machineSize.x, 0, machineSize.z)
|
||||
glVertex3f(machineSize.x, machineSize.y, 0)
|
||||
glVertex3f(machineSize.x, machineSize.y, machineSize.z)
|
||||
glVertex3f(0, machineSize.y, 0)
|
||||
glVertex3f(0, machineSize.y, machineSize.z)
|
||||
glEnd()
|
||||
else:
|
||||
glDisable(GL_CULL_FACE)
|
||||
glEnable(GL_BLEND)
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
|
||||
glColor4ub(5, 171, 231, 127)
|
||||
glBegin(GL_QUADS)
|
||||
for x in xrange(0, int(machineSize.x), 20):
|
||||
for y in xrange(0, int(machineSize.y), 20):
|
||||
glVertex3f(x, y, -0.01)
|
||||
glVertex3f(min(x + 10, machineSize.x), y, -0.01)
|
||||
glVertex3f(min(x + 10, machineSize.x), min(y + 10, machineSize.y), -0.01)
|
||||
glVertex3f(x, min(y + 10, machineSize.y), -0.01)
|
||||
for x in xrange(10, int(machineSize.x), 20):
|
||||
for y in xrange(10, int(machineSize.y), 20):
|
||||
glVertex3f(x, y, -0.01)
|
||||
glVertex3f(min(x + 10, machineSize.x), y, -0.01)
|
||||
glVertex3f(min(x + 10, machineSize.x), min(y + 10, machineSize.y), -0.01)
|
||||
glVertex3f(x, min(y + 10, machineSize.y), -0.01)
|
||||
glEnd()
|
||||
glColor4ub(5 * 8 / 10, 171 * 8 / 10, 231 * 8 / 10, 128)
|
||||
glBegin(GL_QUADS)
|
||||
for x in xrange(10, int(machineSize.x), 20):
|
||||
for y in xrange(0, int(machineSize.y), 20):
|
||||
glVertex3f(x, y, -0.01)
|
||||
glVertex3f(min(x + 10, machineSize.x), y, -0.01)
|
||||
glVertex3f(min(x + 10, machineSize.x), min(y + 10, machineSize.y), -0.01)
|
||||
glVertex3f(x, min(y + 10, machineSize.y), -0.01)
|
||||
for x in xrange(0, int(machineSize.x), 20):
|
||||
for y in xrange(10, int(machineSize.y), 20):
|
||||
glVertex3f(x, y, -0.01)
|
||||
glVertex3f(min(x + 10, machineSize.x), y, -0.01)
|
||||
glVertex3f(min(x + 10, machineSize.x), min(y + 10, machineSize.y), -0.01)
|
||||
glVertex3f(x, min(y + 10, machineSize.y), -0.01)
|
||||
glEnd()
|
||||
glEnable(GL_CULL_FACE)
|
||||
|
||||
glColor4ub(5, 171, 231, 64)
|
||||
glBegin(GL_QUADS)
|
||||
glVertex3f(0, 0, machineSize.z)
|
||||
glVertex3f(0, machineSize.y, machineSize.z)
|
||||
glVertex3f(machineSize.x, machineSize.y, machineSize.z)
|
||||
glVertex3f(machineSize.x, 0, machineSize.z)
|
||||
glEnd()
|
||||
|
||||
glColor4ub(5, 171, 231, 96)
|
||||
glBegin(GL_QUADS)
|
||||
glVertex3f(0, 0, 0)
|
||||
glVertex3f(0, 0, machineSize.z)
|
||||
glVertex3f(machineSize.x, 0, machineSize.z)
|
||||
glVertex3f(machineSize.x, 0, 0)
|
||||
|
||||
glVertex3f(0, machineSize.y, machineSize.z)
|
||||
glVertex3f(0, machineSize.y, 0)
|
||||
glVertex3f(machineSize.x, machineSize.y, 0)
|
||||
glVertex3f(machineSize.x, machineSize.y, machineSize.z)
|
||||
glEnd()
|
||||
|
||||
glColor4ub(5, 171, 231, 128)
|
||||
glBegin(GL_QUADS)
|
||||
glVertex3f(0, 0, machineSize.z)
|
||||
glVertex3f(0, 0, 0)
|
||||
glVertex3f(0, machineSize.y, 0)
|
||||
glVertex3f(0, machineSize.y, machineSize.z)
|
||||
|
||||
glVertex3f(machineSize.x, 0, 0)
|
||||
glVertex3f(machineSize.x, 0, machineSize.z)
|
||||
glVertex3f(machineSize.x, machineSize.y, machineSize.z)
|
||||
glVertex3f(machineSize.x, machineSize.y, 0)
|
||||
glEnd()
|
||||
|
||||
glDisable(GL_BLEND)
|
||||
|
||||
glPushMatrix()
|
||||
glTranslate(5, 5, 2)
|
||||
glLineWidth(2)
|
||||
glColor3f(0.5, 0, 0)
|
||||
glBegin(GL_LINES)
|
||||
glVertex3f(0, 0, 0)
|
||||
glVertex3f(20, 0, 0)
|
||||
glEnd()
|
||||
glColor3f(0, 0.5, 0)
|
||||
glBegin(GL_LINES)
|
||||
glVertex3f(0, 0, 0)
|
||||
glVertex3f(0, 20, 0)
|
||||
glEnd()
|
||||
glColor3f(0, 0, 0.5)
|
||||
glBegin(GL_LINES)
|
||||
glVertex3f(0, 0, 0)
|
||||
glVertex3f(0, 0, 20)
|
||||
glEnd()
|
||||
|
||||
glDisable(GL_DEPTH_TEST)
|
||||
#X
|
||||
glColor3f(1, 0, 0)
|
||||
glPushMatrix()
|
||||
glTranslate(23, 0, 0)
|
||||
noZ = ResetMatrixRotationAndScale()
|
||||
glBegin(GL_LINES)
|
||||
glVertex3f(-0.8, 1, 0)
|
||||
glVertex3f(0.8, -1, 0)
|
||||
glVertex3f(0.8, 1, 0)
|
||||
glVertex3f(-0.8, -1, 0)
|
||||
glEnd()
|
||||
glPopMatrix()
|
||||
|
||||
#Y
|
||||
glColor3f(0, 1, 0)
|
||||
glPushMatrix()
|
||||
glTranslate(0, 23, 0)
|
||||
ResetMatrixRotationAndScale()
|
||||
glBegin(GL_LINES)
|
||||
glVertex3f(-0.8, 1, 0)
|
||||
glVertex3f(0.0, 0, 0)
|
||||
glVertex3f(0.8, 1, 0)
|
||||
glVertex3f(-0.8, -1, 0)
|
||||
glEnd()
|
||||
glPopMatrix()
|
||||
|
||||
#Z
|
||||
if not noZ:
|
||||
glColor3f(0, 0, 1)
|
||||
glPushMatrix()
|
||||
glTranslate(0, 0, 23)
|
||||
ResetMatrixRotationAndScale()
|
||||
glBegin(GL_LINES)
|
||||
glVertex3f(-0.8, 1, 0)
|
||||
glVertex3f(0.8, 1, 0)
|
||||
glVertex3f(0.8, 1, 0)
|
||||
glVertex3f(-0.8, -1, 0)
|
||||
glVertex3f(-0.8, -1, 0)
|
||||
glVertex3f(0.8, -1, 0)
|
||||
glEnd()
|
||||
glPopMatrix()
|
||||
|
||||
glPopMatrix()
|
||||
glEnable(GL_DEPTH_TEST)
|
||||
|
||||
|
||||
def ResetMatrixRotationAndScale():
|
||||
matrix = glGetFloatv(GL_MODELVIEW_MATRIX)
|
||||
noZ = False
|
||||
if matrix[3][2] > 0:
|
||||
return False
|
||||
scale2D = matrix[0][0]
|
||||
matrix[0][0] = 1.0
|
||||
matrix[1][0] = 0.0
|
||||
matrix[2][0] = 0.0
|
||||
matrix[0][1] = 0.0
|
||||
matrix[1][1] = 1.0
|
||||
matrix[2][1] = 0.0
|
||||
matrix[0][2] = 0.0
|
||||
matrix[1][2] = 0.0
|
||||
matrix[2][2] = 1.0
|
||||
|
||||
if matrix[3][2] != 0.0:
|
||||
matrix[3][0] = matrix[3][0] / (-matrix[3][2] / 100)
|
||||
matrix[3][1] = matrix[3][1] / (-matrix[3][2] / 100)
|
||||
matrix[3][2] = -100
|
||||
else:
|
||||
matrix[0][0] = scale2D
|
||||
matrix[1][1] = scale2D
|
||||
matrix[2][2] = scale2D
|
||||
matrix[3][2] = -100
|
||||
noZ = True
|
||||
|
||||
glLoadMatrixf(matrix)
|
||||
return noZ
|
||||
|
||||
|
||||
def DrawBox(vMin, vMax):
|
||||
glBegin(GL_LINE_LOOP)
|
||||
glVertex3f(vMin[0], vMin[1], vMin[2])
|
||||
glVertex3f(vMax[0], vMin[1], vMin[2])
|
||||
glVertex3f(vMax[0], vMax[1], vMin[2])
|
||||
glVertex3f(vMin[0], vMax[1], vMin[2])
|
||||
glEnd()
|
||||
|
||||
glBegin(GL_LINE_LOOP)
|
||||
glVertex3f(vMin[0], vMin[1], vMax[2])
|
||||
glVertex3f(vMax[0], vMin[1], vMax[2])
|
||||
glVertex3f(vMax[0], vMax[1], vMax[2])
|
||||
glVertex3f(vMin[0], vMax[1], vMax[2])
|
||||
glEnd()
|
||||
glBegin(GL_LINES)
|
||||
glVertex3f(vMin[0], vMin[1], vMin[2])
|
||||
glVertex3f(vMin[0], vMin[1], vMax[2])
|
||||
glVertex3f(vMax[0], vMin[1], vMin[2])
|
||||
glVertex3f(vMax[0], vMin[1], vMax[2])
|
||||
glVertex3f(vMax[0], vMax[1], vMin[2])
|
||||
glVertex3f(vMax[0], vMax[1], vMax[2])
|
||||
glVertex3f(vMin[0], vMax[1], vMin[2])
|
||||
glVertex3f(vMin[0], vMax[1], vMax[2])
|
||||
glEnd()
|
||||
|
||||
|
||||
def DrawMeshOutline(mesh):
|
||||
glEnable(GL_CULL_FACE)
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glVertexPointer(3, GL_FLOAT, 0, mesh.vertexes)
|
||||
|
||||
glCullFace(GL_FRONT)
|
||||
glLineWidth(3)
|
||||
glPolygonMode(GL_BACK, GL_LINE)
|
||||
glDrawArrays(GL_TRIANGLES, 0, mesh.vertexCount)
|
||||
glPolygonMode(GL_BACK, GL_FILL)
|
||||
glCullFace(GL_BACK)
|
||||
|
||||
glDisableClientState(GL_VERTEX_ARRAY)
|
||||
|
||||
|
||||
def DrawMesh(mesh):
|
||||
glEnable(GL_CULL_FACE)
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_NORMAL_ARRAY);
|
||||
glVertexPointer(3, GL_FLOAT, 0, mesh.vertexes)
|
||||
glNormalPointer(GL_FLOAT, 0, mesh.normal)
|
||||
|
||||
#Odd, drawing in batchs is a LOT faster then drawing it all at once.
|
||||
batchSize = 999 #Warning, batchSize needs to be dividable by 3
|
||||
extraStartPos = int(mesh.vertexCount / batchSize) * batchSize
|
||||
extraCount = mesh.vertexCount - extraStartPos
|
||||
|
||||
glCullFace(GL_BACK)
|
||||
for i in xrange(0, int(mesh.vertexCount / batchSize)):
|
||||
glDrawArrays(GL_TRIANGLES, i * batchSize, batchSize)
|
||||
glDrawArrays(GL_TRIANGLES, extraStartPos, extraCount)
|
||||
|
||||
glCullFace(GL_FRONT)
|
||||
glNormalPointer(GL_FLOAT, 0, mesh.invNormal)
|
||||
for i in xrange(0, int(mesh.vertexCount / batchSize)):
|
||||
glDrawArrays(GL_TRIANGLES, i * batchSize, batchSize)
|
||||
extraStartPos = int(mesh.vertexCount / batchSize) * batchSize
|
||||
extraCount = mesh.vertexCount - extraStartPos
|
||||
glDrawArrays(GL_TRIANGLES, extraStartPos, extraCount)
|
||||
glCullFace(GL_BACK)
|
||||
|
||||
glDisableClientState(GL_VERTEX_ARRAY)
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
|
||||
|
||||
def DrawGCodeLayer(layer):
|
||||
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], [0.0, 0.5, 0.5], [0.5, 0.0, 0.5]]
|
||||
moveColor = [0, 0, 1]
|
||||
retractColor = [1, 0, 0.5]
|
||||
supportColor = [0, 1, 1]
|
||||
extrudeColor = [1, 0, 0]
|
||||
innerWallColor = [0, 1, 0]
|
||||
skirtColor = [0, 0.5, 0.5]
|
||||
prevPathWasRetract = False
|
||||
|
||||
glDisable(GL_CULL_FACE)
|
||||
for path in layer:
|
||||
if path.type == 'move':
|
||||
if prevPathWasRetract:
|
||||
c = retractColor
|
||||
else:
|
||||
c = moveColor
|
||||
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
|
||||
if path.type == 'retract':
|
||||
c = [0, 1, 1]
|
||||
if path.type == 'extrude':
|
||||
drawLength = 0.0
|
||||
prevNormal = None
|
||||
for i in xrange(0, len(path.list) - 1):
|
||||
v0 = path.list[i]
|
||||
v1 = path.list[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)
|
||||
glColor3fv(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 != None:
|
||||
n = (normal + prevNormal)
|
||||
n.normalize()
|
||||
vv4 = v0 + n * lineWidth
|
||||
vv5 = v0 - n * lineWidth
|
||||
glBegin(GL_QUADS)
|
||||
glColor3fv(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:
|
||||
glBegin(GL_LINE_STRIP)
|
||||
glColor3fv(c)
|
||||
for v in path.list:
|
||||
glVertex3f(v.x, v.y, v.z)
|
||||
glEnd()
|
||||
if not path.type == 'move':
|
||||
prevPathWasRetract = False
|
||||
if path.type == 'retract' and path.list[0].almostEqual(path.list[-1]):
|
||||
prevPathWasRetract = True
|
||||
glEnable(GL_CULL_FACE)
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,39 +1,39 @@
|
|||
import sys, os
|
||||
#We only need the core here, which speeds up the import. As we want to show the splashscreen ASAP.
|
||||
import wx._core
|
||||
# coding=utf-8
|
||||
from __future__ import absolute_import
|
||||
|
||||
import wx._core #We only need the core here, which speeds up the import. As we want to show the splashscreen ASAP.
|
||||
|
||||
from util.resources import getPathForImage
|
||||
|
||||
def getBitmapImage(filename):
|
||||
#The frozen executable has the script files in a zip, so we need to exit another level to get to our images.
|
||||
if hasattr(sys, 'frozen'):
|
||||
return wx.Bitmap(os.path.normpath(os.path.join(os.path.split(__file__)[0], "../../images", filename)))
|
||||
else:
|
||||
return wx.Bitmap(os.path.normpath(os.path.join(os.path.split(__file__)[0], "../images", filename)))
|
||||
|
||||
class splashScreen(wx.SplashScreen):
|
||||
def __init__(self, callback):
|
||||
self.callback = callback
|
||||
bitmap = getBitmapImage("splash.png")
|
||||
bitmap = wx.Bitmap(getPathForImage('splash.png'))
|
||||
super(splashScreen, self).__init__(bitmap, wx.SPLASH_CENTRE_ON_SCREEN, 0, None)
|
||||
wx.CallAfter(self.DoCallback)
|
||||
|
||||
|
||||
def DoCallback(self):
|
||||
self.callback(self)
|
||||
self.Destroy()
|
||||
|
||||
|
||||
def showSplash(callback):
|
||||
app = wx.App(False)
|
||||
splashScreen(callback)
|
||||
app.MainLoop()
|
||||
|
||||
|
||||
def testCallback(splashscreen):
|
||||
print "Callback!"
|
||||
import time
|
||||
|
||||
time.sleep(2)
|
||||
print "!Callback"
|
||||
|
||||
|
||||
def main():
|
||||
showSplash(testCallback)
|
||||
|
||||
if __name__ == u'__main__':
|
||||
main()
|
||||
|
||||
|
|
|
@ -1,28 +1,23 @@
|
|||
# coding=utf-8
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
|
||||
import os, sys
|
||||
|
||||
import wx
|
||||
from wx.lib import buttons
|
||||
|
||||
from util import profile
|
||||
from util.resources import getPathForImage
|
||||
|
||||
|
||||
#######################################################
|
||||
# toolbarUtil contains help classes and functions for
|
||||
# toolbar buttons.
|
||||
#######################################################
|
||||
|
||||
def getBitmapImage(filename):
|
||||
#The frozen executable has the script files in a zip, so we need to exit another level to get to our images.
|
||||
if hasattr(sys, 'frozen'):
|
||||
return wx.Bitmap(os.path.normpath(os.path.join(os.path.split(__file__)[0], "../../images", filename)))
|
||||
else:
|
||||
return wx.Bitmap(os.path.normpath(os.path.join(os.path.split(__file__)[0], "../images", filename)))
|
||||
|
||||
class Toolbar(wx.ToolBar):
|
||||
def __init__(self, parent):
|
||||
super(Toolbar, self).__init__(parent, -1, style=wx.TB_HORIZONTAL | wx.NO_BORDER)
|
||||
self.SetToolBitmapSize( ( 21, 21 ) )
|
||||
self.SetToolBitmapSize(( 21, 21 ))
|
||||
|
||||
if not hasattr(parent, 'popup'):
|
||||
# Create popup window
|
||||
|
@ -30,14 +25,14 @@ class Toolbar(wx.ToolBar):
|
|||
parent.popup.SetBackgroundColour(wx.SystemSettings.GetColour(wx.SYS_COLOUR_INFOBK))
|
||||
parent.popup.text = wx.StaticText(parent.popup, -1, '')
|
||||
parent.popup.sizer = wx.BoxSizer()
|
||||
parent.popup.sizer.Add(parent.popup.text, flag=wx.EXPAND|wx.ALL, border=1)
|
||||
parent.popup.sizer.Add(parent.popup.text, flag=wx.EXPAND | wx.ALL, border=1)
|
||||
parent.popup.SetSizer(parent.popup.sizer)
|
||||
parent.popup.owner = None
|
||||
|
||||
def OnPopupDisplay(self, e):
|
||||
self.UpdatePopup(e.GetEventObject())
|
||||
self.GetParent().popup.Show(True)
|
||||
|
||||
|
||||
def OnPopupHide(self, e):
|
||||
if self.GetParent().popup.owner == e.GetEventObject():
|
||||
self.GetParent().popup.Show(False)
|
||||
|
@ -50,13 +45,14 @@ class Toolbar(wx.ToolBar):
|
|||
popup.Fit();
|
||||
x, y = control.ClientToScreenXY(0, 0)
|
||||
sx, sy = control.GetSizeTuple()
|
||||
popup.SetPosition((x, y+sy))
|
||||
popup.SetPosition((x, y + sy))
|
||||
|
||||
|
||||
class ToggleButton(buttons.GenBitmapToggleButton):
|
||||
def __init__(self, parent, profileSetting, bitmapFilenameOn, bitmapFilenameOff,
|
||||
helpText='', id=-1, callback=None, size=(20,20)):
|
||||
self.bitmapOn = getBitmapImage(bitmapFilenameOn)
|
||||
self.bitmapOff = getBitmapImage(bitmapFilenameOff)
|
||||
helpText='', id=-1, callback=None, size=(20, 20)):
|
||||
self.bitmapOn = wx.Bitmap(getPathForImage(bitmapFilenameOn))
|
||||
self.bitmapOff = wx.Bitmap(getPathForImage(bitmapFilenameOff))
|
||||
|
||||
super(ToggleButton, self).__init__(parent, id, self.bitmapOff, size=size)
|
||||
|
||||
|
@ -75,7 +71,7 @@ class ToggleButton(buttons.GenBitmapToggleButton):
|
|||
|
||||
self.Bind(wx.EVT_ENTER_WINDOW, self.OnMouseEnter)
|
||||
self.Bind(wx.EVT_LEAVE_WINDOW, self.OnMouseLeave)
|
||||
|
||||
|
||||
parent.AddControl(self)
|
||||
|
||||
def SetBitmap(self, boolValue):
|
||||
|
@ -117,11 +113,12 @@ class ToggleButton(buttons.GenBitmapToggleButton):
|
|||
self.Refresh()
|
||||
event.Skip()
|
||||
|
||||
|
||||
class RadioButton(buttons.GenBitmapButton):
|
||||
def __init__(self, parent, group, bitmapFilenameOn, bitmapFilenameOff,
|
||||
helpText='', id=-1, callback=None, size=(20,20)):
|
||||
self.bitmapOn = getBitmapImage(bitmapFilenameOn)
|
||||
self.bitmapOff = getBitmapImage(bitmapFilenameOff)
|
||||
helpText='', id=-1, callback=None, size=(20, 20)):
|
||||
self.bitmapOn = wx.Bitmap(getPathForImage(bitmapFilenameOn))
|
||||
self.bitmapOff = wx.Bitmap(getPathForImage(bitmapFilenameOff))
|
||||
|
||||
super(RadioButton, self).__init__(parent, id, self.bitmapOff, size=size)
|
||||
|
||||
|
@ -138,10 +135,10 @@ class RadioButton(buttons.GenBitmapButton):
|
|||
|
||||
self.Bind(wx.EVT_ENTER_WINDOW, self.OnMouseEnter)
|
||||
self.Bind(wx.EVT_LEAVE_WINDOW, self.OnMouseLeave)
|
||||
|
||||
|
||||
if len(group) == 1:
|
||||
self.SetValue(True)
|
||||
|
||||
|
||||
parent.AddControl(self)
|
||||
|
||||
def SetBitmap(self, boolValue):
|
||||
|
@ -158,7 +155,7 @@ class RadioButton(buttons.GenBitmapButton):
|
|||
for other in self.group:
|
||||
if other != self:
|
||||
other.SetValue(False)
|
||||
|
||||
|
||||
def GetValue(self):
|
||||
return self._value
|
||||
|
||||
|
@ -179,10 +176,11 @@ class RadioButton(buttons.GenBitmapButton):
|
|||
self.Refresh()
|
||||
event.Skip()
|
||||
|
||||
|
||||
class NormalButton(buttons.GenBitmapButton):
|
||||
def __init__(self, parent, callback, bitmapFilename,
|
||||
helpText='', id=-1, size=(20,20)):
|
||||
self.bitmap = getBitmapImage(bitmapFilename)
|
||||
helpText='', id=-1, size=(20, 20)):
|
||||
self.bitmap = wx.Bitmap(getPathForImage(bitmapFilename))
|
||||
super(NormalButton, self).__init__(parent, id, self.bitmap, size=size)
|
||||
|
||||
self.helpText = helpText
|
||||
|
@ -193,9 +191,9 @@ class NormalButton(buttons.GenBitmapButton):
|
|||
|
||||
self.Bind(wx.EVT_ENTER_WINDOW, self.OnMouseEnter)
|
||||
self.Bind(wx.EVT_LEAVE_WINDOW, self.OnMouseLeave)
|
||||
|
||||
|
||||
self.Bind(wx.EVT_BUTTON, self.OnButton)
|
||||
|
||||
|
||||
parent.AddControl(self)
|
||||
|
||||
def OnButton(self, event):
|
||||
|
|
|
@ -1,141 +1,156 @@
|
|||
import os, glob, subprocess, platform
|
||||
import wx
|
||||
|
||||
from util import profile
|
||||
from gui import toolbarUtil
|
||||
|
||||
try:
|
||||
#Try to find the OpenCV library for video capture.
|
||||
from opencv import cv
|
||||
from opencv import highgui
|
||||
except:
|
||||
cv = None
|
||||
|
||||
try:
|
||||
#Use the vidcap library directly from the VideoCapture package. (Windows only)
|
||||
# http://videocapture.sourceforge.net/
|
||||
# We're using the binary interface, not the python interface, so we don't depend on PIL
|
||||
import vidcap as win32vidcap
|
||||
except:
|
||||
win32vidcap = None
|
||||
|
||||
def hasWebcamSupport():
|
||||
if cv == None and win32vidcap == None:
|
||||
return False
|
||||
if not os.path.exists(getFFMPEGpath()):
|
||||
return False
|
||||
return True
|
||||
|
||||
def getFFMPEGpath():
|
||||
if platform.system() == "Windows":
|
||||
return os.path.normpath(os.path.join(os.path.split(__file__)[0], "../ffmpeg.exe"))
|
||||
elif os.path.exists('/usr/bin/ffmpeg'):
|
||||
return '/usr/bin/ffmpeg'
|
||||
return os.path.normpath(os.path.join(os.path.split(__file__)[0], "../ffmpeg"))
|
||||
|
||||
class webcam(object):
|
||||
def __init__(self):
|
||||
self._cam = None
|
||||
self._overlayImage = toolbarUtil.getBitmapImage("cura-overlay.png")
|
||||
self._overlayUltimaker = toolbarUtil.getBitmapImage("ultimaker-overlay.png")
|
||||
if cv != None:
|
||||
self._cam = highgui.cvCreateCameraCapture(-1)
|
||||
elif win32vidcap != None:
|
||||
try:
|
||||
self._cam = win32vidcap.new_Dev(0, False)
|
||||
except:
|
||||
pass
|
||||
|
||||
self._doTimelaps = False
|
||||
self._bitmap = None
|
||||
|
||||
def hasCamera(self):
|
||||
return self._cam != None
|
||||
|
||||
def propertyPages(self):
|
||||
if self._cam == None:
|
||||
return []
|
||||
if cv != None:
|
||||
#TODO Make an OpenCV property page
|
||||
return []
|
||||
elif win32vidcap != None:
|
||||
return ['Image properties', 'Format properties']
|
||||
|
||||
def openPropertyPage(self, pageType = 0):
|
||||
if self._cam == None:
|
||||
return
|
||||
if cv != None:
|
||||
pass
|
||||
elif win32vidcap != None:
|
||||
if pageType == 0:
|
||||
self._cam.displaycapturefilterproperties()
|
||||
else:
|
||||
del self._cam
|
||||
self._cam = None
|
||||
tmp = win32vidcap.new_Dev(0, False)
|
||||
tmp.displaycapturepinproperties()
|
||||
self._cam = tmp
|
||||
|
||||
def takeNewImage(self):
|
||||
if self._cam == None:
|
||||
return
|
||||
if cv != None:
|
||||
frame = cv.QueryFrame(self._cam)
|
||||
cv.CvtColor(frame, frame, cv.CV_BGR2RGB)
|
||||
bitmap = wx.BitmapFromBuffer(frame.width, frame.height, frame.imageData)
|
||||
elif win32vidcap != None:
|
||||
buffer, width, height = self._cam.getbuffer()
|
||||
try:
|
||||
wxImage = wx.EmptyImage(width, height)
|
||||
wxImage.SetData(buffer[::-1])
|
||||
if self._bitmap != None:
|
||||
del self._bitmap
|
||||
bitmap = wxImage.ConvertToBitmap()
|
||||
del wxImage
|
||||
del buffer
|
||||
except:
|
||||
pass
|
||||
|
||||
dc = wx.MemoryDC()
|
||||
dc.SelectObject(bitmap)
|
||||
dc.DrawBitmap(self._overlayImage, bitmap.GetWidth() - self._overlayImage.GetWidth() - 5, 5, True)
|
||||
if profile.getPreference('machine_type') == 'ultimaker':
|
||||
dc.DrawBitmap(self._overlayUltimaker, (bitmap.GetWidth() - self._overlayUltimaker.GetWidth()) / 2, bitmap.GetHeight() - self._overlayUltimaker.GetHeight() - 5, True)
|
||||
dc.SelectObject(wx.NullBitmap)
|
||||
|
||||
self._bitmap = bitmap
|
||||
|
||||
if self._doTimelaps:
|
||||
filename = os.path.normpath(os.path.join(os.path.split(__file__)[0], "../__tmp_snap", "__tmp_snap_%04d.jpg" % (self._snapshotCount)))
|
||||
self._snapshotCount += 1
|
||||
bitmap.SaveFile(filename, wx.BITMAP_TYPE_JPEG)
|
||||
|
||||
return self._bitmap
|
||||
|
||||
def getLastImage(self):
|
||||
return self._bitmap
|
||||
|
||||
def startTimelaps(self, filename):
|
||||
if self._cam == None:
|
||||
return
|
||||
self._cleanTempDir()
|
||||
self._timelapsFilename = filename
|
||||
self._snapshotCount = 0
|
||||
self._doTimelaps = True
|
||||
print "startTimelaps"
|
||||
|
||||
def endTimelaps(self):
|
||||
if self._doTimelaps:
|
||||
ffmpeg = getFFMPEGpath()
|
||||
basePath = os.path.normpath(os.path.join(os.path.split(__file__)[0], "../__tmp_snap", "__tmp_snap_%04d.jpg"))
|
||||
subprocess.call([ffmpeg, '-r', '12.5', '-i', basePath, '-vcodec', 'mpeg2video', '-pix_fmt', 'yuv420p', '-r', '25', '-y', '-b:v', '1500k', '-f', 'vob', self._timelapsFilename])
|
||||
self._doTimelaps = False
|
||||
|
||||
def _cleanTempDir(self):
|
||||
basePath = os.path.normpath(os.path.join(os.path.split(__file__)[0], "../__tmp_snap"))
|
||||
try:
|
||||
os.makedirs(basePath)
|
||||
except:
|
||||
pass
|
||||
for filename in glob.iglob(basePath + "/*.jpg"):
|
||||
os.remove(filename)
|
||||
# coding=utf-8
|
||||
from __future__ import absolute_import
|
||||
|
||||
import os
|
||||
import glob
|
||||
import subprocess
|
||||
import platform
|
||||
|
||||
import wx
|
||||
|
||||
from util import profile
|
||||
from util.resources import getPathForImage
|
||||
from gui import toolbarUtil
|
||||
|
||||
try:
|
||||
#Try to find the OpenCV library for video capture.
|
||||
from opencv import cv
|
||||
from opencv import highgui
|
||||
except:
|
||||
cv = None
|
||||
|
||||
try:
|
||||
#Use the vidcap library directly from the VideoCapture package. (Windows only)
|
||||
# http://videocapture.sourceforge.net/
|
||||
# We're using the binary interface, not the python interface, so we don't depend on PIL
|
||||
import vidcap as win32vidcap
|
||||
except:
|
||||
win32vidcap = None
|
||||
|
||||
def hasWebcamSupport():
|
||||
if cv == None and win32vidcap == None:
|
||||
return False
|
||||
if not os.path.exists(getFFMPEGpath()):
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def getFFMPEGpath():
|
||||
if platform.system() == "Windows":
|
||||
return os.path.normpath(os.path.join(os.path.split(__file__)[0], "../ffmpeg.exe"))
|
||||
elif os.path.exists('/usr/bin/ffmpeg'):
|
||||
return '/usr/bin/ffmpeg'
|
||||
return os.path.normpath(os.path.join(os.path.split(__file__)[0], "../ffmpeg"))
|
||||
|
||||
|
||||
class webcam(object):
|
||||
def __init__(self):
|
||||
self._cam = None
|
||||
self._overlayImage = wx.Bitmap(getPathForImage('cura-overlay.png'))
|
||||
self._overlayUltimaker = wx.Bitmap(getPathForImage('ultimaker-overlay.png'))
|
||||
if cv != None:
|
||||
self._cam = highgui.cvCreateCameraCapture(-1)
|
||||
elif win32vidcap != None:
|
||||
try:
|
||||
self._cam = win32vidcap.new_Dev(0, False)
|
||||
except:
|
||||
pass
|
||||
|
||||
self._doTimelaps = False
|
||||
self._bitmap = None
|
||||
|
||||
def hasCamera(self):
|
||||
return self._cam != None
|
||||
|
||||
def propertyPages(self):
|
||||
if self._cam == None:
|
||||
return []
|
||||
if cv != None:
|
||||
#TODO Make an OpenCV property page
|
||||
return []
|
||||
elif win32vidcap != None:
|
||||
return ['Image properties', 'Format properties']
|
||||
|
||||
def openPropertyPage(self, pageType=0):
|
||||
if self._cam == None:
|
||||
return
|
||||
if cv != None:
|
||||
pass
|
||||
elif win32vidcap != None:
|
||||
if pageType == 0:
|
||||
self._cam.displaycapturefilterproperties()
|
||||
else:
|
||||
del self._cam
|
||||
self._cam = None
|
||||
tmp = win32vidcap.new_Dev(0, False)
|
||||
tmp.displaycapturepinproperties()
|
||||
self._cam = tmp
|
||||
|
||||
def takeNewImage(self):
|
||||
if self._cam == None:
|
||||
return
|
||||
if cv != None:
|
||||
frame = cv.QueryFrame(self._cam)
|
||||
cv.CvtColor(frame, frame, cv.CV_BGR2RGB)
|
||||
bitmap = wx.BitmapFromBuffer(frame.width, frame.height, frame.imageData)
|
||||
elif win32vidcap != None:
|
||||
buffer, width, height = self._cam.getbuffer()
|
||||
try:
|
||||
wxImage = wx.EmptyImage(width, height)
|
||||
wxImage.SetData(buffer[::-1])
|
||||
if self._bitmap != None:
|
||||
del self._bitmap
|
||||
bitmap = wxImage.ConvertToBitmap()
|
||||
del wxImage
|
||||
del buffer
|
||||
except:
|
||||
pass
|
||||
|
||||
dc = wx.MemoryDC()
|
||||
dc.SelectObject(bitmap)
|
||||
dc.DrawBitmap(self._overlayImage, bitmap.GetWidth() - self._overlayImage.GetWidth() - 5, 5, True)
|
||||
if profile.getPreference('machine_type') == 'ultimaker':
|
||||
dc.DrawBitmap(self._overlayUltimaker, (bitmap.GetWidth() - self._overlayUltimaker.GetWidth()) / 2,
|
||||
bitmap.GetHeight() - self._overlayUltimaker.GetHeight() - 5, True)
|
||||
dc.SelectObject(wx.NullBitmap)
|
||||
|
||||
self._bitmap = bitmap
|
||||
|
||||
if self._doTimelaps:
|
||||
filename = os.path.normpath(os.path.join(os.path.split(__file__)[0], "../__tmp_snap",
|
||||
"__tmp_snap_%04d.jpg" % (self._snapshotCount)))
|
||||
self._snapshotCount += 1
|
||||
bitmap.SaveFile(filename, wx.BITMAP_TYPE_JPEG)
|
||||
|
||||
return self._bitmap
|
||||
|
||||
def getLastImage(self):
|
||||
return self._bitmap
|
||||
|
||||
def startTimelaps(self, filename):
|
||||
if self._cam == None:
|
||||
return
|
||||
self._cleanTempDir()
|
||||
self._timelapsFilename = filename
|
||||
self._snapshotCount = 0
|
||||
self._doTimelaps = True
|
||||
print "startTimelaps"
|
||||
|
||||
def endTimelaps(self):
|
||||
if self._doTimelaps:
|
||||
ffmpeg = getFFMPEGpath()
|
||||
basePath = os.path.normpath(
|
||||
os.path.join(os.path.split(__file__)[0], "../__tmp_snap", "__tmp_snap_%04d.jpg"))
|
||||
subprocess.call(
|
||||
[ffmpeg, '-r', '12.5', '-i', basePath, '-vcodec', 'mpeg2video', '-pix_fmt', 'yuv420p', '-r', '25', '-y',
|
||||
'-b:v', '1500k', '-f', 'vob', self._timelapsFilename])
|
||||
self._doTimelaps = False
|
||||
|
||||
def _cleanTempDir(self):
|
||||
basePath = os.path.normpath(os.path.join(os.path.split(__file__)[0], "../__tmp_snap"))
|
||||
try:
|
||||
os.makedirs(basePath)
|
||||
except:
|
||||
pass
|
||||
for filename in glob.iglob(basePath + "/*.jpg"):
|
||||
os.remove(filename)
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
# coding=utf-8
|
||||
from __future__ import absolute_import
|
||||
import os
|
||||
import sys
|
||||
|
||||
__all__ = ['getPathForResource', 'getPathForImage', 'getPathForMesh']
|
||||
|
||||
|
||||
if sys.platform.startswith('darwin'):
|
||||
if hasattr(sys, 'frozen'):
|
||||
from Foundation import *
|
||||
imagesPath = os.path.join(NSBundle.mainBundle().resourcePath(), 'images')
|
||||
meshesPath = os.path.join(NSBundle.mainBundle().resourcePath(), 'images')
|
||||
else:
|
||||
imagesPath = os.path.join(os.path.dirname(__file__), "../images")
|
||||
meshesPath = os.path.join(os.path.dirname(__file__), "../images")
|
||||
else:
|
||||
if hasattr(sys, 'frozen'):
|
||||
imagesPath = os.path.join(os.path.dirname(__file__), "../../images")
|
||||
meshesPath = os.path.join(os.path.dirname(__file__), "../../images")
|
||||
else:
|
||||
imagesPath = os.path.join(os.path.dirname(__file__), "../images")
|
||||
meshesPath = os.path.join(os.path.dirname(__file__), "../images")
|
||||
|
||||
|
||||
def getPathForResource(dir, resource_name):
|
||||
assert os.path.isdir(dir), "{p} is not a directory".format(p=dir)
|
||||
path = os.path.normpath(os.path.join(dir, resource_name))
|
||||
assert os.path.isfile(path), "{p} is not a file.".format(p=path)
|
||||
return path
|
||||
|
||||
def getPathForImage(name):
|
||||
return getPathForResource(imagesPath, name)
|
||||
|
||||
def getPathForMesh(name):
|
||||
return getPathForResource(meshesPath, name)
|
Loading…
Reference in New Issue