Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python 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 detect a document switching?

    Cinema 4D SDK
    python r23 s24 sdk
    4
    5
    810
    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.
    • mocolocoM
      mocoloco
      last edited by mocoloco

      Hi there,

      I'm trying to find a way to detect in a Python plugin a document change when I'm switching between different document in C4D. The switch do not concern file open, then close, and open an other document, but really having 2 or 3 different scenes opened at the same time and switching from one to an another.

      I went through the different post here, but I didn't found anything relevant, only few tracks, and also some C++ examples but they have some functions that are not existing in Python (ie GeDialog::CheckCoreMessage()). The best example I found is in C++ there : https://developers.maxon.net/docs/cpp/2023_2/page_manual_gedialog.html#page_manual_gedialog_interaction_global_events
      But the scope of EVMSG_CHANGE is too wide and appears for many operations and not only windows/doc switching.

      I tried to trace the msg IDs inside CoreMessage(), but I didn't found the correspondance for the IDs that I traced in console.

      For example I'm getting this when switching between opened documents:

      Python extract for the CoreMessage call,

      def CoreMessage(self, id, msg):
          doc = c4d.documents.GetActiveDocument()
      
          # if id == c4d.EVMSG_CHANGE:
          if msg.GetId() != 1298360653:
              print ( f"COREMSG_ID {msg.GetId()}" )
      

      In console,

      COREMSG_ID 1937337955
      

      I'm skipping the COREMSG_ID = 1298360653 otherwise I'm filing the console in a blink of an eye - it's maybe the redraw or evaluate scene.

      I tried to explore the ge_prepass.h file but didn't found any match. Where are located those ID Core Message definitions and their related readable values?

      That would helps me to found the right ID message called when switching.

      Then, I thought analyse the doc.GetDocumentName() once I do know that I effectively switch from a document to an another.

      If someone have some answers, just let me know, it would be really helpful!

      Thanks!
      Christophe

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

        Hi @mocoloco, this topic was discussed not so long ago in Modifying Scene On First Open or Before Save?. But this involve SceneHook which are only possible in C++.

        The best way in Python would be to create a MessageData plugin with a Timer and check if the active document changed. Relying on the Document Name is indeed a bad idea since unsaved document, are all unnamed. Find bellow a MessageData checking for the document change.

        class TimerMessage(c4d.plugins.MessageData):
        
            @property
            def activeDoc(self):
                doc = getattr(self, '_activeDoc', None)
                if doc is None:
                    return None
        
                # Check if we don't have a dead reference
                if not doc.IsAlive():
                    del self._activeDoc
                    return None
        
                return doc
        
            @activeDoc.setter
            def activeDoc(self, value):
                if not isinstance(value, c4d.documents.BaseDocument):
                    raise TypeError("value is not a c4d.documents.BaseDocument.")
        
                self._activeDoc = value
        
            def GetTimer(self):
                return 500
        
            def CoreMessage(self, id, bc):
                if id == c4d.MSG_TIMER:
                    activeDoc = c4d.documents.GetActiveDocument()
                    if activeDoc is None:
                        return
                    
                    if activeDoc != self.activeDoc:
                        oldDoc = self.activeDoc
                        self.activeDoc = activeDoc
                        print("Document Changed")
        
                return True
        

        Cheer,
        Maxime.

        MAXON SDK Specialist

        Development Blog, MAXON Registered Developer

        1 Reply Last reply Reply Quote 0
        • mocolocoM
          mocoloco
          last edited by

          Thanks a lot @m_adam for this detailed answer. I missed that post about the SceneHook method in C++ - as our main plugin is already in C++, maybe we can incorporate this SceneHook inside it instead of having a perpetual running timer checking for a scene change in Python.

          Are you aware if there some example somewhere in the SDK talking about this?

          Cheer,
          Christophe

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

            Hi there is no special documentation about SceneHook. It's like an object, but instead you register an SceneHookData with RegisterSceneHookPlugin.

            For more information about MSG_DOCUMENTINFO find an example in Notification on change of active document.

            Cheers,
            Maxime.

            MAXON SDK Specialist

            Development Blog, MAXON Registered Developer

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

              Hello @mocoloco,

              without further questions or replies, we will consider this topic as solved by Monday, the 30th and flag it accordingly.

              Thank you for your understanding,
              Ferdinand

              MAXON SDK Specialist
              developers.maxon.net

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