ReferenceError?



  • Got a simple script that gives me errors.
    First time in C4D so maybe it is a simple API call mistake, but it does not seem so.
    the error isReferenceError: could not find 'main' in generator 'Python Generator'

    My thanks for helping out, looking forward to building cool stuff in C4D

    import numpy as np
    
    n = 10
    y = 0
    grid = np.random.choice([1, 0], n * n).reshape(10, 10)
    for i in range(n):
        for j in range(n):
            if grid[i, j] == 1:
                vec = c4d.Vector(i * 230, j * 230, y)
                obj = c4d.BaseObject(c4d.Ocube)  # Create new cube
                obj.SetRelPos(c4d.Vector(vec))  # Set position of cube
                doc.InsertObject(obj)  # Insert object in document
    


  • Have a look at the code template you get when you create a fresh PythonGenerator object: it contains a main() function that returns a BaseObject. You will need to do the same in your code, instead of inserting an object into the document directly (which would be the way to go in a Script but not in a Generator).

    The returned object will be inserted by the C4D object tree evaluation into the rebuilt virtual hierarchy (in place of the Generator object). If you would actually insert stuff directly, you would end up with newly generated objects every time this evaluation happens.

    So basically you have four issues here (unless you didn't quote the full content of the generator):

    • no main() function (which gives you the error)
    • no return value
    • direct insertion
    • no c4d import

    (not sure whether you have installed NumPy even, this is not a library that comes with C4D and needs to be installed so the internal Python interpreter can find it)



  • thanks for the response, make's everything a bit more clear now.
    I got the numpy module in C4D. so if I want to generate multiple objects with a generator and not place the objects directly into C4D, I expected something like this quick example to work.

    import c4d
    
    def main():
        y = 0 
        for i in range(10):
            vec = c4d.Vector(y,230,y)
            obj = c4d.BaseObject(c4d.Ocube)  # Create new cube
            obj.SetRelPos(c4d.Vector(vec))  # Set position of cube
            y += 100
            return obj
    main()
    

    why would a generator only give me 1 and not 10 cubes cloned?
    chancing the return line and adding them directly into the document works, and gives me 10 cubes.
    doc.InsertObject(obj)

    my thanks



  • If you have a "return" in a "for" loop, and the return is hit in the very first pass, of course the other nine passes are skipped...

    If you want to have more than one object returned, you need to link them. Try to create a null first, then loop for the 10 cubes, and attach the cubes as children of the null. Then return the null.

    (No guarantee, I can't test that right now)



  • @cairyn
    ah yeah, that was a dumb mistake. Got it working now. thanks you for that., but I do still have a question.
    If I want to inherit from c4d modules in my own class as a child. how would I do that? I tried it like this.

    from c4d.modules.thinkingparticles.TP_MasterSystem import TP_MasterSystem
    
    class Particle(TP_MasterSystem):
    

    but that is not how it works. :\

    The import seems to work fine. but I'm not able to inherit the particle class methods like size or life.
    type 'c4d.modules.thinkingparticles.TP_MasterSystem' is not an acceptable base type


  • Global Moderator

    Hi,

    first of all thanks to @Cairyn for nice explanations and helping in solving this.

    I'd just like to add a link to one of our examples, pretty much demonstrating this workflow: mengersponge.py (plus the scene file).

    @Jvos : I hope you don't mind, may I ask you to please open a new topic for unrelated topics/questions.
    I have also moved this thread into the Cinema 4D Development category, added some tags and turned the thread into a question.

    Cheers,
    Andreas