Skip to content

Instantly share code, notes, and snippets.

@JacRossiter
Last active December 12, 2019 17:32
Show Gist options
  • Save JacRossiter/8a1d25366769d96fc92157074564afa8 to your computer and use it in GitHub Desktop.
Save JacRossiter/8a1d25366769d96fc92157074564afa8 to your computer and use it in GitHub Desktop.
Add tools to Link Object and Apply menu. (Copy transforms and apply deltas)
bl_info = {
"name" : "JLink: Link Transforms",
"author" : "Jac Rossiter",
"description" : "Adds to Object Link and Apply menus",
"blender" : (2, 81, 0),
"version" : (0, 0, 0, 5),
"warning" : "",
"category" : "Object"
}
import bpy
import mathutils
from bpy.types import Panel, Operator
class LinkLocation_Operator(Operator):
bl_idname = "link.location"
bl_label = "Link Location"
bl_description = "............."
bl_options = {'REGISTER'}
def execute(self, context):
active_location = bpy.context.view_layer.objects.active.location
for obj in bpy.context.selected_objects:
try:
bpy.context.view_layer.objects.active = obj
bpy.context.view_layer.objects.active.location = active_location
except:
pass
return {'FINISHED'}
class LinkRotation_Operator(Operator):
bl_idname = "link.rotation"
bl_label = "Link Rotation"
bl_description = "............."
bl_options = {'REGISTER'}
def execute(self, context):
active_rotation = bpy.context.view_layer.objects.active.rotation_euler
for obj in bpy.context.selected_objects:
try:
bpy.context.view_layer.objects.active = obj
bpy.context.view_layer.objects.active.rotation_euler = active_rotation
except:
pass
return {'FINISHED'}
class LinkScale_Operator(Operator):
bl_idname = "link.scale"
bl_label = "Link Scale"
bl_description = "............."
bl_options = {'REGISTER'}
def execute(self, context):
active_scale = bpy.context.view_layer.objects.active.scale
for obj in bpy.context.selected_objects:
try:
bpy.context.view_layer.objects.active = obj
bpy.context.view_layer.objects.active.scale = active_scale
except:
pass
return {'FINISHED'}
class LinkTransform_Operator(Operator):
bl_idname = "link.transform"
bl_label = "Link Transform"
bl_description = "............."
bl_options = {'REGISTER'}
def execute(self, context):
active_location = bpy.context.view_layer.objects.active.location
active_rotation = bpy.context.view_layer.objects.active.rotation_euler
active_scale = bpy.context.view_layer.objects.active.scale
for obj in bpy.context.selected_objects:
try:
bpy.context.view_layer.objects.active = obj
bpy.context.view_layer.objects.active.location = active_location
bpy.context.view_layer.objects.active.rotation_euler = active_rotation
bpy.context.view_layer.objects.active.scale = active_scale
except:
pass
return {'FINISHED'}
class RotationFromCursor_Operator(Operator):
bl_idname = "link.cursor_rotation"
bl_label = "Set Object Rotation using 3D Cursor"
bl_description = "Orients your object rotation in relation to your 3D Cursor"
bl_options = {'REGISTER'}
def execute(self, context):
#Code from Sergey Kritskiy
def Rotate(myMesh, mat):
for v in myMesh.vertices:
vec = mat @ v.co
v.co = vec
def RotateFromCursor():
source = bpy.context.scene.cursor
objects = bpy.context.selected_objects
mat_source = source.rotation_euler.to_matrix()
mat_source.invert()
for ob in objects:
mat_ob = ob.rotation_euler.to_matrix()
if ob.type == 'MESH':
mat = mat_source @ mat_ob
Rotate(ob.data, mat)
ob.rotation_euler = source.rotation_euler
RotateFromCursor()#
return {'FINISHED'}
class ApplyDelta_Operator(Operator):
bl_idname = "apply.delta"
bl_label = "Apply Delta Transforms"
bl_description = "Applies Delta Transforms to selected objects"
bl_options = {'REGISTER'}
def execute(self, context):
bpy.ops.object.make_single_user(type='SELECTED_OBJECTS', obdata=True)
for obj in bpy.context.selected_objects:
bpy.context.view_layer.objects.active = obj
#Apply Loc
obj.location = [x+y for x,y in zip(obj.location,obj.delta_location)]
obj.delta_location = (0,0,0)
#Apply Rotation
bpy.ops.object.transforms_to_deltas(mode='ROT')
obj.rotation_euler = [x+y for x,y in zip(obj.rotation_euler,obj.delta_rotation_euler)]
obj.delta_rotation_euler = (0,0,0)
#apply scale
bpy.ops.object.transforms_to_deltas(mode='SCALE')
obj.scale = obj.delta_scale
obj.delta_scale = (1,1,1)
return {'FINISHED'}
def link_menu(self, context):
layout = self.layout
layout.separator()
layout.operator("link.location", text="Location")
layout.operator("link.rotation", text="Rotation")
layout.operator("link.scale", text="Scale")
layout.operator("link.transform", text="All Transforms")
layout.operator("link.cursor_rotation", text="Rotation from 3D Cursor")
def apply_menu(self, context):
layout = self.layout
layout.separator()
layout.operator("apply.delta", text="Apply Delta Transforms")
classes = (
LinkLocation_Operator,
LinkRotation_Operator,
LinkScale_Operator,
LinkTransform_Operator,
RotationFromCursor_Operator,
ApplyDelta_Operator
)
def register():
from bpy.utils import register_class
for cls in classes:
register_class(cls)
bpy.types.VIEW3D_MT_make_links.append(link_menu)
bpy.types.VIEW3D_MT_object_apply.append(apply_menu)
def unregister():
from bpy.utils import unregister_class
for cls in reversed(classes):
unregister_class(cls)
bpy.types.VIEW3D_MT_make_links.remove(draw_menu)
if __name__ == "__main__":
register()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment