triggered time(r) events



  • On 21/01/2017 at 10:04, xxxxxxxx wrote:

    Hello,

    I am trying to familiarise myself better with the way python works in cinema 4d, so I am working on a python tag which helps control a dynamics vehicle.

    Is there a built in function which is part of the c4d module which can initiate timed events?
    I think more likely there is a simple function which can be defined using the current frame input. But I'm not sure how to write such a function (or do you say, definition?);

    My main problem is understanding what is the "main" def in places like the python tag and node in xpresso.

    My assumption is that whatever is in "main", is run every frame. Is there more to it than that?

    I come across issues when I define something outside of "main" and try to call it from "main", sometimes it works, sometimes it doesn't. Sometimes I can define a variable, sometimes it doesn't work unless I define it with a value.. can someone explain to me the fundamentals, or link to some help?



  • On 23/01/2017 at 03:11, xxxxxxxx wrote:

    Hi,

    Yes the main() function is executed every frame and when the object the tag is attached to is updated.
    You can get the current frame inside main() using:

    frame = doc.GetTime().GetFrame(doc.GetFps())
    

    Inside a Python tag main() there are 2 important variables defined automatically: doc is the active document and op is the tag itself.

    You should be able to define other functions then main() and also variables outside of it. The code that's compiled and executed is just plain Python.



  • On 24/01/2017 at 04:22, xxxxxxxx wrote:

    Thank you Yannick, that's useful to know, I will try and make a timed event using standard python examples from google as a guide.

    I noticed when defining functions, they need to be written above the line of code which references them, is this correct? it took me a while to figure this out!



  • On 24/01/2017 at 08:51, xxxxxxxx wrote:

    Originally posted by xxxxxxxx

    I noticed when defining functions, they need to be written above the line of code which references them, is this correct? it took me a while to figure this out!

    This shouldn't be the case. Do you have some code showing this? In which context are you executing the code? In a Python tag/generator or another object executing a Python script?



  • On 25/01/2017 at 08:23, xxxxxxxx wrote:

    This is occurring in the context of a python scripting tag, here is an example of the issue:

    https://www.dropbox.com/s/ujrpz653x1imeq0/def location_Issues.c4d?dl=0

    breakdown of code:

    import c4d

    with the getObjectByAddress def here, the code works fine.

    alignObj = op.GetObject().GetNext()
    LeftWheel = getObjectByAddress(op.GetObject(), "uupd")
    RightWheel = getObjectByAddress(op.GetObject(), "uupdn")

    def main() :
        print LeftWheel
        print RightWheel

    with the def here, get NameError

    def getObjectByAddress(startobject, address) :
    #   long bit of code
        return result



  • On 26/01/2017 at 02:53, xxxxxxxx wrote:

    From Python language reference: "When a name is used in a code block, it is resolved using the nearest enclosing scope. The set of all such scopes visible to a code block is called the block's environment."
    For more information see Execution model.

    So if getObjectByAddress() is called from main() to initialize the global variables LeftWheel and RightWheel , the code runs fine:

    LeftWheel = None
    RightWheel = None
      
    def main() :
        global LeftWheel
        global RightWheel
        
        LeftWheel = getObjectByAddress(op.GetObject(), "uupd")
        RightWheel = getObjectByAddress(op.GetObject(), "uupdn")
        
        print LeftWheel
        print RightWheel
      
    def getObjectByAddress(startobject, address) :
        ...
    


  • On 26/01/2017 at 05:56, xxxxxxxx wrote:

    So, for the name to be resolved, it has to be one layer deeper than the definition?
    So why does it work when the def is above the variables, but not below main or just below the variables?

    Say for example I didn't want to update LeftWheel and RightWheel every frame, how would I do it?



  • On 27/01/2017 at 08:34, xxxxxxxx wrote:

    Originally posted by xxxxxxxx

    So, for the name to be resolved, it has to be one layer deeper than the definition?
    So why does it work when the def is above the variables, but not below main or just below the variables?

    This is because of the order of definition and execution of Python as it executes the code in a source from top to bottom.
    In your initial code you try to initialize the variables calling getObjectByAddress() while the function hasn't been defined yet ().
    main() is a special case because it's executed at the end so getObjectByAddress() is defined.

    Originally posted by xxxxxxxx

    Say for example I didn't want to update LeftWheel and RightWheel every frame, how would I do it?

    You can add an if statement for LeftWheel and RightWheel if they're None to skip initializing them again inside main().



  • On 27/01/2017 at 09:25, xxxxxxxx wrote:

    ahh I see, great! thank you!


Log in to reply