Merge remote-tracking branch 'upstream/master' into macosx

Conflicts:
	Cura/gui/configWizard.py
	Cura/gui/mainWindow.py
	Cura/gui/opengl.py
	Cura/gui/printWindow.py
	scripts/osx64/Cura.app/Contents/MacOS/Cura
master
Ilya Kulakov 2012-12-06 00:33:55 +07:00
commit 9f3d727817
26 changed files with 1487 additions and 1277 deletions

View File

@ -10,8 +10,9 @@ class Stk500v2(ispBase.IspBase):
self.serial = None
self.seq = 1
self.lastAddr = -1
self.progressCallback = None
def connect(self, port = 'COM31', speed = 115200):
def connect(self, port = 'COM22', speed = 115200):
if self.serial != None:
self.close()
try:
@ -145,8 +146,8 @@ class Stk500v2(ispBase.IspBase):
def main():
programmer = Stk500v2()
programmer.connect()
programmer.programChip(intelHex.readHex("cfg_4f55234def059.hex"))
programmer.connect(port = sys.argv[1])
programmer.programChip(intelHex.readHex(sys.argv[2]))
sys.exit(1)
if __name__ == '__main__':

View File

@ -27,6 +27,8 @@ class daeModel(triangle_mesh.TriangleMesh):
self._idMap = {}
self._geometryList = []
r.ParseFile(open(filename, "r"))
self._scale = float(self._base['collada'][0]['asset'][0]['unit'][0]['_meter']) * 1000
for instance_visual_scene in self._base['collada'][0]['scene'][0]['instance_visual_scene']:
for node in self._idMap[instance_visual_scene['_url']]['node']:
@ -81,9 +83,9 @@ class daeModel(triangle_mesh.TriangleMesh):
startIndex = len(self.vertexes)
for idx in xrange(0, len(positionList)/3):
x = positionList[idx*3]
y = positionList[idx*3+1]
z = positionList[idx*3+2]
x = positionList[idx*3] * self._scale
y = positionList[idx*3+1] * self._scale
z = positionList[idx*3+2] * self._scale
if matrix != None:
self.vertexes.append(Vector3(x * matrix[0] + y * matrix[1] + z * matrix[2] + matrix[3], x * matrix[4] + y * matrix[5] + z * matrix[6] + matrix[7], x * matrix[8] + y * matrix[9] + z * matrix[10] + matrix[11]))
else:

View File

