SOLVED Importing RSproxies using Python


We would like to import RSproxy inside C4D using Python script but we don't find any documentation about how we can set the import path and the animation type.
these fields seams unaccesible with python in C4D.
This one:
and this one:

Is it right?

Hello @umd,

welcome to the Plugin Café and thank you for reaching out to us.

Is it right?

Well, the answer is yes and no at the same time. The type of the file parameter is indeed not exposed (not only in Python but also in C++), but it is a composed type and its subchannels are exposed. The topic was discussed in Attribute Error when accessing Redshift parameters before where I gave a brief overview of the technical background.

You can explore the subchannels of a parameter with the option "Show Sub-channels" in the Attribute Manger. To then get the full set of DescLevel for that subchannel, you can then use the console approach of discovering parameter symbols.


In your case the specific DescID for (File, Path) would for example be c4d.REDSHIFT_PROXY_FILE,c4d.REDSHIFT_FILE_PATH.


Hello @ferdinand ,
thank you for your answer !

But we have another issue with that!
We want to edit the REDSHIFT_PROXY_SELECTION_OBJECTS parameter after import

but this parameter does not seem to be initialized on creation and it returns an empty string.
I tried to refresh c4d ui, switch frame, etc.. to force reload but nothing happens
To get the param value I have to run another script by hand after the import command.

Here is the simplified code:

proxy = proxy_utils.import_proxy(doc, "tutu", "hello")


Hey @umd,

Your question and code example are a bit ambiguous for me. You say:

We want to edit the REDSHIFT_PROXY_SELECTION_OBJECTS parameter after import, but this parameter does not seem to be initialized on creation and it returns an empty string.

and then show this line which I assume uses a private module proxy_utils of yours:

proxy = proxy_utils.import_proxy(doc, "tutu", "hello")

From this I would conclude that when you say import or creation, you mean that you manually instantiate an RSProxy object and set its proxy file, likely in the function import_proxy. So, the interesting thing to show would have been what this function does, but I assume you are not building the caches there for the returned BaseObject. A scene state, among other things: its caches, can be evaluated with BaseDocument.ExecutePasses. See the example at the end of my posting for details.


The result:

After parameter change: rsProxy[c4d.REDSHIFT_PROXY_SELECTION_OBJECTS] = ''
After passes: rsProxy[c4d.REDSHIFT_PROXY_SELECTION_OBJECTS] = '{"format":1,"objects":[{"name":"Cube","state":1,"type":0}]}\n'

The code:

"""Demonstrates executing the passes on a document to reflect parameter changes on an object within
the scope of a function.

import c4d
import redshift

doc: c4d.documents.BaseDocument  # The active document

def main() -> None:
    # Setup the rsProxy object and set the proxy file.
    rsProxy = c4d.BaseList2D(redshift.Orsproxy)
    rsProxy[c4d.REDSHIFT_PROXY_FILE,c4d.REDSHIFT_FILE_PATH] = "/Users/f_hoppe/Desktop/Untitled"

    # Something like this wont work, as the cache for #rsProxy has not been built yet. This is
    # basically the same as when we would have instantiated a cube object, its geometry would not
    # have been build yet too.
    print (f"After parameter change: {rsProxy[c4d.REDSHIFT_PROXY_SELECTION_OBJECTS] = }")

    # The same applies to this ...

    # doc.InsertObject(rsProxy)
    # c4d.EventAdd()
    # print (f"{rsProxy[c4d.REDSHIFT_PROXY_SELECTION_OBJECTS] = }")

    # We must insert #rsProxy into some document and execute the passes on it. It is best to
    # use a dummy document for that.
    temp = c4d.documents.BaseDocument()

    # Evaluate the scene state of #temp. It is likely enough to build the caches here (the fourth
    # argument), but I do not know much about RSProxy, so I did evaluate everything. Feel free to
    # optimize, but it should not make a big difference for "normal" scenes.
        bt=None, animation= True, expressions=True, caches=True, flags=c4d.BUILDFLAGS_NONE)

    # We can remove #rsProxy at this point from #temp, its cache will stay attached to the object.
    # When we print the parameter you are interested in, it will now be populated.
    print (f"After passes: {rsProxy[c4d.REDSHIFT_PROXY_SELECTION_OBJECTS] = }")

    # On the forum you said "We want to edit the REDSHIFT_PROXY_SELECTION_OBJECTS parameter after 
    # import". I am not sure if this is a good idea or possible. But again, I do not know much about
    # RSProxy. The value returned here seems to be more a string representation of an internal
    # state than an actual value, i.e., is meant to be read-only, but I might be wrong.

    # Since we removed #rsProxy from #temp, we can also insert it into #doc if we wanted to.

if __name__ == '__main__':

Oh I see..
The ExecutePasses was the key !

Thank you for your answers !