# Solved 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.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)

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