Jump to content

Cinema 4D Python Performance

Recommended Posts

Hi, i'm new to c4d and 3d in general. I started learning xpresso nodes and python.




I'm recreating this video with shaders and cloners, using xpresso nodes I created inside a python lfo (could have used the formula node) and connected it to the parameters of number of clones, shaders fallof linear position , strength, shader gradient, etc. 




When I wanted to replace several xpresso nodes with a python script (creating my own rangemapper function, real2vector) connected to my other lfo script, the animation got quite slow, giving very slow render times.


My questions are: 

what are the ways to optimize python performance?

does c4d have optimized python functions like xpresso?

is running python inside an xpresso node very expensive?

what is the least expensive way to run python scripts?

Does this way of using the script run in every frame?



I like xpresso but python is much easier for me to code.

I'm using c4d r19. Is the runtime of python improved in the new versions?



I'm redoing all, using only a null object with a python tag and api functions, i think this is going well.

Is just a little bit slower than xpresso, but python is easier for me.


import c4d
import math
#Welcome to the world of Python

def lfo(cframe, frecuencia, amplitud=1):
    return 1-(((math.sin(cframe*frecuencia)*amplitud)+1)*0.5)

def main():
    #User Data
    obj = op.GetObject()
    UC = obj.GetUserDataContainer()
    frecuencia= obj[c4d.ID_USERDATA,2]
    amplitud= 50
    #Current Frame
    cFrame = doc.GetTime().GetFrame(doc.GetFps())
    cloner = doc.SearchObject('Cloner')
    shader = doc.SearchObject('Shader')
    cube = doc.SearchObject('Cubito')
    random = doc.SearchObject('Random')
    osc = lfo(cFrame, frecuencia)
    #print osc
    #Move between -600,600 Shader
    shader[c4d.ID_BASEOBJECT_REL_POSITION,c4d.VECTOR_X]= c4d.utils.RangeMap(osc,0,1,-600,600,False)
    #Shader Strength
    shader[c4d.ID_MG_BASEEFFECTOR_STRENGTH]= osc

    #Random Strength

    #Cloner Count
    cloner[c4d.MG_GRID_RESOLUTION]= c4d.Vector(1+osc*50,1,1+osc*50)



Link to post

The reason Python is slower than XPresso is because many of the XPresso nodes were created using compiled C++ code. You can speed up your Python code by precomputing everything possible and just looking up, or better yet, iterating over the precomputed values. Just to give you an example, take your lfo function:


def lfo(cframe, frecuencia, amplitud=1):
    return 1-(((math.sin(cframe*frecuencia)*amplitud)+1)*0.5)

After computing a result that is a function of a permutation of the input values, you can cache it by storing it into a dict(), keyed by a tuple consisting of the inputs. Assuming the number of permutations of your inputs is relatively small and discrete, this can speed things up.


In similar fashion, use Dynamic Programming whenever possible. If you are not familiar with this concept, you can read about it on the Geeks for Geeks web site. Basically, cache everything you can after it is calculated once and use the cached values from that point on.



Link to post

Great, i will look for dynamic programming.

Another thing I had trouble with was accessing the blending properties of a layer in a texture within python.



I had to pass the values from python to the gradients through user data variables and connect them with xpresso.



Link to post

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Create New...