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

    Render to picture viewer from plugin crash

    Cinema 4D SDK
    windows python 2025
    2
    2
    447
    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.
    • P
      popandchop
      last edited by

      Hey guys,

      This is probably a very simple question and i suspect to do with threading. I have a little workflow tool i'm working on and have this Render to Picture Viewer button.

      0467208b-a101-445e-8472-3c2c8ccecbb0-image.png

      The code behind this button is as simple as this

      if id == BTN_SceneRenderPictureViewer:
                  
                  self.PrintStatusMessage('Rendering to Picture Viewer.')
                  self.Close()
                  c4d.StopAllThreads()
                  time.sleep(0.1)  # Wait a bit to ensure the dialog is closed before rendering
                  c4d.CallCommand(12099)
      

      However this causes Cinema to crash. I've tried recreating the Render to Picture viewer function but this was seems much simpler so would be great for it work - any help appreaciated 🙂

      Thanks alot,
      Will

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

        Hello @popandchop,

        Welcome to the Maxon developers forum and its community, it is great to have you with us!

        Getting Started

        Before creating your next postings, we would recommend making yourself accustomed with our forum and support procedures. You did not do anything wrong, we point all new users to these rules.

        • Forum Overview: Provides a broad overview of the fundamental structure and rules of this forum, such as the purpose of the different sub-forums or the fact that we will ban users who engage in hate speech or harassment.
        • Support Procedures: Provides a more in detail overview of how we provide technical support for APIs here. This topic will tell you how to ask good questions and limits of our technical support.
        • Forum Features: Provides an overview of the technical features of this forum, such as Markdown markup or file uploads.

        It is strongly recommended to read the first two topics carefully, especially the section Support Procedures: How to Ask Questions.

        About your First Question

        The question is impossible to answer in this form, we would need something concrete (a plugin and a scene which crashes for you) or a time stamp of a submitted crash report.

        What you do there is this code snippet looks a bit unusual. I assume from the screen shot that you are inside a GeDialog, the code looks a bit like this could be GeDialog.Command or Message. Please read the Threading Manual, invoking an event, e.g., a command, is forbidden off-main thread. But in a dialog you are usually on the main thread (but you should still check with c4d,.threading.GeIsMainThread()). What is also rather odd, is what you call there:

        if id == BTN_SceneRenderPictureViewer:
            self.Close()             # This will shut down the dialog, think of it as a return statement.
            c4d.StopAllThreads()     # This is generally the biggest nuke you can drop on Cinema 4D and should
                                     # be avoided. But in this context (a dialog that has been closed) this
                                     # seems extra dangerous. Why are you doing this?
            time.sleep(0.1)          # This makes things even worse, as it increases the chance that the dialog
                                     # has been destroyed before the last line of this function has been 
                                     # executed. If I had to guess, this is probably crashing here.
            c4d.CallCommand(12099)
        

        I assume you hve a modal dialog and that you run into issues with opening the picture viewer due to that? Either make your dialog non-modal (in GeDialog.Open) and then first send the command and then close the dialog or keep using a modal dialog and detach the code from the instance of the dialog.

        import c4d
        
        class MyModalDialog (c4d.gui.GeDialog):
        
            BTN_SceneRenderPictureViewer: int = 1000
        
            # ...
        
            def Command(self, cid: int, msg: c4d.BaseContainer) -> bool:
                if cid == MyModalDialog.BTN_SceneRenderPictureViewer:
                    MyModalDialog.CloseAndAction(self, 12099)
                return True
        
            @staticmethod
            def CloseAndAction(dlg: "MyModalDialog", cid: int) -> None:
                """Closes the passed dialog and executes a command.
        
                Args:
                    dlg (MyModalDialog): The dialog instance to close.
                    cid (int): The command ID to execute after closing the dialog.
                """
                if not dlg or not c4d.threading.GeIsMainThread():
                    return
                
                dlg.Close()
                c4d.CallCommand(cid)
        
        if __name__ == '__main__':
            dlg = MyModalDialog()
            dlg.Open(c4d.DLG_TYPE_MODAL, defaultw=400, defaulth=300, title="My Modal Dialog")
        

        Cheers,
        Ferdinand

        MAXON SDK Specialist
        developers.maxon.net

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