On 12/09/2016 at 07:40, xxxxxxxx wrote:
Hi,
while it is not possible to add command line options that alter the behavior of built-in functionality (like in your case the rendering process), there are quite a few options. Which fits best, depends of course highly on your situation and the plugin you already seem to have.
a) If your plugin is running on the server side (i.e. being responsible for distributing the data to the render nodes) you could modify the render settings before sending the scene to a node. For a hint on how to do this, see my Python example code below.
b) Somewhat the compromise of a) and c), you could write a plugin to run on the render nodes. This plugin would add a new command line option (see either C++ Plugin Functions Manual or Plugin Messages in Python docs (a bit down the page)), which loads the scene (that will later be rendered by C4D), modifies the render settings, saves the scene again. Further down the line C4D would then take over and render.
c) I once did an example for a Dev Kitchen, which partly already does what you are asking for. It adds a command line option for tiled rendering.
The downside: You will need to take over the rendering part, e.g. saving to the correct format...
Note the quotation marks enclosing the entire command line option, needed by this example:
See here:
# Dev Kitchen 2015 - Python Commandline #5 - Rendering Tiles
import sys, os, ntpath, math
import c4d
from c4d import bitmaps, documents
# Renders a tile of the current camera
# Syntax: cinema4d.exe "-rendertiled numtiles tileidx file"
# with numtiles the number of tiles in x and y direction (numtiles=2 => 4 tiles total)
# and tileidx either all or between 0 and (numtiles*numtiles)-1
def CommandRenderTiled(arg) :
# Parse arguments
argComponents = arg.split(' ')
numTiles = int(argComponents[1])
fNumTiles = float(numTiles)
if argComponents[2] == "all":
tileIdxMin = 0
tileIdxMax = (numTiles * numTiles)
else:
tileIdxMin = int(argComponents[2])
tileIdxMax = tileIdxMin + 1
fname = argComponents[3]
# Load the scene without inserting into C4D's document list
doc = documents.LoadDocument(fname, c4d.SCENEFILTER_OBJECTS | c4d.SCENEFILTER_MATERIALS)
if doc is None:
print "Failed to load file: %s" % fname
return
bd = doc.GetRenderBaseDraw()
if bd is None:
return
# Get the active camera
cam = bd.GetSceneCamera(doc)
if cam is None:
cam = bd.GetEditorCamera(doc)
if cam is None:
return
# Get the active render settings and
rd = doc.GetActiveRenderData()
filepath, filename = ntpath.split(rd[c4d.RDATA_PATH])
for tileIdx in range(tileIdxMin, tileIdxMax) :
# Prefix the output filename with tile index
outputPath = filepath + "/" + str(tileIdx) + "_" + filename
rd[c4d.RDATA_PATH] = outputPath
# Delete previous render
if ntpath.isfile(outputPath) is True:
os.remove(outputPath)
# Create a new camera and configure it for tiled render
camOffset = c4d.BaseObject(c4d.Ocamera)
camOffset.SetMg(cam.GetMg())
camOffset[c4d.CAMERA_PROJECTION] = cam[c4d.CAMERA_PROJECTION]
camOffset[c4d.CAMERAOBJECT_APERTURE] = cam[c4d.CAMERAOBJECT_APERTURE]
camOffset[c4d.CAMERAOBJECT_SHOW] = cam[c4d.CAMERAOBJECT_SHOW]
camOffset[c4d.CAMERA_FOCUS] = cam[c4d.CAMERA_FOCUS] * fNumTiles
camOffset[c4d.CAMERA_ZOOM] = cam[c4d.CAMERA_ZOOM] * fNumTiles
biasX = math.fmod(float(tileIdx), fNumTiles) - (fNumTiles - 1.0) * 0.5
biasY = float(tileIdx / numTiles) - (fNumTiles - 1.0) * 0.5
camOffset[c4d.CAMERAOBJECT_FILM_OFFSET_X] = fNumTiles * cam[c4d.CAMERAOBJECT_FILM_OFFSET_X] + biasX
camOffset[c4d.CAMERAOBJECT_FILM_OFFSET_Y] = fNumTiles * cam[c4d.CAMERAOBJECT_FILM_OFFSET_Y] + biasY
# Insert the new camera into the scene and set it for rendering
doc.InsertObject(camOffset)
bd.SetSceneCamera(camOffset)
# Initialize a bitmap with the result size (must match output size of render settings)
bmp = bitmaps.BaseBitmap()
bmp.Init(x=rd[c4d.RDATA_XRES], y=rd[c4d.RDATA_YRES], depth=24)
# Render the file (and assure saving of rendered image)
documents.RenderDocument(doc, rd.GetData(), bmp, c4d.RENDERFLAGS_EXTERNAL)
if rd[c4d.RDATA_SAVEIMAGE] is False: # if saving is enabled in render settings it will be saved automatically
if bmp.Save(outputPath, c4d.FILTER_TIF, None, c4d.SAVEBIT_0) is not IMAGERESULT_OK:
print "An error occurred, when saving the image %s" % outputPath
def ParseCommandline(argv) :
for arg in argv:
if arg.find("-rendertiled") == 0:
CommandRenderTiled(arg)
def PluginMessage(id, data) :
if id == c4d.C4DPL_COMMANDLINEARGS:
# Extend command line parsing, here
# This is the last plugin message on Cinema 4D's start process
ParseCommandline(sys.argv)
return True