@ -114,8 +114,8 @@ def getProfileInformation():
'SwapYZ': storedSetting("swap_yz"),
'Scale': storedSettingFloat("model_scale"),
'Rotate': storedSettingFloat("model_rotate_base"),
'CenterX': storedSettingFloat("machine_center_x"),
'CenterY': storedSettingFloat("machine_center_y"),
'CenterX': lambda setting: profile.getProfileSettingFloat('object_center_x') if profile.getProfileSettingFloat('object_center_x') > 0 else profile.getPreferenceFloat("machine_width") / 2,
'CenterY': lambda setting: profile.getProfileSettingFloat('object_center_y') if profile.getProfileSettingFloat('object_center_y') > 0 else profile.getPreferenceFloat("machine_depth") / 2,
'AlternativeCenterFile': storedSetting("alternative_center"),
},'scale': {
'Activate_Scale': "False",
@ -176,8 +176,8 @@ def getProfileInformation():
'Thread_Sequence_Choice': storedSetting('sequence'),
},'multiply': {
'Activate_Multiply': "False",
'Center_X_mm': storedSettingFloat("machine_center_x"),
'Center_Y_mm': storedSettingFloat("machine_center_y"),
'Center_X_mm': lambda setting: profile.getProfileSettingFloat('object_center_x') if profile.getProfileSettingFloat('object_center_x') > 0 else profile.getPreferenceFloat("machine_width") / 2,
'Center_Y_mm': lambda setting: profile.getProfileSettingFloat('object_center_y') if profile.getProfileSettingFloat('object_center_y') > 0 else profile.getPreferenceFloat("machine_depth") / 2,
'Number_of_Columns_integer': storedSetting('model_multiply_x'),
'Number_of_Rows_integer': storedSetting('model_multiply_y'),
'Reverse_Sequence_every_Odd_Layer': DEFSET,
@ -311,8 +311,8 @@ def getProfileInformation():
'Fan_speed_min_%': storedSettingInt('fan_speed'),
'Fan_speed_max_%': storedSettingInt('fan_speed_max'),
},'hop': {
'Activate_Hop': "False",
'Hop_Over_Layer_Thickness_ratio': DEFSET,
'Activate_Hop': storedSetting('hop_on_move'),
'Hop_Over_Layer_Thickness_ratio': lambda setting: 0.2 / profile.getProfileSettingFloat('layer_height'),
'Minimum_Hop_Angle_degrees': DEFSET,
},'wipe': {
'Activate_Wipe': "False",

View File

@ -266,7 +266,7 @@ def writeOutput(fileName, shouldAnalyze=True):
repository = ExportRepository()
settings.getReadRepository(repository)
startTime = time.time()
print('File ' + archive.getSummarizedFileName(fileName) + ' is being chain exported.')
print('File ' + archive.getSummarizedFileName(fileName.encode('ascii', 'replace')) + ' is being chain exported.')
fileNameSuffix = fileName[: fileName.rfind('.')]
if repository.addExportSuffix.value:
fileNameSuffix += '_export'

File diff suppressed because it is too large Load Diff

View File

@ -67,6 +67,9 @@ class expertConfigWindow(configBase.configWindowBase):
configBase.TitleRow(right, "Retraction")
c = configBase.SettingRow(right, "Retract on jumps only", 'retract_on_jumps_only', True, 'Only retract when we are making a move that is over a hole in the model, else retract on every move. This effects print quality in different ways.')
configBase.TitleRow(right, "Hop")
c = configBase.SettingRow(right, "Enable hop on move", 'hop_on_move', False, 'When moving from print position to print position, raise the printer head 0.2mm so it does not knock off the print (experimental).')
main.Fit()
self.Fit()

View File

@ -84,7 +84,7 @@ class flatSlicerWindow(wx.Frame):
if dlg.ShowModal() == wx.ID_OK:
self.filename = dlg.GetPath()
self.svg = svg.SVG(self.filename)
self.svg.center(complex(profile.getProfileSettingFloat('machine_center_x'), profile.getProfileSettingFloat('machine_center_y')))
self.svg.center(complex(profile.getPreferenceFloat('machine_width')/2, profile.getPreferenceFloat('machine_depth')/2))
self.preview.Refresh()
dlg.Destroy()

View File

@ -113,7 +113,7 @@ class mainWindow(configBase.configWindowBase):
helpMenu = wx.Menu()
i = helpMenu.Append(-1, 'Online documentation...')
self.Bind(wx.EVT_MENU, lambda e: webbrowser.open('https://daid.github.com/Cura'), i)
self.Bind(wx.EVT_MENU, lambda e: webbrowser.open('http://daid.github.com/Cura'), i)
i = helpMenu.Append(-1, 'Report a problem...')
self.Bind(wx.EVT_MENU, lambda e: webbrowser.open('https://github.com/daid/Cura/issues'), i)
menubar.Append(helpMenu, 'Help')
@ -134,7 +134,7 @@ class mainWindow(configBase.configWindowBase):
(left, right) = self.CreateConfigTab(nb, 'Print config')
configBase.TitleRow(left, "Accuracy")
configBase.TitleRow(left, "Quality")
c = configBase.SettingRow(left, "Layer height (mm)", 'layer_height', '0.2', 'Layer height in millimeters.\n0.2 is a good value for quick prints.\n0.1 gives high quality prints.')
validators.validFloat(c, 0.0001)
validators.warningAbove(c, lambda : (float(profile.getProfileSetting('nozzle_size')) * 80.0 / 100.0), "Thicker layers then %.2fmm (80%% nozzle size) usually give bad results and are not recommended.")
@ -149,12 +149,6 @@ class mainWindow(configBase.configWindowBase):
c = configBase.SettingRow(left, "Fill Density (%)", 'fill_density', '20', 'This controls how densily filled the insides of your print will be. For a solid part use 100%, for an empty part use 0%. A value around 20% is usually enough')
validators.validFloat(c, 0.0, 100.0)
configBase.TitleRow(left, "Skirt")
c = configBase.SettingRow(left, "Line count", 'skirt_line_count', '1', 'The skirt is a line drawn around the object at the first layer. This helps to prime your extruder, and to see if the object fits on your platform.\nSetting this to 0 will disable the skirt. Multiple skirt lines can help priming your extruder better for small objects.')
validators.validInt(c, 0, 10)
c = configBase.SettingRow(left, "Start distance (mm)", 'skirt_gap', '6.0', 'The distance between the skirt and the first layer.\nThis is the minimal distance, multiple skirt lines will be put outwards from this distance.')
validators.validFloat(c, 0.0)
configBase.TitleRow(right, "Speed && Temperature")
c = configBase.SettingRow(right, "Print speed (mm/s)", 'print_speed', '50', 'Speed at which printing happens. A well adjusted Ultimaker can reach 150mm/s, but for good quality prints you want to print slower. Printing speed depends on a lot of factors. So you will be experimenting with optimal settings for this.')
validators.validFloat(c, 1.0)
@ -187,15 +181,15 @@ class mainWindow(configBase.configWindowBase):
configBase.TitleRow(left, "Machine size")
c = configBase.SettingRow(left, "Nozzle size (mm)", 'nozzle_size', '0.4', 'The nozzle size is very important, this is used to calculate the line width of the infill, and used to calculate the amount of outside wall lines and thickness for the wall thickness you entered in the print settings.')
validators.validFloat(c, 0.1, 10.0)
c = configBase.SettingRow(left, "Machine center X (mm)", 'machine_center_x', '100', 'The center of your machine, your print will be placed at this location')
validators.validInt(c, 10)
configBase.settingNotify(c, self.preview3d.updateCenterX)
c = configBase.SettingRow(left, "Machine center Y (mm)", 'machine_center_y', '100', 'The center of your machine, your print will be placed at this location')
validators.validInt(c, 10)
configBase.settingNotify(c, self.preview3d.updateCenterY)
configBase.TitleRow(left, "Skirt")
c = configBase.SettingRow(left, "Line count", 'skirt_line_count', '1', 'The skirt is a line drawn around the object at the first layer. This helps to prime your extruder, and to see if the object fits on your platform.\nSetting this to 0 will disable the skirt. Multiple skirt lines can help priming your extruder better for small objects.')
validators.validInt(c, 0, 10)
c = configBase.SettingRow(left, "Start distance (mm)", 'skirt_gap', '6.0', 'The distance between the skirt and the first layer.\nThis is the minimal distance, multiple skirt lines will be put outwards from this distance.')
validators.validFloat(c, 0.0)
configBase.TitleRow(left, "Retraction")
c = configBase.SettingRow(left, "Minimal travel (mm)", 'retraction_min_travel', '5.0', 'Minimal amount of travel needed for a retraction to happen at all. To make sure you do not get a lot of retractions in a small area')
c = configBase.SettingRow(left, "Minimum travel (mm)", 'retraction_min_travel', '5.0', 'Minimum amount of travel needed for a retraction to happen at all. To make sure you do not get a lot of retractions in a small area')
validators.validFloat(c, 0.0)
c = configBase.SettingRow(left, "Speed (mm/s)", 'retraction_speed', '40.0', 'Speed at which the filament is retracted, a higher retraction speed works better. But a very high retraction speed can lead to filament grinding.')
validators.validFloat(c, 0.1)
@ -218,11 +212,11 @@ class mainWindow(configBase.configWindowBase):
validators.validFloat(c, 0.0)
c = configBase.SettingRow(right, "Enable cooling fan", 'fan_enabled', True, 'Enable the cooling fan during the print. The extra cooling from the cooling fan is essensial during faster prints.')
configBase.TitleRow(right, "Accuracy")
configBase.TitleRow(right, "Quality")
c = configBase.SettingRow(right, "Initial layer thickness (mm)", 'bottom_thickness', '0.0', 'Layer thickness of the bottom layer. A thicker bottom layer makes sticking to the bed easier. Set to 0.0 to have the bottom layer thickness the same as the other layers.')
validators.validFloat(c, 0.0)
validators.warningAbove(c, lambda : (float(profile.getProfileSetting('nozzle_size')) * 3.0 / 4.0), "A bottom layer of more then %.2fmm (3/4 nozzle size) usually give bad results and is not recommended.")
c = configBase.SettingRow(right, "Enable 'skin'", 'enable_skin', False, 'Skin prints the outer lines of the prints twice, each time with half the thickness. This gives the illusion of a higher print quality.')
c = configBase.SettingRow(right, "Duplicate outlines", 'enable_skin', False, 'Skin prints the outer lines of the prints twice, each time with half the thickness. This gives the illusion of a higher print quality.')
#Plugin page
self.pluginPanel = pluginPanel.pluginPanel(nb)
@ -236,7 +230,7 @@ class mainWindow(configBase.configWindowBase):
nb.AddPage(self.alterationPanel, "Start/End-GCode")
# load and slice buttons.
loadButton = wx.Button(self, -1, '&Load Model')
loadButton = wx.Button(self, -1, '&Load model')
sliceButton = wx.Button(self, -1, 'P&repare print')
printButton = wx.Button(self, -1, '&Print')
self.Bind(wx.EVT_BUTTON, lambda e: self._showModelLoadDialog(1), loadButton)
@ -331,10 +325,6 @@ class mainWindow(configBase.configWindowBase):
dlg.Destroy()
if result:
profile.resetGlobalProfile()
if profile.getPreference('machine_type') == 'reprap':
profile.putProfileSetting('nozzle_size', '0.5')
profile.putProfileSetting('machine_center_x', '40')
profile.putProfileSetting('machine_center_y', '40')
self.updateProfileToControls()
def OnBatchRun(self, e):

View File

@ -1,458 +1,496 @@
# 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)
# 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 DrawMeshSteep(mesh, angle):
cosAngle = math.sin(angle / 180.0 * math.pi)
glDisable(GL_LIGHTING)
glDepthFunc(GL_EQUAL)
for i in xrange(0, int(mesh.vertexCount), 3):
if mesh.normal[i][2] < -0.999999:
if mesh.vertexes[i + 0][2] > 0.01:
glColor3f(0.5, 0, 0)
glBegin(GL_TRIANGLES)
glVertex3f(mesh.vertexes[i + 0][0], mesh.vertexes[i + 0][1], mesh.vertexes[i + 0][2])
glVertex3f(mesh.vertexes[i + 1][0], mesh.vertexes[i + 1][1], mesh.vertexes[i + 1][2])
glVertex3f(mesh.vertexes[i + 2][0], mesh.vertexes[i + 2][1], mesh.vertexes[i + 2][2])
glEnd()
elif mesh.normal[i][2] < -cosAngle:
glColor3f(-mesh.normal[i][2], 0, 0)
glBegin(GL_TRIANGLES)
glVertex3f(mesh.vertexes[i + 0][0], mesh.vertexes[i + 0][1], mesh.vertexes[i + 0][2])
glVertex3f(mesh.vertexes[i + 1][0], mesh.vertexes[i + 1][1], mesh.vertexes[i + 1][2])
glVertex3f(mesh.vertexes[i + 2][0], mesh.vertexes[i + 2][1], mesh.vertexes[i + 2][2])
glEnd()
elif mesh.normal[i][2] > 0.999999:
if mesh.vertexes[i + 0][2] > 0.01:
glColor3f(0.5, 0, 0)
glBegin(GL_TRIANGLES)
glVertex3f(mesh.vertexes[i + 0][0], mesh.vertexes[i + 0][1], mesh.vertexes[i + 0][2])
glVertex3f(mesh.vertexes[i + 2][0], mesh.vertexes[i + 2][1], mesh.vertexes[i + 2][2])
glVertex3f(mesh.vertexes[i + 1][0], mesh.vertexes[i + 1][1], mesh.vertexes[i + 1][2])
glEnd()
elif mesh.normal[i][2] > cosAngle:
glColor3f(mesh.normal[i][2], 0, 0)
glBegin(GL_TRIANGLES)
glVertex3f(mesh.vertexes[i + 0][0], mesh.vertexes[i + 0][1], mesh.vertexes[i + 0][2])
glVertex3f(mesh.vertexes[i + 2][0], mesh.vertexes[i + 2][1], mesh.vertexes[i + 2][2])
glVertex3f(mesh.vertexes[i + 1][0], mesh.vertexes[i + 1][1], mesh.vertexes[i + 1][2])
glEnd()
glDepthFunc(GL_LESS)
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)

View File

