Large configuration update, the new UI now starts to work a bit.
Still missing a bunch of configuration settings. And the start/end code is not editable yet, and never included.
This commit is contained in:
parent
66ed99c4db
commit
68944bb221
4 changed files with 184 additions and 74 deletions
|
@ -14,7 +14,7 @@ def getSkeinPyPyConfigInformation():
|
||||||
return {
|
return {
|
||||||
'carve': {
|
'carve': {
|
||||||
'Add_Layer_Template_to_SVG': 'ignore',
|
'Add_Layer_Template_to_SVG': 'ignore',
|
||||||
'Edge_Width_mm': 'ignore',
|
'Edge_Width_mm': 'save',
|
||||||
'Extra_Decimal_Places_float': 'ignore',
|
'Extra_Decimal_Places_float': 'ignore',
|
||||||
'Import_Coarseness_ratio': 'ignore',
|
'Import_Coarseness_ratio': 'ignore',
|
||||||
'Layer_Height_mm': 'save',
|
'Layer_Height_mm': 'save',
|
||||||
|
@ -71,7 +71,7 @@ def getSkeinPyPyConfigInformation():
|
||||||
'Line': 'ignore',
|
'Line': 'ignore',
|
||||||
'Infill_Perimeter_Overlap_ratio': 'save',
|
'Infill_Perimeter_Overlap_ratio': 'save',
|
||||||
'Infill_Solidity_ratio': 'save',
|
'Infill_Solidity_ratio': 'save',
|
||||||
'Infill_Width': 'save',
|
'Infill_Width': 'use:carve:Edge_Width_mm',
|
||||||
'Solid_Surface_Thickness_layers': 'save',
|
'Solid_Surface_Thickness_layers': 'save',
|
||||||
'Start_From_Choice': 'ignore',
|
'Start_From_Choice': 'ignore',
|
||||||
'Surrounding_Angle_degrees': 'ignore',
|
'Surrounding_Angle_degrees': 'ignore',
|
||||||
|
@ -92,12 +92,12 @@ def getSkeinPyPyConfigInformation():
|
||||||
'Duty_Cyle_at_Beginning_portion': 'ignore',
|
'Duty_Cyle_at_Beginning_portion': 'ignore',
|
||||||
'Duty_Cyle_at_Ending_portion': 'ignore',
|
'Duty_Cyle_at_Ending_portion': 'ignore',
|
||||||
'Feed_Rate_mm/s': 'save',
|
'Feed_Rate_mm/s': 'save',
|
||||||
'Flow_Rate_Setting_float': 'use:Feed_Rate_mm/s',
|
'Flow_Rate_Setting_float': 'use:speed:Feed_Rate_mm/s',
|
||||||
'Object_First_Layer_Feed_Rate_Infill_Multiplier_ratio': 'save',
|
'Object_First_Layer_Feed_Rate_Infill_Multiplier_ratio': 'save',
|
||||||
'Object_First_Layer_Feed_Rate_Perimeter_Multiplier_ratio': 'use:Object_First_Layer_Feed_Rate_Infill_Multiplier_ratio',
|
'Object_First_Layer_Feed_Rate_Perimeter_Multiplier_ratio': 'use:speed:Object_First_Layer_Feed_Rate_Infill_Multiplier_ratio',
|
||||||
'Object_First_Layer_Feed_Rate_Travel_Multiplier_ratio': 'use:Object_First_Layer_Feed_Rate_Infill_Multiplier_ratio',
|
'Object_First_Layer_Feed_Rate_Travel_Multiplier_ratio': 'use:speed:Object_First_Layer_Feed_Rate_Infill_Multiplier_ratio',
|
||||||
'Object_First_Layer_Flow_Rate_Infill_Multiplier_ratio': 'use:Object_First_Layer_Feed_Rate_Infill_Multiplier_ratio',
|
'Object_First_Layer_Flow_Rate_Infill_Multiplier_ratio': 'use:speed:Object_First_Layer_Feed_Rate_Infill_Multiplier_ratio',
|
||||||
'Object_First_Layer_Flow_Rate_Perimeter_Multiplier_ratio': 'use:Object_First_Layer_Feed_Rate_Infill_Multiplier_ratio',
|
'Object_First_Layer_Flow_Rate_Perimeter_Multiplier_ratio': 'use:speed:Object_First_Layer_Feed_Rate_Infill_Multiplier_ratio',
|
||||||
'Object_First_Layers_Amount_Of_Layers_For_Speed_Change': 'save',
|
'Object_First_Layers_Amount_Of_Layers_For_Speed_Change': 'save',
|
||||||
'Orbital_Feed_Rate_over_Operating_Feed_Rate_ratio': 'ignore',
|
'Orbital_Feed_Rate_over_Operating_Feed_Rate_ratio': 'ignore',
|
||||||
'Maximum_Z_Feed_Rate_mm/s': 'save',
|
'Maximum_Z_Feed_Rate_mm/s': 'save',
|
||||||
|
@ -345,7 +345,8 @@ def getReadRepository(repository):
|
||||||
continue
|
continue
|
||||||
#Load this setting from another value.
|
#Load this setting from another value.
|
||||||
if info[name][0:4] == "use:":
|
if info[name][0:4] == "use:":
|
||||||
p.setValueToString(globalConfigParser.get(repository.name, info[name][4:]))
|
i = info[name][4:].split(':')
|
||||||
|
p.setValueToString(globalConfigParser.get(i[0], i[1]))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -357,10 +358,35 @@ def getReadRepository(repository):
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
globalConfigParser.set(repository.name, name, str(p.value))
|
globalConfigParser.set(repository.name, name, str(p.value))
|
||||||
saveGlobalConfig(getDefaultConfigPath())
|
#saveGlobalConfig(getDefaultConfigPath())
|
||||||
#print "============" + str(p) + "|" + p.name + "|" + str(p.value) + "|" + str(type(p.value))
|
#print "============" + str(p) + "|" + p.name + "|" + str(p.value) + "|" + str(type(p.value))
|
||||||
return repository
|
return repository
|
||||||
|
|
||||||
|
def storeRepository(repository):
|
||||||
|
"Store the configuration for this 'repository'"
|
||||||
|
#Check if we have a configuration file loaded, else load the default.
|
||||||
|
if not globals().has_key('globalConfigParser'):
|
||||||
|
loadGlobalConfig(getDefaultConfigPath())
|
||||||
|
|
||||||
|
info = getSkeinPyPyConfigInformation()
|
||||||
|
if not info.has_key(repository.name):
|
||||||
|
print "Warning: Plugin: " + repository.name + " missing from SkeinPyPy info"
|
||||||
|
return repository
|
||||||
|
info = info[repository.name]
|
||||||
|
if not type(info) is dict:
|
||||||
|
print "Ignoring plugin configuration: " + repository.name
|
||||||
|
return repository
|
||||||
|
|
||||||
|
for p in repository.preferences:
|
||||||
|
name = safeConfigName(p.name)
|
||||||
|
if not info.has_key(name):
|
||||||
|
print "Setting: " + repository.name + ":" + name + " missing from SkeinPyPy info"
|
||||||
|
continue
|
||||||
|
|
||||||
|
if info[name] == "save":
|
||||||
|
globalConfigParser.set(repository.name, name, str(p.value))
|
||||||
|
return repository
|
||||||
|
|
||||||
def printProgress(layerIndex, procedureName):
|
def printProgress(layerIndex, procedureName):
|
||||||
print("Progress: ", procedureName, layerIndex)
|
print("Progress: ", procedureName, layerIndex)
|
||||||
def printProgressByNumber(layerIndex, numberOfLayers, procedureName):
|
def printProgressByNumber(layerIndex, numberOfLayers, procedureName):
|
||||||
|
@ -491,6 +517,7 @@ class FloatSpin( FloatSetting ):
|
||||||
"Initialize."
|
"Initialize."
|
||||||
self.name = name
|
self.name = name
|
||||||
self.value = value
|
self.value = value
|
||||||
|
if repository != None:
|
||||||
repository.preferences.append(self)
|
repository.preferences.append(self)
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
import __init__
|
import __init__
|
||||||
|
|
||||||
|
import skeinpypy
|
||||||
|
|
||||||
import wx, os
|
import wx, os
|
||||||
|
|
||||||
from newui import preview3d
|
from newui import preview3d
|
||||||
|
@ -21,62 +23,86 @@ class mainWindow(wx.Frame):
|
||||||
fileMenu = wx.Menu()
|
fileMenu = wx.Menu()
|
||||||
fitem = fileMenu.Append(-1, 'Open Profile...', 'Open Profile...')
|
fitem = fileMenu.Append(-1, 'Open Profile...', 'Open Profile...')
|
||||||
fitem = fileMenu.Append(-1, 'Save Profile...', 'Save Profile...')
|
fitem = fileMenu.Append(-1, 'Save Profile...', 'Save Profile...')
|
||||||
|
self.Bind(wx.EVT_MENU, self.OnSaveProfile, fitem)
|
||||||
fitem = fileMenu.Append(wx.ID_EXIT, 'Quit', 'Quit application')
|
fitem = fileMenu.Append(wx.ID_EXIT, 'Quit', 'Quit application')
|
||||||
self.Bind(wx.EVT_MENU, self.OnQuit, fitem)
|
self.Bind(wx.EVT_MENU, self.OnQuit, fitem)
|
||||||
menubar.Append(fileMenu, '&File')
|
menubar.Append(fileMenu, '&File')
|
||||||
menubar.Append(wx.Menu(), 'Expert')
|
menubar.Append(wx.Menu(), 'Expert')
|
||||||
self.SetMenuBar(menubar)
|
self.SetMenuBar(menubar)
|
||||||
|
|
||||||
plugins = {}
|
self.filename = None
|
||||||
|
self.controlList = []
|
||||||
|
self.plugins = {}
|
||||||
for m in skeinforge_profile.getCraftTypePluginModule().getCraftSequence():
|
for m in skeinforge_profile.getCraftTypePluginModule().getCraftSequence():
|
||||||
plugins[m] = archive.getModuleWithDirectoryPath(archive.getCraftPluginsDirectoryPath(), m).getNewRepository()
|
self.plugins[m] = archive.getModuleWithDirectoryPath(archive.getCraftPluginsDirectoryPath(), m).getNewRepository()
|
||||||
settings.getReadRepository(plugins[m])
|
settings.getReadRepository(self.plugins[m])
|
||||||
|
|
||||||
|
skeinPyPySettingInfo = settings.getSkeinPyPyConfigInformation()
|
||||||
|
|
||||||
|
for pluginName in self.plugins.keys():
|
||||||
|
self.plugins[pluginName].preferencesDict = {}
|
||||||
|
for pref in self.plugins[pluginName].preferences:
|
||||||
|
if skeinPyPySettingInfo[pluginName][settings.safeConfigName(pref.name)] == 'save':
|
||||||
|
self.plugins[pluginName].preferencesDict[settings.safeConfigName(pref.name)] = pref
|
||||||
|
|
||||||
p = wx.Panel(self)
|
p = wx.Panel(self)
|
||||||
nb = wx.Notebook(p, size=(500,10))
|
nb = wx.Notebook(p, size=(500,10))
|
||||||
|
|
||||||
printConfig = wx.Panel(nb);
|
configPanel = wx.Panel(nb);
|
||||||
|
nb.AddPage(configPanel, "Print")
|
||||||
sizer = wx.GridBagSizer(2, 2)
|
sizer = wx.GridBagSizer(2, 2)
|
||||||
printConfig.SetSizer(sizer)
|
configPanel.SetSizer(sizer)
|
||||||
|
|
||||||
skeinPyPySettingInfo = settings.getSkeinPyPyConfigInformation()
|
self.AddTitle(configPanel, "Accuracy")
|
||||||
|
self.AddSetting(configPanel, "Layer height (mm)", self.plugins['carve'].preferencesDict['Layer_Height_mm'])
|
||||||
|
self.AddTitle(configPanel, "Skirt")
|
||||||
|
self.AddSetting(configPanel, "Enable skirt", self.plugins['skirt'].preferencesDict['Activate_Skirt'])
|
||||||
|
self.AddSetting(configPanel, "Skirt distance (mm)", self.plugins['skirt'].preferencesDict['Gap_over_Perimeter_Width_ratio'])
|
||||||
|
self.AddTitle(configPanel, "Fill")
|
||||||
|
self.AddSetting(configPanel, "Solid layers", self.plugins['fill'].preferencesDict['Solid_Surface_Thickness_layers'])
|
||||||
|
self.AddSetting(configPanel, "Fill Density", self.plugins['fill'].preferencesDict['Infill_Solidity_ratio'])
|
||||||
|
self.AddTitle(configPanel, "Retraction")
|
||||||
|
self.AddSetting(configPanel, "Speed (mm/s)", self.plugins['dimension'].preferencesDict['Extruder_Retraction_Speed_mm/s'])
|
||||||
|
self.AddSetting(configPanel, "Distance (mm)", self.plugins['dimension'].preferencesDict['Retraction_Distance_millimeters'])
|
||||||
|
self.AddSetting(configPanel, "Extra length on start (mm)", self.plugins['dimension'].preferencesDict['Restart_Extra_Distance_millimeters'])
|
||||||
|
|
||||||
for pluginName in plugins.keys():
|
configPanel = wx.Panel(nb);
|
||||||
box, configPanel = self.CreateGroup(printConfig, pluginName)
|
nb.AddPage(configPanel, "Machine")
|
||||||
|
|
||||||
for pref in plugins[pluginName].preferences:
|
|
||||||
if skeinPyPySettingInfo[pluginName][settings.safeConfigName(pref.name)] == 'save':
|
|
||||||
self.AddSetting(configPanel, pref.name, wx.TextCtrl(configPanel, -1, str(pref.value)))
|
|
||||||
|
|
||||||
if configPanel.GetSizer().GetRows() > 0:
|
|
||||||
sizer.Add(box, (sizer.GetRows(),0))
|
|
||||||
sizer.SetRows(sizer.GetRows()+1)
|
|
||||||
|
|
||||||
#self.AddSetting(generalConfig, "Speed (mm/s)", wx.TextCtrl(generalConfig, -1, "50.0"))
|
|
||||||
|
|
||||||
machineConfig = wx.Panel(nb);
|
|
||||||
sizer = wx.GridBagSizer(2, 2)
|
sizer = wx.GridBagSizer(2, 2)
|
||||||
machineConfig.SetSizer(sizer)
|
configPanel.SetSizer(sizer)
|
||||||
box, dimensionsConfig = self.CreateGroup(machineConfig, "Dimensions")
|
|
||||||
self.AddSetting(dimensionsConfig, "Printer size (mm)", wx.TextCtrl(dimensionsConfig, -1, "205,205,200"))
|
self.AddTitle(configPanel, "Machine size")
|
||||||
sizer.Add(box, (0,0))
|
self.AddSetting(configPanel, "Width (mm)", settings.IntSpin().getFromValue(10, "machine_width", None, 1000, 205))
|
||||||
|
self.AddSetting(configPanel, "Depth (mm)", settings.IntSpin().getFromValue(10, "machine_depth", None, 1000, 205))
|
||||||
|
self.AddSetting(configPanel, "Height (mm)", settings.IntSpin().getFromValue(10, "machine_height", None, 1000, 200))
|
||||||
|
|
||||||
|
self.AddTitle(configPanel, "Machine nozzle")
|
||||||
|
self.AddSetting(configPanel, "Nozzle size (mm)", self.plugins['carve'].preferencesDict['Edge_Width_mm'])
|
||||||
|
|
||||||
|
self.AddTitle(configPanel, "Speed")
|
||||||
|
self.AddSetting(configPanel, "Print speed (mm/s)", self.plugins['speed'].preferencesDict['Feed_Rate_mm/s'])
|
||||||
|
self.AddSetting(configPanel, "Travel speed (mm/s)", self.plugins['speed'].preferencesDict['Travel_Feed_Rate_mm/s'])
|
||||||
|
|
||||||
|
self.AddTitle(configPanel, "Filament")
|
||||||
|
self.AddSetting(configPanel, "Diameter (mm)", self.plugins['dimension'].preferencesDict['Filament_Diameter_mm'])
|
||||||
|
self.AddSetting(configPanel, "Packing Density", self.plugins['dimension'].preferencesDict['Filament_Packing_Density_ratio'])
|
||||||
|
|
||||||
nb.AddPage(printConfig, "Print")
|
|
||||||
nb.AddPage(machineConfig, "Machine")
|
|
||||||
nb.AddPage(wx.Panel(nb), "Start/End-GCode")
|
nb.AddPage(wx.Panel(nb), "Start/End-GCode")
|
||||||
|
|
||||||
#Preview window, load and slice buttons.
|
#Preview window, load and slice buttons.
|
||||||
self.preview3d = preview3d.myGLCanvas(p)
|
self.preview3d = preview3d.myGLCanvas(p)
|
||||||
|
|
||||||
loadButton = wx.Button(p, 1, 'Load STL')
|
loadButton = wx.Button(p, -1, 'Load STL')
|
||||||
|
sliceButton = wx.Button(p, -1, 'Slice to GCode')
|
||||||
self.Bind(wx.EVT_BUTTON, self.OnLoadSTL, loadButton)
|
self.Bind(wx.EVT_BUTTON, self.OnLoadSTL, loadButton)
|
||||||
|
self.Bind(wx.EVT_BUTTON, self.OnSlice, sliceButton)
|
||||||
|
|
||||||
sizer = wx.GridBagSizer()
|
sizer = wx.GridBagSizer()
|
||||||
sizer.Add(nb, (0,0), span=(2,1), flag=wx.EXPAND)
|
sizer.Add(nb, (0,0), span=(2,1), flag=wx.EXPAND)
|
||||||
sizer.Add(self.preview3d, (0,1), span=(1,1), flag=wx.EXPAND)
|
sizer.Add(self.preview3d, (0,1), span=(1,3), flag=wx.EXPAND)
|
||||||
sizer.Add(loadButton, (1,1))
|
sizer.Add(loadButton, (1,1))
|
||||||
sizer.AddGrowableCol(1)
|
sizer.Add(sliceButton, (1,2))
|
||||||
|
sizer.AddGrowableCol(2)
|
||||||
sizer.AddGrowableRow(0)
|
sizer.AddGrowableRow(0)
|
||||||
p.SetSizer(sizer)
|
p.SetSizer(sizer)
|
||||||
|
|
||||||
|
@ -84,32 +110,65 @@ class mainWindow(wx.Frame):
|
||||||
self.Centre()
|
self.Centre()
|
||||||
self.Show(True)
|
self.Show(True)
|
||||||
|
|
||||||
def CreateGroup(self, panel, name):
|
def AddTitle(self, panel, name):
|
||||||
retPanel = wx.Panel(panel)
|
|
||||||
sizer = wx.GridBagSizer(2, 2)
|
|
||||||
retPanel.SetSizer(sizer)
|
|
||||||
|
|
||||||
box = wx.StaticBox(panel, -1, name)
|
|
||||||
sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
|
|
||||||
sizer.Add(retPanel)
|
|
||||||
|
|
||||||
return (sizer, retPanel)
|
|
||||||
|
|
||||||
def AddSetting(self, panel, name, ctrl):
|
|
||||||
sizer = panel.GetSizer()
|
sizer = panel.GetSizer()
|
||||||
sizer.Add(wx.StaticText(panel, -1, name), (sizer.GetRows(),0), flag=wx.ALIGN_BOTTOM)
|
title = wx.StaticText(panel, -1, name)
|
||||||
sizer.Add(ctrl, (sizer.GetRows(),1), flag=wx.ALIGN_BOTTOM|wx.EXPAND)
|
title.SetFont(wx.Font(8, wx.FONTFAMILY_DEFAULT, wx.NORMAL, wx.FONTWEIGHT_BOLD))
|
||||||
|
sizer.Add(title, (sizer.GetRows(),1), (1,2), flag=wx.EXPAND)
|
||||||
|
sizer.Add(wx.StaticLine(panel), (sizer.GetRows()+1,1), (1,2), flag=wx.EXPAND)
|
||||||
|
sizer.SetRows(sizer.GetRows() + 2)
|
||||||
|
|
||||||
|
def AddSetting(self, panel, name, setting):
|
||||||
|
sizer = panel.GetSizer()
|
||||||
|
sizer.Add(wx.StaticText(panel, -1, name), (sizer.GetRows(),1), flag=wx.ALIGN_CENTER_VERTICAL)
|
||||||
|
ctrl = None
|
||||||
|
if setting.__class__ is settings.FloatSpin:
|
||||||
|
ctrl = wx.TextCtrl(panel, -1, str(setting.value))
|
||||||
|
if setting.__class__ is settings.IntSpin:
|
||||||
|
ctrl = wx.TextCtrl(panel, -1, str(setting.value))
|
||||||
|
if setting.__class__ is settings.BooleanSetting:
|
||||||
|
ctrl = wx.CheckBox(panel, -1, '')
|
||||||
|
ctrl.SetValue(setting.value)
|
||||||
|
if ctrl == None:
|
||||||
|
print "No WX control for: " + str(setting), str(setting.__class__)
|
||||||
|
else:
|
||||||
|
ctrl.setting = setting
|
||||||
|
self.controlList.append(ctrl)
|
||||||
|
sizer.Add(ctrl, (sizer.GetRows(),2), flag=wx.ALIGN_BOTTOM|wx.EXPAND)
|
||||||
sizer.SetRows(sizer.GetRows()+1)
|
sizer.SetRows(sizer.GetRows()+1)
|
||||||
|
|
||||||
|
def OnSaveProfile(self, e):
|
||||||
|
dlg=wx.FileDialog(self, "Select profile file to save", style=wx.FD_SAVE)
|
||||||
|
dlg.SetWildcard("ini files (*.ini)|*.ini")
|
||||||
|
if dlg.ShowModal() == wx.ID_OK:
|
||||||
|
profileFile = dlg.GetPath()
|
||||||
|
self.updateConfig()
|
||||||
|
settings.saveGlobalConfig(profileFile)
|
||||||
|
|
||||||
def OnLoadSTL(self, e):
|
def OnLoadSTL(self, e):
|
||||||
dlg=wx.FileDialog(self, "Open file to print", style=wx.FD_OPEN|wx.FD_FILE_MUST_EXIST)
|
dlg=wx.FileDialog(self, "Open file to print", style=wx.FD_OPEN|wx.FD_FILE_MUST_EXIST)
|
||||||
dlg.SetWildcard("OBJ, STL files (;*.stl;*.STL;*.obj;*.OBJ;)")
|
dlg.SetWildcard("OBJ, STL files (*.stl;*.STL;*.obj;*.OBJ;)")
|
||||||
if dlg.ShowModal() == wx.ID_OK:
|
if dlg.ShowModal() == wx.ID_OK:
|
||||||
self.filename=dlg.GetPath()
|
self.filename=dlg.GetPath()
|
||||||
if not(os.path.exists(self.filename)):
|
if not(os.path.exists(self.filename)):
|
||||||
return
|
return
|
||||||
self.preview3d.loadFile(self.filename)
|
self.preview3d.loadFile(self.filename)
|
||||||
|
|
||||||
|
def OnSlice(self, e):
|
||||||
|
if self.filename == None:
|
||||||
|
return
|
||||||
|
for pluginName in self.plugins.keys():
|
||||||
|
settings.storeRepository(self.plugins[pluginName])
|
||||||
|
settings.saveGlobalConfig(settings.getDefaultConfigPath())
|
||||||
|
skeinpypy.runSkein([self.filename])
|
||||||
|
|
||||||
|
def updateConfig(self):
|
||||||
|
for ctrl in self.controlList:
|
||||||
|
ctrl.setting.setValueToString(ctrl.GetValue())
|
||||||
|
for pluginName in self.plugins.keys():
|
||||||
|
settings.storeRepository(self.plugins[pluginName])
|
||||||
|
settings.saveGlobalConfig(settings.getDefaultConfigPath())
|
||||||
|
|
||||||
def OnQuit(self, e):
|
def OnQuit(self, e):
|
||||||
self.Close()
|
self.Close()
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#from wxPython.glcanvas import wxGLCanvas
|
#from wxPython.glcanvas import wxGLCanvas
|
||||||
import wx
|
import wx
|
||||||
import sys,math
|
import sys,math,threading
|
||||||
|
|
||||||
from wx.glcanvas import GLCanvas
|
from wx.glcanvas import GLCanvas
|
||||||
try:
|
try:
|
||||||
|
@ -24,6 +24,7 @@ class myGLCanvas(GLCanvas):
|
||||||
wx.EVT_MOTION(self, self.OnMouseMotion)
|
wx.EVT_MOTION(self, self.OnMouseMotion)
|
||||||
self.init = 0
|
self.init = 0
|
||||||
self.triangleMesh = None
|
self.triangleMesh = None
|
||||||
|
self.modelDisplayList = None
|
||||||
self.yaw = 30
|
self.yaw = 30
|
||||||
self.pitch = 60
|
self.pitch = 60
|
||||||
self.zoom = 150
|
self.zoom = 150
|
||||||
|
@ -31,8 +32,17 @@ class myGLCanvas(GLCanvas):
|
||||||
self.machineCenter = Vector3(100, 100, 0)
|
self.machineCenter = Vector3(100, 100, 0)
|
||||||
|
|
||||||
def loadFile(self, filename):
|
def loadFile(self, filename):
|
||||||
self.triangleMesh = fabmetheus_interpret.getCarving(filename)
|
self.filename = filename
|
||||||
|
#Do the STL file loading in a background thread so we don't block the UI.
|
||||||
|
thread = threading.Thread(target=self.DoLoad)
|
||||||
|
thread.setDaemon(True)
|
||||||
|
thread.start()
|
||||||
|
|
||||||
|
def DoLoad(self):
|
||||||
|
self.modelDirty = False
|
||||||
|
self.triangleMesh = fabmetheus_interpret.getCarving(self.filename)
|
||||||
self.moveModel()
|
self.moveModel()
|
||||||
|
self.Refresh()
|
||||||
|
|
||||||
def moveModel(self):
|
def moveModel(self):
|
||||||
if self.triangleMesh == None:
|
if self.triangleMesh == None:
|
||||||
|
@ -46,6 +56,8 @@ class myGLCanvas(GLCanvas):
|
||||||
v.y -= min.y + (max.y - min.y) / 2
|
v.y -= min.y + (max.y - min.y) / 2
|
||||||
v.x += self.machineCenter.x
|
v.x += self.machineCenter.x
|
||||||
v.y += self.machineCenter.y
|
v.y += self.machineCenter.y
|
||||||
|
self.triangleMesh.getMinimumZ()
|
||||||
|
self.modelDirty = True
|
||||||
|
|
||||||
def OnMouseMotion(self,e):
|
def OnMouseMotion(self,e):
|
||||||
if e.Dragging() and e.LeftIsDown():
|
if e.Dragging() and e.LeftIsDown():
|
||||||
|
@ -55,11 +67,12 @@ class myGLCanvas(GLCanvas):
|
||||||
self.pitch = 170
|
self.pitch = 170
|
||||||
if self.pitch < 10:
|
if self.pitch < 10:
|
||||||
self.pitch = 10
|
self.pitch = 10
|
||||||
|
self.Refresh()
|
||||||
if e.Dragging() and e.RightIsDown():
|
if e.Dragging() and e.RightIsDown():
|
||||||
self.zoom += e.GetY() - self.oldY
|
self.zoom += e.GetY() - self.oldY
|
||||||
|
self.Refresh()
|
||||||
self.oldX = e.GetX()
|
self.oldX = e.GetX()
|
||||||
self.oldY = e.GetY()
|
self.oldY = e.GetY()
|
||||||
self.Refresh()
|
|
||||||
|
|
||||||
def OnEraseBackground(self,event):
|
def OnEraseBackground(self,event):
|
||||||
pass
|
pass
|
||||||
|
@ -85,6 +98,11 @@ class myGLCanvas(GLCanvas):
|
||||||
glTranslate(-self.machineCenter.x, -self.machineCenter.y, 0)
|
glTranslate(-self.machineCenter.x, -self.machineCenter.y, 0)
|
||||||
|
|
||||||
if self.triangleMesh != None:
|
if self.triangleMesh != None:
|
||||||
|
if self.modelDisplayList == None:
|
||||||
|
self.modelDisplayList = glGenLists(1);
|
||||||
|
if self.modelDirty:
|
||||||
|
self.modelDirty = False
|
||||||
|
glNewList(self.modelDisplayList, GL_COMPILE)
|
||||||
glBegin(GL_TRIANGLES)
|
glBegin(GL_TRIANGLES)
|
||||||
for face in self.triangleMesh.faces:
|
for face in self.triangleMesh.faces:
|
||||||
v1 = self.triangleMesh.vertexes[face.vertexIndexes[0]]
|
v1 = self.triangleMesh.vertexes[face.vertexIndexes[0]]
|
||||||
|
@ -97,6 +115,8 @@ class myGLCanvas(GLCanvas):
|
||||||
glVertex3f(v2.x, v2.y, v2.z)
|
glVertex3f(v2.x, v2.y, v2.z)
|
||||||
glVertex3f(v3.x, v3.y, v3.z)
|
glVertex3f(v3.x, v3.y, v3.z)
|
||||||
glEnd()
|
glEnd()
|
||||||
|
glEndList()
|
||||||
|
glCallList(self.modelDisplayList)
|
||||||
|
|
||||||
glLineWidth(4)
|
glLineWidth(4)
|
||||||
glDisable(GL_LIGHTING)
|
glDisable(GL_LIGHTING)
|
||||||
|
@ -160,6 +180,6 @@ class myGLCanvas(GLCanvas):
|
||||||
glTranslate(0,0,-self.zoom)
|
glTranslate(0,0,-self.zoom)
|
||||||
glRotate(-self.pitch, 1,0,0)
|
glRotate(-self.pitch, 1,0,0)
|
||||||
glRotate(self.yaw, 0,0,1)
|
glRotate(self.yaw, 0,0,1)
|
||||||
#glRotate(90, 1,0,0)
|
if self.triangleMesh != None:
|
||||||
|
glTranslate(0,0,-self.triangleMesh.getCarveCornerMaximum().z / 2)
|
||||||
return
|
return
|
||||||
|
|
|
@ -13,7 +13,11 @@ from __future__ import absolute_import
|
||||||
|
|
||||||
from optparse import OptionParser
|
from optparse import OptionParser
|
||||||
from skeinforge_application.skeinforge_utilities import skeinforge_craft
|
from skeinforge_application.skeinforge_utilities import skeinforge_craft
|
||||||
|
#For some reason the newui import fails when we are importing this from newui.mainWindow (circle references not allowed?) in that case we don't need the UI so skip it.
|
||||||
|
try:
|
||||||
from newui import mainWindow
|
from newui import mainWindow
|
||||||
|
except:
|
||||||
|
pass
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import platform
|
import platform
|
||||||
|
|
Loading…
Reference in a new issue