from Cura.util import meshLoader
import shutil
- def commandlineProgressCallback(progress, ready):
- if progress >= 0 and not ready:
- print 'Preparing: %d%%' % (progress * 100)
+ def commandlineProgressCallback(progress):
+ if progress >= 0:
+ #print 'Preparing: %d%%' % (progress * 100)
+ pass
scene = objectScene.Scene()
scene.updateMachineDimensions()
- slicer = sliceEngine.Slicer(commandlineProgressCallback)
+ engine = sliceEngine.Engine(commandlineProgressCallback)
for m in meshLoader.loadMeshes(args[0]):
scene.add(m)
- slicer.runSlicer(scene)
- slicer.wait()
- profile.replaceGCodeTagsFromSlicer(slicer.getGCodeFilename(), slicer)
+ engine.runEngine(scene)
+ engine.wait()
- if options.output:
- shutil.copyfile(slicer.getGCodeFilename(), options.output)
- print 'GCode file saved : %s' % options.output
- else:
- shutil.copyfile(slicer.getGCodeFilename(), args[0] + '.gcode')
- print 'GCode file saved as: %s' % (args[0] + '.gcode')
+ if not options.output:
+ options.output = args[0] + '.gcode'
+ with open(options.output, "wb") as f:
+ f.write(engine.getResult().getGCode())
+ print 'GCode file saved : %s' % options.output
- slicer.cleanup()
+ engine.cleanup()
else:
from Cura.gui import app
app.CuraApp(args).MainLoop()
import random
def treeWalk(moduleList, dirname, fnames):
+ """ Callback from the os.path.walk function, see if the given path is a module and import it to put it in the moduleList """
dirname = dirname.replace("\\", ".").replace("/", ".")
if dirname == 'Cura.util.pymclevel':
return
print "Failed to load: %s" % (fullName)
def main():
+ """
+ Main doctest function.
+ Calculate how many things are documented and not documented yet.
+ And report a random selection of undocumented functions/ modules.
+ """
moduleList = []
os.path.walk("Cura", treeWalk, moduleList)
moduleDocCount = 0
undocList.append(module.__name__)
for name in dir(module):
a = getattr(module, name)
+ try:
+ if not inspect.getfile(a).startswith('Cura'):
+ continue
+ except:
+ continue
if type(a) is types.FunctionType:
functionCount += 1
if inspect.getdoc(a):
print '%d/%d modules have documentation.' % (moduleDocCount, len(moduleList))
print '%d/%d functions have documentation.' % (functionDocCount, functionCount)
print '%d/%d types have documentation.' % (typeDocCount, typeCount)
+ print '%.1f%% documented.' % (float(moduleDocCount + functionDocCount + typeDocCount) / float(len(moduleList) + functionCount + typeCount) * 100.0)
print ''
print 'You might want to document:'
for n in xrange(0, 10):
-__copyright__ = "Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License"
+"""
+Serial communication with the printer for printing is done from a separate process,
+this to ensure that the PIL does not block the serial printing.
-# Serial communication with the printer for printing is done from a separate process,
-# this to ensure that the PIL does not block the serial printing.
+This file is the 2nd process that is started to handle communication with the printer.
+And handles all communication with the initial process.
+"""
+__copyright__ = "Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License"
import sys
import time
import os
+"""
+Simple utility module to open "explorer" file dialogs.
+The name "explorer" comes from the windows file explorer, which is called explorer.
+"""
__copyright__ = "Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License"
import sys
import subprocess
def hasExplorer():
+ """Check if we have support for opening file dialog windows."""
if sys.platform == 'win32' or sys.platform == 'cygwin' or sys.platform == 'darwin':
return True
if sys.platform == 'linux2':
return False
def openExplorer(filename):
+ """Open an file dialog window in the directory of a file, and select the file."""
if sys.platform == 'win32' or sys.platform == 'cygwin':
subprocess.Popen(r'explorer /select,"%s"' % (filename))
if sys.platform == 'darwin':
subprocess.Popen(['open', '-R', filename])
if sys.platform.startswith('linux'):
+ #TODO: On linux we cannot seem to select a certain file, only open the specified path.
if os.path.isfile('/usr/bin/nautilus'):
subprocess.Popen(['/usr/bin/nautilus', os.path.split(filename)[0]])
elif os.path.isfile('/usr/bin/dolphin'):
subprocess.Popen(['/usr/bin/dolphin', os.path.split(filename)[0]])
def openExplorerPath(filename):
+ """Open a file dialog inside a directory, without selecting any file."""
if sys.platform == 'win32' or sys.platform == 'cygwin':
subprocess.Popen(r'explorer "%s"' % (filename))
if sys.platform == 'darwin':
+"""
+AMF file reader.
+AMF files are the proposed replacement for STL. AMF is an open standard to share 3D manufacturing files.
+Many of the features found in AMF are currently not yet support in Cura. Most important the curved surfaces.
+
+http://en.wikipedia.org/wiki/Additive_Manufacturing_File_Format
+"""
__copyright__ = "Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License"
import cStringIO as StringIO
+"""
+DAE are COLLADA files.
+The DAE reader is a limited COLLADA reader. And has only been tested with DAE exports from SketchUp, http://www.sketchup.com/
+The reason for this reader in Cura is that the free version of SketchUp by default does not support any other format that we can read.
+
+http://en.wikipedia.org/wiki/COLLADA
+"""
__copyright__ = "Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License"
from xml.parsers.expat import ParserCreate
+"""
+OBJ file reader.
+OBJ are wavefront object files. These are quite common and can be exported from a lot of 3D tools.
+Only vertex information is read from the OBJ file, information about textures and normals is ignored.
+
+http://en.wikipedia.org/wiki/Wavefront_.obj_file
+"""
__copyright__ = "Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License"
import os
+"""
+STL file mesh loader.
+STL is the most common file format used for 3D printing right now.
+STLs come in 2 flavors.
+ Binary, which is easy and quick to read.
+ Ascii, which is harder to read, as can come with windows, mac and unix style newlines.
+ The ascii reader has been designed so it has great compatibility with all kinds of formats or slightly broken exports from tools.
+
+This module also contains a function to save objects as an STL file.
+
+http://en.wikipedia.org/wiki/STL_(file_format)
+"""
__copyright__ = "Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License"
import sys
+"""
+The polygon module has functions that assist in working with 2D convex polygons.
+"""
__copyright__ = "Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License"
import numpy
def convexHull(pointList):
+ """ Create a convex hull from a list of points. """
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]
return numpy.array(upper + lower, numpy.float32)
def minkowskiHull(a, b):
+ """Calculate the minkowski hull of 2 convex polygons"""
points = numpy.zeros((len(a) * len(b), 2))
for n in xrange(0, len(a)):
for m in xrange(0, len(b)):
return convexHull(points.copy())
def projectPoly(poly, normal):
+ """
+ Project a convex polygon on a given normal.
+ A projection of a convex polygon on a infinite line is a finite line.
+ Give the min and max value on the normal line.
+ """
pMin = numpy.dot(normal, poly[0])
pMax = pMin
for n in xrange(1 , len(poly)):
return pMin, pMax
def polygonCollision(polyA, polyB):
+ """ Check if convexy polygon A and B collide, return True if this is the case. """
for n in xrange(0, len(polyA)):
p0 = polyA[n-1]
p1 = polyA[n]
return True
def polygonCollisionPushVector(polyA, polyB):
+ """ Check if convex polygon A and B collide, return the vector of penetration if this is the case, else return False. """
retSize = 10000000.0
ret = False
for n in xrange(0, len(polyA)):
retSize = size
return ret
-#Check if polyA is fully inside of polyB.
def fullInside(polyA, polyB):
+ """
+ Check if convex polygon A is completely inside of convex polygon B.
+ """
for n in xrange(0, len(polyA)):
p0 = polyA[n-1]
p1 = polyA[n]
return True
def isLeft(a, b, c):
+ """ Check if C is left of the infinite line from A to B """
return ((b[0] - a[0])*(c[1] - a[1]) - (b[1] - a[1])*(c[0] - a[0])) > 0
def lineLineIntersection(p0, p1, p2, p3):
+ """ Return the intersection of the infinite line trough points p0 and p1 and infinite line trough points p2 and p3. """
A1 = p1[1] - p0[1]
B1 = p0[0] - p1[0]
C1 = A1*p0[0] + B1*p0[1]
return [(B2*C1 - B1*C2)/det, (A1 * C2 - A2 * C1) / det]
def clipConvex(poly0, poly1):
+ """ Cut the convex polygon 0 so that it completely fits in convex polygon 1, any part sticking out of polygon 1 is cut off """
res = poly0
for p1idx in xrange(0, len(poly1)):
src = res
+"""
+The profile module contains all the settings for Cura.
+These settings can be globally accessed and modified.
+"""
from __future__ import division
__copyright__ = "Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License"
+"""
+This module handles detection and clean ejection of removable storage. (Mainly SD cards)
+This is OS depended.
+ On windows it looks for removable storage drives.
+ On MacOS it specificly looks for SD cards.
+ On Linux it looks for anything mounted in /media/
+"""
__copyright__ = "Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License"
import platform
import string
+"""
+Helper module to get easy access to the path where resources are stored.
+This is because the resource location is depended on the packaging method and OS
+"""
__copyright__ = "Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License"
import os
+"""
+Slice engine communication.
+This module handles all communication with the slicing engine.
+"""
__copyright__ = "Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License"
import subprocess
import time
+"""
+The util3d module a vector class to work with 3D points. All the basic math operators have been overloaded to work on this object.
+This module is deprecated and only used by the SplitModels function.
+
+Use numpy arrays instead to work with vectors.
+"""
__copyright__ = "Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License"
import math
class Vector3(object):
+ """ 3D vector object. """
def __init__(self, x=0.0, y=0.0, z=0.0):
+ """Create a new 3D vector"""
self.x = x
self.y = y
self.z = z
+"""
+Setting validators.
+These are the validators for various profile settings, each validator can be attached to a setting.
+The validators can be queried to see if the setting is valid.
+There are 3 possible outcomes:
+ Valid - No problems found
+ Warning - The value is valid, but not recommended
+ Error - The value is not a proper number, out of range, or some other way wrong.
+"""
from __future__ import division
__copyright__ = "Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License"
+"""
+The version utility module is used to get the current Cura version, and check for updates.
+It can also see if we are running a development build of Cura.
+"""
__copyright__ = "Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License"
import os
+"""
+YouMagine communication module.
+This module handles all communication with the YouMagine API.
+"""
__copyright__ = "Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License"
import json