I'm trying to find a way to place an object on the selected face from another object according the normal face.
I'd like the local orientation of my first object correspond to the normals of the selected face from my second object.
This is my code.
import bpy
import bmesh
from mathutils import Vector
class TestPanel(bpy.types.Panel):
bl_idname = "object.test_panel"
bl_label = "Test Panel"
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
def draw(self, context):
layout = self.layout
layout.operator("object.clone_object", text="Add Suzanne")
class AddCloneObject(bpy.types.Operator):
bl_idname = "object.clone_object"
bl_label = "Clone object"
def execute(self, context):
if context.object.mode == 'EDIT':
bpy.ops.object.mode_set(mode='OBJECT')
obj = bpy.context.active_object
bm = bmesh.new()
bm.from_mesh(obj.data)
selected_faces = [f for f in bm.faces if f.select]
for face in selected_faces:
face_location = face.calc_center_median()
loc_world_space = obj.matrix_world * Vector(face_location)
z = Vector((0,0,1))
angle = face.normal.angle(z)
axis = z.cross(face.normal)
bpy.context.scene.cursor_location = loc_world_space
bpy.ops.mesh.primitive_monkey_add(radius=0.5)
bpy.ops.transform.rotate(value=angle, axis=axis)
print("face location = ", loc_world_space)
print("angle = ", angle)
print("axis = ", axis)
print("Suzanne = ", context.active_object.matrix_world)
bm.to_mesh(obj.data)
bm.free()
return {'FINISHED'}
else:
self.report({'INFO'}, "Need to be in edit_mode")
return {'FINISHED'}
def register():
bpy.utils.register_module(__name__)
def unregister():
bpy.utils.unregister_module(__name__)
if __name__ == "__main__":
register()
The X and Y axis are good, but the Z axis seems not to undergo rotation.