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
    1. Maxon Developers Forum
    2. Dunhou
    3. Best
    • Profile
    • Following 2
    • Followers 4
    • Topics 56
    • Posts 273
    • Best 53
    • Controversial 0
    • Groups 0

    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
    • RE: Timeline commands ran via Python script does not have same result

      Hi @Daguna ,

      Sorry to bad answer, I misread your target, see a new one here:

      from typing import Optional
      import c4d
      
      doc: c4d.documents.BaseDocument  # The active document
      op: Optional[c4d.BaseObject]  # The active object, None if unselected
      
      def main():
      
          # Retrieves BaseTime of frame 5, 20
          start = 0
          end = 1
      
          # Loops through the frames
          for frame in range(start, end + 1):
      
              # Changes the time of the document
              doc.SetTime(c4d.BaseTime(frame, doc.GetFps()))
      
              # Updates timeline
              c4d.GeSyncMessage(c4d.EVMSG_TIMECHANGED)
      
              # Redraws the viewport and regenerate the cache object
              c4d.DrawViews(c4d.DRAWFLAGS_ONLY_ACTIVE_VIEW | c4d.DRAWFLAGS_NO_THREAD | c4d.DRAWFLAGS_STATICBREAK)
      
      
      
          # Pushes an update event to Cinema 4D
          c4d.EventAdd(c4d.EVENT_ANIMATE)
      
      
      if __name__ == '__main__':
          main()
      
      posted in Cinema 4D SDK
      DunhouD
      Dunhou
    • RE: Free plugin : Octane Light Manager

      Redshift Manager Here, and Octane also had a huge update, please use my plugin manager version to check new furtures.

      49845e69-c2ef-4d79-a429-4c1433f5a773-image.png

      posted in General Talk
      DunhouD
      Dunhou
    • RE: How do I create a menu item on the home screen next to the buttons.

      And a great example by @ferdinand at Building menus with C4DPL_BUILDMENU in S26+.

      posted in Cinema 4D SDK
      DunhouD
      Dunhou
    • RE: Free Python Plugin: Quad Disc

      I have add zh-CN string to this and make an icon that similar to c4d Disc object.
      6c427beb-e10b-4d1f-81ec-c9410aa47038-image.png

      posted in General Talk
      DunhouD
      Dunhou
    • RE: python script change Redshift setting

      Hi @RTF , the c4d.PREFS_REDSHIFT_MATPREVIEW_MODE doesn't seem stored in Redshift VideoPost, is this code generated by GPT or something similar?

      Back to the topic, this parameter is stored in the Redshift tab of the preferences node. You should get the redshift preference node and then set the parameter.

      If you installed Renderer lib or boghma hub, you can use this:

      import c4d
      from Renderer import Redshift
      
      if __name__ == '__main__':
          Redshift.SetMaterialPreview(preview_mode = 1)
      

      or just few codes:

      import c4d
      
      ID_PREFERENCES_NODE = 465001632 # Prefs ID
      
      def GetPreference() -> c4d.BaseList2D:
          """
          Get the Redshift preferenc.
          """
          prefs: c4d.plugins.BasePlugin = c4d.plugins.FindPlugin(ID_PREFERENCES_NODE)
          if not isinstance(prefs, c4d.BaseList2D):
              raise RuntimeError("Could not access preferences node.")
            
          descIdSettings = c4d.DescID(
          c4d.DescLevel(1036220, 1, 465001632), # pref ID Redshift
          c4d.DescLevel(888, 133, 465001632)
          )
          return prefs[descIdSettings]
      
      if __name__ == '__main__':
          redshift_pref: c4d.BaseList2D = GetPreference()
          redshift_pref[c4d.PREFS_REDSHIFT_MATPREVIEW_MODE] = 1
      

      Cheers~
      DunHou

      posted in Cinema 4D SDK
      DunhouD
      Dunhou
    • RE: Open source wrapper for Octane/Redshift/Arnold/Vray/Corona in Cinema 4D.

      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()
      
      posted in General Talk
      DunhouD
      Dunhou
    • RE: Hiding Node Previews for all Redshift Nodes in Redshift Materials

      Hey @d_keith ,

      I'll hide all nodes preview and un-hide the output preview, I write two examples.

      • First one uses my Renderer lib, if you installed boghma plugin manager, it will out of the box to use.
      • Second one uses maxon codes, it should work more widely.

      Cheers~
      DunHou

      Renderer

      import c4d
      import maxon
      import Renderer
      
      def mylib_solution():
          doc = c4d.documents.GetActiveDocument()
          for mat in doc.GetMaterials():
              with Renderer.EasyTransaction(mat) as tr:
                  tr.FoldPreview(tr.GetAllShaders(), False)
                  tr.FoldPreview(tr.GetOutput(), True)
          c4d.EventAdd()
      

      maxon

      import c4d
      import maxon
      def maxon_solution():
          doc = c4d.documents.GetActiveDocument()
          for mat in doc.GetMaterials():
              nodeMaterial: c4d.NodeMaterial = mat.GetNodeMaterialReference()
              if not nodeMaterial.HasSpace(maxon.NodeSpaceIdentifiers.RedshiftMaterial):
                  continue
      
              graph: maxon.NodesGraphModelRef = nodeMaterial.GetGraph(maxon.NodeSpaceIdentifiers.RedshiftMaterial)
              root: maxon.GraphNode = graph.GetViewRoot()
              nimbusRef: maxon.NimbusBaseRef = mat.GetNimbusRef(maxon.NodeSpaceIdentifiers.RedshiftMaterial)
              endNodePath: maxon.NodePath = nimbusRef.GetPath(maxon.NIMBUS_PATH.MATERIALENDNODE)
              endNode: maxon.GraphNode = graph.GetNode(endNodePath)
      
              with graph.BeginTransaction() as transaction:
                  node: maxon.GraphNode
                  for node in root.GetInnerNodes(mask=maxon.NODE_KIND.NODE, includeThis=False):
                      node.SetValue(maxon.NODE.BASE.DISPLAYPREVIEW, maxon.Bool(False))
      
                  endNode.SetValue(maxon.NODE.BASE.DISPLAYPREVIEW, maxon.Bool(True))
      
                  transaction.Commit()
      
          c4d.EventAdd()
      
      posted in Cinema 4D SDK
      DunhouD
      Dunhou
    • RE: Add Expression Value in Render Settings Save Path

      Hey @Gemini ,

      You should take a look at py-render-token example, and filter the version number of your project like re.findall("v"+"\d+",filePath) if I understand not wrong.

      Cheers~
      DunHou

      posted in General Talk
      DunhouD
      Dunhou
    • RE: 2025.2.0 SDK Release

      Love the mxutils and GeDialog Changes, I use these features almost every time, thank you for having a more refined official version.

      Thank you to the SDK team for their work achievements

      Cheers~
      DunHou

      posted in News & Information
      DunhouD
      Dunhou
    • RE: Can I download a Tex in Asset Browser and add into select RS node mat?

      @ferdinand Maybe the broblem in not the code but the Cinema Application, Some friends also told me when they load Aseets(especially at a large Asset data like 20G in disk) , It always take a long time or even not load unless restart C4D.

      You are right, I should call WaitForDatabaseLoading() function for safe. That's my stupid , I didn't notice the loading failed in state bar😧

      I do check the Python examples in GitHub , but I think maybe it is a dcc of my config problem, some friends also said assets broswer is a little slower . (perhaps due to china a internet far away from maxon server) .hope it will be fix in uncoming C4D

      posted in Cinema 4D SDK
      DunhouD
      Dunhou