自作アドオンで何回か使いそうな気がするのでいくつか作っておこうと思う
- オブジェクトの原点にてエンプティを置く(回転はローカル座標の回転方向)
- オブジェクトの中心にエンプティを置く(回転はローカル座標の回転方向)
- オブジェクトの一番下の辺の真ん中にエンプティを置く(回転はローカル座標の回転方向)
- オブジェクトの一番下の辺の真ん中にエンプティを置く(回転は面の向きに合わせる(板ポリの場合のみ有効))
オブジェクトの原点にエンプティを置く
回転はローカル座標の回転方向
import bpy obj = bpy.context.view_layer.objects.active mat = obj.matrix_world bpy.ops.object.empty_add(type='ARROWS', location=(0, 0, 0)) emp = bpy.context.view_layer.objects.active emp.matrix_world = mat for s in bpy.context.object.scale: s = 1
オブジェクトの中心にエンプティを置く
回転はローカル座標の回転方向
面だけならbmeshにbm.face.calc_center_median()という便利なものもあるがここでは使わない
import bpy from mathutils import Vector, Matrix obj = bpy.context.view_layer.objects.active mat = obj.matrix_world x = [] y = [] z = [] for v in obj.data.vertices: x.append(v.co.x) y.append(v.co.y) z.append(v.co.z) emp_x = min(x)+(max(x)-min(x))/2 emp_y = min(y)+(max(y)-min(y))/2 emp_z = min(z)+(max(z)-min(z))/2 emp_p = mat @ Vector((emp_x,emp_y,emp_z)) bpy.ops.object.empty_add(type='ARROWS', location=(0,0,0)) emp = bpy.context.object mat_emp = mat.copy() mat_emp[0][3]=emp_p[0] mat_emp[1][3]=emp_p[1] mat_emp[2][3]=emp_p[2] emp.matrix_world = mat_emp for s in bpy.context.object.scale: s = 1
オブジェクトの一番下の辺の真ん中にエンプティを置く
上下の定義は人によると思うがここではz軸とする
回転はローカル座標の回転方向
x = [] y = [] z = [] for e in obj.data.edges: id_0 = e.vertices[0] id_1 = e.vertices[1] v = obj.data.vertices c_p = mat @ v[id_1].co +(mat @ v[id_0].co-mat @ v[id_1].co)/2 x.append(c_p[0]) y.append(c_p[1]) z.append(c_p[2]) id = z.index(min(z)) emp_x = x[id] emp_y = y[id] emp_z = min(z) emp_p = Vector((emp_x,emp_y,emp_z)) bpy.ops.object.empty_add(type='ARROWS', location=(0,0,0)) emp = bpy.context.object mat_emp = mat.copy() mat_emp[0][3]=emp_p[0] mat_emp[1][3]=emp_p[1] mat_emp[2][3]=emp_p[2] emp.matrix_world = mat_emp for s in emp.scale: s = 1
オブジェクトの一番下の辺の真ん中にエンプティを置く
回転は面の向きに合わせる(オブジェクトが一枚の板ポリの場合のみ有効)
import bpy from mathutils import Vector, Matrix obj = bpy.context.view_layer.objects.active mat = obj.matrix_world msh = obj.data x = [] y = [] z = [] for e in msh.edges: id_0 = e.vertices[0] id_1 = e.vertices[1] v = msh.vertices c_p = (mat @ v[id_0].co + mat @ v[id_1].co)/2 x.append(c_p[0]) y.append(c_p[1]) z.append(c_p[2]) id = z.index(min(z)) emp_x = x[id] emp_y = y[id] emp_z = min(z) emp_p = Vector((emp_x,emp_y,emp_z)) m_id_0 = msh.edges[id].vertices[0] m_id_1 = msh.edges[id].vertices[1] muki = (mat@msh.vertices[m_id_0].co - mat@msh.vertices[m_id_1].co) mw_rot = mat.decompose()[1] norm = msh.polygons[0].normal mx_inv = mat.inverted() mx_norm = mx_inv.transposed().to_3x3() world_norm = mx_norm @ norm world_norm.normalize() cro = muki.cross(world_no) cro.normalize() muki.normalize() bpy.ops.object.empty_add(type='ARROWS', location=(0,0,0)) emp = bpy.context.object moto_mat=emp.matrix_world mat_emp = Matrix([[muki.x, -cro.x,world_norm.x, emp_p[0]], [muki.y, -cro.y, world_norm, emp_p[1]], [muki.z, -cro.z, world_norm.z, emp_p[2]], [0, 0, 0, 1]]) emp.matrix_world = moto_mat @ mat_emp