@ -3,6 +3,7 @@ import sys, math, threading, os, webbrowser
from wx.lib import scrolledpanel
from util import profile
from util import exporer
class pluginPanel(wx.Panel):
def __init__(self, parent):
@ -20,19 +21,23 @@ class pluginPanel(wx.Panel):
self.listbox = wx.ListBox(self, -1, choices=effectStringList)
title = wx.StaticText(self, -1, "Plugins:")
title.SetFont(wx.Font(wx.SystemSettings.GetFont(wx.SYS_ANSI_VAR_FONT).GetPointSize(), wx.FONTFAMILY_DEFAULT, wx.NORMAL, wx.FONTWEIGHT_BOLD))
helpButton = wx.Button(self, -1, '?', style=wx.BU_EXACTFIT)
addButton = wx.Button(self, -1, '>', style=wx.BU_EXACTFIT)
openPluginLocationButton = wx.Button(self, -1, 'Open plugin location')
sb = wx.StaticBox(self, label="Enabled plugins")
boxsizer = wx.StaticBoxSizer(sb, wx.VERTICAL)
self.pluginEnabledPanel = scrolledpanel.ScrolledPanel(self)
self.pluginEnabledPanel.SetupScrolling(False, True)
sizer.Add(title, (0,0), border=10, flag=wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.TOP)
sizer.Add(self.listbox, (1,0), span=(2,1), border=10, flag=wx.EXPAND|wx.LEFT|wx.RIGHT|wx.BOTTOM)
sizer.Add(addButton, (1,1), border=5, flag=wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_BOTTOM)
sizer.Add(boxsizer, (1,2), span=(2,1), border=10, flag=wx.EXPAND|wx.LEFT|wx.RIGHT|wx.BOTTOM)
sizer.Add(helpButton, (0,1), border=10, flag=wx.ALIGN_RIGHT|wx.RIGHT|wx.TOP)
sizer.Add(self.listbox, (1,0), span=(2,2), border=10, flag=wx.EXPAND|wx.LEFT|wx.RIGHT)
sizer.Add(addButton, (1,2), border=5, flag=wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_BOTTOM)
sizer.Add(boxsizer, (1,3), span=(2,1), border=10, flag=wx.EXPAND|wx.LEFT|wx.RIGHT)
sizer.Add(openPluginLocationButton, (3, 0), span=(1,2), border=10, flag=wx.LEFT|wx.BOTTOM)
boxsizer.Add(self.pluginEnabledPanel, 1, flag=wx.EXPAND)
sizer.AddGrowableCol(2)
sizer.AddGrowableCol(3)
sizer.AddGrowableRow(1)
sizer.AddGrowableRow(2)
@ -40,6 +45,9 @@ class pluginPanel(wx.Panel):
self.pluginEnabledPanel.SetSizer(sizer)
self.Bind(wx.EVT_BUTTON, self.OnAdd, addButton)
self.Bind(wx.EVT_BUTTON, self.OnGeneralHelp, helpButton)
self.Bind(wx.EVT_BUTTON, self.OnOpenPluginLocation, openPluginLocationButton)
self.listbox.Bind(wx.EVT_LEFT_DCLICK, self.OnAdd)
self.panelList = []
self.updateProfileToControls()
@ -151,3 +159,9 @@ class pluginPanel(wx.Panel):
fname = fname[0].upper() + fname[1:]
fname = fname[:fname.rfind('.')]
webbrowser.open('http://wiki.ultimaker.com/CuraPlugin:_' + fname)
def OnGeneralHelp(self, e):
webbrowser.open('http://wiki.ultimaker.com/Category:CuraPlugin')
def OnOpenPluginLocation(self, e):
exporer.openExporerPath(profile.getPluginBasePaths()[0])

View File

@ -22,11 +22,11 @@ class preferencesDialog(configBase.configWindowBase):
configBase.TitleRow(left, 'Machine settings')
c = configBase.SettingRow(left, 'Steps per E', 'steps_per_e', '0', 'Amount of steps per mm filament extrusion', type = 'preference')
validators.validFloat(c, 0.1)
c = configBase.SettingRow(left, 'Machine width (mm)', 'machine_width', '205', 'Size of the machine in mm', type = 'preference')
c = configBase.SettingRow(left, 'Maximum width (mm)', 'machine_width', '205', 'Size of the machine in mm', type = 'preference')
validators.validFloat(c, 10.0)
c = configBase.SettingRow(left, 'Machine depth (mm)', 'machine_depth', '205', 'Size of the machine in mm', type = 'preference')
c = configBase.SettingRow(left, 'Maximum depth (mm)', 'machine_depth', '205', 'Size of the machine in mm', type = 'preference')
validators.validFloat(c, 10.0)
c = configBase.SettingRow(left, 'Machine height (mm)', 'machine_height', '200', 'Size of the machine in mm', type = 'preference')
c = configBase.SettingRow(left, 'Maximum height (mm)', 'machine_height', '200', 'Size of the machine in mm', type = 'preference')
validators.validFloat(c, 10.0)
c = configBase.SettingRow(left, 'Extruder count', 'extruder_amount', ['1', '2', '3', '4'], 'Amount of extruders in your machine.', type = 'preference')
c = configBase.SettingRow(left, 'Heated bed', 'has_heated_bed', False, 'If you have an heated bed, this enabled heated bed settings', type = 'preference')
@ -44,11 +44,11 @@ class preferencesDialog(configBase.configWindowBase):
c = configBase.SettingRow(left, 'Model colour (%d)' % (i+1), 'model_colour%d' % (i+1), wx.Colour(0,0,0), '', type = 'preference')
configBase.TitleRow(right, 'Filament settings')
c = configBase.SettingRow(right, 'Filament density (kg/m3)', 'filament_density', '1300', 'Weight of the filament per m3. Around 1300 for PLA. And around 1040 for ABS. This value is used to estimate the weight if the filament used for the print.', type = 'preference')
c = configBase.SettingRow(right, 'Density (kg/m3)', 'filament_density', '1300', 'Weight of the filament per m3. Around 1300 for PLA. And around 1040 for ABS. This value is used to estimate the weight if the filament used for the print.', type = 'preference')
validators.validFloat(c, 500.0, 3000.0)
c = configBase.SettingRow(right, 'Filament cost (price/kg)', 'filament_cost_kg', '0', 'Cost of your filament per kg, to estimate the cost of the final print.', type = 'preference')
c = configBase.SettingRow(right, 'Cost (price/kg)', 'filament_cost_kg', '0', 'Cost of your filament per kg, to estimate the cost of the final print.', type = 'preference')
validators.validFloat(c, 0.0)
c = configBase.SettingRow(right, 'Filament cost (price/m)', 'filament_cost_meter', '0', 'Cost of your filament per meter, to estimate the cost of the final print.', type = 'preference')
c = configBase.SettingRow(right, 'Cost (price/m)', 'filament_cost_meter', '0', 'Cost of your filament per meter, to estimate the cost of the final print.', type = 'preference')
validators.validFloat(c, 0.0)
configBase.TitleRow(right, 'Communication settings')

View File

