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 make Python Field react to camera?

    Cinema 4D SDK
    python 2023
    4
    8
    1.1k
    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.
    • W
      wuzelwazel
      last edited by

      I'm working on a Python Field that updates based on a camera linked by user data. I was able to get the field to update as the camera attributes are modified or animated by "forwarding" the camera's dirty state to the field object. However, this doesn't work when viewing through the camera and manipulating with shortcuts in the viewport.

      I tried reading the dirty state of the associated BaseDraw but that didn't seem to work. Is this a priority issue? Is there an alternative method to trigger calculation of the field when manipulating the active camera?

      Thanks.

      1 Reply Last reply Reply Quote 0
      • ManuelM
        Manuel
        last edited by

        Hi,

        while i understood the issue with the camera it is a bit hard to be sure where you are checking the camera dirty state on your field object.

        Would it be possible to share your scene or code so we can reproduce the issue faster without guessing what you did?

        Cheers,
        Manuel

        MAXON SDK Specialist

        MAXON Registered Developer

        W 1 Reply Last reply Reply Quote 0
        • W
          wuzelwazel @Manuel
          last edited by

          @manuel thanks for getting back to me and apologies for the delay in providing more information.

          I'm attaching a C4D scene file here that includes the setup with Python Field and Camera object.

          camera_field_simple.c4d

          The part of the code where I'm attempting to trigger a refresh of the sampling is in the InitSampling() function and it's pretty simple:

          if camera.GetDirty(c4d.DIRTYFLAGS_MATRIX | c4d.DIRTYFLAGS_DATA):
                  op.SetDirty(c4d.DIRTYFLAGS_DATA)
          

          I had also attempted getting the active BaseDraw from the document, checking whether it's linked camera was the one linked in the field, and checking the BaseDraw dirty state instead of the camera but that didn't work out.

          I've also noticed that if I transform the camera and undo the transform the field does not update.

          1 Reply Last reply Reply Quote 0
          • ManuelM
            Manuel
            last edited by

            hi,

            The camera is a special beast in some cases. Fields also. They are supposed to trigger the less updates possible.
            There is no direct way of fixing this issue. One workaround (pretty dirty) is to create a python tag attached to your plain effector.
            As showed in this thread, this python tag can register and react to an event.

            The idea is to set the effector itself or the field layer dirty. (Not the field object).
            You can react to the message that have the ID c4d.MSG_GETREALCAMERADATA. If this message is received, then you can set the effector dirty. This will trigger the field layer to be recalculated and the field object to be re-evaluated.

            This is a bit dirty because the effector will be re-evaluated every time you move the camera, even if this is the viewport camera.
            But you can add a few lines of code to check if the active camera is the object camera linked in your field object.

            For this to work, you must use the function AddEventNotification. Have a look at the c++ documentation as it is more precise in the way it describes the flags to use.

            Be aware that will also slow down the viewport as maybe some useless calculation will be triggered.

            import c4d
            
            def message(msgType, data):
                if msgType == c4d.MSG_NOTIFY_EVENT:
                    if data["eventid"] == c4d.NOTIFY_EVENT_MESSAGE:
                        if data["event_data"]["msg_id"] == c4d.MSG_GETREALCAMERADATA:
                            obj = op.GetObject()
                            obj.SetDirty(c4d.DIRTYFLAGS_DATA)
            
            
            def main():
                obj = op.GetObject()
                # Chekc if the event nofication is already added otherwise add it.
                if not obj.FindEventNotification(doc, op, c4d.NOTIFY_EVENT_MESSAGE):
                    obj.AddEventNotification(op, c4d.NOTIFY_EVENT_MESSAGE, c4d.NOTIFY_EVENT_FLAG_COPY, c4d.BaseContainer())
            
            if __name__=='__main__':
                main()
            

            Cheers,
            Manuel

            MAXON SDK Specialist

            MAXON Registered Developer

            W 1 Reply Last reply Reply Quote 0
            • W
              wuzelwazel @Manuel
              last edited by

              @manuel Amazing! Thank you for stepping through this with me.

              I was thinking that messages could be the solution here but I'd only ever dealt with them in the context of a MessageData plug-in and was not aware of AddEventNotification().

              1 Reply Last reply Reply Quote 0
              • W
                wuzelwazel
                last edited by

                Calling AddEventNotification() in Python seems to consistently crash Cinema 4D 😞

                1 Reply Last reply Reply Quote 0
                • ManuelM
                  Manuel
                  last edited by

                  hi,
                  it happens with the scene you provided ?

                  MAXON SDK Specialist

                  MAXON Registered Developer

                  1 Reply Last reply Reply Quote 0
                  • M
                    m_adam
                    last edited by

                    Hello @wuzelwazel,

                    without further questions or postings, we will consider this topic as solved by Friday 02/06/2023 and flag it accordingly.

                    Thank you for your understanding,
                    Maxime.

                    MAXON SDK Specialist

                    Development Blog, MAXON Registered Developer

                    1 Reply Last reply Reply Quote 0
                    • First post
                      Last post