netrender
Support for fluid files and better support for point cache (including external cache for particles) This also fixes a couple of bugs with frame based dependencies and with file transfer. NOTE: With external point cache and fluids, the path needs to be relative or relative to the file (starting with //) if the files are not on a shared drive. It should eventually warn if that is not the case, but doesn't right now, so be careful.
This commit is contained in:
@@ -8,67 +8,52 @@ import netrender.slave as slave
|
||||
import netrender.master as master
|
||||
from netrender.utils import *
|
||||
|
||||
def clientSendJob(conn, scene, anim = False):
|
||||
netsettings = scene.network_render
|
||||
job = netrender.model.RenderJob()
|
||||
def addFluidFiles(job, path):
|
||||
if os.path.exists(path):
|
||||
pattern = re.compile("fluidsurface_(final|preview)_([0-9]+)\.(bobj|bvel)\.gz")
|
||||
|
||||
if anim:
|
||||
for f in range(scene.start_frame, scene.end_frame + 1):
|
||||
job.addFrame(f)
|
||||
else:
|
||||
job.addFrame(scene.current_frame)
|
||||
for fluid_file in sorted(os.listdir(path)):
|
||||
match = pattern.match(fluid_file)
|
||||
|
||||
filename = bpy.data.filename
|
||||
job.addFile(filename)
|
||||
if match:
|
||||
current_frame = int(match.groups()[1])
|
||||
job.addFile(path + fluid_file, current_frame, current_frame)
|
||||
|
||||
job_name = netsettings.job_name
|
||||
path, name = os.path.split(filename)
|
||||
if job_name == "[default]":
|
||||
job_name = name
|
||||
def addPointCache(job, ob, point_cache, default_path):
|
||||
if not point_cache.disk_cache:
|
||||
return
|
||||
|
||||
###########################
|
||||
# LIBRARIES
|
||||
###########################
|
||||
for lib in bpy.data.libraries:
|
||||
lib_path = lib.filename
|
||||
|
||||
if lib_path.startswith("//"):
|
||||
lib_path = path + os.sep + lib_path[2:]
|
||||
name = point_cache.name
|
||||
if name == "":
|
||||
name = "".join(["%02X" % ord(c) for c in ob.name])
|
||||
|
||||
job.addFile(lib_path)
|
||||
cache_path = bpy.sys.expandpath(point_cache.filepath) if point_cache.external else default_path
|
||||
|
||||
###########################
|
||||
# POINT CACHES
|
||||
###########################
|
||||
|
||||
root, ext = os.path.splitext(name)
|
||||
cache_path = path + os.sep + "blendcache_" + root + os.sep # need an API call for that
|
||||
index = "%02i" % point_cache.index
|
||||
|
||||
if os.path.exists(cache_path):
|
||||
caches = {}
|
||||
pattern = re.compile("([a-zA-Z0-9]+)_([0-9]+)_[0-9]+\.bphys")
|
||||
pattern = re.compile(name + "_([0-9]+)_" + index + "\.bphys")
|
||||
|
||||
cache_files = []
|
||||
|
||||
for cache_file in sorted(os.listdir(cache_path)):
|
||||
match = pattern.match(cache_file)
|
||||
|
||||
if match:
|
||||
cache_id = match.groups()[0]
|
||||
cache_frame = int(match.groups()[1])
|
||||
|
||||
cache_files = caches.get(cache_id, [])
|
||||
cache_frame = int(match.groups()[0])
|
||||
cache_files.append((cache_frame, cache_file))
|
||||
caches[cache_id] = cache_files
|
||||
|
||||
for cache in caches.values():
|
||||
cache.sort()
|
||||
cache_files.sort()
|
||||
|
||||
if len(cache) == 1:
|
||||
cache_frame, cache_file = cache[0]
|
||||
if len(cache_files) == 1:
|
||||
cache_frame, cache_file = cache_files[0]
|
||||
job.addFile(cache_path + cache_file, cache_frame, cache_frame)
|
||||
else:
|
||||
for i in range(len(cache)):
|
||||
current_item = cache[i]
|
||||
next_item = cache[i+1] if i + 1 < len(cache) else None
|
||||
previous_item = cache[i - 1] if i > 0 else None
|
||||
for i in range(len(cache_files)):
|
||||
current_item = cache_files[i]
|
||||
next_item = cache_files[i+1] if i + 1 < len(cache_files) else None
|
||||
previous_item = cache_files[i - 1] if i > 0 else None
|
||||
|
||||
current_frame, current_file = current_item
|
||||
|
||||
@@ -85,12 +70,61 @@ def clientSendJob(conn, scene, anim = False):
|
||||
previous_frame = previous_item[0]
|
||||
job.addFile(cache_path + current_file, previous_frame + 1, next_frame - 1)
|
||||
|
||||
def clientSendJob(conn, scene, anim = False):
|
||||
netsettings = scene.network_render
|
||||
job = netrender.model.RenderJob()
|
||||
|
||||
if anim:
|
||||
for f in range(scene.start_frame, scene.end_frame + 1):
|
||||
job.addFrame(f)
|
||||
else:
|
||||
job.addFrame(scene.current_frame)
|
||||
|
||||
filename = bpy.data.filename
|
||||
job.addFile(filename)
|
||||
|
||||
job_name = netsettings.job_name
|
||||
path, name = os.path.split(filename)
|
||||
path += os.sep
|
||||
if job_name == "[default]":
|
||||
job_name = name
|
||||
|
||||
###########################
|
||||
# LIBRARIES
|
||||
###########################
|
||||
for lib in bpy.data.libraries:
|
||||
job.addFile(bpy.sys.expandpath(lib_path))
|
||||
|
||||
###########################
|
||||
# IMAGES
|
||||
###########################
|
||||
for image in bpy.data.images:
|
||||
if image.source == "FILE" and not image.packed_file:
|
||||
job.addFile(image.filename)
|
||||
job.addFile(bpy.sys.expandpath(image.filename))
|
||||
|
||||
###########################
|
||||
# FLUID + POINT CACHE
|
||||
###########################
|
||||
root, ext = os.path.splitext(name)
|
||||
default_path = path + "blendcache_" + root + os.sep # need an API call for that
|
||||
|
||||
for object in bpy.data.objects:
|
||||
for modifier in object.modifiers:
|
||||
if modifier.type == 'FLUID_SIMULATION' and modifier.settings.type == "DOMAIN":
|
||||
addFluidFiles(job, bpy.sys.expandpath(modifier.settings.path))
|
||||
elif modifier.type == "CLOTH":
|
||||
addPointCache(job, object, modifier.point_cache, default_path)
|
||||
elif modifier.type == "SOFT_BODY":
|
||||
addPointCache(job, object, modifier.point_cache, default_path)
|
||||
elif modifier.type == "SMOKE" and modifier.smoke_type == "TYPE_DOMAIN":
|
||||
addPointCache(job, object, modifier.domain_settings.point_cache_low, default_path)
|
||||
if modifier.domain_settings.highres:
|
||||
addPointCache(job, object, modifier.domain_settings.point_cache_high, default_path)
|
||||
|
||||
# particles modifier are stupid and don't contain data
|
||||
# we have to go through the object property
|
||||
for psys in object.particle_systems:
|
||||
addPointCache(job, object, psys.point_cache, default_path)
|
||||
|
||||
# print(job.files)
|
||||
|
||||
|
||||
@@ -149,7 +149,7 @@ class RenderJob:
|
||||
"id": self.id,
|
||||
"type": self.type,
|
||||
"name": self.name,
|
||||
"files": [f for f in self.files if f[1] == -1 or not frames or (f[1] <= min_frame <= f[2] or f[1] <= max_frame <= f[2])],
|
||||
"files": [f for f in self.files if f[1] == -1 or not frames or (f[1] <= max_frame and f[2] >= min_frame)],
|
||||
"frames": [f.serialize() for f in self.frames if not frames or f in frames],
|
||||
"chunks": self.chunks,
|
||||
"priority": self.priority,
|
||||
|
||||
@@ -75,7 +75,7 @@ def prefixPath(prefix_directory, file_path, prefix_path):
|
||||
|
||||
if prefix_path and p.startswith(prefix_path):
|
||||
directory = prefix_directory + p[len(prefix_path):]
|
||||
full_path = directory + n
|
||||
full_path = directory + os.sep + n
|
||||
if not os.path.exists(directory):
|
||||
os.mkdir(directory)
|
||||
else:
|
||||
|
||||
Reference in New Issue
Block a user