mirror of
https://git.mirrors.martin98.com/https://github.com/Ultimaker/Cura
synced 2025-08-05 16:10:37 +08:00
Merge commit 'd0691018c211d1dbd500c0b3d363da8c5bd2f11d'
This commit is contained in:
commit
53aa2efd71
@ -64,6 +64,27 @@ def calculateMultiplyDistance(setting):
|
||||
edgeWidth = calculateEdgeWidth(setting)
|
||||
return 10.0 / edgeWidth
|
||||
|
||||
def calcBottomLayerFlowRateRatio(setting):
|
||||
bottomThickness = float(profile.getProfileSetting('bottom_thickness'))
|
||||
layerThickness = float(profile.getProfileSetting('layer_height'))
|
||||
if bottomThickness < layerThickness:
|
||||
return 1.0
|
||||
return bottomThickness / layerThickness
|
||||
|
||||
def calcExtraBottomThickness(setting):
|
||||
bottomThickness = float(profile.getProfileSetting('bottom_thickness'))
|
||||
layerThickness = float(profile.getProfileSetting('layer_height'))
|
||||
if bottomThickness < layerThickness:
|
||||
return 0.0
|
||||
return bottomThickness - layerThickness
|
||||
|
||||
def calcLayerSkip(setting):
|
||||
bottomThickness = float(profile.getProfileSetting('bottom_thickness'))
|
||||
layerThickness = float(profile.getProfileSetting('layer_height'))
|
||||
if bottomThickness < layerThickness:
|
||||
return 0
|
||||
return int(math.ceil((bottomThickness - layerThickness) / layerThickness + 0.0001) - 1)
|
||||
|
||||
def getProfileInformation():
|
||||
return {
|
||||
'carve': {
|
||||
@ -72,7 +93,7 @@ def getProfileInformation():
|
||||
'Extra_Decimal_Places_float': DEFSET,
|
||||
'Import_Coarseness_ratio': DEFSET,
|
||||
'Layer_Height_mm': storedSetting("layer_height"),
|
||||
'Layers_From_index': DEFSET,
|
||||
'Layers_From_index': calcLayerSkip,
|
||||
'Layers_To_index': DEFSET,
|
||||
'Correct_Mesh': DEFSET,
|
||||
'Unproven_Mesh': DEFSET,
|
||||
@ -80,6 +101,8 @@ def getProfileInformation():
|
||||
'FlipX': storedSetting("flip_x"),
|
||||
'FlipY': storedSetting("flip_y"),
|
||||
'FlipZ': storedSetting("flip_z"),
|
||||
'SwapXZ': storedSetting("swap_xz"),
|
||||
'SwapYZ': storedSetting("swap_yz"),
|
||||
'Scale': storedSetting("model_scale"),
|
||||
'Rotate': storedSetting("model_rotate_base"),
|
||||
},'scale': {
|
||||
@ -90,7 +113,7 @@ def getProfileInformation():
|
||||
},'bottom': {
|
||||
'Activate_Bottom': DEFSET,
|
||||
'Additional_Height_over_Layer_Thickness_ratio': DEFSET,
|
||||
'Altitude_mm': DEFSET,
|
||||
'Altitude_mm': calcExtraBottomThickness,
|
||||
'SVG_Viewer': DEFSET,
|
||||
},'preface': {
|
||||
'Meta': DEFSET,
|
||||
@ -167,6 +190,7 @@ def getProfileInformation():
|
||||
'Perimeter_Feed_Rate_Multiplier_ratio': DEFSET,
|
||||
'Perimeter_Flow_Rate_Multiplier_ratio': DEFSET,
|
||||
'Travel_Feed_Rate_mm/s': storedSetting("travel_speed"),
|
||||
'Bottom_layer_flow_rate_ratio': calcBottomLayerFlowRateRatio,
|
||||
},'temperature': {
|
||||
'Activate_Temperature': DEFSET,#ifSettingAboveZero('print_temperature'),
|
||||
'Cooling_Rate_Celcius/second': DEFSET,
|
||||
@ -246,12 +270,12 @@ def getProfileInformation():
|
||||
'Perimeter_Outside_Stretch_Over_Perimeter_Width_ratio': DEFSET,
|
||||
'Stretch_From_Distance_Over_Perimeter_Width_ratio': DEFSET,
|
||||
},'skin': {
|
||||
'Activate_Skin': "False",
|
||||
'Horizontal_Infill_Divisions_integer': DEFSET,
|
||||
'Horizontal_Perimeter_Divisions_integer': DEFSET,
|
||||
'Vertical_Divisions_integer': DEFSET,
|
||||
'Hop_When_Extruding_Infill': DEFSET,
|
||||
'Layers_From_index': DEFSET,
|
||||
'Activate_Skin': storedSetting("enable_skin"),
|
||||
'Horizontal_Infill_Divisions_integer': "1",
|
||||
'Horizontal_Perimeter_Divisions_integer': "1",
|
||||
'Vertical_Divisions_integer': "2",
|
||||
'Hop_When_Extruding_Infill': "False",
|
||||
'Layers_From_index': "1",
|
||||
},'comb': {
|
||||
'Activate_Comb': "True",
|
||||
'Running_Jump_Space_mm': DEFSET,
|
||||
|
@ -183,6 +183,8 @@ class CarveRepository:
|
||||
self.flipX = settings.BooleanSetting().getFromValue('FlipX', self, False)
|
||||
self.flipY = settings.BooleanSetting().getFromValue('FlipY', self, False)
|
||||
self.flipZ = settings.BooleanSetting().getFromValue('FlipZ', self, False)
|
||||
self.swapXZ = settings.BooleanSetting().getFromValue('SwapXZ', self, False)
|
||||
self.swapYZ = settings.BooleanSetting().getFromValue('SwapYZ', self, False)
|
||||
self.scale = settings.FloatSpin().getFromValue( 0.1, 'Scale', self, 10.0, 1.0 )
|
||||
self.rotate = settings.FloatSpin().getFromValue( -180.0, 'Rotate', self, 180.0, 0.0 )
|
||||
|
||||
@ -210,6 +212,8 @@ class CarveSkein:
|
||||
scaleY = -scaleY
|
||||
if repository.flipZ.value == True:
|
||||
scaleZ = -scaleZ
|
||||
swapXZ = repository.swapXZ.value
|
||||
swapYZ = repository.swapYZ.value
|
||||
mat00 = math.cos(rotate) * scaleX
|
||||
mat01 =-math.sin(rotate) * scaleY
|
||||
mat10 = math.sin(rotate) * scaleX
|
||||
@ -226,10 +230,17 @@ class CarveSkein:
|
||||
#v.y += self.machineCenter.y
|
||||
|
||||
for i in xrange(0, len(carving.vertexes)):
|
||||
x = carving.vertexes[i].x
|
||||
y = carving.vertexes[i].y
|
||||
z = carving.vertexes[i].z
|
||||
if swapXZ:
|
||||
x, z = z, x
|
||||
if swapYZ:
|
||||
y, z = z, y
|
||||
carving.vertexes[i] = Vector3(
|
||||
carving.vertexes[i].x * mat00 + carving.vertexes[i].y * mat01,
|
||||
carving.vertexes[i].x * mat10 + carving.vertexes[i].y * mat11,
|
||||
carving.vertexes[i].z * scaleZ)
|
||||
x * mat00 + y * mat01,
|
||||
x * mat10 + y * mat11,
|
||||
z * scaleZ)
|
||||
|
||||
layerHeight = repository.layerHeight.value
|
||||
edgeWidth = repository.edgeWidth.value
|
||||
|
@ -210,6 +210,8 @@ class SpeedRepository:
|
||||
settings.LabelSeparator().getFromRepository(self)
|
||||
self.travelFeedRatePerSecond = settings.FloatSpin().getFromValue( 2.0, 'Travel Feed Rate (mm/s):', self, 350.0, 250.0 )
|
||||
self.executeTitle = 'Speed'
|
||||
|
||||
self.bottomLayerFlowRateMultiplier = settings.FloatSpin().getFromValue(0.0, 'Bottom layer flow rate (ratio):', self, 10.0, 1.0)
|
||||
|
||||
def execute(self):
|
||||
"Speed button has been clicked."
|
||||
@ -246,6 +248,8 @@ class SpeedSkein:
|
||||
flowRate *= ((self.repository.objectFirstLayerFlowRatePerimeterMultiplier.value * (self.repository.objectFirstLayersLayerAmount.value - self.layerIndex)) + self.layerIndex) / self.repository.objectFirstLayersLayerAmount.value
|
||||
else:
|
||||
flowRate *= ((self.repository.objectFirstLayerFlowRateInfillMultiplier.value * (self.repository.objectFirstLayersLayerAmount.value - self.layerIndex)) + self.layerIndex) / self.repository.objectFirstLayersLayerAmount.value
|
||||
if self.layerIndex == 0:
|
||||
flowRate *= self.repository.bottomLayerFlowRateMultiplier.value
|
||||
if flowRate != self.oldFlowRate:
|
||||
self.distanceFeedRate.addLine('M108 S' + euclidean.getFourSignificantFigures(flowRate))
|
||||
self.oldFlowRate = flowRate
|
||||
|
@ -10,10 +10,10 @@ from gui import sliceProgessPanel
|
||||
from gui import alterationPanel
|
||||
from gui import validators
|
||||
|
||||
class advancedConfigWindow(configBase.configWindowBase):
|
||||
"Advanced configuration window"
|
||||
class expertConfigWindow(configBase.configWindowBase):
|
||||
"Expert configuration window"
|
||||
def __init__(self):
|
||||
super(advancedConfigWindow, self).__init__(title='Expert config')
|
||||
super(expertConfigWindow, self).__init__(title='Expert config')
|
||||
|
||||
wx.EVT_CLOSE(self, self.OnClose)
|
||||
|
@ -106,18 +106,33 @@ class InstallFirmware(wx.Dialog):
|
||||
class VirtualPrinter():
|
||||
def __init__(self):
|
||||
self.readList = ['start\n']
|
||||
self.temp = 0.0
|
||||
self.targetTemp = 0.0
|
||||
|
||||
def write(self, data):
|
||||
if self.readList == None:
|
||||
return
|
||||
print "Send: %s" % (data.rstrip())
|
||||
self.readList.append("ok\n")
|
||||
if 'M104' in data:
|
||||
try:
|
||||
self.targetTemp = float(data[data.find('S')+1:])
|
||||
except:
|
||||
pass
|
||||
if 'M105' in data:
|
||||
self.readList.append("ok T:%f/%f\n" % (self.temp, self.targetTemp))
|
||||
else:
|
||||
self.readList.append("ok\n")
|
||||
|
||||
def readline(self):
|
||||
if self.readList == None:
|
||||
return ''
|
||||
n = 0
|
||||
self.temp = (self.temp + self.targetTemp) / 2
|
||||
while len(self.readList) < 1:
|
||||
time.sleep(0.1)
|
||||
n += 1
|
||||
if n == 20:
|
||||
return ''
|
||||
if self.readList == None:
|
||||
return ''
|
||||
time.sleep(0.001)
|
||||
@ -141,7 +156,7 @@ class MachineCom():
|
||||
programmer.connect(port)
|
||||
programmer.close()
|
||||
print "Connecting to: %s %i" % (port, baudrate)
|
||||
self.serial = Serial(port, baudrate, timeout=5)
|
||||
self.serial = Serial(port, baudrate, timeout=2)
|
||||
break
|
||||
except ispBase.IspError:
|
||||
pass
|
||||
@ -152,7 +167,7 @@ class MachineCom():
|
||||
self.serial = VirtualPrinter()
|
||||
else:
|
||||
try:
|
||||
self.serial = Serial(port, baudrate, timeout=5)
|
||||
self.serial = Serial(port, baudrate, timeout=2)
|
||||
except:
|
||||
print "Unexpected error while connecting to serial port:" + port, sys.exc_info()[0]
|
||||
|
||||
|
@ -4,7 +4,7 @@ import __init__
|
||||
import wx, os, platform, types, webbrowser
|
||||
|
||||
from gui import configBase
|
||||
from gui import advancedConfig
|
||||
from gui import expertConfig
|
||||
from gui import preview3d
|
||||
from gui import sliceProgessPanel
|
||||
from gui import alterationPanel
|
||||
@ -96,7 +96,7 @@ class mainWindow(configBase.configWindowBase):
|
||||
configBase.TitleRow(left, "Accuracy")
|
||||
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.0)
|
||||
validators.warningAbove(c, lambda : (float(profile.getProfileSetting('nozzle_size')) * 80 / 100), "Thicker layers then %.2fmm (80%% nozzle size) usually give bad results and are not recommended.")
|
||||
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.")
|
||||
c = configBase.SettingRow(left, "Wall thickness (mm)", 'wall_thickness', '0.8', 'Thickness of the walls.\nThis is used in combination with the nozzle size to define the number\nof perimeter lines and the thickness of those perimeter lines.')
|
||||
validators.validFloat(c, 0.0)
|
||||
validators.wallThicknessValidator(c)
|
||||
@ -126,7 +126,7 @@ class mainWindow(configBase.configWindowBase):
|
||||
|
||||
configBase.TitleRow(right, "Support")
|
||||
c = configBase.SettingRow(right, "Support type", 'support', ['None', 'Exterior Only', 'Everywhere', 'Empty Layers Only'], 'Type of support structure build.\nNone does not do any support.\nExterior only only creates support on the outside.\nEverywhere creates support even on the insides of the model.\nOnly on empty layers is for stacked objects.')
|
||||
c = configBase.SettingRow(right, "Add raft", 'enable_raft', False, 'A raft is a few layers of lines below the bottom of the object. It prevents warping. Full raft settings can be found in the advanced settings.\nFor PLA this is usually not required. But if you print with ABS it is almost required.')
|
||||
c = configBase.SettingRow(right, "Add raft", 'enable_raft', False, 'A raft is a few layers of lines below the bottom of the object. It prevents warping. Full raft settings can be found in the expert settings.\nFor PLA this is usually not required. But if you print with ABS it is almost required.')
|
||||
|
||||
configBase.TitleRow(right, "Filament")
|
||||
c = configBase.SettingRow(right, "Diameter (mm)", 'filament_diameter', '2.89', 'Diameter of your filament, as accurately as possible.\nIf you cannot measure this value you will have to callibrate it, a higher number means less extrusion, a smaller number generates more extrusion.')
|
||||
@ -171,6 +171,12 @@ 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")
|
||||
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.')
|
||||
|
||||
nb.AddPage(alterationPanel.alterationPanel(nb), "Start/End-GCode")
|
||||
|
||||
# load and slice buttons.
|
||||
@ -287,9 +293,9 @@ class mainWindow(configBase.configWindowBase):
|
||||
printWindow.printFile(self.filename[: self.filename.rfind('.')] + "_export.gcode")
|
||||
|
||||
def OnExpertOpen(self, e):
|
||||
acw = advancedConfig.advancedConfigWindow()
|
||||
acw.Centre()
|
||||
acw.Show(True)
|
||||
ecw = expertConfig.expertConfigWindow()
|
||||
ecw.Centre()
|
||||
ecw.Show(True)
|
||||
|
||||
def removeSliceProgress(self, spp):
|
||||
self.progressPanelList.remove(spp)
|
||||
|
94
Cura/gui/opengl.py
Normal file
94
Cura/gui/opengl.py
Normal file
@ -0,0 +1,94 @@
|
||||
|
||||
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, [1.0, 1.0, 1.0, 0.0])
|
||||
|
||||
glEnable(GL_LIGHTING)
|
||||
glEnable(GL_LIGHT0)
|
||||
glEnable(GL_DEPTH_TEST)
|
||||
glEnable(GL_CULL_FACE)
|
||||
glDisable(GL_BLEND)
|
||||
|
||||
glClearColor(0.0, 0.0, 0.0, 1.0)
|
||||
glClearStencil(0)
|
||||
glClearDepth(1.0)
|
||||
|
||||
glMatrixMode(GL_PROJECTION)
|
||||
glLoadIdentity()
|
||||
aspect = float(size.GetWidth()) / float(size.GetHeight())
|
||||
if view3D:
|
||||
gluPerspective(90.0, aspect, 1.0, 1000.0)
|
||||
else:
|
||||
glOrtho(-aspect, aspect, -1, 1, -1000.0, 1000.0)
|
||||
|
||||
glMatrixMode(GL_MODELVIEW)
|
||||
glLoadIdentity()
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)
|
||||
|
||||
def DrawMachine(machineSize):
|
||||
glColor3f(1,1,1)
|
||||
glLineWidth(4)
|
||||
glDisable(GL_LIGHTING)
|
||||
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_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()
|
||||
glLineWidth(1)
|
||||
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()
|
||||
|
||||
def DrawSTL(mesh):
|
||||
for face in mesh.faces:
|
||||
glBegin(GL_TRIANGLES)
|
||||
v1 = face.v[0]
|
||||
v2 = face.v[1]
|
||||
v3 = face.v[2]
|
||||
glNormal3f(face.normal.x, face.normal.y, face.normal.z)
|
||||
glVertex3f(v1.x, v1.y, v1.z)
|
||||
glVertex3f(v2.x, v2.y, v2.z)
|
||||
glVertex3f(v3.x, v3.y, v3.z)
|
||||
glNormal3f(-face.normal.x, -face.normal.y, -face.normal.z)
|
||||
glVertex3f(v1.x, v1.y, v1.z)
|
||||
glVertex3f(v3.x, v3.y, v3.z)
|
||||
glVertex3f(v2.x, v2.y, v2.z)
|
||||
glEnd()
|
@ -17,6 +17,8 @@ except:
|
||||
print "Failed to find PyOpenGL: http://pyopengl.sourceforge.net/"
|
||||
hasOpenGLlibs = False
|
||||
|
||||
from gui import opengl
|
||||
|
||||
from util import profile
|
||||
from util import gcodeInterpreter
|
||||
from util import stl
|
||||
@ -75,6 +77,16 @@ class previewPanel(wx.Panel):
|
||||
self.flipZ.SetValue(profile.getProfileSetting('flip_z') == 'True')
|
||||
self.toolbar2.AddControl(self.flipZ)
|
||||
self.Bind(wx.EVT_CHECKBOX, self.OnFlipZClick, self.flipZ)
|
||||
|
||||
self.swapXZ = wx.CheckBox(self.toolbar2, -1, "XZ")
|
||||
self.swapXZ.SetValue(profile.getProfileSetting('swap_xz') == 'True')
|
||||
self.toolbar2.AddControl(self.swapXZ)
|
||||
self.Bind(wx.EVT_CHECKBOX, self.OnSwapXZClick, self.swapXZ)
|
||||
|
||||
self.swapYZ = wx.CheckBox(self.toolbar2, -1, "YZ")
|
||||
self.swapYZ.SetValue(profile.getProfileSetting('swap_yz') == 'True')
|
||||
self.toolbar2.AddControl(self.swapYZ)
|
||||
self.Bind(wx.EVT_CHECKBOX, self.OnSwapYZClick, self.swapYZ)
|
||||
|
||||
self.toolbar2.InsertSeparator(self.toolbar2.GetToolsCount())
|
||||
self.toolbar2.AddControl(wx.StaticText(self.toolbar2, -1, 'Scale'))
|
||||
@ -126,6 +138,14 @@ class previewPanel(wx.Panel):
|
||||
profile.putProfileSetting('flip_z', str(self.flipZ.GetValue()))
|
||||
self.updateModelTransform()
|
||||
|
||||
def OnSwapXZClick(self, e):
|
||||
profile.putProfileSetting('swap_xz', str(self.swapXZ.GetValue()))
|
||||
self.updateModelTransform()
|
||||
|
||||
def OnSwapYZClick(self, e):
|
||||
profile.putProfileSetting('swap_yz', str(self.swapYZ.GetValue()))
|
||||
self.updateModelTransform()
|
||||
|
||||
def OnMulXAddClick(self, e):
|
||||
profile.putProfileSetting('model_multiply_x', str(max(1, int(profile.getProfileSetting('model_multiply_x'))+1)))
|
||||
self.updateModelTransform()
|
||||
@ -285,15 +305,24 @@ class previewPanel(wx.Panel):
|
||||
scaleY = -scaleY
|
||||
if profile.getProfileSetting('flip_z') == 'True':
|
||||
scaleZ = -scaleZ
|
||||
swapXZ = profile.getProfileSetting('swap_xz') == 'True'
|
||||
swapYZ = profile.getProfileSetting('swap_yz') == 'True'
|
||||
mat00 = math.cos(rotate) * scaleX
|
||||
mat01 =-math.sin(rotate) * scaleY
|
||||
mat10 = math.sin(rotate) * scaleX
|
||||
mat11 = math.cos(rotate) * scaleY
|
||||
|
||||
for i in xrange(0, len(self.triangleMesh.origonalVertexes)):
|
||||
self.triangleMesh.vertexes[i].x = self.triangleMesh.origonalVertexes[i].x * mat00 + self.triangleMesh.origonalVertexes[i].y * mat01
|
||||
self.triangleMesh.vertexes[i].y = self.triangleMesh.origonalVertexes[i].x * mat10 + self.triangleMesh.origonalVertexes[i].y * mat11
|
||||
self.triangleMesh.vertexes[i].z = self.triangleMesh.origonalVertexes[i].z * scaleZ
|
||||
x = self.triangleMesh.origonalVertexes[i].x
|
||||
y = self.triangleMesh.origonalVertexes[i].y
|
||||
z = self.triangleMesh.origonalVertexes[i].z
|
||||
if swapXZ:
|
||||
x, z = z, x
|
||||
if swapYZ:
|
||||
y, z = z, y
|
||||
self.triangleMesh.vertexes[i].x = x * mat00 + y * mat01
|
||||
self.triangleMesh.vertexes[i].y = x * mat10 + y * mat11
|
||||
self.triangleMesh.vertexes[i].z = z * scaleZ
|
||||
|
||||
for face in self.triangleMesh.faces:
|
||||
v1 = face.v[0]
|
||||
@ -381,51 +410,24 @@ class PreviewGLCanvas(glcanvas.GLCanvas):
|
||||
dc.DrawText("No PyOpenGL installation found.\nNo preview window available.", 10, 10)
|
||||
return
|
||||
self.SetCurrent(self.context)
|
||||
self.InitGL()
|
||||
opengl.InitGL(self, self.view3D, self.zoom)
|
||||
if self.view3D:
|
||||
glTranslate(0,0,-self.zoom)
|
||||
glRotate(-self.pitch, 1,0,0)
|
||||
glRotate(self.yaw, 0,0,1)
|
||||
if self.parent.triangleMesh != None:
|
||||
glTranslate(0,0,-self.parent.triangleMesh.getMaximum().z / 2)
|
||||
else:
|
||||
glScale(1.0/self.zoom, 1.0/self.zoom, 1.0)
|
||||
glTranslate(self.offsetX, self.offsetY, 0.0)
|
||||
glTranslate(-self.parent.machineCenter.x, -self.parent.machineCenter.y, 0)
|
||||
|
||||
self.OnDraw()
|
||||
self.SwapBuffers()
|
||||
|
||||
def OnDraw(self):
|
||||
machineSize = self.parent.machineSize
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)
|
||||
|
||||
glTranslate(-self.parent.machineCenter.x, -self.parent.machineCenter.y, 0)
|
||||
|
||||
glColor3f(1,1,1)
|
||||
glLineWidth(4)
|
||||
glDisable(GL_LIGHTING)
|
||||
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_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()
|
||||
glLineWidth(1)
|
||||
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()
|
||||
opengl.DrawMachine(machineSize)
|
||||
|
||||
if self.parent.gcode != None:
|
||||
if self.gcodeDisplayList == None:
|
||||
@ -439,10 +441,13 @@ class PreviewGLCanvas(glcanvas.GLCanvas):
|
||||
layerThickness = 0.0
|
||||
filamentRadius = float(profile.getProfileSetting('filament_diameter')) / 2
|
||||
filamentArea = math.pi * filamentRadius * filamentRadius
|
||||
lineWidth = float(profile.getProfileSetting('nozzle_size')) / 2
|
||||
lineWidth = float(profile.getProfileSetting('nozzle_size')) / 2 / 10
|
||||
|
||||
curLayerNum = 0
|
||||
for layer in self.parent.gcode.layerList:
|
||||
curLayerZ = layer[0].list[1].z
|
||||
layerThickness = curLayerZ - prevLayerZ
|
||||
prevLayerZ = layer[-1].list[-1].z
|
||||
for path in layer:
|
||||
c = 1.0
|
||||
if curLayerNum != self.parent.layerSpin.GetValue():
|
||||
@ -530,26 +535,16 @@ class PreviewGLCanvas(glcanvas.GLCanvas):
|
||||
glTranslate(-(modelSize.x+10)*(multiX-1)/2,-(modelSize.y+10)*(multiY-1)/2, 0)
|
||||
for mx in xrange(0, multiX):
|
||||
for my in xrange(0, multiY):
|
||||
for face in self.parent.triangleMesh.faces:
|
||||
glPushMatrix()
|
||||
glTranslate((modelSize.x+10)*mx,(modelSize.y+10)*my, 0)
|
||||
glBegin(GL_TRIANGLES)
|
||||
v1 = face.v[0]
|
||||
v2 = face.v[1]
|
||||
v3 = face.v[2]
|
||||
glNormal3f(face.normal.x, face.normal.y, face.normal.z)
|
||||
glVertex3f(v1.x, v1.y, v1.z)
|
||||
glVertex3f(v2.x, v2.y, v2.z)
|
||||
glVertex3f(v3.x, v3.y, v3.z)
|
||||
glNormal3f(-face.normal.x, -face.normal.y, -face.normal.z)
|
||||
glVertex3f(v1.x, v1.y, v1.z)
|
||||
glVertex3f(v3.x, v3.y, v3.z)
|
||||
glVertex3f(v2.x, v2.y, v2.z)
|
||||
glEnd()
|
||||
glPopMatrix()
|
||||
glPushMatrix()
|
||||
glTranslate((modelSize.x+10)*mx,(modelSize.y+10)*my, 0)
|
||||
opengl.DrawSTL(self.parent.triangleMesh)
|
||||
glPopMatrix()
|
||||
glPopMatrix()
|
||||
glEndList()
|
||||
|
||||
if self.viewMode == "Model - Transparent" or self.viewMode == "Mixed":
|
||||
glLightfv(GL_LIGHT0, GL_DIFFUSE, [0.5, 0.4, 0.3, 1.0])
|
||||
glLightfv(GL_LIGHT0, GL_AMBIENT, [0.1, 0.1, 0.1, 0.0])
|
||||
#If we want transparent, then first render a solid black model to remove the printer size lines.
|
||||
if self.viewMode != "Mixed":
|
||||
glDisable(GL_BLEND)
|
||||
@ -606,6 +601,8 @@ class PreviewGLCanvas(glcanvas.GLCanvas):
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
glEnable(GL_DEPTH_TEST)
|
||||
elif self.viewMode == "Model - Normal":
|
||||
glLightfv(GL_LIGHT0, GL_DIFFUSE, [1.0, 0.8, 0.6, 1.0])
|
||||
glLightfv(GL_LIGHT0, GL_AMBIENT, [0.2, 0.2, 0.2, 0.0])
|
||||
glEnable(GL_LIGHTING)
|
||||
glCallList(self.modelDisplayList)
|
||||
|
||||
@ -622,48 +619,3 @@ class PreviewGLCanvas(glcanvas.GLCanvas):
|
||||
glEnd()
|
||||
|
||||
glFlush()
|
||||
|
||||
def InitGL(self):
|
||||
# set viewing projection
|
||||
glMatrixMode(GL_MODELVIEW)
|
||||
glLoadIdentity()
|
||||
size = self.GetSize()
|
||||
glViewport(0,0, size.GetWidth(), size.GetHeight())
|
||||
|
||||
if self.viewMode == "Model - Transparent" or self.viewMode == "Mixed":
|
||||
glLightfv(GL_LIGHT0, GL_DIFFUSE, [0.5, 0.4, 0.3, 1.0])
|
||||
glLightfv(GL_LIGHT0, GL_AMBIENT, [0.1, 0.1, 0.1, 0.0])
|
||||
else:
|
||||
glLightfv(GL_LIGHT0, GL_DIFFUSE, [1.0, 0.8, 0.6, 1.0])
|
||||
glLightfv(GL_LIGHT0, GL_AMBIENT, [0.2, 0.2, 0.2, 0.0])
|
||||
glLightfv(GL_LIGHT0, GL_POSITION, [1.0, 1.0, 1.0, 0.0])
|
||||
|
||||
glEnable(GL_LIGHTING)
|
||||
glEnable(GL_LIGHT0)
|
||||
glEnable(GL_DEPTH_TEST)
|
||||
glEnable(GL_CULL_FACE)
|
||||
glDisable(GL_BLEND)
|
||||
|
||||
glClearColor(0.0, 0.0, 0.0, 1.0)
|
||||
glClearStencil(0)
|
||||
glClearDepth(1.0)
|
||||
|
||||
glMatrixMode(GL_PROJECTION)
|
||||
glLoadIdentity()
|
||||
aspect = float(self.GetSize().GetWidth()) / float(self.GetSize().GetHeight())
|
||||
if self.view3D:
|
||||
gluPerspective(90.0, aspect, 1.0, 1000.0)
|
||||
else:
|
||||
glOrtho(-self.zoom * aspect, self.zoom * aspect, -self.zoom, self.zoom, -1000.0, 1000.0)
|
||||
|
||||
glMatrixMode(GL_MODELVIEW)
|
||||
glLoadIdentity()
|
||||
if self.view3D:
|
||||
glTranslate(0,0,-self.zoom)
|
||||
glRotate(-self.pitch, 1,0,0)
|
||||
glRotate(self.yaw, 0,0,1)
|
||||
if self.parent.triangleMesh != None:
|
||||
glTranslate(0,0,-self.parent.triangleMesh.getMaximum().z / 2)
|
||||
else:
|
||||
glTranslate(self.offsetX, self.offsetY, 0)
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
from __future__ import absolute_import
|
||||
import __init__
|
||||
|
||||
import wx, threading
|
||||
import wx, threading, re
|
||||
|
||||
from gui import machineCom
|
||||
from gui import icon
|
||||
@ -27,7 +27,9 @@ class printWindow(wx.Frame):
|
||||
self.thread = None
|
||||
self.gcode = None
|
||||
self.gcodeList = None
|
||||
self.sendList = []
|
||||
self.printIdx = None
|
||||
self.temp = None
|
||||
self.bufferLineCount = 4
|
||||
self.sendCnt = 0
|
||||
|
||||
@ -51,11 +53,20 @@ class printWindow(wx.Frame):
|
||||
self.printButton = wx.Button(self.panel, -1, 'Print GCode')
|
||||
self.cancelButton = wx.Button(self.panel, -1, 'Cancel print')
|
||||
self.progress = wx.Gauge(self.panel, -1)
|
||||
|
||||
h = self.connectButton.GetSize().GetHeight()
|
||||
self.temperatureSelect = wx.SpinCtrl(self.panel, -1, '0', size=(21*3,21), style=wx.SP_ARROW_KEYS)
|
||||
self.temperatureSelect.SetRange(0, 400)
|
||||
|
||||
self.sizer.Add(self.connectButton, pos=(0,1))
|
||||
#self.sizer.Add(self.loadButton, pos=(1,1))
|
||||
self.sizer.Add(self.printButton, pos=(2,1))
|
||||
self.sizer.Add(self.cancelButton, pos=(3,1))
|
||||
self.sizer.Add(self.progress, pos=(4,0), span=(1,2), flag=wx.EXPAND)
|
||||
|
||||
self.sizer.Add(wx.StaticText(self.panel, -1, "Temp:"), pos=(0,3))
|
||||
self.sizer.Add(self.temperatureSelect, pos=(0,4))
|
||||
|
||||
self.sizer.AddGrowableRow(3)
|
||||
self.sizer.AddGrowableCol(0)
|
||||
|
||||
@ -65,6 +76,8 @@ class printWindow(wx.Frame):
|
||||
self.printButton.Bind(wx.EVT_BUTTON, self.OnPrint)
|
||||
self.cancelButton.Bind(wx.EVT_BUTTON, self.OnCancel)
|
||||
|
||||
self.Bind(wx.EVT_SPINCTRL, self.OnTempChange, self.temperatureSelect)
|
||||
|
||||
self.Layout()
|
||||
self.Fit()
|
||||
self.Centre()
|
||||
@ -90,6 +103,8 @@ class printWindow(wx.Frame):
|
||||
else:
|
||||
self.progress.SetValue(self.printIdx)
|
||||
status += 'Line: %d/%d\n' % (self.printIdx, len(self.gcodeList))
|
||||
if self.temp != None:
|
||||
status += 'Temp: %d\n' % (self.temp)
|
||||
self.statsText.SetLabel(status)
|
||||
|
||||
def OnConnect(self, e):
|
||||
@ -128,9 +143,13 @@ class printWindow(wx.Frame):
|
||||
self.thread.join()
|
||||
self.Destroy()
|
||||
|
||||
def OnTempChange(self, e):
|
||||
self.sendCommand("M104 S%d" % (self.temperatureSelect.GetValue()))
|
||||
|
||||
def LoadGCodeFile(self, filename):
|
||||
if self.printIdx != None:
|
||||
return
|
||||
#Send an initial M110 to reset the line counter to zero.
|
||||
gcodeList = ["M110"]
|
||||
for line in open(filename, 'r'):
|
||||
if ';' in line:
|
||||
@ -146,6 +165,13 @@ class printWindow(wx.Frame):
|
||||
self.gcodeList = gcodeList
|
||||
self.UpdateButtonStates()
|
||||
self.UpdateProgress()
|
||||
|
||||
def sendCommand(self, cmd):
|
||||
if self.machineConnected:
|
||||
if self.printIdx == None:
|
||||
self.machineCom.sendCommand(cmd)
|
||||
else:
|
||||
self.sendList.append(cmd)
|
||||
|
||||
def sendLine(self, lineNr):
|
||||
if lineNr >= len(self.gcodeList):
|
||||
@ -155,7 +181,6 @@ class printWindow(wx.Frame):
|
||||
return True
|
||||
|
||||
def PrinterMonitor(self):
|
||||
skipCount = 0
|
||||
while True:
|
||||
line = self.machineCom.readline()
|
||||
if line == None:
|
||||
@ -170,10 +195,16 @@ class printWindow(wx.Frame):
|
||||
elif line.startswith("start"):
|
||||
self.machineConnected = True
|
||||
wx.CallAfter(self.UpdateButtonStates)
|
||||
if self.printIdx != None:
|
||||
if 'T:' in line:
|
||||
self.temp = float(re.search("[0-9\.]*", line.split('T:')[1]).group(0))
|
||||
wx.CallAfter(self.UpdateProgress)
|
||||
if self.printIdx == None:
|
||||
if line == '': #When we have a communication "timeout" and we're not sending gcode, then read the temperature.
|
||||
self.machineCom.sendCommand("M105")
|
||||
else:
|
||||
if line.startswith("ok"):
|
||||
if skipCount > 0:
|
||||
skipCount -= 1
|
||||
if len(self.sendList) > 0:
|
||||
self.machineCom.sendCommand(self.sendList.pop(0))
|
||||
else:
|
||||
if self.sendLine(self.printIdx):
|
||||
self.printIdx += 1
|
||||
|
@ -205,7 +205,7 @@ class simpleModeWindow(configBase.configWindowBase):
|
||||
put('infill_type', 'Line')
|
||||
put('solid_top', 'True')
|
||||
put('fill_overlap', '15')
|
||||
put('support_rate', '100')
|
||||
put('support_rate', '50')
|
||||
put('support_distance', '0.5')
|
||||
put('joris', 'False')
|
||||
put('cool_min_feedrate', '5')
|
||||
@ -214,6 +214,7 @@ class simpleModeWindow(configBase.configWindowBase):
|
||||
put('raft_margin', '5')
|
||||
put('raft_base_material_amount', '100')
|
||||
put('raft_interface_material_amount', '100')
|
||||
put('bottom_thickness', '0.0')
|
||||
|
||||
if self.printSupport.GetValue():
|
||||
put('support', 'Exterior Only')
|
||||
@ -234,6 +235,7 @@ class simpleModeWindow(configBase.configWindowBase):
|
||||
put('layer_height', '0.1')
|
||||
put('fill_density', '30')
|
||||
put('bottom_layer_speed', '15')
|
||||
put('bottom_thickness', '0.2')
|
||||
elif self.printTypeJoris.GetValue():
|
||||
put('wall_thickness', nozzle_size * 1.5)
|
||||
put('layer_height', '0.2')
|
||||
@ -255,6 +257,7 @@ class simpleModeWindow(configBase.configWindowBase):
|
||||
put('enable_raft', 'True')
|
||||
put('skirt_line_count', '0')
|
||||
put('fan_layer', '1')
|
||||
put('bottom_thickness', '0.0')
|
||||
|
||||
#Create a progress panel and add it to the window. The progress panel will start the Skein operation.
|
||||
spp = sliceProgessPanel.sliceProgessPanel(self, self, self.filename)
|
||||
|
@ -28,6 +28,7 @@ class sliceProgessPanel(wx.Panel):
|
||||
'speed': 12.759510994,
|
||||
'raft': 31.4580039978,
|
||||
'skirt': 19.3436040878,
|
||||
'skin': 1.0,
|
||||
'joris': 1.0,
|
||||
'comb': 23.7805759907,
|
||||
'cool': 27.148763895,
|
||||
|
@ -105,7 +105,7 @@ class gcode():
|
||||
else:
|
||||
pos.z += z * scale
|
||||
#Check if we have a new layer.
|
||||
if oldPos.z != pos.z and startCodeDone:
|
||||
if oldPos.z < pos.z and startCodeDone and len(currentLayer) > 0:
|
||||
self.layerList.append(currentLayer)
|
||||
currentLayer = []
|
||||
if f is not None:
|
||||
|
@ -42,6 +42,8 @@ profileDefaultSettings = {
|
||||
'flip_x': 'False',
|
||||
'flip_y': 'False',
|
||||
'flip_z': 'False',
|
||||
'swap_xz': 'False',
|
||||
'swap_yz': 'False',
|
||||
'model_rotate_base': '0',
|
||||
'model_multiply_x': '1',
|
||||
'model_multiply_y': '1',
|
||||
@ -51,9 +53,10 @@ profileDefaultSettings = {
|
||||
'infill_type': 'Line',
|
||||
'solid_top': 'True',
|
||||
'fill_overlap': '15',
|
||||
'support_rate': '100',
|
||||
'support_rate': '50',
|
||||
'support_distance': '0.5',
|
||||
'joris': 'False',
|
||||
'enable_skin': 'False',
|
||||
'enable_raft': 'False',
|
||||
'cool_min_feedrate': '5',
|
||||
'bridge_speed': '100',
|
||||
@ -61,6 +64,7 @@ profileDefaultSettings = {
|
||||
'raft_margin': '5',
|
||||
'raft_base_material_amount': '100',
|
||||
'raft_interface_material_amount': '100',
|
||||
'bottom_thickness': '0.0',
|
||||
}
|
||||
preferencesDefaultSettings = {
|
||||
'wizardDone': 'False',
|
||||
@ -158,7 +162,7 @@ def getPreference(name):
|
||||
globalPreferenceParser.set('preference', name, str(default))
|
||||
print name + " not found in preferences, so using default: " + str(default)
|
||||
return default
|
||||
return globalPreferenceParser.get('preference', name)
|
||||
return unicode(globalPreferenceParser.get('preference', name), "utf-8")
|
||||
|
||||
def putPreference(name, value):
|
||||
#Check if we have a configuration file loaded, else load the default.
|
||||
@ -168,7 +172,7 @@ def putPreference(name, value):
|
||||
globalPreferenceParser.read(getPreferencePath())
|
||||
if not globalPreferenceParser.has_section('preference'):
|
||||
globalPreferenceParser.add_section('preference')
|
||||
globalPreferenceParser.set('preference', name, str(value))
|
||||
globalPreferenceParser.set('preference', name, str(value).encode("utf-8"))
|
||||
globalPreferenceParser.write(open(getPreferencePath(), 'w'))
|
||||
|
||||
#########################################################
|
||||
|
@ -89,7 +89,7 @@ def getSliceCommand(filename):
|
||||
'--solid-layers', str(profile.calculateSolidLayerCount()),
|
||||
'--fill-density', str(float(profile.getProfileSetting('fill_density'))/100),
|
||||
'--fill-angle', '45',
|
||||
'--fill-pattern', 'rectilinear',
|
||||
'--fill-pattern', 'rectilinear', #rectilinear line concentric hilbertcurve archimedeanchords octagramspiral
|
||||
'--solid-fill-pattern', 'rectilinear',
|
||||
'--start-gcode', profile.getAlterationFilePath('start.gcode'),
|
||||
'--end-gcode', profile.getAlterationFilePath('end.gcode'),
|
||||
|
66
README
66
README
@ -1,66 +0,0 @@
|
||||
For documentation check: https://github.com/daid/Cura/wiki
|
||||
For downloads check: https://github.com/daid/Cura/downloads
|
||||
|
||||
This package includes two programs:
|
||||
|
||||
Pronterface:
|
||||
|
||||
An application for both manually controlling and automatically feeding gcode to a 3D printer.
|
||||
|
||||
Cura:
|
||||
|
||||
A easy to use program for slicing STL files using SkeinForge. Cura can also visualize the 3D models in a variety of ways.
|
||||
|
||||
On first run, Cura will ask to go through a set of calibration steps that will perform a series of operations on your 3D printer. One of those steps involves extruding a bit of filament where the filament is initially nearly fully extracted. As such, it you will probably need to run Pronterface first, heat up the extruder enough to be able to extract the filament and then use the Pronterface interface to reverse the extruder motor until the filament is at the right position (specifically, until the filament end is even with where the Bowden tube leaves the extuder motor assembly, on an Ultimaker).
|
||||
|
||||
========
|
||||
BUILDING
|
||||
========
|
||||
|
||||
./package.sh
|
||||
|
||||
The build script defaults to building for Windows. If you want to build for Mac OS X or Linux, choose one of:
|
||||
|
||||
./package.sh osx64
|
||||
./package.sh linux
|
||||
|
||||
Note that Mac OS X currently requires the manual installation of wxPython, PySerial, and PyOpenGL:
|
||||
|
||||
sudo easy_install-2.7 pyserial
|
||||
sudo easy_install-2.7 PyOpenGL
|
||||
|
||||
You will need to download the appropriate wxPython Installer package and install it. It is available from:
|
||||
|
||||
http://www.wxpython.org/download.php
|
||||
|
||||
Specifically, install "wxPython2.9-osx-cocoa-py2.7" as it is the build that supports 64-bit execution.
|
||||
|
||||
=======
|
||||
RUNNING
|
||||
=======
|
||||
|
||||
Windows
|
||||
-------
|
||||
|
||||
Double-click skeinforge.bat and Printrun.bat.
|
||||
|
||||
Mac OS X & Linux
|
||||
----------------
|
||||
|
||||
Once built, the two apps -- Pronterface and Cura -- must be started from the command line (for now):
|
||||
|
||||
# open a new terminal window and....
|
||||
cd osx64-Cura-NewUI-Beta4
|
||||
./pronterface.sh &
|
||||
./Cura.sh &
|
||||
|
||||
This will start both applications with their console logging output directed into the terminal window.
|
||||
|
||||
========
|
||||
FIRMWARE
|
||||
========
|
||||
|
||||
For Ultimaker users, it is highly recommended -- nearly required -- that you upgrade your firmware to the latest Marlin builds. See:
|
||||
|
||||
http://wiki.ultimaker.com/Skeinforge_PyPy
|
||||
|
17
README.md
Normal file
17
README.md
Normal file
@ -0,0 +1,17 @@
|
||||
Cura
|
||||
====
|
||||
|
||||
If you are reading this, then you are looking at the *development* version of Cura. If you just want to use Cura look at the following location: https://github.com/daid/Cura/wiki
|
||||
|
||||
Development
|
||||
===========
|
||||
|
||||
Cura is developed in Python. Getting Cura up and running for development is not very difficult. If you copy the python and pypy from a release into your Cura development checkout then you can use Cura right away, just like you would with a release.
|
||||
For development with git, check the help on github. Pull requests is the fastest way to get changes into Cura.
|
||||
|
||||
Packaging
|
||||
---------
|
||||
|
||||
Cura development comes with a script "package.sh", this script has been designed to run under unix like OSes (Linux, MacOS). Running it from sygwin is not a priority.
|
||||
The "package.sh" script generates a final release package. You should not need it during development, unless you are changing the release process. If you want to distribute your own version of Cura, then the package.sh script will allow you to do that.
|
||||
|
@ -85,6 +85,7 @@ Section "Cura Installer"
|
||||
CreateDirectory "$SMPROGRAMS\Cura ${VERSION}"
|
||||
CreateShortCut "$SMPROGRAMS\Cura ${VERSION}\Uninstall.lnk" "$INSTDIR\uninstall.exe" "" "$INSTDIR\uninstall.exe" 0
|
||||
CreateShortCut "$SMPROGRAMS\Cura ${VERSION}\Cura.lnk" "$INSTDIR\cura.bat" "" "$INSTDIR\cura.icon" 0
|
||||
CreateShortCut "$SMPROGRAMS\Cura ${VERSION}\PrintRun.lnk" "$INSTDIR\printrun.bat" "" "$INSTDIR\cura.icon" 0
|
||||
|
||||
; Set output path to the driver directory.
|
||||
SetOutPath "$INSTDIR\drivers\"
|
||||
@ -108,9 +109,6 @@ Section "Uninstall"
|
||||
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Cura_${VERSION}"
|
||||
DeleteRegKey HKLM "SOFTWARE\Cura_${VERSION}"
|
||||
|
||||
; Remove shortcuts, if any
|
||||
Delete "$SMPROGRAMS\Cura ${VERSION}\*.*"
|
||||
|
||||
; Remove directories used
|
||||
RMDir /r "$SMPROGRAMS\Cura ${VERSION}"
|
||||
RMDir /r "$INSTDIR"
|
||||
|
Loading…
x
Reference in New Issue
Block a user