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



  • 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()
    


  • 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.


  • @m_adam

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

    Have a great day ahead!


Log in to reply