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

    Run a GUI Dialog AFTER C4D Launches not BEFORE?

    Cinema 4D SDK
    python 2023
    3
    7
    1.3k
    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.
    • B
      bentraje
      last edited by

      Hi,

      How do I run a dialog after C4D UI launches not before?

      Here is the code that I used:

      if __name__ == "__main__":
      
          if condition:
              c4d.gui.MessageDialog("BT Rendering Utilities. This beta version expired. Please download another on the website.")
      
          else:
              c4d.plugins.RegisterCommandPlugin(BASE_PLUGIN_ID, "_BT Rendering Utilities Pop Up",0, None, "_BT Rendering Utilities Pop Up", MyMenuPlugin())
      

      591dcb62-ffcb-494e-8790-a475e819313e-image.png

      H 1 Reply Last reply Reply Quote 0
      • H
        HerrMay @bentraje
        last edited by

        Hi @bentraje,

        Iā€˜m not sure but maybe checking for c4d. C4DPL_PROGRAM_STARTED in def PluginMessage(id, data) could be of any help here.

        Something like below.

        import c4d
        import sys
        
        def PluginMessage(id, data):
            if id == c4d.C4DPL_PROGRAM_STARTED:
                # Do your messaging here. 
                return True
        
            return False
        
        

        Cheers,
        Sebastian!

        1 Reply Last reply Reply Quote 1
        • B
          bentraje
          last edited by

          Hi @HerrMay

          Thanks for the response.
          Unfortunately, it doesn't work in my use case since that code requires the plug-in to be initialized first.

          I want to do the check first before any plug-in initialization.

          I did try to have a pseudo plug-in. The plug-in to initialize first before others. But the PluginMessage only gets called after all the plug-in is initialized.

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

            Hello @bentraje,

            Thank you for reaching out to us. The answer from @HerrMay is correct, you should use PluginMessage, it will convey the multiple stages of a Cinema 4D app life cycle to you, including stages where the plugins have not yet been registered.

            Be aware that in some stages, e.g., C4DPL_INIT_SYS, even system modules, e.g., c4d and maxon, might not have been fully initialized or are not fully functional. C4DPL_INIT is the earliest point where you are guaranteed to have full access to all modules.

            Using dummy plugins is not recommend due to plugins slots being limited to fifty for NodeData derived plugins and the general overhead a plugin does produce. Also remember that you can make use of the different execution contexts of a module, when it is initialized and the execution context is '__main__', i.e., when Cinema 4D wants to actually register the plugin.

            Cheers,
            Ferdinand

            MAXON SDK Specialist
            developers.maxon.net

            B 1 Reply Last reply Reply Quote 0
            • B
              bentraje @ferdinand
              last edited by

              @ferdinand

              Ah gotcha. There is no way around it as again I don't want to initialize the plug-ins at all until the UI + check works out.

              Anyway, having the the GUI dialog before C4D launches is not bad.
              I was just wondering if I can do it after without initializing all the plugins.

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

                Hello @bentraje,

                I might have been unclear here. You can have the dialog at a different point of time, but you are bound to what PluginMessage is able to convey. You can also do it like you and licensing_example_r21.py are doing it, and simply rely on the __main__ execution context, because when the file is being called with it, you are in the C4DPL_INIT stage. But you can also launch your dialog when for example

                • C4DPL_STARTACTIVITY is being emitted after all plugins have been loaded but before Cinema 4D is done loading. dd6478f2-140b-487d-aea2-c3fbcb024b6a-image.png
                • or when C4DPL_PROGRAM_STARTED is being emitted, and the app is "ready to go"
                  0af86ee9-ce51-4969-b714-a5c589f87f17-image.png

                You can also go earlier or later; I would recommend having a look at the plugin message IDs. And just in case you are planning to do some hot swapping, i.e., update an outdated plugin before Cinema 4D wants to load it, this can be quite complicated, and it is not supported by us.

                Find a simple example below.

                Cheers,
                Ferdinand

                import c4d
                import typing
                
                LICENSE_IS_VALID: bool = True
                
                def PluginMessage(mid: int, data: typing.Any) -> bool:
                    """Called by Cinema 4D to convey larger portions of the app state starting or ending.
                    """
                    if mid == c4d.C4DPL_PROGRAM_STARTED and not LICENSE_IS_VALID:
                        c4d.gui.MessageDialog("BT Rendering Utilities. This beta version expired. "
                                              "Please download another one from our website.")
                        return True
                        
                    return False
                
                def RegisterPlugin() -> bool:
                    """Checks the license of the plugin and registers it.
                
                    Could also be done inside the __main__ context guard, but I like putting it in a function :)
                    """
                    CheckLicense = lambda : False
                
                    # CHeck for a valid license and bail on registering when it is not given.
                    if not CheckLicense():
                        global LICENSE_IS_VALID
                        LICENSE_IS_VALID = False
                        return False
                    
                    # Do the registering ...
                    # return c4d.plugins.Register...
                    return True
                
                
                if __name__ == "__main__":
                    if not RegisterPlugin():
                        print ("Warning: Could not register ...")
                

                MAXON SDK Specialist
                developers.maxon.net

                1 Reply Last reply Reply Quote 1
                • B
                  bentraje
                  last edited by

                  @ferdinand

                  Thanks for the response.

                  With the illustration code you provided, I misunderstood the documentation. Thanks for the clarification.

                  Basically, I thought the

                  PluginMessage/RegisterPlugin functions should be method (i.e. they should be under the class of the plugin data, command data etc).

                  They actually live outside the classes.

                  It now works as expected.
                  Thanks! šŸ™‚

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