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 understand symbols of some spcial case ?

    Cinema 4D SDK
    2023 python windows
    2
    5
    443
    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.
    • DunhouD
      Dunhou
      last edited by

      Hello everyone,

      Question

      I get some strange words from sdk and never found what they means, how can I get some info more spcificly?

      e.g. I try to check rendering states of my batch render ,when batch render come with a error then , alert me rather than waste all night time, some I think I can get a state list of render queue, when error happens , take an alert and never warning this element this time . but when I test the state , it seems RM_ERROR2 is the only one , I delete some texture to test a warning document , RM_ERROR still not worked , How can I get this symbols meaning ?

      This problem also heppened when some undo or some symbols have a number ending

      17091cc1-2e2b-488f-82fa-6a9eaa9aaf9c-image.png

      by the way , I think GetEnableElement document is wrong ?

      Cheers

      https://boghma.com
      https://github.com/DunHouGo

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

        Hello @dunhou,

        Thank you for reaching out to us. I am not fully sure if I understand you correctly here. I wrote a small example script (see end of posting), and BatchRender.GetElementStatus does what I would expect it to do.

        The problem here is the sparsely documented nature of RM_ERROR and RM_ERROR_2. Both statuses are of semi-private nature and are not really meant to convey anything else than that 'something' has gone wrong with a rendering. Internally, it is RM_ERROR which conveys most of the 'interesting' error cases.

        case RM_ERROR2:
          switch (error)
          {
            case RM_ERR_OUTPUT: ...
            case RM_ERR_OUTPUTMULTI: ...
            case RM_ERR_TEXFAIL: ...
            default: ...
          }
        case RM_ERROR:
        {
          switch (error)
          {
            case (Int32)RENDERRESULT::OUTOFMEMORY: ...
            case (Int32)RENDERRESULT::ASSETMISSING: ...
            case (Int32)RENDERRESULT::SAVINGFAILED: ...
            case (Int32)RENDERRESULT::GICACHEMISSING: ...
            case (Int32)RENDERRESULT::NOMACHINE: ...
            case RM_ERR_DEL: ...
            case (Int32)RENDERRESULT::ERRORLOADINGPROJECT: ...
            case (Int32)RENDERRESULT::USERBREAK: ...
            default: ...
          }
        }
        

        But in the front-end, they are then lumped together, with both errors then having their combined meaning.

        It is also important that not all statuses are conveyed in all contexts. The statues are meant to feed the render queue manager. So, when there is a problem with a job it will convey that before the queue is running. But once a job is queued in a running queue, it will not convey anymore missing textures, because in the logic of the render queue, it is now either "too late for that" or "intended by the user". So, when one wants to detect a problem with a job, one must also do that before running a queue. It might also be worth having a look at BatchRender.GetJsonJobs in addition to BatchRender.GetElementStatus, because the JSON data is more granular.

        I agree that the short description for BatchRender.GetEnableElement is misleading a probably was copied from .EnableElement I will fix that in an upcoming release. Having a quick look at the C++ documentation, it also seems like the C++ and Python docs are not aligned.

        Cheers,
        Ferdinand

        Result:

        Before rendering:
        ----------------------------------------------------------------------------------------------------
        Render job 0 (C:\Users\f_hoppe\Desktop\missing_texture.c4d) has the status: RM_ERROR2.
        ----------------------------------------------------------------------------------------------------
        [{'added_to_queue': '01/03/2023, 13:47:14',
          'estimated_time': '',
          'filename': 'missing_texture.c4d',
          'frame': '00:00:00 ',
          'frames': [],
          'id': '0',
          'image': 'missing_texture.c4d',
          'image_path': 'missing_texture_rendering',
          'last_frame': '00:00:00 ',
          'log': '',
          'message': 'Error - Missing Files',
          'outputheight': '720',
          'outputwidth': '1280',
          'progress': '0',
          'render_started_on': '-',
          'render_time': '00:00:00 ',
          'status': 'Error',
          'total_frames': '1',
          'uuid': '19140F93-1025-4836-BDA0-8279BEB58999'}]
        
        While rendering:
        ----------------------------------------------------------------------------------------------------
        Render job 0 (C:\Users\f_hoppe\Desktop\missing_texture.c4d) has the status: RM_PROGRESS.
        ----------------------------------------------------------------------------------------------------
        [{'added_to_queue': '01/03/2023, 13:47:14',
          'estimated_time': '00:00:00 ',
          'filename': 'missing_texture.c4d',
          'frame': '00:00:00 ',
          'frames': [],
          'id': '0',
          'image': 'missing_texture.c4d',
          'image_path': 'missing_texture_rendering',
          'last_frame': '00:00:00 ',
          'log': '---File Information---\r\n'
                 'File Name : missing_texture.c4d\r\n'
                 'File Path : C:\\Users\\f_hoppe\\Desktop\r\n'
                 '---Render Data---\r\n'
                 'Render Settings : My Render Setting\r\n'
                 'Take : Main\r\n'
                 'Camera : Default Camera\r\n'
                 'Width : 1280\r\n'
                 'Height : 720\r\n'
                 'Film Aspect : 1.778\r\n'
                 'Pixel Aspect : 1\r\n'
                 'FPS : 30\r\n'
                 'From : 0\r\n'
                 'To : 0\r\n'
                 'Step : 1\r\n'
                 '---Save Information---\r\n'
                 'Path : \r\n'
                 'Depth : 8\r\n'
                 'Format : PNG\r\n'
                 '---Render Information---\r\n',
          'message': '',
          'outputheight': '720',
          'outputwidth': '1280',
          'progress': '0',
          'render_started_on': '01/03/2023, 13:47:15',
          'render_time': '00:00:00 ',
          'status': 'In Progress',
          'total_frames': '1',
          'uuid': '19140F93-1025-4836-BDA0-8279BEB58999'}]
        

        Code:

        """Demonstrates the different contexts and methods to retrieve render queue job item information with.
        
        Must be run as a Script Manager script. Should be run on a scene which is missing assets, e.g., a 
        texture to have a meaningful output.
        """
        
        import c4d
        import os
        import pprint
        
        """Translates render queue error symbols to their symbol string.
        """
        RM_STATUS_SYMBOLS: dict[int, str] = {
            c4d.RM_PROGRESS: "RM_PROGRESS",
            c4d.RM_FINISHED: "RM_FINISHED",
            c4d.RM_STOPPED: "RM_STOPPED",
            c4d.RM_ERROR: "RM_ERROR",
            c4d.RM_ERROR2: "RM_ERROR2",
            c4d.RM_PAUSED: "RM_PAUSED",
            c4d.RM_QUEUE: "RM_QUEUE",
            c4d.RM_NONE: "RM_NONE",
        }
        
        doc: c4d.documents.BaseDocument # The active document.
        
        def GetBatchRenderJobStatusesString(batchRender: c4d.documents.BatchRender) -> str:
            """Returns a pretty formatted string for all currently enqueued batch render jobs.
        
            This will include disabled jobs.
            """
            result: list[str] = []
            for index in range(batchRender.GetElementCount()):
                result.append(f"Render job {index} ({batchRender.GetElement(index)}) has the status: "
                              f"{RM_STATUS_SYMBOLS[batchRender.GetElementStatus(index)]}.")
        
            return "\n".join(result)
        
        
        def main() -> None:
            """Runs the example.
            """
            # Get the document path and the batch renderer.
            path: str = os.path.join(doc.GetDocumentPath(), doc.GetDocumentName())
            if not os.path.exists(path):
                c4d.gui.MessageDialog("Please save the document first.")
                return
        
            batchRender: c4d.documents.BatchRender = c4d.documents.GetBatchRender()
            if batchRender.IsRendering():
                c4d.gui.MessageDialog("Batch renderer is already rendering.")
                return
        
            # Put the new job in front of the queue.
            batchRender.AddFile(path, 0)
        
            # When #doc contains an #RENDERRESULT::ASSETMISSING error, it will bubble up as an #RM_ERROR here.
            print ("Before rendering:")
            print("-" * 100)
            print(GetBatchRenderJobStatusesString(batchRender))
            print("-" * 100)
            pprint.pprint(batchRender.GetJsonJobs())
        
            # Start the rendering.
            batchRender.SetRendering(c4d.BR_START)
        
            # But it will not here since in the logic of the render queue, it is "too late" to worry about
            # that once the rendering is running.
            print ("\nWhile rendering:")
            print("-" * 100)
            print(GetBatchRenderJobStatusesString(batchRender))
            print("-" * 100)
            pprint.pprint(batchRender.GetJsonJobs())
        
            
        if __name__ == '__main__':
            main()
        

        MAXON SDK Specialist
        developers.maxon.net

        DunhouD 1 Reply Last reply Reply Quote 0
        • DunhouD
          Dunhou @ferdinand
          last edited by

          @ferdinand Thanks for that!

          I think BatchRender.GetJsonJobs do a great job but a little pitty that the velue of the json is not use an "int" , so when I want to support Chinese users , it returns 'status': '在队列&#x4e2d like this , so I think it a little bit limitation for not a native English users.

          And the RM_ERROR and RM_ERROR2 code shows most I want , I belive a lot of symbols has teh same XXXX and XXXX2 situation,but most document didn't have any infomations .

          And a little questions with "Batch Render" but not the symbol, I don't sure should I post in another topic:

          When I use IsRendering to spy the render queue ,if A and B is switch rendering status ( aka , A is finishing , and B is just starting ).this few time would break the while and return a bad value not I want. How can I fix this?

          batchRender: BatchRender = c4d.documents.GetBatchRender()
          while batchRender.IsRendering():
              c4d.StatusSetText(f"Rendering....")    
              time.sleep(5)
          

          Cheers~

          https://boghma.com
          https://github.com/DunHouGo

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

            Hello @dunhou,

            it returns 'status': 在队列&#x4e2d like this , so I think it a little bit limitation for not a native English users.

            status is the HTML-encoded Unicode string for the characters '在队列中'. &# is how Unicode is encoded in HTML, and xNNNN is the Unicode and ; is the delimiter. You can either decode them manually using str and bytes or just use the handy html.unescape.

            import html
            
            status: str = "在队列&#x4e2d"
            print (html.unescape(status))
            

            82cbd235-fbc9-473c-8368-94e5aa3711ae-image.png

            And the RM_ERROR and RM_ERROR2 code shows most I want , I belive a lot of symbols has teh same XXXX and XXXX2 situation,but most document didn't have any infomations.

            Yes, we are aware. We fix them when we are pushed onto errors, but cannot just fix them all at once. You must understand that Cinema 4D has code which is up to two decades old, so documentation can get out of whack over time.

            When I use IsRendering to spy the render queue ,if A and B is switch rendering status ( aka , A is finishing , and B is just starting ).this few time would break the while and return a bad value not I want. How can I fix this?

            I assume you are talking here about the case that you have a render queue with two jobs A and B. And it seems to be the case that there is a brief moment when A has already finished B has not yet started, where batchRender.IsRendering() returns False, although there is still an upcoming rendering.

            Your solution with time.sleep seems sort of fine, but error prone for cases where initializing the new rendering takes more than five seconds. I would simply write something which checks if there are still pending jobs (c4d.RM_QUEUE) in the queue in addition to checking if the batch renderer is actively rendering.

            Cheers,
            Ferdinand

            MAXON SDK Specialist
            developers.maxon.net

            DunhouD 1 Reply Last reply Reply Quote 0
            • DunhouD
              Dunhou @ferdinand
              last edited by

              @ferdinand Thanks for your help.

              I did search on web and find the Unicode string, and Chinese characters is so much complicated ,when most user use Chinese for the GUI language, Maybe sometime the translation of the world "在队列中" witch means "in the queue" in English has changed ( I belive now Chinese translation is response to IHDT so it won't randomly changed). That is not a big problem but maybe a little "uniform" with the "ID"😊

              And the "brief moment" is I don't sure why does it happend. In another word ,I think the initializing render process can be also called "rendering" . so it is a bit of counterintuitive for me , maybe I should add an additional check to make sure the spying will not break while the brief.

              Cheers~

              https://boghma.com
              https://github.com/DunHouGo

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