Updated all lineends for py files to unix style.
parent
c4b3c26be1
commit
6c4c4ba2f9
|
@ -1,20 +1,20 @@
|
|||
|
||||
avrChipDB = {
|
||||
'ATMega1280': {
|
||||
'signature': [0x1E, 0x97, 0x03],
|
||||
'pageSize': 128,
|
||||
'pageCount': 512,
|
||||
},
|
||||
'ATMega2560': {
|
||||
'signature': [0x1E, 0x98, 0x01],
|
||||
'pageSize': 128,
|
||||
'pageCount': 1024,
|
||||
},
|
||||
}
|
||||
|
||||
def getChipFromDB(sig):
|
||||
for chip in avrChipDB.values():
|
||||
if chip['signature'] == sig:
|
||||
return chip
|
||||
return False
|
||||
|
||||
|
||||
avrChipDB = {
|
||||
'ATMega1280': {
|
||||
'signature': [0x1E, 0x97, 0x03],
|
||||
'pageSize': 128,
|
||||
'pageCount': 512,
|
||||
},
|
||||
'ATMega2560': {
|
||||
'signature': [0x1E, 0x98, 0x01],
|
||||
'pageSize': 128,
|
||||
'pageCount': 1024,
|
||||
},
|
||||
}
|
||||
|
||||
def getChipFromDB(sig):
|
||||
for chip in avrChipDB.values():
|
||||
if chip['signature'] == sig:
|
||||
return chip
|
||||
return False
|
||||
|
||||
|
|
|
@ -1,35 +1,35 @@
|
|||
import io
|
||||
|
||||
def readHex(filename):
|
||||
data = []
|
||||
extraAddr = 0
|
||||
f = io.open(filename, "r")
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
if line[0] != ':':
|
||||
raise Exception("Hex file has a line not starting with ':'")
|
||||
recLen = int(line[1:3], 16)
|
||||
addr = int(line[3:7], 16) + extraAddr
|
||||
recType = int(line[7:9], 16)
|
||||
if len(line) != recLen * 2 + 11:
|
||||
raise Exception("Error in hex file: " + line)
|
||||
checkSum = 0
|
||||
for i in xrange(0, recLen + 5):
|
||||
checkSum += int(line[i*2+1:i*2+3], 16)
|
||||
checkSum &= 0xFF
|
||||
if checkSum != 0:
|
||||
raise Exception("Checksum error in hex file: " + line)
|
||||
|
||||
if recType == 0:#Data record
|
||||
while len(data) < addr + recLen:
|
||||
data.append(0)
|
||||
for i in xrange(0, recLen):
|
||||
data[addr + i] = int(line[i*2+9:i*2+11], 16)
|
||||
elif recType == 1: #End Of File record
|
||||
pass
|
||||
elif recType == 2: #Extended Segment Address Record
|
||||
extraAddr = int(line[9:13], 16) * 16
|
||||
else:
|
||||
print(recType, recLen, addr, checkSum, line)
|
||||
f.close()
|
||||
import io
|
||||
|
||||
def readHex(filename):
|
||||
data = []
|
||||
extraAddr = 0
|
||||
f = io.open(filename, "r")
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
if line[0] != ':':
|
||||
raise Exception("Hex file has a line not starting with ':'")
|
||||
recLen = int(line[1:3], 16)
|
||||
addr = int(line[3:7], 16) + extraAddr
|
||||
recType = int(line[7:9], 16)
|
||||
if len(line) != recLen * 2 + 11:
|
||||
raise Exception("Error in hex file: " + line)
|
||||
checkSum = 0
|
||||
for i in xrange(0, recLen + 5):
|
||||
checkSum += int(line[i*2+1:i*2+3], 16)
|
||||
checkSum &= 0xFF
|
||||
if checkSum != 0:
|
||||
raise Exception("Checksum error in hex file: " + line)
|
||||
|
||||
if recType == 0:#Data record
|
||||
while len(data) < addr + recLen:
|
||||
data.append(0)
|
||||
for i in xrange(0, recLen):
|
||||
data[addr + i] = int(line[i*2+9:i*2+11], 16)
|
||||
elif recType == 1: #End Of File record
|
||||
pass
|
||||
elif recType == 2: #Extended Segment Address Record
|
||||
extraAddr = int(line[9:13], 16) * 16
|
||||
else:
|
||||
print(recType, recLen, addr, checkSum, line)
|
||||
f.close()
|
||||
return data
|
|
@ -1,35 +1,35 @@
|
|||
import os, struct, sys, time
|
||||
|
||||
from serial import Serial
|
||||
|
||||
import chipDB
|
||||
|
||||
class IspBase():
|
||||
def programChip(self, flashData):
|
||||
self.curExtAddr = -1
|
||||
self.chip = chipDB.getChipFromDB(self.getSignature())
|
||||
if self.chip == False:
|
||||
raise IspError("Chip with signature: " + str(self.getSignature()) + "not found")
|
||||
self.chipErase()
|
||||
|
||||
print("Flashing %i bytes" % len(flashData))
|
||||
self.writeFlash(flashData)
|
||||
print("Verifying %i bytes" % len(flashData))
|
||||
self.verifyFlash(flashData)
|
||||
|
||||
#low level ISP commands
|
||||
def getSignature(self):
|
||||
sig = []
|
||||
sig.append(self.sendISP([0x30, 0x00, 0x00, 0x00])[3])
|
||||
sig.append(self.sendISP([0x30, 0x00, 0x01, 0x00])[3])
|
||||
sig.append(self.sendISP([0x30, 0x00, 0x02, 0x00])[3])
|
||||
return sig
|
||||
|
||||
def chipErase(self):
|
||||
self.sendISP([0xAC, 0x80, 0x00, 0x00])
|
||||
|
||||
class IspError():
|
||||
def __init__(self, value):
|
||||
self.value = value
|
||||
def __str__(self):
|
||||
return repr(self.value)
|
||||
import os, struct, sys, time
|
||||
|
||||
from serial import Serial
|
||||
|
||||
import chipDB
|
||||
|
||||
class IspBase():
|
||||
def programChip(self, flashData):
|
||||
self.curExtAddr = -1
|
||||
self.chip = chipDB.getChipFromDB(self.getSignature())
|
||||
if self.chip == False:
|
||||
raise IspError("Chip with signature: " + str(self.getSignature()) + "not found")
|
||||
self.chipErase()
|
||||
|
||||
print("Flashing %i bytes" % len(flashData))
|
||||
self.writeFlash(flashData)
|
||||
print("Verifying %i bytes" % len(flashData))
|
||||
self.verifyFlash(flashData)
|
||||
|
||||
#low level ISP commands
|
||||
def getSignature(self):
|
||||
sig = []
|
||||
sig.append(self.sendISP([0x30, 0x00, 0x00, 0x00])[3])
|
||||
sig.append(self.sendISP([0x30, 0x00, 0x01, 0x00])[3])
|
||||
sig.append(self.sendISP([0x30, 0x00, 0x02, 0x00])[3])
|
||||
return sig
|
||||
|
||||
def chipErase(self):
|
||||
self.sendISP([0xAC, 0x80, 0x00, 0x00])
|
||||
|
||||
class IspError():
|
||||
def __init__(self, value):
|
||||
self.value = value
|
||||
def __str__(self):
|
||||
return repr(self.value)
|
||||
|
|
|
@ -1,154 +1,154 @@
|
|||
import os, struct, sys, time
|
||||
|
||||
from serial import Serial
|
||||
from serial import SerialException
|
||||
|
||||
import ispBase, intelHex
|
||||
|
||||
class Stk500v2(ispBase.IspBase):
|
||||
def __init__(self):
|
||||
self.serial = None
|
||||
self.seq = 1
|
||||
self.lastAddr = -1
|
||||
self.progressCallback = None
|
||||
|
||||
def connect(self, port = 'COM22', speed = 115200):
|
||||
if self.serial != None:
|
||||
self.close()
|
||||
try:
|
||||
self.serial = Serial(port, speed, timeout=1, writeTimeout=10000)
|
||||
except SerialException as e:
|
||||
raise ispBase.IspError("Failed to open serial port")
|
||||
except:
|
||||
raise ispBase.IspError("Unexpected error while connecting to serial port:" + port + ":" + str(sys.exc_info()[0]))
|
||||
self.seq = 1
|
||||
|
||||
#Reset the controller
|
||||
self.serial.setDTR(1)
|
||||
time.sleep(0.1)
|
||||
self.serial.setDTR(0)
|
||||
time.sleep(0.2)
|
||||
|
||||
self.sendMessage([1])
|
||||
if self.sendMessage([0x10, 0xc8, 0x64, 0x19, 0x20, 0x00, 0x53, 0x03, 0xac, 0x53, 0x00, 0x00]) != [0x10, 0x00]:
|
||||
self.close()
|
||||
raise ispBase.IspError("Failed to enter programming mode")
|
||||
|
||||
def close(self):
|
||||
if self.serial != None:
|
||||
self.serial.close()
|
||||
self.serial = None
|
||||
|
||||
#Leave ISP does not reset the serial port, only resets the device, and returns the serial port after disconnecting it from the programming interface.
|
||||
# This allows you to use the serial port without opening it again.
|
||||
def leaveISP(self):
|
||||
if self.serial != None:
|
||||
if self.sendMessage([0x11]) != [0x11, 0x00]:
|
||||
raise ispBase.IspError("Failed to leave programming mode")
|
||||
ret = self.serial
|
||||
self.serial = None
|
||||
return ret
|
||||
return None
|
||||
|
||||
def isConnected(self):
|
||||
return self.serial != None
|
||||
|
||||
def sendISP(self, data):
|
||||
recv = self.sendMessage([0x1D, 4, 4, 0, data[0], data[1], data[2], data[3]])
|
||||
return recv[2:6]
|
||||
|
||||
def writeFlash(self, flashData):
|
||||
#Set load addr to 0, in case we have more then 64k flash we need to enable the address extension
|
||||
pageSize = self.chip['pageSize'] * 2
|
||||
flashSize = pageSize * self.chip['pageCount']
|
||||
if flashSize > 0xFFFF:
|
||||
self.sendMessage([0x06, 0x80, 0x00, 0x00, 0x00])
|
||||
else:
|
||||
self.sendMessage([0x06, 0x00, 0x00, 0x00, 0x00])
|
||||
|
||||
loadCount = (len(flashData) + pageSize - 1) / pageSize
|
||||
for i in xrange(0, loadCount):
|
||||
recv = self.sendMessage([0x13, pageSize >> 8, pageSize & 0xFF, 0xc1, 0x0a, 0x40, 0x4c, 0x20, 0x00, 0x00] + flashData[(i * pageSize):(i * pageSize + pageSize)])
|
||||
if self.progressCallback != None:
|
||||
self.progressCallback(i + 1, loadCount*2)
|
||||
|
||||
def verifyFlash(self, flashData):
|
||||
#Set load addr to 0, in case we have more then 64k flash we need to enable the address extension
|
||||
flashSize = self.chip['pageSize'] * 2 * self.chip['pageCount']
|
||||
if flashSize > 0xFFFF:
|
||||
self.sendMessage([0x06, 0x80, 0x00, 0x00, 0x00])
|
||||
else:
|
||||
self.sendMessage([0x06, 0x00, 0x00, 0x00, 0x00])
|
||||
|
||||
loadCount = (len(flashData) + 0xFF) / 0x100
|
||||
for i in xrange(0, loadCount):
|
||||
recv = self.sendMessage([0x14, 0x01, 0x00, 0x20])[2:0x102]
|
||||
if self.progressCallback != None:
|
||||
self.progressCallback(loadCount + i + 1, loadCount*2)
|
||||
for j in xrange(0, 0x100):
|
||||
if i * 0x100 + j < len(flashData) and flashData[i * 0x100 + j] != recv[j]:
|
||||
raise ispBase.IspError('Verify error at: 0x%x' % (i * 0x100 + j))
|
||||
|
||||
def sendMessage(self, data):
|
||||
message = struct.pack(">BBHB", 0x1B, self.seq, len(data), 0x0E)
|
||||
for c in data:
|
||||
message += struct.pack(">B", c)
|
||||
checksum = 0
|
||||
for c in message:
|
||||
checksum ^= ord(c)
|
||||
message += struct.pack(">B", checksum)
|
||||
try:
|
||||
self.serial.write(message)
|
||||
self.serial.flush()
|
||||
except SerialTimeoutException:
|
||||
raise ispBase.IspError('Serial send timeout')
|
||||
self.seq = (self.seq + 1) & 0xFF
|
||||
return self.recvMessage()
|
||||
|
||||
def recvMessage(self):
|
||||
state = 'Start'
|
||||
checksum = 0
|
||||
while True:
|
||||
s = self.serial.read()
|
||||
if len(s) < 1:
|
||||
raise ispBase.IspError("Timeout")
|
||||
b = struct.unpack(">B", s)[0]
|
||||
checksum ^= b
|
||||
#print(hex(b))
|
||||
if state == 'Start':
|
||||
if b == 0x1B:
|
||||
state = 'GetSeq'
|
||||
checksum = 0x1B
|
||||
elif state == 'GetSeq':
|
||||
state = 'MsgSize1'
|
||||
elif state == 'MsgSize1':
|
||||
msgSize = b << 8
|
||||
state = 'MsgSize2'
|
||||
elif state == 'MsgSize2':
|
||||
msgSize |= b
|
||||
state = 'Token'
|
||||
elif state == 'Token':
|
||||
if b != 0x0E:
|
||||
state = 'Start'
|
||||
else:
|
||||
state = 'Data'
|
||||
data = []
|
||||
elif state == 'Data':
|
||||
data.append(b)
|
||||
if len(data) == msgSize:
|
||||
state = 'Checksum'
|
||||
elif state == 'Checksum':
|
||||
if checksum != 0:
|
||||
state = 'Start'
|
||||
else:
|
||||
return data
|
||||
|
||||
|
||||
def main():
|
||||
programmer = Stk500v2()
|
||||
programmer.connect(port = sys.argv[1])
|
||||
programmer.programChip(intelHex.readHex(sys.argv[2]))
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
import os, struct, sys, time
|
||||
|
||||
from serial import Serial
|
||||
from serial import SerialException
|
||||
|
||||
import ispBase, intelHex
|
||||
|
||||
class Stk500v2(ispBase.IspBase):
|
||||
def __init__(self):
|
||||
self.serial = None
|
||||
self.seq = 1
|
||||
self.lastAddr = -1
|
||||
self.progressCallback = None
|
||||
|
||||
def connect(self, port = 'COM22', speed = 115200):
|
||||
if self.serial != None:
|
||||
self.close()
|
||||
try:
|
||||
self.serial = Serial(port, speed, timeout=1, writeTimeout=10000)
|
||||
except SerialException as e:
|
||||
raise ispBase.IspError("Failed to open serial port")
|
||||
except:
|
||||
raise ispBase.IspError("Unexpected error while connecting to serial port:" + port + ":" + str(sys.exc_info()[0]))
|
||||
self.seq = 1
|
||||
|
||||
#Reset the controller
|
||||
self.serial.setDTR(1)
|
||||
time.sleep(0.1)
|
||||
self.serial.setDTR(0)
|
||||
time.sleep(0.2)
|
||||
|
||||
self.sendMessage([1])
|
||||
if self.sendMessage([0x10, 0xc8, 0x64, 0x19, 0x20, 0x00, 0x53, 0x03, 0xac, 0x53, 0x00, 0x00]) != [0x10, 0x00]:
|
||||
self.close()
|
||||
raise ispBase.IspError("Failed to enter programming mode")
|
||||
|
||||
def close(self):
|
||||
if self.serial != None:
|
||||
self.serial.close()
|
||||
self.serial = None
|
||||
|
||||
#Leave ISP does not reset the serial port, only resets the device, and returns the serial port after disconnecting it from the programming interface.
|
||||
# This allows you to use the serial port without opening it again.
|
||||
def leaveISP(self):
|
||||
if self.serial != None:
|
||||
if self.sendMessage([0x11]) != [0x11, 0x00]:
|
||||
raise ispBase.IspError("Failed to leave programming mode")
|
||||
ret = self.serial
|
||||
self.serial = None
|
||||
return ret
|
||||
return None
|
||||
|
||||
def isConnected(self):
|
||||
return self.serial != None
|
||||
|
||||
def sendISP(self, data):
|
||||
recv = self.sendMessage([0x1D, 4, 4, 0, data[0], data[1], data[2], data[3]])
|
||||
return recv[2:6]
|
||||
|
||||
def writeFlash(self, flashData):
|
||||
#Set load addr to 0, in case we have more then 64k flash we need to enable the address extension
|
||||
pageSize = self.chip['pageSize'] * 2
|
||||
flashSize = pageSize * self.chip['pageCount']
|
||||
if flashSize > 0xFFFF:
|
||||
self.sendMessage([0x06, 0x80, 0x00, 0x00, 0x00])
|
||||
else:
|
||||
self.sendMessage([0x06, 0x00, 0x00, 0x00, 0x00])
|
||||
|
||||
loadCount = (len(flashData) + pageSize - 1) / pageSize
|
||||
for i in xrange(0, loadCount):
|
||||
recv = self.sendMessage([0x13, pageSize >> 8, pageSize & 0xFF, 0xc1, 0x0a, 0x40, 0x4c, 0x20, 0x00, 0x00] + flashData[(i * pageSize):(i * pageSize + pageSize)])
|
||||
if self.progressCallback != None:
|
||||
self.progressCallback(i + 1, loadCount*2)
|
||||
|
||||
def verifyFlash(self, flashData):
|
||||
#Set load addr to 0, in case we have more then 64k flash we need to enable the address extension
|
||||
flashSize = self.chip['pageSize'] * 2 * self.chip['pageCount']
|
||||
if flashSize > 0xFFFF:
|
||||
self.sendMessage([0x06, 0x80, 0x00, 0x00, 0x00])
|
||||
else:
|
||||
self.sendMessage([0x06, 0x00, 0x00, 0x00, 0x00])
|
||||
|
||||
loadCount = (len(flashData) + 0xFF) / 0x100
|
||||
for i in xrange(0, loadCount):
|
||||
recv = self.sendMessage([0x14, 0x01, 0x00, 0x20])[2:0x102]
|
||||
if self.progressCallback != None:
|
||||
self.progressCallback(loadCount + i + 1, loadCount*2)
|
||||
for j in xrange(0, 0x100):
|
||||
if i * 0x100 + j < len(flashData) and flashData[i * 0x100 + j] != recv[j]:
|
||||
raise ispBase.IspError('Verify error at: 0x%x' % (i * 0x100 + j))
|
||||
|
||||
def sendMessage(self, data):
|
||||
message = struct.pack(">BBHB", 0x1B, self.seq, len(data), 0x0E)
|
||||
for c in data:
|
||||
message += struct.pack(">B", c)
|
||||
checksum = 0
|
||||
for c in message:
|
||||
checksum ^= ord(c)
|
||||
message += struct.pack(">B", checksum)
|
||||
try:
|
||||
self.serial.write(message)
|
||||
self.serial.flush()
|
||||
except SerialTimeoutException:
|
||||
raise ispBase.IspError('Serial send timeout')
|
||||
self.seq = (self.seq + 1) & 0xFF
|
||||
return self.recvMessage()
|
||||
|
||||
def recvMessage(self):
|
||||
state = 'Start'
|
||||
checksum = 0
|
||||
while True:
|
||||
s = self.serial.read()
|
||||
if len(s) < 1:
|
||||
raise ispBase.IspError("Timeout")
|
||||
b = struct.unpack(">B", s)[0]
|
||||
checksum ^= b
|
||||
#print(hex(b))
|
||||
if state == 'Start':
|
||||
if b == 0x1B:
|
||||
state = 'GetSeq'
|
||||
checksum = 0x1B
|
||||
elif state == 'GetSeq':
|
||||
state = 'MsgSize1'
|
||||
elif state == 'MsgSize1':
|
||||
msgSize = b << 8
|
||||
state = 'MsgSize2'
|
||||
elif state == 'MsgSize2':
|
||||
msgSize |= b
|
||||
state = 'Token'
|
||||
elif state == 'Token':
|
||||
if b != 0x0E:
|
||||
state = 'Start'
|
||||
else:
|
||||
state = 'Data'
|
||||
data = []
|
||||
elif state == 'Data':
|
||||
data.append(b)
|
||||
if len(data) == msgSize:
|
||||
state = 'Checksum'
|
||||
elif state == 'Checksum':
|
||||
if checksum != 0:
|
||||
state = 'Start'
|
||||
else:
|
||||
return data
|
||||
|
||||
|
||||
def main():
|
||||
programmer = Stk500v2()
|
||||
programmer.connect(port = sys.argv[1])
|
||||
programmer.programChip(intelHex.readHex(sys.argv[2]))
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
|
@ -1,48 +1,48 @@
|
|||
import wx,wx.stc
|
||||
import sys,math,threading,os
|
||||
|
||||
from gui import gcodeTextArea
|
||||
from util import profile
|
||||
|
||||
class alterationPanel(wx.Panel):
|
||||
def __init__(self, parent):
|
||||
wx.Panel.__init__(self, parent,-1)
|
||||
|
||||
self.alterationFileList = ['start.gcode', 'end.gcode', 'nextobject.gcode', 'replace.csv']
|
||||
if int(profile.getPreference('extruder_amount')) > 1:
|
||||
self.alterationFileList.append('switchExtruder.gcode')
|
||||
self.currentFile = None
|
||||
|
||||
#self.textArea = wx.TextCtrl(self, style=wx.TE_MULTILINE|wx.TE_DONTWRAP|wx.TE_PROCESS_TAB)
|
||||
#self.textArea.SetFont(wx.Font(wx.SystemSettings.GetFont(wx.SYS_ANSI_VAR_FONT).GetPointSize(), wx.FONTFAMILY_MODERN, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL))
|
||||
self.textArea = gcodeTextArea.GcodeTextArea(self)
|
||||
self.list = wx.ListBox(self, choices=self.alterationFileList, style=wx.LB_SINGLE)
|
||||
self.list.SetSelection(0)
|
||||
self.Bind(wx.EVT_LISTBOX, self.OnSelect, self.list)
|
||||
self.textArea.Bind(wx.EVT_KILL_FOCUS, self.OnFocusLost, self.textArea)
|
||||
self.textArea.Bind(wx.stc.EVT_STC_CHANGE, self.OnFocusLost, self.textArea)
|
||||
|
||||
sizer = wx.GridBagSizer()
|
||||
sizer.Add(self.list, (0,0), span=(1,1), flag=wx.EXPAND)
|
||||
sizer.Add(self.textArea, (0,1), span=(1,1), flag=wx.EXPAND)
|
||||
sizer.AddGrowableCol(1)
|
||||
sizer.AddGrowableRow(0)
|
||||
self.SetSizer(sizer)
|
||||
|
||||
self.loadFile(self.alterationFileList[self.list.GetSelection()])
|
||||
self.currentFile = self.list.GetSelection()
|
||||
|
||||
def OnSelect(self, e):
|
||||
self.loadFile(self.alterationFileList[self.list.GetSelection()])
|
||||
self.currentFile = self.list.GetSelection()
|
||||
|
||||
def loadFile(self, filename):
|
||||
self.textArea.SetValue(profile.getAlterationFile(filename))
|
||||
|
||||
def OnFocusLost(self, e):
|
||||
if self.currentFile == self.list.GetSelection():
|
||||
profile.setAlterationFile(self.alterationFileList[self.list.GetSelection()], self.textArea.GetValue())
|
||||
|
||||
def updateProfileToControls(self):
|
||||
self.OnSelect(None)
|
||||
|
||||
import wx,wx.stc
|
||||
import sys,math,threading,os
|
||||
|
||||
from gui import gcodeTextArea
|
||||
from util import profile
|
||||
|
||||
class alterationPanel(wx.Panel):
|
||||
def __init__(self, parent):
|
||||
wx.Panel.__init__(self, parent,-1)
|
||||
|
||||
self.alterationFileList = ['start.gcode', 'end.gcode', 'nextobject.gcode', 'replace.csv']
|
||||
if int(profile.getPreference('extruder_amount')) > 1:
|
||||
self.alterationFileList.append('switchExtruder.gcode')
|
||||
self.currentFile = None
|
||||
|
||||
#self.textArea = wx.TextCtrl(self, style=wx.TE_MULTILINE|wx.TE_DONTWRAP|wx.TE_PROCESS_TAB)
|
||||
#self.textArea.SetFont(wx.Font(wx.SystemSettings.GetFont(wx.SYS_ANSI_VAR_FONT).GetPointSize(), wx.FONTFAMILY_MODERN, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL))
|
||||
self.textArea = gcodeTextArea.GcodeTextArea(self)
|
||||
self.list = wx.ListBox(self, choices=self.alterationFileList, style=wx.LB_SINGLE)
|
||||
self.list.SetSelection(0)
|
||||
self.Bind(wx.EVT_LISTBOX, self.OnSelect, self.list)
|
||||
self.textArea.Bind(wx.EVT_KILL_FOCUS, self.OnFocusLost, self.textArea)
|
||||
self.textArea.Bind(wx.stc.EVT_STC_CHANGE, self.OnFocusLost, self.textArea)
|
||||
|
||||
sizer = wx.GridBagSizer()
|
||||
sizer.Add(self.list, (0,0), span=(1,1), flag=wx.EXPAND)
|
||||
sizer.Add(self.textArea, (0,1), span=(1,1), flag=wx.EXPAND)
|
||||
sizer.AddGrowableCol(1)
|
||||
sizer.AddGrowableRow(0)
|
||||
self.SetSizer(sizer)
|
||||
|
||||
self.loadFile(self.alterationFileList[self.list.GetSelection()])
|
||||
self.currentFile = self.list.GetSelection()
|
||||
|
||||
def OnSelect(self, e):
|
||||
self.loadFile(self.alterationFileList[self.list.GetSelection()])
|
||||
self.currentFile = self.list.GetSelection()
|
||||
|
||||
def loadFile(self, filename):
|
||||
self.textArea.SetValue(profile.getAlterationFile(filename))
|
||||
|
||||
def OnFocusLost(self, e):
|
||||
if self.currentFile == self.list.GetSelection():
|
||||
profile.setAlterationFile(self.alterationFileList[self.list.GetSelection()], self.textArea.GetValue())
|
||||
|
||||
def updateProfileToControls(self):
|
||||
self.OnSelect(None)
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,496 +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 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)
|
||||
# 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)
|
||||
|
|
|
@ -1,82 +1,82 @@
|
|||
from __future__ import absolute_import
|
||||
import __init__
|
||||
|
||||
import wx, os, platform, types, string, glob, stat
|
||||
import ConfigParser
|
||||
|
||||
from gui import configBase
|
||||
from util import validators
|
||||
from util import machineCom
|
||||
from util import profile
|
||||
|
||||
class preferencesDialog(configBase.configWindowBase):
|
||||
def __init__(self, parent):
|
||||
super(preferencesDialog, self).__init__(title="Preferences", style=wx.DEFAULT_DIALOG_STYLE)
|
||||
|
||||
wx.EVT_CLOSE(self, self.OnClose)
|
||||
|
||||
self.parent = parent
|
||||
self.oldExtruderAmount = int(profile.getPreference('extruder_amount'))
|
||||
|
||||
left, right, main = self.CreateConfigPanel(self)
|
||||
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, 'Maximum width (mm)', 'machine_width', '205', 'Size of the machine in mm', type = 'preference')
|
||||
validators.validFloat(c, 10.0)
|
||||
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, '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')
|
||||
|
||||
for i in xrange(1, self.oldExtruderAmount):
|
||||
configBase.TitleRow(left, 'Extruder %d' % (i+1))
|
||||
c = configBase.SettingRow(left, 'Offset X', 'extruder_offset_x%d' % (i), '0.0', 'The offset of your secondary extruder compared to the primary.', type = 'preference')
|
||||
validators.validFloat(c)
|
||||
c = configBase.SettingRow(left, 'Offset Y', 'extruder_offset_y%d' % (i), '0.0', 'The offset of your secondary extruder compared to the primary.', type = 'preference')
|
||||
validators.validFloat(c)
|
||||
|
||||
configBase.TitleRow(left, 'Colours')
|
||||
c = configBase.SettingRow(left, 'Model colour', 'model_colour', wx.Colour(0,0,0), '', type = 'preference')
|
||||
for i in xrange(1, self.oldExtruderAmount):
|
||||
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, '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, '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, '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')
|
||||
c = configBase.SettingRow(right, 'Serial port', 'serial_port', ['AUTO'] + machineCom.serialList(), 'Serial port to use for communication with the printer', type = 'preference')
|
||||
c = configBase.SettingRow(right, 'Baudrate', 'serial_baud', ['AUTO'] + map(str, machineCom.baudrateList()), 'Speed of the serial port communication\nNeeds to match your firmware settings\nCommon values are 250000, 115200, 57600', type = 'preference')
|
||||
|
||||
configBase.TitleRow(right, 'Slicer settings')
|
||||
#c = configBase.SettingRow(right, 'Slicer selection', 'slicer', ['Cura (Skeinforge based)', 'Slic3r'], 'Which slicer to use to slice objects. Usually the Cura engine produces the best results. But Slic3r is developing fast and is faster with slicing.', type = 'preference')
|
||||
c = configBase.SettingRow(right, 'Save profile on slice', 'save_profile', False, 'When slicing save the profile as [stl_file]_profile.ini next to the model.', type = 'preference')
|
||||
|
||||
configBase.TitleRow(right, 'SD Card settings')
|
||||
if len(profile.getSDcardDrives()) > 1:
|
||||
c = configBase.SettingRow(right, 'SD card drive', 'sdpath', profile.getSDcardDrives(), 'Location of your SD card, when using the copy to SD feature.', type = 'preference')
|
||||
else:
|
||||
c = configBase.SettingRow(right, 'SD card path', 'sdpath', '', 'Location of your SD card, when using the copy to SD feature.', type = 'preference')
|
||||
c = configBase.SettingRow(right, 'Copy to SD with 8.3 names', 'sdshortnames', False, 'Save the gcode files in short filenames, so they are properly shown on the UltiController', type = 'preference')
|
||||
|
||||
self.okButton = wx.Button(right, -1, 'Ok')
|
||||
right.GetSizer().Add(self.okButton, (right.GetSizer().GetRows(), 0), flag=wx.BOTTOM, border=5)
|
||||
self.okButton.Bind(wx.EVT_BUTTON, self.OnClose)
|
||||
|
||||
self.MakeModal(True)
|
||||
main.Fit()
|
||||
self.Fit()
|
||||
|
||||
def OnClose(self, e):
|
||||
if self.oldExtruderAmount != int(profile.getPreference('extruder_amount')):
|
||||
wx.MessageBox('After changing the amount of extruders you need to restart Cura for full effect.', 'Extruder amount warning.', wx.OK | wx.ICON_INFORMATION)
|
||||
self.MakeModal(False)
|
||||
self.parent.updateProfileToControls()
|
||||
self.Destroy()
|
||||
from __future__ import absolute_import
|
||||
import __init__
|
||||
|
||||
import wx, os, platform, types, string, glob, stat
|
||||
import ConfigParser
|
||||
|
||||
from gui import configBase
|
||||
from util import validators
|
||||
from util import machineCom
|
||||
from util import profile
|
||||
|
||||
class preferencesDialog(configBase.configWindowBase):
|
||||
def __init__(self, parent):
|
||||
super(preferencesDialog, self).__init__(title="Preferences", style=wx.DEFAULT_DIALOG_STYLE)
|
||||
|
||||
wx.EVT_CLOSE(self, self.OnClose)
|
||||
|
||||
self.parent = parent
|
||||
self.oldExtruderAmount = int(profile.getPreference('extruder_amount'))
|
||||
|
||||
left, right, main = self.CreateConfigPanel(self)
|
||||
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, 'Maximum width (mm)', 'machine_width', '205', 'Size of the machine in mm', type = 'preference')
|
||||
validators.validFloat(c, 10.0)
|
||||
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, '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')
|
||||
|
||||
for i in xrange(1, self.oldExtruderAmount):
|
||||
configBase.TitleRow(left, 'Extruder %d' % (i+1))
|
||||
c = configBase.SettingRow(left, 'Offset X', 'extruder_offset_x%d' % (i), '0.0', 'The offset of your secondary extruder compared to the primary.', type = 'preference')
|
||||
validators.validFloat(c)
|
||||
c = configBase.SettingRow(left, 'Offset Y', 'extruder_offset_y%d' % (i), '0.0', 'The offset of your secondary extruder compared to the primary.', type = 'preference')
|
||||
validators.validFloat(c)
|
||||
|
||||
configBase.TitleRow(left, 'Colours')
|
||||
c = configBase.SettingRow(left, 'Model colour', 'model_colour', wx.Colour(0,0,0), '', type = 'preference')
|
||||
for i in xrange(1, self.oldExtruderAmount):
|
||||
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, '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, '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, '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')
|
||||
c = configBase.SettingRow(right, 'Serial port', 'serial_port', ['AUTO'] + machineCom.serialList(), 'Serial port to use for communication with the printer', type = 'preference')
|
||||
c = configBase.SettingRow(right, 'Baudrate', 'serial_baud', ['AUTO'] + map(str, machineCom.baudrateList()), 'Speed of the serial port communication\nNeeds to match your firmware settings\nCommon values are 250000, 115200, 57600', type = 'preference')
|
||||
|
||||
configBase.TitleRow(right, 'Slicer settings')
|
||||
#c = configBase.SettingRow(right, 'Slicer selection', 'slicer', ['Cura (Skeinforge based)', 'Slic3r'], 'Which slicer to use to slice objects. Usually the Cura engine produces the best results. But Slic3r is developing fast and is faster with slicing.', type = 'preference')
|
||||
c = configBase.SettingRow(right, 'Save profile on slice', 'save_profile', False, 'When slicing save the profile as [stl_file]_profile.ini next to the model.', type = 'preference')
|
||||
|
||||
configBase.TitleRow(right, 'SD Card settings')
|
||||
if len(profile.getSDcardDrives()) > 1:
|
||||
c = configBase.SettingRow(right, 'SD card drive', 'sdpath', profile.getSDcardDrives(), 'Location of your SD card, when using the copy to SD feature.', type = 'preference')
|
||||
else:
|
||||
c = configBase.SettingRow(right, 'SD card path', 'sdpath', '', 'Location of your SD card, when using the copy to SD feature.', type = 'preference')
|
||||
c = configBase.SettingRow(right, 'Copy to SD with 8.3 names', 'sdshortnames', False, 'Save the gcode files in short filenames, so they are properly shown on the UltiController', type = 'preference')
|
||||
|
||||
self.okButton = wx.Button(right, -1, 'Ok')
|
||||
right.GetSizer().Add(self.okButton, (right.GetSizer().GetRows(), 0), flag=wx.BOTTOM, border=5)
|
||||
self.okButton.Bind(wx.EVT_BUTTON, self.OnClose)
|
||||
|
||||
self.MakeModal(True)
|
||||
main.Fit()
|
||||
self.Fit()
|
||||
|
||||
def OnClose(self, e):
|
||||
if self.oldExtruderAmount != int(profile.getPreference('extruder_amount')):
|
||||
wx.MessageBox('After changing the amount of extruders you need to restart Cura for full effect.', 'Extruder amount warning.', wx.OK | wx.ICON_INFORMATION)
|
||||
self.MakeModal(False)
|
||||
self.parent.updateProfileToControls()
|
||||
self.Destroy()
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
1270
Cura/util/profile.py
1270
Cura/util/profile.py
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue