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
    1. Home
    2. chuanzhen
    3. Posts
    • Profile
    • Following 1
    • Followers 6
    • Topics 72
    • Posts 214
    • Best 18
    • Controversial 0
    • Groups 0

    Posts made by chuanzhen

    • RE: Frozen Matrix different

      When I restart C4D, I cannot reproduce this problem. It's really confusing, c4d 2025.2.1😵 (And I also forgot to save the file at that time, resulting in the loss of the file on site)

      posted in Cinema 4D SDK
      chuanzhenC
      chuanzhen
    • Frozen Matrix different

      hi,
      A parent object has 2 child objects whose global matrix are the same. They have the same frozen transform value, but the transform values are different. I used GetFrozenMln() to obtain the frozen matrix and found that the frozen matrix of the 2 child objects are *different.

      Why do 2 child objects have the same frozen transform value but different frozen matrix?
      4c0880f6-fb6f-4cd9-9e0e-a1c29320d8f9-image.png

      posted in Cinema 4D SDK 2025 python
      chuanzhenC
      chuanzhen
    • RE: Set RenderData framerate causing C4D to crash

      @i_mazlov there is video, 2025.2.1,win11

      posted in Bugs
      chuanzhenC
      chuanzhen
    • Set RenderData framerate causing C4D to crash

      Hi,
      use bellow code will causing C4D to crash

      import c4d
      
      doc: c4d.documents.BaseDocument  # The currently active document.
      op: c4d.BaseObject | None  # The primary selected object in `doc`. Can be `None`.
      
      def main() -> None:
          rd = c4d.documents.RenderData()
          rd[c4d.RDATA_FRAMERATE] = 2.0
      
      
      if __name__ == '__main__':
          main()
      

      safe setting code:

          rd = c4d.documents.RenderData()
          data = rd.GetDataInstance()
          data[c4d.c4d.RDATA_FRAMERATE] = 2.0
      
      
      

      bug?

      posted in Bugs python 2025
      chuanzhenC
      chuanzhen
    • RE: How to Execute a Modifier plugin in Expression priority

      @i_mazlov Thanks,it works!

      posted in Cinema 4D SDK
      chuanzhenC
      chuanzhen
    • RE: Problem encountered when check double click in Message() Use MSG_EDIT

      @i_mazlov Thanks

      posted in Cinema 4D SDK
      chuanzhenC
      chuanzhen
    • RE: How to Execute a Modifier plugin in Expression priority

      @i_mazlov Thanks,in my code I found an error and directly used the value obtained from PRIORITYVALUEMYODE in the priority GUI to set the list The priority parameter in Add() is a low-level error.
      But there is still a problem. When I used your code and adjusted the priority of **Python tag*to expression 1, the calculation order did not execute as expected. Where exactly is the problem?
      My version is also 2025.2.0
      aa3b604f-b0ba-49cc-8b40-6276b19dca35-image.png
      c438db28-6569-45f8-b1d8-82049db07a2b-image.png

      posted in Cinema 4D SDK
      chuanzhenC
      chuanzhen
    • RE: How to Execute a Modifier plugin in Expression priority

      @i_mazlov Thanks for reply!
      I added this flag and modified the content of AddToExecution(). Execute() was successfully called, but it did not run in the expected calculation order. In the image below, The Cube object has a Python tag with priority=expression 0 and objectplugin with priority=expression 10. My expected work order should be python tag (priority=expression 0) -> objectplugin (priority=expression 10), but why is the actual running result objectplugin (priority=expression 10) ->python tags (priority=expression 10)
      bd57c2f7-c340-4c85-a9f3-ed22600fbb19-image.png

      my code:

          def Execute(self, op, doc, bt, priority, flags) -> int:
      
              print("Execute")
              return c4d.EXECUTIONRESULT_OK
      
          def AddToExecution(self, op, list) -> bool:
              print("AddToExecution")
              mode = op[c4d.S_TEMP_PRIORITY].GetPriorityValue(c4d.PRIORITYVALUE_MODE)
              list.Add(op, mode,c4d.EXECUTIONFLAGS_NONE)
      
      posted in Cinema 4D SDK
      chuanzhenC
      chuanzhen
    • Problem encountered when check double click in Message() Use MSG_EDIT

      Hi,
      In the tag plugin, i use MSG_EDIT in Message() to detect the double-click behavior of the mouse, and then execute some commands. However, when create tag, MSG_EDIT is also used. I tried using gui.GetInputState (c4d.BFM_INPUT_MOUSE, c4d.BFM_INPUT_DOUBLECLICK,bc) obtains specific information to distinguish between label create tag and double-click behavior, but bc no double click information is obtained.
      code:

          def Message(self, node: GeListNode, type: int, data: object) -> bool:
              if type == c4d.MSG_EDIT:
                  
                  c4d.CallCommand(200000084) # Rectangle Selection
      
                  bc = c4d.BaseContainer()
                  gui.GetInputState(c4d.BFM_INPUT_MOUSE,c4d.BFM_INPUT_DOUBLECLICK,bc)
                  if bc[c4d.BFM_INPUT_DOUBLECLICK] : 
                      print("double")
                  return True
              return True
      

      How to distinguish between these two behaviors
      Thanks for any help!

      posted in Cinema 4D SDK 2025 python
      chuanzhenC
      chuanzhen
    • How to Execute a Modifier plugin in Expression priority

      Hi,
      I have created a object modifier plugin and I want it to work once in priority Expression 10, and then again in Generator 1. How can I make it work as expected?
      In the code, AddToExecution() and Execute() do not seem to work (the documentation states that switching priorities requires calling these two functions).

      import c4d
      from c4d import plugins, bitmaps
      
      
      PLUGIN_ID = 1000001
      
      class S_Temp(plugins.ObjectData):
      
      
          def Execute(self, op, doc, bt, priority, flags) -> int:
              print("Execute")
              return c4d.EXECUTIONRESULT_OK
      
          def AddToExecution(self, op, list) -> bool:
              print("AddToExecution")
              return True
      
      
          def Init(self, node, isCloneInit: bool) -> bool:
              self.InitAttr(node, c4d.BaseList2D, c4d.S_TEMP_POSEDTARGETS)
              self.InitAttr(node, c4d.BaseList2D, c4d.S_TEMP_POSEDSOURCEADD)
              self.InitAttr(node, c4d.PriorityData, c4d.S_TEMP_PRIORITY)
      
              if not isCloneInit:
                  pridata = c4d.PriorityData()
                  pridata.SetPriorityValue(c4d.PRIORITYVALUE_MODE, c4d.CYCLE_EXPRESSION)
                  pridata.SetPriorityValue(c4d.PRIORITYVALUE_PRIORITY, 10)
                  node[c4d.S_TEMP_PRIORITY] = pridata
              return True
      
          def ModifyObject(self, mod, doc, op, op_mg, mod_mg, lod, flags, thread):
              allp = [pos + c4d.Vector(0,100,0) for pos in op.GetAllPoints()]
              op.SetAllPoints(allp)
              op.Message(c4d.MSG_UPDATE)
      
              return True
      
      
      if __name__ == '__main__':
          plugins.RegisterObjectPlugin(id=PLUGIN_ID, str="S_Temp", g=S_Temp, description="stemp", info=c4d.OBJECT_MODIFIER,
                                       icon=None)
      

      Here is the file of this plugin --> s_Temp.zip

      Thanks for any help!

      posted in Cinema 4D SDK 2024 python
      chuanzhenC
      chuanzhen
    • RE: Change Icon Color parameter

      @i_mazlov Thanks for your help, it works well.

      posted in Cinema 4D SDK
      chuanzhenC
      chuanzhen
    • RE: Change Icon Color parameter

      @JH23 Thanks for your help,this is indeed a solution.
      For existing objects in Object Manager, using this code is effective, but creating a new object and setting it up yields a different result, which is confusing.

      @chuanzhen said in Change Icon Color parameter:

      import c4d
      
      doc: c4d.documents.BaseDocument  # The currently active document.
      op: c4d.BaseObject | None  # The primary selected object in `doc`. Can be `None`.
      
      def main() -> None:
          for i in range(2):
              obj = c4d.BaseObject(c4d.Ojoint)
              obj[c4d.ID_BASELIST_ICON_COLORIZE_MODE] = 2
              obj[c4d.ID_BASEOBJECT_USECOLOR] = 2
              obj[c4d.ID_BASEOBJECT_COLOR] = c4d.Vector()
      
              obj.SetName(str(i))
              doc.InsertObject(obj)
          c4d.EventAdd()
      
      
      if __name__ == '__main__':
          main()
      
      posted in Cinema 4D SDK
      chuanzhenC
      chuanzhen
    • Change Icon Color parameter

      hi,
      I use script to create bone and insert it to document, set it Icon Color=Display Color,Why does the Icon Color parameter of the object turn to Custom when I click on it.

      import c4d
      
      doc: c4d.documents.BaseDocument  # The currently active document.
      op: c4d.BaseObject | None  # The primary selected object in `doc`. Can be `None`.
      
      def main() -> None:
          for i in range(2):
              obj = c4d.BaseObject(c4d.Ojoint)
              obj[c4d.ID_BASELIST_ICON_COLORIZE_MODE] = 2
              obj[c4d.ID_BASEOBJECT_USECOLOR] = 2
              obj[c4d.ID_BASEOBJECT_COLOR] = c4d.Vector()
      
              obj.SetName(str(i))
              doc.InsertObject(obj)
          c4d.EventAdd()
      
      
      if __name__ == '__main__':
          main()
      

      Thanks for any help!

      posted in Cinema 4D SDK 2024 python
      chuanzhenC
      chuanzhen
    • RE: How to convert the length of a line on the screen to the length of an object.

      @ferdinand Thanks for your help.
      For the unwanted effect of perspective distortion, I tried projecting a fixed size line onto an object to determine the length of the projected line in the world, and then proceeded to draw it.

      code:

      
      
      import c4d
      
      doc: c4d.documents.BaseDocument  # The document containing this field object.
      op: c4d.BaseTag  # The Python tag containing this code.
      flags: int  # The execution flags of `main()`. See c4d.EXECUTIONFLAGS for details.
      priority: int  # The execution priority of this tag. See c4d.EXECUTIONPRIORITY for details.
      tp: c4d.modules.thinkingparticles.TP_MasterSystem  # The TP system of the document.
      
      def GetLineAndPlaneIntersection(plane_pos, plane_normal, line_start, line_dir):
      
          zero_find = line_dir.Dot(plane_normal)
          if zero_find == 0:
              return False, None
          else:
              d = (plane_pos - line_start).Dot(plane_normal) / zero_find
      
      
          return True, line_start + d * line_dir
      
      
      def main() -> None:
      
          pass
      
      
      
      
      
      
      
      def draw(bd: c4d.BaseDraw) -> bool:
      
      
          if op[c4d.EXPRESSION_ENABLE]:
              c_mg = bd.GetMg()
              c_mi = bd.GetMi()
      
              plane_normal = c_mg.v3
      
              plane_100_point = c_mg * c4d.Vector(0,0,100)
              plane_obj_point = op.GetMain().GetMg().off
      
              intersect,intersect_100_plane_point = GetLineAndPlaneIntersection(plane_100_point, plane_normal, plane_obj_point, c_mg.off - plane_obj_point)
              line_end = intersect_100_plane_point + (c_mg * c4d.Vector(5,0,0) - c_mg.off)  # fixed size
              intersect,intersect_obj_plane_point = GetLineAndPlaneIntersection(plane_obj_point, plane_normal, c_mg.off, line_end - c_mg.off)
              length = (intersect_obj_plane_point - plane_obj_point).GetLength()
      
      
      
              mg = op.GetMain().GetMg()
              pos = bd.WS(plane_obj_point)
              bd.SetMatrix_Screen()
              bd.SetPen(c4d.GetViewColor(c4d.VIEWCOLOR_XAXIS))
              x = bd.WS(mg * c4d.Vector(length,0,0))
              bd.DrawLine2D(pos,x)
              bd.SetPen(c4d.GetViewColor(c4d.VIEWCOLOR_YAXIS))
              y = bd.WS(mg * c4d.Vector(0,length,0))
              bd.DrawLine2D(pos,y)
              bd.SetPen(c4d.GetViewColor(c4d.VIEWCOLOR_ZAXIS))
              z = bd.WS(mg * c4d.Vector(0,0,length))
              bd.DrawLine2D(pos,z)
      
      
          return True
      

      posted in Cinema 4D SDK
      chuanzhenC
      chuanzhen
    • How to convert the length of a line on the screen to the length of an object.

      hi,
      I tried to have an object display its coordinate axis at a fixed screen space length, but it didn't work properly. Where did I make a mistake with my code?

      This is a c4d file that displays its coordinate axis using tags.-->

      video:

      code:

      import c4d
      
      doc: c4d.documents.BaseDocument  # The document containing this field object.
      op: c4d.BaseTag  # The Python tag containing this code.
      flags: int  # The execution flags of `main()`. See c4d.EXECUTIONFLAGS for details.
      priority: int  # The execution priority of this tag. See c4d.EXECUTIONPRIORITY for details.
      tp: c4d.modules.thinkingparticles.TP_MasterSystem  # The TP system of the document.
      
      
      def main() -> None:
          """Called by Cinema 4D to execute the tag.
          """
          # Get the object the tag is attached to and its global position.
          pass
      
      
      
      
      
      
      def draw(bd: c4d.BaseDraw) -> bool:
          # Called to display some visual element in the viewport. Similar to TagData.Draw.
          # Write your code here
          if op[c4d.EXPRESSION_ENABLE]:
              size = 40  #  40 pixel length line
              bd.SetMatrix_Screen()
              start = c4d.Vector(200)
              end = start + c4d.Vector(size,0,0)
              bd.SetPen(c4d.Vector(1.0))
              bd.DrawLine2D(start, end)
      
              mg = op.GetMain().GetMg()
              pos = bd.WS(mg.off)
      
      
              length = size/bd.WP_W(pos,True)
      
      
              bd.SetPen(c4d.Vector(1.0,0,0))
              x = bd.WS(mg * c4d.Vector(length,0,0))
              bd.DrawLine2D(pos,x)
              bd.SetPen(c4d.Vector(0,1.0,0))
              y = bd.WS(mg * c4d.Vector(0,length,0))
              bd.DrawLine2D(pos,y)
              bd.SetPen(c4d.Vector(0,0,1.0))
              z = bd.WS(mg * c4d.Vector(0,0,length))
              bd.DrawLine2D(pos,z)
      
      
          return True
      

      Thanks for any help!

      posted in Cinema 4D SDK 2024 python
      chuanzhenC
      chuanzhen
    • RE: Show or Hide Object in Viewport

      @gheyret Thanks for your help!👍
      i use "c4d.CallCommand(12147) # Redraw" to replace c4d.EventAdd() or c4d.Redraw(), it also work!

      change code:

              if id == 1001:
                  for obj in doc.GetObjects():
                      obj.ChangeNBit(c4d.NBIT_EHIDE,c4d.NBITCONTROL_CLEAR)
                  c4d.CallCommand(12147) # Redraw
                  return True
      
      posted in Cinema 4D SDK
      chuanzhenC
      chuanzhen
    • Show or Hide Object in Viewport

      Hi,
      I encountered some issues when importing documents and performing hide and display object.

      this is an example c4d file to import --> import.c4d

      this is an example script code:

      
      import c4d
      
      class MyDialog (c4d.gui.GeDialog):
      
          def CreateLayout(self) -> bool:
      
              self.GroupBorderSpace(5, 5, 5, 5)
              self.GroupSpace(5, 5)
              self.AddButton(1000, c4d.BFH_SCALEFIT, name = "import")
              self.AddButton(1001, c4d.BFH_SCALEFIT, name = "show")
              self.AddButton(1002, c4d.BFH_SCALEFIT, name = "hide")
              return True
      
          def Command(self, id, msg):
              if id == 1000:
                  file_path = c4d.storage.LoadDialog()
                  c4d.documents.MergeDocument(doc,file_path,c4d.SCENEFILTER_OBJECTS|c4d.SCENEFILTER_MATERIALS)
                  for obj in doc.GetObjects():
                      obj.ChangeNBit(c4d.NBIT_EHIDE,c4d.NBITCONTROL_SET)
                  c4d.EventAdd()
                  return True
              if id == 1001:
                  for obj in doc.GetObjects():
                      obj.ChangeNBit(c4d.NBIT_EHIDE,c4d.NBITCONTROL_CLEAR)
                  c4d.EventAdd()
                  c4d.DrawViews(c4d.DRAWFLAGS_FORCEFULLREDRAW)
                  return True
              if id == 1002:
                  for obj in doc.GetObjects():
                      obj.ChangeNBit(c4d.NBIT_EHIDE,c4d.NBITCONTROL_SET)
                  c4d.EventAdd()
                  return True
              return True
      
      
      if __name__ == "__main__":
          dlg = MyDialog()
          dlg.Open(c4d.DLG_TYPE_ASYNC, 0, -1, -1, 200, 200)
      

      ui:df043d32-7828-4b64-9aa6-2306499035af-image.png

      Step 1: Use "import" to merge a document into the current document, and then hide the imported object

      Step 2: Use "show" to restore the display of the object, but it will not refresh the display. Only by using the "Redraw" command can the display be refreshed

      Why c4d.EventAdd() and c4d.DrawView() doesn't work, did I miss something?

      It seems to only occur in the document imported for the first time, and when the "show" or "hide" command is used again, it works normally.
      Thanks for any help!

      posted in Cinema 4D SDK 2024 python
      chuanzhenC
      chuanzhen
    • RE: How to drag rows in Treeview

      @ferdinand Thanks for your help!👍

      posted in Cinema 4D SDK
      chuanzhenC
      chuanzhen
    • How to drag rows in Treeview

      Hi,
      I have read many posts about the dragging behavior of treeview, all of which are examples of dragging from the outside into treeview. What I want is to drag the rows of treeview to rearrange them, just like an object manager dragging objects.
      drag.gif
      This post also mentioned some explanations about the drag and drop process, but I am still confused about how to start.

      I found an example of code in this post. Can we implement the drag behavior of treeview rows on this basis

      import c4d
      import weakref
      
      # Be sure to use a unique ID obtained from [URL-REMOVED]
      PLUGIN_ID = 1000010  # TEST ID ONLY
      
      # TreeView Column IDs.
      ID_CHECKBOX = 1
      ID_NAME = 2
      ID_OTHER = 3
      
      
      def TextureObjectIterator(lst):
          for parentTex in lst:
              yield parentTex
              for childTex in TextureObjectIterator(parentTex.GetChildren()):
                  yield childTex
      
      
      class TextureObject(object):
          """
          Class which represent a texture, aka an Item in our list
          """
          texturePath = "TexPath"
          otherData = "OtherData"
          _selected = False
          _open = True
      
          def __init__(self, texturePath):
              self.texturePath = texturePath
              self.otherData += texturePath
              self.children = []
              self._parent = None
      
          @property
          def IsSelected(self):
              return self._selected
      
          def Select(self):
              self._selected = True
      
          def Deselect(self):
              self._selected = False
      
          @property
          def IsOpened(self):
              return self._open
      
          def Open(self):
              self._open = True
      
          def Close(self):
              self._open = False
      
          def AddChild(self, obj):
              obj._parent = weakref.ref(self)
              self.children.append(obj)
      
          def GetChildren(self):
              return self.children
      
          def GetParent(self):
              if self._parent:
                  return self._parent()
      
              return None
      
          def __repr__(self):
              return str(self)
      
          def __str__(self):
              return self.texturePath
      
      
      class ListView(c4d.gui.TreeViewFunctions):
      
          def __init__(self):
              self.listOfTexture = list()  # Store all objects we need to display in this list
      
              # Add some defaults values 
              t1 = TextureObject("T1")
              t2 = TextureObject("T2")
              t3 = TextureObject("T3")
              t4 = TextureObject("T4")
      
              self.listOfTexture.extend([t1, t2, t3, t4])
      
          def IsResizeColAllowed(self, root, userdata, lColID):
              return True
      
          def IsTristate(self, root, userdata):
              return False
      
          def GetColumnWidth(self, root, userdata, obj, col, area):
              return 80  # All have the same initial width
      
          def IsMoveColAllowed(self, root, userdata, lColID):
              # The user is allowed to move all columns.
              # TREEVIEW_MOVE_COLUMN must be set in the container of AddCustomGui.
              return True
      
          def GetFirst(self, root, userdata):
              """
              Return the first element in the hierarchy, or None if there is no element.
              """
              rValue = None if not self.listOfTexture else self.listOfTexture[0]
              return rValue
      
          def GetDown(self, root, userdata, obj):
              """
              Return a child of a node, since we only want a list, we return None everytime
              """
              children = obj.GetChildren()
              if children:
                  return children[0]
      
              return None
      
          def GetNext(self, root, userdata, obj):
              """
              Returns the next Object to display after arg:'obj'
              """
              rValue = None
      
              # If does have a child it means it's a child.
              objParent = obj.GetParent()
              listToSearch = objParent.GetChildren() if objParent is not None else self.listOfTexture
      
              currentObjIndex = listToSearch.index(obj)
              nextIndex = currentObjIndex + 1
              if nextIndex < len(listToSearch):
                  rValue = listToSearch[nextIndex]
      
              return rValue
      
          def GetPred(self, root, userdata, obj):
              """
              Returns the previous Object to display before arg:'obj'
              """
              rValue = None
      
              # If does have a child it means it's a child.
              objParent = obj.GetParent()
              listToSearch = objParent.GetChildren() if objParent is not None else self.listOfTexture
      
              currentObjIndex = listToSearch.index(obj)
              predIndex = currentObjIndex - 1
              if 0 <= predIndex < len(listToSearch):
                  rValue = listToSearch[predIndex]
      
              return rValue
      
          def GetId(self, root, userdata, obj):
              """
              Return a unique ID for the element in the TreeView.
              """
              return hash(obj)
      
          def Select(self, root, userdata, obj, mode):
              """
              Called when the user selects an element.
              """
              if mode == c4d.SELECTION_NEW:
                  for tex in self.listOfTexture:
                      tex.Deselect()
                  obj.Select()
              elif mode == c4d.SELECTION_ADD:
                  obj.Select()
              elif mode == c4d.SELECTION_SUB:
                  obj.Deselect()
      
          def IsSelected(self, root, userdata, obj):
              """
              Returns: True if *obj* is selected, False if not.
              """
              return obj.IsSelected
      
          def SetCheck(self, root, userdata, obj, column, checked, msg):
              """
              Called when the user clicks on a checkbox for an object in a
              `c4d.LV_CHECKBOX` column.
              """
              if checked:
                  obj.Select()
              else:
                  obj.Deselect()
      
          def IsChecked(self, root, userdata, obj, column):
              """
              Returns: (int): Status of the checkbox in the specified *column* for *obj*.
              """
              if obj.IsSelected:
                  return c4d.LV_CHECKBOX_CHECKED | c4d.LV_CHECKBOX_ENABLED
              else:
                  return c4d.LV_CHECKBOX_ENABLED
      
          def IsOpened(self, root, userdata, obj):
              """
              Returns: (bool): Status If it's opened = True (folded) or closed = False.
              """
              # If there is some children
              return obj.IsOpened
      
          def Open(self, root, userdata, obj, onoff):
              """
              Called when the user clicks on a folding state of an object to display/hide its children
              """
              if onoff:
                  obj.Open()
      
              else:
                  obj.Close()
      
          def GetName(self, root, userdata, obj):
              """
              Returns the name to display for arg:'obj', only called for column of type LV_TREE
              """
              return str(obj)  # Or obj.texturePath
      
          def DrawCell(self, root, userdata, obj, col, drawinfo, bgColor):
              """
              Draw into a Cell, only called for column of type LV_USER
              """
              if col == ID_OTHER:
                  name = obj.otherData
                  geUserArea = drawinfo["frame"]
                  w = geUserArea.DrawGetTextWidth(name)
                  h = geUserArea.DrawGetFontHeight()
                  xpos = drawinfo["xpos"]
                  ypos = drawinfo["ypos"] + drawinfo["height"]
                  drawinfo["frame"].DrawText(name, xpos, int(ypos - h * 1.1))
      
          def DoubleClick(self, root, userdata, obj, col, mouseinfo):
              """
              Called when the user double-clicks on an entry in the TreeView.
      
              Returns:
                (bool): True if the double-click was handled, False if the
                  default action should kick in. The default action will invoke
                  the rename procedure for the object, causing `SetName()` to be
                  called.
              """
              c4d.gui.MessageDialog("You clicked on " + str(obj))
              return True
      
          def DeletePressed(self, root, userdata):
              "Called when a delete event is received."
              for tex in reversed(list(TextureObjectIterator(self.listOfTexture))):
                  if tex.IsSelected:
                      listToRemove = objParent.GetChildren() if objParent is not None else self.listOfTexture
                      listToRemove.remove(tex)
      
          def DragStart(self, root: object, userdata: object, obj: object) -> int:
              print("drag")
              c4d.gui.SetMousePointer(c4d.MOUSE_INSERTMOVE)
              return c4d.TREEVIEW_DRAGSTART_ALLOW | c4d.TREEVIEW_DRAGSTART_SELECT
      
          def SetDragObject(self, root: object, userdata: object, obj: object) -> None:
              pass
      
      class TestDialog(c4d.gui.GeDialog):
          _treegui = None  # Our CustomGui TreeView
          _listView = ListView()  # Our Instance of c4d.gui.TreeViewFunctions
      
          def CreateLayout(self):
              # Create the TreeView GUI.
              customgui = c4d.BaseContainer()
              customgui.SetBool(c4d.TREEVIEW_BORDER, c4d.BORDER_THIN_IN)
              customgui.SetBool(c4d.TREEVIEW_HAS_HEADER, True)  # True if the tree view may have a header line.
              customgui.SetBool(c4d.TREEVIEW_HIDE_LINES, False)  # True if no lines should be drawn.
              customgui.SetBool(c4d.TREEVIEW_MOVE_COLUMN, True)  # True if the user can move the columns.
              customgui.SetBool(c4d.TREEVIEW_RESIZE_HEADER, True)  # True if the column width can be changed by the user.
              customgui.SetBool(c4d.TREEVIEW_FIXED_LAYOUT, True)  # True if all lines have the same height.
              customgui.SetBool(c4d.TREEVIEW_ALTERNATE_BG, True)  # Alternate background per line.
              customgui.SetBool(c4d.TREEVIEW_CURSORKEYS, True)  # True if cursor keys should be processed.
              customgui.SetBool(c4d.TREEVIEW_NOENTERRENAME, False)  # Suppresses the rename popup when the user presses enter.
              customgui.SetBool(c4d.TREEVIEW_NO_MULTISELECT, True)
      
              self._treegui = self.AddCustomGui(1000, c4d.CUSTOMGUI_TREEVIEW, "", c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, 300,
                                                300, customgui)
              if not self._treegui:
                  print("[ERROR]: Could not create TreeView")
                  return False
      
              self.AddButton(1001, c4d.BFH_CENTER, name="Add")
              self.AddButton(1002, c4d.BFH_CENTER, name="Add Child to selected")
              return True
      
          def InitValues(self):
              # Initialize the column layout for the TreeView.
              layout = c4d.BaseContainer()
              layout.SetLong(ID_CHECKBOX, c4d.LV_CHECKBOX)
              layout.SetLong(ID_NAME, c4d.LV_TREE)
              layout.SetLong(ID_OTHER, c4d.LV_USER)
              self._treegui.SetLayout(3, layout)
      
              # Set the header titles.
              self._treegui.SetHeaderText(ID_CHECKBOX, "Check")
              self._treegui.SetHeaderText(ID_NAME, "Name")
              self._treegui.SetHeaderText(ID_OTHER, "Other")
              self._treegui.Refresh()
      
              # Set TreeViewFunctions instance used by our CUSTOMGUI_TREEVIEW
              self._treegui.SetRoot(self._treegui, self._listView, None)
              return True
      
          def Command(self, id, msg):
              # Click on button
              if id == 1001:
                  # Add data to our DataStructure (ListView)
                  newID = len(self._listView.listOfTexture) + 1
                  tex = TextureObject("T{}".format(newID))
                  self._listView.listOfTexture.append(tex)
      
                  # Refresh the TreeView
                  self._treegui.Refresh()
      
              elif id == 1002:
                  for parentTex in TextureObjectIterator(self._listView.listOfTexture):
                      if not parentTex.IsSelected:
                          continue
      
                      newID = len(parentTex.GetChildren()) + 1
                      tex = TextureObject("T{0}.{1}".format(str(parentTex), newID))
                      parentTex.AddChild(tex)
      
                  # Refresh the TreeView
                  self._treegui.Refresh()
      
              return True
      
      
      def main():
          global dialog
          dialog = TestDialog()
          dialog.Open(c4d.DLG_TYPE_ASYNC, defaulth=600, defaultw=600)
      
      
      if __name__ == "__main__":
          main()
      
      

      Thanks for your help

      posted in Cinema 4D SDK 2024 python
      chuanzhenC
      chuanzhen
    • RE: Switching of Multi Object Working Axis for Move Tools

      @ferdinand Thanks for reply. Perhaps not expressed clearly. For changing the axis of an object, it is not a problem. What I want to ask is whether the manual operation step of selecting the axis before the Move tool works can be implemented using a script.

      posted in Cinema 4D SDK
      chuanzhenC
      chuanzhen