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
    • Recent
    • Tags
    • Users
    • Login
    The Maxon SDK Team is currently short staffed due to the winter holidays. No forum support is being provided between 15/12/2025 and 5/1/2026. For details see Maxon SDK 2025 Winter Holidays.

    Problem on Freezing and Parenting objects (i.e. Double Transformations)

    Scheduled Pinned Locked Moved Cinema 4D SDK
    r20python
    3 Posts 2 Posters 530 Views 1 Watching
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • B Offline
      bentraje
      last edited by

      Hi,

      I'm trying to create a script that

      1. Creates a control spline and freezes it
      2. Parents the control to another object and freezes it.

      They all work okay when executed independently but when run together they somehow produce a double transform (especially with the parent and freeze function)

      You can see the illustration of the problem here:
      https://www.dropbox.com/s/zs966vk9jokhqfy/c4d086_parent_freeze_python.jpg?dl=0

      You can also see the working code below.

      Is there a way around this? Thank you for looking at the problem.

      import c4d
      
      
      # Creates a control spline and freezes it
      # Parents the control to another object and freezes it. 
      
      
      def freeze_PSR(obj, pos=True, scale=True, rot=True):
          
          matrix = obj.GetMg()
          
          if pos==True:
              obj.SetFrozenPos(matrix.off)
              obj.SetRelPos(c4d.Vector(0))
              
          if scale==True:
              obj.SetFrozenScale(c4d.Vector(matrix.v1.GetLength(),
                                           matrix.v2.GetLength(),
                                           matrix.v3.GetLength()
                                          )
                                )
              obj.SetRelScale(c4d.Vector(1))
              
          if rot==True:
              obj.SetFrozenRot(c4d.utils.MatrixToHPB(matrix))
              obj.SetRelRot(c4d.Vector(0))
              
          else:
              pass
      
      def parent(children, parent):
      
          pos = children.GetMg()
          children.InsertUnder(parent)
          children.SetMg(pos)
          freeze_PSR(children)
      
      def create_control (move, name):
          
          control = c4d.BaseObject(c4d.Osplinecircle)
          control[c4d.PRIM_CIRCLE_RADIUS] = 30
          control[c4d.ID_BASEOBJECT_REL_POSITION,c4d.VECTOR_Z]=move
          control[c4d.PRIM_PLANE]=0
          doc.InsertObject(control)
          control[c4d.ID_BASELIST_NAME]=name
      
          freeze_PSR(control)
      
          return control
      
      shoulder = create_control (50, "shoulder")
      elbow = create_control (100, "elbow")
      wrist = create_control (150, "wrist")
      
      parent (elbow, shoulder)
      parent (wrist, elbow)
      
      c4d.EventAdd()
      
      1 Reply Last reply Reply Quote 0
      • M Offline
        m_adam
        last edited by

        Hi @bentraje, it seems you confuse you a bit since every coordinate you express in your scripts are expressed in World Space, while object always expects Local Space.
        So typically what's should be done it's the creation to occurs in WorldSpace.
        But the Parenting operation should take care of the local Space.

        import c4d
        
        
        # Creates a control spline and freezes it
        # Parents the control to another object and freezes it. 
        
        
        def freeze_PSR(obj, pos=True, scale=True, rot=True):
            # Instead of retrieveing the global matrice, you should retrive the matrice relative to the parent one.
            matrix = obj.GetMln()
            
            if pos==True:
                obj.SetFrozenPos(matrix.off)
                obj.SetRelPos(c4d.Vector(0))
                
            if scale==True:
                obj.SetFrozenScale(c4d.Vector(matrix.v1.GetLength(),
                                             matrix.v2.GetLength(),
                                             matrix.v3.GetLength()
                                            )
                                  )
                obj.SetRelScale(c4d.Vector(1))
                
            if rot==True:
                obj.SetFrozenRot(c4d.utils.MatrixToHPB(matrix))
                obj.SetRelRot(c4d.Vector(0))
                
            else:
                pass
        
        def parent(children, parent):
        
            pos = children.GetMg()
            children.InsertUnder(parent)
            children.SetMg(pos)
            freeze_PSR(children)
        
        def create_control (move, name):
            
            control = c4d.BaseObject(c4d.Osplinecircle)
            control[c4d.PRIM_CIRCLE_RADIUS] = 30
            control[c4d.ID_BASEOBJECT_REL_POSITION,c4d.VECTOR_Z]=move
            control[c4d.PRIM_PLANE]=0
            doc.InsertObject(control)
            control[c4d.ID_BASELIST_NAME]=name
        
            # Since there are no parents it's no sense to freeze the transform
            # freeze_PSR(control)
        
            return control
        
        # Express position in global space here
        shoulder = create_control (0, "shoulder")
        elbow = create_control (50, "elbow")
        wrist = create_control (100, "wrist")
        
        parent (elbow, shoulder)
        parent (wrist, elbow)
        
        c4d.EventAdd()
        ```
        Cheers,
        Maxime.

        MAXON SDK Specialist

        Development Blog, MAXON Registered Developer

        1 Reply Last reply Reply Quote 3
        • B Offline
          bentraje
          last edited by

          @m_adam

          Interesting. I never thought of doing it that way.
          Thanks for the response. It works as expected.

          Have a great day ahead!

          1 Reply Last reply Reply Quote 0
          • First post
            Last post