@ -43,9 +43,10 @@ class previewPanel(wx.Panel):
self.gcode = None
self.objectsMinV = None
self.objectsMaxV = None
self.objectsBounderyCircleSize = None
self.loadThread = None
self.machineSize = util3d.Vector3(profile.getPreferenceFloat('machine_width'), profile.getPreferenceFloat('machine_depth'), profile.getPreferenceFloat('machine_height'))
self.machineCenter = util3d.Vector3(float(profile.getProfileSetting('machine_center_x')), float(profile.getProfileSetting('machine_center_y')), 0)
self.machineCenter = util3d.Vector3(self.machineSize.x / 2, self.machineSize.y / 2, 0)
self.glCanvas = PreviewGLCanvas(self)
#Create the popup window
@ -77,6 +78,7 @@ class previewPanel(wx.Panel):
self.toolbar.AddSeparator()
self.showBorderButton = toolbarUtil.ToggleButton(self.toolbar, '', 'view-border-on.png', 'view-border-off.png', 'Show model borders', callback=self.OnViewChange)
self.showSteepOverhang = toolbarUtil.ToggleButton(self.toolbar, '', 'steepOverhang-on.png', 'steepOverhang-off.png', 'Show steep overhang', callback=self.OnViewChange)
self.toolbar.AddSeparator()
group = []
@ -90,18 +92,21 @@ class previewPanel(wx.Panel):
self.layerSpin = wx.SpinCtrl(self.toolbar, -1, '', size=(21*4,21), style=wx.SP_ARROW_KEYS)
self.toolbar.AddControl(self.layerSpin)
self.Bind(wx.EVT_SPINCTRL, self.OnLayerNrChange, self.layerSpin)
self.toolbar.AddSeparator()
self.toolbarInfo = wx.TextCtrl(self.toolbar, -1, '', style=wx.TE_READONLY)
self.toolbar.AddControl(self.toolbarInfo)
self.toolbar2 = toolbarUtil.Toolbar(self)
# Mirror
self.mirrorX = toolbarUtil.ToggleButton(self.toolbar2, 'flip_x', 'object-mirror-x-on.png', 'object-mirror-x-off.png', 'Mirror X', callback=self.updateModelTransform)
self.mirrorY = toolbarUtil.ToggleButton(self.toolbar2, 'flip_y', 'object-mirror-y-on.png', 'object-mirror-y-off.png', 'Mirror Y', callback=self.updateModelTransform)
self.mirrorZ = toolbarUtil.ToggleButton(self.toolbar2, 'flip_z', 'object-mirror-z-on.png', 'object-mirror-z-off.png', 'Mirror Z', callback=self.updateModelTransform)
self.mirrorX = toolbarUtil.ToggleButton(self.toolbar2, 'flip_x', 'object-mirror-x-on.png', 'object-mirror-x-off.png', 'Mirror X', callback=self.returnToModelViewAndUpdateModel)
self.mirrorY = toolbarUtil.ToggleButton(self.toolbar2, 'flip_y', 'object-mirror-y-on.png', 'object-mirror-y-off.png', 'Mirror Y', callback=self.returnToModelViewAndUpdateModel)
self.mirrorZ = toolbarUtil.ToggleButton(self.toolbar2, 'flip_z', 'object-mirror-z-on.png', 'object-mirror-z-off.png', 'Mirror Z', callback=self.returnToModelViewAndUpdateModel)
self.toolbar2.AddSeparator()
# Swap
self.swapXZ = toolbarUtil.ToggleButton(self.toolbar2, 'swap_xz', 'object-swap-xz-on.png', 'object-swap-xz-off.png', 'Swap XZ', callback=self.updateModelTransform)
self.swapYZ = toolbarUtil.ToggleButton(self.toolbar2, 'swap_yz', 'object-swap-yz-on.png', 'object-swap-yz-off.png', 'Swap YZ', callback=self.updateModelTransform)
self.swapXZ = toolbarUtil.ToggleButton(self.toolbar2, 'swap_xz', 'object-swap-xz-on.png', 'object-swap-xz-off.png', 'Swap XZ', callback=self.returnToModelViewAndUpdateModel)
self.swapYZ = toolbarUtil.ToggleButton(self.toolbar2, 'swap_yz', 'object-swap-yz-on.png', 'object-swap-yz-off.png', 'Swap YZ', callback=self.returnToModelViewAndUpdateModel)
self.toolbar2.AddSeparator()
# Scale
@ -136,6 +141,11 @@ class previewPanel(wx.Panel):
sizer.Add(self.toolbar2, 0, flag=wx.EXPAND|wx.BOTTOM|wx.LEFT|wx.RIGHT, border=1)
self.SetSizer(sizer)
def returnToModelViewAndUpdateModel(self):
if self.glCanvas.viewMode == 'GCode' or self.glCanvas.viewMode == 'Mixed':
self.setViewMode('Normal')
self.updateModelTransform()
def OnMove(self, e = None):
if e != None:
e.Skip()
@ -168,21 +178,34 @@ class previewPanel(wx.Panel):
if self.scale.GetValue() != '':
scale = self.scale.GetValue()
profile.putProfileSetting('model_scale', scale)
if self.glCanvas.viewMode == 'GCode' or self.glCanvas.viewMode == 'Mixed':
self.setViewMode('Normal')
self.glCanvas.Refresh()
def OnScaleMax(self, e):
if self.objectsMaxV != None:
size = (self.objectsMaxV - self.objectsMinV) * float(scale)
self.toolbarInfo.SetValue('%0.1f %0.1f %0.1f' % (size[0], size[1], size[2]))
def OnScaleMax(self, e = None, onlyScaleDown = False):
if self.objectsMinV == None:
return
vMin = self.objectsMinV
vMax = self.objectsMaxV
scaleX1 = (self.machineSize.x - self.machineCenter.x) / ((vMax[0] - vMin[0]) / 2)
scaleY1 = (self.machineSize.y - self.machineCenter.y) / ((vMax[1] - vMin[1]) / 2)
scaleX2 = (self.machineCenter.x) / ((vMax[0] - vMin[0]) / 2)
scaleY2 = (self.machineCenter.y) / ((vMax[1] - vMin[1]) / 2)
skirtSize = 3
if profile.getProfileSettingFloat('skirt_line_count') > 0:
skirtSize = 3 + profile.getProfileSettingFloat('skirt_line_count') * profile.calculateEdgeWidth() + profile.getProfileSettingFloat('skirt_gap')
scaleX1 = (self.machineSize.x - self.machineCenter.x - skirtSize) / ((vMax[0] - vMin[0]) / 2)
scaleY1 = (self.machineSize.y - self.machineCenter.y - skirtSize) / ((vMax[1] - vMin[1]) / 2)
scaleX2 = (self.machineCenter.x - skirtSize) / ((vMax[0] - vMin[0]) / 2)
scaleY2 = (self.machineCenter.y - skirtSize) / ((vMax[1] - vMin[1]) / 2)
scaleZ = self.machineSize.z / (vMax[2] - vMin[2])
scale = min(scaleX1, scaleY1, scaleX2, scaleY2, scaleZ)
if scale > 1.0 and onlyScaleDown:
return
self.scale.SetValue(str(scale))
profile.putProfileSetting('model_scale', self.scale.GetValue())
if self.glCanvas.viewMode == 'GCode' or self.glCanvas.viewMode == 'Mixed':
self.setViewMode('Normal')
self.glCanvas.Refresh()
def OnRotateReset(self, e):
@ -191,7 +214,7 @@ class previewPanel(wx.Panel):
def OnRotate(self, e):
profile.putProfileSetting('model_rotate_base', self.rotate.GetValue())
self.updateModelTransform()
self.returnToModelViewAndUpdateModel()
def On3DClick(self):
self.glCanvas.yaw = 30
@ -209,14 +232,6 @@ class previewPanel(wx.Panel):
def OnLayerNrChange(self, e):
self.glCanvas.Refresh()
def updateCenterX(self):
self.machineCenter.x = profile.getProfileSettingFloat('machine_center_x')
self.glCanvas.Refresh()
def updateCenterY(self):
self.machineCenter.y = profile.getProfileSettingFloat('machine_center_y')
self.glCanvas.Refresh()
def setViewMode(self, mode):
if mode == "Normal":
@ -249,8 +264,8 @@ class previewPanel(wx.Panel):
self.loadThread.start()
if showWarning:
if profile.getProfileSettingFloat('model_scale') != 1.0 or profile.getProfileSettingFloat('model_rotate_base') != 0 or profile.getProfileSetting('flip_x') != 'False' or profile.getProfileSetting('flip_y') != 'False' or profile.getProfileSetting('flip_z') != 'False' or profile.getProfileSetting('swap_xz') != 'False' or profile.getProfileSetting('swap_yz') != 'False':
self.ShowWarningPopup('Reset scale, rotation and mirror?', self.OnResetAll)
if profile.getProfileSettingFloat('model_scale') != 1.0 or profile.getProfileSettingFloat('model_rotate_base') != 0 or profile.getProfileSetting('flip_x') != 'False' or profile.getProfileSetting('flip_y') != 'False' or profile.getProfileSetting('flip_z') != 'False' or profile.getProfileSetting('swap_xz') != 'False' or profile.getProfileSetting('swap_yz') != 'False' or len(profile.getPluginConfig()) > 0:
self.ShowWarningPopup('Reset scale, rotation, mirror and plugins?', self.OnResetAll)
def loadReModelFiles(self, filelist):
#Only load this again if the filename matches the file we have already loaded (for auto loading GCode after slicing)
@ -268,10 +283,10 @@ class previewPanel(wx.Panel):
obj.dirty = False
obj.mesh = mesh
self.updateModelTransform()
self.OnScaleMax(None, True)
scale = profile.getProfileSettingFloat('model_scale')
size = (self.objectsMaxV - self.objectsMinV) * scale
if size[0] > self.machineSize.x or size[1] > self.machineSize.y or size[2] > self.machineSize.z:
self.OnScaleMax(None)
self.toolbarInfo.SetValue('%0.1f %0.1f %0.1f' % (size[0], size[1], size[2]))
self.glCanvas.zoom = numpy.max(size) * 2.5
self.errorList = []
wx.CallAfter(self.updateToolbar)
@ -311,7 +326,8 @@ class previewPanel(wx.Panel):
profile.putProfileSetting('flip_z', 'False')
profile.putProfileSetting('swap_xz', 'False')
profile.putProfileSetting('swap_yz', 'False')
self.updateProfileToControls()
profile.setPluginConfig([])
self.GetParent().updateProfileToControls()
def ShowWarningPopup(self, text, callback = None):
self.warningPopup.text.SetLabel(text)
@ -358,6 +374,7 @@ class previewPanel(wx.Panel):
elif self.mixedViewButton.GetValue():
self.glCanvas.viewMode = "Mixed"
self.glCanvas.drawBorders = self.showBorderButton.GetValue()
self.glCanvas.drawSteepOverhang = self.showSteepOverhang.GetValue()
self.updateToolbar()
self.glCanvas.Refresh()
@ -379,6 +396,7 @@ class previewPanel(wx.Panel):
minV = self.objectList[0].mesh.getMinimum()
maxV = self.objectList[0].mesh.getMaximum()
objectsBounderyCircleSize = self.objectList[0].mesh.bounderyCircleSize
for obj in self.objectList:
if obj.mesh == None:
continue
@ -386,9 +404,11 @@ class previewPanel(wx.Panel):
obj.mesh.getMinimumZ()
minV = numpy.minimum(minV, obj.mesh.getMinimum())
maxV = numpy.maximum(maxV, obj.mesh.getMaximum())
objectsBounderyCircleSize = max(objectsBounderyCircleSize, obj.mesh.bounderyCircleSize)
self.objectsMaxV = maxV
self.objectsMinV = minV
self.objectsBounderyCircleSize = objectsBounderyCircleSize
for obj in self.objectList:
if obj.mesh == None:
continue
@ -400,6 +420,11 @@ class previewPanel(wx.Panel):
# v[1] -= minV[1] + (maxV[1] - minV[1]) / 2
obj.mesh.getMinimumZ()
obj.dirty = True
scale = profile.getProfileSettingFloat('model_scale')
size = (self.objectsMaxV - self.objectsMinV) * scale
self.toolbarInfo.SetValue('%0.1f %0.1f %0.1f' % (size[0], size[1], size[2]))
self.glCanvas.Refresh()
def updateProfileToControls(self):
@ -447,16 +472,15 @@ class PreviewGLCanvas(glcanvas.GLCanvas):
def OnMouseMotion(self,e):
cursorXY = 100000
sizeXY = 0
radius = 0
if self.parent.objectsMaxV != None:
size = (self.parent.objectsMaxV - self.parent.objectsMinV)
sizeXY = math.sqrt((size[0] * size[0]) + (size[1] * size[1]))
radius = self.parent.objectsBounderyCircleSize * profile.getProfileSettingFloat('model_scale')
p0 = numpy.array(gluUnProject(e.GetX(), self.viewport[1] + self.viewport[3] - e.GetY(), 0, self.modelMatrix, self.projMatrix, self.viewport))
p1 = numpy.array(gluUnProject(e.GetX(), self.viewport[1] + self.viewport[3] - e.GetY(), 1, self.modelMatrix, self.projMatrix, self.viewport))
cursorZ0 = p0 - (p1 - p0) * (p0[2] / (p1[2] - p0[2]))
cursorXY = math.sqrt((cursorZ0[0] * cursorZ0[0]) + (cursorZ0[1] * cursorZ0[1]))
if cursorXY >= sizeXY * 0.7 and cursorXY <= sizeXY * 0.7 + 3 and False:
if cursorXY >= radius * 1.1 and cursorXY <= radius * 1.3:
self.SetCursor(wx.StockCursor(wx.CURSOR_SIZING))
else:
self.SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT))
@ -464,7 +488,7 @@ class PreviewGLCanvas(glcanvas.GLCanvas):
if e.Dragging() and e.LeftIsDown():
if self.dragType == '':
#Define the drag type depending on the cursor position.
if cursorXY >= sizeXY * 0.7 and cursorXY <= sizeXY * 0.7 + 3 and False:
if cursorXY >= radius * 1.1 and cursorXY <= radius * 1.3:
self.dragType = 'modelRotate'
self.dragStart = math.atan2(cursorZ0[0], cursorZ0[1])
else:
@ -485,6 +509,8 @@ class PreviewGLCanvas(glcanvas.GLCanvas):
angle = math.atan2(cursorZ0[0], cursorZ0[1])
diff = self.dragStart - angle
self.tempRotate = diff * 180 / math.pi
rot = profile.getProfileSettingFloat('model_rotate_base')
self.tempRotate = round((self.tempRotate + rot) / 15) * 15 - rot
#Workaround for buggy ATI cards.
size = self.GetSizeTuple()
self.SetSize((size[0]+1, size[1]))
@ -492,7 +518,13 @@ class PreviewGLCanvas(glcanvas.GLCanvas):
self.Refresh()
else:
if self.tempRotate != 0:
profile.putProfileSetting('model_rotate_base', profile.getProfileSettingFloat('model_rotate_base') + self.tempRotate)
newRotation = profile.getProfileSettingFloat('model_rotate_base') + self.tempRotate
while newRotation >= 360:
newRotation -= 360
while newRotation < 0:
newRotation += 360
profile.putProfileSetting('model_rotate_base', newRotation)
self.parent.rotate.SetValue(newRotation)
self.parent.updateModelTransform()
self.tempRotate = 0
@ -580,12 +612,16 @@ class PreviewGLCanvas(glcanvas.GLCanvas):
if obj.mesh == None:
continue
if obj.displayList == None:
obj.displayList = glGenLists(1);
obj.displayList = glGenLists(1)
obj.steepDisplayList = glGenLists(1)
if obj.dirty:
obj.dirty = False
glNewList(obj.displayList, GL_COMPILE)
opengl.DrawMesh(obj.mesh)
glEndList()
glNewList(obj.steepDisplayList, GL_COMPILE)
opengl.DrawMeshSteep(obj.mesh, 60)
glEndList()
if self.viewMode == "Mixed":
glDisable(GL_BLEND)
@ -706,6 +742,15 @@ class PreviewGLCanvas(glcanvas.GLCanvas):
glScalef(modelScale, modelScale, modelScale)
opengl.DrawMeshOutline(obj.mesh)
glPopMatrix()
if self.drawSteepOverhang:
glDisable(GL_LIGHTING)
glColor3f(1,1,1)
glPushMatrix()
modelScale = profile.getProfileSettingFloat('model_scale')
glScalef(modelScale, modelScale, modelScale)
glCallList(obj.steepDisplayList)
glPopMatrix()
glPopMatrix()
if self.viewMode == "Normal" or self.viewMode == "Transparent" or self.viewMode == "X-Ray":
@ -720,29 +765,36 @@ class PreviewGLCanvas(glcanvas.GLCanvas):
glEnd()
glEnable(GL_DEPTH_TEST)
opengl.DrawMachine(machineSize)
glPushMatrix()
glTranslate(self.parent.machineCenter.x, self.parent.machineCenter.y, 0)
#Draw the rotate circle
if self.parent.objectsMaxV != None and False:
if self.parent.objectsMaxV != None:
glDisable(GL_LIGHTING)
glDisable(GL_CULL_FACE)
glEnable(GL_BLEND)
glRotate(self.tempRotate + profile.getProfileSettingFloat('model_rotate_base'), 0, 0, 1)
radius = self.parent.objectsBounderyCircleSize * profile.getProfileSettingFloat('model_scale')
glScalef(radius, radius, 1)
glBegin(GL_TRIANGLE_STRIP)
size = (self.parent.objectsMaxV - self.parent.objectsMinV)
sizeXY = math.sqrt((size[0] * size[0]) + (size[1] * size[1]))
for i in xrange(0, 64+1):
f = i if i < 64/2 else 64 - i
glColor4ub(255,int(f*255/(64/2)),0,128)
glVertex3f(sizeXY * 0.7 * math.cos(i/32.0*math.pi), sizeXY * 0.7 * math.sin(i/32.0*math.pi),0.1)
glColor4ub( 0,128,0,128)
glVertex3f((sizeXY * 0.7 + 3) * math.cos(i/32.0*math.pi), (sizeXY * 0.7 + 3) * math.sin(i/32.0*math.pi),0.1)
glColor4ub(255,int(f*255/(64/2)),0,255)
glVertex3f(1.1 * math.cos(i/32.0*math.pi), 1.1 * math.sin(i/32.0*math.pi),0.1)
glColor4ub( 0,128,0,255)
glVertex3f(1.3 * math.cos(i/32.0*math.pi), 1.3 * math.sin(i/32.0*math.pi),0.1)
glEnd()
glBegin(GL_TRIANGLES)
glColor4ub(0,0,0,192)
glVertex3f(1, 0.1,0.15)
glVertex3f(1,-0.1,0.15)
glVertex3f(1.4,0,0.15)
glEnd()
glEnable(GL_CULL_FACE)
glPopMatrix()
opengl.DrawMachine(machineSize)
glFlush()

