Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    How to increase the number of calculations in a Python tag?

    Cinema 4D SDK
    windows python 2023
    2
    4
    787
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • L
      ll2pakll
      last edited by

      Windows 10
      Cinema 4d 2023.2.1

      Good afternoon. I've encountered a problem where the calculation of object behavior written in the Python tag is either not synchronized with the scene frame rate, or otherwise does not have time to calculate some parameters. Because of this, when the amplitude of movements is large, the springs that connect the cubes in the scene look in the wrong direction. In the parameters of the python tag, I have not found a setting for the calculation frequency. Is there any way to increase the number of calculations per frame?
      P.S. I made a video in viewport, but when rendering the picture does not change.

      ferdinandF 1 Reply Last reply Reply Quote 0
      • ferdinandF
        ferdinand @ll2pakll
        last edited by ferdinand

        Hello @ll2pakll,

        Thank you for reaching out to us. I assume with calculation frequency you mean how often your tag is invoked, i.e., how often Cinema 4D calls its TagData::Execute or by extension the main function of a python programming tag.

        Cinema 4D, at least in the classic API you are bound to here, is event driven and follows its so called Scene Execution Pipeline. So your tag(s) are simply as often updated as EVMSG_CHANGE is broadcasted into your scene. You cannot cause the tags of type T or set of instances S of type T to be updated more frequently than the rest.

        You could write a plugin which permanently EVMSG_CHANGE into the scene, or to similar effect, permanently marks your tags as dirty (to more or less the same effect). But both these things would be terrible ideas, as they both would always bring Cinema 4D to a crawl, at it would be always recalculating all of the scene.

        What can I do?

        I am a bit fuzzy on what you are trying to do, but it looks like some kind of spring dynamics system.

        1. Execute the passes yourself. You can execute the passes yourself on a document with BaseDocument.ExecutePasses, we talked for example recently about it here. Since you are in a tag you are bound by the threading restrictions as already pointed out in the other thread. So you cannot execute the passes on the scene you are in. But you could create a temporary document, copy all the stuff over you need, and then execute the passes until 'things settle'. Then you can copy back parameters like positions and orientations from your little simulation dummy scene. You cannot copy back the object itself, because that would mean modifying the scene from the main function of your tag which runs off-main-thread.
        2. The problem with (1.) is that it is quite expensive to do, even in the best scenario of running things in a dummy document. Executing the passes is never cheap, because it is the main event loop of a document. Writing a solver be it springs, or rigid bodies in general, is not trivial, but you should have some kind of centralized abstraction in there. I.e., only one 'solver' tag and then as many 'data' tags as you need to express springs between objects. The solver tag would then do as many iterations on as many objects as you want and simply write the results back into the objects which are marked with the data tags.

        Long story short, the primary event loop of Cinema 4D is not a good thing to tie a solver too, because you will run for once into performance problems and also be sometimes event-starved, i.e., your solver does simply not update as there is a longer period without EVMSG_CHANGE being emitted.

        If I get this, right, this all has an educational/explorational context. If I were you, I would try to write abstractly a solver which takes in a system S with N objects and M springs. And then computes any number of iterations/time you want on that system S. Once this runs, you can then tie it to c4d by for example running your spring model in a tag which then writes its result into a scene.

        Cheers,
        Ferdinand

        MAXON SDK Specialist
        developers.maxon.net

        L 1 Reply Last reply Reply Quote 1
        • L
          ll2pakll @ferdinand
          last edited by

          @ferdinand Thank you for your answer, I didn’t think that the solution would be so difficult. From this point of view, unfortunately, the use of the python tag, in a sense, loses its relevance in the case of complex calculations. I tried the option with ExecutePasses, but it completely hangs the entire program. As a result, the only thing that more or less works, without completely reworking the code, is increasing the FPS of the scene from 25 to 100, this is exactly what I wanted - increasing the number of calculations per second. Unfortunately, this does a lot of unnecessary work related to calculating graphics for frames, which I will reduce to 25 per second anyway. Perhaps my comment will help someone who encounters a similar problem, and who, like me, is not a professional programmer. As always, I thank you and wish you a good mood.

          ferdinandF 1 Reply Last reply Reply Quote 0
          • ferdinandF
            ferdinand @ll2pakll
            last edited by

            Hey @ll2pakll,

            yes, any kind of simulation/solver is usually quite a bit of work; and as with most things, most of it is pushing data around in a 'clever' way and not the actual algorithm. You might get away with just saturating the system (add frames or "redraws"), but be warned, you will run into more problems with this approach.

            To have a robust solver, you must decouple it from the FPS and scene update events; this is not just a Cinema 4D thing, but universal.

            Cheers,
            Ferdinand

            MAXON SDK Specialist
            developers.maxon.net

            1 Reply Last reply Reply Quote 0
            • i_mazlovI i_mazlov referenced this topic on
            • First post
              Last post