MRが楽しい

MRやVRについて学習したことを書き残す

Blender2.8で利用可能なpythonスクリプトを作る その26(バウンドボックスの利用)

本日は Blender の技術調査枠です。
Blender2.8で利用可能なpythonスクリプトを作ります。

オブジェクトのバウンドボックスから中心点を計算する

オブジェクトのバウンドボックス(境界サイズ)から、オブジェクトの中心座標を計算します。
座標はリスト形式で返ります。
・get_object_center.py

# bpyインポート
import bpy

# オブジェクトのバウンドボックスから中心点を計算する
def get_object_center(arg_objectname="Default") -> list:
    """オブジェクトのバウンドボックスから中心点を計算する

    Keyword Arguments:
        arg_objectname {str} -- 対象オブジェクト名 (default: {"Default"})

    Returns:
        list -- 中心座標
    """
    
    # 指定オブジェクトを取得する
    # (get関数は対象が存在しない場合 None が返る)
    selectob = bpy.data.objects.get(arg_objectname)

    # 指定オブジェクトが存在するか確認する
    if selectob == None:
        # 指定オブジェクトが存在しない場合は処理しない
        return [0.0, 0.0, 0.0]
    
    # 指定オブジェクトの境界情報を取得する
    # オブジェクトのインタフェース
    # (https://docs.blender.org/api/current/bpy.types.Object.html)
    target_boundbox = selectob.bound_box

    # 変数の初期化
    vertcount = 0
    center_x = 0.0
    center_y = 0.0
    center_z = 0.0

    # 頂点座標の加算
    for vert_boundbox in target_boundbox:
        center_x += vert_boundbox[0]
        center_y += vert_boundbox[1]
        center_z += vert_boundbox[2]
        vertcount += 1

    # 中点の計算
    center_x = center_x / vertcount
    center_y = center_y / vertcount
    center_z = center_z / vertcount

    return [center_x, center_y, center_z]

# 関数の実行例
center_pos = get_object_center(arg_objectname="Combo")
print(center_pos)

f:id:bluebirdofoz:20200512091223j:plain

対象オブジェクトのバウンドボックス(境界)と同じサイズのCubeを作成する

対象オブジェクトのバウンドボックス(境界)と同じサイズのCubeを作成します。
・make_cube_boundbox

# bpyインポート
import bpy

# 対象オブジェクトのバウンドボックス(境界)と同じサイズのCubeを作成する
def make_cube_boundbox(arg_objectname="Default", arg_makename="BoundBox") -> bool:
    """対象オブジェクトのバウンドボックス(境界)と同じサイズのCubeを作成する

    Keyword Arguments:
        arg_objectname {str} -- 指定オブジェクト名 (default: {"Default"})
        arg_makename {str} -- 作成オブジェクト名 (default: {"BoundBox"})

    Returns:
        bool -- 実行正否
    """

    # 指定オブジェクトを取得する
    # (get関数は対象が存在しない場合 None が返る)
    selectob = bpy.data.objects.get(arg_objectname)

    # 指定オブジェクトが存在するか確認する
    if selectob == None:
        # 指定オブジェクトが存在しない場合は処理しない
        return False
    
    # 指定オブジェクトの境界情報を取得する
    # オブジェクトのインタフェース
    # (https://docs.blender.org/api/current/bpy.types.Object.html)
    target_boundbox = selectob.bound_box

    # 変数の初期化
    vertcount = 0
    center_x = 0.0
    center_y = 0.0
    center_z = 0.0

    # 頂点座標の加算
    for vert_boundbox in target_boundbox:
        center_x += vert_boundbox[0]
        center_y += vert_boundbox[1]
        center_z += vert_boundbox[2]
        vertcount += 1

    # 中点の計算
    center_x = center_x / vertcount
    center_y = center_y / vertcount
    center_z = center_z / vertcount

    # 寸法の取得
    dimension_x = selectob.dimensions[0]
    dimension_y = selectob.dimensions[1]
    dimension_z = selectob.dimensions[2]


    # もし作成予定と同名のメッシュオブジェクトが既に存在していれば新規作成しない
    if arg_makename in bpy.data.objects:
        return False

    # Cubeオブジェクトを作成する
    bpy.ops.mesh.primitive_cube_add(
        size=2.0,
        location=(0.0, 0.0, 0.0),
        rotation=(0.0, 0.0, 0.0)
    )

    # 作成したオブジェクトの参照を取得する
    makeob = bpy.context.view_layer.objects.active
    
    # オブジェクト名を変更する
    makeob.name = arg_makename
    
    # オブジェクトの位置を中点位置に変更する
    makeob.location = (center_x, center_y, center_z)

    # オブジェクトのスケールを対象オブジェクトと同じにする
    makeob.scale = (dimension_x / 2.0, dimension_y / 2.0, dimension_z / 2.0)

    return True

# 関数の実行例
make_cube_boundbox(
    arg_objectname="Combo",
    arg_makename="BoundBox"
)

f:id:bluebirdofoz:20200512091234j:plain

オブジェクトのバウンドボックスから指定軸の対角線の長さを計算する

オブジェクトのバウンドボックスから指定軸の対角線の長さを計算します。
・make_cube_boundbox

# bpyインポート
import bpy
# numpyインポート(ベクトルの長さ計算のため)
import numpy as np

# オブジェクトのバウンドボックスから指定軸の対角線の長さを計算する
def get_object_diagonal(arg_objectname="Default", arg_x=True, arg_Y=True, arg_Z=True) -> float:
    """オブジェクトのバウンドボックスから対角線の長さを計算する

    Keyword Arguments:
        arg_objectname {str} -- 対象オブジェクト名 (default: {"Default"})
        arg_x {bool} -- X軸の指定 (default: {True})
        arg_Y {bool} -- Y軸の指定 (default: {True})
        arg_Z {bool} -- Z軸の指定 (default: {True})

    Returns:
        float -- 対角線の長さ
    """
    
    # 指定オブジェクトを取得する
    # (get関数は対象が存在しない場合 None が返る)
    selectob = bpy.data.objects.get(arg_objectname)

    # 指定オブジェクトが存在するか確認する
    if selectob == None:
        # 指定オブジェクトが存在しない場合は処理しない
        return 0.0

    # X軸の寸法の取得
    dimension_x = 0.0
    if arg_x:
        dimension_x = selectob.dimensions[0]
    
    # Y軸の寸法の取得
    dimension_y = 0.0
    if arg_Y:
        dimension_y = selectob.dimensions[1]

    # Z軸の寸法の取得
    dimension_z = 0.0
    if arg_Z:
        dimension_z = selectob.dimensions[2]
    
    # 対角線の配列を取得する
    dimension = np.array([dimension_x, dimension_y, dimension_z])

    # 対角線の長さを取得する
    diagonal = np.linalg.norm(dimension)

    return diagonal

# 関数の実行例
get_size = get_object_diagonal(arg_objectname="Sphere", arg_x=True, arg_Y=True, arg_Z=True)
print(get_size)

f:id:bluebirdofoz:20200601022112j:plain