View File

@ -134,7 +134,7 @@ class printWindow(wx.Frame):
self.powerWarningText = wx.StaticText(parent=self.panel,
id=-1,
label="Connect your computer to AC power\nIf it shuts down during printing, the product will be lost.",
label="Your computer is running on battery power.\nConnect your computer to AC power or your print might not finish.",
style=wx.ALIGN_CENTER)
self.powerWarningText.SetBackgroundColour('red')
self.powerWarningText.SetForegroundColour('white')
@ -309,7 +309,7 @@ class printWindow(wx.Frame):
self.camPreview.timer.Start(500)
self.camPreview.Bind(wx.EVT_ERASE_BACKGROUND, self.OnCameraEraseBackground)
self.sizer.AddGrowableRow(5)
self.sizer.AddGrowableRow(6)
self.sizer.AddGrowableCol(3)
self.Bind(wx.EVT_CLOSE, self.OnClose)
@ -521,9 +521,11 @@ class printWindow(wx.Frame):
type = self.powerManagement.get_providing_power_source_type()
if type == power.POWER_TYPE_AC and self.powerWarningText.IsShown():
self.powerWarningText.Hide()
self.panel.Layout()
self.Layout()
elif type != power.POWER_TYPE_AC and not self.powerWarningText.IsShown():
self.powerWarningText.Show()
self.panel.Layout()
self.Layout()
def LoadGCodeFile(self, filename):
@ -579,10 +581,11 @@ class printWindow(wx.Frame):
def mcTempUpdate(self, temp, bedTemp, targetTemp, bedTargetTemp):
self.temperatureGraph.addPoint(temp, targetTemp, bedTemp, bedTargetTemp)
if self.temperatureSelect.GetValue() != targetTemp:
wx.CallAfter(self.temperatureSelect.SetValue, targetTemp)
if self.bedTemperatureSelect.GetValue() != bedTargetTemp:
wx.CallAfter(self.bedTemperatureSelect.SetValue, bedTargetTemp)
# ToFix, this causes problems with setting the temperature with the keyboard
# if self.temperatureSelect.GetValue() != targetTemp:
# wx.CallAfter(self.temperatureSelect.SetValue, targetTemp)
# if self.bedTemperatureSelect.GetValue() != bedTargetTemp:
# wx.CallAfter(self.bedTemperatureSelect.SetValue, bedTargetTemp)
def mcStateChange(self, state):
if self.machineCom != None:
@ -643,6 +646,7 @@ class temperatureGraph(wx.Panel):
dc = wx.MemoryDC()
dc.SelectObject(self.backBuffer)
dc.Clear()
dc.SetFont(wx.SystemSettings.GetFont(wx.SYS_SYSTEM_FONT))
w, h = self.GetSizeTuple()
bgLinePen = wx.Pen('#A0A0A0')
tempPen = wx.Pen('#FF4040')
@ -677,9 +681,12 @@ class temperatureGraph(wx.Panel):
for x in xrange(w, 0, -30):
dc.SetPen(bgLinePen)
dc.DrawLine(x, 0, x, h)
tmpNr = 0
for y in xrange(h - 1, 0, -h * 50 / 300):
dc.SetPen(bgLinePen)
dc.DrawLine(0, y, w, y)
dc.DrawText(str(tmpNr), 0, y - dc.GetFont().GetPixelSize().GetHeight())
tmpNr += 50
dc.DrawLine(0, 0, w, 0)
dc.DrawLine(0, 0, 0, h)

