The main issue is that a GvNode or a Script Manager is not persistent. Meaning, for example, the script manager.
Things only exist for the time you execute your command. At the moment your script finishes being executed everything is deleted this is due to the GIL.
Same things for Xpresso Node (GvNode) the python code is only executed when the scene calls the execution of the Xpresso tag. So that's means again the data are somehow not persistent. A quick hack is to define a variable as global so you will be available to access this variable along with multiple executions of the Xpresso Tag see Python Global, Local and NonLocal variable.
So with that's said, an important thing to understand, Xpresso Tag execution and actually the whole scene execution (aka retrieving the cache of objects, executing tags, Xpresso Tag, Xpresso Node) is multithreaded. And as described in the
Threading Information, you can't do whatever you want in a thread and for example trigger a render have no sense. Here some background about what is a thread Thread Wikipedia.
So some stuffs are executed in parallel,in your case, it will make no sense to render the scene (from the execution of Xpresso Tag) if the cube geometry is not yet created.
So that means we need a way to say once you have finished to build the scene, do something. Such things in Cinema 4D is usually done with Message and message stack. So typically in your Xpresso node you will put a MessageID on a stack of others Cinema 4D MessageId that will be executed at the end of the current scene execution (actually a scene execution is also launched from another message, so literally Cinema 4D has a list of operation to do in the main thread and it simply iterate over theses things to do).
Then you will create a MessageData plugin in order to receive this message, that will be executed in the main thread and there you will be able to render the document.
So long story short. Here is a scene file with a python node the code is inspired by this post in stackoverflow:
And the plugin to create your own message that will render into the picture viewer. You have to put it into your plugin folder and name it "WhateverYouWant.pyp"
# Make sure to have an Unique ID from https://plugincafe.maxon.net/c4dpluginid_cp
PLUGIN_ID = 1000001
def CoreMessage(self, id, msg) :
if id == PLUGIN_ID:
# Render the document if there is not actually another render running
if not c4d.CheckIsRunning(c4d.CHECKISRUNNING_EXTERNALRENDERING):
if __name__ == "__main__":
c4d.plugins.RegisterMessagePlugin(PLUGIN_ID, "MyMessagePlugin", 0, MyMessagePlugin())
I know it can be a bit hard for a beginner if you have any questions, please don't hesitate to ask.