Transforms to Delta Transforms

* Added new operators to take the current transform value (loc/rot/scale or all 3)
  and convert/apply that transform to a corresponding delta transform value. By default,
  the transform value will be zeroed out again afterwards, so you don't end up with a
  double transform.

* These operators can be found in the "Apply" menu (Ctrl-A)

* The "Animated Transforms to Deltas" (which does a similar job, except it adjusts all
  existing animation data instead of the current transform) has also been moved to the
  Apply menu (it was in the Transform menu instead)
This commit is contained in:
Joshua Leung 2016-07-04 12:52:51 +12:00
parent 92c9bdbbb9
commit 2ba2860e11
2 changed files with 91 additions and 4 deletions

View File

@ -685,6 +685,88 @@ class ClearAllRestrictRender(Operator):
return {'FINISHED'}
class TransformsToDeltas(Operator):
"""Convert normal object transforms to delta transforms, """ \
"""any existing delta transforms will be included as well"""
bl_idname = "object.transforms_to_deltas"
bl_label = "Transforms to Deltas"
bl_options = {'REGISTER', 'UNDO'}
mode = EnumProperty(
items=(('ALL',
"All Transforms",
"Transfer location, rotation, and scale transforms",
),
('LOC',
"Location",
"Transfer location transforms only",
),
('ROT',
"Rotation",
"Transfer rotation transforms only",
),
('SCALE',
"Scale",
"Transfer scale transforms only",
),
),
name="Mode",
description="Which transforms to transfer",
default='ALL',
)
reset_values = BoolProperty(
name="Reset Values",
description=("Clear transform values after transferring to deltas"),
default=True,
)
@classmethod
def poll(cls, context):
obs = context.selected_editable_objects
return (obs is not None)
def execute(self, context):
for obj in context.selected_editable_objects:
if self.mode in ('ALL', 'LOC'):
self.transfer_location(obj)
if self.mode in ('ALL', 'ROT'):
self.transfer_rotation(obj)
if self.mode in ('ALL', 'SCALE'):
self.transfer_scale(obj)
return {'FINISHED'}
def transfer_location(self, obj):
obj.delta_location += obj.location
if self.reset_values:
obj.location.zero()
def transfer_rotation(self, obj):
# TODO: add transforms together...
if obj.rotation_mode == 'QUATERNION':
obj.delta_rotation_quaternion += obj.rotation_quaternion
if self.reset_values:
obj.rotation_quaternion.identity()
elif obj.rotation_mode == 'AXIS_ANGLE':
pass # Unsupported
else:
delta = obj.delta_rotation_euler.copy()
obj.delta_rotation_euler = obj.rotation_euler.copy()
obj.delta_rotation_euler.rotate(delta)
if self.reset_values:
obj.rotation_euler.zero()
def transfer_scale(self, obj):
obj.delta_scale += obj.scale
if self.reset_values:
obj.scale[:] = (1, 1, 1)
class TransformsToDeltasAnim(Operator):
"""Convert object animation for normal transforms to delta transforms"""
bl_idname = "object.anim_transforms_to_deltas"

View File

@ -296,10 +296,6 @@ class VIEW3D_MT_transform_object(VIEW3D_MT_transform_base):
layout.operator("object.randomize_transform")
layout.operator("object.align")
layout.separator()
layout.operator("object.anim_transforms_to_deltas")
# Armature EditMode extensions to Transform menu
class VIEW3D_MT_transform_armature(VIEW3D_MT_transform_base):
@ -1507,6 +1503,15 @@ class VIEW3D_MT_object_apply(Menu):
props = layout.operator("object.transform_apply", text="Rotation & Scale", text_ctxt=i18n_contexts.default)
props.location, props.rotation, props.scale = False, True, True
layout.separator()
layout.operator("object.transforms_to_deltas", text="Location to Deltas", text_ctxt=i18n_contexts.default).mode = 'LOC'
layout.operator("object.transforms_to_deltas", text="Rotation to Deltas", text_ctxt=i18n_contexts.default).mode = 'ROT'
layout.operator("object.transforms_to_deltas", text="Scale to Deltas", text_ctxt=i18n_contexts.default).mode = 'SCALE'
layout.operator("object.transforms_to_deltas", text="All Transforms to Deltas", text_ctxt=i18n_contexts.default).mode = 'ALL'
layout.operator("object.anim_transforms_to_deltas")
layout.separator()
layout.operator("object.visual_transform_apply", text="Visual Transform", text_ctxt=i18n_contexts.default)