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

    Bundle fonts with Cinema 4D submissions

    Cinema 4D SDK
    python 2025 2024
    2
    7
    347
    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.
    • K
      karthikbp
      last edited by

      Dear community,

      I'm facing an issue with custom fonts when rendering on a render farm. Is there a way to bundle fonts with a scene so that Cinema 4D automatically uses these bundled fonts when rendering on a render farm?

      I have already reviewed the official documentation: https://support.maxon.net/hc/en-us/articles/1500006439721-Why-don-t-fonts-look-correct-on-machines-rendered-with-Team-Render-but-appear-correct-when-rendered-locally. However, making the text editable (as suggested in the article) is not an acceptable solution for our plugin users.

      Is the following approach possible through the Cinema 4D SDK?

      • Get the location of the fonts used in the scene (Could c4d.documents.GetAllAssetsNew() help with this?)
      • Bundle these fonts with the scene file
      • And then we could:
        • Get Cinema 4D to recognize and use the bundled font while rendering?
        • Or at least install the now bundled font on the render node and then uninstall the font once it's done rendering?

      Has anyone implemented a similar solution or can provide guidance on whether this approach is feasible?

      Thank you for your assistance.

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

        Hey @karthikbp,

        Thank you for reaching out to us. Here are sort of two questions layered into one.

        Could c4d.documents.GetAllAssetsNew() help with this?

        Yes, fonts are also recognized as assets (a relatively new feature). You need the flag ASSETDATA_FLAG_WITHFONTS to get them yielded as assets.

        How to export scenes with fonts as assets?

        This is effectively not SDK domain but an end-user question. But you are right, when I export my scene from above as 'Save Project with assets ...'. I end up with a folder that holds my scene but not the font.

        But for me this makes sense, as fonts are often deeply integrated into systems and not fully transferable between OS's. In my case, Cinema 4D would have to rip the Roboto Condensed font out of my /Windows/Fonts directory (where the actual Roboto Condensed.ttf is then buried in the Roboto font collection). On the other side, on a target system, Cinema 4D would have to install that font with OS appropriate system. That strikes me as asking for quite a bit to be automated.

        What you can do, is use GetAllAssetsNew to scan the scene for font data and then try to match that with system data, to either reject a scene (when there are missing fonts) or overwrite that parameter with a new font.

        Cheers,
        Ferdinand

        Output

        d6e854ab-2ffd-4580-967d-1ba6685f2a9b-image.png

        You need beta access and have to uncomment the mxutils.GetContainerTreeString calls to get this exact output. The general approach will work in all versions of Cinema 4D.

        Code

        """Scans the active document for font assets and prints their details, and tries to find a matching
        installed system font.
        """
        
        import c4d
        import mxutils
        
        doc: c4d.documents.BaseDocument  # The currently active document.
        op: c4d.BaseObject | None  # The primary selected object in `doc`. Can be `None`.
        
        def main() -> None:
            """Called by Cinema 4D when the script is being executed.
            """
            assets: list[dict[str, any]]=[]
            c4d.documents.GetAllAssetsNew(doc, False, "", c4d.ASSETDATA_FLAG_WITHFONTS, assets)
        
            for asset in assets:
                pid: int = asset.get("paramId", c4d.NOTOK)
                owner: c4d.BaseList2D | None = asset.get("owner", None)
                if pid == c4d.NOTOK or owner is None:
                    continue
                
                # There is no super good way to check if an asset is a font asset, so we check the type of 
                # the parameter value. If it is a FontData, we assume it is a font asset.
                value: any = owner.GetParameter(pid, c4d.DESCFLAGS_GET_NONE)
                if not isinstance(value, c4d.FontData):
                    continue
                
                name: str = asset.get("assetname", "")
                font: c4d.BaseContainer = value.GetFont()
                print(f"Font asset: {name} (ID: {pid})")
        
                # mxutils.GetContainerTreeString is a beta feature not available in 2025.3.1 or lower. When
                # you have beta access, you can uncomment the next line to print the font container.
        
                # print(f"Font data found in scene:\n{mxutils.GetContainerTreeString(font)}")
                
                # There is quite a bit of hand-wavy stuff going on here. I figured out the font data 
                # container ID 508 by using the 2026.0.0 feature mxutils.GetContainerTreeString. There seem
                # to be no symbols for these IDs, at least I couldn't find any. 508 is where the container
                # stores the PostScript name of the font, e.g. "ArialMT-Regular".
        
                # Try to get a system font with the PostScript name of the font asset. When we find a match,
                # it means the font is installed on the system.
                bc: c4d.BaseContainer | None = c4d.bitmaps.GeClipMap.GetFontDescription(
                    font[508], c4d.GE_FONT_NAME_POSTSCRIPT)
                if not bc:
                    print(f"{font[508]} is not a system font.")
                    continue
                
                # print(f"Matched with system data:\n{mxutils.GetContainerTreeString(bc)}")
        
        if __name__ == '__main__':
            main()
        

        MAXON SDK Specialist
        developers.maxon.net

        1 Reply Last reply Reply Quote 0
        • K
          karthikbp
          last edited by

          Hi @ferdinand,

          Thanks so much for your responses and sharing the code above. I really appreciate it! But our plugin users still want to have completed renders.

          Which leads me to wonder if we can convert all the text objects into editable before submission through code? I was thinking of something like this:

          • check if there is a custom font in the scene (this should be possible with the code that you just shared)
          • find all the text objects in the scene
          • convert it to the editable state just before submitting to the render farm (similar to what happens when we select the Text and press 'C')

          Is this approach feasible? Are there downsides for it, would animations stop working with this approach when the object turns into several different objects?

          The article mentioned that if we need to keep the text objects "procedural" we need to install the fonts.

          What does "procedural" mean in this context?

          Thanks again

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

            Hey @karthikbp,

            Which leads me to wonder if we can convert all the text objects into editable before submission through code [...]

            In general, I would say that this is not a feasible route. First, collapsing ('current state to object' in Cinema slang) things destroys animations. I.e., if a Text Object had an animated height, you would lose that data. And secondly collapsing things can also mess with your scene structure as text objects and splines can be influenced on a by character basis by fields, effectors, and materials.

            The article mentioned that if we need to keep the text objects "procedural" we need to install the fonts.

            I am sorry, I cannot read and answer end user articles. As I said, this is an end user question not an API question. Please contact end user support about their material. My hunch would be that they just misspoke here, were a bit informal, and meant that when you want to keep the objects as generators (the proper term for procedural geometry in Cinema 4D), you must install the font for the scene to work.

            An alternative route could be to bring up this subject in our beta community (I assume you already have access). This is an end user subject, and how to handle this or if we plan on adding features there, would have to be solved by customer support or our beta community.

            Cheers,
            Ferdinand

            MAXON SDK Specialist
            developers.maxon.net

            1 Reply Last reply Reply Quote 0
            • K
              karthikbp
              last edited by

              Hi @ferdinand ,

              Thanks for your support so far. I should be able to go forward from here.

              I do have a question though. Is there a reason why the flag "ASSETDATA_FLAG_WITHFONTS" does not appear in the docs? https://developers.maxon.net/docs/py/2025_3_1/modules/c4d.documents/index.html#c4d.documents.GetAllAssetsNew

              The users of our plugin generally have Cinema 4D 2024 and 2025 installed. Will there be any issues using this flag? I tried running the script that you shared above on 2024 and that seemed to work as well so I assume there are no issues on that front.

              Thanks,
              Karthik

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

                Hey @karthikbp,

                that is because other than in C++, the documentation of some symbols is not automated in Python (the definition is). So, we simply forgot to update the doc file for this flag when it was introduced. I already fixed that when I wrote the answer above, in the next doc update it will be included.

                And as I said, the symbol is a 2024.0.0 feature, you can always check the C++ docs to confirm something like this. So, in 2023.2 and lower, neither the flag nor the feature will exist. To use this flag client sided, you would have to check the Cinema 4D version the user is running.

                ⚠ Work on the Project Asset Inspector (PAI) spanned over a good part of 2024. I do not think that we would add symbols without them being functional. But to be sure, I would grab a 2024.0.0 release and check if it does what you expect it to do, when using that symbol.


                While I understand the direction you are coming from, I still think you are heading a bit in the wrong direction. And I understand that you want and have to solve that problem, but the angle you are taking is in my opinion not the right one.

                When I wrote my first answer here, my first reaction was like yours - 'why is this not working?'. But then I realized the technical complexity of grabbing a font from one system and providing it - possibly over OS boundaries - on another system. I also briefly talked with one of the PAI developers and one concern they also seem to have is copyright issues (as fonts are often licensed). But there is a complex discussion to be had if we still plan to add features there and what the recommended workflows are right now. You can only answer these with end user support and the beta community.

                I personally would just go the route I hinted at above. Just scan the scene for missing fonts and then emit a warning. You could then give the user the option to use a replacement font, upload a font, or to discretize the font object (at the risk of losing animation, mograph, or simulation data). When you absolutely have to work client sided, you would either have to limit the feature to 2024+ clients or write something yourself which abstractly searches for such scene elements (note that the mxutils scene traversal tools are a 2025.0.0 feature, so you cannot use them too - but you could use something inspired by their code). You then would have to provide a hardcoded list of fonts supported by your server/render node. The middle ground would be something more complex where you evaluate client sided, and then ask the server if 'these' fonts are supported.

                Cheers,
                Ferdinand

                MAXON SDK Specialist
                developers.maxon.net

                1 Reply Last reply Reply Quote 0
                • K
                  karthikbp
                  last edited by

                  Hey @ferdinand ,

                  Sorry for the late replies.

                  You can only answer these with end user support and the beta community.

                  I will do that. Although I haven't used the beta community yet, I'll post the same question there to better understand what the recommended workflows are right now.

                  you would either have to limit the feature to 2024+ clients

                  That's good enough for us. Our plugin officially supports only the latest versions of 2024 and 2025.

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