To yse run the folling scripts from the command line with the latest CVS bf-blender since this relys on a python function I added for this script. ( context.setBorder() )
blender myscene.blend -P render_client.py
This script is working but needs some intergration.
All the tiles need to be composited, I can do this using PIL but need to make a script that composites a directory of images.
It renders an image as many tiles (128px x 128px default)
Each tile is indexed and blender only renders if there are mo existing image of that index (a dummy is created before the render so computers dont render the same tile)
This requires all PC's to be able to accsess a networked filesystem.
if the file has a num at the end eg.
blender myscene_256.blend -P render_client.py
Then a 256 x 256 tile will be used.
Here is render_client.py
Code: Select all
import Blender
from Blender import sys, Scene, Noise
from Blender.Scene import Render
import string
NUM = '0123456789'
DEFAULT_TILE_SIZE=64 # px
# Clamp
def max(number):
if number > 1.0:
number = 1.0
return number
def isfile(file):
try:
open(file)
return 1
except:
return 0
def randList(list):
randList = []
lenList = len(list)
while lenList != len(randList):
randIndex = int( Noise.random() * len(list) )
randList.append( list[randIndex] )
list.remove( list[randIndex] )
return randList
# Strip all chars after a '.'
def stripExt(text):
return text[:text.index('.')]
def getParts():
name = Blender.Get('filename')
name = stripExt(name)
# Check that there is a number at the end of the filename.
if name[-1] not in NUM:
tileSize = DEFAULT_TILE_SIZE
else:
# Work out the tile size from the file name.
tileSize = ''
while name[-1] in NUM: # Keep pulling in the numbers as long as they are nums.
tileSize = name[-1] + tileSize
name = name[0:-1]
tileSize = eval(tileSize)
# OK either way we have a tile size.
# Get the data
scn = Scene.GetCurrent()
context = scn.getRenderingContext()
xPix = context.imageSizeX()
yPix = context.imageSizeY()
xParts = int(xPix / tileSize)
yParts = int(yPix / tileSize)
# Incase the tile size is larger then the render size.
if xParts < 2:
xParts = 2
if yParts < 2:
yParts = 2
return xParts, yParts
# Makes a list of rects that setBorder will pass.
def makeBorderList(xparts, yparts):
borderRectList=[] #We store all the rects here and then return them.
xlen = 1.0 / xparts
ylen = 1.0 / yparts
xPoint = 0.0 # This stores the current X value, and incriments xlen each iteration until its equel to 1.0
yPoint = 0.0
counter = 1 # Inde each border
while xPoint < 0.999:
while yPoint < 0.999:
# Write the rect to the list
borderRectList.append( (counter, max(xPoint), max(yPoint), max(xPoint+xlen), max(yPoint+ylen)) )
counter += 1 # Keep a tag of which index this one is.
yPoint += ylen
# Reset yPoint for the next colum.
yPoint = 0.0
xPoint += xlen
return borderRectList
# SETS UP DEFAULTS NEEDED FOR OUTPUTTING AN IMAGE THAT CAN BE COMPOSITED.
scn = Scene.GetCurrent()
context = scn.getRenderingContext()
context.enableBorderRender(1)
context.enableRGBAColor() # Save RGBA
context.setImageType(Render.PNG) # Save RGBA
context.enableExtensions(1)
# Make image name
imageName = Blender.Get('filename')
# Remove .blend
imageName = stripExt(imageName)
renderName = imageName + '_' # frameNum.png will be added.
xParts, yParts = getParts()
randBorderList = randList( makeBorderList(xParts,yParts) )
# Set the start and end frame to the current frame.
curFrame = Blender.Get( 'curframe')
context.startFrame(curFrame)
context.endFrame(curFrame)
# Keep track of frames rendered, only for a report.
renderedFrames = 0
for border in randBorderList:
# Set the new file name WITH X/Y parts
# blendfilename_partnum_framenum.ext
# eg. render_01_0001.png
partNum = str(border[0])
while len(partNum) < 4:
partNum = '0' + partNum
uniqueRenderName = renderName + partNum + '_' # We add 1 so that the first image is 1, not 0
# CREATE THE REAL NAME OF THE OYTPUT FILE
frameNum = str(curFrame)
while len(frameNum) < 5:
frameNum = '0' + frameNum
fileToRender = uniqueRenderName + frameNum + '.png'
# Chech that the file isnt alredy there
if isfile(fileToRender) == 0:
# TOUCH FILE SO NOBODY OVERWRITES IT.
#Create a dummy file so no other nodes try to render the image.
file = open(fileToRender,"w")
file.close()
# SET RENDER NAME AND PATH.
context.setRenderPath('//' + uniqueRenderName) # // is the currentdir
# Set border
context.setBorder(border[1], border[2], border[3], border[4] )
# RENDER THE IMAGE
context.renderAnim() # This saves the pics.
renderedFrames += 1
# Print report
print 'XParts', xParts,' YParts', yParts
print renderedFrames, ' of ', len(randBorderList), ' rendered'
# Quit
Blender.Quit()