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
    1. Maxon Developers Forum
    2. Dunhou
    • Profile
    • Following 2
    • Followers 4
    • Topics 55
    • Posts 269
    • Best 52
    • Controversial 0
    • Groups 0

    Dunhou

    @Dunhou

    81
    Reputation
    118
    Profile views
    269
    Posts
    4
    Followers
    2
    Following
    Joined Last Online
    Website www.boghma.com Location China

    Dunhou Unfollow Follow

    Best posts made by Dunhou

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

      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
      posted in General Talk programming learning-resource
      DunhouD
      Dunhou
    • RE: UserArea drag and drop example?

      Hi @m_adam ,

      Thanks for your reply! After some research, I had expanded the code for this case to adapt to the requirements I mentioned earlier:

      • we can drag c4d.BaseObject , c4d.BaseMaterial or Image into UA, create their icon.
      • we can drag the UA item(Object) back to OM, and drag the UA item(Material) into Material Manager or OM(on the selected object), or drag the UA item(ImageRef) into a shader link.

      The UserArea Accept:

      • c4d.BaseObject
      • c4d.BaseMaterial
      • Image file outside Cinema 4D.

      Here is the code in case anyone is interested in this topic in the future.Hope it can be helpful.

      Cheers~
      DunHou

      Animation.gif

      import c4d
      from c4d import Vector
      from c4d.gui import GeUserArea, GeDialog
      
      GADGET_ID_GEUSERAREA = 10000
      
      class DropArea(GeUserArea):
      
          def __init__(self):
              # data host
              self.receivedObject: list[c4d.BaseList2D, str] = []
              # bg color of the pen
              self.color: Vector = self._get_color()
      
          def _get_color(self, colorId: int = c4d.COLOR_BG) -> Vector:
              """
              Get a rgb color from c4d color id
              """
              color = self.GetColorRGB(colorId)
              r = color['r']/255
              g = color['g']/255
              b = color['b']/255
              return c4d.Vector(r,g,b)
      
          def DrawMsg(self, x1, y1, x2, y2, msg):
              """This Method is called automatically when Cinema 4D Draw the Gadget.
      
              Args:
                  x1 (int): The upper left x coordinate.
                  y1 (int): The upper left y coordinate.
                  x2 (int): The lower right x coordinate.
                  y2 (int): The lower right y coordinate.
                  msg (c4d.BaseContainer): The original message container.
              """
      
              # Initializes draw region
              self.OffScreenOn()
              self.SetClippingRegion(x1, y1, x2, y2)
      
              # Defines the color used in draw operation, use c4d backgroud color here.
              self.DrawSetPen(self.color)
      
              # Draws a rectangle filling the whole UI
              self.DrawRectangle(x1, y1, x2, y2)
      
              # Draw a Icon with the drop object, only consider c4d.BaseList2D and ImageRef here
              if msg.GetInt32(c4d.BFM_DRAG_FINISHED) == 1:
                              
                  # If drag info recive a image, draw a icon of image
                  if isinstance(self.receivedObject, str):
                      icon = c4d.bitmaps.InitResourceBitmap(1050500)
                      self.DrawBitmap(icon, x1, y1, x2, y2, 0, 0, icon.GetBw(), icon.GetBh(), mode= c4d.BMP_ALLOWALPHA)
      
                  # If drag info recive a list of BaseList2D, draw a icon of first one.
                  else:
                      if self.receivedObject:
                          # Draw the first drop object's Icon, 
                          # for BaseMaterial, we can get the preview image.
                          # for BaseObject, we can get the icon.
                          if isinstance(self.receivedObject[0], c4d.BaseList2D):
                              icon = self.receivedObject[0].GetIcon()
                              self.DrawBitmap(icon['bmp'], x1, y1, x2, y2, icon['x'], icon['y'], icon['w'], icon['h'],mode= c4d.BMP_ALLOWALPHA)
      
          def GetMinSize(self):
              # do a calculation here, min size.
              return 200, 200
      
          def Message(self, msg, result) :
              if msg.GetId()==c4d.BFM_DRAGRECEIVE:
                  # Discard if lost drag or if it has been escaped
                  if msg.GetInt32(c4d.BFM_DRAG_LOST) or msg.GetInt32(c4d.BFM_DRAG_ESC):
                      return self.SetDragDestination(c4d.MOUSE_FORBIDDEN)
                  
                  if not self.CheckDropArea(msg, True, True):
                      return self.SetDragDestination(c4d.MOUSE_FORBIDDEN)
                                          
                  # Check if drag is finished (=drop)
                  if msg.GetInt32(c4d.BFM_DRAG_FINISHED) == 1:
                      # Get drag object type and data
                      dragInfo = self.GetDragObject(msg)
      
                      # Redraw the GeUserArea (will call DrawMsg)
                      self.Redraw()
      
                      #print(type(dragInfo['object']))
                      self.receivedObject = dragInfo['object']
                      print(f"Dropped: {self.receivedObject}")
                      return True
                  
                  # Return current mouse cursor for valid drag operation
                  return self.SetDragDestination(c4d.MOUSE_MOVE)
              
              # Call GeUserAre.Message() implementation so that it can handle all the other messages
              return c4d.gui.GeUserArea.Message(self, msg, result)
      
          def InputEvent(self, msg):
              """Called by Cinema 4D when a click occurs"""
              
              # If the #self.receivedObject host the file path of the image, we generate the file path.
              # this means we can drag it into a image link like a shader link.
              if isinstance(self.receivedObject, str):
                  self.HandleMouseDrag(msg, c4d.DRAGTYPE_FILENAME_IMAGE, self.receivedObject, 0)
      
              else:
                  # Create a list of C4DAtom and pass that to the HandleMouseDrag function that will generate all the drag information
                  self.HandleMouseDrag(msg, c4d.DRAGTYPE_ATOMARRAY, self.receivedObject, 0)        
      
              return True
          
      class ExampleDialog(GeDialog):
          # The GeUserArea need to be stored somewhere, we will need this instance to be attached to the current Layout
          geUserArea = DropArea()
      
          def CreateLayout(self):
              """This Method is called automatically when Cinema 4D Create the Layout (display) of the Dialog."""
              
              self.SetTitle("Drag Area")
      
              if self.GroupBegin(0,  c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, cols=1, rows=0, title="", groupflags=0, initw=100, inith=100):
                  
                  self.GroupBorderSpace(8,8,8,8)
                  self.GroupSpace(2, 2)
                  
                  # Adds a Gadget that will host a GeUserArea
                  self.AddUserArea(GADGET_ID_GEUSERAREA, c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, 200, 200)
          
                  # Attaches the stored GeUserArea to the Gadget previously created
                  self.AttachUserArea(self.geUserArea, GADGET_ID_GEUSERAREA)
                  
              self.GroupEnd()
              
              return True
      
      
      if __name__ == "__main__":
          global dlg
          dlg = ExampleDialog()
          dlg.Open(dlgtype=c4d.DLG_TYPE_ASYNC, defaultw=200, defaulth=200)
      
      posted in Cinema 4D SDK
      DunhouD
      Dunhou
    • Free plugin : Octane Light Manager

      A free plugin for manage octane lights in the active document.

      Here is the dialog looks like, hope it can help you😊

      🤡 Octane verison : oc-light-manager v1.0.2.zip
      🤡 Redshift verison : rs-light-manager v1.0.1.zip

      preview.png


      Cinema 4D Octane Light Manager

      🔒:Cinema 4D R2023.2.0 above

      Online Help

      Standalone Download

      • Boghma Community(Chinese Language)

      • Gitee(Chinese Language)

      • Github( .pypv)

      Plugin Manager Download

      • Boghma Plugin Manager (Beta)

      Function Highlights

      • track document Octane lights and get/set some key parameter
      • Drag to set Light ID
      • Quickly set Texture or Distribution slot with RGB or Texture
      • Solo / Enable / As Camera for Octane Light
      • And so on, please check document

      Cheers~
      DunHou

      posted in General Talk
      DunhouD
      Dunhou
    • Free plugins all in one : Boghma HUB

      Hi community!

      Here is a new plugin to manage all my(boghma) plugins and some open source librarys like ualib and renderEngine for Cinema 4D.

      All the boghma plugin is 100% Free
      

      About boghma: boghma is the pronounce of python in Uighur, It is a free community for Cinema 4D and operated by me and my two friends.If you want to share your plugins for free and put it into the manager, please contact me👍

      Hope it can help you.

      Cheers~
      DunHou


      Boghma-Plugin-HUB

      This plugin manage all the boghma plugin, and install/update/uninstall them.

      Install

      1. Download boghma hub and unzip it.

      2. Put boghma hub folder to your ssd disk,Like:D:/boghma hub

      3. Start Cinema 4D,Preference - Plugins - Add Folder,Add the boghma hub folder and keep active,like:D:/boghma hub

      4. Restart Cinema,find boghma menu and enjoy
        15633e63-cbd0-4294-9452-a003199b1088-image.png

      Do not change the folder structure of boghma hub
      

      How to use

      53c621b5-1b83-4e0e-b0a8-ab68115b9811-image.png

      • Install
      • Update
      • Unstall
      posted in General Talk
      DunhouD
      Dunhou
    • RE: Open source wrapper for Octane/Redshift/Arnold/Vray/Corona in Cinema 4D.

      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

      posted in General Talk
      DunhouD
      Dunhou
    • Cinema 4D plugin market and tons of free plugins!

      Hi community!

      It is a great honor to introduce new Boghma and core products : Boghma Plugins Manager

      We try to provide free plugins market for users and developers :

      As User:
      • Just install the manager, you already get tons of plugins and growing plugin numbers!
      • You can download any plugin you want and get the newest update all in manager.
      • All the plugins are free, even needn't have to login.
      As Developer:
      • Deliver your plugins and updates directly to users with no fees.
      • Emphasize the developers themselves, uploading your plugins here will not weaken your personal brand. On the contrary, we encourage self promotion.
      • Intuitively obtaining your plugin popularity, investing more energy into user favorite plugins, and achieving a great sense of accomplishment

      So far, we have above 30 plugins and keeping going on, over a month of internal testing inside China, there have been over 9000 downloads, hoping to attract more developers to release their free plugins here.

      And as always, if you have any good ideas, please let me know, or you can join our discord channel in the website and get real-time updates and feedback .

      Cheers~
      DunHou

      posted in General Talk plugin-information chit-chat
      DunhouD
      Dunhou
    • RE: Get the Name of the Node?

      @bentraje

      I think name atttribute is not easy as old c4d SDK to use . It cann't print in console .

      I use this to get Name , and Set Name .
      some codes in python sdk didn't work and return None .Maxon SDK has a example to get info form node retrieve_information_r26.py

          # 获取名称 : 
          def GetNodeName(self, node, display=False):
              """
              Retrieve the displayed name of a node.
              
              Parameters
              ----------        
              Args:
                  node: (maxon.GraphNode): The node to retrieve the name from.
                  display: print info when display is True
              Returns:
                  Optional[str]: The node name, or None if the Node name can't be retrieved.
              """
              if node is None:
                  return None
      
              nodeName = node.GetValue(maxon.NODE.BASE.NAME)
      
              if nodeName is None:
                  nodeName = node.GetValue(maxon.EffectiveName)
      
              if nodeName is None:
                  nodeName = str(node)
              if display ==True :
                  print(nodeName)
              return nodeName   
      
      posted in Cinema 4D SDK
      DunhouD
      Dunhou
    • RE: Open source wrapper for Octane/Redshift/Arnold/Vray/Corona in Cinema 4D.

      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

      posted in General Talk
      DunhouD
      Dunhou
    • RE: Running Automatic UV for all objects

      @BineeMan here is my unwrap script, but I didn't find how to change to cubic or angle mode, there seems not a symbol in the .h file.

      import c4d
      
      MCOMMAND_AUTOMATICUV = 1053624
      
      def unwrap(node: c4d.BaseObject):
          doc = node.GetDocument()
          if isinstance(node, c4d.PolygonObject) and node.GetTag(c4d.Tuvw) is not None:
              pass
          elif isinstance(node, c4d.PolygonObject) and node.GetTag(c4d.Tuvw) is None:
              doc.AddUndo(c4d.UNDOTYPE_CHANGE, node)
              settings = c4d.BaseContainer()
              settings[c4d.MDATA_AUTOMATICUV_TAGINDEX] = 0
              settings[c4d.MDATA_AUTOMATICUV_FORCESEAMS] = False
              settings[c4d.MDATA_AUTOMATICUV_OVERLAPMIRRORED] = False
              settings[c4d.MDATA_AUTOMATICUV_OVERLAPIDENTICAL] = False
              settings[c4d.MDATA_AUTOMATICUV_SPACING] = 0.01
              settings[c4d.MDATA_AUTOMATICUV_USENORMALS] = True
              settings[c4d.MDATA_AUTOMATICUV_SPACINGASPECT] = 1.0
              c4d.utils.SendModelingCommand(command = MCOMMAND_AUTOMATICUV,
                                          list=[node],
                                          mode=c4d.MODELINGCOMMANDMODE_POLYGONSELECTION,
                                          bc=settings,
                                          doc=doc)
      
      def do_it():
          doc = c4d.documents.GetActiveDocument()
          for node in doc.GetActiveObjects(0):
              unwrap(node)
          c4d.EventAdd()
      
      if __name__ == '__main__':
          do_it()
      
      posted in Cinema 4D SDK
      DunhouD
      Dunhou
    • RE: Open source wrapper for Octane/Redshift/Arnold/Vray/Corona in Cinema 4D.

      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

      posted in General Talk
      DunhouD
      Dunhou

    Latest posts made by Dunhou

    • RE: How to get explicit import node space?

      Thanks @ferdinand for your great solution!

      Cheers~
      DunHou

      posted in Cinema 4D SDK
      DunhouD
      Dunhou
    • RE: Graph Description Explicit Connections can not work in 3rd-renderer (Arnold).

      Hey @ferdinand ,

      thanks for details.

      Cheers~
      DunHou


      About forum, I can get notification about my own topic, And I clear all the cache, but nothing changed.

      After I tried to reset my account settings manually, then it worked as expected.

      posted in Cinema 4D SDK
      DunhouD
      Dunhou
    • RE: Updated Redshift node material examples

      Hey @ferdinand ,

      Thanks for your answer, unfortunately, the answer is the same as I thought, and I am powerless to do anything about it. I can only wait for the exposed parameters.

      Based on your suggestion, there may be many issues, and it is not worth spending a lot of time debugging them. Fortunately, this is not a very urgent task.

      Cheers~
      DunHou

      posted in Bugs
      DunhouD
      Dunhou
    • RE: Graph Description Explicit Connections can not work in 3rd-renderer (Arnold).

      Hey @ferdinand,

      Thanks for your tips! Disabled validateAbsolutePaths with lazy paths can also work in this case, but if you interested, here is the console without disabled:

      I know third party APIs are not supported, just want to know if it is possible due to Arnold. It looks like it is due to my poor knowledge 🤡

      And as I know, Arnold has demo plugin that only has watermark on render, I use the demo to create plugins and it it worked as same as the full version.

      Cheers~
      DunHou

      Traceback (most recent call last):
        File "scriptmanager", line 19, in <module>
        File "C:\Program Files\Maxon Cinema 4D 2025\resource\modules\python\libs\python311\maxon\frameworks\nodes.py", line 548, in ApplyDescription
          res: DataDictionary = GraphDescription._ApplyDescription(
                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "C:\Program Files\Maxon Cinema 4D 2025\resource\modules\python\libs\python311\maxon\decorators.py", line 495, in Auto
          ExecStaticMethod(*args)
      RuntimeError: The node attribute reference '>output.r' (space: 'com.autodesk.arnold.nodespace', lang: 'en-US', node: 'com.autodesk.arnold.shader.image') is not associated with any IDs. [graphdescription_impl.cpp(2003)]
      In:
      { <- Error in this scope ->
         $type: #~.image
         #<filename: asset:///file_2e316c303b15a330
         #<multiply -> #>output.r: {
      
           $type: #~.image
           #<filename: asset:///file_2e316c303b15a330
        }
      } [graphdescription_impl.cpp(203)]
      

      I test on a brand new Macbook, and refresh my PC browser, and try to use private mode. None of them worked, but the notification of my question does show in the Ring icon, but the sort does not work. not sure about UNREAD, but I do miss the recent topic.
      370c425b-0e9b-49d2-9f73-d68db93029ce-image.png

      posted in Cinema 4D SDK
      DunhouD
      Dunhou
    • How to get explicit import node space?

      Hey community,

      I want to get the explicit render engine name of the default import plugin but not the index, can I do this?

      e.g. I want to set the importor to Standard or Redshift, but if I remove some renderer like CentiLeo, the index of Standard will changed.

      Cheers~
      DunHou

      35e08814-bb69-4007-8c3d-a7068406a031-image.png

      posted in Cinema 4D SDK windows python 2025
      DunhouD
      Dunhou
    • RE: Updated Redshift node material examples

      Hey @ferdinand ,

      I notice that GraphDescription also have two undo steps even I create graph and insert before apply description, how can I avoid this.

      the description dict is steal from GraphDescription Manual

      Cheers~
      DunHou

      import c4d
      import maxon
      
      data = {
          "$type": "Output",
          "Surface -> outColor": {
              "$type": "Standard Material",
              "Base/Metalness": 1.,
              "Base/Color": {
                  "$type": "Texture",
                  "Image/Filename/Path": maxon.Url("asset:///file_eb62aff065c50a2b"),
                  "Scale": {
                      "$type": "Value",
                      "$id": "texTransform",
                      "Input": maxon.Color(2, 2, 1)
                  }
              },
              "Reflection/Roughness": {
                  "$type": "Texture",
                  "Image/Filename/Path": maxon.Url("asset:///file_8bf49bb0b9992dbe"),
                  "Scale": "#texTransform"
              },
              "Geometry/Bump Map": {
                  "$type": "Bump Map",
                  "Input Map Type": 0,
                  "Height Scale": .2,
                  "Input": {
                      "$type": "Texture",
                      "Image/Filename/Path": maxon.Url("asset:///file_e706df60a3a533d2"),
                      "Scale": "#texTransform"
                  }
              }
          }
      }
      
      
      def main() -> None:
          """Called by Cinema 4D when the script is being executed.
          """
          doc = c4d.documents.GetActiveDocument()
          doc.StartUndo()
          material = c4d.BaseMaterial(c4d.Mmaterial)
          node_space = maxon.Id("com.redshift3d.redshift4c4d.class.nodespace")
          graph: maxon.NodesGraphModelRef = maxon.GraphDescription.GetGraph(material, node_space, True)
          doc.InsertMaterial(material)
          doc.AddUndo(c4d.UNDOTYPE_NEWOBJ, material)
          
          maxon.GraphDescription.ApplyDescription(graph, data)
          doc.EndUndo()
      if __name__ == '__main__':
          main()
      
      posted in Bugs
      DunhouD
      Dunhou
    • Graph Description Explicit Connections can not work in 3rd-renderer (Arnold).

      Hey community,

      I am working on something with GraphDescription, but seems I can not use explicit connection with Arnold, but Redshift and VRay worked as I want.
      I know 3rd is not full supported, but is this a problem with SDK design or Arnold's lack of adaptation, should I ask to Arnold dev?
      I tried match label/id/lazy id, but none of them work.

      btw: The notification and sorting of the forum have not been fixed yet. I have also tested it on a new computer and browser

      Cheers~
      DunHou

      this is want I want:

      0273eee1-1a1b-4140-b095-f1ae45c5df10-image.png

      Code:

      import maxon
      
      desc = {
          "$type": "#~.material",
          "#<shader":
              {
                  "$type": "#~.standard_surface",
                  "#<base_color": {
                      "$type": "#~.image",
                      "#<filename": maxon.Url("asset:///file_2e316c303b15a330"),
                      "#<multiply -> #>output.r": {
                          "$type": "#~.image",
                          "#<filename": maxon.Url("asset:///file_2e316c303b15a330")
                      }
                  }
              }
      }
      
      maxon.GraphDescription.ApplyDescription(
          maxon.GraphDescription.GetGraph(name="test"), desc)
      
      posted in Cinema 4D SDK windows python 2025
      DunhouD
      Dunhou
    • Broken Push Notifications

      Hi community,

      I notice that I can not get the newest and unread topic, when I open the form the sort seems not worked as before, I need to changed it manually to NEWEST TO OLDEST. Has anyone else encountered a similar situation?

      Cheers~
      DunHou

      posted in News & Information information forum
      DunhouD
      Dunhou
    • RE: How do I create a Plugin Identifier?

      Maybe you can try Google Chrome browser. The auto-fill doesn't work well in Edge sometimes, even manually passing your info. I can not login old plugin cafe with Edge, but it can work with Chrome, @ferdinand reminds me that in the past, I think it is good to mention here.

      Cheers~
      DunHou

      posted in Cinema 4D SDK
      DunhouD
      Dunhou
    • RE: Getting an effective value of an enum from a GraphNode

      Hey @ferdinand,

      Sorry to interject here, I'm just curious why it's recommended to put the return type at the end (of course, I prefer this Python-like writing style), but as far as I know, this is a relatively old-fashioned writing style (c++11), and the code I observed during my learning process was all of the predecessor types, this is quite confusing for a C++ beginner like me.

      Cheers~
      DunHou

      Result<GraphNode> getConnectedNode(const GraphNode& input, const NODE_KIND kind);```
      posted in Cinema 4D SDK
      DunhouD
      Dunhou