from → to を指すempty arrowを追加する。以下では、現在のアクティブオブジェクトのoriginから3D cursorへ矢印を作成する
import bpy import math import numpy import mathutils # @brief オブジェクトを指定座標へ向けるための回転軸と回転角を計算する # @param [in] オブジェクト # @param [in] 向ける方向(座標) # @return 回転軸,回転角(ラジアン) def calc_lookat_param(obj,lookat): # オブジェクトのローカルのZ軸のベクトルを取得 mat = obj.matrix_world localZ = mathutils.Vector((mat[0][2],mat[1][2],mat[2][2])) print(localZ) va = mathutils.Vector(lookat) - obj.location vb = mathutils.Vector(localZ) va.normalize() vb.normalize() # 外積 axis = mathutils.Vector.cross(va,vb) axis.normalize() # 内積 th = mathutils.Vector.dot(va,vb) # 角度算出 rad = -math.acos( numpy.clip(th,-1.0,1.0) ) return axis , rad # @brief 任意軸回転 # @param [in,out] obj 回転するオブジェクト # @param [in] axis 回転軸 # @param [in] radian 回転角をラジアンで指定 # @return なし # @sa https://www.study.suzulang.com/bpy-calculation/bpy-arbitrary-axis-rotation def rotate_object(obj,axis,radian): rot_mat= mathutils.Matrix.Rotation( radian, 4, axis ) # decompose world_matrix's components, and from them assemble 4x4 matrices orig_loc, orig_rot, orig_scale = obj.matrix_world.decompose() # orig_loc_mat = mathutils.Matrix.Translation(orig_loc) orig_rot_mat = orig_rot.to_matrix().to_4x4() orig_scale_mat = (mathutils.Matrix.Scale(orig_scale[0],4,(1,0,0)) @ mathutils.Matrix.Scale(orig_scale[1],4,(0,1,0)) @ mathutils.Matrix.Scale(orig_scale[2],4,(0,0,1))) # # assemble the new matrix obj.matrix_world = orig_loc_mat @ rot_mat @ orig_rot_mat @ orig_scale_mat
# @brief _fromから_toを指すEmptyArrowを作成 # @param [in] 矢印の根元の座標 # @param [in] 矢印の先端の座標 # @return 作成したオブジェクト def make_empty_arrow(_from,_to): # 新しいEmpty ObjectのArrowを作成 bpy.ops.object.empty_add(type="SINGLE_ARROW",location=_from) aobj = bpy.context.object # 方向を一致させるためのパラメータ取得 axis , rad = calc_lookat_param(aobj,_to) # 回転 rotate_object(aobj,axis,rad) # _from → _to の距離を計算 objlen = ( _from - _to ).length # 矢印の長さ==スケール aobj.scale[0] = objlen aobj.scale[1] = objlen aobj.scale[2] = objlen return aobj
# 使用例 obj = bpy.context.active_object arrow = make_empty_arrow( obj.location, bpy.context.scene.cursor.location ) print(arrow.name)