2014-11-20 13:21:19 +00:00
/ *
* Copyright ( C ) 2010 - 2014 Laurent CLOUET
* Author Laurent CLOUET < laurent . clouet @nopnop.net >
*
2020-05-28 13:28:42 +02:00
* This program is free software ; you can redistribute it and / or
2014-11-20 13:21:19 +00:00
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation ; version 2
* of the License .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 , USA .
* /
package com.sheepit.client ;
2021-05-11 15:36:59 +00:00
import com.sheepit.client.Configuration.ComputeType ;
import com.sheepit.client.Error.Type ;
2023-09-19 17:14:49 +00:00
import com.sheepit.client.datamodel.Chunk ;
2021-05-11 15:36:59 +00:00
import com.sheepit.client.os.OS ;
import lombok.Data ;
import lombok.Getter ;
2015-05-06 20:34:59 +01:00
import java.io.BufferedReader ;
2014-11-20 13:21:19 +00:00
import java.io.File ;
2015-05-06 20:34:59 +01:00
import java.io.FileWriter ;
import java.io.FilenameFilter ;
import java.io.IOException ;
import java.io.InputStreamReader ;
import java.io.PrintWriter ;
import java.io.StringWriter ;
import java.text.DateFormat ;
import java.text.ParseException ;
import java.text.SimpleDateFormat ;
2022-09-29 14:06:40 +00:00
import java.time.Duration ;
import java.time.Instant ;
2023-05-26 21:05:23 +00:00
import java.time.LocalTime ;
2015-05-06 20:34:59 +01:00
import java.util.ArrayList ;
2023-01-06 14:53:06 +00:00
import java.util.Arrays ;
2015-05-06 20:34:59 +01:00
import java.util.Date ;
import java.util.HashMap ;
import java.util.List ;
import java.util.Map ;
2019-08-07 18:40:02 +02:00
import java.util.Observable ;
import java.util.Observer ;
2023-07-30 21:34:11 +00:00
import java.util.Optional ;
2015-05-06 20:34:59 +01:00
import java.util.TimeZone ;
2017-04-25 13:06:23 +02:00
import java.util.Timer ;
import java.util.TimerTask ;
2020-03-19 23:48:06 +01:00
import java.util.regex.Matcher ;
2021-05-11 15:36:59 +00:00
import java.util.regex.Pattern ;
2014-11-30 23:42:57 +00:00
2020-05-28 13:28:42 +02:00
@Data public class Job {
2015-05-06 20:34:59 +01:00
public static final String UPDATE_METHOD_BY_REMAINING_TIME = " remainingtime " ;
2018-08-24 19:46:03 +02:00
public static final String UPDATE_METHOD_BY_TILE = " by_tile " ;
2023-04-26 09:33:53 +00:00
public static final String POST_LOAD_NOTIFICATION = " POST_LOAD_SCRIPT_loaded " ;
2020-05-28 13:28:42 +02:00
2020-03-19 23:48:06 +01:00
public static final int SHOW_BASE_ICON = - 1 ;
2020-05-28 13:28:42 +02:00
2019-08-07 22:17:59 +02:00
private String frameNumber ;
2023-09-19 17:14:49 +00:00
private List < Chunk > archiveChunks ;
2014-11-20 13:21:19 +00:00
private String rendererMD5 ;
private String id ;
2019-08-07 22:17:59 +02:00
private String outputImagePath ;
2023-01-06 14:53:06 +00:00
private String previewImagePath ;
2020-05-28 13:28:42 +02:00
private long outputImageSize ;
2014-11-20 13:21:19 +00:00
private String path ; // path inside of the archive
private String rendererCommand ;
2020-04-14 17:35:54 +02:00
private String validationUrl ;
2014-11-20 13:21:19 +00:00
private String script ;
private boolean useGPU ;
2016-01-08 20:53:58 +01:00
private String name ;
2021-05-11 15:36:59 +00:00
private char [ ] password ;
2014-11-20 13:21:19 +00:00
private String updateRenderingStatusMethod ;
2020-06-03 00:06:03 +10:00
private String blenderShortVersion ;
private String blenderLongVersion ;
2014-12-05 15:15:24 +00:00
private boolean synchronousUpload ;
2023-02-02 18:25:53 +01:00
private float speedSamplesRendered ; // only used for powerdetection project
2015-04-27 20:10:36 +01:00
private RenderProcess render ;
2014-12-03 20:09:50 +00:00
private boolean askForRendererKill ;
2015-10-27 21:00:44 +00:00
private boolean userBlockJob ;
2016-11-01 19:44:09 +01:00
private boolean serverBlockJob ;
2015-05-06 20:34:59 +01:00
private Gui gui ;
2019-08-07 22:17:59 +02:00
private Configuration configuration ;
2015-05-06 20:34:59 +01:00
private Log log ;
2014-11-20 13:21:19 +00:00
2020-05-28 13:28:42 +02:00
public Job ( Configuration config_ , Gui gui_ , Log log_ , String id_ , String frame_ , String path_ , boolean use_gpu , String command_ , String validationUrl_ ,
2023-09-19 17:14:49 +00:00
String script_ , List < Chunk > archiveChunks_ , String rendererMd5_ , String name_ , char [ ] password_ , boolean synchronous_upload_ ,
2020-05-28 13:28:42 +02:00
String update_method_ ) {
2019-08-07 22:17:59 +02:00
configuration = config_ ;
2014-11-20 13:21:19 +00:00
id = id_ ;
2019-08-07 22:17:59 +02:00
frameNumber = frame_ ;
2014-11-20 13:21:19 +00:00
path = path_ ;
useGPU = use_gpu ;
rendererCommand = command_ ;
2020-04-14 17:35:54 +02:00
validationUrl = validationUrl_ ;
2023-09-19 17:14:49 +00:00
archiveChunks = archiveChunks_ ;
2014-11-20 13:21:19 +00:00
rendererMD5 = rendererMd5_ ;
2016-01-08 20:53:58 +01:00
name = name_ ;
2016-10-05 23:01:03 +02:00
password = password_ ;
2014-12-05 15:15:24 +00:00
synchronousUpload = synchronous_upload_ ;
2015-05-06 20:34:59 +01:00
gui = gui_ ;
2019-08-07 22:17:59 +02:00
outputImagePath = null ;
2020-04-20 01:01:43 +10:00
outputImageSize = 0 ;
2014-11-20 13:21:19 +00:00
script = script_ ;
2015-01-13 21:07:58 +01:00
updateRenderingStatusMethod = update_method_ ;
2014-12-03 20:09:50 +00:00
askForRendererKill = false ;
2015-10-27 21:00:44 +00:00
userBlockJob = false ;
2016-11-01 19:44:09 +01:00
serverBlockJob = false ;
2015-05-06 20:34:59 +01:00
log = log_ ;
2021-12-21 10:08:59 +00:00
render = new RenderProcess ( log_ ) ;
2020-06-03 00:06:03 +10:00
blenderShortVersion = null ;
blenderLongVersion = null ;
2023-02-02 18:25:53 +01:00
speedSamplesRendered = 0 ;
2015-04-27 20:10:36 +01:00
}
2017-02-19 14:19:48 +01:00
public void block ( ) {
setAskForRendererKill ( true ) ;
setUserBlockJob ( true ) ;
RenderProcess process = getProcessRender ( ) ;
if ( process ! = null ) {
2023-07-15 14:49:03 +00:00
process . kill ( ) ;
2017-02-19 14:19:48 +01:00
}
}
2015-04-27 20:10:36 +01:00
public RenderProcess getProcessRender ( ) {
return render ;
2014-11-20 13:21:19 +00:00
}
public String toString ( ) {
2020-05-28 13:28:42 +02:00
return String
2023-09-19 17:14:49 +00:00
. format ( " Job (numFrame '%s' archiveChunks %s rendererMD5 '%s' ID '%s' pictureFilename '%s' jobPath '%s' gpu %s name '%s' updateRenderingStatusMethod '%s' render %s) " ,
frameNumber , archiveChunks , rendererMD5 , id , outputImagePath , path , useGPU , name , updateRenderingStatusMethod , render ) ;
2014-11-20 13:21:19 +00:00
}
public String getPrefixOutputImage ( ) {
return id + " _ " ;
}
public String getRendererDirectory ( ) {
2019-08-07 22:17:59 +02:00
return configuration . getWorkingDirectory ( ) . getAbsolutePath ( ) + File . separator + rendererMD5 ;
2014-11-20 13:21:19 +00:00
}
2020-10-21 22:03:09 +11:00
public String getRequiredRendererArchivePath ( ) {
if ( configuration . getSharedDownloadsDirectory ( ) ! = null ) {
return configuration . getSharedDownloadsDirectory ( ) . getAbsolutePath ( ) + File . separator + rendererMD5 + " .zip " ;
}
else {
return getRendererArchivePath ( ) ;
}
}
2014-11-20 13:21:19 +00:00
public String getRendererPath ( ) {
2014-11-30 23:42:57 +00:00
return getRendererDirectory ( ) + File . separator + OS . getOS ( ) . getRenderBinaryPath ( ) ;
2014-11-20 13:21:19 +00:00
}
public String getRendererArchivePath ( ) {
2019-08-07 22:17:59 +02:00
return configuration . getStorageDir ( ) . getAbsolutePath ( ) + File . separator + rendererMD5 + " .zip " ;
2014-11-20 13:21:19 +00:00
}
2023-09-19 17:14:49 +00:00
public String getRequiredProjectChunkPath ( String chunk ) {
2020-10-21 22:03:09 +11:00
if ( configuration . getSharedDownloadsDirectory ( ) ! = null ) {
2023-09-19 17:14:49 +00:00
return configuration . getSharedDownloadsDirectory ( ) . getAbsolutePath ( ) + File . separator + chunk + " .wool " ;
2020-10-21 22:03:09 +11:00
}
else {
2023-09-19 17:14:49 +00:00
return getSceneArchiveChunkPath ( chunk ) ;
2020-10-21 22:03:09 +11:00
}
}
2014-11-20 13:21:19 +00:00
public String getSceneDirectory ( ) {
2023-09-19 17:14:49 +00:00
return configuration . getWorkingDirectory ( ) . getAbsolutePath ( ) + File . separator + this . id ;
2014-11-20 13:21:19 +00:00
}
public String getScenePath ( ) {
return getSceneDirectory ( ) + File . separator + this . path ;
}
2023-09-19 17:14:49 +00:00
public String getSceneArchiveChunkPath ( String chunk ) {
return configuration . getWorkingDirectory ( ) . getAbsolutePath ( ) + File . separator + chunk + " .wool " ;
2014-11-20 13:21:19 +00:00
}
2015-05-06 20:34:59 +01:00
2019-08-07 18:40:02 +02:00
public Error . Type render ( Observer renderStarted ) {
2016-10-12 00:34:51 +02:00
gui . status ( " Rendering " ) ;
2015-05-06 20:34:59 +01:00
RenderProcess process = getProcessRender ( ) ;
2017-04-25 13:06:23 +02:00
Timer timerOfMaxRenderTime = null ;
2017-02-11 16:54:40 +01:00
String core_script = " " ;
2018-06-02 15:11:45 +02:00
// When sending Ctrl+C to the terminal it also get's sent to all subprocesses e.g. also the render process.
// The java program handles Ctrl+C but the renderer quits on Ctrl+C.
// This script causes the renderer to ignore Ctrl+C.
2020-05-28 13:28:42 +02:00
String ignore_signal_script = " import signal \ n " + " def hndl(signum, frame): \ n " + " pass \ n " + " signal.signal(signal.SIGINT, hndl) \ n " ;
2019-08-07 22:17:59 +02:00
if ( isUseGPU ( ) & & configuration . getGPUDevice ( ) ! = null & & configuration . getComputeMethod ( ) ! = ComputeType . CPU ) {
2020-05-28 13:28:42 +02:00
core_script = " sheepit_set_compute_device( \" " + configuration . getGPUDevice ( ) . getType ( ) + " \" , \" GPU \" , \" " + configuration . getGPUDevice ( ) . getId ( )
+ " \" ) \ n " ;
2017-05-07 21:00:20 +02:00
gui . setComputeMethod ( " GPU " ) ;
2015-05-06 20:34:59 +01:00
}
else {
2020-05-16 18:20:38 +10:00
// Otherwise (CPU), fix the tile size to 32x32px
2017-02-11 16:54:40 +01:00
core_script = " sheepit_set_compute_device( \" NONE \" , \" CPU \" , \" CPU \" ) \ n " ;
2017-05-07 21:00:20 +02:00
gui . setComputeMethod ( " CPU " ) ;
2015-05-06 20:34:59 +01:00
}
2018-06-02 15:11:45 +02:00
core_script + = ignore_signal_script ;
2023-03-27 15:39:09 +00:00
File disableViewportScript = null ;
2015-05-06 20:34:59 +01:00
File script_file = null ;
2021-05-11 15:36:59 +00:00
String [ ] command1 = getRendererCommand ( ) . split ( " " ) ;
2015-05-06 20:34:59 +01:00
int size_command = command1 . length + 2 ; // + 2 for script
2019-08-07 22:17:59 +02:00
if ( configuration . getNbCores ( ) > 0 ) { // user has specified something
2015-05-06 20:34:59 +01:00
size_command + = 2 ;
}
2021-05-11 15:36:59 +00:00
List < String > command = new ArrayList < > ( size_command ) ;
2015-05-06 20:34:59 +01:00
2021-05-11 15:36:59 +00:00
Map < String , String > new_env = new HashMap < > ( ) ;
2015-05-06 20:34:59 +01:00
2021-04-04 17:34:39 +00:00
2020-12-13 10:29:38 +01:00
new_env . put ( " TEMP " , configuration . getWorkingDirectory ( ) . getAbsolutePath ( ) . replace ( " \\ " , " \\ \\ " ) ) ;
new_env . put ( " TMP " , configuration . getWorkingDirectory ( ) . getAbsolutePath ( ) . replace ( " \\ " , " \\ \\ " ) ) ;
2019-08-07 22:17:59 +02:00
new_env . put ( " CORES " , Integer . toString ( configuration . getNbCores ( ) ) ) ;
new_env . put ( " PRIORITY " , Integer . toString ( configuration . getPriority ( ) ) ) ;
2021-04-04 17:34:39 +00:00
//make sure the system doesn´ t interfere with the blender runtime, and that blender doesn´ t attempt to load external libraries/scripts.
new_env . put ( " BLENDER_USER_CONFIG " , " " ) ;
new_env . put ( " BLENDER_USER_SCRIPTS " , " " ) ;
new_env . put ( " BLENDER_SYSTEM_SCRIPTS " , " " ) ;
new_env . put ( " BLENDER_USER_DATAFILES " , " " ) ;
new_env . put ( " BLENDER_SYSTEM_DATAFILES " , " " ) ;
2021-05-27 22:36:41 +02:00
new_env . put ( " OCIO " , " " ) ; //prevent blender from loading a non-standard color configuration
2015-05-06 20:34:59 +01:00
2023-07-30 21:34:11 +00:00
// Add own lib folder first, because Steam or other environments may set an LD_LIBRARY_PATH that has priority over the runpath in the Blender excutable,
// but contains incompatible libraries.
String currentLDLibraryPath = Optional . ofNullable ( System . getenv ( " LD_LIBRARY_PATH " ) ) . orElse ( " " ) ;
new_env . put ( " LD_LIBRARY_PATH " , getRendererDirectory ( ) + " /lib " + " : " + currentLDLibraryPath ) ;
2015-05-06 20:34:59 +01:00
for ( String arg : command1 ) {
switch ( arg ) {
case " .c " :
2023-03-27 15:39:09 +00:00
command . add ( " -P " ) ;
try {
2023-04-26 09:33:53 +00:00
disableViewportScript = File . createTempFile ( " pre_load_script_ " , " .py " , configuration . getWorkingDirectory ( ) ) ;
2023-03-27 15:39:09 +00:00
File file = new File ( disableViewportScript . getAbsolutePath ( ) ) ;
FileWriter fwriter ;
fwriter = new FileWriter ( file ) ;
PrintWriter out = new PrintWriter ( fwriter ) ;
out . write ( " import bpy " ) ;
out . write ( " \ n " ) ;
2023-04-26 09:33:53 +00:00
out . write ( " import sys " ) ;
out . write ( " \ n " ) ;
2023-03-27 15:39:09 +00:00
out . write ( " from bpy.app.handlers import persistent " ) ;
out . write ( " \ n " ) ;
out . write ( " @persistent " ) ;
out . write ( " \ n " ) ;
2023-04-26 09:33:53 +00:00
out . write ( " def hide_stuff(hide_dummy): " ) ;
out . write ( " \ n " ) ;
out . write ( " print('PRE_LOAD_SCRIPT_hide_viewport') " ) ;
2023-03-27 15:39:09 +00:00
out . write ( " \ n " ) ;
2023-04-26 09:33:53 +00:00
out . write ( " #Hide collections in the viewport " ) ;
2023-03-27 15:39:09 +00:00
out . write ( " \ n " ) ;
out . write ( " for col in bpy.data.collections: " ) ;
out . write ( " \ n " ) ;
2023-04-26 09:33:53 +00:00
out . write ( " col.hide_viewport = True " ) ;
2023-03-27 15:39:09 +00:00
out . write ( " \ n " ) ;
out . write ( " for obj in bpy.data.objects: " ) ;
out . write ( " \ n " ) ;
out . write ( " #Hide objects in the viewport " ) ;
out . write ( " \ n " ) ;
out . write ( " obj.hide_viewport = True " ) ;
out . write ( " \ n " ) ;
out . write ( " #Hide modifier in the viewport " ) ;
out . write ( " \ n " ) ;
out . write ( " for mod in obj.modifiers: " ) ;
out . write ( " \ n " ) ;
out . write ( " mod.show_viewport = False " ) ;
out . write ( " \ n " ) ;
2023-04-26 09:33:53 +00:00
out . write ( " sys.stdout.flush() " ) ;
out . write ( " \ n " ) ;
2023-03-27 15:39:09 +00:00
out . write ( " bpy.app.handlers.version_update.append(hide_stuff) " ) ;
out . write ( " \ n " ) ;
out . close ( ) ;
command . add ( disableViewportScript . getAbsolutePath ( ) ) ;
}
catch ( IOException e ) {
StringWriter sw = new StringWriter ( ) ;
e . printStackTrace ( new PrintWriter ( sw ) ) ;
for ( String logline : configuration . filesystemHealthCheck ( ) ) {
log . debug ( logline ) ;
}
log . error ( " Job::render exception on script generation, will return UNKNOWN " + e + " stacktrace " + sw . toString ( ) ) ;
return Error . Type . UNKNOWN ;
}
2015-05-06 20:34:59 +01:00
command . add ( getScenePath ( ) ) ;
command . add ( " -P " ) ;
try {
2023-04-26 09:33:53 +00:00
script_file = File . createTempFile ( " post_load_script_ " , " .py " , configuration . getWorkingDirectory ( ) ) ;
2015-05-06 20:34:59 +01:00
File file = new File ( script_file . getAbsolutePath ( ) ) ;
FileWriter txt ;
txt = new FileWriter ( file ) ;
PrintWriter out = new PrintWriter ( txt ) ;
out . write ( getScript ( ) ) ;
out . write ( " \ n " ) ;
2023-04-26 09:33:53 +00:00
out . write ( " import sys " ) ;
out . write ( " \ n " ) ;
out . write ( " print(' " + POST_LOAD_NOTIFICATION + " ') " ) ;
out . write ( " \ n " ) ;
out . write ( " sys.stdout.flush() " ) ;
out . write ( " \ n " ) ;
2015-05-06 20:34:59 +01:00
out . write ( core_script ) ; // GPU part
out . write ( " \ n " ) ; // GPU part
out . close ( ) ;
command . add ( script_file . getAbsolutePath ( ) ) ;
}
catch ( IOException e ) {
StringWriter sw = new StringWriter ( ) ;
e . printStackTrace ( new PrintWriter ( sw ) ) ;
2023-01-06 14:43:14 +00:00
for ( String logline : configuration . filesystemHealthCheck ( ) ) {
log . debug ( logline ) ;
}
2016-08-29 17:56:21 +02:00
log . error ( " Job::render exception on script generation, will return UNKNOWN " + e + " stacktrace " + sw . toString ( ) ) ;
2015-05-06 20:34:59 +01:00
return Error . Type . UNKNOWN ;
}
script_file . deleteOnExit ( ) ;
break ;
case " .e " :
command . add ( getRendererPath ( ) ) ;
// the number of cores has to be put after the binary and before the scene arg
2019-08-07 22:17:59 +02:00
if ( configuration . getNbCores ( ) > 0 ) {
2015-05-06 20:34:59 +01:00
command . add ( " -t " ) ;
2019-08-07 22:17:59 +02:00
command . add ( Integer . toString ( configuration . getNbCores ( ) ) ) ;
2015-05-06 20:34:59 +01:00
}
break ;
case " .o " :
2019-08-07 22:17:59 +02:00
command . add ( configuration . getWorkingDirectory ( ) . getAbsolutePath ( ) + File . separator + getPrefixOutputImage ( ) ) ;
2015-05-06 20:34:59 +01:00
break ;
case " .f " :
command . add ( getFrameNumber ( ) ) ;
break ;
default :
command . add ( arg ) ;
break ;
}
}
2021-11-16 14:51:53 +00:00
Timer memoryCheck = new Timer ( ) ;
2015-05-06 20:34:59 +01:00
try {
2019-08-07 18:40:02 +02:00
renderStartedObservable event = new renderStartedObservable ( renderStarted ) ;
2015-05-06 20:34:59 +01:00
String line ;
log . debug ( command . toString ( ) ) ;
OS os = OS . getOS ( ) ;
2019-08-07 22:17:59 +02:00
process . setCoresUsed ( configuration . getNbCores ( ) ) ;
2015-05-06 20:34:59 +01:00
process . start ( ) ;
getProcessRender ( ) . setProcess ( os . exec ( command , new_env ) ) ;
2021-12-21 10:08:59 +00:00
getProcessRender ( ) . setOsProcess ( OS . operatingSystem . getProcess ( ( int ) getProcessRender ( ) . getProcess ( ) . pid ( ) ) ) ;
2015-05-06 20:34:59 +01:00
BufferedReader input = new BufferedReader ( new InputStreamReader ( getProcessRender ( ) . getProcess ( ) . getInputStream ( ) ) ) ;
2021-11-16 14:51:53 +00:00
memoryCheck . scheduleAtFixedRate ( new TimerTask ( ) {
@Override
public void run ( ) {
2021-12-21 10:08:59 +00:00
updateProcess ( ) ;
2021-11-16 14:51:53 +00:00
}
2021-12-21 10:08:59 +00:00
} , 0L , 200L ) ;
2015-05-06 20:34:59 +01:00
2020-08-30 00:13:20 +10:00
// Make initial test/power frames ignore the maximum render time in user configuration. Initial test frames have Job IDs below 20
// so we just activate the user defined timeout when the scene is not one of the initial ones.
if ( configuration . getMaxRenderTime ( ) > 0 & & Integer . parseInt ( this . getId ( ) ) > = 20 ) {
2017-04-25 13:06:23 +02:00
timerOfMaxRenderTime = new Timer ( ) ;
timerOfMaxRenderTime . schedule ( new TimerTask ( ) {
2020-05-28 13:28:42 +02:00
@Override public void run ( ) {
2017-04-25 13:06:23 +02:00
RenderProcess process = getProcessRender ( ) ;
if ( process ! = null ) {
2020-05-28 13:28:42 +02:00
long duration = ( new Date ( ) . getTime ( ) - process . getStartTime ( ) ) / 1000 ; // in seconds
if ( configuration . getMaxRenderTime ( ) > 0 & & duration > configuration . getMaxRenderTime ( ) ) {
2020-06-12 19:32:06 +10:00
setAskForRendererKill ( true ) ;
2023-07-15 14:49:03 +00:00
log . debug ( " Killing render - exceeding allowed process duration " ) ;
process . kill ( ) ;
2017-04-25 13:06:23 +02:00
}
}
}
2019-08-07 22:17:59 +02:00
} , configuration . getMaxRenderTime ( ) * 1000 + 2000 ) ; // +2s to be sure the delay is over
2017-04-25 13:06:23 +02:00
}
2022-09-29 14:06:40 +00:00
2015-05-06 20:34:59 +01:00
log . debug ( " renderer output " ) ;
try {
2020-03-19 23:48:06 +01:00
int progress = - 1 ;
2020-05-28 13:28:42 +02:00
2022-02-14 11:30:09 +00:00
Pattern progressPattern = Pattern . compile ( " (Rendered|Path Tracing Tile|Rendering|Sample) ( \\ d+) \\ s? \\ / \\ s?( \\ d+)( Tiles| samples|,)* " ) ;
2023-04-26 09:33:53 +00:00
Pattern beginScenePrepPattern = Pattern . compile ( POST_LOAD_NOTIFICATION ) ;
2022-09-29 14:06:40 +00:00
Pattern beginPostProcessingPattern = Pattern . compile ( " ^Fra: \\ d* \\ w*(.)* \\ | (Compositing|Denoising) " ) ;
2023-05-26 21:05:23 +00:00
Pattern savingPattern = Pattern . compile ( " Time: \\ d \\ d: \\ d \\ d. \\ d \\ d \\ (Saving: ( \\ d \\ d: \\ d \\ d. \\ d \\ d) " ) ;
int savingTimeSeconds = - 1 ;
2022-09-29 14:06:40 +00:00
Instant timeStamp = null ;
Duration phaseDuration ; //We divide the job into 3 phases: preparation, rendering, compositing
boolean scenePrepStarted = false ;
boolean renderingStarted = false ;
boolean postProcessingStarted = false ;
2020-05-28 13:28:42 +02:00
2020-06-17 18:24:59 +10:00
// Initialise the progress bar in the icon and the UI (0% completed at this time)
2020-03-19 23:48:06 +01:00
gui . updateTrayIcon ( 0 ) ;
2023-01-05 16:25:29 +01:00
gui . status ( " Preparing project " , 0 ) ;
2020-05-28 13:28:42 +02:00
2015-05-06 20:34:59 +01:00
while ( ( line = input . readLine ( ) ) ! = null ) {
2017-03-29 22:13:04 +02:00
log . debug ( line ) ;
2020-05-28 13:28:42 +02:00
2020-06-03 00:06:03 +10:00
// Process lines until the version is loaded (usually first or second line of log)
if ( blenderLongVersion = = null ) {
Pattern blenderPattern = Pattern . compile ( " Blender (([0-9]{1,3} \\ .[0-9]{0,3}).*)$ " ) ;
Matcher blendDetectedVersion = blenderPattern . matcher ( line ) ;
if ( blendDetectedVersion . find ( ) ) {
blenderLongVersion = blendDetectedVersion . group ( 1 ) ;
blenderShortVersion = blendDetectedVersion . group ( 2 ) ;
}
}
2022-09-29 14:06:40 +00:00
Matcher scenePrepDetector = beginScenePrepPattern . matcher ( line ) ;
if ( scenePrepStarted = = false & & scenePrepDetector . find ( ) ) {
scenePrepStarted = true ;
timeStamp = Instant . now ( ) ;
}
2022-02-14 11:30:09 +00:00
progress = computeRenderingProgress ( line , progressPattern , progress ) ;
2022-09-29 14:06:40 +00:00
if ( renderingStarted = = false & & progress ! = - 1 ) {
renderingStarted = true ;
if ( timeStamp = = null ) {
timeStamp = new Date ( process . getStartTime ( ) ) . toInstant ( ) ;
}
phaseDuration = Duration . between ( timeStamp , Instant . now ( ) ) ;
timeStamp = Instant . now ( ) ;
process . setScenePrepDuration ( ( int ) phaseDuration . toSeconds ( ) ) ;
}
Matcher postProcessingDetector = beginPostProcessingPattern . matcher ( line ) ;
if ( postProcessingStarted = = false & & postProcessingDetector . find ( ) ) {
postProcessingStarted = true ;
if ( timeStamp = = null ) {
timeStamp = new Date ( process . getStartTime ( ) ) . toInstant ( ) ;
}
phaseDuration = Duration . between ( timeStamp , Instant . now ( ) ) ;
timeStamp = Instant . now ( ) ;
process . setRenderDuration ( ( int ) phaseDuration . toSeconds ( ) ) ;
}
2023-05-26 21:05:23 +00:00
Matcher savingTimeDetector = savingPattern . matcher ( line ) ;
if ( savingTimeDetector . find ( ) ) {
String savingTime = savingTimeDetector . group ( 1 ) ;
if ( savingTime ! = null ) {
savingTimeSeconds = ( int ) Duration . between ( LocalTime . MIN , LocalTime . parse ( " 00: " + savingTime ) ) . toSeconds ( ) ; //add leading hours to comply with ISO time format
}
}
2021-12-21 10:08:59 +00:00
if ( configuration . getMaxAllowedMemory ( ) ! = - 1 & & getProcessRender ( ) . getMemoryUsed ( ) . get ( ) > configuration . getMaxAllowedMemory ( ) ) {
log . debug ( " Blocking render because process ram used ( " + getProcessRender ( ) . getMemoryUsed ( ) . get ( ) + " k) is over user setting ( " + configuration
2021-11-16 14:51:53 +00:00
. getMaxAllowedMemory ( ) + " k) " ) ;
2017-03-29 22:13:04 +02:00
process . finish ( ) ;
2022-09-29 14:06:40 +00:00
if ( process . getRenderDuration ( ) = = - 1 ) {
if ( timeStamp = = null ) {
timeStamp = new Date ( process . getStartTime ( ) ) . toInstant ( ) ;
}
phaseDuration = Duration . between ( timeStamp , Instant . now ( ) ) ;
process . setRenderDuration ( ( int ) phaseDuration . toSeconds ( ) ) ;
}
2017-03-29 22:13:04 +02:00
if ( script_file ! = null ) {
script_file . delete ( ) ;
}
2023-03-27 15:39:09 +00:00
if ( disableViewportScript ! = null ) {
disableViewportScript . delete ( ) ;
}
2020-05-28 13:28:42 +02:00
2020-03-19 23:48:06 +01:00
// Once the process is finished (either finished successfully or with an error) move back to
// base icon (isolated S with no progress bar)
gui . updateTrayIcon ( Job . SHOW_BASE_ICON ) ;
2020-05-28 13:28:42 +02:00
2017-03-29 22:13:04 +02:00
return Error . Type . RENDERER_OUT_OF_MEMORY ;
}
2015-05-06 20:34:59 +01:00
2023-02-02 18:25:53 +01:00
updateSpeedSamplesRendered ( line , progress ) ;
2022-02-14 11:30:09 +00:00
updateRenderingStatus ( line , progress ) ;
2015-05-06 20:34:59 +01:00
Type error = detectError ( line ) ;
if ( error ! = Error . Type . OK ) {
if ( script_file ! = null ) {
script_file . delete ( ) ;
}
2023-03-27 15:39:09 +00:00
if ( disableViewportScript ! = null ) {
disableViewportScript . delete ( ) ;
}
2022-09-29 14:06:40 +00:00
if ( process . getRenderDuration ( ) = = - 1 ) {
if ( timeStamp = = null ) {
timeStamp = new Date ( process . getStartTime ( ) ) . toInstant ( ) ;
}
phaseDuration = Duration . between ( timeStamp , Instant . now ( ) ) ;
process . setRenderDuration ( ( int ) phaseDuration . toSeconds ( ) ) ;
}
2020-03-19 23:48:06 +01:00
// Put back base icon
gui . updateTrayIcon ( Job . SHOW_BASE_ICON ) ;
2023-07-15 14:49:03 +00:00
process . kill ( ) ;
2023-01-06 14:43:14 +00:00
for ( String logline : configuration . filesystemHealthCheck ( ) ) {
log . debug ( logline ) ;
}
2020-05-28 13:28:42 +02:00
2015-05-06 20:34:59 +01:00
return error ;
}
2020-05-28 13:28:42 +02:00
2023-04-06 14:27:02 +02:00
if ( ! event . isStarted ( ) & & ( getProcessRender ( ) . getMemoryUsed ( ) . get ( ) > 0 & & scenePrepStarted | | process . getRemainingDuration ( ) > 0 ) ) {
2019-08-07 18:40:02 +02:00
event . doNotifyIsStarted ( ) ;
2019-08-07 17:02:52 +02:00
}
2015-05-06 20:34:59 +01:00
}
2022-09-29 14:06:40 +00:00
if ( timeStamp = = null ) {
timeStamp = new Date ( process . getStartTime ( ) ) . toInstant ( ) ;
}
2023-05-26 21:05:23 +00:00
2022-09-29 14:06:40 +00:00
if ( postProcessingStarted = = false ) {
phaseDuration = Duration . between ( timeStamp , Instant . now ( ) ) ;
process . setRenderDuration ( ( int ) phaseDuration . toSeconds ( ) ) ;
2023-05-26 21:05:23 +00:00
//we need to subtract the time to save the frame to disk
if ( savingTimeSeconds > 0 & & process . getRenderDuration ( ) > 0 ) {
process . setRenderDuration ( Math . max ( 0 , process . getRenderDuration ( ) - savingTimeSeconds ) ) ;
}
2022-09-29 14:06:40 +00:00
}
else {
phaseDuration = Duration . between ( timeStamp , Instant . now ( ) ) ;
process . setPostProcessingDuration ( ( int ) phaseDuration . toSeconds ( ) ) ;
}
2015-05-06 20:34:59 +01:00
input . close ( ) ;
2022-09-29 14:06:40 +00:00
2023-05-26 21:05:23 +00:00
log . debug ( String . format ( " render times: %n \ tScene prep: %ds%n \ tRendering: %ds%n \ tPost: %ss%n \ tTotal: %ds%n \ tRendering/Total: %.03f%n " ,
2022-09-29 14:06:40 +00:00
process . getScenePrepDuration ( ) ,
process . getRenderDuration ( ) ,
process . getPostProcessingDuration ( ) ,
process . getDuration ( ) ,
( Math . max ( process . getRenderDuration ( ) , 0 ) * 100 . 0 ) / process . getDuration ( )
) ) ;
2015-05-06 20:34:59 +01:00
}
catch ( IOException err1 ) { // for the input.readline
// most likely The handle is invalid
2016-08-29 17:56:21 +02:00
log . error ( " Job::render exception(B) (silent error) " + err1 ) ;
2015-05-06 20:34:59 +01:00
}
2021-11-16 14:51:53 +00:00
finally {
memoryCheck . cancel ( ) ;
}
2020-05-28 13:28:42 +02:00
2020-03-19 23:48:06 +01:00
// Put back base icon
gui . updateTrayIcon ( Job . SHOW_BASE_ICON ) ;
2023-07-15 14:49:03 +00:00
2015-05-06 20:34:59 +01:00
log . debug ( " end of rendering " ) ;
2023-07-15 14:49:03 +00:00
2015-05-06 20:34:59 +01:00
}
catch ( Exception err ) {
if ( script_file ! = null ) {
script_file . delete ( ) ;
}
2023-03-27 15:39:09 +00:00
if ( disableViewportScript ! = null ) {
disableViewportScript . delete ( ) ;
}
2015-05-06 20:34:59 +01:00
StringWriter sw = new StringWriter ( ) ;
err . printStackTrace ( new PrintWriter ( sw ) ) ;
2023-01-06 14:43:14 +00:00
for ( String logline : configuration . filesystemHealthCheck ( ) ) {
log . debug ( logline ) ;
}
2016-08-29 17:56:21 +02:00
log . error ( " Job::render exception(A) " + err + " stacktrace " + sw . toString ( ) ) ;
2015-05-06 20:34:59 +01:00
return Error . Type . FAILED_TO_EXECUTE ;
}
int exit_value = process . exitValue ( ) ;
process . finish ( ) ;
2017-04-25 13:06:23 +02:00
if ( timerOfMaxRenderTime ! = null ) {
timerOfMaxRenderTime . cancel ( ) ;
}
2015-05-06 20:34:59 +01:00
if ( script_file ! = null ) {
script_file . delete ( ) ;
}
2023-03-27 15:39:09 +00:00
if ( disableViewportScript ! = null ) {
disableViewportScript . delete ( ) ;
}
2015-05-06 20:34:59 +01:00
// find the picture file
final String filename_without_extension = getPrefixOutputImage ( ) + getFrameNumber ( ) ;
FilenameFilter textFilter = new FilenameFilter ( ) {
public boolean accept ( File dir , String name ) {
return name . startsWith ( filename_without_extension ) ;
}
} ;
2019-08-07 22:17:59 +02:00
File [ ] files = configuration . getWorkingDirectory ( ) . listFiles ( textFilter ) ;
2020-05-28 13:28:42 +02:00
2019-08-07 22:17:59 +02:00
if ( isAskForRendererKill ( ) ) {
2016-08-29 18:06:17 +02:00
log . debug ( " Job::render been asked to end render " ) ;
2017-04-25 13:06:23 +02:00
2020-05-28 13:28:42 +02:00
long duration = ( new Date ( ) . getTime ( ) - process . getStartTime ( ) ) / 1000 ; // in seconds
2020-08-30 00:13:20 +10:00
if ( configuration . getMaxRenderTime ( ) > 0 & & duration > configuration . getMaxRenderTime ( ) & & Integer . parseInt ( this . getId ( ) ) > = 20 ) {
2019-08-07 22:17:59 +02:00
log . debug ( " Render killed because process duration ( " + duration + " s) is over user setting ( " + configuration . getMaxRenderTime ( ) + " s) " ) ;
2017-04-25 13:06:23 +02:00
return Error . Type . RENDERER_KILLED_BY_USER_OVER_TIME ;
}
2016-08-29 18:06:17 +02:00
if ( files . length ! = 0 ) {
2023-01-06 14:53:06 +00:00
Arrays . stream ( files ) . forEach ( file - > new File ( file . getAbsolutePath ( ) ) . delete ( ) ) ;
2016-08-29 18:06:17 +02:00
}
2019-08-07 22:17:59 +02:00
if ( isServerBlockJob ( ) ) {
2016-11-01 19:44:09 +01:00
return Error . Type . RENDERER_KILLED_BY_SERVER ;
}
2019-08-07 22:17:59 +02:00
if ( isUserBlockJob ( ) ) {
2016-08-29 18:06:17 +02:00
return Error . Type . RENDERER_KILLED_BY_USER ;
}
return Error . Type . RENDERER_KILLED ;
}
2015-05-06 20:34:59 +01:00
if ( files . length = = 0 ) {
2023-01-06 14:43:14 +00:00
for ( String logline : configuration . filesystemHealthCheck ( ) ) {
log . debug ( logline ) ;
}
2016-08-29 17:56:21 +02:00
log . error ( " Job::render no picture file found (after finished render (filename_without_extension " + filename_without_extension + " ) " ) ;
2015-05-06 20:34:59 +01:00
String basename = " " ;
try {
basename = getPath ( ) . substring ( 0 , getPath ( ) . lastIndexOf ( '.' ) ) ;
}
catch ( Exception e ) {
e . printStackTrace ( ) ;
}
2019-08-07 22:17:59 +02:00
File crash_file = new File ( configuration . getWorkingDirectory ( ) + File . separator + basename + " .crash.txt " ) ;
2015-05-06 20:34:59 +01:00
if ( crash_file . exists ( ) ) {
2023-01-06 14:43:14 +00:00
for ( String logline : configuration . filesystemHealthCheck ( ) ) {
log . debug ( logline ) ;
}
2016-08-29 17:56:21 +02:00
log . error ( " Job::render crash file found => the renderer crashed " ) ;
2015-05-06 20:34:59 +01:00
crash_file . delete ( ) ;
return Error . Type . RENDERER_CRASHED ;
}
if ( exit_value = = 127 & & process . getDuration ( ) < 10 ) {
2023-01-06 14:43:14 +00:00
for ( String logline : configuration . filesystemHealthCheck ( ) ) {
log . debug ( logline ) ;
}
2016-08-29 17:56:21 +02:00
log . error ( " Job::render renderer returned 127 and took " + process . getDuration ( ) + " s, some libraries may be missing " ) ;
2015-05-06 20:34:59 +01:00
return Error . Type . RENDERER_MISSING_LIBRARIES ;
}
return Error . Type . NOOUTPUTFILE ;
}
else {
2023-01-06 14:53:06 +00:00
if ( files . length = = 2 ) {
Arrays . sort ( files ) ; //in case of an exr we end up with 2 images, the output as an exr and the preview as a jpg, we want to ensure the output comes first
String path = files [ 1 ] . getAbsolutePath ( ) ;
String extension = path . substring ( path . lastIndexOf ( " . " ) + 1 ) . toLowerCase ( ) ;
if ( " jpg " . equals ( extension ) ) {
setPreviewImagePath ( files [ 1 ] . getAbsolutePath ( ) ) ;
}
}
2015-05-06 20:34:59 +01:00
setOutputImagePath ( files [ 0 ] . getAbsolutePath ( ) ) ;
2020-04-20 01:01:43 +10:00
this . outputImageSize = new File ( getOutputImagePath ( ) ) . length ( ) ;
2020-05-28 13:28:42 +02:00
log . debug ( String . format ( " Job::render pictureFilename: %s, size: %d' " , getOutputImagePath ( ) , this . outputImageSize ) ) ;
2015-05-06 20:34:59 +01:00
}
File scene_dir = new File ( getSceneDirectory ( ) ) ;
long date_modification_scene_directory = ( long ) Utils . lastModificationTime ( scene_dir ) ;
if ( date_modification_scene_directory > process . getStartTime ( ) ) {
scene_dir . delete ( ) ;
}
2023-05-21 15:07:18 +00:00
gui . status ( String . format ( " Render time: %dmin%ds " ,
2022-09-29 14:06:40 +00:00
process . getRenderDuration ( ) / 60 ,
process . getRenderDuration ( ) % 60 )
) ;
2015-05-06 20:34:59 +01:00
return Error . Type . OK ;
}
2020-05-28 13:28:42 +02:00
2020-03-19 23:48:06 +01:00
private int computeRenderingProgress ( String line , Pattern tilePattern , int currentProgress ) {
Matcher standardTileInfo = tilePattern . matcher ( line ) ;
int newProgress = currentProgress ;
2020-05-28 13:28:42 +02:00
2020-03-19 23:48:06 +01:00
if ( standardTileInfo . find ( ) ) {
2020-06-17 18:24:59 +10:00
int tileJustProcessed = Integer . parseInt ( standardTileInfo . group ( 2 ) ) ;
int totalTilesInJob = Integer . parseInt ( standardTileInfo . group ( 3 ) ) ;
2020-05-28 13:28:42 +02:00
2020-03-19 23:48:06 +01:00
newProgress = Math . abs ( ( tileJustProcessed * 100 ) / totalTilesInJob ) ;
}
2020-05-28 13:28:42 +02:00
2020-06-17 18:24:59 +10:00
// Only update the tray icon and the screen if percentage has changed
2020-03-19 23:48:06 +01:00
if ( newProgress ! = currentProgress ) {
gui . updateTrayIcon ( newProgress ) ;
2020-06-17 18:24:59 +10:00
gui . status ( " Rendering " , newProgress ) ;
2020-03-19 23:48:06 +01:00
}
2020-05-28 13:28:42 +02:00
2020-03-19 23:48:06 +01:00
return newProgress ;
}
2020-05-28 13:28:42 +02:00
2023-02-02 18:25:53 +01:00
private void updateSpeedSamplesRendered ( String line , int progress ) {
// Looking for "Rendered 1281 samples in 66.319402 seconds"
Pattern pattern = Pattern . compile ( " ^Rendered ( \\ d+) samples in ([ \\ d.]+) seconds$ " ) ;
Matcher matcher = pattern . matcher ( line ) ;
if ( matcher . find ( ) ) {
int amount = Integer . parseInt ( matcher . group ( 1 ) ) ;
float duration = Float . parseFloat ( matcher . group ( 2 ) ) ;
if ( duration ! = 0 & & amount ! = 0 ) {
this . speedSamplesRendered = amount / duration ;
}
}
// should we use this, instead ???
// "Average time per sample: 0.052112 seconds"
}
2022-02-14 11:30:09 +00:00
private void updateRenderingStatus ( String line , int progress ) {
if ( getUpdateRenderingStatusMethod ( ) = = null | | getUpdateRenderingStatusMethod ( ) . equals ( Job . UPDATE_METHOD_BY_REMAINING_TIME ) ) {
2015-05-06 20:34:59 +01:00
String search_remaining = " remaining: " ;
int index = line . toLowerCase ( ) . indexOf ( search_remaining ) ;
if ( index ! = - 1 ) {
String buf1 = line . substring ( index + search_remaining . length ( ) ) ;
index = buf1 . indexOf ( " " ) ;
if ( index ! = - 1 ) {
String remaining_time = buf1 . substring ( 0 , index ) . trim ( ) ;
int last_index = remaining_time . lastIndexOf ( '.' ) ; //format 00:00:00.00 (hr:min:sec)
if ( last_index > 0 ) {
remaining_time = remaining_time . substring ( 0 , last_index ) ;
}
try {
DateFormat date_parse_minute = new SimpleDateFormat ( " m:s " ) ;
DateFormat date_parse_hour = new SimpleDateFormat ( " h:m:s " ) ;
DateFormat date_parse = date_parse_minute ;
if ( remaining_time . split ( " : " ) . length > 2 ) {
date_parse = date_parse_hour ;
}
date_parse . setTimeZone ( TimeZone . getTimeZone ( " GMT " ) ) ;
Date date = date_parse . parse ( remaining_time ) ;
2016-10-12 00:34:51 +02:00
gui . setRemainingTime ( Utils . humanDuration ( date ) ) ;
2015-05-06 20:34:59 +01:00
getProcessRender ( ) . setRemainingDuration ( ( int ) ( date . getTime ( ) / 1000 ) ) ;
}
catch ( ParseException err ) {
log . error ( " Client::updateRenderingStatus ParseException " + err ) ;
}
}
}
2022-02-14 11:30:09 +00:00
else { //extrapolate remaining time from time rendered & progress
if ( line . contains ( " Time " ) = = true ) {
long timeRendered = new Date ( ) . getTime ( ) - getProcessRender ( ) . getStartTime ( ) ;
if ( progress > 0 & & timeRendered > 0 ) {
long linearTimeEstimation = ( long ) ( ( 100 . 0 / progress ) * timeRendered ) ;
long timeRemaining = linearTimeEstimation - timeRendered ;
Date date = new Date ( timeRemaining ) ;
gui . setRemainingTime ( Utils . humanDuration ( date ) ) ;
getProcessRender ( ) . setRemainingDuration ( ( int ) ( date . getTime ( ) / 1000 ) ) ;
}
}
}
2015-05-06 20:34:59 +01:00
}
2019-08-05 14:11:24 +02:00
else if ( getUpdateRenderingStatusMethod ( ) . equals ( Job . UPDATE_METHOD_BY_TILE ) ) {
2018-08-24 19:46:03 +02:00
String search = " Tile " ;
int index = line . lastIndexOf ( search ) ;
if ( index ! = - 1 ) {
String buf = line . substring ( index + search . length ( ) ) ;
String [ ] parts = buf . split ( " / " ) ;
2019-08-05 14:11:24 +02:00
if ( parts . length = = 2 ) {
2018-08-24 19:46:03 +02:00
try {
int current = Integer . parseInt ( parts [ 0 ] ) ;
int total = Integer . parseInt ( parts [ 1 ] ) ;
if ( total ! = 0 ) {
gui . status ( String . format ( " Rendering %s %% " , ( int ) ( 100 . 0 * current / total ) ) ) ;
return ;
}
}
catch ( NumberFormatException e ) {
System . out . println ( " Exception 94: " + e ) ;
}
}
}
gui . status ( " Rendering " ) ;
}
2015-05-06 20:34:59 +01:00
}
2021-12-21 10:08:59 +00:00
private void updateProcess ( ) {
getProcessRender ( ) . update ( ) ;
2015-05-06 20:34:59 +01:00
}
2020-05-28 13:28:42 +02:00
2015-05-06 20:34:59 +01:00
private Type detectError ( String line ) {
2023-04-07 06:34:48 +00:00
if ( line . contains ( " version `GLIBC_2.28' not found " ) ) {
// 07-04 07:43:12 (debug) renderer output
// 07-04 07:43:12 (debug) /tmp///rend.exe: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.28' not found (required by /tmp///rend.exe)
// 07-04 07:43:12 (debug) /tmp///rend.exe: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.28' not found (required by /tmp///lib/libboost_filesystem.so.1.80.0)
return Type . OS_NOT_SUPPORTED ;
}
else if ( line . contains ( " CUDA error: Out of memory " ) ) {
2015-05-06 20:34:59 +01:00
// Fra:151 Mem:405.91M (0.00M, Peak 633.81M) | Mem:470.26M, Peak:470.26M | Scene, RenderLayer | Updating Device | Writing constant memory
// Fra:151 Mem:405.91M (0.00M, Peak 633.81M) | Mem:470.26M, Peak:470.26M | Scene, RenderLayer | Path Tracing Tile 0/135, Sample 0/200
// Fra:151 Mem:405.91M (0.00M, Peak 633.81M) | Mem:470.82M, Peak:470.82M | Scene, RenderLayer | Path Tracing Tile 1/135, Sample 0/200
// CUDA error: Out of memory in cuLaunchKernel(cuPathTrace, xblocks , yblocks, 1, xthreads, ythreads, 1, 0, 0, args, 0)
// Refer to the Cycles GPU rendering documentation for possible solutions:
// http://www.blender.org/manual/render/cycles/gpu_rendering.html
// Fra:151 Mem:405.91M (0.00M, Peak 633.81M) | Remaining:09:26.57 | Mem:470.26M, Peak:470.82M | Scene, RenderLayer | Path Tracing Tile 1/135, Sample 200/200
// Fra:151 Mem:405.91M (0.00M, Peak 633.81M) | Remaining:00:00.06 | Mem:470.50M, Peak:470.82M | Scene, RenderLayer | Path Tracing Tile 134/135, Sample 0/200
// Fra:151 Mem:405.91M (0.00M, Peak 633.81M) | Remaining:00:00.03 | Mem:470.26M, Peak:470.82M | Scene, RenderLayer | Path Tracing Tile 134/135, Sample 200/200
// Fra:151 Mem:405.91M (0.00M, Peak 633.81M) | Remaining:00:00.03 | Mem:470.50M, Peak:470.82M | Scene, RenderLayer | Path Tracing Tile 135/135, Sample 0/200
// Fra:151 Mem:405.91M (0.00M, Peak 633.81M) | Mem:470.26M, Peak:470.82M | Scene, RenderLayer | Path Tracing Tile 135/135, Sample 200/200
// Error: CUDA error: Out of memory in cuLaunchKernel(cuPathTrace, xblocks , yblocks, 1, xthreads, ythreads, 1, 0, 0, args, 0)
// Fra:151 Mem:405.91M (0.00M, Peak 633.81M) | Mem:470.26M, Peak:470.82M | Scene, RenderLayer | Cancel | CUDA error: Out of memory in cuLaunchKernel(cuPathTrace, xblocks , yblocks, 1, xthreads, ythreads, 1, 0, 0, args, 0)
// Fra:151 Mem:405.89M (0.00M, Peak 633.81M) Sce: Scene Ve:0 Fa:0 La:0
// Saved: /tmp/xx/26885_0151.png Time: 00:04.67 (Saving: 00:00.22)
// Blender quit
return Type . RENDERER_OUT_OF_VIDEO_MEMORY ;
}
2019-08-05 14:11:24 +02:00
else if ( line . contains ( " CUDA error at cuCtxCreate: Out of memory " ) ) {
2017-05-20 13:56:43 +02:00
// renderer output
// CUDA error at cuCtxCreate: Out of memory
// Refer to the Cycles GPU rendering documentation for possible solutions:
// http://www.blender.org/manual/render/cycles/gpu_rendering.html
// found bundled python: /tmp/aaaa/bbbb/2.78/python
// read blend: /tmp/aaaa/bbbb/compute-method.blend
// Fra:340 Mem:7.25M (0.00M, Peak 7.25M) | Time:00:00.13 | Mem:0.00M, Peak:0.00M | Scene, RenderLayer | Synchronizing object | Sun
// Fra:340 Mem:7.25M (0.00M, Peak 7.25M) | Time:00:00.13 | Mem:0.00M, Peak:0.00M | Scene, RenderLayer | Synchronizing object | Plane
// Fra:340 Mem:7.25M (0.00M, Peak 7.26M) | Time:00:00.13 | Mem:0.00M, Peak:0.00M | Scene, RenderLayer | Synchronizing object | Cube
// Fra:340 Mem:7.25M (0.00M, Peak 7.26M) | Time:00:00.13 | Mem:0.00M, Peak:0.00M | Scene, RenderLayer | Synchronizing object | Camera
// Fra:340 Mem:7.25M (0.00M, Peak 7.26M) | Time:00:00.13 | Mem:0.00M, Peak:0.00M | Scene, RenderLayer | Initializing
// Fra:340 Mem:7.25M (0.00M, Peak 7.26M) | Time:00:00.13 | Mem:0.00M, Peak:0.00M | Scene, RenderLayer | Loading render kernels (may take a few minutes the first time)
// Fra:340 Mem:7.25M (0.00M, Peak 7.26M) | Time:00:00.13 | Mem:0.00M, Peak:0.00M | Scene, RenderLayer | Error | CUDA error at cuCtxCreate: Out of memory
// Error: CUDA error at cuCtxCreate: Out of memory
// Fra:340 Mem:7.25M (0.00M, Peak 7.26M) | Time:00:00.13 | Mem:0.00M, Peak:0.00M | Scene, RenderLayer | Waiting for render to start
// Fra:340 Mem:7.25M (0.00M, Peak 7.26M) | Time:00:00.13 | Mem:0.00M, Peak:0.00M | Scene, RenderLayer | Cancel | CUDA error at cuCtxCreate: Out of memory
// CUDA error: Invalid value in cuCtxDestroy(cuContext)
// Fra:340 Mem:7.25M (0.00M, Peak 7.26M) | Time:00:00.13 | Sce: Scene Ve:0 Fa:0 La:0
// Blender quit
// end of rendering
return Type . RENDERER_OUT_OF_VIDEO_MEMORY ;
}
2023-11-28 12:28:39 +00:00
else if ( line . contains ( " Error: Out of memory in CUDA " ) | | line . contains ( " Error: Out of memory in OPTIX " ) ) {
2022-03-21 16:23:00 +00:00
// 15-03 21:13:45 (debug) Fra:27 Mem:8441.68M (Peak 9675.81M) | Time:00:16.27 | Mem:8411.20M, Peak:8411.20M | Scene, View Layer | Loading render kernels (may take a few minutes the first time)
// 15-03 21:13:45 (debug) Out of memory in CUDA queue enqueue (integrator_shade_surface)
// 15-03 21:13:45 (debug) Refer to the Cycles GPU rendering documentation for possible solutions:
// 15-03 21:13:45 (debug) https://docs.blender.org/manual/en/latest/render/cycles/gpu_rendering.html
// 15-03 21:13:45 (debug) Fra:27 Mem:8441.68M (Peak 9675.81M) | Time:00:16.38 | Mem:8411.27M, Peak:8411.27M | Scene, View Layer | Updating Scene
// 15-03 21:13:45 (debug) Fra:27 Mem:8441.68M (Peak 9675.81M) | Time:00:16.38 | Mem:8411.27M, Peak:8411.27M | Scene, View Layer | Updating Shaders
// 15-03 21:13:45 (debug) Fra:27 Mem:8447.08M (Peak 9675.81M) | Time:00:16.63 | Mem:8763.00M, Peak:8763.00M | Scene, View Layer | Out of memory in CUDA queue enqueue (integrator_shade_surface)
// 15-03 21:13:45 (debug) Error: Out of memory in CUDA queue enqueue (integrator_shade_surface)
// 15-03 21:13:46 (debug) Blender quit
return Error . Type . RENDERER_OUT_OF_VIDEO_MEMORY ;
}
2023-11-28 12:28:39 +00:00
else if ( line . contains ( " CUDA error: Launch exceeded timeout in " ) | | line . contains ( " CUDA error: Invalid value in cuTexRefSetAddress( " ) | | line . contains ( " CUDA error: Launch failed in cuCtxSynchronize() " ) | | line . contains ( " CUDA error: Illegal address in cuCtxSynchronize() " ) ) {
return Error . Type . GPU_OR_DRIVER_ERROR ;
}
else if ( line . contains ( " System is out of GPU memory " ) ) {
2022-03-21 16:23:00 +00:00
// 16-03 18:37:37 (debug) Fra:192 Mem:15826.70M (Peak 15831.18M) | Time:02:21.86 | Mem:6622.87M, Peak:6625.35M | Scene, ViewLayer | Loading denoising kernels (may take a few minutes the first time)
// 16-03 18:37:37 (debug) System is out of GPU memory
// 16-03 18:37:37 (debug) Refer to the Cycles GPU rendering documentation for possible solutions:
// 16-03 18:37:37 (debug) https://docs.blender.org/manual/en/latest/render/cycles/gpu_rendering.html
// 16-03 18:37:37 (debug) System is out of GPU memory
// 16-03 18:37:38 (debug) Fra:192 Mem:15831.01M (Peak 15831.18M) | Time:02:23.11 | Mem:7017.46M, Peak:7017.46M | Scene, ViewLayer | System is out of GPU memory
// 16-03 18:37:38 (debug) Error: System is out of GPU memory
// 16-03 18:37:40 (debug) Blender quit
// 16-03 18:37:40 (debug) end of rendering
return Error . Type . RENDERER_OUT_OF_VIDEO_MEMORY ;
}
2023-11-28 12:28:39 +00:00
else if ( line . contains ( " CUDA device supported only with compute capability " ) | | line . contains ( " OPTIX device supported only with compute capability " ) ) {
2015-05-06 20:34:59 +01:00
// found bundled python: /tmp/xx/2.73/python
// read blend: /tmp/xx/compute-method.blend
// Fra:340 Mem:7.64M (0.00M, Peak 8.23M) | Mem:0.00M, Peak:0.00M | Scene, RenderLayer | Synchronizing object | Sun
// Fra:340 Mem:7.64M (0.00M, Peak 8.23M) | Mem:0.00M, Peak:0.00M | Scene, RenderLayer | Synchronizing object | Plane
// Fra:340 Mem:7.64M (0.00M, Peak 8.23M) | Mem:0.00M, Peak:0.00M | Scene, RenderLayer | Synchronizing object | Cube
// Fra:340 Mem:7.64M (0.00M, Peak 8.23M) | Mem:0.00M, Peak:0.00M | Scene, RenderLayer | Synchronizing object | Camera
// Fra:340 Mem:7.64M (0.00M, Peak 8.23M) | Mem:0.00M, Peak:0.00M | Scene, RenderLayer | Initializing
// Fra:340 Mem:7.64M (0.00M, Peak 8.23M) | Mem:0.00M, Peak:0.00M | Scene, RenderLayer | Loading render kernels (may take a few minutes the first time)
// CUDA device supported only with compute capability 2.0 or up, found 1.2.
// Refer to the Cycles GPU rendering documentation for possible solutions:
// http://www.blender.org/manual/render/cycles/gpu_rendering.html
// Fra:340 Mem:7.64M (0.00M, Peak 8.23M) | Mem:0.00M, Peak:0.00M | Scene, RenderLayer | Error | CUDA device supported only with compute capability 2.0 or up, found 1.2.
// Error: CUDA device supported only with compute capability 2.0 or up, found 1.2.
// Fra:340 Mem:7.64M (0.00M, Peak 8.23M) | Mem:0.00M, Peak:0.00M | Scene, RenderLayer | Waiting for render to start
// Fra:340 Mem:7.64M (0.00M, Peak 8.23M) | Mem:0.00M, Peak:0.00M | Scene, RenderLayer | Cancel | CUDA device supported only with compute capability 2.0 or up, found 1.2.
// Fra:340 Mem:7.64M (0.00M, Peak 8.23M) Sce: Scene Ve:0 Fa:0 La:0
// Saved: /tmp/xx/0_0340.png Time: 00:00.12 (Saving: 00:00.03)
// Blender quit
return Type . GPU_NOT_SUPPORTED ;
}
2019-08-05 14:11:24 +02:00
else if ( line . contains ( " terminate called after throwing an instance of 'boost::filesystem::filesystem_error' " ) ) {
2015-12-26 10:44:56 +00:00
// Fra:2103 Mem:29.54M (0.00M, Peak 29.54M) | Time:00:00.24 | Mem:1.64M, Peak:1.64M | Scene, RenderLayer | Updating Mesh | Computing attributes
// Fra:2103 Mem:29.54M (0.00M, Peak 29.54M) | Time:00:00.24 | Mem:1.64M, Peak:1.64M | Scene, RenderLayer | Updating Mesh | Copying Attributes to device
// Fra:2103 Mem:29.54M (0.00M, Peak 29.54M) | Time:00:00.24 | Mem:1.97M, Peak:1.97M | Scene, RenderLayer | Updating Scene BVH | Building
// Fra:2103 Mem:29.54M (0.00M, Peak 29.54M) | Time:00:00.24 | Mem:1.97M, Peak:1.97M | Scene, RenderLayer | Updating Scene BVH | Building BVH
// Fra:2103 Mem:29.54M (0.00M, Peak 29.54M) | Time:00:00.24 | Mem:1.97M, Peak:1.97M | Scene, RenderLayer | Updating Scene BVH | Looking in BVH cache
// Fra:2103 Mem:29.54M (0.00M, Peak 29.54M) | Time:00:00.27 | Mem:1.97M, Peak:1.97M | Scene, RenderLayer | Updating Scene BVH | Packing BVH triangles and strands
// Fra:2103 Mem:29.54M (0.00M, Peak 29.54M) | Time:00:00.27 | Mem:1.97M, Peak:1.97M | Scene, RenderLayer | Updating Scene BVH | Packing BVH nodes
// Fra:2103 Mem:29.54M (0.00M, Peak 29.54M) | Time:00:00.27 | Mem:1.97M, Peak:1.97M | Scene, RenderLayer | Updating Scene BVH | Writing BVH cache
// terminate called after throwing an instance of 'boost::filesystem::filesystem_error'
// what(): boost::filesystem::create_directory: Permission denied: "/var/local/cache"
return Error . Type . NOOUTPUTFILE ;
}
2019-08-05 14:11:24 +02:00
else if ( line . contains ( " terminate called after throwing an instance of 'std::bad_alloc' " ) ) {
2016-04-03 20:49:24 +02:00
// Fra:80 Mem:1333.02M (0.00M, Peak 1651.23M) | Mem:780.37M, Peak:780.37M | Scene, RenderLayer | Updating Mesh BVH Plane.083 171/2 | Building BVH
// Fra:80 Mem:1333.02M (0.00M, Peak 1651.23M) | Mem:780.37M, Peak:780.37M | Scene, RenderLayer | Updating Mesh BVH Mesh 172/2 | Building BVH
// Fra:80 Mem:1333.02M (0.00M, Peak 1651.23M) | Mem:780.37M, Peak:780.37M | Scene, RenderLayer | Updating Mesh BVH Mesh 172/2 | Packing BVH triangles and strands
// Fra:80 Mem:1333.02M (0.00M, Peak 1651.23M) | Mem:780.37M, Peak:780.37M | Scene, RenderLayer | Updating Mesh BVH Mesh 172/2 | Packing BVH nodes
// Fra:80 Mem:1333.02M (0.00M, Peak 1651.23M) | Mem:780.37M, Peak:780.37M | Scene, RenderLayer | Updating Scene BVH | Building
// Fra:80 Mem:1333.02M (0.00M, Peak 1651.23M) | Mem:780.37M, Peak:780.37M | Scene, RenderLayer | Updating Scene BVH | Building BVH
// terminate called after throwing an instance of 'std::bad_alloc'
// what(): std::bad_alloc
return Error . Type . RENDERER_OUT_OF_MEMORY ;
}
2019-08-05 14:11:24 +02:00
else if ( line . contains ( " what(): std::bad_alloc " ) ) {
2016-05-01 15:04:31 +02:00
// Fra:7 Mem:1247.01M (0.00M, Peak 1247.01M) | Time:00:28.84 | Mem:207.63M, Peak:207.63M | Scene, RenderLayer | Updating Scene BVH | Building BVH 93%, duplicates 0%terminate called recursively
// terminate called after throwing an instance of 'St9bad_alloc'
// what(): std::bad_alloc
// scandir: Cannot allocate memory
return Error . Type . RENDERER_OUT_OF_MEMORY ;
}
2019-08-05 14:11:24 +02:00
else if ( line . contains ( " EXCEPTION_ACCESS_VIOLATION " ) ) {
2018-06-30 01:31:42 +02:00
// Fra:638 Mem:342.17M (63.28M, Peak 735.33M) | Time:00:07.65 | Remaining:02:38.28 | Mem:246.91M, Peak:262.16M | scene_top_01_90, chip_top_view_scene_01 | Path Tracing Tile 57/2040, Denoised 0 tiles
// Fra:638 Mem:342.32M (63.28M, Peak 735.33M) | Time:00:07.70 | Remaining:02:38.20 | Mem:247.05M, Peak:262.16M | scene_top_01_90, chip_top_view_scene_01 | Path Tracing Tile 58/2040, Denoised 0 tiles
// Error: EXCEPTION_ACCESS_VIOLATION
return Error . Type . RENDERER_CRASHED ;
}
2022-03-09 23:15:20 +00:00
else if ( line . contains ( " Fatal Python error: " ) ) {
2018-07-10 09:59:05 +02:00
// Fatal Python error: Py_Initialize: unable to load the file system codec
// ImportError: No module named 'encodings'
// Current thread 0x0000388c (most recent call first):
return Error . Type . RENDERER_CRASHED_PYTHON_ERROR ;
}
2019-08-05 14:11:24 +02:00
else if ( line . contains ( " Calloc returns null " ) ) {
2016-05-01 15:04:31 +02:00
// Fra:1 Mem:976.60M (0.00M, Peak 1000.54M) | Time:00:01.34 | Mem:0.00M, Peak:0.00M | Scene, RenderLayer | Synchronizing object | Left
// Calloc returns null: len=7186416 in CDMLoopUV, total 2145859048
// Calloc returns null: len=7186416 in CDMLoopUV, total 2145859048
// Malloc returns null: len=3190672 in CDMTexPoly, total 2149293176
// Writing: /home/user/.sheepit/LEFT packed.crash.txt
return Error . Type . RENDERER_OUT_OF_MEMORY ;
}
2019-08-05 14:11:24 +02:00
else if ( line . contains ( " Malloc returns null " ) ) {
2016-05-01 15:04:31 +02:00
// Fra:1 Mem:976.60M (0.00M, Peak 1000.54M) | Time:00:01.34 | Mem:0.00M, Peak:0.00M | Scene, RenderLayer | Synchronizing object | Left
// Calloc returns null: len=7186416 in CDMLoopUV, total 2145859048
// Calloc returns null: len=7186416 in CDMLoopUV, total 2145859048
// Malloc returns null: len=3190672 in CDMTexPoly, total 2149293176
// Writing: /home/user/.sheepit/LEFT packed.crash.txt
return Error . Type . RENDERER_OUT_OF_MEMORY ;
}
2023-01-12 15:59:56 +00:00
else if ( line . contains ( " Error: run out of memory! " ) ) {
// 09-01 09:26:45 (debug) Fra:4 Mem:8444.44M (Peak 12092.10M) | Time:01:11.45 | Mem:6632.02M, Peak:6632.02M | Scene, ViewLayer | Updating Mesh | Tessellating Plane 1/1
//09-01 09:27:30 (debug) Error: run out of memory!
//09-01 09:27:30 (debug) Fra:4 Mem:8444.44M (Peak 12092.10M) | Time:01:55.95 | Mem:6632.02M, Peak:6632.02M | Scene, ViewLayer | Sample 0/1024
//09-01 09:27:30 (debug) Error: Out of memory
//09-01 09:27:30 (debug) Fra:4 Mem:8745.04M (Peak 12092.10M) | Time:01:55.97 | Mem:6632.03M, Peak:6632.03M | Scene, ViewLayer | Out of memory
//09-01 09:27:33 (debug) Blender quit
return Error . Type . RENDERER_OUT_OF_MEMORY ;
}
2023-11-28 12:28:39 +00:00
else if ( line . contains ( " CUDA kernel compilation failed " ) | | line . contains ( " OPTIX kernel compilation failed " ) ) {
2016-09-21 23:52:41 +02:00
// Fra:1 Mem:200.70M (0.00M, Peak 378.15M) | Time:00:01.02 | Mem:0.00M, Peak:0.00M | Scene, RenderLayer | Synchronizing object | Sun.001
// Fra:1 Mem:200.70M (0.00M, Peak 378.15M) | Time:00:01.02 | Mem:0.00M, Peak:0.00M | Scene, RenderLayer | Synchronizing object | Sun.002
// Fra:1 Mem:200.70M (0.00M, Peak 378.15M) | Time:00:01.02 | Mem:0.00M, Peak:0.00M | Scene, RenderLayer | Initializing
// Fra:1 Mem:200.70M (0.00M, Peak 378.15M) | Time:00:01.02 | Mem:0.00M, Peak:0.00M | Scene, RenderLayer | Loading render kernels (may take a few minutes the first time)
// nvcc fatal : Value 'sm_61' is not defined for option 'gpu-architecture'
// CUDA kernel compilation failed, see console for details.
// Refer to the Cycles GPU rendering documentation for possible solutions:
// http://www.blender.org/manual/render/cycles/gpu_rendering.html
// Compiling CUDA kernel ...
// "nvcc" -arch=sm_61 -m64 --cubin "/tmp/cache/c36db40aa5e59f5ea4ff139180353dbc/2.77/scripts/addons/cycles/kernel/kernels/cuda/kernel.cu" -o "/tmp/cache/cycles_kernel_sm61_079195D400571E023CC499D037AB6EE5.cubin" --ptxas-options="-v" --use_fast_math -I"/tmp/cache/c36db40aa5e59f5ea4ff139180353dbc/2.77/scripts/addons/cycles/kernel" -DNVCC -D__KERNEL_CUDA_VERSION__=75
// Fra:1 Mem:200.70M (0.00M, Peak 378.15M) | Time:00:01.08 | Mem:0.00M, Peak:0.00M | Scene, RenderLayer | Error | CUDA kernel compilation failed, see console for details.
// Error: CUDA kernel compilation failed, see console for details.
// Fra:1 Mem:200.70M (0.00M, Peak 378.15M) | Time:00:01.08 | Mem:0.00M, Peak:0.00M | Scene, RenderLayer | Waiting for render to start
// Fra:1 Mem:200.70M (0.00M, Peak 378.15M) | Time:00:01.08 | Mem:0.00M, Peak:0.00M | Scene, RenderLayer | Cancel | CUDA kernel compilation failed, see console for details.
// Fra:1 Mem:147.74M (0.00M, Peak 378.15M) | Time:00:01.12 | Sce: Scene Ve:0 Fa:0 La:0
// Saved: '/tmp/cache/8_0001.png'
return Error . Type . GPU_NOT_SUPPORTED ;
}
2023-09-02 08:54:25 +00:00
else if ( line . contains ( " Engine 'CYCLES' not available for scene " ) | | line . contains ( " Engine 'BLENDER_EEVEE' not available for scene " ) | | line . contains ( " Engine 'BLENDER_WORKBENCH' not available for scene " ) | | line . contains ( " Engine 'HYDRA_STORM' not available for scene " ) ) {
2020-12-13 10:46:55 +00:00
return Error . Type . ENGINE_NOT_AVAILABLE ;
}
else if ( line . contains ( " Warning: Cycles is not enabled! " ) ) {
return Error . Type . ENGINE_NOT_AVAILABLE ;
}
2022-04-29 15:52:16 +00:00
else if ( line . contains ( " OpenImageDenoise error: SSE4.1 support is required at minimum " ) | | line . contains ( " OpenImageDenoiser is not supported on this CPU: " ) | | line . contains ( " No device available to denoise on " ) ) {
2022-03-08 16:25:07 +00:00
// denoising capability detection
// Fra:201 Mem:8.89M (Peak 10.09M) | Time:00:00.04 | Mem:0.27M, Peak:0.27M | Scene, View Layer | Updating Device | Writing constant memory
// Fra:201 Mem:8.89M (Peak 10.09M) | Time:00:00.04 | Mem:0.27M, Peak:0.27M | Scene, View Layer | Loading denoising kernels (may take a few minutes the first time)
// Fra:201 Mem:8.89M (Peak 10.09M) | Time:00:00.04 | Mem:0.27M, Peak:0.27M | Scene, View Layer | Sample 0/16
// Fra:201 Mem:127.55M (Peak 127.55M) | Time:00:00.65 | Remaining:00:09.13 | Mem:118.92M, Peak:118.92M | Scene, View Layer | Sample 1/16
// E0308 1719 31449 denoiser_oidn.cpp:197] OpenImageDenoise error: SSE4.1 support is required at minimum
// Fra:201 Mem:198.74M (Peak 301.58M) | Time:00:08.74 | Mem:118.92M, Peak:118.92M | Scene, View Layer | Sample 16/16
// Rendering done
// Fra:201 Mem:198.74M (Peak 301.58M) | Time:00:08.74 | Mem:118.92M, Peak:118.92M | Scene, View Layer | Finished
// Saved: '/tmp/5/sheepit/1541_0201.png'
// Time: 00:09.30 (Saving: 00:00.55)
// Blender quit
2022-04-29 15:52:16 +00:00
return Error . Type . DENOISING_NOT_SUPPORTED ;
2022-03-08 16:25:07 +00:00
}
2022-03-11 14:29:27 +00:00
else if ( line . contains ( " Error: File format is not supported " ) ) {
//09-03 23:36:03 (debug) Blender 2.83.19 (hash 86c526d2c733 built 2022-02-02 00:44:40)
//09-03 23:36:03 (debug) found bundled python: C:\Users\Username\Documents\sheepit\sheepit\f1f9e587201b428c9416faf614b677bf\2.83\python
//09-03 23:36:03 (debug) Error: File format is not supported in file 'C:\Users\Username\Documents\sheepit\sheepit\686c6bdbf752790b28c1b21180aa5db5\correndo4.blend'
//09-03 23:36:03 (debug) Blender quit
//09-03 23:36:03 (debug) end of rendering
return Error . Type . RENDERER_CRASHED ;
}
2023-04-06 10:19:56 +00:00
else if ( line . contains ( " Unable to open a display " ) | | line . contains ( " Managed to successfully fallback to surfaceless EGL rendering! " ) ) {
2022-05-17 14:05:49 +00:00
//17-03 07:38:47 (debug) Fra:7 Mem:1667.27M (Peak 1762.19M) | Time:06:27.86 | Mem:1184.92M, Peak:1194.58M | Scene, ViewLayer | Sample 187/187
//17-03 07:38:47 (debug) Fra:7 Mem:1667.27M (Peak 1762.19M) | Time:06:27.86 | Mem:1184.92M, Peak:1194.58M | Scene, ViewLayer | Finished
//17-03 07:38:47 (debug) Unable to open a display
//17-03 07:38:47 (debug) end of rendering
//17-03 07:38:47 (error) Job::render no picture file found (after finished render (filename_without_extension 116372253_0007)
return Error . Type . CURRENTLY_HEADLESS ;
}
2023-04-01 12:42:09 +00:00
else if ( line . contains ( " Error: Cannot read file " ) | | line . contains ( " Error: Failed to read blend file " ) ) {
2023-01-04 16:24:15 +00:00
//14-10 11:03:21 (debug) Blender 3.1.0 (hash c77597cd0e15 built 2022-03-09 00:44:13)
//14-10 11:03:21 (debug) Error: Cannot read file 'C:\SheepIT\sheepit\ef925644a319c5ad604ebc077769bcb8\Passeio Virtual FINAL.blend': No such file or directory
//14-10 11:03:21 (debug) Blender quit
return Error . Type . CANNOT_READ_FILE ;
}
2023-01-13 10:27:01 +01:00
else if ( line . contains ( " DETECT_DEVICE_ERROR " ) ) {
2023-01-12 16:02:03 +00:00
//./blender-3.3.2-linux-x64/blender -b -E CYCLES -P /mnt/d/sheep_gpu/set_gpu.py -f 1
//Blender 3.3.2 (hash bf24652e38a2 built 2022-12-07 01:12:36)
//Read prefs: /home/raimund/.config/blender/3.3/config/userpref.blend
///run/user/1000/gvfs/ non-existent directory
2023-01-13 10:27:01 +01:00
//DETECT_DEVICE_ERRORR: Couldn't find OPTIX device with id CUDA_NVIDIA GeForce GTX 1080_0000:01:00_OptiX
return Error . Type . DETECT_DEVICE_ERROR ;
2023-01-12 16:02:03 +00:00
}
2023-01-04 16:24:15 +00:00
2015-05-06 20:34:59 +01:00
return Type . OK ;
}
2020-05-28 13:28:42 +02:00
2019-08-07 18:40:02 +02:00
public static class renderStartedObservable extends Observable {
2020-05-28 13:28:42 +02:00
@Getter private boolean isStarted ;
2019-08-07 18:40:02 +02:00
public renderStartedObservable ( Observer observer ) {
super ( ) ;
addObserver ( observer ) ;
}
2020-05-28 13:28:42 +02:00
2019-08-07 18:40:02 +02:00
public void doNotifyIsStarted ( ) {
setChanged ( ) ;
notifyObservers ( ) ;
isStarted = true ;
}
}
2014-11-20 13:21:19 +00:00
}