Solved Extending the Command Line with Python

Hi All!

I'm trying to run a python script before running a command line render. For example, change the subdivisions of a scene before you render the project.

The problem is the order of operations. The example below doesn't work.

The custom script is called -customsubs and works with the C4DPL_COMMANDLINEARGS function.

"C:\Program Files\MAXON\Cinema 4D R21\Commandline.exe" -render%userprofile%\Desktop\test.c4d -frame 0 0 -oimage %userprofile%\Desktop\test -omultipass %userprofile%\Desktop\test_mp -oformat TIFF -customsubs

I found a user with a similar problem but he is using C++ and this method of priorities is not working with python as far as I know.
Link to user with same problem

So the questions is: How can I run a custom python script before the -render command?

Thanks you!:)

Hi,

I think you cannot invoke a Python script with the Cinema 4D CL app. But you can run a Python script with c4dpy from the command line. To run your script manager scripts with c4dpy you would have either to make sure that they do not rely on that special script manager environment (not a very elegant solution) or alternatively emulate that environment. Since you want the changes of the script to be persistent, you would have also save the document after that. I had a go at that fun problem and came up with this tiny wrapper that does its best to emulate the script manager environment [1]. The usage in your scenario would be then:

c4dpy script_manager_environment.py -script my_script.py -in my_doc.c4d -out my_doc_scripted.c4d
CommandLine -my_doc_scripted.c4d ...

Where script_manager_environment.py is a file with the code from [1]. I did some simple tests and it seemed to work in these tests.

Cheers,
zipit

[1] Note that it is very unlikely that the environment that the wrapper does create is identical to the one Cinema 4D does create for its script manager (see the module docstring for details on what the wrapper does). A safer but lengthier version of such wrapper would use importlib instead of runpy. Due to that, your computer might explode and other terrible things could happen. You have been warned ;) The code forscript_manager_environment.py can be found here.

MAXON SDK Specialist
developers.maxon.net

Do you want to execute a Python Script or just some Python code?

You can write a Python plugin, that reacts to command line arguments (and thus executes your code). This is done by implementing PluginMessage(). But I don't know if that allows executing code before the command line renderer is executed.

See Command Line Arguments.

@PluginStudent said in Extending the Command Line with Python:

Do you want to execute a Python Script or just some Python code?

Python code is always a Python script ;) But given the fact that he said:

For example, change the subdivisions of a scene before you render the project.

It seems very likely that he wants to execute a Python script that was intended for Cinema's Script Manager environment.

You can write a Python plugin, that reacts to command line arguments (and thus executes your code). This is done by implementing PluginMessage(). But I don't know if that allows executing code before the command line renderer is executed.

Hm, I might be wrong about this, but I would have assumed that the command line app does not pipe through its arguments to the plugin messages, since it is a different app. It would also solve not much IMHO, as you would have in a plugin the same problem of faithfully recreating the Script Manager environment.

Cheers,
zipit

MAXON SDK Specialist
developers.maxon.net

Thanks Zipit and PluginStudent,

@PluginStudent I already use the Pluginmessage function, see example below.

def PluginMessage(id, data):
	if id == c4d.C4DPL_COMMANDLINEARGS:
		argstring = ' '.join(sys.argv)
		if "- customsubs" in argstring:
			CommandRenderChangesomething(sys.argv)

	return True

But than you have the problem that is not running before the -render command just like you said. It all about the order of operations I think. Cinema needs to wait until the script is done before starting the render.

@zipit Very interesting and something to look at. I already have another workaround. I can set a RenderDocument function in the script. Meaning I will do everything from the script. Making the adjustments and also the rendering. Skipping the whole -render.

But I like to do it with the method above for many reason to long to explain:D Something like this must be possible right? Or maybe not:grimacing:

https://plugincafe.maxon.net/topic/9303/12381_command-line-args-before-render-solved/3

This is exactly what I also need, only just for Python. :innocent:

@jwzegelaar said in Extending the Command Line with Python:

But I like to do it with the method above for many reasons to long to explain:D Something like this must be possible right? Or maybe not:grimacing:

No this is not possible, you will have to use workarounds (various exists, the one from @zipit seems for us totally valid).

But we need to know your requirements to suggest you the best one because we can't find a good reason why the method described by @zipit is not correct for you.

If its too confidential feel free to contact us on [email protected]

Cheers,
Maxime.

Hi Maxime,

Thank you for the response, we are trying out a few others methods now. :) There is not much confidential, it just comes down to our current queue manager software and workflow methods here, and with that this option from Zipit is not ideal.

Thank you very much for all the support guys, I will update this post when we know more.

Stay safe!

We found a good workaround! We now made a custom commandline plugin where we can add our own arguments. And it works great. If anybody in the future has this issue you can always contact us and we will help.

Thanks again everybody for all the help!

@jwzegelaar said in Extending the Command Line with Python:

We found a good workaround! We now made a custom commandline plugin where we can add our own arguments. And it works great. If anybody in the future has this issue you can always contact us and we will help.

Thanks again everybody for all the help!

Hi jwzegelaar,
I believe that I share the same needs as you, where I also need to pass in external parameters via a .py file to make modifications to the file before rendering. Unfortunately, I am encountering the same issue as you.
Although this post has been quite some time, I am still hopeful for your assistance. Your help would be greatly appreciated and it is highly important to me.