freeze transformation by using delta transform

I noticed the delta transform in the object panel, and I didn’t find any instruction about how to use it and what it is for… but it looks like we can use it to create a freeze transformation like maya. And since I could find a way to use it, I created this python script.

I’m really new to python scripting, I come from maya and mel, so I’m sure we can make it a lot more simple.

Anyway, I just wanted to share it.

#using delta transform...
#looks like a freeze transformation to me


import bpy
import math

#location
bpy.context.active_object.delta_location+=bpy.context.active_object.location
bpy.context.active_object.location=[0,0,0]


#rotation X
rotX=(math.degrees(bpy.context.active_object.rotation_euler.x))
rotDeltaX=(math.degrees(bpy.context.active_object.delta_rotation_euler.x))
bpy.context.active_object.rotation_euler.x=0
bpy.context.active_object.delta_rotation_euler.x=math.radians(rotX)+math.radians(rotDeltaX)

#rotation Y
rotY=(math.degrees(bpy.context.active_object.rotation_euler.y))
rotDeltaY=(math.degrees(bpy.context.active_object.delta_rotation_euler.y))
bpy.context.active_object.rotation_euler.y=0
bpy.context.active_object.delta_rotation_euler.y=math.radians(rotY)+math.radians(rotDeltaY)

#rotation Z
rotZ=(math.degrees(bpy.context.active_object.rotation_euler.z))
rotDeltaZ=(math.degrees(bpy.context.active_object.delta_rotation_euler.z))
bpy.context.active_object.rotation_euler.z=0
bpy.context.active_object.delta_rotation_euler.z=math.radians(rotZ)+math.radians(rotDeltaZ)

#scale
bpy.context.active_object.delta_scale+=bpy.context.active_object.scale
bpy.context.active_object.delta_scale.x-=1
bpy.context.active_object.delta_scale.y-=1
bpy.context.active_object.delta_scale.z-=1
bpy.context.active_object.scale=[1,1,1]

welcome, the purpose of that tab is to offset animated copies of an object I think…

thank you for the welcome liero, and that’s true, you can offset easily an animated object this way… that’s cool. So if we use if to freeze the transformation, the only thing when you want offset an animation is that instead of having every thing at 0 for the location, it will already have some value…

it seems that it’s not really working in fact with the rotation, the first time it works but not after… because of the gimbal… the delta transform does not affect the gimbal, so for the rotation, it’s better to use the Ctrl A rotation

but it seems that it’s working nicely for the location and with the scale.

so here is the code to have the button in the tool panel of the 3d View… and the freeze rotation is already changed for the apply.rotation (the Ctrl+A/rotation)


import bpy


class OBJECT_PT_pingpong(bpy.types.Panel):
    bl_space_type = "VIEW_3D"
    bl_region_type = "TOOLS"
    bl_context = "objectmode"
    bl_label = "Freeze Transformation"
    
    
    def draw_header(self, context):
        layout = self.layout
        layout.label(text="", icon="PROP_ON")
    
    def draw(self, context):
        layout = self.layout
        row = layout.row()
        row.operator("fz_loc", text="freeze location")
        row = layout.row()
        row.operator("fz_rot", text="freeze rotation")
        row = layout.row()
        row.operator("fz_sc", text="freeze scale")
        
  


class OBJECT_OT_FREEZE(bpy.types.Operator):
    bl_label = "freeze location operator"
    bl_idname = "fz_loc"
    bl_description = "freeze location"


    def invoke(self, context, event):
        import bpy
        bpy.context.active_object.delta_location+=bpy.context.active_object.location
        bpy.context.active_object.location=[0,0,0]
        return{"FINISHED"}
    
 
class OBJECT_OT_FREEZE(bpy.types.Operator):
    bl_label = "freeze rotation operator"
    bl_idname = "fz_rot"
    bl_description = "freeze rotation"


    def invoke(self, context, event):
        bpy.ops.object.rotation_apply()
        
        return{"FINISHED"}
    