View File

@ -153,6 +153,7 @@ class projectPlanner(wx.Frame):
self.list = []
self.selection = None
self.printMode = 0
self.alwaysAutoPlace = True
self.machineSize = numpy.array([profile.getPreferenceFloat('machine_width'), profile.getPreferenceFloat('machine_depth'), profile.getPreferenceFloat('machine_height')])
self.headSizeMin = numpy.array([profile.getPreferenceFloat('extruder_head_size_min_x'), profile.getPreferenceFloat('extruder_head_size_min_y'),0])
@ -170,8 +171,8 @@ class projectPlanner(wx.Frame):
toolbarUtil.NormalButton(self.toolbar, self.OnSaveProject, 'save.png', 'Save project')
self.toolbar.AddSeparator()
group = []
toolbarUtil.RadioButton(self.toolbar, group, 'object-3d-on.png', 'object-3d-off.png', '3D view', callback=self.On3DClick)
toolbarUtil.RadioButton(self.toolbar, group, 'object-top-on.png', 'object-top-off.png', 'Topdown view', callback=self.OnTopClick).SetValue(True)
toolbarUtil.RadioButton(self.toolbar, group, 'object-3d-on.png', 'object-3d-off.png', '3D view', callback=self.On3DClick).SetValue(self.alwaysAutoPlace)
toolbarUtil.RadioButton(self.toolbar, group, 'object-top-on.png', 'object-top-off.png', 'Topdown view', callback=self.OnTopClick).SetValue(not self.alwaysAutoPlace)
self.toolbar.AddSeparator()
toolbarUtil.NormalButton(self.toolbar, self.OnPreferences, 'preferences.png', 'Project planner preferences')
self.toolbar.AddSeparator()
@ -196,7 +197,8 @@ class projectPlanner(wx.Frame):
toolbarUtil.NormalButton(self.toolbar2, self.OnCopy, 'copy.png', 'Make a copy of the current selected object')
toolbarUtil.NormalButton(self.toolbar2, self.OnSetCustomProfile, 'set-profile.png', 'Set a custom profile to be used to prepare a specific object.')
self.toolbar2.AddSeparator()
toolbarUtil.NormalButton(self.toolbar2, self.OnAutoPlace, 'autoplace.png', 'Automaticly organize the objects on the platform.')
if not self.alwaysAutoPlace:
toolbarUtil.NormalButton(self.toolbar2, self.OnAutoPlace, 'autoplace.png', 'Automaticly organize the objects on the platform.')
toolbarUtil.NormalButton(self.toolbar2, self.OnSlice, 'slice.png', 'Prepare to project into a gcode file.')
self.toolbar2.Realize()
@ -218,7 +220,8 @@ class projectPlanner(wx.Frame):
self.addButton = wx.Button(self.panel, -1, "Add")
self.remButton = wx.Button(self.panel, -1, "Remove")
self.sliceButton = wx.Button(self.panel, -1, "Prepare")
self.autoPlaceButton = wx.Button(self.panel, -1, "Auto Place")
if not self.alwaysAutoPlace:
self.autoPlaceButton = wx.Button(self.panel, -1, "Auto Place")
sizer.Add(self.toolbar, (0,0), span=(1,1), flag=wx.EXPAND|wx.LEFT|wx.RIGHT)
sizer.Add(self.toolbar2, (0,1), span=(1,2), flag=wx.EXPAND|wx.LEFT|wx.RIGHT)
@ -228,14 +231,16 @@ class projectPlanner(wx.Frame):
sizer.Add(self.addButton, (3,1), span=(1,1))
sizer.Add(self.remButton, (3,2), span=(1,1))
sizer.Add(self.sliceButton, (4,1), span=(1,1))
sizer.Add(self.autoPlaceButton, (4,2), span=(1,1))
if not self.alwaysAutoPlace:
sizer.Add(self.autoPlaceButton, (4,2), span=(1,1))
sizer.AddGrowableCol(0)
sizer.AddGrowableRow(1)
self.addButton.Bind(wx.EVT_BUTTON, self.OnAddModel)
self.remButton.Bind(wx.EVT_BUTTON, self.OnRemModel)
self.sliceButton.Bind(wx.EVT_BUTTON, self.OnSlice)
self.autoPlaceButton.Bind(wx.EVT_BUTTON, self.OnAutoPlace)
if not self.alwaysAutoPlace:
self.autoPlaceButton.Bind(wx.EVT_BUTTON, self.OnAutoPlace)
self.listbox.Bind(wx.EVT_LISTBOX, self.OnListSelect)
panel = wx.Panel(self.panel, -1)
@ -309,6 +314,8 @@ class projectPlanner(wx.Frame):
self.printMode = 0
if self.printAllAtOnce.GetValue():
self.printMode = 1
if self.alwaysAutoPlace:
self.OnAutoPlace(None)
self.preview.Refresh()
def OnSaveCombinedSTL(self, e):
@ -508,6 +515,8 @@ class projectPlanner(wx.Frame):
else:
self.selection = None
self.listbox.SetSelection(-1)
if self.alwaysAutoPlace:
self.OnAutoPlace(None)
def OnAutoPlace(self, e):
bestAllowedSize = int(self.machineSize[1])
@ -587,8 +596,8 @@ class projectPlanner(wx.Frame):
for item in self.list:
if item.profile != None and os.path.isfile(item.profile):
profile.loadGlobalProfile(item.profile)
put('machine_center_x', item.centerX - self.extruderOffset[item.extruder][0])
put('machine_center_y', item.centerY - self.extruderOffset[item.extruder][1])
put('object_center_x', item.centerX - self.extruderOffset[item.extruder][0])
put('object_center_y', item.centerY - self.extruderOffset[item.extruder][1])
put('model_scale', item.scale)
put('flip_x', item.flipX)
put('flip_y', item.flipY)
@ -630,8 +639,8 @@ class projectPlanner(wx.Frame):
action = Action()
action.sliceCmd = sliceRun.getSliceCommand(resultFilename + "_temp_.stl")
action.centerX = profile.getProfileSettingFloat('machine_center_x')
action.centerY = profile.getProfileSettingFloat('machine_center_y')
action.centerX = profile.getPreferenceFloat('machine_width') / 2
action.centerY = profile.getPreferenceFloat('machine_depth') / 2
action.temperature = profile.getProfileSettingFloat('print_temperature')
action.extruder = 0
action.filename = resultFilename + "_temp_.stl"
@ -663,6 +672,8 @@ class projectPlanner(wx.Frame):
return
self.selection.rotate = float(self.rotateCtrl.GetValue())
self.selection.updateModelTransform()
if self.alwaysAutoPlace:
self.OnAutoPlace(None)
self.preview.Refresh()
def OnExtruderChange(self, e):
@ -680,6 +691,8 @@ class projectPlanner(wx.Frame):
self.selection.swapXZ = self.swapXZ.GetValue()
self.selection.swapYZ = self.swapYZ.GetValue()
self.selection.updateModelTransform()
if self.alwaysAutoPlace:
self.OnAutoPlace(None)
self.preview.Refresh()
def getExtraHeadSize(self):
@ -717,17 +730,25 @@ class PreviewGLCanvas(glcanvas.GLCanvas):
wx.EVT_MOUSEWHEEL(self, self.OnMouseWheel)
self.yaw = 30
self.pitch = 60
self.zoom = self.parent.machineSize[0] / 2 + 10
self.offsetX = 0
self.offsetY = 0
self.view3D = False
self.view3D = self.parent.alwaysAutoPlace
if self.view3D:
self.zoom = 300
else:
self.zoom = self.parent.machineSize[0] / 2 + 10
self.allowDrag = False
self.objColor = profile.getPreferenceColour('model_colour')
def OnMouseLeftDown(self,e):
self.allowDrag = True
if not self.parent.alwaysAutoPlace and not self.view3D:
#TODO: Translate mouse X/Y to 3D X/Y/Z
for item in self.parent.list:
iMin = (item.getMinimum() * item.scale) + numpy.array([item.centerX, item.centerY, 0]) - self.parent.extruderOffset[item.extruder]
iMax = (item.getMaximum() * item.scale) + numpy.array([item.centerX, item.centerY, 0]) - self.parent.extruderOffset[item.extruder]
def OnMouseMotion(self,e):
if self.allowDrag and e.Dragging() and e.LeftIsDown():
if self.view3D:
@ -737,7 +758,7 @@ class PreviewGLCanvas(glcanvas.GLCanvas):
self.pitch = 170
if self.pitch < 10:
self.pitch = 10
else:
elif not self.parent.alwaysAutoPlace:
item = self.parent.selection
if item != None:
item.centerX += float(e.GetX() - self.oldX) * self.zoom / self.GetSize().GetHeight() * 2
@ -851,29 +872,30 @@ class PreviewGLCanvas(glcanvas.GLCanvas):
glDisable(GL_LIGHTING)
if self.parent.selection == item:
if item.gotHit:
glColor3f(1.0,0.0,0.3)
if not self.parent.alwaysAutoPlace:
if self.parent.selection == item:
if item.gotHit:
glColor3f(1.0,0.0,0.3)
else:
glColor3f(1.0,0.0,1.0)
opengl.DrawBox(vMin, vMax)
if item.gotHit:
glColor3f(1.0,0.3,0.0)
else:
glColor3f(1.0,1.0,0.0)
opengl.DrawBox(vMinHead, vMaxHead)
elif seenSelected:
if item.gotHit:
glColor3f(0.5,0.0,0.1)
else:
glColor3f(0.5,0.0,0.5)
opengl.DrawBox(vMinHead, vMaxHead)
else:
glColor3f(1.0,0.0,1.0)
opengl.DrawBox(vMin, vMax)
if item.gotHit:
glColor3f(1.0,0.3,0.0)
else:
glColor3f(1.0,1.0,0.0)
opengl.DrawBox(vMinHead, vMaxHead)
elif seenSelected:
if item.gotHit:
glColor3f(0.5,0.0,0.1)
else:
glColor3f(0.5,0.0,0.5)
opengl.DrawBox(vMinHead, vMaxHead)
else:
if item.gotHit:
glColor3f(0.7,0.1,0.0)
else:
glColor3f(0.7,0.7,0.0)
opengl.DrawBox(vMin, vMax)
if item.gotHit:
glColor3f(0.7,0.1,0.0)
else:
glColor3f(0.7,0.7,0.0)
opengl.DrawBox(vMin, vMax)
glPopMatrix()
@ -964,8 +986,8 @@ class ProjectSliceProgressWindow(wx.Frame):
line = p.stdout.readline()
self.returnCode = p.wait()
put('machine_center_x', action.centerX - self.extruderOffset[action.extruder][0])
put('machine_center_y', action.centerY - self.extruderOffset[action.extruder][1])
put('object_center_x', action.centerX - self.extruderOffset[action.extruder][0])
put('object_center_y', action.centerY - self.extruderOffset[action.extruder][1])
put('clear_z', action.clearZ)
put('extruder', action.extruder)
put('print_temperature', action.temperature)

