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

    Best posts made by chuanzhen

    • RE: ObjectData plugin Draw() question

      Hi,in another post I found a way to achieve my goal of converting the coordinate position to camera space and then scaling it to a small size so that he appears first.

      this is new code:

      def Draw(self,op, drawpass, bd, bh):
          
          
          if not op[c4d.S_MOTIONTRAIL_GTWO_DRAWENABLE]:
              return c4d.DRAWRESULT_OK
          #bd.SetMatrix_Matrix(None, c4d.Matrix())
          pmg = ~bd.GetMg()
          bd.SetMatrix_Camera()
      
          all_pos = self.parameters['all_pos']
          color_lis = self.parameters['color_lis']
          point_size = op[c4d.S_MOTIONTRAIL_GTWO_POINTSIZE]
          bd.SetPointSize(point_size)
          for per_pos,color in zip(all_pos,color_lis):
              bd.SetPen(color)
              cnt = len(per_pos)
              temp_lis = []
              for i in xrange(cnt-1):
                  c = (pmg * per_pos[i]).GetNormalized() * 20
                  f = (pmg * per_pos[i+1]).GetNormalized() * 20
                  bd.DrawLine(c,f,c4d.NOCLIP_D)
                  temp_lis.append(c)
              temp_lis.append(f)
              bd.DrawPoints(temp_lis)
          
      
          return c4d.DRAWRESULT_OK
      

      why * 20 will work, * 1or 2 not work (c = (pmg * per_pos[i]).GetNormalized() * 20)?

      posted in Cinema 4D SDK
      chuanzhenC
      chuanzhen
    • RE: GeUserArea use DrawBitmap() to overlay multiple images(has alpha)

      I found a solution in other posts, and this is an video example:

      example code:

      
      import c4d
      
      from c4d import bitmaps,gui
      
      
      
      
      
      class DraggingArea(c4d.gui.GeUserArea):
          def __init__(self):
              self.startx = 0
              self.starty = 0
      
          def DrawMsg(self, x1, y1, x2, y2, msg):
      
      
              # Initializes draw region
              self.OffScreenOn()
              self.SetClippingRegion(x1, y1, x2, y2)
              icon_bmp = bitmaps.InitResourceBitmap(5159)
              icon_clip = bitmaps.GeClipMap()
              icon_clip.InitWithBitmap(icon_bmp,icon_bmp.GetInternalChannel())
      
              clip = bitmaps.GeClipMap()
              w,h = self.GetWidth(),self.GetHeight()
              clip.Init(w,h)
              clip.BeginDraw()
              clip.SetColor(0,0,180)
              clip.FillRect(0,0,w,int(h*0.4))
              clip.SetColor(180,0,0)
              clip.FillRect(0,int(h*0.4),w,h)
      
              clip.SetDrawMode(c4d.GE_CM_DRAWMODE_BLEND,255)
              clip.Blit(self.startx,self.starty,icon_clip,0,0,icon_clip.GetBw(),icon_clip.GetBh(),c4d.GE_CM_BLIT_COL)
      
      
              clip.EndDraw()
              # Get default Background color
              bmp = clip.GetBitmap()
              self.DrawBitmap(bmp,0,0,w,h,0,0,w,h,c4d.BMP_NORMAL)
      
      
      
      
          def InputEvent(self, msg):
              """
              Called by Cinema 4D, when there is a user interaction (click) on the GeUserArea.
              This is the place to catch and handle drag interaction.
      
              :param msg: The event container.
              :type msg: c4d.BaseContainer
              :return: True if the event was handled, otherwise False.
              :rtype: bool
              """
              # Do nothing if its not a left mouse click event
              if msg[c4d.BFM_INPUT_DEVICE] != c4d.BFM_INPUT_MOUSE and msg[c4d.BFM_INPUT_CHANNEL] != c4d.BFM_INPUT_MOUSELEFT:
                  return True
      
              # Retrieves the initial position of the click
              mouseX = msg[c4d.BFM_INPUT_X]
              mouseY = msg[c4d.BFM_INPUT_Y]
              mouse_pos_dict = self.Global2Local()
              x, y = mouse_pos_dict['x'] + msg.GetInt32(c4d.BFM_INPUT_X), mouse_pos_dict['y'] + msg.GetInt32(
                  c4d.BFM_INPUT_Y)  
              self.startx = x
              self.starty = y
      
              # Initializes the start of the dragging process (needs to be initialized with the original mouseX, mouseY).
              self.MouseDragStart(c4d.KEY_MLEFT, mouseX, mouseY, c4d.MOUSEDRAGFLAGS_DONTHIDEMOUSE | c4d.MOUSEDRAGFLAGS_NOMOVE)
              isFirstTick = True
      
              # MouseDrag needs to be called all time to update information about the current drag process.
              # This allow to catch when the mouse is released and leave the infinite loop.
              while True:
      
                  # Updates the current mouse information
                  result, deltaX, deltaY, channels = self.MouseDrag()
                  if result != c4d.MOUSEDRAGRESULT_CONTINUE:
                      break
      
                  # The first tick is ignored as deltaX/Y include the mouse clicking behavior with a deltaX/Y always equal to 4.0.
                  # However it can be useful to do some initialization or even trigger single click event
                  if isFirstTick:
                      isFirstTick = False
                      continue
      
                  # If the mouse didn't move, don't need to do anything
                  if deltaX == 0.0 and deltaY == 0.0:
                      continue
      
                  # Updates mouse position with the updated delta
                  mouseX -= deltaX
                  mouseY -= deltaY
                  x -= deltaX
                  y -= deltaY
                  self.startx = int(x)
                  self.starty = int(y)
      
      
      
      
                  # Redraw the GeUserArea (it will call DrawMsg)
                  self.Redraw()
      
              # Asks why we leave the while loop
              endState = self.MouseDragEnd()
      
      
      
              return True
      
      
      class MyDialog(c4d.gui.GeDialog):
          """
          Creates a Dialog with only a GeUserArea within.
          """
      
          def __init__(self):
              # It's important to stores our Python implementation instance of the GeUserArea in class variable,
              # This way we are sure the GeUserArea instance live as long as the GeDialog.
              self.area = DraggingArea()
      
          def CreateLayout(self):
              """
              This method is called automatically when Cinema 4D Create the Layout (display) of the Dialog.
              """
              self.AddUserArea(1000, c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT)
              self.AttachUserArea(self.area, 1000)
              return True
      
      
      def main():
          # Creates a new dialog
          dialog = MyDialog()
      
          # Opens it
          dialog.Open(dlgtype=c4d.DLG_TYPE_MODAL_RESIZEABLE, defaultw=500, defaulth=500)
      
      
      if __name__ == '__main__':
          main()
      

      posted in Cinema 4D SDK
      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
    • RE: Discussions about spline ik

      @r_gigante @zipit
      The detailed explanation is shown below
      “up interpolattion”
      reback_01.png
      reback_02.png
      Try use "spline trail"
      reback_03.png

      I read some papers, but always been very slow, just only expanded know, such as Frenet–Serret formulas etc. But I did not directly find a better way to replace my current method, and I have been looking for it.

      Computation of Rotation Minimizing Frames This seems to be a good paper, I will read it carefully.

      posted in General Talk
      chuanzhenC
      chuanzhen
    • RE: Some questions about PSD correction

      @m_adam Thank you for your team's reply.
      I will share my exploration in this post in the future.☺

      posted in Cinema 4D SDK
      chuanzhenC
      chuanzhen
    • RE: Viewport render always causing c4d stop running

      The problem has been resolved, reinstall the graphics driver and perform a custom clean installation!

      posted in General Talk
      chuanzhenC
      chuanzhen
    • RE: Is there any way to check deformcache dirty

      try use GetDirty(DIRTYFLAGS_CACHE),compare last dirty and current dirty

      posted in Cinema 4D SDK
      chuanzhenC
      chuanzhen
    • RE: Discussion on Methods for Calculating the Inner Points of a Quadrilateral

      @i_mazlov Thank you for your detailed reply, it was really helpful!
      The following video shows the results, which work well. The blue polygon uses GetPolyPointST()

      posted in General Talk
      chuanzhenC
      chuanzhen
    • RE: Method to access CAMorphNode pointdata reference index?

      Hi,
      you can read this thread

      posted in Cinema 4D SDK
      chuanzhenC
      chuanzhen
    • RE: Discussion on Methods for Calculating the Inner Points of a Quadrilateral

      Hi @i_mazlov
      Through exploring these two pages,page1,page2, I have converted them into Python code Inverse_Bilinear_Interpolation(), which can replace GetPolyPointST(). I am not sure why GetPolyPointST() may obtain incorrect values in certain situations, but Inverse_Bilinear_Interpolation() does not go wrong in complex situations.

      video use Inverse_Bilinear_Interpolation()

      code:

      import math
      
      
      # algorithm_InverseBilinearInterpolation 逆双线性插值 的算法
      
      def Wedge2D(v:c4d.Vector,w:c4d.Vector):
          return v[0] * w[1] - v[1] * w[0]
      
      def Inverse_Bilinear_Interpolation(p:c4d.Vector,p0:c4d.Vector,p1:c4d.Vector,p3:c4d.Vector,p2:c4d.Vector):
      
          """
          注意对点顺序的定义
          Attention :  points Order
      
          p2 --- p3
          |      |
          |      |
          p0 --- p1
      
          """
      
          q = p - p0
          b1 = p1 - p0
          b2 = p2 - p0
          b3 = p0 - p1 - p2 + p3
      
          A = Wedge2D(b2,b3)
          B = Wedge2D(b3,q) - Wedge2D(b1,b2)
          C = Wedge2D(b1,q)
          # 求V - solve v
          if abs(A) < 0.00000001:
              v = -C / B
          else:
              discrim = B * B - 4.0 * A * C
              v = 0.5 * (-B - math.sqrt(discrim)) / A  # CCW
              #v = 0.5 * (-B + math.sqrt(discrim)) / A  # CW
      
          # 求 u - solve u
          denom = b1 + v * b3
      
          if abs(denom[0]) > abs(denom[1]):
              u = (q[0] - b2[0] * v) / denom[0]
          else:
              u = (q[1] - b2[1] * v) / denom[1]
      
          return u,v
      # example use CPolygon point position a,b,c,d, and point p in quard(CPolygon)
      # u,v = Inverse_Bilinear_Interpolation(p,a,b,c,d)
      

      sample file: custom-quadrilateral.c4d

      But for the code part, there are still some doubts about the difference between CCW and CW. When I understand what's going on, I will come back and reply. If any friend can explain, that's the best!

      posted in General Talk
      chuanzhenC
      chuanzhen
    • python sdk document error

      Hi,
      i read python sdk BaseContainer.FindIndex() return a bool but actually return a dict

      xxx.png

      posted in Cinema 4D SDK python
      chuanzhenC
      chuanzhen
    • RE: how to Scroll UserArea

      This is the sample code, I tried to dynamically create the element inside the group to achieve, the picture is not drawn completely as expected:

      import c4d
      import os
      import sys
      from c4d import gui,bitmaps,plugins,utils,modules,storage
      
      
      PLUGIN_ID = 10000000 #only for test
      
      
      
      GROUP_SCROLL = 1100
      USEEAREA_GROUP = 1102
      USERAREA = 1101
      
      ADD_BUTTON = 1200
      
      class PreViewArea(gui.GeUserArea):
          bmp = None
      
      
          def DrawMsg(self,x1, y1, x2, y2, msg):
              self.OffScreenOn()
              self.SetClippingRegion(x1, y1, x2, y2)
              BG_colorDict = self.GetColorRGB(c4d.COLOR_BG)
              BG_color = c4d.Vector(BG_colorDict['r'], BG_colorDict['g'], BG_colorDict['b']) / 255.0
              self.DrawSetPen(BG_color)
              self.DrawRectangle(x1, y1, x2, y2)
      
              if self.bmp:
                  width = self.bmp.GetBw()
                  height = self.bmp.GetBh()
                  self.DrawBitmap(self.bmp, 0, 0, width, height, 0, 0, width, height, c4d.BMP_NORMAL)
      
      def dynamic_Group(dialog,ua):
          dialog.LayoutFlushGroup(USEEAREA_GROUP)
      
          if ua.bmp:
              width = ua.bmp.GetBw()
              height = ua.bmp.GetBh()
          else:
              width,height = 0,0
          dialog.AddUserArea(USERAREA, c4d.BFH_SCALE | c4d.BFV_SCALE,width,height)
          dialog.AttachUserArea(ua, USERAREA)
          dialog.LayoutChanged(USEEAREA_GROUP)
      
      class S_Lib_Dialog(gui.GeDialog):
          ua = PreViewArea()
      
      
          def CreateLayout(self):
              self.SetTitle("test")
              self.ScrollGroupBegin(PLUGIN_ID, c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, c4d.SCROLLGROUP_HORIZ | c4d.SCROLLGROUP_VERT)
              self.GroupBegin(USEEAREA_GROUP,c4d.BFH_LEFT | c4d.BFV_TOP,1,1)
              self.GroupBorder(c4d.BORDER_ACTIVE_1)
              self.AddUserArea(USERAREA, c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT)
              self.AttachUserArea(self.ua, USERAREA)
              self.GroupEnd()
      
              self.GroupEnd()
              self.AddButton(ADD_BUTTON,c4d.BFH_SCALEFIT,150,30,"Load image")
      
      
              return True
      
          def Command(self, id, msg):
              if id == ADD_BUTTON:
                  path = storage.LoadDialog(type=c4d.FILESELECTTYPE_IMAGES)
                  if path:
                      bmp = bitmaps.BaseBitmap()
                      result,ismovie = bmp.InitWith(path)
                      if result == c4d.IMAGERESULT_OK:
                          self.ua.bmp = bmp
                          dynamic_Group(self, self.ua)
                          self.ua.Redraw()
                      else:
                          print("Load image Fail")
                  else:
                      print("Not select image")
      
      
      
                  return True
      
              return True
      
      
      
      
      
      
      class S_Lib(plugins.CommandData):
      
          dialog = None
      
          def Execute(self,doc):
              # create the dialog
              if self.dialog is None:
                  self.dialog = S_Lib_Dialog()
      
              return self.dialog.Open(dlgtype=c4d.DLG_TYPE_ASYNC, pluginid=PLUGIN_ID, defaultw=800, defaulth=400)
      
          def RestoreLayout(self, sec_ref):
              # manage nonmodal dialog
              if self.dialog is None:
                  self.dialog = S_Lib_Dialog()
      
              return self.dialog.Restore(pluginid=PLUGIN_ID, secret=sec_ref)
      
      
      # Execute main()
      if __name__=='__main__':
          path, fn = os.path.split(__file__)
          plugins.RegisterCommandPlugin(id=PLUGIN_ID,
                                        str="test",
                                        info=0,
                                        help="",
                                        dat=S_Lib(),
                                        icon=None)
      
      
      posted in Cinema 4D SDK
      chuanzhenC
      chuanzhen
    • RE: c4d 2024 "MENURESOURCE_SEPERATOR"

      @ferdinand Thanks,hope to fix spelling in c4dpython doc in future versions

      posted in Cinema 4D SDK
      chuanzhenC
      chuanzhen
    • 2024 c4d python doc link error

      Hi,
      online and offline 2024 c4d python doc link error, not find file
      0ba012b1-0e2e-453a-8370-fad6b0fcda06-image.png

      posted in Cinema 4D SDK python 2024
      chuanzhenC
      chuanzhen
    • GV Node AddPort fail

      This is my code,but it is not work

      def main():
          xp = op.GetTag(c4d.Texpresso)
          m = xp.GetNodeMaster()
          root = m.GetRoot()
          one = m.CreateNode(root,c4d.ID_OPERATOR_OBJECT)
          one[c4d.GV_OBJECT_OBJECT_ID] = op
          one.AddPort(c4d.GV_PORT_OUTPUT,c4d.GV_OBJECT_OPERATOR_OBJECT_OUT,message=True)
          c4d.EventAdd()
      

      image
      test.png

      Thanks for any help!

      posted in Cinema 4D SDK python r19
      chuanzhenC
      chuanzhen
    • RE: restore weight to BaseContainer and get it Vs Direct get weight from weight Tag

      @m_adam Wow, I learned some tricks from your code! ( so important to me)
      Thank you very much for your optimization and testing of your personal time, which is very helpful to me!
      (C++ is so fast)

      posted in Cinema 4D SDK
      chuanzhenC
      chuanzhen
    • After undo, point object SetAllPoints not update

      Hi,
      I encountered a problem. When I set the position of an object's point, however, when I undo it and set it again, the object does not refresh in time. Only if I click on the object again and set it again will it be refreshed in time.

      This is the video,

      This is simple code:

      
      
      import c4d
      import os
      import sys
      from c4d import gui,bitmaps,plugins,utils,modules
      
      
      PLUGIN_ID = 10000001
      
      
      class S_test_Dialog(gui.GeDialog):
      
      
          def CreateLayout(self):
              self.SetTitle("test")
      
      
              self.GroupBegin(1000,c4d.BFH_SCALEFIT,4,0)
      
              self.AddStaticText(1003, c4d.BFH_RIGHT, 80, 20, "  Target ")
              bc = c4d.GetCustomDataTypeDefault(c4d.DTYPE_BASELISTLINK)
              self.AddCustomGui(1004, c4d.CUSTOMGUI_LINKBOX, "", c4d.BFH_SCALEFIT, 300, 0, bc)
      
              self.GroupEnd()
      
              self.AddButton(1010, c4d.BFH_SCALEFIT, 150, 30, "ChangePoints")
      
      
      
              return True
      
      
      
          def Command(self, id, msg):
      
              if id == 1010:
                  doc = c4d.documents.GetActiveDocument()
      
                  target = self.FindCustomGui(1004, c4d.CUSTOMGUI_LINKBOX).GetData()
      
                  all_p = target.GetAllPoints()
                  for id,pos in enumerate(all_p):
                      all_p[id] = c4d.Vector(0)
      
                  doc.StartUndo()
                  doc.AddUndo(c4d.UNDOTYPE_CHANGE,target)
                  target.SetAllPoints(all_p)
                  target.Message(c4d.MSG_UPDATE)
                  doc.EndUndo()
                  c4d.EventAdd()
      
                  return True
      
      
      
      
              return True
      
      
      
      
      
      
      class S_test(plugins.CommandData):
      
          dialog = None
      
          def Execute(self,doc):
              # create the dialog
              if self.dialog is None:
                  self.dialog = S_test_Dialog()
      
              return self.dialog.Open(dlgtype=c4d.DLG_TYPE_ASYNC, pluginid=PLUGIN_ID, defaultw=400, defaulth=100)
      
          def RestoreLayout(self, sec_ref):
              # manage nonmodal dialog
              if self.dialog is None:
                  self.dialog = S_test_Dialog()
      
              return self.dialog.Restore(pluginid=PLUGIN_ID, secret=sec_ref)
      
      
      # Execute main()
      if __name__=='__main__':
          path, fn = os.path.split(__file__)
      
          plugins.RegisterCommandPlugin(id=PLUGIN_ID,
                                        str="S_test",
                                        info=0,
                                        help="",
                                        dat=S_test(),
                                        icon=None)
      
      
      
      

      Thanks for any help!

      posted in Cinema 4D SDK 2024 python
      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