2012-02-21 14:27:03 +00:00
from __future__ import absolute_import
import __init__
2012-11-06 13:46:26 +00:00
import wx , sys , os , shutil , math , threading , subprocess , time , re , platform
2012-02-23 14:56:03 +00:00
2012-10-10 11:43:44 +00:00
from gui import taskbar
2012-11-06 07:52:16 +00:00
from gui import preferencesDialog
2012-04-12 11:58:19 +00:00
from util import profile
2012-03-28 12:26:40 +00:00
from util import sliceRun
2012-04-18 12:07:41 +00:00
from util import exporer
2012-04-29 10:00:13 +00:00
from util import gcodeInterpreter
2012-02-21 14:27:03 +00:00
class sliceProgessPanel ( wx . Panel ) :
2012-04-24 16:46:29 +00:00
def __init__ ( self , mainWindow , parent , filelist ) :
2012-02-21 14:27:03 +00:00
wx . Panel . __init__ ( self , parent , - 1 )
2012-02-21 15:37:31 +00:00
self . mainWindow = mainWindow
2012-04-24 16:46:29 +00:00
self . filelist = filelist
2012-02-21 14:27:03 +00:00
self . abort = False
2012-02-23 14:56:03 +00:00
2012-04-24 16:46:29 +00:00
box = wx . StaticBox ( self , - 1 , filelist [ 0 ] )
2012-02-21 22:05:30 +00:00
self . sizer = wx . StaticBoxSizer ( box , wx . HORIZONTAL )
2012-02-21 14:27:03 +00:00
mainSizer = wx . BoxSizer ( wx . VERTICAL )
2012-02-21 22:05:30 +00:00
mainSizer . Add ( self . sizer , 0 , flag = wx . EXPAND )
2012-02-21 14:27:03 +00:00
self . statusText = wx . StaticText ( self , - 1 , " Starting... " )
self . progressGauge = wx . Gauge ( self , - 1 )
2012-04-25 11:34:25 +00:00
self . progressGauge . SetRange ( 10000 * len ( filelist ) )
2012-02-21 14:27:03 +00:00
self . abortButton = wx . Button ( self , - 1 , " X " , style = wx . BU_EXACTFIT )
2012-02-21 22:05:30 +00:00
self . sizer . Add ( self . statusText , 2 , flag = wx . ALIGN_CENTER )
self . sizer . Add ( self . progressGauge , 2 )
self . sizer . Add ( self . abortButton , 0 )
2012-02-21 14:27:03 +00:00
self . Bind ( wx . EVT_BUTTON , self . OnAbort , self . abortButton )
self . SetSizer ( mainSizer )
2012-02-23 14:56:03 +00:00
self . prevStep = ' start '
self . totalDoneFactor = 0.0
self . startTime = time . time ( )
2012-04-12 11:58:19 +00:00
if profile . getPreference ( ' save_profile ' ) == ' True ' :
2012-04-24 16:46:29 +00:00
profile . saveGlobalProfile ( self . filelist [ 0 ] [ : self . filelist [ 0 ] . rfind ( ' . ' ) ] + " _profile.ini " )
cmdList = [ ]
for filename in self . filelist :
2012-04-29 09:35:36 +00:00
idx = self . filelist . index ( filename )
2012-06-21 17:53:18 +00:00
#print filename, idx
2012-04-29 09:35:36 +00:00
if idx > 0 :
2012-05-03 10:29:55 +00:00
profile . setTempOverride ( ' fan_enabled ' , ' False ' )
profile . setTempOverride ( ' skirt_line_count ' , ' 0 ' )
profile . setTempOverride ( ' machine_center_x ' , profile . getProfileSettingFloat ( ' machine_center_x ' ) - profile . getPreferenceFloat ( ' extruder_offset_x %d ' % ( idx ) ) )
profile . setTempOverride ( ' machine_center_y ' , profile . getProfileSettingFloat ( ' machine_center_y ' ) - profile . getPreferenceFloat ( ' extruder_offset_y %d ' % ( idx ) ) )
profile . setTempOverride ( ' alternative_center ' , self . filelist [ 0 ] )
2012-04-24 16:46:29 +00:00
if len ( self . filelist ) > 1 :
2012-05-03 10:29:55 +00:00
profile . setTempOverride ( ' add_start_end_gcode ' , ' False ' )
profile . setTempOverride ( ' gcode_extension ' , ' multi_extrude_tmp ' )
2012-04-24 16:46:29 +00:00
cmdList . append ( sliceRun . getSliceCommand ( filename ) )
2012-05-03 10:29:55 +00:00
profile . resetTempOverride ( )
2012-04-24 16:46:29 +00:00
self . thread = WorkerThread ( self , filelist , cmdList )
2012-02-21 14:27:03 +00:00
def OnAbort ( self , e ) :
if self . abort :
2012-02-21 15:37:31 +00:00
self . mainWindow . removeSliceProgress ( self )
2012-02-21 14:27:03 +00:00
else :
self . abort = True
2012-02-21 22:05:30 +00:00
def OnShowGCode ( self , e ) :
2012-04-24 16:46:29 +00:00
self . mainWindow . preview3d . loadModelFiles ( self . filelist )
2012-03-23 13:04:50 +00:00
self . mainWindow . preview3d . setViewMode ( " GCode " )
2012-02-21 22:05:30 +00:00
2012-03-05 17:53:19 +00:00
def OnShowLog ( self , e ) :
LogWindow ( ' \n ' . join ( self . progressLog ) )
2012-04-18 12:07:41 +00:00
def OnOpenFileLocation ( self , e ) :
2012-05-29 11:42:33 +00:00
exporer . openExporer ( sliceRun . getExportFilename ( self . filelist [ 0 ] ) )
2012-04-18 12:07:41 +00:00
2012-06-22 04:42:07 +00:00
def OnCopyToSD ( self , e ) :
2012-11-06 07:52:16 +00:00
if profile . getPreference ( ' sdpath ' ) == ' ' :
wx . MessageBox ( " You need to configure your SD card drive first before you can copy files to it. \n Opening the preferences now. " , ' No SD card drive. ' , wx . OK | wx . ICON_INFORMATION )
prefDialog = preferencesDialog . preferencesDialog ( self . GetParent ( ) )
prefDialog . Centre ( )
prefDialog . Show ( True )
if profile . getPreference ( ' sdpath ' ) == ' ' :
print " No path set "
return
2012-06-22 04:42:07 +00:00
exportFilename = sliceRun . getExportFilename ( self . filelist [ 0 ] )
filename = os . path . basename ( exportFilename )
if profile . getPreference ( ' sdshortnames ' ) == ' True ' :
filename = sliceRun . getShortFilename ( filename )
2012-11-06 08:11:57 +00:00
try :
shutil . copy ( exportFilename , os . path . join ( profile . getPreference ( ' sdpath ' ) , filename ) )
except :
self . GetParent ( ) . preview3d . ShowWarningPopup ( " Failed to copy file to SD card. " )
return
2012-11-06 10:06:09 +00:00
self . GetParent ( ) . preview3d . ShowWarningPopup ( " Copy finished, safely remove SD card? " , self . OnSafeRemove )
2012-06-22 04:42:07 +00:00
2012-11-06 08:11:57 +00:00
def OnSafeRemove ( self ) :
2012-11-06 10:06:09 +00:00
if platform . system ( ) == " Windows " :
cmd = " %s %s >NUL " % ( os . path . abspath ( os . path . join ( os . path . dirname ( __file__ ) , ' .. ' , ' EjectMedia.exe ' ) ) , profile . getPreference ( ' sdpath ' ) )
2012-11-08 09:56:31 +00:00
elif platform . system ( ) == " Darwin " :
cmd = " diskutil eject ' %s ' > /dev/null 2>&1 " % ( profile . getPreference ( ' sdpath ' ) )
2012-11-06 10:06:09 +00:00
else :
2012-11-08 09:56:31 +00:00
cmd = " umount ' %s ' > /dev/null 2>&1 " % ( profile . getPreference ( ' sdpath ' ) )
2012-11-06 10:06:09 +00:00
if os . system ( cmd ) :
self . GetParent ( ) . preview3d . ShowWarningPopup ( " Safe remove failed. " )
else :
self . GetParent ( ) . preview3d . ShowWarningPopup ( " You can now eject the card. " )
2012-11-06 08:11:57 +00:00
2012-03-05 17:53:19 +00:00
def OnSliceDone ( self , result ) :
2012-02-21 22:05:30 +00:00
self . progressGauge . Destroy ( )
2012-03-20 13:50:22 +00:00
self . abortButton . Destroy ( )
2012-03-05 17:53:19 +00:00
self . progressLog = result . progressLog
2012-03-11 10:56:50 +00:00
self . logButton = wx . Button ( self , - 1 , " Show Log " )
2012-03-20 13:50:22 +00:00
self . abortButton = wx . Button ( self , - 1 , " X " , style = wx . BU_EXACTFIT )
2012-03-11 10:56:50 +00:00
self . Bind ( wx . EVT_BUTTON , self . OnShowLog , self . logButton )
2012-03-20 13:50:22 +00:00
self . Bind ( wx . EVT_BUTTON , self . OnAbort , self . abortButton )
2012-03-11 10:56:50 +00:00
self . sizer . Add ( self . logButton , 0 )
2012-03-05 17:53:19 +00:00
if result . returnCode == 0 :
2012-04-29 10:00:13 +00:00
status = " Ready: Filament: %.2f m %.2f g " % ( result . gcode . extrusionAmount / 1000 , result . gcode . calculateWeight ( ) * 1000 )
2012-04-29 10:01:56 +00:00
status + = " Print time: %02d : %02d " % ( int ( result . gcode . totalMoveTimeMinute / 60 ) , int ( result . gcode . totalMoveTimeMinute % 60 ) )
2012-04-29 10:00:13 +00:00
cost = result . gcode . calculateCost ( )
if cost != False :
2012-04-29 12:22:20 +00:00
status + = " Cost: %s " % ( cost )
2012-04-29 10:00:13 +00:00
self . statusText . SetLabel ( status )
2012-04-18 12:07:41 +00:00
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 , 0 )
2012-11-06 07:52:16 +00:00
if len ( profile . getSDcardDrives ( ) ) > 0 :
self . copyToSDButton = wx . Button ( self , - 1 , " Copy to SDCard " )
2012-06-22 04:42:07 +00:00
self . Bind ( wx . EVT_BUTTON , self . OnCopyToSD , self . copyToSDButton )
self . sizer . Add ( self . copyToSDButton , 0 )
2012-03-19 15:15:16 +00:00
self . showButton = wx . Button ( self , - 1 , " Show result " )
2012-02-24 22:01:22 +00:00
self . Bind ( wx . EVT_BUTTON , self . OnShowGCode , self . showButton )
self . sizer . Add ( self . showButton , 0 )
else :
2012-03-05 17:53:19 +00:00
self . statusText . SetLabel ( " Something went wrong during slicing! " )
2012-03-11 10:56:50 +00:00
self . sizer . Add ( self . abortButton , 0 )
2012-02-21 22:05:30 +00:00
self . sizer . Layout ( )
2012-03-09 16:33:40 +00:00
self . Layout ( )
2012-02-21 22:05:30 +00:00
self . abort = True
2012-04-24 16:46:29 +00:00
if self . mainWindow . preview3d . loadReModelFiles ( self . filelist ) :
2012-03-23 13:04:50 +00:00
self . mainWindow . preview3d . setViewMode ( " GCode " )
2012-10-10 11:43:44 +00:00
taskbar . setBusy ( self . GetParent ( ) , False )
2012-02-23 14:56:03 +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-02-23 14:56:03 +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-02-23 14:56:03 +00:00
self . progressGauge . SetValue ( int ( progresValue ) )
2012-10-10 11:43:44 +00:00
taskbar . setProgress ( self . GetParent ( ) , int ( progresValue ) , self . progressGauge . GetRange ( ) )
2012-10-26 13:43:18 +00:00
self . statusText . SetLabel ( " Preparing: processing %s [ %d / %d ] " % ( stepName , layer , maxLayer ) )
2012-02-21 14:27:03 +00:00
class WorkerThread ( threading . Thread ) :
2012-04-24 16:46:29 +00:00
def __init__ ( self , notifyWindow , filelist , cmdList ) :
2012-02-21 14:27:03 +00:00
threading . Thread . __init__ ( self )
2012-04-24 16:46:29 +00:00
self . filelist = filelist
2012-02-21 14:27:03 +00:00
self . notifyWindow = notifyWindow
2012-04-24 16:46:29 +00:00
self . cmdList = cmdList
self . fileIdx = 0
2012-02-21 14:27:03 +00:00
self . start ( )
def run ( self ) :
2012-10-01 16:15:51 +00:00
p = sliceRun . startSliceCommandProcess ( self . cmdList [ self . fileIdx ] )
2012-02-21 14:27:03 +00:00
line = p . stdout . readline ( )
2012-03-05 17:53:19 +00:00
self . progressLog = [ ]
2012-04-24 16:46:29 +00:00
maxValue = 1
2012-02-21 14:27:03 +00:00
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 ] )
2012-02-23 14:56:03 +00:00
wx . CallAfter ( self . notifyWindow . SetProgress , progress [ 0 ] , int ( progress [ 1 ] ) , maxValue )
2012-02-21 14:27:03 +00:00
else :
2012-03-05 17:53:19 +00:00
self . progressLog . append ( line )
2012-02-21 14:27:03 +00:00
wx . CallAfter ( self . notifyWindow . statusText . SetLabel , line )
if self . notifyWindow . abort :
p . terminate ( )
wx . CallAfter ( self . notifyWindow . statusText . SetLabel , " Aborted by user. " )
return
line = p . stdout . readline ( )
2012-03-05 17:53:19 +00:00
self . returnCode = p . wait ( )
2012-04-24 16:46:29 +00:00
self . fileIdx + = 1
if self . fileIdx == len ( self . cmdList ) :
if len ( self . filelist ) > 1 :
self . _stitchMultiExtruder ( )
2012-07-05 12:12:13 +00:00
gcodeFilename = sliceRun . getExportFilename ( self . filelist [ 0 ] )
gcodefile = open ( gcodeFilename , " a " )
for logLine in self . progressLog :
if logLine . startswith ( ' Model error( ' ) :
gcodefile . write ( ' ; %s \n ' % ( logLine ) )
gcodefile . close ( )
2012-11-01 08:12:07 +00:00
wx . CallAfter ( self . notifyWindow . statusText . SetLabel , " Running plugins " )
2012-11-01 08:07:03 +00:00
ret = profile . runPostProcessingPlugins ( gcodeFilename )
if ret != None :
self . progressLog . append ( ret )
2012-04-29 10:00:13 +00:00
self . gcode = gcodeInterpreter . gcode ( )
2012-07-05 12:12:13 +00:00
self . gcode . load ( gcodeFilename )
profile . replaceGCodeTags ( gcodeFilename , self . gcode )
2012-04-24 16:46:29 +00:00
wx . CallAfter ( self . notifyWindow . OnSliceDone , self )
else :
self . run ( )
def _stitchMultiExtruder ( self ) :
files = [ ]
2012-05-29 11:42:33 +00:00
resultFile = open ( sliceRun . getExportFilename ( self . filelist [ 0 ] ) , " w " )
2012-04-24 16:46:29 +00:00
resultFile . write ( ' ;TYPE:CUSTOM \n ' )
2012-04-25 11:34:25 +00:00
resultFile . write ( profile . getAlterationFileContents ( ' start.gcode ' ) )
2012-04-24 16:46:29 +00:00
for filename in self . filelist :
2012-05-29 11:42:33 +00:00
if os . path . isfile ( sliceRun . getExportFilename ( filename , ' multi_extrude_tmp ' ) ) :
files . append ( open ( sliceRun . getExportFilename ( filename , ' multi_extrude_tmp ' ) , " r " ) )
2012-05-03 10:29:55 +00:00
else :
return
2012-04-24 16:46:29 +00:00
2012-04-25 11:34:25 +00:00
currentExtruder = 0
2012-04-27 11:45:32 +00:00
resultFile . write ( ' T %d \n ' % ( currentExtruder ) )
2012-04-25 11:34:25 +00:00
layerNr = - 1
2012-04-24 16:46:29 +00:00
hasLine = True
while hasLine :
hasLine = False
for f in files :
2012-04-25 11:34:25 +00:00
layerHasLine = False
2012-04-24 16:46:29 +00:00
for line in f :
hasLine = True
if line . startswith ( ' ;LAYER: ' ) :
break
2012-05-01 16:40:10 +00:00
if ' Z ' in line :
lastZ = float ( re . search ( ' Z([^ \ s]+) ' , line ) . group ( 1 ) )
2012-04-25 11:34:25 +00:00
if not layerHasLine :
nextExtruder = files . index ( f )
resultFile . write ( ' ;LAYER: %d \n ' % ( layerNr ) )
resultFile . write ( ' ;EXTRUDER: %d \n ' % ( nextExtruder ) )
if nextExtruder != currentExtruder :
2012-05-07 15:42:46 +00:00
resultFile . write ( ' ;TYPE:CUSTOM \n ' )
profile . setTempOverride ( ' extruder ' , nextExtruder )
resultFile . write ( profile . getAlterationFileContents ( ' switchExtruder.gcode ' ) )
profile . resetTempOverride ( )
2012-04-25 11:34:25 +00:00
currentExtruder = nextExtruder
layerHasLine = True
resultFile . write ( line )
layerNr + = 1
2012-04-24 16:46:29 +00:00
for f in files :
f . close ( )
for filename in self . filelist :
2012-05-29 11:42:33 +00:00
os . remove ( sliceRun . getExportFilename ( filename , ' multi_extrude_tmp ' ) )
2012-04-24 16:46:29 +00:00
resultFile . write ( ' ;TYPE:CUSTOM \n ' )
2012-04-25 11:34:25 +00:00
resultFile . write ( profile . getAlterationFileContents ( ' end.gcode ' ) )
2012-04-24 16:46:29 +00:00
resultFile . close ( )
2012-03-05 17:53:19 +00:00
class LogWindow ( wx . Frame ) :
def __init__ ( self , logText ) :
super ( LogWindow , self ) . __init__ ( None , title = " Slice log " )
self . textBox = wx . TextCtrl ( self , - 1 , logText , style = wx . TE_MULTILINE | wx . TE_DONTWRAP | wx . TE_READONLY )
self . SetSize ( ( 400 , 300 ) )
self . Centre ( )
self . Show ( True )
2012-02-23 14:56:03 +00:00