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
    • Register
    • Login

    Open source wrapper for Octane/Redshift/Arnold/Vray/Corona in Cinema 4D.

    General Talk
    programming learning-resource
    7
    23
    16.9k
    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 Dunhou

      Hi community!

      Older version called renderEngine had been move to versions folder, if you are still interested.
      

      Renderer is a wrapper class for the maxon and c4d api of popular render engine for Cinema 4D.

      Intended for more user-friendly manipulation of node materials with the new maxon.GraphNode model. And also with Octane Material.

      Provide helper class for convenient access AOV , Material , Scene Object(Object/Tag/Light/...) in Cinema 4D popular renderer.

      I try to keep it as same as possible, but each renderer has their own logic, so there are some compromises.

      Happy Rendering and Scpriting!😊

      Cheers~
      DunHou


      Renderer

      This is a custom wrapper for most popular render engine like Octane\Redshift\Arnold\Corona\VRay in Cinema 4D, which is also contains in boghma library.

      All the boghma plugins and boghma library is FREE.
      

      Supported Renderer

      • Octane
      • Corona
      • Node Materials with the new GraphNode model
      • Redshift ( Only Node Material for Material Helper)
      • Arnold ( Only Node Material for Material Helper)
      • Vray ( Only Node Material for Material Helper)

      Installation

      1. (Recommend) Download Boghma Plugin Manager and install any plugin, the boghma lib will auto installed or updated.
      2. Download the source code and import it to your Cinema 4D.

      Quick Intro

      
      import c4d
      import maxon
      from Renderer import Redshift, EasyTransaction, TextureHelper
      from pprint import pprint
      
      # Create a TextureHelper instance
      # 创建一个 TextureHelper 实例
      tex_helper: TextureHelper = TextureHelper()
      
      # Get the url with given asset id
      # 获取给定资产ID的URL
      # "si-v1_fingerprints_02_15cm.png" with AssetId : file_fa9c42774dd05049
      disp: maxon.Url = tex_helper.GetAssetUrl("file_fa9c42774dd05049")
      
      def HowToUse():
          """
          How to reate a redshift material and modify the gragh with EasyTransaction.
          """
      
          # Create Redshift Node Material instance, if no material filled, we create a new STD material
          # 创建一个Redshift节点材质实例,如果没有材质传入,创建新的STD材质
          material: c4d.BaseMaterial = Redshift.Material("MyMaterial")
      
          # Use EasyTransaction to modify the graph
          # 使用EasyTransaction来修改材质
          with EasyTransaction(material) as tr:
          
              # the attribute #tr is the instance of Redshift.MaterialHelper, 
              # we got it with just apply to the #material to the EasyTransaction
              # it will inherit from NodeGraghHelper class
              # 属性tr是Redshift.MaterialHelper的实例,通过将材质赋予EasyTransaction获得,继承自NodeGraghHelper
      
              # Use Redshift.MaterialHelper methods : add a texture + displacement to the Output node
              # 使用Redshift.MaterialHelper中的方法: 添加图片+置换节点到Output节点
              tr.AddDisplacementTree(filepath = disp, shadername = "DISP")
      
              # Use NodeGraghHelper methods: get the Output(endNode)
              # 使用NodeGraghHelper中的方法: 获取输出节点
              output = tr.GetOutput()
              print(f"{output = }")
      
              # Insert the material to the document
              # 导入材质(来自Redshift MaterialHelper)
              tr.InsertMaterial()
      
          # Auto apply GraphTransaction.Commit() to the graph
          # 退出with后, 自动执行GraphTransaction.Commit()
      
      

      Limit

      • For some reasons, AddShader-like methods(maxon.GraphModelInterface.AddChild) will add the node in the center of the graph, if we call those methods on exsited material, it will return a mess graph, you can call Renderer.ArrangeAll() after.
      • Material(except Octane) helper only support material with the new GraphNode model(Node Material after R26)
      • Due to Octane use his Custom UserArea UI base on old layer system, and didn't support python, we can only modify Octane materials in material level, but can not interactive with selections in octane node editor.
      • Also Octane materials didn't have a "port" or "wire" context, we can not use all those methods as same as NodeGraghHelper.
      • Arnold mask tag SetPrameter has a refresh bug.

      Examples

      • Material Example
      • AOV Example
      • Scene Example

      Class Presentation and Highlights

      Renderer

      • NodeGraghHelper
      • TextureHelper
      • EasyTransaction
      • Redshift
        • AOV
        • Material
        • Scene
      • Octane
        • AOV
        • Material
        • Scene
      • Arnold
        • AOV
        • Material
        • Scene
      • Vray
        • AOV
        • Material
      • Corona
        • AOV
        • Material
      • utils
        • NodeGraghHelper
        • TextureHelper
        • EasyTransaction
      • constants

      Version & Updates

      • Change Log

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

      ferdinandF 1 Reply Last reply Reply Quote 8
      • ferdinandF ferdinand pinned this topic on
      • ferdinandF
        ferdinand @Dunhou
        last edited by

        Hey @Dunhou,

        This looks AWESOME! Thank you so much for all the awesome stuff you create!

        I have pinned this topic, so that it remains visible.

        Cheers,
        Ferdinand

        MAXON SDK Specialist
        developers.maxon.net

        DunhouD 1 Reply Last reply Reply Quote 0
        • T
          thomas
          last edited by

          this looks amazing. Can't wait to see arnold / RS

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

            Hey @ferdinand , that's very honor to contribute to the community, and also thanks for your pin, that inspire me a lot too.

            And a little plan I want to take your advice, what do you think the next update I should post, should I edit the first post, or just update the links when redshift/arnold is ready, and reply to the topic to show the main changes? which is better for more read convinence?

            Cheers~
            DunHou

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

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

              Hey @thomas , thanks for your like, redshift_helper is 80% for beta I think, I will try to post ASAP.

              Cheers~
              DunHou

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

              1 Reply Last reply Reply Quote 1
              • DunhouD
                Dunhou
                last edited by

                Hi community!

                the renderEngine helper is beta now, I set version number to 1.0.0, it contains three renderer now:

                • Octane
                • Arnold ( MaterialHelper only support NodeGragh )
                • Redshift ( MaterialHelper only support NodeGragh )

                I personally not use Vray and Corona quite often, if anyone is a pro user of these , very welcome to add them to renderEngine

                You can modify the aovs/materials with renderEngine quickly and easliy . See the examples above this topic.

                Hope you can have fun with it, and any improvement and fix is very appreciated.

                Cheers~
                DunHou

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

                1 Reply Last reply Reply Quote 2
                • T
                  thomas
                  last edited by

                  @Dunhou is it possible to get in touch for you for freelance development? I couldn't find any email or socials.

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

                    @thomas Hi, I had update my github readme file, and put my email on it😊

                    Cheers~
                    DunHou

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

                    1 Reply Last reply Reply Quote 0
                    • DunhouD Dunhou referenced this topic on
                    • DunhouD
                      Dunhou
                      last edited by

                      Hi community!

                      Th renderEngine library has been updated to the 1.0.4 version, there are some re-write functions and may not incompatible with older versions,see the main changes as follows:

                      • rename all node & material functions to Capitalize style.
                      • remove transaction in node_helper, use it in the final scripts.
                      • organize the functions in node_helper with comments ( node\port\wire\util )
                      • add some functions to check node or port info, like if it is connected , see the README.
                      • add a InserShader function to create a shader into a wire.
                      • re-write RemoveConnection in node_helper and support one argument(port) to remove connection.
                      • see the Version & Updates

                      Cheers~
                      DunHou

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

                      1 Reply Last reply Reply Quote 2
                      • DunhouD Dunhou referenced this topic on
                      • DunhouD Dunhou referenced this topic on
                      • DunhouD
                        Dunhou
                        last edited by

                        Hi community!

                        Since my last post, I had some updates and fix to this library.

                        And the following picture shows the new node functions added to my Render Flow plugin based on the use of this library within few lines( just the node context ).

                        Have fun with it.

                        Cheers~
                        DunHou

                        all.gif

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

                        gheyretG 1 Reply Last reply Reply Quote 3
                        • gheyretG
                          gheyret @Dunhou
                          last edited by

                          @Dunhou
                          It's realy cool and usefull, keep going bro 🍻

                          www.boghma.com

                          1 Reply Last reply Reply Quote 1
                          • M
                            mogh
                            last edited by

                            Wow ... good stuff
                            My c4d Programing slowed down this year, but this might be something I want to use some day ...

                            1 Reply Last reply Reply Quote 1
                            • czt_306C
                              czt_306
                              last edited by

                              amazing!

                              DunhouD 1 Reply Last reply Reply Quote 0
                              • DunhouD Dunhou referenced this topic on
                              • DunhouD
                                Dunhou @czt_306
                                last edited by Dunhou

                                Hi community!

                                New versions here!

                                I had change the name from renderEngine to Renderer, and also changed the main structure. see more in the very first of this topic. (renderEngine had been move to versions folder, if you still interested.)

                                This version is way more organized and user-friendly, you can use few lines of code to do something normal work, find an example below:

                                Cheers~
                                DunHou


                                Result:

                                e7eb47f4-f118-45d7-9101-bb610a25921b-image.png

                                Code:

                                import c4d
                                import maxon
                                from Renderer import Redshift, EasyTransaction, TextureHelper
                                
                                tex_helper: TextureHelper = TextureHelper()
                                disp: maxon.Url = tex_helper.GetAssetUrl("file_fa9c42774dd05049")
                                
                                def HowToUse():
                                
                                    material: c4d.BaseMaterial = Redshift.Material("MyMaterial")
                                
                                    with EasyTransaction(material) as tr:
                                
                                        tr.AddDisplacementTree(filepath = disp, shadername = "DISP")
                                
                                        tr.InsertMaterial()
                                
                                if __name__ == '__main__':
                                    HowToUse()
                                

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

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

                                  Hi community!

                                  Here is a little example of how we modify aovs in Octane, find more examples in the top.

                                  Have fun with it😊

                                  Cheers~
                                  DunHou

                                  Result:

                                  a25ad801-72c0-4e10-9572-e4e20541d0e3-image.png

                                  Codes:

                                  import c4d
                                  import maxon
                                  import Renderer
                                  from Renderer import Octane
                                  from pprint import pprint
                                  
                                  # How to create and modify octane aovs
                                  def modify_octane_aov():
                                  
                                      # Get the doc host the aovs, in this case th active doc
                                      doc: c4d.documents.BaseDocument = c4d.documents.GetActiveDocument()
                                      # Set Octane AOVHelper instance
                                      aov_helper = Octane.AOV(doc)
                                      
                                      # Create a Octane aov item
                                      # the id can find from Renderer.constants.octane_id.py or in octane folder
                                      # If #name is None, defulat to type.
                                      diff_aov = aov_helper.create_aov_shader(aov_type = Octane.RNDAOV_DIFFUSE)
                                  
                                      # Add the DIFFUSE aov we just created to the Octane aov system
                                      aov_helper.add_aov(diff_aov)
                                      
                                      # Add some aovs
                                      aov_helper.add_aov(aov_helper.create_aov_shader(aov_type = Octane.RNDAOV_POST,aov_name = 'POST'))
                                      aov_helper.add_aov(aov_helper.create_aov_shader(Octane.RNDAOV_DIF_D))
                                      aov_helper.add_aov(aov_helper.create_aov_shader(Octane.RNDAOV_DIF_I))
                                      aov_helper.add_aov(aov_helper.create_aov_shader(Octane.RNDAOV_REFL_D))
                                      aov_helper.add_aov(aov_helper.create_aov_shader(Octane.RNDAOV_REFL_I))
                                      aov_helper.add_aov(aov_helper.create_aov_shader(Octane.RNDAOV_WIRE))
                                      aov_helper.add_aov(aov_helper.create_aov_shader(Octane.RNDAOV_OBJECT_LAYER_COLOR))
                                      aov_helper.add_aov(aov_helper.create_aov_shader(Octane.RNDAOV_VOLUME))
                                      
                                      # Remove last aov: volume
                                      aov_helper.remove_last_aov()
                                      
                                      # Remove specified aov: wire
                                      aov_helper.remove_aov_type(aov_type = Octane.RNDAOV_WIRE)
                                      
                                      # Add 2 custom aovs with id 1 and 2
                                      aov_helper.add_custom_aov(customID = 1)
                                      aov_helper.add_custom_aov(customID = 2)
                                      
                                      # Get the custom aov with id 2
                                      custom2 = aov_helper.get_custom_aov(customID = 2)
                                      if custom2:
                                          print(f'We find a Custom AOV with id 2 Named{custom2.GetName()}')
                                          
                                      # Print current aov info
                                      aov_helper.print_aov()
                                  
                                  
                                  if __name__ == '__main__':
                                      Renderer.ClearConsole()
                                      modify_octane_aov()
                                  

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

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

                                    Hi community!

                                    Here is a little example of how we modify scene objects in Arnold, find more examples in the top.

                                    We want:

                                    • Add a Arnold Sky with hdr
                                    • Add a gobo light with a node-base gobo material, and a IES light
                                    • Add a cube and add a custom mask to the driver
                                    • Add a Scatter with custom instance shapes
                                    • Auto export proxy with a BaseObject and load back the ass file (need to save project first)

                                    Have fun with it😊

                                    Cheers~
                                    DunHou

                                    Results:

                                    63288895-1f52-49f3-8a3e-5a691c394d8f-image.png
                                    8cfd5b22-0bbe-42f5-b949-86aa3d19591a-image.png

                                    Codes:

                                    import c4d
                                    import maxon
                                    import Renderer
                                    from Renderer import Arnold, TextureHelper
                                    from pprint import pprint
                                    
                                    # Create a TextureHelper instance
                                    tex_helper: TextureHelper = TextureHelper()
                                    
                                    # How to create and modify arnold scene
                                    def modify_arnold_scene():
                                    
                                        # Get the doc host the scene, in this case th active doc
                                        doc: c4d.documents.BaseDocument = c4d.documents.GetActiveDocument()
                                        # Set arnold SceneHelper instance
                                        scene_helper = Arnold.Scene(doc)
                                        
                                        ### == Light == ###
                                        # Add a rig of hdr and rgb backdrop
                                        hdr_url: str =  tex_helper.GetAssetStr(maxon.Id("file_d21cf4cfdec8c636"))
                                        scene_helper.add_dome_rig(texture_path = hdr_url, rgb = c4d.Vector(0,0,0))
                                        
                                        # Add a light object and and some modify tags
                                        gobo_url: maxon.Url = tex_helper.GetAssetUrl("file_66b116a34a150e7e")
                                        gobo_light = scene_helper.add_gobo(texture_path = str(gobo_url), intensity=2, exposure=0)
                                        scene_helper.add_light_modifier(light = gobo_light, gsg_link = True, rand_color = True)
                                        
                                        # Add a IES light
                                        ies_url: str = tex_helper.GetAssetStr("file_6f300f2ba077da4a")
                                        ies = scene_helper.add_ies(texture_path = ies_url, intensity=1, exposure=0)
                                        
                                        ### == Tag == ###
                                        # Add a Cude object and an arnold tag with mask_name
                                        cube = c4d.BaseObject(c4d.Ocube)
                                        scene_helper.add_mask_tag(node=cube, mask_name='My Mask 01')
                                        doc.InsertObject(cube)
                                            
                                        ### == Object == ###
                                        # Add a scatter obejct with some children and count 12345
                                        generate_object = c4d.BaseObject(c4d.Oplane)
                                        doc.InsertObject(generate_object)
                                        scatter_A = c4d.BaseObject(c4d.Oplatonic)
                                        scatter_B = c4d.BaseObject(c4d.Ooiltank)
                                        doc.InsertObject(scatter_A)
                                        doc.InsertObject(scatter_B)
                                        scatters: list[c4d.BaseObject] = [scatter_A, scatter_B]
                                        scene_helper.add_scatter(generator_node=generate_object, scatter_nodes=scatters, count=12345)
                                        
                                        # Add a object and set auto proxy
                                        the_object = c4d.BaseObject(c4d.Oplane)
                                        doc.InsertObject(the_object)
                                        the_object.SetName("Original Object")
                                        scene_helper.auto_proxy(nodes=the_object,remove_objects=False)
                                    
                                    if __name__ == '__main__':
                                        Renderer.ClearConsole()
                                        modify_arnold_scene()
                                        c4d.EventAdd()
                                    

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

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

                                      Hi community!

                                      Another little update, as we didn't have DataDescriptionDatabaseInterface as @ferdinand said in How can we get the default port of a GraphNode?

                                      I add a ConverterPorts to Renderer, we can use this to get the "default " port of a node until the DataDescriptionDatabaseInterface is valid in python.

                                      Note: It can only provide the str data of the port and it's not 100% rigorous

                                      Cheers~
                                      DunHou


                                      Result:

                                      ef6aaffd-aa4f-4def-9b4e-e626bda37c51-image.png

                                      Codes:

                                      import c4d
                                      from Renderer import Redshift,EasyTransaction,ClearConsole
                                      
                                      def ConvertTest():
                                      
                                          material: c4d.BaseMaterial = c4d.documents.GetActiveDocument().GetActiveMaterial()
                                      
                                          with EasyTransaction(material) as tr: 
                                      
                                              nodes = tr.GetActiveNodes()
                                              
                                              for node in nodes:
                                                  print(f"Node: {tr.GetName(node)}")
                                                  print(f"Default Input: {tr.GetConvertInput(node)}")
                                                  print(f"Default Output: {tr.GetConvertOutput(node)}")
                                                  print("-"*10)
                                              
                                      if __name__ == '__main__':
                                          ClearConsole()
                                          ConvertTest()
                                      

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

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

                                        Hi community!

                                        I had add a basic support to V-Ray and Corona to fit the basic PBR usage, no Scene and AOV yet (AOV seems I can not get them in python, if someone knows where it stores, please let me know that).

                                        Cheers~
                                        DunHou

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

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

                                          Hi regarding Vray, I once wrote this plugin that have the duty to create ObjectId passes.
                                          I did not try it since age, but previously Vray AOV where stored within a branch on the Render Engine.

                                          I don't have vray installed currently, but I guess if you compile the C++ SDK, with the help of the C++ SDK Active Object Example it should be trivial to inspect a Vray scene and find these AOV.

                                          Cheers,
                                          Maxime

                                          MAXON SDK Specialist

                                          Development Blog, MAXON Registered Developer

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

                                            Hi community!

                                            Thanks for @m_adam prompt, I had add a AOV to Vray as same as other renderers, see a basic example here, hope it can help 😊

                                            Cheer~
                                            DunHou


                                            Result:

                                            3b1dfcb9-efb4-4dcc-a65f-a4800c3b9517-image.png

                                            Code:

                                            import c4d
                                            import Renderer
                                            from Renderer import Vray
                                            
                                            def modify_vray_aov():
                                            
                                                # Set Vray AOVHelper instance
                                                doc = c4d.documents.GetActiveDocument()
                                                vp: c4d.documents.BaseVideoPost = Renderer.GetVideoPost(doc, Renderer.ID_VRAY)    
                                                aov_helper = Vray.AOV(vp)
                                            
                                                # Add the DIFFUSE aov
                                                diff_aov = aov_helper.create_aov_shader(aov_type = Vray.VRAY_AOV_DIFFUSE)
                                                aov_helper.add_aov(diff_aov)
                                            
                                                # Add some aovs
                                                aov_helper.add_aov(aov_helper.create_aov_shader(aov_type = Vray.VRAY_AOV_BACKGROUND, aov_name = 'BG'))
                                                aov_helper.add_aov(aov_helper.create_aov_shader(Vray.VRAY_AOV_SPECULAR))
                                                aov_helper.add_aov(aov_helper.create_aov_shader(Vray.VRAY_AOV_REFLECTION))
                                                aov_helper.add_aov(aov_helper.create_aov_shader(Vray.VRAY_AOV_SHADOW))
                                                aov_helper.add_aov(aov_helper.create_aov_shader(Vray.VRAY_AOV_LIGHT_MIX))
                                            
                                                # Remove last aov
                                                aov_helper.remove_last_aov()
                                            
                                                # Remove specified aov: diffuse
                                                aov_helper.remove_aov_type(aov_type = Vray.VRAY_AOV_DIFFUSE[0])
                                            
                                                # Print current aov info
                                                aov_helper.print_aov()
                                            
                                                c4d.EventAdd()
                                            
                                            if __name__ == '__main__':
                                                Renderer.ClearConsole()
                                                modify_vray_aov()
                                            

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

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