View File

@ -110,7 +110,7 @@ class simpleModeWindow(configBase.configWindowBase):
sizer.Add(boxsizer, (2,0), flag=wx.EXPAND)
# load and slice buttons.
loadButton = wx.Button(self, -1, '&Load Model')
loadButton = wx.Button(self, -1, '&Load model')
sliceButton = wx.Button(self, -1, 'P&repare print')
printButton = wx.Button(self, -1, '&Print')
self.Bind(wx.EVT_BUTTON, self.OnLoadModel, loadButton)
@ -187,8 +187,6 @@ class simpleModeWindow(configBase.configWindowBase):
put('print_speed', '50')
put('print_temperature', '220')
put('support', 'None')
#put('machine_center_x', '100')
#put('machine_center_y', '100')
put('retraction_enable', 'False')
put('retraction_min_travel', '5.0')
put('retraction_speed', '40.0')

View File

@ -46,8 +46,8 @@ class sliceProgessPanel(wx.Panel):
if idx > 0:
profile.setTempOverride('fan_enabled', 'False')
profile.setTempOverride('skirt_line_count', '0')
profile.setTempOverride('machine_center_x', profile.getProfileSettingFloat('machine_center_x') - profile.getPreferenceFloat('extruder_offset_x%d' % (idx)))
profile.setTempOverride('machine_center_y', profile.getProfileSettingFloat('machine_center_y') - profile.getPreferenceFloat('extruder_offset_y%d' % (idx)))
profile.setTempOverride('object_center_x', profile.getPreferenceFloat('machine_width') / 2 - profile.getPreferenceFloat('extruder_offset_x%d' % (idx)))
profile.setTempOverride('object_center_y', profile.getPreferenceFloat('machine_depth') / 2 - profile.getPreferenceFloat('extruder_offset_y%d' % (idx)))
profile.setTempOverride('alternative_center', self.filelist[0])
if len(self.filelist) > 1:
profile.setTempOverride('add_start_end_gcode', 'False')
@ -183,6 +183,11 @@ class WorkerThread(threading.Thread):
wx.CallAfter(self.notifyWindow.statusText.SetLabel, "Aborted by user.")
return
line = p.stdout.readline()
line = p.stderr.readline()
while(len(line) > 0):
line = line.rstrip()
self.progressLog.append(line)
line = p.stderr.readline()
self.returnCode = p.wait()
self.fileIdx += 1
if self.fileIdx == len(self.cmdList):
@ -220,9 +225,11 @@ class WorkerThread(threading.Thread):
resultFile.write('T%d\n' % (currentExtruder))
layerNr = -1
hasLine = True
filesOrder = files[:]
while hasLine:
hasLine = False
for f in files:
filesOrder.reverse()
for f in filesOrder:
layerHasLine = False
for line in f:
hasLine = True
@ -237,7 +244,7 @@ class WorkerThread(threading.Thread):
if nextExtruder != currentExtruder:
resultFile.write(';TYPE:CUSTOM\n')
profile.setTempOverride('extruder', nextExtruder)
resultFile.write(profile.getAlterationFileContents('switchExtruder.gcode'))
resultFile.write(profile.getAlterationFileContents('switchExtruder.gcode') + '\n')
profile.resetTempOverride()
currentExtruder = nextExtruder
layerHasLine = True