class OBJECT_OT_FREEZE(bpy.types.Operator):
    bl_label = "freeze scale operator"
    bl_idname = "fz_sc"
    bl_description = "freeze scale"


    def invoke(self, context, event):
        import bpy
        #scale
        bpy.context.active_object.delta_scale+=bpy.context.active_object.scale
        bpy.context.active_object.delta_scale.x-=1
        bpy.context.active_object.delta_scale.y-=1
        bpy.context.active_object.delta_scale.z-=1
        bpy.context.active_object.scale=[1,1,1]
        return{"FINISHED"}


hi mathiasa

thanks for the script … freeze transform works similar to maya… only screws up rotation when rotated with manupilator.(as you said the gimbal issue ). Most of the maya animator use manupilator to animate… if there are minor gimbal issues use of euler filter fixes it, i am yet to discover such feature in blender.
i ran the script the first one works, for the button i ran the script, the script didnt show any errors but also didnt give any button in the tools panel… what should i do …

i am a maya animator and rigger …with very basic knowledge of mel… but at the same time i keep exploring blender.

thank you sangramdange

I’m like you discovering blender and getting so excited about it…

For the script, just to make sure, the buttons should appear on the left panel in the 3d views when you are in object mode. under the Objects tools. If it doesn’t work, I really don’t know what’s wrong for now, especially if it doesn’t give any error.

thank you again and I hope this script will be useful for you.

Mathias.

Sorry for reviving this old thread (didn’t think another was needed).

Hi mathias, I had the same thought. I know someone transitioning from Maya, and he misses freeze transform. So, I’ve written this little python file to help. It does exactly what you suggested above, but only for location (rotation and scale are just applied as normal).

Just in case anyone is wondering, freeze transform (in Maya) works slightly differently from apply tranforms (in blender). With freeze in Maya the rotate pivot isn’t reset to the origin of the scene (as with apply location in blender). Instead it stays where it is but all translates are zeroed out. Essentially you can have an object in somewhere in the scene with a zeroed location, and the origin at the center of the geometry (not back at the origin). Rotate and scale work the same way. This script does this by transferring the objects current location into delta transform (which is acting as an offset, while it’s location it set back to 0 0 0)

I don’t know how useful this would be to anyone (if at all, as most blender users are used to this way of working), but I’ve pasted the python in below. You should be able to install as an addon as normal. This is the limit of my python knowledge, so sorry if there any issues with it.

bl_info = {    "name": "Freeze Transform",
    "description": "Adds Freeze transform to the Apply transforms menu (Ctrl A).  Mimics Maya's freeze transform.  The location is transferred to Delta transform and the current location is zeroed",
    "author": "kettlefish",
    "version": (1, 0),
    "blender": (2, 74, 0),
    "location": "View3D > Object > Apply",
    "warning": "", 
    "wiki_url": "",
    "category": "Object"}


#   Adds Freeze transform to apply transform menu
#   
#   Mimics Maya's freeze transform by transfering location attributes to Delta transform and applying scale and rotation.
#   Differs from apply location because rotation pivot will remain at original location rather than
#   snapping to scene origin while location attributes are zeroed out.   




import bpy


def main (context):
    bpy.context.active_object.delta_location+=bpy.context.active_object.location
    bpy.context.active_object.location=[0,0,0]
    bpy.ops.object.transform_apply(location=False, rotation = True, scale = True)


class freezeLocation(bpy.types.Operator):
    """Applies current Location to Delta transform"""
    bl_idname = "object.freezelocation"
    bl_label = "Freeze Transforms"


    def execute(self, context):
        main (context)
        return {'FINISHED'}


def menu_func(self, context):
    self.layout.operator ("object.freezelocation", text="Freeze Transforms")
        
def register():
    bpy.utils.register_class(freezeLocation)
    bpy.types.VIEW3D_MT_object_apply.append(menu_func)




def unregister():
    bpy.utils.unregister_class(freezeLocation)
    bpy.types.VIEW3D_MT_object_apply.remove(menu_func)




if __name__ == "__main__":
    register()



Of course this can cause problems if you want to apply the location later, and I don’t imagine it’ll work very well with physics but thought I’d share it. Personally I don’t really see the need for it but, it kinda works :slight_smile:

wow… yeah, this is an old post!!! lol
When I started rigging in blender, I was a bit lost… not finding the freeze transform, but now that I understand how it works with armature, I don’t use that anymore! :slight_smile:
but thank you for posting it kettlefish

Mathias.