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

    chuanzhen

    @chuanzhen

    rigger

    21
    Reputation
    416
    Profile views
    219
    Posts
    6
    Followers
    1
    Following
    Joined Last Online
    Location 北京

    chuanzhen Unfollow Follow

    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

    Latest posts made by chuanzhen

    • RE: How to obtain the object deformed by the deformer

      @ferdinand Thanks for detailed explanation.
      Let me introduce the goals that the custom deformer plugin wants to achieve. (As can be seen from the cube, cube. 1, cube. 2... in the image, each object has a weight tag.) The custom deformer plugin needs to preprocess and store some data before the ModifyObjects () function works. (By clicking a button) Access the weight tag of each object to be deformed in Message (), preprocess and store some data, and then use the preprocessed data to execute the ModifyObjects () function to correctly process the deformation calculation.
      9c418a15-9d3c-4466-83c2-0481e7b67c69-image.png

      In C4D, it seems that the Surface deformer has achieved a similar function
      5ef7303f-0ea2-4d3b-bed4-c342a755350c-image.png

      (there are certain benefits to restricting the custom deformer plugin only to the parent level, as there is no need to spend effort on correctly linking the corresponding preprocessed data when the ModifyObjects () function works.But it did break the general logic operation of the deformer)

      The only way you could do that is by checking each deformed object being passed into , to be the parent of the also passed in (i.e., the deformer also simply accessible via ). Only for an which is the parent of would you then carry out the modification.

      posted in Cinema 4D SDK
      chuanzhenC
      chuanzhen
    • RE: How to obtain the object deformed by the deformer

      @ferdinand Thank you for your detailed reply.
      If there is no direct method, it is a feasible solution to re implement the defoemer logic. However, since it requires storing data separately for each object that needs to be deformed, limiting the deformable device to only act on the parent object is a limited but more efficient method.

      posted in Cinema 4D SDK
      chuanzhenC
      chuanzhen
    • How to obtain the object deformed by the deformer

      Hi,
      deformer object can deform an object in two ways:
      method A as a child of the deformed object,
      method B at the same level as the deformed object.

      There is a problem. In a custom deformer plugin, I obtain the deformed object in the Message() function. Using the first method A, I can obtain the deformed object ''Cube. x'' through node. GetUp(). but method B, how can I access the deformed object (Cube, Cube. 1, Cube. 2)?
      4c727a8a-c175-4c4a-adf6-b6c94a183ec0-image.png

      Thanks for any help!

      posted in Cinema 4D SDK 2025 windows python
      chuanzhenC
      chuanzhen
    • RE: pythonsdk doc Matrix manunl error?

      @ferdinand Thank you for explanation. The point of confusion should be marked as 2 in the image. in doc the counterclockwise rotation (ccw) refers to the counterclockwise rotation from the spatial perspective of the image. but for the same rotation, the z-axis should have rotated clockwise(cw). However, in any case, the calculation is correct, only the description is different。
      (Describing a rotation of an axis, it is assumed that a person looks in the negative direction from the positive direction of the axis, and based on this, counterclockwise and clockwise are defined)

      posted in Cinema 4D SDK
      chuanzhenC
      chuanzhen
    • pythonsdk doc Matrix manunl error?

      Hi,
      When I read the matrix manual in python sdk doc, I found that the descriptions of 1 and 2 seem contradictory. In c4d, counter-clockwise rotation (ccw) displays a positive value 90 °, while clockwise rotation (cw) displays a negative value -90 °. However, in image marker 2, the transformation should be clockwise cw 90 ° (i.e. R.B=-90 °), not ccw90 °
      d52ff3e3-4c20-4f0a-a6eb-e20f2284dba3-image.png

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