Binary file not shown.

After

Width:  |  Height:  |  Size: 372 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 313 B

View File

@ -27,6 +27,9 @@ class daeModel(mesh.mesh):
for instance_visual_scene in self._base['collada'][0]['scene'][0]['instance_visual_scene']:
for node in self._idMap[instance_visual_scene['_url']]['node']:
self._ProcessNode2(node)
scale = float(self._base['collada'][0]['asset'][0]['unit'][0]['_meter']) * 1000
self.origonalVertexes *= scale
self._base = None
self._cur = None

View File

@ -21,3 +21,14 @@ def openExporer(filename):
elif os.path.isfile('/usr/bin/dolphin'):
subprocess.Popen(['/usr/bin/dolphin', os.path.split(filename)[0]])
def openExporerPath(filename):
if sys.platform == 'win32' or sys.platform == 'cygwin':
subprocess.Popen(r'explorer "%s"' % (filename))
if sys.platform == 'darwin':
subprocess.Popen(['open', filename])
if sys.platform.startswith('linux'):
if os.path.isfile('/usr/bin/nautilus'):
subprocess.Popen(['/usr/bin/nautilus', filename])
elif os.path.isfile('/usr/bin/dolphin'):
subprocess.Popen(['/usr/bin/dolphin', filename])

View File

@ -207,6 +207,9 @@ class MachineCom(object):
if len(self._errorValue) < 20:
return self._errorValue
return self._errorValue[:20] + "..."
def getErrorString(self):
return self._errorValue
def isClosedOrError(self):
return self._state == self.STATE_ERROR or self._state == self.STATE_CLOSED_WITH_ERROR or self._state == self.STATE_CLOSED

View File

@ -41,6 +41,7 @@ class mesh(object):
return self.size
def setRotateMirror(self, rotate, mirrorX, mirrorY, mirrorZ, swapXZ, swapYZ):
#Modify the vertexes with the rotation/mirror
rotate = rotate / 180.0 * math.pi
scaleX = 1.0
scaleY = 1.0
@ -62,7 +63,14 @@ class mesh(object):
if swapYZ:
mat = numpy.array([mat[0],mat[2],mat[1]], numpy.float32)
self.vertexes = (numpy.matrix(self.origonalVertexes, copy = False) * numpy.matrix(mat)).getA()
#Calculate the boundery box of the object
self.getMinimumZ()
#Calculate the boundery circle
center = (self.max + self.min) / 2.0
self.bounderyCircleSize = round(math.sqrt(numpy.max(((self.vertexes[::,0] - center[0]) * (self.vertexes[::,0] - center[0])) + ((self.vertexes[::,1] - center[1]) * (self.vertexes[::,1] - center[1])))), 3)
#Calculate the normals
tris = self.vertexes.reshape(self.vertexCount / 3, 3, 3)
normals = numpy.cross( tris[::,1 ] - tris[::,0] , tris[::,2 ] - tris[::,0] )
lens = numpy.sqrt( normals[:,0]**2 + normals[:,1]**2 + normals[:,2]**2 )
@ -76,8 +84,6 @@ class mesh(object):
n[:,6:9] = normals
self.normal = n.reshape(self.vertexCount, 3)
self.invNormal = -self.normal
self.getMinimumZ()
def splitToParts(self, callback = None):
t0 = time.time()

View File

@ -31,8 +31,6 @@ profileDefaultSettings = {
'support': 'None',
'filament_diameter': '2.89',
'filament_density': '1.00',
'machine_center_x': '100',
'machine_center_y': '100',
'retraction_min_travel': '5.0',
'retraction_enable': 'False',
'retraction_speed': '40.0',
@ -42,7 +40,7 @@ profileDefaultSettings = {
'travel_speed': '150',
'max_z_speed': '3.0',
'bottom_layer_speed': '20',
'cool_min_layer_time': '10',
'cool_min_layer_time': '5',
'fan_enabled': 'True',
'fan_layer': '1',
'fan_speed': '100',
@ -74,6 +72,7 @@ profileDefaultSettings = {
'raft_base_material_amount': '100',
'raft_interface_material_amount': '100',
'bottom_thickness': '0.3',
'hop_on_move': 'False',
'plugin_config': '',
'add_start_end_gcode': 'True',
@ -102,9 +101,6 @@ G1 Z15.0 F{max_z_speed} ;move the platform down 15mm
G92 E0 ;zero the extruded length
G1 F200 E3 ;extrude 3mm of feed stock
G92 E0 ;zero the extruded length again
;go to the middle of the platform (disabled, as there is no need to go to the center)
;G1 X{machine_center_x} Y{machine_center_y} F{travel_speed}
G1 F{travel_speed}
""",
#######################################################################################
@ -137,7 +133,7 @@ G90 ;absolute positioning
G1 Z{clear_z} F{max_z_speed}
G92 E0
G1 X{machine_center_x} Y{machine_center_y} F{travel_speed}
G1 X{object_center_x} Y{object_center_x} F{travel_speed}
G1 F200 E6
G92 E0
""",
@ -158,6 +154,7 @@ preferencesDefaultSettings = {
'machine_depth': '205',
'machine_height': '200',
'machine_type': 'unknown',
'ultimaker_extruder_upgrade': 'False',
'has_heated_bed': 'False',
'extruder_amount': '1',
'extruder_offset_x1': '-22.0',
@ -219,6 +216,13 @@ def resetGlobalProfile():
global globalProfileParser
globalProfileParser = ConfigParser.ConfigParser()
if getPreference('machine_type') == 'ultimaker':
putProfileSetting('nozzle_size', '0.4')
if getPreference('ultimaker_extruder_upgrade') == 'True':
putProfileSetting('retraction_enable', 'True')
else:
putProfileSetting('nozzle_size', '0.5')
def saveGlobalProfile(filename):
#Save the current profile to an ini file
globalProfileParser.write(open(filename, 'w'))
@ -545,9 +549,10 @@ def setPluginConfig(config):
putProfileSetting('plugin_config', pickle.dumps(config))
def getPluginBasePaths():
ret = [os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'plugins'))]
ret = []
if platform.system() != "Windows":
ret.append(os.path.expanduser('~/.cura/plugins/'))
ret.append(os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'plugins')))
return ret
def getPluginList():

View File

@ -26,6 +26,7 @@ sliceStepTimeFactor = {
'dwindle': 1.0,
'comb': 23.7805759907,
'cool': 27.148763895,
'hop': 1.0,
'dimension': 90.4914340973
}
@ -114,7 +115,7 @@ def getSliceCommand(filename):
cmd = [slic3rExe,
'--output-filename-format', '[input_filename_base].gcode',
'--nozzle-diameter', str(profile.calculateEdgeWidth()),
'--print-center', '%s,%s' % (profile.getProfileSetting('machine_center_x'), profile.getProfileSetting('machine_center_y')),
'--print-center', '%s,%s' % (profile.getPreferenceFloat('machine_width') / 2, profile.getPreferenceFloat('machine_depth') / 2),
'--z-offset', '0',
'--gcode-flavor', 'reprap',
'--gcode-comments',

View File

@ -215,7 +215,7 @@ if __name__ == '__main__':
f.write(';TYPE:CUSTOM\n')
f.write(profile.getAlterationFileContents('start.gcode'))
svg.center(complex(profile.getProfileSettingFloat('machine_center_x'), profile.getProfileSettingFloat('machine_center_y')))
svg.center(complex(profile.getPreferenceFloat('machine_width') / 2, profile.getPreferenceFloat('machine_depth') / 2))
layerThickness = 0.4
filamentRadius = profile.getProfileSettingFloat('filament_diameter') / 2