Save variables during current session (until C4D is closed)



  • I've wrote a script which must make some calculations only once and then use these values until C4D is closed.
    After C4D is opened again the script must recalculate values again, but only once.
    It's not a plugin, but only python script.
    Is it possible to realize?
    Cheers


  • Global Moderator

    Hi @kisaf, while is not the recommended way since we could not guarantee the safeness of this method, you could use a global variable.
    This variable will be available across multiple frames but only to the current python scope (if you define a variable in a Python Generator, you can't get it from a Python Tag).
    Here a short example from a Python Scripting Tag

    import c4d
    global previousCount
    
    def main():
        global previousCount
        if 'previousCount' not in globals():
            previousCount = 0
            
        previousCount += 1
        print previousCount
    

    Besides that, you are free to use any kind of datatype/structure python or the Cinema 4D API provides.
    BaseContainer from the Cinema 4D API can be well suited since you can store it in multiple levels such as Object/tag or even document.
    All of them inherit from BaseList2D which provide the GetData/SetData which let you access the BaseContainer where you can store your BaseContainer holding your data as long as you use a unique ID from https://plugincafe.maxon.net/c4dpluginid_cp.

    If you have any questions please let me know and do not hesitate, especially if you decide to go to the second way, which may sound a bit more complicated.
    Cheers,
    Maxime.



  • In addition to @m_adam's answer, you can use GetWorldPluginData() to save variables. Those even do exist after restarting Cinema 4D. You can clear them on application exit.


  • Global Moderator

    Hi @mp5gosu, thanks for the addition, in this case c4d.GetWorldContainer is more suited since it's not about a plugin but a script.

    But in all cases you are right, data stored are persistent and it's not recommended to store any kind of caching data in these containers. It takes some memory and this can become very problematic if the developer forgets to free the container at the application exit.

    Moreover, you can easily screw up, user preference with that, so, be careful when dealing with these methods.
    Cheers,
    Maxime.



  • Since the OP has asked explicitly for scripts, I would like to add: @m_adam 's "Global" method will not work for scripts, as their Python scope is (apparently) only valid for the current execution. It does work for Python tags and XPresso Python nodes where the scope seems to exist for the lifetime of the tag.

    If you work with tags/nodes and have actual variables to store in the globals, you need to account for the timing and the frequency of execution (e.g. do not rely that the next execution is actually the next frame). This will not apply for one-time executions like an initialization, but even there you may want to determine an anchor point (e.g. at frame 0) where the value is reset or calculated for the first time.


  • Global Moderator

    Thanks a lot @Cairyn I overlooked this part and you are right, from the Script Manager my solution does not work, only for embedded BaseList2D such as Python Tag, Python Generator and so on.

    So the only reliable way is to store data in a BaseContainer, or any "generic way" e.g. files.

    Cheers,
    Maxime.



  • Thank you very much guys!
    I think that plugin will be better solution then script in this case.
    Cheers