2012-04-18 20:51:19 +00:00
from __future__ import absolute_import
import __init__
2012-04-20 15:06:50 +00:00
import wx , os , platform , types , webbrowser , math , subprocess , threading , time
2012-04-18 20:51:19 +00:00
import ConfigParser
from wx import glcanvas
import wx
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
from gui import opengl
2012-04-19 14:16:15 +00:00
from gui import toolbarUtil
2012-04-18 20:51:19 +00:00
from gui import icon
2012-05-07 14:03:42 +00:00
from gui import configBase
from gui import validators
2012-05-11 10:13:24 +00:00
from gui import printWindow
2012-04-18 20:51:19 +00:00
from util import profile
from util import util3d
from util import stl
from util import sliceRun
2012-05-04 17:28:24 +00:00
from util import gcodeInterpreter
2012-05-11 10:13:24 +00:00
from util import exporer
2012-04-18 20:51:19 +00:00
2012-05-04 15:57:24 +00:00
class Action ( object ) :
2012-04-20 15:06:50 +00:00
pass
2012-05-04 15:57:24 +00:00
class ProjectObject ( stl . stlModel ) :
2012-05-07 15:36:41 +00:00
def __init__ ( self , parent , filename ) :
2012-05-04 15:57:24 +00:00
super ( ProjectObject , self ) . __init__ ( )
self . load ( filename )
2012-05-07 15:36:41 +00:00
self . parent = parent
2012-05-04 15:57:24 +00:00
self . filename = filename
self . scale = 1.0
self . rotate = 0.0
self . flipX = False
self . flipY = False
self . flipZ = False
self . swapXZ = False
self . swapYZ = False
self . extruder = 0
2012-05-09 12:21:58 +00:00
self . profile = None
2012-05-04 15:57:24 +00:00
self . modelDisplayList = None
self . modelDirty = False
self . origonalVertexes = list ( self . vertexes )
for i in xrange ( 0 , len ( self . origonalVertexes ) ) :
self . origonalVertexes [ i ] = self . origonalVertexes [ i ] . copy ( )
self . getMinimumZ ( )
self . centerX = - self . getMinimum ( ) . x + 5
self . centerY = - self . getMinimum ( ) . y + 5
self . updateModelTransform ( )
self . centerX = - self . getMinimum ( ) . x + 5
self . centerY = - self . getMinimum ( ) . y + 5
def updateModelTransform ( self ) :
rotate = self . rotate / 180.0 * math . pi
scaleX = 1.0
scaleY = 1.0
scaleZ = 1.0
if self . flipX :
scaleX = - scaleX
if self . flipY :
scaleY = - scaleY
if self . flipZ :
scaleZ = - scaleZ
swapXZ = self . swapXZ
swapYZ = self . swapYZ
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 . origonalVertexes ) ) :
x = self . origonalVertexes [ i ] . x
y = self . origonalVertexes [ i ] . y
z = self . origonalVertexes [ i ] . z
if swapXZ :
x , z = z , x
if swapYZ :
y , z = z , y
self . vertexes [ i ] . x = x * mat00 + y * mat01
self . vertexes [ i ] . y = x * mat10 + y * mat11
self . vertexes [ i ] . z = z * scaleZ
for face in self . faces :
v1 = face . v [ 0 ]
v2 = face . v [ 1 ]
v3 = face . v [ 2 ]
face . normal = ( v2 - v1 ) . cross ( v3 - v1 )
face . normal . normalize ( )
minZ = self . getMinimumZ ( )
minV = self . getMinimum ( )
maxV = self . getMaximum ( )
for v in self . vertexes :
v . z - = minZ
v . x - = minV . x + ( maxV . x - minV . x ) / 2
v . y - = minV . y + ( maxV . y - minV . y ) / 2
self . getMinimumZ ( )
self . modelDirty = True
def clone ( self ) :
2012-05-07 15:36:41 +00:00
p = ProjectObject ( self . parent , self . filename )
2012-05-04 15:57:24 +00:00
p . centerX = self . centerX + 5
p . centerY = self . centerY + 5
p . filename = self . filename
p . scale = self . scale
p . rotate = self . rotate
p . flipX = self . flipX
p . flipY = self . flipY
p . flipZ = self . flipZ
p . swapXZ = self . swapXZ
p . swapYZ = self . swapYZ
p . extruder = self . extruder
2012-05-10 14:52:31 +00:00
p . profile = self . profile
2012-05-04 15:57:24 +00:00
p . updateModelTransform ( )
return p
2012-05-07 15:36:41 +00:00
def clampXY ( self ) :
if self . centerX < - self . getMinimum ( ) . x * self . scale + self . parent . extruderOffset [ self . extruder ] . x :
self . centerX = - self . getMinimum ( ) . x * self . scale + self . parent . extruderOffset [ self . extruder ] . x
if self . centerY < - self . getMinimum ( ) . y * self . scale + self . parent . extruderOffset [ self . extruder ] . y :
self . centerY = - self . getMinimum ( ) . y * self . scale + self . parent . extruderOffset [ self . extruder ] . y
if self . centerX > self . parent . machineSize . x + self . parent . extruderOffset [ self . extruder ] . x - self . getMaximum ( ) . x * self . scale :
self . centerX = self . parent . machineSize . x + self . parent . extruderOffset [ self . extruder ] . x - self . getMaximum ( ) . x * self . scale
if self . centerY > self . parent . machineSize . y + self . parent . extruderOffset [ self . extruder ] . y - self . getMaximum ( ) . y * self . scale :
self . centerY = self . parent . machineSize . y + self . parent . extruderOffset [ self . extruder ] . y - self . getMaximum ( ) . y * self . scale
2012-05-04 15:57:24 +00:00
2012-04-18 20:51:19 +00:00
class projectPlanner ( wx . Frame ) :
" Main user interface window "
def __init__ ( self ) :
2012-04-20 15:15:10 +00:00
super ( projectPlanner , self ) . __init__ ( None , title = ' Cura - Project Planner ' )
2012-04-18 20:51:19 +00:00
self . SetBackgroundColour ( wx . SystemSettings . GetColour ( wx . SYS_COLOUR_BTNFACE ) )
wx . EVT_CLOSE ( self , self . OnClose )
#self.SetIcon(icon.getMainIcon())
self . list = [ ]
self . selection = None
2012-05-01 09:39:52 +00:00
self . machineSize = util3d . Vector3 ( profile . getPreferenceFloat ( ' machine_width ' ) , profile . getPreferenceFloat ( ' machine_depth ' ) , profile . getPreferenceFloat ( ' machine_height ' ) )
self . headSizeMin = util3d . Vector3 ( profile . getPreferenceFloat ( ' extruder_head_size_min_x ' ) , profile . getPreferenceFloat ( ' extruder_head_size_min_y ' ) , 0 )
self . headSizeMax = util3d . Vector3 ( profile . getPreferenceFloat ( ' extruder_head_size_max_x ' ) , profile . getPreferenceFloat ( ' extruder_head_size_max_y ' ) , 0 )
2012-04-18 20:51:19 +00:00
2012-04-29 09:35:36 +00:00
self . extruderOffset = [
util3d . Vector3 ( 0 , 0 , 0 ) ,
2012-05-01 09:39:52 +00:00
util3d . Vector3 ( profile . getPreferenceFloat ( ' extruder_offset_x1 ' ) , profile . getPreferenceFloat ( ' extruder_offset_y1 ' ) , 0 ) ,
util3d . Vector3 ( profile . getPreferenceFloat ( ' extruder_offset_x2 ' ) , profile . getPreferenceFloat ( ' extruder_offset_y2 ' ) , 0 ) ,
util3d . Vector3 ( profile . getPreferenceFloat ( ' extruder_offset_x3 ' ) , profile . getPreferenceFloat ( ' extruder_offset_y3 ' ) , 0 ) ]
2012-04-27 17:18:29 +00:00
2012-05-10 23:49:51 +00:00
self . toolbarPanel = wx . Panel ( self , - 1 )
2012-05-11 11:41:17 +00:00
self . toolbarPanel . SetSizer ( wx . BoxSizer ( wx . VERTICAL ) )
2012-05-10 23:49:51 +00:00
self . toolbar = toolbarUtil . Toolbar ( self . toolbarPanel )
2012-05-11 11:41:17 +00:00
self . toolbarPanel . GetSizer ( ) . Add ( self . toolbar , 0 )
2012-04-18 20:51:19 +00:00
2012-04-23 16:23:29 +00:00
toolbarUtil . NormalButton ( self . toolbar , self . OnLoadProject , ' open.png ' , ' Open project ' )
toolbarUtil . NormalButton ( self . toolbar , self . OnSaveProject , ' save.png ' , ' Save project ' )
self . toolbar . AddSeparator ( )
2012-04-19 14:16:15 +00:00
group = [ ]
toolbarUtil . RadioButton ( self . toolbar , group , ' object-3d-on.png ' , ' object-3d-off.png ' , ' 3D view ' , callback = self . On3DClick )
2012-04-19 15:35:08 +00:00
toolbarUtil . RadioButton ( self . toolbar , group , ' object-top-on.png ' , ' object-top-off.png ' , ' Topdown view ' , callback = self . OnTopClick ) . SetValue ( True )
2012-04-23 16:23:29 +00:00
self . toolbar . AddSeparator ( )
toolbarUtil . NormalButton ( self . toolbar , self . OnQuit , ' exit.png ' , ' Close project planner ' )
2012-05-07 14:03:42 +00:00
self . toolbar . AddSeparator ( )
toolbarUtil . NormalButton ( self . toolbar , self . OnPreferences , ' preferences.png ' , ' Project planner preferences ' )
2012-04-18 20:51:19 +00:00
self . toolbar . Realize ( )
2012-05-04 10:39:23 +00:00
2012-05-10 23:49:51 +00:00
self . toolbar2Panel = wx . Panel ( self , - 1 )
2012-05-11 11:41:17 +00:00
self . toolbar2Panel . SetSizer ( wx . BoxSizer ( wx . VERTICAL ) )
2012-05-10 23:49:51 +00:00
self . toolbar2 = toolbarUtil . Toolbar ( self . toolbar2Panel )
2012-05-11 11:41:17 +00:00
self . toolbar2Panel . GetSizer ( ) . Add ( self . toolbar2 , 0 )
2012-05-04 10:39:23 +00:00
toolbarUtil . NormalButton ( self . toolbar2 , self . OnAddModel , ' object-add.png ' , ' Add model ' )
toolbarUtil . NormalButton ( self . toolbar2 , self . OnRemModel , ' object-remove.png ' , ' Remove model ' )
2012-05-10 11:59:52 +00:00
self . toolbar2 . AddSeparator ( )
2012-05-04 10:39:23 +00:00
toolbarUtil . NormalButton ( self . toolbar2 , self . OnMoveUp , ' move-up.png ' , ' Move model up in print list ' )
toolbarUtil . NormalButton ( self . toolbar2 , self . OnMoveDown , ' move-down.png ' , ' Move model down in print list ' )
2012-05-04 15:57:24 +00:00
toolbarUtil . NormalButton ( self . toolbar2 , self . OnCopy , ' copy.png ' , ' Make a copy of the current selected object ' )
2012-05-10 14:52:31 +00:00
toolbarUtil . NormalButton ( self . toolbar2 , self . OnSetCustomProfile , ' set-profile.png ' , ' Set a custom profile to be used to slice a specific object. ' )
2012-05-10 11:59:52 +00:00
self . toolbar2 . AddSeparator ( )
2012-05-09 12:21:58 +00:00
toolbarUtil . NormalButton ( self . toolbar2 , self . OnAutoPlace , ' autoplace.png ' , ' Automaticly organize the objects on the platform. ' )
2012-05-10 11:59:52 +00:00
toolbarUtil . NormalButton ( self . toolbar2 , self . OnSlice , ' slice.png ' , ' Slice to project into a gcode file. ' )
2012-05-04 10:39:23 +00:00
self . toolbar2 . Realize ( )
2012-04-18 20:51:19 +00:00
sizer = wx . GridBagSizer ( 2 , 2 )
self . SetSizer ( sizer )
self . preview = PreviewGLCanvas ( self )
self . listbox = wx . ListBox ( self , - 1 , choices = [ ] )
self . addButton = wx . Button ( self , - 1 , " Add " )
self . remButton = wx . Button ( self , - 1 , " Remove " )
self . sliceButton = wx . Button ( self , - 1 , " Slice " )
2012-04-21 18:45:53 +00:00
self . autoPlaceButton = wx . Button ( self , - 1 , " Auto Place " )
2012-04-18 20:51:19 +00:00
2012-05-10 23:49:51 +00:00
sizer . Add ( self . toolbarPanel , ( 0 , 0 ) , span = ( 1 , 1 ) , flag = wx . EXPAND | wx . TOP | wx . LEFT | wx . RIGHT )
sizer . Add ( self . toolbar2Panel , ( 0 , 1 ) , span = ( 1 , 2 ) , flag = wx . EXPAND | wx . TOP | wx . LEFT | wx . RIGHT )
2012-04-20 13:12:06 +00:00
sizer . Add ( self . preview , ( 1 , 0 ) , span = ( 4 , 1 ) , flag = wx . EXPAND )
sizer . Add ( self . listbox , ( 1 , 1 ) , span = ( 1 , 2 ) , flag = wx . EXPAND )
2012-04-18 20:51:19 +00:00
sizer . Add ( self . addButton , ( 2 , 1 ) , span = ( 1 , 1 ) )
sizer . Add ( self . remButton , ( 2 , 2 ) , span = ( 1 , 1 ) )
sizer . Add ( self . sliceButton , ( 3 , 1 ) , span = ( 1 , 1 ) )
2012-04-21 18:45:53 +00:00
sizer . Add ( self . autoPlaceButton , ( 3 , 2 ) , span = ( 1 , 1 ) )
2012-04-18 20:51:19 +00:00
sizer . AddGrowableCol ( 0 )
sizer . AddGrowableRow ( 1 )
self . addButton . Bind ( wx . EVT_BUTTON , self . OnAddModel )
self . remButton . Bind ( wx . EVT_BUTTON , self . OnRemModel )
self . sliceButton . Bind ( wx . EVT_BUTTON , self . OnSlice )
2012-04-21 18:45:53 +00:00
self . autoPlaceButton . Bind ( wx . EVT_BUTTON , self . OnAutoPlace )
2012-04-18 20:51:19 +00:00
self . listbox . Bind ( wx . EVT_LISTBOX , self . OnListSelect )
2012-04-20 13:12:06 +00:00
panel = wx . Panel ( self , - 1 )
sizer . Add ( panel , ( 4 , 1 ) , span = ( 1 , 2 ) )
sizer = wx . GridBagSizer ( 2 , 2 )
panel . SetSizer ( sizer )
2012-04-18 20:51:19 +00:00
2012-04-20 13:12:06 +00:00
self . scaleCtrl = wx . TextCtrl ( panel , - 1 , ' ' )
self . rotateCtrl = wx . SpinCtrl ( panel , - 1 , ' ' , size = ( 21 * 4 , 21 ) , style = wx . SP_ARROW_KEYS )
self . rotateCtrl . SetRange ( 0 , 360 )
sizer . Add ( wx . StaticText ( panel , - 1 , ' Scale ' ) , ( 0 , 0 ) , flag = wx . ALIGN_CENTER_VERTICAL )
sizer . Add ( self . scaleCtrl , ( 0 , 1 ) , flag = wx . ALIGN_BOTTOM | wx . EXPAND )
sizer . Add ( wx . StaticText ( panel , - 1 , ' Rotate ' ) , ( 1 , 0 ) , flag = wx . ALIGN_CENTER_VERTICAL )
sizer . Add ( self . rotateCtrl , ( 1 , 1 ) , flag = wx . ALIGN_BOTTOM | wx . EXPAND )
2012-05-09 12:21:58 +00:00
2012-04-27 17:18:29 +00:00
if int ( profile . getPreference ( ' extruder_amount ' ) ) > 1 :
self . extruderCtrl = wx . ComboBox ( panel , - 1 , ' 1 ' , choices = map ( str , range ( 1 , int ( profile . getPreference ( ' extruder_amount ' ) ) + 1 ) ) , style = wx . CB_DROPDOWN | wx . CB_READONLY )
sizer . Add ( wx . StaticText ( panel , - 1 , ' Extruder ' ) , ( 2 , 0 ) , flag = wx . ALIGN_CENTER_VERTICAL )
sizer . Add ( self . extruderCtrl , ( 2 , 1 ) , flag = wx . ALIGN_BOTTOM | wx . EXPAND )
self . extruderCtrl . Bind ( wx . EVT_COMBOBOX , self . OnExtruderChange )
2012-04-20 13:12:06 +00:00
self . scaleCtrl . Bind ( wx . EVT_TEXT , self . OnScaleChange )
self . rotateCtrl . Bind ( wx . EVT_SPINCTRL , self . OnRotateChange )
2012-04-18 20:51:19 +00:00
self . SetSize ( ( 800 , 600 ) )
def OnClose ( self , e ) :
self . Destroy ( )
def OnQuit ( self , e ) :
self . Close ( )
2012-05-07 14:03:42 +00:00
def OnPreferences ( self , e ) :
prefDialog = preferencesDialog ( self )
prefDialog . Centre ( )
prefDialog . Show ( True )
2012-04-18 20:51:19 +00:00
def OnSaveProject ( self , e ) :
dlg = wx . FileDialog ( self , " Save project file " , os . path . split ( profile . getPreference ( ' lastFile ' ) ) [ 0 ] , style = wx . FD_SAVE )
dlg . SetWildcard ( " Project files (*.curaproject)|*.curaproject " )
if dlg . ShowModal ( ) == wx . ID_OK :
cp = ConfigParser . ConfigParser ( )
i = 0
for item in self . list :
section = ' model_ %d ' % ( i )
cp . add_section ( section )
cp . set ( section , ' filename ' , item . filename . encode ( " utf-8 " ) )
cp . set ( section , ' centerX ' , str ( item . centerX ) )
cp . set ( section , ' centerY ' , str ( item . centerY ) )
cp . set ( section , ' scale ' , str ( item . scale ) )
cp . set ( section , ' rotate ' , str ( item . rotate ) )
cp . set ( section , ' flipX ' , str ( item . flipX ) )
cp . set ( section , ' flipY ' , str ( item . flipY ) )
cp . set ( section , ' flipZ ' , str ( item . flipZ ) )
cp . set ( section , ' swapXZ ' , str ( item . swapXZ ) )
cp . set ( section , ' swapYZ ' , str ( item . swapYZ ) )
2012-04-27 17:18:29 +00:00
cp . set ( section , ' extruder ' , str ( item . extruder + 1 ) )
2012-05-09 12:21:58 +00:00
if item . profile != None :
cp . set ( section , ' profile ' , item . profile )
2012-04-18 20:51:19 +00:00
i + = 1
cp . write ( open ( dlg . GetPath ( ) , " w " ) )
dlg . Destroy ( )
def OnLoadProject ( self , e ) :
dlg = wx . FileDialog ( self , " Open project file " , os . path . split ( profile . getPreference ( ' lastFile ' ) ) [ 0 ] , style = wx . FD_OPEN | wx . FD_FILE_MUST_EXIST )
dlg . SetWildcard ( " Project files (*.curaproject)|*.curaproject " )
if dlg . ShowModal ( ) == wx . ID_OK :
cp = ConfigParser . ConfigParser ( )
cp . read ( dlg . GetPath ( ) )
self . list = [ ]
i = 0
while cp . has_section ( ' model_ %d ' % ( i ) ) :
section = ' model_ %d ' % ( i )
2012-05-07 15:36:41 +00:00
item = ProjectObject ( self , unicode ( cp . get ( section , ' filename ' ) , " utf-8 " ) )
2012-04-18 20:51:19 +00:00
item . centerX = float ( cp . get ( section , ' centerX ' ) )
item . centerY = float ( cp . get ( section , ' centerY ' ) )
item . scale = float ( cp . get ( section , ' scale ' ) )
item . rotate = float ( cp . get ( section , ' rotate ' ) )
2012-04-27 17:18:29 +00:00
item . flipX = cp . get ( section , ' flipX ' ) == ' True '
item . flipY = cp . get ( section , ' flipY ' ) == ' True '
item . flipZ = cp . get ( section , ' flipZ ' ) == ' True '
item . swapXZ = cp . get ( section , ' swapXZ ' ) == ' True '
item . swapYZ = cp . get ( section , ' swapYZ ' ) == ' True '
2012-04-27 19:48:56 +00:00
if cp . has_option ( section , ' extruder ' ) :
2012-05-09 12:21:58 +00:00
item . extuder = int ( cp . get ( section , ' extruder ' ) ) - 1
if cp . has_option ( section , ' profile ' ) :
item . profile = cp . get ( section , ' profile ' )
2012-05-04 15:57:24 +00:00
item . updateModelTransform ( )
2012-04-18 20:51:19 +00:00
i + = 1
self . list . append ( item )
2012-05-10 14:52:31 +00:00
self . selected = self . list [ 0 ]
self . _updateListbox ( )
2012-04-18 20:51:19 +00:00
self . OnListSelect ( None )
2012-05-04 15:57:24 +00:00
self . preview . Refresh ( )
2012-04-18 20:51:19 +00:00
dlg . Destroy ( )
2012-04-19 14:16:15 +00:00
def On3DClick ( self ) :
2012-04-18 20:51:19 +00:00
self . preview . yaw = 30
self . preview . pitch = 60
self . preview . zoom = 300
self . preview . view3D = True
self . preview . Refresh ( )
2012-04-19 14:16:15 +00:00
def OnTopClick ( self ) :
2012-04-18 20:51:19 +00:00
self . preview . view3D = False
self . preview . zoom = self . machineSize . x / 2 + 10
self . preview . offsetX = 0
self . preview . offsetY = 0
self . preview . Refresh ( )
def OnListSelect ( self , e ) :
2012-04-20 12:23:11 +00:00
if self . listbox . GetSelection ( ) == - 1 :
return
2012-04-18 20:51:19 +00:00
self . selection = self . list [ self . listbox . GetSelection ( ) ]
2012-04-20 13:12:06 +00:00
self . scaleCtrl . SetValue ( str ( self . selection . scale ) )
self . rotateCtrl . SetValue ( int ( self . selection . rotate ) )
2012-04-27 17:18:29 +00:00
if int ( profile . getPreference ( ' extruder_amount ' ) ) > 1 :
self . extruderCtrl . SetValue ( str ( self . selection . extruder + 1 ) )
2012-04-18 20:51:19 +00:00
self . preview . Refresh ( )
2012-04-27 17:18:29 +00:00
2012-04-18 20:51:19 +00:00
def OnAddModel ( self , e ) :
2012-04-21 18:45:53 +00:00
dlg = wx . FileDialog ( self , " Open file to print " , os . path . split ( profile . getPreference ( ' lastFile ' ) ) [ 0 ] , style = wx . FD_OPEN | wx . FD_FILE_MUST_EXIST | wx . FD_MULTIPLE )
2012-04-18 20:51:19 +00:00
dlg . SetWildcard ( " STL files (*.stl)|*.stl;*.STL " )
if dlg . ShowModal ( ) == wx . ID_OK :
2012-04-21 18:45:53 +00:00
for filename in dlg . GetPaths ( ) :
2012-05-07 15:36:41 +00:00
item = ProjectObject ( self , filename )
2012-04-21 18:45:53 +00:00
profile . putPreference ( ' lastFile ' , item . filename )
self . list . append ( item )
2012-05-04 15:57:24 +00:00
self . selection = item
self . _updateListbox ( )
2012-05-10 14:52:31 +00:00
self . OnListSelect ( None )
2012-05-04 15:57:24 +00:00
self . preview . Refresh ( )
2012-04-18 20:51:19 +00:00
dlg . Destroy ( )
def OnRemModel ( self , e ) :
if self . selection == None :
return
self . list . remove ( self . selection )
2012-05-04 15:57:24 +00:00
self . _updateListbox ( )
2012-04-21 18:45:53 +00:00
self . preview . Refresh ( )
2012-05-04 10:39:23 +00:00
def OnMoveUp ( self , e ) :
if self . selection == None :
return
2012-04-21 18:45:53 +00:00
i = self . listbox . GetSelection ( )
2012-05-04 10:39:23 +00:00
if i == 0 :
return
self . list . remove ( self . selection )
self . list . insert ( i - 1 , self . selection )
self . _updateListbox ( )
self . preview . Refresh ( )
def OnMoveDown ( self , e ) :
if self . selection == None :
return
i = self . listbox . GetSelection ( )
if i == len ( self . list ) - 1 :
return
self . list . remove ( self . selection )
self . list . insert ( i + 1 , self . selection )
self . _updateListbox ( )
2012-04-21 18:45:53 +00:00
self . preview . Refresh ( )
2012-05-04 15:57:24 +00:00
def OnCopy ( self , e ) :
if self . selection == None :
return
item = self . selection . clone ( )
self . list . append ( item )
self . selection = item
self . _updateListbox ( )
self . preview . Refresh ( )
2012-05-10 14:52:31 +00:00
def OnSetCustomProfile ( self , e ) :
if self . selection == None :
return
dlg = wx . FileDialog ( self , " Select profile " , os . path . split ( profile . getPreference ( ' lastFile ' ) ) [ 0 ] , style = wx . FD_OPEN | wx . FD_FILE_MUST_EXIST )
dlg . SetWildcard ( " Profile files (*.ini)|*.ini;*.INI " )
if dlg . ShowModal ( ) == wx . ID_OK :
self . selection . profile = dlg . GetPath ( )
else :
self . selection . profile = None
self . _updateListbox ( )
dlg . Destroy ( )
2012-05-04 10:39:23 +00:00
def _updateListbox ( self ) :
self . listbox . Clear ( )
for item in self . list :
2012-05-10 14:52:31 +00:00
if item . profile != None :
self . listbox . AppendAndEnsureVisible ( os . path . split ( item . filename ) [ 1 ] + " * " )
else :
self . listbox . AppendAndEnsureVisible ( os . path . split ( item . filename ) [ 1 ] )
2012-05-04 15:57:24 +00:00
if self . selection in self . list :
self . listbox . SetSelection ( self . list . index ( self . selection ) )
elif len ( self . list ) > 0 :
self . selection = self . list [ 0 ]
self . listbox . SetSelection ( 0 )
else :
self . selection = None
self . listbox . SetSelection ( - 1 )
2012-05-04 10:39:23 +00:00
2012-04-21 18:45:53 +00:00
def OnAutoPlace ( self , e ) :
bestAllowedSize = int ( self . machineSize . y )
bestArea = self . _doAutoPlace ( bestAllowedSize )
for i in xrange ( 10 , int ( self . machineSize . y ) , 10 ) :
area = self . _doAutoPlace ( i )
if area < bestArea :
bestAllowedSize = i
bestArea = area
self . _doAutoPlace ( bestAllowedSize )
2012-05-07 15:36:41 +00:00
for item in self . list :
item . clampXY ( )
2012-04-18 20:51:19 +00:00
self . preview . Refresh ( )
2012-04-21 18:45:53 +00:00
def _doAutoPlace ( self , allowedSizeY ) :
2012-04-22 21:45:19 +00:00
extraSizeMin = self . headSizeMin
extraSizeMax = self . headSizeMax
if profile . getProfileSettingFloat ( ' skirt_line_count ' ) > 0 :
skirtSize = profile . getProfileSettingFloat ( ' skirt_line_count ' ) * profile . calculateEdgeWidth ( ) + profile . getProfileSettingFloat ( ' skirt_gap ' )
2012-04-27 17:18:29 +00:00
extraSizeMin = extraSizeMin + util3d . Vector3 ( skirtSize , skirtSize , 0 )
2012-04-22 21:45:19 +00:00
extraSizeMax = extraSizeMax + util3d . Vector3 ( skirtSize , skirtSize , 0 )
2012-05-09 12:21:58 +00:00
if extraSizeMin . x > extraSizeMax . x :
posX = self . machineSize . x
dirX = - 1
else :
posX = 0
dirX = 1
2012-04-21 18:45:53 +00:00
posY = 0
2012-05-09 12:21:58 +00:00
dirY = 1
2012-04-21 18:45:53 +00:00
minX = self . machineSize . x
minY = self . machineSize . y
maxX = 0
maxY = 0
for item in self . list :
item . centerX = posX + item . getMaximum ( ) . x * item . scale * dirX
item . centerY = posY + item . getMaximum ( ) . y * item . scale * dirY
if item . centerY + item . getSize ( ) . y > = allowedSizeY :
2012-05-09 12:21:58 +00:00
if dirX < 0 :
posX = minX - extraSizeMax . x - 1
else :
posX = maxX + extraSizeMin . x + 1
2012-04-21 18:45:53 +00:00
posY = 0
item . centerX = posX + item . getMaximum ( ) . x * item . scale * dirX
item . centerY = posY + item . getMaximum ( ) . y * item . scale * dirY
2012-04-22 21:45:19 +00:00
posY + = item . getSize ( ) . y * item . scale * dirY + extraSizeMin . y + 1
2012-04-21 18:45:53 +00:00
minX = min ( minX , item . centerX - item . getSize ( ) . x * item . scale / 2 )
minY = min ( minY , item . centerY - item . getSize ( ) . y * item . scale / 2 )
maxX = max ( maxX , item . centerX + item . getSize ( ) . x * item . scale / 2 )
maxY = max ( maxY , item . centerY + item . getSize ( ) . y * item . scale / 2 )
for item in self . list :
2012-05-09 12:21:58 +00:00
if dirX < 0 :
item . centerX - = minX / 2
else :
item . centerX + = ( self . machineSize . x - maxX ) / 2
2012-04-21 18:45:53 +00:00
item . centerY + = ( self . machineSize . y - maxY ) / 2
2012-05-09 12:21:58 +00:00
if minX < 0 or maxX > self . machineSize . x :
2012-04-21 18:45:53 +00:00
return ( ( maxX - minX ) + ( maxY - minY ) ) * 100
return ( maxX - minX ) + ( maxY - minY )
2012-04-18 20:51:19 +00:00
def OnSlice ( self , e ) :
2012-05-03 10:29:55 +00:00
put = profile . setTempOverride
2012-05-09 12:21:58 +00:00
oldProfile = profile . getGlobalProfileString ( )
2012-04-18 20:51:19 +00:00
put ( ' model_multiply_x ' , ' 1 ' )
put ( ' model_multiply_y ' , ' 1 ' )
put ( ' enable_raft ' , ' False ' )
put ( ' add_start_end_gcode ' , ' False ' )
put ( ' gcode_extension ' , ' project_tmp ' )
2012-04-20 15:06:50 +00:00
clearZ = 0
actionList = [ ]
2012-04-18 20:51:19 +00:00
for item in self . list :
2012-05-09 12:21:58 +00:00
if item . profile != None and os . path . isfile ( item . profile ) :
profile . loadGlobalProfile ( item . profile )
2012-04-27 17:18:29 +00:00
put ( ' machine_center_x ' , item . centerX - self . extruderOffset [ item . extruder ] . x )
put ( ' machine_center_y ' , item . centerY - self . extruderOffset [ item . extruder ] . y )
2012-04-18 20:51:19 +00:00
put ( ' model_scale ' , item . scale )
put ( ' flip_x ' , item . flipX )
put ( ' flip_y ' , item . flipY )
put ( ' flip_z ' , item . flipZ )
put ( ' model_rotate_base ' , item . rotate )
put ( ' swap_xz ' , item . swapXZ )
put ( ' swap_yz ' , item . swapYZ )
2012-04-20 15:06:50 +00:00
action = Action ( )
action . sliceCmd = sliceRun . getSliceCommand ( item . filename )
action . centerX = item . centerX
action . centerY = item . centerY
2012-04-27 17:18:29 +00:00
action . extruder = item . extruder
2012-04-20 15:06:50 +00:00
action . filename = item . filename
clearZ = max ( clearZ , item . getMaximum ( ) . z * item . scale )
action . clearZ = clearZ
actionList . append ( action )
2012-05-09 12:21:58 +00:00
if item . profile != None :
profile . loadGlobalProfileFromString ( oldProfile )
2012-04-18 20:51:19 +00:00
#Restore the old profile.
2012-05-03 10:29:55 +00:00
profile . resetTempOverride ( )
2012-04-18 20:51:19 +00:00
2012-04-19 14:31:39 +00:00
dlg = wx . FileDialog ( self , " Save project gcode file " , os . path . split ( profile . getPreference ( ' lastFile ' ) ) [ 0 ] , style = wx . FD_SAVE )
dlg . SetWildcard ( " GCode file (*.gcode)|*.gcode " )
if dlg . ShowModal ( ) != wx . ID_OK :
dlg . Destroy ( )
return
2012-04-20 15:06:50 +00:00
resultFilename = dlg . GetPath ( )
2012-04-19 14:31:39 +00:00
dlg . Destroy ( )
2012-04-20 15:06:50 +00:00
pspw = ProjectSliceProgressWindow ( actionList , resultFilename )
2012-04-27 17:18:29 +00:00
pspw . extruderOffset = self . extruderOffset
2012-04-20 15:06:50 +00:00
pspw . Centre ( )
pspw . Show ( True )
2012-04-18 20:51:19 +00:00
2012-04-20 13:12:06 +00:00
def OnScaleChange ( self , e ) :
if self . selection == None :
return
try :
self . selection . scale = float ( self . scaleCtrl . GetValue ( ) )
except ValueError :
self . selection . scale = 1.0
self . preview . Refresh ( )
def OnRotateChange ( self , e ) :
if self . selection == None :
return
self . selection . rotate = float ( self . rotateCtrl . GetValue ( ) )
2012-05-04 15:57:24 +00:00
self . selection . updateModelTransform ( )
self . preview . Refresh ( )
2012-04-20 13:12:06 +00:00
2012-04-27 17:18:29 +00:00
def OnExtruderChange ( self , e ) :
if self . selection == None :
return
self . selection . extruder = int ( self . extruderCtrl . GetValue ( ) ) - 1
self . preview . Refresh ( )
2012-04-18 20:51:19 +00:00
class PreviewGLCanvas ( glcanvas . GLCanvas ) :
def __init__ ( self , parent ) :
attribList = ( glcanvas . WX_GL_RGBA , glcanvas . WX_GL_DOUBLEBUFFER , glcanvas . WX_GL_DEPTH_SIZE , 24 , glcanvas . WX_GL_STENCIL_SIZE , 8 )
glcanvas . GLCanvas . __init__ ( self , parent , attribList = attribList )
self . parent = parent
self . context = glcanvas . GLContext ( self )
wx . EVT_PAINT ( self , self . OnPaint )
wx . EVT_SIZE ( self , self . OnSize )
wx . EVT_ERASE_BACKGROUND ( self , self . OnEraseBackground )
wx . EVT_LEFT_DOWN ( self , self . OnMouseLeftDown )
wx . EVT_MOTION ( self , self . OnMouseMotion )
wx . EVT_MOUSEWHEEL ( self , self . OnMouseWheel )
self . yaw = 30
self . pitch = 60
self . zoom = self . parent . machineSize . x / 2 + 10
self . offsetX = 0
self . offsetY = 0
self . view3D = False
self . allowDrag = False
def OnMouseLeftDown ( self , e ) :
self . allowDrag = True
def OnMouseMotion ( self , e ) :
if self . allowDrag and e . Dragging ( ) and e . LeftIsDown ( ) :
if self . view3D :
self . yaw + = e . GetX ( ) - self . oldX
self . pitch - = e . GetY ( ) - self . oldY
if self . pitch > 170 :
self . pitch = 170
if self . pitch < 10 :
self . pitch = 10
else :
item = self . parent . selection
if item != None :
item . centerX + = float ( e . GetX ( ) - self . oldX ) * self . zoom / self . GetSize ( ) . GetHeight ( ) * 2
item . centerY - = float ( e . GetY ( ) - self . oldY ) * self . zoom / self . GetSize ( ) . GetHeight ( ) * 2
2012-05-07 15:36:41 +00:00
item . clampXY ( )
2012-04-18 20:51:19 +00:00
self . Refresh ( )
else :
self . allowDrag = False
if e . Dragging ( ) and e . RightIsDown ( ) :
if self . view3D :
self . zoom + = e . GetY ( ) - self . oldY
if self . zoom < 1 :
self . zoom = 1
self . Refresh ( )
self . oldX = e . GetX ( )
self . oldY = e . GetY ( )
def OnMouseWheel ( self , e ) :
if self . view3D :
self . zoom * = 1.0 - float ( e . GetWheelRotation ( ) / e . GetWheelDelta ( ) ) / 10.0
if self . zoom < 1.0 :
self . zoom = 1.0
self . Refresh ( )
def OnEraseBackground ( self , event ) :
#Workaround for windows background redraw flicker.
pass
def OnSize ( self , event ) :
self . Refresh ( )
def OnPaint ( self , event ) :
dc = wx . PaintDC ( self )
if not hasOpenGLlibs :
dc . Clear ( )
dc . DrawText ( " No PyOpenGL installation found. \n No preview window available. " , 10 , 10 )
return
self . SetCurrent ( self . context )
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 False : #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 . machineSize . x / 2 , - self . parent . machineSize . y / 2 , 0 )
self . OnDraw ( )
self . SwapBuffers ( )
def OnDraw ( self ) :
machineSize = self . parent . machineSize
opengl . DrawMachine ( machineSize )
2012-04-22 21:45:19 +00:00
extraSizeMin = self . parent . headSizeMin
extraSizeMax = self . parent . headSizeMax
if profile . getProfileSettingFloat ( ' skirt_line_count ' ) > 0 :
skirtSize = profile . getProfileSettingFloat ( ' skirt_line_count ' ) * profile . calculateEdgeWidth ( ) + profile . getProfileSettingFloat ( ' skirt_gap ' )
2012-04-27 17:18:29 +00:00
extraSizeMin = extraSizeMin + util3d . Vector3 ( skirtSize , skirtSize , 0 )
2012-04-22 21:45:19 +00:00
extraSizeMax = extraSizeMax + util3d . Vector3 ( skirtSize , skirtSize , 0 )
2012-04-18 20:51:19 +00:00
for item in self . parent . list :
item . validPlacement = True
item . gotHit = False
for idx1 in xrange ( 0 , len ( self . parent . list ) ) :
item = self . parent . list [ idx1 ]
2012-04-27 17:18:29 +00:00
iMin1 = item . getMinimum ( ) * item . scale + util3d . Vector3 ( item . centerX , item . centerY , 0 ) - extraSizeMin - self . parent . extruderOffset [ item . extruder ]
iMax1 = item . getMaximum ( ) * item . scale + util3d . Vector3 ( item . centerX , item . centerY , 0 ) + extraSizeMax - self . parent . extruderOffset [ item . extruder ]
2012-04-18 20:51:19 +00:00
for idx2 in xrange ( 0 , idx1 ) :
item2 = self . parent . list [ idx2 ]
iMin2 = item2 . getMinimum ( ) * item2 . scale + util3d . Vector3 ( item2 . centerX , item2 . centerY , 0 )
iMax2 = item2 . getMaximum ( ) * item2 . scale + util3d . Vector3 ( item2 . centerX , item2 . centerY , 0 )
if item != item2 and iMax1 . x > = iMin2 . x and iMin1 . x < = iMax2 . x and iMax1 . y > = iMin2 . y and iMin1 . y < = iMax2 . y :
item . validPlacement = False
item2 . gotHit = True
2012-04-19 14:16:15 +00:00
seenSelected = False
2012-04-18 20:51:19 +00:00
for item in self . parent . list :
2012-04-19 14:16:15 +00:00
if item == self . parent . selection :
seenSelected = True
2012-04-18 20:51:19 +00:00
if item . modelDisplayList == None :
item . modelDisplayList = glGenLists ( 1 ) ;
if item . modelDirty :
item . modelDirty = False
modelSize = item . getMaximum ( ) - item . getMinimum ( )
glNewList ( item . modelDisplayList , GL_COMPILE )
opengl . DrawSTL ( item )
glEndList ( )
if item . validPlacement :
if self . parent . selection == item :
glLightfv ( GL_LIGHT0 , GL_DIFFUSE , [ 1.0 , 0.9 , 0.7 , 1.0 ] )
glLightfv ( GL_LIGHT0 , GL_AMBIENT , [ 0.2 , 0.3 , 0.2 , 0.0 ] )
else :
glLightfv ( GL_LIGHT0 , GL_DIFFUSE , [ 1.0 , 0.8 , 0.6 , 1.0 ] )
glLightfv ( GL_LIGHT0 , GL_AMBIENT , [ 0.2 , 0.1 , 0.1 , 0.0 ] )
else :
if self . parent . selection == item :
glLightfv ( GL_LIGHT0 , GL_DIFFUSE , [ 1.0 , 0.0 , 0.0 , 0.0 ] )
glLightfv ( GL_LIGHT0 , GL_AMBIENT , [ 0.2 , 0.0 , 0.0 , 0.0 ] )
else :
glLightfv ( GL_LIGHT0 , GL_DIFFUSE , [ 1.0 , 0.0 , 0.0 , 0.0 ] )
glLightfv ( GL_LIGHT0 , GL_AMBIENT , [ 0.2 , 0.0 , 0.0 , 0.0 ] )
glPushMatrix ( )
glEnable ( GL_LIGHTING )
glTranslate ( item . centerX , item . centerY , 0 )
glPushMatrix ( )
glEnable ( GL_NORMALIZE )
glScalef ( item . scale , item . scale , item . scale )
glCallList ( item . modelDisplayList )
glPopMatrix ( )
vMin = item . getMinimum ( ) * item . scale
vMax = item . getMaximum ( ) * item . scale
2012-04-27 17:18:29 +00:00
vMinHead = vMin - extraSizeMin - self . parent . extruderOffset [ item . extruder ]
vMaxHead = vMax + extraSizeMax - self . parent . extruderOffset [ item . extruder ]
2012-04-19 14:16:15 +00:00
2012-04-18 20:51:19 +00:00
glDisable ( GL_LIGHTING )
2012-04-19 14:16:15 +00:00
if self . parent . selection == item :
if item . gotHit :
2012-04-20 13:12:06 +00:00
glColor3f ( 1.0 , 0.0 , 0.3 )
2012-04-19 14:16:15 +00:00
else :
2012-04-20 13:12:06 +00:00
glColor3f ( 1.0 , 0.0 , 1.0 )
2012-04-19 14:16:15 +00:00
opengl . DrawBox ( vMin , vMax )
if item . gotHit :
2012-04-20 13:12:06 +00:00
glColor3f ( 1.0 , 0.3 , 0.0 )
2012-04-19 14:16:15 +00:00
else :
2012-04-20 13:12:06 +00:00
glColor3f ( 1.0 , 1.0 , 0.0 )
2012-04-19 14:16:15 +00:00
opengl . DrawBox ( vMinHead , vMaxHead )
elif seenSelected :
if item . gotHit :
glColor3f ( 0.5 , 0.0 , 0.1 )
else :
glColor3f ( 0.5 , 0.0 , 0.5 )
opengl . DrawBox ( vMinHead , vMaxHead )
2012-04-18 20:51:19 +00:00
else :
2012-04-19 14:16:15 +00:00
if item . gotHit :
glColor3f ( 0.7 , 0.1 , 0.0 )
else :
glColor3f ( 0.7 , 0.7 , 0.0 )
opengl . DrawBox ( vMin , vMax )
2012-04-18 20:51:19 +00:00
glPopMatrix ( )
glFlush ( )
2012-04-20 15:06:50 +00:00
class ProjectSliceProgressWindow ( wx . Frame ) :
def __init__ ( self , actionList , resultFilename ) :
super ( ProjectSliceProgressWindow , self ) . __init__ ( None , title = ' Cura ' )
2012-04-21 18:45:53 +00:00
self . SetBackgroundColour ( wx . SystemSettings . GetColour ( wx . SYS_COLOUR_BTNFACE ) )
2012-04-20 15:06:50 +00:00
self . actionList = actionList
self . resultFilename = resultFilename
self . abort = False
self . prevStep = ' start '
self . totalDoneFactor = 0.0
self . startTime = time . time ( )
2012-04-25 13:49:43 +00:00
self . sliceStartTime = time . time ( )
2012-04-20 15:06:50 +00:00
self . sizer = wx . GridBagSizer ( 2 , 2 )
self . statusText = wx . StaticText ( self , - 1 , " Building: %s " % ( resultFilename ) )
self . progressGauge = wx . Gauge ( self , - 1 )
self . progressGauge . SetRange ( 10000 )
self . progressGauge2 = wx . Gauge ( self , - 1 )
self . progressGauge2 . SetRange ( len ( self . actionList ) )
self . abortButton = wx . Button ( self , - 1 , " Abort " )
2012-05-11 10:13:24 +00:00
self . sizer . Add ( self . statusText , ( 0 , 0 ) , span = ( 1 , 3 ) )
self . sizer . Add ( self . progressGauge , ( 1 , 0 ) , span = ( 1 , 3 ) , flag = wx . EXPAND )
self . sizer . Add ( self . progressGauge2 , ( 2 , 0 ) , span = ( 1 , 3 ) , flag = wx . EXPAND )
2012-05-03 10:29:55 +00:00
2012-05-11 10:13:24 +00:00
self . sizer . Add ( self . abortButton , ( 3 , 0 ) , span = ( 1 , 3 ) , flag = wx . ALIGN_CENTER )
2012-04-21 18:45:53 +00:00
self . sizer . AddGrowableCol ( 0 )
self . sizer . AddGrowableRow ( 0 )
2012-04-20 15:06:50 +00:00
self . Bind ( wx . EVT_BUTTON , self . OnAbort , self . abortButton )
self . SetSizer ( self . sizer )
self . Layout ( )
self . Fit ( )
threading . Thread ( target = self . OnRun ) . start ( )
def OnAbort ( self , e ) :
2012-04-21 19:27:53 +00:00
if self . abort :
self . Close ( )
else :
self . abort = True
self . abortButton . SetLabel ( ' Close ' )
2012-04-20 15:06:50 +00:00
def SetProgress ( self , stepName , layer , maxLayer ) :
if self . prevStep != stepName :
2012-05-04 10:03:08 +00:00
self . totalDoneFactor + = sliceRun . sliceStepTimeFactor [ self . prevStep ]
2012-04-20 15:06:50 +00:00
newTime = time . time ( )
#print "#####" + str(newTime-self.startTime) + " " + self.prevStep + " -> " + stepName
self . startTime = newTime
self . prevStep = stepName
2012-05-04 10:03:08 +00:00
progresValue = ( ( self . totalDoneFactor + sliceRun . sliceStepTimeFactor [ stepName ] * layer / maxLayer ) / sliceRun . totalRunTimeFactor ) * 10000
2012-04-20 15:06:50 +00:00
self . progressGauge . SetValue ( int ( progresValue ) )
self . statusText . SetLabel ( stepName + " [ " + str ( layer ) + " / " + str ( maxLayer ) + " ] " )
def OnRun ( self ) :
resultFile = open ( self . resultFilename , " w " )
2012-05-03 10:29:55 +00:00
put = profile . setTempOverride
2012-04-20 15:06:50 +00:00
for action in self . actionList :
2012-05-09 15:30:24 +00:00
wx . CallAfter ( self . SetTitle , " Building: [ %d / %d ] " % ( self . actionList . index ( action ) + 1 , len ( self . actionList ) ) )
2012-04-20 15:06:50 +00:00
p = subprocess . Popen ( action . sliceCmd , stdout = subprocess . PIPE , stderr = subprocess . STDOUT )
line = p . stdout . readline ( )
maxValue = 1
self . progressLog = [ ]
while ( len ( line ) > 0 ) :
line = line . rstrip ( )
if line [ 0 : 9 ] == " Progress[ " and line [ - 1 : ] == " ] " :
progress = line [ 9 : - 1 ] . split ( " : " )
if len ( progress ) > 2 :
maxValue = int ( progress [ 2 ] )
wx . CallAfter ( self . SetProgress , progress [ 0 ] , int ( progress [ 1 ] ) , maxValue )
else :
print line
self . progressLog . append ( line )
wx . CallAfter ( self . statusText . SetLabel , line )
if self . abort :
p . terminate ( )
wx . CallAfter ( self . statusText . SetLabel , " Aborted by user. " )
2012-05-04 17:28:24 +00:00
resultFile . close ( )
2012-04-20 15:06:50 +00:00
return
line = p . stdout . readline ( )
self . returnCode = p . wait ( )
2012-04-27 17:18:29 +00:00
put ( ' machine_center_x ' , action . centerX - self . extruderOffset [ action . extruder ] . x )
put ( ' machine_center_y ' , action . centerY - self . extruderOffset [ action . extruder ] . y )
2012-04-20 15:06:50 +00:00
put ( ' clear_z ' , action . clearZ )
2012-04-27 17:18:29 +00:00
put ( ' extruder ' , action . extruder )
2012-04-20 15:06:50 +00:00
if action == self . actionList [ 0 ] :
resultFile . write ( ' ;TYPE:CUSTOM \n ' )
2012-04-27 17:18:29 +00:00
resultFile . write ( ' T %d \n ' % ( action . extruder ) )
currentExtruder = action . extruder
2012-04-25 11:34:25 +00:00
resultFile . write ( profile . getAlterationFileContents ( ' start.gcode ' ) )
2012-04-20 15:06:50 +00:00
else :
#reset the extrusion length, and move to the next object center.
resultFile . write ( ' ;TYPE:CUSTOM \n ' )
2012-04-25 11:34:25 +00:00
resultFile . write ( profile . getAlterationFileContents ( ' nextobject.gcode ' ) )
2012-04-20 15:06:50 +00:00
resultFile . write ( ' ;PRINTNR: %d \n ' % self . actionList . index ( action ) )
2012-05-03 10:29:55 +00:00
profile . resetTempOverride ( )
2012-04-20 15:06:50 +00:00
f = open ( action . filename [ : action . filename . rfind ( ' . ' ) ] + " _export.project_tmp " , " r " )
data = f . read ( 4096 )
while data != ' ' :
resultFile . write ( data )
data = f . read ( 4096 )
f . close ( )
os . remove ( action . filename [ : action . filename . rfind ( ' . ' ) ] + " _export.project_tmp " )
wx . CallAfter ( self . progressGauge . SetValue , 10000 )
2012-04-25 13:49:43 +00:00
self . totalDoneFactor = 0.0
2012-04-20 15:06:50 +00:00
wx . CallAfter ( self . progressGauge2 . SetValue , self . actionList . index ( action ) + 1 )
resultFile . write ( ' ;TYPE:CUSTOM \n ' )
2012-04-25 11:34:25 +00:00
resultFile . write ( profile . getAlterationFileContents ( ' end.gcode ' ) )
2012-04-20 15:06:50 +00:00
resultFile . close ( )
2012-05-04 17:28:24 +00:00
gcode = gcodeInterpreter . gcode ( )
gcode . load ( self . resultFilename )
2012-04-21 19:27:53 +00:00
self . abort = True
2012-04-25 13:49:43 +00:00
sliceTime = time . time ( ) - self . sliceStartTime
2012-05-09 15:30:24 +00:00
status = " Build: %s " % ( self . resultFilename )
status + = " \n Slicing took: %02d : %02d " % ( sliceTime / 60 , sliceTime % 60 )
status + = " \n Filament: %.2f m %.2f g " % ( gcode . extrusionAmount / 1000 , gcode . calculateWeight ( ) * 1000 )
status + = " \n Print time: %02d : %02d " % ( int ( gcode . totalMoveTimeMinute / 60 ) , int ( gcode . totalMoveTimeMinute % 60 ) )
2012-05-04 17:28:24 +00:00
cost = gcode . calculateCost ( )
if cost != False :
2012-05-09 15:30:24 +00:00
status + = " \n Cost: %s " % ( cost )
2012-05-04 17:28:24 +00:00
wx . CallAfter ( self . statusText . SetLabel , status )
2012-05-11 10:13:24 +00:00
wx . CallAfter ( self . OnSliceDone )
def OnSliceDone ( self ) :
self . abortButton . Destroy ( )
self . closeButton = wx . Button ( self , - 1 , " Close " )
self . printButton = wx . Button ( self , - 1 , " Print " )
self . sizer . Add ( self . closeButton , ( 3 , 0 ) , span = ( 1 , 1 ) )
self . sizer . Add ( self . printButton , ( 3 , 1 ) , span = ( 1 , 1 ) )
if exporer . hasExporer ( ) :
self . openFileLocationButton = wx . Button ( self , - 1 , " Open file location " )
self . Bind ( wx . EVT_BUTTON , self . OnOpenFileLocation , self . openFileLocationButton )
self . sizer . Add ( self . openFileLocationButton , ( 3 , 2 ) , span = ( 1 , 1 ) )
self . Bind ( wx . EVT_BUTTON , self . OnAbort , self . closeButton )
self . Bind ( wx . EVT_BUTTON , self . OnPrint , self . printButton )
self . Layout ( )
self . Fit ( )
def OnOpenFileLocation ( self , e ) :
exporer . openExporer ( self . resultFilename )
def OnPrint ( self , e ) :
printWindow . printFile ( self . resultFilename )
2012-04-20 15:06:50 +00:00
2012-05-07 14:03:42 +00:00
class preferencesDialog ( configBase . configWindowBase ) :
def __init__ ( self , parent ) :
super ( preferencesDialog , self ) . __init__ ( title = " Project Planner Preferences " )
self . parent = parent
wx . EVT_CLOSE ( self , self . OnClose )
extruderAmount = int ( profile . getPreference ( ' extruder_amount ' ) )
left , right , main = self . CreateConfigPanel ( self )
configBase . TitleRow ( left , ' Machine head size ' )
c = configBase . SettingRow ( left , ' Head size - X towards home (mm) ' , ' extruder_head_size_min_x ' , ' 0 ' , ' Size of your printer head in the X direction, on the Ultimaker your fan is in this direction. ' , type = ' preference ' )
validators . validFloat ( c , 0.1 )
c = configBase . SettingRow ( left , ' Head size - X towards end (mm) ' , ' extruder_head_size_max_x ' , ' 0 ' , ' Size of your printer head in the X direction. ' , type = ' preference ' )
validators . validFloat ( c , 0.1 )
c = configBase . SettingRow ( left , ' Head size - Y towards home (mm) ' , ' extruder_head_size_min_y ' , ' 0 ' , ' Size of your printer head in the Y direction. ' , type = ' preference ' )
validators . validFloat ( c , 0.1 )
c = configBase . SettingRow ( left , ' Head size - Y towards end (mm) ' , ' extruder_head_size_max_y ' , ' 0 ' , ' Size of your printer head in the Y direction. ' , type = ' preference ' )
validators . validFloat ( c , 0.1 )
self . okButton = wx . Button ( left , - 1 , ' Ok ' )
left . GetSizer ( ) . Add ( self . okButton , ( left . GetSizer ( ) . GetRows ( ) , 1 ) )
self . okButton . Bind ( wx . EVT_BUTTON , self . OnClose )
self . MakeModal ( True )
main . Fit ( )
self . Fit ( )
def OnClose ( self , e ) :
self . parent . headSizeMin = util3d . Vector3 ( profile . getPreferenceFloat ( ' extruder_head_size_min_x ' ) , profile . getPreferenceFloat ( ' extruder_head_size_min_y ' ) , 0 )
self . parent . headSizeMax = util3d . Vector3 ( profile . getPreferenceFloat ( ' extruder_head_size_max_x ' ) , profile . getPreferenceFloat ( ' extruder_head_size_max_y ' ) , 0 )
self . MakeModal ( False )
self . Destroy ( )
2012-04-18 20:51:19 +00:00
def main ( ) :
app = wx . App ( False )
projectPlanner ( ) . Show ( True )
app . MainLoop ( )
if __name__ == ' __main__ ' :
main ( )