Page MenuHome

space_view3d_align_faces.py

space_view3d_align_faces.py

import bpy
import math
from mathutils import Vector
from functools import reduce
bl_info = {
"name": "Align by faces",
"author": "Tom Rethaller",
"version": (0,2),
"blender": (2, 65, 0),
"description": "Align two objects by their active faces",
"warning": "",
"category": "3D View"}
def align_faces(from_obj, to_obj):
fpolys = from_obj.data.polygons
tpolys = to_obj.data.polygons
fpoly = fpolys[fpolys.active]
tpoly = tpolys[tpolys.active]
to_obj.rotation_mode = 'QUATERNION'
tnorm = -(to_obj.rotation_quaternion * tpoly.normal)
cross = fpoly.normal.cross(tnorm)
dot = fpoly.normal.normalized().dot(tnorm.normalized())
from_obj.rotation_mode = 'AXIS_ANGLE'
from_obj.rotation_axis_angle = [math.acos(dot),cross[0],cross[1],cross[2]]
bpy.context.scene.update()
fvertices = [from_obj.data.vertices[i].co for i in fpoly.vertices]
tvertices = [to_obj.data.vertices[i].co for i in tpoly.vertices]
fbary = from_obj.matrix_world * (reduce(Vector.__add__, fvertices) / len(fvertices))
tbary = to_obj.matrix_world * (reduce(Vector.__add__, tvertices) / len(tvertices))
from_obj.location = tbary - (fbary - from_obj.location)
class OBJECT_OT_AlignByFaces(bpy.types.Operator):
bl_label = "Align by faces"
bl_description= "Align two objects by their active faces"
bl_idname = "object.align_by_faces"
@classmethod
def poll(cls, context):
if not len(context.selected_objects) is 2:
return False
for obj in context.selected_objects:
if obj.type != 'MESH':
return False
return True
def execute(self, context):
objs = context.selected_objects
align_faces(objs[0], objs[1])
return {'FINISHED'}
def register():
bpy.utils.register_module(__name__)
def unregister():
bpy.utils.unregister_module(__name__)

File Metadata

Mime Type
text/x-python
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
16/46/f17b49736f558e59f9751d27140a

Event Timeline