Solved Setting Noise as the Shader in a Displacer

I am trying to set the Shader field in the Displacemtn object to Noise. However, the filed is not filled.

Here the code.
What am I doing wrong?

from typing import Optional
import c4d

doc: c4d.documents.BaseDocument  # The active document
op: Optional[c4d.BaseObject]  # The active object, None if unselected

def main() -> None:

    displacer = c4d.BaseObject(c4d.Odisplacer)
    doc.InsertObject(displacer)
    
    shd = c4d.BaseList2D(c4d.Xnoise)
    #displacer[c4d.ID_MG_SHADER_SHADER] = shd
    
    displacer.InsertShader(shd)
    c4d.EventAdd()
    
if __name__ == '__main__':
    main()
    

Ok, I understand it now better, thanks.

@pim
I solved it.
You must insert the shader into the document and then insert it in the displacer

from typing import Optional
import c4d

doc: c4d.documents.BaseDocument  # The active document
op: Optional[c4d.BaseObject]  # The active object, None if unselected

def main() -> None:

    displacer = c4d.BaseObject(c4d.Odisplacer)
    doc.InsertObject(displacer)
    
    shd = c4d.BaseList2D(c4d.Xnoise)
    doc.InsertShader(shd)
    displacer[c4d.ID_MG_SHADER_SHADER] = shd
    
    #displacer.InsertShader(shd)
    c4d.EventAdd()
    
if __name__ == '__main__':
    main()

Hey @pim,

Thank you for reaching out to us. Your first code example was correct, but you had commented out the line where you referenced the shader; which then will of course lead to a an object with no referenced shader. Inserting the shader and referencing it are two separate things. And since the Displace object owns the shader in this case, it should be the entity below which the shader is being inserted.

The document is not the correct place to insert the shader. Inserting a shader primarily makes sure that the shader is attached to the scene graph and sometimes one can get away with inserting shaders in wonky places (e.g., insert a shader referenced by material A under material B). But doing this eventually will lead to crashes.

You should also first insert the shader and then reference it or call other shader related functions.

Cheers,
Ferdinand

PS: I have removed your "Solved" flag, since the code you show there is not correct.

Result:
Screenshot 2023-06-25 at 22.39.54.png

Code

from typing import Optional
import c4d

doc: c4d.documents.BaseDocument  # The active document
op: Optional[c4d.BaseObject]  # The active object, None if unselected

def main() -> None:

    displacer = c4d.BaseObject(c4d.Odisplacer)
    shader = c4d.BaseList2D(c4d.Xnoise)
    if None in (displacer, shader):
        raise MemoryError(f"{displacer = }, {shader = }")

    doc.InsertObject(displacer)
    displacer.InsertShader(shader)
    displacer[c4d.ID_MG_SHADER_SHADER] = shader
    
    c4d.EventAdd()
    
if __name__ == '__main__':
    main()

MAXON SDK Specialist
developers.maxon.net

Ok, I understand it now better, thanks.